diff --git a/hdl/core.v b/hdl/core.v index 0985e09..2310b5b 100644 --- a/hdl/core.v +++ b/hdl/core.v @@ -91,7 +91,8 @@ reg r_ex_load, r_mem_load; reg [31:0] r_mem_wdata, r_wb_wdata; reg r_id_valid=0, r_ex_valid=0, r_mem_valid=0, r_wb_valid=0; reg r_ex_branch_pol; -reg r_ex_branch; +reg r_ex_branch, r_mem_branch, r_wb_branch; +reg [31:0] r_ex_immed_btype; // IF reg s_if_stall = 0; @@ -101,12 +102,10 @@ reg [31:0] s_if_inst; always @(*) begin s_if_stall = s_id_stall; - if (s_ex_take_branch && r_ex_valid) begin - s_if_next_pc = s_ex_alu_out; - // s_if_stall = 1'b1; + if (s_ex_take_branch) begin + s_if_next_pc = s_ex_branch_addr; end else begin s_if_next_pc = r_if_pc + 4; - // s_if_stall = 1'b0; end mem_inst_addr = r_if_pc; @@ -289,7 +288,7 @@ always @(*) begin endcase s_id_stall = s_ex_stall || - (r_ex_valid && + (r_ex_valid && (s_ex_take_branch == 0) && (((r_ex_rd == s_id_rs1) && (s_id_rs1 != 0)) || ((r_ex_rd == s_id_rs2) && (s_id_rs2 != 0)))) || (r_mem_valid && @@ -310,9 +309,9 @@ reg s_ex_stall = 0; reg [31:0] s_ex_data1, s_ex_data2; reg [31:0] s_ex_alu_out; reg s_ex_alu_zero; -reg [31:0] s_ex_ra; reg [31:0] s_ex_wdata; reg s_ex_take_branch; +reg [31:0] s_ex_branch_addr; always @(*) begin s_ex_stall = s_mem_stall; @@ -358,14 +357,13 @@ always @(*) begin endcase s_ex_alu_zero = (s_ex_alu_out == 0); - s_ex_ra = r_ex_pc + 4; - // s_ex_branch_addr = r_ex_pc + - // TODO: determine and go to branch address (pc+offset) - s_ex_take_branch = r_ex_jump || (r_ex_branch && (s_ex_alu_zero ^ r_ex_branch_pol)); + s_ex_take_branch = r_ex_valid && (r_ex_jump || (r_ex_branch && (s_ex_alu_zero ^ r_ex_branch_pol))); if (r_ex_jump) begin - s_ex_wdata = s_ex_ra; + s_ex_wdata = r_ex_pc + 4; + s_ex_branch_addr = s_ex_alu_out; end else begin s_ex_wdata = s_ex_alu_out; + s_ex_branch_addr = r_ex_pc + r_ex_immed_btype; end end @@ -402,7 +400,7 @@ always @(*) begin s_wb_data = r_wb_wdata; // FIXME: always writes!!! - s_wb_write = 1; //!s_wb_stall; + s_wb_write = (r_wb_branch == 0); end // SYS @@ -474,6 +472,7 @@ always @(posedge clk) begin: pipeline_update r_ex_load <= s_id_load; r_ex_valid <= r_id_valid && ~(s_ex_take_branch && r_ex_valid) && ~(s_id_stall && r_id_valid); r_ex_branch_pol <= s_id_branch_pol; + r_ex_immed_btype <= s_id_immed_btype; end @@ -490,6 +489,7 @@ always @(posedge clk) begin: pipeline_update r_mem_load <= r_ex_load; r_mem_wdata <= s_ex_wdata; r_mem_valid <= r_ex_valid; + r_mem_branch <= r_ex_branch; end // WB @@ -500,6 +500,7 @@ always @(posedge clk) begin: pipeline_update r_wb_alu_out <= r_mem_alu_out; r_wb_wdata <= r_mem_wdata; r_wb_valid <= r_mem_valid; + r_wb_branch <= r_mem_branch; end // Register File diff --git a/sim/core_tb.wcfg b/sim/core_tb.wcfg index 3c93a60..4400b6b 100644 --- a/sim/core_tb.wcfg +++ b/sim/core_tb.wcfg @@ -255,6 +255,31 @@ s_id_rs2[4:0] UNSIGNEDDECRADIX + + s_id_immed_itype[31:0] + s_id_immed_itype[31:0] + HEXRADIX + + + s_id_immed_stype[31:0] + s_id_immed_stype[31:0] + HEXRADIX + + + s_id_immed_utype[31:0] + s_id_immed_utype[31:0] + HEXRADIX + + + s_id_immed_btype[31:0] + s_id_immed_btype[31:0] + HEXRADIX + + + s_id_immed_jtype[31:0] + s_id_immed_jtype[31:0] + HEXRADIX + s_id_s1[31:0] s_id_s1[31:0] @@ -361,6 +386,16 @@ s_ex_take_branch s_ex_take_branch + + r_ex_immed_btype[31:0] + r_ex_immed_btype[31:0] + HEXRADIX + + + s_ex_branch_addr[31:0] + s_ex_branch_addr[31:0] + HEXRADIX + MEM @@ -405,10 +440,6 @@ r_wb_valid r_wb_valid - - s_wb_stall - s_wb_stall - r_wb_pc[31:0] r_wb_pc[31:0] diff --git a/test/test.S b/test/test.S index 2b64c9e..f9bf714 100644 --- a/test/test.S +++ b/test/test.S @@ -137,26 +137,49 @@ _start: # jal jal x1, test_jalr -# test1: -# # TODO: redo these tests because my nop test messed it up -# # beq -# addi x30, x0, 1 # x30 = 1 -# addi x9, x8, 0 # x9 == x8 -# bne x0, x0, fail # 0 == 0 -# bne x9, x8, fail # x9 == x8 -# bne x7, x8, test2 # x7 != x8 -# j fail +test1: + # beq + addi x30, x0, 1 # x30 = 1 + addi x9, x8, 0 # x9 = 0xffffff00 + bne x0, x0, fail # 0 == 0 + bne x9, x8, fail # x9 == x8 + bne x7, x8, test2 # x7 != x8 + j fail -# test2: -# # beq -# addi x30, x0, 2 # x30 = 2 -# beq x0, x8, fail # 0 != x8 -# beq x7, x8, fail # x7 != x8 -# beq x8, x9, test3 # x8 == x9 -# j fail +test2: + # beq + addi x30, x0, 2 # x30 = 2 + beq x0, x8, fail # 0 != x8 + beq x7, x8, fail # x7 != x8 + beq x8, x9, test3 # x8 == x9 + j fail -# test3: +test3: + #blt + addi x30, x0, 3 # x30 = 3 + blt x8, x9, fail # x8 == x9 + blt x7, x8, fail # x7 > x8 + blt x30, x8, fail # x30 > x8 + blt x8, x7, test4 # x8 < x7 + j fail +test4: + #bltu + addi x30, x0, 4 # x30 = 4 + bltu x8, x9, fail # x8 == x9 + bltu x8, x7, fail # x8 < x7 + bltu x30, x8, test5 # x30 < x8 unsigned + +test5: + addi x30, x0, 5 # x30 = 5 + + + # set registers to known values before loop + addi x2, x0, 1 # x1 = 1 + addi x3, x0, 1 # x1 = 1 + addi x4, x0, 1 # x1 = 1 + addi x5, x0, 1 # x1 = 1 + addi x6, x0, 1 # x1 = 1 # counter and infinite loop addi x31, x0, 1 # x1 = 1 @@ -182,7 +205,17 @@ test_jalr: jalr x0, x1, 0 # return fail: - jal x0, fail # loop forever + # set some registers to make it blatantly obvious an error occurred + addi x1, x0, 0x7ff # x1 = 0x1111 + addi x2, x0, 0x7ff # x1 = 0x1111 + addi x3, x0, 0x7ff # x1 = 0x1111 + addi x4, x0, 0x7ff # x1 = 0x1111 + addi x5, x0, 0x7ff # x1 = 0x1111 + addi x6, x0, 0x7ff # x1 = 0x1111 + addi x7, x0, 0x7ff # x1 = 0x1111 + addi x8, x0, 0x7ff # x1 = 0x1111 + addi x9, x0, 0x7ff # x1 = 0x1111 + j fail # loop forever nop nop nop