Fix IBusCached single cycle interaction with mmu bus
Add random test configs
This commit is contained in:
parent
08a1212fca
commit
83864710a3
|
@ -106,9 +106,10 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
|
|||
|
||||
|
||||
cache.io.cpu.fetch.isRemoved := flush
|
||||
val iBusRspOutputHalt = False
|
||||
if (mmuBus != null) {
|
||||
cache.io.cpu.fetch.mmuBus <> mmuBus
|
||||
iBusRsp.inputPipelineHalt(0) setWhen(mmuBus.cmd.isValid && !mmuBus.rsp.hit && !mmuBus.rsp.miss)
|
||||
(if(twoCycleCache) iBusRsp.inputPipelineHalt(0) else iBusRspOutputHalt) setWhen(mmuBus.cmd.isValid && !mmuBus.rsp.hit && !mmuBus.rsp.miss)
|
||||
} else {
|
||||
cache.io.cpu.fetch.mmuBus.rsp.physicalAddress := cache.io.cpu.fetch.mmuBus.cmd.virtualAddress
|
||||
cache.io.cpu.fetch.mmuBus.rsp.allowExecute := True
|
||||
|
@ -169,7 +170,7 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
|
|||
}
|
||||
|
||||
|
||||
iBusRsp.output.arbitrationFrom(cacheRspArbitration.haltWhen(issueDetected))
|
||||
iBusRsp.output.arbitrationFrom(cacheRspArbitration.haltWhen(issueDetected || iBusRspOutputHalt))
|
||||
iBusRsp.output.rsp.inst := cacheRsp.data
|
||||
iBusRsp.output.pc := cacheRspArbitration.payload
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import vexriscv.plugin._
|
|||
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import scala.sys.process._
|
||||
import scala.util.Random
|
||||
|
||||
|
||||
abstract class ConfigDimension[T](val name: String) {
|
||||
|
@ -84,6 +85,10 @@ class MulDivDimension extends VexRiscvDimension("MulDiv") {
|
|||
)
|
||||
}
|
||||
|
||||
trait InstructionAnticipatedPosition{
|
||||
def instructionAnticipatedOk() : Boolean
|
||||
}
|
||||
|
||||
class RegFileDimension extends VexRiscvDimension("RegFile") {
|
||||
override val positions = List(
|
||||
new VexRiscvPosition("Async") {
|
||||
|
@ -95,6 +100,11 @@ class RegFileDimension extends VexRiscvDimension("RegFile") {
|
|||
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new RegFilePlugin(
|
||||
regFileReadyKind = plugin.SYNC
|
||||
)
|
||||
|
||||
override def isCompatibleWith(positions: Seq[ConfigPosition[VexRiscvConfig]]) = positions.exists{
|
||||
case p : InstructionAnticipatedPosition => p.instructionAnticipatedOk()
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -203,7 +213,7 @@ class IBusDimension extends VexRiscvDimension("IBus") {
|
|||
compressed <- List(false, true);
|
||||
injectorStage <- List(false, true);
|
||||
relaxedPcCalculation <- List(false, true);
|
||||
if latency > 1 || injectorStage) yield new VexRiscvPosition("Simple" + latency + (if(relaxedPcCalculation) "Relax" else "") + (if(injectorStage) "InjStage" else "") + (if(compressed) "Rvc" else "") + prediction.getClass.getTypeName().replace("$","")) {
|
||||
if latency > 1 || injectorStage) yield new VexRiscvPosition("Simple" + latency + (if(relaxedPcCalculation) "Relax" else "") + (if(injectorStage) "InjStage" else "") + (if(compressed) "Rvc" else "") + prediction.getClass.getTypeName().replace("$","")) with InstructionAnticipatedPosition{
|
||||
override def testParam = "IBUS=SIMPLE" + (if(compressed) " COMPRESSED=yes" else "")
|
||||
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new IBusSimplePlugin(
|
||||
resetVector = 0x80000000l,
|
||||
|
@ -214,6 +224,7 @@ class IBusDimension extends VexRiscvDimension("IBus") {
|
|||
busLatencyMin = latency,
|
||||
injectorStage = injectorStage
|
||||
)
|
||||
override def instructionAnticipatedOk() = injectorStage
|
||||
}) :+ new VexRiscvPosition("SimpleFullRelaxedDeep"){
|
||||
override def testParam = "IBUS=SIMPLE COMPRESSED=yes"
|
||||
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new IBusSimplePlugin(
|
||||
|
@ -226,7 +237,7 @@ class IBusDimension extends VexRiscvDimension("IBus") {
|
|||
busLatencyMin = 3,
|
||||
injectorStage = false
|
||||
)
|
||||
} :+ new VexRiscvPosition("SimpleFullRelaxedStd") {
|
||||
} :+ new VexRiscvPosition("SimpleFullRelaxedStd") with InstructionAnticipatedPosition{
|
||||
override def testParam = "IBUS=SIMPLE"
|
||||
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new IBusSimplePlugin(
|
||||
resetVector = 0x80000000l,
|
||||
|
@ -238,6 +249,7 @@ class IBusDimension extends VexRiscvDimension("IBus") {
|
|||
busLatencyMin = 1,
|
||||
injectorStage = true
|
||||
)
|
||||
override def instructionAnticipatedOk() = true
|
||||
}) ++ (for(prediction <- List(NONE, STATIC, DYNAMIC, DYNAMIC_TARGET);
|
||||
twoCycleCache <- List(false, true);
|
||||
twoCycleRam <- List(false, true);
|
||||
|
@ -245,7 +257,7 @@ class IBusDimension extends VexRiscvDimension("IBus") {
|
|||
cacheSize <- List(512, 4096);
|
||||
compressed <- List(false, true);
|
||||
relaxedPcCalculation <- List(false, true);
|
||||
if !(!twoCycleCache && twoCycleRam ) && !(prediction != NONE && (wayCount == 1 || cacheSize == 4096 ))) yield new VexRiscvPosition("Cached" + (if(twoCycleCache) "2cc" else "") + (if(twoCycleRam) "2cr" else "") + "S" + cacheSize + "W" + wayCount + (if(relaxedPcCalculation) "Relax" else "") + (if(compressed) "Rvc" else "") + prediction.getClass.getTypeName().replace("$","")) {
|
||||
if !(!twoCycleCache && twoCycleRam ) && !(prediction != NONE && (wayCount == 1 || cacheSize == 4096 ))) yield new VexRiscvPosition("Cached" + (if(twoCycleCache) "2cc" else "") + (if(twoCycleRam) "2cr" else "") + "S" + cacheSize + "W" + wayCount + (if(relaxedPcCalculation) "Relax" else "") + (if(compressed) "Rvc" else "") + prediction.getClass.getTypeName().replace("$","")) with InstructionAnticipatedPosition{
|
||||
override def testParam = "IBUS=CACHED" + (if(compressed) " COMPRESSED=yes" else "")
|
||||
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new IBusCachedPlugin(
|
||||
resetVector = 0x80000000l,
|
||||
|
@ -267,6 +279,7 @@ class IBusDimension extends VexRiscvDimension("IBus") {
|
|||
twoCycleCache = twoCycleCache
|
||||
)
|
||||
)
|
||||
override def instructionAnticipatedOk() = !twoCycleCache || ((!twoCycleRam || wayCount == 1) && !compressed)
|
||||
})
|
||||
|
||||
// override def default = List(positions.last)
|
||||
|
@ -325,6 +338,7 @@ class DBusDimension extends VexRiscvDimension("DBus") {
|
|||
abstract class ConfigPosition[T](val name: String) {
|
||||
def applyOn(config: T): Unit
|
||||
var dimension : ConfigDimension[_] = null
|
||||
def isCompatibleWith(positions : Seq[ConfigPosition[T]]) : Boolean = true
|
||||
}
|
||||
|
||||
abstract class VexRiscvPosition(name: String) extends ConfigPosition[VexRiscvConfig](name){
|
||||
|
@ -368,39 +382,54 @@ class TestIndividualFeatures extends FunSuite {
|
|||
case Nil => List(stack)
|
||||
}
|
||||
|
||||
|
||||
def doTest(positionsToApply : List[VexRiscvPosition], prefix : String = ""): Unit ={
|
||||
def gen = {
|
||||
SpinalVerilog{
|
||||
val config = VexRiscvConfig(
|
||||
plugins = List(
|
||||
new DecoderSimplePlugin(
|
||||
catchIllegalInstruction = false
|
||||
),
|
||||
new IntAluPlugin,
|
||||
new YamlPlugin("cpu0.yaml")
|
||||
)
|
||||
)
|
||||
for (positionToApply <- positionsToApply) positionToApply.applyOn(config)
|
||||
new VexRiscv(config)
|
||||
}
|
||||
}
|
||||
val name = positionsToApply.map(d => d.dimension.name + "_" + d.name).mkString("_")
|
||||
test(prefix + name + "_gen") {
|
||||
gen
|
||||
}
|
||||
test(prefix + name + "_test") {
|
||||
val testCmd = "make clean run REDO=10 CSR=no MMU=no DEBUG_PLUGIN=no " + (positionsToApply).map(_.testParam).mkString(" ")
|
||||
val str = doCmd(testCmd)
|
||||
assert(!str.contains("FAIL"))
|
||||
val intFind = "(\\d+\\.?)+".r
|
||||
val dmips = intFind.findFirstIn("DMIPS per Mhz\\: (\\d+.?)+".r.findAllIn(str).toList.last).get.toDouble
|
||||
}
|
||||
}
|
||||
|
||||
dimensions.foreach(d => d.positions.foreach(_.dimension = d))
|
||||
|
||||
for(i <- 0 until 40){
|
||||
var positions : List[VexRiscvPosition] = null
|
||||
do{
|
||||
positions = dimensions.map(d => d.positions(Random.nextInt(d.positions.size)))
|
||||
}while(!positions.forall(_.isCompatibleWith(positions)))
|
||||
doTest(positions," random_" + i + "_")
|
||||
}
|
||||
|
||||
for (dimension <- dimensions) {
|
||||
for (position <- dimension.positions/* if position.name.contains("Cached")*/) {
|
||||
for(defaults <- genDefaultsPositions(dimensions.filter(_ != dimension))){
|
||||
def gen = {
|
||||
val config = VexRiscvConfig(
|
||||
plugins = List(
|
||||
new DecoderSimplePlugin(
|
||||
catchIllegalInstruction = false
|
||||
),
|
||||
new IntAluPlugin,
|
||||
new YamlPlugin("cpu0.yaml")
|
||||
)
|
||||
)
|
||||
position.applyOn(config)
|
||||
for (dimensionOthers <- defaults) dimensionOthers.applyOn(config)
|
||||
|
||||
SpinalVerilog(new VexRiscv(config))
|
||||
}
|
||||
val name = dimension.name + "_ " + position.name + "_" + defaults.map(d => d.dimension.name + "_" + d.name).mkString("_")
|
||||
test(name + "_gen") {
|
||||
gen
|
||||
}
|
||||
test(name + "_test") {
|
||||
val testCmd = "make clean run REDO=10 CSR=no MMU=no DEBUG_PLUGIN=no " + (position :: defaults).map(_.testParam).mkString(" ")
|
||||
val str = doCmd(testCmd)
|
||||
assert(!str.contains("FAIL"))
|
||||
val intFind = "(\\d+\\.?)+".r
|
||||
val dmips = intFind.findFirstIn("DMIPS per Mhz\\: (\\d+.?)+".r.findAllIn(str).toList.last).get.toDouble
|
||||
}
|
||||
doTest(position :: defaults)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue