diff --git a/config/buildroot/config.vh b/config/buildroot/config.vh index 8aa6d0435..34fcd02d3 100644 --- a/config/buildroot/config.vh +++ b/config/buildroot/config.vh @@ -45,6 +45,11 @@ localparam ZIHPM_SUPPORTED = 1; localparam COUNTERS = 12'd32; localparam ZFH_SUPPORTED = 0; localparam SSTC_SUPPORTED = 0; +localparam ZICBOM_SUPPORTED = 0; +localparam ZICBOZ_SUPPORTED = 0; +localparam ZICBOP_SUPPORTED = 0; +localparam SVPBMT_SUPPORTED = 0; + // LSU microarchitectural Features localparam BUS_SUPPORTED = 1; diff --git a/config/rv32e/config.vh b/config/rv32e/config.vh index 680e4355f..5d4e34630 100644 --- a/config/rv32e/config.vh +++ b/config/rv32e/config.vh @@ -45,6 +45,10 @@ localparam ZICNTR_SUPPORTED = 0; localparam ZIHPM_SUPPORTED = 0; localparam ZFH_SUPPORTED = 0; localparam SSTC_SUPPORTED = 0; +localparam ZICBOM_SUPPORTED = 0; +localparam ZICBOZ_SUPPORTED = 0; +localparam ZICBOP_SUPPORTED = 0; +localparam SVPBMT_SUPPORTED = 0; // LSU microarchitectural Features localparam BUS_SUPPORTED = 1; diff --git a/config/rv32gc/config.vh b/config/rv32gc/config.vh index 00619c936..c5d4d07ba 100644 --- a/config/rv32gc/config.vh +++ b/config/rv32gc/config.vh @@ -46,6 +46,10 @@ localparam ZICNTR_SUPPORTED = 1; localparam ZIHPM_SUPPORTED = 1; localparam ZFH_SUPPORTED = 0; localparam SSTC_SUPPORTED = 1; +localparam ZICBOM_SUPPORTED = 0; +localparam ZICBOZ_SUPPORTED = 0; +localparam ZICBOP_SUPPORTED = 0; +localparam SVPBMT_SUPPORTED = 0; // LSU microarchitectural Features localparam BUS_SUPPORTED = 1; diff --git a/config/rv32i/config.vh b/config/rv32i/config.vh index 0ca375051..2e1284282 100644 --- a/config/rv32i/config.vh +++ b/config/rv32i/config.vh @@ -45,6 +45,10 @@ localparam ZICNTR_SUPPORTED = 0; localparam ZIHPM_SUPPORTED = 0; localparam ZFH_SUPPORTED = 0; localparam SSTC_SUPPORTED = 0; +localparam ZICBOM_SUPPORTED = 0; +localparam ZICBOZ_SUPPORTED = 0; +localparam ZICBOP_SUPPORTED = 0; +localparam SVPBMT_SUPPORTED = 0; // LSU microarchitectural Features localparam BUS_SUPPORTED = 0; diff --git a/config/rv32imc/config.vh b/config/rv32imc/config.vh index 317c642a9..cc4be9886 100644 --- a/config/rv32imc/config.vh +++ b/config/rv32imc/config.vh @@ -44,6 +44,10 @@ localparam ZICNTR_SUPPORTED = 1; localparam ZIHPM_SUPPORTED = 1; localparam ZFH_SUPPORTED = 0; localparam SSTC_SUPPORTED = 0; +localparam ZICBOM_SUPPORTED = 0; +localparam ZICBOZ_SUPPORTED = 0; +localparam ZICBOP_SUPPORTED = 0; +localparam SVPBMT_SUPPORTED = 0; // LSU microarchitectural Features localparam BUS_SUPPORTED = 1; diff --git a/config/rv64fpquad/config.vh b/config/rv64fpquad/config.vh index e29f3fb3b..82d295f2e 100644 --- a/config/rv64fpquad/config.vh +++ b/config/rv64fpquad/config.vh @@ -45,6 +45,10 @@ localparam ZICNTR_SUPPORTED = 1; localparam ZIHPM_SUPPORTED = 1; localparam ZFH_SUPPORTED = 1; localparam SSTC_SUPPORTED = 0; +localparam ZICBOM_SUPPORTED = 0; +localparam ZICBOZ_SUPPORTED = 0; +localparam ZICBOP_SUPPORTED = 0; +localparam SVPBMT_SUPPORTED = 0; // LSU microarchitectural Features localparam BUS_SUPPORTED = 1; diff --git a/config/rv64gc/config.vh b/config/rv64gc/config.vh index 34c824270..c8158e159 100644 --- a/config/rv64gc/config.vh +++ b/config/rv64gc/config.vh @@ -48,6 +48,10 @@ localparam ZICNTR_SUPPORTED = 1; localparam ZIHPM_SUPPORTED = 1; localparam ZFH_SUPPORTED = 0; localparam SSTC_SUPPORTED = 1; +localparam ZICBOM_SUPPORTED = 0; +localparam ZICBOZ_SUPPORTED = 0; +localparam ZICBOP_SUPPORTED = 0; +localparam SVPBMT_SUPPORTED = 0; // LSU microarchitectural Features localparam BUS_SUPPORTED = 1; diff --git a/config/rv64i/config.vh b/config/rv64i/config.vh index 204fb172a..6fbdf057a 100644 --- a/config/rv64i/config.vh +++ b/config/rv64i/config.vh @@ -45,6 +45,10 @@ localparam ZICNTR_SUPPORTED = 0; localparam ZIHPM_SUPPORTED = 0; localparam ZFH_SUPPORTED = 0; localparam SSTC_SUPPORTED = 0; +localparam ZICBOM_SUPPORTED = 0; +localparam ZICBOZ_SUPPORTED = 0; +localparam ZICBOP_SUPPORTED = 0; +localparam SVPBMT_SUPPORTED = 0; // LSU microarchitectural Features localparam BUS_SUPPORTED = 0; diff --git a/config/shared/parameter-defs.vh b/config/shared/parameter-defs.vh index d03a8cf4e..e897f3dd0 100644 --- a/config/shared/parameter-defs.vh +++ b/config/shared/parameter-defs.vh @@ -15,17 +15,21 @@ parameter cvw_t P = '{ ZIHPM_SUPPORTED : ZIHPM_SUPPORTED, ZFH_SUPPORTED : ZFH_SUPPORTED, SSTC_SUPPORTED : SSTC_SUPPORTED, - VIRTMEM_SUPPORTED : VIRTMEM_SUPPORTED, - VECTORED_INTERRUPTS_SUPPORTED : VECTORED_INTERRUPTS_SUPPORTED, - BIGENDIAN_SUPPORTED : BIGENDIAN_SUPPORTED, - SVADU_SUPPORTED : SVADU_SUPPORTED, - ZMMUL_SUPPORTED : ZMMUL_SUPPORTED, + VIRTMEM_SUPPORTED : VIRTMEM_SUPPORTED, + VECTORED_INTERRUPTS_SUPPORTED : VECTORED_INTERRUPTS_SUPPORTED, + BIGENDIAN_SUPPORTED : BIGENDIAN_SUPPORTED, + SVADU_SUPPORTED : SVADU_SUPPORTED, + ZMMUL_SUPPORTED : ZMMUL_SUPPORTED, + ZICBOM_SUPPORTED : ZICBOM_SUPPORTED, + ZICBOZ_SUPPORTED : ZICBOZ_SUPPORTED, + ZICBOP_SUPPORTED : ZICBOP_SUPPORTED, + SVPBMT_SUPPORTED : SVPBMT_SUPPORTED, BUS_SUPPORTED : BUS_SUPPORTED, - DCACHE_SUPPORTED : DCACHE_SUPPORTED, - ICACHE_SUPPORTED : ICACHE_SUPPORTED, - ITLB_ENTRIES : ITLB_ENTRIES, - DTLB_ENTRIES : DTLB_ENTRIES, - DCACHE_NUMWAYS : DCACHE_NUMWAYS, + DCACHE_SUPPORTED : DCACHE_SUPPORTED, + ICACHE_SUPPORTED : ICACHE_SUPPORTED, + ITLB_ENTRIES : ITLB_ENTRIES, + DTLB_ENTRIES : DTLB_ENTRIES, + DCACHE_NUMWAYS : DCACHE_NUMWAYS, DCACHE_WAYSIZEINBYTES : DCACHE_WAYSIZEINBYTES, DCACHE_LINELENINBITS : DCACHE_LINELENINBITS, ICACHE_NUMWAYS : ICACHE_NUMWAYS, diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index 3cc150fc0..7bf2bf7d5 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -94,35 +94,36 @@ module csr import cvw::*; #(parameter cvw_t P) ( localparam MIP = 12'h344; localparam SIP = 12'h144; - logic [P.XLEN-1:0] CSRMReadValM, CSRSReadValM, CSRUReadValM, CSRCReadValM; - logic [P.XLEN-1:0] CSRReadValM; - logic [P.XLEN-1:0] CSRSrcM; - logic [P.XLEN-1:0] CSRRWM, CSRRSM, CSRRCM; - logic [P.XLEN-1:0] CSRWriteValM; - logic [P.XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, MSTATUSH_REGW; - logic [P.XLEN-1:0] STVEC_REGW, MTVEC_REGW; - logic [P.XLEN-1:0] MEPC_REGW, SEPC_REGW; + logic [P.XLEN-1:0] CSRMReadValM, CSRSReadValM, CSRUReadValM, CSRCReadValM; + logic [P.XLEN-1:0] CSRReadValM; + logic [P.XLEN-1:0] CSRSrcM; + logic [P.XLEN-1:0] CSRRWM, CSRRSM, CSRRCM; + logic [P.XLEN-1:0] CSRWriteValM; + logic [P.XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, MSTATUSH_REGW; + logic [P.XLEN-1:0] STVEC_REGW, MTVEC_REGW; + logic [P.XLEN-1:0] MEPC_REGW, SEPC_REGW; logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW; logic WriteMSTATUSM, WriteMSTATUSHM, WriteSSTATUSM; logic CSRMWriteM, CSRSWriteM, CSRUWriteM; logic UngatedCSRMWriteM; logic WriteFRMM, WriteFFLAGSM; - logic [P.XLEN-1:0] UnalignedNextEPCM, NextEPCM, NextMtvalM; + logic [P.XLEN-1:0] UnalignedNextEPCM, NextEPCM, NextMtvalM; logic [4:0] NextCauseM; logic [11:0] CSRAdrM; logic IllegalCSRCAccessM, IllegalCSRMAccessM, IllegalCSRSAccessM, IllegalCSRUAccessM; logic InsufficientCSRPrivilegeM; logic IllegalCSRMWriteReadonlyM; - logic [P.XLEN-1:0] CSRReadVal2M; + logic [P.XLEN-1:0] CSRReadVal2M; logic [11:0] MIP_REGW_writeable; - logic [P.XLEN-1:0] TVecM, TrapVectorM, NextFaultMtvalM; + logic [P.XLEN-1:0] TVecM, TrapVectorM, NextFaultMtvalM; logic MTrapM, STrapM; - logic [P.XLEN-1:0] EPC; + logic [P.XLEN-1:0] EPC; logic RetM; logic SelMtvecM; - logic [P.XLEN-1:0] TVecAlignedM; + logic [P.XLEN-1:0] TVecAlignedM; logic InstrValidNotFlushedM; logic STimerInt; + logic MENVCFG_STCE; // only valid unflushed instructions can access CSRs assign InstrValidNotFlushedM = InstrValidM & ~StallW & ~FlushW; @@ -213,7 +214,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, .MIP_REGW, .MIE_REGW, .MIP_REGW_writeable); + .MIDELEG_REGW, .MENVCFG_STCE, .MIP_REGW, .MIE_REGW, .MIP_REGW_writeable); csrsr #(P) csrsr(.clk, .reset, .StallW, .WriteMSTATUSM, .WriteMSTATUSHM, .WriteSSTATUSM, @@ -231,7 +232,8 @@ module csr import cvw::*; #(parameter cvw_t P) ( .MEPC_REGW, .MCOUNTEREN_REGW, .MCOUNTINHIBIT_REGW, .MEDELEG_REGW, .MIDELEG_REGW,.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .MIP_REGW, .MIE_REGW, .WriteMSTATUSM, .WriteMSTATUSHM, - .IllegalCSRMAccessM, .IllegalCSRMWriteReadonlyM); + .IllegalCSRMAccessM, .IllegalCSRMWriteReadonlyM, + .MENVCFG_STCE); if (P.S_SUPPORTED) begin:csrs @@ -242,7 +244,7 @@ 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, + .SATP_REGW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MTIME_CLINT, .MENVCFG_STCE, .WriteSSTATUSM, .IllegalCSRSAccessM, .STimerInt); end else begin assign WriteSSTATUSM = 0; diff --git a/src/privileged/csri.sv b/src/privileged/csri.sv index 7da8985d5..c7e6ca51a 100644 --- a/src/privileged/csri.sv +++ b/src/privileged/csri.sv @@ -30,10 +30,11 @@ module csri import cvw::*; #(parameter cvw_t P) ( input logic clk, reset, input logic CSRMWriteM, CSRSWriteM, - input logic [P.XLEN-1:0] CSRWriteValM, + input logic [P.XLEN-1:0] CSRWriteValM, input logic [11:0] CSRAdrM, input logic MExtInt, SExtInt, MTimerInt, STimerInt, MSwInt, input logic [11:0] MIDELEG_REGW, + input logic MENVCFG_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 ); @@ -60,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 = STimerInt; + assign STIP = MENVCFG_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 44cdc2c94..40dc73996 100644 --- a/src/privileged/csrm.sv +++ b/src/privileged/csrm.sv @@ -32,29 +32,34 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module csrm import cvw::*; #(parameter cvw_t P) ( - input logic clk, reset, - input logic UngatedCSRMWriteM, CSRMWriteM, MTrapM, - input logic [11:0] CSRAdrM, + input logic clk, reset, + input logic UngatedCSRMWriteM, CSRMWriteM, MTrapM, + input logic [11:0] CSRAdrM, input logic [P.XLEN-1:0] NextEPCM, NextMtvalM, MSTATUS_REGW, MSTATUSH_REGW, - input logic [4:0] NextCauseM, + input logic [4:0] NextCauseM, input logic [P.XLEN-1:0] CSRWriteValM, - input logic [11:0] MIP_REGW, MIE_REGW, + input logic [11:0] MIP_REGW, MIE_REGW, output logic [P.XLEN-1:0] CSRMReadValM, MTVEC_REGW, output logic [P.XLEN-1:0] MEPC_REGW, - output logic [31:0] MCOUNTEREN_REGW, MCOUNTINHIBIT_REGW, - output logic [15:0] MEDELEG_REGW, - output logic [11:0] MIDELEG_REGW, - output var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], + output logic [31:0] MCOUNTEREN_REGW, MCOUNTINHIBIT_REGW, + output logic [15:0] MEDELEG_REGW, + output logic [11:0] MIDELEG_REGW, + 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 WriteMSTATUSM, WriteMSTATUSHM, - output logic IllegalCSRMAccessM, IllegalCSRMWriteReadonlyM + output logic WriteMSTATUSM, WriteMSTATUSHM, + output logic IllegalCSRMAccessM, IllegalCSRMWriteReadonlyM, + output logic MENVCFG_STCE ); logic [P.XLEN-1:0] MISA_REGW, MHARTID_REGW; logic [P.XLEN-1:0] MSCRATCH_REGW, MTVAL_REGW, MCAUSE_REGW; - logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM; - logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM; - logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM; + logic [63:0] MENVCFG_REGW; + logic [P.XLEN-1:0] MENVCFGH_REGW; + logic [63:0] MENVCFG_PreWriteValM, MENVCFG_WriteValM; + logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM; + logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM; + logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM; + logic WriteMENVCFGM; // Machine CSRs localparam MVENDORID = 12'hF11; @@ -69,7 +74,9 @@ module csrm import cvw::*; #(parameter cvw_t P) ( localparam MIE = 12'h304; localparam MTVEC = 12'h305; localparam MCOUNTEREN = 12'h306; + localparam MENVCFG = 12'h30A; localparam MSTATUSH = 12'h310; + localparam MENVCFGH = 12'h31A; localparam MCOUNTINHIBIT = 12'h320; localparam MSCRATCH = 12'h340; localparam MEPC = 12'h341; @@ -131,7 +138,7 @@ module csrm import cvw::*; #(parameter cvw_t P) ( // Write machine Mode CSRs assign WriteMSTATUSM = CSRMWriteM & (CSRAdrM == MSTATUS); - assign WriteMSTATUSHM = CSRMWriteM & (CSRAdrM == MSTATUSH)& (P.XLEN==32); + assign WriteMSTATUSHM = CSRMWriteM & (CSRAdrM == MSTATUSH) & (P.XLEN==32); assign WriteMTVECM = CSRMWriteM & (CSRAdrM == MTVEC); assign WriteMEDELEGM = CSRMWriteM & (CSRAdrM == MEDELEG); assign WriteMIDELEGM = CSRMWriteM & (CSRAdrM == MIDELEG); @@ -140,6 +147,7 @@ module csrm import cvw::*; #(parameter cvw_t P) ( assign WriteMCAUSEM = MTrapM | (CSRMWriteM & (CSRAdrM == MCAUSE)); assign WriteMTVALM = MTrapM | (CSRMWriteM & (CSRAdrM == MTVAL)); assign WriteMCOUNTERENM = CSRMWriteM & (CSRAdrM == MCOUNTEREN); + assign WriteMENVCFGM = CSRMWriteM & (CSRAdrM == MENVCFG); assign WriteMCOUNTINHIBITM = CSRMWriteM & (CSRAdrM == MCOUNTINHIBIT); assign IllegalCSRMWriteReadonlyM = UngatedCSRMWriteM & (CSRAdrM == MVENDORID | CSRAdrM == MARCHID | CSRAdrM == MIMPID | CSRAdrM == MHARTID); @@ -161,6 +169,39 @@ module csrm import cvw::*; #(parameter cvw_t P) ( flopenr #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], MCOUNTEREN_REGW); end else assign MCOUNTEREN_REGW = '0; + // MENVCFG is always 64 bits even for RV32 + assign MENVCFG_WriteValM = { + MENVCFG_PreWriteValM[63] & P.SSTC_SUPPORTED, + MENVCFG_PreWriteValM[62] & P.SVPBMT_SUPPORTED, + 54'b0, + MENVCFG_PreWriteValM[7] & P.ZICBOZ_SUPPORTED, + MENVCFG_PreWriteValM[6:4] & {3{P.ZICBOM_SUPPORTED}}, + 3'b0, + MENVCFG_PreWriteValM[0] & P.S_SUPPORTED & P.VIRTMEM_SUPPORTED + }; + + if (P.XLEN == 64) begin + assign MENVCFG_PreWriteValM = CSRWriteValM; + flopenr #(P.XLEN) MENVCFGreg(clk, reset, WriteMENVCFGM, MENVCFG_WriteValM, MENVCFG_REGW); + assign MENVCFGH_REGW = 0; + end else begin + logic WriteMENVCFGHM; + assign MENVCFG_PreWriteValM = {CSRWriteValM, CSRWriteValM}; + assign WriteMENVCFGHM = CSRMWriteM & (CSRAdrM == MENVCFGH) & (P.XLEN==32); + flopenr #(P.XLEN) MENVCFGreg(clk, reset, WriteMENVCFGM, MENVCFG_WriteValM[31:0], MENVCFG_REGW[31:0]); + flopenr #(P.XLEN) MENVCFGHreg(clk, reset, WriteMENVCFGHM, MENVCFG_WriteValM[63:32], MENVCFG_REGW[63:32]); + 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; @@ -200,6 +241,8 @@ module csrm import cvw::*; #(parameter cvw_t P) ( MTVAL: CSRMReadValM = MTVAL_REGW; MTINST: CSRMReadValM = 0; // implemented as trivial zero MCOUNTEREN:CSRMReadValM = {{(P.XLEN-32){1'b0}}, MCOUNTEREN_REGW}; + MENVCFG: CSRMReadValM = MENVCFG_REGW[P.XLEN-1:0]; + MENVCFGH: CSRMReadValM = MENVCFGH_REGW; MCOUNTINHIBIT:CSRMReadValM = {{(P.XLEN-32){1'b0}}, MCOUNTINHIBIT_REGW}; default: begin diff --git a/src/privileged/csrs.sv b/src/privileged/csrs.sv index 9a8bb9d8e..e28ec79da 100644 --- a/src/privileged/csrs.sv +++ b/src/privileged/csrs.sv @@ -29,24 +29,25 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module csrs import cvw::*; #(parameter cvw_t P) ( - input logic clk, reset, - input logic CSRSWriteM, STrapM, - input logic [11:0] CSRAdrM, + input logic clk, reset, + input logic CSRSWriteM, STrapM, + input logic [11:0] CSRAdrM, input logic [P.XLEN-1:0] NextEPCM, NextMtvalM, SSTATUS_REGW, - input logic [4:0] NextCauseM, - input logic STATUS_TVM, - input logic MCOUNTEREN_TM, // TM bit (1) of MCOUNTEREN; cause illegal instruction when trying to access STIMECMP if clear + input logic [4:0] NextCauseM, + input logic STATUS_TVM, + input logic MCOUNTEREN_TM, // TM bit (1) of MCOUNTEREN; cause illegal instruction when trying to access STIMECMP if clear input logic [P.XLEN-1:0] CSRWriteValM, - input logic [1:0] PrivilegeModeW, + input logic [1:0] PrivilegeModeW, output logic [P.XLEN-1:0] CSRSReadValM, STVEC_REGW, output logic [P.XLEN-1:0] SEPC_REGW, - output logic [31:0] SCOUNTEREN_REGW, + output logic [31:0] SCOUNTEREN_REGW, output logic [P.XLEN-1:0] SATP_REGW, - input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, - input logic [63:0] MTIME_CLINT, - output logic WriteSSTATUSM, - output logic IllegalCSRSAccessM, - output logic STimerInt + input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, + input logic [63:0] MTIME_CLINT, + input logic MENVCFG_STCE, + output logic WriteSSTATUSM, + output logic IllegalCSRSAccessM, + output logic STimerInt ); // Supervisor CSRs @@ -54,6 +55,7 @@ module csrs import cvw::*; #(parameter cvw_t P) ( localparam SIE = 12'h104; localparam STVEC = 12'h105; localparam SCOUNTEREN = 12'h106; + localparam SENVCFG = 12'h10A; localparam SSCRATCH = 12'h140; localparam SEPC = 12'h141; localparam SCAUSE = 12'h142; @@ -70,7 +72,12 @@ module csrs import cvw::*; #(parameter cvw_t P) ( logic WriteSSCRATCHM, WriteSEPCM; logic WriteSCAUSEM, WriteSTVALM, WriteSATPM, WriteSCOUNTERENM; logic WriteSTIMECMPM, WriteSTIMECMPHM; - logic [P.XLEN-1:0] SSCRATCH_REGW, STVAL_REGW, SCAUSE_REGW; + 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; // write enables @@ -82,8 +89,9 @@ module csrs import cvw::*; #(parameter cvw_t P) ( assign WriteSTVALM = STrapM | (CSRSWriteM & (CSRAdrM == STVAL)); assign WriteSATPM = CSRSWriteM & (CSRAdrM == SATP) & (PrivilegeModeW == P.M_MODE | ~STATUS_TVM); assign WriteSCOUNTERENM = CSRSWriteM & (CSRAdrM == SCOUNTEREN); - assign WriteSTIMECMPM = CSRSWriteM & (CSRAdrM == STIMECMP) & (PrivilegeModeW == P.M_MODE | MCOUNTEREN_TM); - assign WriteSTIMECMPHM = CSRSWriteM & (CSRAdrM == STIMECMPH) & (PrivilegeModeW == P.M_MODE | MCOUNTEREN_TM) & (P.XLEN == 32); + 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); // CSRs flopenr #(P.XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[P.XLEN-1:2], 1'b0, CSRWriteValM[0]}, STVEC_REGW); @@ -111,6 +119,24 @@ module csrs import cvw::*; #(parameter cvw_t P) ( assign STimerInt = ({1'b0, MTIME_CLINT} >= {1'b0, STIMECMP_REGW}); // unsigned comparison else assign STimerInt = 0; + + assign SENVCFG_WriteValM = { + {(P.XLEN-8){1'b0}}, + CSRWriteValM[7] & P.ZICBOZ_SUPPORTED, + CSRWriteValM[6:4] & {3{P.ZICBOM_SUPPORTED}}, + 3'b0, + CSRWriteValM[0] & P.S_SUPPORTED & 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 @@ -130,12 +156,15 @@ module csrs import cvw::*; #(parameter cvw_t P) ( IllegalCSRSAccessM = 1; end SCOUNTEREN:CSRSReadValM = {{(P.XLEN-32){1'b0}}, SCOUNTEREN_REGW}; - STIMECMP: if (P.SSTC_SUPPORTED & (PrivilegeModeW == P.M_MODE | MCOUNTEREN_TM)) CSRSReadValM = STIMECMP_REGW[P.XLEN-1:0]; + SENVCFG: CSRSReadValM = SENVCFG_REGW; + STIMECMP: if (P.SSTC_SUPPORTED & (PrivilegeModeW == P.M_MODE | (MCOUNTEREN_TM && MENVCFG_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)) CSRSReadValM[31:0] = STIMECMP_REGW[63:32]; + STIMECMPH: if (P.SSTC_SUPPORTED & (P.XLEN == 32) & (PrivilegeModeW == P.M_MODE | (MCOUNTEREN_TM && MENVCFG_STCE))) + CSRSReadValM[31:0] = STIMECMP_REGW[63:32]; else begin // not supported for RV64 CSRSReadValM = 0; IllegalCSRSAccessM = 1; diff --git a/src/privileged/csrsr.sv b/src/privileged/csrsr.sv index fc98dcb56..a4b89297f 100644 --- a/src/privileged/csrsr.sv +++ b/src/privileged/csrsr.sv @@ -4,7 +4,7 @@ // Written: David_Harris@hmc.edu 9 January 2021 // Modified: // -// Purpose: Status register +// Purpose: Status register (and environment configuration register and others shared across modes) // See RISC-V Privileged Mode Specification 20190608 // // Documentation: RISC-V System on Chip Design Chapter 5 diff --git a/src/wally/cvw.sv b/src/wally/cvw.sv index e61c8b9ce..65f9c5371 100644 --- a/src/wally/cvw.sv +++ b/src/wally/cvw.sv @@ -57,6 +57,10 @@ typedef struct packed { logic BIGENDIAN_SUPPORTED; logic SVADU_SUPPORTED; logic ZMMUL_SUPPORTED; + logic ZICBOM_SUPPORTED; + logic ZICBOZ_SUPPORTED; + logic ZICBOP_SUPPORTED; + logic SVPBMT_SUPPORTED; // Microarchitectural Features logic BUS_SUPPORTED; diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-01.reference_output index d885ab6c0..5b0d84182 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-01.reference_output +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-01.reference_output @@ -1,4 +1,5 @@ 00000aaa # Test 5.3.1.4: readback value from writing mie to enable interrupts # skipping instruction address fault since they're impossible with compressed instrs enabled +80000000 # readback value from writing menvcfgh 00000001 # mcause from an instruction access fault 00000000 # mtval of faulting instruction address (0x0) 00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-trap-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-trap-01.S index d90dff9eb..7de42d887 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-trap-01.S +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-trap-01.S @@ -34,8 +34,8 @@ TRAP_HANDLER m, EXT_SIGNATURE=1 // turn on recording mtval and status bits on tr li x28, 0x8 csrs mstatus, x28 // set mstatus.MIE bit to 1 -WRITE_READ_CSR mie, 0xFFF // Enable interrupts from all sources // *** commented out until I can get the trap handler (and spike for time interrupts) to work correctly with interrupts - +WRITE_READ_CSR mie, 0xFFF // Enable interrupts from all sources +WRITE_READ_CSR menvcfgh, 0x80000000 // Enable menvcfg.STCE // test 5.3.1.4 Basic trap tests // instr address misaligned instructions are excluded from this test since they are impossible to cause when compressed instructions are enabled. diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-01.reference_output index cb872b5b8..265de8583 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-01.reference_output +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-01.reference_output @@ -1,5 +1,7 @@ 00000aaa # Test 5.3.1.4: readback value from writing mie to enable interrupts 00000000 # skipping instruction address fault since they're impossible with compressed instrs enabled +00000000 # menvcfg low bits +80000000 # menvcfg high bits 00000001 # mcause from an instruction access fault 00000000 00000000 # mtval of faulting instruction address (0x0) diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-trap-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-trap-01.S index 26c06e053..a553726b5 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-trap-01.S +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-trap-01.S @@ -34,6 +34,7 @@ TRAP_HANDLER m, EXT_SIGNATURE=1 // turn on recording mtval and status bits on tr li x28, 0x8 csrs mstatus, x28 // set mstatus.MIE bit to 1 WRITE_READ_CSR mie, 0xFFF // Enable interrupts from all sources +WRITE_READ_CSR menvcfg, 0x8000000000000000 // Enable menvcfg.STCE // test 5.3.1.4 Basic trap tests