From 54b9745a75ac1165b2bed7a5b4d5450738683101 Mon Sep 17 00:00:00 2001 From: bbracker Date: Wed, 30 Mar 2022 13:22:41 -0700 Subject: [PATCH] big interrupts refactor --- pipelined/src/ifu/ifu.sv | 2 +- pipelined/src/privileged/csr.sv | 13 ++-- pipelined/src/privileged/csri.sv | 68 ++++++++----------- pipelined/src/privileged/csrm.sv | 79 ++++++++++++----------- pipelined/src/privileged/privileged.sv | 17 +++-- pipelined/src/privileged/trap.sv | 29 +++++---- pipelined/src/uncore/plic.sv | 12 ++-- pipelined/src/uncore/uncore.sv | 8 +-- pipelined/src/wally/wallypipelinedcore.sv | 9 ++- pipelined/src/wally/wallypipelinedsoc.sv | 6 +- pipelined/testbench/testbench-linux.sv | 2 +- 11 files changed, 116 insertions(+), 129 deletions(-) diff --git a/pipelined/src/ifu/ifu.sv b/pipelined/src/ifu/ifu.sv index 480556aaa..0e8c2f79f 100644 --- a/pipelined/src/ifu/ifu.sv +++ b/pipelined/src/ifu/ifu.sv @@ -66,7 +66,7 @@ module ifu ( output logic IllegalIEUInstrFaultD, output logic InstrMisalignedFaultM, output logic [`XLEN-1:0] InstrMisalignedAdrM, - input logic ExceptionM, PendingInterruptM, + input logic ExceptionM, // mmu management input logic [1:0] PrivilegeModeW, input logic [`XLEN-1:0] PTE, diff --git a/pipelined/src/privileged/csr.sv b/pipelined/src/privileged/csr.sv index ecdcbe50d..489ee9539 100644 --- a/pipelined/src/privileged/csr.sv +++ b/pipelined/src/privileged/csr.sv @@ -43,7 +43,7 @@ module csr #(parameter input logic [31:0] InstrM, input logic [`XLEN-1:0] PCM, SrcAM, input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, - input logic TimerIntM, ExtIntM, ExtIntS, SwIntM, + input logic TimerIntM, MExtIntM, SExtIntM, SwIntM, input logic [63:0] MTIME_CLINT, input logic InstrValidM, FRegWriteM, LoadStallD, input logic BPPredDirWrongM, @@ -60,9 +60,9 @@ module csr #(parameter output logic [1:0] STATUS_MPP, output logic STATUS_SPP, STATUS_TSR, output logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW, - output logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW, + output logic [`XLEN-1:0] MEDELEG_REGW, output logic [`XLEN-1:0] SATP_REGW, - output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, + output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, MIDELEG_REGW, output logic STATUS_MIE, STATUS_SIE, output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, STATUS_TW, output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], @@ -122,9 +122,10 @@ module csr #(parameter assign CSRSWriteM = CSRWriteM & (|PrivilegeModeW); assign CSRUWriteM = CSRWriteM; - csri csri(.clk, .reset, .InstrValidNotFlushedM, .StallW, .CSRMWriteM, .CSRSWriteM, - .CSRAdrM, .ExtIntM, .ExtIntS, .TimerIntM, .SwIntM, - .MIDELEG_REGW, .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .CSRWriteValM); + csri csri(.clk, .reset, .InstrValidNotFlushedM, .StallW, + .CSRMWriteM, .CSRSWriteM, .CSRWriteValM, .CSRAdrM, + .MExtIntM, .SExtIntM, .TimerIntM, .SwIntM, + .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIDELEG_REGW); csrsr csrsr(.clk, .reset, .StallW, .WriteMSTATUSM, .WriteSSTATUSM, .TrapM, .FRegWriteM, .NextPrivilegeModeM, .PrivilegeModeW, diff --git a/pipelined/src/privileged/csri.sv b/pipelined/src/privileged/csri.sv index 16d084f8d..68a265b55 100644 --- a/pipelined/src/privileged/csri.sv +++ b/pipelined/src/privileged/csri.sv @@ -32,78 +32,62 @@ `include "wally-config.vh" module csri #(parameter - // Machine CSRs - MIE = 12'h304, - MIP = 12'h344, - SIE = 12'h104, - SIP = 12'h144) ( + MIE = 12'h304, + MIP = 12'h344, + SIE = 12'h104, + SIP = 12'h144 + ) ( input logic clk, reset, input logic InstrValidNotFlushedM, StallW, input logic CSRMWriteM, CSRSWriteM, + input logic [`XLEN-1:0] CSRWriteValM, input logic [11:0] CSRAdrM, - input logic ExtIntM, ExtIntS, TimerIntM, SwIntM, - input logic [`XLEN-1:0] MIDELEG_REGW, - output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, - input logic [`XLEN-1:0] CSRWriteValM + input logic MExtIntM, SExtIntM, TimerIntM, SwIntM, + input logic [11:0] MIDELEG_REGW, + output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW ); - logic [9:0] IP_REGW_writeable; - logic [11:0] IntInM, IP_REGW, IE_REGW; - logic [11:0] MIP_WRITE_MASK, SIP_WRITE_MASK; + logic [11:0] IP_REGW_writeable; // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0 + logic [11:0] IP_REGW, IE_REGW; + logic [11:0] MIP_WRITE_MASK, SIP_WRITE_MASK, MIE_WRITE_MASK; logic WriteMIPM, WriteMIEM, WriteSIPM, WriteSIEM; - // Determine which interrupts need to be set - // assumes no N-mode user interrupts - - always_comb begin - IntInM = 0; - IntInM[11] = ExtIntM; // MEIP - IntInM[9] = (ExtIntM & MIDELEG_REGW[9]); // SEIP - IntInM[7] = TimerIntM; // MTIP - IntInM[5] = TimerIntM & MIDELEG_REGW[5]; // STIP - IntInM[3] = SwIntM; // MSIP - IntInM[1] = SwIntM & MIDELEG_REGW[1]; // SSIP - end - // Interrupt Write Enables assign WriteMIPM = CSRMWriteM & (CSRAdrM == MIP) & InstrValidNotFlushedM; assign WriteMIEM = CSRMWriteM & (CSRAdrM == MIE) & InstrValidNotFlushedM; assign WriteSIPM = CSRSWriteM & (CSRAdrM == SIP) & InstrValidNotFlushedM; assign WriteSIEM = CSRSWriteM & (CSRAdrM == SIE) & InstrValidNotFlushedM; -// Interrupt Pending and Enable Registers -// MEIP, MTIP, MSIP are read-only -// SEIP, STIP, SSIP is writable in MIP if S mode exists -// SSIP is writable in SIP if S mode exists + // Interrupt Pending and Enable Registers + // MEIP, MTIP, MSIP are read-only + // SEIP, STIP, SSIP is writable in MIP if S mode exists + // SSIP is writable in SIP if S mode exists if (`S_SUPPORTED) begin:mask assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writable in MIP (20210108-draft 3.1.9) assign SIP_WRITE_MASK = 12'h002; // SSIP is writable in SIP (privileged 20210108-draft 4.1.3) + assign MIE_WRITE_MASK = 12'hAAA; end else begin:mask assign MIP_WRITE_MASK = 12'h000; assign SIP_WRITE_MASK = 12'h000; + assign MIE_WRITE_MASK = 12'h888; end always @(posedge clk) - if (reset) IP_REGW_writeable <= 10'b0; - else if (WriteMIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & MIP_WRITE_MASK[9:0]) | {1'b0,IntInM[8:0]}; // MTIP unclearable - else if (WriteSIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & SIP_WRITE_MASK[9:0]) | {1'b0,IntInM[8:0]}; // MTIP unclearable - else IP_REGW_writeable <= IP_REGW_writeable | {1'b0, IntInM[8:0]}; // *** check this turns off interrupts properly even when MIDELEG changes + if (reset) IP_REGW_writeable <= 12'b0; + else if (WriteMIPM) IP_REGW_writeable <= (CSRWriteValM[11:0] & MIP_WRITE_MASK); + else if (WriteSIPM) IP_REGW_writeable <= (CSRWriteValM[11:0] & SIP_WRITE_MASK); always @(posedge clk) if (reset) IE_REGW <= 12'b0; - else if (WriteMIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'hAAA); // MIE controls M and S fields + else if (WriteMIEM) IE_REGW <= (CSRWriteValM[11:0] & MIE_WRITE_MASK); // MIE controls M and S fields else if (WriteSIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'h222) | (IE_REGW & 12'h888); // only S fields - // restricted views of registers - // Add ExtIntM read-only signal - assign IP_REGW = {ExtIntM,1'b0,ExtIntS,1'b0, IntInM[7], 7'b0} | {2'b0, IP_REGW_writeable[9], 3'b0, IP_REGW_writeable[5], 3'b0, IP_REGW_writeable[1], 1'b0}; // *** This is just to force the Machine level bits of IP to be unwriteable and to only come from intInM. PLEASE CHANGE ME!!! - - // Machine Mode + assign IP_REGW = {MExtIntM,1'b0,SExtIntM|IP_REGW_writeable[9],1'b0,TimerIntM,1'b0,IP_REGW_writeable[5],1'b0,SwIntM,1'b0,IP_REGW_writeable[1],1'b0}; + assign MIP_REGW = IP_REGW; assign MIE_REGW = IE_REGW; - // Supervisor mode if (`S_SUPPORTED) begin - assign SIP_REGW = IP_REGW & MIDELEG_REGW[11:0] & 'h222; // only delegated interrupts visible - assign SIE_REGW = IE_REGW & MIDELEG_REGW[11:0] & 'h222; + assign SIP_REGW = IP_REGW & 12'h222; + assign SIE_REGW = IE_REGW & 12'h222; end else begin assign SIP_REGW = 12'b0; assign SIE_REGW = 12'b0; diff --git a/pipelined/src/privileged/csrm.sv b/pipelined/src/privileged/csrm.sv index c66d2d38a..8315d38f0 100644 --- a/pipelined/src/privileged/csrm.sv +++ b/pipelined/src/privileged/csrm.sv @@ -33,42 +33,42 @@ `include "wally-config.vh" module csrm #(parameter - // Machine CSRs - MVENDORID = 12'hF11, - MARCHID = 12'hF12, - MIMPID = 12'hF13, - MHARTID = 12'hF14, - MSTATUS = 12'h300, - MISA_ADR = 12'h301, - MEDELEG = 12'h302, - MIDELEG = 12'h303, - MIE = 12'h304, - MTVEC = 12'h305, - MCOUNTEREN = 12'h306, - MSTATUSH = 12'h310, - MCOUNTINHIBIT = 12'h320, - MSCRATCH = 12'h340, - MEPC = 12'h341, - MCAUSE = 12'h342, - MTVAL = 12'h343, - MIP = 12'h344, - PMPCFG0 = 12'h3A0, - // .. up to 15 more at consecutive addresses - PMPADDR0 = 12'h3B0, - // ... up to 63 more at consecutive addresses - TSELECT = 12'h7A0, - TDATA1 = 12'h7A1, - TDATA2 = 12'h7A2, - TDATA3 = 12'h7A3, - DCSR = 12'h7B0, - DPC = 12'h7B1, - DSCRATCH0 = 12'h7B2, - DSCRATCH1 = 12'h7B3, - // Constants - ZERO = {(`XLEN){1'b0}}, - MEDELEG_MASK = ~(ZERO | `XLEN'b1 << 11), - MIDELEG_MASK = {{(`XLEN-12){1'b0}}, 12'h222} -) ( + // Machine CSRs + MVENDORID = 12'hF11, + MARCHID = 12'hF12, + MIMPID = 12'hF13, + MHARTID = 12'hF14, + MSTATUS = 12'h300, + MISA_ADR = 12'h301, + MEDELEG = 12'h302, + MIDELEG = 12'h303, + MIE = 12'h304, + MTVEC = 12'h305, + MCOUNTEREN = 12'h306, + MSTATUSH = 12'h310, + MCOUNTINHIBIT = 12'h320, + MSCRATCH = 12'h340, + MEPC = 12'h341, + MCAUSE = 12'h342, + MTVAL = 12'h343, + MIP = 12'h344, + PMPCFG0 = 12'h3A0, + // .. up to 15 more at consecutive addresses + PMPADDR0 = 12'h3B0, + // ... up to 63 more at consecutive addresses + TSELECT = 12'h7A0, + TDATA1 = 12'h7A1, + TDATA2 = 12'h7A2, + TDATA3 = 12'h7A3, + DCSR = 12'h7B0, + DPC = 12'h7B1, + DSCRATCH0 = 12'h7B2, + DSCRATCH1 = 12'h7B3, + // Constants + ZERO = {(`XLEN){1'b0}}, + MEDELEG_MASK = ~(ZERO | `XLEN'b1 << 11), + MIDELEG_MASK = 12'h222 // we choose to not make machine interrupts delegable + ) ( input logic clk, reset, input logic InstrValidNotFlushedM, StallW, input logic CSRMWriteM, MTrapM, @@ -78,7 +78,8 @@ module csrm #(parameter output logic [`XLEN-1:0] CSRMReadValM, MTVEC_REGW, (* mark_debug = "true" *) output logic [`XLEN-1:0] MEPC_REGW, output logic [31:0] MCOUNTEREN_REGW, MCOUNTINHIBIT_REGW, - output logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW, + output logic [`XLEN-1:0] MEDELEG_REGW, + output logic [11:0] MIDELEG_REGW, // 64-bit registers in RV64, or two 32-bit registers in RV32 //output var logic [63:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES/8-1:0], output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], @@ -148,7 +149,7 @@ module csrm #(parameter flopenr #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, MTVEC_REGW); if (`S_SUPPORTED) begin:deleg // DELEG registers should exist flopenr #(`XLEN) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM & MEDELEG_MASK /*12'h7FF*/, MEDELEG_REGW); - flopenr #(`XLEN) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM & MIDELEG_MASK /*12'h222*/, MIDELEG_REGW); + flopenr #(12) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM[11:0] & MIDELEG_MASK /*12'h222*/, MIDELEG_REGW); end else assign {MEDELEG_REGW, MIDELEG_REGW} = 0; flopenr #(`XLEN) MSCRATCHreg(clk, reset, WriteMSCRATCHM, CSRWriteValM, MSCRATCH_REGW); @@ -188,7 +189,7 @@ module csrm #(parameter MSTATUSH: CSRMReadValM = 0; // flush this out later if MBE and SBE fields are supported MTVEC: CSRMReadValM = MTVEC_REGW; MEDELEG: CSRMReadValM = MEDELEG_REGW; - MIDELEG: CSRMReadValM = MIDELEG_REGW; + MIDELEG: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIDELEG_REGW}; MIP: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIP_REGW}; MIE: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIE_REGW}; MSCRATCH: CSRMReadValM = MSCRATCH_REGW; diff --git a/pipelined/src/privileged/privileged.sv b/pipelined/src/privileged/privileged.sv index 9a8fb9f8a..4f056662b 100644 --- a/pipelined/src/privileged/privileged.sv +++ b/pipelined/src/privileged/privileged.sv @@ -55,7 +55,7 @@ module privileged ( input logic InstrMisalignedFaultM, IllegalIEUInstrFaultD, IllegalFPUInstrD, input logic LoadMisalignedFaultM, input logic StoreAmoMisalignedFaultM, - input logic TimerIntM, ExtIntM, ExtIntS, SwIntM, + input logic TimerIntM, MExtIntM, SExtIntM, SwIntM, input logic [63:0] MTIME_CLINT, input logic [`XLEN-1:0] InstrMisalignedAdrM, IEUAdrM, input logic [4:0] SetFflagsM, @@ -69,7 +69,6 @@ module privileged ( input logic StoreAmoAccessFaultM, output logic ExceptionM, - output logic PendingInterruptM, output logic IllegalFPUInstrE, output logic [1:0] PrivilegeModeW, output logic [`XLEN-1:0] SATP_REGW, @@ -86,7 +85,8 @@ module privileged ( logic [`XLEN-1:0] CauseM, NextFaultMtvalM; logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW; - logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW; + logic [`XLEN-1:0] MEDELEG_REGW; + logic [11:0] MIDELEG_REGW; logic sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM; logic IllegalCSRAccessM; @@ -111,7 +111,7 @@ module privileged ( /////////////////////////////////////////// // get bits of DELEG registers based on CAUSE - assign md = CauseM[`XLEN-1] ? MIDELEG_REGW[CauseM[`LOG_XLEN-1:0]] : MEDELEG_REGW[CauseM[`LOG_XLEN-1:0]]; + assign md = CauseM[`XLEN-1] ? MIDELEG_REGW[CauseM[3:0]] : MEDELEG_REGW[CauseM[`LOG_XLEN-1:0]]; // PrivilegeMode FSM always_comb begin @@ -150,7 +150,7 @@ module privileged ( .StallE, .StallM, .StallW, .InstrM, .PCM, .SrcAM, .CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .UTrapM, .mretM, .sretM, - .TimerIntM, .ExtIntM, .ExtIntS, .SwIntM, + .TimerIntM, .MExtIntM, .SExtIntM, .SwIntM, .MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .BPPredDirWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, @@ -159,9 +159,9 @@ module privileged ( .CauseM, .NextFaultMtvalM, .STATUS_MPP, .STATUS_SPP, .STATUS_TSR, .MEPC_REGW, .SEPC_REGW, .STVEC_REGW, .MTVEC_REGW, - .MEDELEG_REGW, .MIDELEG_REGW, + .MEDELEG_REGW, .SATP_REGW, - .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, + .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIDELEG_REGW, .STATUS_MIE, .STATUS_SIE, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TW, .PMPCFG_ARRAY_REGW, @@ -210,7 +210,7 @@ module privileged ( .mretM, .sretM, .PrivilegeModeW, .NextPrivilegeModeM, .MEPC_REGW, .SEPC_REGW, .STVEC_REGW, .MTVEC_REGW, - .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, + .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIDELEG_REGW, .STATUS_MIE, .STATUS_SIE, .PCM, .InstrMisalignedAdrM, .IEUAdrM, @@ -219,7 +219,6 @@ module privileged ( .TrapM, .MTrapM, .STrapM, .UTrapM, .RetM, .InterruptM, .ExceptionM, - .PendingInterruptM, .PrivilegedNextPCM, .CauseM, .NextFaultMtvalM); endmodule diff --git a/pipelined/src/privileged/trap.sv b/pipelined/src/privileged/trap.sv index 7f61a5a71..25a246a5a 100644 --- a/pipelined/src/privileged/trap.sv +++ b/pipelined/src/privileged/trap.sv @@ -41,7 +41,7 @@ module trap ( (* mark_debug = "true" *) input logic mretM, sretM, input logic [1:0] PrivilegeModeW, NextPrivilegeModeM, (* mark_debug = "true" *) input logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW, - (* mark_debug = "true" *) input logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, + (* 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, @@ -50,15 +50,13 @@ module trap ( output logic TrapM, MTrapM, STrapM, UTrapM, RetM, output logic InterruptM, output logic ExceptionM, - output logic PendingInterruptM, - output logic [`XLEN-1:0] PrivilegedNextPCM, CauseM, NextFaultMtvalM // output logic [11:0] MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW, // input logic WriteMIPM, WriteSIPM, WriteUIPM, WriteMIEM, WriteSIEM, WriteUIEM ); logic MIntGlobalEnM, SIntGlobalEnM; - (* mark_debug = "true" *) logic [11:0] PendingIntsM; + (* mark_debug = "true" *) logic [11:0] MPendingIntsM, SPendingIntsM; //logic InterruptM; logic [`XLEN-1:0] PrivilegedTrapVector, PrivilegedVectoredTrapVector; logic Exception1M; @@ -67,11 +65,13 @@ module trap ( // interrupt if any sources are pending // & with a M stage valid bit to avoid interrupts from interrupt a nonexistent flushed instruction (in the M stage) // & with ~CommittedM to make sure MEPC isn't chosen so as to rerun the same instr twice + // MPendingIntsM[i] = ((priv == M & mstatus.MIE) | (priv < M)) & mip[i] & mie[i] & ~mideleg[i] + // Sinterrupt[i] = ((priv == S & sstatus.SIE) | (priv < S)) & sip[i] & sie[i] assign MIntGlobalEnM = (PrivilegeModeW != `M_MODE) | STATUS_MIE; // if M ints enabled or lower priv 3.1.9 assign SIntGlobalEnM = (PrivilegeModeW == `U_MODE) | ((PrivilegeModeW == `S_MODE) & STATUS_SIE); // if in lower priv mode, or if S ints enabled and not in higher priv mode 3.1.9 - assign PendingIntsM = ((MIP_REGW & MIE_REGW) & ({12{MIntGlobalEnM}} & 12'h888)) | ((SIP_REGW & SIE_REGW) & ({12{SIntGlobalEnM}} & 12'h222)); - assign PendingInterruptM = (|PendingIntsM) & InstrValidM; - assign InterruptM = PendingInterruptM & ~(CommittedM); // *** RT. temporary hack to prevent integer division from having an interrupt during divide. + assign MPendingIntsM = {12{MIntGlobalEnM}} & MIP_REGW & MIE_REGW & ~MIDELEG_REGW; + assign SPendingIntsM = {12{SIntGlobalEnM}} & SIP_REGW & SIE_REGW; + assign InterruptM = (|MPendingIntsM || |SPendingIntsM) && InstrValidM && ~(CommittedM); // *** RT. CommittedM is a temporary hack to prevent integer division from having an interrupt during divide. // Trigger Traps and RET // According to RISC-V Spec Section 1.6, exceptions are caused by instructions. Interrupts are external asynchronous. @@ -119,12 +119,15 @@ module trap ( // Exceptions are of lower priority than all interrupts (3.1.9) always_comb if (reset) CauseM = 0; // hard reset 3.3 - else if (PendingIntsM[11]) CauseM = (1 << (`XLEN-1)) + 11; // Machine External Int - else if (PendingIntsM[3]) CauseM = (1 << (`XLEN-1)) + 3; // Machine Sw Int - else if (PendingIntsM[7]) CauseM = (1 << (`XLEN-1)) + 7; // Machine Timer Int - else if (PendingIntsM[9]) CauseM = (1 << (`XLEN-1)) + 9; // Supervisor External Int - else if (PendingIntsM[1]) CauseM = (1 << (`XLEN-1)) + 1; // Supervisor Sw Int - else if (PendingIntsM[5]) CauseM = (1 << (`XLEN-1)) + 5; // Supervisor Timer Int + else if (MPendingIntsM[11]) CauseM = (1 << (`XLEN-1)) + 11; // Machine External Int + else if (MPendingIntsM[3]) CauseM = (1 << (`XLEN-1)) + 3; // Machine Sw Int + else if (MPendingIntsM[7]) CauseM = (1 << (`XLEN-1)) + 7; // Machine Timer Int + else if (MPendingIntsM[9]) CauseM = (1 << (`XLEN-1)) + 9; // Supervisor External Int handled by M-mode + else if (MPendingIntsM[1]) CauseM = (1 << (`XLEN-1)) + 1; // Supervisor Sw Int handled by M-mode + else if (MPendingIntsM[5]) CauseM = (1 << (`XLEN-1)) + 5; // Supervisor Timer Int handled by M-mode + else if (SPendingIntsM[9]) CauseM = (1 << (`XLEN-1)) + 9; // Supervisor External Int handled by S-mode + else if (SPendingIntsM[1]) CauseM = (1 << (`XLEN-1)) + 1; // Supervisor Sw Int handled by S-mode + 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; diff --git a/pipelined/src/uncore/plic.sv b/pipelined/src/uncore/plic.sv index cccbe75cf..4db7e8a0e 100644 --- a/pipelined/src/uncore/plic.sv +++ b/pipelined/src/uncore/plic.sv @@ -57,7 +57,7 @@ module plic ( input logic UARTIntr,GPIOIntr, output logic [`XLEN-1:0] HREADPLIC, output logic HRESPPLIC, HREADYPLIC, - output logic ExtIntM, ExtIntS); + output logic MExtIntM, SExtIntM); logic memwrite, memread, initTrans; logic [23:0] entry, entryd; @@ -253,10 +253,10 @@ module plic ( threshMask[ctx][2] = (intThreshold[ctx] != 2) & threshMask[ctx][3]; threshMask[ctx][1] = (intThreshold[ctx] != 1) & threshMask[ctx][2]; end - // is the max priority > threshold? - // *** would it be any better to first priority encode maxPriority into binary and then ">" with threshold? - end - assign ExtIntM = |(threshMask[0] & priorities_with_irqs[0]); - assign ExtIntS = |(threshMask[1] & priorities_with_irqs[1]); + end + // is the max priority > threshold? + // *** would it be any better to first priority encode maxPriority into binary and then ">" with threshold? + assign MExtIntM = |(threshMask[0] & priorities_with_irqs[0]); + assign SExtIntM = |(threshMask[1] & priorities_with_irqs[1]); endmodule diff --git a/pipelined/src/uncore/uncore.sv b/pipelined/src/uncore/uncore.sv index f48b96963..17daf50b1 100644 --- a/pipelined/src/uncore/uncore.sv +++ b/pipelined/src/uncore/uncore.sv @@ -55,7 +55,7 @@ module uncore ( input logic [3:0] HSIZED, input logic HWRITED, // peripheral pins - output logic TimerIntM, SwIntM, ExtIntM, ExtIntS, + output logic TimerIntM, SwIntM, MExtIntM, SExtIntM, input logic [31:0] GPIOPinsIn, output logic [31:0] GPIOPinsOut, GPIOPinsEn, input logic UARTSin, @@ -133,10 +133,10 @@ module uncore ( .HWRITE, .HREADY, .HTRANS, .HWDATA, .UARTIntr, .GPIOIntr, .HREADPLIC, .HRESPPLIC, .HREADYPLIC, - .ExtIntM, .ExtIntS); + .MExtIntM, .SExtIntM); end else begin : plic - assign ExtIntM = 0; - assign ExtIntS = 0; + assign MExtIntM = 0; + assign SExtIntM = 0; end if (`GPIO_SUPPORTED == 1) begin : gpio gpio gpio( diff --git a/pipelined/src/wally/wallypipelinedcore.sv b/pipelined/src/wally/wallypipelinedcore.sv index dd07949bc..43b61e6d5 100644 --- a/pipelined/src/wally/wallypipelinedcore.sv +++ b/pipelined/src/wally/wallypipelinedcore.sv @@ -34,7 +34,7 @@ module wallypipelinedcore ( input logic clk, reset, // Privileged - input logic TimerIntM, ExtIntM, ExtIntS, SwIntM, + input logic TimerIntM, MExtIntM, SExtIntM, SwIntM, input logic [63:0] MTIME_CLINT, // Bus Interface input logic [`AHBW-1:0] HRDATA, @@ -157,7 +157,6 @@ module wallypipelinedcore ( logic [2:0] LSUBusSize; logic ExceptionM; - logic PendingInterruptM; logic DCacheMiss; logic DCacheAccess; logic ICacheMiss; @@ -170,7 +169,7 @@ module wallypipelinedcore ( .StallF, .StallD, .StallE, .StallM, .StallW, .FlushF, .FlushD, .FlushE, .FlushM, .FlushW, - .ExceptionM, .PendingInterruptM, + .ExceptionM, // Fetch .IFUBusHRDATA, .IFUBusAck, .PCF, .IFUBusAdr, .IFUBusRead, .IFUStallF, @@ -331,7 +330,7 @@ module wallypipelinedcore ( .InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM, .InstrMisalignedFaultM, .IllegalIEUInstrFaultD, .IllegalFPUInstrD, .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, - .TimerIntM, .ExtIntM, .ExtIntS, .SwIntM, + .TimerIntM, .MExtIntM, .SExtIntM, .SwIntM, .MTIME_CLINT, .InstrMisalignedAdrM, .IEUAdrM, .SetFflagsM, @@ -339,7 +338,7 @@ module wallypipelinedcore ( // *** do these need to be split up into one for dmem and one for ifu? // instead, could we only care about the instr and F pins that come from ifu and only care about the load/store and m pins that come from dmem? .InstrAccessFaultF, .LoadAccessFaultM, .StoreAmoAccessFaultM, - .ExceptionM, .PendingInterruptM, .IllegalFPUInstrE, + .ExceptionM, .IllegalFPUInstrE, .PrivilegeModeW, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, diff --git a/pipelined/src/wally/wallypipelinedsoc.sv b/pipelined/src/wally/wallypipelinedsoc.sv index 0d844d3cf..f199fe3e3 100644 --- a/pipelined/src/wally/wallypipelinedsoc.sv +++ b/pipelined/src/wally/wallypipelinedsoc.sv @@ -74,7 +74,7 @@ module wallypipelinedsoc ( logic HRESP; logic TimerIntM, SwIntM; // from CLINT logic [63:0] MTIME_CLINT; // from CLINT to CSRs - logic ExtIntM,ExtIntS; // from PLIC + logic MExtIntM,SExtIntM; // from PLIC logic [2:0] HADDRD; logic [3:0] HSIZED; logic HWRITED; @@ -84,7 +84,7 @@ module wallypipelinedsoc ( // instantiate processor and memories wallypipelinedcore core(.clk, .reset, - .TimerIntM, .ExtIntM, .ExtIntS, .SwIntM, + .TimerIntM, .MExtIntM, .SExtIntM, .SwIntM, .MTIME_CLINT, .HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn, .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, @@ -94,7 +94,7 @@ module wallypipelinedsoc ( uncore uncore(.HCLK, .HRESETn, .TIMECLK, .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT, .HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HADDRD, .HSIZED, .HWRITED, - .TimerIntM, .SwIntM, .ExtIntM, .ExtIntS, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .UARTSin, .UARTSout, .MTIME_CLINT, + .TimerIntM, .SwIntM, .MExtIntM, .SExtIntM, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .UARTSin, .UARTSout, .MTIME_CLINT, .HSELEXT, .SDCCmdOut, .SDCCmdOE, .SDCCmdIn, .SDCDatIn, .SDCCLK diff --git a/pipelined/testbench/testbench-linux.sv b/pipelined/testbench/testbench-linux.sv index 50893cf65..8de0f90eb 100644 --- a/pipelined/testbench/testbench-linux.sv +++ b/pipelined/testbench/testbench-linux.sv @@ -357,7 +357,7 @@ module testbench; initial begin force dut.core.priv.priv.SwIntM = 0; force dut.core.priv.priv.TimerIntM = 0; - force dut.core.priv.priv.ExtIntM = 0; + force dut.core.priv.priv.MExtIntM = 0; $sformat(testvectorDir,"%s/linux-testvectors/",RISCV_DIR); $sformat(linuxImageDir,"%s/buildroot/output/images/",RISCV_DIR); if (CHECKPOINT!=0)