1
0

First cut at refactoring unittests into a top-level utility. Individual tests co-located with their DUT. No functional changes.

This commit is contained in:
Henry Cook 2016-09-13 15:37:29 -07:00 committed by Howard Mao
parent dfd6bfb454
commit 7dd4492abb
24 changed files with 353 additions and 364 deletions

View File

@ -8,9 +8,8 @@ import uncore.tilelink._
import uncore.coherence._ import uncore.coherence._
import uncore.agents._ import uncore.agents._
import uncore.devices.NTiles import uncore.devices.NTiles
import uncore.unittests._ import unittest._
import junctions._ import junctions._
import junctions.unittests._
import scala.collection.mutable.LinkedHashSet import scala.collection.mutable.LinkedHashSet
import cde.{Parameters, Config, Dump, Knob, CDEMatchError} import cde.{Parameters, Config, Dump, Knob, CDEMatchError}
import scala.math.max import scala.math.max

View File

@ -1,7 +1,7 @@
package coreplex package coreplex
import Chisel._ import Chisel._
import junctions.unittests.UnitTestSuite import unittest.UnitTestSuite
import rocket.Tile import rocket.Tile
import uncore.tilelink.TLId import uncore.tilelink.TLId
import cde.Parameters import cde.Parameters

View File

@ -5,6 +5,7 @@ import uncore.tilelink._
import uncore.constants._ import uncore.constants._
import junctions._ import junctions._
import rocket._ import rocket._
import util.Timer
import scala.util.Random import scala.util.Random
import cde.{Parameters, Field} import cde.{Parameters, Field}

View File

@ -6,6 +6,7 @@ import uncore.devices.NTiles
import uncore.constants._ import uncore.constants._
import junctions._ import junctions._
import rocket._ import rocket._
import util.Timer
import scala.util.Random import scala.util.Random
import cde.{Parameters, Field} import cde.{Parameters, Field}

View File

@ -4,6 +4,7 @@ import Chisel._
import uncore.tilelink._ import uncore.tilelink._
import uncore.converters._ import uncore.converters._
import junctions._ import junctions._
import util.Timer
import rocket.TileId import rocket.TileId
import cde.Parameters import cde.Parameters

View File

@ -5,7 +5,8 @@ import uncore.tilelink._
import uncore.constants._ import uncore.constants._
import uncore.agents._ import uncore.agents._
import uncore.util._ import uncore.util._
import junctions.{ParameterizedBundle, HasAddrMapParameters, Timer} import junctions.{ParameterizedBundle, HasAddrMapParameters}
import util.Timer
import rocket.HellaCacheIO import rocket.HellaCacheIO
import cde.{Parameters, Field} import cde.{Parameters, Field}

View File

@ -22,6 +22,7 @@ import uncore.constants._
import uncore.devices.NTiles import uncore.devices.NTiles
import junctions._ import junctions._
import rocket._ import rocket._
import util.{Timer, DynamicTimer}
import scala.util.Random import scala.util.Random
import cde.{Parameters, Field} import cde.{Parameters, Field}

View File

@ -2,35 +2,6 @@ package groundtest
import Chisel._ import Chisel._
// =============
// Dynamic timer
// =============
// Timer with a dynamically-settable period.
class DynamicTimer(w: Int) extends Module {
val io = new Bundle {
val start = Bool(INPUT)
val period = UInt(INPUT, w)
val stop = Bool(INPUT)
val timeout = Bool(OUTPUT)
}
val countdown = Reg(init = UInt(0, w))
val active = Reg(init = Bool(false))
when (io.start) {
countdown := io.period
active := Bool(true)
} .elsewhen (io.stop || countdown === UInt(0)) {
active := Bool(false)
} .elsewhen (active) {
countdown := countdown - UInt(1)
}
io.timeout := countdown === UInt(0) && active
}
// ============ // ============
// LCG16 module // LCG16 module
// ============ // ============

View File

@ -0,0 +1,158 @@
package junctions
import Chisel._
import unittest.UnitTest
class MultiWidthFifo(inW: Int, outW: Int, n: Int) extends Module {
val io = new Bundle {
val in = Decoupled(Bits(width = inW)).flip
val out = Decoupled(Bits(width = outW))
val count = UInt(OUTPUT, log2Up(n + 1))
}
if (inW == outW) {
val q = Module(new Queue(Bits(width = inW), n))
q.io.enq <> io.in
io.out <> q.io.deq
io.count := q.io.count
} else if (inW > outW) {
val nBeats = inW / outW
require(inW % outW == 0, s"MultiWidthFifo: in: $inW not divisible by out: $outW")
require(n % nBeats == 0, s"Cannot store $n output words when output beats is $nBeats")
val wdata = Reg(Vec(n / nBeats, Bits(width = inW)))
val rdata = Vec(wdata.flatMap { indat =>
(0 until nBeats).map(i => indat(outW * (i + 1) - 1, outW * i)) })
val head = Reg(init = UInt(0, log2Up(n / nBeats)))
val tail = Reg(init = UInt(0, log2Up(n)))
val size = Reg(init = UInt(0, log2Up(n + 1)))
when (io.in.fire()) {
wdata(head) := io.in.bits
head := head + UInt(1)
}
when (io.out.fire()) { tail := tail + UInt(1) }
size := MuxCase(size, Seq(
(io.in.fire() && io.out.fire()) -> (size + UInt(nBeats - 1)),
io.in.fire() -> (size + UInt(nBeats)),
io.out.fire() -> (size - UInt(1))))
io.out.valid := size > UInt(0)
io.out.bits := rdata(tail)
io.in.ready := size < UInt(n)
io.count := size
} else {
val nBeats = outW / inW
require(outW % inW == 0, s"MultiWidthFifo: out: $outW not divisible by in: $inW")
val wdata = Reg(Vec(n * nBeats, Bits(width = inW)))
val rdata = Vec.tabulate(n) { i =>
Cat(wdata.slice(i * nBeats, (i + 1) * nBeats).reverse)}
val head = Reg(init = UInt(0, log2Up(n * nBeats)))
val tail = Reg(init = UInt(0, log2Up(n)))
val size = Reg(init = UInt(0, log2Up(n * nBeats + 1)))
when (io.in.fire()) {
wdata(head) := io.in.bits
head := head + UInt(1)
}
when (io.out.fire()) { tail := tail + UInt(1) }
size := MuxCase(size, Seq(
(io.in.fire() && io.out.fire()) -> (size - UInt(nBeats - 1)),
io.in.fire() -> (size + UInt(1)),
io.out.fire() -> (size - UInt(nBeats))))
io.count := size >> UInt(log2Up(nBeats))
io.out.valid := io.count > UInt(0)
io.out.bits := rdata(tail)
io.in.ready := size < UInt(n * nBeats)
}
}
class MultiWidthFifoTest extends UnitTest {
val big2little = Module(new MultiWidthFifo(16, 8, 8))
val little2big = Module(new MultiWidthFifo(8, 16, 4))
val bl_send = Reg(init = Bool(false))
val lb_send = Reg(init = Bool(false))
val bl_recv = Reg(init = Bool(false))
val lb_recv = Reg(init = Bool(false))
val bl_finished = Reg(init = Bool(false))
val lb_finished = Reg(init = Bool(false))
val bl_data = Vec.tabulate(4){i => UInt((2 * i + 1) * 256 + 2 * i, 16)}
val lb_data = Vec.tabulate(8){i => UInt(i, 8)}
val (bl_send_cnt, bl_send_done) = Counter(big2little.io.in.fire(), 4)
val (lb_send_cnt, lb_send_done) = Counter(little2big.io.in.fire(), 8)
val (bl_recv_cnt, bl_recv_done) = Counter(big2little.io.out.fire(), 8)
val (lb_recv_cnt, lb_recv_done) = Counter(little2big.io.out.fire(), 4)
big2little.io.in.valid := bl_send
big2little.io.in.bits := bl_data(bl_send_cnt)
big2little.io.out.ready := bl_recv
little2big.io.in.valid := lb_send
little2big.io.in.bits := lb_data(lb_send_cnt)
little2big.io.out.ready := lb_recv
val bl_recv_data_idx = bl_recv_cnt >> UInt(1)
val bl_recv_data = Mux(bl_recv_cnt(0),
bl_data(bl_recv_data_idx)(15, 8),
bl_data(bl_recv_data_idx)(7, 0))
val lb_recv_data = Cat(
lb_data(Cat(lb_recv_cnt, UInt(1, 1))),
lb_data(Cat(lb_recv_cnt, UInt(0, 1))))
when (io.start) {
bl_send := Bool(true)
lb_send := Bool(true)
}
when (bl_send_done) {
bl_send := Bool(false)
bl_recv := Bool(true)
}
when (lb_send_done) {
lb_send := Bool(false)
lb_recv := Bool(true)
}
when (bl_recv_done) {
bl_recv := Bool(false)
bl_finished := Bool(true)
}
when (lb_recv_done) {
lb_recv := Bool(false)
lb_finished := Bool(true)
}
io.finished := bl_finished && lb_finished
val bl_start_recv = Reg(next = bl_send_done)
val lb_start_recv = Reg(next = lb_send_done)
assert(!little2big.io.out.valid || little2big.io.out.bits === lb_recv_data,
"Little to Big data mismatch")
assert(!big2little.io.out.valid || big2little.io.out.bits === bl_recv_data,
"Bit to Little data mismatch")
assert(!lb_start_recv || little2big.io.count === UInt(4),
"Little to Big count incorrect")
assert(!bl_start_recv || big2little.io.count === UInt(8),
"Big to Little count incorrect")
}

View File

@ -1,8 +1,6 @@
package junctions.unittests package junctions
import Chisel._ import Chisel._
import junctions._
import junctions.NastiConstants._
import cde.Parameters import cde.Parameters
class NastiDemuxDriver(n: Int)(implicit p: Parameters) extends Module { class NastiDemuxDriver(n: Int)(implicit p: Parameters) extends Module {
@ -93,7 +91,7 @@ class NastiDemuxSlave(implicit p: Parameters) extends NastiModule()(p) {
io.r.bits := NastiReadDataChannel(id = id, data = value) io.r.bits := NastiReadDataChannel(id = id, data = value)
} }
class NastiMemoryDemuxTest(implicit p: Parameters) extends UnitTest { class NastiMemoryDemuxTest(implicit p: Parameters) extends unittest.UnitTest {
val nSlaves = 4 val nSlaves = 4
val driver = Module(new NastiDemuxDriver(nSlaves)) val driver = Module(new NastiDemuxDriver(nSlaves))

View File

@ -1,8 +1,6 @@
package junctions.unittests package junctions
import Chisel._ import Chisel._
import junctions._
import junctions.NastiConstants._
import cde.Parameters import cde.Parameters
class NastiDriver(dataWidth: Int, burstLen: Int, nBursts: Int) class NastiDriver(dataWidth: Int, burstLen: Int, nBursts: Int)
@ -76,16 +74,3 @@ class NastiDriver(dataWidth: Int, burstLen: Int, nBursts: Int)
assert(!io.nasti.r.valid || read_data === expected_data, assert(!io.nasti.r.valid || read_data === expected_data,
s"NastiDriver got wrong data") s"NastiDriver got wrong data")
} }
class HastiTest(implicit p: Parameters) extends UnitTest {
val sram = Module(new HastiTestSRAM(8))
val bus = Module(new HastiBus(Seq(a => Bool(true))))
val conv = Module(new HastiMasterIONastiIOConverter)
val driver = Module(new NastiDriver(32, 8, 2))
bus.io.slaves(0) <> sram.io
bus.io.master <> conv.io.hasti
conv.io.nasti <> driver.io.nasti
io.finished := driver.io.finished
driver.io.start := io.start
}

View File

@ -2,6 +2,7 @@ package junctions
import Chisel._ import Chisel._
import cde.{Parameters, Field} import cde.{Parameters, Field}
import unittest.UnitTest
object HastiConstants object HastiConstants
{ {
@ -547,3 +548,16 @@ class HastiTestSRAM(depth: Int)(implicit p: Parameters) extends HastiModule()(p)
io.hready := ready io.hready := ready
io.hresp := HRESP_OKAY io.hresp := HRESP_OKAY
} }
class HastiTest(implicit p: Parameters) extends UnitTest {
val sram = Module(new HastiTestSRAM(8))
val bus = Module(new HastiBus(Seq(a => Bool(true))))
val conv = Module(new HastiMasterIONastiIOConverter)
val driver = Module(new NastiDriver(32, 8, 2))
bus.io.slaves(0) <> sram.io
bus.io.master <> conv.io.hasti
conv.io.nasti <> driver.io.nasti
io.finished := driver.io.finished
driver.io.start := io.start
}

View File

@ -1,85 +0,0 @@
package junctions.unittests
import Chisel._
import junctions._
import junctions.NastiConstants._
class MultiWidthFifoTest extends UnitTest {
val big2little = Module(new MultiWidthFifo(16, 8, 8))
val little2big = Module(new MultiWidthFifo(8, 16, 4))
val bl_send = Reg(init = Bool(false))
val lb_send = Reg(init = Bool(false))
val bl_recv = Reg(init = Bool(false))
val lb_recv = Reg(init = Bool(false))
val bl_finished = Reg(init = Bool(false))
val lb_finished = Reg(init = Bool(false))
val bl_data = Vec.tabulate(4){i => UInt((2 * i + 1) * 256 + 2 * i, 16)}
val lb_data = Vec.tabulate(8){i => UInt(i, 8)}
val (bl_send_cnt, bl_send_done) = Counter(big2little.io.in.fire(), 4)
val (lb_send_cnt, lb_send_done) = Counter(little2big.io.in.fire(), 8)
val (bl_recv_cnt, bl_recv_done) = Counter(big2little.io.out.fire(), 8)
val (lb_recv_cnt, lb_recv_done) = Counter(little2big.io.out.fire(), 4)
big2little.io.in.valid := bl_send
big2little.io.in.bits := bl_data(bl_send_cnt)
big2little.io.out.ready := bl_recv
little2big.io.in.valid := lb_send
little2big.io.in.bits := lb_data(lb_send_cnt)
little2big.io.out.ready := lb_recv
val bl_recv_data_idx = bl_recv_cnt >> UInt(1)
val bl_recv_data = Mux(bl_recv_cnt(0),
bl_data(bl_recv_data_idx)(15, 8),
bl_data(bl_recv_data_idx)(7, 0))
val lb_recv_data = Cat(
lb_data(Cat(lb_recv_cnt, UInt(1, 1))),
lb_data(Cat(lb_recv_cnt, UInt(0, 1))))
when (io.start) {
bl_send := Bool(true)
lb_send := Bool(true)
}
when (bl_send_done) {
bl_send := Bool(false)
bl_recv := Bool(true)
}
when (lb_send_done) {
lb_send := Bool(false)
lb_recv := Bool(true)
}
when (bl_recv_done) {
bl_recv := Bool(false)
bl_finished := Bool(true)
}
when (lb_recv_done) {
lb_recv := Bool(false)
lb_finished := Bool(true)
}
io.finished := bl_finished && lb_finished
val bl_start_recv = Reg(next = bl_send_done)
val lb_start_recv = Reg(next = lb_send_done)
assert(!little2big.io.out.valid || little2big.io.out.bits === lb_recv_data,
"Little to Big data mismatch")
assert(!big2little.io.out.valid || big2little.io.out.bits === bl_recv_data,
"Bit to Little data mismatch")
assert(!lb_start_recv || little2big.io.count === UInt(4),
"Little to Big count incorrect")
assert(!bl_start_recv || big2little.io.count === UInt(8),
"Big to Little count incorrect")
}

View File

@ -244,128 +244,3 @@ class DecoupledHelper(val rvs: Seq[Bool]) {
(rvs.filter(_ ne exclude) ++ includes).reduce(_ && _) (rvs.filter(_ ne exclude) ++ includes).reduce(_ && _)
} }
} }
class MultiWidthFifo(inW: Int, outW: Int, n: Int) extends Module {
val io = new Bundle {
val in = Decoupled(Bits(width = inW)).flip
val out = Decoupled(Bits(width = outW))
val count = UInt(OUTPUT, log2Up(n + 1))
}
if (inW == outW) {
val q = Module(new Queue(Bits(width = inW), n))
q.io.enq <> io.in
io.out <> q.io.deq
io.count := q.io.count
} else if (inW > outW) {
val nBeats = inW / outW
require(inW % outW == 0, s"MultiWidthFifo: in: $inW not divisible by out: $outW")
require(n % nBeats == 0, s"Cannot store $n output words when output beats is $nBeats")
val wdata = Reg(Vec(n / nBeats, Bits(width = inW)))
val rdata = Vec(wdata.flatMap { indat =>
(0 until nBeats).map(i => indat(outW * (i + 1) - 1, outW * i)) })
val head = Reg(init = UInt(0, log2Up(n / nBeats)))
val tail = Reg(init = UInt(0, log2Up(n)))
val size = Reg(init = UInt(0, log2Up(n + 1)))
when (io.in.fire()) {
wdata(head) := io.in.bits
head := head + UInt(1)
}
when (io.out.fire()) { tail := tail + UInt(1) }
size := MuxCase(size, Seq(
(io.in.fire() && io.out.fire()) -> (size + UInt(nBeats - 1)),
io.in.fire() -> (size + UInt(nBeats)),
io.out.fire() -> (size - UInt(1))))
io.out.valid := size > UInt(0)
io.out.bits := rdata(tail)
io.in.ready := size < UInt(n)
io.count := size
} else {
val nBeats = outW / inW
require(outW % inW == 0, s"MultiWidthFifo: out: $outW not divisible by in: $inW")
val wdata = Reg(Vec(n * nBeats, Bits(width = inW)))
val rdata = Vec.tabulate(n) { i =>
Cat(wdata.slice(i * nBeats, (i + 1) * nBeats).reverse)}
val head = Reg(init = UInt(0, log2Up(n * nBeats)))
val tail = Reg(init = UInt(0, log2Up(n)))
val size = Reg(init = UInt(0, log2Up(n * nBeats + 1)))
when (io.in.fire()) {
wdata(head) := io.in.bits
head := head + UInt(1)
}
when (io.out.fire()) { tail := tail + UInt(1) }
size := MuxCase(size, Seq(
(io.in.fire() && io.out.fire()) -> (size - UInt(nBeats - 1)),
io.in.fire() -> (size + UInt(1)),
io.out.fire() -> (size - UInt(nBeats))))
io.count := size >> UInt(log2Up(nBeats))
io.out.valid := io.count > UInt(0)
io.out.bits := rdata(tail)
io.in.ready := size < UInt(n * nBeats)
}
}
// ============
// Static timer
// ============
// Timer with a statically-specified period.
// Can take multiple inflight start-stop events with ID
// Will continue to count down as long as at least one event is inflight
class Timer(initCount: Int, maxInflight: Int) extends Module {
val io = new Bundle {
val start = Valid(UInt(width = log2Up(maxInflight))).flip
val stop = Valid(UInt(width = log2Up(maxInflight))).flip
val timeout = Valid(UInt(width = log2Up(maxInflight)))
}
val inflight = Reg(init = Vec.fill(maxInflight) { Bool(false) })
val countdown = Reg(UInt(width = log2Up(initCount)))
val active = inflight.reduce(_ || _)
when (active) {
countdown := countdown - UInt(1)
}
when (io.start.valid) {
inflight(io.start.bits) := Bool(true)
countdown := UInt(initCount - 1)
}
when (io.stop.valid) {
inflight(io.stop.bits) := Bool(false)
}
io.timeout.valid := countdown === UInt(0) && active
io.timeout.bits := PriorityEncoder(inflight)
assert(!io.stop.valid || inflight(io.stop.bits),
"Timer stop for transaction that's not inflight")
}
object Timer {
def apply(initCount: Int, start: Bool, stop: Bool): Bool = {
val timer = Module(new Timer(initCount, 1))
timer.io.start.valid := start
timer.io.start.bits := UInt(0)
timer.io.stop.valid := stop
timer.io.stop.bits := UInt(0)
timer.io.timeout.valid
}
}

View File

@ -7,9 +7,8 @@ import uncore.tilelink._
import uncore.coherence._ import uncore.coherence._
import uncore.agents._ import uncore.agents._
import uncore.devices.NTiles import uncore.devices.NTiles
import uncore.unittests._ import unittest._
import junctions._ import junctions._
import junctions.unittests._
import scala.collection.mutable.LinkedHashSet import scala.collection.mutable.LinkedHashSet
import scala.collection.immutable.HashMap import scala.collection.immutable.HashMap
import cde.{Parameters, Config, Dump, Knob, CDEMatchError} import cde.{Parameters, Config, Dump, Knob, CDEMatchError}

View File

@ -30,3 +30,30 @@ class SmiIOTileLinkIOConverter(val dataWidth: Int, val addrWidth: Int)
decoupledNastiConnect(nasti2smi.io.nasti, tl2nasti.io.nasti) decoupledNastiConnect(nasti2smi.io.nasti, tl2nasti.io.nasti)
io.smi <> nasti2smi.io.smi io.smi <> nasti2smi.io.smi
} }
class SmiConverterTest(implicit val p: Parameters) extends unittest.UnitTest
with HasTileLinkParameters {
val outermostParams = p.alterPartial({ case TLId => "Outermost" })
val smiWidth = 32
val smiDepth = 64
val tlDepth = (smiWidth * smiDepth) / tlDataBits
val smimem = Module(new SmiMem(smiWidth, smiDepth))
val conv = Module(new SmiIOTileLinkIOConverter(
smiWidth, log2Up(smiDepth))(outermostParams))
val driver = Module(new DriverSet(
(driverParams: Parameters) => {
implicit val p = driverParams
Seq(
Module(new PutSweepDriver(tlDepth)),
Module(new PutMaskDriver(smiWidth / 8)),
Module(new PutBlockSweepDriver(tlDepth / tlDataBeats)),
Module(new GetMultiWidthDriver))
})(outermostParams))
conv.io.tl <> driver.io.mem
smimem.io <> conv.io.smi
driver.io.start := io.start
io.finished := driver.io.finished
}

View File

@ -2,6 +2,7 @@ package uncore.devices
import Chisel._ import Chisel._
import cde.{Parameters, Field} import cde.{Parameters, Field}
import unittest.UnitTest
import junctions._ import junctions._
import uncore.tilelink._ import uncore.tilelink._
import uncore.util._ import uncore.util._
@ -159,3 +160,24 @@ class TileLinkTestRAM(depth: Int)(implicit val p: Parameters) extends Module
ram(acq_addr) := (old_data & ~wmask) | (result & wmask) ram(acq_addr) := (old_data & ~wmask) | (result & wmask)
} }
} }
class TileLinkRAMTest(implicit val p: Parameters)
extends UnitTest with HasTileLinkParameters {
val depth = 2 * tlDataBeats
val ram = Module(new TileLinkTestRAM(depth))
val driver = Module(new DriverSet(
(driverParams: Parameters) => {
implicit val p = driverParams
Seq(
Module(new PutSweepDriver(depth)),
Module(new PutMaskDriver),
Module(new PutAtomicDriver),
Module(new PutBlockSweepDriver(depth / tlDataBeats)),
Module(new PrefetchDriver),
Module(new GetMultiWidthDriver))
}))
ram.io <> driver.io.mem
driver.io.start := io.start
io.finished := driver.io.finished
}

View File

@ -1,6 +1,7 @@
package uncore.devices package uncore.devices
import Chisel._ import Chisel._
import unittest.UnitTest
import junctions._ import junctions._
import uncore.tilelink._ import uncore.tilelink._
import uncore.util._ import uncore.util._
@ -41,6 +42,26 @@ class ROMSlave(contents: Seq[Byte])(implicit val p: Parameters) extends Module
data = rdata) data = rdata)
} }
class ROMSlaveTest(implicit p: Parameters) extends UnitTest {
implicit val testName = "ROMSlaveTest"
val romdata = Seq(
BigInt("01234567deadbeef", 16),
BigInt("ab32fee8d00dfeed", 16))
val rombytes = romdata.map(_.toByteArray.reverse).flatten
val rom = Module(new ROMSlave(rombytes))
val driver = Module(new DriverSet(
(driverParams: Parameters) => {
implicit val p = driverParams
Seq(
Module(new GetMultiWidthDriver),
Module(new GetSweepDriver(romdata)),
Module(new GetBlockSweepDriver(romdata)))
}))
rom.io <> driver.io.mem
driver.io.start := io.start
io.finished := driver.io.finished
}
class NastiROM(contents: Seq[Byte])(implicit p: Parameters) extends Module { class NastiROM(contents: Seq[Byte])(implicit p: Parameters) extends Module {
val io = new NastiIO().flip val io = new NastiIO().flip
val ar = Queue(io.ar, 1) val ar = Queue(io.ar, 1)

View File

@ -1,8 +1,7 @@
package uncore.unittests package uncore.tilelink
import Chisel._ import Chisel._
import junctions._ import junctions._
import uncore.tilelink._
import uncore.constants._ import uncore.constants._
import uncore.util._ import uncore.util._
import cde.Parameters import cde.Parameters

View File

@ -3,7 +3,7 @@ package uncore.tilelink2
import Chisel._ import Chisel._
import chisel3.util.LFSR16 import chisel3.util.LFSR16
import junctions.unittests._ import unittest._
class IDMapGenerator(numIds: Int) extends Module { class IDMapGenerator(numIds: Int) extends Module {
val w = log2Up(numIds) val w = log2Up(numIds)

View File

@ -1,86 +0,0 @@
package uncore.unittests
import Chisel._
import junctions._
import junctions.unittests._
import uncore.devices._
import uncore.tilelink._
import uncore.converters._
import cde.Parameters
class SmiConverterTest(implicit val p: Parameters) extends UnitTest
with HasTileLinkParameters {
val outermostParams = p.alterPartial({ case TLId => "Outermost" })
val smiWidth = 32
val smiDepth = 64
val tlDepth = (smiWidth * smiDepth) / tlDataBits
val smimem = Module(new SmiMem(smiWidth, smiDepth))
val conv = Module(new SmiIOTileLinkIOConverter(
smiWidth, log2Up(smiDepth))(outermostParams))
val driver = Module(new DriverSet(
(driverParams: Parameters) => {
implicit val p = driverParams
Seq(
Module(new PutSweepDriver(tlDepth)),
Module(new PutMaskDriver(smiWidth / 8)),
Module(new PutBlockSweepDriver(tlDepth / tlDataBeats)),
Module(new GetMultiWidthDriver))
})(outermostParams))
conv.io.tl <> driver.io.mem
smimem.io <> conv.io.smi
driver.io.start := io.start
io.finished := driver.io.finished
}
class ROMSlaveTest(implicit p: Parameters) extends UnitTest {
implicit val testName = "ROMSlaveTest"
val romdata = Seq(
BigInt("01234567deadbeef", 16),
BigInt("ab32fee8d00dfeed", 16))
val rombytes = romdata.map(_.toByteArray.reverse).flatten
val rom = Module(new ROMSlave(rombytes))
val driver = Module(new DriverSet(
(driverParams: Parameters) => {
implicit val p = driverParams
Seq(
Module(new GetMultiWidthDriver),
Module(new GetSweepDriver(romdata)),
Module(new GetBlockSweepDriver(romdata)))
}))
rom.io <> driver.io.mem
driver.io.start := io.start
io.finished := driver.io.finished
}
class TileLinkRAMTest(implicit val p: Parameters)
extends UnitTest with HasTileLinkParameters {
val depth = 2 * tlDataBeats
val ram = Module(new TileLinkTestRAM(depth))
val driver = Module(new DriverSet(
(driverParams: Parameters) => {
implicit val p = driverParams
Seq(
Module(new PutSweepDriver(depth)),
Module(new PutMaskDriver),
Module(new PutAtomicDriver),
Module(new PutBlockSweepDriver(depth / tlDataBeats)),
Module(new PrefetchDriver),
Module(new GetMultiWidthDriver))
}))
ram.io <> driver.io.mem
driver.io.start := io.start
io.finished := driver.io.finished
}
object UncoreUnitTests {
def apply(implicit p: Parameters): Seq[UnitTest] =
Seq(
Module(new SmiConverterTest),
Module(new ROMSlaveTest),
Module(new TileLinkRAMTest),
Module(new uncore.tilelink2.TLFuzzRAMTest))
}

View File

@ -0,0 +1,21 @@
package unittest
import Chisel._
import cde.Parameters
object JunctionsUnitTests {
def apply(implicit p: Parameters): Seq[UnitTest] =
Seq(
Module(new junctions.MultiWidthFifoTest),
Module(new junctions.NastiMemoryDemuxTest),
Module(new junctions.HastiTest))
}
object UncoreUnitTests {
def apply(implicit p: Parameters): Seq[UnitTest] =
Seq(
Module(new uncore.converters.SmiConverterTest),
Module(new uncore.devices.ROMSlaveTest),
Module(new uncore.devices.TileLinkRAMTest),
Module(new uncore.tilelink2.TLFuzzRAMTest))
}

View File

@ -1,8 +1,8 @@
package junctions.unittests package unittest
import Chisel._ import Chisel._
import junctions._
import cde.{Field, Parameters} import cde.{Field, Parameters}
import util.Timer
trait HasUnitTestIO { trait HasUnitTestIO {
val io = new Bundle { val io = new Bundle {
@ -56,11 +56,3 @@ class UnitTestSuite(implicit p: Parameters) extends Module {
assert(!timer.io.timeout.valid, "UnitTest timed out") assert(!timer.io.timeout.valid, "UnitTest timed out")
} }
object JunctionsUnitTests {
def apply(implicit p: Parameters): Seq[UnitTest] =
Seq(
Module(new MultiWidthFifoTest),
Module(new NastiMemoryDemuxTest),
Module(new HastiTest))
}

View File

@ -0,0 +1,74 @@
/// See LICENSE for license details.
package util
import Chisel._
/** Timer with a statically-specified period.
* Can take multiple inflight start-stop events with ID
* Will continue to count down as long as at least one event is inflight
*/
class Timer(initCount: Int, maxInflight: Int) extends Module {
val io = new Bundle {
val start = Valid(UInt(width = log2Up(maxInflight))).flip
val stop = Valid(UInt(width = log2Up(maxInflight))).flip
val timeout = Valid(UInt(width = log2Up(maxInflight)))
}
val inflight = Reg(init = Vec.fill(maxInflight) { Bool(false) })
val countdown = Reg(UInt(width = log2Up(initCount)))
val active = inflight.reduce(_ || _)
when (active) {
countdown := countdown - UInt(1)
}
when (io.start.valid) {
inflight(io.start.bits) := Bool(true)
countdown := UInt(initCount - 1)
}
when (io.stop.valid) {
inflight(io.stop.bits) := Bool(false)
}
io.timeout.valid := countdown === UInt(0) && active
io.timeout.bits := PriorityEncoder(inflight)
assert(!io.stop.valid || inflight(io.stop.bits),
"Timer stop for transaction that's not inflight")
}
object Timer {
def apply(initCount: Int, start: Bool, stop: Bool): Bool = {
val timer = Module(new Timer(initCount, 1))
timer.io.start.valid := start
timer.io.start.bits := UInt(0)
timer.io.stop.valid := stop
timer.io.stop.bits := UInt(0)
timer.io.timeout.valid
}
}
/** Timer with a statically-specified period. */
class DynamicTimer(w: Int) extends Module {
val io = new Bundle {
val start = Bool(INPUT)
val period = UInt(INPUT, w)
val stop = Bool(INPUT)
val timeout = Bool(OUTPUT)
}
val countdown = Reg(init = UInt(0, w))
val active = Reg(init = Bool(false))
when (io.start) {
countdown := io.period
active := Bool(true)
} .elsewhen (io.stop || countdown === UInt(0)) {
active := Bool(false)
} .elsewhen (active) {
countdown := countdown - UInt(1)
}
io.timeout := countdown === UInt(0) && active
}