diff --git a/config/buildroot/wally-config.vh b/config/buildroot/wally-config.vh index bfe69e84d..fbb5799d5 100644 --- a/config/buildroot/wally-config.vh +++ b/config/buildroot/wally-config.vh @@ -135,7 +135,7 @@ `define BTB_SIZE 10 -`define HPTW_WRITES_SUPPORTED 1 +`define SVADU_SUPPORTED 1 // FPU division architecture `define RADIX 32'h4 diff --git a/config/fpga/wally-config.vh b/config/fpga/wally-config.vh index 3ae91e3a7..03bc3f755 100644 --- a/config/fpga/wally-config.vh +++ b/config/fpga/wally-config.vh @@ -144,7 +144,7 @@ `define BTB_SIZE 10 -`define HPTW_WRITES_SUPPORTED 1 +`define SVADU_SUPPORTED 1 // FPU division architecture `define RADIX 32'h4 diff --git a/config/rv32e/wally-config.vh b/config/rv32e/wally-config.vh index 6e0de3347..b000b7911 100644 --- a/config/rv32e/wally-config.vh +++ b/config/rv32e/wally-config.vh @@ -138,7 +138,7 @@ `define BPRED_SIZE 10 `define BTB_SIZE 10 -`define HPTW_WRITES_SUPPORTED 0 +`define SVADU_SUPPORTED 0 // FPU division architecture `define RADIX 32'h4 diff --git a/config/rv32gc/wally-config.vh b/config/rv32gc/wally-config.vh index 57857f3be..d1571067b 100644 --- a/config/rv32gc/wally-config.vh +++ b/config/rv32gc/wally-config.vh @@ -137,7 +137,7 @@ `define BPRED_SIZE 10 `define BTB_SIZE 10 -`define HPTW_WRITES_SUPPORTED 0 +`define SVADU_SUPPORTED 0 // FPU division architecture `define RADIX 32'h4 diff --git a/config/rv32i/wally-config.vh b/config/rv32i/wally-config.vh index efbf6e7c0..0f2e91c95 100644 --- a/config/rv32i/wally-config.vh +++ b/config/rv32i/wally-config.vh @@ -138,7 +138,7 @@ `define BPRED_SIZE 10 `define BTB_SIZE 10 -`define HPTW_WRITES_SUPPORTED 0 +`define SVADU_SUPPORTED 0 // FPU division architecture `define RADIX 32'h4 diff --git a/config/rv32imc/wally-config.vh b/config/rv32imc/wally-config.vh index 8fb29a678..f6b29895d 100644 --- a/config/rv32imc/wally-config.vh +++ b/config/rv32imc/wally-config.vh @@ -137,7 +137,7 @@ `define BPRED_SIZE 10 `define BTB_SIZE 10 -`define HPTW_WRITES_SUPPORTED 0 +`define SVADU_SUPPORTED 0 // FPU division architecture `define RADIX 32'h4 diff --git a/config/rv64fpquad/wally-config.vh b/config/rv64fpquad/wally-config.vh index dd8058c28..3e4b91600 100644 --- a/config/rv64fpquad/wally-config.vh +++ b/config/rv64fpquad/wally-config.vh @@ -140,7 +140,7 @@ `define BPRED_SIZE 10 `define BTB_SIZE 10 -`define HPTW_WRITES_SUPPORTED 0 +`define SVADU_SUPPORTED 0 // FPU division architecture `define RADIX 32'h4 diff --git a/config/rv64gc/wally-config.vh b/config/rv64gc/wally-config.vh index 4100f4c08..f0dad93b4 100644 --- a/config/rv64gc/wally-config.vh +++ b/config/rv64gc/wally-config.vh @@ -140,7 +140,7 @@ `define BPRED_SIZE 10 `define BTB_SIZE 10 -`define HPTW_WRITES_SUPPORTED 0 +`define SVADU_SUPPORTED 0 // FPU division architecture `define RADIX 32'h4 diff --git a/config/rv64i/wally-config.vh b/config/rv64i/wally-config.vh index a3702c3fd..f485c667d 100644 --- a/config/rv64i/wally-config.vh +++ b/config/rv64i/wally-config.vh @@ -140,7 +140,7 @@ `define BPRED_SIZE 10 `define BTB_SIZE 10 -`define HPTW_WRITES_SUPPORTED 0 +`define SVADU_SUPPORTED 0 // FPU division architecture `define RADIX 32'h4 diff --git a/src/ifu/spill.sv b/src/ifu/spill.sv index 4bb677cab..a5b274633 100644 --- a/src/ifu/spill.sv +++ b/src/ifu/spill.sv @@ -77,7 +77,7 @@ module spill #( //////////////////////////////////////////////////////////////////////////////////////////////////// assign SpillF = &PCF[$clog2(SPILLTHRESHOLD)+1:1]; - assign TakeSpillF = SpillF & ~IFUCacheBusStallD & ~(ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF)); + assign TakeSpillF = SpillF & ~IFUCacheBusStallD & ~(ITLBMissF | (`SVADU_SUPPORTED & InstrDAPageFaultF)); always_ff @(posedge clk) if (reset | FlushD) CurrState <= #1 STATE_READY; diff --git a/src/mmu/hptw.sv b/src/mmu/hptw.sv index c0b7ad933..19a3aca79 100644 --- a/src/mmu/hptw.sv +++ b/src/mmu/hptw.sv @@ -87,7 +87,7 @@ module hptw ( logic [`XLEN-1:0] TranslationVAdr; logic [`XLEN-1:0] NextPTE; logic UpdatePTE; - logic DAPageFault; + logic HPTWDAPageFault; logic [`PA_BITS-1:0] HPTWReadAdr; logic SelHPTWAdr; logic [`XLEN+1:0] HPTWAdrExt; @@ -125,7 +125,7 @@ module hptw ( assign ValidLeafPTE = ValidPTE & LeafPTE; assign ValidNonLeafPTE = ValidPTE & ~LeafPTE; - if(`HPTW_WRITES_SUPPORTED) begin : hptwwrites + if(`SVADU_SUPPORTED) begin : hptwwrites logic ReadAccess, WriteAccess; logic InvalidRead, InvalidWrite; logic UpperBitsUnequalPageFault; @@ -167,14 +167,14 @@ module hptw ( // memory access. If there is the PTE needs to be updated seting Access // and possibly also Dirty. Dirty is set if the operation is a store/amo. // However any other fault should not cause the update. - assign DAPageFault = ValidLeafPTE & (~Accessed | SetDirty) & ~OtherPageFault; + assign HPTWDAPageFault = ValidLeafPTE & (~Accessed | SetDirty) & ~OtherPageFault; assign HPTWRW[0] = (WalkerState == UPDATE_PTE); - assign UpdatePTE = (WalkerState == LEAF) & DAPageFault; + assign UpdatePTE = (WalkerState == LEAF) & HPTWDAPageFault; end else begin // block: hptwwrites assign NextPTE = ReadDataM; assign HPTWAdr = HPTWReadAdr; - assign DAPageFault = '0; + assign HPTWDAPageFault = '0; assign UpdatePTE = '0; assign HPTWRW[0] = '0; end @@ -182,8 +182,8 @@ module hptw ( // Enable and select signals based on states assign StartWalk = (WalkerState == IDLE) & TLBMiss; assign HPTWRW[1] = (WalkerState == L3_RD) | (WalkerState == L2_RD) | (WalkerState == L1_RD) | (WalkerState == L0_RD); - assign DTLBWriteM = (WalkerState == LEAF & ~DAPageFault) & DTLBWalk; - assign ITLBWriteF = (WalkerState == LEAF & ~DAPageFault) & ~DTLBWalk; + assign DTLBWriteM = (WalkerState == LEAF & ~HPTWDAPageFault) & DTLBWalk; + assign ITLBWriteF = (WalkerState == LEAF & ~HPTWDAPageFault) & ~DTLBWalk; // FSM to track PageType based on the levels of the page table traversed flopr #(2) PageTypeReg(clk, reset, NextPageType, PageType); @@ -262,7 +262,7 @@ module hptw ( else NextWalkerState = LEAF; L0_RD: if (DCacheStallM) NextWalkerState = L0_RD; else NextWalkerState = LEAF; - LEAF: if (`HPTW_WRITES_SUPPORTED & DAPageFault) NextWalkerState = UPDATE_PTE; + LEAF: if (`SVADU_SUPPORTED & HPTWDAPageFault) NextWalkerState = UPDATE_PTE; else NextWalkerState = IDLE; UPDATE_PTE: if(DCacheStallM) NextWalkerState = UPDATE_PTE; else NextWalkerState = LEAF; @@ -273,8 +273,8 @@ module hptw ( assign SelHPTW = WalkerState != IDLE; assign HPTWStall = (WalkerState != IDLE) | (WalkerState == IDLE & TLBMiss); - assign ITLBMissOrDAFaultF = ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF); - assign DTLBMissOrDAFaultM = DTLBMissM | (`HPTW_WRITES_SUPPORTED & DataDAPageFaultM); + assign ITLBMissOrDAFaultF = ITLBMissF | (`SVADU_SUPPORTED & InstrDAPageFaultF); + assign DTLBMissOrDAFaultM = DTLBMissM | (`SVADU_SUPPORTED & DataDAPageFaultM); // HTPW address/data/control muxing @@ -291,7 +291,7 @@ module hptw ( mux2 #(7) funct7mux(Funct7M, 7'b0, SelHPTW, LSUFunct7M); mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LSUAtomicM); mux2 #(`XLEN+2) lsupadrmux(IEUAdrExtM, HPTWAdrExt, SelHPTWAdr, IHAdrM); - if(`HPTW_WRITES_SUPPORTED) + if(`SVADU_SUPPORTED) mux2 #(`XLEN) lsuwritedatamux(WriteDataM, PTE, SelHPTW, IHWriteDataM); else assign IHWriteDataM = WriteDataM; diff --git a/src/mmu/mmu.sv b/src/mmu/mmu.sv index 5b5248161..0193a5478 100644 --- a/src/mmu/mmu.sv +++ b/src/mmu/mmu.sv @@ -120,9 +120,9 @@ module mmu #(parameter TLB_ENTRIES = 8, IMMU = 0) ( // Access faults // If TLB miss and translating we want to not have faults from the PMA and PMP checkers. - assign InstrAccessFaultF = (PMAInstrAccessFaultF | PMPInstrAccessFaultF) & ~(Translate & ~TLBHit); - assign LoadAccessFaultM = (PMALoadAccessFaultM | PMPLoadAccessFaultM) & ~(Translate & ~TLBHit); - assign StoreAmoAccessFaultM = (PMAStoreAmoAccessFaultM | PMPStoreAmoAccessFaultM) & ~(Translate & ~TLBHit); + assign InstrAccessFaultF = (PMAInstrAccessFaultF | PMPInstrAccessFaultF) & ~TLBMiss; + assign LoadAccessFaultM = (PMALoadAccessFaultM | PMPLoadAccessFaultM) & ~TLBMiss; + assign StoreAmoAccessFaultM = (PMAStoreAmoAccessFaultM | PMPStoreAmoAccessFaultM) & ~TLBMiss; // Misaligned faults always_comb diff --git a/src/mmu/pmpadrdec.sv b/src/mmu/pmpadrdec.sv index 4aeea116a..5f666eeaf 100644 --- a/src/mmu/pmpadrdec.sv +++ b/src/mmu/pmpadrdec.sv @@ -85,5 +85,9 @@ module pmpadrdec ( assign W = PMPCfg[1]; assign R = PMPCfg[0]; assign Active = |PMPCfg[4:3]; + + // known bug: The size of the access is not yet checked. For example, if an NA4 entry matches 0xC-0xF and the system + // attempts an 8-byte access to 0x8, the access should fail (see page 60 of privileged specification 20211203). This + // implementation will not detect the failure. endmodule diff --git a/src/mmu/tlbcontrol.sv b/src/mmu/tlbcontrol.sv index abbdba8f6..4007b6a08 100644 --- a/src/mmu/tlbcontrol.sv +++ b/src/mmu/tlbcontrol.sv @@ -76,7 +76,7 @@ module tlbcontrol #(parameter ITLB = 0) ( // only execute non-user mode pages. assign ImproperPrivilege = ((EffectivePrivilegeMode == `U_MODE) & ~PTE_U) | ((EffectivePrivilegeMode == `S_MODE) & PTE_U); - if(`HPTW_WRITES_SUPPORTED) begin : hptwwrites + if(`SVADU_SUPPORTED) begin : hptwwrites assign DAPageFault = Translate & TLBHit & ~PTE_A & ~TLBPageFault; assign TLBPageFault = (Translate & TLBHit & (ImproperPrivilege | ~PTE_X | UpperBitsUnequalPageFault | Misaligned | ~PTE_V)); end else begin @@ -98,7 +98,7 @@ module tlbcontrol #(parameter ITLB = 0) ( // Check for write error. Writes are invalid when the page's write bit is // low. assign InvalidWrite = WriteAccess & ~PTE_W; - if(`HPTW_WRITES_SUPPORTED) begin : hptwwrites + if(`SVADU_SUPPORTED) begin : hptwwrites assign DAPageFault = Translate & TLBHit & (~PTE_A | WriteAccess & ~PTE_D) & ~TLBPageFault; assign TLBPageFault = (Translate & TLBHit & (ImproperPrivilege | InvalidRead | InvalidWrite | UpperBitsUnequalPageFault | Misaligned | ~PTE_V)); end else begin diff --git a/src/privileged/csrs.sv b/src/privileged/csrs.sv index 99c56ad1b..253d02457 100644 --- a/src/privileged/csrs.sv +++ b/src/privileged/csrs.sv @@ -86,8 +86,8 @@ module csrs #(parameter assign WriteSTVALM = STrapM | (CSRSWriteM & (CSRAdrM == STVAL)) & InstrValidNotFlushedM; assign WriteSATPM = CSRSWriteM & (CSRAdrM == SATP) & (PrivilegeModeW == `M_MODE | ~STATUS_TVM) & InstrValidNotFlushedM; assign WriteSCOUNTERENM = CSRSWriteM & (CSRAdrM == SCOUNTEREN) & InstrValidNotFlushedM; - assign WriteSTIMECMPM = CSRSWriteM & (CSRAdrM == STIMECMP) & MCOUNTEREN_TM & InstrValidNotFlushedM; - assign WriteSTIMECMPHM = CSRSWriteM & (CSRAdrM == STIMECMPH) & MCOUNTEREN_TM & (`XLEN == 32) & InstrValidNotFlushedM; + assign WriteSTIMECMPM = CSRSWriteM & (CSRAdrM == STIMECMP) & (PrivilegeModeW == `M_MODE | MCOUNTEREN_TM) & InstrValidNotFlushedM; + assign WriteSTIMECMPHM = CSRSWriteM & (CSRAdrM == STIMECMPH) & (PrivilegeModeW == `M_MODE | MCOUNTEREN_TM) & (`XLEN == 32) & InstrValidNotFlushedM; // CSRs flopenr #(`XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, STVEC_REGW); @@ -100,12 +100,14 @@ module csrs #(parameter else assign SATP_REGW = 0; // hardwire to zero if virtual memory not supported flopens #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, CSRWriteValM[31:0], SCOUNTEREN_REGW); - if (`XLEN == 64) - flopenr #(`XLEN) STIMECMPreg(clk, reset, WriteSTIMECMPM, CSRWriteValM, STIMECMP_REGW); - else begin - flopenr #(`XLEN) STIMECMPreg(clk, reset, WriteSTIMECMPM, CSRWriteValM, STIMECMP_REGW[31:0]); - flopenr #(`XLEN) STIMECMPHreg(clk, reset, WriteSTIMECMPHM, CSRWriteValM, STIMECMP_REGW[63:32]); - end + if (`SSTC_SUPPORTED) begin + if (`XLEN == 64) + flopenr #(`XLEN) STIMECMPreg(clk, reset, WriteSTIMECMPM, CSRWriteValM, STIMECMP_REGW); + else begin + flopenr #(`XLEN) STIMECMPreg(clk, reset, WriteSTIMECMPM, CSRWriteValM, STIMECMP_REGW[31:0]); + flopenr #(`XLEN) STIMECMPHreg(clk, reset, WriteSTIMECMPHM, CSRWriteValM, STIMECMP_REGW[63:32]); + end + end else assign STIMECMP_REGW = 0; // Supervisor timer interrupt logic // Spec is a bit peculiar - Machine timer interrupts are produced in CLINT, while Supervisor timer interrupts are in CSRs @@ -132,12 +134,12 @@ module csrs #(parameter if (PrivilegeModeW == `S_MODE & STATUS_TVM) IllegalCSRSAccessM = 1; end SCOUNTEREN:CSRSReadValM = {{(`XLEN-32){1'b0}}, SCOUNTEREN_REGW}; - STIMECMP: if (MCOUNTEREN_TM) CSRSReadValM = STIMECMP_REGW[`XLEN-1:0]; + STIMECMP: if (`SSTC_SUPPORTED & (PrivilegeModeW == `M_MODE | MCOUNTEREN_TM)) CSRSReadValM = STIMECMP_REGW[`XLEN-1:0]; else begin CSRSReadValM = 0; IllegalCSRSAccessM = 1; end - STIMECMPH: if (MCOUNTEREN_TM & (`XLEN == 32)) CSRSReadValM[31:0] = STIMECMP_REGW[63:32]; + STIMECMPH: if (`SSTC_SUPPORTED & (`XLEN == 32) & (PrivilegeModeW == `M_MODE | MCOUNTEREN_TM)) CSRSReadValM[31:0] = STIMECMP_REGW[63:32]; else begin // not supported for RV64 CSRSReadValM = 0; IllegalCSRSAccessM = 1; diff --git a/src/wally/cvw.sv b/src/wally/cvw.sv index c4541b698..eb6146283 100644 --- a/src/wally/cvw.sv +++ b/src/wally/cvw.sv @@ -101,7 +101,7 @@ package cvw; parameter BPRED_SUPPORTED = `BPRED_SUPPORTED; parameter BPRED_TYPE = `BPRED_TYPE; parameter BPRED_SIZE = `BPRED_SIZE; - parameter HPTW_WRITES_SUPPORTED = `HPTW_WRITES_SUPPORTED; + parameter SVADU_SUPPORTED = `SVADU_SUPPORTED; // parameter = `;