diff --git a/src/main/scala/uncore/tilelink2/Fuzzer.scala b/src/main/scala/uncore/tilelink2/Fuzzer.scala index 233572a9..630f5521 100644 --- a/src/main/scala/uncore/tilelink2/Fuzzer.scala +++ b/src/main/scala/uncore/tilelink2/Fuzzer.scala @@ -4,6 +4,7 @@ package uncore.tilelink2 import Chisel._ import chisel3.util.LFSR16 import unittest._ +import util.Pow2ClockDivider class IDMapGenerator(numIds: Int) extends Module { val w = log2Up(numIds) @@ -208,15 +209,6 @@ class TLFuzzer( } } -class ClockDivider extends BlackBox { - val io = new Bundle { - val clock_in = Clock(INPUT) - val reset_in = Bool(INPUT) - val clock_out = Clock(OUTPUT) - val reset_out = Bool(OUTPUT) - } -} - class TLFuzzRAM extends LazyModule { val model = LazyModule(new TLRAMModel) @@ -240,17 +232,14 @@ class TLFuzzRAM extends LazyModule io.finished := fuzz.module.io.finished // Shove the RAM into another clock domain - val clocks = Module(new ClockDivider) + val clocks = Module(new Pow2ClockDivider(2)) ram.module.clock := clocks.io.clock_out - ram.module.reset := clocks.io.reset_out - clocks.io.clock_in := clock - clocks.io.reset_in := reset // ... 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 := clocks.io.reset_out + cross.module.io.out_reset := reset } } diff --git a/src/main/scala/uncore/tilelink2/RegisterRouterTest.scala b/src/main/scala/uncore/tilelink2/RegisterRouterTest.scala index 0c71428e..eb6a1944 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 util.Pow2ClockDivider object LFSR16Seed { @@ -225,9 +226,7 @@ trait RRTest1Bundle trait RRTest1Module extends Module with HasRegMap { - val clocks = Module(new ClockDivider) - clocks.io.clock_in := clock - clocks.io.reset_in := reset + val clocks = Module(new Pow2ClockDivider(2)) def x(bits: Int) = { val field = UInt(width = bits) @@ -237,7 +236,7 @@ trait RRTest1Module extends Module with HasRegMap readCross.io.master_reset := reset readCross.io.master_allow := Bool(true) readCross.io.slave_clock := clocks.io.clock_out - readCross.io.slave_reset := clocks.io.reset_out + readCross.io.slave_reset := reset readCross.io.slave_allow := Bool(true) val writeCross = Module(new RegisterWriteCrossing(field)) @@ -245,7 +244,7 @@ trait RRTest1Module extends Module with HasRegMap writeCross.io.master_reset := reset writeCross.io.master_allow := Bool(true) writeCross.io.slave_clock := clocks.io.clock_out - writeCross.io.slave_reset := clocks.io.reset_out + writeCross.io.slave_reset := reset writeCross.io.slave_allow := Bool(true) readCross.io.slave_register := writeCross.io.slave_register diff --git a/src/main/scala/util/ClockDivider.scala b/src/main/scala/util/ClockDivider.scala new file mode 100644 index 00000000..7bd58338 --- /dev/null +++ b/src/main/scala/util/ClockDivider.scala @@ -0,0 +1,36 @@ +package util + +import Chisel._ + +/** Divide the clock by 2 */ +class ClockDivider2 extends Module { + val io = new Bundle { + val clock_out = Clock(OUTPUT) + } + + val clock_reg = Reg(Bool()) + clock_reg := !clock_reg + + io.clock_out := clock_reg.asClock +} + +/** Divide the clock by power of 2 times. + * @param pow2 divides the clock 2 ^ pow2 times + * WARNING: This is meant for simulation use only. */ +class Pow2ClockDivider(pow2: Int) extends Module { + val io = new Bundle { + val clock_out = Clock(OUTPUT) + } + + if (pow2 == 0) { + io.clock_out := clock + } else { + val dividers = Seq.fill(pow2) { Module(new ClockDivider2) } + + dividers.init.zip(dividers.tail).map { case (last, next) => + next.clock := last.io.clock_out + } + + io.clock_out := dividers.last.io.clock_out + } +} diff --git a/vsim/Makefrag b/vsim/Makefrag index 8d694ea6..a6e04f2f 100644 --- a/vsim/Makefrag +++ b/vsim/Makefrag @@ -9,7 +9,6 @@ bb_vsrcs = $(base_dir)/vsrc/DebugTransportModuleJtag.v \ $(base_dir)/vsrc/AsyncMailbox.v \ $(base_dir)/vsrc/AsyncResetReg.v \ $(base_dir)/vsrc/AsyncSetReg.v \ - $(base_dir)/vsrc/ClockDivider.v \ sim_vsrcs = \ diff --git a/vsrc/ClockDivider.v b/vsrc/ClockDivider.v deleted file mode 100644 index 83bb561b..00000000 --- a/vsrc/ClockDivider.v +++ /dev/null @@ -1,19 +0,0 @@ -// You can't divide clocks in Chisel -module ClockDivider( - input clock_in, - input reset_in, - output clock_out, - output reset_out -); - - reg [2:0] shift = 3'b001; - - always @(posedge clock_in) - begin - shift <= {shift[0], shift[2:1]}; - end - - assign reset_out = reset_in; - assign clock_out = shift[0]; - -endmodule