Update Bmb brides and comment out SmpCluster for now

This commit is contained in:
Dolu1990 2020-06-29 11:44:10 +02:00
parent c12f9a378d
commit 062509deee
9 changed files with 1297 additions and 1300 deletions

View File

@ -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

View File

@ -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)
}
}
}
}
// }
// }

View File

@ -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)
// }
// }
// }
//}

View File

@ -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))

View File

@ -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
))
)
}

View File

@ -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
)
}

View File

@ -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
)
}

View File

@ -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
)
}