mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-22 22:19:14 +01:00
82 lines
1.9 KiB
Coq
82 lines
1.9 KiB
Coq
|
`default_nettype none
|
||
|
module serv_alu
|
||
|
#(
|
||
|
parameter W = 1,
|
||
|
parameter B = W-1
|
||
|
)
|
||
|
(
|
||
|
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 [B:0] i_rs1,
|
||
|
input wire [B:0] i_op_b,
|
||
|
input wire [B:0] i_buf,
|
||
|
output wire [B:0] o_rd);
|
||
|
|
||
|
wire [B:0] result_add;
|
||
|
wire [B:0] result_slt;
|
||
|
|
||
|
reg cmp_r;
|
||
|
|
||
|
wire add_cy;
|
||
|
reg [B:0] add_cy_r;
|
||
|
|
||
|
//Sign-extended operands
|
||
|
wire rs1_sx = i_rs1[B] & i_cmp_sig;
|
||
|
wire op_b_sx = i_op_b[B] & i_cmp_sig;
|
||
|
|
||
|
wire [B:0] add_b = i_op_b^{W{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 [B:0] result_bool = ((i_rs1 ^ i_op_b) & ~{W{i_bool_op[0]}}) | ({W{i_bool_op[1]}} & i_op_b & i_rs1);
|
||
|
|
||
|
assign result_slt[0] = cmp_r & i_cnt0;
|
||
|
generate
|
||
|
if (W>1) begin : gen_w_gt_1
|
||
|
assign result_slt[B:1] = {B{1'b0}};
|
||
|
end
|
||
|
endgenerate
|
||
|
|
||
|
assign o_rd = i_buf |
|
||
|
({W{i_rd_sel[0]}} & result_add) |
|
||
|
({W{i_rd_sel[1]}} & result_slt) |
|
||
|
({W{i_rd_sel[2]}} & result_bool);
|
||
|
|
||
|
always @(posedge clk) begin
|
||
|
add_cy_r <= {W{1'b0}};
|
||
|
add_cy_r[0] <= i_en ? add_cy : i_sub;
|
||
|
|
||
|
if (i_en)
|
||
|
cmp_r <= o_cmp;
|
||
|
end
|
||
|
|
||
|
endmodule
|