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:
@@ -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
|
||||
|
||||
26
src_Core/ISA/CHERIExceptions.bsvi
Normal file
26
src_Core/ISA/CHERIExceptions.bsvi
Normal 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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
15
src_Core/RISCY_OOO/procs/lib/Exceptions.bsvi
Normal file
15
src_Core/RISCY_OOO/procs/lib/Exceptions.bsvi
Normal 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)
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
14
src_Core/RISCY_OOO/procs/lib/Interrupts.bsvi
Normal file
14
src_Core/RISCY_OOO/procs/lib/Interrupts.bsvi
Normal 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
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
6
src_Core/RISCY_OOO/procs/lib/RVRoundModes.bsvi
Normal file
6
src_Core/RISCY_OOO/procs/lib/RVRoundModes.bsvi
Normal 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)
|
||||
Reference in New Issue
Block a user