mirror of
https://github.com/openhwgroup/cvw.git
synced 2025-04-22 12:57:23 -04:00
Merge branch 'main' of github.com:davidharrishmc/riscv-wally into main
This commit is contained in:
commit
b0fab61d34
18 changed files with 106 additions and 106 deletions
|
@ -58,7 +58,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
|
|||
#run 100 ns
|
||||
#force -deposit testbench/dut/core/priv/priv/csr/csri/IE_REGW 16'h2aa
|
||||
#force -deposit testbench/dut/uncore/clint/clint/MTIMECMP 64'h1000
|
||||
run 13000 ms
|
||||
run 14000 ms
|
||||
#add log -recursive /*
|
||||
#do linux-wave.do
|
||||
#run -all
|
||||
|
|
|
@ -79,8 +79,8 @@ module hazard(
|
|||
|
||||
// Each stage flushes if the previous stage is the last one stalled (for cause) or the system has reason to flush
|
||||
assign FlushF = BPPredWrongE | InvalidateICacheM;
|
||||
assign FlushD = FirstUnstalledD | TrapM | RetM | BPPredWrongE | InvalidateICacheM;
|
||||
assign FlushE = FirstUnstalledE | TrapM | RetM | BPPredWrongE | InvalidateICacheM;
|
||||
assign FlushD = FirstUnstalledD | TrapM | RetM | BPPredWrongE | InvalidateICacheM; // *** does RetM only need to flush if the privilege changes?
|
||||
assign FlushE = FirstUnstalledE | TrapM | RetM | BPPredWrongE | InvalidateICacheM; // *** why is BPPredWrongE here, but not needed in simple processor
|
||||
assign FlushM = FirstUnstalledM | TrapM | RetM | InvalidateICacheM;
|
||||
// on Trap the memory stage should be flushed going into the W stage,
|
||||
// except if the instruction causing the Trap is an ecall or ebreak.
|
||||
|
|
|
@ -65,7 +65,6 @@ module ifu (
|
|||
output logic InstrPageFaultF,
|
||||
output logic IllegalIEUInstrFaultD,
|
||||
output logic InstrMisalignedFaultM,
|
||||
output logic [`XLEN-1:0] InstrMisalignedAdrM,
|
||||
input logic ExceptionM,
|
||||
// mmu management
|
||||
input logic [1:0] PrivilegeModeW,
|
||||
|
@ -330,7 +329,6 @@ module ifu (
|
|||
// Traps: Can’t happen. The bottom two bits of MTVEC are ignored so the trap always is to a multiple of 4. See 3.1.7 of the privileged spec.
|
||||
assign BranchMisalignedFaultE = (IEUAdrE[1] & ~`C_SUPPORTED) & PCSrcE;
|
||||
flopenr #(1) InstrMisalginedReg(clk, reset, ~StallM, BranchMisalignedFaultE, InstrMisalignedFaultM);
|
||||
flopenr #(`XLEN) InstrMisalignedAdrReg(clk, reset, ~StallM, PCNextF, InstrMisalignedAdrM);
|
||||
|
||||
// Instruction and PC/PCLink pipeline registers
|
||||
mux2 #(32) FlushInstrEMux(InstrD, nop, FlushE, NextInstrD);
|
||||
|
|
|
@ -81,7 +81,7 @@ module csr #(parameter
|
|||
logic [`XLEN-1:0] CSRRWM, CSRRSM, CSRRCM;
|
||||
(* mark_debug = "true" *) logic [`XLEN-1:0] CSRWriteValM;
|
||||
|
||||
(* mark_debug = "true" *) logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW;
|
||||
(* mark_debug = "true" *) logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, MSTATUSH_REGW;
|
||||
logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW;
|
||||
logic WriteMSTATUSM, WriteSSTATUSM;
|
||||
logic CSRMWriteM, CSRSWriteM, CSRUWriteM;
|
||||
|
@ -139,7 +139,7 @@ module csr #(parameter
|
|||
.WriteMSTATUSM, .WriteSSTATUSM,
|
||||
.TrapM, .FRegWriteM, .NextPrivilegeModeM, .PrivilegeModeW,
|
||||
.mretM, .sretM, .WriteFRMM, .WriteFFLAGSM, .CSRWriteValM,
|
||||
.MSTATUS_REGW, .SSTATUS_REGW,
|
||||
.MSTATUS_REGW, .SSTATUS_REGW, .MSTATUSH_REGW,
|
||||
.STATUS_MPP, .STATUS_SPP, .STATUS_TSR, .STATUS_TW,
|
||||
.STATUS_MIE, .STATUS_SIE, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TVM);
|
||||
csrc counters(.clk, .reset,
|
||||
|
@ -152,7 +152,7 @@ module csr #(parameter
|
|||
.MTIME_CLINT, .CSRCReadValM, .IllegalCSRCAccessM);
|
||||
csrm csrm(.clk, .reset, .InstrValidNotFlushedM, .StallW,
|
||||
.CSRMWriteM, .MTrapM, .CSRAdrM,
|
||||
.NextEPCM, .NextCauseM, .NextMtvalM, .MSTATUS_REGW,
|
||||
.NextEPCM, .NextCauseM, .NextMtvalM, .MSTATUS_REGW, .MSTATUSH_REGW,
|
||||
.CSRWriteValM, .CSRMReadValM, .MTVEC_REGW,
|
||||
.MEPC_REGW, .MCOUNTEREN_REGW, .MCOUNTINHIBIT_REGW,
|
||||
.MEDELEG_REGW, .MIDELEG_REGW,.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
|
||||
|
|
|
@ -52,6 +52,7 @@ module csrm #(parameter
|
|||
MCAUSE = 12'h342,
|
||||
MTVAL = 12'h343,
|
||||
MIP = 12'h344,
|
||||
MTINST = 12'h34A,
|
||||
PMPCFG0 = 12'h3A0,
|
||||
// .. up to 15 more at consecutive addresses
|
||||
PMPADDR0 = 12'h3B0,
|
||||
|
@ -73,7 +74,7 @@ module csrm #(parameter
|
|||
input logic InstrValidNotFlushedM, StallW,
|
||||
input logic CSRMWriteM, MTrapM,
|
||||
input logic [11:0] CSRAdrM,
|
||||
input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, MSTATUS_REGW,
|
||||
input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, MSTATUS_REGW, MSTATUSH_REGW,
|
||||
input logic [`XLEN-1:0] CSRWriteValM,
|
||||
output logic [`XLEN-1:0] CSRMReadValM, MTVEC_REGW,
|
||||
(* mark_debug = "true" *) output logic [`XLEN-1:0] MEPC_REGW,
|
||||
|
@ -133,6 +134,7 @@ module csrm #(parameter
|
|||
|
||||
// Write machine Mode CSRs
|
||||
assign WriteMSTATUSM = CSRMWriteM & (CSRAdrM == MSTATUS) & InstrValidNotFlushedM;
|
||||
// writes to MSTATUSH are not yet supported because the register is always 0
|
||||
assign WriteMTVECM = CSRMWriteM & (CSRAdrM == MTVEC) & InstrValidNotFlushedM;
|
||||
assign WriteMEDELEGM = CSRMWriteM & (CSRAdrM == MEDELEG) & InstrValidNotFlushedM;
|
||||
assign WriteMIDELEGM = CSRMWriteM & (CSRAdrM == MIDELEG) & InstrValidNotFlushedM;
|
||||
|
@ -160,7 +162,6 @@ module csrm #(parameter
|
|||
flopenr #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], MCOUNTEREN_REGW);
|
||||
flopenr #(32) MCOUNTINHIBITreg(clk, reset, WriteMCOUNTINHIBITM, CSRWriteValM[31:0], MCOUNTINHIBIT_REGW);
|
||||
|
||||
|
||||
// Read machine mode CSRs
|
||||
// verilator lint_off WIDTH
|
||||
logic [5:0] entry;
|
||||
|
@ -186,7 +187,7 @@ module csrm #(parameter
|
|||
MIMPID: CSRMReadValM = `XLEN'h100; // pipelined implementation
|
||||
MHARTID: CSRMReadValM = MHARTID_REGW; // hardwired to 0
|
||||
MSTATUS: CSRMReadValM = MSTATUS_REGW;
|
||||
MSTATUSH: CSRMReadValM = 0; // flush this out later if MBE and SBE fields are supported
|
||||
MSTATUSH: CSRMReadValM = MSTATUSH_REGW;
|
||||
MTVEC: CSRMReadValM = MTVEC_REGW;
|
||||
MEDELEG: CSRMReadValM = MEDELEG_REGW;
|
||||
MIDELEG: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIDELEG_REGW};
|
||||
|
@ -196,6 +197,7 @@ module csrm #(parameter
|
|||
MEPC: CSRMReadValM = MEPC_REGW;
|
||||
MCAUSE: CSRMReadValM = MCAUSE_REGW;
|
||||
MTVAL: CSRMReadValM = MTVAL_REGW;
|
||||
MTINST: CSRMReadValM = 0; // implemented as trivial zero
|
||||
MCOUNTEREN:CSRMReadValM = {{(`XLEN-32){1'b0}}, MCOUNTEREN_REGW};
|
||||
MCOUNTINHIBIT:CSRMReadValM = {{(`XLEN-32){1'b0}}, MCOUNTINHIBIT_REGW};
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ module csrsr (
|
|||
input logic mretM, sretM,
|
||||
input logic WriteFRMM, WriteFFLAGSM,
|
||||
input logic [`XLEN-1:0] CSRWriteValM,
|
||||
output logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW,
|
||||
output logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, MSTATUSH_REGW,
|
||||
output logic [1:0] STATUS_MPP,
|
||||
output logic STATUS_SPP, STATUS_TSR, STATUS_TW,
|
||||
output logic STATUS_MIE, STATUS_SIE,
|
||||
|
@ -49,33 +49,34 @@ module csrsr (
|
|||
|
||||
logic STATUS_SD, STATUS_TW_INT, STATUS_TSR_INT, STATUS_TVM_INT, STATUS_MXR_INT, STATUS_SUM_INT, STATUS_MPRV_INT;
|
||||
logic [1:0] STATUS_SXL, STATUS_UXL, STATUS_XS, STATUS_FS, STATUS_FS_INT, STATUS_MPP_NEXT;
|
||||
logic STATUS_MPIE, STATUS_SPIE, STATUS_UPIE, STATUS_UIE;
|
||||
logic STATUS_MPIE, STATUS_SPIE, STATUS_UBE, STATUS_SBE, STATUS_MBE;
|
||||
|
||||
// STATUS REGISTER FIELD
|
||||
// See Privileged Spec Section 3.1.6
|
||||
// Lower privilege status registers are a subset of the full status register
|
||||
// *** consider adding MBE, SBE, UBE fields later from 20210108 draft spec
|
||||
// *** consider adding MBE, SBE, UBE fields, parameterized to be fixed or adjustable
|
||||
if (`XLEN==64) begin: csrsr64 // RV64
|
||||
assign MSTATUS_REGW = {STATUS_SD, 27'b0, STATUS_SXL, STATUS_UXL, 9'b0,
|
||||
assign MSTATUS_REGW = {STATUS_SD, 25'b0, STATUS_MBE, STATUS_UBE, STATUS_SXL, STATUS_UXL, 9'b0,
|
||||
STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV,
|
||||
STATUS_XS, STATUS_FS, STATUS_MPP, 2'b0,
|
||||
STATUS_SPP, STATUS_MPIE, 1'b0, STATUS_SPIE, STATUS_UPIE,
|
||||
STATUS_MIE, 1'b0, STATUS_SIE, STATUS_UIE};
|
||||
STATUS_SPP, STATUS_MPIE, STATUS_UBE, STATUS_SPIE, 1'b0,
|
||||
STATUS_MIE, 1'b0, STATUS_SIE, 1'b0};
|
||||
assign SSTATUS_REGW = {STATUS_SD, /*27'b0, */ 29'b0, /*STATUS_SXL, */ {`QEMU ? 2'b0 : STATUS_UXL}, /*9'b0, */ 12'b0,
|
||||
/*STATUS_TSR, STATUS_TW, STATUS_TVM, */STATUS_MXR, STATUS_SUM, /* STATUS_MPRV, */ 1'b0,
|
||||
STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0,
|
||||
STATUS_SPP, /*STATUS_MPIE, 1'b0*/ 2'b0, STATUS_SPIE, STATUS_UPIE,
|
||||
/*STATUS_MIE, 1'b0*/ 2'b0, STATUS_SIE, STATUS_UIE};
|
||||
STATUS_SPP, /*STATUS_MPIE*/ 1'b0, STATUS_UBE, STATUS_SPIE,
|
||||
/*1'b0, STATUS_MIE, 1'b0*/ 3'b0, STATUS_SIE, 1'b0};
|
||||
end else begin: csrsr32 // RV32
|
||||
assign MSTATUS_REGW = {STATUS_SD, 8'b0,
|
||||
STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV,
|
||||
STATUS_XS, STATUS_FS, STATUS_MPP, 2'b0,
|
||||
STATUS_SPP, STATUS_MPIE, 1'b0, STATUS_SPIE, STATUS_UPIE, STATUS_MIE, 1'b0, STATUS_SIE, STATUS_UIE};
|
||||
STATUS_SPP, STATUS_MPIE, STATUS_UBE, STATUS_SPIE, 1'b0, STATUS_MIE, 1'b0, STATUS_SIE, 1'b0};
|
||||
assign MSTATUSH_REGW = {26'b0, STATUS_MBE, STATUS_SBE, 4'b0};
|
||||
assign SSTATUS_REGW = {STATUS_SD, 11'b0,
|
||||
/*STATUS_TSR, STATUS_TW, STATUS_TVM, */STATUS_MXR, STATUS_SUM, /* STATUS_MPRV, */ 1'b0,
|
||||
STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0,
|
||||
STATUS_SPP, /*STATUS_MPIE, 1'b0*/ 2'b0, STATUS_SPIE, STATUS_UPIE,
|
||||
/*STATUS_MIE, 1'b0*/ 2'b0, STATUS_SIE, STATUS_UIE};
|
||||
STATUS_SPP, /*STATUS_MPIE*/ 1'b0, STATUS_UBE, STATUS_SPIE,
|
||||
/*1'b0, STATUS_MIE, 1'b0*/ 3'b0, STATUS_SIE, 1'b0};
|
||||
end
|
||||
|
||||
// harwired STATUS bits
|
||||
|
@ -83,6 +84,9 @@ module csrsr (
|
|||
assign STATUS_TW = (`S_SUPPORTED | `U_SUPPORTED) & STATUS_TW_INT; // override reigster with 0 if only machine mode supported
|
||||
assign STATUS_TVM = `S_SUPPORTED & STATUS_TVM_INT; // override reigster with 0 if supervisor mode not supported
|
||||
assign STATUS_MXR = `S_SUPPORTED & STATUS_MXR_INT; // override reigster with 0 if supervisor mode not supported
|
||||
assign STATUS_UBE = 0; // little-endian
|
||||
assign STATUS_SBE = 0; // little-endian
|
||||
assign STATUS_MBE = 0; // little-endian
|
||||
// SXL and UXL bits only matter for RV64. Set to 10 for RV64 if mode is supported, or 0 if not
|
||||
assign STATUS_SXL = `S_SUPPORTED ? 2'b10 : 2'b00; // 10 if supervisor mode supported
|
||||
assign STATUS_UXL = `U_SUPPORTED ? 2'b10 : 2'b00; // 10 if user mode supported
|
||||
|
@ -112,10 +116,8 @@ module csrsr (
|
|||
STATUS_SPP <= #1 0; //1'b1;
|
||||
STATUS_MPIE <= #1 0; //1;
|
||||
STATUS_SPIE <= #1 0; //`S_SUPPORTED;
|
||||
STATUS_UPIE <= #1 0; // `U_SUPPORTED;
|
||||
STATUS_MIE <= #1 0; // Per Priv 3.3
|
||||
STATUS_SIE <= #1 0; //`S_SUPPORTED;
|
||||
STATUS_UIE <= #1 0; //`U_SUPPORTED;
|
||||
end else if (~StallW) begin
|
||||
if (FRegWriteM | WriteFRMM | WriteFFLAGSM) STATUS_FS_INT <= #12'b11; // mark Float State dirty *** this should happen in M stage, be part of if/else;
|
||||
|
||||
|
@ -128,26 +130,22 @@ module csrsr (
|
|||
STATUS_MPIE <= #1 STATUS_MIE;
|
||||
STATUS_MIE <= #1 0;
|
||||
STATUS_MPP <= #1 PrivilegeModeW;
|
||||
end else if (NextPrivilegeModeM == `S_MODE) begin
|
||||
end else begin // supervisor mode
|
||||
STATUS_SPIE <= #1 STATUS_SIE;
|
||||
STATUS_SIE <= #1 0;
|
||||
STATUS_SPP <= #1 PrivilegeModeW[0]; // *** seems to disagree with P. 56
|
||||
end else begin // user mode
|
||||
STATUS_UPIE <= #1 STATUS_UIE;
|
||||
STATUS_UIE <= #1 0;
|
||||
end
|
||||
STATUS_SPP <= #1 PrivilegeModeW[0];
|
||||
end
|
||||
end else if (mretM) begin // Privileged 3.1.6.1
|
||||
STATUS_MIE <= #1 STATUS_MPIE;
|
||||
STATUS_MPIE <= #1 1;
|
||||
STATUS_MPP <= #1 `U_SUPPORTED ? `U_MODE : `M_MODE; // per spec, not sure why
|
||||
// possible bug *** Ross Thompson
|
||||
//STATUS_MPRV_INT <= #1 (STATUS_MPP == `M_MODE & STATUS_MPRV_INT); //0; // per 20210108 draft spec
|
||||
STATUS_MPRV_INT <= #1 0; // per 20210108 draft spec
|
||||
STATUS_MIE <= #1 STATUS_MPIE; // restore global interrupt enable
|
||||
STATUS_MPIE <= #1 1; //
|
||||
STATUS_MPP <= #1 `U_SUPPORTED ? `U_MODE : `M_MODE; // set MPP to lowest supported privilege level
|
||||
// STATUS_MPRV_INT <= #1 0; // changed to this by Ross to solve Linux bug; might have been s spurious disagreement with QEMU
|
||||
STATUS_MPRV_INT <= #1 STATUS_MPRV_INT & (STATUS_MPP == `M_MODE); // Seems to be given by page 21 of spec.
|
||||
end else if (sretM) begin
|
||||
STATUS_SIE <= #1 STATUS_SPIE;
|
||||
STATUS_SPIE <= #1 `S_SUPPORTED;
|
||||
STATUS_SPP <= #1 0; // Privileged 4.1.1
|
||||
STATUS_MPRV_INT <= #1 0; // per 20210108 draft spec
|
||||
STATUS_SIE <= #1 STATUS_SPIE; // restore global interrupt enable
|
||||
STATUS_SPIE <= #1 `S_SUPPORTED;
|
||||
STATUS_SPP <= #1 0; // set SPP to lowest supported privilege level to catch bugs
|
||||
STATUS_MPRV_INT <= #1 0; // always clear MPRV
|
||||
end else if (WriteMSTATUSM) begin
|
||||
STATUS_TSR_INT <= #1 CSRWriteValM[22];
|
||||
STATUS_TW_INT <= #1 CSRWriteValM[21];
|
||||
|
@ -160,19 +158,15 @@ module csrsr (
|
|||
STATUS_SPP <= #1 `S_SUPPORTED & CSRWriteValM[8];
|
||||
STATUS_MPIE <= #1 CSRWriteValM[7];
|
||||
STATUS_SPIE <= #1 `S_SUPPORTED & CSRWriteValM[5];
|
||||
STATUS_UPIE <= #1 `U_SUPPORTED & CSRWriteValM[4];
|
||||
STATUS_MIE <= #1 CSRWriteValM[3];
|
||||
STATUS_SIE <= #1 `S_SUPPORTED & CSRWriteValM[1];
|
||||
STATUS_UIE <= #1 `U_SUPPORTED & CSRWriteValM[0];
|
||||
end else if (WriteSSTATUSM) begin // write a subset of the STATUS bits
|
||||
STATUS_MXR_INT <= #1 CSRWriteValM[19];
|
||||
STATUS_SUM_INT <= #1 CSRWriteValM[18];
|
||||
STATUS_FS_INT <= #1 CSRWriteValM[14:13];
|
||||
STATUS_SPP <= #1 `S_SUPPORTED & CSRWriteValM[8];
|
||||
STATUS_SPIE <= #1 `S_SUPPORTED & CSRWriteValM[5];
|
||||
STATUS_UPIE <= #1 `U_SUPPORTED & CSRWriteValM[4];
|
||||
STATUS_SIE <= #1 `S_SUPPORTED & CSRWriteValM[1];
|
||||
STATUS_UIE <= #1 `U_SUPPORTED & CSRWriteValM[0];
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
|
@ -57,7 +57,7 @@ module privileged (
|
|||
input logic StoreAmoMisalignedFaultM,
|
||||
input logic TimerIntM, MExtIntM, SExtIntM, SwIntM,
|
||||
input logic [63:0] MTIME_CLINT,
|
||||
input logic [`XLEN-1:0] InstrMisalignedAdrM, IEUAdrM,
|
||||
input logic [`XLEN-1:0] IEUAdrM,
|
||||
input logic [4:0] SetFflagsM,
|
||||
|
||||
// Trap signals from pmp/pma in mmu
|
||||
|
@ -139,7 +139,7 @@ module privileged (
|
|||
logic [`WFI_TIMEOUT_BIT:0] WFICount, WFICountPlus1;
|
||||
assign WFICountPlus1 = WFICount + 1;
|
||||
floprc #(`WFI_TIMEOUT_BIT+1) wficountreg(clk, reset, ~wfiM, WFICountPlus1, WFICount); // count while in WFI
|
||||
assign WFITimeoutM = STATUS_TW & PrivilegeModeW != `M_MODE & WFICount[`WFI_TIMEOUT_BIT];
|
||||
assign WFITimeoutM = ((STATUS_TW & PrivilegeModeW != `M_MODE) | (`S_SUPPORTED & PrivilegeModeW == `U_MODE)) & WFICount[`WFI_TIMEOUT_BIT];
|
||||
end else assign WFITimeoutM = 0;
|
||||
|
||||
///////////////////////////////////////////
|
||||
|
@ -222,7 +222,7 @@ module privileged (
|
|||
.MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIDELEG_REGW,
|
||||
.STATUS_MIE, .STATUS_SIE,
|
||||
.PCM,
|
||||
.InstrMisalignedAdrM, .IEUAdrM,
|
||||
.IEUAdrM,
|
||||
.InstrM,
|
||||
.InstrValidM, .CommittedM, .DivE,
|
||||
.TrapM, .MTrapM, .STrapM, .UTrapM, .RetM,
|
||||
|
|
|
@ -44,7 +44,7 @@ module trap (
|
|||
(* mark_debug = "true" *) input logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, MIDELEG_REGW,
|
||||
input logic STATUS_MIE, STATUS_SIE,
|
||||
input logic [`XLEN-1:0] PCM,
|
||||
input logic [`XLEN-1:0] InstrMisalignedAdrM, IEUAdrM,
|
||||
input logic [`XLEN-1:0] IEUAdrM,
|
||||
input logic [31:0] InstrM,
|
||||
input logic InstrValidM, CommittedM, DivE,
|
||||
output logic TrapM, MTrapM, STrapM, UTrapM, RetM,
|
||||
|
@ -130,8 +130,8 @@ module trap (
|
|||
else if (SPendingIntsM[5]) CauseM = (1 << (`XLEN-1)) + 5; // Supervisor Timer Int handled by S-mode
|
||||
else if (InstrPageFaultM) CauseM = 12;
|
||||
else if (InstrAccessFaultM) CauseM = 1;
|
||||
else if (InstrMisalignedFaultM) CauseM = 0;
|
||||
else if (IllegalInstrFaultM) CauseM = 2;
|
||||
else if (InstrMisalignedFaultM) CauseM = 0;
|
||||
else if (BreakpointFaultM) CauseM = 3;
|
||||
else if (EcallFaultM) CauseM = {{(`XLEN-2){1'b0}}, PrivilegeModeW} + 8;
|
||||
else if (LoadMisalignedFaultM) CauseM = 4;
|
||||
|
@ -152,13 +152,17 @@ module trap (
|
|||
// Technically
|
||||
|
||||
always_comb
|
||||
if (InstrMisalignedFaultM) NextFaultMtvalM = InstrMisalignedAdrM;
|
||||
if (InstrPageFaultM) NextFaultMtvalM = PCM;
|
||||
else if (InstrAccessFaultM) NextFaultMtvalM = PCM;
|
||||
else if (IllegalInstrFaultM) NextFaultMtvalM = {{(`XLEN-32){1'b0}}, InstrM};
|
||||
else if (InstrMisalignedFaultM) NextFaultMtvalM = IEUAdrM;
|
||||
else if (EcallFaultM) NextFaultMtvalM = 0;
|
||||
else if (BreakpointFaultM) NextFaultMtvalM = PCM;
|
||||
else if (LoadMisalignedFaultM) NextFaultMtvalM = IEUAdrM;
|
||||
else if (StoreAmoMisalignedFaultM) NextFaultMtvalM = IEUAdrM;
|
||||
else if (BreakpointFaultM) NextFaultMtvalM = PCM;
|
||||
else if (InstrPageFaultM) NextFaultMtvalM = PCM;
|
||||
else if (LoadPageFaultM) NextFaultMtvalM = IEUAdrM;
|
||||
else if (StoreAmoPageFaultM) NextFaultMtvalM = IEUAdrM;
|
||||
else if (IllegalInstrFaultM) NextFaultMtvalM = {{(`XLEN-32){1'b0}}, InstrM};
|
||||
else if (LoadAccessFaultM) NextFaultMtvalM = IEUAdrM;
|
||||
else if (StoreAmoAccessFaultM) NextFaultMtvalM = IEUAdrM;
|
||||
else NextFaultMtvalM = 0;
|
||||
endmodule
|
||||
|
|
|
@ -82,7 +82,6 @@ module wallypipelinedcore (
|
|||
logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM;
|
||||
logic LoadMisalignedFaultM, LoadAccessFaultM;
|
||||
logic StoreAmoMisalignedFaultM, StoreAmoAccessFaultM;
|
||||
logic [`XLEN-1:0] InstrMisalignedAdrM;
|
||||
logic InvalidateICacheM, FlushDCacheM;
|
||||
logic PCSrcE;
|
||||
logic CSRWritePendingDEM;
|
||||
|
@ -190,7 +189,6 @@ module wallypipelinedcore (
|
|||
// Faults
|
||||
.IllegalBaseInstrFaultD, .InstrPageFaultF,
|
||||
.IllegalIEUInstrFaultD, .InstrMisalignedFaultM,
|
||||
.InstrMisalignedAdrM,
|
||||
|
||||
// mmu management
|
||||
.PrivilegeModeW, .PTE, .PageType, .SATP_REGW,
|
||||
|
@ -332,7 +330,7 @@ module wallypipelinedcore (
|
|||
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM,
|
||||
.TimerIntM, .MExtIntM, .SExtIntM, .SwIntM,
|
||||
.MTIME_CLINT,
|
||||
.InstrMisalignedAdrM, .IEUAdrM,
|
||||
.IEUAdrM,
|
||||
.SetFflagsM,
|
||||
// Trap signals from pmp/pma in mmu
|
||||
// *** do these need to be split up into one for dmem and one for ifu?
|
||||
|
|
|
@ -173,10 +173,8 @@ module testbench;
|
|||
`define STATUS_SPP `CSR_BASE.csrsr.STATUS_SPP
|
||||
`define STATUS_MPIE `CSR_BASE.csrsr.STATUS_MPIE
|
||||
`define STATUS_SPIE `CSR_BASE.csrsr.STATUS_SPIE
|
||||
`define STATUS_UPIE `CSR_BASE.csrsr.STATUS_UPIE
|
||||
`define STATUS_MIE `CSR_BASE.csrsr.STATUS_MIE
|
||||
`define STATUS_SIE `CSR_BASE.csrsr.STATUS_SIE
|
||||
`define STATUS_UIE `CSR_BASE.csrsr.STATUS_UIE
|
||||
`define UART dut.uncore.uart.uart.u
|
||||
`define UART_IER `UART.IER
|
||||
`define UART_LCR `UART.LCR
|
||||
|
@ -446,8 +444,10 @@ module testbench;
|
|||
force {`STATUS_TSR,`STATUS_TW,`STATUS_TVM,`STATUS_MXR,`STATUS_SUM,`STATUS_MPRV} = initMSTATUS[0][22:17];
|
||||
force {`STATUS_FS,`STATUS_MPP} = initMSTATUS[0][14:11];
|
||||
force {`STATUS_SPP,`STATUS_MPIE} = initMSTATUS[0][8:7];
|
||||
force {`STATUS_SPIE,`STATUS_UPIE,`STATUS_MIE} = initMSTATUS[0][5:3];
|
||||
force {`STATUS_SIE,`STATUS_UIE} = initMSTATUS[0][1:0];
|
||||
// force {`STATUS_SPIE,`STATUS_UPIE,`STATUS_MIE} = initMSTATUS[0][5:3]; // dh removed UPIE and UIE 4/25/22 from depricated n-mode
|
||||
force {`STATUS_SPIE} = initMSTATUS[0][5];
|
||||
force {`STATUS_MIE} = initMSTATUS[0][3];
|
||||
force {`STATUS_SIE} = initMSTATUS[0][1];
|
||||
force `PLIC_INT_ENABLE = {initPLIC_INT_ENABLE[1][`PLIC_NUM_SRC:1],initPLIC_INT_ENABLE[0][`PLIC_NUM_SRC:1]}; // would need to expand into a generate loop to cover an arbitrary number of contexts
|
||||
force `INSTRET = CHECKPOINT;
|
||||
while (reset!==1) #1;
|
||||
|
@ -456,8 +456,8 @@ module testbench;
|
|||
release {`STATUS_TSR,`STATUS_TW,`STATUS_TVM,`STATUS_MXR,`STATUS_SUM,`STATUS_MPRV};
|
||||
release {`STATUS_FS,`STATUS_MPP};
|
||||
release {`STATUS_SPP,`STATUS_MPIE};
|
||||
release {`STATUS_SPIE,`STATUS_UPIE,`STATUS_MIE};
|
||||
release {`STATUS_SIE,`STATUS_UIE};
|
||||
release {`STATUS_SPIE,`STATUS_MIE};
|
||||
release {`STATUS_SIE};
|
||||
release `PLIC_INT_ENABLE;
|
||||
release `INSTRET;
|
||||
end
|
||||
|
|
|
@ -33,10 +33,19 @@ li x28, 0x8
|
|||
csrs mstatus, x28 // set mstatus.MIE bit to 1.
|
||||
WRITE_READ_CSR mie, 0x0 // force zeroing out mie CSR.
|
||||
|
||||
// test 5.3.1.6 Interrupt enabling and priority tests
|
||||
// test 5.3.1.6 Interrupt enabling and priority tests
|
||||
// testing with MIE bits set already tested in WALLY-trap
|
||||
// note that none of these interrupts should be caught or handled.
|
||||
|
||||
jal cause_s_soft_interrupt
|
||||
jal cause_m_soft_interrupt
|
||||
jal cause_s_time_interrupt
|
||||
jal cause_m_time_interrupt
|
||||
li a3, 0x40 // these interrupts involve a time loop waiting for the interrupt to go off.
|
||||
// since interrupts are not always enabled, we need to make it stop after a certain number of loops, which is the number in a3
|
||||
jal cause_s_ext_interrupt_GPIO
|
||||
li a3, 0x40
|
||||
jal cause_m_ext_interrupt
|
||||
|
||||
END_TESTS
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ nowrap:
|
|||
time_loop:
|
||||
//wfi // *** this may now spin us forever in the loop???
|
||||
addi a3, a3, -1
|
||||
bnez a3, m_ext_loop // go through this loop for [a3 value] iterations before returning without performing interrupt
|
||||
bnez a3, time_loop // go through this loop for [a3 value] iterations before returning without performing interrupt
|
||||
ret
|
||||
|
||||
cause_s_time_interrupt:
|
||||
|
@ -178,6 +178,7 @@ cause_m_ext_interrupt:
|
|||
li x28, 0x10060000 // load base GPIO memory location
|
||||
li x29, 0x1
|
||||
sw x29, 0x08(x28) // enable the first pin as an output
|
||||
sw x29, 0x04(x28) // enable the first pin as an input as well to cause the interrupt to fire
|
||||
|
||||
sw x0, 0x1C(x28) // clear rise_ip
|
||||
sw x0, 0x24(x28) // clear fall_ip
|
||||
|
@ -214,6 +215,7 @@ cause_s_ext_interrupt_GPIO:
|
|||
li x28, 0x10060000 // load base GPIO memory location
|
||||
li x29, 0x1
|
||||
sw x29, 0x08(x28) // enable the first pin as an output
|
||||
sw x29, 0x04(x28) // enable the first pin as an input as well to cause the interrupt to fire
|
||||
|
||||
sw x0, 0x1C(x28) // clear rise_ip
|
||||
sw x0, 0x24(x28) // clear fall_ip
|
||||
|
@ -225,7 +227,7 @@ cause_s_ext_interrupt_GPIO:
|
|||
s_ext_loop:
|
||||
//wfi
|
||||
addi a3, a3, -1
|
||||
bnez a3, m_ext_loop // go through this loop for [a3 value] iterations before returning without performing interrupt
|
||||
bnez a3, s_ext_loop // go through this loop for [a3 value] iterations before returning without performing interrupt
|
||||
ret
|
||||
|
||||
end_trap_triggers:
|
||||
|
|
|
@ -52,9 +52,9 @@ GOTO_U_MODE // Causes S mode ecall
|
|||
GOTO_S_MODE // Causes U mode ecall
|
||||
|
||||
|
||||
// some interrupts excluded becaus writing MIP is illegal from S mode
|
||||
jal cause_s_soft_interrupt
|
||||
jal cause_m_soft_interrupt
|
||||
//jal cause_s_time_interrupt // *** S time interrupts cannot come from S mode as of 4/19/22.
|
||||
jal cause_m_time_interrupt
|
||||
li a3, 0x40 // this interrupt involves a time loop waiting for the interrupt to go off.
|
||||
// since interrupts are not always enabled,
|
||||
|
@ -84,13 +84,10 @@ jal cause_store_acc
|
|||
GOTO_U_MODE // Causes S mode ecall
|
||||
GOTO_S_MODE // Causes U mode ecall
|
||||
|
||||
jal cause_s_soft_interrupt // *** M mode Interrupts cannot be delegated in this implementation
|
||||
//jal cause_m_soft_interrupt
|
||||
//jal cause_s_time_interrupt
|
||||
//jal cause_m_time_interrupt
|
||||
// M mode interrupts cannot be delegated in this implementation, so they are excluded from tests
|
||||
jal cause_s_soft_interrupt
|
||||
li a3, 0x40
|
||||
jal cause_s_ext_interrupt_GPIO
|
||||
//jal cause_m_ext_interrupt
|
||||
|
||||
|
||||
END_TESTS
|
||||
|
|
|
@ -50,9 +50,8 @@ jal cause_store_addr_misaligned
|
|||
jal cause_store_acc
|
||||
jal cause_ecall
|
||||
|
||||
//jal cause_s_soft_interrupt // *** writing SIP from u mode is illegal
|
||||
// some interrupts excluded becaus writing SIP/MIP is illegal from U mode
|
||||
jal cause_m_soft_interrupt
|
||||
//jal cause_s_time_interrupt // *** S time interrupts cannot come from U mode as of 4/19/22.
|
||||
jal cause_m_time_interrupt
|
||||
li a3, 0x40 // this interrupt involves a time loop waiting for the interrupt to go off.
|
||||
// since interrupts are not always enabled,
|
||||
|
@ -81,15 +80,9 @@ jal cause_store_addr_misaligned
|
|||
jal cause_store_acc
|
||||
jal cause_ecall
|
||||
|
||||
//jal cause_s_soft_interrupt // *** S Soft interrupts cannot be caused from u mode since writing SIP is illegal
|
||||
// *** M mode Interrupts cannot be delegated in this implementation
|
||||
//jal cause_m_soft_interrupt
|
||||
//jal cause_s_time_interrupt
|
||||
//jal cause_m_time_interrupt
|
||||
// M mode interrupts cannot be delegated in this implementation, so they are excluded from tests
|
||||
li a3, 0x40
|
||||
jal cause_s_ext_interrupt_GPIO
|
||||
//jal cause_m_ext_interrupt
|
||||
|
||||
|
||||
END_TESTS
|
||||
|
||||
|
|
|
@ -34,9 +34,18 @@ csrs mstatus, x28 // set mstatus.MIE bit to 1.
|
|||
WRITE_READ_CSR mie, 0x0 // force zeroing out mie CSR.
|
||||
|
||||
// test 5.3.1.6 Interrupt enabling and priority tests
|
||||
// testing with MIE bits set already tested in WALLY-trap
|
||||
// note that none of these interrupts should be caught or handled.
|
||||
|
||||
jal cause_s_soft_interrupt
|
||||
jal cause_m_soft_interrupt
|
||||
jal cause_s_time_interrupt
|
||||
jal cause_m_time_interrupt
|
||||
li a3, 0x40 // these interrupts involve a time loop waiting for the interrupt to go off.
|
||||
// since interrupts are not always enabled, we need to make it stop after a certain number of loops, which is the number in a3
|
||||
jal cause_s_ext_interrupt_GPIO
|
||||
li a3, 0x40
|
||||
jal cause_m_ext_interrupt
|
||||
|
||||
END_TESTS
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ j end_trap_triggers
|
|||
cause_instr_addr_misaligned:
|
||||
// cause a misaligned address trap
|
||||
auipc x28, 0 // get current PC, which is aligned
|
||||
addi x28, x28, 0x3 // add 1 to pc to create misaligned address
|
||||
addi x28, x28, 0x2 // add 2 to pc to create misaligned address (Assumes compressed instructions are disabled)
|
||||
jr x28 // cause instruction address midaligned trap
|
||||
ret
|
||||
|
||||
|
@ -138,7 +138,7 @@ nowrap:
|
|||
time_loop:
|
||||
//wfi // *** this may now spin us forever in the loop???
|
||||
addi a3, a3, -1
|
||||
bnez a3, m_ext_loop // go through this loop for [a3 value] iterations before returning without performing interrupt
|
||||
bnez a3, time_loop // go through this loop for [a3 value] iterations before returning without performing interrupt
|
||||
ret
|
||||
|
||||
cause_s_time_interrupt:
|
||||
|
@ -180,6 +180,7 @@ cause_m_ext_interrupt:
|
|||
li x28, 0x10060000 // load base GPIO memory location
|
||||
li x29, 0x1
|
||||
sw x29, 0x08(x28) // enable the first pin as an output
|
||||
sw x29, 0x04(x28) // enable the first pin as an input as well to cause the interrupt to fire
|
||||
|
||||
sw x0, 0x1C(x28) // clear rise_ip
|
||||
sw x0, 0x24(x28) // clear fall_ip
|
||||
|
@ -216,6 +217,7 @@ cause_s_ext_interrupt_GPIO:
|
|||
li x28, 0x10060000 // load base GPIO memory location
|
||||
li x29, 0x1
|
||||
sw x29, 0x08(x28) // enable the first pin as an output
|
||||
sw x29, 0x04(x28) // enable the first pin as an input as well to cause the interrupt to fire
|
||||
|
||||
sw x0, 0x1C(x28) // clear rise_ip
|
||||
sw x0, 0x24(x28) // clear fall_ip
|
||||
|
@ -227,7 +229,7 @@ cause_s_ext_interrupt_GPIO:
|
|||
s_ext_loop:
|
||||
//wfi
|
||||
addi a3, a3, -1
|
||||
bnez a3, m_ext_loop // go through this loop for [a3 value] iterations before returning without performing interrupt
|
||||
bnez a3, s_ext_loop // go through this loop for [a3 value] iterations before returning without performing interrupt
|
||||
ret
|
||||
|
||||
end_trap_triggers:
|
||||
|
@ -354,7 +356,7 @@ trap_stack_saved_\MODE\(): // jump here after handling vectored interupt since w
|
|||
csrr x1, \MODE\()cause
|
||||
li x5, 0x8000000000000000 // if msb is set, it is an interrupt
|
||||
and x5, x5, x1
|
||||
bnez x5, interrupt_handler_\MODE\() // return from interrupt
|
||||
bnez x5, interrupt_handler_\MODE\()
|
||||
// Other trap handling is specified in the vector Table
|
||||
la x5, exception_vector_table_\MODE\()
|
||||
slli x1, x1, 3 // multiply cause by 8 to get offset in vector Table
|
||||
|
@ -370,7 +372,7 @@ interrupt_handler_\MODE\():
|
|||
jr x5 // and jump to the handler
|
||||
|
||||
segfault_\MODE\():
|
||||
sd x7, -24(sp) // restore registers from stack before faulting
|
||||
ld x7, -24(sp) // restore registers from stack before faulting
|
||||
ld x5, -16(sp)
|
||||
ld x1, -8(sp)
|
||||
j terminate_test // halt program.
|
||||
|
@ -426,6 +428,8 @@ trapreturn_finished_\MODE\():
|
|||
csrrw sp, \MODE\()scratch, sp // switch sp and scratch stack back to restore the non-trap stack pointer
|
||||
\MODE\()ret // return from trap
|
||||
|
||||
// specific exception handlers
|
||||
|
||||
ecallhandler_\MODE\():
|
||||
// Check input parameter a0. encoding above.
|
||||
li x5, 2 // case 2: change to machine mode
|
||||
|
@ -442,7 +446,7 @@ ecallhandler_changetomachinemode_\MODE\():
|
|||
// note that it is impossible to return to M mode after a trap delegated to S mode
|
||||
li x1, 0b1100000000000
|
||||
csrs \MODE\()status, x1
|
||||
j trapreturn_\MODE\()
|
||||
j trapreturn_\MODE\()
|
||||
|
||||
ecallhandler_changetosupervisormode_\MODE\():
|
||||
// Force status.MPP (bits 12:11) and status.SPP (bit 8) to 01 to enter supervisor mode after (m/s)ret
|
||||
|
@ -478,6 +482,9 @@ addr_misaligned_\MODE\():
|
|||
breakpt_\MODE\():
|
||||
j trapreturn_\MODE\()
|
||||
|
||||
// Vectored interrupt handlers: record the fact that the handler went to the correct vector and then continue to handling
|
||||
// note: does not mess up any registers, saves and restores them to the stack instead.
|
||||
|
||||
s_soft_vector_\MODE\():
|
||||
csrrw sp, \MODE\()scratch, sp // swap sp and scratch so we can use the scratch stack in the trap hanler without messing up sp's value or the stack itself.
|
||||
sd x5, -8(sp) // put x5 on the scratch stack before messing with it
|
||||
|
@ -521,6 +528,8 @@ vectored_int_end_\MODE\():
|
|||
ld x5, -8(sp) // restore x5 before continuing to handle trap in case its needed.
|
||||
j trap_stack_saved_\MODE\()
|
||||
|
||||
// specific interrupt handlers
|
||||
|
||||
soft_interrupt_\MODE\():
|
||||
la x5, 0x02000000 // Reset by clearing MSIP interrupt from CLINT
|
||||
sw x0, 0(x5)
|
||||
|
@ -575,8 +584,6 @@ ext_interrupt_\MODE\():
|
|||
j trapreturn_finished_\MODE\() // return to the code at ra value from before trap
|
||||
|
||||
|
||||
|
||||
|
||||
// Table of trap behavior
|
||||
// lists what to do on each exception (not interrupts)
|
||||
// unexpected exceptions should cause segfaults for easy detection
|
||||
|
@ -1023,8 +1030,6 @@ goto_sv39:
|
|||
or x7, x7, x29 // put ASID into the correct field of SATP
|
||||
or x7, x7, x28 // Base Pagetable physical page number, satp.PPN field.
|
||||
csrw satp, x7
|
||||
li x29, 0xFFFFFFFFFFFFF888
|
||||
sfence.vma x0, x29 // just an attempt ***
|
||||
j test_loop // go to next test case
|
||||
|
||||
goto_sv48:
|
||||
|
|
|
@ -52,9 +52,9 @@ GOTO_U_MODE // Causes S mode ecall
|
|||
GOTO_S_MODE // Causes U mode ecall
|
||||
|
||||
|
||||
// some interrupts excluded becaus writing MIP is illegal from S mode
|
||||
jal cause_s_soft_interrupt
|
||||
jal cause_m_soft_interrupt
|
||||
//jal cause_s_time_interrupt // *** S time interrupts cannot come from S mode as of 4/19/22.
|
||||
jal cause_m_time_interrupt
|
||||
li a3, 0x40 // this interrupt involves a time loop waiting for the interrupt to go off.
|
||||
// since interrupts are not always enabled,
|
||||
|
@ -84,14 +84,10 @@ jal cause_store_acc
|
|||
GOTO_U_MODE // Causes S mode ecall
|
||||
GOTO_S_MODE // Causes U mode ecall
|
||||
|
||||
jal cause_s_soft_interrupt // *** M mode Interrupts cannot be delegated in this implementation
|
||||
//jal cause_m_soft_interrupt
|
||||
//jal cause_s_time_interrupt
|
||||
//jal cause_m_time_interrupt
|
||||
// M mode interrupts cannot be delegated in this implementation, so they are excluded from tests
|
||||
jal cause_s_soft_interrupt
|
||||
li a3, 0x40
|
||||
jal cause_s_ext_interrupt_GPIO
|
||||
//jal cause_m_ext_interrupt
|
||||
|
||||
|
||||
END_TESTS
|
||||
|
||||
|
|
|
@ -50,9 +50,8 @@ jal cause_store_addr_misaligned
|
|||
jal cause_store_acc
|
||||
jal cause_ecall
|
||||
|
||||
//jal cause_s_soft_interrupt // *** writing SIP from u mode is illegal
|
||||
// some interrupts excluded becaus writing SIP/MIP is illegal from U mode
|
||||
jal cause_m_soft_interrupt
|
||||
//jal cause_s_time_interrupt // *** S time interrupts cannot come from U mode as of 4/19/22.
|
||||
jal cause_m_time_interrupt
|
||||
li a3, 0x40 // this interrupt involves a time loop waiting for the interrupt to go off.
|
||||
// since interrupts are not always enabled,
|
||||
|
@ -81,15 +80,9 @@ jal cause_store_addr_misaligned
|
|||
jal cause_store_acc
|
||||
jal cause_ecall
|
||||
|
||||
//jal cause_s_soft_interrupt // *** S Soft interrupts cannot be caused from u mode since writing SIP is illegal
|
||||
// *** M mode Interrupts cannot be delegated in this implementation
|
||||
//jal cause_m_soft_interrupt
|
||||
//jal cause_s_time_interrupt
|
||||
//jal cause_m_time_interrupt
|
||||
// M mode interrupts cannot be delegated in this implementation, so they are excluded from tests
|
||||
li a3, 0x40
|
||||
jal cause_s_ext_interrupt_GPIO
|
||||
//jal cause_m_ext_interrupt
|
||||
|
||||
|
||||
END_TESTS
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue