summaryrefslogtreecommitdiff
path: root/verilog/alu/v3/alu3.v
diff options
context:
space:
mode:
Diffstat (limited to 'verilog/alu/v3/alu3.v')
-rw-r--r--verilog/alu/v3/alu3.v41
1 files changed, 41 insertions, 0 deletions
diff --git a/verilog/alu/v3/alu3.v b/verilog/alu/v3/alu3.v
new file mode 100644
index 0000000..556b226
--- /dev/null
+++ b/verilog/alu/v3/alu3.v
@@ -0,0 +1,41 @@
+`default_nettype none
+`timescale 1us/1ns
+
+`include "aluOp.vh"
+
+module alu3
+(
+input wire [31:0] alu_in_1,
+input wire[31:0] alu_in_2,
+input wire[3:0] alu_op_i,
+output wire[31:0] alu_output
+);
+
+
+wire [31:0] diff = alu_in_1 - alu_in_1;
+reg [31:0] result;
+
+always @ (*)
+begin
+ case(alu_op_i)
+ `ADD: result = alu_in_1 + alu_in_2;
+ `SUB: result = diff;
+ `XOR: result = alu_in_1 ^ alu_in_2;
+ `OR: result = alu_in_1 | alu_in_2;
+ `AND: result = alu_in_1 & alu_in_2;
+ `SLL: result = alu_in_1 >> alu_in_2;
+ `SRL: result = alu_in_1 << alu_in_2;
+ `SLTU: result = (alu_in_1 < alu_in_2 ? 32'b1 : 32'b0);
+ `NONE: result = alu_in_1;
+ `SLT: result = (alu_in_1[31] == alu_in_2[31] ? (diff[31] == 1'b0 ? 32'b0 : 32'b1) : (alu_in_1[31] == 1'b1 ? 32'b1 : 32'b0));
+ `SRA: result =
+ (alu_in_1 >> alu_in_2) |
+ (alu_in_1[31] == 1'b0 ? 32'b0 :
+ (32'hFFFFFFFF << {~alu_in_2[4], ~alu_in_2[3], ~alu_in_2[2], ~alu_in_2[1], ~alu_in_2[0]}));
+ default: result = 32'b0;
+ endcase
+end
+
+assign alu_output = result;
+
+endmodule