`default_nettype none module serv_alu ( input wire clk, //State input wire i_en, input wire i_cnt0, output wire o_cmp, //Control input wire i_sub, input wire [1:0] i_bool_op, input wire i_cmp_eq, input wire i_cmp_sig, input wire [2:0] i_rd_sel, //Data input wire i_rs1, input wire i_op_b, input wire i_buf, output wire o_rd); wire result_add; reg cmp_r; wire add_cy; reg add_cy_r; //Sign-extended operands wire rs1_sx = i_rs1 & i_cmp_sig; wire op_b_sx = i_op_b & i_cmp_sig; wire add_b = i_op_b^i_sub; assign {add_cy,result_add} = i_rs1+add_b+add_cy_r; wire result_lt = rs1_sx + ~op_b_sx + add_cy; wire result_eq = !result_add & (cmp_r | i_cnt0); assign o_cmp = i_cmp_eq ? result_eq : result_lt; /* The result_bool expression implements the following operations between i_rs1 and i_op_b depending on the value of i_bool_op 00 xor 01 0 10 or 11 and i_bool_op will be 01 during shift operations, so by outputting zero under this condition we can safely or result_bool with i_buf */ wire result_bool = ((i_rs1 ^ i_op_b) & ~ i_bool_op[0]) | (i_bool_op[1] & i_op_b & i_rs1); assign o_rd = i_buf | (i_rd_sel[0] & result_add) | (i_rd_sel[1] & cmp_r & i_cnt0) | (i_rd_sel[2] & result_bool); always @(posedge clk) begin add_cy_r <= i_en ? add_cy : i_sub; if (i_en) cmp_r <= o_cmp; end endmodule