diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv index 28ca04e4d..55a2d7bac 100644 --- a/src/ieu/controller.sv +++ b/src/ieu/controller.sv @@ -33,6 +33,7 @@ module controller import cvw::*; #(parameter cvw_t P) ( input logic StallD, FlushD, // Stall, flush Decode stage input logic [31:0] InstrD, // Instruction in Decode stage input logic [1:0] STATUS_FS, // is FPU enabled? + input logic [3:0] ENVCFG_CBE, // Cache block operation enables output logic [2:0] ImmSrcD, // Type of immediate extension input logic IllegalIEUFPUInstrD, // Illegal IEU and FPU instruction output logic IllegalBaseInstrD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers @@ -171,8 +172,9 @@ module controller import cvw::*; #(parameter cvw_t P) ( (Funct3D == 3'b100 & P.Q_SUPPORTED) | (Funct3D == 3'b001 & P.ZFH_SUPPORTED)); assign FenceFunctD = (Funct3D == 3'b000) | (P.ZIFENCEI_SUPPORTED & Funct3D == 3'b001); assign CMOFunctD = (Funct3D == 3'b010 & RdD == 5'b0) & - ((P.ZICBOZ_SUPPORTED & InstrD[31:20] == 12'd4) | - (P.ZICBOM_SUPPORTED & (InstrD[31:20] == 12'd0 | InstrD[31:20] == 12'd1 | InstrD[31:20] == 12'd2))); + ((P.ZICBOZ_SUPPORTED & InstrD[31:20] == 12'd4 & ENVCFG_CBE[3]) | + (P.ZICBOM_SUPPORTED & ((InstrD[31:20] == 12'd0 & (ENVCFG_CBE[1:0] != 2'b00))) | + (InstrD[31:20] == 12'd1 | InstrD[31:20] == 12'd2) & ENVCFG_CBE[2])); // *** need to get with enable bits such as MENVCFG_CBZE assign AFunctD = (Funct3D == 3'b010) | (P.XLEN == 64 & Funct3D == 3'b011); assign AMOFunctD = (InstrD[31:27] == 5'b00001) | diff --git a/src/ieu/ieu.sv b/src/ieu/ieu.sv index 444080c62..f930b1103 100644 --- a/src/ieu/ieu.sv +++ b/src/ieu/ieu.sv @@ -31,6 +31,7 @@ module ieu import cvw::*; #(parameter cvw_t P) ( // Decode stage signals input logic [31:0] InstrD, // Instruction input logic [1:0] STATUS_FS, // is FPU enabled? + input logic [3:0] ENVCFG_CBE, // Cache block operation enables input logic IllegalIEUFPUInstrD, // Illegal instruction output logic IllegalBaseInstrD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers // Execute stage signals @@ -99,7 +100,7 @@ module ieu import cvw::*; #(parameter cvw_t P) ( logic BMUActiveE; // Bit manipulation instruction being executed controller #(P) c( - .clk, .reset, .StallD, .FlushD, .InstrD, .STATUS_FS, .ImmSrcD, + .clk, .reset, .StallD, .FlushD, .InstrD, .STATUS_FS, .ENVCFG_CBE, .ImmSrcD, .IllegalIEUFPUInstrD, .IllegalBaseInstrD, .StallE, .FlushE, .FlagsE, .FWriteIntE, .PCSrcE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .MemReadE, .CSRReadE, .Funct3E, .IntDivE, .MDUE, .W64E, .SubArithE, .BranchD, .BranchE, .JumpD, .JumpE, .SCE, diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index fba8a89c5..5b2ea802a 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -84,6 +84,7 @@ module csr import cvw::*; #(parameter cvw_t P) ( output var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0], output logic [2:0] FRM_REGW, + output logic [3:0] ENVCFG_CBE, // output logic [P.XLEN-1:0] CSRReadValW, // value read from CSR output logic [P.XLEN-1:0] UnalignedPCNextF, // Next PC, accounting for traps and returns @@ -123,7 +124,11 @@ module csr import cvw::*; #(parameter cvw_t P) ( logic [P.XLEN-1:0] TVecAlignedM; logic InstrValidNotFlushedM; logic STimerInt; - logic MENVCFG_STCE; + logic [63:0] MENVCFG_REGW; + logic [P.XLEN-1:0] SENVCFG_REGW; + logic ENVCFG_STCE; // supervisor timer counter enable + logic ENVCFG_PBMTE; // page-based memory types enable + logic ENVCFG_FIOM; // fence implies io (presently not used) // only valid unflushed instructions can access CSRs assign InstrValidNotFlushedM = InstrValidM & ~StallW & ~FlushW; @@ -214,7 +219,7 @@ module csr import cvw::*; #(parameter cvw_t P) ( csri #(P) csri(.clk, .reset, .CSRMWriteM, .CSRSWriteM, .CSRWriteValM, .CSRAdrM, .MExtInt, .SExtInt, .MTimerInt, .STimerInt, .MSwInt, - .MIDELEG_REGW, .MENVCFG_STCE, .MIP_REGW, .MIE_REGW, .MIP_REGW_writeable); + .MIDELEG_REGW, .ENVCFG_STCE, .MIP_REGW, .MIE_REGW, .MIP_REGW_writeable); csrsr #(P) csrsr(.clk, .reset, .StallW, .WriteMSTATUSM, .WriteMSTATUSHM, .WriteSSTATUSM, @@ -233,10 +238,12 @@ module csr import cvw::*; #(parameter cvw_t P) ( .MEDELEG_REGW, .MIDELEG_REGW,.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .MIP_REGW, .MIE_REGW, .WriteMSTATUSM, .WriteMSTATUSHM, .IllegalCSRMAccessM, .IllegalCSRMWriteReadonlyM, - .MENVCFG_STCE); + .MENVCFG_REGW); if (P.S_SUPPORTED) begin:csrs + logic STCE; + assign STCE = P.SSTC_SUPPORTED & (PrivilegeModeW == P.M_MODE | (MCOUNTEREN_REGW[1] & ENVCFG_STCE)); csrs #(P) csrs(.clk, .reset, .CSRSWriteM, .STrapM, .CSRAdrM, .NextEPCM, .NextCauseM, .NextMtvalM, .SSTATUS_REGW, @@ -244,8 +251,8 @@ module csr import cvw::*; #(parameter cvw_t P) ( .CSRWriteValM, .PrivilegeModeW, .CSRSReadValM, .STVEC_REGW, .SEPC_REGW, .SCOUNTEREN_REGW, - .SATP_REGW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MTIME_CLINT, .MENVCFG_STCE, - .WriteSSTATUSM, .IllegalCSRSAccessM, .STimerInt); + .SATP_REGW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MTIME_CLINT, .STCE, + .WriteSSTATUSM, .IllegalCSRSAccessM, .STimerInt, .SENVCFG_REGW); end else begin assign WriteSSTATUSM = 0; assign CSRSReadValM = 0; @@ -282,6 +289,14 @@ module csr import cvw::*; #(parameter cvw_t P) ( assign IllegalCSRCAccessM = 1; // counters aren't enabled end + // Broadcast appropriate environment configuration based on privilege mode + assign ENVCFG_STCE = MENVCFG_REGW[63]; // supervisor timer counter enable + assign ENVCFG_PBMTE = MENVCFG_REGW[62]; // page-based memory types enable + assign ENVCFG_CBE = (PrivilegeModeW == P.M_MODE) ? 4'b1111 : + (PrivilegeModeW == P.S_MODE | !P.S_SUPPORTED) ? MENVCFG_REGW[7:4] : SENVCFG_REGW[7:4]; + assign ENVCFG_FIOM = (PrivilegeModeW == P.M_MODE) ? 1'b1 : + (PrivilegeModeW == P.S_MODE | !P.S_SUPPORTED) ? MENVCFG_REGW[0] : SENVCFG_REGW[0]; + // merge CSR Reads assign CSRReadValM = CSRUReadValM | CSRSReadValM | CSRMReadValM | CSRCReadValM; flopenrc #(P.XLEN) CSRValWReg(clk, reset, FlushW, ~StallW, CSRReadValM, CSRReadValW); diff --git a/src/privileged/csri.sv b/src/privileged/csri.sv index ca89617d9..2e5488af7 100644 --- a/src/privileged/csri.sv +++ b/src/privileged/csri.sv @@ -34,7 +34,7 @@ module csri import cvw::*; #(parameter cvw_t P) ( input logic [11:0] CSRAdrM, input logic MExtInt, SExtInt, MTimerInt, STimerInt, MSwInt, input logic [11:0] MIDELEG_REGW, - input logic MENVCFG_STCE, + input logic ENVCFG_STCE, output logic [11:0] MIP_REGW, MIE_REGW, output logic [11:0] MIP_REGW_writeable // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0 ); @@ -61,7 +61,7 @@ module csri import cvw::*; #(parameter cvw_t P) ( if (P.S_SUPPORTED) begin:mask if (P.SSTC_SUPPORTED) begin assign MIP_WRITE_MASK = 12'h202; // SEIP and SSIP are writable, but STIP is not writable when STIMECMP is implemented (see SSTC spec) - assign STIP = MENVCFG_STCE ? STimerInt : MIP_REGW_writeable[5]; + assign STIP = ENVCFG_STCE ? STimerInt : MIP_REGW_writeable[5]; end else begin assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writeable in MIP (20210108-draft 3.1.9) assign STIP = MIP_REGW_writeable[5]; diff --git a/src/privileged/csrm.sv b/src/privileged/csrm.sv index bce7af681..fd2496c44 100644 --- a/src/privileged/csrm.sv +++ b/src/privileged/csrm.sv @@ -48,12 +48,11 @@ module csrm import cvw::*; #(parameter cvw_t P) ( output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW [P.PMP_ENTRIES-1:0], output logic WriteMSTATUSM, WriteMSTATUSHM, output logic IllegalCSRMAccessM, IllegalCSRMWriteReadonlyM, - output logic MENVCFG_STCE + output logic [63:0] MENVCFG_REGW ); logic [P.XLEN-1:0] MISA_REGW, MHARTID_REGW; logic [P.XLEN-1:0] MSCRATCH_REGW, MTVAL_REGW, MCAUSE_REGW; - logic [63:0] MENVCFG_REGW; logic [P.XLEN-1:0] MENVCFGH_REGW; logic [63:0] MENVCFG_PreWriteValM, MENVCFG_WriteValM; logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM; @@ -193,15 +192,6 @@ module csrm import cvw::*; #(parameter cvw_t P) ( assign MENVCFGH_REGW = MENVCFG_REGW[63:32]; end - // Extract bit fields - assign MENVCFG_STCE = MENVCFG_REGW[63]; - // Uncomment these other fields when they are defined - // assign MENVCFG_PBMTE = MENVCFG_REGW[62]; - // assign MENVCFG_CBZE = MENVCFG_REGW[7]; - // assign MENVCFG_CBCFE = MENVCFG_REGW[6]; - // assign MENVCFG_CBIE = MENVCFG_REGW[5:4]; - // assign MENVCFG_FIOM = MENVCFG_REGW[0]; - // Read machine mode CSRs // verilator lint_off WIDTH logic [5:0] entry; diff --git a/src/privileged/csrs.sv b/src/privileged/csrs.sv index 97c8b3f22..84a4d0a4b 100644 --- a/src/privileged/csrs.sv +++ b/src/privileged/csrs.sv @@ -44,10 +44,12 @@ module csrs import cvw::*; #(parameter cvw_t P) ( output logic [P.XLEN-1:0] SATP_REGW, input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, input logic [63:0] MTIME_CLINT, - input logic MENVCFG_STCE, + input logic STCE, output logic WriteSSTATUSM, output logic IllegalCSRSAccessM, - output logic STimerInt + output logic STimerInt, + output logic [P.XLEN-1:0] SENVCFG_REGW + ); // Supervisor CSRs @@ -75,7 +77,6 @@ module csrs import cvw::*; #(parameter cvw_t P) ( logic WriteSENVCFGM; logic [P.XLEN-1:0] SSCRATCH_REGW, STVAL_REGW, SCAUSE_REGW; - logic [P.XLEN-1:0] SENVCFG_REGW; logic [P.XLEN-1:0] SENVCFG_WriteValM; logic [63:0] STIMECMP_REGW; @@ -90,8 +91,8 @@ module csrs import cvw::*; #(parameter cvw_t P) ( assign WriteSATPM = CSRSWriteM & (CSRAdrM == SATP) & (PrivilegeModeW == P.M_MODE | ~STATUS_TVM); assign WriteSCOUNTERENM = CSRSWriteM & (CSRAdrM == SCOUNTEREN); assign WriteSENVCFGM = CSRSWriteM & (CSRAdrM == SENVCFG); - assign WriteSTIMECMPM = CSRSWriteM & (CSRAdrM == STIMECMP) & (PrivilegeModeW == P.M_MODE | (MCOUNTEREN_TM & MENVCFG_STCE)); - assign WriteSTIMECMPHM = CSRSWriteM & (CSRAdrM == STIMECMPH) & (PrivilegeModeW == P.M_MODE | (MCOUNTEREN_TM & MENVCFG_STCE)) & (P.XLEN == 32); + assign WriteSTIMECMPM = CSRSWriteM & (CSRAdrM == STIMECMP) & STCE; + assign WriteSTIMECMPHM = CSRSWriteM & (CSRAdrM == STIMECMPH) & STCE & (P.XLEN == 32); // CSRs flopenr #(P.XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[P.XLEN-1:2], 1'b0, CSRWriteValM[0]}, STVEC_REGW); @@ -125,18 +126,10 @@ module csrs import cvw::*; #(parameter cvw_t P) ( CSRWriteValM[7] & P.ZICBOZ_SUPPORTED, CSRWriteValM[6:4] & {3{P.ZICBOM_SUPPORTED}}, 3'b0, - CSRWriteValM[0] & P.S_SUPPORTED & P.VIRTMEM_SUPPORTED + CSRWriteValM[0] & P.VIRTMEM_SUPPORTED }; flopenr #(P.XLEN) SENVCFGreg(clk, reset, WriteSENVCFGM, SENVCFG_WriteValM, SENVCFG_REGW); - - // Extract bit fields - // Uncomment these other fields when they are defined - // assign SENVCFG_PBMTE = SENVCFG_REGW[62]; - // assign SENVCFG_CBZE = SENVCFG_REGW[7]; - // assign SENVCFG_CBCFE = SENVCFG_REGW[6]; - // assign SENVCFG_CBIE = SENVCFG_REGW[5:4]; - // assign SENVCFG_FIOM = SENVCFG_REGW[0]; // CSR Reads always_comb begin:csrr @@ -157,13 +150,13 @@ module csrs import cvw::*; #(parameter cvw_t P) ( end SCOUNTEREN:CSRSReadValM = {{(P.XLEN-32){1'b0}}, SCOUNTEREN_REGW}; SENVCFG: CSRSReadValM = SENVCFG_REGW; - STIMECMP: if (P.SSTC_SUPPORTED & (PrivilegeModeW == P.M_MODE | (MCOUNTEREN_TM && MENVCFG_STCE))) + STIMECMP: if (STCE) CSRSReadValM = STIMECMP_REGW[P.XLEN-1:0]; else begin CSRSReadValM = 0; IllegalCSRSAccessM = 1; end - STIMECMPH: if (P.SSTC_SUPPORTED & (P.XLEN == 32) & (PrivilegeModeW == P.M_MODE | (MCOUNTEREN_TM && MENVCFG_STCE))) + STIMECMPH: if (STCE) CSRSReadValM[31:0] = STIMECMP_REGW[63:32]; else begin // not supported for RV64 CSRSReadValM = 0; diff --git a/src/privileged/privileged.sv b/src/privileged/privileged.sv index 95ba2b0bd..1023618b5 100644 --- a/src/privileged/privileged.sv +++ b/src/privileged/privileged.sv @@ -82,6 +82,7 @@ module privileged import cvw::*; #(parameter cvw_t P) ( output var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration entries to MMU output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW [P.PMP_ENTRIES-1:0], // PMP address entries to MMU output logic [2:0] FRM_REGW, // FPU rounding mode + output logic [3:0] ENVCFG_CBE, // Cache block operation enables // PC logic output in privileged unit output logic [P.XLEN-1:0] UnalignedPCNextF, // Next PC from trap/return PC logic // control outputs @@ -136,7 +137,7 @@ module privileged import cvw::*; #(parameter cvw_t P) ( .STATUS_MIE, .STATUS_SIE, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TW, .STATUS_FS, .MEDELEG_REGW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .SATP_REGW, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, - .SetFflagsM, .FRM_REGW, + .SetFflagsM, .FRM_REGW, .ENVCFG_CBE, .CSRReadValW,.UnalignedPCNextF, .IllegalCSRAccessM, .BigEndianM); // pipeline early-arriving trap sources diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index ae9931e45..563e4f987 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -79,6 +79,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( logic SquashSCW; logic MDUActiveE; // Mul/Div instruction being executed logic CMOE; // Cache management instruction being executed + logic [3:0] ENVCFG_CBE; // Cache block operation enables // floating point unit signals logic [2:0] FRM_REGW; @@ -189,7 +190,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( // integer execution unit: integer register file, datapath and controller ieu #(P) ieu(.clk, .reset, // Decode Stage interface - .InstrD, .STATUS_FS, .IllegalIEUFPUInstrD, .IllegalBaseInstrD, + .InstrD, .STATUS_FS, .ENVCFG_CBE, .IllegalIEUFPUInstrD, .IllegalBaseInstrD, // Execute Stage interface .PCE, .PCLinkE, .FWriteIntE, .FCvtIntE, .IEUAdrE, .IntDivE, .W64E, .Funct3E, .ForwardedSrcAE, .ForwardedSrcBE, .MDUActiveE, .CMOE, @@ -290,9 +291,9 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( .MTIME_CLINT, .IEUAdrM, .SetFflagsM, .InstrAccessFaultF, .HPTWInstrAccessFaultF, .LoadAccessFaultM, .StoreAmoAccessFaultM, .SelHPTW, .PrivilegeModeW, .SATP_REGW, - .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS, + .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, - .FRM_REGW,.BreakpointFaultM, .EcallFaultM, .wfiM, .IntPendingM, .BigEndianM); + .FRM_REGW, .ENVCFG_CBE, .BreakpointFaultM, .EcallFaultM, .wfiM, .IntPendingM, .BigEndianM); end else begin assign CSRReadValW = 0; assign UnalignedPCNextF = PC2NextF;