This commit is contained in:
Dolu1990 2018-06-19 16:15:42 +02:00
parent 1090111a6f
commit 8886f7e6d4
5 changed files with 97 additions and 72 deletions

View file

@ -31,39 +31,40 @@ object TestsWorkspace {
SpinalConfig(mergeAsyncProcess = false).generateVerilog { SpinalConfig(mergeAsyncProcess = false).generateVerilog {
val configFull = VexRiscvConfig( val configFull = VexRiscvConfig(
plugins = List( plugins = List(
// new IBusSimplePlugin( new IBusSimplePlugin(
// resetVector = 0x80000000l,
// relaxedPcCalculation = true,
// relaxedBusCmdValid = false,
// prediction = DYNAMIC_TARGET,
// historyRamSizeLog2 = 10,
// catchAccessFault = true,
// compressedGen = false,
// busLatencyMin = 1
// ),
new IBusCachedPlugin(
resetVector = 0x80000000l, resetVector = 0x80000000l,
compressedGen = true, relaxedPcCalculation = true,
prediction = DYNAMIC_TARGET, relaxedBusCmdValid = false,
injectorStage = true, prediction = NONE,
config = InstructionCacheConfig( historyRamSizeLog2 = 10,
cacheSize = 1024*16, catchAccessFault = true,
bytePerLine = 32, compressedGen = false,
wayCount = 1, busLatencyMin = 3,
addressWidth = 32, injectorStage = false
cpuDataWidth = 32,
memDataWidth = 32,
catchIllegalAccess = true,
catchAccessFault = true,
catchMemoryTranslationMiss = true,
asyncTagMemory = false,
twoCycleRam = false,
twoCycleCache = true
),
memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
portTlbSize = 4
)
), ),
// new IBusCachedPlugin(
// resetVector = 0x80000000l,
// compressedGen = true,
// prediction = DYNAMIC_TARGET,
// injectorStage = true,
// config = InstructionCacheConfig(
// cacheSize = 1024*16,
// bytePerLine = 32,
// wayCount = 1,
// addressWidth = 32,
// cpuDataWidth = 32,
// memDataWidth = 32,
// catchIllegalAccess = true,
// catchAccessFault = true,
// catchMemoryTranslationMiss = true,
// asyncTagMemory = false,
// twoCycleRam = false,
// twoCycleCache = true
// ),
// memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
// portTlbSize = 4
// )
// ),
// new DBusSimplePlugin( // new DBusSimplePlugin(
// catchAddressMisaligned = true, // catchAddressMisaligned = true,
// catchAccessFault = true, // catchAccessFault = true,

View file

@ -381,8 +381,8 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
io.cpu.fetch.physicalAddress := io.cpu.fetch.mmuBus.rsp.physicalAddress io.cpu.fetch.physicalAddress := io.cpu.fetch.mmuBus.rsp.physicalAddress
val resolution = ifGen(!twoCycleCache)( new Area{ val resolution = ifGen(!twoCycleCache)( new Area{
def stage[T <: Data](that : T) = RegNextWhen(that,!io.cpu.decode.isStuck) // def stage[T <: Data](that : T) = RegNextWhen(that,!io.cpu.decode.isStuck)
val mmuRsp = stage(io.cpu.fetch.mmuBus.rsp) val mmuRsp = io.cpu.fetch.mmuBus.rsp
io.cpu.fetch.cacheMiss := !hit.valid io.cpu.fetch.cacheMiss := !hit.valid
io.cpu.fetch.error := hit.error io.cpu.fetch.error := hit.error

View file

@ -242,10 +242,10 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean, catchAccessFault : Bool
memoryExceptionPort.code := (input(INSTRUCTION)(5) ? U(6) | U(4)).resized memoryExceptionPort.code := (input(INSTRUCTION)(5) ? U(6) | U(4)).resized
memoryExceptionPort.valid := input(ALIGNEMENT_FAULT) memoryExceptionPort.valid := input(ALIGNEMENT_FAULT)
} else if(!catchAddressMisaligned){ } else if(!catchAddressMisaligned){
memoryExceptionPort.valid := dBus.rsp.ready && dBus.rsp.error memoryExceptionPort.valid := dBus.rsp.ready && dBus.rsp.error && !input(INSTRUCTION)(5)
memoryExceptionPort.code := 5 memoryExceptionPort.code := 5
} else { } else {
memoryExceptionPort.valid := dBus.rsp.ready && dBus.rsp.error memoryExceptionPort.valid := dBus.rsp.ready && dBus.rsp.error && !input(INSTRUCTION)(5)
memoryExceptionPort.code := 5 memoryExceptionPort.code := 5
when(input(ALIGNEMENT_FAULT)){ when(input(ALIGNEMENT_FAULT)){
memoryExceptionPort.code := (input(INSTRUCTION)(5) ? U(6) | U(4)).resized memoryExceptionPort.code := (input(INSTRUCTION)(5) ? U(6) | U(4)).resized

View file

@ -137,6 +137,8 @@ class IBusCachedPlugin(resetVector : BigInt = 0x80000000l,
if((!twoCycleRam || wayCount == 1) && !compressedGen && !injectorStage){ if((!twoCycleRam || wayCount == 1) && !compressedGen && !injectorStage){
decode.insert(INSTRUCTION_ANTICIPATED) := Mux(decode.arbitration.isStuck, decode.input(INSTRUCTION), cache.io.cpu.fetch.data) decode.insert(INSTRUCTION_ANTICIPATED) := Mux(decode.arbitration.isStuck, decode.input(INSTRUCTION), cache.io.cpu.fetch.data)
} }
} else {
cache.io.cpu.fetch.isUser := (if (privilegeService != null) privilegeService.isUser(decode) else False)
} }

View file

@ -2,6 +2,7 @@ package vexriscv
import java.io.File import java.io.File
import org.apache.commons.io.FileUtils
import org.scalatest.FunSuite import org.scalatest.FunSuite
import spinal.core._ import spinal.core._
import vexriscv.demo._ import vexriscv.demo._
@ -46,20 +47,23 @@ class ShiftDimension extends VexRiscvDimension("Shift") {
} }
class BranchDimension extends VexRiscvDimension("Branch") { class BranchDimension extends VexRiscvDimension("Branch") {
override val positions = List( override val positions = (for(catchAll <- List(false,true)) yield List(
new VexRiscvPosition("Late") { new VexRiscvPosition("Late") {
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new BranchPlugin( override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new BranchPlugin(
earlyBranch = false, earlyBranch = false,
catchAddressMisaligned = false catchAddressMisaligned = catchAll
) )
override def isCompatibleWith(positions: Seq[ConfigPosition[VexRiscvConfig]]) = catchAll == positions.exists(_.isInstanceOf[CatchAllPosition])
}, },
new VexRiscvPosition("Early") { new VexRiscvPosition("Early") {
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new BranchPlugin( override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new BranchPlugin(
earlyBranch = true, earlyBranch = true,
catchAddressMisaligned = false catchAddressMisaligned = catchAll
) )
override def isCompatibleWith(positions: Seq[ConfigPosition[VexRiscvConfig]]) = catchAll == positions.exists(_.isInstanceOf[CatchAllPosition])
} }
) )).flatten
} }
@ -219,7 +223,7 @@ class SrcDimension extends VexRiscvDimension("Src") {
class IBusDimension extends VexRiscvDimension("IBus") { class IBusDimension extends VexRiscvDimension("IBus") {
override val positions = ((for(prediction <- List(NONE, STATIC, DYNAMIC, DYNAMIC_TARGET); override val positions = (for(catchAll <- List(false,true)) yield ((for(prediction <- List(NONE, STATIC, DYNAMIC, DYNAMIC_TARGET);
latency <- List(1,3); latency <- List(1,3);
compressed <- List(false, true); compressed <- List(false, true);
injectorStage <- List(false, true); injectorStage <- List(false, true);
@ -230,12 +234,13 @@ class IBusDimension extends VexRiscvDimension("IBus") {
resetVector = 0x80000000l, resetVector = 0x80000000l,
relaxedPcCalculation = relaxedPcCalculation, relaxedPcCalculation = relaxedPcCalculation,
prediction = prediction, prediction = prediction,
catchAccessFault = false, catchAccessFault = catchAll,
compressedGen = compressed, compressedGen = compressed,
busLatencyMin = latency, busLatencyMin = latency,
injectorStage = injectorStage injectorStage = injectorStage
) )
override def instructionAnticipatedOk() = injectorStage override def instructionAnticipatedOk() = injectorStage
override def isCompatibleWith(positions: Seq[ConfigPosition[VexRiscvConfig]]) = catchAll == positions.exists(_.isInstanceOf[CatchAllPosition])
}) :+ new VexRiscvPosition("SimpleFullRelaxedDeep"){ }) :+ new VexRiscvPosition("SimpleFullRelaxedDeep"){
override def testParam = "IBUS=SIMPLE COMPRESSED=yes" override def testParam = "IBUS=SIMPLE COMPRESSED=yes"
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new IBusSimplePlugin( override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new IBusSimplePlugin(
@ -243,11 +248,12 @@ class IBusDimension extends VexRiscvDimension("IBus") {
relaxedPcCalculation = true, relaxedPcCalculation = true,
relaxedBusCmdValid = true, relaxedBusCmdValid = true,
prediction = STATIC, prediction = STATIC,
catchAccessFault = false, catchAccessFault = catchAll,
compressedGen = true, compressedGen = true,
busLatencyMin = 3, busLatencyMin = 3,
injectorStage = false injectorStage = false
) )
override def isCompatibleWith(positions: Seq[ConfigPosition[VexRiscvConfig]]) = catchAll == positions.exists(_.isInstanceOf[CatchAllPosition])
} :+ new VexRiscvPosition("SimpleFullRelaxedStd") with InstructionAnticipatedPosition{ } :+ new VexRiscvPosition("SimpleFullRelaxedStd") with InstructionAnticipatedPosition{
override def testParam = "IBUS=SIMPLE" override def testParam = "IBUS=SIMPLE"
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new IBusSimplePlugin( override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new IBusSimplePlugin(
@ -255,11 +261,12 @@ class IBusDimension extends VexRiscvDimension("IBus") {
relaxedPcCalculation = true, relaxedPcCalculation = true,
relaxedBusCmdValid = true, relaxedBusCmdValid = true,
prediction = STATIC, prediction = STATIC,
catchAccessFault = false, catchAccessFault = catchAll,
compressedGen = false, compressedGen = false,
busLatencyMin = 1, busLatencyMin = 1,
injectorStage = true injectorStage = true
) )
override def isCompatibleWith(positions: Seq[ConfigPosition[VexRiscvConfig]]) = catchAll == positions.exists(_.isInstanceOf[CatchAllPosition])
override def instructionAnticipatedOk() = true override def instructionAnticipatedOk() = true
}) ++ (for(prediction <- List(NONE, STATIC, DYNAMIC, DYNAMIC_TARGET); }) ++ (for(prediction <- List(NONE, STATIC, DYNAMIC, DYNAMIC_TARGET);
twoCycleCache <- List(false, true); twoCycleCache <- List(false, true);
@ -284,16 +291,17 @@ class IBusDimension extends VexRiscvDimension("IBus") {
addressWidth = 32, addressWidth = 32,
cpuDataWidth = 32, cpuDataWidth = 32,
memDataWidth = 32, memDataWidth = 32,
catchIllegalAccess = false, catchIllegalAccess = catchAll,
catchAccessFault = false, catchAccessFault = catchAll,
catchMemoryTranslationMiss = false, catchMemoryTranslationMiss = catchAll,
asyncTagMemory = false, asyncTagMemory = false,
twoCycleRam = twoCycleRam, twoCycleRam = twoCycleRam,
twoCycleCache = twoCycleCache twoCycleCache = twoCycleCache
) )
) )
override def isCompatibleWith(positions: Seq[ConfigPosition[VexRiscvConfig]]) = catchAll == positions.exists(_.isInstanceOf[CatchAllPosition])
override def instructionAnticipatedOk() = !twoCycleCache || ((!twoCycleRam || wayCount == 1) && !compressed) override def instructionAnticipatedOk() = !twoCycleCache || ((!twoCycleRam || wayCount == 1) && !compressed)
}) })).flatten
// override def default = List(positions.last) // override def default = List(positions.last)
} }
@ -302,22 +310,24 @@ class IBusDimension extends VexRiscvDimension("IBus") {
class DBusDimension extends VexRiscvDimension("DBus") { class DBusDimension extends VexRiscvDimension("DBus") {
override val positions = List( override val positions = (for(catchAll <- List(false,true)) yield List(
new VexRiscvPosition("SimpleLate") { new VexRiscvPosition("SimpleLate") {
override def testParam = "DBUS=SIMPLE" override def testParam = "DBUS=SIMPLE"
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new DBusSimplePlugin( override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new DBusSimplePlugin(
catchAddressMisaligned = false, catchAddressMisaligned = catchAll,
catchAccessFault = false, catchAccessFault = catchAll,
earlyInjection = false earlyInjection = false
) )
override def isCompatibleWith(positions: Seq[ConfigPosition[VexRiscvConfig]]) = catchAll == positions.exists(_.isInstanceOf[CatchAllPosition])
}, },
new VexRiscvPosition("SimpleEarly") { new VexRiscvPosition("SimpleEarly") {
override def testParam = "DBUS=SIMPLE" override def testParam = "DBUS=SIMPLE"
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new DBusSimplePlugin( override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new DBusSimplePlugin(
catchAddressMisaligned = false, catchAddressMisaligned = catchAll,
catchAccessFault = false, catchAccessFault = catchAll,
earlyInjection = true earlyInjection = true
) )
override def isCompatibleWith(positions: Seq[ConfigPosition[VexRiscvConfig]]) = catchAll == positions.exists(_.isInstanceOf[CatchAllPosition])
} }
) ++ (for(wayCount <- List(1); ) ++ (for(wayCount <- List(1);
cacheSize <- List(512, 4096)) yield new VexRiscvPosition("Cached" + "S" + cacheSize + "W" + wayCount) { cacheSize <- List(512, 4096)) yield new VexRiscvPosition("Cached" + "S" + cacheSize + "W" + wayCount) {
@ -331,10 +341,10 @@ class DBusDimension extends VexRiscvDimension("DBus") {
addressWidth = 32, addressWidth = 32,
cpuDataWidth = 32, cpuDataWidth = 32,
memDataWidth = 32, memDataWidth = 32,
catchAccessError = false, catchAccessError = catchAll,
catchIllegal = false, catchIllegal = catchAll,
catchUnaligned = false, catchUnaligned = catchAll,
catchMemoryTranslationMiss = false, catchMemoryTranslationMiss = catchAll,
atomicEntriesCount = 0 atomicEntriesCount = 0
), ),
memoryTranslatorPortConfig = null memoryTranslatorPortConfig = null
@ -343,26 +353,37 @@ class DBusDimension extends VexRiscvDimension("DBus") {
ioRange = _(31 downto 28) === 0xF ioRange = _(31 downto 28) === 0xF
) )
} }
}) override def isCompatibleWith(positions: Seq[ConfigPosition[VexRiscvConfig]]) = catchAll == positions.exists(_.isInstanceOf[CatchAllPosition])
})).flatten
} }
trait CatchAllPosition trait CatchAllPosition
class CsrDimension extends VexRiscvDimension("Src") { class CsrDimension extends VexRiscvDimension("Csr") {
override val positions = List( override val positions = List(
new VexRiscvPosition("None") { // new VexRiscvPosition("None") {
override def applyOn(config: VexRiscvConfig): Unit = {} // override def applyOn(config: VexRiscvConfig): Unit = {}
override def testParam = "CSR=no" // override def testParam = "CSR=no"
}, // },
new VexRiscvPosition("All") with CatchAllPosition{ new VexRiscvPosition("All") with CatchAllPosition{
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new CsrPlugin(CsrPluginConfig.all) override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new CsrPlugin(CsrPluginConfig.all(0x80000020l))
override def testParam = "CSR=no"
} }
) )
} }
class DecoderDimension extends VexRiscvDimension("Decoder") {
override val positions = (for(catchAll <- List(false,true)) yield List(
new VexRiscvPosition("") {
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new DecoderSimplePlugin(
catchIllegalInstruction = catchAll
)
override def isCompatibleWith(positions: Seq[ConfigPosition[VexRiscvConfig]]) = catchAll == positions.exists(_.isInstanceOf[CatchAllPosition])
}
)).flatten
}
@ -396,7 +417,8 @@ class TestIndividualFeatures extends FunSuite {
new HazardDimension, new HazardDimension,
new RegFileDimension, new RegFileDimension,
new SrcDimension, new SrcDimension,
new CsrDimension new CsrDimension,
new DecoderDimension
) )
@ -411,12 +433,10 @@ class TestIndividualFeatures extends FunSuite {
def doTest(positionsToApply : List[VexRiscvPosition], prefix : String = ""): Unit ={ def doTest(positionsToApply : List[VexRiscvPosition], prefix : String = ""): Unit ={
usedPositions ++= positionsToApply usedPositions ++= positionsToApply
def gen = { def gen = {
FileUtils.deleteQuietly(new File("VexRiscv.v"))
SpinalVerilog{ SpinalVerilog{
val config = VexRiscvConfig( val config = VexRiscvConfig(
plugins = List( plugins = List(
new DecoderSimplePlugin(
catchIllegalInstruction = false
),
new IntAluPlugin, new IntAluPlugin,
new YamlPlugin("cpu0.yaml") new YamlPlugin("cpu0.yaml")
) )
@ -430,15 +450,17 @@ class TestIndividualFeatures extends FunSuite {
gen gen
} }
test(prefix + name + "_test") { test(prefix + name + "_test") {
val testCmd = "make clean run REDO=5 MMU=no DEBUG_PLUGIN=no " + (positionsToApply).map(_.testParam).mkString(" ") val debug = false
val stdCmd = if(debug) "make clean run REDO=1 TRACE=yes MMU=no DEBUG_PLUGIN=no DHRYSTONE=no " else "make clean run REDO=10 TRACE=yess MMU=no DEBUG_PLUGIN=no "
val testCmd = stdCmd + (positionsToApply).map(_.testParam).mkString(" ")
val str = doCmd(testCmd) val str = doCmd(testCmd)
assert(!str.contains("FAIL")) assert(!str.contains("FAIL"))
val intFind = "(\\d+\\.?)+".r // val intFind = "(\\d+\\.?)+".r
val dmips = intFind.findFirstIn("DMIPS per Mhz\\: (\\d+.?)+".r.findAllIn(str).toList.last).get.toDouble // val dmips = intFind.findFirstIn("DMIPS per Mhz\\: (\\d+.?)+".r.findAllIn(str).toList.last).get.toDouble
} }
} }
dimensions.foreach(d => d.positions.foreach(_.dimension = d)) dimensions.foreach(d => d.positions.foreach(p => p.dimension = d))
for(i <- 0 until 200){ for(i <- 0 until 200){