Merge branch 'main' of github.com:ucb-bar/chipyard into enable-sba

This commit is contained in:
-T.K.-
2024-02-11 14:38:21 -08:00
30 changed files with 314 additions and 763 deletions

View File

@@ -11,24 +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.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
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 ++
@@ -53,43 +60,98 @@ class AbstractConfig extends Config(
new chipyard.iobinders.WithUARTTSIPunchthrough ++
new chipyard.iobinders.WithNMITiedOff ++
new chipyard.clocking.WithClockTapIOCells ++ // Default generate a clock tapio
new chipyard.clocking.WithPassthroughClockGenerator ++ // Default punch out IOs to the Harness
new chipyard.clocking.WithClockGroupsCombinedByName(("uncore", // Default merge all the bus clocks
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.WithControlBusFrequency(500.0) ++ // Default 500 MHz cbus
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()), // serial-tilelink interface will master the FBUS, and support 4 idBits
phyParams = testchipip.serdes.ExternalSyncSerialParams(width=32) // serial-tilelink interface with 32 lanes
client = Some(testchipip.serdes.SerialTLClientParams(idBits=4)), /** serial-tilelink interface will master the FBUS, and support 4 idBits */
phyParams = testchipip.serdes.ExternalSyncSerialParams(width=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.WithNoSubsystemClockIO ++ // 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.WithDebugSBA ++ // enable the SBA (system-bus-access) feature of the debug module
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 */
)

View File

@@ -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
@@ -164,7 +198,8 @@ trait CanHavePeripheryGCD { this: BaseSubsystem =>
val gcd_busy = p(GCDKey) match {
case Some(params) => {
val gcd = if (params.useAXI4) {
val gcd = pbus { LazyModule(new GCDAXI4(params, pbus.beatBytes)(p)) }
val gcd = LazyModule(new GCDAXI4(params, pbus.beatBytes)(p))
gcd.clockNode := pbus.fixedClockNode
pbus.coupleTo(portName) {
gcd.node :=
AXI4Buffer () :=
@@ -174,18 +209,14 @@ trait CanHavePeripheryGCD { this: BaseSubsystem =>
}
gcd
} else {
val gcd = pbus { LazyModule(new GCDTL(params, pbus.beatBytes)(p)) }
val gcd = LazyModule(new GCDTL(params, pbus.beatBytes)(p))
gcd.clockNode := pbus.fixedClockNode
pbus.coupleTo(portName) { gcd.node := TLFragmenter(pbus.beatBytes, pbus.blockBytes) := _ }
gcd
}
val pbus_io = pbus { InModuleBody {
val busy = IO(Output(Bool()))
busy := gcd.module.io.gcd_busy
busy
}}
val gcd_busy = InModuleBody {
val busy = IO(Output(Bool())).suggestName("gcd_busy")
busy := pbus_io
busy := gcd.module.io.gcd_busy
busy
}
Some(gcd_busy)

View File

@@ -360,3 +360,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)