module alu( input [2:0] op, input [WIDTH - 1:0] a, b, input sign, input b_add_one, input b_negate, output reg [WIDTH - 1:0] out, output reg zero_flag); parameter WIDTH = 32; reg [WIDTH - 1:0] real_b; always_comb begin if (b_negate) real_b = ~b; else real_b = b; real_b = real_b + (b_add_one ? 1 : 0); end always_comb begin case (op) 3'b000 : out = a + real_b; 3'b001 : out = a << real_b[4:0]; 3'b010 : out = (signed'(a) < signed'(real_b)) ? 1 : 0; 3'b011 : out = (a < real_b) ? 1 : 0; 3'b100 : out = a ^ real_b; 3'b101 : begin if (sign) out = signed'(a) >>> signed'(real_b[4:0]); else out = a >> real_b[4:0]; end 3'b110 : out = a | real_b; 3'b111 : out = a & real_b; default: out = {WIDTH{1'bX}}; endcase end always_comb zero_flag = (out == 0) ? 1 : 0; endmodule