Add configs without memory/writeback stages in regressions

Add rfReadInExecute configs in regressions
Fix ShiftPluginLight and DBusSimplePlugin for configs with rfReadInExecute stage configs
This commit is contained in:
Charles Papon 2019-04-25 17:36:10 +02:00
parent 431bec84fb
commit d64589cc48
8 changed files with 177 additions and 153 deletions

View File

@ -70,6 +70,9 @@ class Stage() extends Area{
val dontSample = mutable.HashMap[Stageable[_], ArrayBuffer[Bool]]()
def dontSampleStageable(s : Stageable[_], cond : Bool): Unit ={
dontSample.getOrElseUpdate(s, ArrayBuffer[Bool]()) += cond
}
def inputInit[T <: BaseType](stageable : Stageable[T],initValue : T) =
Component.current.addPrePopTask(() => inputsDefault(stageable.asInstanceOf[Stageable[Data]]).asInstanceOf[T].getDrivingReg.init(initValue))
}

View File

@ -99,18 +99,13 @@ class VexRiscv(val config : VexRiscvConfig) extends Component with Pipeline{
plugins ++= config.plugins
//regression usage
decode.input(config.INSTRUCTION).addAttribute(Verilator.public)
decode.input(config.PC).addAttribute(Verilator.public)
decode.arbitration.isValid.addAttribute(Verilator.public)
decode.arbitration.flushAll.addAttribute(Verilator.public)
decode.arbitration.haltItself.addAttribute(Verilator.public)
if(withWriteBackStage) {
writeBack.input(config.INSTRUCTION) keep() addAttribute (Verilator.public)
writeBack.input(config.PC) keep() addAttribute (Verilator.public)
writeBack.arbitration.isValid keep() addAttribute (Verilator.public)
writeBack.arbitration.isFiring keep() addAttribute (Verilator.public)
}
decode.arbitration.removeIt.noBackendCombMerge //Verilator perf
val lastStageInstruction = CombInit(stages.last.input(config.INSTRUCTION)) keep() addAttribute (Verilator.public)
val lastStagePc = CombInit(stages.last.input(config.PC)) keep() addAttribute (Verilator.public)
val lastStageIsValid = CombInit(stages.last.arbitration.isValid) keep() addAttribute (Verilator.public)
val lastStageIsFiring = CombInit(stages.last.arbitration.isFiring) keep() addAttribute (Verilator.public)
//Verilator perf
decode.arbitration.removeIt.noBackendCombMerge
if(withMemoryStage){
memory.arbitration.removeIt.noBackendCombMerge
}

View File

@ -329,12 +329,12 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
}
//Emit dBus.cmd request
val cmdSent = if(rspStage == execute) RegInit(False) setWhen(dBus.cmd.fire) clearWhen(!execute.arbitration.isStuck) else False
val cmdStage = if(emitCmdInMemoryStage) memory else execute
cmdStage plug new Area{
import cmdStage._
val privilegeService = pipeline.serviceElse(classOf[PrivilegeService], PrivilegeServiceDefault())
val cmdSent = if(rspStage == execute) RegInit(False) setWhen(dBus.cmd.fire) clearWhen(!execute.arbitration.isStuck) else False
if (catchAddressMisaligned)
insert(ALIGNEMENT_FAULT) := (dBus.cmd.size === 2 && dBus.cmd.address(1 downto 0) =/= 0) || (dBus.cmd.size === 1 && dBus.cmd.address(0 downto 0) =/= 0)
@ -413,7 +413,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
insert(MEMORY_READ_DATA) := dBus.rsp.data
arbitration.haltItself setWhen(arbitration.isValid && input(MEMORY_ENABLE) && !input(MEMORY_STORE) && !dBus.rsp.ready)
arbitration.haltItself setWhen(arbitration.isValid && input(MEMORY_ENABLE) && !input(MEMORY_STORE) && (!dBus.rsp.ready || (if(rspStage == execute) !cmdSent else False)))
if(catchSomething) {
memoryExceptionPort.valid := False

View File

@ -91,7 +91,7 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind,
import writeStage._
def shadowPrefix(that : Bits) = if(withShadow) global.shadow.write ## that else that
val regFileWrite = global.regFile.writePort.addAttribute(Verilator.public)
val regFileWrite = global.regFile.writePort.addAttribute(Verilator.public).setName("lastStageRegFileWrite")
regFileWrite.valid := output(REGFILE_WRITE_VALID) && arbitration.isFiring
regFileWrite.address := U(shadowPrefix(output(INSTRUCTION)(rdRange)))
regFileWrite.data := output(REGFILE_WRITE_DATA)

View File

@ -69,6 +69,7 @@ class FullBarrelShifterPlugin(earlyInjection : Boolean = false) extends Plugin[V
val injectionStage = if(earlyInjection) execute else memory
injectionStage plug new Area{
import injectionStage._
when(arbitration.isValid){
switch(input(SHIFT_CTRL)) {
is(ShiftCtrlEnum.SLL) {
output(REGFILE_WRITE_DATA) := Reverse(input(SHIFT_RIGHT))
@ -80,6 +81,7 @@ class FullBarrelShifterPlugin(earlyInjection : Boolean = false) extends Plugin[V
}
}
}
}
@ -162,6 +164,7 @@ class LightShifterPlugin extends Plugin[VexRiscv]{
val shiftInput = isActive ? (if(withMemoryStage) memory.input(REGFILE_WRITE_DATA) else shiftReg) | input(SRC1)
val done = amplitude(4 downto 1) === 0
if(withMemoryStage) memory.dontSampleStageable(REGFILE_WRITE_DATA, arbitration.isStuckByOthers)
when(arbitration.isValid && isShift && input(SRC2)(4 downto 0) =/= 0){
output(REGFILE_WRITE_DATA) := input(SHIFT_CTRL).mux(

View File

@ -1,39 +1,29 @@
[*]
[*] GTKWave Analyzer v3.3.100 (w)1999-2019 BSI
[*] Sun Apr 14 19:28:23 2019
[*] Thu Apr 25 14:41:35 2019
[*]
[dumpfile] "/home/miaou/pro/VexRiscv/src/test/cpp/regression/mmu.vcd"
[dumpfile_mtime] "Sun Apr 14 19:27:24 2019"
[dumpfile_size] 1551340
[dumpfile] "/home/miaou/pro/VexRiscv/src/test/cpp/regression/C.SLLI.vcd"
[dumpfile_mtime] "Thu Apr 25 14:39:03 2019"
[dumpfile_size] 295925
[savefile] "/home/miaou/pro/VexRiscv/src/test/cpp/regression/fail.gtkw"
[timestart] 348
[timestart] 0
[size] 1920 1030
[pos] -458 -215
*-2.000000 357 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
*-2.000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] TOP.
[treeopen] TOP.VexRiscv.
[sst_width] 287
[signals_width] 563
[sst_width] 196
[signals_width] 366
[sst_expanded] 1
[sst_vpaned_height] 279
[sst_vpaned_height] 299
@28
TOP.VexRiscv.writeBack_arbitration_isFiring
TOP.VexRiscv.lastStageIsValid
TOP.VexRiscv.lastStageIsFiring
@22
TOP.VexRiscv.writeBack_PC[31:0]
TOP.VexRiscv.writeBack_INSTRUCTION[31:0]
TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_payload_address[4:0]
TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_payload_data[31:0]
TOP.VexRiscv.lastStageInstruction[31:0]
TOP.VexRiscv.lastStagePc[31:0]
TOP.VexRiscv.lastStageRegFileWrite_payload_address[4:0]
TOP.VexRiscv.lastStageRegFileWrite_payload_data[31:0]
@28
TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_valid
@29
TOP.VexRiscv.CsrPlugin_interrupt
@28
TOP.VexRiscv.CsrPlugin_exception
@22
TOP.VexRiscv.CsrPlugin_mcause_exceptionCode[3:0]
@28
TOP.VexRiscv.CsrPlugin_mcause_interrupt
@22
TOP.VexRiscv.CsrPlugin_mepc[31:0]
TOP.VexRiscv.lastStageRegFileWrite_valid
[pattern_trace] 1
[pattern_trace] 0

View File

@ -1411,7 +1411,7 @@ public:
virtual void fillSimELements();
void dump(int i){
#ifdef TRACE
if(i == TRACE_START) cout << "START TRACE" << endl;
if(i == TRACE_START && i != 0) cout << "START TRACE" << endl;
if(i >= TRACE_START) tfp->dump(i);
#endif
}
@ -1509,7 +1509,7 @@ public:
#ifndef MTIME_INSTR_FACTOR
mTime = i/2;
#else
mTime += top->VexRiscv->writeBack_arbitration_isFiring*MTIME_INSTR_FACTOR;
mTime += top->VexRiscv->lastStageIsFiring*MTIME_INSTR_FACTOR;
#endif
#endif
#ifdef TIMER_INTERRUPT
@ -1554,7 +1554,7 @@ public:
}
}
#endif
if(top->VexRiscv->writeBack_arbitration_isFiring){
if(top->VexRiscv->lastStageIsFiring){
if(riscvRefEnable) {
// privilegeCounters[riscvRef.privilege]++;
// if((riscvRef.stepCounter & 0xFFFFF) == 0){
@ -1568,8 +1568,8 @@ public:
bool mIntExt = false;
}
if(riscvRefEnable && top->VexRiscv->writeBack_PC != riscvRef.lastPc){
cout << hex << " pc missmatch " << top->VexRiscv->writeBack_PC << " should be " << riscvRef.lastPc << dec << endl;
if(riscvRefEnable && top->VexRiscv->lastStagePc != riscvRef.lastPc){
cout << hex << " pc missmatch " << top->VexRiscv->lastStagePc << " should be " << riscvRef.lastPc << dec << endl;
fail();
}
@ -1578,16 +1578,16 @@ public:
int32_t rfWriteAddress;
int32_t rfWriteData;
if(top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_valid == 1 && top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_address != 0){
if(top->VexRiscv->lastStageRegFileWrite_valid == 1 && top->VexRiscv->lastStageRegFileWrite_payload_address != 0){
rfWriteValid = true;
rfWriteAddress = top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_address;
rfWriteData = top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_data;
rfWriteAddress = top->VexRiscv->lastStageRegFileWrite_payload_address;
rfWriteData = top->VexRiscv->lastStageRegFileWrite_payload_data;
#ifdef TRACE_ACCESS
regTraces <<
#ifdef TRACE_WITH_TIME
currentTime <<
#endif
" PC " << hex << setw(8) << top->VexRiscv->writeBack_PC << " : reg[" << dec << setw(2) << (uint32_t)top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_address << "] = " << hex << setw(8) << top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_data << dec << endl;
" PC " << hex << setw(8) << top->VexRiscv->lastStagePc << " : reg[" << dec << setw(2) << (uint32_t)top->VexRiscv->lastStageRegFileWrite_payload_address << "] = " << hex << setw(8) << top->VexRiscv->lastStageRegFileWrite_payload_data << dec << endl;
#endif
} else {
#ifdef TRACE_ACCESS
@ -1595,7 +1595,7 @@ public:
#ifdef TRACE_WITH_TIME
currentTime <<
#endif
" PC " << hex << setw(8) << top->VexRiscv->writeBack_PC << dec << endl;
" PC " << hex << setw(8) << top->VexRiscv->lastStagePc << dec << endl;
#endif
}
if(riscvRefEnable) if(rfWriteValid != riscvRef.rfWriteValid ||
@ -1636,7 +1636,7 @@ public:
} catch (const std::exception& e) {
staticMutex.lock();
cout << "FAIL " << name << " at PC=" << hex << setw(8) << top->VexRiscv->writeBack_PC << dec; //<< " seed : " << seed <<
cout << "FAIL " << name << " at PC=" << hex << setw(8) << top->VexRiscv->lastStagePc << dec; //<< " seed : " << seed <<
if(riscvRefEnable) cout << hex << " REF PC=" << riscvRef.lastPc << " REF I=" << riscvRef.lastInstruction << dec;
cout << " time=" << i;
cout << endl;
@ -2701,9 +2701,9 @@ public:
}
virtual void checks(){
if(top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_valid == 1 && top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_address != 0){
assertEq(top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_address, regFileWriteRefArray[regFileWriteRefIndex][0]);
assertEq(top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_data, regFileWriteRefArray[regFileWriteRefIndex][1]);
if(top->VexRiscv->lastStageRegFileWrite_valid == 1 && top->VexRiscv->lastStageRegFileWrite_payload_address != 0){
assertEq(top->VexRiscv->lastStageRegFileWrite_payload_address, regFileWriteRefArray[regFileWriteRefIndex][0]);
assertEq(top->VexRiscv->lastStageRegFileWrite_payload_data, regFileWriteRefArray[regFileWriteRefIndex][1]);
//printf("%d\n",i);
regFileWriteRefIndex++;
@ -2727,8 +2727,8 @@ public:
}
virtual void checks(){
if(top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_valid == 1 && top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_address == 28){
assertEq(top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_data, ref[refIndex]);
if(top->VexRiscv->lastStageRegFileWrite_valid == 1 && top->VexRiscv->lastStageRegFileWrite_payload_address == 28){
assertEq(top->VexRiscv->lastStageRegFileWrite_payload_data, ref[refIndex]);
//printf("%d\n",i);
refIndex++;
@ -2755,11 +2755,11 @@ public:
}
virtual void checks(){
if(top->VexRiscv->writeBack_arbitration_isFiring && top->VexRiscv->writeBack_INSTRUCTION == 0x00000013){
if(top->VexRiscv->lastStageIsFiring && top->VexRiscv->lastStageInstruction == 0x00000013){
uint32_t instruction;
bool error;
Workspace::mem.read(top->VexRiscv->writeBack_PC, 4, (uint8_t*)&instruction);
//printf("%x => %x\n", top->VexRiscv->writeBack_PC, instruction );
Workspace::mem.read(top->VexRiscv->lastStagePc, 4, (uint8_t*)&instruction);
//printf("%x => %x\n", top->VexRiscv->lastStagePc, instruction );
if(instruction == 0x00000073){
uint32_t code = top->VexRiscv->RegFilePlugin_regFile[28];
uint32_t code2 = top->VexRiscv->RegFilePlugin_regFile[3];

View File

@ -47,6 +47,9 @@ object VexRiscvUniverse{
val MMU = new VexRiscvUniverse
val FORCE_MULDIV = new VexRiscvUniverse
val SUPERVISOR = new VexRiscvUniverse
val NO_WRITEBACK = new VexRiscvUniverse
val NO_MEMORY = new VexRiscvUniverse
val EXECUTE_RF = new VexRiscvUniverse
}
@ -55,24 +58,29 @@ object Hack{
}
class ShiftDimension extends VexRiscvDimension("Shift") {
override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = random(r, List(
new VexRiscvPosition("FullLate") {
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new FullBarrelShifterPlugin(earlyInjection = false)
},
override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = {
var l = List(
new VexRiscvPosition("FullEarly") {
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new FullBarrelShifterPlugin(earlyInjection = true)
},
new VexRiscvPosition("Light") {
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new LightShifterPlugin
}
))
)
if(!universes.contains(VexRiscvUniverse.NO_MEMORY)) l = new VexRiscvPosition("FullLate") {
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new FullBarrelShifterPlugin(earlyInjection = false)
} :: l
random(r, l)
}
}
class BranchDimension extends VexRiscvDimension("Branch") {
override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = {
val catchAll = universes.contains(VexRiscvUniverse.CATCH_ALL)
val early = r.nextBoolean()
val early = r.nextBoolean() || universes.contains(VexRiscvUniverse.NO_MEMORY)
new VexRiscvPosition(if(early) "Early" else "Late") {
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new BranchPlugin(
earlyBranch = early,
@ -87,7 +95,51 @@ class BranchDimension extends VexRiscvDimension("Branch") {
class MulDivDimension extends VexRiscvDimension("MulDiv") {
override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = {
var l = List(
val noMemory = universes.contains(VexRiscvUniverse.NO_MEMORY)
val noWriteBack = universes.contains(VexRiscvUniverse.NO_WRITEBACK)
var l = List[VexRiscvPosition]()
if(!noMemory) {
l = new VexRiscvPosition("MulDivAsic") {
override def testParam = "MUL=yes DIV=yes"
override def applyOn(config: VexRiscvConfig): Unit = {
config.plugins += new MulDivIterativePlugin(
genMul = true,
genDiv = true,
mulUnrollFactor = 32,
divUnrollFactor = 4
)
}
} :: new VexRiscvPosition("MulDivFpgaNoDsp") {
override def testParam = "MUL=yes DIV=yes"
override def applyOn(config: VexRiscvConfig): Unit = {
config.plugins += new MulDivIterativePlugin(
genMul = true,
genDiv = true,
mulUnrollFactor = 1,
divUnrollFactor = 1
)
}
} :: new VexRiscvPosition("MulDivFpgaNoDspFastMul") {
override def testParam = "MUL=yes DIV=yes"
override def applyOn(config: VexRiscvConfig): Unit = {
config.plugins += new MulDivIterativePlugin(
genMul = true,
genDiv = true,
mulUnrollFactor = 8,
divUnrollFactor = 1
)
}
} :: l
}
if(!universes.contains(VexRiscvUniverse.FORCE_MULDIV)) l = new VexRiscvPosition("NoMulDiv") {
override def applyOn(config: VexRiscvConfig): Unit = {}
override def testParam = "MUL=no DIV=no"
} :: l
if(!noMemory && !noWriteBack) l =
new VexRiscvPosition("MulDivFpga") {
override def testParam = "MUL=yes DIV=yes"
override def applyOn(config: VexRiscvConfig): Unit = {
@ -99,45 +151,6 @@ class MulDivDimension extends VexRiscvDimension("MulDiv") {
divUnrollFactor = 1
)
}
},
new VexRiscvPosition("MulDivAsic") {
override def testParam = "MUL=yes DIV=yes"
override def applyOn(config: VexRiscvConfig): Unit = {
config.plugins += new MulDivIterativePlugin(
genMul = true,
genDiv = true,
mulUnrollFactor = 32,
divUnrollFactor = 4
)
}
},
new VexRiscvPosition("MulDivFpgaNoDsp") {
override def testParam = "MUL=yes DIV=yes"
override def applyOn(config: VexRiscvConfig): Unit = {
config.plugins += new MulDivIterativePlugin(
genMul = true,
genDiv = true,
mulUnrollFactor = 1,
divUnrollFactor = 1
)
}
},
new VexRiscvPosition("MulDivFpgaNoDspFastMul") {
override def testParam = "MUL=yes DIV=yes"
override def applyOn(config: VexRiscvConfig): Unit = {
config.plugins += new MulDivIterativePlugin(
genMul = true,
genDiv = true,
mulUnrollFactor = 8,
divUnrollFactor = 1
)
}
}
)
if(!universes.contains(VexRiscvUniverse.FORCE_MULDIV)) l = new VexRiscvPosition("NoMulDiv") {
override def applyOn(config: VexRiscvConfig): Unit = {}
override def testParam = "MUL=no DIV=no"
} :: l
random(r, l)
@ -149,27 +162,31 @@ trait InstructionAnticipatedPosition{
}
class RegFileDimension extends VexRiscvDimension("RegFile") {
override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = random(r, List(
new VexRiscvPosition("Async") {
override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = {
val executeRf = universes.contains(VexRiscvUniverse.EXECUTE_RF)
random(r, List(
new VexRiscvPosition("Async" + (if(executeRf) "ER" else "DR")) {
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new RegFilePlugin(
regFileReadyKind = plugin.ASYNC,
zeroBoot = true
zeroBoot = true,
readInExecute = executeRf
)
},
new VexRiscvPosition("Sync") {
new VexRiscvPosition("Sync" + (if(executeRf) "ER" else "DR")) {
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new RegFilePlugin(
regFileReadyKind = plugin.SYNC,
zeroBoot = true
zeroBoot = true,
readInExecute = executeRf
)
override def isCompatibleWith(positions: Seq[ConfigPosition[VexRiscvConfig]]) = positions.exists{
override def isCompatibleWith(positions: Seq[ConfigPosition[VexRiscvConfig]]) = executeRf || positions.exists{
case p : InstructionAnticipatedPosition => p.instructionAnticipatedOk()
case _ => false
}
}
))
}
}
@ -255,7 +272,8 @@ class HazardDimension extends VexRiscvDimension("Hazard") {
class SrcDimension extends VexRiscvDimension("Src") {
override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = {
val separatedAddSub, executeInsertion = r.nextBoolean()
val separatedAddSub = r.nextBoolean()
val executeInsertion = universes.contains(VexRiscvUniverse.EXECUTE_RF) || r.nextBoolean()
new VexRiscvPosition((if (separatedAddSub) "AddSub" else "") + (if (executeInsertion) "Execute" else "")) {
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new SrcPlugin(
separatedAddSub = separatedAddSub,
@ -353,10 +371,14 @@ class DBusDimension extends VexRiscvDimension("DBus") {
override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = {
val catchAll = universes.contains(VexRiscvUniverse.CATCH_ALL)
val mmuConfig = if(universes.contains(VexRiscvUniverse.MMU)) MmuPortConfig( portTlbSize = 4) else null
val noMemory = universes.contains(VexRiscvUniverse.NO_MEMORY)
val noWriteBack = universes.contains(VexRiscvUniverse.NO_WRITEBACK)
if(r.nextDouble() < 0.4){
if(r.nextDouble() < 0.4 || noMemory || noWriteBack){
val withLrSc = catchAll
val earlyInjection = r.nextBoolean()
val earlyInjection = r.nextBoolean() && !universes.contains(VexRiscvUniverse.NO_WRITEBACK)
new VexRiscvPosition("Simple" + (if(earlyInjection) "Early" else "Late")) {
override def testParam = "DBUS=SIMPLE " + (if(withLrSc) "LRSC=yes " else "")
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new DBusSimplePlugin(
@ -540,12 +562,16 @@ class TestIndividualFeatures extends FunSuite {
// val usedPositions = mutable.HashSet[VexRiscvPosition]();
// val positionsCount = dimensions.map(d => d.positions.length).sum
def doTest(positionsToApply : List[VexRiscvPosition], prefix : String = "", testSeed : Int): Unit ={
def doTest(positionsToApply : List[VexRiscvPosition], prefix : String = "", testSeed : Int, universes : mutable.HashSet[VexRiscvUniverse]): Unit ={
// usedPositions ++= positionsToApply
val noMemory = universes.contains(VexRiscvUniverse.NO_MEMORY)
val noWriteback = universes.contains(VexRiscvUniverse.NO_WRITEBACK)
def gen = {
FileUtils.deleteQuietly(new File("VexRiscv.v"))
SpinalVerilog{
val config = VexRiscvConfig(
withMemoryStage = !noMemory,
withWriteBackStage = !noWriteback,
plugins = List(
new IntAluPlugin,
new YamlPlugin("cpu0.yaml")
@ -555,7 +581,8 @@ class TestIndividualFeatures extends FunSuite {
new VexRiscv(config)
}
}
val name = positionsToApply.map(d => d.dimension.name + "_" + d.name).mkString("_")
val name = (if(noMemory) "noMemoryStage_" else "") + (if(noWriteback) "noWritebackStage_" else "") + positionsToApply.map(d => d.dimension.name + "_" + d.name).mkString("_")
test(prefix + name + "_gen") {
gen
}
@ -564,14 +591,10 @@ class TestIndividualFeatures extends FunSuite {
test(prefix + name + "_test") {
val debug = true
val stdCmd = (s"make clean run WITH_USER_IO=no REDO=10 TRACE=${if(debug) "yes" else "no"} TRACE_START=9999924910246l FLOW_INFO=no STOP_ON_ERROR=no DHRYSTONE=yes COREMARK=yes THREAD_COUNT=${sys.env.getOrElse("VEXRISCV_REGRESSION_THREAD_COUNT", 1)} ") + s" SEED=${testSeed} "
// val stdCmd = "make clean run REDO=40 DHRYSTONE=no STOP_ON_ERROR=yes TRACE=yess "
val testCmd = stdCmd + (positionsToApply).map(_.testParam).mkString(" ")
println(testCmd)
val str = doCmd(testCmd)
assert(str.contains("REGRESSION SUCCESS") && !str.contains("Broken pipe"))
// val intFind = "(\\d+\\.?)+".r
// val dmips = intFind.findFirstIn("DMIPS per Mhz\\: (\\d+.?)+".r.findAllIn(str).toList.last).get.toDouble
}
}
@ -581,9 +604,9 @@ class TestIndividualFeatures extends FunSuite {
val seed = Random.nextLong()
// val testId = Some(mutable.HashSet(18,34,77,85,118,129,132,134,152,167,175,188,191,198,199)) //37/29 sp_flop_rv32i_O3
//val testId = Some(mutable.HashSet(3))
// val testId = Some(mutable.HashSet(129, 134))
// val seed = -1580866821569084523l
//val testId = Some(mutable.HashSet(0))
// val testId = Some(mutable.HashSet(4))
// val seed = -8309068850561113754l
val rand = new Random(seed)
@ -595,15 +618,25 @@ class TestIndividualFeatures extends FunSuite {
for(i <- 0 until sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_COUNT", "100").toInt){
var positions : List[VexRiscvPosition] = null
var universe = mutable.HashSet[VexRiscvUniverse]()
if(sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_LINUX_RATE", "0.3").toDouble > Math.random()) {
if(rand.nextDouble() < 0.5) universe += VexRiscvUniverse.EXECUTE_RF
if(sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_LINUX_RATE", "0.3").toDouble > rand.nextDouble()) {
universe += VexRiscvUniverse.CATCH_ALL
universe += VexRiscvUniverse.MMU
universe += VexRiscvUniverse.FORCE_MULDIV
universe += VexRiscvUniverse.SUPERVISOR
}
if(sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_MACHINE_OS_RATE", "0.5").toDouble > Math.random()) {
} else {
if(sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_MACHINE_OS_RATE", "0.5").toDouble > rand.nextDouble()) {
universe += VexRiscvUniverse.CATCH_ALL
}
var tmp = rand.nextDouble()
if(sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_DEMW_RATE", "0.6").toDouble > rand.nextDouble()){
}else if(sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_DEM_RATE", "0.5").toDouble > rand.nextDouble()){
universe += VexRiscvUniverse.NO_WRITEBACK
} else {
universe += VexRiscvUniverse.NO_WRITEBACK
universe += VexRiscvUniverse.NO_MEMORY
}
}
do{
positions = dimensions.map(d => d.randomPosition(universe.toList, rand))
@ -611,7 +644,7 @@ class TestIndividualFeatures extends FunSuite {
val testSeed = rand.nextInt()
if(testId.isEmpty || testId.get.contains(i))
doTest(positions," random_" + i + "_", testSeed)
doTest(positions," random_" + i + "_", testSeed, universe)
Hack.dCounter += 1
}