Merge branch 'main' into uart-patch
This commit is contained in:
Submodule generators/bar-fetchers updated: a5bd985d29...45380026ff
Submodule generators/boom updated: 96da674bc9...9459af0c1f
Submodule generators/caliptra-aes-acc updated: 82fa7080f4...8bcd6b6bc1
@@ -12,7 +12,7 @@
|
||||
|
||||
#if __has_include("spiketile_tsi.h")
|
||||
#define SPIKETILE_HTIF_TSI
|
||||
extern htif_t* tsi;
|
||||
extern std::map<int, htif_t*> tsis;
|
||||
#endif
|
||||
#if __has_include("spiketile_dtm.h")
|
||||
#define SPIKETILE_HTIF_DTM
|
||||
@@ -346,8 +346,8 @@ extern "C" void spike_tile(int hartid, char* isa,
|
||||
chipyard_simif_t* simif = tile->simif;
|
||||
processor_t* proc = tile->proc;
|
||||
#if defined(SPIKETILE_HTIF_TSI)
|
||||
if (!simif->htif && tsi)
|
||||
simif->htif = tsi;
|
||||
if (!simif->htif && tsis.size() > 0 && tsis[0])
|
||||
simif->htif = tsis[0];
|
||||
#endif
|
||||
#if defined(SPIKETILE_HTIF_DTM)
|
||||
if (!simif->htif && dtm)
|
||||
|
||||
@@ -5,7 +5,6 @@ import chisel3._
|
||||
import scala.collection.mutable.{ArrayBuffer}
|
||||
|
||||
import freechips.rocketchip.prci.{ClockGroupIdentityNode, ClockSinkParameters, ClockSinkNode, ClockGroup}
|
||||
import freechips.rocketchip.subsystem.{BaseSubsystem, SubsystemDriveAsyncClockGroupsKey}
|
||||
import org.chipsalliance.cde.config.{Parameters, Field}
|
||||
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, LazyRawModuleImp, LazyModuleImpLike, BindingScope}
|
||||
import freechips.rocketchip.util.{DontTouch}
|
||||
|
||||
@@ -19,8 +19,11 @@ class DigitalTop(implicit p: Parameters) extends ChipyardSystem
|
||||
with testchipip.cosim.CanHaveTraceIO // Enables optionally adding trace IO
|
||||
with testchipip.soc.CanHaveBankedScratchpad // Enables optionally adding a banked scratchpad
|
||||
with testchipip.iceblk.CanHavePeripheryBlockDevice // Enables optionally adding the block device
|
||||
with testchipip.serdes.CanHavePeripheryTLSerial // Enables optionally adding the backing memory and serial adapter
|
||||
with testchipip.serdes.CanHavePeripheryTLSerial // Enables optionally adding the tl-serial interface
|
||||
with testchipip.serdes.old.CanHavePeripheryTLSerial // Enables optionally adding the DEPRECATED tl-serial interface
|
||||
with testchipip.soc.CanHavePeripheryChipIdPin // Enables optional pin to set chip id for multi-chip configs
|
||||
with sifive.blocks.devices.i2c.HasPeripheryI2C // Enables optionally adding the sifive I2C
|
||||
with sifive.blocks.devices.timer.HasPeripheryTimer // Enables optionally adding the timer device
|
||||
with sifive.blocks.devices.pwm.HasPeripheryPWM // Enables optionally adding the sifive PWM
|
||||
with sifive.blocks.devices.uart.HasPeripheryUART // Enables optionally adding the sifive UART
|
||||
with sifive.blocks.devices.gpio.HasPeripheryGPIO // Enables optionally adding the sifive GPIOs
|
||||
@@ -33,6 +36,7 @@ class DigitalTop(implicit p: Parameters) extends ChipyardSystem
|
||||
with chipyard.example.CanHavePeripheryStreamingPassthrough // Enables optionally adding the DSPTools streaming-passthrough example widget
|
||||
with nvidia.blocks.dla.CanHavePeripheryNVDLA // Enables optionally having an NVDLA
|
||||
with chipyard.clocking.HasChipyardPRCI // Use Chipyard reset/clock distribution
|
||||
with chipyard.clocking.CanHaveClockTap // Enables optionally adding a clock tap output port
|
||||
with fftgenerator.CanHavePeripheryFFT // Enables optionally having an MMIO-based FFT block
|
||||
with constellation.soc.CanHaveGlobalNoC // Support instantiating a global NoC interconnect
|
||||
{
|
||||
@@ -40,13 +44,11 @@ class DigitalTop(implicit p: Parameters) extends ChipyardSystem
|
||||
}
|
||||
|
||||
class DigitalTopModule[+L <: DigitalTop](l: L) extends ChipyardSystemModule(l)
|
||||
with testchipip.cosim.CanHaveTraceIOModuleImp
|
||||
with sifive.blocks.devices.i2c.HasPeripheryI2CModuleImp
|
||||
with sifive.blocks.devices.pwm.HasPeripheryPWMModuleImp
|
||||
with sifive.blocks.devices.uart.HasPeripheryUARTModuleImp
|
||||
with sifive.blocks.devices.gpio.HasPeripheryGPIOModuleImp
|
||||
with sifive.blocks.devices.spi.HasPeripherySPIFlashModuleImp
|
||||
with sifive.blocks.devices.spi.HasPeripherySPIModuleImp
|
||||
with chipyard.example.CanHavePeripheryGCDModuleImp
|
||||
with freechips.rocketchip.util.DontTouch
|
||||
// DOC include end: DigitalTop
|
||||
|
||||
@@ -2,7 +2,7 @@ package chipyard
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import chisel3.experimental.{IntParam, StringParam, IO}
|
||||
import chisel3.experimental.{IntParam, StringParam}
|
||||
|
||||
import org.chipsalliance.cde.config._
|
||||
import freechips.rocketchip.subsystem._
|
||||
@@ -77,14 +77,15 @@ case class SpikeTileAttachParams(
|
||||
}
|
||||
|
||||
case class SpikeTileParams(
|
||||
hartId: Int = 0,
|
||||
tileId: Int = 0,
|
||||
val core: SpikeCoreParams = SpikeCoreParams(),
|
||||
icacheParams: ICacheParams = ICacheParams(nWays = 32),
|
||||
dcacheParams: DCacheParams = DCacheParams(nWays = 32),
|
||||
tcmParams: Option[MasterPortParams] = None // tightly coupled memory
|
||||
) extends InstantiableTileParams[SpikeTile]
|
||||
{
|
||||
val name = Some("spike_tile")
|
||||
val baseName = "spike_tile"
|
||||
val uniqueName = s"${baseName}_$tileId"
|
||||
val beuAddr = None
|
||||
val blockerCtrlAddr = None
|
||||
val btb = None
|
||||
@@ -92,7 +93,7 @@ case class SpikeTileParams(
|
||||
val dcache = Some(dcacheParams)
|
||||
val icache = Some(icacheParams)
|
||||
val clockSinkParams = ClockSinkParameters()
|
||||
def instantiate(crossing: TileCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters): SpikeTile = {
|
||||
def instantiate(crossing: HierarchicalElementCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters): SpikeTile = {
|
||||
new SpikeTile(this, crossing, lookup)
|
||||
}
|
||||
}
|
||||
@@ -106,11 +107,11 @@ class SpikeTile(
|
||||
with SourcesExternalNotifications
|
||||
{
|
||||
// Private constructor ensures altered LazyModule.p is used implicitly
|
||||
def this(params: SpikeTileParams, crossing: TileCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters) =
|
||||
def this(params: SpikeTileParams, crossing: HierarchicalElementCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters) =
|
||||
this(params, crossing.crossingType, lookup, p)
|
||||
|
||||
// Required TileLink nodes
|
||||
val intOutwardNode = IntIdentityNode()
|
||||
val intOutwardNode = None
|
||||
val masterNode = visibilityNode
|
||||
val slaveNode = TLIdentityNode()
|
||||
|
||||
@@ -129,21 +130,21 @@ class SpikeTile(
|
||||
}
|
||||
|
||||
ResourceBinding {
|
||||
Resource(cpuDevice, "reg").bind(ResourceAddress(hartId))
|
||||
Resource(cpuDevice, "reg").bind(ResourceAddress(tileId))
|
||||
}
|
||||
|
||||
|
||||
val icacheNode = TLClientNode(Seq(TLMasterPortParameters.v1(Seq(TLMasterParameters.v1(
|
||||
sourceId = IdRange(0, 1),
|
||||
name = s"Core ${staticIdForMetadataUseOnly} ICache")))))
|
||||
name = s"Core ${tileId} ICache")))))
|
||||
|
||||
val dcacheNode = TLClientNode(Seq(TLMasterPortParameters.v1(Seq(TLMasterParameters.v1(
|
||||
name = s"Core ${staticIdForMetadataUseOnly} DCache",
|
||||
name = s"Core ${tileId} DCache",
|
||||
sourceId = IdRange(0, tileParams.dcache.get.nMSHRs),
|
||||
supportsProbe = TransferSizes(p(CacheBlockBytes), p(CacheBlockBytes)))))))
|
||||
|
||||
val mmioNode = TLClientNode((Seq(TLMasterPortParameters.v1(Seq(TLMasterParameters.v1(
|
||||
name = s"Core ${staticIdForMetadataUseOnly} MMIO",
|
||||
name = s"Core ${tileId} MMIO",
|
||||
sourceId = IdRange(0, 1),
|
||||
requestFifo = true))))))
|
||||
|
||||
@@ -313,7 +314,7 @@ class SpikeBlackBox(
|
||||
}
|
||||
|
||||
class SpikeTileModuleImp(outer: SpikeTile) extends BaseTileModuleImp(outer) {
|
||||
|
||||
val tileParams = outer.tileParams
|
||||
// We create a bundle here and decode the interrupt.
|
||||
val int_bundle = Wire(new TileInterrupts())
|
||||
outer.decodeCoreInterrupts(int_bundle)
|
||||
@@ -337,7 +338,7 @@ class SpikeTileModuleImp(outer: SpikeTile) extends BaseTileModuleImp(outer) {
|
||||
// then the DTM-based bringup with SimDTM will be used. This isn't required to be
|
||||
// true, but it usually is
|
||||
val useDTM = p(ExportDebug).protocols.contains(DMI)
|
||||
val spike = Module(new SpikeBlackBox(hartId, isaDTS, tileParams.core.nPMPs,
|
||||
val spike = Module(new SpikeBlackBox(outer.tileId, outer.isaDTS, tileParams.core.nPMPs,
|
||||
tileParams.icache.get.nSets, tileParams.icache.get.nWays,
|
||||
tileParams.dcache.get.nSets, tileParams.dcache.get.nWays,
|
||||
tileParams.dcache.get.nMSHRs,
|
||||
@@ -467,19 +468,21 @@ class SpikeTileModuleImp(outer: SpikeTile) extends BaseTileModuleImp(outer) {
|
||||
}
|
||||
}
|
||||
|
||||
class WithNSpikeCores(n: Int = 1, tileParams: SpikeTileParams = SpikeTileParams(),
|
||||
overrideIdOffset: Option[Int] = None) extends Config((site, here, up) => {
|
||||
class WithNSpikeCores(n: Int = 1, tileParams: SpikeTileParams = SpikeTileParams()
|
||||
) extends Config((site, here, up) => {
|
||||
case TilesLocated(InSubsystem) => {
|
||||
// Calculate the next available hart ID (since hart ID cannot be duplicated)
|
||||
val prev = up(TilesLocated(InSubsystem), site)
|
||||
val idOffset = overrideIdOffset.getOrElse(prev.size)
|
||||
val idOffset = up(NumTiles)
|
||||
// Create TileAttachParams for every core to be instantiated
|
||||
(0 until n).map { i =>
|
||||
SpikeTileAttachParams(
|
||||
tileParams = tileParams.copy(hartId = i + idOffset)
|
||||
tileParams = tileParams.copy(tileId = i + idOffset)
|
||||
)
|
||||
} ++ prev
|
||||
}
|
||||
case NumTiles => up(NumTiles) + n
|
||||
|
||||
})
|
||||
|
||||
class WithSpikeTCM extends Config((site, here, up) => {
|
||||
@@ -492,5 +495,5 @@ class WithSpikeTCM extends Config((site, here, up) => {
|
||||
)))
|
||||
}
|
||||
case ExtMem => None
|
||||
case BankedL2Key => up(BankedL2Key).copy(nBanks = 0)
|
||||
case SubsystemBankedCoherenceKey => up(SubsystemBankedCoherenceKey).copy(nBanks = 0)
|
||||
})
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
package chipyard
|
||||
|
||||
import chisel3._
|
||||
import chisel3.internal.sourceinfo.{SourceInfo}
|
||||
|
||||
import freechips.rocketchip.prci._
|
||||
import org.chipsalliance.cde.config.{Field, Parameters}
|
||||
@@ -71,18 +70,24 @@ trait CanHaveChosenInDTS { this: BaseSubsystem =>
|
||||
}
|
||||
|
||||
class ChipyardSubsystem(implicit p: Parameters) extends BaseSubsystem
|
||||
with HasTiles
|
||||
with HasPeripheryDebug
|
||||
with CanHaveHTIF
|
||||
with CanHaveChosenInDTS
|
||||
with InstantiatesHierarchicalElements
|
||||
with HasTileNotificationSinks
|
||||
with HasTileInputConstants
|
||||
with CanHavePeripheryCLINT
|
||||
with CanHavePeripheryPLIC
|
||||
with HasPeripheryDebug
|
||||
with HasHierarchicalElementsRootContext
|
||||
with HasHierarchicalElements
|
||||
with CanHaveHTIF
|
||||
with CanHaveChosenInDTS
|
||||
{
|
||||
def coreMonitorBundles = tiles.map {
|
||||
def coreMonitorBundles = totalTiles.values.map {
|
||||
case r: RocketTile => r.module.core.rocketImpl.coreMonitorBundle
|
||||
case b: BoomTile => b.module.core.coreMonitorBundle
|
||||
}.toList
|
||||
|
||||
// No-tile configs have to be handled specially.
|
||||
if (tiles.size == 0) {
|
||||
if (totalTiles.size == 0) {
|
||||
// no PLIC, so sink interrupts to nowhere
|
||||
require(!p(PLICKey).isDefined)
|
||||
val intNexus = IntNexusNode(sourceFn = x => x.head, sinkFn = x => x.head)
|
||||
@@ -90,16 +95,12 @@ class ChipyardSubsystem(implicit p: Parameters) extends BaseSubsystem
|
||||
intSink := intNexus :=* ibus.toPLIC
|
||||
|
||||
// avoids a bug when there are no interrupt sources
|
||||
ibus.fromAsync := NullIntSource()
|
||||
ibus { ibus.fromAsync := NullIntSource() }
|
||||
|
||||
// Need to have at least 1 driver to the tile notification sinks
|
||||
tileHaltXbarNode := IntSourceNode(IntSourcePortSimple())
|
||||
tileWFIXbarNode := IntSourceNode(IntSourcePortSimple())
|
||||
tileCeaseXbarNode := IntSourceNode(IntSourcePortSimple())
|
||||
|
||||
// Sink reset vectors to nowhere
|
||||
val resetVectorSink = BundleBridgeSink[UInt](Some(() => UInt(28.W)))
|
||||
resetVectorSink := tileResetVectorNode
|
||||
}
|
||||
|
||||
// Relying on [[TLBusWrapperConnection]].driveClockFromMaster for
|
||||
@@ -107,7 +108,7 @@ class ChipyardSubsystem(implicit p: Parameters) extends BaseSubsystem
|
||||
// ClockGroup. This makes it impossible to determine which clocks are driven
|
||||
// by which bus based on the member names, which is problematic when there is
|
||||
// a rational crossing between two buses. Instead, provide all bus clocks
|
||||
// directly from the asyncClockGroupsNode in the subsystem to ensure bus
|
||||
// directly from the allClockGroupsNode in the subsystem to ensure bus
|
||||
// names are always preserved in the top-level clock names.
|
||||
//
|
||||
// For example, using a RationalCrossing between the Sbus and Cbus, and
|
||||
@@ -116,12 +117,12 @@ class ChipyardSubsystem(implicit p: Parameters) extends BaseSubsystem
|
||||
// Conversly, if an async crossing is used, they instead receive names of the
|
||||
// form "subsystem_cbus_[0-9]*". The assignment below provides the latter names in all cases.
|
||||
Seq(PBUS, FBUS, MBUS, CBUS).foreach { loc =>
|
||||
tlBusWrapperLocationMap.lift(loc).foreach { _.clockGroupNode := asyncClockGroupsNode }
|
||||
tlBusWrapperLocationMap.lift(loc).foreach { _.clockGroupNode := allClockGroupsNode }
|
||||
}
|
||||
override lazy val module = new ChipyardSubsystemModuleImp(this)
|
||||
}
|
||||
|
||||
class ChipyardSubsystemModuleImp[+L <: ChipyardSubsystem](_outer: L) extends BaseSubsystemModuleImp(_outer)
|
||||
with HasTilesModuleImp
|
||||
with HasHierarchicalElementsRootContextModuleImp
|
||||
{
|
||||
}
|
||||
|
||||
@@ -32,13 +32,6 @@ class ChipyardSystem(implicit p: Parameters) extends ChipyardSubsystem
|
||||
val bootROM = p(BootROMLocated(location)).map { BootROM.attach(_, this, CBUS) }
|
||||
val maskROMs = p(MaskROMLocated(location)).map { MaskROM.attach(_, this, CBUS) }
|
||||
|
||||
// If there is no bootrom, the tile reset vector bundle will be tied to zero
|
||||
if (bootROM.isEmpty) {
|
||||
val fakeResetVectorSourceNode = BundleBridgeSource[UInt]()
|
||||
InModuleBody { fakeResetVectorSourceNode.bundle := 0.U }
|
||||
tileResetVectorNexusNode := fakeResetVectorSourceNode
|
||||
}
|
||||
|
||||
override lazy val module = new ChipyardSystemModule(this)
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ class TestSuiteHelper
|
||||
*/
|
||||
def addGenericTestSuites(tiles: Seq[TileParams])(implicit p: Parameters) = {
|
||||
val xlen = p(XLen)
|
||||
tiles.find(_.hartId == 0).map { tileParams =>
|
||||
tiles.find(_.tileId == 0).map { tileParams =>
|
||||
val coreParams = tileParams.core
|
||||
val vm = coreParams.useVM
|
||||
val env = if (vm) List("p","v") else List("p")
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package chipyard.clocking
|
||||
|
||||
import chisel3._
|
||||
|
||||
import org.chipsalliance.cde.config.{Parameters, Field, Config}
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.util._
|
||||
import freechips.rocketchip.tile._
|
||||
import freechips.rocketchip.prci._
|
||||
|
||||
case object ClockTapKey extends Field[Boolean](true)
|
||||
|
||||
trait CanHaveClockTap { this: BaseSubsystem =>
|
||||
require(!p(SubsystemDriveClockGroupsFromIO), "Subsystem must not drive clocks from IO")
|
||||
val clockTapNode = Option.when(p(ClockTapKey)) {
|
||||
val clockTap = ClockSinkNode(Seq(ClockSinkParameters(name=Some("clock_tap"))))
|
||||
clockTap := ClockGroup() := allClockGroupsNode
|
||||
clockTap
|
||||
}
|
||||
val clockTapIO = clockTapNode.map { node => InModuleBody {
|
||||
val clock_tap = IO(Output(Clock()))
|
||||
clock_tap := node.in.head._1.clock
|
||||
clock_tap
|
||||
}}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package chipyard.clocking
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import chipyard.iobinders.{OverrideLazyIOBinder, GetSystemParameters, IOCellKey, ClockPort, ResetPort}
|
||||
import chipyard.iobinders._
|
||||
import freechips.rocketchip.prci._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.subsystem._
|
||||
@@ -14,31 +14,24 @@ import barstools.iocell.chisel._
|
||||
// blocks, which allow memory-mapped control of clock division, and clock muxing
|
||||
// between the FakePLL and the slow off-chip clock
|
||||
// Note: This will not simulate properly with firesim
|
||||
class WithPLLSelectorDividerClockGenerator extends OverrideLazyIOBinder({
|
||||
// Unsetting enable will prevent the divider/selector from actually modifying the clock,
|
||||
// while preserving the address map. Unsetting enable should only be done for RTL
|
||||
// simulators (Verilator) which do not model reset properly
|
||||
class WithPLLSelectorDividerClockGenerator(enable: Boolean = true) extends OverrideLazyIOBinder({
|
||||
(system: HasChipyardPRCI) => {
|
||||
// Connect the implicit clock
|
||||
implicit val p = GetSystemParameters(system)
|
||||
val implicitClockSinkNode = ClockSinkNode(Seq(ClockSinkParameters(name = Some("implicit_clock"))))
|
||||
system.connectImplicitClockSinkNode(implicitClockSinkNode)
|
||||
InModuleBody {
|
||||
val implicit_clock = implicitClockSinkNode.in.head._1.clock
|
||||
val implicit_reset = implicitClockSinkNode.in.head._1.reset
|
||||
system.asInstanceOf[BaseSubsystem].module match { case l: LazyModuleImp => {
|
||||
l.clock := implicit_clock
|
||||
l.reset := implicit_reset
|
||||
}}
|
||||
}
|
||||
val tlbus = system.asInstanceOf[BaseSubsystem].locateTLBusWrapper(system.prciParams.slaveWhere)
|
||||
val baseAddress = system.prciParams.baseAddress
|
||||
val clockDivider = system.prci_ctrl_domain { LazyModule(new TLClockDivider (baseAddress + 0x20000, tlbus.beatBytes)) }
|
||||
val clockSelector = system.prci_ctrl_domain { LazyModule(new TLClockSelector(baseAddress + 0x30000, tlbus.beatBytes)) }
|
||||
val clockDivider = system.prci_ctrl_domain { LazyModule(new TLClockDivider (baseAddress + 0x20000, tlbus.beatBytes, enable=enable)) }
|
||||
val clockSelector = system.prci_ctrl_domain { LazyModule(new TLClockSelector(baseAddress + 0x30000, tlbus.beatBytes, enable=enable)) }
|
||||
val pllCtrl = system.prci_ctrl_domain { LazyModule(new FakePLLCtrl (baseAddress + 0x40000, tlbus.beatBytes)) }
|
||||
|
||||
clockDivider.tlNode := system.prci_ctrl_domain { TLFragmenter(tlbus.beatBytes, tlbus.blockBytes) := system.prci_ctrl_bus.get }
|
||||
clockSelector.tlNode := system.prci_ctrl_domain { TLFragmenter(tlbus.beatBytes, tlbus.blockBytes) := system.prci_ctrl_bus.get }
|
||||
pllCtrl.tlNode := system.prci_ctrl_domain { TLFragmenter(tlbus.beatBytes, tlbus.blockBytes) := system.prci_ctrl_bus.get }
|
||||
|
||||
system.allClockGroupsNode := clockDivider.clockNode := clockSelector.clockNode
|
||||
system.chiptopClockGroupsNode := clockDivider.clockNode := clockSelector.clockNode
|
||||
|
||||
// Connect all other requested clocks
|
||||
val slowClockSource = ClockSourceNode(Seq(ClockSourceParameters()))
|
||||
@@ -83,23 +76,12 @@ class WithPLLSelectorDividerClockGenerator extends OverrideLazyIOBinder({
|
||||
// This passes all clocks through to the TestHarness
|
||||
class WithPassthroughClockGenerator extends OverrideLazyIOBinder({
|
||||
(system: HasChipyardPRCI) => {
|
||||
// Connect the implicit clock
|
||||
implicit val p = GetSystemParameters(system)
|
||||
val implicitClockSinkNode = ClockSinkNode(Seq(ClockSinkParameters(name = Some("implicit_clock"))))
|
||||
system.connectImplicitClockSinkNode(implicitClockSinkNode)
|
||||
InModuleBody {
|
||||
val implicit_clock = implicitClockSinkNode.in.head._1.clock
|
||||
val implicit_reset = implicitClockSinkNode.in.head._1.reset
|
||||
system.asInstanceOf[BaseSubsystem].module match { case l: LazyModuleImp => {
|
||||
l.clock := implicit_clock
|
||||
l.reset := implicit_reset
|
||||
}}
|
||||
}
|
||||
|
||||
// This aggregate node should do nothing
|
||||
val clockGroupAggNode = ClockGroupAggregateNode("fake")
|
||||
val clockGroupsSourceNode = ClockGroupSourceNode(Seq(ClockGroupSourceParameters()))
|
||||
system.allClockGroupsNode := clockGroupAggNode := clockGroupsSourceNode
|
||||
system.chiptopClockGroupsNode := clockGroupAggNode := clockGroupsSourceNode
|
||||
|
||||
InModuleBody {
|
||||
val reset_io = IO(Input(AsyncReset()))
|
||||
@@ -119,3 +101,12 @@ class WithPassthroughClockGenerator extends OverrideLazyIOBinder({
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
class WithClockTapIOCells extends OverrideIOBinder({
|
||||
(system: CanHaveClockTap) => {
|
||||
system.clockTapIO.map { tap =>
|
||||
val (clock_tap_io, clock_tap_cell) = IOCell.generateIOFromSignal(tap.getWrappedValue, "clock_tap")
|
||||
(Seq(ClockTapPort(() => clock_tap_io)), clock_tap_cell)
|
||||
}.getOrElse((Nil, Nil))
|
||||
}
|
||||
})
|
||||
|
||||
@@ -2,7 +2,7 @@ package chipyard.clocking
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import chisel3.experimental.{Analog, IO}
|
||||
import chisel3.experimental.Analog
|
||||
|
||||
import org.chipsalliance.cde.config._
|
||||
import freechips.rocketchip.subsystem._
|
||||
|
||||
@@ -30,15 +30,14 @@ case class ChipyardPRCIControlParams(
|
||||
|
||||
case object ChipyardPRCIControlKey extends Field[ChipyardPRCIControlParams](ChipyardPRCIControlParams())
|
||||
|
||||
trait HasChipyardPRCI { this: BaseSubsystem with InstantiatesTiles =>
|
||||
require(p(SubsystemDriveAsyncClockGroupsKey).isEmpty, "Subsystem asyncClockGroups must be undriven")
|
||||
trait HasChipyardPRCI { this: BaseSubsystem with InstantiatesHierarchicalElements =>
|
||||
require(!p(SubsystemDriveClockGroupsFromIO), "Subsystem allClockGroups cannot be driven from implicit clocks")
|
||||
|
||||
val prciParams = p(ChipyardPRCIControlKey)
|
||||
|
||||
// Set up clock domain
|
||||
private val tlbus = locateTLBusWrapper(prciParams.slaveWhere)
|
||||
val prci_ctrl_domain = LazyModule(new ClockSinkDomain(name=Some("chipyard-prci-control")))
|
||||
prci_ctrl_domain.clockNode := tlbus.fixedClockNode
|
||||
val prci_ctrl_domain = tlbus.generateSynchronousDomain.suggestName("chipyard_prcictrl_domain")
|
||||
|
||||
val prci_ctrl_bus = Option.when(prciParams.generatePRCIXBar) { prci_ctrl_domain { TLXbar() } }
|
||||
prci_ctrl_bus.foreach(xbar => tlbus.coupleTo("prci_ctrl") { (xbar
|
||||
@@ -49,29 +48,13 @@ trait HasChipyardPRCI { this: BaseSubsystem with InstantiatesTiles =>
|
||||
|
||||
// Aggregate all the clock groups into a single node
|
||||
val aggregator = LazyModule(new ClockGroupAggregator("allClocks")).node
|
||||
val allClockGroupsNode = ClockGroupEphemeralNode()
|
||||
|
||||
// There are two "sets" of clocks which must be dealt with
|
||||
|
||||
// 1. The implicit clock from the subsystem. RC is moving away from depending on this
|
||||
// clock, but some modules still use it. Since the implicit clock sink node
|
||||
// is created in the ChipTop (the hierarchy wrapping the subsystem), this function
|
||||
// is provided to allow connecting that clock to the clock aggregator. This function
|
||||
// should be called in the ChipTop context
|
||||
def connectImplicitClockSinkNode(sink: ClockSinkNode) = {
|
||||
val implicitClockGrouper = this { ClockGroup() }
|
||||
(sink
|
||||
:= implicitClockGrouper
|
||||
:= aggregator)
|
||||
}
|
||||
|
||||
// 2. The rest of the diplomatic clocks in the subsystem are routed to this asyncClockGroupsNode
|
||||
// The diplomatic clocks in the subsystem are routed to this allClockGroupsNode
|
||||
val clockNamePrefixer = ClockGroupNamePrefixer()
|
||||
(asyncClockGroupsNode
|
||||
(allClockGroupsNode
|
||||
:*= clockNamePrefixer
|
||||
:*= aggregator)
|
||||
|
||||
|
||||
// Once all the clocks are gathered in the aggregator node, several steps remain
|
||||
// 1. Assign frequencies to any clock groups which did not specify a frequency.
|
||||
// 2. Combine duplicated clock groups (clock groups which physically should be in the same clock domain)
|
||||
@@ -92,7 +75,7 @@ trait HasChipyardPRCI { this: BaseSubsystem with InstantiatesTiles =>
|
||||
} }
|
||||
val tileResetSetter = Option.when(prciParams.enableTileResetSetting) { prci_ctrl_domain {
|
||||
val reset_setter = LazyModule(new TileResetSetter(prciParams.baseAddress + 0x10000, tlbus.beatBytes,
|
||||
tile_prci_domains.map(_.tile_reset_domain.clockNode.portParams(0).name.get), Nil))
|
||||
tile_prci_domains.map(_._2.tile_reset_domain.clockNode.portParams(0).name.get).toSeq, Nil))
|
||||
reset_setter.tlNode := TLFragmenter(tlbus.beatBytes, tlbus.blockBytes) := prci_ctrl_bus.get
|
||||
reset_setter
|
||||
} }
|
||||
@@ -116,11 +99,14 @@ RTL SIMULATORS, NAMELY VERILATOR.
|
||||
""" + Console.RESET)
|
||||
}
|
||||
|
||||
// The chiptopClockGroupsNode shouuld be what ClockBinders attach to
|
||||
val chiptopClockGroupsNode = ClockGroupEphemeralNode()
|
||||
|
||||
(aggregator
|
||||
:= frequencySpecifier
|
||||
:= clockGroupCombiner
|
||||
:= resetSynchronizer
|
||||
:= tileClockGater.map(_.clockNode).getOrElse(ClockGroupEphemeralNode()(ValName("temp")))
|
||||
:= tileResetSetter.map(_.clockNode).getOrElse(ClockGroupEphemeralNode()(ValName("temp")))
|
||||
:= allClockGroupsNode)
|
||||
:= chiptopClockGroupsNode)
|
||||
}
|
||||
|
||||
@@ -15,11 +15,27 @@ import testchipip.clocking._
|
||||
|
||||
// This module adds a TileLink memory-mapped clock divider to the clock graph
|
||||
// The output clock/reset pairs from this module should be synchronized later
|
||||
class TLClockDivider(address: BigInt, beatBytes: Int, divBits: Int = 8)(implicit p: Parameters) extends LazyModule {
|
||||
// If enable is unset, this will not divide the clock
|
||||
// DO NOT unset enable for VLSI, or prototyping flows. The disable feature is a work around for
|
||||
// some RTL simulators which do not simulate the reset synchronization properly
|
||||
class TLClockDivider(address: BigInt, beatBytes: Int, divBits: Int = 8, enable: Boolean = true)(implicit p: Parameters) extends LazyModule {
|
||||
val device = new SimpleDevice(s"clk-div-ctrl", Nil)
|
||||
val clockNode = ClockGroupIdentityNode()
|
||||
val tlNode = TLRegisterNode(Seq(AddressSet(address, 4096-1)), device, "reg/control", beatBytes=beatBytes)
|
||||
|
||||
if (!enable) println(Console.RED + s"""
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
WARNING:
|
||||
|
||||
YOU ARE USING THE TLCLOCKDIVIDER IN
|
||||
"DISABLED" MODE. THIS SHOULD ONLY BE DONE
|
||||
FOR RTL SIMULATION
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
""" + Console.RESET)
|
||||
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
require (clockNode.out.size == 1)
|
||||
val sources = clockNode.in.head._1.member.data.toSeq
|
||||
@@ -45,13 +61,21 @@ class TLClockDivider(address: BigInt, beatBytes: Int, divBits: Int = 8)(implicit
|
||||
// by setting divisor=0. The divisor signal into the ClockDividerOrPass is synchronized internally
|
||||
divider.io.divisor := Mux(busReset.asBool, 0.U, reg.io.q)
|
||||
divider.io.resetAsync := ResetStretcher(sources(i).clock, asyncReset, 20).asAsyncReset
|
||||
sinks(i)._2.clock := divider.io.clockOut
|
||||
|
||||
// Note this is not synchronized to the output clock, which takes time to appear
|
||||
// so this is still asyncreset
|
||||
// Stretch the reset for 40 cycles, to give enough time to reset any downstream
|
||||
// digital logic
|
||||
sinks(i)._2.reset := ResetStretcher(sources(i).clock, asyncReset, 40).asAsyncReset
|
||||
if (enable) {
|
||||
sinks(i)._2.clock := divider.io.clockOut
|
||||
|
||||
// Note this is not synchronized to the output clock, which takes time to appear
|
||||
// so this is still asyncreset
|
||||
// Stretch the reset for 40 cycles, to give enough time to reset any downstream
|
||||
// digital logic
|
||||
sinks(i)._2.reset := ResetStretcher(sources(i).clock, asyncReset, 40).asAsyncReset
|
||||
} else {
|
||||
// WARNING: THIS IS FOR RTL SIMULATION ONLY
|
||||
sinks(i)._2.clock := sources(i).clock
|
||||
sinks(i)._2.reset := sources(i).reset
|
||||
}
|
||||
|
||||
reg
|
||||
}
|
||||
|
||||
|
||||
@@ -21,12 +21,30 @@ case class ClockSelNode()(implicit valName: ValName)
|
||||
|
||||
// This module adds a TileLink memory-mapped clock mux for each downstream clock domain
|
||||
// in the clock graph. The output clock/reset should be synchronized downstream
|
||||
class TLClockSelector(address: BigInt, beatBytes: Int)(implicit p: Parameters) extends LazyModule {
|
||||
// If enable is unset, this will always pass through the 0'th clock
|
||||
// DO NOT unset enable for VLSI, or prototyping flows. The disable feature is a work around for
|
||||
// some RTL simulators which do not simulate the reset synchronization properly
|
||||
class TLClockSelector(address: BigInt, beatBytes: Int, enable: Boolean = true)(implicit p: Parameters) extends LazyModule {
|
||||
val device = new SimpleDevice("clk-sel-ctrl", Nil)
|
||||
val tlNode = TLRegisterNode(Seq(AddressSet(address, 4096-1)), device, "reg/control", beatBytes=beatBytes)
|
||||
|
||||
val clockNode = ClockSelNode()
|
||||
|
||||
if (!enable) println(Console.RED + s"""
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
WARNING:
|
||||
|
||||
YOU ARE USING THE TLCLOCKSELECTOR IN
|
||||
"DISABLED" MODE. THIS SHOULD ONLY BE DONE
|
||||
FOR RTL SIMULATION
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
""" + Console.RESET)
|
||||
|
||||
|
||||
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
val asyncReset = clockNode.in.map(_._1).map(_.reset).toSeq(0)
|
||||
val clocks = clockNode.in.map(_._1).map(_.clock)
|
||||
@@ -43,10 +61,15 @@ class TLClockSelector(address: BigInt, beatBytes: Int)(implicit p: Parameters) e
|
||||
val mux = ClockMutexMux(clocks).suggestName(s"${sinkName}_clkmux")
|
||||
mux.io.sel := sel
|
||||
mux.io.resetAsync := asyncReset.asAsyncReset
|
||||
sinks(i).clock := mux.io.clockOut
|
||||
// Stretch the reset for 20 cycles, to give time to reset any downstream digital logic
|
||||
sinks(i).reset := ResetStretcher(clocks(0), asyncReset, 20).asAsyncReset
|
||||
|
||||
if (enable) {
|
||||
sinks(i).clock := mux.io.clockOut
|
||||
// Stretch the reset for 20 cycles, to give time to reset any downstream digital logic
|
||||
sinks(i).reset := ResetStretcher(clocks(0), asyncReset, 20).asAsyncReset
|
||||
} else {
|
||||
// WARNING: THIS IS FOR RTL SIMULATION ONLY
|
||||
sinks(i).clock := clocks(0)
|
||||
sinks(i).reset := asyncReset
|
||||
}
|
||||
reg
|
||||
}
|
||||
tlNode.regmap((0 until sinks.size).map { i =>
|
||||
|
||||
@@ -2,7 +2,7 @@ package chipyard.clocking
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import chisel3.experimental.{Analog, IO}
|
||||
import chisel3.experimental.Analog
|
||||
|
||||
import org.chipsalliance.cde.config._
|
||||
import freechips.rocketchip.subsystem._
|
||||
|
||||
@@ -2,7 +2,7 @@ package chipyard.clocking
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import chisel3.experimental.{Analog, IO}
|
||||
import chisel3.experimental.Analog
|
||||
|
||||
import org.chipsalliance.cde.config._
|
||||
import freechips.rocketchip.subsystem._
|
||||
|
||||
@@ -11,23 +11,31 @@ import org.chipsalliance.cde.config.{Config}
|
||||
// --------------
|
||||
|
||||
class AbstractConfig extends Config(
|
||||
// ================================================
|
||||
// Set up TestHarness
|
||||
// ================================================
|
||||
// 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.WithBlackBoxSimMem ++ // add SimDRAM DRAM model for axi4 backing memory, if axi4 mem is enabled
|
||||
new chipyard.harness.WithSimTSIOverSerialTL ++ // add external serial-adapter and RAM
|
||||
new chipyard.harness.WithSimJTAGDebug ++ // add SimJTAG if JTAG for debug exposed
|
||||
new chipyard.harness.WithSimDMI ++ // add SimJTAG if DMI exposed
|
||||
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
|
||||
new chipyard.harness.WithCustomBootPinPlusArg ++ // drive custom-boot pin with a plusarg, if custom-boot-pin is present
|
||||
new chipyard.harness.WithSimUARTToUARTTSI ++ // connect a SimUART to the UART-TSI port
|
||||
new chipyard.harness.WithClockFromHarness ++ // all Clock I/O in ChipTop should be driven by harnessClockInstantiator
|
||||
new chipyard.harness.WithResetFromHarness ++ // reset controlled by harness
|
||||
new chipyard.harness.WithAbsoluteFreqHarnessClockInstantiator ++ // generate clocks in harness with unsynthesizable ClockSourceAtFreqMHz
|
||||
new chipyard.harness.WithUARTAdapter ++ /** add UART adapter to display UART on stdout, if uart is present */
|
||||
new chipyard.harness.WithBlackBoxSimMem ++ /** add SimDRAM DRAM model for axi4 backing memory, if axi4 mem is enabled */
|
||||
new chipyard.harness.WithSimTSIOverSerialTL ++ /** add external serial-adapter and RAM */
|
||||
new chipyard.harness.WithSimJTAGDebug ++ /** add SimJTAG if JTAG for debug exposed */
|
||||
new chipyard.harness.WithSimDMI ++ /** add SimJTAG if DMI exposed */
|
||||
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 */
|
||||
new chipyard.harness.WithCustomBootPinPlusArg ++ /** drive custom-boot pin with a plusarg, if custom-boot-pin is present */
|
||||
new chipyard.harness.WithDriveChipIdPin ++ /** drive chip id pin from harness binder, if chip id pin is present */
|
||||
new chipyard.harness.WithSimUARTToUARTTSI ++ /** connect a SimUART to the UART-TSI port */
|
||||
new chipyard.harness.WithClockFromHarness ++ /** all Clock I/O in ChipTop should be driven by harnessClockInstantiator */
|
||||
new chipyard.harness.WithResetFromHarness ++ /** reset controlled by harness */
|
||||
new chipyard.harness.WithAbsoluteFreqHarnessClockInstantiator ++ /** generate clocks in harness with unsynthesizable ClockSourceAtFreqMHz */
|
||||
|
||||
|
||||
// ================================================
|
||||
// Set up I/O cells + punch I/Os in ChipTop
|
||||
// ================================================
|
||||
// The IOBinders instantiate ChipTop IOs to match desired digital IOs
|
||||
// IOCells are generated for "Chip-like" IOs
|
||||
new chipyard.iobinders.WithSerialTLIOCells ++
|
||||
@@ -36,6 +44,7 @@ class AbstractConfig extends Config(
|
||||
new chipyard.iobinders.WithGPIOCells ++
|
||||
new chipyard.iobinders.WithSPIFlashIOCells ++
|
||||
new chipyard.iobinders.WithExtInterruptIOCells ++
|
||||
new chipyard.iobinders.WithChipIdIOCells ++
|
||||
new chipyard.iobinders.WithCustomBootPin ++
|
||||
// The "punchthrough" IOBInders below don't generate IOCells, as these interfaces shouldn't really be mapped to ASIC IO
|
||||
// Instead, they directly pass through the DigitalTop ports to ports in the ChipTop
|
||||
@@ -51,40 +60,98 @@ class AbstractConfig extends Config(
|
||||
new chipyard.iobinders.WithUARTTSIPunchthrough ++
|
||||
new chipyard.iobinders.WithNMITiedOff ++
|
||||
|
||||
// By default, punch out IOs to the Harness
|
||||
new chipyard.clocking.WithPassthroughClockGenerator ++
|
||||
new chipyard.clocking.WithClockGroupsCombinedByName(("uncore", Seq("sbus", "mbus", "pbus", "fbus", "cbus", "obus", "implicit"), Seq("tile"))) ++
|
||||
new chipyard.config.WithPeripheryBusFrequency(500.0) ++ // Default 500 MHz pbus
|
||||
new chipyard.config.WithMemoryBusFrequency(500.0) ++ // Default 500 MHz mbus
|
||||
new chipyard.config.WithControlBusFrequency(500.0) ++ // Default 500 MHz cbus
|
||||
new chipyard.config.WithSystemBusFrequency(500.0) ++ // Default 500 MHz sbus
|
||||
new chipyard.config.WithFrontBusFrequency(500.0) ++ // Default 500 MHz fbus
|
||||
new chipyard.config.WithOffchipBusFrequency(500.0) ++ // Default 500 MHz obus
|
||||
|
||||
new testchipip.boot.WithCustomBootPin ++ // add a custom-boot-pin to support pin-driven boot address
|
||||
new testchipip.boot.WithBootAddrReg ++ // add a boot-addr-reg for configurable boot address
|
||||
new testchipip.serdes.WithSerialTL(Seq( // add a serial-tilelink interface
|
||||
// ================================================
|
||||
// Set up External Memory and IO Devices
|
||||
// ================================================
|
||||
// External memory section
|
||||
new testchipip.serdes.WithSerialTL(Seq( /** add a serial-tilelink interface */
|
||||
testchipip.serdes.SerialTLParams(
|
||||
client = Some(testchipip.serdes.SerialTLClientParams(idBits=4)), // serial-tilelink interface will master the FBUS, and support 4 idBits
|
||||
width = 32 // serial-tilelink interface with 32 lanes
|
||||
client = Some(testchipip.serdes.SerialTLClientParams(totalIdBits=4)), // serial-tilelink interface will master the FBUS, and support 4 idBits
|
||||
phyParams = testchipip.serdes.ExternalSyncSerialPhyParams(phitWidth=32, flitWidth=32) // serial-tilelink interface with 32 lanes
|
||||
)
|
||||
)) ++
|
||||
new testchipip.soc.WithMbusScratchpad(base = 0x08000000, // add 64 KiB on-chip scratchpad
|
||||
new freechips.rocketchip.subsystem.WithNMemoryChannels(1) ++ /** Default 1 AXI-4 memory channels */
|
||||
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) */
|
||||
|
||||
// MMIO device section
|
||||
new chipyard.config.WithUART ++ /** add a UART */
|
||||
|
||||
|
||||
// ================================================
|
||||
// Set up Debug/Bringup/Testing Features
|
||||
// ================================================
|
||||
// JTAG
|
||||
new freechips.rocketchip.subsystem.WithDebugSBA ++ /** enable the SBA (system-bus-access) feature of the debug module */
|
||||
new chipyard.config.WithDebugModuleAbstractDataWords(8) ++ /** increase debug module data word capacity */
|
||||
new freechips.rocketchip.subsystem.WithJtagDTM ++ /** set the debug module to expose a JTAG port */
|
||||
|
||||
// Boot Select Pins
|
||||
new testchipip.boot.WithCustomBootPin ++ /** add a custom-boot-pin to support pin-driven boot address */
|
||||
new testchipip.boot.WithBootAddrReg ++ /** add a boot-addr-reg for configurable boot address */
|
||||
|
||||
|
||||
// ================================================
|
||||
// Set up Interrupts
|
||||
// ================================================
|
||||
// CLINT and PLIC related settings goes here
|
||||
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ /** no external interrupts */
|
||||
|
||||
|
||||
// ================================================
|
||||
// Set up Tiles
|
||||
// ================================================
|
||||
// tile-local settings goes here
|
||||
|
||||
|
||||
// ================================================
|
||||
// Set up Memory system
|
||||
// ================================================
|
||||
// On-chip memory section
|
||||
new freechips.rocketchip.subsystem.WithDTS("ucb-bar,chipyard", Nil) ++ /** custom device name for DTS (embedded in BootROM) */
|
||||
new chipyard.config.WithBootROM ++ /** use default bootrom */
|
||||
new testchipip.soc.WithMbusScratchpad(base = 0x08000000, /** add 64 KiB on-chip scratchpad */
|
||||
size = 64 * 1024) ++
|
||||
new chipyard.config.WithDebugModuleAbstractDataWords(8) ++ // increase debug module data capacity
|
||||
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 freechips.rocketchip.subsystem.WithNMemoryChannels(1) ++ // Default 1 memory channels
|
||||
new freechips.rocketchip.subsystem.WithClockGateModel ++ // add default EICG_wrapper clock gate model
|
||||
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 freechips.rocketchip.subsystem.WithDontDriveBusClocksFromSBus ++ // leave the bus clocks undriven by sbus
|
||||
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ // hierarchical buses including sbus/mbus/pbus/fbus/cbus/l2
|
||||
new freechips.rocketchip.subsystem.WithDTS("ucb-bar,chipyard", Nil) ++ // custom device name for DTS
|
||||
new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system
|
||||
|
||||
// Coherency settings
|
||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++ /** use Sifive LLC cache as root of coherence */
|
||||
|
||||
// Bus/interconnect settings
|
||||
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ /** hierarchical buses including sbus/mbus/pbus/fbus/cbus/l2 */
|
||||
|
||||
|
||||
// ================================================
|
||||
// Set up power, reset and clocking
|
||||
// ================================================
|
||||
|
||||
// ChipTop clock IO/PLL/Divider/Mux settings
|
||||
new chipyard.clocking.WithClockTapIOCells ++ /** Default generate a clock tapio */
|
||||
new chipyard.clocking.WithPassthroughClockGenerator ++
|
||||
|
||||
// DigitalTop-internal clocking settings
|
||||
new freechips.rocketchip.subsystem.WithDontDriveBusClocksFromSBus ++ /** leave the bus clocks undriven by sbus */
|
||||
new freechips.rocketchip.subsystem.WithClockGateModel ++ /** add default EICG_wrapper clock gate model */
|
||||
new chipyard.clocking.WithClockGroupsCombinedByName(("uncore", /** create a "uncore" clock group tieing all the bus clocks together */
|
||||
Seq("sbus", "mbus", "pbus", "fbus", "cbus", "obus", "implicit", "clock_tap"),
|
||||
Seq("tile"))) ++
|
||||
|
||||
new chipyard.config.WithPeripheryBusFrequency(500.0) ++ /** Default 500 MHz pbus */
|
||||
new chipyard.config.WithMemoryBusFrequency(500.0) ++ /** Default 500 MHz mbus */
|
||||
new chipyard.config.WithControlBusFrequency(500.0) ++ /** Default 500 MHz cbus */
|
||||
new chipyard.config.WithSystemBusFrequency(500.0) ++ /** Default 500 MHz sbus */
|
||||
new chipyard.config.WithFrontBusFrequency(500.0) ++ /** Default 500 MHz fbus */
|
||||
new chipyard.config.WithOffchipBusFrequency(500.0) ++ /** Default 500 MHz obus */
|
||||
new chipyard.config.WithInheritBusFrequencyAssignments ++ /** Unspecified clocks within a bus will receive the bus frequency if set */
|
||||
new chipyard.config.WithNoSubsystemClockIO ++ /** drive the subsystem diplomatic clocks from ChipTop instead of using implicit clocks */
|
||||
|
||||
// reset
|
||||
|
||||
// power
|
||||
|
||||
|
||||
// ==================================
|
||||
// Base Settings
|
||||
// ==================================
|
||||
new freechips.rocketchip.system.BaseConfig /** "base" rocketchip system */
|
||||
)
|
||||
|
||||
@@ -22,8 +22,18 @@ class ChipLikeRocketConfig extends Config(
|
||||
//==================================
|
||||
// Set up I/O
|
||||
//==================================
|
||||
new testchipip.serdes.WithSerialTLWidth(4) ++ // 4bit wide Serialized TL interface to minimize IO
|
||||
new testchipip.serdes.WithSerialTLMem(size = (1 << 30) * 4L) ++ // Configure the off-chip memory accessible over serial-tl as backing memory
|
||||
new testchipip.serdes.WithSerialTL(Seq(testchipip.serdes.SerialTLParams( // 1 serial tilelink port
|
||||
manager = Some(testchipip.serdes.SerialTLManagerParams( // port acts as a manager of offchip memory
|
||||
memParams = Seq(testchipip.serdes.ManagerRAMParams( // 4 GB of off-chip memory
|
||||
address = BigInt("80000000", 16),
|
||||
size = BigInt("100000000", 16)
|
||||
)),
|
||||
isMemoryDevice = true
|
||||
)),
|
||||
client = Some(testchipip.serdes.SerialTLClientParams()), // Allow an external manager to probe this chip
|
||||
phyParams = testchipip.serdes.ExternalSyncSerialPhyParams(phitWidth=4, flitWidth=16) // 4-bit bidir interface, sync'd to an external clock
|
||||
))) ++
|
||||
|
||||
new freechips.rocketchip.subsystem.WithNoMemPort ++ // Remove axi4 mem port
|
||||
new freechips.rocketchip.subsystem.WithNMemoryChannels(1) ++ // 1 memory channel
|
||||
|
||||
@@ -60,10 +70,16 @@ class ChipBringupHostConfig extends Config(
|
||||
//=============================
|
||||
// Setup the SerialTL side on the bringup device
|
||||
//=============================
|
||||
new testchipip.serdes.WithSerialTLWidth(4) ++ // match width with the chip
|
||||
new testchipip.serdes.WithSerialTLMem(base = 0x0, size = 0x80000000L, // accessible memory of the chip that doesn't come from the tethered host
|
||||
idBits = 4, isMainMemory = false) ++ // This assumes off-chip mem starts at 0x8000_0000
|
||||
new testchipip.serdes.WithSerialTLClockDirection(provideClockFreqMHz = Some(75)) ++ // bringup board drives the clock for the serial-tl receiver on the chip, use 75MHz clock
|
||||
new testchipip.serdes.WithSerialTL(Seq(testchipip.serdes.SerialTLParams(
|
||||
manager = Some(testchipip.serdes.SerialTLManagerParams(
|
||||
memParams = Seq(testchipip.serdes.ManagerRAMParams( // Bringup platform can access all memory from 0 to DRAM_BASE
|
||||
address = BigInt("00000000", 16),
|
||||
size = BigInt("80000000", 16)
|
||||
))
|
||||
)),
|
||||
client = Some(testchipip.serdes.SerialTLClientParams()), // Allow chip to access this device's memory (DRAM)
|
||||
phyParams = testchipip.serdes.InternalSyncSerialPhyParams(phitWidth=4, flitWidth=16, freqMHz = 75) // bringup platform provides the clock
|
||||
))) ++
|
||||
|
||||
//============================
|
||||
// Setup bus topology on the bringup system
|
||||
@@ -110,5 +126,9 @@ class TetheredChipLikeRocketConfig extends Config(
|
||||
class VerilatorCITetheredChipLikeRocketConfig 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 chipyard.config.WithNoResetSynchronizers ++ new ChipLikeRocketConfig) ++
|
||||
new chipyard.harness.WithMultiChip(0, // These fragments remove all troublesome
|
||||
new chipyard.clocking.WithPLLSelectorDividerClockGenerator(enable=false) ++ // clocking features from the design
|
||||
new chipyard.iobinders.WithDebugIOCells(syncReset = false) ++
|
||||
new chipyard.config.WithNoResetSynchronizers ++
|
||||
new ChipLikeRocketConfig) ++
|
||||
new chipyard.harness.WithMultiChip(1, new ChipBringupHostConfig))
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
package chipyard
|
||||
|
||||
import org.chipsalliance.cde.config.{Config}
|
||||
import freechips.rocketchip.diplomacy.{AddressSet}
|
||||
import freechips.rocketchip.subsystem.{SBUS}
|
||||
import testchipip.soc.{OBUS}
|
||||
|
||||
// ------------------------------------------------
|
||||
// Configs demonstrating chip-to-chip communication
|
||||
// ------------------------------------------------
|
||||
|
||||
// Simple design which exposes a second serial-tl port that can connect to another instance of itself
|
||||
class SymmetricChipletRocketConfig extends Config(
|
||||
new testchipip.soc.WithChipIdPin ++ // Add pin to identify chips
|
||||
new chipyard.harness.WithSerialTLTiedOff(tieoffs=Some(Seq(1))) ++ // Tie-off the chip-to-chip link in single-chip sims
|
||||
new testchipip.serdes.WithSerialTL(Seq(
|
||||
testchipip.serdes.SerialTLParams( // 0th serial-tl is chip-to-bringup-fpga
|
||||
client = Some(testchipip.serdes.SerialTLClientParams()), // bringup serial-tl acts only as a client
|
||||
phyParams = testchipip.serdes.ExternalSyncSerialPhyParams() // bringup serial-tl is sync'd to external clock
|
||||
),
|
||||
testchipip.serdes.SerialTLParams( // 1st serial-tl is chip-to-chip
|
||||
client = Some(testchipip.serdes.SerialTLClientParams()), // chip-to-chip serial-tl acts as a client
|
||||
manager = Some(testchipip.serdes.SerialTLManagerParams( // chip-to-chip serial-tl managers other chip's memory
|
||||
memParams = Seq(testchipip.serdes.ManagerRAMParams(
|
||||
address = 0,
|
||||
size = 1L << 32,
|
||||
)),
|
||||
slaveWhere = OBUS
|
||||
)),
|
||||
phyParams = testchipip.serdes.SourceSyncSerialPhyParams() // chip-to-chip serial-tl is symmetric source-sync'd
|
||||
))
|
||||
) ++
|
||||
new testchipip.soc.WithOffchipBusClient(SBUS, // obus provides path to other chip's memory
|
||||
blockRange = Seq(AddressSet(0, (1L << 32) - 1)), // The lower 4GB is mapped to this chip
|
||||
replicationBase = Some(1L << 32) // The upper 4GB goes off-chip
|
||||
) ++
|
||||
new testchipip.soc.WithOffchipBus ++
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
// Simulates 2X of the SymmetricChipletRocketConfig in a multi-sim config
|
||||
class MultiSimSymmetricChipletRocketConfig extends Config(
|
||||
new chipyard.harness.WithAbsoluteFreqHarnessClockInstantiator ++
|
||||
new chipyard.harness.WithMultiChipSerialTL(chip0=0, chip1=1, chip0portId=1, chip1portId=1) ++
|
||||
new chipyard.harness.WithMultiChip(0, new SymmetricChipletRocketConfig) ++
|
||||
new chipyard.harness.WithMultiChip(1, new SymmetricChipletRocketConfig)
|
||||
)
|
||||
|
||||
// Core-only chiplet config, where the coherent memory is located on the LLC-chiplet
|
||||
class RocketCoreChipletConfig extends Config(
|
||||
new testchipip.serdes.WithSerialTL(Seq(
|
||||
testchipip.serdes.SerialTLParams(
|
||||
client = Some(testchipip.serdes.SerialTLClientParams()),
|
||||
phyParams = testchipip.serdes.ExternalSyncSerialPhyParams() // chip-to-chip serial-tl is symmetric source-sync'd
|
||||
),
|
||||
testchipip.serdes.SerialTLParams(
|
||||
manager = Some(testchipip.serdes.SerialTLManagerParams(
|
||||
cohParams = Seq(testchipip.serdes.ManagerCOHParams(
|
||||
address = BigInt("80000000", 16),
|
||||
size = BigInt("100000000", 16)
|
||||
)),
|
||||
slaveWhere = OBUS,
|
||||
isMemoryDevice = true
|
||||
)),
|
||||
phyParams = testchipip.serdes.SourceSyncSerialPhyParams()
|
||||
)
|
||||
)) ++
|
||||
new testchipip.soc.WithOffchipBusClient(SBUS) ++
|
||||
new testchipip.soc.WithOffchipBus ++
|
||||
new testchipip.soc.WithNoScratchpads ++
|
||||
new freechips.rocketchip.subsystem.WithIncoherentBusTopology ++
|
||||
new freechips.rocketchip.subsystem.WithNoMemPort ++
|
||||
new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
// LLC-only chiplet
|
||||
class LLCChipletConfig extends Config(
|
||||
new chipyard.harness.WithSerialTLTiedOff ++
|
||||
new testchipip.serdes.WithSerialTL(Seq(testchipip.serdes.SerialTLParams( // 1st serial-tl is chip-to-chip
|
||||
client = Some(testchipip.serdes.SerialTLClientParams(supportsProbe=true)),
|
||||
phyParams = testchipip.serdes.SourceSyncSerialPhyParams() // chip-to-chip serial-tl is symmetric source-sync'd
|
||||
))) ++
|
||||
new freechips.rocketchip.subsystem.WithExtMemSize((1 << 30) * 4L) ++
|
||||
new chipyard.NoCoresConfig
|
||||
)
|
||||
|
||||
class MultiSimLLCChipletRocketConfig extends Config(
|
||||
new chipyard.harness.WithAbsoluteFreqHarnessClockInstantiator ++
|
||||
new chipyard.harness.WithMultiChipSerialTL(chip0=0, chip1=1, chip0portId=1, chip1portId=0) ++
|
||||
new chipyard.harness.WithMultiChip(0, new RocketCoreChipletConfig) ++
|
||||
new chipyard.harness.WithMultiChip(1, new LLCChipletConfig)
|
||||
)
|
||||
@@ -39,3 +39,8 @@ class QuadChannelRocketConfig extends Config(
|
||||
new freechips.rocketchip.subsystem.WithNMemoryChannels(4) ++ // 4 AXI4 channels
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
class BroadcastCoherenceRocketConfig extends Config(
|
||||
new chipyard.config.WithBroadcastManager ++ // Use broadcast-based coherence hub
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
@@ -75,6 +75,7 @@ class ManyPeripheralsRocketConfig extends Config(
|
||||
new testchipip.serdes.WithSerialTLMem(isMainMemory=true) ++ // set lbwif memory base to DRAM_BASE, use as main memory
|
||||
new chipyard.harness.WithSimSPIFlashModel(true) ++ // add the SPI flash model in the harness (read-only)
|
||||
new chipyard.harness.WithSimBlockDevice ++ // drive block-device IOs with SimBlockDevice
|
||||
new chipyard.config.WithPeripheryTimer ++ // add the pwm timer device
|
||||
new chipyard.config.WithSPIFlash ++ // add the SPI flash controller
|
||||
new freechips.rocketchip.subsystem.WithDefaultMMIOPort ++ // add default external master port
|
||||
new freechips.rocketchip.subsystem.WithDefaultSlavePort ++ // add default external slave port
|
||||
|
||||
@@ -2,6 +2,7 @@ package chipyard
|
||||
|
||||
import org.chipsalliance.cde.config.{Config}
|
||||
import freechips.rocketchip.diplomacy.{AsynchronousCrossing}
|
||||
import freechips.rocketchip.subsystem.{InCluster}
|
||||
|
||||
// --------------
|
||||
// Rocket Configs
|
||||
@@ -62,7 +63,7 @@ class MulticlockRocketConfig extends Config(
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
// Frequency specifications
|
||||
new chipyard.config.WithTileFrequency(1000.0) ++ // Matches the maximum frequency of U540
|
||||
new chipyard.clocking.WithClockGroupsCombinedByName(("uncore" , Seq("sbus", "cbus", "implicit"), Nil),
|
||||
new chipyard.clocking.WithClockGroupsCombinedByName(("uncore" , Seq("sbus", "cbus", "implicit", "clock_tap"), Nil),
|
||||
("periphery", Seq("pbus", "fbus"), Nil)) ++
|
||||
new chipyard.config.WithSystemBusFrequency(500.0) ++ // Matches the maximum frequency of U540
|
||||
new chipyard.config.WithMemoryBusFrequency(500.0) ++ // Matches the maximum frequency of U540
|
||||
@@ -88,3 +89,14 @@ class PrefetchingRocketConfig extends Config(
|
||||
new freechips.rocketchip.subsystem.WithNonblockingL1(2) ++ // non-blocking L1D$, L1 prefetching only works with non-blocking L1D$
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // single rocket-core
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
class ClusteredRocketConfig extends Config(
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(4, location=InCluster(1)) ++
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(4, location=InCluster(0)) ++
|
||||
new freechips.rocketchip.subsystem.WithCluster(1) ++
|
||||
new freechips.rocketchip.subsystem.WithCluster(0) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
class FastRTLSimRocketConfig extends Config(
|
||||
new freechips.rocketchip.subsystem.WithoutTLMonitors ++
|
||||
new chipyard.RocketConfig)
|
||||
|
||||
@@ -12,10 +12,11 @@ class AbstractTraceGenConfig extends Config(
|
||||
new chipyard.iobinders.WithAXI4MemPunchthrough ++
|
||||
new chipyard.iobinders.WithTraceGenSuccessPunchthrough ++
|
||||
new chipyard.clocking.WithPassthroughClockGenerator ++
|
||||
new chipyard.clocking.WithClockGroupsCombinedByName(("uncore", Seq("sbus", "implicit"), Nil)) ++
|
||||
new chipyard.clocking.WithClockGroupsCombinedByName(("uncore", Seq("sbus"), Nil)) ++
|
||||
new chipyard.config.WithTracegenSystem ++
|
||||
new chipyard.config.WithNoSubsystemDrivenClocks ++
|
||||
new chipyard.config.WithNoSubsystemClockIO ++
|
||||
new chipyard.config.WithMemoryBusFrequency(1000.0) ++
|
||||
new chipyard.config.WithControlBusFrequency(1000.0) ++
|
||||
new chipyard.config.WithSystemBusFrequency(1000.0) ++
|
||||
new chipyard.config.WithPeripheryBusFrequency(1000.0) ++
|
||||
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++
|
||||
|
||||
@@ -19,8 +19,8 @@ import testchipip.soc.{OffchipBusKey}
|
||||
// with the implicit clocks of Subsystem. Don't do that, instead we extend
|
||||
// the diplomacy graph upwards into the ChipTop, where we connect it to
|
||||
// our clock drivers
|
||||
class WithNoSubsystemDrivenClocks extends Config((site, here, up) => {
|
||||
case SubsystemDriveAsyncClockGroupsKey => None
|
||||
class WithNoSubsystemClockIO extends Config((site, here, up) => {
|
||||
case SubsystemDriveClockGroupsFromIO => false
|
||||
})
|
||||
|
||||
/**
|
||||
@@ -111,14 +111,22 @@ class WithOffchipBusFrequency(freqMHz: Double) extends Config((site, here, up) =
|
||||
class WithRationalMemoryBusCrossing extends WithSbusToMbusCrossingType(RationalCrossing(Symmetric))
|
||||
class WithAsynchrousMemoryBusCrossing extends WithSbusToMbusCrossingType(AsynchronousCrossing())
|
||||
|
||||
// Remove the tile clock gaters in this system
|
||||
class WithNoTileClockGaters extends Config((site, here, up) => {
|
||||
case ChipyardPRCIControlKey => up(ChipyardPRCIControlKey).copy(enableTileClockGating = false)
|
||||
})
|
||||
|
||||
// Remove the tile reset control blocks in this system
|
||||
class WithNoTileResetSetters extends Config((site, here, up) => {
|
||||
case ChipyardPRCIControlKey => up(ChipyardPRCIControlKey).copy(enableTileResetSetting = false)
|
||||
})
|
||||
|
||||
// Remove the global reset synchronizers in this system
|
||||
class WithNoResetSynchronizers extends Config((site, here, up) => {
|
||||
case ChipyardPRCIControlKey => up(ChipyardPRCIControlKey).copy(enableResetSynchronizers = false)
|
||||
})
|
||||
|
||||
// Remove any ClockTap ports in this system
|
||||
class WithNoClockTap extends Config((site, here, up) => {
|
||||
case ClockTapKey => false
|
||||
})
|
||||
|
||||
@@ -16,6 +16,7 @@ import sifive.blocks.devices.gpio._
|
||||
import sifive.blocks.devices.uart._
|
||||
import sifive.blocks.devices.spi._
|
||||
import sifive.blocks.devices.i2c._
|
||||
import sifive.blocks.devices.timer._
|
||||
|
||||
import testchipip._
|
||||
|
||||
@@ -169,3 +170,7 @@ class WithNoBusErrorDevices extends Config((site, here, up) => {
|
||||
case MemoryBusKey => up(MemoryBusKey).copy(errorDevice = None)
|
||||
case FrontBusKey => up(FrontBusKey).copy(errorDevice = None)
|
||||
})
|
||||
|
||||
class WithPeripheryTimer(timerParams: TimerParams = TimerParams(0x4000)) extends Config((site, here, up) => {
|
||||
case PeripheryTimerKey => Seq(timerParams)
|
||||
})
|
||||
|
||||
@@ -12,15 +12,15 @@ import gemmini._
|
||||
import chipyard.{TestSuitesKey, TestSuiteHelper}
|
||||
|
||||
/**
|
||||
* Map from a hartId to a particular RoCC accelerator
|
||||
* Map from a tileId to a particular RoCC accelerator
|
||||
*/
|
||||
case object MultiRoCCKey extends Field[Map[Int, Seq[Parameters => LazyRoCC]]](Map.empty[Int, Seq[Parameters => LazyRoCC]])
|
||||
|
||||
/**
|
||||
* Config fragment to enable different RoCCs based on the hartId
|
||||
* Config fragment to enable different RoCCs based on the tileId
|
||||
*/
|
||||
class WithMultiRoCC extends Config((site, here, up) => {
|
||||
case BuildRoCC => site(MultiRoCCKey).getOrElse(site(TileKey).hartId, Nil)
|
||||
case BuildRoCC => site(MultiRoCCKey).getOrElse(site(TileKey).tileId, Nil)
|
||||
})
|
||||
|
||||
/**
|
||||
@@ -39,7 +39,7 @@ class WithMultiRoCCFromBuildRoCC(harts: Int*) extends Config((site, here, up) =>
|
||||
*
|
||||
* For ex:
|
||||
* Core 0, 1, 2, 3 have been defined earlier
|
||||
* with hartIds of 0, 1, 2, 3 respectively
|
||||
* with tileIds of 0, 1, 2, 3 respectively
|
||||
* And you call WithMultiRoCCHwacha(0,1)
|
||||
* Then Core 0 and 1 will get a Hwacha
|
||||
*
|
||||
|
||||
@@ -7,7 +7,7 @@ import sifive.blocks.inclusivecache.{InclusiveCachePortParameters}
|
||||
|
||||
// Replaces the L2 with a broadcast manager for maintaining coherence
|
||||
class WithBroadcastManager extends Config((site, here, up) => {
|
||||
case BankedL2Key => up(BankedL2Key, site).copy(coherenceManager = CoherenceManagerWrapper.broadcastManager)
|
||||
case SubsystemBankedCoherenceKey => up(SubsystemBankedCoherenceKey, site).copy(coherenceManager = CoherenceManagerWrapper.broadcastManager)
|
||||
})
|
||||
|
||||
class WithBroadcastParams(params: BroadcastParams) extends Config((site, here, up) => {
|
||||
|
||||
@@ -78,7 +78,7 @@ class WithRocketCacheRowBits(rowBits: Int = 64) extends Config((site, here, up)
|
||||
class WithRocketICacheScratchpad extends Config((site, here, up) => {
|
||||
case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
|
||||
case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
|
||||
icache = tp.tileParams.icache.map(_.copy(itimAddr = Some(0x300000 + tp.tileParams.hartId * 0x10000)))
|
||||
icache = tp.tileParams.icache.map(_.copy(itimAddr = Some(0x300000 + tp.tileParams.tileId * 0x10000)))
|
||||
))
|
||||
}
|
||||
})
|
||||
@@ -86,7 +86,7 @@ class WithRocketICacheScratchpad extends Config((site, here, up) => {
|
||||
class WithRocketDCacheScratchpad extends Config((site, here, up) => {
|
||||
case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
|
||||
case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
|
||||
dcache = tp.tileParams.dcache.map(_.copy(nSets = 32, nWays = 1, scratch = Some(0x200000 + tp.tileParams.hartId * 0x10000)))
|
||||
dcache = tp.tileParams.dcache.map(_.copy(nSets = 32, nWays = 1, scratch = Some(0x200000 + tp.tileParams.tileId * 0x10000)))
|
||||
))
|
||||
}
|
||||
})
|
||||
@@ -94,15 +94,15 @@ class WithRocketDCacheScratchpad extends Config((site, here, up) => {
|
||||
class WithTilePrefetchers extends Config((site, here, up) => {
|
||||
case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
|
||||
case tp: RocketTileAttachParams => tp.copy(crossingParams = tp.crossingParams.copy(
|
||||
master = TilePrefetchingMasterPortParams(tp.tileParams.hartId, tp.crossingParams.master)))
|
||||
master = TilePrefetchingMasterPortParams(tp.tileParams.tileId, tp.crossingParams.master)))
|
||||
case tp: BoomTileAttachParams => tp.copy(crossingParams = tp.crossingParams.copy(
|
||||
master = TilePrefetchingMasterPortParams(tp.tileParams.hartId, tp.crossingParams.master)))
|
||||
master = TilePrefetchingMasterPortParams(tp.tileParams.tileId, tp.crossingParams.master)))
|
||||
case tp: SodorTileAttachParams => tp.copy(crossingParams = tp.crossingParams.copy(
|
||||
master = TilePrefetchingMasterPortParams(tp.tileParams.hartId, tp.crossingParams.master)))
|
||||
master = TilePrefetchingMasterPortParams(tp.tileParams.tileId, tp.crossingParams.master)))
|
||||
case tp: IbexTileAttachParams => tp.copy(crossingParams = tp.crossingParams.copy(
|
||||
master = TilePrefetchingMasterPortParams(tp.tileParams.hartId, tp.crossingParams.master)))
|
||||
master = TilePrefetchingMasterPortParams(tp.tileParams.tileId, tp.crossingParams.master)))
|
||||
case tp: CVA6TileAttachParams => tp.copy(crossingParams = tp.crossingParams.copy(
|
||||
master = TilePrefetchingMasterPortParams(tp.tileParams.hartId, tp.crossingParams.master)))
|
||||
master = TilePrefetchingMasterPortParams(tp.tileParams.tileId, tp.crossingParams.master)))
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -30,9 +30,6 @@ class FlatChipTop(implicit p: Parameters) extends LazyModule with HasChipyardPor
|
||||
//========================
|
||||
// Diplomatic clock stuff
|
||||
//========================
|
||||
val implicitClockSinkNode = ClockSinkNode(Seq(ClockSinkParameters(name = Some("implicit_clock"))))
|
||||
system.connectImplicitClockSinkNode(implicitClockSinkNode)
|
||||
|
||||
val tlbus = system.locateTLBusWrapper(system.prciParams.slaveWhere)
|
||||
val baseAddress = system.prciParams.baseAddress
|
||||
val clockDivider = system.prci_ctrl_domain { LazyModule(new TLClockDivider (baseAddress + 0x20000, tlbus.beatBytes)) }
|
||||
@@ -43,7 +40,7 @@ class FlatChipTop(implicit p: Parameters) extends LazyModule with HasChipyardPor
|
||||
tlbus.coupleTo("clock-sel-ctrl") { clockSelector.tlNode := TLFragmenter(tlbus.beatBytes, tlbus.blockBytes) := TLBuffer() := _ }
|
||||
tlbus.coupleTo("pll-ctrl") { pllCtrl.tlNode := TLFragmenter(tlbus.beatBytes, tlbus.blockBytes) := TLBuffer() := _ }
|
||||
|
||||
system.allClockGroupsNode := clockDivider.clockNode := clockSelector.clockNode
|
||||
system.chiptopClockGroupsNode := clockDivider.clockNode := clockSelector.clockNode
|
||||
|
||||
// Connect all other requested clocks
|
||||
val slowClockSource = ClockSourceNode(Seq(ClockSourceParameters()))
|
||||
@@ -69,13 +66,6 @@ class FlatChipTop(implicit p: Parameters) extends LazyModule with HasChipyardPor
|
||||
//=========================
|
||||
// Clock/reset
|
||||
//=========================
|
||||
val implicit_clock = implicitClockSinkNode.in.head._1.clock
|
||||
val implicit_reset = implicitClockSinkNode.in.head._1.reset
|
||||
system.module match { case l: LazyModuleImp => {
|
||||
l.clock := implicit_clock
|
||||
l.reset := implicit_reset
|
||||
}}
|
||||
|
||||
val clock_wire = Wire(Input(Clock()))
|
||||
val reset_wire = Wire(Input(AsyncReset()))
|
||||
val (clock_pad, clockIOCell) = IOCell.generateIOFromSignal(clock_wire, "clock", p(IOCellKey))
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
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}
|
||||
@@ -11,10 +10,10 @@ import freechips.rocketchip.util.{PlusArg}
|
||||
import freechips.rocketchip.subsystem.{CacheBlockBytes}
|
||||
import freechips.rocketchip.devices.debug.{SimJTAG}
|
||||
import freechips.rocketchip.jtag.{JTAGIO}
|
||||
import testchipip.serdes.{SerialTLKey}
|
||||
import testchipip.serdes._
|
||||
import testchipip.uart.{UARTAdapter}
|
||||
import testchipip.dram.{SimDRAM}
|
||||
import testchipip.tsi.{TSIHarness, SimTSI}
|
||||
import testchipip.tsi.{TSIHarness, SimTSI, SerialRAM}
|
||||
import chipyard.harness.{BuildTop}
|
||||
|
||||
// A "flat" TestHarness that doesn't use IOBinders
|
||||
@@ -46,18 +45,28 @@ class FlatTestHarness(implicit val p: Parameters) extends Module {
|
||||
val serialTLManagerParams = sVal.manager.get
|
||||
require(serialTLManagerParams.isMemoryDevice)
|
||||
|
||||
withClockAndReset(clock, reset) {
|
||||
val serial_bits = dut.serial_tl_pad.bits
|
||||
if (DataMirror.directionOf(dut.serial_tl_pad.clock) == Direction.Input) {
|
||||
dut.serial_tl_pad.clock := clock
|
||||
}
|
||||
val harnessRAM = TSIHarness.connectRAM(
|
||||
p(SerialTLKey)(0),
|
||||
lazyDut.system.serdessers(0),
|
||||
serial_bits,
|
||||
reset)
|
||||
io.success := SimTSI.connect(harnessRAM.module.io.tsi, clock, reset)
|
||||
// Figure out which clock drives the harness TLSerdes, based on the port type
|
||||
val serial_ram_clock = dut.serial_tl_pad match {
|
||||
case io: InternalSyncPhitIO => io.clock_out
|
||||
case io: ExternalSyncPhitIO => clock
|
||||
}
|
||||
dut.serial_tl_pad match {
|
||||
case io: ExternalSyncPhitIO => io.clock_in := clock
|
||||
case io: InternalSyncPhitIO =>
|
||||
}
|
||||
|
||||
dut.serial_tl_pad match {
|
||||
case pad: DecoupledPhitIO => {
|
||||
withClockAndReset(serial_ram_clock, reset) {
|
||||
// SerialRAM implements the memory regions the chip expects
|
||||
val ram = Module(LazyModule(new SerialRAM(lazyDut.system.serdessers(0), p(SerialTLKey)(0))).module)
|
||||
ram.io.ser.in <> pad.out
|
||||
pad.in <> ram.io.ser.out
|
||||
|
||||
// Allow TSI to master the chip
|
||||
io.success := SimTSI.connect(ram.io.tsi, serial_ram_clock, reset)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// JTAG
|
||||
|
||||
@@ -4,6 +4,7 @@ import chisel3._
|
||||
import chisel3.util._
|
||||
import chisel3.experimental.{IntParam, BaseModule}
|
||||
import freechips.rocketchip.amba.axi4._
|
||||
import freechips.rocketchip.prci._
|
||||
import freechips.rocketchip.subsystem.BaseSubsystem
|
||||
import org.chipsalliance.cde.config.{Parameters, Field, Config}
|
||||
import freechips.rocketchip.diplomacy._
|
||||
@@ -36,27 +37,24 @@ class GCDIO(val w: Int) extends Bundle {
|
||||
val busy = Output(Bool())
|
||||
}
|
||||
|
||||
trait GCDTopIO extends Bundle {
|
||||
class GCDTopIO extends Bundle {
|
||||
val gcd_busy = Output(Bool())
|
||||
}
|
||||
|
||||
trait HasGCDIO extends BaseModule {
|
||||
val w: Int
|
||||
val io = IO(new GCDIO(w))
|
||||
trait HasGCDTopIO {
|
||||
def io: GCDTopIO
|
||||
}
|
||||
|
||||
// DOC include start: GCD blackbox
|
||||
class GCDMMIOBlackBox(val w: Int) extends BlackBox(Map("WIDTH" -> IntParam(w))) with HasBlackBoxResource
|
||||
with HasGCDIO
|
||||
{
|
||||
class GCDMMIOBlackBox(val w: Int) extends BlackBox(Map("WIDTH" -> IntParam(w))) with HasBlackBoxResource {
|
||||
val io = IO(new GCDIO(w))
|
||||
addResource("/vsrc/GCDMMIOBlackBox.v")
|
||||
}
|
||||
// DOC include end: GCD blackbox
|
||||
|
||||
// DOC include start: GCD chisel
|
||||
class GCDMMIOChiselModule(val w: Int) extends Module
|
||||
with HasGCDIO
|
||||
{
|
||||
class GCDMMIOChiselModule(val w: Int) extends Module {
|
||||
val io = IO(new GCDIO(w))
|
||||
val s_idle :: s_run :: s_done :: Nil = Enum(3)
|
||||
|
||||
val state = RegInit(s_idle)
|
||||
@@ -90,70 +88,106 @@ class GCDMMIOChiselModule(val w: Int) extends Module
|
||||
}
|
||||
// DOC include end: GCD chisel
|
||||
|
||||
// DOC include start: GCD instance regmap
|
||||
|
||||
trait GCDModule extends HasRegMap {
|
||||
val io: GCDTopIO
|
||||
|
||||
implicit val p: Parameters
|
||||
def params: GCDParams
|
||||
val clock: Clock
|
||||
val reset: Reset
|
||||
|
||||
|
||||
// How many clock cycles in a PWM cycle?
|
||||
val x = Reg(UInt(params.width.W))
|
||||
val y = Wire(new DecoupledIO(UInt(params.width.W)))
|
||||
val gcd = Wire(new DecoupledIO(UInt(params.width.W)))
|
||||
val status = Wire(UInt(2.W))
|
||||
|
||||
val impl = if (params.useBlackBox) {
|
||||
Module(new GCDMMIOBlackBox(params.width))
|
||||
} else {
|
||||
Module(new GCDMMIOChiselModule(params.width))
|
||||
}
|
||||
|
||||
impl.io.clock := clock
|
||||
impl.io.reset := reset.asBool
|
||||
|
||||
impl.io.x := x
|
||||
impl.io.y := y.bits
|
||||
impl.io.input_valid := y.valid
|
||||
y.ready := impl.io.input_ready
|
||||
|
||||
gcd.bits := impl.io.gcd
|
||||
gcd.valid := impl.io.output_valid
|
||||
impl.io.output_ready := gcd.ready
|
||||
|
||||
status := Cat(impl.io.input_ready, impl.io.output_valid)
|
||||
io.gcd_busy := impl.io.busy
|
||||
|
||||
regmap(
|
||||
0x00 -> Seq(
|
||||
RegField.r(2, status)), // a read-only register capturing current status
|
||||
0x04 -> Seq(
|
||||
RegField.w(params.width, x)), // a plain, write-only register
|
||||
0x08 -> Seq(
|
||||
RegField.w(params.width, y)), // write-only, y.valid is set on write
|
||||
0x0C -> Seq(
|
||||
RegField.r(params.width, gcd))) // read-only, gcd.ready is set on read
|
||||
}
|
||||
// DOC include end: GCD instance regmap
|
||||
|
||||
// DOC include start: GCD router
|
||||
class GCDTL(params: GCDParams, beatBytes: Int)(implicit p: Parameters)
|
||||
extends TLRegisterRouter(
|
||||
params.address, "gcd", Seq("ucbbar,gcd"),
|
||||
beatBytes = beatBytes)(
|
||||
new TLRegBundle(params, _) with GCDTopIO)(
|
||||
new TLRegModule(params, _, _) with GCDModule)
|
||||
class GCDTL(params: GCDParams, beatBytes: Int)(implicit p: Parameters) extends ClockSinkDomain(ClockSinkParameters())(p) {
|
||||
val device = new SimpleDevice("gcd", Seq("ucbbar,gcd"))
|
||||
val node = TLRegisterNode(Seq(AddressSet(params.address, 4096-1)), device, "reg/control", beatBytes=beatBytes)
|
||||
|
||||
class GCDAXI4(params: GCDParams, beatBytes: Int)(implicit p: Parameters)
|
||||
extends AXI4RegisterRouter(
|
||||
params.address,
|
||||
beatBytes=beatBytes)(
|
||||
new AXI4RegBundle(params, _) with GCDTopIO)(
|
||||
new AXI4RegModule(params, _, _) with GCDModule)
|
||||
override lazy val module = new GCDImpl
|
||||
class GCDImpl extends Impl with HasGCDTopIO {
|
||||
val io = IO(new GCDTopIO)
|
||||
withClockAndReset(clock, reset) {
|
||||
// How many clock cycles in a PWM cycle?
|
||||
val x = Reg(UInt(params.width.W))
|
||||
val y = Wire(new DecoupledIO(UInt(params.width.W)))
|
||||
val gcd = Wire(new DecoupledIO(UInt(params.width.W)))
|
||||
val status = Wire(UInt(2.W))
|
||||
|
||||
val impl_io = if (params.useBlackBox) {
|
||||
val impl = Module(new GCDMMIOBlackBox(params.width))
|
||||
impl.io
|
||||
} else {
|
||||
val impl = Module(new GCDMMIOChiselModule(params.width))
|
||||
impl.io
|
||||
}
|
||||
|
||||
impl_io.clock := clock
|
||||
impl_io.reset := reset.asBool
|
||||
|
||||
impl_io.x := x
|
||||
impl_io.y := y.bits
|
||||
impl_io.input_valid := y.valid
|
||||
y.ready := impl_io.input_ready
|
||||
|
||||
gcd.bits := impl_io.gcd
|
||||
gcd.valid := impl_io.output_valid
|
||||
impl_io.output_ready := gcd.ready
|
||||
|
||||
status := Cat(impl_io.input_ready, impl_io.output_valid)
|
||||
io.gcd_busy := impl_io.busy
|
||||
|
||||
// DOC include start: GCD instance regmap
|
||||
node.regmap(
|
||||
0x00 -> Seq(
|
||||
RegField.r(2, status)), // a read-only register capturing current status
|
||||
0x04 -> Seq(
|
||||
RegField.w(params.width, x)), // a plain, write-only register
|
||||
0x08 -> Seq(
|
||||
RegField.w(params.width, y)), // write-only, y.valid is set on write
|
||||
0x0C -> Seq(
|
||||
RegField.r(params.width, gcd))) // read-only, gcd.ready is set on read
|
||||
// DOC include end: GCD instance regmap
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GCDAXI4(params: GCDParams, beatBytes: Int)(implicit p: Parameters) extends ClockSinkDomain(ClockSinkParameters())(p) {
|
||||
val node = AXI4RegisterNode(AddressSet(params.address, 4096-1), beatBytes=beatBytes)
|
||||
override lazy val module = new GCDImpl
|
||||
class GCDImpl extends Impl with HasGCDTopIO {
|
||||
val io = IO(new GCDTopIO)
|
||||
withClockAndReset(clock, reset) {
|
||||
// How many clock cycles in a PWM cycle?
|
||||
val x = Reg(UInt(params.width.W))
|
||||
val y = Wire(new DecoupledIO(UInt(params.width.W)))
|
||||
val gcd = Wire(new DecoupledIO(UInt(params.width.W)))
|
||||
val status = Wire(UInt(2.W))
|
||||
|
||||
val impl_io = if (params.useBlackBox) {
|
||||
val impl = Module(new GCDMMIOBlackBox(params.width))
|
||||
impl.io
|
||||
} else {
|
||||
val impl = Module(new GCDMMIOChiselModule(params.width))
|
||||
impl.io
|
||||
}
|
||||
|
||||
impl_io.clock := clock
|
||||
impl_io.reset := reset.asBool
|
||||
|
||||
impl_io.x := x
|
||||
impl_io.y := y.bits
|
||||
impl_io.input_valid := y.valid
|
||||
y.ready := impl_io.input_ready
|
||||
|
||||
gcd.bits := impl_io.gcd
|
||||
gcd.valid := impl_io.output_valid
|
||||
impl_io.output_ready := gcd.ready
|
||||
|
||||
status := Cat(impl_io.input_ready, impl_io.output_valid)
|
||||
io.gcd_busy := impl_io.busy
|
||||
|
||||
node.regmap(
|
||||
0x00 -> Seq(
|
||||
RegField.r(2, status)), // a read-only register capturing current status
|
||||
0x04 -> Seq(
|
||||
RegField.w(params.width, x)), // a plain, write-only register
|
||||
0x08 -> Seq(
|
||||
RegField.w(params.width, y)), // write-only, y.valid is set on write
|
||||
0x0C -> Seq(
|
||||
RegField.r(params.width, gcd))) // read-only, gcd.ready is set on read
|
||||
}
|
||||
}
|
||||
}
|
||||
// DOC include end: GCD router
|
||||
|
||||
// DOC include start: GCD lazy trait
|
||||
@@ -161,10 +195,11 @@ trait CanHavePeripheryGCD { this: BaseSubsystem =>
|
||||
private val portName = "gcd"
|
||||
|
||||
// Only build if we are using the TL (nonAXI4) version
|
||||
val gcd = p(GCDKey) match {
|
||||
val gcd_busy = p(GCDKey) match {
|
||||
case Some(params) => {
|
||||
if (params.useAXI4) {
|
||||
val gcd = if (params.useAXI4) {
|
||||
val gcd = LazyModule(new GCDAXI4(params, pbus.beatBytes)(p))
|
||||
gcd.clockNode := pbus.fixedClockNode
|
||||
pbus.coupleTo(portName) {
|
||||
gcd.node :=
|
||||
AXI4Buffer () :=
|
||||
@@ -172,34 +207,25 @@ trait CanHavePeripheryGCD { this: BaseSubsystem =>
|
||||
// toVariableWidthSlave doesn't use holdFirstDeny, which TLToAXI4() needsx
|
||||
TLFragmenter(pbus.beatBytes, pbus.blockBytes, holdFirstDeny = true) := _
|
||||
}
|
||||
Some(gcd)
|
||||
gcd
|
||||
} else {
|
||||
val gcd = LazyModule(new GCDTL(params, pbus.beatBytes)(p))
|
||||
gcd.clockNode := pbus.fixedClockNode
|
||||
pbus.coupleTo(portName) { gcd.node := TLFragmenter(pbus.beatBytes, pbus.blockBytes) := _ }
|
||||
Some(gcd)
|
||||
gcd
|
||||
}
|
||||
val gcd_busy = InModuleBody {
|
||||
val busy = IO(Output(Bool())).suggestName("gcd_busy")
|
||||
busy := gcd.module.io.gcd_busy
|
||||
busy
|
||||
}
|
||||
Some(gcd_busy)
|
||||
}
|
||||
case None => None
|
||||
}
|
||||
}
|
||||
// DOC include end: GCD lazy trait
|
||||
|
||||
// DOC include start: GCD imp trait
|
||||
trait CanHavePeripheryGCDModuleImp extends LazyModuleImp {
|
||||
val outer: CanHavePeripheryGCD
|
||||
val gcd_busy = outer.gcd match {
|
||||
case Some(gcd) => {
|
||||
val busy = IO(Output(Bool()))
|
||||
busy := gcd.module.io.gcd_busy
|
||||
Some(busy)
|
||||
}
|
||||
case None => None
|
||||
}
|
||||
}
|
||||
|
||||
// DOC include end: GCD imp trait
|
||||
|
||||
|
||||
// DOC include start: GCD config fragment
|
||||
class WithGCD(useAXI4: Boolean = false, useBlackBox: Boolean = false) extends Config((site, here, up) => {
|
||||
case GCDKey => Some(GCDParams(useAXI4 = useAXI4, useBlackBox = useBlackBox))
|
||||
|
||||
@@ -82,7 +82,7 @@ case class MyTileAttachParams(
|
||||
|
||||
case class MyTileParams(
|
||||
name: Option[String] = Some("my_tile"),
|
||||
hartId: Int = 0,
|
||||
tileId: Int = 0,
|
||||
trace: Boolean = false,
|
||||
val core: MyCoreParams = MyCoreParams()
|
||||
) extends InstantiableTileParams[MyTile]
|
||||
@@ -94,9 +94,11 @@ case class MyTileParams(
|
||||
val dcache: Option[DCacheParams] = Some(DCacheParams())
|
||||
val icache: Option[ICacheParams] = Some(ICacheParams())
|
||||
val clockSinkParams: ClockSinkParameters = ClockSinkParameters()
|
||||
def instantiate(crossing: TileCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters): MyTile = {
|
||||
def instantiate(crossing: HierarchicalElementCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters): MyTile = {
|
||||
new MyTile(this, crossing, lookup)
|
||||
}
|
||||
val baseName = name.getOrElse("my_tile")
|
||||
val uniqueName = s"${baseName}_$tileId"
|
||||
}
|
||||
|
||||
// DOC include start: Tile class
|
||||
@@ -111,11 +113,11 @@ class MyTile(
|
||||
{
|
||||
|
||||
// Private constructor ensures altered LazyModule.p is used implicitly
|
||||
def this(params: MyTileParams, crossing: TileCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters) =
|
||||
def this(params: MyTileParams, crossing: HierarchicalElementCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters) =
|
||||
this(params, crossing.crossingType, lookup, p)
|
||||
|
||||
// Require TileLink nodes
|
||||
val intOutwardNode = IntIdentityNode()
|
||||
val intOutwardNode = None
|
||||
val masterNode = visibilityNode
|
||||
val slaveNode = TLIdentityNode()
|
||||
|
||||
@@ -135,7 +137,7 @@ class MyTile(
|
||||
}
|
||||
|
||||
ResourceBinding {
|
||||
Resource(cpuDevice, "reg").bind(ResourceAddress(hartId))
|
||||
Resource(cpuDevice, "reg").bind(ResourceAddress(tileId))
|
||||
}
|
||||
|
||||
// TODO: Create TileLink nodes and connections here.
|
||||
@@ -228,15 +230,15 @@ class MyTileModuleImp(outer: MyTile) extends BaseTileModuleImp(outer){
|
||||
}
|
||||
|
||||
// DOC include start: Config fragment
|
||||
class WithNMyCores(n: Int = 1, overrideIdOffset: Option[Int] = None) extends Config((site, here, up) => {
|
||||
class WithNMyCores(n: Int = 1) extends Config((site, here, up) => {
|
||||
case TilesLocated(InSubsystem) => {
|
||||
// Calculate the next available hart ID (since hart ID cannot be duplicated)
|
||||
val prev = up(TilesLocated(InSubsystem), site)
|
||||
val idOffset = overrideIdOffset.getOrElse(prev.size)
|
||||
val idOffset = up(NumTiles)
|
||||
// Create TileAttachParams for every core to be instantiated
|
||||
(0 until n).map { i =>
|
||||
MyTileAttachParams(
|
||||
tileParams = MyTileParams(hartId = i + idOffset),
|
||||
tileParams = MyTileParams(tileId = i + idOffset),
|
||||
crossingParams = RocketCrossingParams()
|
||||
)
|
||||
} ++ prev
|
||||
@@ -245,5 +247,6 @@ class WithNMyCores(n: Int = 1, overrideIdOffset: Option[Int] = None) extends Con
|
||||
case SystemBusKey => up(SystemBusKey, site).copy(beatBytes = 8)
|
||||
// The # of instruction bits. Use maximum # of bits if your core supports both 32 and 64 bits.
|
||||
case XLen => 64
|
||||
case NumTiles => up(NumTiles) + n
|
||||
})
|
||||
// DOC include end: Config fragment
|
||||
|
||||
@@ -199,12 +199,13 @@ class TLGenericFIRChain[T<:Data:Ring] (genIn: T, genOut: T, coeffs: => Seq[T], p
|
||||
trait CanHavePeripheryStreamingFIR extends BaseSubsystem {
|
||||
val streamingFIR = p(GenericFIRKey) match {
|
||||
case Some(params) => {
|
||||
val streamingFIR = LazyModule(new TLGenericFIRChain(
|
||||
val domain = pbus.generateSynchronousDomain.suggestName("fir_domain")
|
||||
val streamingFIR = domain { LazyModule(new TLGenericFIRChain(
|
||||
genIn = FixedPoint(8.W, 3.BP),
|
||||
genOut = FixedPoint(8.W, 3.BP),
|
||||
coeffs = Seq(1.U.asFixedPoint(0.BP), 2.U.asFixedPoint(0.BP), 3.U.asFixedPoint(0.BP)),
|
||||
params = params))
|
||||
pbus.coupleTo("streamingFIR") { streamingFIR.mem.get := TLFIFOFixer() := TLFragmenter(pbus.beatBytes, pbus.blockBytes) := _ }
|
||||
params = params)) }
|
||||
pbus.coupleTo("streamingFIR") { domain { streamingFIR.mem.get := TLFIFOFixer() := TLFragmenter(pbus.beatBytes, pbus.blockBytes) } := _ }
|
||||
Some(streamingFIR)
|
||||
}
|
||||
case None => None
|
||||
|
||||
@@ -131,8 +131,9 @@ class TLStreamingPassthroughChain[T<:Data:Ring](params: StreamingPassthroughPara
|
||||
trait CanHavePeripheryStreamingPassthrough { this: BaseSubsystem =>
|
||||
val passthrough = p(StreamingPassthroughKey) match {
|
||||
case Some(params) => {
|
||||
val streamingPassthroughChain = LazyModule(new TLStreamingPassthroughChain(params, UInt(32.W)))
|
||||
pbus.coupleTo("streamingPassthrough") { streamingPassthroughChain.mem.get := TLFIFOFixer() := TLFragmenter(pbus.beatBytes, pbus.blockBytes) := _ }
|
||||
val domain = pbus.generateSynchronousDomain.suggestName("streaming_passthrough_domain")
|
||||
val streamingPassthroughChain = domain { LazyModule(new TLStreamingPassthroughChain(params, UInt(32.W))) }
|
||||
pbus.coupleTo("streamingPassthrough") { domain { streamingPassthroughChain.mem.get := TLFIFOFixer() := TLFragmenter(pbus.beatBytes, pbus.blockBytes)} := _ }
|
||||
Some(streamingPassthroughChain)
|
||||
}
|
||||
case None => None
|
||||
|
||||
@@ -2,7 +2,8 @@ package chipyard.harness
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import chisel3.experimental.{Analog, BaseModule, DataMirror, Direction}
|
||||
import chisel3.reflect.DataMirror
|
||||
import chisel3.experimental.Direction
|
||||
|
||||
import org.chipsalliance.cde.config.{Field, Config, Parameters}
|
||||
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImpLike}
|
||||
@@ -17,7 +18,7 @@ import testchipip.tsi.{SimTSI, SerialRAM, TSI, TSIIO}
|
||||
import testchipip.soc.{TestchipSimDTM}
|
||||
import testchipip.spi.{SimSPIFlashModel}
|
||||
import testchipip.uart.{UARTAdapter, UARTToSerial}
|
||||
import testchipip.serdes.{SerialWidthAdapter}
|
||||
import testchipip.serdes._
|
||||
import testchipip.iceblk.{SimBlockDevice, BlockDeviceModel}
|
||||
import testchipip.cosim.{SpikeCosim}
|
||||
import icenet.{NicLoopback, SimNetwork}
|
||||
@@ -28,8 +29,8 @@ import chipyard.iobinders._
|
||||
case object HarnessBinders extends Field[HarnessBinderFunction]({case _ => })
|
||||
|
||||
object ApplyHarnessBinders {
|
||||
def apply(th: HasHarnessInstantiators, ports: Seq[Port[_]])(implicit p: Parameters): Unit = {
|
||||
ports.foreach(port => p(HarnessBinders)(th, port))
|
||||
def apply(th: HasHarnessInstantiators, ports: Seq[Port[_]], chipId: Int)(implicit p: Parameters): Unit = {
|
||||
ports.foreach(port => p(HarnessBinders)(th, port, chipId))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,24 +42,22 @@ class HarnessBinder[T <: HasHarnessInstantiators, S <: Port[_]](
|
||||
|
||||
|
||||
class WithGPIOTiedOff extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: GPIOPort) => {
|
||||
case (th: HasHarnessInstantiators, port: GPIOPort, chipId: Int) => {
|
||||
port.io <> AnalogConst(0)
|
||||
}
|
||||
})
|
||||
|
||||
// DOC include start: WithUARTAdapter
|
||||
class WithUARTAdapter extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: UARTPort) => {
|
||||
case (th: HasHarnessInstantiators, port: UARTPort, chipId: Int) => {
|
||||
val div = (th.getHarnessBinderClockFreqMHz.toDouble * 1000000 / port.io.c.initBaudRate.toDouble).toInt
|
||||
val uart_sim = Module(new UARTAdapter(port.uartNo, div, false)).suggestName(s"uart_sim_uartno${port.uartNo}")
|
||||
uart_sim.io.uart.txd := port.io.txd
|
||||
port.io.rxd := uart_sim.io.uart.rxd
|
||||
UARTAdapter.connect(Seq(port.io), div, false)
|
||||
}
|
||||
})
|
||||
// DOC include end: WithUARTAdapter
|
||||
|
||||
class WithSimSPIFlashModel(rdOnly: Boolean = true) extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: SPIFlashPort) => {
|
||||
case (th: HasHarnessInstantiators, port: SPIFlashPort, chipId: Int) => {
|
||||
val spi_mem = Module(new SimSPIFlashModel(port.params.fSize, port.spiId, rdOnly)).suggestName(s"spi_mem${port.spiId}")
|
||||
spi_mem.io.sck := port.io.sck
|
||||
require(port.params.csWidth == 1, "I don't know what to do with your extra CS bits. Fix me please.")
|
||||
@@ -69,7 +68,7 @@ class WithSimSPIFlashModel(rdOnly: Boolean = true) extends HarnessBinder({
|
||||
})
|
||||
|
||||
class WithSimBlockDevice extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: BlockDevicePort) => {
|
||||
case (th: HasHarnessInstantiators, port: BlockDevicePort, chipId: Int) => {
|
||||
val sim_blkdev = Module(new SimBlockDevice(port.params))
|
||||
sim_blkdev.io.bdev <> port.io.bits
|
||||
sim_blkdev.io.clock := port.io.clock
|
||||
@@ -78,7 +77,7 @@ class WithSimBlockDevice extends HarnessBinder({
|
||||
})
|
||||
|
||||
class WithBlockDeviceModel extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: BlockDevicePort) => {
|
||||
case (th: HasHarnessInstantiators, port: BlockDevicePort, chipId: Int) => {
|
||||
val blkdev_model = Module(new BlockDeviceModel(16, port.params))
|
||||
blkdev_model.io <> port.io.bits
|
||||
blkdev_model.clock := port.io.clock
|
||||
@@ -87,33 +86,33 @@ class WithBlockDeviceModel extends HarnessBinder({
|
||||
})
|
||||
|
||||
class WithLoopbackNIC extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: NICPort) => {
|
||||
case (th: HasHarnessInstantiators, port: NICPort, chipId: Int) => {
|
||||
withClock(port.io.clock) { NicLoopback.connect(port.io.bits, port.params) }
|
||||
}
|
||||
})
|
||||
|
||||
class WithSimNetwork extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: NICPort) => {
|
||||
case (th: HasHarnessInstantiators, port: NICPort, chipId: Int) => {
|
||||
withClock(port.io.clock) { SimNetwork.connect(Some(port.io.bits), port.io.clock, th.harnessBinderReset.asBool) }
|
||||
}
|
||||
})
|
||||
|
||||
class WithSimAXIMem extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: AXI4MemPort) => {
|
||||
case (th: HasHarnessInstantiators, port: AXI4MemPort, chipId: Int) => {
|
||||
val mem = LazyModule(new SimAXIMem(port.edge, size=port.params.master.size)(Parameters.empty))
|
||||
withClock(port.io.clock) { Module(mem.module) }
|
||||
mem.io_axi4.head <> port.io
|
||||
mem.io_axi4.head <> port.io.bits
|
||||
}
|
||||
})
|
||||
|
||||
class WithBlackBoxSimMem(additionalLatency: Int = 0) extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: AXI4MemPort) => {
|
||||
case (th: HasHarnessInstantiators, port: AXI4MemPort, chipId: Int) => {
|
||||
// TODO FIX: This currently makes each SimDRAM contain the entire memory space
|
||||
val memSize = port.params.master.size
|
||||
val memBase = port.params.master.base
|
||||
val lineSize = 64 // cache block size
|
||||
val clockFreq = port.clockFreqMHz
|
||||
val mem = Module(new SimDRAM(memSize, lineSize, clockFreq, memBase, port.edge.bundle)).suggestName("simdram")
|
||||
val mem = Module(new SimDRAM(memSize, lineSize, clockFreq, memBase, port.edge.bundle, chipId)).suggestName("simdram")
|
||||
|
||||
mem.io.clock := port.io.clock
|
||||
mem.io.reset := th.harnessBinderReset.asAsyncReset
|
||||
@@ -140,7 +139,7 @@ class WithBlackBoxSimMem(additionalLatency: Int = 0) extends HarnessBinder({
|
||||
})
|
||||
|
||||
class WithSimAXIMMIO extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: AXI4MMIOPort) => {
|
||||
case (th: HasHarnessInstantiators, port: AXI4MMIOPort, chipId: Int) => {
|
||||
val mmio_mem = LazyModule(new SimAXIMem(port.edge, size = port.params.size)(Parameters.empty))
|
||||
withClock(port.io.clock) { Module(mmio_mem.module).suggestName("mmio_mem") }
|
||||
mmio_mem.io_axi4.head <> port.io.bits
|
||||
@@ -148,13 +147,13 @@ class WithSimAXIMMIO extends HarnessBinder({
|
||||
})
|
||||
|
||||
class WithTieOffInterrupts extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: ExtIntPort) => {
|
||||
case (th: HasHarnessInstantiators, port: ExtIntPort, chipId: Int) => {
|
||||
port.io := 0.U
|
||||
}
|
||||
})
|
||||
|
||||
class WithTieOffL2FBusAXI extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: AXI4InPort) => {
|
||||
case (th: HasHarnessInstantiators, port: AXI4InPort, chipId: Int) => {
|
||||
port.io := DontCare
|
||||
port.io.bits.aw.valid := false.B
|
||||
port.io.bits.w.valid := false.B
|
||||
@@ -165,7 +164,7 @@ class WithTieOffL2FBusAXI extends HarnessBinder({
|
||||
})
|
||||
|
||||
class WithSimJTAGDebug extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: JTAGPort) => {
|
||||
case (th: HasHarnessInstantiators, port: JTAGPort, chipId: Int) => {
|
||||
val dtm_success = WireInit(false.B)
|
||||
when (dtm_success) { th.success := true.B }
|
||||
val jtag_wire = Wire(new JTAGIO)
|
||||
@@ -180,7 +179,7 @@ class WithSimJTAGDebug extends HarnessBinder({
|
||||
})
|
||||
|
||||
class WithSimDMI extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: DMIPort) => {
|
||||
case (th: HasHarnessInstantiators, port: DMIPort, chipId: Int) => {
|
||||
val dtm_success = WireInit(false.B)
|
||||
when (dtm_success) { th.success := true.B }
|
||||
val dtm = Module(new TestchipSimDTM()(Parameters.empty)).connect(th.harnessBinderClock, th.harnessBinderReset.asBool, port.io, dtm_success)
|
||||
@@ -188,7 +187,7 @@ class WithSimDMI extends HarnessBinder({
|
||||
})
|
||||
|
||||
class WithTiedOffJTAG extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: JTAGPort) => {
|
||||
case (th: HasHarnessInstantiators, port: JTAGPort, chipId: Int) => {
|
||||
port.io.TCK := true.B.asClock
|
||||
port.io.TMS := true.B
|
||||
port.io.TDI := true.B
|
||||
@@ -196,7 +195,7 @@ class WithTiedOffJTAG extends HarnessBinder({
|
||||
})
|
||||
|
||||
class WithTiedOffDMI extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: DMIPort) => {
|
||||
case (th: HasHarnessInstantiators, port: DMIPort, chipId: Int) => {
|
||||
port.io.dmi.req.valid := false.B
|
||||
port.io.dmi.req.bits := DontCare
|
||||
port.io.dmi.resp.ready := true.B
|
||||
@@ -205,40 +204,65 @@ class WithTiedOffDMI extends HarnessBinder({
|
||||
}
|
||||
})
|
||||
|
||||
class WithSerialTLTiedOff extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: SerialTLPort) => {
|
||||
if (DataMirror.directionOf(port.io.clock) == Direction.Input) {
|
||||
port.io.clock := false.B.asClock
|
||||
// If tieoffs is specified, a list of serial portIds to tie off
|
||||
// If tieoffs is unspecified, ties off all serial ports
|
||||
class WithSerialTLTiedOff(tieoffs: Option[Seq[Int]] = None) extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: SerialTLPort, chipId: Int) if (tieoffs.map(_.contains(port.portId)).getOrElse(true)) => {
|
||||
port.io match {
|
||||
case io: DecoupledPhitIO => io.out.ready := false.B; io.in.valid := false.B; io.in.bits := DontCare;
|
||||
case io: SourceSyncPhitIO => {
|
||||
io.clock_in := false.B.asClock
|
||||
io.reset_in := false.B.asAsyncReset
|
||||
io.in := DontCare
|
||||
}
|
||||
}
|
||||
port.io match {
|
||||
case io: InternalSyncPhitIO =>
|
||||
case io: ExternalSyncPhitIO => io.clock_in := false.B.asClock
|
||||
case io: SourceSyncPhitIO =>
|
||||
case _ =>
|
||||
}
|
||||
port.io.bits.out.ready := false.B
|
||||
port.io.bits.in.valid := false.B
|
||||
port.io.bits.in.bits := DontCare
|
||||
}
|
||||
})
|
||||
|
||||
class WithSimTSIOverSerialTL extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: SerialTLPort) => {
|
||||
val bits = port.io.bits
|
||||
if (DataMirror.directionOf(port.io.clock) == Direction.Input) {
|
||||
port.io.clock := th.harnessBinderClock
|
||||
case (th: HasHarnessInstantiators, port: SerialTLPort, chipId: Int) if (port.portId == 0) => {
|
||||
port.io match {
|
||||
case io: InternalSyncPhitIO =>
|
||||
case io: ExternalSyncPhitIO => io.clock_in := th.harnessBinderClock
|
||||
case io: SourceSyncPhitIO => io.clock_in := th.harnessBinderClock; io.reset_in := th.harnessBinderReset
|
||||
}
|
||||
val ram = LazyModule(new SerialRAM(port.serdesser, port.params)(port.serdesser.p))
|
||||
Module(ram.module)
|
||||
ram.module.io.ser <> port.io.bits
|
||||
val tsi = Module(new SimTSI)
|
||||
tsi.io.clock := th.harnessBinderClock
|
||||
tsi.io.reset := th.harnessBinderReset
|
||||
tsi.io.tsi <> ram.module.io.tsi.get
|
||||
val exit = tsi.io.exit
|
||||
val success = exit === 1.U
|
||||
val error = exit >= 2.U
|
||||
assert(!error, "*** FAILED *** (exit code = %d)\n", exit >> 1.U)
|
||||
when (success) { th.success := true.B }
|
||||
|
||||
port.io match {
|
||||
case io: DecoupledPhitIO => {
|
||||
// If the port is locally synchronous (provides a clock), drive everything with that clock
|
||||
// Else, drive everything with the harnes clock
|
||||
val clock = port.io match {
|
||||
case io: InternalSyncPhitIO => io.clock_out
|
||||
case io: ExternalSyncPhitIO => th.harnessBinderClock
|
||||
}
|
||||
withClock(clock) {
|
||||
val ram = Module(LazyModule(new SerialRAM(port.serdesser, port.params)(port.serdesser.p)).module)
|
||||
ram.io.ser.in <> io.out
|
||||
io.in <> ram.io.ser.out
|
||||
|
||||
val success = SimTSI.connect(ram.io.tsi, clock, th.harnessBinderReset, chipId)
|
||||
when (success) { th.success := true.B }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
class WithDriveChipIdPin extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: ChipIdPort, chipId: Int) => {
|
||||
require(chipId < math.pow(2, port.io.getWidth), "ID Pin is not wide enough")
|
||||
port.io := chipId.U
|
||||
}
|
||||
})
|
||||
|
||||
class WithSimUARTToUARTTSI extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: UARTPort) => {
|
||||
case (th: HasHarnessInstantiators, port: UARTPort, chipId: Int) => {
|
||||
UARTAdapter.connect(Seq(port.io),
|
||||
baudrate=port.io.c.initBaudRate,
|
||||
clockFrequency=th.getHarnessBinderClockFreqHz.toInt,
|
||||
@@ -247,7 +271,7 @@ class WithSimUARTToUARTTSI extends HarnessBinder({
|
||||
})
|
||||
|
||||
class WithSimTSIToUARTTSI extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: UARTTSIPort) => {
|
||||
case (th: HasHarnessInstantiators, port: UARTTSIPort, chipId: Int) => {
|
||||
val freq = th.getHarnessBinderClockFreqHz.toInt
|
||||
val uart_to_serial = Module(new UARTToSerial(freq, port.io.uart.c))
|
||||
val serial_width_adapter = Module(new SerialWidthAdapter(8, TSI.WIDTH))
|
||||
@@ -261,27 +285,27 @@ class WithSimTSIToUARTTSI extends HarnessBinder({
|
||||
})
|
||||
|
||||
class WithTraceGenSuccess extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: SuccessPort) => {
|
||||
case (th: HasHarnessInstantiators, port: SuccessPort, chipId: Int) => {
|
||||
when (port.io) { th.success := true.B }
|
||||
}
|
||||
})
|
||||
|
||||
class WithCospike extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: TracePort) => {
|
||||
case (th: HasHarnessInstantiators, port: TracePort, chipId: Int) => {
|
||||
port.io.traces.zipWithIndex.map(t => SpikeCosim(t._1, t._2, port.cosimCfg))
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
class WithCustomBootPinPlusArg extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: CustomBootPort) => {
|
||||
case (th: HasHarnessInstantiators, port: CustomBootPort, chipId: Int) => {
|
||||
val pin = PlusArg("custom_boot_pin", width=1)
|
||||
port.io := pin
|
||||
}
|
||||
})
|
||||
|
||||
class WithClockFromHarness extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: ClockPort) => {
|
||||
case (th: HasHarnessInstantiators, port: ClockPort, chipId: Int) => {
|
||||
// DOC include start: HarnessClockInstantiatorEx
|
||||
port.io := th.harnessClockInstantiator.requestClockMHz(s"clock_${port.freqMHz}MHz", port.freqMHz)
|
||||
// DOC include end: HarnessClockInstantiatorEx
|
||||
@@ -289,7 +313,7 @@ class WithClockFromHarness extends HarnessBinder({
|
||||
})
|
||||
|
||||
class WithResetFromHarness extends HarnessBinder({
|
||||
case (th: HasHarnessInstantiators, port: ResetPort) => {
|
||||
case (th: HasHarnessInstantiators, port: ResetPort, chipId: Int) => {
|
||||
port.io := th.referenceReset.asAsyncReset
|
||||
}
|
||||
})
|
||||
|
||||
@@ -89,7 +89,7 @@ trait HasHarnessInstantiators {
|
||||
withClockAndReset (harnessBinderClock, harnessBinderReset) {
|
||||
lazyDuts.zipWithIndex.foreach {
|
||||
case (d: HasChipyardPorts, i: Int) => {
|
||||
ApplyHarnessBinders(this, d.ports)(chipParameters(i))
|
||||
ApplyHarnessBinders(this, d.ports, i)(chipParameters(i))
|
||||
}
|
||||
case _ =>
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package chipyard.harness
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import chisel3.experimental.{DataMirror, Direction}
|
||||
|
||||
import org.chipsalliance.cde.config.{Field, Config, Parameters}
|
||||
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImpLike}
|
||||
@@ -10,7 +9,7 @@ import freechips.rocketchip.devices.debug._
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.util._
|
||||
|
||||
import testchipip._
|
||||
import testchipip.serdes._
|
||||
|
||||
import chipyard._
|
||||
import chipyard.iobinders.{GetSystemParameters, JTAGChipIO, HasChipyardPorts, Port, SerialTLPort}
|
||||
@@ -38,10 +37,10 @@ class MultiHarnessBinder[T <: Port[_], S <: HasHarnessInstantiators](
|
||||
)(implicit tag0: ClassTag[T], tag1: ClassTag[S]) extends Config((site, here, up) => {
|
||||
// Override any HarnessBinders for chip0/chip1
|
||||
case MultiChipParameters(`chip0`) => new Config(
|
||||
new HarnessBinder({case (th: S, port: T) if chip0portFn(port) => }) ++ up(MultiChipParameters(chip0))
|
||||
new HarnessBinder({case (th: S, port: T, chipId: Int) if chip0portFn(port) => }) ++ up(MultiChipParameters(chip0))
|
||||
)
|
||||
case MultiChipParameters(`chip1`) => new Config(
|
||||
new HarnessBinder({case (th: S, port: T) if chip1portFn(port) => }) ++ up(MultiChipParameters(chip1))
|
||||
new HarnessBinder({case (th: S, port: T, chipId: Int) if chip1portFn(port) => }) ++ up(MultiChipParameters(chip1))
|
||||
)
|
||||
// Set the multiharnessbinder key
|
||||
case MultiHarnessBinders(`chip0`, `chip1`) => up(MultiHarnessBinders(chip0, chip1)) :+ {
|
||||
@@ -60,11 +59,23 @@ class WithMultiChipSerialTL(chip0: Int, chip1: Int, chip0portId: Int = 0, chip1p
|
||||
(p0: SerialTLPort) => p0.portId == chip0portId,
|
||||
(p1: SerialTLPort) => p1.portId == chip1portId,
|
||||
(th: HasHarnessInstantiators, p0: SerialTLPort, p1: SerialTLPort) => {
|
||||
(DataMirror.directionOf(p0.io.clock), DataMirror.directionOf(p1.io.clock)) match {
|
||||
case (Direction.Input, Direction.Output) => p0.io.clock := p1.io.clock
|
||||
case (Direction.Output, Direction.Input) => p1.io.clock := p0.io.clock
|
||||
def connectDecoupledSyncPhitIO(clkSource: InternalSyncPhitIO, clkSink: ExternalSyncPhitIO) = {
|
||||
clkSink.clock_in := clkSource.clock_out
|
||||
clkSink.in <> clkSource.out
|
||||
clkSource.in <> clkSink.out
|
||||
}
|
||||
def connectSourceSyncPhitIO(a: SourceSyncPhitIO, b: SourceSyncPhitIO) = {
|
||||
a.clock_in := b.clock_out
|
||||
b.clock_in := a.clock_out
|
||||
a.reset_in := b.reset_out
|
||||
b.reset_in := a.reset_out
|
||||
a.in := b.out
|
||||
b.in := a.out
|
||||
}
|
||||
(p0.io, p1.io) match {
|
||||
case (io0: InternalSyncPhitIO, io1: ExternalSyncPhitIO) => connectDecoupledSyncPhitIO(io0, io1)
|
||||
case (io0: ExternalSyncPhitIO, io1: InternalSyncPhitIO) => connectDecoupledSyncPhitIO(io1, io0)
|
||||
case (io0: SourceSyncPhitIO , io1: SourceSyncPhitIO ) => connectSourceSyncPhitIO (io0, io1)
|
||||
}
|
||||
p0.io.bits.in <> p1.io.bits.out
|
||||
p1.io.bits.in <> p0.io.bits.out
|
||||
}
|
||||
)
|
||||
|
||||
@@ -6,6 +6,6 @@ import scala.collection.immutable.ListMap
|
||||
package object harness
|
||||
{
|
||||
import chipyard.iobinders.Port
|
||||
type HarnessBinderFunction = PartialFunction[(HasHarnessInstantiators, Port[_]), Unit]
|
||||
type HarnessBinderFunction = PartialFunction[(HasHarnessInstantiators, Port[_], Int), Unit]
|
||||
type MultiHarnessBinderFunction = (HasHarnessInstantiators, Seq[Port[_]], Seq[Port[_]]) => Unit
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package chipyard.iobinders
|
||||
|
||||
import chisel3._
|
||||
import chisel3.experimental.{Analog, IO, DataMirror}
|
||||
import chisel3.reflect.DataMirror
|
||||
import chisel3.experimental.Analog
|
||||
|
||||
import org.chipsalliance.cde.config._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
@@ -26,9 +27,10 @@ import barstools.iocell.chisel._
|
||||
import testchipip.serdes.{CanHavePeripheryTLSerial, SerialTLKey}
|
||||
import testchipip.spi.{SPIChipIO}
|
||||
import testchipip.boot.{CanHavePeripheryCustomBootPin}
|
||||
import testchipip.soc.{CanHavePeripheryChipIdPin}
|
||||
import testchipip.util.{ClockedIO}
|
||||
import testchipip.iceblk.{CanHavePeripheryBlockDevice, BlockDeviceKey, BlockDeviceIO}
|
||||
import testchipip.cosim.{CanHaveTraceIOModuleImp, TraceOutputTop, SpikeCosimConfig}
|
||||
import testchipip.cosim.{CanHaveTraceIO, TraceOutputTop, SpikeCosimConfig}
|
||||
import testchipip.tsi.{CanHavePeripheryUARTTSI, UARTTSIIO}
|
||||
import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly}
|
||||
import chipyard.{CanHaveMasterTLMemPort, ChipyardSystem, ChipyardSystemModule}
|
||||
@@ -172,6 +174,7 @@ class WithGPIOCells extends OverrideIOBinder({
|
||||
iocell.io.oe := pin.o.oe
|
||||
iocell.io.ie := pin.o.ie
|
||||
pin.i.ival := iocell.io.i
|
||||
pin.i.po.foreach(_ := DontCare)
|
||||
iocell.io.pad <> g
|
||||
(GPIOPort(() => g, i, j), iocell)
|
||||
}).unzip
|
||||
@@ -284,7 +287,9 @@ class JTAGChipIO extends Bundle {
|
||||
val TDO = Output(Bool())
|
||||
}
|
||||
|
||||
class WithDebugIOCells extends OverrideLazyIOBinder({
|
||||
// WARNING: Don't disable syncReset unless you are trying to
|
||||
// get around bugs in RTL simulators
|
||||
class WithDebugIOCells(syncReset: Boolean = true) extends OverrideLazyIOBinder({
|
||||
(system: HasPeripheryDebug) => {
|
||||
implicit val p = GetSystemParameters(system)
|
||||
val tlbus = system.asInstanceOf[BaseSubsystem].locateTLBusWrapper(p(ExportDebug).slaveWhere)
|
||||
@@ -308,7 +313,7 @@ class WithDebugIOCells extends OverrideLazyIOBinder({
|
||||
d.disableDebug.foreach { d => d := false.B }
|
||||
// Drive JTAG on-chip IOs
|
||||
d.systemjtag.map { j =>
|
||||
j.reset := ResetCatchAndSync(j.jtag.TCK, clockBundle.reset.asBool)
|
||||
j.reset := (if (syncReset) ResetCatchAndSync(j.jtag.TCK, clockBundle.reset.asBool) else clockBundle.reset.asBool)
|
||||
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)
|
||||
@@ -352,6 +357,14 @@ class WithSerialTLIOCells extends OverrideIOBinder({
|
||||
}
|
||||
})
|
||||
|
||||
class WithChipIdIOCells extends OverrideIOBinder({
|
||||
(system: CanHavePeripheryChipIdPin) => system.chip_id_pin.map({ p =>
|
||||
val sys = system.asInstanceOf[BaseSubsystem]
|
||||
val (port, cells) = IOCell.generateIOFromSignal(p.getWrappedValue, s"chip_id", sys.p(IOCellKey), abstractResetAsAsync = true)
|
||||
(Seq(ChipIdPort(() => port)), cells)
|
||||
}).getOrElse(Nil, Nil)
|
||||
})
|
||||
|
||||
class WithSerialTLPunchthrough extends OverrideIOBinder({
|
||||
(system: CanHavePeripheryTLSerial) => {
|
||||
val (ports, cells) = system.serial_tls.zipWithIndex.map({ case (s, id) =>
|
||||
@@ -454,14 +467,14 @@ class WithTraceGenSuccessPunchthrough extends OverrideIOBinder({
|
||||
}
|
||||
})
|
||||
|
||||
class WithTraceIOPunchthrough extends OverrideIOBinder({
|
||||
(system: CanHaveTraceIOModuleImp) => {
|
||||
class WithTraceIOPunchthrough extends OverrideLazyIOBinder({
|
||||
(system: CanHaveTraceIO) => InModuleBody {
|
||||
val ports: Option[TracePort] = system.traceIO.map { t =>
|
||||
val trace = IO(DataMirror.internal.chiselTypeClone[TraceOutputTop](t)).suggestName("trace")
|
||||
trace <> t
|
||||
val p = GetSystemParameters(system)
|
||||
val chipyardSystem = system.asInstanceOf[ChipyardSystemModule[_]].outer.asInstanceOf[ChipyardSystem]
|
||||
val tiles = chipyardSystem.tiles
|
||||
val chipyardSystem = system.asInstanceOf[ChipyardSystem]
|
||||
val tiles = chipyardSystem.totalTiles.values
|
||||
val cfg = SpikeCosimConfig(
|
||||
isa = tiles.headOption.map(_.isaDTS).getOrElse(""),
|
||||
vlen = tiles.headOption.map(_.tileParams.core.vLen).getOrElse(0),
|
||||
@@ -510,8 +523,8 @@ class WithDontTouchPorts extends OverrideIOBinder({
|
||||
})
|
||||
|
||||
class WithNMITiedOff extends ComposeIOBinder({
|
||||
(system: HasTilesModuleImp) => {
|
||||
system.nmi.flatten.foreach { nmi =>
|
||||
(system: HasHierarchicalElementsRootContextModuleImp) => {
|
||||
system.nmi.foreach { nmi =>
|
||||
nmi.rnmi := false.B
|
||||
nmi.rnmi_interrupt_vector := 0.U
|
||||
nmi.rnmi_exception_vector := 0.U
|
||||
|
||||
@@ -72,8 +72,12 @@ case class DMIPort (val getIO: () => ClockedDMIIO)
|
||||
case class JTAGPort (val getIO: () => JTAGChipIO)
|
||||
extends Port[JTAGChipIO]
|
||||
|
||||
case class SerialTLPort (val getIO: () => ClockedIO[SerialIO], val params: SerialTLParams, val serdesser: TLSerdesser, val portId: Int)
|
||||
extends Port[ClockedIO[SerialIO]]
|
||||
// Lack of nice union types in scala-2 means we have to set this type as Data
|
||||
case class SerialTLPort (val getIO: () => Data, val params: SerialTLParams, val serdesser: TLSerdesser, val portId: Int)
|
||||
extends Port[Data]
|
||||
|
||||
case class ChipIdPort (val getIO: () => UInt)
|
||||
extends Port[UInt]
|
||||
|
||||
case class UARTTSIPort (val getIO: () => UARTTSIIO)
|
||||
extends Port[UARTTSIIO]
|
||||
@@ -90,6 +94,9 @@ case class CustomBootPort (val getIO: () => Bool)
|
||||
case class ClockPort (val getIO: () => Clock, val freqMHz: Double)
|
||||
extends Port[Clock]
|
||||
|
||||
case class ClockTapPort (val getIO: () => Clock)
|
||||
extends Port[Clock]
|
||||
|
||||
case class ResetPort (val getIO: () => AsyncReset)
|
||||
extends Port[Reset]
|
||||
|
||||
|
||||
Submodule generators/constellation updated: 3632183fd1...81f005ffea
Submodule generators/cva6 updated: 46323fcd74...9d1c106834
Submodule generators/fft-generator updated: 811951b44a...4e7e6cbbbc
@@ -15,6 +15,7 @@ import freechips.rocketchip.prci.{ClockBundle, ClockBundleParameters}
|
||||
import freechips.rocketchip.util.{ResetCatchAndSync}
|
||||
import sifive.blocks.devices.uart._
|
||||
|
||||
import testchipip.serdes.{ExternalSyncPhitIO}
|
||||
import testchipip.tsi.{SerialRAM}
|
||||
import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly}
|
||||
|
||||
@@ -66,43 +67,46 @@ class WithFireSimIOCellModels extends Config((site, here, up) => {
|
||||
})
|
||||
|
||||
class WithTSIBridgeAndHarnessRAMOverSerialTL extends HarnessBinder({
|
||||
case (th: FireSim, port: SerialTLPort) => {
|
||||
val bits = port.io.bits
|
||||
port.io.clock := th.harnessBinderClock
|
||||
val ram = LazyModule(new SerialRAM(port.serdesser, port.params)(port.serdesser.p))
|
||||
Module(ram.module)
|
||||
ram.module.io.ser <> port.io.bits
|
||||
case (th: FireSim, port: SerialTLPort, chipId: Int) => {
|
||||
port.io match {
|
||||
case io: ExternalSyncPhitIO => {
|
||||
io.clock_in := th.harnessBinderClock
|
||||
val ram = Module(LazyModule(new SerialRAM(port.serdesser, port.params)(port.serdesser.p)).module)
|
||||
ram.io.ser.in <> io.out
|
||||
io.in <> ram.io.ser.out
|
||||
|
||||
// This assumes that:
|
||||
// If ExtMem for the target is defined, then FASED bridge will be attached
|
||||
// If FASED bridge is attached, loadmem widget is present
|
||||
val hasMainMemory = th.chipParameters(th.p(MultiChipIdx))(ExtMem).isDefined
|
||||
val mainMemoryName = Option.when(hasMainMemory)(MainMemoryConsts.globalName(th.p(MultiChipIdx)))
|
||||
TSIBridge(th.harnessBinderClock, ram.module.io.tsi.get, mainMemoryName, th.harnessBinderReset.asBool)(th.p)
|
||||
// This assumes that:
|
||||
// If ExtMem for the target is defined, then FASED bridge will be attached
|
||||
// If FASED bridge is attached, loadmem widget is present
|
||||
val hasMainMemory = th.chipParameters(chipId)(ExtMem).isDefined
|
||||
val mainMemoryName = Option.when(hasMainMemory)(MainMemoryConsts.globalName(chipId))
|
||||
TSIBridge(th.harnessBinderClock, ram.io.tsi.get, mainMemoryName, th.harnessBinderReset.asBool)(th.p)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
class WithNICBridge extends HarnessBinder({
|
||||
case (th: FireSim, port: NICPort) => {
|
||||
case (th: FireSim, port: NICPort, chipId: Int) => {
|
||||
NICBridge(port.io.clock, port.io.bits)(th.p)
|
||||
}
|
||||
})
|
||||
|
||||
class WithUARTBridge extends HarnessBinder({
|
||||
case (th: FireSim, port: UARTPort) =>
|
||||
case (th: FireSim, port: UARTPort, chipId: Int) =>
|
||||
val uartSyncClock = th.harnessClockInstantiator.requestClockMHz("uart_clock", port.freqMHz)
|
||||
UARTBridge(uartSyncClock, port.io, th.harnessBinderReset.asBool, port.freqMHz)(th.p)
|
||||
})
|
||||
|
||||
class WithBlockDeviceBridge extends HarnessBinder({
|
||||
case (th: FireSim, port: BlockDevicePort) => {
|
||||
case (th: FireSim, port: BlockDevicePort, chipId: Int) => {
|
||||
BlockDevBridge(port.io.clock, port.io.bits, th.harnessBinderReset.asBool)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
class WithFASEDBridge extends HarnessBinder({
|
||||
case (th: FireSim, port: AXI4MemPort) => {
|
||||
case (th: FireSim, port: AXI4MemPort, chipId: Int) => {
|
||||
val nastiKey = NastiParameters(port.io.bits.r.bits.data.getWidth,
|
||||
port.io.bits.ar.bits.addr.getWidth,
|
||||
port.io.bits.ar.bits.id.getWidth)
|
||||
@@ -110,24 +114,24 @@ class WithFASEDBridge extends HarnessBinder({
|
||||
CompleteConfig(th.p(firesim.configs.MemModelKey),
|
||||
nastiKey,
|
||||
Some(AXI4EdgeSummary(port.edge)),
|
||||
Some(MainMemoryConsts.globalName(th.p(MultiChipIdx)))))(th.p)
|
||||
Some(MainMemoryConsts.globalName(chipId))))(th.p)
|
||||
}
|
||||
})
|
||||
|
||||
class WithTracerVBridge extends HarnessBinder({
|
||||
case (th: FireSim, port: TracePort) => {
|
||||
case (th: FireSim, port: TracePort, chipId: Int) => {
|
||||
port.io.traces.map(tileTrace => TracerVBridge(tileTrace)(th.p))
|
||||
}
|
||||
})
|
||||
|
||||
class WithCospikeBridge extends HarnessBinder({
|
||||
case (th: FireSim, port: TracePort) => {
|
||||
case (th: FireSim, port: TracePort, chipId: Int) => {
|
||||
port.io.traces.zipWithIndex.map(t => CospikeBridge(t._1, t._2, port.cosimCfg))
|
||||
}
|
||||
})
|
||||
|
||||
class WithSuccessBridge extends HarnessBinder({
|
||||
case (th: FireSim, port: SuccessPort) => {
|
||||
case (th: FireSim, port: SuccessPort, chipId: Int) => {
|
||||
GroundTestBridge(th.harnessBinderClock, port.io)(th.p)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -8,7 +8,7 @@ import chisel3._
|
||||
import chisel3.experimental.{IO, annotate}
|
||||
|
||||
import freechips.rocketchip.prci._
|
||||
import freechips.rocketchip.subsystem.{BaseSubsystem, SubsystemDriveAsyncClockGroupsKey, HasTiles}
|
||||
import freechips.rocketchip.subsystem._
|
||||
import org.chipsalliance.cde.config.{Field, Config, Parameters}
|
||||
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, InModuleBody, ValName}
|
||||
import freechips.rocketchip.util.{ResetCatchAndSync, RecordMap}
|
||||
@@ -103,8 +103,8 @@ class FireSim(implicit val p: Parameters) extends RawModule with HasHarnessInsta
|
||||
// FireSim ModelMultithreading
|
||||
chiptops.foreach {
|
||||
case c: ChipTop => c.lazySystem match {
|
||||
case ls: HasTiles => {
|
||||
if (p(FireSimMultiCycleRegFile)) ls.tiles.map {
|
||||
case ls: InstantiatesHierarchicalElements => {
|
||||
if (p(FireSimMultiCycleRegFile)) ls.totalTiles.values.map {
|
||||
case r: RocketTile => {
|
||||
annotate(MemModelAnnotation(r.module.core.rocketImpl.rf.rf))
|
||||
r.module.fpuOpt.foreach(fpu => annotate(MemModelAnnotation(fpu.fpuImpl.regfile)))
|
||||
@@ -120,7 +120,7 @@ class FireSim(implicit val p: Parameters) extends RawModule with HasHarnessInsta
|
||||
}
|
||||
case _ =>
|
||||
}
|
||||
if (p(FireSimFAME5)) ls.tiles.map {
|
||||
if (p(FireSimFAME5)) ls.totalTiles.values.map {
|
||||
case b: BoomTile =>
|
||||
annotate(EnableModelMultiThreadingAnnotation(b.module))
|
||||
case r: RocketTile =>
|
||||
|
||||
@@ -85,6 +85,7 @@ class WithMinimalFireSimDesignTweaks extends Config(
|
||||
new chipyard.harness.WithHarnessBinderClockFreqMHz(1000.0) ++
|
||||
new chipyard.harness.WithClockFromHarness ++
|
||||
new chipyard.harness.WithResetFromHarness ++
|
||||
new chipyard.config.WithNoClockTap ++
|
||||
new chipyard.clocking.WithPassthroughClockGenerator ++
|
||||
// Required*: When using FireSim-as-top to provide a correct path to the target bootrom source
|
||||
new WithBootROM ++
|
||||
@@ -99,6 +100,8 @@ class WithMinimalFireSimDesignTweaks extends Config(
|
||||
// Non-frequency tweaks that are generally applied to all firesim configs
|
||||
class WithFireSimDesignTweaks extends Config(
|
||||
new WithMinimalFireSimDesignTweaks ++
|
||||
// Required: Remove the debug clock tap, this breaks compilation of target-level sim in FireSim
|
||||
new chipyard.config.WithNoClockTap ++
|
||||
// Required: Bake in the default FASED memory model
|
||||
new WithDefaultMemModel ++
|
||||
// Optional: reduce the width of the Serial TL interface
|
||||
@@ -125,6 +128,7 @@ class WithFireSimHighPerfClocking extends Config(
|
||||
// This frequency selection matches FireSim's legacy selection and is required
|
||||
// to support 200Gb NIC performance. You may select a smaller value.
|
||||
new chipyard.config.WithPeripheryBusFrequency(3200.0) ++
|
||||
new chipyard.config.WithControlBusFrequency(3200.0) ++
|
||||
new chipyard.config.WithSystemBusFrequency(3200.0) ++
|
||||
new chipyard.config.WithFrontBusFrequency(3200.0) ++
|
||||
new chipyard.config.WithControlBusFrequency(3200.0) ++
|
||||
@@ -145,6 +149,7 @@ class WithFireSimConfigTweaks extends Config(
|
||||
new chipyard.config.WithSystemBusFrequency(1000.0) ++
|
||||
new chipyard.config.WithControlBusFrequency(1000.0) ++
|
||||
new chipyard.config.WithPeripheryBusFrequency(1000.0) ++
|
||||
new chipyard.config.WithControlBusFrequency(1000.0) ++
|
||||
new chipyard.config.WithMemoryBusFrequency(1000.0) ++
|
||||
new chipyard.config.WithFrontBusFrequency(1000.0) ++
|
||||
new WithFireSimDesignTweaks
|
||||
@@ -262,8 +267,8 @@ class FireSimSmallSystemConfig extends Config(
|
||||
new WithoutTLMonitors ++
|
||||
new freechips.rocketchip.subsystem.WithExtMemSize(1 << 28) ++
|
||||
new testchipip.serdes.WithSerialTL(Seq(testchipip.serdes.SerialTLParams(
|
||||
client = Some(testchipip.serdes.SerialTLClientParams(idBits = 4)),
|
||||
width = 32
|
||||
client = Some(testchipip.serdes.SerialTLClientParams(totalIdBits = 4)),
|
||||
phyParams = testchipip.serdes.ExternalSyncSerialPhyParams(phitWidth=32, flitWidth=32)
|
||||
))) ++
|
||||
new testchipip.iceblk.WithBlockDevice ++
|
||||
new chipyard.config.WithUARTInitBaudRate(BigInt(3686400L)) ++
|
||||
@@ -358,3 +363,10 @@ class FireSimLeanGemminiRocketMMIOOnlyConfig extends Config(
|
||||
new WithDefaultMemModel ++
|
||||
new WithFireSimConfigTweaks ++
|
||||
new chipyard.LeanGemminiRocketConfig)
|
||||
|
||||
class FireSimLargeBoomCospikeConfig extends Config(
|
||||
new firesim.firesim.WithCospikeBridge ++
|
||||
new WithDefaultFireSimBridges ++
|
||||
new WithDefaultMemModel ++
|
||||
new WithFireSimConfigTweaks++
|
||||
new chipyard.LargeBoomConfig)
|
||||
|
||||
Submodule generators/gemmini updated: 8c8b38b9de...c16f815a38
Submodule generators/ibex updated: 66ec6e56ed...c2174aba4f
Submodule generators/icenet updated: 18e88b5779...ab30e23e8e
Submodule generators/mempress updated: c3d4901ab0...415f55b583
Submodule generators/nvdla updated: 730fad4360...95697452e5
Submodule generators/riscv-sodor updated: c1c809ebd5...bbfc3c3510
Submodule generators/rocket-chip updated: 50adbdb3e4...8026b6bc9a
1
generators/rocket-chip-blocks
Submodule
1
generators/rocket-chip-blocks
Submodule
Submodule generators/rocket-chip-blocks added at f9263535be
1
generators/rocket-chip-inclusive-cache
Submodule
1
generators/rocket-chip-inclusive-cache
Submodule
Submodule generators/rocket-chip-inclusive-cache added at 1332d2268a
Submodule generators/sha3 updated: 5e49347f06...2d38585d64
Submodule generators/shuttle updated: e628836c3c...4bc2fa1e36
Submodule generators/sifive-blocks deleted from 5edd72e793
Submodule generators/sifive-cache deleted from 51d400bd32
Submodule generators/testchipip updated: c13b8f658b...5d6ec23cd6
@@ -13,19 +13,18 @@ import scala.math.{max, min}
|
||||
|
||||
class WithTraceGen(
|
||||
n: Int = 2,
|
||||
overrideIdOffset: Option[Int] = None,
|
||||
overrideMemOffset: Option[BigInt] = None)(
|
||||
params: Seq[DCacheParams] = List.fill(n){ DCacheParams(nSets = 16, nWays = 1) },
|
||||
nReqs: Int = 8192
|
||||
) extends Config((site, here, up) => {
|
||||
case TilesLocated(InSubsystem) => {
|
||||
val prev = up(TilesLocated(InSubsystem), site)
|
||||
val idOffset = overrideIdOffset.getOrElse(prev.size)
|
||||
val idOffset = up(NumTiles)
|
||||
val memOffset: BigInt = overrideMemOffset.orElse(site(ExtMem).map(_.master.base)).getOrElse(0x0L)
|
||||
params.zipWithIndex.map { case (dcp, i) =>
|
||||
TraceGenTileAttachParams(
|
||||
tileParams = TraceGenParams(
|
||||
hartId = i + idOffset,
|
||||
tileId = i + idOffset,
|
||||
dcache = Some(dcp),
|
||||
wordBits = site(XLen),
|
||||
addrBits = 48,
|
||||
@@ -48,23 +47,23 @@ class WithTraceGen(
|
||||
)
|
||||
} ++ prev
|
||||
}
|
||||
case NumTiles => up(NumTiles) + n
|
||||
})
|
||||
|
||||
class WithBoomTraceGen(
|
||||
n: Int = 2,
|
||||
overrideIdOffset: Option[Int] = None,
|
||||
overrideMemOffset: Option[BigInt] = None)(
|
||||
params: Seq[DCacheParams] = List.fill(n){ DCacheParams(nMSHRs = 4, nSets = 16, nWays = 2) },
|
||||
nReqs: Int = 8192
|
||||
) extends Config((site, here, up) => {
|
||||
case TilesLocated(InSubsystem) => {
|
||||
val prev = up(TilesLocated(InSubsystem), site)
|
||||
val idOffset = overrideIdOffset.getOrElse(prev.size)
|
||||
val idOffset = up(NumTiles)
|
||||
val memOffset: BigInt = overrideMemOffset.orElse(site(ExtMem).map(_.master.base)).getOrElse(0x0L)
|
||||
params.zipWithIndex.map { case (dcp, i) =>
|
||||
BoomTraceGenTileAttachParams(
|
||||
tileParams = BoomTraceGenParams(
|
||||
hartId = i + idOffset,
|
||||
tileId = i + idOffset,
|
||||
dcache = Some(dcp),
|
||||
wordBits = site(XLen),
|
||||
addrBits = 48,
|
||||
@@ -84,24 +83,24 @@ class WithBoomTraceGen(
|
||||
)
|
||||
} ++ prev
|
||||
}
|
||||
case NumTiles => up(NumTiles) + n
|
||||
})
|
||||
|
||||
class WithL2TraceGen(
|
||||
n: Int = 2,
|
||||
overrideIdOffset: Option[Int] = None,
|
||||
overrideMemOffset: Option[BigInt] = None)(
|
||||
params: Seq[DCacheParams] = List.fill(n){ DCacheParams(nSets = 16, nWays = 1) },
|
||||
nReqs: Int = 8192
|
||||
) extends Config((site, here, up) => {
|
||||
case TilesLocated(InSubsystem) => {
|
||||
val prev = up(TilesLocated(InSubsystem), site)
|
||||
val idOffset = overrideIdOffset.getOrElse(prev.size)
|
||||
val idOffset = up(NumTiles)
|
||||
val memOffset: BigInt = overrideMemOffset.orElse(site(ExtMem).map(_.master.base)).getOrElse(0x0L)
|
||||
|
||||
params.zipWithIndex.map { case (dcp, i) =>
|
||||
TraceGenTileAttachParams(
|
||||
tileParams = TraceGenParams(
|
||||
hartId = i + idOffset,
|
||||
tileId = i + idOffset,
|
||||
dcache = Some(dcp),
|
||||
wordBits = site(XLen),
|
||||
addrBits = 48,
|
||||
@@ -126,4 +125,5 @@ class WithL2TraceGen(
|
||||
)
|
||||
} ++ prev
|
||||
}
|
||||
case NumTiles => up(NumTiles) + n
|
||||
})
|
||||
|
||||
@@ -9,15 +9,28 @@ import freechips.rocketchip.subsystem._
|
||||
import boom.lsu.BoomTraceGenTile
|
||||
|
||||
class TraceGenSystem(implicit p: Parameters) extends BaseSubsystem
|
||||
with HasTiles
|
||||
with InstantiatesHierarchicalElements
|
||||
with HasTileNotificationSinks
|
||||
with HasTileInputConstants
|
||||
with HasHierarchicalElementsRootContext
|
||||
with HasHierarchicalElements
|
||||
with CanHaveMasterAXI4MemPort {
|
||||
|
||||
def coreMonitorBundles = Nil
|
||||
val tileStatusNodes = tiles.collect {
|
||||
|
||||
val tileStatusNodes = totalTiles.values.toSeq.collect {
|
||||
case t: GroundTestTile => t.statusNode.makeSink()
|
||||
case t: BoomTraceGenTile => t.statusNode.makeSink()
|
||||
}
|
||||
lazy val debugNode = IntSyncXbar() := NullIntSyncSource()
|
||||
|
||||
lazy val fakeClockDomain = sbus.generateSynchronousDomain
|
||||
|
||||
lazy val clintOpt = None
|
||||
lazy val debugOpt = None
|
||||
lazy val plicOpt = None
|
||||
lazy val clintDomainOpt = Some(fakeClockDomain)
|
||||
lazy val plicDomainOpt = Some(fakeClockDomain)
|
||||
|
||||
override lazy val module = new TraceGenSystemModuleImp(this)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user