diff --git a/src/main/scala/SpinalRiscv/TopLevel.scala b/src/main/scala/SpinalRiscv/TopLevel.scala index 30dff4c..4b2d879 100644 --- a/src/main/scala/SpinalRiscv/TopLevel.scala +++ b/src/main/scala/SpinalRiscv/TopLevel.scala @@ -428,7 +428,7 @@ case class IBusSimpleRsp() extends Bundle{ val inst = Bits(32 bits) } -class IBusSimplePlugin extends Plugin[VexRiscv]{ +class IBusSimplePlugin(interfaceKeepData : Boolean) extends Plugin[VexRiscv]{ var iCmd : Stream[IBusSimpleCmd] = null var iRsp : IBusSimpleRsp = null @@ -436,6 +436,7 @@ class IBusSimplePlugin extends Plugin[VexRiscv]{ import pipeline._ import pipeline.config._ + require(interfaceKeepData) iCmd = master(Stream(IBusSimpleCmd())).setName("iCmd") iCmd.valid := prefetch.arbitration.isFiring iCmd.pc := prefetch.output(PC) @@ -468,6 +469,7 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{ object MEMORY_ENABLE extends Stageable(Bool) object MEMORY_CTRL extends Stageable(MemoryCtrlEnum()) object MEMORY_READ_DATA extends Stageable(Bits(32 bits)) + object MEMORY_ADDRESS_LOW extends Stageable(UInt(2 bits)) override def setup(pipeline: VexRiscv): Unit = { import pipeline.config._ @@ -479,23 +481,33 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{ LEGAL_INSTRUCTION -> True, SRC1_CTRL -> Src1CtrlEnum.RS, SRC_USE_SUB_LESS -> False, - BYPASSABLE_EXECUTE_STAGE -> True, - BYPASSABLE_MEMORY_STAGE -> True, MEMORY_ENABLE -> True, REG1_USE -> True ) + val loadActions = stdActions ++ List( + SRC2_CTRL -> Src2CtrlEnum.IMI, + REGFILE_WRITE_VALID -> True, + BYPASSABLE_EXECUTE_STAGE -> False, + BYPASSABLE_MEMORY_STAGE -> False + ) + + val storeActions = stdActions ++ List( + SRC2_CTRL -> Src2CtrlEnum.IMS, + REG2_USE -> True + ) + decoderService.addDefault(MEMORY_ENABLE, False) decoderService.add(List( - LB -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMI, REGFILE_WRITE_VALID -> True)), - LH -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMI, REGFILE_WRITE_VALID -> True)), - LW -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMI, REGFILE_WRITE_VALID -> True)), - 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, REG2_USE -> True)), - SH -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMS, REG2_USE -> True)), - SW -> (stdActions ++ List(SRC2_CTRL -> Src2CtrlEnum.IMS, REG2_USE -> True)) + LB -> (loadActions), + LH -> (loadActions), + LW -> (loadActions), + LBU -> (loadActions), + LHU -> (loadActions), + LWU -> (loadActions), + SB -> (storeActions), + SH -> (storeActions), + SW -> (storeActions) )) } @@ -511,13 +523,17 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{ dCmd.valid := input(MEMORY_ENABLE) && arbitration.isFiring dCmd.wr := input(INSTRUCTION)(5) dCmd.address := input(SRC_ADD_SUB).asUInt - dCmd.payload.data := input(SRC2) dCmd.size := input(INSTRUCTION)(13 downto 12).asUInt + dCmd.payload.data := dCmd.size.mux ( + U(0) -> input(REG2)(7 downto 0) ## input(REG2)(7 downto 0) ## input(REG2)(7 downto 0) ## input(REG2)(7 downto 0), + U(1) -> input(REG2)(15 downto 0) ## input(REG2)(15 downto 0), + default -> input(REG2)(31 downto 0) + ) when(input(MEMORY_ENABLE) && !dCmd.ready){ arbitration.haltIt := True } - dCmd.elements + insert(MEMORY_ADDRESS_LOW) := dCmd.address(1 downto 0) } memory plug new Area { @@ -529,12 +545,21 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{ } writeBack plug new Area { - import memory._ + 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)){ + is(1){rspShifted(7 downto 0) := input(MEMORY_READ_DATA)(15 downto 8)} + is(2){rspShifted(15 downto 0) := input(MEMORY_READ_DATA)(31 downto 16)} + is(3){rspShifted(7 downto 0) := input(MEMORY_READ_DATA)(31 downto 24)} + } val rspFormated = input(INSTRUCTION)(13 downto 12).mux( - default -> input(MEMORY_READ_DATA), //W - 1 -> B((31 downto 8) -> (input(MEMORY_READ_DATA)(7) && !input(INSTRUCTION)(14)),(7 downto 0) -> input(MEMORY_READ_DATA)(7 downto 0)), - 2 -> B((31 downto 16) -> (input(MEMORY_READ_DATA)(15) && ! input(INSTRUCTION)(14)),(15 downto 0) -> input(MEMORY_READ_DATA)(15 downto 0)) + 0 -> B((31 downto 8) -> (rspShifted(7) && !input(INSTRUCTION)(14)),(7 downto 0) -> rspShifted(7 downto 0)), + 1 -> B((31 downto 16) -> (rspShifted(15) && ! input(INSTRUCTION)(14)),(15 downto 0) -> rspShifted(15 downto 0)), + default -> rspShifted //W ) when(input(MEMORY_ENABLE)) { @@ -906,7 +931,7 @@ object TopLevel { config.plugins ++= List( new PcManagerSimplePlugin(0, false), - new IBusSimplePlugin, + new IBusSimplePlugin(true), new DecoderSimplePlugin, new RegFilePlugin(SYNC), new IntAluPlugin, diff --git a/src/test/cpp/testA/main.cpp b/src/test/cpp/testA/main.cpp index d0191be..f5eea13 100644 --- a/src/test/cpp/testA/main.cpp +++ b/src/test/cpp/testA/main.cpp @@ -173,6 +173,8 @@ public: for (i = 16; i < timeout*2; i+=2) { uint32_t iRsp_inst_next = top->iRsp_inst; + uint32_t dRsp_inst_next = VL_RANDOM_I(32); + if (top->iCmd_valid) { assertEq(top->iCmd_payload_pc & 3,0); //printf("%d\n",top->iCmd_payload_pc); @@ -183,6 +185,25 @@ public: | (mem[top->iCmd_payload_pc + 3] << 24); } + if (top->dCmd_valid) { +// assertEq(top->iCmd_payload_pc & 3,0); + //printf("%d\n",top->iCmd_payload_pc); + + uint32_t addr = top->dCmd_payload_address; + if(top->dCmd_payload_wr){ + for(uint32_t b = 0;b < (1 << top->dCmd_payload_size);b++){ + uint32_t offset = (addr+b)&0x3; + *mem.get(addr + b) = top->dCmd_payload_data >> (offset*8); + } + }else{ + for(uint32_t b = 0;b < (1 << top->dCmd_payload_size);b++){ + uint32_t offset = (addr+b)&0x3; + dRsp_inst_next &= ~(0xFF << (offset*8)); + dRsp_inst_next |= mem[addr + b] << (offset*8); + } + } + } + checks(); @@ -196,6 +217,7 @@ public: } top->iRsp_inst = iRsp_inst_next; + top->dRsp_data = dRsp_inst_next; if (Verilated::gotFinish()) exit(0); @@ -328,7 +350,9 @@ int main(int argc, char **argv, char **env) { for(const string &name : riscvTestMain){ RiscvTest(name).run(); } - + for(const string &name : riscvTestMemory){ + RiscvTest(name).run(); + } printf("exit\n"); exit(0); } diff --git a/src/test/cpp/testA/yolo.gtkw b/src/test/cpp/testA/yolo.gtkw index 57d6d07..66b5bbc 100644 --- a/src/test/cpp/testA/yolo.gtkw +++ b/src/test/cpp/testA/yolo.gtkw @@ -1,15 +1,15 @@ [*] [*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI -[*] Tue Mar 14 18:15:03 2017 +[*] Tue Mar 14 21:27:40 2017 [*] -[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 +[dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/rv32ui-p-lw.vcd" +[dumpfile_mtime] "Tue Mar 14 21:24:45 2017" +[dumpfile_size] 1017741 [savefile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/yolo.gtkw" -[timestart] 0 +[timestart] 41 [size] 1776 953 -[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 +[pos] -1 -1 +*-1.801840 49 -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] 418 [signals_width] 559 @@ -17,6 +17,26 @@ [sst_vpaned_height] 279 @28 TOP.clk +TOP.dCmd_valid +TOP.dCmd_ready +TOP.dCmd_payload_wr +@22 +TOP.dCmd_payload_address[31:0] +TOP.dCmd_payload_data[31:0] +@28 +TOP.dCmd_payload_size[1:0] +@23 +TOP.dRsp_data[31:0] +@22 +TOP.iCmd_payload_pc[31:0] +@28 +TOP.iCmd_ready +TOP.iCmd_valid +@22 +TOP.iRsp_inst[31:0] +@28 +TOP.reset +TOP.clk TOP.iCmd_valid @22 TOP.iCmd_payload_pc[31:0] @@ -26,14 +46,39 @@ TOP.iCmd_ready TOP.iRsp_inst[31:0] @28 TOP.reset -@29 TOP.VexRiscv.writeBack_arbitration_isValid @22 +TOP.VexRiscv.writeBack_input_INSTRUCTION[31:0] 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.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_isStuck +TOP.VexRiscv.fetch_arbitration_isStuck +TOP.VexRiscv.decode_arbitration_isStuck +TOP.VexRiscv.execute_arbitration_isStuck +TOP.VexRiscv.memory_arbitration_isStuck +TOP.VexRiscv.writeBack_arbitration_isStuck +@22 +TOP.VexRiscv.prefetch_input_PC[31:0] +TOP.VexRiscv.fetch_input_PC[31:0] +TOP.VexRiscv.decode_input_PC[31:0] +TOP.VexRiscv.execute_input_PC[31:0] +TOP.VexRiscv.memory_input_PC[31:0] +TOP.VexRiscv.writeBack_input_PC[31:0] +TOP.VexRiscv.fetch_input_INSTRUCTION[31:0] +TOP.VexRiscv.decode_input_INSTRUCTION[31:0] +TOP.VexRiscv.execute_input_INSTRUCTION[31:0] +TOP.VexRiscv.memory_input_INSTRUCTION[31:0] +TOP.VexRiscv.writeBack_input_INSTRUCTION[31:0] [pattern_trace] 1 [pattern_trace] 0