Merge remote-tracking branch 'ch/lazy-iobinders' into local-fpga-temp
This commit is contained in:
@@ -23,12 +23,10 @@ case object BuildSystem extends Field[Parameters => LazyModule]((p: Parameters)
|
||||
* drive clock and reset generation
|
||||
*/
|
||||
|
||||
class ChipTop(implicit p: Parameters) extends LazyModule with HasTestHarnessFunctions with BindingScope {
|
||||
// A publicly accessible list of IO cells (useful for a floorplanning tool, for example)
|
||||
val iocells = ArrayBuffer.empty[IOCell]
|
||||
|
||||
class ChipTop(implicit p: Parameters) extends LazyModule
|
||||
with HasTestHarnessFunctions with HasIOBinders with BindingScope {
|
||||
// The system module specified by BuildSystem
|
||||
val lazySystem = LazyModule(p(BuildSystem)(p)).suggestName("system")
|
||||
lazy val lazySystem = LazyModule(p(BuildSystem)(p)).suggestName("system")
|
||||
|
||||
// The implicitClockSinkNode provides the implicit clock and reset for the System
|
||||
val implicitClockSinkNode = ClockSinkNode(Seq(ClockSinkParameters(name = Some("implicit_clock"))))
|
||||
@@ -45,13 +43,6 @@ class ChipTop(implicit p: Parameters) extends LazyModule with HasTestHarnessFunc
|
||||
val implicit_clock = implicitClockSinkNode.in.head._1.clock
|
||||
val implicit_reset = implicitClockSinkNode.in.head._1.reset
|
||||
|
||||
|
||||
// Note: IOBinders cannot rely on the implicit clock/reset, as this is a LazyRawModuleImp
|
||||
val (_ports, _iocells, _portMap) = ApplyIOBinders(lazySystem, p(IOBinders))
|
||||
// We ignore _ports for now...
|
||||
iocells ++= _iocells
|
||||
portMap ++= _portMap
|
||||
|
||||
// Connect the implicit clock/reset, if present
|
||||
lazySystem.module match { case l: LazyModuleImp => {
|
||||
l.clock := implicit_clock
|
||||
|
||||
@@ -8,12 +8,12 @@ import freechips.rocketchip.prci._
|
||||
import freechips.rocketchip.subsystem.{BaseSubsystem, SubsystemDriveAsyncClockGroupsKey, InstantiatesTiles}
|
||||
import freechips.rocketchip.config.{Parameters, Field, Config}
|
||||
import freechips.rocketchip.diplomacy.{OutwardNodeHandle, InModuleBody, LazyModule}
|
||||
import freechips.rocketchip.util.{ResetCatchAndSync, Pow2ClockDivider}
|
||||
import freechips.rocketchip.util.{ResetCatchAndSync}
|
||||
|
||||
import barstools.iocell.chisel._
|
||||
import testchipip.{TLTileResetCtrl}
|
||||
|
||||
import chipyard.clocking.{DividerOnlyClockGenerator, ClockGroupNamePrefixer, ClockGroupFrequencySpecifier}
|
||||
import chipyard.clocking._
|
||||
|
||||
/**
|
||||
* Chipyard provides three baseline, top-level reset schemes, set using the
|
||||
@@ -121,13 +121,14 @@ object ClockingSchemeGenerators {
|
||||
:= ClockGroup()
|
||||
:= aggregator)
|
||||
(systemAsyncClockGroup
|
||||
:= resetSetter
|
||||
:= ClockGroupNamePrefixer()
|
||||
:= aggregator)
|
||||
:*= resetSetter
|
||||
:*= ClockGroupNamePrefixer()
|
||||
:*= aggregator)
|
||||
|
||||
val referenceClockSource = ClockSourceNode(Seq(ClockSourceParameters()))
|
||||
(aggregator
|
||||
:= ClockGroupFrequencySpecifier(p(ClockFrequencyAssignersKey), p(DefaultClockFrequencyKey))
|
||||
:= ClockGroupResetSynchronizer()
|
||||
:= DividerOnlyClockGenerator()
|
||||
:= referenceClockSource)
|
||||
|
||||
|
||||
@@ -5,13 +5,13 @@ import chisel3.util.{log2Up}
|
||||
|
||||
import freechips.rocketchip.config.{Field, Parameters, Config}
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.diplomacy.{LazyModule, ValName}
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.devices.tilelink.{BootROMLocated}
|
||||
import freechips.rocketchip.devices.debug.{Debug, ExportDebug, DebugModuleKey, DMI}
|
||||
import freechips.rocketchip.groundtest.{GroundTestSubsystem}
|
||||
import freechips.rocketchip.tile._
|
||||
import freechips.rocketchip.rocket.{RocketCoreParams, MulDivParams, DCacheParams, ICacheParams}
|
||||
import freechips.rocketchip.util.{AsyncResetReg}
|
||||
import freechips.rocketchip.util.{AsyncResetReg, Symmetric}
|
||||
import freechips.rocketchip.prci._
|
||||
|
||||
import testchipip._
|
||||
@@ -172,3 +172,46 @@ class WithPeripheryBusFrequencyAsDefault extends Config((site, here, up) => {
|
||||
case DefaultClockFrequencyKey => (site(PeripheryBusKey).dtsFrequency.get / (1000 * 1000)).toDouble
|
||||
})
|
||||
|
||||
/**
|
||||
* Mixins to specify crossing types between the 5 traditional TL buses
|
||||
*
|
||||
* Note: these presuppose the legacy connections between buses and set
|
||||
* parameters in SubsystemCrossingParams; they may not be resuable in custom
|
||||
* topologies (but you can specify the desired crossings in your topology).
|
||||
*
|
||||
* @param xType The clock crossing type
|
||||
*
|
||||
*/
|
||||
|
||||
class WithSbusToMbusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => {
|
||||
case SbusToMbusXTypeKey => xType
|
||||
})
|
||||
class WithSbusToCbusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => {
|
||||
case SbusToCbusXTypeKey => xType
|
||||
})
|
||||
class WithCbusToPbusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => {
|
||||
case CbusToPbusXTypeKey => xType
|
||||
})
|
||||
class WithFbusToSbusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => {
|
||||
case FbusToSbusXTypeKey => xType
|
||||
})
|
||||
|
||||
/**
|
||||
* Mixins to set the dtsFrequency field of BusParams -- these will percolate its way
|
||||
* up the diplomatic graph to the clock sources.
|
||||
*/
|
||||
class WithPeripheryBusFrequency(freqMHz: Double) extends Config((site, here, up) => {
|
||||
case PeripheryBusKey => up(PeripheryBusKey).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
|
||||
})
|
||||
class WithMemoryBusFrequency(freqMHz: Double) extends Config((site, here, up) => {
|
||||
case MemoryBusKey => up(MemoryBusKey).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
|
||||
})
|
||||
class WithSystemBusFrequency(freqMHz: Double) extends Config((site, here, up) => {
|
||||
case SystemBusKey => up(SystemBusKey).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
|
||||
})
|
||||
class WithControlBusFrequency(freqMHz: Double) extends Config((site, here, up) => {
|
||||
case ControlBusKey => up(ControlBusKey).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
|
||||
})
|
||||
|
||||
class WithRationalMemoryBusCrossing extends WithSbusToMbusCrossingType(RationalCrossing(Symmetric))
|
||||
class WithAsynchrousMemoryBusCrossing extends WithSbusToMbusCrossingType(AsynchronousCrossing())
|
||||
|
||||
62
generators/chipyard/src/main/scala/CustomBusTopologies.scala
Normal file
62
generators/chipyard/src/main/scala/CustomBusTopologies.scala
Normal file
@@ -0,0 +1,62 @@
|
||||
|
||||
package chipyard
|
||||
|
||||
import freechips.rocketchip.config.{Field, Config, Parameters}
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.util.{Location, Symmetric}
|
||||
import freechips.rocketchip.subsystem._
|
||||
|
||||
// I'm putting this code here temporarily as I think it should be a candidate
|
||||
// for upstreaming based on input from Henry Cook, but don't wnat to deal with
|
||||
// an RC branch just yet.
|
||||
|
||||
// For subsystem/BusTopology.scala
|
||||
|
||||
/**
|
||||
* Keys that serve as a means to define crossing types from a Parameters instance
|
||||
*/
|
||||
case object SbusToMbusXTypeKey extends Field[ClockCrossingType](NoCrossing)
|
||||
case object SbusToCbusXTypeKey extends Field[ClockCrossingType](NoCrossing)
|
||||
case object CbusToPbusXTypeKey extends Field[ClockCrossingType](SynchronousCrossing())
|
||||
case object FbusToSbusXTypeKey extends Field[ClockCrossingType](SynchronousCrossing())
|
||||
|
||||
// Biancolin: This, modified from Henry's email
|
||||
/** Parameterization of a topology containing a banked coherence manager and a bus for attaching memory devices. */
|
||||
case class CoherentMulticlockBusTopologyParams(
|
||||
sbus: SystemBusParams, // TODO remove this after better width propagation
|
||||
mbus: MemoryBusParams,
|
||||
l2: BankedL2Params,
|
||||
sbusToMbusXType: ClockCrossingType = NoCrossing
|
||||
) extends TLBusWrapperTopology(
|
||||
instantiations = (if (l2.nBanks == 0) Nil else List(
|
||||
(MBUS, mbus),
|
||||
(L2, CoherenceManagerWrapperParams(mbus.blockBytes, mbus.beatBytes, l2.nBanks, L2.name)(l2.coherenceManager)))),
|
||||
connections = if (l2.nBanks == 0) Nil else List(
|
||||
(SBUS, L2, TLBusWrapperConnection(xType = NoCrossing, driveClockFromMaster = Some(true), nodeBinding = BIND_STAR)()),
|
||||
(L2, MBUS, TLBusWrapperConnection.crossTo(
|
||||
xType = sbusToMbusXType,
|
||||
driveClockFromMaster = Some(true),
|
||||
nodeBinding = BIND_QUERY))
|
||||
)
|
||||
)
|
||||
|
||||
// For subsystem/Configs.scala
|
||||
|
||||
class WithMulticlockCoherentBusTopology extends Config((site, here, up) => {
|
||||
case TLNetworkTopologyLocated(InSubsystem) => List(
|
||||
JustOneBusTopologyParams(sbus = site(SystemBusKey)),
|
||||
HierarchicalBusTopologyParams(
|
||||
pbus = site(PeripheryBusKey),
|
||||
fbus = site(FrontBusKey),
|
||||
cbus = site(ControlBusKey),
|
||||
xTypes = SubsystemCrossingParams(
|
||||
sbusToCbusXType = site(SbusToCbusXTypeKey),
|
||||
cbusToPbusXType = site(CbusToPbusXTypeKey),
|
||||
fbusToSbusXType = site(FbusToSbusXTypeKey))),
|
||||
CoherentMulticlockBusTopologyParams(
|
||||
sbus = site(SystemBusKey),
|
||||
mbus = site(MemoryBusKey),
|
||||
l2 = site(BankedL2Key),
|
||||
sbusToMbusXType = site(SbusToMbusXTypeKey)))
|
||||
})
|
||||
@@ -1,7 +1,7 @@
|
||||
package chipyard.harness
|
||||
|
||||
import chisel3._
|
||||
import chisel3.experimental.{Analog}
|
||||
import chisel3.experimental.{Analog, BaseModule}
|
||||
|
||||
import freechips.rocketchip.config.{Field, Config, Parameters}
|
||||
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImpLike}
|
||||
@@ -31,42 +31,43 @@ case object HarnessBinders extends Field[Map[String, (Any, HasHarnessSignalRefer
|
||||
Map[String, (Any, HasHarnessSignalReferences, Seq[Data]) => Seq[Any]]().withDefaultValue((t: Any, th: HasHarnessSignalReferences, d: Seq[Data]) => Nil)
|
||||
)
|
||||
|
||||
|
||||
object ApplyHarnessBinders {
|
||||
def apply(th: HasHarnessSignalReferences, sys: LazyModule, map: Map[String, (Any, HasHarnessSignalReferences, Seq[Data]) => Seq[Any]], portMap: Map[String, Seq[Data]]) = {
|
||||
def apply(th: HasHarnessSignalReferences, sys: LazyModule, portMap: Map[String, Seq[Data]])(implicit p: Parameters) = {
|
||||
val pm = portMap.withDefaultValue(Nil)
|
||||
map.map { case (s, f) => f(sys, th, pm(s)) ++ f(sys.module, th, pm(s)) }
|
||||
p(HarnessBinders).map { case (s, f) => f(sys, th, pm(s)) ++ f(sys.module, th, pm(s)) }
|
||||
}
|
||||
}
|
||||
|
||||
class OverrideHarnessBinder[T, S <: Data](fn: => (T, HasHarnessSignalReferences, Seq[S]) => Seq[Any])(implicit tag: ClassTag[T], ptag: ClassTag[S]) extends Config((site, here, up) => {
|
||||
case HarnessBinders => up(HarnessBinders, site) + (tag.runtimeClass.toString ->
|
||||
// The ClassTags here are necessary to overcome issues arising from type erasure
|
||||
class HarnessBinder[T, S <: HasHarnessSignalReferences, U <: Data](composer: ((T, S, Seq[U]) => Seq[Any]) => (T, S, Seq[U]) => Seq[Any])(implicit systemTag: ClassTag[T], harnessTag: ClassTag[S], portTag: ClassTag[U]) extends Config((site, here, up) => {
|
||||
case HarnessBinders => up(HarnessBinders, site) + (systemTag.runtimeClass.toString ->
|
||||
((t: Any, th: HasHarnessSignalReferences, ports: Seq[Data]) => {
|
||||
val pts = ports.collect({case p: S => p})
|
||||
require (pts.length == ports.length, s"Port type mismatch between IOBinder and HarnessBinder: ${ptag}")
|
||||
t match {
|
||||
case system: T => fn(system, th, pts)
|
||||
val pts = ports.collect({case p: U => p})
|
||||
require (pts.length == ports.length, s"Port type mismatch between IOBinder and HarnessBinder: ${portTag}")
|
||||
val upfn = up(HarnessBinders, site)(systemTag.runtimeClass.toString)
|
||||
th match {
|
||||
case th: S =>
|
||||
t match {
|
||||
case system: T => composer(upfn)(system, th, pts)
|
||||
case _ => Nil
|
||||
}
|
||||
case _ => Nil
|
||||
}
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
class ComposeHarnessBinder[T, S <: Data](fn: => (T, HasHarnessSignalReferences, Seq[S]) => Seq[Any])(implicit tag: ClassTag[T], ptag: ClassTag[S]) extends Config((site, here, up) => {
|
||||
case HarnessBinders => up(HarnessBinders, site) + (tag.runtimeClass.toString ->
|
||||
((t: Any, th: HasHarnessSignalReferences, ports: Seq[Data]) => {
|
||||
val pts = ports.collect({case p: S => p})
|
||||
require (pts.length == ports.length, s"Port type mismatch between IOBinder and HarnessBinder: ${ptag}")
|
||||
t match {
|
||||
case system: T => up(HarnessBinders, site)(tag.runtimeClass.toString)(system, th, pts) ++ fn(system, th, pts)
|
||||
case _ => Nil
|
||||
}
|
||||
})
|
||||
)
|
||||
})
|
||||
class OverrideHarnessBinder[T, S <: HasHarnessSignalReferences, U <: Data](fn: => (T, S, Seq[U]) => Seq[Any])
|
||||
(implicit tag: ClassTag[T], thtag: ClassTag[S], ptag: ClassTag[U])
|
||||
extends HarnessBinder[T, S, U]((upfn: (T, S, Seq[U]) => Seq[Any]) => fn)
|
||||
|
||||
class ComposeHarnessBinder[T, S <: HasHarnessSignalReferences, U <: Data](fn: => (T, S, Seq[U]) => Seq[Any])
|
||||
(implicit tag: ClassTag[T], thtag: ClassTag[S], ptag: ClassTag[U])
|
||||
extends HarnessBinder[T, S, U]((upfn: (T, S, Seq[U]) => Seq[Any]) => (t, th, p) => upfn(t, th, p) ++ fn(t, th, p))
|
||||
|
||||
|
||||
class WithGPIOTiedOff extends OverrideHarnessBinder({
|
||||
(system: HasPeripheryGPIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[Analog]) => {
|
||||
(system: HasPeripheryGPIOModuleImp, th: BaseModule with HasHarnessSignalReferences, ports: Seq[Analog]) => {
|
||||
ports.foreach { _ <> AnalogConst(0) }
|
||||
Nil
|
||||
}
|
||||
@@ -74,7 +75,7 @@ class WithGPIOTiedOff extends OverrideHarnessBinder({
|
||||
|
||||
// DOC include start: WithUARTAdapter
|
||||
class WithUARTAdapter extends OverrideHarnessBinder({
|
||||
(system: HasPeripheryUARTModuleImp, th: HasHarnessSignalReferences, ports: Seq[UARTPortIO]) => {
|
||||
(system: HasPeripheryUARTModuleImp, th: BaseModule with HasHarnessSignalReferences, ports: Seq[UARTPortIO]) => {
|
||||
UARTAdapter.connect(ports)(system.p)
|
||||
Nil
|
||||
}
|
||||
@@ -82,14 +83,14 @@ class WithUARTAdapter extends OverrideHarnessBinder({
|
||||
// DOC include end: WithUARTAdapter
|
||||
|
||||
class WithSimSPIFlashModel(rdOnly: Boolean = true) extends OverrideHarnessBinder({
|
||||
(system: HasPeripherySPIFlashModuleImp, th: HasHarnessSignalReferences, ports: Seq[SPIChipIO]) => {
|
||||
(system: HasPeripherySPIFlashModuleImp, th: BaseModule with HasHarnessSignalReferences, ports: Seq[SPIChipIO]) => {
|
||||
SimSPIFlashModel.connect(ports, th.harnessReset, rdOnly)(system.p)
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithSimBlockDevice extends OverrideHarnessBinder({
|
||||
(system: CanHavePeripheryBlockDevice, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => {
|
||||
(system: CanHavePeripheryBlockDevice, th: BaseModule with HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => {
|
||||
implicit val p: Parameters = GetSystemParameters(system)
|
||||
ports.map { b => SimBlockDevice.connect(b.clock, th.harnessReset.asBool, Some(b.bits)) }
|
||||
Nil
|
||||
@@ -97,7 +98,7 @@ class WithSimBlockDevice extends OverrideHarnessBinder({
|
||||
})
|
||||
|
||||
class WithBlockDeviceModel extends OverrideHarnessBinder({
|
||||
(system: CanHavePeripheryBlockDevice, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => {
|
||||
(system: CanHavePeripheryBlockDevice, th: BaseModule with HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => {
|
||||
implicit val p: Parameters = GetSystemParameters(system)
|
||||
ports.map { b => withClockAndReset(b.clock, th.harnessReset) { BlockDeviceModel.connect(Some(b.bits)) } }
|
||||
Nil
|
||||
@@ -105,7 +106,7 @@ class WithBlockDeviceModel extends OverrideHarnessBinder({
|
||||
})
|
||||
|
||||
class WithLoopbackNIC extends OverrideHarnessBinder({
|
||||
(system: CanHavePeripheryIceNIC, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => {
|
||||
(system: CanHavePeripheryIceNIC, th: BaseModule with HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => {
|
||||
implicit val p: Parameters = GetSystemParameters(system)
|
||||
ports.map { n =>
|
||||
withClockAndReset(n.clock, th.harnessReset) {
|
||||
@@ -117,7 +118,7 @@ class WithLoopbackNIC extends OverrideHarnessBinder({
|
||||
})
|
||||
|
||||
class WithSimNetwork extends OverrideHarnessBinder({
|
||||
(system: CanHavePeripheryIceNIC, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => {
|
||||
(system: CanHavePeripheryIceNIC, th: BaseModule with HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => {
|
||||
implicit val p: Parameters = GetSystemParameters(system)
|
||||
ports.map { n => SimNetwork.connect(Some(n.bits), n.clock, th.harnessReset.asBool) }
|
||||
Nil
|
||||
@@ -125,11 +126,11 @@ class WithSimNetwork extends OverrideHarnessBinder({
|
||||
})
|
||||
|
||||
class WithSimAXIMem extends OverrideHarnessBinder({
|
||||
(system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => {
|
||||
(system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedAndResetIO[AXI4Bundle]]) => {
|
||||
val p: Parameters = chipyard.iobinders.GetSystemParameters(system)
|
||||
(ports zip system.memAXI4Node.edges.in).map { case (port, edge) =>
|
||||
val mem = LazyModule(new SimAXIMem(edge, size=p(ExtMem).get.master.size)(p))
|
||||
withClockAndReset(port.clock, th.harnessReset) {
|
||||
withClockAndReset(port.clock, port.reset) {
|
||||
Module(mem.module).suggestName("mem")
|
||||
}
|
||||
mem.io_axi4.head <> port.bits
|
||||
@@ -139,7 +140,7 @@ class WithSimAXIMem extends OverrideHarnessBinder({
|
||||
})
|
||||
|
||||
class WithBlackBoxSimMem extends OverrideHarnessBinder({
|
||||
(system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => {
|
||||
(system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedAndResetIO[AXI4Bundle]]) => {
|
||||
val p: Parameters = chipyard.iobinders.GetSystemParameters(system)
|
||||
(ports zip system.memAXI4Node.edges.in).map { case (port, edge) =>
|
||||
val memSize = p(ExtMem).get.master.size
|
||||
@@ -147,18 +148,18 @@ class WithBlackBoxSimMem extends OverrideHarnessBinder({
|
||||
val mem = Module(new SimDRAM(memSize, lineSize, edge.bundle)).suggestName("simdram")
|
||||
mem.io.axi <> port.bits
|
||||
mem.io.clock := port.clock
|
||||
mem.io.reset := th.harnessReset
|
||||
mem.io.reset := port.reset
|
||||
}
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithSimAXIMMIO extends OverrideHarnessBinder({
|
||||
(system: CanHaveMasterAXI4MMIOPort, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => {
|
||||
(system: CanHaveMasterAXI4MMIOPort, th: HasHarnessSignalReferences, ports: Seq[ClockedAndResetIO[AXI4Bundle]]) => {
|
||||
val p: Parameters = chipyard.iobinders.GetSystemParameters(system)
|
||||
(ports zip system.mmioAXI4Node.edges.in).map { case (port, edge) =>
|
||||
val mmio_mem = LazyModule(new SimAXIMem(edge, size = p(ExtBus).get.size)(p))
|
||||
withClockAndReset(port.clock, th.harnessReset) {
|
||||
withClockAndReset(port.clock, port.reset) {
|
||||
Module(mmio_mem.module).suggestName("mmio_mem")
|
||||
}
|
||||
mmio_mem.io_axi4.head <> port.bits
|
||||
@@ -168,26 +169,27 @@ class WithSimAXIMMIO extends OverrideHarnessBinder({
|
||||
})
|
||||
|
||||
class WithTieOffInterrupts extends OverrideHarnessBinder({
|
||||
(system: HasExtInterruptsModuleImp, th: HasHarnessSignalReferences, ports: Seq[UInt]) => {
|
||||
(system: HasExtInterruptsModuleImp, th: BaseModule with HasHarnessSignalReferences, ports: Seq[UInt]) => {
|
||||
ports.foreach { _ := 0.U }
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithTieOffL2FBusAXI extends OverrideHarnessBinder({
|
||||
(system: CanHaveSlaveAXI4Port, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => {
|
||||
(system: CanHaveSlaveAXI4Port, th: BaseModule with HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => {
|
||||
ports.foreach({ p => p := DontCare; p.bits.tieoff() })
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithSimDebug extends OverrideHarnessBinder({
|
||||
(system: HasPeripheryDebugModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => {
|
||||
(system: HasPeripheryDebug, th: BaseModule with HasHarnessSignalReferences, ports: Seq[Data]) => {
|
||||
implicit val p: Parameters = GetSystemParameters(system)
|
||||
ports.map {
|
||||
case d: ClockedDMIIO =>
|
||||
val dtm_success = WireInit(false.B)
|
||||
when (dtm_success) { th.success := true.B }
|
||||
val dtm = Module(new SimDTM()(system.p)).connect(th.harnessClock, th.harnessReset.asBool, d, dtm_success)
|
||||
val dtm = Module(new SimDTM).connect(th.harnessClock, th.harnessReset.asBool, d, dtm_success)
|
||||
case j: JTAGIO =>
|
||||
val dtm_success = WireInit(false.B)
|
||||
when (dtm_success) { th.success := true.B }
|
||||
@@ -198,7 +200,7 @@ class WithSimDebug extends OverrideHarnessBinder({
|
||||
})
|
||||
|
||||
class WithTiedOffDebug extends OverrideHarnessBinder({
|
||||
(system: HasPeripheryDebugModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => {
|
||||
(system: HasPeripheryDebug, th: BaseModule with HasHarnessSignalReferences, ports: Seq[Data]) => {
|
||||
ports.map {
|
||||
case j: JTAGIO =>
|
||||
j.TCK := true.B.asClock
|
||||
@@ -224,7 +226,7 @@ class WithTiedOffDebug extends OverrideHarnessBinder({
|
||||
|
||||
|
||||
class WithSerialAdapterTiedOff extends OverrideHarnessBinder({
|
||||
(system: CanHavePeripheryTLSerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => {
|
||||
(system: CanHavePeripheryTLSerial, th: BaseModule with HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => {
|
||||
implicit val p = chipyard.iobinders.GetSystemParameters(system)
|
||||
ports.map({ port =>
|
||||
val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, port, th.harnessReset)
|
||||
@@ -234,7 +236,7 @@ class WithSerialAdapterTiedOff extends OverrideHarnessBinder({
|
||||
})
|
||||
|
||||
class WithSimSerial extends OverrideHarnessBinder({
|
||||
(system: CanHavePeripheryTLSerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => {
|
||||
(system: CanHavePeripheryTLSerial, th: BaseModule with HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => {
|
||||
implicit val p = chipyard.iobinders.GetSystemParameters(system)
|
||||
ports.map({ port =>
|
||||
val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, port, th.harnessReset)
|
||||
@@ -245,14 +247,14 @@ class WithSimSerial extends OverrideHarnessBinder({
|
||||
})
|
||||
|
||||
class WithTraceGenSuccess extends OverrideHarnessBinder({
|
||||
(system: TraceGenSystemModuleImp, th: HasHarnessSignalReferences, ports: Seq[Bool]) => {
|
||||
(system: TraceGenSystemModuleImp, th: BaseModule with HasHarnessSignalReferences, ports: Seq[Bool]) => {
|
||||
ports.map { p => when (p) { th.success := true.B } }
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithSimDromajoBridge extends ComposeHarnessBinder({
|
||||
(system: CanHaveTraceIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[TraceOutputTop]) => {
|
||||
(system: CanHaveTraceIOModuleImp, th: BaseModule with HasHarnessSignalReferences, ports: Seq[TraceOutputTop]) => {
|
||||
ports.map { p => p.traces.map(tileTrace => SimDromajoBridge(tileTrace)(system.p)) }
|
||||
Nil
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
package chipyard.iobinders
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util.experimental.{BoringUtils}
|
||||
import chisel3.experimental.{Analog, IO, DataMirror}
|
||||
|
||||
import freechips.rocketchip.config._
|
||||
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImpLike}
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.devices.debug._
|
||||
import freechips.rocketchip.jtag.{JTAGIO}
|
||||
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.groundtest.{GroundTestSubsystemModuleImp, GroundTestSubsystem}
|
||||
|
||||
import sifive.blocks.devices.gpio._
|
||||
@@ -28,6 +28,12 @@ import chipyard.GlobalResetSchemeKey
|
||||
|
||||
import scala.reflect.{ClassTag}
|
||||
|
||||
object IOBinderTypes {
|
||||
type IOBinderTuple = (Seq[Data], Seq[IOCell])
|
||||
type IOBinderFunction = (Boolean, => Any) => ModuleValue[IOBinderTuple]
|
||||
}
|
||||
import IOBinderTypes._
|
||||
|
||||
// System for instantiating binders based
|
||||
// on the scala type of the Target (_not_ its IO). This avoids needing to
|
||||
// duplicate harnesses (essentially test harnesses) for each target.
|
||||
@@ -40,21 +46,30 @@ import scala.reflect.{ClassTag}
|
||||
|
||||
// You can add your own binder by adding a new (key, fn) pair, typically by using
|
||||
// the OverrideIOBinder or ComposeIOBinder macros
|
||||
case object IOBinders extends Field[Map[String, (Any) => (Seq[Data], Seq[IOCell])]](
|
||||
Map[String, (Any) => (Seq[Data], Seq[IOCell])]().withDefaultValue((Any) => (Nil, Nil))
|
||||
case object IOBinders extends Field[Map[String, Seq[IOBinderFunction]]](
|
||||
Map[String, Seq[IOBinderFunction]]().withDefaultValue(Nil)
|
||||
)
|
||||
object ApplyIOBinders {
|
||||
def apply(sys: LazyModule, map: Map[String, (Any) => (Seq[Data], Seq[IOCell])]):
|
||||
(Iterable[Data], Iterable[IOCell], Map[String, Seq[Data]]) = {
|
||||
val lzy = map.map({ case (s,f) => s -> f(sys) })
|
||||
val imp = map.map({ case (s,f) => s -> f(sys.module) })
|
||||
val unzipped = (lzy.values ++ imp.values).unzip
|
||||
|
||||
val ports: Iterable[Data] = unzipped._1.flatten
|
||||
val cells: Iterable[IOCell] = unzipped._2.flatten
|
||||
val portMap: Map[String, Seq[Data]] = map.keys.map(k => k -> (lzy(k)._1 ++ imp(k)._1)).toMap
|
||||
(ports, cells, portMap)
|
||||
}
|
||||
abstract trait HasIOBinders { this: LazyModule =>
|
||||
val lazySystem: LazyModule
|
||||
private val iobinders = p(IOBinders)
|
||||
// Note: IOBinders cannot rely on the implicit clock/reset, as they may be called from the
|
||||
// context of a LazyRawModuleImp
|
||||
private val lzy = iobinders.map({ case (s,fns) => s -> fns.map(f => f(true, lazySystem)) })
|
||||
private val imp = iobinders.map({ case (s,fns) => s -> fns.map(f => f(false, lazySystem.module)) })
|
||||
|
||||
private lazy val lzyFlattened: Map[String, IOBinderTuple] = lzy.map({
|
||||
case (s,ms) => s -> (ms.map(_._1).flatten, ms.map(_._2).flatten)
|
||||
})
|
||||
private lazy val impFlattened: Map[String, IOBinderTuple] = imp.map({
|
||||
case (s,ms) => s -> (ms.map(_._1).flatten, ms.map(_._2).flatten)
|
||||
})
|
||||
|
||||
// A publicly accessible list of IO cells (useful for a floorplanning tool, for example)
|
||||
lazy val iocells = (lzyFlattened.values ++ impFlattened.values).unzip._2.flatten.toBuffer
|
||||
|
||||
// A mapping between stringified DigitalSystem traits and their corresponding ChipTop ports
|
||||
lazy val portMap = iobinders.keys.map(k => k -> (lzyFlattened(k)._1 ++ impFlattened(k)._1)).toMap
|
||||
}
|
||||
|
||||
// Note: The parameters instance is accessible only through LazyModule
|
||||
@@ -72,52 +87,45 @@ object GetSystemParameters {
|
||||
}
|
||||
}
|
||||
|
||||
class IOBinder(f: (View, View, View) => PartialFunction[Any, Any]) extends Config(f)
|
||||
|
||||
// This macro overrides previous matches on some Top mixin. This is useful for
|
||||
// binders which drive IO, since those typically cannot be composed
|
||||
class OverrideIOBinder[T, S <: Data](fn: => (T) => (Seq[S], Seq[IOCell]))(implicit tag: ClassTag[T]) extends IOBinder((site, here, up) => {
|
||||
case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString ->
|
||||
((t: Any) => {
|
||||
t match {
|
||||
case system: T =>
|
||||
val (ports, cells) = fn(system)
|
||||
(ports, cells)
|
||||
case _ => (Nil, Nil)
|
||||
}
|
||||
})
|
||||
)
|
||||
class IOBinder[T](composer: Seq[IOBinderFunction] => Seq[IOBinderFunction])(implicit tag: ClassTag[T]) extends Config((site, here, up) => {
|
||||
case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString -> composer(up(IOBinders, site)(tag.runtimeClass.toString)))
|
||||
})
|
||||
|
||||
// This macro composes with previous matches on some Top mixin. This is useful for
|
||||
// annotation-like binders, since those can typically be composed
|
||||
class ComposeIOBinder[T, S <: Data](fn: => (T) => (Seq[S], Seq[IOCell]))(implicit tag: ClassTag[T]) extends IOBinder((site, here, up) => {
|
||||
case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString ->
|
||||
((t: Any) => {
|
||||
t match {
|
||||
case system: T =>
|
||||
val r = up(IOBinders, site)(tag.runtimeClass.toString)(system)
|
||||
val h = fn(system)
|
||||
val ports = r._1 ++ h._1
|
||||
val cells = r._2 ++ h._2
|
||||
(ports, cells)
|
||||
case _ => (Nil, Nil)
|
||||
}
|
||||
})
|
||||
)
|
||||
})
|
||||
class ConcreteIOBinder[T](composes: Boolean, fn: T => IOBinderTuple)(implicit tag: ClassTag[T]) extends IOBinder[T](
|
||||
up => (if (composes) up else Nil) ++ Seq(((_, t) => { InModuleBody {
|
||||
t match {
|
||||
case system: T => fn(system)
|
||||
case _ => (Nil, Nil)
|
||||
}
|
||||
}}): IOBinderFunction)
|
||||
)
|
||||
|
||||
object BoreHelper {
|
||||
def apply(name: String, source: Clock): Clock = {
|
||||
val clock_io = IO(Output(Clock())).suggestName(name)
|
||||
val clock_wire = Wire(Clock()).suggestName(s"chiptop_${name}")
|
||||
dontTouch(clock_wire)
|
||||
clock_wire := false.B.asClock // necessary for BoringUtils to work properly
|
||||
BoringUtils.bore(source, Seq(clock_wire))
|
||||
clock_io := clock_wire
|
||||
clock_io
|
||||
}
|
||||
}
|
||||
class LazyIOBinder[T](composes: Boolean, fn: T => ModuleValue[IOBinderTuple])(implicit tag: ClassTag[T]) extends IOBinder[T](
|
||||
up => (if (composes) up else Nil) ++ Seq(((isLazy, t) => {
|
||||
val empty = new ModuleValue[IOBinderTuple] {
|
||||
def getWrappedValue: IOBinderTuple = (Nil, Nil)
|
||||
}
|
||||
if (isLazy) {
|
||||
t match {
|
||||
case system: T => fn(system)
|
||||
case _ => empty
|
||||
}
|
||||
} else {
|
||||
empty
|
||||
}
|
||||
}): IOBinderFunction)
|
||||
)
|
||||
|
||||
// The "Override" binders override any previous IOBinders (lazy or concrete) defined on the same trait.
|
||||
// The "Compose" binders do not override previously defined IOBinders on the same trait
|
||||
// The default IOBinders evaluate only in the concrete "ModuleImp" phase of elaboration
|
||||
// The "Lazy" IOBinders evaluate in the LazyModule phase, but can also generate hardware through InModuleBody
|
||||
|
||||
class OverrideIOBinder[T](fn: T => IOBinderTuple)(implicit tag: ClassTag[T]) extends ConcreteIOBinder[T](false, fn)
|
||||
class ComposeIOBinder[T](fn: T => IOBinderTuple)(implicit tag: ClassTag[T]) extends ConcreteIOBinder[T](true, fn)
|
||||
|
||||
class OverrideLazyIOBinder[T](fn: T => ModuleValue[IOBinderTuple])(implicit tag: ClassTag[T]) extends LazyIOBinder[T](false, fn)
|
||||
class ComposeLazyIOBinder[T](fn: T => ModuleValue[IOBinderTuple])(implicit tag: ClassTag[T]) extends LazyIOBinder[T](true, fn)
|
||||
|
||||
|
||||
case object IOCellKey extends Field[IOCellTypeParams](GenericIOCellParams())
|
||||
@@ -194,55 +202,55 @@ class WithExtInterruptIOCells extends OverrideIOBinder({
|
||||
})
|
||||
|
||||
|
||||
class WithDebugIOCells extends OverrideIOBinder({
|
||||
(system: HasPeripheryDebugModuleImp) => {
|
||||
system.debug.map({ debug =>
|
||||
val p = system.p
|
||||
val tlbus = system.outer.asInstanceOf[BaseSubsystem].locateTLBusWrapper(p(ExportDebug).slaveWhere)
|
||||
val debug_clock = Wire(Clock()).suggestName("debug_clock")
|
||||
val debug_reset = Wire(Reset()).suggestName("debug_reset")
|
||||
debug_clock := false.B.asClock // must provide default assignment to avoid firrtl unassigned error
|
||||
debug_reset := false.B // must provide default assignment to avoid firrtl unassigned error
|
||||
BoringUtils.bore(tlbus.module.clock, Seq(debug_clock))
|
||||
BoringUtils.bore(tlbus.module.reset, Seq(debug_reset))
|
||||
class WithDebugIOCells extends OverrideLazyIOBinder({
|
||||
(system: HasPeripheryDebug) => {
|
||||
implicit val p = GetSystemParameters(system)
|
||||
val tlbus = system.asInstanceOf[BaseSubsystem].locateTLBusWrapper(p(ExportDebug).slaveWhere)
|
||||
val clockSinkNode = system.debugOpt.map(_ => ClockSinkNode(Seq(ClockSinkParameters())))
|
||||
clockSinkNode.map(_ := tlbus.fixedClockNode)
|
||||
def clockBundle = clockSinkNode.get.in.head._1
|
||||
|
||||
// We never use the PSDIO, so tie it off on-chip
|
||||
system.psd.psd.foreach { _ <> 0.U.asTypeOf(new PSDTestMode) }
|
||||
system.resetctrl.map { rcio => rcio.hartIsInReset.map { _ := debug_reset.asBool } }
|
||||
system.debug.map { d =>
|
||||
// Tie off extTrigger
|
||||
d.extTrigger.foreach { t =>
|
||||
t.in.req := false.B
|
||||
t.out.ack := t.out.req
|
||||
|
||||
InModuleBody { system.asInstanceOf[BaseSubsystem].module match { case system: HasPeripheryDebugModuleImp => {
|
||||
system.debug.map({ debug =>
|
||||
// We never use the PSDIO, so tie it off on-chip
|
||||
system.psd.psd.foreach { _ <> 0.U.asTypeOf(new PSDTestMode) }
|
||||
system.resetctrl.map { rcio => rcio.hartIsInReset.map { _ := clockBundle.reset.asBool } }
|
||||
system.debug.map { d =>
|
||||
// Tie off extTrigger
|
||||
d.extTrigger.foreach { t =>
|
||||
t.in.req := false.B
|
||||
t.out.ack := t.out.req
|
||||
}
|
||||
// Tie off disableDebug
|
||||
d.disableDebug.foreach { d => d := false.B }
|
||||
// Drive JTAG on-chip IOs
|
||||
d.systemjtag.map { j =>
|
||||
j.reset := clockBundle.reset
|
||||
j.mfr_id := p(JtagDTMKey).idcodeManufId.U(11.W)
|
||||
j.part_number := p(JtagDTMKey).idcodePartNum.U(16.W)
|
||||
j.version := p(JtagDTMKey).idcodeVersion.U(4.W)
|
||||
}
|
||||
}
|
||||
// Tie off disableDebug
|
||||
d.disableDebug.foreach { d => d := false.B }
|
||||
// Drive JTAG on-chip IOs
|
||||
d.systemjtag.map { j =>
|
||||
j.reset := debug_reset
|
||||
j.mfr_id := system.p(JtagDTMKey).idcodeManufId.U(11.W)
|
||||
j.part_number := system.p(JtagDTMKey).idcodePartNum.U(16.W)
|
||||
j.version := system.p(JtagDTMKey).idcodeVersion.U(4.W)
|
||||
Debug.connectDebugClockAndReset(Some(debug), clockBundle.clock)
|
||||
|
||||
// Add IOCells for the DMI/JTAG/APB ports
|
||||
val dmiTuple = debug.clockeddmi.map { d =>
|
||||
IOCell.generateIOFromSignal(d, "dmi", p(IOCellKey), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync)
|
||||
}
|
||||
}
|
||||
Debug.connectDebugClockAndReset(Some(debug), debug_clock)(system.p)
|
||||
|
||||
// Add IOCells for the DMI/JTAG/APB ports
|
||||
val dmiTuple = debug.clockeddmi.map { d =>
|
||||
IOCell.generateIOFromSignal(d, "dmi", p(IOCellKey), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync)
|
||||
}
|
||||
val jtagTuple = debug.systemjtag.map { j =>
|
||||
IOCell.generateIOFromSignal(j.jtag, "jtag", p(IOCellKey), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync)
|
||||
}
|
||||
|
||||
val jtagTuple = debug.systemjtag.map { j =>
|
||||
IOCell.generateIOFromSignal(j.jtag, "jtag", p(IOCellKey), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync)
|
||||
}
|
||||
val apbTuple = debug.apb.map { a =>
|
||||
IOCell.generateIOFromSignal(a, "apb", p(IOCellKey), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync)
|
||||
}
|
||||
|
||||
val apbTuple = debug.apb.map { a =>
|
||||
IOCell.generateIOFromSignal(a, "apb", p(IOCellKey), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync)
|
||||
}
|
||||
|
||||
val allTuples = (dmiTuple ++ jtagTuple ++ apbTuple).toSeq
|
||||
(allTuples.map(_._1).toSeq, allTuples.flatMap(_._2).toSeq)
|
||||
}).getOrElse((Nil, Nil))
|
||||
val allTuples = (dmiTuple ++ jtagTuple ++ apbTuple).toSeq
|
||||
(allTuples.map(_._1).toSeq, allTuples.flatMap(_._2).toSeq)
|
||||
}).getOrElse((Nil, Nil))
|
||||
}}}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -255,39 +263,62 @@ class WithSerialTLIOCells extends OverrideIOBinder({
|
||||
})
|
||||
|
||||
|
||||
class WithAXI4MemPunchthrough extends OverrideIOBinder({
|
||||
class WithAXI4MemPunchthrough extends OverrideLazyIOBinder({
|
||||
(system: CanHaveMasterAXI4MemPort) => {
|
||||
val ports: Seq[ClockedIO[AXI4Bundle]] = system.mem_axi4.zipWithIndex.map({ case (m, i) =>
|
||||
val p = IO(new ClockedIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mem_${i}")
|
||||
p.bits <> m
|
||||
p.clock := BoreHelper("axi4_mem_clock", system.asInstanceOf[BaseSubsystem].mbus.module.clock)
|
||||
p
|
||||
})
|
||||
(ports, Nil)
|
||||
implicit val p: Parameters = GetSystemParameters(system)
|
||||
val clockSinkNode = p(ExtMem).map(_ => ClockSinkNode(Seq(ClockSinkParameters())))
|
||||
clockSinkNode.map(_ := system.asInstanceOf[HasTileLinkLocations].locateTLBusWrapper(MBUS).fixedClockNode)
|
||||
def clockBundle = clockSinkNode.get.in.head._1
|
||||
|
||||
InModuleBody {
|
||||
val ports: Seq[ClockedAndResetIO[AXI4Bundle]] = system.mem_axi4.zipWithIndex.map({ case (m, i) =>
|
||||
val p = IO(new ClockedAndResetIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mem_${i}")
|
||||
p.bits <> m
|
||||
p.clock := clockBundle.clock
|
||||
p.reset := clockBundle.reset
|
||||
p
|
||||
})
|
||||
(ports, Nil)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
class WithAXI4MMIOPunchthrough extends OverrideIOBinder({
|
||||
class WithAXI4MMIOPunchthrough extends OverrideLazyIOBinder({
|
||||
(system: CanHaveMasterAXI4MMIOPort) => {
|
||||
val ports: Seq[ClockedIO[AXI4Bundle]] = system.mmio_axi4.zipWithIndex.map({ case (m, i) =>
|
||||
val p = IO(new ClockedIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mmio_${i}")
|
||||
p.bits <> m
|
||||
p.clock := BoreHelper("axi4_mmio_clock", system.asInstanceOf[BaseSubsystem].mbus.module.clock)
|
||||
p
|
||||
})
|
||||
(ports, Nil)
|
||||
implicit val p: Parameters = GetSystemParameters(system)
|
||||
val clockSinkNode = p(ExtBus).map(_ => ClockSinkNode(Seq(ClockSinkParameters())))
|
||||
clockSinkNode.map(_ := system.asInstanceOf[HasTileLinkLocations].locateTLBusWrapper(MBUS).fixedClockNode)
|
||||
def clockBundle = clockSinkNode.get.in.head._1
|
||||
|
||||
InModuleBody {
|
||||
val ports: Seq[ClockedAndResetIO[AXI4Bundle]] = system.mmio_axi4.zipWithIndex.map({ case (m, i) =>
|
||||
val p = IO(new ClockedAndResetIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mmio_${i}")
|
||||
p.bits <> m
|
||||
p.clock := clockBundle.clock
|
||||
p.reset := clockBundle.reset
|
||||
p
|
||||
})
|
||||
(ports, Nil)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
class WithL2FBusAXI4Punchthrough extends OverrideIOBinder({
|
||||
(system: CanHaveSlaveAXI4Port) => {
|
||||
val ports: Seq[ClockedIO[AXI4Bundle]] = system.l2_frontend_bus_axi4.zipWithIndex.map({ case (m, i) =>
|
||||
val p = IO(new ClockedIO(Flipped(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)))).suggestName(s"axi4_fbus_${i}")
|
||||
m <> p.bits
|
||||
p.clock := BoreHelper("axi4_fbus_clock", system.asInstanceOf[BaseSubsystem].fbus.module.clock)
|
||||
p
|
||||
})
|
||||
(ports, Nil)
|
||||
class WithL2FBusAXI4Punchthrough extends OverrideLazyIOBinder({
|
||||
(system: CanHaveSlaveAXI4Port) => {
|
||||
implicit val p: Parameters = GetSystemParameters(system)
|
||||
val clockSinkNode = p(ExtIn).map(_ => ClockSinkNode(Seq(ClockSinkParameters())))
|
||||
clockSinkNode.map(_ := system.asInstanceOf[BaseSubsystem].fbus.fixedClockNode)
|
||||
def clockBundle = clockSinkNode.get.in.head._1
|
||||
|
||||
InModuleBody {
|
||||
val ports: Seq[ClockedIO[AXI4Bundle]] = system.l2_frontend_bus_axi4.zipWithIndex.map({ case (m, i) =>
|
||||
val p = IO(new ClockedIO(Flipped(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)))).suggestName(s"axi4_fbus_${i}")
|
||||
m <> p.bits
|
||||
p.clock := clockBundle.clock
|
||||
p
|
||||
})
|
||||
(ports, Nil)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import freechips.rocketchip.diplomacy.{LazyModule}
|
||||
import freechips.rocketchip.config.{Field, Parameters}
|
||||
|
||||
import chipyard.harness.{ApplyHarnessBinders, HarnessBinders}
|
||||
import chipyard.iobinders.HasIOBinders
|
||||
|
||||
// -------------------------------
|
||||
// Chipyard Test Harness
|
||||
@@ -14,9 +15,7 @@ import chipyard.harness.{ApplyHarnessBinders, HarnessBinders}
|
||||
case object BuildTop extends Field[Parameters => LazyModule]((p: Parameters) => new ChipTop()(p))
|
||||
|
||||
trait HasTestHarnessFunctions {
|
||||
val lazySystem: LazyModule
|
||||
val harnessFunctions = ArrayBuffer.empty[HasHarnessSignalReferences => Seq[Any]]
|
||||
val portMap = scala.collection.mutable.Map[String, Seq[Data]]()
|
||||
}
|
||||
|
||||
trait HasHarnessSignalReferences {
|
||||
@@ -44,7 +43,9 @@ class TestHarness(implicit val p: Parameters) extends Module with HasHarnessSign
|
||||
|
||||
lazyDut match { case d: HasTestHarnessFunctions =>
|
||||
d.harnessFunctions.foreach(_(this))
|
||||
ApplyHarnessBinders(this, d.lazySystem, p(HarnessBinders), d.portMap.toMap)
|
||||
}
|
||||
lazyDut match { case d: HasIOBinders =>
|
||||
ApplyHarnessBinders(this, d.lazySystem, d.portMap)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,10 @@ case class DividerOnlyClockGeneratorNode(pllName: String)(implicit valName: ValN
|
||||
* fast reference clock (roughly LCM(requested frequencies)) which is passed up the
|
||||
* diplomatic graph, and then generates dividers for each unique requested
|
||||
* frequency.
|
||||
*
|
||||
* Output resets are not synchronized to generated clocks and should be
|
||||
* synchronized by the user in a manner they see fit.
|
||||
*
|
||||
*/
|
||||
|
||||
class DividerOnlyClockGenerator(pllName: String)(implicit p: Parameters, valName: ValName) extends LazyModule {
|
||||
@@ -87,6 +91,7 @@ class DividerOnlyClockGenerator(pllName: String)(implicit p: Parameters, valName
|
||||
for (((sinkBName, sinkB), sinkP) <- outClocks.member.elements.zip(outSinkParams.members)) {
|
||||
val div = pllConfig.sinkDividerMap(sinkP)
|
||||
sinkB.clock := dividedClocks.getOrElse(div, instantiateDivider(div))
|
||||
// Reset handling and synchronization is expected to be handled by a downstream node
|
||||
sinkB.reset := refClock.reset
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
|
||||
package chipyard.clocking
|
||||
|
||||
import chisel3._
|
||||
|
||||
import freechips.rocketchip.config.{Parameters}
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.prci._
|
||||
import freechips.rocketchip.util.{ResetCatchAndSync}
|
||||
|
||||
/**
|
||||
* Instantiates a reset synchronizer on all clock-reset pairs in a clock group
|
||||
*/
|
||||
class ClockGroupResetSynchronizer(implicit p: Parameters) extends LazyModule {
|
||||
val node = ClockGroupIdentityNode()
|
||||
lazy val module = new LazyRawModuleImp(this) {
|
||||
(node.out zip node.in).map { case ((oG, _), (iG, _)) =>
|
||||
(oG.member.data zip iG.member.data).foreach { case (o, i) =>
|
||||
o.clock := i.clock
|
||||
o.reset := ResetCatchAndSync(i.clock, i.reset.asBool)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object ClockGroupResetSynchronizer {
|
||||
def apply()(implicit p: Parameters, valName: ValName) = LazyModule(new ClockGroupResetSynchronizer()).node
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,6 @@ class AbstractConfig extends Config(
|
||||
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 freechips.rocketchip.subsystem.WithCoherentBusTopology ++ // hierarchical buses including mbus+l2
|
||||
new chipyard.WithMulticlockCoherentBusTopology ++ // hierarchical buses including mbus+l2
|
||||
new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system
|
||||
|
||||
|
||||
@@ -179,6 +179,9 @@ class DividedClockRocketConfig extends Config(
|
||||
new chipyard.config.WithTileFrequency(200.0) ++
|
||||
new freechips.rocketchip.subsystem.WithRationalRocketTiles ++ // Add rational crossings between RocketTile and uncore
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.WithMemoryBusFrequency(50.0) ++
|
||||
new chipyard.config.WithAsynchrousMemoryBusCrossing ++
|
||||
new testchipip.WithAsynchronousSerialSlaveCrossing ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
class LBWIFRocketConfig extends Config(
|
||||
|
||||
@@ -9,7 +9,7 @@ class Sodor1StageConfig extends Config(
|
||||
new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage1Factory) ++
|
||||
new testchipip.WithSerialPBusMem ++
|
||||
new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad
|
||||
new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // use no external memory
|
||||
new freechips.rocketchip.subsystem.WithNoMemPort ++ // use no external memory
|
||||
new freechips.rocketchip.subsystem.WithNBanks(0) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
@@ -18,7 +18,7 @@ class Sodor2StageConfig extends Config(
|
||||
new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage2Factory) ++
|
||||
new testchipip.WithSerialPBusMem ++
|
||||
new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad
|
||||
new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // use no external memory
|
||||
new freechips.rocketchip.subsystem.WithNoMemPort ++ // use no external memory
|
||||
new freechips.rocketchip.subsystem.WithNBanks(0) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
@@ -27,7 +27,7 @@ class Sodor3StageConfig extends Config(
|
||||
new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage3Factory(ports = 2)) ++
|
||||
new testchipip.WithSerialPBusMem ++
|
||||
new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad
|
||||
new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // use no external memory
|
||||
new freechips.rocketchip.subsystem.WithNoMemPort ++ // use no external memory
|
||||
new freechips.rocketchip.subsystem.WithNBanks(0) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
@@ -36,7 +36,7 @@ class Sodor3StageSinglePortConfig extends Config(
|
||||
new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage3Factory(ports = 1)) ++
|
||||
new testchipip.WithSerialPBusMem ++
|
||||
new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad
|
||||
new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // use no external memory
|
||||
new freechips.rocketchip.subsystem.WithNoMemPort ++ // use no external memory
|
||||
new freechips.rocketchip.subsystem.WithNBanks(0) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
@@ -45,7 +45,7 @@ class Sodor5StageConfig extends Config(
|
||||
new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage5Factory) ++
|
||||
new testchipip.WithSerialPBusMem ++
|
||||
new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad
|
||||
new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // use no external memory
|
||||
new freechips.rocketchip.subsystem.WithNoMemPort ++ // use no external memory
|
||||
new freechips.rocketchip.subsystem.WithNBanks(0) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
@@ -54,6 +54,6 @@ class SodorUCodeConfig extends Config(
|
||||
new sodor.common.WithNSodorCores(1, internalTile = sodor.common.UCodeFactory) ++
|
||||
new testchipip.WithSerialPBusMem ++
|
||||
new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad
|
||||
new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // use no external memory
|
||||
new freechips.rocketchip.subsystem.WithNoMemPort ++ // use no external memory
|
||||
new freechips.rocketchip.subsystem.WithNBanks(0) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
@@ -12,10 +12,11 @@ private[stage] object UnderscoreDelimitedConfigsAnnotation extends HasShellOptio
|
||||
new ShellOption[String](
|
||||
longOption = "legacy-configs",
|
||||
toAnnotationSeq = a => {
|
||||
val split = a.split('.')
|
||||
val packageName = split.init.mkString(".")
|
||||
val split = a.split(':')
|
||||
assert(split.length == 2)
|
||||
val packageName = split.head
|
||||
val configs = split.last.split("_")
|
||||
Seq(new ConfigsAnnotation(configs map { config => s"${packageName}.${config}" } ))
|
||||
Seq(new ConfigsAnnotation(configs map { config => if (config contains ".") s"${config}" else s"${packageName}.${config}" } ))
|
||||
},
|
||||
helpText = "A string of underscore-delimited configs (configs have decreasing precendence from left to right).",
|
||||
shortOption = Some("LC")
|
||||
|
||||
@@ -18,7 +18,7 @@ import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvon
|
||||
|
||||
import junctions.{NastiKey, NastiParameters}
|
||||
import midas.models.{FASEDBridge, AXI4EdgeSummary, CompleteConfig}
|
||||
import midas.targetutils.{FAMEModelAnnotation, MemModelAnnotation, EnableModelMultiThreadingAnnotation}
|
||||
import midas.targetutils.{MemModelAnnotation, EnableModelMultiThreadingAnnotation}
|
||||
import firesim.bridges._
|
||||
import firesim.configs.MemModelKey
|
||||
import tracegen.{TraceGenSystemModuleImp}
|
||||
@@ -66,7 +66,7 @@ class WithFireSimIOCellModels extends Config((site, here, up) => {
|
||||
})
|
||||
|
||||
class WithSerialBridge extends OverrideHarnessBinder({
|
||||
(system: CanHavePeripheryTLSerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => {
|
||||
(system: CanHavePeripheryTLSerial, th: FireSim, ports: Seq[ClockedIO[SerialIO]]) => {
|
||||
ports.map { port =>
|
||||
implicit val p = GetSystemParameters(system)
|
||||
val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, port, th.harnessReset)
|
||||
@@ -77,7 +77,7 @@ class WithSerialBridge extends OverrideHarnessBinder({
|
||||
})
|
||||
|
||||
class WithNICBridge extends OverrideHarnessBinder({
|
||||
(system: CanHavePeripheryIceNIC, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => {
|
||||
(system: CanHavePeripheryIceNIC, th: FireSim, ports: Seq[ClockedIO[NICIOvonly]]) => {
|
||||
val p: Parameters = GetSystemParameters(system)
|
||||
ports.map { n => NICBridge(n.clock, n.bits)(p) }
|
||||
Nil
|
||||
@@ -85,12 +85,12 @@ class WithNICBridge extends OverrideHarnessBinder({
|
||||
})
|
||||
|
||||
class WithUARTBridge extends OverrideHarnessBinder({
|
||||
(system: HasPeripheryUARTModuleImp, th: HasHarnessSignalReferences, ports: Seq[UARTPortIO]) =>
|
||||
(system: HasPeripheryUARTModuleImp, th: FireSim, ports: Seq[UARTPortIO]) =>
|
||||
ports.map { p => UARTBridge(th.harnessClock, p)(system.p) }; Nil
|
||||
})
|
||||
|
||||
class WithBlockDeviceBridge extends OverrideHarnessBinder({
|
||||
(system: CanHavePeripheryBlockDevice, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => {
|
||||
(system: CanHavePeripheryBlockDevice, th: FireSim, ports: Seq[ClockedIO[BlockDeviceIO]]) => {
|
||||
implicit val p: Parameters = GetSystemParameters(system)
|
||||
ports.map { b => BlockDevBridge(b.clock, b.bits, th.harnessReset.toBool) }
|
||||
Nil
|
||||
@@ -98,14 +98,14 @@ class WithBlockDeviceBridge extends OverrideHarnessBinder({
|
||||
})
|
||||
|
||||
class WithFASEDBridge extends OverrideHarnessBinder({
|
||||
(system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => {
|
||||
(system: CanHaveMasterAXI4MemPort, th: FireSim, ports: Seq[ClockedAndResetIO[AXI4Bundle]]) => {
|
||||
implicit val p: Parameters = GetSystemParameters(system)
|
||||
(ports zip system.memAXI4Node.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, th.harnessReset.asBool,
|
||||
case s: BaseSubsystem => FASEDBridge(axi4.clock, axi4.bits, axi4.reset.asBool,
|
||||
CompleteConfig(p(firesim.configs.MemModelKey),
|
||||
nastiKey,
|
||||
Some(AXI4EdgeSummary(edge)),
|
||||
@@ -118,20 +118,20 @@ class WithFASEDBridge extends OverrideHarnessBinder({
|
||||
})
|
||||
|
||||
class WithTracerVBridge extends ComposeHarnessBinder({
|
||||
(system: CanHaveTraceIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[TraceOutputTop]) => {
|
||||
(system: CanHaveTraceIOModuleImp, th: FireSim, ports: Seq[TraceOutputTop]) => {
|
||||
ports.map { p => p.traces.map(tileTrace => TracerVBridge(tileTrace)(system.p)) }
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithDromajoBridge extends ComposeHarnessBinder({
|
||||
(system: CanHaveTraceIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[TraceOutputTop]) =>
|
||||
(system: CanHaveTraceIOModuleImp, th: FireSim, ports: Seq[TraceOutputTop]) =>
|
||||
ports.map { p => p.traces.map(tileTrace => DromajoBridge(tileTrace)(system.p)) }; Nil
|
||||
})
|
||||
|
||||
|
||||
class WithTraceGenBridge extends OverrideHarnessBinder({
|
||||
(system: TraceGenSystemModuleImp, th: HasHarnessSignalReferences, ports: Seq[Bool]) =>
|
||||
(system: TraceGenSystemModuleImp, th: FireSim, ports: Seq[Bool]) =>
|
||||
ports.map { p => GroundTestBridge(th.harnessClock, p)(system.p) }; Nil
|
||||
})
|
||||
|
||||
@@ -161,10 +161,8 @@ class WithFireSimFAME5 extends ComposeIOBinder({
|
||||
(system: HasTilesModuleImp) => {
|
||||
system.outer.tiles.map {
|
||||
case b: BoomTile =>
|
||||
annotate(FAMEModelAnnotation(b.module))
|
||||
annotate(EnableModelMultiThreadingAnnotation(b.module))
|
||||
case r: RocketTile =>
|
||||
annotate(FAMEModelAnnotation(r.module))
|
||||
annotate(EnableModelMultiThreadingAnnotation(r.module))
|
||||
}
|
||||
(Nil, Nil)
|
||||
|
||||
@@ -16,7 +16,7 @@ import midas.widgets.{Bridge, PeekPokeBridge, RationalClockBridge, RationalClock
|
||||
import chipyard._
|
||||
import chipyard.harness._
|
||||
import chipyard.iobinders._
|
||||
import chipyard.clocking.{FrequencyUtils, ClockGroupNamePrefixer, ClockGroupFrequencySpecifier, SimplePllConfiguration}
|
||||
import chipyard.clocking._
|
||||
|
||||
// Determines the number of times to instantiate the DUT in the harness.
|
||||
// Subsumes legacy supernode support
|
||||
@@ -96,11 +96,12 @@ class WithFireSimSimpleClocks extends Config((site, here, up) => {
|
||||
|
||||
val aggregator = LazyModule(new ClockGroupAggregator("allClocks")).node
|
||||
(chiptop.implicitClockSinkNode := ClockGroup() := aggregator)
|
||||
(systemAsyncClockGroup := ClockGroupNamePrefixer() := aggregator)
|
||||
(systemAsyncClockGroup :*= ClockGroupNamePrefixer() :*= aggregator)
|
||||
|
||||
val inputClockSource = ClockGroupSourceNode(Seq(ClockGroupSourceParameters()))
|
||||
|
||||
(aggregator
|
||||
:= ClockGroupResetSynchronizer()
|
||||
:= ClockGroupFrequencySpecifier(p(ClockFrequencyAssignersKey), p(DefaultClockFrequencyKey))
|
||||
:= inputClockSource)
|
||||
|
||||
@@ -113,15 +114,7 @@ class WithFireSimSimpleClocks extends Config((site, here, up) => {
|
||||
|
||||
(clockGroupBundle.member.data zip input_clocks.data).foreach { case (clockBundle, inputClock) =>
|
||||
clockBundle.clock := inputClock
|
||||
}
|
||||
|
||||
// Assign resets. The synchronization scheme is still WIP.
|
||||
for ((name, clockBundle) <- clockGroupBundle.member.elements) {
|
||||
if (name.contains("core")) {
|
||||
clockBundle.reset := ResetCatchAndSync(clockBundle.clock, reset.asBool)
|
||||
} else {
|
||||
clockBundle.reset := reset
|
||||
}
|
||||
clockBundle.reset := reset
|
||||
}
|
||||
|
||||
val pllConfig = new SimplePllConfiguration("FireSim RationalClockBridge", clockGroupEdge.sink.members)
|
||||
@@ -160,7 +153,9 @@ class FireSim(implicit val p: Parameters) extends RawModule with HasHarnessSigna
|
||||
lazyModule match { case d: HasTestHarnessFunctions =>
|
||||
require(d.harnessFunctions.size == 1, "There should only be 1 harness function to connect clock+reset")
|
||||
d.harnessFunctions.foreach(_(this))
|
||||
ApplyHarnessBinders(this, d.lazySystem, p(HarnessBinders), d.portMap.toMap)
|
||||
}
|
||||
lazyModule match { case d: HasIOBinders =>
|
||||
ApplyHarnessBinders(this, d.lazySystem, d.portMap)
|
||||
}
|
||||
NodeIdx.increment()
|
||||
}
|
||||
|
||||
@@ -37,10 +37,6 @@ class WithBootROM extends Config((site, here, up) => {
|
||||
}
|
||||
})
|
||||
|
||||
class WithPeripheryBusFrequency(freq: BigInt) extends Config((site, here, up) => {
|
||||
case PeripheryBusKey => up(PeripheryBusKey).copy(dtsFrequency = Some(freq))
|
||||
})
|
||||
|
||||
// Disables clock-gating; doesn't play nice with our FAME-1 pass
|
||||
class WithoutClockGating extends Config((site, here, up) => {
|
||||
case DebugModuleKey => up(DebugModuleKey, site).map(_.copy(clockGate = false))
|
||||
@@ -66,13 +62,23 @@ class WithNVDLASmall extends nvidia.blocks.dla.WithNVDLA("small")
|
||||
|
||||
// Tweaks that are generally applied to all firesim configs
|
||||
class WithFireSimConfigTweaks extends Config(
|
||||
// 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 ++
|
||||
// Optional*: Removing this will require adjusting the UART baud rate and
|
||||
// potential target-software changes to properly capture UART output
|
||||
new WithPeripheryBusFrequency(BigInt(3200000000L)) ++
|
||||
new chipyard.config.WithPeripheryBusFrequency(3200.0) ++
|
||||
// Optional: These three configs put the DRAM memory system in it's own clock domian.
|
||||
// Removing the first config will result in the FASED timing model running
|
||||
// at the pbus freq (above, 3.2 GHz), which is outside the range of valid DDR3 speedgrades.
|
||||
// 1 GHz matches the FASED default, using some other frequency will require
|
||||
// runnings the FASED runtime configuration generator to generate faithful DDR3 timing values.
|
||||
new chipyard.config.WithMemoryBusFrequency(1000.0) ++
|
||||
new chipyard.config.WithAsynchrousMemoryBusCrossing ++
|
||||
new testchipip.WithAsynchronousSerialSlaveCrossing ++
|
||||
// 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)
|
||||
@@ -127,7 +133,7 @@ class FireSimSmallSystemConfig extends Config(
|
||||
new WithDefaultFireSimBridges ++
|
||||
new WithDefaultMemModel ++
|
||||
new WithBootROM ++
|
||||
new WithPeripheryBusFrequency(BigInt(3200000000L)) ++
|
||||
new chipyard.config.WithPeripheryBusFrequency(3200.0) ++
|
||||
new WithoutClockGating ++
|
||||
new WithoutTLMonitors ++
|
||||
new freechips.rocketchip.subsystem.WithExtMemSize(1 << 28) ++
|
||||
|
||||
Submodule generators/testchipip updated: 56bfaa3f9b...03af7aa539
Reference in New Issue
Block a user