SmpCluster now with proper jtag and plic
This commit is contained in:
parent
2e8a059c77
commit
b0cd88c462
|
@ -6,8 +6,10 @@ import spinal.core.sim.{onSimEnd, simSuccess}
|
||||||
import spinal.lib._
|
import spinal.lib._
|
||||||
import spinal.lib.bus.bmb.sim.BmbMemoryAgent
|
import spinal.lib.bus.bmb.sim.BmbMemoryAgent
|
||||||
import spinal.lib.bus.bmb.{Bmb, BmbArbiter, BmbDecoder, BmbExclusiveMonitor, BmbInvalidateMonitor, BmbParameter}
|
import spinal.lib.bus.bmb.{Bmb, BmbArbiter, BmbDecoder, BmbExclusiveMonitor, BmbInvalidateMonitor, BmbParameter}
|
||||||
import spinal.lib.com.jtag.Jtag
|
import spinal.lib.bus.misc.SizeMapping
|
||||||
|
import spinal.lib.com.jtag.{Jtag, JtagTapInstructionCtrl}
|
||||||
import spinal.lib.com.jtag.sim.JtagTcp
|
import spinal.lib.com.jtag.sim.JtagTcp
|
||||||
|
import spinal.lib.system.debugger.SystemDebuggerConfig
|
||||||
import vexriscv.ip.{DataCacheAck, DataCacheConfig, DataCacheMemBus, InstructionCache, InstructionCacheConfig}
|
import vexriscv.ip.{DataCacheAck, DataCacheConfig, DataCacheMemBus, InstructionCache, InstructionCacheConfig}
|
||||||
import vexriscv.plugin.{BranchPlugin, CsrAccess, CsrPlugin, CsrPluginConfig, DBusCachedPlugin, DBusSimplePlugin, DYNAMIC_TARGET, DebugPlugin, DecoderSimplePlugin, FullBarrelShifterPlugin, HazardSimplePlugin, IBusCachedPlugin, IBusSimplePlugin, IntAluPlugin, MmuPlugin, MmuPortConfig, MulDivIterativePlugin, MulPlugin, RegFilePlugin, STATIC, SrcPlugin, YamlPlugin}
|
import vexriscv.plugin.{BranchPlugin, CsrAccess, CsrPlugin, CsrPluginConfig, DBusCachedPlugin, DBusSimplePlugin, DYNAMIC_TARGET, DebugPlugin, DecoderSimplePlugin, FullBarrelShifterPlugin, HazardSimplePlugin, IBusCachedPlugin, IBusSimplePlugin, IntAluPlugin, MmuPlugin, MmuPortConfig, MulDivIterativePlugin, MulPlugin, RegFilePlugin, STATIC, SrcPlugin, YamlPlugin}
|
||||||
import vexriscv.{Riscv, VexRiscv, VexRiscvConfig, plugin}
|
import vexriscv.{Riscv, VexRiscv, VexRiscvConfig, plugin}
|
||||||
|
@ -38,21 +40,23 @@ case class VexRiscvSmpCluster(p : VexRiscvSmpClusterParameter,
|
||||||
val externalInterrupts = in Bits(p.cpuConfigs.size bits)
|
val externalInterrupts = in Bits(p.cpuConfigs.size bits)
|
||||||
val softwareInterrupts = in Bits(p.cpuConfigs.size bits)
|
val softwareInterrupts = in Bits(p.cpuConfigs.size bits)
|
||||||
val externalSupervisorInterrupts = in Bits(p.cpuConfigs.size bits)
|
val externalSupervisorInterrupts = in Bits(p.cpuConfigs.size bits)
|
||||||
val jtag = slave(Jtag())
|
val debugBus = slave(Bmb(SystemDebuggerConfig().getBmbParameter.copy(addressWidth = 20)))
|
||||||
val debugReset = out Bool()
|
val debugReset = out Bool()
|
||||||
val time = in UInt(64 bits)
|
val time = in UInt(64 bits)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
io.debugReset := False
|
||||||
val cpus = for((cpuConfig, cpuId) <- p.cpuConfigs.zipWithIndex) yield new Area{
|
val cpus = for((cpuConfig, cpuId) <- p.cpuConfigs.zipWithIndex) yield new Area{
|
||||||
var iBus : Bmb = null
|
var iBus : Bmb = null
|
||||||
var dBus : Bmb = null
|
var dBus : Bmb = null
|
||||||
|
var debug : Bmb = null
|
||||||
cpuConfig.plugins.foreach {
|
cpuConfig.plugins.foreach {
|
||||||
case plugin: DebugPlugin => debugClockDomain{
|
case plugin: DebugPlugin => debugClockDomain{
|
||||||
plugin.debugClockDomain = debugClockDomain
|
plugin.debugClockDomain = debugClockDomain
|
||||||
}
|
}
|
||||||
case _ =>
|
case _ =>
|
||||||
}
|
}
|
||||||
if(cpuId == 0) cpuConfig.plugins += new DebugPlugin(debugClockDomain)
|
cpuConfig.plugins += new DebugPlugin(debugClockDomain)
|
||||||
val core = new VexRiscv(cpuConfig)
|
val core = new VexRiscv(cpuConfig)
|
||||||
core.plugins.foreach {
|
core.plugins.foreach {
|
||||||
case plugin: IBusCachedPlugin => iBus = plugin.iBus.toBmb()
|
case plugin: IBusCachedPlugin => iBus = plugin.iBus.toBmb()
|
||||||
|
@ -65,8 +69,8 @@ case class VexRiscvSmpCluster(p : VexRiscvSmpClusterParameter,
|
||||||
if (plugin.utime != null) plugin.utime := io.time
|
if (plugin.utime != null) plugin.utime := io.time
|
||||||
}
|
}
|
||||||
case plugin: DebugPlugin => debugClockDomain{
|
case plugin: DebugPlugin => debugClockDomain{
|
||||||
io.debugReset := RegNext(plugin.io.resetOut)
|
io.debugReset setWhen(RegNext(plugin.io.resetOut))
|
||||||
io.jtag <> plugin.io.bus.fromJtag()
|
debug = plugin.io.bus.fromBmb()
|
||||||
}
|
}
|
||||||
case _ =>
|
case _ =>
|
||||||
}
|
}
|
||||||
|
@ -97,19 +101,18 @@ case class VexRiscvSmpCluster(p : VexRiscvSmpClusterParameter,
|
||||||
|
|
||||||
io.dMem << invalidateMonitor.io.output
|
io.dMem << invalidateMonitor.io.output
|
||||||
|
|
||||||
// val iBusArbiter = BmbArbiter(
|
|
||||||
// p = iBusArbiterParameter,
|
|
||||||
// portCount = cpus.size,
|
|
||||||
// pendingRspMax = 64,
|
|
||||||
// lowerFirstPriority = false,
|
|
||||||
// inputsWithInv = cpus.map(_ => true),
|
|
||||||
// inputsWithSync = cpus.map(_ => true),
|
|
||||||
// pendingInvMax = 16
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// (iBusArbiter.io.inputs, cpus).zipped.foreach(_ << _.iBus)
|
|
||||||
// io.iMem << iBusArbiter.io.output
|
|
||||||
(io.iMems, cpus).zipped.foreach(_ << _.iBus)
|
(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(_ >> _)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -417,10 +420,7 @@ object VexRiscvSmpClusterTestInfrastructure{
|
||||||
import spinal.core.sim._
|
import spinal.core.sim._
|
||||||
dut.clockDomain.forkStimulus(10)
|
dut.clockDomain.forkStimulus(10)
|
||||||
dut.debugClockDomain.forkStimulus(10)
|
dut.debugClockDomain.forkStimulus(10)
|
||||||
// JtagTcp(dut.io.jtag, 100)
|
dut.io.debugBus.cmd.valid #= false
|
||||||
dut.io.jtag.tck #= false
|
|
||||||
dut.io.jtag.tdi #= false
|
|
||||||
dut.io.jtag.tms #= false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,15 @@ package vexriscv.demo.smp
|
||||||
import spinal.core._
|
import spinal.core._
|
||||||
import spinal.lib.bus.bmb._
|
import spinal.lib.bus.bmb._
|
||||||
import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig, WishboneSlaveFactory}
|
import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig, WishboneSlaveFactory}
|
||||||
import spinal.lib.com.jtag.Jtag
|
import spinal.lib.com.jtag.{Jtag, JtagTapInstructionCtrl}
|
||||||
import spinal.lib._
|
import spinal.lib._
|
||||||
import spinal.lib.bus.bmb.sim.{BmbMemoryMultiPort, BmbMemoryTester}
|
import spinal.lib.bus.bmb.sim.{BmbMemoryMultiPort, BmbMemoryTester}
|
||||||
import spinal.lib.bus.misc.{AddressMapping, DefaultMapping, SizeMapping}
|
import spinal.lib.bus.misc.{AddressMapping, DefaultMapping, SizeMapping}
|
||||||
import spinal.lib.eda.bench.Bench
|
import spinal.lib.eda.bench.Bench
|
||||||
import spinal.lib.misc.Clint
|
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.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.VexRiscvLitexSmpClusterOpenSbi.{cpuCount, parameter}
|
||||||
import vexriscv.demo.smp.VexRiscvSmpClusterGen.vexRiscvConfig
|
import vexriscv.demo.smp.VexRiscvSmpClusterGen.vexRiscvConfig
|
||||||
import vexriscv.{VexRiscv, VexRiscvConfig}
|
import vexriscv.{VexRiscv, VexRiscvConfig}
|
||||||
|
@ -25,7 +27,8 @@ case class VexRiscvLitexSmpClusterParameter( cluster : VexRiscvSmpClusterParamet
|
||||||
|
|
||||||
//addAttribute("""mark_debug = "true"""")
|
//addAttribute("""mark_debug = "true"""")
|
||||||
case class VexRiscvLitexSmpCluster(p : VexRiscvLitexSmpClusterParameter,
|
case class VexRiscvLitexSmpCluster(p : VexRiscvLitexSmpClusterParameter,
|
||||||
debugClockDomain : ClockDomain) extends Component{
|
debugClockDomain : ClockDomain,
|
||||||
|
jtagClockDomain : ClockDomain) extends Component{
|
||||||
|
|
||||||
val peripheralWishboneConfig = WishboneConfig(
|
val peripheralWishboneConfig = WishboneConfig(
|
||||||
addressWidth = 30,
|
addressWidth = 30,
|
||||||
|
@ -41,9 +44,9 @@ case class VexRiscvLitexSmpCluster(p : VexRiscvLitexSmpClusterParameter,
|
||||||
val iMem = master(LiteDramNative(p.liteDram))
|
val iMem = master(LiteDramNative(p.liteDram))
|
||||||
val peripheral = master(Wishbone(peripheralWishboneConfig))
|
val peripheral = master(Wishbone(peripheralWishboneConfig))
|
||||||
val clint = slave(Wishbone(Clint.getWisboneConfig()))
|
val clint = slave(Wishbone(Clint.getWisboneConfig()))
|
||||||
val externalInterrupts = in Bits(p.cluster.cpuConfigs.size bits)
|
val plic = slave(Wishbone(WishboneConfig(addressWidth = 20, dataWidth = 32)))
|
||||||
val externalSupervisorInterrupts = in Bits(p.cluster.cpuConfigs.size bits)
|
val interrupts = in Bits(32 bits)
|
||||||
val jtag = slave(Jtag())
|
val jtagInstruction = slave(JtagTapInstructionCtrl())
|
||||||
val debugReset = out Bool()
|
val debugReset = out Bool()
|
||||||
}
|
}
|
||||||
val cpuCount = p.cluster.cpuConfigs.size
|
val cpuCount = p.cluster.cpuConfigs.size
|
||||||
|
@ -51,14 +54,25 @@ case class VexRiscvLitexSmpCluster(p : VexRiscvLitexSmpClusterParameter,
|
||||||
clint.driveFrom(WishboneSlaveFactory(io.clint))
|
clint.driveFrom(WishboneSlaveFactory(io.clint))
|
||||||
|
|
||||||
val cluster = VexRiscvSmpCluster(p.cluster, debugClockDomain)
|
val cluster = VexRiscvSmpCluster(p.cluster, debugClockDomain)
|
||||||
cluster.io.externalInterrupts <> io.externalInterrupts
|
|
||||||
cluster.io.externalSupervisorInterrupts <> io.externalSupervisorInterrupts
|
|
||||||
cluster.io.jtag <> io.jtag
|
|
||||||
cluster.io.debugReset <> io.debugReset
|
cluster.io.debugReset <> io.debugReset
|
||||||
cluster.io.timerInterrupts <> B(clint.harts.map(_.timerInterrupt))
|
cluster.io.timerInterrupts <> B(clint.harts.map(_.timerInterrupt))
|
||||||
cluster.io.softwareInterrupts <> B(clint.harts.map(_.softwareInterrupt))
|
cluster.io.softwareInterrupts <> B(clint.harts.map(_.softwareInterrupt))
|
||||||
cluster.io.time := clint.time
|
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(
|
val dBusDecoder = BmbDecoderOutOfOrder(
|
||||||
p = cluster.io.dMem.p,
|
p = cluster.io.dMem.p,
|
||||||
mappings = Seq(DefaultMapping, p.liteDramMapping),
|
mappings = Seq(DefaultMapping, p.liteDramMapping),
|
||||||
|
@ -114,9 +128,39 @@ case class VexRiscvLitexSmpCluster(p : VexRiscvLitexSmpClusterParameter,
|
||||||
|
|
||||||
val peripheralWishbone = peripheralArbiter.io.output.pipelined(cmdValid = true).toWishbone()
|
val peripheralWishbone = peripheralArbiter.io.output.pipelined(cmdValid = true).toWishbone()
|
||||||
io.peripheral << peripheralWishbone
|
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))
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//ifconfig eth0 192.168.0.50 netmask 255.255.255.0 up
|
|
||||||
object VexRiscvLitexSmpClusterGen extends App {
|
object VexRiscvLitexSmpClusterGen extends App {
|
||||||
for(cpuCount <- List(1,2,4,8)) {
|
for(cpuCount <- List(1,2,4,8)) {
|
||||||
def parameter = VexRiscvLitexSmpClusterParameter(
|
def parameter = VexRiscvLitexSmpClusterParameter(
|
||||||
|
@ -136,7 +180,8 @@ object VexRiscvLitexSmpClusterGen extends App {
|
||||||
def dutGen = {
|
def dutGen = {
|
||||||
val toplevel = VexRiscvLitexSmpCluster(
|
val toplevel = VexRiscvLitexSmpCluster(
|
||||||
p = parameter,
|
p = parameter,
|
||||||
debugClockDomain = ClockDomain.current.copy(reset = Bool().setName("debugResetIn"))
|
debugClockDomain = ClockDomain.current.copy(reset = Bool().setName("debugResetIn")),
|
||||||
|
jtagClockDomain = ClockDomain.external("jtag", withReset = false)
|
||||||
)
|
)
|
||||||
toplevel
|
toplevel
|
||||||
}
|
}
|
||||||
|
@ -175,7 +220,8 @@ object VexRiscvLitexSmpClusterOpenSbi extends App{
|
||||||
def dutGen = {
|
def dutGen = {
|
||||||
val top = VexRiscvLitexSmpCluster(
|
val top = VexRiscvLitexSmpCluster(
|
||||||
p = parameter,
|
p = parameter,
|
||||||
debugClockDomain = ClockDomain.current.copy(reset = Bool().setName("debugResetIn"))
|
debugClockDomain = ClockDomain.current.copy(reset = Bool().setName("debugResetIn")),
|
||||||
|
jtagClockDomain = ClockDomain.external("jtag", withReset = false)
|
||||||
)
|
)
|
||||||
top.rework{
|
top.rework{
|
||||||
top.io.clint.setAsDirectionLess.allowDirectionLessIo
|
top.io.clint.setAsDirectionLess.allowDirectionLessIo
|
||||||
|
@ -216,8 +262,7 @@ object VexRiscvLitexSmpClusterOpenSbi extends App{
|
||||||
dut.io.iMem.simSlave(ram, dut.clockDomain)
|
dut.io.iMem.simSlave(ram, dut.clockDomain)
|
||||||
dut.io.dMem.simSlave(ram, dut.clockDomain, dut.dMemBridge.unburstified)
|
dut.io.dMem.simSlave(ram, dut.clockDomain, dut.dMemBridge.unburstified)
|
||||||
|
|
||||||
dut.io.externalInterrupts #= 0
|
dut.io.interrupts #= 0
|
||||||
dut.io.externalSupervisorInterrupts #= 0
|
|
||||||
|
|
||||||
dut.clockDomain.onFallingEdges{
|
dut.clockDomain.onFallingEdges{
|
||||||
if(dut.io.peripheral.CYC.toBoolean){
|
if(dut.io.peripheral.CYC.toBoolean){
|
||||||
|
|
|
@ -3,13 +3,19 @@ package vexriscv.demo.smp
|
||||||
import spinal.core._
|
import spinal.core._
|
||||||
import spinal.lib.bus.bmb._
|
import spinal.lib.bus.bmb._
|
||||||
import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig, WishboneSlaveFactory}
|
import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig, WishboneSlaveFactory}
|
||||||
import spinal.lib.com.jtag.Jtag
|
import spinal.lib.com.jtag.{Jtag, JtagTap, JtagTapInstructionCtrl}
|
||||||
import spinal.lib._
|
import spinal.lib._
|
||||||
|
import spinal.lib.blackbox.xilinx.s7.BSCANE2
|
||||||
import spinal.lib.bus.bmb.sim.{BmbMemoryMultiPort, BmbMemoryTester}
|
import spinal.lib.bus.bmb.sim.{BmbMemoryMultiPort, BmbMemoryTester}
|
||||||
import spinal.lib.bus.misc.{AddressMapping, DefaultMapping, SizeMapping}
|
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.eda.bench.Bench
|
||||||
import spinal.lib.misc.Clint
|
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.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.VexRiscvLitexSmpMpClusterOpenSbi.{cpuCount, parameter}
|
||||||
import vexriscv.demo.smp.VexRiscvSmpClusterGen.vexRiscvConfig
|
import vexriscv.demo.smp.VexRiscvSmpClusterGen.vexRiscvConfig
|
||||||
import vexriscv.{VexRiscv, VexRiscvConfig}
|
import vexriscv.{VexRiscv, VexRiscvConfig}
|
||||||
|
@ -24,8 +30,9 @@ case class VexRiscvLitexSmpMpClusterParameter( cluster : VexRiscvSmpClusterParam
|
||||||
liteDramMapping : AddressMapping)
|
liteDramMapping : AddressMapping)
|
||||||
|
|
||||||
//addAttribute("""mark_debug = "true"""")
|
//addAttribute("""mark_debug = "true"""")
|
||||||
case class VexRiscvLitexSmpMpCluster(p : VexRiscvLitexSmpMpClusterParameter,
|
class VexRiscvLitexSmpMpCluster(val p : VexRiscvLitexSmpMpClusterParameter,
|
||||||
debugClockDomain : ClockDomain) extends Component{
|
val debugClockDomain : ClockDomain,
|
||||||
|
val jtagClockDomain : ClockDomain) extends Component{
|
||||||
|
|
||||||
val peripheralWishboneConfig = WishboneConfig(
|
val peripheralWishboneConfig = WishboneConfig(
|
||||||
addressWidth = 30,
|
addressWidth = 30,
|
||||||
|
@ -43,23 +50,48 @@ case class VexRiscvLitexSmpMpCluster(p : VexRiscvLitexSmpMpClusterParameter,
|
||||||
val iMem = Vec(master(LiteDramNative(p.liteDram)), cpuCount)
|
val iMem = Vec(master(LiteDramNative(p.liteDram)), cpuCount)
|
||||||
val peripheral = master(Wishbone(peripheralWishboneConfig))
|
val peripheral = master(Wishbone(peripheralWishboneConfig))
|
||||||
val clint = slave(Wishbone(Clint.getWisboneConfig()))
|
val clint = slave(Wishbone(Clint.getWisboneConfig()))
|
||||||
val externalInterrupts = in Bits(p.cluster.cpuConfigs.size bits)
|
val plic = slave(Wishbone(WishboneConfig(addressWidth = 20, dataWidth = 32)))
|
||||||
val externalSupervisorInterrupts = in Bits(p.cluster.cpuConfigs.size bits)
|
val interrupts = in Bits(32 bits)
|
||||||
val jtag = slave(Jtag())
|
val jtagInstruction = slave(JtagTapInstructionCtrl())
|
||||||
val debugReset = out Bool()
|
val debugReset = out Bool()
|
||||||
}
|
}
|
||||||
val clint = Clint(cpuCount)
|
val clint = Clint(cpuCount)
|
||||||
clint.driveFrom(WishboneSlaveFactory(io.clint))
|
clint.driveFrom(WishboneSlaveFactory(io.clint))
|
||||||
|
|
||||||
val cluster = VexRiscvSmpCluster(p.cluster, debugClockDomain)
|
val cluster = VexRiscvSmpCluster(p.cluster, debugClockDomain)
|
||||||
cluster.io.externalInterrupts <> io.externalInterrupts
|
|
||||||
cluster.io.externalSupervisorInterrupts <> io.externalSupervisorInterrupts
|
|
||||||
cluster.io.jtag <> io.jtag
|
|
||||||
cluster.io.debugReset <> io.debugReset
|
cluster.io.debugReset <> io.debugReset
|
||||||
cluster.io.timerInterrupts <> B(clint.harts.map(_.timerInterrupt))
|
cluster.io.timerInterrupts <> B(clint.harts.map(_.timerInterrupt))
|
||||||
cluster.io.softwareInterrupts <> B(clint.harts.map(_.softwareInterrupt))
|
cluster.io.softwareInterrupts <> B(clint.harts.map(_.softwareInterrupt))
|
||||||
cluster.io.time := clint.time
|
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)
|
||||||
|
//
|
||||||
|
// 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(
|
val dBusDecoder = BmbDecoderOutOfOrder(
|
||||||
p = cluster.io.dMem.p,
|
p = cluster.io.dMem.p,
|
||||||
mappings = Seq(DefaultMapping, p.liteDramMapping),
|
mappings = Seq(DefaultMapping, p.liteDramMapping),
|
||||||
|
@ -116,6 +148,38 @@ case class VexRiscvLitexSmpMpCluster(p : VexRiscvLitexSmpMpClusterParameter,
|
||||||
val dMemBridge = for(id <- 0 until cpuCount) yield {
|
val dMemBridge = for(id <- 0 until cpuCount) yield {
|
||||||
io.dMem(id).fromBmb(dBusDemux.io.outputs(id), wdataFifoSize = 32, rdataFifoSize = 32)
|
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.valid.addAttribute("""mark_debug = "true""""))
|
||||||
// io.dMem.foreach(_.cmd.ready.addAttribute("""mark_debug = "true""""))
|
// io.dMem.foreach(_.cmd.ready.addAttribute("""mark_debug = "true""""))
|
||||||
|
@ -145,9 +209,10 @@ object VexRiscvLitexSmpMpClusterGen extends App {
|
||||||
)
|
)
|
||||||
|
|
||||||
def dutGen = {
|
def dutGen = {
|
||||||
val toplevel = VexRiscvLitexSmpMpCluster(
|
val toplevel = new VexRiscvLitexSmpMpCluster(
|
||||||
p = parameter,
|
p = parameter,
|
||||||
debugClockDomain = ClockDomain.current.copy(reset = Bool().setName("debugResetIn"))
|
debugClockDomain = ClockDomain.current.copy(reset = Bool().setName("debugResetIn")),
|
||||||
|
jtagClockDomain = ClockDomain.external("jtag", withReset = false)
|
||||||
)
|
)
|
||||||
toplevel
|
toplevel
|
||||||
}
|
}
|
||||||
|
@ -185,10 +250,20 @@ object VexRiscvLitexSmpMpClusterOpenSbi extends App{
|
||||||
)
|
)
|
||||||
|
|
||||||
def dutGen = {
|
def dutGen = {
|
||||||
val top = VexRiscvLitexSmpMpCluster(
|
val top = new VexRiscvLitexSmpMpCluster(
|
||||||
p = parameter,
|
p = parameter,
|
||||||
debugClockDomain = ClockDomain.current.copy(reset = Bool().setName("debugResetIn"))
|
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.rework{
|
||||||
top.io.clint.setAsDirectionLess.allowDirectionLessIo
|
top.io.clint.setAsDirectionLess.allowDirectionLessIo
|
||||||
top.io.peripheral.setAsDirectionLess.allowDirectionLessIo.simPublic()
|
top.io.peripheral.setAsDirectionLess.allowDirectionLessIo.simPublic()
|
||||||
|
@ -217,6 +292,7 @@ object VexRiscvLitexSmpMpClusterOpenSbi extends App{
|
||||||
dut.debugClockDomain.resetSim #= false
|
dut.debugClockDomain.resetSim #= false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JtagTcp(dut.jtag, 10*20)
|
||||||
|
|
||||||
val ram = SparseMemory()
|
val ram = SparseMemory()
|
||||||
ram.loadBin(0x80000000l, "../opensbi/build/platform/spinal/vexriscv/sim/smp/firmware/fw_jump.bin")
|
ram.loadBin(0x80000000l, "../opensbi/build/platform/spinal/vexriscv/sim/smp/firmware/fw_jump.bin")
|
||||||
|
@ -229,8 +305,8 @@ object VexRiscvLitexSmpMpClusterOpenSbi extends App{
|
||||||
dut.io.dMem(id).simSlave(ram, dut.clockDomain)
|
dut.io.dMem(id).simSlave(ram, dut.clockDomain)
|
||||||
}
|
}
|
||||||
|
|
||||||
dut.io.externalInterrupts #= 0
|
dut.io.interrupts #= 0
|
||||||
dut.io.externalSupervisorInterrupts #= 0
|
|
||||||
|
|
||||||
// val stdin = mutable.Queue[Byte]()
|
// val stdin = mutable.Queue[Byte]()
|
||||||
// def stdInPush(str : String) = stdin ++= str.toCharArray.map(_.toByte)
|
// def stdInPush(str : String) = stdin ++= str.toCharArray.map(_.toByte)
|
||||||
|
@ -272,7 +348,7 @@ object VexRiscvLitexSmpMpClusterOpenSbi extends App{
|
||||||
|
|
||||||
fork{
|
fork{
|
||||||
val at = 0
|
val at = 0
|
||||||
val duration = 0
|
val duration = 1000
|
||||||
while(simTime() < at*1000000l) {
|
while(simTime() < at*1000000l) {
|
||||||
disableSimWave()
|
disableSimWave()
|
||||||
sleep(100000 * 10)
|
sleep(100000 * 10)
|
||||||
|
|
Loading…
Reference in New Issue