Replace enums-for-constants with structs wrapping a plain Bit#(n)

BSC does not play nicely with enums whose labels do not start at 0 and
increase linearly. Instead, in such cases, it generates a whole bunch of
conditions to "legalise" any read values, which causes an explosion of
logic in places like the ROB. Thus, use this ugly (but still typed)
alternative that, other than naming conventions enforced by BSC, looks
almost the same as an enum.
This commit is contained in:
Jessica Clarke
2020-07-15 02:43:50 +01:00
parent b65576b112
commit 7eff218288
20 changed files with 590 additions and 497 deletions

View File

@@ -758,69 +758,69 @@ module mkCsrFile #(Data hartid)(CsrFile);
function Reg#(Data) get_csr(CSR csr);
return (case (csr)
// User CSRs
CSRfflags: fflags_csr;
CSRfrm: frm_csr;
CSRfcsr: fcsr_csr;
CSRcycle: cycle_csr;
CSRtime: time_csr;
CSRinstret: instret_csr;
CSRterminate: terminate_csr;
CSRstats: stats_csr;
csrAddrFFLAGS: fflags_csr;
csrAddrFRM: frm_csr;
csrAddrFCSR: fcsr_csr;
csrAddrCYCLE: cycle_csr;
csrAddrTIME: time_csr;
csrAddrINSTRET: instret_csr;
csrAddrTERMINATE: terminate_csr;
csrAddrSTATS: stats_csr;
// Supervisor CSRs
CSRsstatus: sstatus_csr;
CSRsie: sie_csr;
CSRstvec: scrToCsr(stcc_reg); // Only accessed by debugger. CPU accesses decoded into cspecialrw
CSRscounteren: scounteren_csr;
CSRsscratch: sscratch_csr;
CSRsepc: scrToCsr(sepcc_reg[1]); // Only accessed by debugger. CPU accesses decoded into cspecialrw
CSRscause: scause_csr;
CSRstval: stval_csr;
CSRsip: sip_csr;
CSRsatp: satp_csr;
csrAddrSSTATUS: sstatus_csr;
csrAddrSIE: sie_csr;
csrAddrSTVEC: scrToCsr(stcc_reg); // Only accessed by debugger. CPU accesses decoded into cspecialrw
csrAddrSCOUNTEREN: scounteren_csr;
csrAddrSSCRATCH: sscratch_csr;
csrAddrSEPC: scrToCsr(sepcc_reg[1]); // Only accessed by debugger. CPU accesses decoded into cspecialrw
csrAddrSCAUSE: scause_csr;
csrAddrSTVAL: stval_csr;
csrAddrSIP: sip_csr;
csrAddrSATP: satp_csr;
// Machine CSRs
CSRmstatus: mstatus_csr;
CSRmisa: misa_csr;
CSRmedeleg: medeleg_csr;
CSRmideleg: mideleg_csr;
CSRmie: mie_csr;
CSRmtvec: scrToCsr(mtcc_reg); // Only accessed by debugger. CPU accesses decoded into cspecialrw
CSRmcounteren: mcounteren_csr;
CSRmscratch: mscratch_csr;
CSRmepc: scrToCsr(mepcc_reg[1]); // Only accessed by debugger. CPU accesses decoded into cspecialrw
CSRmcause: mcause_csr;
CSRmtval: mtval_csr;
CSRmip: mip_csr;
CSRmcycle: mcycle_csr;
CSRminstret: minstret_csr;
CSRmvendorid: mvendorid_csr;
CSRmarchid: marchid_csr;
CSRmimpid: mimpid_csr;
CSRmhartid: mhartid_csr;
CSRmccsr: csr_capcause(mccsr_reg);
csrAddrMSTATUS: mstatus_csr;
csrAddrMISA: misa_csr;
csrAddrMEDELEG: medeleg_csr;
csrAddrMIDELEG: mideleg_csr;
csrAddrMIE: mie_csr;
csrAddrMTVEC: scrToCsr(mtcc_reg); // Only accessed by debugger. CPU accesses decoded into cspecialrw
csrAddrMCOUNTEREN: mcounteren_csr;
csrAddrMSCRATCH: mscratch_csr;
csrAddrMEPC: scrToCsr(mepcc_reg[1]); // Only accessed by debugger. CPU accesses decoded into cspecialrw
csrAddrMCAUSE: mcause_csr;
csrAddrMTVAL: mtval_csr;
csrAddrMIP: mip_csr;
csrAddrMCYCLE: mcycle_csr;
csrAddrMINSTRET: minstret_csr;
csrAddrMVENDORID: mvendorid_csr;
csrAddrMARCHID: marchid_csr;
csrAddrMIMPID: mimpid_csr;
csrAddrMHARTID: mhartid_csr;
csrAddrMCCSR: csr_capcause(mccsr_reg);
`ifdef SECURITY
CSRmevbase: mevbase_csr;
CSRmevmask: mevmask_csr;
CSRmeatp: meatp_csr;
CSRmmrbm: mmrbm_csr;
CSRmemrbm: memrbm_csr;
CSRmparbase: mparbase_csr;
CSRmparmask: mparmask_csr;
CSRmeparbase: meparbase_csr;
CSRmeparmask: meparmask_csr;
CSRmspec: mspec_csr;
CSRtrng: trng_csr;
csrAddrMEVBASE: mevbase_csr;
csrAddrMEVMASK: mevmask_csr;
csrAddrMEATP: meatp_csr;
csrAddrMMRBM: mmrbm_csr;
csrAddrMEMRBM: memrbm_csr;
csrAddrMPARBASE: mparbase_csr;
csrAddrMPARMASK: mparmask_csr;
csrAddrMEPARBASE: meparbase_csr;
csrAddrMEPARMASK: meparmask_csr;
csrAddrMSPEC: mspec_csr;
csrAddrTRNG: trng_csr;
`endif
CSRtselect: rg_tselect;
CSRtdata1: rg_tdata1;
CSRtdata2: rg_tdata2;
CSRtdata3: rg_tdata3;
csrAddrTSELECT: rg_tselect;
csrAddrTDATA1: rg_tdata1;
csrAddrTDATA2: rg_tdata2;
csrAddrTDATA3: rg_tdata3;
`ifdef INCLUDE_GDB_CONTROL
CSRdcsr: rg_dcsr; // TODO: take NMI into account (cf. Piccolo/Flute)
CSRdpc: scrToCsr(rg_dpc);
CSRdscratch0: rg_dscratch0;
CSRdscratch1: rg_dscratch1;
csrAddrDCSR: rg_dcsr; // TODO: take NMI into account (cf. Piccolo/Flute)
csrAddrDPC: scrToCsr(rg_dpc);
csrAddrDSCRATCH0: rg_dscratch0;
csrAddrDSCRATCH1: rg_dscratch1;
`endif
default: readOnlyReg(64'b0);
@@ -831,22 +831,22 @@ module mkCsrFile #(Data hartid)(CsrFile);
function Reg#(CapReg) get_scr(SCR scr);
return (case (scr)
// User SCRs
SCR_DDC: ddc_reg;
scrAddrDDC: ddc_reg;
// User CSRs with accessSysRegs
// SCR_UTCC: utcc_reg;
// SCR_UTDC: utdc_reg;
// SCR_UScratchC: uScratchC_reg;
// SCR_UEPCC: uepcc_reg;
// scrAddrUTCC: utcc_reg;
// scrAddrUTDC: utdc_reg;
// scrAddrUScratchC: uScratchC_reg;
// scrAddrUEPCC: uepcc_reg;
// System CSRs with accessSysRegs
SCR_STCC: stcc_reg;
SCR_STDC: stdc_reg;
SCR_SScratchC: sScratchC_reg;
SCR_SEPCC: sepcc_reg[1];
scrAddrSTCC: stcc_reg;
scrAddrSTDC: stdc_reg;
scrAddrSScratchC: sScratchC_reg;
scrAddrSEPCC: sepcc_reg[1];
// Machine CSRs with accessSysRegs
SCR_MTCC: mtcc_reg;
SCR_MTDC: mtdc_reg;
SCR_MScratchC: mScratchC_reg;
SCR_MEPCC: mepcc_reg[1];
scrAddrMTCC: mtcc_reg;
scrAddrMTDC: mtdc_reg;
scrAddrMScratchC: mScratchC_reg;
scrAddrMEPCC: mepcc_reg[1];
endcase);
endfunction
@@ -864,12 +864,12 @@ module mkCsrFile #(Data hartid)(CsrFile);
return (
case (csr)
// Machine CSRs
CSRmisa: {getXLBits, 36'b0, getExtensionBits(isa)};
CSRmvendorid: 0;
CSRmarchid: 0;
CSRmimpid: 0;
CSRmhartid: hartid;
CSRmstatus: fn_mstatus_val (getXLBits, // sxl
csrAddrMISA: {getXLBits, 36'b0, getExtensionBits(isa)};
csrAddrMVENDORID: 0;
csrAddrMARCHID: 0;
csrAddrMIMPID: 0;
csrAddrMHARTID: hartid;
csrAddrMSTATUS: fn_mstatus_val (getXLBits, // sxl
getXLBits, // uxl
x [22], // tsr
x [21], // tw
@@ -887,17 +887,17 @@ module mkCsrFile #(Data hartid)(CsrFile);
x [3], // ie_vec[prvM]
x [1], // ie_vec[prvS]
x [0]); // ie_vec[prvU]
CSRmedeleg: { 35'b0, x[28:26], 10'b0, x[15], 1'b0, x[13:12], x[11], 1'b0, x[9:0]};
CSRmideleg: { 52'b0, x[11], 1'b0, x[9:8], x[7], 1'b0, x[5:4], x[3], 1'b0, x[1:0]};
CSRmip: ((mip_csr & (~ mip_mie_warl_mask)) | (x & mip_mie_warl_mask));
CSRmie: (x & mip_mie_warl_mask);
CSRmcounteren: { 61'b0, x[2:0]};
CSRmcause: { x[63], 59'b0, x[3:0] };
csrAddrMEDELEG: { 35'b0, x[28:26], 10'b0, x[15], 1'b0, x[13:12], x[11], 1'b0, x[9:0]};
csrAddrMIDELEG: { 52'b0, x[11], 1'b0, x[9:8], x[7], 1'b0, x[5:4], x[3], 1'b0, x[1:0]};
csrAddrMIP: ((mip_csr & (~ mip_mie_warl_mask)) | (x & mip_mie_warl_mask));
csrAddrMIE: (x & mip_mie_warl_mask);
csrAddrMCOUNTEREN: { 61'b0, x[2:0]};
csrAddrMCAUSE: { x[63], 59'b0, x[3:0] };
CSRtdata1: { 4'b0, x [59:0] }; // Force tdata.type == 0 ("no trigger at this tselect")
csrAddrTDATA1: { 4'b0, x [59:0] }; // Force tdata.type == 0 ("no trigger at this tselect")
// Supervisor level CSRs
CSRsstatus: fn_sstatus_val (getXLBits, // uxl
csrAddrSSTATUS: fn_sstatus_val (getXLBits, // uxl
x [19], // mxr
x [18], // sum
2'b0, // xs
@@ -907,23 +907,23 @@ module mkCsrFile #(Data hartid)(CsrFile);
x [4], // prev_ie_vec[prvU]
x [1], // ie_vec[prvS]
x [0]); // ie_vec[prvU]
CSRsip: ((sip_csr & (~ sip_sie_warl_mask)) | (x & sip_sie_warl_mask));
CSRsie: (x & sip_sie_warl_mask);
CSRscounteren: { 61'b0, x[2:0]};
CSRscause: { x[63], 59'b0, x[3:0] };
CSRsatp: { x[63], 3'b0, asid, x [43:0] };
csrAddrSIP: ((sip_csr & (~ sip_sie_warl_mask)) | (x & sip_sie_warl_mask));
csrAddrSIE: (x & sip_sie_warl_mask);
csrAddrSCOUNTEREN: { 61'b0, x[2:0]};
csrAddrSCAUSE: { x[63], 59'b0, x[3:0] };
csrAddrSATP: { x[63], 3'b0, asid, x [43:0] };
// User level CSRs
CSRfflags: { 59'b0, x [4:0] };
CSRfrm: { 61'b0, x [2:0] };
CSRfcsr: { 56'b0, x [7:0] };
csrAddrFFLAGS: { 59'b0, x [4:0] };
csrAddrFRM: { 61'b0, x [2:0] };
csrAddrFCSR: { 56'b0, x [7:0] };
`ifdef INCLUDE_GDB_CONTROL
// Debug Mode CSRs
CSRdcsr: { 32'b0, x[31:28], 12'b0, x[14], 1'b0, x[13:6], 1'b0, x[4:0] };
csrAddrDCSR: { 32'b0, x[31:28], 12'b0, x[14], 1'b0, x[13:6], 1'b0, x[4:0] };
`endif
default: x;
default: x;
endcase);
endfunction
@@ -941,7 +941,7 @@ module mkCsrFile #(Data hartid)(CsrFile);
method Action csrInstWr(CSR csr, Data x);
get_csr(csr)._write(x);
`ifdef INCLUDE_GDB_CONTROL
if (csr == CSRdcsr) begin
if (csr == csrAddrDCSR) begin
let prv = x [1:0];
prv_reg <= prv;
end
@@ -1033,19 +1033,19 @@ module mkCsrFile #(Data hartid)(CsrFile);
tagged Exception .e: begin
cause_code = pack(e);
trap_val = (case(e)
IllegalInst: zeroExtend (orig_inst);
InstAddrMisaligned, Breakpoint: return getOffset(pcc); // TODO do we want getAddr?
excIllegalInst: zeroExtend (orig_inst);
excInstAddrMisaligned, excBreakpoint: return getOffset(pcc); // TODO do we want getAddr?
InstAccessFault, InstPageFault,
LoadAddrMisaligned, LoadAccessFault,
StoreAddrMisaligned, StoreAccessFault,
LoadPageFault, StorePageFault: return addr;
excInstAccessFault, excInstPageFault,
excLoadAddrMisaligned, excLoadAccessFault,
excStoreAddrMisaligned, excStoreAccessFault,
excLoadPageFault, excStorePageFault: return addr;
default: return 0;
endcase);
end
tagged CapException .ce: begin
cause_code = pack(CHERIFault);
cause_code = pack(excCHERIFault);
trap_val = zeroExtend({pack(ce.cheri_exc_reg), pack(ce.cheri_exc_code)});
end
tagged Interrupt .i: begin
@@ -1071,7 +1071,7 @@ module mkCsrFile #(Data hartid)(CsrFile);
// check if trap is delegated
Bool deleg = prv_reg <= prvS && (case(t) matches
tagged Exception .e: return medeleg_csr[pack(e)] == 1;
tagged CapException .ce: return medeleg_csr[pack(CHERIFault)] == 1;
tagged CapException .ce: return medeleg_csr[pack(excCHERIFault)] == 1;
tagged Interrupt .i: return mideleg_csr[pack(i)] == 1;
endcase);
// handle the trap

View File

@@ -0,0 +1,26 @@
`CHERIException(None, 5'd0)
`CHERIException(LengthViolation, 5'd1)
`CHERIException(TagViolation, 5'd2)
`CHERIException(SealViolation, 5'd3)
`CHERIException(TypeViolation, 5'd4)
`CHERIException(CallTrap, 5'd5)
`CHERIException(ReturnTrap, 5'd6)
`CHERIException(StackUnderflow, 5'd7)
`CHERIException(SoftwarePermViolation, 5'd8)
`CHERIException(MMUStoreCapProhibit, 5'd9)
`CHERIException(RepresentViolation, 5'd10)
`CHERIException(UnalignedBase, 5'd11)
// 5'd12 - 5'd15 reserved
`CHERIException(GlobalViolation, 5'd16)
`CHERIException(PermitXViolation, 5'd17)
`CHERIException(PermitRViolation, 5'd18)
`CHERIException(PermitWViolation, 5'd19)
`CHERIException(PermitRCapViolation, 5'd20)
`CHERIException(PermitWCapViolation, 5'd21)
`CHERIException(PermitWLocalCapViolation, 5'd22)
`CHERIException(PermitSealViolation, 5'd23)
`CHERIException(PermitASRViolation, 5'd24)
`CHERIException(PermitCCallViolation, 5'd25)
`CHERIException(PermitUnsealViolation, 5'd26)
`CHERIException(PermitSetCIDViolation, 5'd27)
// 5'd28 - 5'd31 reserved

View File

@@ -36,41 +36,29 @@ typedef TMul#(XLEN, 2) CLEN;
// Exception codes
typedef enum {
None = 5'd0,
LengthViolation = 5'd1,
TagViolation = 5'd2,
SealViolation = 5'd3,
TypeViolation = 5'd4,
CallTrap = 5'd5,
ReturnTrap = 5'd6,
StackUnderflow = 5'd7,
SoftwarePermViolation = 5'd8,
MMUStoreCapProhibit = 5'd9,
RepresentViolation = 5'd10,
UnalignedBase = 5'd11,
// 5'd12 - 5'd15 reserved
GlobalViolation = 5'd16,
PermitXViolation = 5'd17,
PermitRViolation = 5'd18,
PermitWViolation = 5'd19,
PermitRCapViolation = 5'd20,
PermitWCapViolation = 5'd21,
PermitWLocalCapViolation = 5'd22,
PermitSealViolation = 5'd23,
PermitASRViolation = 5'd24,
PermitCCallViolation = 5'd25,
PermitUnsealViolation = 5'd26,
PermitSetCIDViolation = 5'd27
// 5'd28 - 5'd31 reserved
} CHERIException deriving(Bits, Eq, FShow);
typedef struct { Bit#(5) code; } CHERIException deriving(Bits, Eq);
`define CHERIException(n, v) CHERIException cheriExc``n = CHERIException { code: v };
`include "CHERIExceptions.bsvi"
`undef CHERIException
instance FShow#(CHERIException);
function Fmt fshow(CHERIException exc);
return (case(exc.code)
`define CHERIException(n, v) v: $format(`"``cheriExc``n```");
`include "CHERIExceptions.bsvi"
`undef CHERIException
default: $format("cheriExcUnknown");
endcase);
endfunction
endinstance
typedef struct {
Bit #(6) cheri_exc_reg;
CHERIException cheri_exc_code;
} CSR_XCapCause deriving(Bits, Eq, FShow);
CSR_XCapCause noCapCause = CSR_XCapCause {cheri_exc_code: None,
CSR_XCapCause noCapCause = CSR_XCapCause {cheri_exc_code: cheriExcNone,
cheri_exc_reg: unpack(0)};
function Bit#(64) xccsr_to_word(CSR_XCapCause xccsr);
@@ -87,20 +75,31 @@ endfunction
// SCR map
typedef enum {
`define SCR(s,v) s = v,
`include "SCRs.bsvi"
`undef SCR
// As with CSRs, SCR that catches all unimplemented SCRs
SCR_None = 5'd10
} SCR deriving(Bits, Eq, FShow, Bounded);
typedef struct { Bit#(5) addr; } SCR deriving(Bits, Eq);
function SCR unpackSCR(Bit#(5) x);
return (case(x)
`define SCR(s,v) pack(SCR'(s)): (s);
`define SCR(n, v) SCR scrAddr``n = SCR { addr: v };
`include "SCRs.bsvi"
// As with CSRs, SCR that catches all unimplemented SCRs
`SCR(None, 5'd10)
`undef SCR
instance FShow#(SCR);
function Fmt fshow(SCR scr);
return (case(scr.addr)
`define SCR(n, v) v: $format(`"``scrAddr``n```");
`include "SCRs.bsvi"
`undef SCR
default : (SCR_None);
default: $format("scrAddrNone");
endcase);
endfunction
endinstance
function SCR unpackSCR(Bit#(5) addr);
return (case(addr)
`define SCR(n, v) v: scrAddr``n;
`include "SCRs.bsvi"
`undef SCR
default: scrAddrNone;
endcase);
endfunction

View File

@@ -1,17 +1,17 @@
`SCR(SCR_PCC , 5'd00)
`SCR(SCR_DDC , 5'd01)
`SCR(PCC, 5'd00)
`SCR(DDC, 5'd01)
//`SCR(SCR_UTCC , 5'd0)
//`SCR(SCR_UTDC , 5'd05)
//`SCR(SCR_UScratchC , 5'd06)
//`SCR(SCR_UEPCC , 5'd07)
//`SCR(UTCC, 5'd0)
//`SCR(UTDC, 5'd05)
//`SCR(UScratchC, 5'd06)
//`SCR(UEPCC, 5'd07)
`SCR(SCR_STCC , 5'd12)
`SCR(SCR_STDC , 5'd13)
`SCR(SCR_SScratchC , 5'd14)
`SCR(SCR_SEPCC , 5'd15)
`SCR(STCC, 5'd12)
`SCR(STDC, 5'd13)
`SCR(SScratchC, 5'd14)
`SCR(SEPCC, 5'd15)
`SCR(SCR_MTCC , 5'd28)
`SCR(SCR_MTDC , 5'd29)
`SCR(SCR_MScratchC , 5'd30)
`SCR(SCR_MEPCC , 5'd31)
`SCR(MTCC, 5'd28)
`SCR(MTDC, 5'd29)
`SCR(MScratchC, 5'd30)
`SCR(MEPCC, 5'd31)

View File

@@ -376,7 +376,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
if (!( (check.check_low >= check.authority_base) &&
(check.check_inclusive ? (check.check_high <= check.authority_top )
: (check.check_high < check.authority_top ))))
x.capException = Valid(CSR_XCapCause{cheri_exc_reg: check.authority_idx, cheri_exc_code: LengthViolation});
x.capException = Valid(CSR_XCapCause{cheri_exc_reg: check.authority_idx, cheri_exc_code: cheriExcLengthViolation});
end
// update the instruction in the reorder buffer.

View File

@@ -350,7 +350,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
rule rl_send_mip_csr_change_to_tv ((! rg_just_after_reset) && send_mip_csr_change_to_tv);
fa_to_TV (way0, rg_serial_num,
tagged Valid (tuple2 (pack (CSRmip), new_mip_csr_val)),
tagged Valid (tuple2 (pack (csrAddrMIP), new_mip_csr_val)),
no_deq_data, no_fflags, no_mstatus, no_trap_updates, no_ret_updates);
rg_old_mip_csr_val <= new_mip_csr_val;
rg_serial_num <= rg_serial_num + 1;
@@ -417,10 +417,10 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
function TraceStateBundle getTSB();
return TraceStateBundle{
sepc: csrf.rd(CSRsepc),
mepc: csrf.rd(CSRmepc),
stvec: csrf.rd(CSRstvec),
mtvec: csrf.rd(CSRmtvec)
sepc: csrf.rd(csrAddrSEPC),
mepc: csrf.rd(csrAddrMEPC),
stvec: csrf.rd(csrAddrSTVEC),
mtvec: csrf.rd(csrAddrMTVEC)
};
endfunction
`endif
@@ -458,7 +458,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
stqEmpty: inIfc.stqEmpty,
tlbNoPendingReq: inIfc.tlbNoPendingReq,
prv: csrf.decodeInfo.prv,
instCount: csrf.rd(CSRinstret)
instCount: csrf.rd(csrAddrINSTRET)
};
endfunction
@@ -647,8 +647,8 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
// record trap info
Addr vaddr = 0;
if ( (trap == tagged Exception InstAccessFault)
|| (trap == tagged Exception InstPageFault)) begin
if ( (trap == tagged Exception excInstAccessFault)
|| (trap == tagged Exception excInstPageFault)) begin
vaddr = getAddr(x.pc);
end
else if(x.ppc_vaddr_csrData matches tagged VAddr .va) begin
@@ -726,7 +726,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
end
`ifdef INCLUDE_GDB_CONTROL
else if (trap.trap == tagged Exception Breakpoint) begin
else if (trap.trap == tagged Exception excBreakpoint) begin
inIfc.commitCsrInstOrInterrupt; // TODO: Why?
end
`endif
@@ -734,9 +734,9 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
Bool debugger_halt = False;
`ifdef INCLUDE_GDB_CONTROL
if ((trap.trap == tagged Interrupt DebugHalt)
|| (trap.trap == tagged Interrupt DebugStep)
|| ((trap.trap == tagged Exception Breakpoint) && (csrf.dcsr_break_bit == 1'b1)))
if ((trap.trap == tagged Interrupt intrDebugHalt)
|| (trap.trap == tagged Interrupt intrDebugStep)
|| ((trap.trap == tagged Exception excBreakpoint) && (csrf.dcsr_break_bit == 1'b1)))
begin
debugger_halt = True;
@@ -745,9 +745,9 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
makeSystemConsistent_for_debug_mode;
// Save values in debugger CSRs
Bit #(3) dcsr_cause = ( (trap.trap == tagged Interrupt DebugHalt)
Bit #(3) dcsr_cause = ( (trap.trap == tagged Interrupt intrDebugHalt)
? 3
: ( (trap.trap == tagged Interrupt DebugStep)
: ( (trap.trap == tagged Interrupt intrDebugStep)
? 4
: 1));
csrf.dcsr_cause_write (dcsr_cause);
@@ -895,15 +895,15 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
x.ppc_vaddr_csrData = tagged CSRData data_warl_xformed;
if (x.will_dirty_fpu_state) begin
Data old_mstatus = csrf.rd (CSRmstatus);
Data old_mstatus = csrf.rd (csrAddrMSTATUS);
new_mstatus = { 1'b1, old_mstatus [62:15], 2'b11, old_mstatus [12:0] };
end
`endif
// check if satp is modified or not
write_satp = csr_idx == CSRsatp;
write_satp = csr_idx == csrAddrSATP;
`ifdef SECURITY
flush_security = csr_idx == CSRmflush;
flush_security = csr_idx == csrAddrMFLUSH;
`endif
end
if(x.iType == Scr) begin

View File

@@ -644,7 +644,7 @@ module mkFetchStage(FetchStage);
end
default: begin
// Access fault
cause = Valid (InstAccessFault);
cause = Valid (excInstAccessFault);
`ifdef DEBUG_WEDGE
lastImemReq <= 'hafafafafafafafaf;
`endif
@@ -925,7 +925,7 @@ module mkFetchStage(FetchStage);
// update cause if decode exception and no earlier (TLB) exception
if (!isValid(cause)) begin
cause = decode_result.illegalInst ? tagged Valid IllegalInst : tagged Invalid;
cause = decode_result.illegalInst ? tagged Valid excIllegalInst : tagged Invalid;
end
let dInst = decode_result.dInst;

View File

@@ -441,7 +441,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
// check conservative scoreboard
let regsReady = inIfc.sbCons_lazyLookup(x.regs);
CapPipe ddc = cast(inIfc.scaprf_rd(SCR_DDC));
CapPipe ddc = cast(inIfc.scaprf_rd(scrAddrDDC));
// get rVal1 (check bypass)
CapPipe rVal1 = nullCap;
@@ -509,7 +509,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
lsq.updateData(stTag, d);
end
CapPipe ddc = cast(inIfc.scaprf_rd(SCR_DDC));
CapPipe ddc = cast(inIfc.scaprf_rd(scrAddrDDC));
// go to next stage by sending to TLB
dTlb.procReq(DTlbReq {
@@ -545,10 +545,10 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
if (!isValid(cause) && (paddr < 'h80000000 || paddr >= 'h80800000)) begin
case(x.mem_func)
Ld, Lr: begin
cause = Valid(Exception(LoadAccessFault));
cause = Valid(Exception(excLoadAccessFault));
end
default: begin
cause = Valid(Exception(StoreAccessFault));
cause = Valid(Exception(excStoreAccessFault));
end
endcase
end
@@ -568,10 +568,10 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
if(!isValid(cause) && x.misaligned) begin
case(x.mem_func)
Ld, Lr: begin
cause = Valid(Exception(LoadAddrMisaligned));
cause = Valid(Exception(excLoadAddrMisaligned));
end
default: begin
cause = Valid(Exception(StoreAddrMisaligned));
cause = Valid(Exception(excStoreAddrMisaligned));
end
endcase
end
@@ -582,10 +582,10 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
if(!isValid(cause) && isMMIO) begin
case(x.mem_func)
Lr: begin
cause = Valid(Exception(LoadAccessFault));
cause = Valid(Exception(excLoadAccessFault));
end
Sc: begin
cause = Valid(Exception(StoreAccessFault));
cause = Valid(Exception(excStoreAccessFault));
end
endcase
end
@@ -600,7 +600,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
if (!( (check.check_low >= check.authority_base) &&
(check.check_inclusive ? (check.check_high <= check.authority_top )
: (check.check_high < check.authority_top ))))
x.capException = Valid(CSR_XCapCause{cheri_exc_reg: check.authority_idx, cheri_exc_code: LengthViolation});
x.capException = Valid(CSR_XCapCause{cheri_exc_reg: check.authority_idx, cheri_exc_code: cheriExcLengthViolation});
end
if (x.capException matches tagged Valid .c) cause = Valid(CapException(c));
Bool access_at_commit = !isValid(cause) && (isMMIO || isLrScAmo);
@@ -1034,7 +1034,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
lsq.deqLd;
waitLrScAmoMMIOResp <= Invalid;
// set ROB to raise access fault
inIfc.rob_setExecuted_deqLSQ(lsqDeqLd.instTag, Valid(Exception(LoadAccessFault)), Invalid
inIfc.rob_setExecuted_deqLSQ(lsqDeqLd.instTag, Valid(Exception(excLoadAccessFault)), Invalid
`ifdef RVFI
, ExtraTraceBundle{
regWriteData: memData[pack(lsqDeqIdx)],
@@ -1393,7 +1393,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
lsq.deqSt;
waitLrScAmoMMIOResp <= Invalid;
// set ROB to raise access fault
inIfc.rob_setExecuted_deqLSQ(lsqDeqSt.instTag, Valid(Exception(StoreAccessFault)), Invalid
inIfc.rob_setExecuted_deqLSQ(lsqDeqSt.instTag, Valid(Exception(excStoreAccessFault)), Invalid
`ifdef RVFI
, ExtraTraceBundle{
regWriteData: fromMemTaggedData(lsqDeqSt.stData),

View File

@@ -184,8 +184,8 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
`endif
`ifdef INCLUDE_GDB_CONTROL
// Is set to Valid DebugHalt on debugger halt request
// Is set to Valid DebugStep on dcsr[stepbit]==1 and one instruction has been processed.
// Is set to Valid intrDebugHalt on debugger halt request
// Is set to Valid intrDebugStep on dcsr[stepbit]==1 and one instruction has been processed.
// Note (step): 1st instruction is guaranteed architectural, cannot possibly be speculative.
// Note (step): 1st instruction may trap; we halt pointing at the trap vector
Reg #(Maybe #(Interrupt)) rg_m_halt_req <- mkReg (tagged Invalid);
@@ -193,9 +193,9 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
function Action fa_step_check;
action
if (csrf.dcsr_step_bit == 1'b1) begin
rg_m_halt_req <= tagged Valid DebugStep;
rg_m_halt_req <= tagged Valid intrDebugStep;
if (verbosity >= 2)
$display ("%0d: %m.renameStage.fa_step_check: rg_m_halt_req <= tagged Valid DebugStep", cur_cycle);
$display ("%0d: %m.renameStage.fa_step_check: rg_m_halt_req <= tagged Valid intrDebugStep", cur_cycle);
end
endaction
endfunction
@@ -250,10 +250,10 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|| fn_ArchReg_is_FpuReg (x.regs.src2)
|| isValid (x.regs.src3)
|| fn_ArchReg_is_FpuReg (x.regs.dst));
let mstatus = csrf.rd (CSRmstatus);
let mstatus = csrf.rd (csrAddrMSTATUS);
// Check CSR access permission
if (x.dInst.csr matches tagged Valid CSRfcsr &&& x.dInst.iType == Csr) begin
if (x.dInst.csr == tagged Valid csrAddrFCSR && x.dInst.iType == Csr) begin
fpr_access = True;
end
@@ -284,7 +284,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
trap = new_exception;
end
else if (fs_trap || wfi_trap) begin
trap = tagged Valid (tagged Exception IllegalInst);
trap = tagged Valid (tagged Exception excIllegalInst);
end
return trap;
endfunction
@@ -319,12 +319,12 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
fa_step_check;
if (verbosity >= 1) begin
if (firstTrap == tagged Valid (tagged Interrupt DebugHalt))
$display ("%0d: %m.renameStage.doRenaming_Trap: DebugHalt", cur_cycle);
else if (firstTrap == tagged Valid (tagged Interrupt DebugStep))
$display ("%0d: %m.renameStage.doRenaming_Trap: DebugStep", cur_cycle);
else if (firstTrap == tagged Valid (tagged Exception Breakpoint))
$display ("%0d: %m.renameStage.doRenaming_Trap: Breakpoint", cur_cycle);
if (firstTrap == tagged Valid (tagged Interrupt intrDebugHalt))
$display ("%0d: %m.renameStage.doRenaming_Trap: intrDebugHalt", cur_cycle);
else if (firstTrap == tagged Valid (tagged Interrupt intrDebugStep))
$display ("%0d: %m.renameStage.doRenaming_Trap: intrDebugStep", cur_cycle);
else if (firstTrap == tagged Valid (tagged Exception excBreakpoint))
$display ("%0d: %m.renameStage.doRenaming_Trap: excBreakpoint", cur_cycle);
end
`endif
let x = fetchStage.pipelines[0].first;
@@ -382,7 +382,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
inIfc.issueCsrInstOrInterrupt;
end
`ifdef INCLUDE_GDB_CONTROL
else if (firstTrap == tagged Valid (tagged Exception Breakpoint)) begin
else if (firstTrap == tagged Valid (tagged Exception excBreakpoint)) begin
inIfc.issueCsrInstOrInterrupt;
end
`endif
@@ -537,7 +537,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
// CSR instrs that touch certain FP CSRs will dirty FP state.
if (dInst.csr matches tagged Valid .csr
&&& ((dInst.iType == Csr)
&& ((csr == CSRfflags) || (csr == CSRfrm) || (csr == CSRfcsr))))
&& ((csr == csrAddrFFLAGS) || (csr == csrAddrFRM) || (csr == csrAddrFCSR))))
begin
Bool is_CSRR_W = (dInst.execFunc == tagged Alu Csrw);
Bool rs1_is_0 = ((arch_regs.src2 == tagged Valid (tagged Gpr 0))
@@ -593,8 +593,8 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
// M mode: turn off speculation for mem inst only
// non-M mode: controlled by mspec CSR
Bool machineMode = csrf.decodeInfo.prv == prvM;
Bool specNone = !machineMode && csrf.rd(CSRmspec) == zeroExtend(mSpecNone);
Bool specNonMem = machineMode || csrf.rd(CSRmspec) == zeroExtend(mSpecNonMem);
Bool specNone = !machineMode && csrf.rd(csrAddrMSPEC) == zeroExtend(mSpecNone);
Bool specNonMem = machineMode || csrf.rd(csrAddrMSPEC) == zeroExtend(mSpecNonMem);
`ifdef PERF_COUNT
rule incSpecNoneCycles(inIfc.doStats && specNone);
@@ -1142,7 +1142,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
`ifdef INCLUDE_GDB_CONTROL
if (debug_step)
rg_m_halt_req <= tagged Valid DebugStep;
rg_m_halt_req <= tagged Valid intrDebugStep;
`endif
// only fire this rule if we make some progress
@@ -1188,7 +1188,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
`ifdef INCLUDE_GDB_CONTROL
method Action debug_halt_req () if (rg_m_halt_req == tagged Invalid);
rg_m_halt_req <= tagged Valid DebugHalt;
rg_m_halt_req <= tagged Valid intrDebugHalt;
if (verbosity >= 1)
$display ("%0d: %m.renameStage.renameStage.debug_halt_req", cur_cycle);
endmethod

View File

@@ -1,72 +1,72 @@
// user standard CSRs
`CSR(CSRfflags , 12'h001)
`CSR(CSRfrm , 12'h002)
`CSR(CSRfcsr , 12'h003)
`CSR(CSRcycle , 12'hc00)
`CSR(CSRtime , 12'hc01)
`CSR(CSRinstret , 12'hc02)
// user non-standard CSRs (TODO)
`CSR(CSRterminate , 12'h800) // terminate (used to exit Linux)
`CSR(CSRstats , 12'h801) // turn on/off perf counters
// `CSR(CSRuccsr , 12'h8c0)
// supervisor standard `CSR(CSRs
`CSR(CSRsstatus , 12'h100)
// no user trap handler, so no se/ideleg
`CSR(CSRsie , 12'h104)
`CSR(CSRstvec , 12'h105)
`CSR(CSRscounteren , 12'h106)
`CSR(CSRsscratch , 12'h140)
`CSR(CSRsepc , 12'h141)
`CSR(CSRscause , 12'h142)
`CSR(CSRstval , 12'h143) // it's still called sbadaddr in spike
`CSR(CSRsip , 12'h144)
`CSR(CSRsatp , 12'h180) // it's still called sptbr in spike
`CSR(CSRsccsr , 12'h9c0)
// machine standard CSRs
`CSR(CSRmstatus , 12'h300)
`CSR(CSRmisa , 12'h301)
`CSR(CSRmedeleg , 12'h302)
`CSR(CSRmideleg , 12'h303)
`CSR(CSRmie , 12'h304)
`CSR(CSRmtvec , 12'h305)
`CSR(CSRmcounteren , 12'h306)
`CSR(CSRmscratch , 12'h340)
`CSR(CSRmepc , 12'h341)
`CSR(CSRmcause , 12'h342)
`CSR(CSRmtval , 12'h343) // it's still called mbadaddr in spike
`CSR(CSRmip , 12'h344)
`CSR(CSRmcycle , 12'hb00)
`CSR(CSRminstret , 12'hb02)
`CSR(CSRmvendorid , 12'hf11)
`CSR(CSRmarchid , 12'hf12)
`CSR(CSRmimpid , 12'hf13)
`CSR(CSRmhartid , 12'hf14)
`CSR(CSRmccsr , 12'hbc0)
// user standard CSRs
`CSR(FFLAGS, 12'h001)
`CSR(FRM, 12'h002)
`CSR(FCSR, 12'h003)
`CSR(CYCLE, 12'hc00)
`CSR(TIME, 12'hc01)
`CSR(INSTRET, 12'hc02)
// user non-standard CSRs (TODO)
`CSR(TERMINATE, 12'h800) // terminate (used to exit Linux)
`CSR(STATS, 12'h801) // turn on/off perf counters
// `CSR(UCCSR, 12'h8c0)
// supervisor standard CSRs
`CSR(SSTATUS, 12'h100)
// no user trap handler, so no se/ideleg
`CSR(SIE, 12'h104)
`CSR(STVEC, 12'h105)
`CSR(SCOUNTEREN, 12'h106)
`CSR(SSCRATCH, 12'h140)
`CSR(SEPC, 12'h141)
`CSR(SCAUSE, 12'h142)
`CSR(STVAL, 12'h143) // it's still called sbadaddr in spike
`CSR(SIP, 12'h144)
`CSR(SATP, 12'h180) // it's still called sptbr in spike
`CSR(SCCSR, 12'h9c0)
// machine standard CSRs
`CSR(MSTATUS, 12'h300)
`CSR(MISA, 12'h301)
`CSR(MEDELEG, 12'h302)
`CSR(MIDELEG, 12'h303)
`CSR(MIE, 12'h304)
`CSR(MTVEC, 12'h305)
`CSR(MCOUNTEREN, 12'h306)
`CSR(MSCRATCH, 12'h340)
`CSR(MEPC, 12'h341)
`CSR(MCAUSE, 12'h342)
`CSR(MTVAL, 12'h343) // it's still called mbadaddr in spike
`CSR(MIP, 12'h344)
`CSR(MCYCLE, 12'hb00)
`CSR(MINSTRET, 12'hb02)
`CSR(MVENDORID, 12'hf11)
`CSR(MARCHID, 12'hf12)
`CSR(MIMPID, 12'hf13)
`CSR(MHARTID, 12'hf14)
`CSR(MCCSR, 12'hbc0)
`ifdef SECURITY
// sanctum machine CSR
`CSR(CSRmevbase , 12'h7c0)
`CSR(CSRmevmask , 12'h7c1)
`CSR(CSRmeatp , 12'h7c2)
`CSR(CSRmmrbm , 12'h7c3)
`CSR(CSRmemrbm , 12'h7c4)
`CSR(CSRmparbase , 12'h7c5)
`CSR(CSRmparmask , 12'h7c6)
`CSR(CSRmeparbase , 12'h7c7)
`CSR(CSRmeparmask , 12'h7c8)
`CSR(CSRmflush , 12'h7c9) // flush pipeline + cache
`CSR(CSRmspec , 12'h7ca) // control speculation
// sanctum user CSR
`CSR(CSRtrng , 12'hcc0) // random number for secure boot
// sanctum machine CSR
`CSR(MEVBASE, 12'h7c0)
`CSR(MEVMASK, 12'h7c1)
`CSR(MEATP, 12'h7c2)
`CSR(MMRBM, 12'h7c3)
`CSR(MEMRBM, 12'h7c4)
`CSR(MPARBASE, 12'h7c5)
`CSR(MPARMASK, 12'h7c6)
`CSR(MEPARBASE, 12'h7c7)
`CSR(MEPARMASK, 12'h7c8)
`CSR(MFLUSH, 12'h7c9) // flush pipeline + cache
`CSR(MSPEC, 12'h7ca) // control speculation
// sanctum user CSR
`CSR(TRNG, 12'hcc0) // random number for secure boot
`endif
`CSR(CSRtselect , 12'h7A0) // Debug/trace tselect
`CSR(CSRtdata1 , 12'h7A1) // Debug/trace tdata1
`CSR(CSRtdata2 , 12'h7A2) // Debug/trace tdata2
`CSR(CSRtdata3 , 12'h7A3) // Debug/trace tdata3
`CSR(TSELECT, 12'h7A0) // Debug/trace tselect
`CSR(TDATA1, 12'h7A1) // Debug/trace tdata1
`CSR(TDATA2, 12'h7A2) // Debug/trace tdata2
`CSR(TDATA3, 12'h7A3) // Debug/trace tdata3
`ifdef INCLUDE_GDB_CONTROL
`CSR(CSRdcsr , 12'h7B0) // Debug control and status
`CSR(CSRdpc , 12'h7B1) // Debug PC
`CSR(CSRdscratch0 , 12'h7B2) // Debug scratch0
`CSR(CSRdscratch1 , 12'h7B3) // Debug scratch1
`CSR(DCSR, 12'h7B0) // Debug control and status
`CSR(DPC, 12'h7B1) // Debug PC
`CSR(DSCRATCH0, 12'h7B2) // Debug scratch0
`CSR(DSCRATCH1, 12'h7B3) // Debug scratch1
`endif

View File

@@ -287,7 +287,7 @@ module mkDTlb#(
end
else begin
// page fault
Exception fault = r.write ? StorePageFault : LoadPageFault;
Exception fault = r.write ? excStorePageFault : excLoadPageFault;
pendResp[idx] <= tuple2(?, Valid (fault));
if(verbose) begin
$display("[DTLB] refill no permission: idx %d; ", idx, fshow(r));
@@ -296,7 +296,7 @@ module mkDTlb#(
end
else begin
// page fault
Exception fault = r.write ? StorePageFault : LoadPageFault;
Exception fault = r.write ? excStorePageFault : excLoadPageFault;
pendResp[idx] <= tuple2(?, Valid (fault));
if(verbose) $display("[DTLB] refill page fault: idx %d; ", idx, fshow(r));
end
@@ -433,7 +433,7 @@ module mkDTlb#(
// (Because we are always non speculative in M mode)
if (!vm_info.sanctum_authShared && outOfProtectionDomain(vm_info, r.addr))begin
pendWait[idx] <= None;
pendResp[idx] <= tuple2(?, Valid (LoadAccessFault));
pendResp[idx] <= tuple2(?, Valid (excLoadAccessFault));
end
`else
// No security check
@@ -472,7 +472,7 @@ module mkDTlb#(
end
else begin
// page fault
Exception fault = r.write ? StorePageFault : LoadPageFault;
Exception fault = r.write ? excStorePageFault : excLoadPageFault;
pendWait[idx] <= None;
pendResp[idx] <= tuple2(?, Valid (fault));
if(verbose) $display("[DTLB] req no permission: idx %d; ", idx, fshow(r));

View File

@@ -57,11 +57,11 @@ function Maybe#(MemInst) decodeMemInst(Instruction inst, Bool cap_mode);
// mem_func + amo_func
MemFunc mem_func = Ld;
AmoFunc amo_func = None;
if (opcode == Load || opcode == LoadFp || opcode == MiscMem) begin
if (opcode == opcLoad || opcode == opcLoadFp || opcode == opcMiscMem) begin
mem_func = Ld;
end else if (opcode == Store || opcode == StoreFp) begin
end else if (opcode == opcStore || opcode == opcStoreFp) begin
mem_func = St;
end else if (opcode == Amo) begin
end else if (opcode == opcAmo) begin
case (funct5)
fnLR : mem_func = Lr;
fnSC : mem_func = Sc;
@@ -105,12 +105,12 @@ function Maybe#(MemInst) decodeMemInst(Instruction inst, Bool cap_mode);
endcase
// This is a minor fix to make our processor's results match spike since
// they don't sign extend when loading single precision values from memory
if (opcode == LoadFp) begin
if (opcode == opcLoadFp) begin
unsignedLd = True;
end
Bool capWidth = (mem_func == St && funct3 == 3'b100)
|| (opcode == MiscMem && funct3 == 3'b010);
|| (opcode == opcMiscMem && funct3 == 3'b010);
// byteEn
// TODO: Some combinations of operations and byteEn's are illegal.
@@ -146,7 +146,7 @@ function Maybe#(MemInst) decodeMemInst(Instruction inst, Bool cap_mode);
// aq + rl
Bool aq = False;
Bool rl = False;
if (opcode == Amo) begin
if (opcode == opcAmo) begin
// aq and rl are only defined for Amo operations
aq = unpack(inst[ 26 ]);
rl = unpack(inst[ 25 ]);
@@ -319,7 +319,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
// TODO better detection of illegal insts
case (opcode)
OpImm: begin
opcOpImm: begin
dInst.iType = Alu;
dInst.execFunc = tagged Alu (case (funct3)
fnADD: Add;
@@ -338,7 +338,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.csr = tagged Invalid;
end
OpImm32: begin
opcOpImm32: begin
dInst.iType = Alu;
dInst.execFunc = tagged Alu (case (funct3)
fnADD: Addw;
@@ -352,7 +352,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.csr = tagged Invalid;
end
Op: begin
opcOp: begin
dInst.iType = Alu;
regs.dst = Valid(tagged Gpr rd);
regs.src1 = Valid(tagged Gpr rs1);
@@ -413,7 +413,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
endcase
end
Op32: begin
opcOp32: begin
dInst.iType = Alu;
case (funct7)
opALU1: begin
@@ -470,7 +470,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.csr = tagged Invalid;
end
Lui: begin // treated as an x0 + immU
opcLui: begin // treated as an x0 + immU
dInst.iType = Alu;
dInst.execFunc = tagged Alu Add;
regs.dst = Valid(tagged Gpr rd);
@@ -480,7 +480,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.csr = tagged Invalid;
end
Auipc: begin
opcAuipc: begin
dInst.iType = cap_mode ? Auipcc : Auipc;
dInst.execFunc = tagged Alu Add;
regs.dst = Valid(tagged Gpr rd);
@@ -490,7 +490,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.csr = tagged Invalid;
end
Jal: begin
opcJal: begin
dInst.iType = J;
regs.dst = Valid(tagged Gpr rd);
regs.src1 = Invalid;
@@ -505,7 +505,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.capChecks.check_inclusive = True;
end
Jalr: begin
opcJalr: begin
dInst.iType = Jr;
regs.dst = Valid(tagged Gpr rd);
regs.src1 = Valid(tagged Gpr rs1);
@@ -520,7 +520,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.capChecks.check_inclusive = True;
end
Branch: begin
opcBranch: begin
dInst.iType = Br;
dInst.execFunc = tagged Br (case(funct3)
fnBEQ: Eq;
@@ -542,7 +542,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.capChecks.check_inclusive = True;
end
Load: begin
opcLoad: begin
dInst.iType = Ld;
if (isValid(mem_inst)) begin
dInst.execFunc = tagged Mem fromMaybe(?, mem_inst);
@@ -557,7 +557,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.capChecks = memCapChecks(cap_mode);
end
Store: begin
opcStore: begin
dInst.iType = St;
if (isValid(mem_inst)) begin
dInst.execFunc = tagged Mem fromMaybe(?, mem_inst);
@@ -572,7 +572,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.capChecks = memCapChecks(cap_mode);
end
Amo: begin
opcAmo: begin
if (!isa.a) begin
// unsupported
illegalInst = True;
@@ -638,7 +638,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
end
// Instructions for "F" and "D" ISA extensions - FPU
OpFp: begin
opcOpFp: begin
// check if instruction is supported
if ((fmt == fmtS && !isa.f) || (fmt == fmtD && !isa.d) || (fmt != fmtS && fmt != fmtD)) begin
illegalInst = True;
@@ -707,7 +707,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
endcase
end
end
LoadFp: begin
opcLoadFp: begin
// check if instruction is supported
if (!isa.f && !isa.d) begin
// FIXME: Check more cases
@@ -728,7 +728,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.capChecks = memCapChecks(cap_mode);
end
end
StoreFp: begin
opcStoreFp: begin
// check if instruction is supported
if (!isa.f && !isa.d) begin
// FIXME: Check more cases
@@ -749,7 +749,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.capChecks = memCapChecks(cap_mode);
end
end
Fmadd, Fmsub, Fnmsub, Fnmadd: begin
opcFmadd, opcFmsub, opcFnmsub, opcFnmadd: begin
// check if instruction is supported
if ((fmt == fmtS && !isa.f) ||
(fmt == fmtD && !isa.d) ||
@@ -761,10 +761,10 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.iType = Fpu;
FpuFunc func = ?;
case (opcode)
Fmadd: func = FMAdd;
Fmsub: func = FMSub;
Fnmsub: func = FNMSub;
Fnmadd: func = FNMAdd;
opcFmadd: func = FMAdd;
opcFmsub: func = FMSub;
opcFnmsub: func = FNMSub;
opcFnmadd: func = FNMAdd;
default: illegalInst = True;
endcase
dInst.execFunc = tagged Fpu (FpuInst {
@@ -781,7 +781,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
end
end
MiscMem: begin
opcMiscMem: begin
regs.dst = Invalid;
regs.src1 = Invalid;
regs.src2 = Invalid;
@@ -849,7 +849,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
endcase
end
System: begin
opcSystem: begin
if (funct3 == fnPRIV) begin
if (funct7 == privSFENCEVMA) begin
dInst.iType = SFence;
@@ -873,7 +873,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.imm = Invalid;
end
else begin // fnCSRRWI, fnCSRRW, fnCSRRSI, fnCSRRS, fnCSRRCI, fnCSRRC
if (truncate(immI) == pack(CSRmtvec) || truncate(immI) == pack(CSRmepc) || truncate(immI) == pack(CSRstvec) || truncate(immI) == pack(CSRsepc)) begin
if (truncate(immI) == pack(csrAddrMTVEC) || truncate(immI) == pack(csrAddrMEPC) || truncate(immI) == pack(csrAddrSTVEC) || truncate(immI) == pack(csrAddrSEPC)) begin
Bool shouldWrite = (funct3 == fnCSRRWI || funct3 == fnCSRRW) || rs1 != 0;
dInst.iType = shouldWrite ? Scr : Cap;
regs.dst = Valid(tagged Gpr rd);
@@ -889,21 +889,21 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
let scrType = ?;
case (truncate(immI))
pack(CSRmepc): begin
pack(csrAddrMEPC): begin
scrType = EPC (accessFunc);
dInst.scr = Valid (SCR_MEPCC);
dInst.scr = Valid (scrAddrMEPCC);
end
pack(CSRmtvec): begin
pack(csrAddrMTVEC): begin
scrType = TVEC (accessFunc);
dInst.scr = Valid (SCR_MTCC);
dInst.scr = Valid (scrAddrMTCC);
end
pack(CSRsepc): begin
pack(csrAddrSEPC): begin
scrType = EPC (accessFunc);
dInst.scr = Valid (SCR_SEPCC);
dInst.scr = Valid (scrAddrSEPCC);
end
pack(CSRstvec): begin
pack(csrAddrSTVEC): begin
scrType = TVEC (accessFunc);
dInst.scr = Valid (SCR_STCC);
dInst.scr = Valid (scrAddrSTCC);
end
endcase
@@ -925,7 +925,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
end
end
OpCHERI: begin
opcOpCHERI: begin
case (funct3)
f3_cap_CIncOffsetImmediate: begin
dInst.capChecks.src1_unsealed = True;
@@ -967,7 +967,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
endcase;
// Decode SCR read to PCC as AUIPCC 0
if (dInst.scr.Valid == SCR_PCC) begin
if (dInst.scr.Valid == scrAddrPCC) begin
dInst.iType = Auipcc;
dInst.execFunc = tagged Alu Add;
regs.src1 = Invalid;
@@ -1135,7 +1135,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
regs.dst = Valid(tagged Gpr rd);
regs.src1 = Valid(tagged Gpr rs2);
regs.src2 = rs1 == 0 ? Invalid : Valid(tagged Gpr rs1);
dInst.scr = rs1 == 0 ? Valid (SCR_DDC) : Invalid;
dInst.scr = rs1 == 0 ? Valid (scrAddrDDC) : Invalid;
dInst.capFunc = CapInspect (TestSubset);
end
f7_cap_CCopyType: begin
@@ -1182,7 +1182,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
regs.src1 = Valid(tagged Gpr rs1);
if (rs2 == 0) begin
regs.src2 = Invalid;
dInst.scr = Valid (SCR_DDC);
dInst.scr = Valid (scrAddrDDC);
end else begin
regs.src2 = Valid (tagged Gpr rs2);
dInst.scr = Invalid;
@@ -1198,7 +1198,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
regs.dst = Valid(tagged Gpr rd);
regs.src1 = Valid(tagged Gpr rs2);
regs.src2 = rs1 == 0 ? Invalid : Valid (tagged Gpr rs1);
dInst.scr = rs1 == 0 ? Valid(SCR_DDC) : Invalid;
dInst.scr = rs1 == 0 ? Valid(scrAddrDDC) : Invalid;
dInst.capFunc = CapModify (FromPtr);
end
f7_cap_CSub: begin
@@ -1226,7 +1226,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
regs.dst = Valid(tagged Gpr rd);
regs.src1 = Valid(tagged Gpr rs2);
if (rs1 == 0) begin
dInst.scr = Valid(SCR_DDC);
dInst.scr = Valid(scrAddrDDC);
end else begin
regs.src2 = Valid(tagged Gpr rs1);
end
@@ -1395,6 +1395,6 @@ endfunction
// All this does is add the CSR state to the decoding
function FpuInst updateRoundingMode(FpuInst fpu_f, CsrDecodeInfo csrState);
let new_fpu_f = fpu_f;
new_fpu_f.rm = (fpu_f.rm == RDyn) ? unpack(csrState.frm) : fpu_f.rm;
new_fpu_f.rm = (fpu_f.rm == rmRDyn) ? unpack(csrState.frm) : fpu_f.rm;
return new_fpu_f;
endfunction

View File

@@ -0,0 +1,15 @@
`Exception(InstAddrMisaligned, 5'd0)
`Exception(InstAccessFault, 5'd1)
`Exception(IllegalInst, 5'd2)
`Exception(Breakpoint, 5'd3)
`Exception(LoadAddrMisaligned, 5'd4)
`Exception(LoadAccessFault, 5'd5)
`Exception(StoreAddrMisaligned, 5'd6)
`Exception(StoreAccessFault, 5'd7)
`Exception(EnvCallU, 5'd8)
`Exception(EnvCallS, 5'd9)
`Exception(EnvCallM, 5'd11)
`Exception(InstPageFault, 5'd12)
`Exception(LoadPageFault, 5'd13)
`Exception(StorePageFault, 5'd15)
`Exception(CHERIFault, 5'd28)

View File

@@ -51,51 +51,51 @@ function Maybe#(CSR_XCapCause) capChecks(CapPipe a, CapPipe b, CapPipe ddc, CapC
function Maybe#(CSR_XCapCause) eDDC(CHERIException e) = Valid(CSR_XCapCause{cheri_exc_reg: 6'b100001, cheri_exc_code: e}); // Not sure where the proper reg number of DDC is stored...
Maybe#(CSR_XCapCause) result = Invalid;
if (toCheck.ddc_tag && !isValidCap(ddc))
result = eDDC(TagViolation);
result = eDDC(cheriExcTagViolation);
else if (toCheck.src1_tag && !isValidCap(a))
result = e1(TagViolation);
result = e1(cheriExcTagViolation);
else if (toCheck.src2_tag && !isValidCap(b))
result = e2(TagViolation);
result = e2(cheriExcTagViolation);
else if (toCheck.ddc_unsealed && isValidCap(ddc) && (getKind(ddc) != UNSEALED))
result = eDDC(SealViolation);
result = eDDC(cheriExcSealViolation);
else if (toCheck.src1_unsealed && isValidCap(a) && (getKind(a) != UNSEALED))
result = e1(SealViolation);
result = e1(cheriExcSealViolation);
else if (toCheck.src1_unsealed_or_sentry && isValidCap(a) && (getKind(a) != UNSEALED) && (getKind(a) != SENTRY))
result = e1(SealViolation);
result = e1(cheriExcSealViolation);
else if (toCheck.src2_unsealed && isValidCap(b) && (getKind(b) != UNSEALED))
result = e2(SealViolation);
result = e2(cheriExcSealViolation);
else if (toCheck.src1_sealed_with_type && (getKind (a) matches tagged SEALED_WITH_TYPE .t ? False : True))
result = e1(SealViolation);
result = e1(cheriExcSealViolation);
else if (toCheck.src2_sealed_with_type && (getKind (b) matches tagged SEALED_WITH_TYPE .t ? False : True))
result = e2(SealViolation);
result = e2(cheriExcSealViolation);
else if (toCheck.src1_type_not_reserved && !validAsType(a, zeroExtend(getKind(a).SEALED_WITH_TYPE)))
result = e1(TypeViolation);
result = e1(cheriExcTypeViolation);
else if (toCheck.src1_src2_types_match && getKind(a).SEALED_WITH_TYPE != getKind(b).SEALED_WITH_TYPE)
result = e1(TypeViolation);
result = e1(cheriExcTypeViolation);
else if (toCheck.src1_permit_ccall && !getHardPerms(a).permitCCall)
result = e1(PermitCCallViolation);
result = e1(cheriExcPermitCCallViolation);
else if (toCheck.src2_permit_ccall && !getHardPerms(b).permitCCall)
result = e2(PermitCCallViolation);
result = e2(cheriExcPermitCCallViolation);
else if (toCheck.src1_permit_x && !getHardPerms(a).permitExecute)
result = e1(PermitXViolation);
result = e1(cheriExcPermitXViolation);
else if (toCheck.src2_no_permit_x && getHardPerms(b).permitExecute)
result = e2(PermitXViolation);
result = e2(cheriExcPermitXViolation);
else if (toCheck.src2_permit_unseal && !getHardPerms(b).permitUnseal)
result = e2(PermitUnsealViolation);
result = e2(cheriExcPermitUnsealViolation);
else if (toCheck.src2_permit_seal && !getHardPerms(b).permitSeal)
result = e2(PermitSealViolation);
result = e2(cheriExcPermitSealViolation);
else if (toCheck.src2_points_to_src1_type && getAddr(b) != zeroExtend(getKind(a).SEALED_WITH_TYPE))
result = e2(TypeViolation);
result = e2(cheriExcTypeViolation);
else if (toCheck.src2_addr_valid_type && !validAsType(b, truncate(getAddr(b))))
result = e2(LengthViolation);
result = e2(cheriExcLengthViolation);
else if (toCheck.src1_perm_subset_src2 && (getPerms(a) & getPerms(b)) != getPerms(a))
result = e2(SoftwarePermViolation);
result = e2(cheriExcSoftwarePermViolation);
else if (toCheck.src1_derivable && !isDerivable(a))
result = e1(LengthViolation);
result = e1(cheriExcLengthViolation);
else if (toCheck.scr_read_only && (toCheck.rn1 != 0))
result = Valid(CSR_XCapCause{cheri_exc_reg: {1,pack(SCR_PCC)}, cheri_exc_code: PermitASRViolation});
result = Valid(CSR_XCapCause{cheri_exc_reg: {1,pack(scrAddrPCC)}, cheri_exc_code: cheriExcPermitASRViolation});
else if (toCheck.cap_exact && !cap_exact)
result = e1(RepresentViolation);
result = e1(cheriExcRepresentViolation);
return result;
endfunction
@@ -116,11 +116,11 @@ function Maybe#(BoundsCheck) prepareBoundsCheck(CapPipe a, CapPipe b, CapPipe pc
end
Pcc: begin
authority = pcc;
ret.authority_idx = {1'b1, pack(SCR_PCC)};
ret.authority_idx = {1'b1, pack(scrAddrPCC)};
end
Ddc: begin
authority = ddc;
ret.authority_idx = {1'b1, pack(SCR_DDC)};
ret.authority_idx = {1'b1, pack(scrAddrDDC)};
end
endcase
ret.authority_base = getBase(authority);
@@ -435,48 +435,48 @@ function Maybe#(Trap) checkForException(
if(dInst.iType == Ecall) begin
exception = Valid (Exception (case(prv)
prvU: EnvCallU;
prvS: EnvCallS;
prvM: EnvCallM;
default: IllegalInst;
prvU: excEnvCallU;
prvS: excEnvCallS;
prvM: excEnvCallM;
default: excIllegalInst;
endcase));
end
else if(dInst.iType == Ebreak) begin
exception = Valid (Exception (Breakpoint));
exception = Valid (Exception (excBreakpoint));
end
else if(dInst.iType == Mret) begin
if(prv < prvM) begin
exception = Valid (Exception (IllegalInst));
exception = Valid (Exception (excIllegalInst));
end
else if (!getHardPerms(pcc).accessSysRegs) begin
exception = Valid (CapException (CSR_XCapCause {cheri_exc_reg: {1'b1, pack(SCR_PCC)}, cheri_exc_code: PermitASRViolation}));
exception = Valid (CapException (CSR_XCapCause {cheri_exc_reg: {1'b1, pack(scrAddrPCC)}, cheri_exc_code: cheriExcPermitASRViolation}));
end
end
else if(dInst.iType == Sret) begin
if(prv < prvS) begin
exception = Valid (Exception (IllegalInst));
exception = Valid (Exception (excIllegalInst));
end
else if(prv == prvS && csrState.trapSret) begin
exception = Valid (Exception (IllegalInst));
exception = Valid (Exception (excIllegalInst));
end
else if (!getHardPerms(pcc).accessSysRegs) begin
exception = Valid (CapException (CSR_XCapCause {cheri_exc_reg: {1'b1, pack(SCR_PCC)}, cheri_exc_code: PermitASRViolation}));
exception = Valid (CapException (CSR_XCapCause {cheri_exc_reg: {1'b1, pack(scrAddrPCC)}, cheri_exc_code: cheriExcPermitASRViolation}));
end
end
else if(dInst.iType == SFence) begin
if(prv == prvS && csrState.trapVM) begin
exception = Valid (Exception (IllegalInst));
exception = Valid (Exception (excIllegalInst));
end
end
else if(dInst.iType == Csr) begin
let csr = pack(fromMaybe(CSRnone, dInst.csr));
let csr = pack(fromMaybe(csrAddrNone, dInst.csr));
Bool csr_has_priv = (prv >= csr[9:8]);
if(!csr_has_priv) begin
exception = Valid (Exception (IllegalInst));
exception = Valid (Exception (excIllegalInst));
end
else if(prv == prvS && csrState.trapVM &&
validValue(dInst.csr) == CSRsatp) begin
exception = Valid (Exception (IllegalInst));
validValue(dInst.csr) == csrAddrSATP) begin
exception = Valid (Exception (excIllegalInst));
end
let rs1 = case (regs.src2) matches
tagged Valid (tagged Gpr .r) : r;
@@ -491,41 +491,41 @@ function Maybe#(Trap) checkForException(
Bool write_deny = (writes_csr && read_only);
Bool asr_deny = !getHardPerms(pcc).accessSysRegs && !(
//((csr_addr_hpmcounter3 <= csr) && (csr <= csr_addr_hpmcounter31) && writes_csr) // TODO seems these aren't implemented?
(csr == pack(CSRfflags))
|| (csr == pack(CSRfrm))
|| (csr == pack(CSRfcsr))
|| (csr == pack(CSRcycle) && writes_csr)
|| (csr == pack(CSRinstret) && writes_csr));
Bool unimplemented = (csr == pack(CSRnone)); // Added by Bluespec
(csr == pack(csrAddrFFLAGS))
|| (csr == pack(csrAddrFRM))
|| (csr == pack(csrAddrFCSR))
|| (csr == pack(csrAddrCYCLE) && writes_csr)
|| (csr == pack(csrAddrINSTRET) && writes_csr));
Bool unimplemented = (csr == pack(csrAddrNone)); // Added by Bluespec
if (write_deny || !csr_has_priv || unimplemented) begin
exception = Valid (Exception (IllegalInst));
exception = Valid (Exception (excIllegalInst));
end else if (asr_deny) begin
exception = Valid (CapException (CSR_XCapCause {cheri_exc_reg: {1'b1, pack(SCR_PCC)}, cheri_exc_code: PermitASRViolation}));
exception = Valid (CapException (CSR_XCapCause {cheri_exc_reg: {1'b1, pack(scrAddrPCC)}, cheri_exc_code: cheriExcPermitASRViolation}));
end
end
else if(dInst.scr matches tagged Valid .scr) begin
Bool scr_has_priv = (prv >= pack(scr)[4:3]);
Bool unimplemented = (scr == SCR_None);
Bool unimplemented = (scr == scrAddrNone);
Bool asr_deny = !getHardPerms(pcc).accessSysRegs && !(
scr == SCR_DDC);
scr == scrAddrDDC);
if(!scr_has_priv || unimplemented) begin // Writes to PCC checked in capChecks
exception = Valid (Exception (IllegalInst));
exception = Valid (Exception (excIllegalInst));
end else if (asr_deny) begin
exception = Valid (CapException (CSR_XCapCause {cheri_exc_reg: {1'b1, pack(SCR_PCC)}, cheri_exc_code: PermitASRViolation}));
exception = Valid (CapException (CSR_XCapCause {cheri_exc_reg: {1'b1, pack(scrAddrPCC)}, cheri_exc_code: cheriExcPermitASRViolation}));
end
end
else if(dInst.iType == Fpu) begin
if(dInst.execFunc matches tagged Fpu .fpu_f) begin
// Get rounding mode
let rm = (fpu_f.rm == RDyn) ? unpack(csrState.frm) : fpu_f.rm;
let rm = (fpu_f.rm == rmRDyn) ? unpack(csrState.frm) : fpu_f.rm;
case(rm)
RNE, RTZ, RDN, RUP, RMM: exception = exception; // legal modes
default : exception = Valid ( Exception (IllegalInst));
rmRNE, rmRTZ, rmRDN, rmRUP, rmRMM: exception = exception; // legal modes
default : exception = Valid (Exception (excIllegalInst));
endcase
end
else begin
// Fpu instruction without FPU execFunc
exception = Valid (Exception (IllegalInst));
exception = Valid (Exception (excIllegalInst));
end
end
@@ -533,11 +533,11 @@ function Maybe#(Trap) checkForException(
CapPipe pcc_end = cast(addPc(pcc, (fourByteInst?4:2)));
CapPipe pcc_start = cast(pcc);
Maybe#(CSR_XCapCause) capException = Invalid;
if (!isValidCap(pcc_start)) capException = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1,pack(SCR_PCC)}, cheri_exc_code: TagViolation});
if (getKind(pcc_start) != UNSEALED) capException = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1,pack(SCR_PCC)}, cheri_exc_code: SealViolation});
if (!getHardPerms(pcc_start).permitExecute) capException = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1,pack(SCR_PCC)}, cheri_exc_code: PermitXViolation});
if (!isInBounds(pcc_end, True)) capException = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1,pack(SCR_PCC)}, cheri_exc_code: LengthViolation});
if (!isInBounds(pcc_start, True)) capException = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1,pack(SCR_PCC)}, cheri_exc_code: LengthViolation});
if (!isValidCap(pcc_start)) capException = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1,pack(scrAddrPCC)}, cheri_exc_code: cheriExcTagViolation});
if (getKind(pcc_start) != UNSEALED) capException = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1,pack(scrAddrPCC)}, cheri_exc_code: cheriExcSealViolation});
if (!getHardPerms(pcc_start).permitExecute) capException = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1,pack(scrAddrPCC)}, cheri_exc_code: cheriExcPermitXViolation});
if (!isInBounds(pcc_end, True)) capException = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1,pack(scrAddrPCC)}, cheri_exc_code: cheriExcLengthViolation});
if (!isInBounds(pcc_start, True)) capException = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1,pack(scrAddrPCC)}, cheri_exc_code: cheriExcLengthViolation});
Maybe#(Trap) retval = Invalid;
if (capException matches tagged Valid .ce) retval = Valid(CapException(ce));

View File

@@ -452,12 +452,12 @@ function FpuResult execFpuSimple(FpuInst fpu_inst, Data rVal1, Data rVal2);
// Convert the Risc-V RVRoundMode to FloatingPoint::RoundMode
FpuRoundMode fpu_rm = (case (fpu_inst.rm)
RNE: Rnd_Nearest_Even;
RTZ: Rnd_Zero;
RDN: Rnd_Minus_Inf;
RUP: Rnd_Plus_Inf;
RMM: Rnd_Nearest_Away_Zero;
RDyn: Rnd_Nearest_Even;
rmRNE: Rnd_Nearest_Even;
rmRTZ: Rnd_Zero;
rmRDN: Rnd_Minus_Inf;
rmRUP: Rnd_Plus_Inf;
rmRMM: Rnd_Nearest_Away_Zero;
rmRDyn: Rnd_Nearest_Even;
default: Rnd_Nearest_Even;
endcase);
@@ -835,12 +835,12 @@ module mkFpuExecPipeline(FpuExec);
Maybe#(PhyDst) dst, InstTag tag, SpecBits spec_bits);
// Convert the Risc-V RVRoundMode to FloatingPoint::RoundMode
FpuRoundMode fpu_rm = (case (fpu_inst.rm)
RNE: Rnd_Nearest_Even;
RTZ: Rnd_Zero;
RDN: Rnd_Minus_Inf;
RUP: Rnd_Plus_Inf;
RMM: Rnd_Nearest_Away_Zero;
RDyn: Rnd_Nearest_Even;
rmRNE: Rnd_Nearest_Even;
rmRTZ: Rnd_Zero;
rmRDN: Rnd_Minus_Inf;
rmRUP: Rnd_Plus_Inf;
rmRMM: Rnd_Nearest_Away_Zero;
rmRDyn: Rnd_Nearest_Even;
default: Rnd_Nearest_Even;
endcase);

View File

@@ -190,7 +190,7 @@ module mkITlb(ITlb::ITlb);
end
else begin
// page fault
hitQ.enq(tuple2(?, Valid (InstPageFault)));
hitQ.enq(tuple2(?, Valid (excInstPageFault)));
if(verbose) begin
$display("ITLB %m refill no permission: ", fshow(vaddr));
end
@@ -198,7 +198,7 @@ module mkITlb(ITlb::ITlb);
end
else begin
// page fault
hitQ.enq(tuple2(?, Valid (InstPageFault)));
hitQ.enq(tuple2(?, Valid (excInstPageFault)));
if(verbose) $display("ITLB %m refill page fault: ", fshow(vaddr));
end
// miss resolved
@@ -268,7 +268,7 @@ module mkITlb(ITlb::ITlb);
eparvm_info.sanctum_evbase = maxBound;
eparvm_info.sanctum_evmask = 0;
if ((vm_info.prv == prvM ? (outOfProtectionDomain(parvm_info,vaddr) && outOfProtectionDomain(eparvm_info,vaddr)) : outOfProtectionDomain(vm_info, vaddr))) begin
hitQ.enq(tuple2(?, Valid (InstAccessFault)));
hitQ.enq(tuple2(?, Valid (excInstAccessFault)));
end
`else
// No security check
@@ -302,7 +302,7 @@ module mkITlb(ITlb::ITlb);
end
else begin
// page fault
hitQ.enq(tuple2(?, Valid (InstPageFault)));
hitQ.enq(tuple2(?, Valid (excInstPageFault)));
if(verbose) begin
$display("ITLB %m req no permission: ",
fshow(vaddr));

View File

@@ -0,0 +1,14 @@
`Interrupt(UserSoftware, 4'd0)
`Interrupt(SupervisorSoftware, 4'd1)
`Interrupt(MachineSoftware, 4'd3)
`Interrupt(UserTimer, 4'd4)
`Interrupt(SupervisorTimer, 4'd5)
`Interrupt(MachineTimer, 4'd7)
`Interrupt(UserExternal, 4'd8)
`Interrupt(SupervisorExternel, 4'd9)
`Interrupt(MachineExternal, 4'd11)
`ifdef INCLUDE_GDB_CONTROL
`Interrupt(DebugHalt, 4'd14) // Debugger halt command (^C in GDB)
`Interrupt(DebugStep, 4'd15) // dcsr.step is set and 1 instr has been processed)
`endif

View File

@@ -1,22 +1,22 @@
`OPCODE(Load , 7'b0000011)
`OPCODE(LoadFp , 7'b0000111)
`OPCODE(MiscMem, 7'b0001111)
`OPCODE(OpImm , 7'b0010011)
`OPCODE(Auipc , 7'b0010111)
`OPCODE(OpImm32, 7'b0011011)
`OPCODE(Store , 7'b0100011)
`OPCODE(StoreFp, 7'b0100111)
`OPCODE(Amo , 7'b0101111)
`OPCODE(Op , 7'b0110011)
`OPCODE(Lui , 7'b0110111)
`OPCODE(Op32 , 7'b0111011)
`OPCODE(Fmadd , 7'b1000011)
`OPCODE(Fmsub , 7'b1000111)
`OPCODE(Fnmsub , 7'b1001011)
`OPCODE(Fnmadd , 7'b1001111)
`OPCODE(OpFp , 7'b1010011)
`OPCODE(OpCHERI, 7'b1011011)
`OPCODE(Branch , 7'b1100011)
`OPCODE(Jalr , 7'b1100111)
`OPCODE(Jal , 7'b1101111)
`OPCODE(System , 7'b1110011)
`Opcode(Load, 7'b0000011)
`Opcode(LoadFp, 7'b0000111)
`Opcode(MiscMem, 7'b0001111)
`Opcode(OpImm, 7'b0010011)
`Opcode(Auipc, 7'b0010111)
`Opcode(OpImm32, 7'b0011011)
`Opcode(Store, 7'b0100011)
`Opcode(StoreFp, 7'b0100111)
`Opcode(Amo, 7'b0101111)
`Opcode(Op, 7'b0110011)
`Opcode(Lui, 7'b0110111)
`Opcode(Op32, 7'b0111011)
`Opcode(Fmadd, 7'b1000011)
`Opcode(Fmsub, 7'b1000111)
`Opcode(Fnmsub, 7'b1001011)
`Opcode(Fnmadd, 7'b1001111)
`Opcode(OpFp, 7'b1010011)
`Opcode(OpCHERI, 7'b1011011)
`Opcode(Branch, 7'b1100011)
`Opcode(Jalr, 7'b1100111)
`Opcode(Jal, 7'b1101111)
`Opcode(System, 7'b1110011)

View File

@@ -185,42 +185,64 @@ function Bool allRegsReady(RegsReady x);
return x.src1 && x.src2 && x.src3 && x.dst;
endfunction
typedef enum {
`define OPCODE(o,v) o = v,
`include "Opcodes.bsvi"
`undef OPCODE
Invalid = 7'b0
} Opcode deriving(Bits, Eq, FShow);
typedef struct { Bit#(7) opc; } Opcode deriving(Bits, Eq);
function Opcode unpackOpcode(Bit#(7) x);
return (case(x)
`define OPCODE(o,v) pack(Opcode'(o)): (o);
`define Opcode(n, v) Opcode opc``n = Opcode { opc: v };
`include "Opcodes.bsvi"
`undef OPCODE
default : Invalid;
`Opcode(Invalid, 7'b0)
`undef Opcode
instance FShow#(Opcode);
function Fmt fshow(Opcode scr);
return (case(scr.opc)
`define Opcode(n, v) v: $format(`"``opc``n```");
`include "Opcodes.bsvi"
`undef Opcode
default: $format("opcInvalid");
endcase);
endfunction
endinstance
function Opcode unpackOpcode(Bit#(7) opc);
return (case(opc)
`define Opcode(n, v) v: opc``n;
`include "Opcodes.bsvi"
`undef Opcode
default: opcInvalid;
endcase);
endfunction
typedef enum {
`define CSR(c,v) c = v,
`include "CSRs.bsvi"
`undef CSR
// CSR that catches all the unimplemented CSRs. To avoid exception on this,
// make it a user non-standard read/write CSR.
// Bluespec: in RenameStage.getTrap(), we force this to be a csr_access_trap
CSRnone = 12'h8ff
} CSR deriving(Bits, Eq, FShow);
typedef struct { Bit#(12) addr; } CSR deriving(Bits, Eq);
function CSR unpackCSR(Bit#(12) x);
return (case(x)
`define CSR(c,v) pack(CSR'(c)): (c);
`define CSR(n, v) CSR csrAddr``n = CSR { addr: v };
`include "CSRs.bsvi"
// CSR that catches all the unimplemented CSRs. To avoid exception on this,
// make it a user non-standard read/write CSR.
// Bluespec: in RenameStage.getTrap(), we force this to be a csr_access_trap
`CSR(None, 12'h8ff)
`undef CSR
instance FShow#(CSR);
function Fmt fshow(CSR csr);
return (case(csr.addr)
`define CSR(n, v) v: $format(`"``csrAddr``n```");
`include "CSRs.bsvi"
`undef CSR
default : (CSRnone );
default: $format("csrAddrNone");
endcase);
endfunction
endinstance
function CSR unpackCSR(Bit#(12) addr);
return (case(addr)
`define CSR(n, v) v: csrAddr``n;
`include "CSRs.bsvi"
`undef CSR
default: csrAddrNone;
endcase);
endfunction
// values for CSRmspec
// values for MSPEC CSR
Bit#(2) mSpecAll = 0; // every inst can speculate
Bit#(2) mSpecNonMem = 1; // only non-memory inst can speculate
Bit#(2) mSpecNone = 2; // no inst can speculate
@@ -369,50 +391,61 @@ typedef union tagged {
} CapFunc deriving(Bits, Eq, FShow);
// Rounding Modes (encoding by risc-v, not general fpu)
typedef enum {
RNE = 3'b000,
RTZ = 3'b001,
RDN = 3'b010,
RUP = 3'b011,
RMM = 3'b100,
RDyn = 3'b111
} RVRoundMode deriving(Bits, Eq, FShow);
typedef struct { Bit#(3) mode; } RVRoundMode deriving(Bits, Eq);
typedef enum {
InstAddrMisaligned = 5'd0,
InstAccessFault = 5'd1,
IllegalInst = 5'd2,
Breakpoint = 5'd3,
LoadAddrMisaligned = 5'd4,
LoadAccessFault = 5'd5,
StoreAddrMisaligned = 5'd6,
StoreAccessFault = 5'd7,
EnvCallU = 5'd8,
EnvCallS = 5'd9,
EnvCallM = 5'd11,
InstPageFault = 5'd12,
LoadPageFault = 5'd13,
StorePageFault = 5'd15,
CHERIFault = 5'd28
} Exception deriving(Bits, Eq, FShow);
`define RVRoundMode(n, v) RVRoundMode rm``n = RVRoundMode { mode: v };
`include "RVRoundModes.bsvi"
`undef RVRoundMode
typedef enum {
UserSoftware = 4'd0,
SupervisorSoftware = 4'd1,
MachineSoftware = 4'd3,
UserTimer = 4'd4,
SupervisorTimer = 4'd5,
MachineTimer = 4'd7,
UserExternal = 4'd8,
SupervisorExternel = 4'd9,
MachineExternal = 4'd11
instance FShow#(RVRoundMode);
function Fmt fshow(RVRoundMode rm);
return (case(rm.mode)
`define RVRoundMode(n, v) v: $format(`"``rm``n```");
`include "RVRoundModes.bsvi"
`undef RVRoundMode
default: $format("rmUnknown");
endcase);
endfunction
endinstance
`ifdef INCLUDE_GDB_CONTROL
, DebugHalt = 4'd14, // Debugger halt command (^C in GDB)
DebugStep = 4'd15 // dcsr.step is set and 1 instr has been processed
`endif
// bsc doesn't like the name colliding with Trap's Exception
typedef struct { Bit#(5) code; } ExceptionS deriving(Bits, Eq);
typedef ExceptionS Exception;
} Interrupt deriving(Bits, Eq, FShow);
`define Exception(n, v) Exception exc``n = ExceptionS { code: v };
`include "Exceptions.bsvi"
`undef Exception
instance FShow#(Exception);
function Fmt fshow(Exception exc);
return (case(exc.code)
`define Exception(n, v) v: $format(`"``exc``n```");
`include "Exceptions.bsvi"
`undef Exception
default: $format("excUnknown");
endcase);
endfunction
endinstance
// bsc doesn't like the name colliding with Trap's Interrupt and IType's
// Interrupt.
typedef struct { Bit#(4) intr; } InterruptS deriving(Bits, Eq);
typedef InterruptS Interrupt;
`define Interrupt(n, v) Interrupt intr``n = InterruptS { intr: v };
`include "Interrupts.bsvi"
`undef Interrupt
instance FShow#(Interrupt);
function Fmt fshow(Interrupt intr);
return (case(intr.intr)
`define Interrupt(n, v) v: $format(`"``intr``n```");
`include "Interrupts.bsvi"
`undef Interrupt
default: $format("intrUnknown");
endcase);
endfunction
endinstance
`ifdef INCLUDE_GDB_CONTROL
typedef 16 InterruptNum; // With debugger
@@ -831,7 +864,7 @@ function Fmt showInst(Instruction inst);
Bit#(32) immJ = signExtend({ inst[31], inst[19:12], inst[20], inst[30:25], inst[24:21], 1'b0});
case (opcode)
OpImm:
opcOpImm:
begin
ret = case (funct3)
fnADD: fshow("addi");
@@ -850,7 +883,7 @@ function Fmt showInst(Instruction inst);
endcase);
end
OpImm32:
opcOpImm32:
begin
ret = case (funct3)
fnADD: fshow("addiw");
@@ -864,7 +897,7 @@ function Fmt showInst(Instruction inst);
endcase);
end
Op:
opcOp:
begin
ret = case (funct3)
fnADD: (immI[10] == 0 ? fshow("add") : fshow("sub"));
@@ -879,7 +912,7 @@ function Fmt showInst(Instruction inst);
ret = ret + fshow(" ") + fshow(rd) + fshow(" = ") + fshow(rs1) + fshow(" ") + fshow(rs2);
end
Op32:
opcOp32:
begin
ret = case (funct3)
fnADD: (immI[10] == 0 ? fshow("addw") : fshow("subw"));
@@ -889,19 +922,19 @@ function Fmt showInst(Instruction inst);
ret = ret + fshow(" ") + fshow(rd) + fshow(" = ") + fshow(rs1) + fshow(" ") + fshow(rs2);
end
Lui:
opcLui:
ret = fshow("lui ") + fshow(rd) + fshow(" ") + fshow(immU);
Auipc:
opcAuipc:
ret = fshow("auipc ") + fshow(rd) + fshow(" ") + fshow(immU);
Jal:
opcJal:
ret = fshow("jal ") + fshow(rd) + fshow(" ") + fshow(immJ);
Jalr:
opcJalr:
ret = fshow("jalr ") + fshow(rd) + fshow(" ") + fshow(rs1) + fshow(" ") + fshow(immI);
Branch:
opcBranch:
begin
ret = case(funct3)
fnBEQ: fshow("beq");
@@ -914,7 +947,7 @@ function Fmt showInst(Instruction inst);
ret = ret + fshow(" ") + fshow(rs1) + fshow(" ") + fshow(rs2) + fshow(" ") + fshow(immB);
end
Load:
opcLoad:
begin
ret = case(funct3)
fnLB: fshow("lb");
@@ -928,7 +961,7 @@ function Fmt showInst(Instruction inst);
ret = ret + fshow(" ") + fshow(rd) + fshow(" = ") + fshow(rs1) + fshow(" ") + fshow(immI);
end
Store:
opcStore:
begin
ret = case(funct3)
fnSB: fshow("sb");
@@ -939,7 +972,7 @@ function Fmt showInst(Instruction inst);
ret = ret + fshow(" ") + fshow(rs1) + fshow(" ") + fshow(rs2) + fshow(" ") + fshow(immS);
end
MiscMem:
opcMiscMem:
begin
ret = case (funct3)
fnFENCE: fshow("fence");
@@ -947,7 +980,7 @@ function Fmt showInst(Instruction inst);
endcase;
end
System:
opcSystem:
begin
case (funct3)
fnCSRRW, fnCSRRS, fnCSRRC, fnCSRRWI, fnCSRRSI, fnCSRRCI:

View File

@@ -0,0 +1,6 @@
`RVRoundMode(RNE, 3'b000)
`RVRoundMode(RTZ, 3'b001)
`RVRoundMode(RDN, 3'b010)
`RVRoundMode(RUP, 3'b011)
`RVRoundMode(RMM, 3'b100)
`RVRoundMode(RDyn, 3'b111)