diff --git a/src/asm/jal_jalr.s b/src/asm/jal_jalr.s new file mode 100644 index 0000000..d46e513 --- /dev/null +++ b/src/asm/jal_jalr.s @@ -0,0 +1,46 @@ +jal x1, jump # x01 = 4 + +addi x1, x1, 10 # x1 = 26 (16 + 10) +beq x0, x0, trap # halt + +jump: +jalr x1, x1, 0 # x1 = 16, jump to addi + +trap: + +#TESTASSERTOUTPUT|---------------------------------------| +#TESTASSERTOUTPUT| Register File State :) | +#TESTASSERTOUTPUT|---------------------------------------| +#TESTASSERTOUTPUT| x00, zero = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x01, ra = 0x0000001a ( 26)| +#TESTASSERTOUTPUT| x02, sp = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x03, gp = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x04, tp = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x05, t0 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x06, t1 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x07, t2 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x08, s0 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x09, s1 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x10, a0 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x11, a1 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x12, a2 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x13, a3 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x14, a4 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x15, a5 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x16, a6 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x17, a7 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x18, s2 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x19, s3 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x20, s4 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x21, s5 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x22, s6 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x23, s7 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x24, s8 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x25, s9 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x26, s10 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x27, s11 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x28, t3 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x29, t4 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x30, t5 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x31, t6 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT|---------------------------------------| diff --git a/src/asm/out/beq.memh b/src/asm/out/beq.memh index c91b2ea..2043bb9 100644 --- a/src/asm/out/beq.memh +++ b/src/asm/out/beq.memh @@ -2,4 +2,4 @@ 00000113 // PC=0x4 line=3: addi x2, x0, 0 # x02 = 0 00110113 // PC=0x8 line=5: addi x2, x2, 1 # x02 ++ 00110463 // PC=0xc line=6: beq x2, x1, trap -fe000ce3 // PC=0x10 line=7: beq x0, x0, loop_head_beq +fe000ce3 // PC=0x10 line=7: beq x0, x0, loop_head diff --git a/src/asm/out/blt.memh b/src/asm/out/blt.memh index e93d2db..b4d0003 100644 --- a/src/asm/out/blt.memh +++ b/src/asm/out/blt.memh @@ -1,5 +1,5 @@ 00500093 // PC=0x0 line=1: addi x1, x0, 5 # x01 = 5 00000113 // PC=0x4 line=3: addi x2, x0, 0 # x02 = 0 00110113 // PC=0x8 line=5: addi x2, x2, 1 # x02 ++ -fe114ee3 // PC=0xc line=6: blt x2, x1, loop_head_blt +fe114ee3 // PC=0xc line=6: blt x2, x1, loop_head 00000263 // PC=0x10 line=7: beq x0, x0, trap diff --git a/src/asm/out/bne.memh b/src/asm/out/bne.memh index b3fa05c..c31618f 100644 --- a/src/asm/out/bne.memh +++ b/src/asm/out/bne.memh @@ -1,5 +1,5 @@ 00500093 // PC=0x0 line=1: addi x1, x0, 5 # x01 = 5 00000113 // PC=0x4 line=3: addi x2, x0, 0 # x02 = 0 00110113 // PC=0x8 line=5: addi x2, x2, 1 # x02 ++ -fe111ee3 // PC=0xc line=6: bne x2, x1, loop_head_bneq +fe111ee3 // PC=0xc line=6: bne x2, x1, loop_head 00000263 // PC=0x10 line=7: beq x0, x0, trap diff --git a/src/asm/out/jal.memh b/src/asm/out/jal.memh new file mode 100644 index 0000000..fbe03ad --- /dev/null +++ b/src/asm/out/jal.memh @@ -0,0 +1,4 @@ +00c000ef // PC=0x0 line=1: jal x1, jump # x01 = 4 +00a08093 // PC=0x4 line=3: addi x1, x1, 10 # x1 += 10 +00000463 // PC=0x8 line=4: beq x0, x0, trap # halt +000080e7 // PC=0xc line=7: jalr x1, x1, 0 # x1 = 16, jump to addi diff --git a/src/asm/out/jal_jalr.memh b/src/asm/out/jal_jalr.memh new file mode 100644 index 0000000..2d5ed3b --- /dev/null +++ b/src/asm/out/jal_jalr.memh @@ -0,0 +1,4 @@ +00c000ef // PC=0x0 line=1: jal x1, jump # x01 = 4 +00a08093 // PC=0x4 line=3: addi x1, x1, 10 # x1 = 26 (16 + 10) +00000463 // PC=0x8 line=4: beq x0, x0, trap # halt +000080e7 // PC=0xc line=7: jalr x1, x1, 0 # x1 = 16, jump to addi diff --git a/src/asm/test/jal.result b/src/asm/test/jal.result new file mode 100644 index 0000000..0f8b405 --- /dev/null +++ b/src/asm/test/jal.result @@ -0,0 +1,50 @@ +Usage: + ./rv32_simulator +initial_memory=path/to/memh/file + Additional arguments: + +initial_memory=path/to/memh/file + Required: path to a memh file that containes the assembled binary to run. + +max_cycles=NUMBER_OF_CYCLES_TO_RUN + +wave_fn=path/to/wave/file + default is rv32_simulator.fst + +final_memory=path/to/memh/file + If provided, the final memory contents will be saved here. Use this to debug your store instructions. +WARNING: ./tests/provided/bytewise_distributed_ram.sv:58: $readmemh(../asm/out/jal.memh): Not enough words in the file for the requested range [0:1023]. +Running simulation of memory ../asm/out/jal.memh for up to 10000 cycles. Waves will be stored to rv32_simulator.fst. +FST info: dumpfile rv32_simulator.fst opened for output. +Ran 10000 cycles, finishing. +#TESTASSERTOUTPUT|---------------------------------------| +#TESTASSERTOUTPUT| Register File State :) | +#TESTASSERTOUTPUT|---------------------------------------| +#TESTASSERTOUTPUT| x00, zero = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x01, ra = 0x0000001a ( 26)| +#TESTASSERTOUTPUT| x02, sp = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x03, gp = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x04, tp = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x05, t0 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x06, t1 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x07, t2 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x08, s0 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x09, s1 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x10, a0 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x11, a1 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x12, a2 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x13, a3 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x14, a4 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x15, a5 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x16, a6 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x17, a7 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x18, s2 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x19, s3 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x20, s4 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x21, s5 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x22, s6 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x23, s7 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x24, s8 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x25, s9 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x26, s10 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x27, s11 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x28, t3 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x29, t4 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x30, t5 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x31, t6 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT|---------------------------------------| diff --git a/src/asm/test/jal_jalr.result b/src/asm/test/jal_jalr.result new file mode 100644 index 0000000..5808481 --- /dev/null +++ b/src/asm/test/jal_jalr.result @@ -0,0 +1,50 @@ +Usage: + ./rv32_simulator +initial_memory=path/to/memh/file + Additional arguments: + +initial_memory=path/to/memh/file + Required: path to a memh file that containes the assembled binary to run. + +max_cycles=NUMBER_OF_CYCLES_TO_RUN + +wave_fn=path/to/wave/file + default is rv32_simulator.fst + +final_memory=path/to/memh/file + If provided, the final memory contents will be saved here. Use this to debug your store instructions. +WARNING: ./tests/provided/bytewise_distributed_ram.sv:58: $readmemh(../asm/out/jal_jalr.memh): Not enough words in the file for the requested range [0:1023]. +Running simulation of memory ../asm/out/jal_jalr.memh for up to 10000 cycles. Waves will be stored to rv32_simulator.fst. +FST info: dumpfile rv32_simulator.fst opened for output. +Ran 10000 cycles, finishing. +#TESTASSERTOUTPUT|---------------------------------------| +#TESTASSERTOUTPUT| Register File State :) | +#TESTASSERTOUTPUT|---------------------------------------| +#TESTASSERTOUTPUT| x00, zero = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x01, ra = 0x0000001a ( 26)| +#TESTASSERTOUTPUT| x02, sp = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x03, gp = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x04, tp = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x05, t0 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x06, t1 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x07, t2 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x08, s0 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x09, s1 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x10, a0 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x11, a1 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x12, a2 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x13, a3 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x14, a4 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x15, a5 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x16, a6 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x17, a7 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x18, s2 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x19, s3 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x20, s4 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x21, s5 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x22, s6 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x23, s7 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x24, s8 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x25, s9 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x26, s10 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x27, s11 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x28, t3 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x29, t4 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x30, t5 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT| x31, t6 = 0x00000000 ( 0)| +#TESTASSERTOUTPUT|---------------------------------------| diff --git a/src/components/Makefile b/src/components/Makefile index 4812d9c..698072b 100644 --- a/src/components/Makefile +++ b/src/components/Makefile @@ -105,9 +105,11 @@ rv32_simulator: tests/provided/rv32_simulator.sv src/**/*.sv %.validate: %.result node ../asm/validate.js $(basename $<).s test/$< +test_rv32_ir_types: addi.validate itypes.validate irtypes.validate test_rv32_branch: beq.validate bne.validate blt.validate bge.validate bgeu.validate bltu.validate +test_rv32_jal: jal_jalr.validate -test_rv32_all: itypes.validate irtypes.validate storeload.validate test_rv32_branch +test_rv32_all: test_rv32_ir_types storeload.validate test_rv32_branch test_rv32_jal # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Instruction Type Tests diff --git a/src/components/src/cpu/rv32i_multicycle_core.sv b/src/components/src/cpu/rv32i_multicycle_core.sv index 2acf38d..c30745f 100644 --- a/src/components/src/cpu/rv32i_multicycle_core.sv +++ b/src/components/src/cpu/rv32i_multicycle_core.sv @@ -35,7 +35,7 @@ module rv32i_multicycle_core( S_ALUWB = 6, S_MEMWRITE = 7, S_BRANCH = 8, - S_JAL = 9 + S_JALR = 9 } state; /* ---------------------- Standard Control Signals ---------------------- */ @@ -70,7 +70,8 @@ module rv32i_multicycle_core( `OP_IMMEDIATE_I_EXECUTE, `OP_I_LOAD: extended_immediate = {{20{IR[31]}}, IR[31:20]}; `OP_I_STORE: extended_immediate = {{20{IR[31]}}, IR[31:25], IR[11:7]}; `OP_BRANCH: extended_immediate = {{19{IR[31]}}, IR[31], IR[7], IR[30:25], IR[11:8], 1'b0}; - `OP_JAL, `OP_JALR: extended_immediate = {{11{IR[31]}}, IR[31], IR[19:12], IR[20], IR[30:21], 1'b0}; + `OP_JAL: extended_immediate = {{11{IR[31]}}, IR[31], IR[19:12], IR[20], IR[30:21], 1'b0}; + `OP_JALR: extended_immediate = {{20{IR[31]}}, IR[31:20]}; `OP_U_IPC, `OP_U_LUI: extended_immediate = {IR[31:12], 12'b0}; endcase end @@ -395,10 +396,6 @@ module rv32i_multicycle_core( alu_src_a = ALU_SRC_A_OLD_PC; alu_src_b = ALU_SRC_B_IMM; end - `OP_JALR: begin - alu_src_a = ALU_SRC_A_RF; - alu_src_b = ALU_SRC_B_IMM; - end endcase end endcase @@ -406,6 +403,25 @@ module rv32i_multicycle_core( /* -------------------------------------------------------------------------------------------------------------------*/ /* DATAPATH for decode / branch target (end) */ /* -------------------------------------------------------------------------------------------------------------------*/ + + /* -------------------------------------------------------------------------------------------------------------------*/ + /* DATAPATH for JALR (start) */ + /* -------------------------------------------------------------------------------------------------------------------*/ + always_comb begin: datapath_jalr + case(state) + // for jalr we need one more cycle to go to the register file compared to jal which can just straight jump + S_JALR: begin + set_default; + alu_control = ALU_ADD; + alu_last_ena = 1; + alu_src_a = ALU_SRC_A_RF; + alu_src_b = ALU_SRC_B_IMM; + end + endcase + end + /* -------------------------------------------------------------------------------------------------------------------*/ + /* DATAPATH for JALR (end) */ + /* -------------------------------------------------------------------------------------------------------------------*/ /* -------------------------------------------------------------------------------------------------------------------*/ /* DATAPATH for branch (begin) */ @@ -481,10 +497,11 @@ module rv32i_multicycle_core( `OP_R_EXECUTE: state <= S_EXECUTE_RI; `OP_BRANCH: state <= S_BRANCH; `OP_JAL: state <= S_ALUWB; - `OP_JALR: state <= S_ALUWB; + `OP_JALR: state <= S_JALR; endcase end S_EXECUTE_RI: state <= S_ALUWB; + S_JALR : state <= S_ALUWB; S_ALUWB: state <= S_FETCH; S_MEMADR: begin case(op)