Litex SoC add coherent DMA master

This commit is contained in:
Dolu1990 2020-07-05 13:15:44 +02:00
parent 32539dfe6d
commit c51e25f8c4
4 changed files with 94 additions and 136 deletions

View File

@ -4,12 +4,13 @@ import spinal.core.SpinalVerilog
import vexriscv.{VexRiscv, VexRiscvConfig, plugin}
import vexriscv.plugin.{BranchPlugin, CsrPlugin, CsrPluginConfig, DBusSimplePlugin, DecoderSimplePlugin, DivPlugin, FullBarrelShifterPlugin, HazardSimplePlugin, IBusSimplePlugin, IntAluPlugin, LightShifterPlugin, MulPlugin, MulSimplePlugin, NONE, RegFilePlugin, SrcPlugin, YamlPlugin}
object GenTwoStage extends App{
object GenTwoThreeStage extends App{
def cpu(withMulDiv : Boolean,
bypass : Boolean,
barrielShifter : Boolean) = new VexRiscv(
barrielShifter : Boolean,
withMemoryStage : Boolean) = new VexRiscv(
config = VexRiscvConfig(
withMemoryStage = false,
withMemoryStage = withMemoryStage,
withWriteBackStage = false,
plugins = List(
new IBusSimplePlugin(
@ -42,8 +43,8 @@ object GenTwoStage extends App{
),
new HazardSimplePlugin(
bypassExecute = bypass,
bypassMemory = false,
bypassWriteBack = false,
bypassMemory = bypass,
bypassWriteBack = bypass,
bypassWriteBackBuffer = bypass,
pessimisticUseSrc = false,
pessimisticWriteRegFile = false,
@ -67,5 +68,5 @@ object GenTwoStage extends App{
)
)
SpinalVerilog(cpu(false,false,false))
SpinalVerilog(cpu(true,true,true,true))
}

View File

@ -108,104 +108,6 @@ class VexRiscvSmpClusterWithPeripherals(p : VexRiscvSmpClusterParameter) extends
}
//case class VexRiscvSmpCluster(p : VexRiscvSmpClusterParameter,
// debugClockDomain : ClockDomain) extends Component{
// val dBusParameter = p.cpuConfigs.head.plugins.find(_.isInstanceOf[DBusCachedPlugin]).get.asInstanceOf[DBusCachedPlugin].config.getBmbParameter()
// val dBusArbiterParameter = dBusParameter.copy(sourceWidth = log2Up(p.cpuConfigs.size))
// val exclusiveMonitorParameter = dBusArbiterParameter
// val invalidateMonitorParameter = BmbExclusiveMonitor.outputParameter(exclusiveMonitorParameter)
// val dMemParameter = BmbInvalidateMonitor.outputParameter(invalidateMonitorParameter)
//
// val iBusParameter = p.cpuConfigs.head.plugins.find(_.isInstanceOf[IBusCachedPlugin]).get.asInstanceOf[IBusCachedPlugin].config.getBmbParameter()
// val iBusArbiterParameter = iBusParameter//.copy(sourceWidth = log2Up(p.cpuConfigs.size))
// val iMemParameter = iBusArbiterParameter
//
// val io = new Bundle {
// val dMem = master(Bmb(dMemParameter))
//// val iMem = master(Bmb(iMemParameter))
// val iMems = Vec(master(Bmb(iMemParameter)), p.cpuConfigs.size)
// val timerInterrupts = in Bits(p.cpuConfigs.size bits)
// val externalInterrupts = in Bits(p.cpuConfigs.size bits)
// val softwareInterrupts = in Bits(p.cpuConfigs.size bits)
// val externalSupervisorInterrupts = in Bits(p.cpuConfigs.size bits)
// val debugBus = slave(Bmb(SystemDebuggerConfig().getBmbParameter.copy(addressWidth = 20)))
// val debugReset = out Bool()
// val time = in UInt(64 bits)
// }
//
// io.debugReset := False
// val cpus = for((cpuConfig, cpuId) <- p.cpuConfigs.zipWithIndex) yield new Area{
// var iBus : Bmb = null
// var dBus : Bmb = null
// var debug : Bmb = null
// cpuConfig.plugins.foreach {
// case plugin: DebugPlugin => debugClockDomain{
// plugin.debugClockDomain = debugClockDomain
// }
// case _ =>
// }
// cpuConfig.plugins += new DebugPlugin(debugClockDomain)
// val core = new VexRiscv(cpuConfig)
// core.plugins.foreach {
// case plugin: IBusCachedPlugin => iBus = plugin.iBus.toBmb()
// case plugin: DBusCachedPlugin => dBus = plugin.dBus.toBmb().pipelined(cmdValid = true)
// case plugin: CsrPlugin => {
// plugin.softwareInterrupt := io.softwareInterrupts(cpuId)
// plugin.externalInterrupt := io.externalInterrupts(cpuId)
// plugin.timerInterrupt := io.timerInterrupts(cpuId)
// if (plugin.config.supervisorGen) plugin.externalInterruptS := io.externalSupervisorInterrupts(cpuId)
// if (plugin.utime != null) plugin.utime := io.time
// }
// case plugin: DebugPlugin => debugClockDomain{
// io.debugReset setWhen(RegNext(plugin.io.resetOut))
// debug = plugin.io.bus.fromBmb()
// }
// case _ =>
// }
// }
//
// val dBusArbiter = BmbArbiter(
// p = dBusArbiterParameter,
// portCount = cpus.size,
// lowerFirstPriority = false,
// inputsWithInv = cpus.map(_ => true),
// inputsWithSync = cpus.map(_ => true),
// pendingInvMax = 16
// )
//
// (dBusArbiter.io.inputs, cpus).zipped.foreach(_ << _.dBus.pipelined(invValid = true, ackValid = true, syncValid = true))
//
// val exclusiveMonitor = BmbExclusiveMonitor(
// inputParameter = exclusiveMonitorParameter,
// pendingWriteMax = 64
// )
// exclusiveMonitor.io.input << dBusArbiter.io.output.pipelined(cmdValid = true, cmdReady = true, rspValid = true)
//
// val invalidateMonitor = BmbInvalidateMonitor(
// inputParameter = invalidateMonitorParameter,
// pendingInvMax = 16
// )
// invalidateMonitor.io.input << exclusiveMonitor.io.output
//
// io.dMem << invalidateMonitor.io.output
//
// (io.iMems, cpus).zipped.foreach(_ << _.iBus)
//
// val debug = debugClockDomain on new Area{
// val arbiter = BmbDecoder(
// p = io.debugBus.p,
// mappings = List.tabulate(p.cpuConfigs.size)(i => SizeMapping(0x00000 + i*0x1000, 0x1000)),
// capabilities = List.fill(p.cpuConfigs.size)(io.debugBus.p),
// pendingMax = 2
// )
// arbiter.io.input << io.debugBus
// (arbiter.io.outputs, cpus.map(_.debug)).zipped.foreach(_ >> _)
// }
//}
//
//
//
object VexRiscvSmpClusterGen {
def vexRiscvConfig(hartId : Int,
ioRange : UInt => Bool = (x => x(31 downto 28) === 0xF),
@ -222,7 +124,7 @@ object VexRiscvSmpClusterGen {
new IBusCachedPlugin(
resetVector = resetVector,
compressedGen = false,
prediction = STATIC,
prediction = vexriscv.plugin.NONE,
historyRamSizeLog2 = 9,
relaxPredictorAddress = true,
injectorStage = false,
@ -309,7 +211,7 @@ object VexRiscvSmpClusterGen {
),
new CsrPlugin(CsrPluginConfig.openSbi(mhartid = hartId, misa = Riscv.misaToInt("imas")).copy(utimeAccess = CsrAccess.READ_ONLY)),
new BranchPlugin(
earlyBranch = false,
earlyBranch = true,
catchAddressMisaligned = true,
fenceiGenAsAJump = false
),
@ -318,6 +220,8 @@ object VexRiscvSmpClusterGen {
)
config
}
// def vexRiscvCluster(cpuCount : Int, resetVector : Long = 0x80000000l) = VexRiscvSmpCluster(
// debugClockDomain = ClockDomain.current.copy(reset = Bool().setName("debugResetIn")),
// p = VexRiscvSmpClusterParameter(

View File

@ -3,8 +3,10 @@ package vexriscv.demo.smp
import spinal.core._
import spinal.lib.bus.bmb._
import spinal.lib.bus.misc.{AddressMapping, DefaultMapping, SizeMapping}
import spinal.lib.bus.wishbone.{WishboneConfig, WishboneToBmbGenerator}
import spinal.lib.sim.SparseMemory
import vexriscv.demo.smp.VexRiscvSmpClusterGen.vexRiscvConfig
import vexriscv.plugin.DBusCachedPlugin
case class VexRiscvLitexSmpClusterParameter( cluster : VexRiscvSmpClusterParameter,
@ -27,6 +29,17 @@ class VexRiscvLitexSmpCluster(p : VexRiscvLitexSmpClusterParameter) extends VexR
dBridge.liteDramParameter.load(p.liteDram)
iBridge.liteDramParameter.load(p.liteDram)
// Coherent DMA interface
val dmaBridge = WishboneToBmbGenerator()
val dmaWishbone = dmaBridge.produceIo(dmaBridge.logic.io.input)
val dmaDataWidth = p.cluster.cpuConfigs.head.find(classOf[DBusCachedPlugin]).get.config.memDataWidth
dmaBridge.config.load(WishboneConfig(
addressWidth = 32-log2Up(dmaDataWidth/8),
dataWidth = p.cluster.cpuConfigs.head.find(classOf[DBusCachedPlugin]).get.config.memDataWidth,
useSTALL = true
))
interconnect.addConnection(dmaBridge.bmb, exclusiveMonitor.input)
// Interconnect pipelining (FMax)
for(core <- cores) {
interconnect.setPipelining(core.cpu.dBus)(cmdValid = true, cmdReady = true, rspValid = true)

View File

@ -1,33 +1,73 @@
//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)
package vexriscv.demo.smp
import spinal.core._
import spinal.lib.bus.bmb._
import spinal.lib.bus.misc.{AddressMapping, DefaultMapping, SizeMapping}
import spinal.lib.bus.wishbone.{WishboneConfig, WishboneToBmbGenerator}
import spinal.lib.sim.SparseMemory
import vexriscv.demo.smp.VexRiscvSmpClusterGen.vexRiscvConfig
case class VexRiscvLitexSmpMpClusterParameter( cluster : VexRiscvSmpClusterParameter,
liteDram : LiteDramNativeParameter,
liteDramMapping : AddressMapping)
class VexRiscvLitexSmpMpCluster(p : VexRiscvLitexSmpMpClusterParameter) extends VexRiscvSmpClusterWithPeripherals(p.cluster) {
val iArbiter = BmbSmpBridgeGenerator()
val iBridge = BmbToLiteDramGenerator(p.liteDramMapping)
val dBridge = BmbToLiteDramGenerator(p.liteDramMapping)
for(core <- cores) interconnect.addConnection(core.cpu.iBus -> List(iArbiter.bmb))
interconnect.addConnection(
iArbiter.bmb -> List(iBridge.bmb, peripheralBridge.bmb),
invalidationMonitor.output -> List(dBridge.bmb, peripheralBridge.bmb)
)
interconnect.masters(invalidationMonitor.output).withOutOfOrderDecoder()
dBridge.liteDramParameter.load(p.liteDram)
iBridge.liteDramParameter.load(p.liteDram)
// Interconnect pipelining (FMax)
for(core <- cores) {
interconnect.setPipelining(core.cpu.dBus)(cmdValid = true, cmdReady = true, rspValid = true)
interconnect.setPipelining(core.cpu.iBus)(cmdHalfRate = true, rspValid = true)
interconnect.setPipelining(iArbiter.bmb)(cmdHalfRate = true, rspValid = true)
}
interconnect.setPipelining(invalidationMonitor.output)(cmdValid = true, cmdReady = true, rspValid = true)
interconnect.setPipelining(peripheralBridge.bmb)(cmdHalfRate = true, rspValid = true)
}
object 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
).toComponent()
toplevel
}
val genConfig = SpinalConfig().addStandardMemBlackboxing(blackboxByteEnables)
// genConfig.generateVerilog(Bench.compressIo(dutGen))
genConfig.generateVerilog(dutGen.setDefinitionName(s"VexRiscvLitexSmpMpCluster_${cpuCount}c"))
}
}
//
////addAttribute("""mark_debug = "true"""")
//class VexRiscvLitexSmpMpCluster(val p : VexRiscvLitexSmpMpClusterParameter,