diff --git a/docs/Advanced-Concepts/Chip-Communication.rst b/docs/Advanced-Concepts/Chip-Communication.rst index 3e067965d1..5a79e96370 100644 --- a/docs/Advanced-Concepts/Chip-Communication.rst +++ b/docs/Advanced-Concepts/Chip-Communication.rst @@ -183,28 +183,21 @@ This new setup (shown below) is a typical Chipyard test chip setup: Simulation Setup of the Example Test Chip ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -To test this type of configuration (TSI/memory transactions over the serial-link), most of the same TSI collateral -would be used. -The main difference is that the TileLink-to-AXI converters and simulated AXI memory resides on the other side of the -serial-link. +The standard test-chip bringup procedure tethers the chip to a FPGA config with serialized tilelink. .. image:: ../_static/images/chip-bringup-simulation.png -.. note:: - Here the simulated AXI memory and the converters can be in a different clock domain in the test harness - than the reference clock of the DUT. - For example, the DUT can be clocked at 3.2GHz while the simulated AXI memory can be clocked at 1GHz. - This functionality is done in the harness binder that instantiates the TSI collateral, TL-to-AXI converters, - and simulated AXI memory. - See :ref:`Advanced-Concepts/Harness-Clocks:Creating Clocks in the Test Harness` on how to generate a clock - in a harness binder. +The entire bringup procedure can be simulated using the Multi-ChipTop simulation feature, where +one ``ChipTop`` is the design-to-be-taped-out, while the other is the FPGA bringup design. -This type of simulation setup is done in the following multi-clock configuration: +This system can be generated and simulated with the following example configuration, which marries +a ``ChipLikeRocketConfig`` (the design to be taped-out) with the ``ChipBringupHostConfig`` (the FPGA +bringup design). -.. literalinclude:: ../../generators/chipyard/src/main/scala/config/RocketConfigs.scala +.. literalinclude:: ../../generators/chipyard/src/main/scala/config/ChipConfigs.scala :language: scala - :start-after: DOC include start: MulticlockAXIOverSerialConfig - :end-before: DOC include end: MulticlockAXIOverSerialConfig + :start-after: DOC include start: TetheredChipLikeRocketConfig + :end-before: DOC include end: TetheredChipLikeRocketConfig Softcore-driven Bringup Setup of the Example Test Chip after Tapeout ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/generators/chipyard/src/main/scala/config/ChipConfigs.scala b/generators/chipyard/src/main/scala/config/ChipConfigs.scala index 4ac80faa02..cc61794cdb 100644 --- a/generators/chipyard/src/main/scala/config/ChipConfigs.scala +++ b/generators/chipyard/src/main/scala/config/ChipConfigs.scala @@ -12,7 +12,6 @@ class ChipLikeRocketConfig extends Config( //================================== new chipyard.harness.WithAbsoluteFreqHarnessClockInstantiator ++ // use absolute frequencies for simulations in the harness // NOTE: This only simulates properly in VCS - new chipyard.harness.WithSimAXIMemOverSerialTL ++ // Attach SimDRAM to serial-tl port //================================== // Set up tiles @@ -90,12 +89,13 @@ class ChipBringupHostConfig extends Config( // Base is the no-cores config new chipyard.NoCoresConfig) +// DOC include start: TetheredChipLikeRocketConfig class TetheredChipLikeRocketConfig extends Config( new chipyard.harness.WithAbsoluteFreqHarnessClockInstantiator ++ // use absolute freqs for sims in the harness new chipyard.harness.WithMultiChipSerialTL(0, 1) ++ // connect the serial-tl ports of the chips together - new chipyard.harness.WithMultiChip(0, new ChipLikeRocketConfig) ++ - new chipyard.harness.WithMultiChip(1, new ChipBringupHostConfig)) - + new chipyard.harness.WithMultiChip(0, new ChipLikeRocketConfig) ++ // ChipTop0 is the design-to-be-taped-out + new chipyard.harness.WithMultiChip(1, new ChipBringupHostConfig)) // ChipTop1 is the bringup design +// DOC include end: TetheredChipLikeRocketConfig // Verilator does not initialize some of the async-reset reset-synchronizer // flops properly, so this config disables them. diff --git a/generators/chipyard/src/main/scala/config/RocketConfigs.scala b/generators/chipyard/src/main/scala/config/RocketConfigs.scala index beb094a913..c45fb6f236 100644 --- a/generators/chipyard/src/main/scala/config/RocketConfigs.scala +++ b/generators/chipyard/src/main/scala/config/RocketConfigs.scala @@ -96,29 +96,6 @@ class MulticlockRocketConfig extends Config( new testchipip.WithAsynchronousSerialSlaveCrossing ++ // Add Async crossing between serial and MBUS. Its master-side is tied to the FBUS new chipyard.config.AbstractConfig) -// DOC include start: MulticlockAXIOverSerialConfig -class MulticlockAXIOverSerialConfig extends Config( - new chipyard.config.WithSystemBusFrequency(250) ++ - new chipyard.config.WithPeripheryBusFrequency(250) ++ - new chipyard.config.WithMemoryBusFrequency(250) ++ - new chipyard.config.WithFrontBusFrequency(50) ++ - new chipyard.config.WithTileFrequency(500, Some(1)) ++ - new chipyard.config.WithTileFrequency(250, Some(0)) ++ - - new chipyard.config.WithFbusToSbusCrossingType(AsynchronousCrossing()) ++ - new testchipip.WithAsynchronousSerialSlaveCrossing ++ - new freechips.rocketchip.subsystem.WithAsynchronousRocketTiles( - AsynchronousCrossing().depth, - AsynchronousCrossing().sourceSync) ++ - - new chipyard.harness.WithSimAXIMemOverSerialTL ++ // add SimDRAM DRAM model for axi4 backing memory over the SerDes link, if axi4 mem is enabled - new testchipip.WithSerialTLBackingMemory ++ // remove axi4 mem port in favor of SerialTL memory - - new freechips.rocketchip.subsystem.WithNBigCores(2) ++ - new freechips.rocketchip.subsystem.WithNMemoryChannels(1) ++ // 1 memory channel - new chipyard.config.AbstractConfig) -// DOC include end: MulticlockAXIOverSerialConfig - class CustomIOChipTopRocketConfig extends Config( new chipyard.example.WithCustomChipTop ++ new chipyard.example.WithCustomIOCells ++ diff --git a/generators/chipyard/src/main/scala/example/FlatTestHarness.scala b/generators/chipyard/src/main/scala/example/FlatTestHarness.scala index afdf67cab7..56bc9a7834 100644 --- a/generators/chipyard/src/main/scala/example/FlatTestHarness.scala +++ b/generators/chipyard/src/main/scala/example/FlatTestHarness.scala @@ -1,7 +1,7 @@ package chipyard.example import chisel3._ - +import chisel3.experimental.{Analog, BaseModule, DataMirror, Direction} import scala.collection.mutable.{ArrayBuffer, LinkedHashMap} import org.chipsalliance.cde.config.{Field, Parameters} @@ -41,30 +41,19 @@ class FlatTestHarness(implicit val p: Parameters) extends Module { // Serialized TL val sVal = p(SerialTLKey).get val serialTLManagerParams = sVal.serialTLManagerParams.get - val axiDomainParams = serialTLManagerParams.axiMemOverSerialTLParams.get require(serialTLManagerParams.isMemoryDevice) - val memFreq = axiDomainParams.getMemFrequency(lazyDut.system) withClockAndReset(clock, reset) { val serial_bits = dut.serial_tl_pad.bits - dut.serial_tl_pad.clock := clock - val harnessMultiClockAXIRAM = TSIHarness.connectMultiClockAXIRAM( + if (DataMirror.directionOf(dut.serial_tl_pad.clock) == Direction.Input) { + dut.serial_tl_pad.clock := clock + } + val harnessRAM = TSIHarness.connectRAM( lazyDut.system.serdesser.get, serial_bits, - clock, reset) - io.success := SimTSI.connect(Some(harnessMultiClockAXIRAM.module.io.tsi), clock, reset) + io.success := SimTSI.connect(Some(harnessRAM.module.io.tsi), clock, reset) - // connect SimDRAM from the AXI port coming from the harness multi clock axi ram - (harnessMultiClockAXIRAM.mem_axi4.get zip harnessMultiClockAXIRAM.memNode.get.edges.in).map { case (axi_port, edge) => - val memSize = serialTLManagerParams.memParams.size - val memBase = serialTLManagerParams.memParams.base - val lineSize = p(CacheBlockBytes) - val mem = Module(new SimDRAM(memSize, lineSize, BigInt(memFreq.toLong), memBase, edge.bundle)).suggestName("simdram") - mem.io.axi <> axi_port.bits - mem.io.clock := axi_port.clock - mem.io.reset := axi_port.reset - } } // JTAG diff --git a/generators/chipyard/src/main/scala/harness/HarnessBinders.scala b/generators/chipyard/src/main/scala/harness/HarnessBinders.scala index 1d5192fbe6..b670fd7404 100644 --- a/generators/chipyard/src/main/scala/harness/HarnessBinders.scala +++ b/generators/chipyard/src/main/scala/harness/HarnessBinders.scala @@ -128,46 +128,6 @@ class WithSimAXIMem extends OverrideHarnessBinder({ } }) -class WithSimAXIMemOverSerialTL extends OverrideHarnessBinder({ - (system: CanHavePeripheryTLSerial, th: HasHarnessInstantiators, ports: Seq[ClockedIO[SerialIO]]) => { - implicit val p = chipyard.iobinders.GetSystemParameters(system) - - p(SerialTLKey).map({ sVal => - val serialTLManagerParams = sVal.serialTLManagerParams.get - val axiDomainParams = serialTLManagerParams.axiMemOverSerialTLParams.get - require(serialTLManagerParams.isMemoryDevice) - - val memFreq = axiDomainParams.getMemFrequency(system.asInstanceOf[HasTileLinkLocations]) - - ports.map({ port => -// DOC include start: HarnessClockInstantiatorEx - val memOverSerialTLClock = th.harnessClockInstantiator.requestClockHz("mem_over_serial_tl_clock", memFreq) - val serial_bits = port.bits - port.clock := th.harnessBinderClock - val harnessMultiClockAXIRAM = TSIHarness.connectMultiClockAXIRAM( - system.serdesser.get, - serial_bits, - memOverSerialTLClock, - th.harnessBinderReset) - // DOC include end: HarnessClockInstantiatorEx - val success = SimTSI.connect(Some(harnessMultiClockAXIRAM.module.io.tsi), th.harnessBinderClock, th.harnessBinderReset.asBool) - when (success) { th.success := true.B } - - // connect SimDRAM from the AXI port coming from the harness multi clock axi ram - (harnessMultiClockAXIRAM.mem_axi4.get zip harnessMultiClockAXIRAM.memNode.get.edges.in).map { case (axi_port, edge) => - val memSize = serialTLManagerParams.memParams.size - val memBase = serialTLManagerParams.memParams.base - val lineSize = p(CacheBlockBytes) - val mem = Module(new SimDRAM(memSize, lineSize, BigInt(memFreq.toLong), memBase, edge.bundle)).suggestName("simdram") - mem.io.axi <> axi_port.bits - mem.io.clock := axi_port.clock - mem.io.reset := axi_port.reset - } - }) - }) - } -}) - class WithBlackBoxSimMem(additionalLatency: Int = 0) extends OverrideHarnessBinder({ (system: CanHaveMasterAXI4MemPort, th: HasHarnessInstantiators, ports: Seq[ClockedAndResetIO[AXI4Bundle]]) => { val p: Parameters = chipyard.iobinders.GetSystemParameters(system) @@ -305,7 +265,9 @@ class WithSimTSIOverSerialTL extends OverrideHarnessBinder({ implicit val p = chipyard.iobinders.GetSystemParameters(system) ports.map({ port => val bits = port.bits - port.clock := th.harnessBinderClock + if (DataMirror.directionOf(port.clock) == Direction.Input) { + port.clock := th.harnessBinderClock + } val ram = TSIHarness.connectRAM(system.serdesser.get, bits, th.harnessBinderReset) val success = SimTSI.connect(Some(ram.module.io.tsi), th.harnessBinderClock, th.harnessBinderReset.asBool) when (success) { th.success := true.B } @@ -385,6 +347,7 @@ class WithClockAndResetFromHarness extends OverrideHarnessBinder({ (system: HasChipyardPRCI, th: HasHarnessInstantiators, ports: Seq[Data]) => { implicit val p = GetSystemParameters(system) val clocks = ports.collect { case c: ClockWithFreq => c } +// DOC include start: HarnessClockInstantiatorEx ports.map ({ case c: ClockWithFreq => { val clock = th.harnessClockInstantiator.requestClockMHz(s"clock_${c.freqMHz.toInt}MHz", c.freqMHz) @@ -392,5 +355,6 @@ class WithClockAndResetFromHarness extends OverrideHarnessBinder({ } case r: AsyncReset => r := th.referenceReset.asAsyncReset }) +// DOC include end: HarnessClockInstantiatorEx } }) diff --git a/generators/firechip/src/main/scala/BridgeBinders.scala b/generators/firechip/src/main/scala/BridgeBinders.scala index 0cb42e14be..db6ec2fbb8 100644 --- a/generators/firechip/src/main/scala/BridgeBinders.scala +++ b/generators/firechip/src/main/scala/BridgeBinders.scala @@ -108,48 +108,6 @@ class WithBlockDeviceBridge extends OverrideHarnessBinder({ } }) -class WithAXIOverSerialTLCombinedBridges extends OverrideHarnessBinder({ - (system: CanHavePeripheryTLSerial, th: FireSim, ports: Seq[ClockedIO[SerialIO]]) => { - implicit val p = GetSystemParameters(system) - - p(SerialTLKey).map({ sVal => - val serialTLManagerParams = sVal.serialTLManagerParams.get - val axiDomainParams = serialTLManagerParams.axiMemOverSerialTLParams.get - require(serialTLManagerParams.isMemoryDevice) - val memFreq = axiDomainParams.getMemFrequency(system.asInstanceOf[HasTileLinkLocations]) - - ports.map({ port => - val axiClock = th.harnessClockInstantiator.requestClockHz("mem_over_serial_tl_clock", memFreq) - - val serial_bits = port.bits - port.clock := th.harnessBinderClock - val harnessMultiClockAXIRAM = TSIHarness.connectMultiClockAXIRAM( - system.serdesser.get, - serial_bits, - axiClock, - ResetCatchAndSync(axiClock, th.harnessBinderReset.asBool)) - TSIBridge(th.harnessBinderClock, harnessMultiClockAXIRAM.module.io.tsi, Some(MainMemoryConsts.globalName), th.harnessBinderReset.asBool) - - // connect SimAxiMem - (harnessMultiClockAXIRAM.mem_axi4.get zip harnessMultiClockAXIRAM.memNode.get.edges.in).map { case (axi4, edge) => - val nastiKey = NastiParameters(axi4.bits.r.bits.data.getWidth, - axi4.bits.ar.bits.addr.getWidth, - axi4.bits.ar.bits.id.getWidth) - system match { - case s: BaseSubsystem => FASEDBridge(axi4.clock, axi4.bits, axi4.reset.asBool, - CompleteConfig(p(firesim.configs.MemModelKey), - nastiKey, - Some(AXI4EdgeSummary(edge)), - Some(MainMemoryConsts.globalName))) - case _ => throw new Exception("Attempting to attach FASED Bridge to misconfigured design") - } - } - }) - }) - - Nil - } -}) class WithFASEDBridge extends OverrideHarnessBinder({ (system: CanHaveMasterAXI4MemPort, th: FireSim, ports: Seq[ClockedAndResetIO[AXI4Bundle]]) => { diff --git a/generators/firechip/src/main/scala/TargetConfigs.scala b/generators/firechip/src/main/scala/TargetConfigs.scala index dd8cd33880..c08a028d23 100644 --- a/generators/firechip/src/main/scala/TargetConfigs.scala +++ b/generators/firechip/src/main/scala/TargetConfigs.scala @@ -302,18 +302,6 @@ class FireSimCVA6Config extends Config( new WithFireSimConfigTweaks ++ new chipyard.CVA6Config) -//********************************************************************************** -//* Multiclock Configurations -//*********************************************************************************/ -class FireSimMulticlockAXIOverSerialConfig extends Config( - new WithAXIOverSerialTLCombinedBridges ++ // use combined bridge to connect to axi mem over serial - new WithDefaultFireSimBridges ++ - new testchipip.WithBlockDevice(false) ++ // disable blockdev - new WithDefaultMemModel ++ - new WithFireSimDesignTweaks ++ // don't inherit firesim clocking - new chipyard.MulticlockAXIOverSerialConfig -) - //********************************************************************************** // System with 16 LargeBOOMs that can be simulated with Golden Gate optimizations // - Requires MTModels and MCRams mixins as prefixes to the platform config diff --git a/generators/testchipip b/generators/testchipip index 47a616d99a..177e307199 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit 47a616d99ae08fe124090817fcec5fbbc3f534a5 +Subproject commit 177e3071991421bdb042fec8411c51463477c7fc