diff options
Diffstat (limited to 'verilog/alu.v')
-rw-r--r-- | verilog/alu.v | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/verilog/alu.v b/verilog/alu.v new file mode 100644 index 0000000..5a4e6c0 --- /dev/null +++ b/verilog/alu.v @@ -0,0 +1,45 @@ +`default_nettype none +`timescale 1us/1ns + +`define ADDSUB 3'b000 +`define XOR 3'b100 +`define OR 3'b110 +`define AND 3'b111 +`define SLL 3'b001 +`define SR 3'b101 +`define SLT 3'b010 +`define SLTU 3'b011 + +module alu +( +input wire [31:0] A, +input wire[31:0] B, +input wire[4:0] OP, +output reg[31:0] C, +output wire Branch +); + +wire [31:0] sum = A + ({32{(OP[3] | OP[1])}} ^ B) + {31'b0, (OP[3] | OP[1])}; +wire [31:0] right = (A >> B[4:0] | (OP[3] == 0 ? 32'b0 : + (32'hFFFFFFFF << {~B[4] , ~B[3], ~B[2], ~B[1], ~B[0]}))); + +assign Branch = |C; + +always @ (*) begin + case(OP[2:0]) + `ADDSUB: C = sum; + `XOR: C = A ^ B; + `OR: C = A | B; + `AND: C = A & B; + `SLL: C = |B[31:5] ? 32'b0 : A << B[4:0]; + `SR: C = right; + `SLT: C = {31'b0, sum[31]}; + `SLTU: C = {31'b0, A < B}; + default: C = 32'b0; + endcase + if (OP[4]) begin + C = B; + end +end + +endmodule |