improve LitexCluster area for single core configuration
This commit is contained in:
parent
da666ade49
commit
9f62f37538
|
@ -22,7 +22,7 @@ import scala.collection.mutable
|
|||
import scala.collection.mutable.ArrayBuffer
|
||||
import spinal.lib.generator._
|
||||
|
||||
case class VexRiscvSmpClusterParameter( cpuConfigs : Seq[VexRiscvConfig])
|
||||
case class VexRiscvSmpClusterParameter(cpuConfigs : Seq[VexRiscvConfig], withExclusiveAndInvalidation : Boolean)
|
||||
|
||||
class VexRiscvSmpClusterBase(p : VexRiscvSmpClusterParameter) extends Generator{
|
||||
val cpuCount = p.cpuConfigs.size
|
||||
|
@ -44,16 +44,28 @@ class VexRiscvSmpClusterBase(p : VexRiscvSmpClusterParameter) extends Generator{
|
|||
|
||||
val debugPort = debugBridge.produceIo(debugBridge.logic.jtagBridge.io.ctrl)
|
||||
|
||||
val dBusCoherent = BmbBridgeGenerator()
|
||||
val dBusNonCoherent = BmbBridgeGenerator()
|
||||
|
||||
val smp = p.withExclusiveAndInvalidation generate new Area{
|
||||
val exclusiveMonitor = BmbExclusiveMonitorGenerator()
|
||||
interconnect.addConnection(dBusCoherent.bmb, exclusiveMonitor.input)
|
||||
|
||||
val invalidationMonitor = BmbInvalidateMonitorGenerator()
|
||||
interconnect.addConnection(exclusiveMonitor.output, invalidationMonitor.input)
|
||||
interconnect.addConnection(invalidationMonitor.output, dBusNonCoherent.bmb)
|
||||
interconnect.masters(invalidationMonitor.output).withOutOfOrderDecoder()
|
||||
}
|
||||
|
||||
val noSmp = !p.withExclusiveAndInvalidation generate new Area{
|
||||
interconnect.addConnection(dBusCoherent.bmb, dBusNonCoherent.bmb)
|
||||
}
|
||||
|
||||
val cores = for(cpuId <- 0 until cpuCount) yield new Area{
|
||||
val cpu = VexRiscvBmbGenerator()
|
||||
cpu.config.load(p.cpuConfigs(cpuId))
|
||||
interconnect.addConnection(
|
||||
cpu.dBus -> List(exclusiveMonitor.input)
|
||||
cpu.dBus -> List(dBusCoherent.bmb)
|
||||
)
|
||||
cpu.enableDebugBmb(
|
||||
debugCd = debugCd,
|
||||
|
@ -113,7 +125,8 @@ object VexRiscvSmpClusterGen {
|
|||
ioRange : UInt => Bool = (x => x(31 downto 28) === 0xF),
|
||||
resetVector : Long = 0x80000000l,
|
||||
iBusWidth : Int = 128,
|
||||
dBusWidth : Int = 64) = {
|
||||
dBusWidth : Int = 64,
|
||||
coherency : Boolean = true) = {
|
||||
|
||||
val config = VexRiscvConfig(
|
||||
plugins = List(
|
||||
|
@ -167,8 +180,8 @@ object VexRiscvSmpClusterGen {
|
|||
catchUnaligned = true,
|
||||
withLrSc = true,
|
||||
withAmo = true,
|
||||
withExclusive = true,
|
||||
withInvalidate = true,
|
||||
withExclusive = coherency,
|
||||
withInvalidate = coherency,
|
||||
aggregationWidth = if(dBusWidth == 32) 0 else log2Up(dBusWidth/8)
|
||||
// )
|
||||
),
|
||||
|
|
|
@ -23,10 +23,10 @@ class VexRiscvLitexSmpCluster(p : VexRiscvLitexSmpClusterParameter) extends VexR
|
|||
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)
|
||||
dBusNonCoherent.bmb -> List(dBridge.bmb, peripheralBridge.bmb)
|
||||
)
|
||||
|
||||
if(p.coherentDma || p.cluster.cpuConfigs.size > 1) interconnect.masters(invalidationMonitor.output).withOutOfOrderDecoder()
|
||||
if(p.cluster.withExclusiveAndInvalidation) interconnect.masters(dBusNonCoherent.bmb).withOutOfOrderDecoder()
|
||||
|
||||
dBridge.liteDramParameter.load(p.liteDram)
|
||||
iBridge.liteDramParameter.load(p.liteDram)
|
||||
|
@ -41,7 +41,7 @@ class VexRiscvLitexSmpCluster(p : VexRiscvLitexSmpClusterParameter) extends VexR
|
|||
dataWidth = p.cluster.cpuConfigs.head.find(classOf[DBusCachedPlugin]).get.config.memDataWidth,
|
||||
useSTALL = true
|
||||
))
|
||||
interconnect.addConnection(bridge.bmb, exclusiveMonitor.input)
|
||||
interconnect.addConnection(bridge.bmb, dBusCoherent.bmb)
|
||||
}
|
||||
|
||||
// Interconnect pipelining (FMax)
|
||||
|
@ -50,7 +50,7 @@ class VexRiscvLitexSmpCluster(p : VexRiscvLitexSmpClusterParameter) extends VexR
|
|||
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(dBusNonCoherent.bmb)(cmdValid = true, cmdReady = true, rspValid = true)
|
||||
interconnect.setPipelining(peripheralBridge.bmb)(cmdHalfRate = true, rspValid = true)
|
||||
}
|
||||
|
||||
|
@ -74,6 +74,7 @@ object VexRiscvLitexSmpClusterCmdGen extends App {
|
|||
opt[String]("netlist-name") action { (v, c) => netlistName = v }
|
||||
}.parse(args))
|
||||
|
||||
val coherency = coherentDma || cpuCount > 1
|
||||
def parameter = VexRiscvLitexSmpClusterParameter(
|
||||
cluster = VexRiscvSmpClusterParameter(
|
||||
cpuConfigs = List.tabulate(cpuCount) { hartId =>
|
||||
|
@ -82,9 +83,11 @@ object VexRiscvLitexSmpClusterCmdGen extends App {
|
|||
ioRange = address => address.msb,
|
||||
resetVector = 0,
|
||||
iBusWidth = iBusWidth,
|
||||
dBusWidth = dBusWidth
|
||||
dBusWidth = dBusWidth,
|
||||
coherency = coherency
|
||||
)
|
||||
}
|
||||
},
|
||||
withExclusiveAndInvalidation = coherency
|
||||
),
|
||||
liteDram = LiteDramNativeParameter(addressWidth = 32, dataWidth = liteDramWidth),
|
||||
liteDramMapping = SizeMapping(0x40000000l, 0x40000000l),
|
||||
|
@ -114,7 +117,8 @@ object VexRiscvLitexSmpClusterGen extends App {
|
|||
ioRange = address => address.msb,
|
||||
resetVector = 0
|
||||
)
|
||||
}
|
||||
},
|
||||
withExclusiveAndInvalidation = true
|
||||
),
|
||||
liteDram = LiteDramNativeParameter(addressWidth = 32, dataWidth = 128),
|
||||
liteDramMapping = SizeMapping(0x40000000l, 0x40000000l),
|
||||
|
@ -152,7 +156,8 @@ object VexRiscvLitexSmpClusterOpenSbi extends App{
|
|||
ioRange = address => address(31 downto 28) === 0xF,
|
||||
resetVector = 0x80000000l
|
||||
)
|
||||
}
|
||||
},
|
||||
withExclusiveAndInvalidation = true
|
||||
),
|
||||
liteDram = LiteDramNativeParameter(addressWidth = 32, dataWidth = 128),
|
||||
liteDramMapping = SizeMapping(0x80000000l, 0x70000000l),
|
||||
|
|
|
@ -7,64 +7,64 @@ 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 = BmbBridgeGenerator()
|
||||
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"))
|
||||
}
|
||||
}
|
||||
//case class VexRiscvLitexSmpMpClusterParameter( cluster : VexRiscvSmpClusterParameter,
|
||||
// liteDram : LiteDramNativeParameter,
|
||||
// liteDramMapping : AddressMapping)
|
||||
//
|
||||
//class VexRiscvLitexSmpMpCluster(p : VexRiscvLitexSmpMpClusterParameter) extends VexRiscvSmpClusterWithPeripherals(p.cluster) {
|
||||
// val iArbiter = BmbBridgeGenerator()
|
||||
// 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"))
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -417,7 +417,8 @@ case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave
|
|||
val timer = Reg(UInt(log2Up(timeoutCycles)+1 bits)) init(0)
|
||||
val timerFull = timer.msb
|
||||
val hit = cmd.address(tagRange) === buffer.address(tagRange)
|
||||
val canAggregate = cmd.valid && cmd.wr && !cmd.uncached && !cmd.exclusive && !timerFull && !aggregationCounterFull && (!buffer.stream.valid || aggregationEnabled && hit)
|
||||
val cmdExclusive = if(p.withExclusive) cmd.exclusive else False
|
||||
val canAggregate = cmd.valid && cmd.wr && !cmd.uncached && !cmdExclusive && !timerFull && !aggregationCounterFull && (!buffer.stream.valid || aggregationEnabled && hit)
|
||||
val doFlush = cmd.valid && !canAggregate || timerFull || aggregationCounterFull || !aggregationEnabled
|
||||
// val canAggregate = False
|
||||
// val doFlush = True
|
||||
|
@ -468,7 +469,7 @@ case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave
|
|||
buffer.length := (cmd.length << 2) | 3
|
||||
if (p.withExclusive) buffer.exclusive := cmd.exclusive
|
||||
|
||||
when(cmd.wr && !cmd.uncached && !cmd.exclusive){
|
||||
when(cmd.wr && !cmd.uncached && !cmdExclusive){
|
||||
aggregationEnabled := True
|
||||
buffer.address(aggregationRange.high downto 0) := 0
|
||||
buffer.length := p.memDataBytes-1
|
||||
|
|
Loading…
Reference in New Issue