1
0
mirror of https://github.com/olofk/serv.git synced 2026-01-13 15:17:25 +00:00

Refactor and Use ALU subtractor for comparisons

This commit is contained in:
Olof Kindgren 2020-08-04 22:46:01 +02:00
parent 1c4e793885
commit 88a1a43438
3 changed files with 26 additions and 33 deletions

View File

@ -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

View File

@ -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];

View File

@ -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),