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]]() 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) = def inputInit[T <: BaseType](stageable : Stageable[T],initValue : T) =
Component.current.addPrePopTask(() => inputsDefault(stageable.asInstanceOf[Stageable[Data]]).asInstanceOf[T].getDrivingReg.init(initValue)) 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 plugins ++= config.plugins
//regression usage //regression usage
decode.input(config.INSTRUCTION).addAttribute(Verilator.public) val lastStageInstruction = CombInit(stages.last.input(config.INSTRUCTION)) keep() addAttribute (Verilator.public)
decode.input(config.PC).addAttribute(Verilator.public) val lastStagePc = CombInit(stages.last.input(config.PC)) keep() addAttribute (Verilator.public)
decode.arbitration.isValid.addAttribute(Verilator.public) val lastStageIsValid = CombInit(stages.last.arbitration.isValid) keep() addAttribute (Verilator.public)
decode.arbitration.flushAll.addAttribute(Verilator.public) val lastStageIsFiring = CombInit(stages.last.arbitration.isFiring) keep() addAttribute (Verilator.public)
decode.arbitration.haltItself.addAttribute(Verilator.public)
if(withWriteBackStage) { //Verilator perf
writeBack.input(config.INSTRUCTION) keep() addAttribute (Verilator.public) decode.arbitration.removeIt.noBackendCombMerge
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
if(withMemoryStage){ if(withMemoryStage){
memory.arbitration.removeIt.noBackendCombMerge memory.arbitration.removeIt.noBackendCombMerge
} }

View file

@ -329,12 +329,12 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
} }
//Emit dBus.cmd request //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 val cmdStage = if(emitCmdInMemoryStage) memory else execute
cmdStage plug new Area{ cmdStage plug new Area{
import cmdStage._ import cmdStage._
val privilegeService = pipeline.serviceElse(classOf[PrivilegeService], PrivilegeServiceDefault()) 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) 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) 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 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) { if(catchSomething) {
memoryExceptionPort.valid := False memoryExceptionPort.valid := False

View file

@ -91,7 +91,7 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind,
import writeStage._ import writeStage._
def shadowPrefix(that : Bits) = if(withShadow) global.shadow.write ## that else that 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.valid := output(REGFILE_WRITE_VALID) && arbitration.isFiring
regFileWrite.address := U(shadowPrefix(output(INSTRUCTION)(rdRange))) regFileWrite.address := U(shadowPrefix(output(INSTRUCTION)(rdRange)))
regFileWrite.data := output(REGFILE_WRITE_DATA) regFileWrite.data := output(REGFILE_WRITE_DATA)

View file

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

View file

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

View file

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

View file

@ -47,6 +47,9 @@ object VexRiscvUniverse{
val MMU = new VexRiscvUniverse val MMU = new VexRiscvUniverse
val FORCE_MULDIV = new VexRiscvUniverse val FORCE_MULDIV = new VexRiscvUniverse
val SUPERVISOR = 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") { class ShiftDimension extends VexRiscvDimension("Shift") {
override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = random(r, List( override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = {
new VexRiscvPosition("FullLate") { var l = List(
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new FullBarrelShifterPlugin(earlyInjection = false)
},
new VexRiscvPosition("FullEarly") { new VexRiscvPosition("FullEarly") {
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new FullBarrelShifterPlugin(earlyInjection = true) override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new FullBarrelShifterPlugin(earlyInjection = true)
}, },
new VexRiscvPosition("Light") { new VexRiscvPosition("Light") {
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new LightShifterPlugin 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") { class BranchDimension extends VexRiscvDimension("Branch") {
override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = { override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = {
val catchAll = universes.contains(VexRiscvUniverse.CATCH_ALL) 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") { new VexRiscvPosition(if(early) "Early" else "Late") {
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new BranchPlugin( override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new BranchPlugin(
earlyBranch = early, earlyBranch = early,
@ -87,7 +95,51 @@ class BranchDimension extends VexRiscvDimension("Branch") {
class MulDivDimension extends VexRiscvDimension("MulDiv") { class MulDivDimension extends VexRiscvDimension("MulDiv") {
override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = { 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") { new VexRiscvPosition("MulDivFpga") {
override def testParam = "MUL=yes DIV=yes" override def testParam = "MUL=yes DIV=yes"
override def applyOn(config: VexRiscvConfig): Unit = { override def applyOn(config: VexRiscvConfig): Unit = {
@ -99,45 +151,6 @@ class MulDivDimension extends VexRiscvDimension("MulDiv") {
divUnrollFactor = 1 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 } :: l
random(r, l) random(r, l)
@ -149,26 +162,30 @@ trait InstructionAnticipatedPosition{
} }
class RegFileDimension extends VexRiscvDimension("RegFile") { class RegFileDimension extends VexRiscvDimension("RegFile") {
override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = {
override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = random(r, List( val executeRf = universes.contains(VexRiscvUniverse.EXECUTE_RF)
new VexRiscvPosition("Async") { random(r, List(
new VexRiscvPosition("Async" + (if(executeRf) "ER" else "DR")) {
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new RegFilePlugin( override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new RegFilePlugin(
regFileReadyKind = plugin.ASYNC, 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( override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new RegFilePlugin(
regFileReadyKind = plugin.SYNC, 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 p : InstructionAnticipatedPosition => p.instructionAnticipatedOk()
case _ => false case _ => false
} }
} }
)) ))
}
} }
@ -255,7 +272,8 @@ class HazardDimension extends VexRiscvDimension("Hazard") {
class SrcDimension extends VexRiscvDimension("Src") { class SrcDimension extends VexRiscvDimension("Src") {
override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = { 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 "")) { new VexRiscvPosition((if (separatedAddSub) "AddSub" else "") + (if (executeInsertion) "Execute" else "")) {
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new SrcPlugin( override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new SrcPlugin(
separatedAddSub = separatedAddSub, separatedAddSub = separatedAddSub,
@ -353,10 +371,14 @@ class DBusDimension extends VexRiscvDimension("DBus") {
override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = { override def randomPositionImpl(universes: Seq[ConfigUniverse], r: Random) = {
val catchAll = universes.contains(VexRiscvUniverse.CATCH_ALL) val catchAll = universes.contains(VexRiscvUniverse.CATCH_ALL)
val mmuConfig = if(universes.contains(VexRiscvUniverse.MMU)) MmuPortConfig( portTlbSize = 4) else null 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 withLrSc = catchAll
val earlyInjection = r.nextBoolean() val earlyInjection = r.nextBoolean() && !universes.contains(VexRiscvUniverse.NO_WRITEBACK)
new VexRiscvPosition("Simple" + (if(earlyInjection) "Early" else "Late")) { new VexRiscvPosition("Simple" + (if(earlyInjection) "Early" else "Late")) {
override def testParam = "DBUS=SIMPLE " + (if(withLrSc) "LRSC=yes " else "") override def testParam = "DBUS=SIMPLE " + (if(withLrSc) "LRSC=yes " else "")
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new DBusSimplePlugin( override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new DBusSimplePlugin(
@ -540,12 +562,16 @@ class TestIndividualFeatures extends FunSuite {
// val usedPositions = mutable.HashSet[VexRiscvPosition](); // val usedPositions = mutable.HashSet[VexRiscvPosition]();
// val positionsCount = dimensions.map(d => d.positions.length).sum // 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 // usedPositions ++= positionsToApply
val noMemory = universes.contains(VexRiscvUniverse.NO_MEMORY)
val noWriteback = universes.contains(VexRiscvUniverse.NO_WRITEBACK)
def gen = { def gen = {
FileUtils.deleteQuietly(new File("VexRiscv.v")) FileUtils.deleteQuietly(new File("VexRiscv.v"))
SpinalVerilog{ SpinalVerilog{
val config = VexRiscvConfig( val config = VexRiscvConfig(
withMemoryStage = !noMemory,
withWriteBackStage = !noWriteback,
plugins = List( plugins = List(
new IntAluPlugin, new IntAluPlugin,
new YamlPlugin("cpu0.yaml") new YamlPlugin("cpu0.yaml")
@ -555,7 +581,8 @@ class TestIndividualFeatures extends FunSuite {
new VexRiscv(config) 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") { test(prefix + name + "_gen") {
gen gen
} }
@ -564,14 +591,10 @@ class TestIndividualFeatures extends FunSuite {
test(prefix + name + "_test") { test(prefix + name + "_test") {
val debug = true 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 = (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(" ") val testCmd = stdCmd + (positionsToApply).map(_.testParam).mkString(" ")
println(testCmd) println(testCmd)
val str = doCmd(testCmd) val str = doCmd(testCmd)
assert(str.contains("REGRESSION SUCCESS") && !str.contains("Broken pipe")) 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 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(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(0))
// val testId = Some(mutable.HashSet(129, 134)) // val testId = Some(mutable.HashSet(4))
// val seed = -1580866821569084523l // val seed = -8309068850561113754l
val rand = new Random(seed) 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){ for(i <- 0 until sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_COUNT", "100").toInt){
var positions : List[VexRiscvPosition] = null var positions : List[VexRiscvPosition] = null
var universe = mutable.HashSet[VexRiscvUniverse]() 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.CATCH_ALL
universe += VexRiscvUniverse.MMU universe += VexRiscvUniverse.MMU
universe += VexRiscvUniverse.FORCE_MULDIV universe += VexRiscvUniverse.FORCE_MULDIV
universe += VexRiscvUniverse.SUPERVISOR universe += VexRiscvUniverse.SUPERVISOR
} } else {
if(sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_MACHINE_OS_RATE", "0.5").toDouble > Math.random()) { if(sys.env.getOrElse("VEXRISCV_REGRESSION_CONFIG_MACHINE_OS_RATE", "0.5").toDouble > rand.nextDouble()) {
universe += VexRiscvUniverse.CATCH_ALL 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{ do{
positions = dimensions.map(d => d.randomPosition(universe.toList, rand)) positions = dimensions.map(d => d.randomPosition(universe.toList, rand))
@ -611,7 +644,7 @@ class TestIndividualFeatures extends FunSuite {
val testSeed = rand.nextInt() val testSeed = rand.nextInt()
if(testId.isEmpty || testId.get.contains(i)) if(testId.isEmpty || testId.get.contains(i))
doTest(positions," random_" + i + "_", testSeed) doTest(positions," random_" + i + "_", testSeed, universe)
Hack.dCounter += 1 Hack.dCounter += 1
} }