diff options
author | Flavian Kaufmann <flavian@flaviankaufmann.ch> | 2024-05-07 21:27:21 +0200 |
---|---|---|
committer | Flavian Kaufmann <flavian@flaviankaufmann.ch> | 2024-05-07 21:27:21 +0200 |
commit | 9a357b3ad679751bc7a9ce85adbc303130211226 (patch) | |
tree | 9898c449a53ff3caa0ae4620a1078c3a8268cbd0 | |
parent | da9b25591e8b4d1c05a2ac84bb40b5cb5e3a86c5 (diff) | |
download | riscv_cpu-9a357b3ad679751bc7a9ce85adbc303130211226.tar.gz riscv_cpu-9a357b3ad679751bc7a9ce85adbc303130211226.zip |
alu equal
-rw-r--r-- | gentestvec/gentestvec_alu.c | 5 | ||||
-rw-r--r-- | sim/testbench_alu.v | 12 | ||||
-rw-r--r-- | src/alu.v | 4 | ||||
-rw-r--r-- | src/control_unit.v | 7 | ||||
-rw-r--r-- | src/cpu.v | 5 |
5 files changed, 26 insertions, 7 deletions
diff --git a/gentestvec/gentestvec_alu.c b/gentestvec/gentestvec_alu.c index 4a11a74..323c43e 100644 --- a/gentestvec/gentestvec_alu.c +++ b/gentestvec/gentestvec_alu.c @@ -21,6 +21,7 @@ typedef enum { void test_op(OP op, uint32_t a, uint32_t b) { uint32_t result; bool zero; + bool equal; switch (op) { case ADD: @@ -58,8 +59,10 @@ void test_op(OP op, uint32_t a, uint32_t b) { } zero = result == 0; + equal = a == b; - printf("%01X__%08X_%08X__%08X_%01X\n", op & 0x0f, a, b, result, zero); + printf("%01X__%08X_%08X__%08X_%01X%01X\n", op & 0x0f, a, b, result, equal, + zero); } void test_op_random(OP op, int num) { diff --git a/sim/testbench_alu.v b/sim/testbench_alu.v index f011ed2..6b40684 100644 --- a/sim/testbench_alu.v +++ b/sim/testbench_alu.v @@ -32,14 +32,16 @@ module testbench_alu(); reg [31:0] a, b, exp_result; reg [3:0] op; - reg [3:0] exp_flags; + reg [7: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 [103:0] alu_testvec [0:20000]; + reg [107:0] alu_testvec [0:20000]; initial begin #5; @@ -52,11 +54,12 @@ module testbench_alu(); #16; {op, a, b, exp_result, exp_flags} = alu_testvec[alu_test_count]; #32; - if ((result !== exp_result) | (zero !== exp_zero)) begin + if ((result !== exp_result) | (zero !== exp_zero) | (equal != exp_equal)) 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 @@ -78,7 +81,8 @@ module testbench_alu(); .b(b), .op(op), .result(result), - .zero(zero) + .zero(zero), + .equal(equal) ); endmodule @@ -2,7 +2,8 @@ module alu ( input [31:0] a, b, input [3:0] op, output reg [31:0] result, - output zero + output zero, + output equal ); wire [31:0] arithmetic_result, logic_result, shift_result; @@ -38,5 +39,6 @@ always @ (*) begin end assign zero = result == 32'b0; +assign equal = a == b; endmodule diff --git a/src/control_unit.v b/src/control_unit.v index 5d18f7a..a0d398a 100644 --- a/src/control_unit.v +++ b/src/control_unit.v @@ -4,6 +4,7 @@ module control_unit ( input [2:0] funct3, input [6:0] funct7, input alu_zero, + input alu_equal, output pc_we, output mem_addr_src, output mem_we, @@ -60,6 +61,12 @@ always @ (*) begin s10_beq: next_state <= s00_fetch; endcase end + +wire branch; +wire pc_update; + +assign pc_we = (alu_zero & branch) | pc_update; + /* always @ (*) begin case(state) @@ -11,6 +11,7 @@ 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; @@ -23,6 +24,7 @@ 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), @@ -153,7 +155,8 @@ alu alu ( .b(b), .op(alu_op), .result(alu_result), - .zero(alu_zero) + .zero(alu_zero), + .equal(alu_equal) ); reg [31:0] result_buf; |