Got VexRiscvSmpLitexCluster refractoring to work

This commit is contained in:
Dolu1990 2020-06-30 22:29:33 +02:00
parent 0da94ac66f
commit 32539dfe6d
4 changed files with 442 additions and 311 deletions

View File

@ -0,0 +1,156 @@
package vexriscv
import spinal.core._
import spinal.lib.bus.bmb.{Bmb, BmbAccessCapabilities, BmbAccessParameter, BmbImplicitDebugDecoder, BmbParameter, BmbSmpInterconnectGenerator}
import spinal.lib.bus.misc.AddressMapping
import spinal.lib.com.jtag.{Jtag, JtagTapInstructionCtrl}
import spinal.lib.generator._
import spinal.lib.slave
import vexriscv.plugin._
object VexRiscvBmbGenerator{
val DEBUG_NONE = 0
val DEBUG_JTAG = 1
val DEBUG_JTAG_CTRL = 2
val DEBUG_BUS = 3
val DEBUG_BMB = 4
}
case class VexRiscvBmbGenerator()(implicit interconnectSmp: BmbSmpInterconnectGenerator = null) extends Generator {
import VexRiscvBmbGenerator._
val config = Handle[VexRiscvConfig]
val withDebug = Handle[Int]
val debugClockDomain = Handle[ClockDomain]
val debugReset = Handle[Bool]
val debugAskReset = Handle[() => Unit]
val hardwareBreakpointCount = Handle(0)
val iBus, dBus = product[Bmb]
val externalInterrupt = product[Bool]
val externalSupervisorInterrupt = product[Bool]
val timerInterrupt = product[Bool]
val softwareInterrupt = product[Bool]
def setTimerInterrupt(that: Handle[Bool]) = Dependable(that, timerInterrupt){timerInterrupt := that}
def setSoftwareInterrupt(that: Handle[Bool]) = Dependable(that, softwareInterrupt){softwareInterrupt := that}
def disableDebug() = {
withDebug.load(DEBUG_NONE)
}
def enableJtag(debugCd : ClockDomainResetGenerator, resetCd : ClockDomainResetGenerator) : Unit = debugCd{
this.debugClockDomain.merge(debugCd.outputClockDomain)
val resetBridge = resetCd.asyncReset(debugReset, ResetSensitivity.HIGH)
debugAskReset.load(null)
withDebug.load(DEBUG_JTAG)
}
def enableJtagInstructionCtrl(debugCd : ClockDomainResetGenerator, resetCd : ClockDomainResetGenerator) : Unit = debugCd{
this.debugClockDomain.merge(debugCd.outputClockDomain)
val resetBridge = resetCd.asyncReset(debugReset, ResetSensitivity.HIGH)
debugAskReset.load(null)
withDebug.load(DEBUG_JTAG_CTRL)
dependencies += jtagClockDomain
}
def enableDebugBus(debugCd : ClockDomainResetGenerator, resetCd : ClockDomainResetGenerator) : Unit = debugCd{
this.debugClockDomain.merge(debugCd.outputClockDomain)
val resetBridge = resetCd.asyncReset(debugReset, ResetSensitivity.HIGH)
debugAskReset.load(null)
withDebug.load(DEBUG_BUS)
}
val debugBmbAccessSource = Handle[BmbAccessCapabilities]
val debugBmbAccessRequirements = Handle[BmbAccessParameter]
def enableDebugBmb(debugCd : ClockDomainResetGenerator, resetCd : ClockDomainResetGenerator, mapping : AddressMapping)(implicit debugMaster : BmbImplicitDebugDecoder = null) : Unit = debugCd{
this.debugClockDomain.merge(debugCd.outputClockDomain)
val resetBridge = resetCd.asyncReset(debugReset, ResetSensitivity.HIGH)
debugAskReset.load(null)
withDebug.load(DEBUG_BMB)
val slaveModel = interconnectSmp.addSlave(
accessSource = debugBmbAccessSource,
accessCapabilities = debugBmbAccessSource.derivate(DebugExtensionBus.getBmbAccessParameter(_)),
accessRequirements = debugBmbAccessRequirements,
bus = debugBmb,
mapping = mapping
)
slaveModel.onClockDomain(debugCd.outputClockDomain)
debugBmb.derivatedFrom(debugBmbAccessRequirements)(Bmb(_))
if(debugMaster != null) interconnectSmp.addConnection(debugMaster.bus, debugBmb)
dependencies += debugBmb
}
dependencies ++= List(config)
dependencies += Dependable(withDebug) {
if (withDebug.get != DEBUG_NONE) {
dependencies ++= List(debugClockDomain, debugAskReset)
}
}
val jtag = add task (withDebug.get == DEBUG_JTAG generate slave(Jtag()))
val jtagInstructionCtrl = withDebug.produce(withDebug.get == DEBUG_JTAG_CTRL generate JtagTapInstructionCtrl())
val debugBus = withDebug.produce(withDebug.get == DEBUG_BUS generate DebugExtensionBus())
val debugBmb = Handle[Bmb]
val jtagClockDomain = Handle[ClockDomain]
val logic = add task new Area {
withDebug.get != DEBUG_NONE generate new Area {
config.add(new DebugPlugin(debugClockDomain, hardwareBreakpointCount))
}
val cpu = new VexRiscv(config)
for (plugin <- cpu.plugins) plugin match {
case plugin: IBusSimplePlugin => iBus.load(plugin.iBus.toBmb())
case plugin: DBusSimplePlugin => dBus.load(plugin.dBus.toBmb())
case plugin: IBusCachedPlugin => iBus.load(plugin.iBus.toBmb())
case plugin: DBusCachedPlugin => dBus.load(plugin.dBus.toBmb())
case plugin: CsrPlugin => {
externalInterrupt load plugin.externalInterrupt
timerInterrupt load plugin.timerInterrupt
softwareInterrupt load plugin.softwareInterrupt
if (plugin.config.supervisorGen) externalSupervisorInterrupt load plugin.externalInterruptS
}
case plugin: DebugPlugin => plugin.debugClockDomain {
if(debugAskReset.get != null) when(RegNext(plugin.io.resetOut)) {
debugAskReset.get()
} else {
debugReset.load(RegNext(plugin.io.resetOut))
}
withDebug.get match {
case DEBUG_JTAG => jtag <> plugin.io.bus.fromJtag()
case DEBUG_JTAG_CTRL => jtagInstructionCtrl <> plugin.io.bus.fromJtagInstructionCtrl(jtagClockDomain)
case DEBUG_BUS => debugBus <> plugin.io.bus
case DEBUG_BMB => debugBmb >> plugin.io.bus.fromBmb()
}
}
case _ =>
}
}
val parameterGenerator = new Generator {
val iBusParameter, dBusParameter = product[BmbParameter]
dependencies += config
add task {
for (plugin <- config.plugins) plugin match {
case plugin: IBusSimplePlugin => iBusParameter.load(IBusSimpleBus.getBmbParameter())
case plugin: DBusSimplePlugin => dBusParameter.load(DBusSimpleBus.getBmbParameter())
case plugin: IBusCachedPlugin => iBusParameter.load(plugin.config.getBmbParameter())
case plugin: DBusCachedPlugin => dBusParameter.load(plugin.config.getBmbParameter())
case _ =>
}
}
}
if(interconnectSmp != null){
interconnectSmp.addMaster(accessRequirements = parameterGenerator.iBusParameter.derivate(_.access), bus = iBus)
interconnectSmp.addMaster(accessRequirements = parameterGenerator.dBusParameter.derivate(_.access), bus = dBus)
}
}

View File

@ -9,6 +9,7 @@ import spinal.lib._
import spinal.lib.bus.bmb.sim.{BmbMemoryMultiPort, BmbMemoryTester}
import spinal.lib.bus.misc.{AddressMapping, DefaultMapping, SizeMapping}
import spinal.lib.eda.bench.Bench
import spinal.lib.generator.{Generator, Handle}
import spinal.lib.misc.Clint
import spinal.lib.sim.{SimData, SparseMemory, StreamDriver, StreamMonitor, StreamReadyRandomizer}
import vexriscv.{VexRiscv, VexRiscvConfig}
@ -245,3 +246,43 @@ object BmbToLiteDramTester extends App{
dut.io.output.simSlave(tester.memory.memory, dut.clockDomain)
}
}
case class BmbToLiteDramGenerator(mapping : AddressMapping)(implicit interconnect : BmbSmpInterconnectGenerator) extends Generator{
val liteDramParameter = createDependency[LiteDramNativeParameter]
val bmb = produce(logic.io.input)
val dram = produceIo(logic.io.output)
val accessSource = Handle[BmbAccessCapabilities]
val accessRequirements = createDependency[BmbAccessParameter]
interconnect.addSlave(
accessSource = accessSource,
accessCapabilities = accessSource,
accessRequirements = accessRequirements,
bus = bmb,
mapping = mapping
)
val logic = add task BmbToLiteDram(
bmbParameter = accessRequirements.toBmbParameter(),
liteDramParameter = liteDramParameter,
wdataFifoSize = 32,
rdataFifoSize = 32
)
}
case class BmbToWishboneGenerator(mapping : AddressMapping)(implicit interconnect : BmbSmpInterconnectGenerator) extends Generator{
val bmb = produce(logic.io.input)
val wishbone = produce(logic.io.output)
val accessSource = Handle[BmbAccessCapabilities]
val accessRequirements = createDependency[BmbAccessParameter]
interconnect.addSlave(
accessSource = accessSource,
accessCapabilities = accessSource,
accessRequirements = accessRequirements,
bus = bmb,
mapping = mapping
)
val logic = add task BmbToWishbone(
p = accessRequirements.toBmbParameter()
)
}

View File

@ -5,21 +5,110 @@ import spinal.core._
import spinal.core.sim.{onSimEnd, simSuccess}
import spinal.lib._
import spinal.lib.bus.bmb.sim.BmbMemoryAgent
import spinal.lib.bus.bmb.{Bmb, BmbArbiter, BmbDecoder, BmbExclusiveMonitor, BmbInvalidateMonitor, BmbParameter}
import spinal.lib.bus.misc.SizeMapping
import spinal.lib.com.jtag.{Jtag, JtagTapInstructionCtrl}
import spinal.lib.bus.bmb._
import spinal.lib.bus.misc.{DefaultMapping, SizeMapping}
import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig, WishboneToBmb, WishboneToBmbGenerator}
import spinal.lib.com.jtag.{Jtag, JtagInstructionDebuggerGenerator, JtagTapInstructionCtrl}
import spinal.lib.com.jtag.sim.JtagTcp
import spinal.lib.com.jtag.xilinx.Bscane2BmbMasterGenerator
import spinal.lib.generator.Handle
import spinal.lib.misc.plic.PlicMapping
import spinal.lib.system.debugger.SystemDebuggerConfig
import vexriscv.ip.{DataCacheAck, DataCacheConfig, DataCacheMemBus, InstructionCache, InstructionCacheConfig}
import vexriscv.plugin.{BranchPlugin, CsrAccess, CsrPlugin, CsrPluginConfig, DBusCachedPlugin, DBusSimplePlugin, DYNAMIC_TARGET, DebugPlugin, DecoderSimplePlugin, FullBarrelShifterPlugin, HazardSimplePlugin, IBusCachedPlugin, IBusSimplePlugin, IntAluPlugin, MmuPlugin, MmuPortConfig, MulDivIterativePlugin, MulPlugin, RegFilePlugin, STATIC, SrcPlugin, YamlPlugin}
import vexriscv.{Riscv, VexRiscv, VexRiscvConfig, plugin}
import vexriscv.{Riscv, VexRiscv, VexRiscvBmbGenerator, VexRiscvConfig, plugin}
import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer
import spinal.lib.generator._
case class VexRiscvSmpClusterParameter( cpuConfigs : Seq[VexRiscvConfig])
class VexRiscvSmpClusterBase(p : VexRiscvSmpClusterParameter) extends Generator{
val cpuCount = p.cpuConfigs.size
val debugCd = ClockDomainResetGenerator()
debugCd.holdDuration.load(4095)
debugCd.makeExternal()
val systemCd = ClockDomainResetGenerator()
systemCd.holdDuration.load(63)
systemCd.setInput(debugCd)
this.onClockDomain(systemCd.outputClockDomain)
implicit val interconnect = BmbSmpInterconnectGenerator()
val debugBridge = JtagInstructionDebuggerGenerator() onClockDomain(debugCd.outputClockDomain)
debugBridge.jtagClockDomain.load(ClockDomain.external("jtag", withReset = false))
val debugPort = debugBridge.produceIo(debugBridge.logic.jtagBridge.io.ctrl)
val exclusiveMonitor = BmbExclusiveMonitorGenerator()
val invalidationMonitor = BmbInvalidateMonitorGenerator()
interconnect.addConnection(exclusiveMonitor.output, invalidationMonitor.input)
interconnect.masters(invalidationMonitor.output).withOutOfOrderDecoder()
val cores = for(cpuId <- 0 until cpuCount) yield new Area{
val cpu = VexRiscvBmbGenerator()
cpu.config.load(p.cpuConfigs(cpuId))
interconnect.addConnection(
cpu.dBus -> List(exclusiveMonitor.input)
)
cpu.enableDebugBmb(
debugCd = debugCd,
resetCd = systemCd,
mapping = SizeMapping(cpuId*0x1000, 0x1000)
)
interconnect.addConnection(debugBridge.bmb, cpu.debugBmb)
}
}
class VexRiscvSmpClusterWithPeripherals(p : VexRiscvSmpClusterParameter) extends VexRiscvSmpClusterBase(p) {
val peripheralBridge = BmbToWishboneGenerator(DefaultMapping)
val peripheral = peripheralBridge.produceIo(peripheralBridge.logic.io.output)
interconnect.slaves(peripheralBridge.bmb).forceAccessSourceDataWidth(32)
val plic = BmbPlicGenerator(0)
plic.priorityWidth.load(2)
plic.mapping.load(PlicMapping.sifive)
val plicWishboneBridge = WishboneToBmbGenerator()
val plicWishbone = plicWishboneBridge.produceIo(plicWishboneBridge.logic.io.input)
plicWishboneBridge.config.load(WishboneConfig(20, 32))
interconnect.addConnection(plicWishboneBridge.bmb, plic.bus)
val clint = BmbClintGenerator(0)
val clintWishboneBridge = WishboneToBmbGenerator()
val clintWishbone = clintWishboneBridge.produceIo(clintWishboneBridge.logic.io.input)
clintWishboneBridge.config.load(WishboneConfig(14, 32))
interconnect.addConnection(clintWishboneBridge.bmb, clint.bus)
val interrupts = add task (in Bits(32 bits))
for(i <- 1 to 31) yield plic.addInterrupt(interrupts.derivate(_.apply(i)), i)
for ((core, cpuId) <- cores.zipWithIndex) {
core.cpu.setTimerInterrupt(clint.timerInterrupt(cpuId))
core.cpu.setSoftwareInterrupt(clint.softwareInterrupt(cpuId))
plic.priorityWidth.load(2)
plic.mapping.load(PlicMapping.sifive)
plic.addTarget(core.cpu.externalInterrupt)
plic.addTarget(core.cpu.externalSupervisorInterrupt)
List(clint.logic, core.cpu.logic).produce {
for (plugin <- core.cpu.config.plugins) plugin match {
case plugin: CsrPlugin if plugin.utime != null => plugin.utime := clint.logic.io.time
case _ =>
}
}
}
clint.cpuCount.load(cpuCount)
}
//
//case class VexRiscvSmpClusterParameter( cpuConfigs : Seq[VexRiscvConfig])
//
//case class VexRiscvSmpCluster(p : VexRiscvSmpClusterParameter,
// debugClockDomain : ClockDomain) extends Component{
// val dBusParameter = p.cpuConfigs.head.plugins.find(_.isInstanceOf[DBusCachedPlugin]).get.asInstanceOf[DBusCachedPlugin].config.getBmbParameter()

View File

@ -1,305 +1,150 @@
//package vexriscv.demo.smp
//
//import spinal.core._
//import spinal.lib.bus.bmb._
//import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig, WishboneSlaveFactory}
//import spinal.lib.com.jtag.{Jtag, JtagTapInstructionCtrl}
//import spinal.lib._
//import spinal.lib.bus.bmb.sim.{BmbMemoryMultiPort, BmbMemoryTester}
//import spinal.lib.bus.misc.{AddressMapping, DefaultMapping, SizeMapping}
//import spinal.lib.eda.bench.Bench
//import spinal.lib.misc.Clint
//import spinal.lib.misc.plic.{PlicGatewayActiveHigh, PlicMapper, PlicMapping, PlicTarget}
//import spinal.lib.sim.{SimData, SparseMemory, StreamDriver, StreamMonitor, StreamReadyRandomizer}
//import spinal.lib.system.debugger.{JtagBridgeNoTap, SystemDebugger, SystemDebuggerConfig}
//import vexriscv.demo.smp.VexRiscvLitexSmpClusterOpenSbi.{cpuCount, parameter}
//import vexriscv.demo.smp.VexRiscvSmpClusterGen.vexRiscvConfig
//import vexriscv.{VexRiscv, VexRiscvConfig}
//import vexriscv.plugin.{CsrPlugin, DBusCachedPlugin, DebugPlugin, IBusCachedPlugin}
//
//import scala.collection.mutable
//import scala.util.Random
//
//
//case class VexRiscvLitexSmpClusterParameter( cluster : VexRiscvSmpClusterParameter,
// liteDram : LiteDramNativeParameter,
// liteDramMapping : AddressMapping)
//
package vexriscv.demo.smp
import spinal.core._
import spinal.lib.bus.bmb._
import spinal.lib.bus.misc.{AddressMapping, DefaultMapping, SizeMapping}
import spinal.lib.sim.SparseMemory
import vexriscv.demo.smp.VexRiscvSmpClusterGen.vexRiscvConfig
case class VexRiscvLitexSmpClusterParameter( cluster : VexRiscvSmpClusterParameter,
liteDram : LiteDramNativeParameter,
liteDramMapping : AddressMapping)
class VexRiscvLitexSmpCluster(p : VexRiscvLitexSmpClusterParameter) extends VexRiscvSmpClusterWithPeripherals(p.cluster) {
val iArbiter = BmbSmpBridgeGenerator()
val iBridge = BmbToLiteDramGenerator(p.liteDramMapping)
val dBridge = BmbToLiteDramGenerator(p.liteDramMapping)
for(core <- cores) interconnect.addConnection(core.cpu.iBus -> List(iArbiter.bmb))
interconnect.addConnection(
iArbiter.bmb -> List(iBridge.bmb, peripheralBridge.bmb),
invalidationMonitor.output -> List(dBridge.bmb, peripheralBridge.bmb)
)
interconnect.masters(invalidationMonitor.output).withOutOfOrderDecoder()
dBridge.liteDramParameter.load(p.liteDram)
iBridge.liteDramParameter.load(p.liteDram)
// Interconnect pipelining (FMax)
for(core <- cores) {
interconnect.setPipelining(core.cpu.dBus)(cmdValid = true, cmdReady = true, rspValid = true)
interconnect.setPipelining(core.cpu.iBus)(cmdHalfRate = true, rspValid = true)
interconnect.setPipelining(iArbiter.bmb)(cmdHalfRate = true, rspValid = true)
}
interconnect.setPipelining(invalidationMonitor.output)(cmdValid = true, cmdReady = true, rspValid = true)
interconnect.setPipelining(peripheralBridge.bmb)(cmdHalfRate = true, rspValid = true)
}
object VexRiscvLitexSmpClusterGen extends App {
for(cpuCount <- List(1,2,4,8)) {
def parameter = VexRiscvLitexSmpClusterParameter(
cluster = VexRiscvSmpClusterParameter(
cpuConfigs = List.tabulate(cpuCount) { hartId =>
vexRiscvConfig(
hartId = hartId,
ioRange = address => address.msb,
resetVector = 0
)
}
),
liteDram = LiteDramNativeParameter(addressWidth = 32, dataWidth = 128),
liteDramMapping = SizeMapping(0x40000000l, 0x40000000l)
)
def dutGen = {
val toplevel = new VexRiscvLitexSmpCluster(
p = parameter
).toComponent()
toplevel
}
val genConfig = SpinalConfig().addStandardMemBlackboxing(blackboxByteEnables)
// genConfig.generateVerilog(Bench.compressIo(dutGen))
genConfig.generateVerilog(dutGen.setDefinitionName(s"VexRiscvLitexSmpCluster_${cpuCount}c"))
}
}
////addAttribute("""mark_debug = "true"""")
//case class VexRiscvLitexSmpCluster(p : VexRiscvLitexSmpClusterParameter,
// debugClockDomain : ClockDomain,
// jtagClockDomain : ClockDomain) extends Component{
//
// val peripheralWishboneConfig = WishboneConfig(
// addressWidth = 30,
// dataWidth = 32,
// selWidth = 4,
// useERR = true,
// useBTE = true,
// useCTI = true
// )
//
// val io = new Bundle {
// val dMem = master(LiteDramNative(p.liteDram))
// val iMem = master(LiteDramNative(p.liteDram))
// val peripheral = master(Wishbone(peripheralWishboneConfig))
// val clint = slave(Wishbone(Clint.getWisboneConfig()))
// val plic = slave(Wishbone(WishboneConfig(addressWidth = 20, dataWidth = 32)))
// val interrupts = in Bits(32 bits)
// val jtagInstruction = slave(JtagTapInstructionCtrl())
// val debugReset = out Bool()
// }
// val cpuCount = p.cluster.cpuConfigs.size
// val clint = Clint(cpuCount)
// clint.driveFrom(WishboneSlaveFactory(io.clint))
//
// val cluster = VexRiscvSmpCluster(p.cluster, debugClockDomain)
// cluster.io.debugReset <> io.debugReset
// cluster.io.timerInterrupts <> B(clint.harts.map(_.timerInterrupt))
// cluster.io.softwareInterrupts <> B(clint.harts.map(_.softwareInterrupt))
// cluster.io.time := clint.time
//
// val debug = debugClockDomain on new Area{
// val jtagConfig = SystemDebuggerConfig()
// val jtagBridge = new JtagBridgeNoTap(
// c = jtagConfig,
// jtagClockDomain = jtagClockDomain
// )
// jtagBridge.io.ctrl << io.jtagInstruction
//
// val debugger = new SystemDebugger(jtagConfig)
// debugger.io.remote <> jtagBridge.io.remote
//
// cluster.io.debugBus << debugger.io.mem.toBmb()
// }
//
// val dBusDecoder = BmbDecoderOutOfOrder(
// p = cluster.io.dMem.p,
// mappings = Seq(DefaultMapping, p.liteDramMapping),
// capabilities = Seq(cluster.io.dMem.p, cluster.io.dMem.p),
// pendingRspTransactionMax = 32
// )
//// val dBusDecoder = BmbDecoderOut(
//// p = cluster.io.dMem.p,
//// mappings = Seq(DefaultMapping, p.liteDramMapping),
//// capabilities = Seq(cluster.io.dMem.p, cluster.io.dMem.p),
//// pendingMax = 31
//// )
// dBusDecoder.io.input << cluster.io.dMem.pipelined(cmdValid = true, cmdReady = true, rspValid = true)
// val dMemBridge = io.dMem.fromBmb(dBusDecoder.io.outputs(1), wdataFifoSize = 32, rdataFifoSize = 32)
//
// val iBusArbiterParameter = cluster.iBusParameter.copy(sourceWidth = log2Up(cpuCount))
// val iBusArbiter = BmbArbiter(
// p = iBusArbiterParameter,
// portCount = cpuCount,
// lowerFirstPriority = false
// )
//
// (iBusArbiter.io.inputs, cluster.io.iMems).zipped.foreach(_ << _.pipelined(cmdHalfRate = true, rspValid = true))
//
// val iBusDecoder = BmbDecoder(
// p = iBusArbiter.io.output.p,
// mappings = Seq(DefaultMapping, p.liteDramMapping),
// capabilities = Seq(iBusArbiterParameter, iBusArbiterParameter),
// pendingMax = 15
// )
// iBusDecoder.io.input << iBusArbiter.io.output.pipelined(cmdValid = true)
//
// val iMem = LiteDramNative(p.liteDram)
// io.iMem.fromBmb(iBusDecoder.io.outputs(1), wdataFifoSize = 0, rdataFifoSize = 32)
//
//
// val iBusDecoderToPeripheral = iBusDecoder.io.outputs(0).resize(dataWidth = 32).pipelined(cmdHalfRate = true, rspValid = true)
// val dBusDecoderToPeripheral = dBusDecoder.io.outputs(0).resize(dataWidth = 32).pipelined(cmdHalfRate = true, rspValid = true)
//
// val peripheralAccessLength = Math.max(iBusDecoder.io.outputs(0).p.lengthWidth, dBusDecoder.io.outputs(0).p.lengthWidth)
// val peripheralArbiter = BmbArbiter(
// p = dBusDecoder.io.outputs(0).p.copy(
// sourceWidth = List(iBusDecoderToPeripheral, dBusDecoderToPeripheral).map(_.p.sourceWidth).max + 1,
// contextWidth = List(iBusDecoderToPeripheral, dBusDecoderToPeripheral).map(_.p.contextWidth).max,
// lengthWidth = peripheralAccessLength,
// dataWidth = 32
// ),
// portCount = 2,
// lowerFirstPriority = true
// )
// peripheralArbiter.io.inputs(0) << iBusDecoderToPeripheral
// peripheralArbiter.io.inputs(1) << dBusDecoderToPeripheral
//
// val peripheralWishbone = peripheralArbiter.io.output.pipelined(cmdValid = true).toWishbone()
// io.peripheral << peripheralWishbone
//
// val plic = new Area{
// val priorityWidth = 2
//
// val gateways = for(i <- 1 until 32) yield PlicGatewayActiveHigh(
// source = io.interrupts(i),
// id = i,
// priorityWidth = priorityWidth
// )
//
// val bus = WishboneSlaveFactory(io.plic)
//
// val targets = for(i <- 0 until cpuCount) yield new Area{
// val machine = PlicTarget(
// gateways = gateways,
// priorityWidth = priorityWidth
// )
// val supervisor = PlicTarget(
// gateways = gateways,
// priorityWidth = priorityWidth
// )
//
// cluster.io.externalInterrupts(i) := machine.iep
// cluster.io.externalSupervisorInterrupts(i) := supervisor.iep
// }
//
// val bridge = PlicMapper(bus, PlicMapping.sifive)(
// gateways = gateways,
// targets = targets.flatMap(t => List(t.machine, t.supervisor))
// )
// }
//}
//
//object VexRiscvLitexSmpClusterGen extends App {
// for(cpuCount <- List(1,2,4,8)) {
// def parameter = VexRiscvLitexSmpClusterParameter(
// cluster = VexRiscvSmpClusterParameter(
// cpuConfigs = List.tabulate(cpuCount) { hartId =>
// vexRiscvConfig(
// hartId = hartId,
// ioRange = address => address.msb,
// resetVector = 0
// )
// }
// ),
// liteDram = LiteDramNativeParameter(addressWidth = 32, dataWidth = 128),
// liteDramMapping = SizeMapping(0x40000000l, 0x40000000l)
// )
//
// def dutGen = {
// val toplevel = VexRiscvLitexSmpCluster(
// p = parameter,
// debugClockDomain = ClockDomain.current.copy(reset = Bool().setName("debugResetIn")),
// jtagClockDomain = ClockDomain.external("jtag", withReset = false)
// )
// toplevel
// }
//
// val genConfig = SpinalConfig().addStandardMemBlackboxing(blackboxByteEnables)
// // genConfig.generateVerilog(Bench.compressIo(dutGen))
// genConfig.generateVerilog(dutGen.setDefinitionName(s"VexRiscvLitexSmpCluster_${cpuCount}c"))
// }
//
//}
//
//
//object VexRiscvLitexSmpClusterOpenSbi extends App{
// import spinal.core.sim._
//
// val simConfig = SimConfig
// simConfig.withWave
// simConfig.allOptimisation
//
// val cpuCount = 2
//
// def parameter = VexRiscvLitexSmpClusterParameter(
// cluster = VexRiscvSmpClusterParameter(
// cpuConfigs = List.tabulate(cpuCount) { hartId =>
// vexRiscvConfig(
// hartId = hartId,
// ioRange = address => address(31 downto 28) === 0xF,
// resetVector = 0x80000000l
// )
// }
// ),
// liteDram = LiteDramNativeParameter(addressWidth = 32, dataWidth = 128),
// liteDramMapping = SizeMapping(0x80000000l, 0x70000000l)
// )
//
// def dutGen = {
// val top = VexRiscvLitexSmpCluster(
// p = parameter,
// debugClockDomain = ClockDomain.current.copy(reset = Bool().setName("debugResetIn")),
// jtagClockDomain = ClockDomain.external("jtag", withReset = false)
// )
// top.rework{
// top.io.clint.setAsDirectionLess.allowDirectionLessIo
// top.io.peripheral.setAsDirectionLess.allowDirectionLessIo.simPublic()
//
// val hit = (top.io.peripheral.ADR <<2 >= 0xF0010000l && top.io.peripheral.ADR<<2 < 0xF0020000l)
// top.io.clint.CYC := top.io.peripheral.CYC && hit
// top.io.clint.STB := top.io.peripheral.STB
// top.io.clint.WE := top.io.peripheral.WE
// top.io.clint.ADR := top.io.peripheral.ADR.resized
// top.io.clint.DAT_MOSI := top.io.peripheral.DAT_MOSI
// top.io.peripheral.DAT_MISO := top.io.clint.DAT_MISO
// top.io.peripheral.ACK := top.io.peripheral.CYC && (!hit || top.io.clint.ACK)
// top.io.peripheral.ERR := False
//
object VexRiscvLitexSmpClusterOpenSbi extends App{
import spinal.core.sim._
val simConfig = SimConfig
simConfig.withWave
simConfig.allOptimisation
val cpuCount = 2
def parameter = VexRiscvLitexSmpClusterParameter(
cluster = VexRiscvSmpClusterParameter(
cpuConfigs = List.tabulate(cpuCount) { hartId =>
vexRiscvConfig(
hartId = hartId,
ioRange = address => address(31 downto 28) === 0xF,
resetVector = 0x80000000l
)
}
),
liteDram = LiteDramNativeParameter(addressWidth = 32, dataWidth = 128),
liteDramMapping = SizeMapping(0x80000000l, 0x70000000l)
)
def dutGen = {
val top = new VexRiscvLitexSmpCluster(
p = parameter
).toComponent()
top.rework{
top.clintWishbone.setAsDirectionLess.allowDirectionLessIo
top.peripheral.setAsDirectionLess.allowDirectionLessIo.simPublic()
val hit = (top.peripheral.ADR <<2 >= 0xF0010000l && top.peripheral.ADR<<2 < 0xF0020000l)
top.clintWishbone.CYC := top.peripheral.CYC && hit
top.clintWishbone.STB := top.peripheral.STB
top.clintWishbone.WE := top.peripheral.WE
top.clintWishbone.ADR := top.peripheral.ADR.resized
top.clintWishbone.DAT_MOSI := top.peripheral.DAT_MOSI
top.peripheral.DAT_MISO := top.clintWishbone.DAT_MISO
top.peripheral.ACK := top.peripheral.CYC && (!hit || top.clintWishbone.ACK)
top.peripheral.ERR := False
// top.dMemBridge.unburstified.cmd.simPublic()
// }
// top
// }
// simConfig.compile(dutGen).doSimUntilVoid(seed = 42){dut =>
// dut.clockDomain.forkStimulus(10)
// fork {
// dut.debugClockDomain.resetSim #= false
// sleep (0)
// dut.debugClockDomain.resetSim #= true
// sleep (10)
// dut.debugClockDomain.resetSim #= false
// }
//
//
// val ram = SparseMemory()
// ram.loadBin(0x80000000l, "../opensbi/build/platform/spinal/vexriscv/sim/smp/firmware/fw_jump.bin")
// ram.loadBin(0xC0000000l, "../buildroot/output/images/Image")
// ram.loadBin(0xC1000000l, "../buildroot/output/images/dtb")
// ram.loadBin(0xC2000000l, "../buildroot/output/images/rootfs.cpio")
//
//
// dut.io.iMem.simSlave(ram, dut.clockDomain)
// dut.io.dMem.simSlave(ram, dut.clockDomain, dut.dMemBridge.unburstified)
//
// dut.io.interrupts #= 0
//
// dut.clockDomain.onFallingEdges{
// if(dut.io.peripheral.CYC.toBoolean){
// (dut.io.peripheral.ADR.toLong << 2) match {
// case 0xF0000000l => print(dut.io.peripheral.DAT_MOSI.toLong.toChar)
// case 0xF0000004l => dut.io.peripheral.DAT_MISO #= (if(System.in.available() != 0) System.in.read() else 0xFFFFFFFFl)
// case _ =>
// }
//// println(f"${dut.io.peripheral.ADR.toLong}%x")
// }
// }
//
//// fork{
//// disableSimWave()
//// val atMs = 3790
//// val durationMs = 5
//// sleep(atMs*1000000l)
//// enableSimWave()
//// println("** enableSimWave **")
//// sleep(durationMs*1000000l)
//// println("** disableSimWave **")
//// while(true) {
//// disableSimWave()
//// sleep(100000 * 10)
//// enableSimWave()
//// sleep( 100 * 10)
//// }
//// // simSuccess()
//// }
//
// fork{
// while(true) {
// disableSimWave()
// sleep(100000 * 10)
// enableSimWave()
// sleep( 100 * 10)
// }
// }
// }
// }
}
top
}
simConfig.compile(dutGen).doSimUntilVoid(seed = 42){dut =>
dut.debugCd.inputClockDomain.get.forkStimulus(10)
val ram = SparseMemory()
ram.loadBin(0x80000000l, "../opensbi/build/platform/spinal/vexriscv/sim/smp/firmware/fw_jump.bin")
ram.loadBin(0xC0000000l, "../buildroot/output/images/Image")
ram.loadBin(0xC1000000l, "../buildroot/output/images/dtb")
ram.loadBin(0xC2000000l, "../buildroot/output/images/rootfs.cpio")
dut.iBridge.dram.simSlave(ram, dut.debugCd.inputClockDomain)
dut.dBridge.dram.simSlave(ram, dut.debugCd.inputClockDomain/*, dut.dMemBridge.unburstified*/)
dut.interrupts.get #= 0
dut.debugCd.inputClockDomain.get.onFallingEdges{
if(dut.peripheral.CYC.toBoolean){
(dut.peripheral.ADR.toLong << 2) match {
case 0xF0000000l => print(dut.peripheral.DAT_MOSI.toLong.toChar)
case 0xF0000004l => dut.peripheral.DAT_MISO #= (if(System.in.available() != 0) System.in.read() else 0xFFFFFFFFl)
case _ =>
}
}
}
fork{
while(true) {
disableSimWave()
sleep(100000 * 10)
enableSimWave()
sleep( 100 * 10)
}
}
}
}