blob: 5c9b0250f758a3defa3363cc1f1164b40d5ea482 [file] [log] [blame]
/*
*
* This file is part of the Elpis processor project.
*
* Copyright © 2020-present. All rights reserved.
* Authors: Aurora Tomas and Rodrigo Huerta.
*
* This file is licensed under both the BSD-3 license for individual/non-commercial
* use. Full text of both licenses can be found in LICENSE file.
*/
`default_nettype none
`ifdef TESTS
`include "elpis/definitions.v"
`else
`include "/project/openlane/user_proj_example/../../verilog/rtl/elpis/definitions.v"
`endif
module alu(
input[31:0] x,
input[31:0] y,
input[3:0] op,
output reg[31:0] w,
output z,
output reg[31:0] exception_code
);
wire[32:0] w_add = x + y;
wire[32:0] w_sub = x - y;
wire[31:0] w_and = x & y;
wire[31:0] w_or = x | y;
wire[31:0] w_xor = x ^ y;
wire[31:0] w_sll = x << y;
wire[31:0] w_srl = x >> y;
//wire[31:0] w_sra = $signed(x) >>> y;
wire[31:0] w_sra = 32'b0;
//wire[31:0] excp = (op == `ALU_OP_ADD) ? ((w_add[32] && (x[31] == y[31])) ? `EXC_OVERFLOW : 0) : ( (op == `ALU_OP_SUB) ? ( (w_sub[32]) ? `EXC_UNDERFLOW : 0) : 32'b0);
assign z = (x==y) ? 1'b1 : 1'b0;
wire is_add = op == `ALU_OP_ADD;
wire is_sub = op == `ALU_OP_SUB;
wire is_and = op == `ALU_OP_AND;
wire is_or = op == `ALU_OP_OR;
wire is_xor = op == `ALU_OP_XOR;
wire is_branch = op == `ALU_OP_BRANCH;
wire is_sll = op == `ALU_OP_SLL;
wire is_slr = op == `ALU_OP_SRL;
wire is_sra = op == `ALU_OP_SRA;
(* parallel_case, full_case *)
always@(*) begin
case(1'b1)
is_add: begin
w = w_add[31:0];
end
is_sub: begin
w = w_sub[31:0];
end
is_and: begin
w = w_and;
end
is_or: begin
w = w_or;
end
is_xor: begin
w = w_xor;
end
is_branch: begin
w = w_add[31:0];
end
is_sll: begin
w = w_sll;
end
is_slr: begin
w = w_srl;
end
is_sra: begin
w = w_sra;
end
default: begin
w = 32'b0;
end
endcase
end
// always@(*) begin
// case(op)
// `ALU_OP_ADD: begin
// {carry, w} = x + y;
// exception_code = (carry && (x[31] == y[31])) ? `EXC_OVERFLOW : 0;
// end
// `ALU_OP_SUB: begin
// {carry, w} = x - y;
// exception_code = (carry) ? `EXC_UNDERFLOW : 0;
// end
// `ALU_OP_AND: begin
// w = x & y;
// exception_code = 32'b0;
// carry = 0;
// end
// `ALU_OP_OR: begin
// w = x | y;
// exception_code = 32'b0;
// carry = 0;
// end
// `ALU_OP_XOR: begin
// w = x ^ y;
// exception_code = 32'b0;
// carry = 0;
// end
// `ALU_OP_BRANCH: begin
// w = x + y;
// exception_code = 32'b0;
// carry = 0;
// end
// `ALU_OP_SLL: begin
// w = x << y;
// exception_code = 32'b0;
// carry = 0;
// end
// `ALU_OP_SRL: begin
// w = x >> y;
// exception_code = 32'b0;
// carry = 0;
// end
// `ALU_OP_SRA: begin
// w = $signed(x) >>> y;
// exception_code = 32'b0;
// carry = 0;
// end
// default: begin
// w = 32'b0;
// exception_code = 32'b0;
// carry = 0;
// end
// endcase
// z = (x==y) ? 1'b1 : 1'b0;
// end
endmodule