1
0
mirror of https://github.com/olofk/serv.git synced 2026-05-05 07:43:34 +00:00
Files
olofk.serv/rtl/serv_alu.v
Olof Kindgren c90920d9b2 bge, bltu, bgeu
2018-11-01 09:35:49 +01:00

109 lines
2.1 KiB
Verilog

`default_nettype none
module serv_alu
(
input clk,
input i_en,
input i_rs1,
input i_op_b,
input i_init,
input i_sub,
input i_cmp_sel,
input i_cmp_neg,
input i_cmp_uns,
output o_cmp,
input i_shamt_en,
input [1:0] i_rd_sel,
output o_rd);
`include "serv_params.vh"
wire result_add;
wire result_eq;
wire result_lt;
wire result_sh;
wire [4:0] shamt;
reg en_r;
wire v;
reg msb_lt = 1'b0;
shift_reg #(.LEN (5)) shamt_reg
(.clk (clk),
.i_en (i_shamt_en),
.i_d (i_op_b),
.o_q (shamt[0]),
.o_par (shamt[4:1]));
ser_shift shift
(
.i_clk (clk),
.i_load (i_init),
.i_shamt (shamt),
.i_sr (/*FIXME*/),
.i_d (i_rs1),
.o_q (result_sh));
wire plus_1 = i_en & !en_r;
wire b_inv_plus_1;
ser_add ser_add_inv_plus_1
(
.clk (clk),
.a (~i_op_b),
.b (plus_1),
.clr (!i_en),
.q (b_inv_plus_1),
.o_v ());
wire add_b = i_sub ? b_inv_plus_1 : i_op_b;
ser_add ser_add
(
.clk (clk),
.a (i_rs1),
.b (add_b),
.clr (!i_en),
.q (result_add),
.o_v (v));
ser_eq ser_eq
(
.clk (clk),
.a (i_rs1),
.b (i_op_b),
.clr (!i_init),
.o_q (result_eq));
ser_lt ser_lt
(
.i_clk (clk),
.i_a (i_rs1),
.i_b (i_op_b),
.i_clr (!i_init),
.o_q (result_lt));
reg last_eq;
wire result_lt2 = last_eq ? result_lt : msb_lt;
assign o_cmp = i_cmp_neg^((i_cmp_sel == ALU_CMP_EQ) ? result_eq : result_lt2);
assign o_rd = (i_rd_sel == ALU_RESULT_ADD) ? result_add :
(i_rd_sel == ALU_RESULT_SR) ? result_sh :
1'bx;
always @(posedge clk) begin
if (i_init) begin
last_eq <= i_rs1 == i_op_b;
msb_lt <= i_cmp_uns ? (~i_rs1 & i_op_b) : (i_rs1 & ~i_op_b);
end
// result_lt <= /*v^*/result_add;
en_r <= i_en;
end
endmodule