From a3e22c78de66131c07e528db7aef2614a803f492 Mon Sep 17 00:00:00 2001 From: Abraham Gonzalez Date: Sun, 28 Feb 2021 22:27:18 +0000 Subject: [PATCH] First attempt at getting Offchip AXI port --- .../src/main/scala/ConfigFragments.scala | 18 +++++- .../src/main/scala/HarnessBinders.scala | 23 ++++++++ .../chipyard/src/main/scala/IOBinders.scala | 30 +++++++++- .../main/scala/config/AbstractConfig.scala | 43 +++++++++++++++ .../src/main/scala/config/RocketConfigs.scala | 52 +++++++++++++++++- .../src/main/scala/BridgeBinders.scala | 28 ++++++++++ .../src/main/scala/TargetConfigs.scala | 55 +++++++++++++++++++ generators/testchipip | 2 +- 8 files changed, 247 insertions(+), 4 deletions(-) diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index 667e5148..f2d77a5f 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -193,7 +193,23 @@ class WithTLBackingMemory extends Config((site, here, up) => { case ExtTLMem => up(ExtMem, site) // enable TL backing memory }) -class WithTileFrequency(fMHz: Double) extends ClockNameContainsAssignment("core", fMHz) +class WithOffchipBackingMemory extends Config((site, here, up) => { + case ExtMem => None + case SerialTLKey => Some(SerialTLParams( + memParams = { + val memPortParams = up(ExtMem, site).get + + require(memPortParams.nMemoryChannels == 1) + + memPortParams.master + }, + width = 4, + isMemoryDevice = true + )) +}) + +class WithTileFrequency(fMHz: Double) extends ClockNameContainsAssignment("tile", fMHz) +class WithSpecificTileFrequency(hartId: Int, fMHz: Double) extends chipyard.ClockNameContainsAssignment(s"tile_$hartId", fMHz) class WithPeripheryBusFrequencyAsDefault extends Config((site, here, up) => { case DefaultClockFrequencyKey => (site(PeripheryBusKey).dtsFrequency.get / (1000 * 1000)).toDouble diff --git a/generators/chipyard/src/main/scala/HarnessBinders.scala b/generators/chipyard/src/main/scala/HarnessBinders.scala index 643b2065..95382f6e 100644 --- a/generators/chipyard/src/main/scala/HarnessBinders.scala +++ b/generators/chipyard/src/main/scala/HarnessBinders.scala @@ -139,6 +139,29 @@ class WithSimAXIMem extends OverrideHarnessBinder({ } }) +class WithOffchipNetwork(offchipFreqMHz: Double = 1000) extends OverrideHarnessBinder({ + (system: CanHavePeripheryTLSerial, th: HasHarnessSignalReferences, ports: Seq[ClockedAndResetIO[ClockedIO[SerialIO]]]) => { + implicit val p = chipyard.iobinders.GetSystemParameters(system) + + ports.map({ port => + val offchipNetwork = SerialAdapter.connectOffChipNetwork(system.serdesser.get, port, th.harnessReset) + val success = SerialAdapter.connectSimSerial(offchipNetwork.module.io.tsi_ser, port.bits.clock, th.harnessReset.asBool) + when (success) { th.success := true.B } + + // connect SimAxiMem + (offchipNetwork.mem_axi4 zip offchipNetwork.memAXI4Node.edges.in).map { case (off_port, edge) => + val memSize = p(SerialTLKey).get.memParams.size + val lineSize = p(CacheBlockBytes) + val mem = Module(new SimDRAM(memSize, lineSize, offchipFreqMHz.toInt*1000000, edge.bundle)).suggestName("simdram") + mem.io.axi <> off_port + // use the clk from the ClockAndResetIO + mem.io.clock := port.clock + mem.io.reset := port.reset + } + }) + } +}) + class WithBlackBoxSimMem(additionalLatency: Int = 0) extends OverrideHarnessBinder({ (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedAndResetIO[AXI4Bundle]]) => { val p: Parameters = chipyard.iobinders.GetSystemParameters(system) diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index ab6ccdf8..eff75ae2 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -11,7 +11,7 @@ import freechips.rocketchip.subsystem._ import freechips.rocketchip.system.{SimAXIMem} import freechips.rocketchip.amba.axi4.{AXI4Bundle, AXI4SlaveNode, AXI4MasterNode, AXI4EdgeParameters} import freechips.rocketchip.util._ -import freechips.rocketchip.prci.{ClockSinkNode, ClockSinkParameters} +import freechips.rocketchip.prci.{ClockSinkNode, ClockSinkParameters, ClockParameters, ClockGroup} import freechips.rocketchip.groundtest.{GroundTestSubsystemModuleImp, GroundTestSubsystem} import sifive.blocks.devices.gpio._ @@ -260,6 +260,34 @@ class WithSerialTLIOCells extends OverrideIOBinder({ }).getOrElse((Nil, Nil)) }) +class WithSerialTLAndOffchipClockPunchthrough(offchipFreqMHz: Double = 1000) extends OverrideLazyIOBinder({ + (system: CanHavePeripheryTLSerial) => { + implicit val p: Parameters = GetSystemParameters(system) + + val serial_clked_tl = system.serial_tl + val sys = system.asInstanceOf[BaseSubsystem] + + val externalDRAMClockSinkNode = ClockSinkNode(Seq(ClockSinkParameters(take = Some(ClockParameters(freqMHz = offchipFreqMHz))))) + (externalDRAMClockSinkNode + := ClockGroup()(p, ValName("OffchipClocking")) + := sys.asyncClockGroupsNode) + def clockBundle = externalDRAMClockSinkNode.in.head._1 + + InModuleBody { + // 1st clock+reset is for offchip, 2nd clock (attached to serial io is the serial clock) + val port: Option[ClockedAndResetIO[ClockedIO[SerialIO]]] = serial_clked_tl.map({ s_io => + val p = IO(new ClockedAndResetIO(DataMirror.internal.chiselTypeClone[ClockedIO[SerialIO]](s_io))).suggestName(s"serial_tl_offchip_clk") + p.bits <> s_io + p.clock := clockBundle.clock + p.reset := clockBundle.reset + p + }) + + // return the ports and no IO cells + (Seq(port.get), Nil) + } + } +}) class WithAXI4MemPunchthrough extends OverrideLazyIOBinder({ (system: CanHaveMasterAXI4MemPort) => { diff --git a/generators/chipyard/src/main/scala/config/AbstractConfig.scala b/generators/chipyard/src/main/scala/config/AbstractConfig.scala index a70ae4df..043bd45e 100644 --- a/generators/chipyard/src/main/scala/config/AbstractConfig.scala +++ b/generators/chipyard/src/main/scala/config/AbstractConfig.scala @@ -55,3 +55,46 @@ class AbstractConfig extends Config( new chipyard.WithMulticlockCoherentBusTopology ++ // hierarchical buses including mbus+l2 new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system +class AbstractOffChipConfig extends Config( + // The HarnessBinders control generation of hardware in the TestHarness + new chipyard.harness.WithUARTAdapter ++ // add UART adapter to display UART on stdout, if uart is present + new chipyard.harness.WithOffchipNetwork ++ // add SimDRAM DRAM model for axi4 backing memory over the SerDes link, if axi4 mem is enabled + new chipyard.harness.WithSimDebug ++ // add SimJTAG or SimDTM adapters if debug module is enabled + new chipyard.harness.WithGPIOTiedOff ++ // tie-off chiptop GPIOs, if GPIOs are present + new chipyard.harness.WithSimSPIFlashModel ++ // add simulated SPI flash memory, if SPI is enabled + new chipyard.harness.WithSimAXIMMIO ++ // add SimAXIMem for axi4 mmio port, if enabled + new chipyard.harness.WithTieOffInterrupts ++ // tie-off interrupt ports, if present + new chipyard.harness.WithTieOffL2FBusAXI ++ // tie-off external AXI4 master, if present + + // The IOBinders instantiate ChipTop IOs to match desired digital IOs + // IOCells are generated for "Chip-like" IOs, while simulation-only IOs are directly punched through + new chipyard.iobinders.WithAXI4MemPunchthrough ++ + new chipyard.iobinders.WithAXI4MMIOPunchthrough ++ + new chipyard.iobinders.WithL2FBusAXI4Punchthrough ++ + new chipyard.iobinders.WithBlockDeviceIOPunchthrough ++ + new chipyard.iobinders.WithNICIOPunchthrough ++ + new chipyard.iobinders.WithSerialTLAndOffchipClockPunchthrough ++ + new chipyard.iobinders.WithDebugIOCells ++ + new chipyard.iobinders.WithUARTIOCells ++ + new chipyard.iobinders.WithGPIOCells ++ + new chipyard.iobinders.WithUARTIOCells ++ + new chipyard.iobinders.WithSPIIOCells ++ + new chipyard.iobinders.WithTraceIOPunchthrough ++ + new chipyard.iobinders.WithExtInterruptIOCells ++ + + new chipyard.config.WithOffchipBackingMemory ++ + new chipyard.config.WithBootROM ++ // use default bootrom + new chipyard.config.WithUART ++ // add a UART + new chipyard.config.WithL2TLBs(1024) ++ // use L2 TLBs + new chipyard.config.WithNoSubsystemDrivenClocks ++ // drive the subsystem diplomatic clocks from ChipTop instead of using implicit clocks + new chipyard.config.WithInheritBusFrequencyAssignments ++ // Unspecified clocks within a bus will receive the bus frequency if set + new chipyard.config.WithPeripheryBusFrequencyAsDefault ++ // Unspecified frequencies with match the pbus frequency (which is always set) + new chipyard.config.WithMemoryBusFrequency(100.0) ++ // Default 100 MHz mbus + new chipyard.config.WithPeripheryBusFrequency(100.0) ++ // Default 100 MHz pbus + new freechips.rocketchip.subsystem.WithJtagDTM ++ // set the debug module to expose a JTAG port + new freechips.rocketchip.subsystem.WithNoMMIOPort ++ // no top-level MMIO master port (overrides default set in rocketchip) + new freechips.rocketchip.subsystem.WithNoSlavePort ++ // no top-level MMIO slave port (overrides default set in rocketchip) + new freechips.rocketchip.subsystem.WithInclusiveCache ++ // use Sifive L2 cache + new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ // no external interrupts + new chipyard.WithMulticlockCoherentBusTopology ++ // hierarchical buses including mbus+l2 + new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system diff --git a/generators/chipyard/src/main/scala/config/RocketConfigs.scala b/generators/chipyard/src/main/scala/config/RocketConfigs.scala index 7c4de6f5..2e6eb40f 100644 --- a/generators/chipyard/src/main/scala/config/RocketConfigs.scala +++ b/generators/chipyard/src/main/scala/config/RocketConfigs.scala @@ -1,7 +1,8 @@ package chipyard import freechips.rocketchip.config.{Config} -import freechips.rocketchip.diplomacy.{AsynchronousCrossing} +import freechips.rocketchip.diplomacy.{AsynchronousCrossing, RationalCrossing} +import freechips.rocketchip.util.{SlowToFast} // -------------- // Rocket Configs @@ -212,3 +213,52 @@ class LBWIFRocketConfig extends Config( new freechips.rocketchip.subsystem.WithNoMemPort ++ // remove AXI4 backing memory new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) + +// DEBUG: To check if UART works (with everything default but serdes slow and ramp up to 1GHz) +class DebugOffchipConfig extends Config( + new testchipip.WithSerialTLWidth(32) ++ + new testchipip.WithAsynchronousSerialSlaveCrossing ++ // SerDes <-async-> mbus. Remember SerDes master tied to fbus + new chipyard.config.WithFbusToSbusCrossingType(RationalCrossing(SlowToFast)) ++ // fbus slow -> sbus fast + new chipyard.config.WithFrontBusFrequency(3200 / 4) ++ // controls SerDes freq. + + new chipyard.config.WithPeripheryBusFrequencyAsDefault ++ // everything default to 3.2GHz + new chipyard.config.WithPeripheryBusFrequency(3200) ++ + new chipyard.config.WithMemoryBusFrequency(3200) ++ + + new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // add 1 rocket cores + new chipyard.config.AbstractOffChipConfig) // new offchip network where AXI is in harness + +// have pbus=3.2GHz,/1, but others are different (fbus=/4, other=/2) +class DebugOffchip2Config extends Config( + new chipyard.config.WithCbusToPbusCrossingType(RationalCrossing(SlowToFast)) ++ + new chipyard.config.WithFbusToSbusCrossingType(RationalCrossing(SlowToFast)) ++ + + new chipyard.config.WithSystemBusFrequencyAsDefault ++ + new chipyard.config.WithSystemBusFrequency(3200 / 2) ++ + + new chipyard.config.WithFrontBusFrequency(3200 / 4) ++ + new chipyard.config.WithPeripheryBusFrequency(3200) ++ + new chipyard.config.WithMemoryBusFrequency(3200) ++ + + new chipyard.config.WithFbusToSbusCrossingType(RationalCrossing(SlowToFast)) ++ // fbus slow -> sbus fast + new testchipip.WithAsynchronousSerialSlaveCrossing ++ // Add Async crossing between serial and MBUS. Its master-side is tied to the FBUS + + new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // add 1 rocket cores + new chipyard.config.AbstractOffChipConfig) + +// fbus=/2, other=/1 +class DebugOffchip3Config extends Config( + new chipyard.config.WithFbusToSbusCrossingType(RationalCrossing(SlowToFast)) ++ + + new chipyard.config.WithSystemBusFrequencyAsDefault ++ + new chipyard.config.WithSystemBusFrequency(4000) ++ + new chipyard.config.WithPeripheryBusFrequency(4000) ++ + new chipyard.config.WithMemoryBusFrequency(4000) ++ + + new chipyard.config.WithFrontBusFrequency(4000 / 2) ++ + + new chipyard.config.WithFbusToSbusCrossingType(RationalCrossing(SlowToFast)) ++ // fbus slow -> sbus fast + new testchipip.WithAsynchronousSerialSlaveCrossing ++ // Add Async crossing between serial and MBUS. Its master-side is tied to the FBUS + + new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // add 1 rocket cores + new chipyard.config.AbstractOffChipConfig) diff --git a/generators/firechip/src/main/scala/BridgeBinders.scala b/generators/firechip/src/main/scala/BridgeBinders.scala index bdbb7d44..34a18f85 100644 --- a/generators/firechip/src/main/scala/BridgeBinders.scala +++ b/generators/firechip/src/main/scala/BridgeBinders.scala @@ -103,6 +103,34 @@ class WithBlockDeviceBridge extends OverrideHarnessBinder({ } }) +class WithOffchipNetworkSerialAXIBridge extends OverrideHarnessBinder({ + (system: CanHavePeripheryTLSerial, th: FireSim, ports: Seq[ClockedAndResetIO[ClockedIO[SerialIO]]]) => { + implicit val p = GetSystemParameters(system) + + ports.map({ port => + val offchipNetwork = SerialAdapter.connectOffChipNetwork(system.serdesser.get, port, th.harnessReset) + SerialBridge(port.bits.clock, offchipNetwork.module.io.tsi_ser, p(ExtMem).map(_ => MainMemoryConsts.globalName)) + + // connect SimAxiMem + (offchipNetwork.mem_axi4 zip offchipNetwork.memAXI4Node.edges.in).map { case (axi4, edge) => + val nastiKey = NastiParameters(axi4.r.bits.data.getWidth, + axi4.ar.bits.addr.getWidth, + axi4.ar.bits.id.getWidth) + system match { + case s: BaseSubsystem => FASEDBridge(port.clock, axi4, port.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]]) => { implicit val p: Parameters = GetSystemParameters(system) diff --git a/generators/firechip/src/main/scala/TargetConfigs.scala b/generators/firechip/src/main/scala/TargetConfigs.scala index 92cd02c3..619137fd 100644 --- a/generators/firechip/src/main/scala/TargetConfigs.scala +++ b/generators/firechip/src/main/scala/TargetConfigs.scala @@ -215,3 +215,58 @@ class FireSim16LargeBoomConfig extends Config( new WithFireSimConfigTweaks ++ new boom.common.WithNLargeBooms(16) ++ new chipyard.config.AbstractConfig) + +class WithOffchipAXINoClksSetup(pbusFreqMHz: BigInt = 3200) extends Config( + // normal bridges + new offchip bridge + new WithNICBridge ++ + new WithUARTBridge ++ + new WithBlockDeviceBridge ++ + new WithOffchipNetworkSerialAXIBridge ++ // NEW BRIDGE COMBINING SERIAL/AXI + new WithFireSimMultiCycleRegfile ++ + new WithFireSimFAME5 ++ + //new WithTracerVBridge ++ + new WithFireSimIOCellModels ++ + + // new tweaks + // Required: Bake in the default FASED memory model + new WithDefaultMemModel ++ + // Required*: Uses FireSim ClockBridge and PeekPokeBridge to drive the system with a single clock/reset + new WithFireSimSimpleClocks ++ + // Required*: When using FireSim-as-top to provide a correct path to the target bootrom source + new WithBootROM ++ + // Required: Existing FAME-1 transform cannot handle black-box clock gates + new WithoutClockGating ++ + // Required*: Removes thousands of assertions that would be synthesized (* pending PriorityMux bugfix) + new WithoutTLMonitors ++ + // Optional: Adds IO to attach tracerV bridges + //new chipyard.config.WithTraceIO ++ + // Optional: Request 16 GiB of target-DRAM by default (can safely request up to 32 GiB on F1) + new freechips.rocketchip.subsystem.WithExtMemSize((1 << 30) * 16L) ++ + // Optional: Removing this will require using an initramfs under linux + new testchipip.WithBlockDevice ++ + // Required*: Scale default baud rate with periphery bus frequency + // Rough math... + // NEW: + // pbus @ 500MHz.... baud @ 576000 = 115200 * 5 (somehow the default was 100M) + // OLD: pbus @ 3200MHz, HW baud @ 3686400L AKA 115200 * 32 + // OLD: Linux @ 115200, SBI @ 115200 + // scale down to 100MHz before multipling up + new chipyard.config.WithUART((pbusFreqMHz / 100) * BigInt(115200L)) ++ + // Required: Do not support debug module w. JTAG until FIRRTL stops emitting @(posedge ~clock) + new chipyard.config.WithNoDebug +) + +class FireSimDebugOffchipConfig extends Config( + new WithOffchipAXINoClksSetup(3200) ++ + new chipyard.DebugOffchipConfig +) + +class FireSimDebugOffchip2Config extends Config( + new WithOffchipAXINoClksSetup(3200) ++ + new chipyard.DebugOffchip2Config +) + +class FireSimDebugOffchip3Config extends Config( + new WithOffchipAXINoClksSetup(4000) ++ + new chipyard.DebugOffchip3Config +) diff --git a/generators/testchipip b/generators/testchipip index f2705592..abc5be8e 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit f27055929a2d4c091bfe10c3b64761e281844a2b +Subproject commit abc5be8ef1dc9bb5614ef81fbb021b51a21679dd