From 69e121260e1611711d29aec3e2c963e23686747c Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Wed, 28 Sep 2016 15:11:05 -0700 Subject: [PATCH] [tilelink2] Add unit tests for many TL2 components These tests mostly use the Fuzzer and RAMModel to check that adapters correctly handle randomly generated legal traffic. --- .../uncore/tilelink2/AtomicAutomata.scala | 22 +++++++++ .../scala/uncore/tilelink2/Crossing.scala | 38 +++++++++++++++ .../scala/uncore/tilelink2/Fragmenter.scala | 21 +++++++++ src/main/scala/uncore/tilelink2/Fuzzer.scala | 7 +-- .../scala/uncore/tilelink2/HintHandler.scala | 22 +++++++++ .../uncore/tilelink2/RegisterRouterTest.scala | 32 +++++++++++++ src/main/scala/uncore/tilelink2/SRAM.scala | 20 ++++++++ src/main/scala/uncore/tilelink2/TLNodes.scala | 22 +++++++++ .../scala/uncore/tilelink2/WidthWidget.scala | 24 ++++++++++ src/main/scala/uncore/tilelink2/Xbar.scala | 47 +++++++++++++++++++ src/main/scala/unittest/Configs.scala | 30 ++++++++++++ 11 files changed, 282 insertions(+), 3 deletions(-) diff --git a/src/main/scala/uncore/tilelink2/AtomicAutomata.scala b/src/main/scala/uncore/tilelink2/AtomicAutomata.scala index 985f1079..19a75a27 100644 --- a/src/main/scala/uncore/tilelink2/AtomicAutomata.scala +++ b/src/main/scala/uncore/tilelink2/AtomicAutomata.scala @@ -283,3 +283,25 @@ object TLAtomicAutomata atomics.node } } + +/** Synthesizeable unit tests */ +import unittest._ + +//TODO ensure handler will pass through operations to clients that can handle them themselves + +class TLRAMAtomicAutomata() extends LazyModule { + val fuzz = LazyModule(new TLFuzzer(5000)) + val model = LazyModule(new TLRAMModel) + val ram = LazyModule(new TLRAM(AddressSet(0x0, 0x3ff))) + + model.node := fuzz.node + ram.node := TLFragmenter(4, 256)(TLAtomicAutomata()(model.node)) + + lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + io.finished := fuzz.module.io.finished + } +} + +class TLRAMAtomicAutomataTest extends UnitTest(timeout = 500000) { + io.finished := Module(LazyModule(new TLRAMAtomicAutomata).module).io.finished +} diff --git a/src/main/scala/uncore/tilelink2/Crossing.scala b/src/main/scala/uncore/tilelink2/Crossing.scala index 4ef5b834..1a90d0af 100644 --- a/src/main/scala/uncore/tilelink2/Crossing.scala +++ b/src/main/scala/uncore/tilelink2/Crossing.scala @@ -40,3 +40,41 @@ class TLAsyncCrossing(depth: Int = 8, sync: Int = 3) extends LazyModule } } } + +/** Synthesizeable unit tests */ +import unittest._ + +class TLRAMCrossing extends LazyModule { + val model = LazyModule(new TLRAMModel) + val ram = LazyModule(new TLRAM(AddressSet(0x0, 0x3ff))) + val fuzz = LazyModule(new TLFuzzer(5000)) + val cross = LazyModule(new TLAsyncCrossing) + + model.node := fuzz.node + cross.node := TLFragmenter(4, 256)(model.node) + val monitor = (ram.node := cross.node) + + lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + io.finished := fuzz.module.io.finished + + // Shove the RAM into another clock domain + val clocks = Module(new util.Pow2ClockDivider(2)) + ram.module.clock := clocks.io.clock_out + + // ... and safely cross TL2 into it + cross.module.io.in_clock := clock + cross.module.io.in_reset := reset + cross.module.io.out_clock := clocks.io.clock_out + cross.module.io.out_reset := reset + + // Push the Monitor into the right clock domain + monitor.foreach { m => + m.module.clock := clocks.io.clock_out + m.module.reset := reset + } + } +} + +class TLRAMCrossingTest extends UnitTest(timeout = 500000) { + io.finished := Module(LazyModule(new TLRAMCrossing).module).io.finished +} diff --git a/src/main/scala/uncore/tilelink2/Fragmenter.scala b/src/main/scala/uncore/tilelink2/Fragmenter.scala index 511863d3..f93e7bed 100644 --- a/src/main/scala/uncore/tilelink2/Fragmenter.scala +++ b/src/main/scala/uncore/tilelink2/Fragmenter.scala @@ -250,3 +250,24 @@ object TLFragmenter fragmenter.node } } + +/** Synthesizeable unit tests */ +import unittest._ + +class TLRAMFragmenter(ramBeatBytes: Int, maxSize: Int) extends LazyModule { + val fuzz = LazyModule(new TLFuzzer(5000)) + val model = LazyModule(new TLRAMModel) + val ram = LazyModule(new TLRAM(AddressSet(0x0, 0x3ff), beatBytes = ramBeatBytes)) + + model.node := fuzz.node + ram.node := TLFragmenter(ramBeatBytes, maxSize)(model.node) + + lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + io.finished := fuzz.module.io.finished + } +} + +class TLRAMFragmenterTest(ramBeatBytes: Int, maxSize: Int) extends UnitTest(timeout = 500000) { + io.finished := Module(LazyModule(new TLRAMFragmenter(ramBeatBytes,maxSize)).module).io.finished +} + diff --git a/src/main/scala/uncore/tilelink2/Fuzzer.scala b/src/main/scala/uncore/tilelink2/Fuzzer.scala index 4b283c87..968f9efd 100644 --- a/src/main/scala/uncore/tilelink2/Fuzzer.scala +++ b/src/main/scala/uncore/tilelink2/Fuzzer.scala @@ -2,8 +2,6 @@ package uncore.tilelink2 import Chisel._ -import unittest._ -import util.Pow2ClockDivider class IDMapGenerator(numIds: Int) extends Module { val w = log2Up(numIds) @@ -208,6 +206,9 @@ class TLFuzzer( } } +/** Synthesizeable integration test */ +import unittest._ + class TLFuzzRAM extends LazyModule { val model = LazyModule(new TLRAMModel) @@ -231,7 +232,7 @@ class TLFuzzRAM extends LazyModule io.finished := fuzz.module.io.finished // Shove the RAM into another clock domain - val clocks = Module(new Pow2ClockDivider(2)) + val clocks = Module(new util.Pow2ClockDivider(2)) ram.module.clock := clocks.io.clock_out // ... and safely cross TL2 into it diff --git a/src/main/scala/uncore/tilelink2/HintHandler.scala b/src/main/scala/uncore/tilelink2/HintHandler.scala index 5480dd67..d943e90e 100644 --- a/src/main/scala/uncore/tilelink2/HintHandler.scala +++ b/src/main/scala/uncore/tilelink2/HintHandler.scala @@ -141,3 +141,25 @@ object TLHintHandler hints.node } } + +/** Synthesizeable unit tests */ +import unittest._ + +//TODO ensure handler will pass through hints to clients that can handle them themselves + +class TLRAMHintHandler() extends LazyModule { + val fuzz = LazyModule(new TLFuzzer(5000)) + val model = LazyModule(new TLRAMModel) + val ram = LazyModule(new TLRAM(AddressSet(0x0, 0x3ff))) + + model.node := fuzz.node + ram.node := TLFragmenter(4, 256)(TLHintHandler()(model.node)) + + lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + io.finished := fuzz.module.io.finished + } +} + +class TLRAMHintHandlerTest extends UnitTest(timeout = 500000) { + io.finished := Module(LazyModule(new TLRAMHintHandler).module).io.finished +} diff --git a/src/main/scala/uncore/tilelink2/RegisterRouterTest.scala b/src/main/scala/uncore/tilelink2/RegisterRouterTest.scala index 4e215a5b..04ae93ed 100644 --- a/src/main/scala/uncore/tilelink2/RegisterRouterTest.scala +++ b/src/main/scala/uncore/tilelink2/RegisterRouterTest.scala @@ -3,6 +3,7 @@ package uncore.tilelink2 import Chisel._ +import unittest._ import util.Pow2ClockDivider object LFSR16Seed @@ -258,3 +259,34 @@ trait RRTest1Module extends Module with HasRegMap class RRTest1(address: BigInt) extends TLRegisterRouter(address, 0, 32, 6, 4)( new TLRegBundle((), _) with RRTest1Bundle)( new TLRegModule((), _, _) with RRTest1Module) + +class FuzzRRTest0 extends LazyModule { + val fuzz = LazyModule(new TLFuzzer(5000)) + val rrtr = LazyModule(new RRTest0(0x400)) + + rrtr.node := TLFragmenter(4, 32)(TLBuffer()(fuzz.node)) + + lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + io.finished := fuzz.module.io.finished + } +} + +class TLRR0Test extends UnitTest(timeout = 500000) { + io.finished := Module(LazyModule(new FuzzRRTest0).module).io.finished +} + +class FuzzRRTest1 extends LazyModule { + val fuzz = LazyModule(new TLFuzzer(5000)) + val rrtr = LazyModule(new RRTest1(0x400)) + + rrtr.node := TLFragmenter(4, 32)(TLBuffer()(fuzz.node)) + + lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + io.finished := fuzz.module.io.finished + } +} + +class TLRR1Test extends UnitTest(timeout = 500000) { + io.finished := Module(LazyModule(new FuzzRRTest1).module).io.finished +} + diff --git a/src/main/scala/uncore/tilelink2/SRAM.scala b/src/main/scala/uncore/tilelink2/SRAM.scala index 9b5b3d8a..24f08540 100644 --- a/src/main/scala/uncore/tilelink2/SRAM.scala +++ b/src/main/scala/uncore/tilelink2/SRAM.scala @@ -75,3 +75,23 @@ class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4) in.e.ready := Bool(true) } } + +/** Synthesizeable unit testing */ +import unittest._ + +class TLRAMSimple(ramBeatBytes: Int) extends LazyModule { + val fuzz = LazyModule(new TLFuzzer(5000)) + val model = LazyModule(new TLRAMModel) + val ram = LazyModule(new TLRAM(AddressSet(0x0, 0x3ff), beatBytes = ramBeatBytes)) + + model.node := fuzz.node + ram.node := model.node + + lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + io.finished := fuzz.module.io.finished + } +} + +class TLRAMSimpleTest(ramBeatBytes: Int) extends UnitTest(timeout = 500000) { + io.finished := Module(LazyModule(new TLRAMSimple(ramBeatBytes)).module).io.finished +} diff --git a/src/main/scala/uncore/tilelink2/TLNodes.scala b/src/main/scala/uncore/tilelink2/TLNodes.scala index 9bbe91fe..2ab3738d 100644 --- a/src/main/scala/uncore/tilelink2/TLNodes.scala +++ b/src/main/scala/uncore/tilelink2/TLNodes.scala @@ -50,3 +50,25 @@ case class TLAdapterNode( numClientPorts: Range.Inclusive = 1 to 1, numManagerPorts: Range.Inclusive = 1 to 1) extends InteriorNode(TLImp)(clientFn, managerFn, numClientPorts, numManagerPorts) + +/** Synthesizeable unit tests */ +import unittest._ + +class TLInputNodeTest extends UnitTest(500000) { + class Acceptor extends LazyModule { + val node = TLInputNode() + val tlram = LazyModule(new TLRAM(AddressSet(0x54321000, 0xfff))) + tlram.node := node + + lazy val module = new LazyModuleImp(this) { + val io = new Bundle { + val in = node.bundleIn + } + } + } + + val fuzzer = LazyModule(new TLFuzzer(5000)) + LazyModule(new Acceptor).node := TLFragmenter(4, 64)(fuzzer.node) + + io.finished := Module(fuzzer.module).io.finished +} diff --git a/src/main/scala/uncore/tilelink2/WidthWidget.scala b/src/main/scala/uncore/tilelink2/WidthWidget.scala index e024a907..09de913e 100644 --- a/src/main/scala/uncore/tilelink2/WidthWidget.scala +++ b/src/main/scala/uncore/tilelink2/WidthWidget.scala @@ -182,3 +182,27 @@ object TLWidthWidget widget.node } } + +/** Synthesizeable unit tests */ +import unittest._ + +class TLRAMWidthWidget(first: Int, second: Int) extends LazyModule { + val fuzz = LazyModule(new TLFuzzer(5000)) + val model = LazyModule(new TLRAMModel) + val ram = LazyModule(new TLRAM(AddressSet(0x0, 0x3ff))) + + model.node := fuzz.node + ram.node := TLFragmenter(4, 256)( + if (first == second ) { TLWidthWidget(first)(model.node) } + else { + TLWidthWidget(second)( + TLWidthWidget(first)(model.node))}) + + lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + io.finished := fuzz.module.io.finished + } +} + +class TLRAMWidthWidgetTest(little: Int, big: Int) extends UnitTest(timeout = 500000) { + io.finished := Module(LazyModule(new TLRAMWidthWidget(little,big)).module).io.finished +} diff --git a/src/main/scala/uncore/tilelink2/Xbar.scala b/src/main/scala/uncore/tilelink2/Xbar.scala index 3a300fc3..3fb8c36f 100644 --- a/src/main/scala/uncore/tilelink2/Xbar.scala +++ b/src/main/scala/uncore/tilelink2/Xbar.scala @@ -178,3 +178,50 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.lowestIndexFirst) extends Lazy } } } + +/** Synthesizeable unit tests */ +import unittest._ + +class TLRAMXbar(nManagers: Int) extends LazyModule { + val fuzz = LazyModule(new TLFuzzer(5000)) + val model = LazyModule(new TLRAMModel) + val xbar = LazyModule(new TLXbar) + + model.node := fuzz.node + xbar.node := model.node + (0 until nManagers) foreach { n => + val ram = LazyModule(new TLRAM(AddressSet(0x0+0x400*n, 0x3ff))) + ram.node := TLFragmenter(4, 256)(xbar.node) + } + + lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + io.finished := fuzz.module.io.finished + } +} + +class TLRAMXbarTest(nManagers: Int) extends UnitTest(timeout = 500000) { + io.finished := Module(LazyModule(new TLRAMXbar(nManagers)).module).io.finished +} + +class TLMulticlientXbar(nManagers: Int, nClients: Int) extends LazyModule { + val xbar = LazyModule(new TLXbar) + + val fuzzers = (0 until nClients) map { n => + val fuzz = LazyModule(new TLFuzzer(5000)) + xbar.node := fuzz.node + fuzz + } + + (0 until nManagers) foreach { n => + val ram = LazyModule(new TLRAM(AddressSet(0x0+0x400*n, 0x3ff))) + ram.node := TLFragmenter(4, 256)(xbar.node) + } + + lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + io.finished := fuzzers.last.module.io.finished + } +} + +class TLMulticlientXbarTest(nManagers: Int, nClients: Int) extends UnitTest(timeout = 5000000) { + io.finished := Module(LazyModule(new TLMulticlientXbar(nManagers, nClients)).module).io.finished +} diff --git a/src/main/scala/unittest/Configs.scala b/src/main/scala/unittest/Configs.scala index 1cf21ae4..122f3f7a 100644 --- a/src/main/scala/unittest/Configs.scala +++ b/src/main/scala/unittest/Configs.scala @@ -31,3 +31,33 @@ class WithUncoreUnitTests extends Config( ) class UncoreUnitTestConfig extends Config(new WithUncoreUnitTests ++ new BaseConfig) + +class WithTL2UnitTests extends Config( + (pname, site, here) => pname match { + case UnitTests => (p: Parameters) => { + Seq( + //Module(new uncore.tilelink2.TLRAMSimpleTest(1)), + //Module(new uncore.tilelink2.TLRAMSimpleTest(4)), + //Module(new uncore.tilelink2.TLRAMSimpleTest(16)), + Module(new uncore.tilelink2.TLRAMFragmenterTest(4, 256)), + Module(new uncore.tilelink2.TLRAMFragmenterTest(16, 64)), + Module(new uncore.tilelink2.TLRAMFragmenterTest(4, 16)), + Module(new uncore.tilelink2.TLRAMXbarTest(1)), + Module(new uncore.tilelink2.TLRAMXbarTest(2)), + Module(new uncore.tilelink2.TLRAMXbarTest(8)), + //Module(new uncore.tilelink2.TLMulticlientXbarTest(4,4)), + //Module(new uncore.tilelink2.TLMulticlientXbarTest(1,4)), + Module(new uncore.tilelink2.TLRAMWidthWidgetTest(1,1)), + Module(new uncore.tilelink2.TLRAMWidthWidgetTest(4,4)), + Module(new uncore.tilelink2.TLRAMWidthWidgetTest(16,16)), + Module(new uncore.tilelink2.TLRAMWidthWidgetTest(4,64)), + Module(new uncore.tilelink2.TLRAMWidthWidgetTest(64,4)), + Module(new uncore.tilelink2.TLRR0Test), + Module(new uncore.tilelink2.TLRR1Test), + Module(new uncore.tilelink2.TLRAMCrossingTest) + ) + } + case _ => throw new CDEMatchError + }) + +class TL2UnitTestConfig extends Config(new WithTL2UnitTests ++ new BasePlatformConfig)