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