summaryrefslogtreecommitdiff
path: root/verilog/alu.v
diff options
context:
space:
mode:
Diffstat (limited to 'verilog/alu.v')
-rw-r--r--verilog/alu.v45
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