diff --git a/rtl/serv_alu.v b/rtl/serv_alu.v index b5e1164..30f033b 100644 --- a/rtl/serv_alu.v +++ b/rtl/serv_alu.v @@ -4,6 +4,7 @@ module serv_alu input wire clk, input wire i_rst, input wire i_en, + input wire i_shift_op, input wire i_cnt0, input wire i_rs1, input wire i_rs2, @@ -15,7 +16,7 @@ module serv_alu input wire i_sub, input wire [1:0] i_bool_op, input wire i_cmp_eq, - input wire i_cmp_uns, + input wire i_cmp_sig, output wire o_cmp, input wire i_shamt_en, input wire i_sh_right, @@ -34,18 +35,10 @@ module serv_alu reg [4:0] shamt; reg shamt_msb; - wire shamt_ser; - wire plus_1; - wire add_cy; reg add_cy_r; - wire b_inv_plus_1; - wire b_inv_plus_1_cy; - reg b_inv_plus_1_cy_r; - wire op_b = i_op_b_rs2 ? i_rs2 : i_imm; - assign shamt_ser = i_sh_right ? op_b : b_inv_plus_1; serv_shift shift ( @@ -59,22 +52,21 @@ module serv_alu .i_d (i_buf), .o_q (result_sh)); - wire add_b = i_sub ? b_inv_plus_1 : op_b; - assign {add_cy,result_add} = i_rs1+add_b+add_cy_r; - assign {b_inv_plus_1_cy,b_inv_plus_1} = {1'b0,~op_b}+plus_1+b_inv_plus_1_cy_r; + //Sign-extended operands + wire rs1_sx = i_rs1 & i_cmp_sig; + wire op_b_sx = op_b & i_cmp_sig; - reg lt_r; + wire result_lt = rs1_sx + ~op_b_sx + add_cy; + + wire add_a = i_rs1 & ~i_shift_op; + wire add_b = op_b^i_sub; + + assign {add_cy,result_add} = add_a+add_b+add_cy_r; reg eq_r; - wire lt_sign = i_cnt_done & !i_cmp_uns; + assign result_eq = !result_add & eq_r; - wire eq = (i_rs1 == op_b); - - assign result_eq = eq & eq_r; - assign result_lt = eq ? lt_r : op_b^lt_sign; - - assign plus_1 = i_cnt0; assign o_cmp = i_cmp_eq ? result_eq : result_lt; localparam [15:0] BOOL_LUT = 16'h8E96;//And, Or, =, xor @@ -82,15 +74,12 @@ module serv_alu assign o_rd = (i_rd_sel[0] & result_add) | (i_rd_sel[1] & result_sh) | - (i_rd_sel[2] & result_lt_r & plus_1) | + (i_rd_sel[2] & result_lt_r & i_cnt0) | (i_rd_sel[3] & result_bool); always @(posedge clk) begin - add_cy_r <= i_en & add_cy; - b_inv_plus_1_cy_r <= i_en & b_inv_plus_1_cy; - - lt_r <= result_lt & i_en; + add_cy_r <= i_en ? add_cy : i_sub; if (i_en) begin result_lt_r <= result_lt; @@ -98,8 +87,8 @@ module serv_alu eq_r <= result_eq | ~i_en; if (i_shamt_en) begin - shamt_msb <= b_inv_plus_1_cy; - shamt <= {shamt_ser,shamt[4:1]}; + shamt_msb <= add_cy; + shamt <= {result_add,shamt[4:1]}; end end diff --git a/rtl/serv_decode.v b/rtl/serv_decode.v index c6fcba8..1e3a637 100644 --- a/rtl/serv_decode.v +++ b/rtl/serv_decode.v @@ -29,7 +29,7 @@ module serv_decode output wire o_alu_sub, output wire [1:0] o_alu_bool_op, output wire o_alu_cmp_eq, - output wire o_alu_cmp_uns, + output wire o_alu_cmp_sig, output wire o_alu_sh_signed, output wire o_alu_sh_right, output wire [3:0] o_alu_rd_sel, @@ -117,7 +117,10 @@ module serv_decode (!opcode[2] & opcode[4] & opcode[0]) | (!opcode[2] & !opcode[3] & !opcode[0])) & (|o_rf_rd_addr); - assign o_alu_sub = opcode[3] & imm30/*alu_sub_r*/; + //True for sub, sll*, b*, slt* + //False for add*, sr* + assign o_alu_sub = (!funct3[2] & (funct3[0] | (opcode[3] & imm30))) | funct3[1] | opcode[4]; + /* 300 0_000 mstatus RWSC @@ -154,7 +157,7 @@ module serv_decode assign o_alu_cmp_eq = funct3[2:1] == 2'b00; - assign o_alu_cmp_uns = (funct3[0] & funct3[1]) | (funct3[1] & funct3[2]); + assign o_alu_cmp_sig = ~((funct3[0] & funct3[1]) | (funct3[1] & funct3[2])); assign o_alu_sh_signed = imm30; assign o_alu_sh_right = funct3[2]; diff --git a/rtl/serv_top.v b/rtl/serv_top.v index 3fdebfa..e7fc9c7 100644 --- a/rtl/serv_top.v +++ b/rtl/serv_top.v @@ -110,7 +110,7 @@ module serv_top wire alu_sub; wire [1:0] alu_bool_op; wire alu_cmp_eq; - wire alu_cmp_uns; + wire alu_cmp_sig; wire alu_cmp; wire alu_shamt_en; wire alu_sh_signed; @@ -229,7 +229,7 @@ module serv_top .o_alu_sub (alu_sub), .o_alu_bool_op (alu_bool_op), .o_alu_cmp_eq (alu_cmp_eq), - .o_alu_cmp_uns (alu_cmp_uns), + .o_alu_cmp_sig (alu_cmp_sig), .o_alu_sh_signed (alu_sh_signed), .o_alu_sh_right (alu_sh_right), .o_alu_rd_sel (alu_rd_sel), @@ -319,6 +319,7 @@ module serv_top ( .clk (clk), .i_rst (i_rst), + .i_shift_op (shift_op), .i_en (cnt_en), .i_cnt0 (cnt0), .i_rs1 (rs1), @@ -331,7 +332,7 @@ module serv_top .i_sub (alu_sub), .i_bool_op (alu_bool_op), .i_cmp_eq (alu_cmp_eq), - .i_cmp_uns (alu_cmp_uns), + .i_cmp_sig (alu_cmp_sig), .o_cmp (alu_cmp), .i_shamt_en (alu_shamt_en), .i_sh_right (alu_sh_right),