Merge remote-tracking branch 'origin/main' into clusters

This commit is contained in:
Jerry Zhao
2023-12-15 15:53:35 -08:00
80 changed files with 3722 additions and 2870 deletions

View File

@@ -7,7 +7,7 @@ import scala.collection.mutable.{ArrayBuffer}
import freechips.rocketchip.prci.{ClockGroupIdentityNode, ClockSinkParameters, ClockSinkNode, ClockGroup}
import org.chipsalliance.cde.config.{Parameters, Field}
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, LazyRawModuleImp, LazyModuleImpLike, BindingScope}
import freechips.rocketchip.util.{ResetCatchAndSync}
import freechips.rocketchip.util.{DontTouch}
import chipyard.iobinders._
import barstools.iocell.chisel._
@@ -30,5 +30,5 @@ class ChipTop(implicit p: Parameters) extends LazyModule with BindingScope
// of ChipTop (ex: ClockGroup) do not receive clock or reset.
// However. anonymous children of ChipTop should not need an implicit Clock or Reset
// anyways, they probably need to be explicitly clocked.
lazy val module: LazyModuleImpLike = new LazyRawModuleImp(this) { }
lazy val module: LazyModuleImpLike = new LazyRawModuleImp(this) with DontTouch { }
}

View File

@@ -65,11 +65,11 @@ class WithPLLSelectorDividerClockGenerator extends OverrideLazyIOBinder({
o.reset := reset_wire
}
(Seq(ClockPort(clock_io, 100), ResetPort(reset_io)), clockIOCell ++ resetIOCell)
(Seq(ClockPort(() => clock_io, 100), ResetPort(() => reset_io)), clockIOCell ++ resetIOCell)
}
}
})
// This passes all clocks through to the TestHarness
class WithPassthroughClockGenerator extends OverrideLazyIOBinder({
(system: HasChipyardPRCI) => {
@@ -92,9 +92,9 @@ class WithPassthroughClockGenerator extends OverrideLazyIOBinder({
val clock_io = IO(Input(Clock())).suggestName(s"clock_${m.name.get}")
b.clock := clock_io
b.reset := reset_io
ClockPort(clock_io, freq)
ClockPort(() => clock_io, freq)
}.toSeq
((clock_ios :+ ResetPort(reset_io)), Nil)
((clock_ios :+ ResetPort(() => reset_io)), Nil)
}
}
})

View File

@@ -43,6 +43,10 @@ class ChipLikeRocketConfig extends Config(
new chipyard.config.AbstractConfig)
class FlatChipTopChipLikeRocketConfig extends Config(
new chipyard.example.WithFlatChipTop ++
new chipyard.ChipLikeRocketConfig)
// A simple config demonstrating a "bringup prototype" to bringup the ChipLikeRocketconfig
class ChipBringupHostConfig extends Config(
//=============================

View File

@@ -9,7 +9,7 @@ import freechips.rocketchip.diplomacy.{AsynchronousCrossing}
// DOC include start: FFTRocketConfig
class FFTRocketConfig extends Config(
new chipyard.iobinders.WithDontTouchIOBinders(false) ++ // TODO: hack around dontTouch not working in SFC
new chipyard.harness.WithDontTouchChipTopPorts(false) ++ // TODO: hack around dontTouch not working in SFC
new fftgenerator.WithFFTGenerator(numPoints=8, width=16, decPt=8) ++ // add 8-point mmio fft at the default addr (0x2400) with 16bit fixed-point numbers.
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.AbstractConfig)
@@ -59,7 +59,7 @@ class LargeNVDLARocketConfig extends Config(
new chipyard.config.AbstractConfig)
class ManyMMIOAcceleratorRocketConfig extends Config(
new chipyard.iobinders.WithDontTouchIOBinders(false) ++ // TODO: hack around dontTouch not working in SFC
new chipyard.harness.WithDontTouchChipTopPorts(false) ++ // TODO: hack around dontTouch not working in SFC
new fftgenerator.WithFFTGenerator(numPoints=8, width=16, decPt=8) ++ // add 8-point mmio fft at the default addr (0x2400) with 16bit fixed-point numbers.
new chipyard.example.WithStreamingPassthrough ++ // use top with tilelink-controlled streaming passthrough
new chipyard.example.WithStreamingFIR ++ // use top with tilelink-controlled streaming FIR

View File

@@ -0,0 +1,41 @@
package chipyard
import org.chipsalliance.cde.config.{Config}
import freechips.rocketchip.diplomacy.{AsynchronousCrossing}
// ------------------------------------------------------------
// Configs which demonstrate modifying the uncore memory system
// ------------------------------------------------------------
class SimAXIRocketConfig extends Config(
new chipyard.harness.WithSimAXIMem ++ // drive the master AXI4 memory with a SimAXIMem, a 1-cycle magic memory, instead of default SimDRAM
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.AbstractConfig)
class GB1MemoryRocketConfig extends Config(
new freechips.rocketchip.subsystem.WithExtMemSize((1<<30) * 1L) ++ // use 1GB simulated external memory
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.AbstractConfig)
// DOC include start: mbusscratchpadrocket
class MbusScratchpadOnlyRocketConfig extends Config(
new testchipip.WithMbusScratchpad(banks=2, partitions=2) ++ // add 2 partitions of 2 banks mbus backing scratchpad
new freechips.rocketchip.subsystem.WithNoMemPort ++ // remove offchip mem port
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.AbstractConfig)
// DOC include end: mbusscratchpadrocket
class SbusScratchpadRocketConfig extends Config(
new testchipip.WithSbusScratchpad(base=0x70000000L, banks=4) ++ // add 4 banks sbus scratchpad
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.AbstractConfig)
class SbusBypassRocketConfig extends Config(
new freechips.rocketchip.subsystem.WithExtMemSbusBypass ++ // Add bypass path to access DRAM incoherently through an address alias
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.AbstractConfig)
class QuadChannelRocketConfig extends Config(
new freechips.rocketchip.subsystem.WithNMemoryChannels(4) ++ // 4 AXI4 channels
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.AbstractConfig)

View File

@@ -79,11 +79,6 @@ class ManyPeripheralsRocketConfig extends Config(
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.AbstractConfig)
class QuadChannelRocketConfig extends Config(
new freechips.rocketchip.subsystem.WithNMemoryChannels(4) ++ // 4 AXI4 channels
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.AbstractConfig)
class UARTTSIRocketConfig extends Config(
new chipyard.harness.WithSerialTLTiedOff ++
new testchipip.WithUARTTSIClient ++

View File

@@ -56,3 +56,9 @@ class HwachaLargeBoomConfig extends Config(
new boom.common.WithNLargeBooms(1) ++
new chipyard.config.WithSystemBusWidth(128) ++
new chipyard.config.AbstractConfig)
class AES256ECBRocketConfig extends Config(
new aes.WithAES256ECBAccel ++ // use Caliptra AES 256 ECB accelerator
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.WithSystemBusWidth(256) ++
new chipyard.config.AbstractConfig)

View File

@@ -13,18 +13,13 @@ class RocketConfig extends Config(
new chipyard.config.AbstractConfig)
class TinyRocketConfig extends Config(
new chipyard.iobinders.WithDontTouchIOBinders(false) ++ // TODO FIX: Don't dontTouch the ports
new chipyard.harness.WithDontTouchChipTopPorts(false) ++ // TODO FIX: Don't dontTouch the ports
new freechips.rocketchip.subsystem.WithIncoherentBusTopology ++ // use incoherent bus topology
new freechips.rocketchip.subsystem.WithNBanks(0) ++ // remove L2$
new freechips.rocketchip.subsystem.WithNoMemPort ++ // remove backing memory
new freechips.rocketchip.subsystem.With1TinyCore ++ // single tiny rocket-core
new chipyard.config.AbstractConfig)
class SimAXIRocketConfig extends Config(
new chipyard.harness.WithSimAXIMem ++ // drive the master AXI4 memory with a SimAXIMem, a 1-cycle magic memory, instead of default SimDRAM
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.AbstractConfig)
class QuadRocketConfig extends Config(
new freechips.rocketchip.subsystem.WithNBigCores(4) ++ // quad-core (4 RocketTiles)
new chipyard.config.AbstractConfig)
@@ -39,11 +34,6 @@ class RV32RocketConfig extends Config(
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.AbstractConfig)
class GB1MemoryRocketConfig extends Config(
new freechips.rocketchip.subsystem.WithExtMemSize((1<<30) * 1L) ++ // use 1GB simulated external memory
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.AbstractConfig)
// DOC include start: l1scratchpadrocket
class ScratchpadOnlyRocketConfig extends Config(
new chipyard.config.WithL2TLBs(0) ++
@@ -66,20 +56,6 @@ class L1ScratchpadRocketConfig extends Config(
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.AbstractConfig)
// DOC include start: mbusscratchpadrocket
class MbusScratchpadOnlyRocketConfig extends Config(
new testchipip.WithMbusScratchpad(banks=2, partitions=2) ++ // add 2 partitions of 2 banks mbus backing scratchpad
new freechips.rocketchip.subsystem.WithNoMemPort ++ // remove offchip mem port
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.AbstractConfig)
// DOC include end: mbusscratchpadrocket
class SbusScratchpadRocketConfig extends Config(
new testchipip.WithSbusScratchpad(base=0x70000000L, banks=4) ++ // add 4 banks sbus backing scratchpad
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.AbstractConfig)
class MulticlockRocketConfig extends Config(
new freechips.rocketchip.subsystem.WithAsynchronousRocketTiles(3, 3) ++ // Add async crossings between RocketTile and uncore
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
@@ -98,6 +74,7 @@ class MulticlockRocketConfig extends Config(
new chipyard.config.AbstractConfig)
class CustomIOChipTopRocketConfig extends Config(
new chipyard.example.WithBrokenOutUARTIO ++
new chipyard.example.WithCustomChipTop ++
new chipyard.example.WithCustomIOCells ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // single rocket-core

View File

@@ -77,7 +77,7 @@ class TutorialSha3BlackBoxConfig extends Config(
// Tutorial Phase 5: Map a multicore heterogeneous SoC with multiple cores and memory-mapped accelerators
class TutorialNoCConfig extends Config(
new chipyard.iobinders.WithDontTouchIOBinders(false) ++
new chipyard.harness.WithDontTouchChipTopPorts(false) ++
// Try changing the dimensions of the Mesh topology
new constellation.soc.WithGlobalNoC(constellation.soc.GlobalNoCParams(
NoCParams(

View File

@@ -13,6 +13,7 @@ import freechips.rocketchip.tilelink.{HasTLBusParams}
import chipyard._
import chipyard.clocking._
import testchipip.{OffchipBusKey}
// The default RocketChip BaseSubsystem drives its diplomatic clock graph
// with the implicit clocks of Subsystem. Don't do that, instead we extend
@@ -103,6 +104,9 @@ class WithFrontBusFrequency(freqMHz: Double) extends Config((site, here, up) =>
class WithControlBusFrequency(freqMHz: Double) extends Config((site, here, up) => {
case ControlBusKey => up(ControlBusKey, site).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
})
class WithOffchipBusFrequency(freqMHz: Double) extends Config((site, here, up) => {
case OffchipBusKey => up(OffchipBusKey, site).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
})
class WithRationalMemoryBusCrossing extends WithSbusToMbusCrossingType(RationalCrossing(Symmetric))
class WithAsynchrousMemoryBusCrossing extends WithSbusToMbusCrossingType(AsynchronousCrossing())

View File

@@ -29,7 +29,7 @@ import chipyard.{ExtTLMem}
* @param hang the power-on reset vector, i.e. the program counter will be set to this value on reset
* @param contentFileName the path to the BootROM image
*/
class WithBootROM(address: BigInt = 0x10000, size: Int = 0x10000, hang: BigInt = 0x10040) extends Config((site, here, up) => {
class WithBootROM(address: BigInt = 0x10000, size: Int = 0x10000, hang: BigInt = 0x10000) extends Config((site, here, up) => {
case BootROMLocated(x) => up(BootROMLocated(x), site)
.map(_.copy(
address = address,

View File

@@ -1,8 +1,9 @@
package chipyard.config
import org.chipsalliance.cde.config.{Config}
import freechips.rocketchip.subsystem.{SystemBusKey, SubsystemBankedCoherenceKey, CoherenceManagerWrapper}
import freechips.rocketchip.subsystem._
import freechips.rocketchip.diplomacy.{DTSTimebase}
import sifive.blocks.inclusivecache.{InclusiveCachePortParameters}
// Replaces the L2 with a broadcast manager for maintaining coherence
class WithBroadcastManager extends Config((site, here, up) => {
@@ -16,3 +17,13 @@ class WithSystemBusWidth(bitWidth: Int) extends Config((site, here, up) => {
class WithDTSTimebase(freqMHz: BigInt) extends Config((site, here, up) => {
case DTSTimebase => freqMHz
})
// Adds buffers on the interior of the inclusive LLC, to improve PD
class WithInclusiveCacheInteriorBuffer(buffer: InclusiveCachePortParameters = InclusiveCachePortParameters.full) extends Config((site, here, up) => {
case InclusiveCacheKey => up(InclusiveCacheKey).copy(bufInnerInterior=buffer, bufOuterInterior=buffer)
})
// Adds buffers on the exterior of the inclusive LLC, to improve PD
class WithInclusiveCacheExteriorBuffer(buffer: InclusiveCachePortParameters = InclusiveCachePortParameters.full) extends Config((site, here, up) => {
case InclusiveCacheKey => up(InclusiveCacheKey).copy(bufInnerExterior=buffer, bufOuterExterior=buffer)
})

View File

@@ -66,6 +66,15 @@ class WithNPMPs(n: Int = 8) extends Config((site, here, up) => {
}
})
class WithRocketCacheRowBits(rowBits: Int = 64) extends Config((site, here, up) => {
case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem)) map {
case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
dcache = tp.tileParams.dcache.map(_.copy(rowBits = rowBits)),
icache = tp.tileParams.icache.map(_.copy(rowBits = rowBits))
))
}
})
class WithRocketICacheScratchpad extends Config((site, here, up) => {
case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
@@ -96,3 +105,13 @@ class WithTilePrefetchers extends Config((site, here, up) => {
master = TilePrefetchingMasterPortParams(tp.tileParams.tileId, tp.crossingParams.master)))
}
})
// Adds boundary buffers to RocketTiles, which places buffers between the caches and the TileLink interface
// This typically makes it easier to close timing
class WithRocketBoundaryBuffers(buffers: Option[RocketTileBoundaryBufferParams] = Some(RocketTileBoundaryBufferParams(true))) extends Config((site, here, up) => {
case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem)) map {
case tp: RocketTileAttachParams => tp.copy(tileParams=tp.tileParams.copy(
boundaryBuffers=buffers
))
}
})

View File

@@ -5,9 +5,11 @@ import chipyard.iobinders._
import org.chipsalliance.cde.config._
import freechips.rocketchip.diplomacy.{InModuleBody}
import freechips.rocketchip.subsystem.{PBUS, HasTileLinkLocations}
import barstools.iocell.chisel._
import chipyard._
import chipyard.harness.{BuildTop}
import sifive.blocks.devices.uart._
// A "custom" IOCell with additional I/O
// The IO don't do anything here in this example
@@ -63,3 +65,21 @@ class WithCustomIOCells extends Config((site, here, up) => {
class WithCustomChipTop extends Config((site, here, up) => {
case BuildTop => (p: Parameters) => new CustomChipTop()(p)
})
class WithBrokenOutUARTIO extends OverrideIOBinder({
(system: HasPeripheryUARTModuleImp) => {
val uart_txd = IO(Output(Bool()))
val uart_rxd = IO(Input(Bool()))
system.uart(0).rxd := uart_rxd
uart_txd := system.uart(0).txd
val where = PBUS // TODO fix
val bus = system.outer.asInstanceOf[HasTileLinkLocations].locateTLBusWrapper(where)
val freqMHz = bus.dtsFrequency.get / 1000000
(Seq(UARTPort(() => {
val uart_wire = Wire(new UARTPortIO(system.uart(0).c))
uart_wire.txd := uart_txd
uart_rxd := uart_wire.rxd
uart_wire
}, 0, freqMHz.toInt)), Nil)
}
})

View File

@@ -2,22 +2,28 @@ package chipyard.example
import chisel3._
import org.chipsalliance.cde.config.{Field, Parameters}
import org.chipsalliance.cde.config.{Config, Field, Parameters}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.prci._
import freechips.rocketchip.util._
import freechips.rocketchip.subsystem.{PBUS, HasTileLinkLocations}
import freechips.rocketchip.devices.debug.{ExportDebug, JtagDTMKey, Debug}
import freechips.rocketchip.tilelink.{TLBuffer, TLFragmenter}
import chipyard.{BuildSystem, DigitalTop}
import chipyard.harness.{BuildTop}
import chipyard.clocking._
import chipyard.iobinders.{IOCellKey, JTAGChipIO}
import chipyard.iobinders._
import barstools.iocell.chisel._
import testchipip.{SerialTLKey}
class WithFlatChipTop extends Config((site, here, up) => {
case BuildTop => (p: Parameters) => new FlatChipTop()(p)
})
// This "FlatChipTop" uses no IOBinders, so all the IO have
// to be explicitly constructed.
// This only supports the base "DigitalTop"
class FlatChipTop(implicit p: Parameters) extends LazyModule {
class FlatChipTop(implicit p: Parameters) extends LazyModule with HasChipyardPorts {
override lazy val desiredName = "ChipTop"
val system = LazyModule(p(BuildSystem)(p)).suggestName("system").asInstanceOf[DigitalTop]
@@ -53,6 +59,8 @@ class FlatChipTop(implicit p: Parameters) extends LazyModule {
debugClockSinkNode := system.locateTLBusWrapper(p(ExportDebug).slaveWhere).fixedClockNode
def debugClockBundle = debugClockSinkNode.in.head._1
var ports: Seq[Port[_]] = Nil
override lazy val module = new FlatChipTopImpl
class FlatChipTopImpl extends LazyRawModuleImp(this) {
//=========================
@@ -68,6 +76,9 @@ class FlatChipTop(implicit p: Parameters) extends LazyModule {
o.reset := reset_wire
}
ports = ports :+ ClockPort(() => clock_pad, 100.0)
ports = ports :+ ResetPort(() => reset_pad)
// For a real chip you should replace this ClockSourceAtFreqFromPlusArg
// with a blackbox of whatever PLL is being integrated
val fake_pll = Module(new ClockSourceAtFreqFromPlusArg("pll_freq_mhz"))
@@ -83,11 +94,13 @@ class FlatChipTop(implicit p: Parameters) extends LazyModule {
// Custom Boot
//=========================
val (custom_boot_pad, customBootIOCell) = IOCell.generateIOFromSignal(system.custom_boot_pin.get.getWrappedValue, "custom_boot", p(IOCellKey))
ports = ports :+ CustomBootPort(() => custom_boot_pad)
//=========================
// Serialized TileLink
//=========================
val (serial_tl_pad, serialTLIOCells) = IOCell.generateIOFromSignal(system.serial_tl.get.getWrappedValue, "serial_tl", p(IOCellKey))
ports = ports :+ SerialTLPort(() => serial_tl_pad, p(SerialTLKey).get, system.serdesser.get, 0)
//=========================
// JTAG/Debug
@@ -126,12 +139,17 @@ class FlatChipTop(implicit p: Parameters) extends LazyModule {
IOCell.generateIOFromSignal(jtag_wire, "jtag", p(IOCellKey), abstractResetAsAsync = true)
}.get
ports = ports :+ JTAGPort(() => jtag_pad)
//==========================
// UART
//==========================
require(system.uarts.size == 1)
val (uart_pad, uartIOCells) = IOCell.generateIOFromSignal(system.module.uart.head, "uart_0", p(IOCellKey))
val where = PBUS // TODO fix
val bus = system.asInstanceOf[HasTileLinkLocations].locateTLBusWrapper(where)
val freqMHz = bus.dtsFrequency.get / 1000000
ports = ports :+ UARTPort(() => uart_pad, 0, freqMHz.toInt)
//==========================
// External interrupts (tie off)

View File

@@ -13,7 +13,7 @@ import freechips.rocketchip.util.UIntIsOneOf
// DOC include start: GCD params
case class GCDParams(
address: BigInt = 0x1000,
address: BigInt = 0x4000,
width: Int = 32,
useAXI4: Boolean = false,
useBlackBox: Boolean = true)

View File

@@ -10,7 +10,6 @@ import freechips.rocketchip.util.{ResetCatchAndSync}
import freechips.rocketchip.prci._
import chipyard.harness.{ApplyHarnessBinders, HarnessBinders, HarnessClockInstantiatorKey}
import chipyard.iobinders.HasIOBinders
import chipyard.clocking.{SimplePllConfiguration, ClockDividerN}

View File

@@ -5,12 +5,12 @@ import chisel3._
import scala.collection.mutable.{ArrayBuffer, LinkedHashMap}
import freechips.rocketchip.diplomacy.{LazyModule}
import org.chipsalliance.cde.config.{Field, Parameters, Config}
import freechips.rocketchip.util.{ResetCatchAndSync}
import freechips.rocketchip.util.{ResetCatchAndSync, DontTouch}
import freechips.rocketchip.prci.{ClockBundle, ClockBundleParameters, ClockSinkParameters, ClockParameters}
import chipyard.stage.phases.TargetDirKey
import chipyard.harness.{ApplyHarnessBinders, HarnessBinders}
import chipyard.iobinders.HasIOBinders
import chipyard.iobinders.HasChipyardPorts
import chipyard.clocking.{SimplePllConfiguration, ClockDividerN}
import chipyard.{ChipTop}
@@ -24,6 +24,7 @@ case object BuildTop extends Field[Parameters => LazyModule]((p: Parameters) =>
case object HarnessClockInstantiatorKey extends Field[() => HarnessClockInstantiator]()
case object HarnessBinderClockFrequencyKey extends Field[Double](100.0) // MHz
case object MultiChipIdx extends Field[Int](0)
case object DontTouchChipTopPorts extends Field[Boolean](true)
class WithMultiChip(id: Int, p: Parameters) extends Config((site, here, up) => {
case MultiChipParameters(`id`) => p
@@ -39,6 +40,10 @@ class WithHarnessBinderClockFreqMHz(freqMHz: Double) extends Config((site, here,
case HarnessBinderClockFrequencyKey => freqMHz
})
class WithDontTouchChipTopPorts(b: Boolean = true) extends Config((site, here, up) => {
case DontTouchChipTopPorts => b
})
// A TestHarness mixing this in will
// - use the HarnessClockInstantiator clock provide
trait HasHarnessInstantiators {
@@ -83,12 +88,20 @@ trait HasHarnessInstantiators {
withClockAndReset (harnessBinderClock, harnessBinderReset) {
lazyDuts.zipWithIndex.foreach {
case (d: HasIOBinders, i: Int) => ApplyHarnessBinders(this, d.portMap.values.flatten.toSeq)(chipParameters(i))
case (d: HasChipyardPorts, i: Int) => {
ApplyHarnessBinders(this, d.ports)(chipParameters(i))
}
case _ =>
}
ApplyMultiHarnessBinders(this, lazyDuts)
}
if (p(DontTouchChipTopPorts)) {
duts.map(_ match {
case d: DontTouch => d.dontTouchPorts()
})
}
val harnessBinderClk = harnessClockInstantiator.requestClockMHz("harnessbinder_clock", getHarnessBinderClockFreqMHz)
println(s"Harness binder clock is $harnessBinderClockFreq")
harnessBinderClock := harnessBinderClk

View File

@@ -13,7 +13,7 @@ import freechips.rocketchip.util._
import testchipip._
import chipyard._
import chipyard.iobinders.{GetSystemParameters, JTAGChipIO, HasIOBinders, Port, SerialTLPort}
import chipyard.iobinders.{GetSystemParameters, JTAGChipIO, HasChipyardPorts, Port, SerialTLPort}
import scala.reflect.{ClassTag}
@@ -23,43 +23,43 @@ object ApplyMultiHarnessBinders {
def apply(th: HasHarnessInstantiators, chips: Seq[LazyModule])(implicit p: Parameters): Unit = {
Seq.tabulate(chips.size, chips.size) { case (i, j) => if (i != j) {
(chips(i), chips(j)) match {
case (l0: HasIOBinders, l1: HasIOBinders) => p(MultiHarnessBinders(i, j)).foreach { f =>
f(l0.portMap.values.flatten.toSeq, l1.portMap.values.flatten.toSeq)
case (l0: HasChipyardPorts, l1: HasChipyardPorts) => p(MultiHarnessBinders(i, j)).foreach { f =>
f(th, l0.ports, l1.ports)
}
}
}}
}
}
class MultiHarnessBinder[T <: Port[_]](
class MultiHarnessBinder[T <: Port[_], S <: HasHarnessInstantiators](
chip0: Int, chip1: Int,
chip0portFn: T => Boolean, chip1portFn: T => Boolean,
connectFn: (T, T) => Unit
)(implicit tag: ClassTag[T]) extends Config((site, here, up) => {
connectFn: (S, T, T) => Unit
)(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, port: T) if chip0portFn(port) => }) ++ up(MultiChipParameters(chip0))
new HarnessBinder({case (th: S, port: T) if chip0portFn(port) => }) ++ up(MultiChipParameters(chip0))
)
case MultiChipParameters(`chip1`) => new Config(
new HarnessBinder({case (th, port: T) if chip1portFn(port) => }) ++ up(MultiChipParameters(chip1))
new HarnessBinder({case (th: S, port: T) if chip1portFn(port) => }) ++ up(MultiChipParameters(chip1))
)
// Set the multiharnessbinder key
case MultiHarnessBinders(`chip0`, `chip1`) => up(MultiHarnessBinders(chip0, chip1)) :+ {
((chip0Ports: Seq[Port[_]], chip1Ports: Seq[Port[_]]) => {
((th: S, chip0Ports: Seq[Port[_]], chip1Ports: Seq[Port[_]]) => {
val chip0Port: Seq[T] = chip0Ports.collect { case (p: T) if chip0portFn(p) => p }
val chip1Port: Seq[T] = chip1Ports.collect { case (p: T) if chip1portFn(p) => p }
require(chip0Port.size == 1 && chip1Port.size == 1)
connectFn(chip0Port(0), chip1Port(0))
connectFn(th, chip0Port(0), chip1Port(0))
})
}
})
class WithMultiChipSerialTL(chip0: Int, chip1: Int, chip0portId: Int = 0, chip1portId: Int = 0) extends MultiHarnessBinder[SerialTLPort](
class WithMultiChipSerialTL(chip0: Int, chip1: Int, chip0portId: Int = 0, chip1portId: Int = 0) extends MultiHarnessBinder(
chip0, chip1,
(p0: SerialTLPort) => p0.portId == chip0portId,
(p1: SerialTLPort) => p1.portId == chip1portId,
(p0: SerialTLPort, p1: SerialTLPort) => {
(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

View File

@@ -9,7 +9,6 @@ import freechips.rocketchip.util.{ResetCatchAndSync}
import freechips.rocketchip.prci.{ClockBundle, ClockBundleParameters, ClockSinkParameters, ClockParameters}
import chipyard.harness.{ApplyHarnessBinders, HarnessBinders}
import chipyard.iobinders.HasIOBinders
import chipyard.clocking.{SimplePllConfiguration, ClockDividerN}
import chipyard.{ChipTop}

View File

@@ -7,5 +7,5 @@ package object harness
{
import chipyard.iobinders.Port
type HarnessBinderFunction = PartialFunction[(HasHarnessInstantiators, Port[_]), Unit]
type MultiHarnessBinderFunction = (Seq[Port[_]], Seq[Port[_]]) => Unit
type MultiHarnessBinderFunction = (HasHarnessInstantiators, Seq[Port[_]], Seq[Port[_]]) => Unit
}

View File

@@ -51,13 +51,7 @@ case object IOBinders extends Field[Map[String, Seq[IOBinderFunction]]](
Map[String, Seq[IOBinderFunction]]().withDefaultValue(Nil)
)
case object DontTouchIOBindersPorts extends Field[Boolean](true)
class WithDontTouchIOBinders(b: Boolean = true) extends Config((site, here, up) => {
case DontTouchIOBindersPorts => b
})
abstract trait HasIOBinders { this: LazyModule =>
abstract trait HasIOBinders extends HasChipyardPorts { this: LazyModule =>
val lazySystem: LazyModule
private val iobinders = p(IOBinders)
// Note: IOBinders cannot rely on the implicit clock/reset, as they may be called from the
@@ -81,11 +75,9 @@ abstract trait HasIOBinders { this: LazyModule =>
// A mapping between stringified DigitalSystem traits and their corresponding ChipTop iocells
val iocellMap = InModuleBody { iobinders.keys.map(k => k -> (lzyFlattened(k)._2 ++ impFlattened(k)._2)).toMap }
InModuleBody {
if (p(DontTouchIOBindersPorts)) {
portMap.values.flatten.foreach { case (port: Port[Data]) => dontTouch(port.io) }
}
def ports = portMap.getWrappedValue.values.flatten.toSeq
InModuleBody {
println("IOCells generated by IOBinders:")
for ((k, v) <- iocellMap) {
if (!v.isEmpty) {
@@ -172,7 +164,7 @@ class WithGPIOCells extends OverrideIOBinder({
iocell.io.ie := pin.o.ie
pin.i.ival := iocell.io.i
iocell.io.pad <> g
(GPIOPort(g, i, j), iocell)
(GPIOPort(() => g, i, j), iocell)
}).unzip
}).unzip
(ports2d.flatten, cells2d.flatten)
@@ -184,7 +176,7 @@ class WithGPIOPunchthrough extends OverrideIOBinder({
val ports = system.gpio.zipWithIndex.map { case (gpio, i) =>
val io_gpio = IO(gpio.cloneType).suggestName(s"gpio_$i")
io_gpio <> gpio
GPIOPinsPort(io_gpio, i)
GPIOPinsPort(() => io_gpio, i)
}
(ports, Nil)
}
@@ -195,7 +187,7 @@ class WithI2CPunchthrough extends OverrideIOBinder({
val ports = system.i2c.zipWithIndex.map { case (i2c, i) =>
val io_i2c = IO(i2c.cloneType).suggestName(s"i2c_$i")
io_i2c <> i2c
I2CPort(i2c)
I2CPort(() => i2c)
}
(ports, Nil)
}
@@ -209,7 +201,7 @@ class WithUARTIOCells extends OverrideIOBinder({
val where = PBUS // TODO fix
val bus = system.outer.asInstanceOf[HasTileLinkLocations].locateTLBusWrapper(where)
val freqMHz = bus.dtsFrequency.get / 1000000
(UARTPort(port, i, freqMHz.toInt), ios)
(UARTPort(() => port, i, freqMHz.toInt), ios)
}).unzip
(ports, cells2d.flatten)
}
@@ -227,7 +219,7 @@ class WithSPIIOPunchthrough extends OverrideLazyIOBinder({
val ports = spi.zipWithIndex.map({ case (s, i) =>
val io_spi = IO(s.cloneType).suggestName(s"spi_$i")
io_spi <> s
SPIPort(io_spi)
SPIPort(() => io_spi)
})
(ports, Nil)
}
@@ -257,7 +249,7 @@ class WithSPIFlashIOCells extends OverrideIOBinder({
iocell
}
(SPIFlashPort(port, system.p(PeripherySPIFlashKey)(i), i), dqIOs ++ csIOs ++ sckIOs)
(SPIFlashPort(() => port, system.p(PeripherySPIFlashKey)(i), i), dqIOs ++ csIOs ++ sckIOs)
}).unzip
(ports, cells2d.flatten)
}
@@ -267,7 +259,7 @@ class WithExtInterruptIOCells extends OverrideIOBinder({
(system: HasExtInterruptsModuleImp) => {
if (system.outer.nExtInterrupts > 0) {
val (port: UInt, cells) = IOCell.generateIOFromSignal(system.interrupts, "ext_interrupts", system.p(IOCellKey), abstractResetAsAsync = true)
(Seq(ExtIntPort(port)), cells)
(Seq(ExtIntPort(() => port)), cells)
} else {
system.interrupts := DontCare // why do I have to drive this 0-wide wire???
(Nil, Nil)
@@ -318,7 +310,7 @@ class WithDebugIOCells extends OverrideLazyIOBinder({
// Add IOCells for the DMI/JTAG/APB ports
val dmiTuple = debug.clockeddmi.map { d =>
val (port, cells) = IOCell.generateIOFromSignal(d, "dmi", p(IOCellKey), abstractResetAsAsync = true)
(DMIPort(port), cells)
(DMIPort(() => port), cells)
}
val jtagTuple = debug.systemjtag.map { j =>
@@ -328,7 +320,7 @@ class WithDebugIOCells extends OverrideLazyIOBinder({
j.jtag.TDI := jtag_wire.TDI
jtag_wire.TDO := j.jtag.TDO.data
val (port, cells) = IOCell.generateIOFromSignal(jtag_wire, "jtag", p(IOCellKey), abstractResetAsAsync = true)
(JTAGPort(port), cells)
(JTAGPort(() => port), cells)
}
require(!debug.apb.isDefined)
@@ -345,7 +337,7 @@ class WithSerialTLIOCells extends OverrideIOBinder({
val (ports, cells) = system.serial_tl.zipWithIndex.map({ case (s, id) =>
val sys = system.asInstanceOf[BaseSubsystem]
val (port, cells) = IOCell.generateIOFromSignal(s.getWrappedValue, "serial_tl", sys.p(IOCellKey), abstractResetAsAsync = true)
(SerialTLPort(port, sys.p(SerialTLKey).get, system.serdesser.get, id), cells)
(SerialTLPort(() => port, sys.p(SerialTLKey).get, system.serdesser.get, id), cells)
}).unzip
(ports.toSeq, cells.flatten.toSeq)
}
@@ -355,9 +347,9 @@ class WithSerialTLPunchthrough extends OverrideIOBinder({
(system: CanHavePeripheryTLSerial) => {
val (ports, cells) = system.serial_tl.zipWithIndex.map({ case (s, id) =>
val sys = system.asInstanceOf[BaseSubsystem]
val port = IO(s.getWrappedValue.cloneType)
val port = IO(chiselTypeOf(s.getWrappedValue))
port <> s.getWrappedValue
(SerialTLPort(port, sys.p(SerialTLKey).get, system.serdesser.get, id), Nil)
(SerialTLPort(() => port, sys.p(SerialTLKey).get, system.serdesser.get, id), Nil)
}).unzip
(ports.toSeq, cells.flatten.toSeq)
}
@@ -375,7 +367,7 @@ class WithAXI4MemPunchthrough extends OverrideLazyIOBinder({
val port = IO(new ClockedIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mem_${i}")
port.bits <> m
port.clock := clockBundle.clock
AXI4MemPort(port, p(ExtMem).get, system.memAXI4Node.edges.in(i), p(MemoryBusKey).dtsFrequency.get.toInt)
AXI4MemPort(() => port, p(ExtMem).get, system.memAXI4Node.edges.in(i), p(MemoryBusKey).dtsFrequency.get.toInt)
}).toSeq
(ports, Nil)
}
@@ -394,7 +386,7 @@ class WithAXI4MMIOPunchthrough extends OverrideLazyIOBinder({
val port = IO(new ClockedIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mmio_${i}")
port.bits <> m
port.clock := clockBundle.clock
AXI4MMIOPort(port, p(ExtBus).get, system.mmioAXI4Node.edges.in(i))
AXI4MMIOPort(() => port, p(ExtBus).get, system.mmioAXI4Node.edges.in(i))
}).toSeq
(ports, Nil)
}
@@ -413,7 +405,7 @@ class WithL2FBusAXI4Punchthrough extends OverrideLazyIOBinder({
val port = IO(new ClockedIO(Flipped(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)))).suggestName(s"axi4_fbus_${i}")
m <> port.bits
port.clock := clockBundle.clock
AXI4InPort(port, p(ExtIn).get)
AXI4InPort(() => port, p(ExtIn).get)
}).toSeq
(ports, Nil)
}
@@ -427,7 +419,7 @@ class WithBlockDeviceIOPunchthrough extends OverrideIOBinder({
val bdParams = p(BlockDeviceKey).get
val port = IO(new ClockedIO(new BlockDeviceIO(bdParams))).suggestName("blockdev")
port <> bdev
BlockDevicePort(port, bdParams)
BlockDevicePort(() => port, bdParams)
}).toSeq
(ports, Nil)
}
@@ -439,7 +431,7 @@ class WithNICIOPunchthrough extends OverrideIOBinder({
val p = GetSystemParameters(system)
val port = IO(new ClockedIO(new NICIOvonly)).suggestName("nic")
port <> n
NICPort(port, p(NICKey).get)
NICPort(() => port, p(NICKey).get)
}).toSeq
(ports, Nil)
}
@@ -449,7 +441,7 @@ class WithTraceGenSuccessPunchthrough extends OverrideIOBinder({
(system: TraceGenSystemModuleImp) => {
val success: Bool = IO(Output(Bool())).suggestName("success")
success := system.success
(Seq(SuccessPort(success)), Nil)
(Seq(SuccessPort(() => success)), Nil)
}
})
@@ -472,7 +464,7 @@ class WithTraceIOPunchthrough extends OverrideLazyIOBinder({
bootrom = chipyardSystem.bootROM.map(_.module.contents.toArray.mkString(" ")).getOrElse(""),
has_dtm = p(ExportDebug).protocols.contains(DMI) // assume that exposing clockeddmi means we will connect SimDTM
)
TracePort(trace, cfg)
TracePort(() => trace, cfg)
}
(ports.toSeq, Nil)
}
@@ -482,7 +474,7 @@ class WithCustomBootPin extends OverrideIOBinder({
(system: CanHavePeripheryCustomBootPin) => system.custom_boot_pin.map({ p =>
val sys = system.asInstanceOf[BaseSubsystem]
val (port, cells) = IOCell.generateIOFromSignal(p.getWrappedValue, "custom_boot", sys.p(IOCellKey), abstractResetAsAsync = true)
(Seq(CustomBootPort(port)), cells)
(Seq(CustomBootPort(() => port)), cells)
}).getOrElse((Nil, Nil))
})
@@ -491,7 +483,7 @@ class WithUARTTSIPunchthrough extends OverrideIOBinder({
val sys = system.asInstanceOf[BaseSubsystem]
val uart_tsi = IO(new UARTTSIIO(p.uartParams))
uart_tsi <> p
(Seq(UARTTSIPort(uart_tsi)), Nil)
(Seq(UARTTSIPort(() => uart_tsi)), Nil)
}).getOrElse((Nil, Nil))
})
@@ -499,7 +491,7 @@ class WithTLMemPunchthrough extends OverrideIOBinder({
(system: CanHaveMasterTLMemPort) => {
val io_tl_mem_pins_temp = IO(DataMirror.internal.chiselTypeClone[HeterogeneousBag[TLBundle]](system.mem_tl)).suggestName("tl_slave")
io_tl_mem_pins_temp <> system.mem_tl
(Seq(TLMemPort(io_tl_mem_pins_temp)), Nil)
(Seq(TLMemPort(() => io_tl_mem_pins_temp)), Nil)
}
})

View File

@@ -16,79 +16,85 @@ import freechips.rocketchip.util.{HeterogeneousBag}
import freechips.rocketchip.tilelink.{TLBundle}
trait Port[T <: Data] {
val io: T
val getIO: () => T
// port.io should only be called in the TestHarness context
lazy val io = getIO()
}
trait HasChipyardPorts {
def ports: Seq[Port[_]]
}
// These case classes are generated by IOBinders, and interpreted by HarnessBinders
case class GPIOPort (val io: Analog, val gpioId: Int, val pinId: Int)
case class GPIOPort (val getIO: () => Analog, val gpioId: Int, val pinId: Int)
extends Port[Analog]
case class GPIOPinsPort (val io: GPIOPortIO, val gpioId: Int)
case class GPIOPinsPort (val getIO: () => GPIOPortIO, val gpioId: Int)
extends Port[GPIOPortIO]
case class I2CPort (val io: sifive.blocks.devices.i2c.I2CPort)
case class I2CPort (val getIO: () => sifive.blocks.devices.i2c.I2CPort)
extends Port[sifive.blocks.devices.i2c.I2CPort]
case class UARTPort (val io: UARTPortIO, val uartNo: Int, val freqMHz: Int)
case class UARTPort (val getIO: () => UARTPortIO, val uartNo: Int, val freqMHz: Int)
extends Port[UARTPortIO]
case class SPIFlashPort (val io: SPIChipIO, val params: SPIFlashParams, val spiId: Int)
case class SPIFlashPort (val getIO: () => SPIChipIO, val params: SPIFlashParams, val spiId: Int)
extends Port[SPIChipIO]
case class SPIPort (val io: SPIPortIO)
case class SPIPort (val getIO: () => SPIPortIO)
extends Port[SPIPortIO]
case class BlockDevicePort (val io: ClockedIO[BlockDeviceIO], val params: BlockDeviceConfig)
case class BlockDevicePort (val getIO: () => ClockedIO[BlockDeviceIO], val params: BlockDeviceConfig)
extends Port[ClockedIO[BlockDeviceIO]]
case class NICPort (val io: ClockedIO[NICIOvonly], val params: NICConfig)
case class NICPort (val getIO: () => ClockedIO[NICIOvonly], val params: NICConfig)
extends Port[ClockedIO[NICIOvonly]]
case class AXI4MemPort (val io: ClockedIO[AXI4Bundle], val params: MemoryPortParams, val edge: AXI4EdgeParameters, val clockFreqMHz: Int)
case class AXI4MemPort (val getIO: () => ClockedIO[AXI4Bundle], val params: MemoryPortParams, val edge: AXI4EdgeParameters, val clockFreqMHz: Int)
extends Port[ClockedIO[AXI4Bundle]]
case class AXI4MMIOPort (val io: ClockedIO[AXI4Bundle], val params: MasterPortParams, val edge: AXI4EdgeParameters)
case class AXI4MMIOPort (val getIO: () => ClockedIO[AXI4Bundle], val params: MasterPortParams, val edge: AXI4EdgeParameters)
extends Port[ClockedIO[AXI4Bundle]]
case class AXI4InPort (val io: ClockedIO[AXI4Bundle], val params: SlavePortParams)
case class AXI4InPort (val getIO: () => ClockedIO[AXI4Bundle], val params: SlavePortParams)
extends Port[ClockedIO[AXI4Bundle]]
case class ExtIntPort (val io: UInt)
case class ExtIntPort (val getIO: () => UInt)
extends Port[UInt]
case class DMIPort (val io: ClockedDMIIO)
case class DMIPort (val getIO: () => ClockedDMIIO)
extends Port[ClockedDMIIO]
case class JTAGPort (val io: JTAGChipIO)
case class JTAGPort (val getIO: () => JTAGChipIO)
extends Port[JTAGChipIO]
case class SerialTLPort (val io: ClockedIO[SerialIO], val params: SerialTLParams, val serdesser: TLSerdesser, val portId: Int)
case class SerialTLPort (val getIO: () => ClockedIO[SerialIO], val params: SerialTLParams, val serdesser: TLSerdesser, val portId: Int)
extends Port[ClockedIO[SerialIO]]
case class UARTTSIPort (val io: UARTTSIIO)
case class UARTTSIPort (val getIO: () => UARTTSIIO)
extends Port[UARTTSIIO]
case class SuccessPort (val io: Bool)
case class SuccessPort (val getIO: () => Bool)
extends Port[Bool]
case class TracePort (val io: TraceOutputTop, val cosimCfg: SpikeCosimConfig)
case class TracePort (val getIO: () => TraceOutputTop, val cosimCfg: SpikeCosimConfig)
extends Port[TraceOutputTop]
case class CustomBootPort (val io: Bool)
case class CustomBootPort (val getIO: () => Bool)
extends Port[Bool]
case class ClockPort (val io: Clock, val freqMHz: Double)
case class ClockPort (val getIO: () => Clock, val freqMHz: Double)
extends Port[Clock]
case class ResetPort (val io: AsyncReset)
case class ResetPort (val getIO: () => AsyncReset)
extends Port[Reset]
case class DebugResetPort (val io: Reset)
case class DebugResetPort (val getIO: () => Reset)
extends Port[Reset]
case class JTAGResetPort (val io: Reset)
case class JTAGResetPort (val getIO: () => Reset)
extends Port[Reset]
case class TLMemPort (val io: HeterogeneousBag[TLBundle])
case class TLMemPort (val getIO: () => HeterogeneousBag[TLBundle])
extends Port[HeterogeneousBag[TLBundle]]

View File

@@ -106,7 +106,7 @@ class WithFireSimDesignTweaks extends Config(
new chipyard.config.WithUARTInitBaudRate(BigInt(3686400L)) ++
// Optional: Adds IO to attach tracerV bridges
new chipyard.config.WithTraceIO ++
// Optional: Request 16 GiB of target-DRAM by default (can safely request up to 32 GiB on F1)
// Optional: Request 16 GiB of target-DRAM by default (can safely request up to 64 GiB on F1)
new freechips.rocketchip.subsystem.WithExtMemSize((1 << 30) * 16L) ++
// Optional: Removing this will require using an initramfs under linux
new testchipip.WithBlockDevice