Update Bmb brides and comment out SmpCluster for now
This commit is contained in:
parent
c12f9a378d
commit
062509deee
|
@ -11,8 +11,6 @@ import spinal.lib.bus.misc.{AddressMapping, DefaultMapping, SizeMapping}
|
|||
import spinal.lib.eda.bench.Bench
|
||||
import spinal.lib.misc.Clint
|
||||
import spinal.lib.sim.{SimData, SparseMemory, StreamDriver, StreamMonitor, StreamReadyRandomizer}
|
||||
import vexriscv.demo.smp.VexRiscvLitexSmpClusterOpenSbi.{cpuCount, parameter}
|
||||
import vexriscv.demo.smp.VexRiscvSmpClusterGen.vexRiscvConfig
|
||||
import vexriscv.{VexRiscv, VexRiscvConfig}
|
||||
import vexriscv.plugin.{CsrPlugin, DBusCachedPlugin, DebugPlugin, IBusCachedPlugin}
|
||||
|
||||
|
@ -166,8 +164,8 @@ case class BmbToLiteDram(bmbParameter : BmbParameter,
|
|||
val resized = io.input.resize(liteDramParameter.dataWidth)
|
||||
val unburstified = resized.unburstify()
|
||||
case class Context() extends Bundle {
|
||||
val context = Bits(unburstified.p.contextWidth bits)
|
||||
val source = UInt(unburstified.p.sourceWidth bits)
|
||||
val context = Bits(unburstified.p.access.contextWidth bits)
|
||||
val source = UInt(unburstified.p.access.sourceWidth bits)
|
||||
val isWrite = Bool()
|
||||
}
|
||||
|
||||
|
@ -183,7 +181,7 @@ case class BmbToLiteDram(bmbParameter : BmbParameter,
|
|||
|
||||
io.output.cmd <-< outputCmd
|
||||
|
||||
if(bmbParameter.canWrite) {
|
||||
if(bmbParameter.access.canWrite) {
|
||||
val wData = Stream(LiteDramNativeWData(liteDramParameter))
|
||||
wData.arbitrationFrom(dataFork.throwWhen(dataFork.isRead))
|
||||
wData.data := dataFork.data
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,305 +1,305 @@
|
|||
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)
|
||||
|
||||
//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(
|
||||
//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)
|
||||
//
|
||||
////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),
|
||||
// pendingMax = 31
|
||||
// pendingRspTransactionMax = 32
|
||||
// )
|
||||
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
|
||||
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
||||
//// 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
|
||||
//
|
||||
// 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{
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// }
|
||||
// }
|
|
@ -1,369 +1,369 @@
|
|||
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, JtagTap, JtagTapInstructionCtrl}
|
||||
import spinal.lib._
|
||||
import spinal.lib.blackbox.xilinx.s7.BSCANE2
|
||||
import spinal.lib.bus.bmb.sim.{BmbMemoryMultiPort, BmbMemoryTester}
|
||||
import spinal.lib.bus.misc.{AddressMapping, DefaultMapping, SizeMapping}
|
||||
import spinal.lib.com.jtag.sim.JtagTcp
|
||||
import spinal.lib.com.jtag.xilinx.Bscane2BmbMaster
|
||||
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 sun.jvm.hotspot.oops.DataLayout
|
||||
import vexriscv.demo.smp.VexRiscvLitexSmpMpClusterOpenSbi.{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 VexRiscvLitexSmpMpClusterParameter( cluster : VexRiscvSmpClusterParameter,
|
||||
liteDram : LiteDramNativeParameter,
|
||||
liteDramMapping : AddressMapping)
|
||||
|
||||
//addAttribute("""mark_debug = "true"""")
|
||||
class VexRiscvLitexSmpMpCluster(val p : VexRiscvLitexSmpMpClusterParameter,
|
||||
val debugClockDomain : ClockDomain,
|
||||
val jtagClockDomain : ClockDomain) extends Component{
|
||||
|
||||
val peripheralWishboneConfig = WishboneConfig(
|
||||
addressWidth = 30,
|
||||
dataWidth = 32,
|
||||
selWidth = 4,
|
||||
useERR = true,
|
||||
useBTE = true,
|
||||
useCTI = true
|
||||
)
|
||||
|
||||
val cpuCount = p.cluster.cpuConfigs.size
|
||||
|
||||
val io = new Bundle {
|
||||
val dMem = Vec(master(LiteDramNative(p.liteDram)), cpuCount)
|
||||
val iMem = Vec(master(LiteDramNative(p.liteDram)), cpuCount)
|
||||
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 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(jtagConfig, jtagClockDomain)
|
||||
jtagBridge.io.ctrl << io.jtagInstruction
|
||||
|
||||
val debugger = new SystemDebugger(jtagConfig)
|
||||
debugger.io.remote <> jtagBridge.io.remote
|
||||
|
||||
cluster.io.debugBus << debugger.io.mem.toBmb()
|
||||
|
||||
// io.jtagInstruction.allowDirectionLessIo.setAsDirectionLess
|
||||
// val bridge = Bscane2BmbMaster(1)
|
||||
// cluster.io.debugBus << bridge.io.bmb
|
||||
|
||||
|
||||
// val bscane2 = BSCANE2(usedId)
|
||||
// val jtagClockDomain = ClockDomain(bscane2.TCK)
|
||||
//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, JtagTap, JtagTapInstructionCtrl}
|
||||
//import spinal.lib._
|
||||
//import spinal.lib.blackbox.xilinx.s7.BSCANE2
|
||||
//import spinal.lib.bus.bmb.sim.{BmbMemoryMultiPort, BmbMemoryTester}
|
||||
//import spinal.lib.bus.misc.{AddressMapping, DefaultMapping, SizeMapping}
|
||||
//import spinal.lib.com.jtag.sim.JtagTcp
|
||||
//import spinal.lib.com.jtag.xilinx.Bscane2BmbMaster
|
||||
//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 sun.jvm.hotspot.oops.DataLayout
|
||||
//import vexriscv.demo.smp.VexRiscvLitexSmpMpClusterOpenSbi.{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 VexRiscvLitexSmpMpClusterParameter( cluster : VexRiscvSmpClusterParameter,
|
||||
// liteDram : LiteDramNativeParameter,
|
||||
// liteDramMapping : AddressMapping)
|
||||
//
|
||||
////addAttribute("""mark_debug = "true"""")
|
||||
//class VexRiscvLitexSmpMpCluster(val p : VexRiscvLitexSmpMpClusterParameter,
|
||||
// val debugClockDomain : ClockDomain,
|
||||
// val jtagClockDomain : ClockDomain) extends Component{
|
||||
//
|
||||
// val peripheralWishboneConfig = WishboneConfig(
|
||||
// addressWidth = 30,
|
||||
// dataWidth = 32,
|
||||
// selWidth = 4,
|
||||
// useERR = true,
|
||||
// useBTE = true,
|
||||
// useCTI = true
|
||||
// )
|
||||
//
|
||||
// val cpuCount = p.cluster.cpuConfigs.size
|
||||
//
|
||||
// val io = new Bundle {
|
||||
// val dMem = Vec(master(LiteDramNative(p.liteDram)), cpuCount)
|
||||
// val iMem = Vec(master(LiteDramNative(p.liteDram)), cpuCount)
|
||||
// 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 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(jtagConfig, jtagClockDomain)
|
||||
// jtagBridge.io.ctrl << bscane2.toJtagTapInstructionCtrl()
|
||||
// jtagBridge.io.ctrl << io.jtagInstruction
|
||||
//
|
||||
// val debugger = new SystemDebugger(jtagConfig)
|
||||
// debugger.io.remote <> jtagBridge.io.remote
|
||||
//
|
||||
// io.bmb << 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(
|
||||
// cluster.io.debugBus << debugger.io.mem.toBmb()
|
||||
//
|
||||
//// io.jtagInstruction.allowDirectionLessIo.setAsDirectionLess
|
||||
//// val bridge = Bscane2BmbMaster(1)
|
||||
//// cluster.io.debugBus << bridge.io.bmb
|
||||
//
|
||||
//
|
||||
//// val bscane2 = BSCANE2(usedId)
|
||||
//// val jtagClockDomain = ClockDomain(bscane2.TCK)
|
||||
////
|
||||
//// val jtagBridge = new JtagBridgeNoTap(jtagConfig, jtagClockDomain)
|
||||
//// jtagBridge.io.ctrl << bscane2.toJtagTapInstructionCtrl()
|
||||
////
|
||||
//// val debugger = new SystemDebugger(jtagConfig)
|
||||
//// debugger.io.remote <> jtagBridge.io.remote
|
||||
////
|
||||
//// io.bmb << 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),
|
||||
// pendingMax = 31
|
||||
// pendingRspTransactionMax = 32
|
||||
// )
|
||||
dBusDecoder.io.input << cluster.io.dMem.pipelined(cmdValid = true, cmdReady = true, rspValid = true)
|
||||
|
||||
|
||||
val perIBus = for(id <- 0 until cpuCount) yield new Area{
|
||||
val decoder = BmbDecoder(
|
||||
p = cluster.io.iMems(id).p,
|
||||
mappings = Seq(DefaultMapping, p.liteDramMapping),
|
||||
capabilities = Seq(cluster.io.iMems(id).p,cluster.io.iMems(id).p),
|
||||
pendingMax = 15
|
||||
)
|
||||
|
||||
decoder.io.input << cluster.io.iMems(id)
|
||||
io.iMem(id).fromBmb(decoder.io.outputs(1).pipelined(cmdHalfRate = true), wdataFifoSize = 0, rdataFifoSize = 32)
|
||||
val toPeripheral = decoder.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(perIBus(0).toPeripheral.p.lengthWidth, dBusDecoder.io.outputs(0).p.lengthWidth)
|
||||
val peripheralArbiter = BmbArbiter(
|
||||
p = dBusDecoder.io.outputs(0).p.copy(
|
||||
sourceWidth = List(perIBus(0).toPeripheral, dBusDecoderToPeripheral).map(_.p.sourceWidth).max + log2Up(cpuCount + 1),
|
||||
contextWidth = List(perIBus(0).toPeripheral, dBusDecoderToPeripheral).map(_.p.contextWidth).max,
|
||||
lengthWidth = peripheralAccessLength,
|
||||
dataWidth = 32
|
||||
),
|
||||
portCount = cpuCount+1,
|
||||
lowerFirstPriority = true
|
||||
)
|
||||
|
||||
for(id <- 0 until cpuCount){
|
||||
peripheralArbiter.io.inputs(id) << perIBus(id).toPeripheral
|
||||
}
|
||||
peripheralArbiter.io.inputs(cpuCount) << dBusDecoderToPeripheral
|
||||
|
||||
val peripheralWishbone = peripheralArbiter.io.output.pipelined(cmdValid = true).toWishbone()
|
||||
io.peripheral << peripheralWishbone
|
||||
|
||||
|
||||
val dBusDemux = BmbSourceDecoder(dBusDecoder.io.outputs(1).p)
|
||||
dBusDemux.io.input << dBusDecoder.io.outputs(1).pipelined(cmdValid = true, cmdReady = true,rspValid = true)
|
||||
val dMemBridge = for(id <- 0 until cpuCount) yield {
|
||||
io.dMem(id).fromBmb(dBusDemux.io.outputs(id), wdataFifoSize = 32, rdataFifoSize = 32)
|
||||
}
|
||||
|
||||
|
||||
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))
|
||||
)
|
||||
}
|
||||
//// 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)
|
||||
//
|
||||
// io.dMem.foreach(_.cmd.valid.addAttribute("""mark_debug = "true""""))
|
||||
// io.dMem.foreach(_.cmd.ready.addAttribute("""mark_debug = "true""""))
|
||||
// io.iMem.foreach(_.cmd.valid.addAttribute("""mark_debug = "true""""))
|
||||
// io.iMem.foreach(_.cmd.ready.addAttribute("""mark_debug = "true""""))
|
||||
//
|
||||
// cluster.io.dMem.cmd.valid.addAttribute("""mark_debug = "true"""")
|
||||
// cluster.io.dMem.cmd.ready.addAttribute("""mark_debug = "true"""")
|
||||
// cluster.io.dMem.rsp.valid.addAttribute("""mark_debug = "true"""")
|
||||
// cluster.io.dMem.rsp.ready.addAttribute("""mark_debug = "true"""")
|
||||
}
|
||||
|
||||
object VexRiscvLitexSmpMpClusterGen extends App {
|
||||
for(cpuCount <- List(1,2,4,8)) {
|
||||
def parameter = VexRiscvLitexSmpMpClusterParameter(
|
||||
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 VexRiscvLitexSmpMpCluster(
|
||||
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"VexRiscvLitexSmpMpCluster_${cpuCount}c"))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
object VexRiscvLitexSmpMpClusterOpenSbi extends App{
|
||||
import spinal.core.sim._
|
||||
|
||||
val simConfig = SimConfig
|
||||
simConfig.withWave
|
||||
simConfig.withFstWave
|
||||
simConfig.allOptimisation
|
||||
|
||||
val cpuCount = 2
|
||||
|
||||
def parameter = VexRiscvLitexSmpMpClusterParameter(
|
||||
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 VexRiscvLitexSmpMpCluster(
|
||||
p = parameter,
|
||||
debugClockDomain = ClockDomain.current.copy(reset = Bool().setName("debugResetIn")),
|
||||
jtagClockDomain = ClockDomain.external("jtag", withReset = false)
|
||||
){
|
||||
io.jtagInstruction.allowDirectionLessIo.setAsDirectionLess
|
||||
val jtag = slave(Jtag())
|
||||
jtagClockDomain.readClockWire.setAsDirectionLess() := jtag.tck
|
||||
val jtagLogic = jtagClockDomain on new Area{
|
||||
val tap = new JtagTap(jtag, 4)
|
||||
val idcodeArea = tap.idcode(B"x10001FFF")(1)
|
||||
val wrapper = tap.map(io.jtagInstruction, instructionId = 2)
|
||||
}
|
||||
}
|
||||
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
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
JtagTcp(dut.jtag, 10*20)
|
||||
|
||||
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")
|
||||
|
||||
for(id <- 0 until cpuCount) {
|
||||
dut.io.iMem(id).simSlave(ram, dut.clockDomain)
|
||||
dut.io.dMem(id).simSlave(ram, dut.clockDomain)
|
||||
}
|
||||
|
||||
dut.io.interrupts #= 0
|
||||
|
||||
|
||||
// val stdin = mutable.Queue[Byte]()
|
||||
// def stdInPush(str : String) = stdin ++= str.toCharArray.map(_.toByte)
|
||||
// fork{
|
||||
// sleep(4000*1000000l)
|
||||
// stdInPush("root\n")
|
||||
// sleep(1000*1000000l)
|
||||
// stdInPush("ping localhost -i 0.01 > /dev/null &\n")
|
||||
// stdInPush("ping localhost -i 0.01 > /dev/null &\n")
|
||||
// stdInPush("ping localhost -i 0.01 > /dev/null &\n")
|
||||
// stdInPush("ping localhost -i 0.01 > /dev/null &\n")
|
||||
// sleep(500*1000000l)
|
||||
// while(true){
|
||||
// sleep(500*1000000l)
|
||||
// stdInPush("uptime\n")
|
||||
// printf("\n** uptime **")
|
||||
// val perIBus = for(id <- 0 until cpuCount) yield new Area{
|
||||
// val decoder = BmbDecoder(
|
||||
// p = cluster.io.iMems(id).p,
|
||||
// mappings = Seq(DefaultMapping, p.liteDramMapping),
|
||||
// capabilities = Seq(cluster.io.iMems(id).p,cluster.io.iMems(id).p),
|
||||
// pendingMax = 15
|
||||
// )
|
||||
//
|
||||
// decoder.io.input << cluster.io.iMems(id)
|
||||
// io.iMem(id).fromBmb(decoder.io.outputs(1).pipelined(cmdHalfRate = true), wdataFifoSize = 0, rdataFifoSize = 32)
|
||||
// val toPeripheral = decoder.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(perIBus(0).toPeripheral.p.lengthWidth, dBusDecoder.io.outputs(0).p.lengthWidth)
|
||||
// val peripheralArbiter = BmbArbiter(
|
||||
// p = dBusDecoder.io.outputs(0).p.copy(
|
||||
// sourceWidth = List(perIBus(0).toPeripheral, dBusDecoderToPeripheral).map(_.p.sourceWidth).max + log2Up(cpuCount + 1),
|
||||
// contextWidth = List(perIBus(0).toPeripheral, dBusDecoderToPeripheral).map(_.p.contextWidth).max,
|
||||
// lengthWidth = peripheralAccessLength,
|
||||
// dataWidth = 32
|
||||
// ),
|
||||
// portCount = cpuCount+1,
|
||||
// lowerFirstPriority = true
|
||||
// )
|
||||
//
|
||||
// for(id <- 0 until cpuCount){
|
||||
// peripheralArbiter.io.inputs(id) << perIBus(id).toPeripheral
|
||||
// }
|
||||
// peripheralArbiter.io.inputs(cpuCount) << dBusDecoderToPeripheral
|
||||
//
|
||||
// val peripheralWishbone = peripheralArbiter.io.output.pipelined(cmdValid = true).toWishbone()
|
||||
// io.peripheral << peripheralWishbone
|
||||
//
|
||||
//
|
||||
// val dBusDemux = BmbSourceDecoder(dBusDecoder.io.outputs(1).p)
|
||||
// dBusDemux.io.input << dBusDecoder.io.outputs(1).pipelined(cmdValid = true, cmdReady = true,rspValid = true)
|
||||
// val dMemBridge = for(id <- 0 until cpuCount) yield {
|
||||
// io.dMem(id).fromBmb(dBusDemux.io.outputs(id), wdataFifoSize = 32, rdataFifoSize = 32)
|
||||
// }
|
||||
//
|
||||
//
|
||||
// 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))
|
||||
// )
|
||||
// }
|
||||
////
|
||||
//// io.dMem.foreach(_.cmd.valid.addAttribute("""mark_debug = "true""""))
|
||||
//// io.dMem.foreach(_.cmd.ready.addAttribute("""mark_debug = "true""""))
|
||||
//// io.iMem.foreach(_.cmd.valid.addAttribute("""mark_debug = "true""""))
|
||||
//// io.iMem.foreach(_.cmd.ready.addAttribute("""mark_debug = "true""""))
|
||||
////
|
||||
//// cluster.io.dMem.cmd.valid.addAttribute("""mark_debug = "true"""")
|
||||
//// cluster.io.dMem.cmd.ready.addAttribute("""mark_debug = "true"""")
|
||||
//// cluster.io.dMem.rsp.valid.addAttribute("""mark_debug = "true"""")
|
||||
//// cluster.io.dMem.rsp.ready.addAttribute("""mark_debug = "true"""")
|
||||
//}
|
||||
//
|
||||
//object VexRiscvLitexSmpMpClusterGen extends App {
|
||||
// for(cpuCount <- List(1,2,4,8)) {
|
||||
// def parameter = VexRiscvLitexSmpMpClusterParameter(
|
||||
// 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 VexRiscvLitexSmpMpCluster(
|
||||
// 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"VexRiscvLitexSmpMpCluster_${cpuCount}c"))
|
||||
// }
|
||||
//
|
||||
//}
|
||||
//
|
||||
//
|
||||
//object VexRiscvLitexSmpMpClusterOpenSbi extends App{
|
||||
// import spinal.core.sim._
|
||||
//
|
||||
// val simConfig = SimConfig
|
||||
// simConfig.withWave
|
||||
// simConfig.withFstWave
|
||||
// simConfig.allOptimisation
|
||||
//
|
||||
// val cpuCount = 2
|
||||
//
|
||||
// def parameter = VexRiscvLitexSmpMpClusterParameter(
|
||||
// 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 VexRiscvLitexSmpMpCluster(
|
||||
// p = parameter,
|
||||
// debugClockDomain = ClockDomain.current.copy(reset = Bool().setName("debugResetIn")),
|
||||
// jtagClockDomain = ClockDomain.external("jtag", withReset = false)
|
||||
// ){
|
||||
// io.jtagInstruction.allowDirectionLessIo.setAsDirectionLess
|
||||
// val jtag = slave(Jtag())
|
||||
// jtagClockDomain.readClockWire.setAsDirectionLess() := jtag.tck
|
||||
// val jtagLogic = jtagClockDomain on new Area{
|
||||
// val tap = new JtagTap(jtag, 4)
|
||||
// val idcodeArea = tap.idcode(B"x10001FFF")(1)
|
||||
// val wrapper = tap.map(io.jtagInstruction, instructionId = 2)
|
||||
// }
|
||||
// }
|
||||
// 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
|
||||
//
|
||||
//// 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
|
||||
// }
|
||||
//
|
||||
// JtagTcp(dut.jtag, 10*20)
|
||||
//
|
||||
// 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")
|
||||
//
|
||||
// for(id <- 0 until cpuCount) {
|
||||
// dut.io.iMem(id).simSlave(ram, dut.clockDomain)
|
||||
// dut.io.dMem(id).simSlave(ram, dut.clockDomain)
|
||||
// }
|
||||
//
|
||||
// dut.io.interrupts #= 0
|
||||
//
|
||||
//
|
||||
//// val stdin = mutable.Queue[Byte]()
|
||||
//// def stdInPush(str : String) = stdin ++= str.toCharArray.map(_.toByte)
|
||||
//// fork{
|
||||
//// sleep(4000*1000000l)
|
||||
//// stdInPush("root\n")
|
||||
//// sleep(1000*1000000l)
|
||||
//// stdInPush("ping localhost -i 0.01 > /dev/null &\n")
|
||||
//// stdInPush("ping localhost -i 0.01 > /dev/null &\n")
|
||||
//// stdInPush("ping localhost -i 0.01 > /dev/null &\n")
|
||||
//// stdInPush("ping localhost -i 0.01 > /dev/null &\n")
|
||||
//// sleep(500*1000000l)
|
||||
//// while(true){
|
||||
//// sleep(500*1000000l)
|
||||
//// stdInPush("uptime\n")
|
||||
//// printf("\n** uptime **")
|
||||
//// }
|
||||
//// }
|
||||
// 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 _ =>
|
||||
// // case 0xF0000004l => {
|
||||
// // val c = if(stdin.nonEmpty) {
|
||||
// // stdin.dequeue().toInt & 0xFF
|
||||
// // } else {
|
||||
// // 0xFFFFFFFFl
|
||||
// // }
|
||||
// // dut.io.peripheral.DAT_MISO #= c
|
||||
// // }
|
||||
// // case _ =>
|
||||
// // }
|
||||
// // println(f"${dut.io.peripheral.ADR.toLong}%x")
|
||||
// }
|
||||
// }
|
||||
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 _ =>
|
||||
// case 0xF0000004l => {
|
||||
// val c = if(stdin.nonEmpty) {
|
||||
// stdin.dequeue().toInt & 0xFF
|
||||
// } else {
|
||||
// 0xFFFFFFFFl
|
||||
// }
|
||||
// dut.io.peripheral.DAT_MISO #= c
|
||||
// }
|
||||
// case _ =>
|
||||
// }
|
||||
// println(f"${dut.io.peripheral.ADR.toLong}%x")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fork{
|
||||
val at = 0
|
||||
val duration = 1000
|
||||
while(simTime() < at*1000000l) {
|
||||
disableSimWave()
|
||||
sleep(100000 * 10)
|
||||
enableSimWave()
|
||||
sleep( 200 * 10)
|
||||
}
|
||||
println("\n\n********************")
|
||||
sleep(duration*1000000l)
|
||||
println("********************\n\n")
|
||||
while(true) {
|
||||
disableSimWave()
|
||||
sleep(100000 * 10)
|
||||
enableSimWave()
|
||||
sleep( 400 * 10)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// }
|
||||
//
|
||||
// fork{
|
||||
// val at = 0
|
||||
// val duration = 1000
|
||||
// while(simTime() < at*1000000l) {
|
||||
// disableSimWave()
|
||||
// sleep(100000 * 10)
|
||||
// enableSimWave()
|
||||
// sleep( 200 * 10)
|
||||
// }
|
||||
// println("\n\n********************")
|
||||
// sleep(duration*1000000l)
|
||||
// println("********************\n\n")
|
||||
// while(true) {
|
||||
// disableSimWave()
|
||||
// sleep(100000 * 10)
|
||||
// enableSimWave()
|
||||
// sleep( 400 * 10)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
|
@ -5,7 +5,7 @@ import spinal.core._
|
|||
import spinal.lib._
|
||||
import spinal.lib.bus.amba4.axi.{Axi4Config, Axi4Shared}
|
||||
import spinal.lib.bus.avalon.{AvalonMM, AvalonMMConfig}
|
||||
import spinal.lib.bus.bmb.{Bmb, BmbCmd, BmbParameter}
|
||||
import spinal.lib.bus.bmb.{Bmb, BmbAccessParameter, BmbCmd, BmbInvalidationParameter, BmbParameter, BmbSourceParameter}
|
||||
import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig}
|
||||
import spinal.lib.bus.simple._
|
||||
import vexriscv.plugin.DBusSimpleBus
|
||||
|
@ -81,20 +81,21 @@ case class DataCacheConfig(cacheSize : Int,
|
|||
)
|
||||
|
||||
def getBmbParameter() = BmbParameter(
|
||||
addressWidth = 32,
|
||||
dataWidth = memDataWidth,
|
||||
lengthWidth = log2Up(this.bytePerLine),
|
||||
sourceWidth = 0,
|
||||
contextWidth = (if(!withWriteResponse) 1 else 0) + (if(cpuDataWidth != memDataWidth) log2Up(memDataBytes) else 0),
|
||||
canRead = true,
|
||||
canWrite = true,
|
||||
alignment = BmbParameter.BurstAlignement.LENGTH,
|
||||
maximumPendingTransactionPerId = Int.MaxValue,
|
||||
canInvalidate = withInvalidate,
|
||||
canSync = withInvalidate,
|
||||
canExclusive = withExclusive,
|
||||
invalidateLength = log2Up(this.bytePerLine),
|
||||
invalidateAlignment = BmbParameter.BurstAlignement.LENGTH
|
||||
BmbAccessParameter(
|
||||
addressWidth = 32,
|
||||
dataWidth = memDataWidth
|
||||
).addSources(1, BmbSourceParameter(
|
||||
lengthWidth = log2Up(this.bytePerLine),
|
||||
contextWidth = (if(!withWriteResponse) 1 else 0) + (if(cpuDataWidth != memDataWidth) log2Up(memDataBytes) else 0),
|
||||
alignment = BmbParameter.BurstAlignement.LENGTH,
|
||||
canExclusive = withExclusive
|
||||
)),
|
||||
BmbInvalidationParameter(
|
||||
canInvalidate = withInvalidate,
|
||||
canSync = withInvalidate,
|
||||
invalidateLength = log2Up(this.bytePerLine),
|
||||
invalidateAlignment = BmbParameter.BurstAlignement.LENGTH
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -399,7 +400,7 @@ case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave
|
|||
val buffer = new Area {
|
||||
val stream = cmd.toEvent().m2sPipe()
|
||||
val address = Reg(UInt(p.addressWidth bits))
|
||||
val length = Reg(UInt(pipelinedMemoryBusConfig.lengthWidth bits))
|
||||
val length = Reg(UInt(pipelinedMemoryBusConfig.access.lengthWidth bits))
|
||||
val write = Reg(Bool)
|
||||
val exclusive = Reg(Bool)
|
||||
val data = Reg(Bits(p.memDataWidth bits))
|
||||
|
|
|
@ -5,7 +5,7 @@ import spinal.core._
|
|||
import spinal.lib._
|
||||
import spinal.lib.bus.amba4.axi.{Axi4Config, Axi4ReadOnly}
|
||||
import spinal.lib.bus.avalon.{AvalonMM, AvalonMMConfig}
|
||||
import spinal.lib.bus.bmb.{Bmb, BmbParameter}
|
||||
import spinal.lib.bus.bmb.{Bmb, BmbAccessParameter, BmbParameter, BmbSourceParameter}
|
||||
import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig}
|
||||
import spinal.lib.bus.simple._
|
||||
import vexriscv.plugin.{IBusSimpleBus, IBusSimplePlugin}
|
||||
|
@ -71,15 +71,16 @@ case class InstructionCacheConfig( cacheSize : Int,
|
|||
)
|
||||
|
||||
def getBmbParameter() = BmbParameter(
|
||||
addressWidth = 32,
|
||||
dataWidth = memDataWidth,
|
||||
lengthWidth = log2Up(this.bytePerLine),
|
||||
sourceWidth = 0,
|
||||
contextWidth = 0,
|
||||
canRead = true,
|
||||
canWrite = false,
|
||||
alignment = BmbParameter.BurstAlignement.LENGTH,
|
||||
maximumPendingTransactionPerId = 1
|
||||
BmbAccessParameter(
|
||||
addressWidth = 32,
|
||||
dataWidth = memDataWidth
|
||||
).addSources(1, BmbSourceParameter(
|
||||
lengthWidth = log2Up(this.bytePerLine),
|
||||
contextWidth = 0,
|
||||
canWrite = false,
|
||||
alignment = BmbParameter.BurstAlignement.LENGTH,
|
||||
maximumPendingTransaction = 1
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -83,10 +83,7 @@ object DBusSimpleBus{
|
|||
lengthWidth = 2,
|
||||
sourceWidth = 0,
|
||||
contextWidth = 1,
|
||||
canRead = true,
|
||||
canWrite = true,
|
||||
alignment = BmbParameter.BurstAlignement.LENGTH,
|
||||
maximumPendingTransactionPerId = Int.MaxValue
|
||||
alignment = BmbParameter.BurstAlignement.LENGTH
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import spinal.core._
|
|||
import spinal.lib._
|
||||
import spinal.lib.bus.amba3.apb.{Apb3, Apb3Config}
|
||||
import spinal.lib.bus.avalon.{AvalonMM, AvalonMMConfig}
|
||||
import spinal.lib.bus.bmb.{Bmb, BmbAccessParameter, BmbParameter}
|
||||
import spinal.lib.bus.bmb.{Bmb, BmbAccessCapabilities, BmbAccessParameter, BmbParameter}
|
||||
import spinal.lib.bus.simple.PipelinedMemoryBus
|
||||
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
|
@ -25,12 +25,12 @@ case class DebugExtensionRsp() extends Bundle{
|
|||
}
|
||||
|
||||
object DebugExtensionBus{
|
||||
def getBmbAccessParameter(source : BmbAccessParameter) = BmbAccessParameter(
|
||||
def getBmbAccessParameter(source : BmbAccessParameter) = BmbAccessCapabilities(
|
||||
addressWidth = 8,
|
||||
dataWidth = 32,
|
||||
lengthWidth = 2,
|
||||
sourceWidth = source.sourceWidth,
|
||||
contextWidth = source.contextWidth
|
||||
lengthWidthMax = 2,
|
||||
sourceWidthMax = source.sourceWidth,
|
||||
contextWidthMax = source.contextWidth
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ object IBusSimpleBus{
|
|||
canRead = true,
|
||||
canWrite = false,
|
||||
alignment = BmbParameter.BurstAlignement.LENGTH,
|
||||
maximumPendingTransactionPerId = if(plugin != null) plugin.pendingMax else Int.MaxValue
|
||||
maximumPendingTransaction = if(plugin != null) plugin.pendingMax else Int.MaxValue
|
||||
)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue