diff --git a/src/main/scala/SpinalRiscv/Pipeline.scala b/src/main/scala/SpinalRiscv/Pipeline.scala index 8ee3be8..ec4db4c 100644 --- a/src/main/scala/SpinalRiscv/Pipeline.scala +++ b/src/main/scala/SpinalRiscv/Pipeline.scala @@ -99,7 +99,8 @@ trait Pipeline { //Arbitration for(stageIndex <- 0 until stages.length; stage = stages(stageIndex)){ - stage.arbitration.isStuck := stages.takeRight(stages.length - stageIndex).map(_.arbitration.haltIt).reduce(_ || _) + stage.arbitration.isStuckByOthers := stages.takeRight(stages.length - stageIndex - 1).map(_.arbitration.haltIt).foldLeft(False)(_ || _) + stage.arbitration.isStuck := stage.arbitration.haltIt || stage.arbitration.isStuckByOthers stage.arbitration.isFiring := stage.arbitration.isValid && !stage.arbitration.isStuck && !stage.arbitration.removeIt } diff --git a/src/main/scala/SpinalRiscv/Stage.scala b/src/main/scala/SpinalRiscv/Stage.scala index 3b2c547..7468b59 100644 --- a/src/main/scala/SpinalRiscv/Stage.scala +++ b/src/main/scala/SpinalRiscv/Stage.scala @@ -49,6 +49,7 @@ class Stage() extends Area{ val removeIt = False val isValid = RegInit(False) val isStuck = Bool + val isStuckByOthers = Bool val isFiring = Bool } diff --git a/src/main/scala/SpinalRiscv/TopLevel.scala b/src/main/scala/SpinalRiscv/TopLevel.scala index 4b2d879..cb9eb8b 100644 --- a/src/main/scala/SpinalRiscv/TopLevel.scala +++ b/src/main/scala/SpinalRiscv/TopLevel.scala @@ -391,7 +391,7 @@ class PcManagerSimplePlugin(resetVector : BigInt,fastFetchCmdPcCalculation : Boo //PC calculation without Jump val pc = Reg(UInt(pcWidth bits)) init(resetVector) addAttribute("verilator public") - when(arbitration.isValid && !arbitration.isStuck){ + when(arbitration.isFiring){ val pcPlus4 = pc + 4 if(fastFetchCmdPcCalculation) pcPlus4.addAttribute("keep") //Disallow to use the carry in as enable pc := pcPlus4 @@ -410,7 +410,6 @@ class PcManagerSimplePlugin(resetVector : BigInt,fastFetchCmdPcCalculation : Boo //Register managments when(pcLoad.valid) { pc := pcLoad.payload - arbitration.removeIt := True } } @@ -438,8 +437,9 @@ class IBusSimplePlugin(interfaceKeepData : Boolean) extends Plugin[VexRiscv]{ require(interfaceKeepData) iCmd = master(Stream(IBusSimpleCmd())).setName("iCmd") - iCmd.valid := prefetch.arbitration.isFiring + iCmd.valid := prefetch.arbitration.isValid && !prefetch.arbitration.isStuckByOthers iCmd.pc := prefetch.output(PC) + prefetch.arbitration.haltIt setWhen(!iCmd.ready) iRsp = in(IBusSimpleRsp()).setName("iRsp") fetch.insert(INSTRUCTION) := iRsp.inst @@ -520,7 +520,7 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{ import execute._ dCmd = master(Stream(DBusSimpleCmd())).setName("dCmd") - dCmd.valid := input(MEMORY_ENABLE) && arbitration.isFiring + dCmd.valid := arbitration.isValid && input(MEMORY_ENABLE) && !arbitration.isStuckByOthers dCmd.wr := input(INSTRUCTION)(5) dCmd.address := input(SRC_ADD_SUB).asUInt dCmd.size := input(INSTRUCTION)(13 downto 12).asUInt @@ -529,7 +529,7 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{ U(1) -> input(REG2)(15 downto 0) ## input(REG2)(15 downto 0), default -> input(REG2)(31 downto 0) ) - when(input(MEMORY_ENABLE) && !dCmd.ready){ + when(arbitration.isValid && input(MEMORY_ENABLE) && !dCmd.ready){ arbitration.haltIt := True } @@ -547,7 +547,7 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{ writeBack plug new Area { import writeBack._ -// val rspShifted = input(MEMORY_READ_DATA) //TODO uncoment it (combloop) + val rspShifted = MEMORY_READ_DATA() rspShifted := input(MEMORY_READ_DATA) switch(input(MEMORY_ADDRESS_LOW)){ diff --git a/src/test/cpp/testA/main.cpp b/src/test/cpp/testA/main.cpp index f3a86e2..6a63a0d 100644 --- a/src/test/cpp/testA/main.cpp +++ b/src/test/cpp/testA/main.cpp @@ -99,15 +99,6 @@ void loadHexImpl(string path,Memory* mem) { } -#define testA1ReagFileWriteRef {1,10},{2,20},{3,40},{4,60} -#define testA2ReagFileWriteRef {5,1},{7,3} -uint32_t regFileWriteRefIndex = 0; -uint32_t regFileWriteRefArray[][2] = { - testA1ReagFileWriteRef, - testA1ReagFileWriteRef, - testA2ReagFileWriteRef, - testA2ReagFileWriteRef -}; #define TEXTIFY(A) #A @@ -118,6 +109,8 @@ uint32_t regFileWriteRefArray[][2] = { class success : public std::exception { }; +uint32_t testsCounter = 0, successCounter = 0; + class Workspace{ public: static uint32_t cycles; @@ -127,6 +120,7 @@ public: int i; Workspace(string name){ + testsCounter++; this->name = name; top = new VVexRiscv; } @@ -175,7 +169,8 @@ public: uint32_t iRsp_inst_next = top->iRsp_inst; uint32_t dRsp_inst_next = VL_RANDOM_I(32); - if (top->iCmd_valid) { + + if (top->iCmd_valid && top->iCmd_ready) { assertEq(top->iCmd_payload_pc & 3,0); //printf("%d\n",top->iCmd_payload_pc); @@ -185,7 +180,7 @@ public: | (mem[top->iCmd_payload_pc + 3] << 24); } - if (top->dCmd_valid) { + if (top->dCmd_valid && top->dCmd_ready) { // assertEq(top->iCmd_payload_pc & 3,0); //printf("%d\n",top->iCmd_payload_pc); @@ -214,9 +209,14 @@ public: top->clk = !top->clk; top->eval(); + if(top->clk == 0){ + top->iCmd_ready = VL_RANDOM_I(1); + top->dCmd_ready = VL_RANDOM_I(1); + } } cycles += 1; + top->iRsp_inst = iRsp_inst_next; top->dRsp_data = dRsp_inst_next; @@ -227,6 +227,7 @@ public: fail(); } catch (const success e) { cout <<"SUCCESS " << name << endl; + successCounter++; } catch (const std::exception& e) { cout << "FAIL " << name << endl; } @@ -241,8 +242,21 @@ public: }; uint32_t Workspace::cycles = 0; +#define testA1ReagFileWriteRef {1,10},{2,20},{3,40},{4,60} +#define testA2ReagFileWriteRef {5,1},{7,3} +uint32_t regFileWriteRefArray[][2] = { + testA1ReagFileWriteRef, + testA1ReagFileWriteRef, + testA2ReagFileWriteRef, + testA2ReagFileWriteRef +}; + class TestA : public Workspace{ public: + + + uint32_t regFileWriteRefIndex = 0; + TestA() : Workspace("testA") { loadHex("../../resources/hex/testA.hex"); } @@ -354,7 +368,7 @@ struct timespec timer_start(){ long timer_end(struct timespec start_time){ struct timespec end_time; clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_time); - long diffInNanos = end_time.tv_nsec - start_time.tv_nsec; + uint64_t diffInNanos = end_time.tv_sec*1e9 + end_time.tv_nsec - start_time.tv_sec*1e9 - start_time.tv_nsec; return diffInNanos; } @@ -364,17 +378,23 @@ int main(int argc, char **argv, char **env) { printf("BOOT\n"); timespec startedAt = timer_start(); - TestA().run(); - - for(const string &name : riscvTestMain){ - RiscvTest(name).run(); - } - for(const string &name : riscvTestMemory){ - RiscvTest(name).run(); + for(int idx = 0;idx < 2;idx++){ + TestA().run(); + for(const string &name : riscvTestMain){ + RiscvTest(name).run(); + } + for(const string &name : riscvTestMemory){ + RiscvTest(name).run(); + } } - long duration = timer_end(startedAt); + uint64_t duration = timer_end(startedAt); cout << "Had simulate " << Workspace::cycles << " clock cycles in " << duration*1e-9 << " s (" << Workspace::cycles / (duration*1e-9) << " Khz)" << endl; - printf("exit\n"); + if(successCounter == testsCounter) + cout << "Success " << successCounter << "/" << testsCounter << endl; + else + cout << "Failure " << testsCounter - successCounter << "/" << testsCounter << endl; + + exit(0); } diff --git a/src/test/cpp/testA/makefile b/src/test/cpp/testA/makefile index 2d23295..6f3f15f 100644 --- a/src/test/cpp/testA/makefile +++ b/src/test/cpp/testA/makefile @@ -2,7 +2,7 @@ run: compile ./obj_dir/VVexRiscv verilate: - verilator -cc ../../../../VexRiscv.v -O3 -CFLAGS -std=c++11 --gdbbt --trace -Wno-WIDTH --x-assign unique --exe main.cpp + verilator -cc ../../../../VexRiscv.v -O3 -CFLAGS -std=c++11 --gdbbt --trace -Wno-WIDTH --x-assign unique --exe main.cpp compile: verilate make -j -C obj_dir/ -f VVexRiscv.mk VVexRiscv