1
0
Fork 0

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".
This commit is contained in:
Wesley W. Terpstra 2017-02-17 14:16:45 +01:00
parent 91d1880dbf
commit 5045696f92
1 changed files with 59 additions and 21 deletions

View File

@ -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
}
}