From 7dd4492abb299fdd030a296d11b39cea666a5159 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Tue, 13 Sep 2016 15:37:29 -0700 Subject: [PATCH] First cut at refactoring unittests into a top-level utility. Individual tests co-located with their DUT. No functional changes. --- src/main/scala/coreplex/TestConfigs.scala | 3 +- src/main/scala/coreplex/UnitTest.scala | 2 +- src/main/scala/groundtest/Comparator.scala | 1 + src/main/scala/groundtest/Generator.scala | 1 + src/main/scala/groundtest/NastiTest.scala | 1 + src/main/scala/groundtest/Regression.scala | 3 +- src/main/scala/groundtest/TraceGen.scala | 1 + src/main/scala/groundtest/Util.scala | 29 ---- src/main/scala/junctions/MultiWidthFifo.scala | 158 ++++++++++++++++++ .../{unittests => }/NastiDemuxTest.scala | 6 +- ...MiscNastiTests.scala => NastiDriver.scala} | 17 +- src/main/scala/junctions/hasti.scala | 14 ++ .../unittests/MultiWidthFifoTest.scala | 85 ---------- src/main/scala/junctions/util.scala | 125 -------------- src/main/scala/rocketchip/TestConfigs.scala | 3 +- src/main/scala/uncore/converters/Smi.scala | 27 +++ src/main/scala/uncore/devices/Bram.scala | 22 +++ src/main/scala/uncore/devices/Rom.scala | 21 +++ .../{unittests => tilelink}/Drivers.scala | 3 +- src/main/scala/uncore/tilelink2/Fuzzer.scala | 2 +- src/main/scala/uncore/unittests/Tests.scala | 86 ---------- src/main/scala/unittest/TempListOfTests.scala | 21 +++ .../unittests => unittest}/UnitTest.scala | 12 +- src/main/scala/util/Timer.scala | 74 ++++++++ 24 files changed, 353 insertions(+), 364 deletions(-) create mode 100644 src/main/scala/junctions/MultiWidthFifo.scala rename src/main/scala/junctions/{unittests => }/NastiDemuxTest.scala (95%) rename src/main/scala/junctions/{unittests/MiscNastiTests.scala => NastiDriver.scala} (83%) delete mode 100644 src/main/scala/junctions/unittests/MultiWidthFifoTest.scala rename src/main/scala/uncore/{unittests => tilelink}/Drivers.scala (99%) delete mode 100644 src/main/scala/uncore/unittests/Tests.scala create mode 100644 src/main/scala/unittest/TempListOfTests.scala rename src/main/scala/{junctions/unittests => unittest}/UnitTest.scala (86%) create mode 100644 src/main/scala/util/Timer.scala diff --git a/src/main/scala/coreplex/TestConfigs.scala b/src/main/scala/coreplex/TestConfigs.scala index 3f435478..b2e7e05c 100644 --- a/src/main/scala/coreplex/TestConfigs.scala +++ b/src/main/scala/coreplex/TestConfigs.scala @@ -8,9 +8,8 @@ import uncore.tilelink._ import uncore.coherence._ import uncore.agents._ import uncore.devices.NTiles -import uncore.unittests._ +import unittest._ import junctions._ -import junctions.unittests._ import scala.collection.mutable.LinkedHashSet import cde.{Parameters, Config, Dump, Knob, CDEMatchError} import scala.math.max diff --git a/src/main/scala/coreplex/UnitTest.scala b/src/main/scala/coreplex/UnitTest.scala index 0e91d697..b308b2e1 100644 --- a/src/main/scala/coreplex/UnitTest.scala +++ b/src/main/scala/coreplex/UnitTest.scala @@ -1,7 +1,7 @@ package coreplex import Chisel._ -import junctions.unittests.UnitTestSuite +import unittest.UnitTestSuite import rocket.Tile import uncore.tilelink.TLId import cde.Parameters diff --git a/src/main/scala/groundtest/Comparator.scala b/src/main/scala/groundtest/Comparator.scala index e07b5861..67cffb9e 100644 --- a/src/main/scala/groundtest/Comparator.scala +++ b/src/main/scala/groundtest/Comparator.scala @@ -5,6 +5,7 @@ import uncore.tilelink._ import uncore.constants._ import junctions._ import rocket._ +import util.Timer import scala.util.Random import cde.{Parameters, Field} diff --git a/src/main/scala/groundtest/Generator.scala b/src/main/scala/groundtest/Generator.scala index d677ab96..f32fd14d 100644 --- a/src/main/scala/groundtest/Generator.scala +++ b/src/main/scala/groundtest/Generator.scala @@ -6,6 +6,7 @@ import uncore.devices.NTiles import uncore.constants._ import junctions._ import rocket._ +import util.Timer import scala.util.Random import cde.{Parameters, Field} diff --git a/src/main/scala/groundtest/NastiTest.scala b/src/main/scala/groundtest/NastiTest.scala index eb2c8a23..4b419834 100644 --- a/src/main/scala/groundtest/NastiTest.scala +++ b/src/main/scala/groundtest/NastiTest.scala @@ -4,6 +4,7 @@ import Chisel._ import uncore.tilelink._ import uncore.converters._ import junctions._ +import util.Timer import rocket.TileId import cde.Parameters diff --git a/src/main/scala/groundtest/Regression.scala b/src/main/scala/groundtest/Regression.scala index 00417b14..65289a23 100644 --- a/src/main/scala/groundtest/Regression.scala +++ b/src/main/scala/groundtest/Regression.scala @@ -5,7 +5,8 @@ import uncore.tilelink._ import uncore.constants._ import uncore.agents._ import uncore.util._ -import junctions.{ParameterizedBundle, HasAddrMapParameters, Timer} +import junctions.{ParameterizedBundle, HasAddrMapParameters} +import util.Timer import rocket.HellaCacheIO import cde.{Parameters, Field} diff --git a/src/main/scala/groundtest/TraceGen.scala b/src/main/scala/groundtest/TraceGen.scala index 140424a6..abf47608 100644 --- a/src/main/scala/groundtest/TraceGen.scala +++ b/src/main/scala/groundtest/TraceGen.scala @@ -22,6 +22,7 @@ import uncore.constants._ import uncore.devices.NTiles import junctions._ import rocket._ +import util.{Timer, DynamicTimer} import scala.util.Random import cde.{Parameters, Field} diff --git a/src/main/scala/groundtest/Util.scala b/src/main/scala/groundtest/Util.scala index f5ffd68d..836ef7d1 100644 --- a/src/main/scala/groundtest/Util.scala +++ b/src/main/scala/groundtest/Util.scala @@ -2,35 +2,6 @@ package groundtest 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 // ============ diff --git a/src/main/scala/junctions/MultiWidthFifo.scala b/src/main/scala/junctions/MultiWidthFifo.scala new file mode 100644 index 00000000..80739cf9 --- /dev/null +++ b/src/main/scala/junctions/MultiWidthFifo.scala @@ -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") +} + + diff --git a/src/main/scala/junctions/unittests/NastiDemuxTest.scala b/src/main/scala/junctions/NastiDemuxTest.scala similarity index 95% rename from src/main/scala/junctions/unittests/NastiDemuxTest.scala rename to src/main/scala/junctions/NastiDemuxTest.scala index 0636eb69..ea7d8b9a 100644 --- a/src/main/scala/junctions/unittests/NastiDemuxTest.scala +++ b/src/main/scala/junctions/NastiDemuxTest.scala @@ -1,8 +1,6 @@ -package junctions.unittests +package junctions import Chisel._ -import junctions._ -import junctions.NastiConstants._ import cde.Parameters 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) } -class NastiMemoryDemuxTest(implicit p: Parameters) extends UnitTest { +class NastiMemoryDemuxTest(implicit p: Parameters) extends unittest.UnitTest { val nSlaves = 4 val driver = Module(new NastiDemuxDriver(nSlaves)) diff --git a/src/main/scala/junctions/unittests/MiscNastiTests.scala b/src/main/scala/junctions/NastiDriver.scala similarity index 83% rename from src/main/scala/junctions/unittests/MiscNastiTests.scala rename to src/main/scala/junctions/NastiDriver.scala index 1c56f590..685743d2 100644 --- a/src/main/scala/junctions/unittests/MiscNastiTests.scala +++ b/src/main/scala/junctions/NastiDriver.scala @@ -1,8 +1,6 @@ -package junctions.unittests +package junctions import Chisel._ -import junctions._ -import junctions.NastiConstants._ import cde.Parameters 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, 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 -} diff --git a/src/main/scala/junctions/hasti.scala b/src/main/scala/junctions/hasti.scala index 37dde595..0f25d19b 100644 --- a/src/main/scala/junctions/hasti.scala +++ b/src/main/scala/junctions/hasti.scala @@ -2,6 +2,7 @@ package junctions import Chisel._ import cde.{Parameters, Field} +import unittest.UnitTest object HastiConstants { @@ -547,3 +548,16 @@ class HastiTestSRAM(depth: Int)(implicit p: Parameters) extends HastiModule()(p) io.hready := ready 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 +} diff --git a/src/main/scala/junctions/unittests/MultiWidthFifoTest.scala b/src/main/scala/junctions/unittests/MultiWidthFifoTest.scala deleted file mode 100644 index 4534feac..00000000 --- a/src/main/scala/junctions/unittests/MultiWidthFifoTest.scala +++ /dev/null @@ -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") -} - - diff --git a/src/main/scala/junctions/util.scala b/src/main/scala/junctions/util.scala index afb10803..109433f1 100644 --- a/src/main/scala/junctions/util.scala +++ b/src/main/scala/junctions/util.scala @@ -244,128 +244,3 @@ class DecoupledHelper(val rvs: Seq[Bool]) { (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 - } -} - - diff --git a/src/main/scala/rocketchip/TestConfigs.scala b/src/main/scala/rocketchip/TestConfigs.scala index 6f1c7b05..3af73d31 100644 --- a/src/main/scala/rocketchip/TestConfigs.scala +++ b/src/main/scala/rocketchip/TestConfigs.scala @@ -7,9 +7,8 @@ import uncore.tilelink._ import uncore.coherence._ import uncore.agents._ import uncore.devices.NTiles -import uncore.unittests._ +import unittest._ import junctions._ -import junctions.unittests._ import scala.collection.mutable.LinkedHashSet import scala.collection.immutable.HashMap import cde.{Parameters, Config, Dump, Knob, CDEMatchError} diff --git a/src/main/scala/uncore/converters/Smi.scala b/src/main/scala/uncore/converters/Smi.scala index 6ec47950..8fa2fa92 100644 --- a/src/main/scala/uncore/converters/Smi.scala +++ b/src/main/scala/uncore/converters/Smi.scala @@ -30,3 +30,30 @@ class SmiIOTileLinkIOConverter(val dataWidth: Int, val addrWidth: Int) decoupledNastiConnect(nasti2smi.io.nasti, tl2nasti.io.nasti) 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 +} diff --git a/src/main/scala/uncore/devices/Bram.scala b/src/main/scala/uncore/devices/Bram.scala index 5bd24854..9de6fa31 100644 --- a/src/main/scala/uncore/devices/Bram.scala +++ b/src/main/scala/uncore/devices/Bram.scala @@ -2,6 +2,7 @@ package uncore.devices import Chisel._ import cde.{Parameters, Field} +import unittest.UnitTest import junctions._ import uncore.tilelink._ 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) } } + +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 +} diff --git a/src/main/scala/uncore/devices/Rom.scala b/src/main/scala/uncore/devices/Rom.scala index f2210d03..d30812f4 100644 --- a/src/main/scala/uncore/devices/Rom.scala +++ b/src/main/scala/uncore/devices/Rom.scala @@ -1,6 +1,7 @@ package uncore.devices import Chisel._ +import unittest.UnitTest import junctions._ import uncore.tilelink._ import uncore.util._ @@ -41,6 +42,26 @@ class ROMSlave(contents: Seq[Byte])(implicit val p: Parameters) extends Module 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 { val io = new NastiIO().flip val ar = Queue(io.ar, 1) diff --git a/src/main/scala/uncore/unittests/Drivers.scala b/src/main/scala/uncore/tilelink/Drivers.scala similarity index 99% rename from src/main/scala/uncore/unittests/Drivers.scala rename to src/main/scala/uncore/tilelink/Drivers.scala index a359207d..dadc0473 100644 --- a/src/main/scala/uncore/unittests/Drivers.scala +++ b/src/main/scala/uncore/tilelink/Drivers.scala @@ -1,8 +1,7 @@ -package uncore.unittests +package uncore.tilelink import Chisel._ import junctions._ -import uncore.tilelink._ import uncore.constants._ import uncore.util._ import cde.Parameters diff --git a/src/main/scala/uncore/tilelink2/Fuzzer.scala b/src/main/scala/uncore/tilelink2/Fuzzer.scala index b5cdd263..deeb936b 100644 --- a/src/main/scala/uncore/tilelink2/Fuzzer.scala +++ b/src/main/scala/uncore/tilelink2/Fuzzer.scala @@ -3,7 +3,7 @@ package uncore.tilelink2 import Chisel._ import chisel3.util.LFSR16 -import junctions.unittests._ +import unittest._ class IDMapGenerator(numIds: Int) extends Module { val w = log2Up(numIds) diff --git a/src/main/scala/uncore/unittests/Tests.scala b/src/main/scala/uncore/unittests/Tests.scala deleted file mode 100644 index c59194b6..00000000 --- a/src/main/scala/uncore/unittests/Tests.scala +++ /dev/null @@ -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)) -} diff --git a/src/main/scala/unittest/TempListOfTests.scala b/src/main/scala/unittest/TempListOfTests.scala new file mode 100644 index 00000000..5cef9920 --- /dev/null +++ b/src/main/scala/unittest/TempListOfTests.scala @@ -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)) +} diff --git a/src/main/scala/junctions/unittests/UnitTest.scala b/src/main/scala/unittest/UnitTest.scala similarity index 86% rename from src/main/scala/junctions/unittests/UnitTest.scala rename to src/main/scala/unittest/UnitTest.scala index b64e0f5f..a5d496ba 100644 --- a/src/main/scala/junctions/unittests/UnitTest.scala +++ b/src/main/scala/unittest/UnitTest.scala @@ -1,8 +1,8 @@ -package junctions.unittests +package unittest import Chisel._ -import junctions._ import cde.{Field, Parameters} +import util.Timer trait HasUnitTestIO { val io = new Bundle { @@ -56,11 +56,3 @@ class UnitTestSuite(implicit p: Parameters) extends Module { 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)) -} diff --git a/src/main/scala/util/Timer.scala b/src/main/scala/util/Timer.scala new file mode 100644 index 00000000..c0c48eeb --- /dev/null +++ b/src/main/scala/util/Timer.scala @@ -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 +} +