summaryrefslogtreecommitdiff
path: root/verilog/alu/v3/alu3.v
blob: 556b2261a9ea1429b65d5e36734ac93aaa5fa871 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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