diff --git a/src/main/scala/SpinalRiscv/TopLevel.scala b/src/main/scala/SpinalRiscv/TopLevel.scala index 5adf5c3..30dff4c 100644 --- a/src/main/scala/SpinalRiscv/TopLevel.scala +++ b/src/main/scala/SpinalRiscv/TopLevel.scala @@ -114,8 +114,6 @@ case class VexRiscvConfig(pcWidth : Int){ object REGFILE_WRITE_VALID extends Stageable(Bool) object REGFILE_WRITE_DATA extends Stageable(Bits(32 bits)) - val SRC1_USE = REG1_USE - val SRC2_USE = REG2_USE object SRC1 extends Stageable(Bits(32 bits)) object SRC2 extends Stageable(Bits(32 bits)) object SRC_ADD_SUB extends Stageable(Bits(32 bits)) @@ -144,6 +142,11 @@ class VexRiscv(val config : VexRiscvConfig) extends Component with Pipeline{ stages ++= List.fill(6)(new Stage()) val prefetch :: fetch :: decode :: execute :: memory :: writeBack :: Nil = stages.toList plugins ++= config.plugins + + //regression usage + writeBack.input(config.INSTRUCTION) keep() addAttribute("verilator public") + writeBack.input(config.PC) keep() addAttribute("verilator public") + writeBack.arbitration.isValid keep() addAttribute("verilator public") } @@ -232,9 +235,9 @@ class DecoderSimplePlugin extends Plugin[VexRiscv] with DecoderService { val decodedBits = Bits(stageables.foldLeft(0)(_ + _.dataType.getBitsWidth) bits) val defaultBits = cloneOf(decodedBits) + assert(defaultValue == 0) + defaultBits := defaultValue - for(i <- decodedBits.range) - defaultBits(i) := Bool(defaultValue.testBit(i)) val logicOr = for((key, mapping) <- spec) yield Mux[Bits](((input(INSTRUCTION) & key.care) === (key.value & key.care)), B(mapping.value & mapping.care, decodedBits.getWidth bits) , B(0, decodedBits.getWidth bits)) decodedBits := logicOr.foldLeft(defaultBits)(_ | _) @@ -291,8 +294,8 @@ class NoPredictionBranchPlugin extends Plugin[VexRiscv]{ SRC1_CTRL -> Src1CtrlEnum.RS, SRC2_CTRL -> Src2CtrlEnum.RS, SRC_USE_SUB_LESS -> True, - SRC1_USE -> True, - SRC2_USE -> True + REG1_USE -> True, + REG2_USE -> True ) val jActions = List[(Stageable[_ <: BaseType],Any)]( @@ -300,14 +303,13 @@ class NoPredictionBranchPlugin extends Plugin[VexRiscv]{ SRC1_CTRL -> Src1CtrlEnum.FOUR, SRC2_CTRL -> Src2CtrlEnum.PC, SRC_USE_SUB_LESS -> False, - REGFILE_WRITE_VALID -> True, - SRC2_USE -> True + REGFILE_WRITE_VALID -> True ) decoderService.addDefault(BRANCH_CTRL, BranchCtrlEnum.INC) decoderService.add(List( JAL -> (jActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.JAL)), - JALR -> (jActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.JALR)), + JALR -> (jActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.JALR, REG1_USE -> True)), BEQ -> (bActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.B)), BNE -> (bActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.B)), BLT -> (bActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.B, SRC_LESS_UNSIGNED -> False)), @@ -388,7 +390,7 @@ class PcManagerSimplePlugin(resetVector : BigInt,fastFetchCmdPcCalculation : Boo arbitration.isValid := True //PC calculation without Jump - val pc = Reg(UInt(pcWidth bits)) init(resetVector) + val pc = Reg(UInt(pcWidth bits)) init(resetVector) addAttribute("verilator public") when(arbitration.isValid && !arbitration.isStuck){ val pcPlus4 = pc + 4 if(fastFetchCmdPcCalculation) pcPlus4.addAttribute("keep") //Disallow to use the carry in as enable @@ -480,7 +482,7 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{ BYPASSABLE_EXECUTE_STAGE -> True, BYPASSABLE_MEMORY_STAGE -> True, MEMORY_ENABLE -> True, - SRC1_USE -> True + REG1_USE -> True ) decoderService.addDefault(MEMORY_ENABLE, False) @@ -491,9 +493,9 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{ LBU -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMI, REGFILE_WRITE_VALID -> True)), LHU -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMI, REGFILE_WRITE_VALID -> True)), LWU -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMI, REGFILE_WRITE_VALID -> True)), - SB -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMS, SRC2_USE -> True)), - SH -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMS, SRC2_USE -> True)), - SW -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMS, SRC2_USE -> True)) + SB -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMS, REG2_USE -> True)), + SH -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMS, REG2_USE -> True)), + SW -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMS, REG2_USE -> True)) )) } @@ -646,7 +648,7 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind) extends Plugin[VexRiscv] import pipeline.config._ val global = pipeline plug new Area{ - val regFile = Mem(Bits(32 bits),32) + val regFile = Mem(Bits(32 bits),32) addAttribute("verilator public") } decode plug new Area{ @@ -745,7 +747,7 @@ class IntAluPlugin extends Plugin[VexRiscv]{ REGFILE_WRITE_VALID -> True, BYPASSABLE_EXECUTE_STAGE -> True, BYPASSABLE_MEMORY_STAGE -> True, - SRC1_USE -> True + REG1_USE -> True ) val nonImmediateActions = List[(Stageable[_ <: BaseType],Any)]( @@ -755,11 +757,11 @@ class IntAluPlugin extends Plugin[VexRiscv]{ REGFILE_WRITE_VALID -> True, BYPASSABLE_EXECUTE_STAGE -> True, BYPASSABLE_MEMORY_STAGE -> True, - SRC1_USE -> True, - SRC2_USE -> True + REG1_USE -> True, + REG2_USE -> True ) - val otherAction = List( + val otherAction = List[(Stageable[_ <: BaseType],Any)]( LEGAL_INSTRUCTION -> True, REGFILE_WRITE_VALID -> True, BYPASSABLE_EXECUTE_STAGE -> True, @@ -790,7 +792,7 @@ class IntAluPlugin extends Plugin[VexRiscv]{ )) decoderService.add(List( - LUI -> (otherAction ++ List(ALU_CTRL -> AluCtrlEnum.SRC1)), + LUI -> (otherAction ++ List(ALU_CTRL -> AluCtrlEnum.SRC1, SRC1_CTRL -> Src1CtrlEnum.IMU)), AUIPC -> (otherAction ++ List(ALU_CTRL -> AluCtrlEnum.ADD_SUB, SRC_USE_SUB_LESS -> False, SRC1_CTRL -> Src1CtrlEnum.IMU, SRC2_CTRL -> Src2CtrlEnum.PC)) )) } @@ -837,7 +839,8 @@ class FullBarrielShifterPlugin extends Plugin[VexRiscv]{ SRC2_CTRL -> Src2CtrlEnum.IMI, REGFILE_WRITE_VALID -> True, BYPASSABLE_EXECUTE_STAGE -> False, - BYPASSABLE_MEMORY_STAGE -> True + BYPASSABLE_MEMORY_STAGE -> True, + REG1_USE -> True ) val nonImmediateActions = List[(Stageable[_ <: BaseType],Any)]( @@ -846,7 +849,9 @@ class FullBarrielShifterPlugin extends Plugin[VexRiscv]{ SRC2_CTRL -> Src2CtrlEnum.RS, REGFILE_WRITE_VALID -> True, BYPASSABLE_EXECUTE_STAGE -> False, - BYPASSABLE_MEMORY_STAGE -> True + BYPASSABLE_MEMORY_STAGE -> True, + REG1_USE -> True, + REG2_USE -> True ) val decoderService = pipeline.service(classOf[DecoderService]) @@ -900,7 +905,7 @@ object TopLevel { ) config.plugins ++= List( - new PcManagerSimplePlugin(0, true), + new PcManagerSimplePlugin(0, false), new IBusSimplePlugin, new DecoderSimplePlugin, new RegFilePlugin(SYNC), @@ -915,6 +920,8 @@ object TopLevel { val toplevel = new VexRiscv(config) + + // toplevel.service(classOf[DecoderSimplePlugin]).bench(toplevel) diff --git a/src/test/cpp/testA/main.cpp b/src/test/cpp/testA/main.cpp index 98ff6d1..d0191be 100644 --- a/src/test/cpp/testA/main.cpp +++ b/src/test/cpp/testA/main.cpp @@ -9,7 +9,32 @@ #include #include -uint8_t memory[1024 * 1024]; +class Memory{ +public: + uint8_t* mem[1 << 12]; + + Memory(){ + for(uint32_t i = 0;i < (1 << 12);i++) mem[i] = NULL; + } + ~Memory(){ + for(uint32_t i = 0;i < (1 << 12);i++) if(mem[i]) delete mem[i]; + } + + uint8_t* get(uint32_t address){ + if(mem[address >> 20] == NULL) mem[address >> 20] = new uint8_t[1024*1024]; + return &mem[address >> 20][address & 0xFFFFF]; + } + + uint8_t& operator [](uint32_t address) { + return *get(address); + } + + /*T operator [](uint32_t address) const { + return get(address); + }*/ +}; + +//uint8_t memory[1024 * 1024]; uint32_t hti(char c) { if (c >= 'A' && c <= 'F') @@ -27,7 +52,7 @@ uint32_t hToI(char *c, uint32_t size) { return value; } -void loadHexImpl(string path) { +void loadHexImpl(string path,Memory* mem) { FILE *fp = fopen(&path[0], "r"); fseek(fp, 0, SEEK_END); uint32_t size = ftell(fp); @@ -46,7 +71,7 @@ void loadHexImpl(string path) { switch (key) { case 0: for (uint32_t i = 0; i < byteCount; i++) { - memory[nextAddr + i] = hToI(line + 9 + i * 2, 2); + *(mem->get(nextAddr + i)) = hToI(line + 9 + i * 2, 2); //printf("%x %x %c%c\n",nextAddr + i,hToI(line + 9 + i*2,2),line[9 + i * 2],line[9 + i * 2+1]); } break; @@ -88,7 +113,6 @@ uint32_t regFileWriteRefArray[][2] = { #define assertEq(x,ref) if(x != ref) {\ printf("\n*** %s is %d but should be %d ***\n\n",TEXTIFY(x),x,ref);\ - error = 1; \ throw std::exception();\ } @@ -97,14 +121,12 @@ class success : public std::exception { }; class Workspace{ public: - + Memory mem; string name; VVexRiscv* top; int i; - int error; Workspace(string name){ - error = 0; this->name = name; top = new VVexRiscv; } @@ -114,15 +136,17 @@ public: } Workspace* loadHex(string path){ - loadHexImpl(path); + loadHexImpl(path,&mem); return this; } + virtual void postReset() {} virtual void checks(){} void pass(){ throw success();} + void fail(){ throw std::exception();} - Workspace* run(uint32_t timeout = 1000){ - cout << "Start " << name << endl; + Workspace* run(uint32_t timeout = 5000){ +// cout << "Start " << name << endl; // init trace dump Verilated::traceEverOn(true); @@ -142,6 +166,7 @@ public: top->reset = 0; top->eval(); + postReset(); try { // run simulation for 100 clock periods @@ -151,8 +176,11 @@ public: if (top->iCmd_valid) { assertEq(top->iCmd_payload_pc & 3,0); //printf("%d\n",top->iCmd_payload_pc); - uint8_t* ptr = memory + top->iCmd_payload_pc; - iRsp_inst_next = (ptr[0] << 0) | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24); + + iRsp_inst_next = (mem[top->iCmd_payload_pc + 0] << 0) + | (mem[top->iCmd_payload_pc + 1] << 8) + | (mem[top->iCmd_payload_pc + 2] << 16) + | (mem[top->iCmd_payload_pc + 3] << 24); } checks(); @@ -172,10 +200,12 @@ public: if (Verilated::gotFinish()) exit(0); } + cout << "timeout" << endl; + fail(); } catch (const success e) { - printf("SUCCESS\n"); + cout <<"SUCCESS " << name << endl; } catch (const std::exception& e) { - std::cout << e.what(); + cout << "FAIL " << name << endl; } @@ -213,53 +243,68 @@ public: loadHex("../../resources/hex/" + name + ".hex"); } - virtual void checks(){ + virtual void postReset() { + top->VexRiscv->prefetch_PcManagerSimplePlugin_pc = 0x800000bcu; + } + virtual void checks(){ + if(top->VexRiscv->writeBack_arbitration_isValid == 1 && top->VexRiscv->writeBack_input_INSTRUCTION == 0x00000073){ + uint32_t code = top->VexRiscv->RegFilePlugin_regFile[28]; + if((code & 1) == 0){ + cout << "Wrong error code"<< endl; + fail(); + } + if(code == 1){ + pass(); + }else{ + cout << "Error code " << code/2 << endl; + fail(); + } + } } }; string riscvTestMain[] = { - "rv32ui-p-add.hex", - "rv32ui-p-addi.hex", - "rv32ui-p-and.hex", - "rv32ui-p-andi.hex", - "rv32ui-p-auipc.hex", - "rv32ui-p-beq.hex", - "rv32ui-p-bge.hex", - "rv32ui-p-bgeu.hex", - "rv32ui-p-blt.hex", - "rv32ui-p-bltu.hex", - "rv32ui-p-bne.hex", - "rv32ui-p-j.hex", - "rv32ui-p-jal.hex", - "rv32ui-p-jalr.hex", - "rv32ui-p-or.hex", - "rv32ui-p-ori.hex", - "rv32ui-p-simple.hex", - "rv32ui-p-sll.hex", - "rv32ui-p-slli.hex", - "rv32ui-p-slt.hex", - "rv32ui-p-slti.hex", - "rv32ui-p-sra.hex", - "rv32ui-p-srai.hex", - "rv32ui-p-srl.hex", - "rv32ui-p-srli.hex", - "rv32ui-p-sub.hex", - "rv32ui-p-xor.hex", - "rv32ui-p-xori.hex" + "rv32ui-p-simple", + "rv32ui-p-lui", + "rv32ui-p-auipc", + "rv32ui-p-jal", + "rv32ui-p-jalr", + "rv32ui-p-beq", + "rv32ui-p-bge", + "rv32ui-p-bgeu", + "rv32ui-p-blt", + "rv32ui-p-bltu", + "rv32ui-p-bne", + "rv32ui-p-add", + "rv32ui-p-addi", + "rv32ui-p-and", + "rv32ui-p-andi", + "rv32ui-p-or", + "rv32ui-p-ori", + "rv32ui-p-sll", + "rv32ui-p-slli", + "rv32ui-p-slt", + "rv32ui-p-slti", + "rv32ui-p-sra", + "rv32ui-p-srai", + "rv32ui-p-srl", + "rv32ui-p-srli", + "rv32ui-p-sub", + "rv32ui-p-xor", + "rv32ui-p-xori" }; string riscvTestMemory[] = { - "rv32ui-p-lb.hex", - "rv32ui-p-lbu.hex", - "rv32ui-p-lh.hex", - "rv32ui-p-lhu.hex", - "rv32ui-p-lui.hex", - "rv32ui-p-lw.hex", - "rv32ui-p-sb.hex", - "rv32ui-p-sh.hex", - "rv32ui-p-sw.hex" + "rv32ui-p-lb", + "rv32ui-p-lbu", + "rv32ui-p-lh", + "rv32ui-p-lhu", + "rv32ui-p-lw", + "rv32ui-p-sb", + "rv32ui-p-sh", + "rv32ui-p-sw" }; diff --git a/src/test/cpp/testA/yolo.gtkw b/src/test/cpp/testA/yolo.gtkw index 9c921cf..57d6d07 100644 --- a/src/test/cpp/testA/yolo.gtkw +++ b/src/test/cpp/testA/yolo.gtkw @@ -1,57 +1,39 @@ [*] [*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI -[*] Sun Mar 12 18:21:04 2017 +[*] Tue Mar 14 18:15:03 2017 [*] -[dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/sim.vcd" -[dumpfile_mtime] "Sun Mar 12 18:18:56 2017" -[dumpfile_size] 105148 +[dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/rv32ui-p-jalr.vcd" +[dumpfile_mtime] "Tue Mar 14 18:13:30 2017" +[dumpfile_size] 7129488 [savefile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/yolo.gtkw" -[timestart] 156 +[timestart] 0 [size] 1776 953 -[pos] -1 -1 -*-4.022038 200 -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 +[pos] -1 -353 +*-4.722985 26 -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. -[sst_width] 487 +[sst_width] 418 [signals_width] 559 [sst_expanded] 1 [sst_vpaned_height] 279 @28 -TOP.VexRiscv.decode_BRANCH_CTRL[1:0] -TOP.VexRiscv.execute_BRANCH_SOLVED[1:0] -TOP.VexRiscv.execute_input_BRANCH_CTRL[1:0] -TOP.VexRiscv.execute_input_BRANCH_SOLVED[1:0] -TOP.VexRiscv.decode_arbitration_isValid -TOP.VexRiscv.decode_arbitration_isStuck +TOP.clk +TOP.iCmd_valid @22 -TOP.VexRiscv.decode_input_INSTRUCTION[31:0] -TOP.VexRiscv.decode_input_PC[31:0] -TOP.VexRiscv.iCmd_payload_pc[31:0] +TOP.iCmd_payload_pc[31:0] @28 -TOP.VexRiscv.iCmd_ready -TOP.VexRiscv.iCmd_valid +TOP.iCmd_ready @22 -TOP.VexRiscv.iRsp_inst[31:0] -TOP.VexRiscv.prefetch_PcManagerSimplePlugin_jump_pcLoad_payload[31:0] +TOP.iRsp_inst[31:0] @28 -TOP.VexRiscv.prefetch_PcManagerSimplePlugin_jump_pcLoad_valid -TOP.VexRiscv.prefetch_arbitration_isValid -TOP.VexRiscv.fetch_arbitration_isValid -TOP.VexRiscv.decode_arbitration_isValid -TOP.VexRiscv.execute_arbitration_isValid -TOP.VexRiscv.memory_arbitration_isValid -TOP.VexRiscv.writeBack_arbitration_isValid -TOP.VexRiscv.prefetch_arbitration_removeIt -TOP.VexRiscv.fetch_arbitration_removeIt -TOP.VexRiscv.decode_arbitration_removeIt -TOP.VexRiscv.execute_arbitration_removeIt -TOP.VexRiscv.memory_arbitration_removeIt -TOP.VexRiscv.writeBack_arbitration_removeIt +TOP.reset @29 +TOP.VexRiscv.writeBack_arbitration_isValid +@22 +TOP.VexRiscv.writeBack_input_PC[31:0] +@28 TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_valid @22 TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_payload_address[4:0] TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_payload_data[31:0] -@28 -TOP.VexRiscv.clk [pattern_trace] 1 [pattern_trace] 0