WIP
This commit is contained in:
parent
086a91ae5b
commit
fda8dafad7
128
src/Cpu/Alu.bsv
128
src/Cpu/Alu.bsv
@ -7,80 +7,76 @@
|
||||
import RV_ISA::*;
|
||||
export AluCfg, AluIfc(..), mkAlu, Execute(..);
|
||||
|
||||
function Maybe#(Bit#(32)) execute32(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
|
||||
|
||||
function Maybe#(Bit#(64)) execute64(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
|
||||
|
||||
typeclass Execute#(numeric type xlen);
|
||||
function Maybe#(Bit#(xlen)) execute(RVALUOperator operator, Bit#(xlen) operand1, Bit#(xlen) operand2);
|
||||
endtypeclass
|
||||
|
||||
instance Execute#(32);
|
||||
function execute = execute32;
|
||||
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 execute = execute64;
|
||||
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 {
|
||||
|
||||
@ -72,21 +72,54 @@ instance DefaultValue#(MachineStatus);
|
||||
};
|
||||
endinstance
|
||||
|
||||
interface MachineStatus_Ifc#(numeric type xlen);
|
||||
method Bit#(xlen) pack;
|
||||
method Action unpack(Bit#(xlen) bits);
|
||||
interface Get#(MachineStatus) getMachineStatus;
|
||||
interface Put#(MachineStatus) putMachineStatus;
|
||||
endinterface
|
||||
typeclass MachineStatusBits#(numeric type xlen);
|
||||
function Bit#(xlen) mstatus_pack(MachineStatus mstatus);
|
||||
function MachineStatus mstatus_unpack(Bit#(xlen) mstatus_packed);
|
||||
endtypeclass
|
||||
|
||||
module mkMachineStatus#(IsaCfg#(xlen) cfg)(MachineStatus_Ifc#(xlen))
|
||||
provisos(
|
||||
Add#(a__, 32, xlen)
|
||||
);
|
||||
Reg#(MachineStatus) mstatus <- mkReg(defaultValue);
|
||||
|
||||
function Bit#(32) packLower;
|
||||
instance MachineStatusBits#(32);
|
||||
function Bit#(32) mstatus_pack(MachineStatus mstatus);
|
||||
Bit#(1) sd = ((mstatus.vs | mstatus.fs | mstatus.xs) == 0 ? 0 : 1);
|
||||
return {
|
||||
sd,
|
||||
8'b0,
|
||||
pack(mstatus.tsr),
|
||||
pack(mstatus.tw),
|
||||
pack(mstatus.tvm),
|
||||
pack(mstatus.mxr),
|
||||
pack(mstatus.sum),
|
||||
pack(mstatus.mprv),
|
||||
pack(mstatus.xs),
|
||||
pack(mstatus.fs),
|
||||
pack(mstatus.mpp),
|
||||
pack(mstatus.vs),
|
||||
pack(mstatus.spp),
|
||||
pack(mstatus.mpie),
|
||||
pack(mstatus.ube),
|
||||
pack(mstatus.spie),
|
||||
1'b0,
|
||||
pack(mstatus.mie),
|
||||
1'b0,
|
||||
pack(mstatus.sie),
|
||||
1'b0
|
||||
};
|
||||
endfunction
|
||||
|
||||
function MachineStatus mstatus_unpack(Bit#(32) mstatus_packed);
|
||||
return defaultValue;
|
||||
endfunction
|
||||
endinstance
|
||||
|
||||
instance MachineStatusBits#(64);
|
||||
function Bit#(64) mstatus_pack(MachineStatus mstatus);
|
||||
Bit#(1) sd = ((mstatus.vs | mstatus.fs | mstatus.xs) == 0 ? 0 : 1);
|
||||
return {
|
||||
sd,
|
||||
25'b0,
|
||||
pack(mstatus.mbe),
|
||||
pack(mstatus.sbe),
|
||||
pack(mstatus.sxl),
|
||||
pack(mstatus.uxl),
|
||||
9'b0,
|
||||
pack(mstatus.tsr),
|
||||
pack(mstatus.tw),
|
||||
@ -110,41 +143,44 @@ module mkMachineStatus#(IsaCfg#(xlen) cfg)(MachineStatus_Ifc#(xlen))
|
||||
};
|
||||
endfunction
|
||||
|
||||
function Bit#(32) packUpper;
|
||||
return {
|
||||
26'b0,
|
||||
pack(mstatus.mbe),
|
||||
pack(mstatus.sbe),
|
||||
pack(mstatus.sxl),
|
||||
pack(mstatus.uxl)
|
||||
};
|
||||
function MachineStatus mstatus_unpack(Bit#(64) mstatus_packed);
|
||||
return defaultValue;
|
||||
endfunction
|
||||
endinstance
|
||||
|
||||
method Bit#(xlen) pack;
|
||||
Bit#(32) lower = packLower;
|
||||
Bit#(xlen) mstatus_ = 0;
|
||||
interface MachineStatus_Ifc#(numeric type xlen);
|
||||
method Action beginTrap(RVPrivilegeLevel currentPriv);
|
||||
interface Get#(Bit#(xlen)) getMachineStatus;
|
||||
interface Put#(Bit#(xlen)) putMachineStatus;
|
||||
endinterface
|
||||
|
||||
Bit#(1) sd = ((mstatus.vs | mstatus.fs | mstatus.xs) == 0 ? 0 : 1);
|
||||
mstatus_[valueof(xlen)-1] = sd;
|
||||
mstatus_[31:0] = lower;
|
||||
module mkMachineStatus#(IsaCfg#(xlen) cfg)(MachineStatus_Ifc#(xlen))
|
||||
provisos(
|
||||
Add#(a__, 32, xlen),
|
||||
MachineStatusBits#(xlen)
|
||||
);
|
||||
Reg#(Bit#(xlen)) mstatus <- mkReg(defaultValue);
|
||||
|
||||
if (valueof(xlen) == 64) begin
|
||||
mstatus_[valueof(xlen)-2:32] = packUpper;
|
||||
end
|
||||
method Action beginTrap(RVPrivilegeLevel currentPriv);
|
||||
// CurPriv => MSTATUS::MPP
|
||||
let mstatus_ = mstatus_unpack(mstatus);
|
||||
mstatus_.mpp = currentPriv;
|
||||
|
||||
return mstatus_;
|
||||
endmethod
|
||||
// MSTATUS::MIE => MSTATUS::MPIE
|
||||
mstatus_.mpie = mstatus_.mie;
|
||||
mstatus_.mie = False; // Disable interrupts
|
||||
|
||||
method Action unpack(Bit#(xlen) bits);
|
||||
mstatus <= mstatus_pack(mstatus_);
|
||||
endmethod
|
||||
|
||||
interface Get getMachineStatus = toGet(mstatus);
|
||||
interface Put putMachineStatus;
|
||||
method Action put(MachineStatus value);
|
||||
method Action put(Bit#(xlen) newValue);
|
||||
//
|
||||
// Only MPP, MIE, and MIE are writable.
|
||||
//
|
||||
MachineStatus mstatus_ = mstatus;
|
||||
MachineStatus mstatus_ = mstatus_unpack(mstatus);
|
||||
MachineStatus value = mstatus_unpack(newValue);
|
||||
|
||||
if (cfg.extS) begin
|
||||
mstatus_.mpp = value.mpp;
|
||||
@ -160,7 +196,7 @@ module mkMachineStatus#(IsaCfg#(xlen) cfg)(MachineStatus_Ifc#(xlen))
|
||||
mstatus_.mpie = value.mpie;
|
||||
mstatus_.mie = value.mie;
|
||||
|
||||
mstatus <= mstatus_;
|
||||
mstatus <= mstatus_pack(mstatus_);
|
||||
endmethod
|
||||
endinterface
|
||||
endmodule
|
||||
|
||||
@ -6,6 +6,12 @@ import Assert::*;
|
||||
module mkTopModule(Empty);
|
||||
Reg#(Bit#(20)) stepNumber <- mkReg(0);
|
||||
|
||||
IsaCfg#(32) rv32icfg = defaultValue;
|
||||
MachineStatus_Ifc#(32) rv32i <- mkMachineStatus(rv32icfg);
|
||||
|
||||
IsaCfg#(64) rv64icfg = defaultValue;
|
||||
MachineStatus_Ifc#(64) rv64i <- mkMachineStatus(rv64icfg);
|
||||
|
||||
(* no_implicit_conditions *)
|
||||
rule test;
|
||||
case(stepNumber)
|
||||
|
||||
@ -170,9 +170,7 @@ module mkCsrFile#(CsrFileCfg#(xlen) cfg)(CsrFile#(xlen))
|
||||
if (!isWARLIgnore(index)) begin
|
||||
case(index)
|
||||
// Machine Information Registers (MRO)
|
||||
/*
|
||||
csr_MVENDORID: result.value = extend(machineInfoCfg.mvendorid);
|
||||
*/
|
||||
csr_MARCHID: result.value = machineInfoCfg.marchid;
|
||||
csr_MIMPID: result.value = machineInfoCfg.mimpid;
|
||||
csr_MHARTID: result.value = machineInfoCfg.mhartid;
|
||||
@ -186,12 +184,12 @@ module mkCsrFile#(CsrFileCfg#(xlen) cfg)(CsrFile#(xlen))
|
||||
csr_MIDELEG: result.value = mideleg;
|
||||
csr_MEDELEG: result.value = medeleg;
|
||||
|
||||
csr_MSTATUS: result.value = mstatus.pack;
|
||||
/*
|
||||
csr_MSTATUS: result.value <- mstatus.getMachineStatus.get;
|
||||
|
||||
csr_MCYCLE, csr_CYCLE: begin
|
||||
result.value = mcycle;
|
||||
end
|
||||
*/
|
||||
|
||||
csr_MSCRATCH: result.value = mscratch;
|
||||
csr_MIP: result.value = mip;
|
||||
csr_MIE: result.value = mie;
|
||||
@ -232,7 +230,7 @@ module mkCsrFile#(CsrFileCfg#(xlen) cfg)(CsrFile#(xlen))
|
||||
// No-Op
|
||||
end
|
||||
csr_MSCRATCH: mscratch <= value;
|
||||
csr_MSTATUS: mstatus.unpack(value);
|
||||
csr_MSTATUS: mstatus.putMachineStatus.put(value);
|
||||
csr_MTVAL: mtval <= value;
|
||||
csr_MTVEC: mtvec <= value;
|
||||
csr_MIE: mie <= value;
|
||||
@ -327,23 +325,16 @@ module mkCsrFile#(CsrFileCfg#(xlen) cfg)(CsrFile#(xlen))
|
||||
Bit#(xlen) cause = 0;
|
||||
|
||||
let trapPrivilegeLevel = getTrapPrivilegeLevel(trap);
|
||||
/*
|
||||
|
||||
cause = zeroExtend(trap.cause);
|
||||
if (!trap.isInterrupt) begin
|
||||
cause[valueOf(xlen)-1] = 1;
|
||||
end
|
||||
*/
|
||||
|
||||
// PC => MEPC
|
||||
writeWithOffset1(trapPrivilegeLevel, csr_EPC, trapProgramCounter);
|
||||
|
||||
// CurPriv => MSTATUS::MPP
|
||||
let mstatus_ <- mstatus.getMachineStatus.get;
|
||||
mstatus_.mpp = currentPriv;
|
||||
|
||||
// MSTATUS::MIE => MSTATUS::MPIE
|
||||
mstatus_.mpie = mstatus_.mie;
|
||||
mstatus_.mie = False; // Disable interrupts
|
||||
mstatus.putMachineStatus.put(mstatus_);
|
||||
mstatus.beginTrap(currentPriv);
|
||||
|
||||
// cause => CAUSE
|
||||
writeWithOffset1(trapPrivilegeLevel, csr_CAUSE, cause);
|
||||
@ -354,14 +345,13 @@ module mkCsrFile#(CsrFileCfg#(xlen) cfg)(CsrFile#(xlen))
|
||||
let trapHandler = vectorTableBase;
|
||||
|
||||
// Check and handle a vectored trap handler table
|
||||
/*
|
||||
if (trapHandler[1:0] == 1) begin
|
||||
trapHandler[1:0] = 0;
|
||||
if(trap.isInterrupt) begin
|
||||
trapHandler = trapHandler + extend(4 * trap.cause);
|
||||
end
|
||||
end
|
||||
*/
|
||||
|
||||
currentPriv <= trapPrivilegeLevel;
|
||||
|
||||
return trapHandler;
|
||||
@ -372,15 +362,14 @@ module mkCsrFile#(CsrFileCfg#(xlen) cfg)(CsrFile#(xlen))
|
||||
|
||||
let readStatus <- readWithOffset1(currentPriv, csr_STATUS);
|
||||
if (readStatus.denied == False) begin
|
||||
/*
|
||||
MachineStatus#(xlen) mstatus = unpack(readStatus.value);
|
||||
let newPrivilegeLevel = mstatus.mpp;
|
||||
mstatus.mie = mstatus.mpie;
|
||||
mstatus.mpie = False;
|
||||
*/
|
||||
MachineStatus mstatus_ = mstatus_unpack(readStatus.value);
|
||||
let newPrivilegeLevel = mstatus_.mpp;
|
||||
mstatus_.mie = mstatus_.mpie;
|
||||
mstatus_.mpie = False;
|
||||
|
||||
// Attempt to update MSTATUS. The current privilege level may prevent this.
|
||||
/*
|
||||
let writeStatus <- writeInternal(csr_MSTATUS, pack(mstatus));
|
||||
|
||||
let writeStatus <- writeInternal(csr_MSTATUS, mstatus_pack(mstatus_));
|
||||
if (writeStatus.denied == False) begin
|
||||
currentPriv <= newPrivilegeLevel;
|
||||
readStatus <- readWithOffset1(currentPriv, csr_EPC);
|
||||
@ -388,7 +377,6 @@ module mkCsrFile#(CsrFileCfg#(xlen) cfg)(CsrFile#(xlen))
|
||||
newProgramCounter = readStatus.value;
|
||||
end
|
||||
end
|
||||
*/
|
||||
end
|
||||
return newProgramCounter;
|
||||
endmethod
|
||||
Loading…
x
Reference in New Issue
Block a user