diff --git a/config/buildroot/config.vh b/config/buildroot/config.vh index 14f329907..371c825e2 100644 --- a/config/buildroot/config.vh +++ b/config/buildroot/config.vh @@ -49,7 +49,7 @@ localparam ZICBOM_SUPPORTED = 0; localparam ZICBOZ_SUPPORTED = 0; localparam ZICBOP_SUPPORTED = 0; localparam SVPBMT_SUPPORTED = 0; - +localparam SVINVAL_SUPPORTED = 1; // LSU microarchitectural Features localparam BUS_SUPPORTED = 1; diff --git a/config/fpga/config.vh b/config/fpga/config.vh index 25fbaae13..dbd7d9687 100644 --- a/config/fpga/config.vh +++ b/config/fpga/config.vh @@ -50,6 +50,7 @@ localparam ZICBOM_SUPPORTED = 0; localparam ZICBOZ_SUPPORTED = 0; localparam ZICBOP_SUPPORTED = 0; localparam SVPBMT_SUPPORTED = 0; +localparam SVINVAL_SUPPORTED = 1; // LSU microarchitectural Features localparam BUS_SUPPORTED = 1; diff --git a/config/rv32e/config.vh b/config/rv32e/config.vh index e19e5e892..30b7c3050 100644 --- a/config/rv32e/config.vh +++ b/config/rv32e/config.vh @@ -49,6 +49,7 @@ localparam ZICBOM_SUPPORTED = 0; localparam ZICBOZ_SUPPORTED = 0; localparam ZICBOP_SUPPORTED = 0; localparam SVPBMT_SUPPORTED = 0; +localparam SVINVAL_SUPPORTED = 0; // LSU microarchitectural Features localparam BUS_SUPPORTED = 1; diff --git a/config/rv32gc/config.vh b/config/rv32gc/config.vh index 031cd523f..a966b0401 100644 --- a/config/rv32gc/config.vh +++ b/config/rv32gc/config.vh @@ -50,6 +50,7 @@ localparam ZICBOM_SUPPORTED = 0; localparam ZICBOZ_SUPPORTED = 0; localparam ZICBOP_SUPPORTED = 0; localparam SVPBMT_SUPPORTED = 0; +localparam SVINVAL_SUPPORTED = 1; // LSU microarchitectural Features localparam BUS_SUPPORTED = 1; diff --git a/config/rv32i/config.vh b/config/rv32i/config.vh index 892ee356b..eda81e298 100644 --- a/config/rv32i/config.vh +++ b/config/rv32i/config.vh @@ -49,6 +49,7 @@ localparam ZICBOM_SUPPORTED = 0; localparam ZICBOZ_SUPPORTED = 0; localparam ZICBOP_SUPPORTED = 0; localparam SVPBMT_SUPPORTED = 0; +localparam SVINVAL_SUPPORTED = 0; // LSU microarchitectural Features localparam BUS_SUPPORTED = 0; diff --git a/config/rv32imc/config.vh b/config/rv32imc/config.vh index 1359cae49..0b2aee01e 100644 --- a/config/rv32imc/config.vh +++ b/config/rv32imc/config.vh @@ -48,6 +48,7 @@ localparam ZICBOM_SUPPORTED = 0; localparam ZICBOZ_SUPPORTED = 0; localparam ZICBOP_SUPPORTED = 0; localparam SVPBMT_SUPPORTED = 0; +localparam SVINVAL_SUPPORTED = 0; // LSU microarchitectural Features localparam BUS_SUPPORTED = 1; diff --git a/config/rv64fpquad/config.vh b/config/rv64fpquad/config.vh index 48a341b93..a784d369f 100644 --- a/config/rv64fpquad/config.vh +++ b/config/rv64fpquad/config.vh @@ -49,6 +49,7 @@ localparam ZICBOM_SUPPORTED = 0; localparam ZICBOZ_SUPPORTED = 0; localparam ZICBOP_SUPPORTED = 0; localparam SVPBMT_SUPPORTED = 0; +localparam SVINVAL_SUPPORTED = 1; // LSU microarchitectural Features localparam BUS_SUPPORTED = 1; diff --git a/config/rv64gc/config.vh b/config/rv64gc/config.vh index 243b6ed47..8d266ab3e 100644 --- a/config/rv64gc/config.vh +++ b/config/rv64gc/config.vh @@ -52,6 +52,7 @@ localparam ZICBOM_SUPPORTED = 0; localparam ZICBOZ_SUPPORTED = 0; localparam ZICBOP_SUPPORTED = 0; localparam SVPBMT_SUPPORTED = 0; +localparam SVINVAL_SUPPORTED = 1; // LSU microarchitectural Features localparam BUS_SUPPORTED = 1; diff --git a/config/rv64i/config.vh b/config/rv64i/config.vh index 426a012ca..ff6a1c61e 100644 --- a/config/rv64i/config.vh +++ b/config/rv64i/config.vh @@ -49,6 +49,7 @@ localparam ZICBOM_SUPPORTED = 0; localparam ZICBOZ_SUPPORTED = 0; localparam ZICBOP_SUPPORTED = 0; localparam SVPBMT_SUPPORTED = 0; +localparam SVINVAL_SUPPORTED = 0; // LSU microarchitectural Features localparam BUS_SUPPORTED = 0; diff --git a/config/shared/parameter-defs.vh b/config/shared/parameter-defs.vh index 713a947e8..f1000d6d9 100644 --- a/config/shared/parameter-defs.vh +++ b/config/shared/parameter-defs.vh @@ -24,6 +24,7 @@ parameter cvw_t P = '{ ZICBOZ_SUPPORTED : ZICBOZ_SUPPORTED, ZICBOP_SUPPORTED : ZICBOP_SUPPORTED, SVPBMT_SUPPORTED : SVPBMT_SUPPORTED, + SVINVAL_SUPPORTED : SVINVAL_SUPPORTED, BUS_SUPPORTED : BUS_SUPPORTED, DCACHE_SUPPORTED : DCACHE_SUPPORTED, ICACHE_SUPPORTED : ICACHE_SUPPORTED, diff --git a/src/cvw.sv b/src/cvw.sv index 896c3245b..e2c81b4e2 100644 --- a/src/cvw.sv +++ b/src/cvw.sv @@ -61,6 +61,7 @@ typedef struct packed { logic ZICBOZ_SUPPORTED; logic ZICBOP_SUPPORTED; logic SVPBMT_SUPPORTED; + logic SVINVAL_SUPPORTED; // Microarchitectural Features logic BUS_SUPPORTED; diff --git a/src/privileged/privdec.sv b/src/privileged/privdec.sv index 59db8c9d4..a0195f366 100644 --- a/src/privileged/privdec.sv +++ b/src/privileged/privdec.sv @@ -30,7 +30,7 @@ module privdec import cvw::*; #(parameter cvw_t P) ( input logic clk, reset, input logic StallM, - input logic [31:20] InstrM, // privileged instruction function field + input logic [31:15] InstrM, // privileged instruction function field input logic PrivilegedM, // is this a privileged instruction (from IEU controller) input logic IllegalIEUFPUInstrM, // Not a legal IEU instruction input logic IllegalCSRAccessM, // Not a legal CSR access @@ -39,24 +39,37 @@ module privdec import cvw::*; #(parameter cvw_t P) ( output logic IllegalInstrFaultM, // Illegal instruction output logic EcallFaultM, BreakpointFaultM, // Ecall or breakpoint; must retire, so don't flush it when the trap occurs output logic sretM, mretM, // return instructions - output logic wfiM, sfencevmaM // wfi / sfence.fma instructions + output logic wfiM, sfencevmaM // wfi / sfence.vma / sinval.vma instructions ); + logic rs1zeroM; // rs1 field = 0 logic IllegalPrivilegedInstrM; // privileged instruction isn't a legal one or in legal mode logic WFITimeoutM; // WFI reaches timeout threshold logic ebreakM, ecallM; // ebreak / ecall instructions + logic sinvalvmaM; // sinval.vma + logic sfencewinvalM, sfenceinvalirM; // sfence.w.inval, sfence.inval.ir + logic invalM; // any of the svinval instructions /////////////////////////////////////////// // Decode privileged instructions /////////////////////////////////////////// - assign sretM = PrivilegedM & (InstrM[31:20] == 12'b000100000010) & P.S_SUPPORTED & + assign rs1zeroM = InstrM[19:15] == 5'b0; + + // svinval instructions + // any svinval instruction is treated as sfence.vma on Wally + assign sinvalvmaM = (InstrM[31:25] == 7'b0001001); + assign sfencewinvalM = (InstrM[31:20] == 12'b000110000000) & rs1zeroM; + assign sfenceinvalirM = (InstrM[31:20] == 12'b000110000001) & rs1zeroM; + assign invalM = P.SVINVAL_SUPPORTED & (sinvalvmaM | sfencewinvalM | sfenceinvalirM); + + assign sretM = PrivilegedM & (InstrM[31:20] == 12'b000100000010) & rs1zeroM & P.S_SUPPORTED & (PrivilegeModeW == P.M_MODE | PrivilegeModeW == P.S_MODE & ~STATUS_TSR); - assign mretM = PrivilegedM & (InstrM[31:20] == 12'b001100000010) & (PrivilegeModeW == P.M_MODE); - assign ecallM = PrivilegedM & (InstrM[31:20] == 12'b000000000000); - assign ebreakM = PrivilegedM & (InstrM[31:20] == 12'b000000000001); - assign wfiM = PrivilegedM & (InstrM[31:20] == 12'b000100000101); - assign sfencevmaM = PrivilegedM & (InstrM[31:25] == 7'b0001001) & + assign mretM = PrivilegedM & (InstrM[31:20] == 12'b001100000010) & rs1zeroM & (PrivilegeModeW == P.M_MODE); + assign ecallM = PrivilegedM & (InstrM[31:20] == 12'b000000000000) & rs1zeroM; + assign ebreakM = PrivilegedM & (InstrM[31:20] == 12'b000000000001) & rs1zeroM; + assign wfiM = PrivilegedM & (InstrM[31:20] == 12'b000100000101) & rs1zeroM; + assign sfencevmaM = PrivilegedM & (InstrM[31:25] == 7'b0001001 | invalM) & (PrivilegeModeW == P.M_MODE | (PrivilegeModeW == P.S_MODE & ~STATUS_TVM)); /////////////////////////////////////////// diff --git a/src/privileged/privileged.sv b/src/privileged/privileged.sv index 1023618b5..46c69f17d 100644 --- a/src/privileged/privileged.sv +++ b/src/privileged/privileged.sv @@ -118,7 +118,7 @@ module privileged import cvw::*; #(parameter cvw_t P) ( .STATUS_MPP, .STATUS_SPP, .NextPrivilegeModeM, .PrivilegeModeW); // decode privileged instructions - privdec #(P) pmd(.clk, .reset, .StallM, .InstrM(InstrM[31:20]), + privdec #(P) pmd(.clk, .reset, .StallM, .InstrM(InstrM[31:15]), .PrivilegedM, .IllegalIEUFPUInstrM, .IllegalCSRAccessM, .PrivilegeModeW, .STATUS_TSR, .STATUS_TVM, .STATUS_TW, .IllegalInstrFaultM, .EcallFaultM, .BreakpointFaultM, .sretM, .mretM, .wfiM, .sfencevmaM);