aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlavian Kaufmann <flavian@flaviankaufmann.ch>2024-05-09 11:02:01 +0200
committerFlavian Kaufmann <flavian@flaviankaufmann.ch>2024-05-09 11:02:01 +0200
commitd810d1cd42a31268ccb33993f1f1f429900c5ff8 (patch)
tree229311919524387d188752c4dcec730ecc115782
parent678aef68af85c04015d8c385f6d6c60ffada7fad (diff)
downloadriscv_cpu-d810d1cd42a31268ccb33993f1f1f429900c5ff8.tar.gz
riscv_cpu-d810d1cd42a31268ccb33993f1f1f429900c5ff8.zip
added remaining branch instructions
-rw-r--r--README.md2
-rw-r--r--gentestvec/gentestvec_alu.c5
-rw-r--r--prog/src/prog.s23
-rw-r--r--sim/testbench_alu.v12
-rw-r--r--src/alu.v4
-rw-r--r--src/alu_op_decode.v4
-rw-r--r--src/control_unit.v29
-rw-r--r--src/cpu.v5
8 files changed, 40 insertions, 44 deletions
diff --git a/README.md b/README.md
index a14a584..68ac156 100644
--- a/README.md
+++ b/README.md
@@ -47,7 +47,7 @@ The board used in this project is a [Tang Nano 9K](https://wiki.sipeed.com/hardw
* R-type: add, sub, and, or, xor, sll, srl, sra, slt, sltu
* I-type: addi, andi, ori, xori, slti, sltiu, slli, srli, srai
* S-type: sw
-* B-type: beq
+* B-type: beq, bne, blt, bge, bltu, bgeu
* U-type:
* J-type: jal, jalr
diff --git a/gentestvec/gentestvec_alu.c b/gentestvec/gentestvec_alu.c
index 323c43e..4a11a74 100644
--- a/gentestvec/gentestvec_alu.c
+++ b/gentestvec/gentestvec_alu.c
@@ -21,7 +21,6 @@ typedef enum {
void test_op(OP op, uint32_t a, uint32_t b) {
uint32_t result;
bool zero;
- bool equal;
switch (op) {
case ADD:
@@ -59,10 +58,8 @@ void test_op(OP op, uint32_t a, uint32_t b) {
}
zero = result == 0;
- equal = a == b;
- printf("%01X__%08X_%08X__%08X_%01X%01X\n", op & 0x0f, a, b, result, equal,
- zero);
+ printf("%01X__%08X_%08X__%08X_%01X\n", op & 0x0f, a, b, result, zero);
}
void test_op_random(OP op, int num) {
diff --git a/prog/src/prog.s b/prog/src/prog.s
index 2b5e4c2..8944306 100644
--- a/prog/src/prog.s
+++ b/prog/src/prog.s
@@ -39,18 +39,27 @@ _start:
# addi t0, zero, 2
#0010 0000
-addi t0, zero, 0x0010
-slli t0, t0, 16
-ori t0, t0, 0x0000
+# addi t0, zero, 0x0010
+# slli t0, t0, 16
+# ori t0, t0, 0x0000
+
+# addi t1, zero, 0xff
+# sw t1, 0(t0)
+# lw t2, 0(t0)
+
+ addi t0, zero, -1
+ addi t1, zero, 2
+ bltu t0, t1, branch_taken
+ addi t2, zero, 1
-addi t1, zero, 0xff
-sw t1, 0(t0)
-lw t2, 0(t0)
-
halt_loop:
j halt_loop
+branch_taken:
+ addi t2, zero, 2
+ j halt_loop
+
#target:
# addi t0, zero, 1
# jalr zero, ra, 0
diff --git a/sim/testbench_alu.v b/sim/testbench_alu.v
index 6b40684..f011ed2 100644
--- a/sim/testbench_alu.v
+++ b/sim/testbench_alu.v
@@ -32,16 +32,14 @@ module testbench_alu();
reg [31:0] a, b, exp_result;
reg [3:0] op;
- reg [7:0] exp_flags;
+ reg [3:0] exp_flags;
wire [31:0] result;
wire zero, exp_zero;
- wire equal, exp_equal;
assign exp_zero = exp_flags[0];
- assign exp_equal = exp_flags[4];
reg [31:0] alu_test_count, alu_error_count;
- reg [107:0] alu_testvec [0:20000];
+ reg [103:0] alu_testvec [0:20000];
initial begin
#5;
@@ -54,12 +52,11 @@ module testbench_alu();
#16;
{op, a, b, exp_result, exp_flags} = alu_testvec[alu_test_count];
#32;
- if ((result !== exp_result) | (zero !== exp_zero) | (equal != exp_equal)) begin
+ if ((result !== exp_result) | (zero !== exp_zero)) begin
$display("ERROR (ALU) time: %5d, test: %d", $time, alu_test_count);
$display(" op: %b, a: %h b: %h", op, a, b);
$display(" result: %h (expected %h)", result, exp_result);
$display(" zero: %b (expected %b)", zero, exp_zero);
- $display(" equal: %b (expected %b)", equal, exp_equal);
alu_error_count = alu_error_count + 1;
end
@@ -81,8 +78,7 @@ module testbench_alu();
.b(b),
.op(op),
.result(result),
- .zero(zero),
- .equal(equal)
+ .zero(zero)
);
endmodule
diff --git a/src/alu.v b/src/alu.v
index 6f9251c..6962129 100644
--- a/src/alu.v
+++ b/src/alu.v
@@ -2,8 +2,7 @@ module alu (
input [31:0] a, b,
input [3:0] op,
output reg [31:0] result,
- output zero,
- output equal
+ output zero
);
wire [31:0] arithmetic_result, logic_result, shift_result;
@@ -39,6 +38,5 @@ always @ (*) begin
end
assign zero = result == 32'b0;
-assign equal = a == b;
endmodule
diff --git a/src/alu_op_decode.v b/src/alu_op_decode.v
index 895b952..b9db664 100644
--- a/src/alu_op_decode.v
+++ b/src/alu_op_decode.v
@@ -1,6 +1,6 @@
module alu_op_decode (
input [6:0] opcode,
- input [1:0] alu_ctrl,
+ input alu_ctrl,
input [2:0] funct3,
input [6:0] funct7,
output reg [3:0] alu_op
@@ -19,7 +19,7 @@ parameter ALU_OP_ADD = 4'b0000,
always @ (*) begin
- if (alu_ctrl == 2'b00) alu_op <= ALU_OP_ADD;
+ if (alu_ctrl == 1'b1) alu_op <= ALU_OP_ADD;
else case (opcode)
7'b0110011: begin // ADD, SUB, SLL, SLT, SLTU, XOR, SRL, SRA, OR, AND
case (funct3)
diff --git a/src/control_unit.v b/src/control_unit.v
index 7ca2cb2..09129bd 100644
--- a/src/control_unit.v
+++ b/src/control_unit.v
@@ -4,7 +4,6 @@ module control_unit (
input [2:0] funct3,
input [6:0] funct7,
input alu_zero,
- input alu_equal,
output pc_we,
output reg mem_addr_src,
output reg mem_we,
@@ -27,7 +26,7 @@ parameter s00_fetch = 4'h0,
s08_execute_i = 4'h8,
s09_jal = 4'h9,
s10_jalr = 4'ha,
- s11_beq = 4'hb;
+ s11_br = 4'hb;
reg [3:0] state, next_state;
@@ -46,7 +45,7 @@ always @ (*) begin
7'b0010011: next_state <= s08_execute_i;
7'b1101111: next_state <= s09_jal;
7'b1100111: next_state <= s10_jalr;
- 7'b1100011: next_state <= s11_beq;
+ 7'b1100011: next_state <= s11_br;
endcase
s02_mem_addr: case(opcode)
@@ -61,15 +60,15 @@ always @ (*) begin
s08_execute_i: next_state <= s07_alu_wb;
s09_jal: next_state <= s07_alu_wb;
s10_jalr: next_state <= s07_alu_wb;
- s11_beq: next_state <= s00_fetch;
+ s11_br: next_state <= s00_fetch;
endcase
end
reg branch;
reg pc_update;
-reg [1:0] alu_ctrl;
+reg alu_ctrl;
-assign pc_we = (alu_zero & branch) | pc_update;
+assign pc_we = ((alu_zero ^ funct3[0] ^ funct3[2]) & branch) | pc_update;
always @ (*) begin
@@ -84,19 +83,19 @@ always @ (*) begin
instr_we = 1'b1;
alu_a_src <= 2'b00;
alu_b_src <= 2'b10;
- alu_ctrl <= 2'b00;
+ alu_ctrl <= 1'b1;
result_src <= 2'b10;
pc_update = 1'b1;
end
s01_decode: begin
alu_a_src <= 2'b01;
alu_b_src <= 2'b01;
- alu_ctrl <= 2'b00;
+ alu_ctrl <= 1'b1;
end
s02_mem_addr: begin
alu_a_src <= 2'b10;
alu_b_src <= 2'b01;
- alu_ctrl <= 2'b00;
+ alu_ctrl <= 1'b1;
end
s03_mem_read: begin
result_src <= 2'b00;
@@ -114,7 +113,7 @@ always @ (*) begin
s06_execute_r: begin
alu_a_src <= 2'b10;
alu_b_src <= 2'b00;
- alu_ctrl <= 2'b10;
+ alu_ctrl <= 1'b0;
end
s07_alu_wb: begin
result_src <= 2'b00;
@@ -123,26 +122,26 @@ always @ (*) begin
s08_execute_i: begin
alu_a_src <= 2'b10;
alu_b_src <= 2'b01;
- alu_ctrl <= 2'b10;
+ alu_ctrl <= 1'b0;
end
s09_jal: begin
alu_a_src <= 2'b01;
alu_b_src <= 2'b10;
- alu_ctrl <= 2'b00;
+ alu_ctrl <= 1'b1;
result_src <= 2'b00;
pc_update = 1'b1;
end
s10_jalr: begin
alu_a_src <= 2'b10;
alu_b_src <= 2'b01;
- alu_ctrl <= 2'b00;
+ alu_ctrl <= 1'b1;
result_src <= 2'b10;
pc_update = 1'b1;
end
- s11_beq: begin
+ s11_br: begin
alu_a_src <= 2'b10;
alu_b_src <= 2'b00;
- alu_ctrl <= 2'b01;
+ alu_ctrl <= 1'b0;
result_src <= 2'b00;
branch = 1'b1;
end
diff --git a/src/cpu.v b/src/cpu.v
index 5362cf9..66ae8ce 100644
--- a/src/cpu.v
+++ b/src/cpu.v
@@ -12,7 +12,6 @@ wire pc_we;
wire instr_we;
wire rf_we;
wire alu_zero;
-wire alu_equal;
wire [3:0] alu_op;
wire [1:0] alu_a_src;
wire [1:0] alu_b_src;
@@ -25,7 +24,6 @@ control_unit cu (
.funct3(funct3),
.funct7(funct7),
.alu_zero(alu_zero),
- .alu_equal(alu_equal),
.pc_we(pc_we),
.mem_addr_src(mem_addr_src),
.mem_we(mem_we),
@@ -156,8 +154,7 @@ alu alu (
.b(b),
.op(alu_op),
.result(alu_result),
- .zero(alu_zero),
- .equal(alu_equal)
+ .zero(alu_zero)
);
reg [31:0] result_buf;