E-Series/src/Cpu/Alu.bsv
John Terrell fda8dafad7
WIP
2023-04-23 10:45:13 -07:00

98 lines
3.5 KiB
Plaintext

//
// ALU
//
// This module is a Arithmetic Logic Unit (ALU) implementation for RISC-V. It is
// reponsible for mathematical operations inside the CPU.
//
import RV_ISA::*;
export AluCfg, AluIfc(..), mkAlu, Execute(..);
typeclass Execute#(numeric type xlen);
function Maybe#(Bit#(xlen)) execute(RVALUOperator operator, Bit#(xlen) operand1, Bit#(xlen) operand2);
endtypeclass
instance Execute#(32);
function Maybe#(Bit#(32)) execute(RVALUOperator operator, Bit#(32) operand1, Bit#(32) operand2);
let sum = operand1 + operand2;
let difference = operand1 - operand2;
let bitwise_and = operand1 & operand2;
let bitwise_or = operand1 | operand2;
let bitwise_xor = operand1 ^ operand2;
let sltu = (operand1 < operand2 ? 1 : 0);
let slt = (begin
Int#(32) signedOperand1 = unpack(pack(operand1));
Int#(32) signedOperand2 = unpack(pack(operand2));
(signedOperand1 < signedOperand2 ? 1 : 0);
end);
let sll = operand1 << operand2[4:0];
let sra = signedShiftRight(operand1, operand2[4:0]);
let srl = operand1 >> operand2[4:0];
return case(operator)
alu_ADD: tagged Valid sum;
alu_SUB: tagged Valid difference;
alu_AND: tagged Valid bitwise_and;
alu_OR: tagged Valid bitwise_or;
alu_XOR: tagged Valid bitwise_xor;
alu_SLTU: tagged Valid sltu;
alu_SLT: tagged Valid slt;
alu_SLL: tagged Valid sll;
alu_SRA: tagged Valid sra;
alu_SRL: tagged Valid srl;
default: tagged Invalid;
endcase;
endfunction
endinstance
instance Execute#(64);
function Maybe#(Bit#(64)) execute(RVALUOperator operator, Bit#(64) operand1, Bit#(64) operand2);
let sum = operand1 + operand2;
let difference = operand1 - operand2;
let bitwise_and = operand1 & operand2;
let bitwise_or = operand1 | operand2;
let bitwise_xor = operand1 ^ operand2;
let sltu = (operand1 < operand2 ? 1 : 0);
let slt = (begin
Int#(64) signedOperand1 = unpack(pack(operand1));
Int#(64) signedOperand2 = unpack(pack(operand2));
(signedOperand1 < signedOperand2 ? 1 : 0);
end);
let sll = operand1 << operand2[5:0];
let sra = signedShiftRight(operand1, operand2[5:0]);
let srl = operand1 >> operand2[5:0];
return case(operator)
alu_ADD: tagged Valid sum;
alu_SUB: tagged Valid difference;
alu_AND: tagged Valid bitwise_and;
alu_OR: tagged Valid bitwise_or;
alu_XOR: tagged Valid bitwise_xor;
alu_SLTU: tagged Valid sltu;
alu_SLT: tagged Valid slt;
alu_SLL: tagged Valid sll;
alu_SRA: tagged Valid sra;
alu_SRL: tagged Valid srl;
default: tagged Invalid;
endcase;
endfunction
endinstance
typedef struct {
} AluCfg#(numeric type xlen);
interface AluIfc#(numeric type xlen);
method Maybe#(Bit#(xlen)) execute(RVALUOperator operator, Bit#(xlen) operand1, Bit#(xlen) operand2);
endinterface
module mkAlu#(AluCfg#(xlen) cfg)(AluIfc#(xlen))
provisos(
Execute#(xlen)
);
method Maybe#(Bit#(xlen)) execute(RVALUOperator operator, Bit#(xlen) operand1, Bit#(xlen) operand2);
return execute(operator, operand1, operand2);
endmethod
endmodule