From 5045696f92a74a76400a1cc321723ce1a7d5aef1 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 17 Feb 2017 14:16:45 +0100 Subject: [PATCH] TLRational: test all corners In order to ensure that verilator is happy, we launch both clocks from a clock divider. Sadly, it does not follow the spec wrt. derived clocks. See the verilator manual section on "Generated Clocks". --- .../uncore/tilelink2/RationalCrossing.scala | 80 ++++++++++++++----- 1 file changed, 59 insertions(+), 21 deletions(-) diff --git a/src/main/scala/uncore/tilelink2/RationalCrossing.scala b/src/main/scala/uncore/tilelink2/RationalCrossing.scala index 8a3b0b64..a736269c 100644 --- a/src/main/scala/uncore/tilelink2/RationalCrossing.scala +++ b/src/main/scala/uncore/tilelink2/RationalCrossing.scala @@ -149,35 +149,73 @@ class TLRationalCrossing(direction: RationalDirection = Symmetric)(implicit p: P /** Synthesizeable unit tests */ import unittest._ -class TLRAMRationalCrossing(implicit p: Parameters) extends LazyModule { +class TLRAMRationalCrossingSource(implicit p: Parameters) extends LazyModule { + val node = TLRationalOutputNode() val fuzz = LazyModule(new TLFuzzer(5000)) val model = LazyModule(new TLRAMModel) - val cross = LazyModule(new TLRationalCrossing(FastToSlow)) - val delay = LazyModule(new TLDelayer(0.25)) - val ram = LazyModule(new TLRAM(AddressSet(0x0, 0x3ff))) model.node := fuzz.node - cross.node := TLDelayer(0.25)(TLFragmenter(4, 256)(model.node)) - val monitor1 = (delay.node := cross.node) - val monitor2 = (ram.node := delay.node) - val monitors = monitor1.toList ++ monitor2.toList + node := TLRationalCrossingSource()(TLDelayer(0.25)(model.node)) + + lazy val module = new LazyModuleImp(this) { + val io = new Bundle { + val finished = Bool(OUTPUT) + val out = node.bundleOut + } + io.finished := fuzz.module.io.finished + } +} + +class TLRAMRationalCrossingSink(direction: RationalDirection)(implicit p: Parameters) extends LazyModule { + val node = TLRationalInputNode() + val ram = LazyModule(new TLRAM(AddressSet(0x0, 0x3ff))) + + ram.node := TLFragmenter(4, 256)(TLDelayer(0.25)(TLRationalCrossingSink(direction)(node))) + + lazy val module = new LazyModuleImp(this) { + val io = new Bundle { + val in = node.bundleIn + } + } +} + +class TLRAMRationalCrossing(implicit p: Parameters) extends LazyModule { + val sym_fast_source = LazyModule(new TLRAMRationalCrossingSource) + val sym_slow_sink = LazyModule(new TLRAMRationalCrossingSink(Symmetric)) + sym_slow_sink.node := sym_fast_source.node + + val sym_slow_source = LazyModule(new TLRAMRationalCrossingSource) + val sym_fast_sink = LazyModule(new TLRAMRationalCrossingSink(Symmetric)) + sym_fast_sink.node := sym_slow_source.node + + val fix_fast_source = LazyModule(new TLRAMRationalCrossingSource) + val fix_slow_sink = LazyModule(new TLRAMRationalCrossingSink(FastToSlow)) + fix_slow_sink.node := fix_fast_source.node + + val fix_slow_source = LazyModule(new TLRAMRationalCrossingSource) + val fix_fast_sink = LazyModule(new TLRAMRationalCrossingSink(SlowToFast)) + fix_fast_sink.node := fix_slow_source.node lazy val module = new LazyModuleImp(this) with HasUnitTestIO { - io.finished := fuzz.module.io.finished + io.finished := + sym_fast_source.module.io.finished && + sym_slow_source.module.io.finished && + fix_fast_source.module.io.finished && + fix_slow_source.module.io.finished - // Shove the RAM into another clock domain - val clocks = Module(new util.Pow2ClockDivider(2)) - ram.module.clock := clocks.io.clock_out - delay.module.clock := clocks.io.clock_out + // Generate faster clock (still divided so verilator approves) + val fast = Module(new util.Pow2ClockDivider(1)) + sym_fast_source.module.clock := fast.io.clock_out + sym_fast_sink .module.clock := fast.io.clock_out + fix_fast_source.module.clock := fast.io.clock_out + fix_fast_sink .module.clock := fast.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 Monitors into the right clock domain - monitors.foreach { m => m.module.clock := clocks.io.clock_out } + // Generate slower clock + val slow = Module(new util.Pow2ClockDivider(2)) + sym_slow_source.module.clock := slow.io.clock_out + sym_slow_sink .module.clock := slow.io.clock_out + fix_slow_source.module.clock := slow.io.clock_out + fix_slow_sink .module.clock := slow.io.clock_out } }