summaryrefslogtreecommitdiff
path: root/verilog/riscv_alu.v
diff options
context:
space:
mode:
Diffstat (limited to 'verilog/riscv_alu.v')
-rw-r--r--verilog/riscv_alu.v39
1 files changed, 39 insertions, 0 deletions
diff --git a/verilog/riscv_alu.v b/verilog/riscv_alu.v
new file mode 100644
index 0000000..87dd637
--- /dev/null
+++ b/verilog/riscv_alu.v
@@ -0,0 +1,39 @@
+module riscv_alu
+(
+input wire signed [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
+);
+
+reg[31:0] tmp_out;
+`include "alu_ops.vh"
+
+wire [31:0] sub_alu = alu_in_1 - alu_in_2;
+
+always @(*)
+begin
+ case (alu_op_i)
+ `ADD: tmp_out = alu_in_1 + alu_in_2;
+ `SUB: tmp_out = sub_alu;
+ `XOR: tmp_out = alu_in_1 ^ alu_in_2;
+ `OR: tmp_out = alu_in_1 | alu_in_2;
+ `AND: tmp_out = alu_in_1 & alu_in_2;
+ `SLL: tmp_out = alu_in_1 << alu_in_2;
+ `SRL: tmp_out = alu_in_1 >> alu_in_2;
+ `SRA: tmp_out = alu_in_1 >>> alu_in_2;
+ `SLT: tmp_out = (alu_in_1 < alu_in_2) ? 32'h1 : 32'h0;
+ `SLTU:
+ begin
+ if (alu_in_1[31] != alu_in_2[31])
+ tmp_out = alu_in_1[31] ? 32'h1 : 32'h0;
+ else
+ tmp_out = sub_alu[31] ? 32'h1 : 32'h0;
+ end
+ default: tmp_out = alu_in_1;
+ endcase
+end
+
+assign alu_output = tmp_out;
+
+endmodule