diff --git a/fpga/src/main/scala/arty/Configs.scala b/fpga/src/main/scala/arty/Configs.scala index 9f113575..1cf7bfce 100644 --- a/fpga/src/main/scala/arty/Configs.scala +++ b/fpga/src/main/scala/arty/Configs.scala @@ -24,7 +24,7 @@ class WithArtyTweaks extends Config( new chipyard.harness.WithHarnessBinderClockFreqMHz(32) ++ new chipyard.harness.WithAllClocksFromHarnessClockInstantiator ++ - new chipyard.config.WithDTSTimebase(32768) ++ + new chipyard.config.WithDTSTimebase(32000) ++ new chipyard.config.WithSystemBusFrequency(32) ++ new chipyard.config.WithPeripheryBusFrequency(32) ++ new testchipip.WithNoSerialTL diff --git a/fpga/src/main/scala/arty/TestHarness.scala b/fpga/src/main/scala/arty/TestHarness.scala index 8bf6e751..306a1743 100644 --- a/fpga/src/main/scala/arty/TestHarness.scala +++ b/fpga/src/main/scala/arty/TestHarness.scala @@ -21,6 +21,7 @@ class ArtyFPGATestHarness(override implicit val p: Parameters) extends ArtyShell def success = {require(false, "Success not supported"); false.B } + def referenceClockFreqMHz = 32.0 def referenceClock = clock_32MHz def referenceReset = hReset diff --git a/fpga/src/main/scala/arty100t/Harness.scala b/fpga/src/main/scala/arty100t/Harness.scala index 21e910b5..64b4b28d 100644 --- a/fpga/src/main/scala/arty100t/Harness.scala +++ b/fpga/src/main/scala/arty100t/Harness.scala @@ -76,6 +76,7 @@ class Arty100THarness(override implicit val p: Parameters) extends Arty100TShell harnessSysPLL.plls.foreach(_._1.getReset.get := pllReset) + def referenceClockFreqMHz = dutFreqMHz def referenceClock = dutClock.in.head._1.clock def referenceReset = dutClock.in.head._1.reset def success = { require(false, "Unused"); false.B } diff --git a/fpga/src/main/scala/vc707/TestHarness.scala b/fpga/src/main/scala/vc707/TestHarness.scala index 7b9d58af..b78b0fe3 100644 --- a/fpga/src/main/scala/vc707/TestHarness.scala +++ b/fpga/src/main/scala/vc707/TestHarness.scala @@ -114,6 +114,7 @@ class VC707FPGATestHarnessImp(_outer: VC707FPGATestHarness) extends LazyRawModul val hReset = Wire(Reset()) hReset := _outer.dutClock.in.head._1.reset + def referenceClockFreqMHz = _outer.dutFreqMHz def referenceClock = _outer.dutClock.in.head._1.clock def referenceReset = hReset def success = { require(false, "Unused"); false.B } diff --git a/fpga/src/main/scala/vcu118/TestHarness.scala b/fpga/src/main/scala/vcu118/TestHarness.scala index 96bba231..cc87c4ea 100644 --- a/fpga/src/main/scala/vcu118/TestHarness.scala +++ b/fpga/src/main/scala/vcu118/TestHarness.scala @@ -118,6 +118,7 @@ class VCU118FPGATestHarnessImp(_outer: VCU118FPGATestHarness) extends LazyRawMod val hReset = Wire(Reset()) hReset := _outer.dutClock.in.head._1.reset + def referenceClockFreqMHz = _outer.dutFreqMHz def referenceClock = _outer.dutClock.in.head._1.clock def referenceReset = hReset def success = { require(false, "Unused"); false.B } diff --git a/generators/chipyard/src/main/scala/harness/HarnessBinders.scala b/generators/chipyard/src/main/scala/harness/HarnessBinders.scala index 42738f87..454d7859 100644 --- a/generators/chipyard/src/main/scala/harness/HarnessBinders.scala +++ b/generators/chipyard/src/main/scala/harness/HarnessBinders.scala @@ -379,9 +379,10 @@ class WithCustomBootPinPlusArg extends OverrideHarnessBinder({ class WithClockAndResetFromHarness extends OverrideHarnessBinder({ (system: HasChipyardPRCI, th: HasHarnessInstantiators, ports: Seq[Data]) => { implicit val p = GetSystemParameters(system) + val clocks = ports.collect { case c: ClockWithFreq => c } ports.map ({ case c: ClockWithFreq => { - val clock = th.harnessClockInstantiator.requestClockMHz(s"clock_${c.freqMHz}MHz", c.freqMHz) + val clock = th.harnessClockInstantiator.requestClockMHz(s"clock_${c.freqMHz.toInt}MHz", c.freqMHz) c.clock := clock } case r: AsyncReset => r := th.harnessBinderReset.asAsyncReset diff --git a/generators/chipyard/src/main/scala/harness/HarnessClocks.scala b/generators/chipyard/src/main/scala/harness/HarnessClocks.scala index 8d1c8756..d284e035 100644 --- a/generators/chipyard/src/main/scala/harness/HarnessClocks.scala +++ b/generators/chipyard/src/main/scala/harness/HarnessClocks.scala @@ -36,7 +36,7 @@ trait HarnessClockInstantiator { } // refClock is the clock generated by TestDriver that is // passed to the TestHarness as its implicit clock - def instantiateHarnessClocks(refClock: Clock): Unit + def instantiateHarnessClocks(refClock: Clock, refClockFreqMHz: Double): Unit } class ClockSourceAtFreqMHz(val freqMHz: Double) extends BlackBox(Map( @@ -65,7 +65,7 @@ class ClockSourceAtFreqMHz(val freqMHz: Double) extends BlackBox(Map( // This ClockInstantiator cannot be synthesized, run in Verilator, or run in FireSim // It is useful for VCS/Xcelium-driven RTL simulations class AbsoluteFreqHarnessClockInstantiator extends HarnessClockInstantiator { - def instantiateHarnessClocks(refClock: Clock): Unit = { + def instantiateHarnessClocks(refClock: Clock, refClockFreqMHz: Double): Unit = { // connect wires to clock source for ((name, (freqHz, clock)) <- clockMap) { val source = Module(new ClockSourceAtFreqMHz(freqHz / (1000 * 1000))) @@ -82,10 +82,14 @@ class WithAbsoluteFreqHarnessClockInstantiator extends Config((site, here, up) = }) class AllClocksFromHarnessClockInstantiator extends HarnessClockInstantiator { - def instantiateHarnessClocks(refClock: Clock): Unit = { + def instantiateHarnessClocks(refClock: Clock, refClockFreqMHz: Double): Unit = { val freqs = clockMap.map(_._2._1) freqs.tail.foreach(t => require(t == freqs.head, s"Mismatching clocks $t != ${freqs.head}")) for ((name, (freq, clock)) <- clockMap) { + val freqMHz = freq / (1000 * 1000) + require(freqMHz == refClockFreqMHz, + s"AllClocksFromHarnessClockInstantiator has reference ${refClockFreqMHz.toInt} MHz attempting to drive clock $name which requires $freqMHz MHz") + clock := refClock } } diff --git a/generators/chipyard/src/main/scala/harness/HasHarnessInstantiators.scala b/generators/chipyard/src/main/scala/harness/HasHarnessInstantiators.scala index af27e073..a66db4af 100644 --- a/generators/chipyard/src/main/scala/harness/HasHarnessInstantiators.scala +++ b/generators/chipyard/src/main/scala/harness/HasHarnessInstantiators.scala @@ -53,6 +53,7 @@ trait HasHarnessInstantiators { val harnessBinderReset = Wire(Reset()) // classes which inherit this trait should provide the below definitions + def referenceClockFreqMHz: Double def referenceClock: Clock def referenceReset: Reset def success: Bool @@ -88,7 +89,7 @@ trait HasHarnessInstantiators { harnessBinderClock := harnessBinderClk harnessBinderReset := ResetCatchAndSync(harnessBinderClk, referenceReset.asBool) - harnessClockInstantiator.instantiateHarnessClocks(referenceClock) + harnessClockInstantiator.instantiateHarnessClocks(referenceClock, referenceClockFreqMHz) lazyDuts } diff --git a/generators/chipyard/src/main/scala/harness/TestHarness.scala b/generators/chipyard/src/main/scala/harness/TestHarness.scala index 80f32c0a..2f75ac8d 100644 --- a/generators/chipyard/src/main/scala/harness/TestHarness.scala +++ b/generators/chipyard/src/main/scala/harness/TestHarness.scala @@ -24,6 +24,11 @@ class TestHarness(implicit val p: Parameters) extends Module with HasHarnessInst val success = WireInit(false.B) io.success := success + // By default, the chipyard makefile sets the TestHarness implicit clock to be 1GHz + // This clock shouldn't be used by this TestHarness however, as most users + // will use the AbsoluteFreqHarnessClockInstantiator, which generates clocks + // in verilog blackboxes + def referenceClockFreqMHz = 1000.0 def referenceClock = clock def referenceReset = reset diff --git a/generators/firechip/src/main/scala/FireSim.scala b/generators/firechip/src/main/scala/FireSim.scala index 6d43928d..a2f24dcb 100644 --- a/generators/firechip/src/main/scala/FireSim.scala +++ b/generators/firechip/src/main/scala/FireSim.scala @@ -28,7 +28,7 @@ import chipyard.clocking._ */ class FireSimClockBridgeInstantiator extends HarnessClockInstantiator { // connect all clock wires specified to the RationalClockBridge - def instantiateHarnessClocks(refClock: Clock): Unit = { + def instantiateHarnessClocks(refClock: Clock, refClockFreqMHz: Double): Unit = { val sinks = clockMap.map({ case (name, (freq, bundle)) => ClockSinkParameters(take=Some(ClockParameters(freqMHz=freq / (1000 * 1000))), name=Some(name)) }).toSeq @@ -72,6 +72,7 @@ class FireSim(implicit val p: Parameters) extends RawModule with HasHarnessInsta // In effect, the bridge counts the length of the reset in terms of this clock. resetBridge.io.clock := harnessBinderClock + def referenceClockFreqMHz = 0.0 def referenceClock = false.B.asClock // unused def referenceReset = resetBridge.io.reset def success = { require(false, "success should not be used in Firesim"); false.B }