From 32539dfe6de5034b01dc9e0c034cd1e3d6e94e8f Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Tue, 30 Jun 2020 22:29:33 +0200 Subject: [PATCH] Got VexRiscvSmpLitexCluster refractoring to work --- .../scala/vexriscv/VexRiscvBmbGenerator.scala | 156 ++++++ src/main/scala/vexriscv/demo/smp/Misc.scala | 43 +- .../demo/smp/VexRiscvSmpCluster.scala | 103 +++- .../demo/smp/VexRiscvSmpLitexCluster.scala | 451 ++++++------------ 4 files changed, 442 insertions(+), 311 deletions(-) create mode 100644 src/main/scala/vexriscv/VexRiscvBmbGenerator.scala diff --git a/src/main/scala/vexriscv/VexRiscvBmbGenerator.scala b/src/main/scala/vexriscv/VexRiscvBmbGenerator.scala new file mode 100644 index 0000000..d7d578f --- /dev/null +++ b/src/main/scala/vexriscv/VexRiscvBmbGenerator.scala @@ -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) + } + +} diff --git a/src/main/scala/vexriscv/demo/smp/Misc.scala b/src/main/scala/vexriscv/demo/smp/Misc.scala index 6fa34ba..01135b6 100644 --- a/src/main/scala/vexriscv/demo/smp/Misc.scala +++ b/src/main/scala/vexriscv/demo/smp/Misc.scala @@ -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} @@ -244,4 +245,44 @@ object BmbToLiteDramTester extends App{ val tester = new BmbMemoryTester(dut.io.input, dut.clockDomain, rspCounterTarget = 3000) dut.io.output.simSlave(tester.memory.memory, dut.clockDomain) } -} \ No newline at end of file +} + +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() + ) +} diff --git a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala index 22e7e7b..471463c 100644 --- a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala +++ b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala @@ -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() diff --git a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpLitexCluster.scala b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpLitexCluster.scala index 44beab7..e5cda93 100644 --- a/src/main/scala/vexriscv/demo/smp/VexRiscvSmpLitexCluster.scala +++ b/src/main/scala/vexriscv/demo/smp/VexRiscvSmpLitexCluster.scala @@ -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) -// } -// } -// } -// } \ No newline at end of file + } + 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) + } + } + } +} \ No newline at end of file