diff --git a/src/privileged/csrsr.sv b/src/privileged/csrsr.sv index fc98dcb56..e17524a90 100644 --- a/src/privileged/csrsr.sv +++ b/src/privileged/csrsr.sv @@ -28,22 +28,22 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module csrsr import cvw::*; #(parameter cvw_t P) ( - input logic clk, reset, StallW, - input logic WriteMSTATUSM, WriteMSTATUSHM, WriteSSTATUSM, - input logic TrapM, FRegWriteM, - input logic [1:0] NextPrivilegeModeM, PrivilegeModeW, - input logic mretM, sretM, - input logic WriteFRMM, WriteFFLAGSM, + input logic clk, reset, StallW, + input logic WriteMSTATUSM, WriteMSTATUSHM, WriteSSTATUSM, + input logic TrapM, FRegWriteM, + input logic [1:0] NextPrivilegeModeM, PrivilegeModeW, + input logic mretM, sretM, + input logic WriteFRMM, WriteFFLAGSM, input logic [P.XLEN-1:0] CSRWriteValM, - input logic SelHPTW, + input logic SelHPTW, output logic [P.XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, MSTATUSH_REGW, - output logic [1:0] STATUS_MPP, - output logic STATUS_SPP, STATUS_TSR, STATUS_TW, - output logic STATUS_MIE, STATUS_SIE, - output logic STATUS_MXR, STATUS_SUM, - output logic STATUS_MPRV, STATUS_TVM, - output logic [1:0] STATUS_FS, - output logic BigEndianM + output logic [1:0] STATUS_MPP, + output logic STATUS_SPP, STATUS_TSR, STATUS_TW, + output logic STATUS_MIE, STATUS_SIE, + output logic STATUS_MXR, STATUS_SUM, + output logic STATUS_MPRV, STATUS_TVM, + output logic [1:0] STATUS_FS, + output logic BigEndianM ); logic STATUS_SD, STATUS_TW_INT, STATUS_TSR_INT, STATUS_TVM_INT, STATUS_MXR_INT, STATUS_SUM_INT, STATUS_MPRV_INT; @@ -56,27 +56,27 @@ module csrsr import cvw::*; #(parameter cvw_t P) ( // Lower privilege status registers are a subset of the full status register // *** consider adding MBE, SBE, UBE fields, parameterized to be fixed or adjustable if (P.XLEN==64) begin: csrsr64 // RV64 - assign MSTATUS_REGW = {STATUS_SD, 25'b0, STATUS_MBE, STATUS_SBE, STATUS_SXL, STATUS_UXL, 9'b0, - STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, - STATUS_XS, STATUS_FS, STATUS_MPP, 2'b0, - STATUS_SPP, STATUS_MPIE, STATUS_UBE, STATUS_SPIE, 1'b0, - STATUS_MIE, 1'b0, STATUS_SIE, 1'b0}; - assign SSTATUS_REGW = {STATUS_SD, /*27'b0, */ 29'b0, /*STATUS_SXL, */ {P.QEMU ? 2'b0 : STATUS_UXL}, /*9'b0, */ 12'b0, + assign MSTATUS_REGW = {STATUS_SD, 25'b0, STATUS_MBE, STATUS_SBE, STATUS_SXL, STATUS_UXL, 9'b0, + STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, + STATUS_XS, STATUS_FS, STATUS_MPP, 2'b0, + STATUS_SPP, STATUS_MPIE, STATUS_UBE, STATUS_SPIE, 1'b0, + STATUS_MIE, 1'b0, STATUS_SIE, 1'b0}; + assign SSTATUS_REGW = {STATUS_SD, /*27'b0, */ 29'b0, /*STATUS_SXL, */ {P.QEMU ? 2'b0 : STATUS_UXL}, /*9'b0, */ 12'b0, /*STATUS_TSR, STATUS_TW, STATUS_TVM, */STATUS_MXR, STATUS_SUM, /* STATUS_MPRV, */ 1'b0, - STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0, - STATUS_SPP, /*STATUS_MPIE*/ 1'b0, STATUS_UBE, STATUS_SPIE, + STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0, + STATUS_SPP, /*STATUS_MPIE*/ 1'b0, STATUS_UBE, STATUS_SPIE, /*1'b0, STATUS_MIE, 1'b0*/ 3'b0, STATUS_SIE, 1'b0}; assign MSTATUSH_REGW = '0; // *** does not exist when XLEN=64, but don't want it to have an undefined value. Spec is not clear what it should be. end else begin: csrsr32 // RV32 - assign MSTATUS_REGW = {STATUS_SD, 8'b0, - STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, - STATUS_XS, STATUS_FS, STATUS_MPP, 2'b0, - STATUS_SPP, STATUS_MPIE, STATUS_UBE, STATUS_SPIE, 1'b0, STATUS_MIE, 1'b0, STATUS_SIE, 1'b0}; + assign MSTATUS_REGW = {STATUS_SD, 8'b0, + STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, + STATUS_XS, STATUS_FS, STATUS_MPP, 2'b0, + STATUS_SPP, STATUS_MPIE, STATUS_UBE, STATUS_SPIE, 1'b0, STATUS_MIE, 1'b0, STATUS_SIE, 1'b0}; assign MSTATUSH_REGW = {26'b0, STATUS_MBE, STATUS_SBE, 4'b0}; - assign SSTATUS_REGW = {STATUS_SD, 11'b0, + assign SSTATUS_REGW = {STATUS_SD, 11'b0, /*STATUS_TSR, STATUS_TW, STATUS_TVM, */STATUS_MXR, STATUS_SUM, /* STATUS_MPRV, */ 1'b0, - STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0, - STATUS_SPP, /*STATUS_MPIE*/ 1'b0, STATUS_UBE, STATUS_SPIE, + STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0, + STATUS_SPP, /*STATUS_MPIE*/ 1'b0, STATUS_UBE, STATUS_SPIE, /*1'b0, STATUS_MIE, 1'b0*/ 3'b0, STATUS_SIE, 1'b0}; end @@ -90,21 +90,21 @@ module csrsr import cvw::*; #(parameter cvw_t P) ( end // harwired STATUS bits - assign STATUS_TSR = P.S_SUPPORTED & STATUS_TSR_INT; // override reigster with 0 if supervisor mode not supported - assign STATUS_TW = (P.S_SUPPORTED | P.U_SUPPORTED) & STATUS_TW_INT; // override register with 0 if only machine mode supported - assign STATUS_TVM = P.S_SUPPORTED & STATUS_TVM_INT; // override reigster with 0 if supervisor mode not supported - assign STATUS_MXR = P.S_SUPPORTED & STATUS_MXR_INT; // override reigster with 0 if supervisor mode not supported -/* assign STATUS_UBE = 0; // little-endian - assign STATUS_SBE = 0; // little-endian - assign STATUS_MBE = 0; // little-endian */ + assign STATUS_TSR = P.S_SUPPORTED & STATUS_TSR_INT; // override reigster with 0 if supervisor mode not supported + assign STATUS_TW = (P.S_SUPPORTED | P.U_SUPPORTED) & STATUS_TW_INT; // override register with 0 if only machine mode supported + assign STATUS_TVM = P.S_SUPPORTED & STATUS_TVM_INT; // override reigster with 0 if supervisor mode not supported + assign STATUS_MXR = P.S_SUPPORTED & STATUS_MXR_INT; // override reigster with 0 if supervisor mode not supported +/* assign STATUS_UBE = 0; // little-endian + assign STATUS_SBE = 0; // little-endian + assign STATUS_MBE = 0; // little-endian */ // SXL and UXL bits only matter for RV64. Set to 10 for RV64 if mode is supported, or 0 if not - assign STATUS_SXL = P.S_SUPPORTED ? 2'b10 : 2'b00; // 10 if supervisor mode supported - assign STATUS_UXL = P.U_SUPPORTED ? 2'b10 : 2'b00; // 10 if user mode supported - assign STATUS_SUM = P.S_SUPPORTED & P.VIRTMEM_SUPPORTED & STATUS_SUM_INT; // override reigster with 0 if supervisor mode not supported + assign STATUS_SXL = P.S_SUPPORTED ? 2'b10 : 2'b00; // 10 if supervisor mode supported + assign STATUS_UXL = P.U_SUPPORTED ? 2'b10 : 2'b00; // 10 if user mode supported + assign STATUS_SUM = P.S_SUPPORTED & P.VIRTMEM_SUPPORTED & STATUS_SUM_INT; // override reigster with 0 if supervisor mode not supported assign STATUS_MPRV = P.U_SUPPORTED & STATUS_MPRV_INT; // override with 0 if user mode not supported - assign STATUS_FS = (P.S_SUPPORTED & (P.F_SUPPORTED | P.D_SUPPORTED)) ? STATUS_FS_INT : 2'b00; // off if no FP - assign STATUS_SD = (STATUS_FS == 2'b11) | (STATUS_XS == 2'b11); // dirty state logic - assign STATUS_XS = 2'b00; // No additional user-mode state to be dirty + assign STATUS_FS = (P.S_SUPPORTED & (P.F_SUPPORTED | P.D_SUPPORTED)) ? STATUS_FS_INT : 2'b00; // off if no FP + assign STATUS_SD = (STATUS_FS == 2'b11) | (STATUS_XS == 2'b11); // dirty state logic + assign STATUS_XS = 2'b00; // No additional user-mode state to be dirty always_comb if (CSRWriteValM[12:11] == P.U_MODE & P.U_SUPPORTED) STATUS_MPP_NEXT = P.U_MODE; @@ -122,14 +122,14 @@ module csrsr import cvw::*; #(parameter cvw_t P) ( if (SelHPTW) EndiannessPrivMode = P.S_MODE; //coverage off -item c 1 -feccondrow 1 // status.MPRV always gets reset upon leaving machine mode, so MPRV will never be high when out of machine mode - else if (PrivilegeModeW == P.M_MODE & STATUS_MPRV) EndiannessPrivMode = STATUS_MPP; + else if (PrivilegeModeW == P.M_MODE & STATUS_MPRV) EndiannessPrivMode = STATUS_MPP; //coverage on else EndiannessPrivMode = PrivilegeModeW; case (EndiannessPrivMode) P.M_MODE: BigEndianM = STATUS_MBE; P.S_MODE: BigEndianM = STATUS_SBE; - default: BigEndianM = STATUS_UBE; + default: BigEndianM = STATUS_UBE; endcase end end else begin: endianmux