mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-03 18:25:27 +00:00
commit
beaec570c7
@ -54,11 +54,9 @@ module csrm import cvw::*; #(parameter cvw_t P) (
|
|||||||
logic [P.XLEN-1:0] MISA_REGW, MHARTID_REGW;
|
logic [P.XLEN-1:0] MISA_REGW, MHARTID_REGW;
|
||||||
logic [P.XLEN-1:0] MSCRATCH_REGW, MTVAL_REGW, MCAUSE_REGW;
|
logic [P.XLEN-1:0] MSCRATCH_REGW, MTVAL_REGW, MCAUSE_REGW;
|
||||||
logic [P.XLEN-1:0] MENVCFGH_REGW;
|
logic [P.XLEN-1:0] MENVCFGH_REGW;
|
||||||
logic [63:0] MENVCFG_PreWriteValM, MENVCFG_WriteValM;
|
|
||||||
logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM;
|
logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM;
|
||||||
logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM;
|
logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM;
|
||||||
logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM;
|
logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM;
|
||||||
logic WriteMENVCFGM;
|
|
||||||
|
|
||||||
// Machine CSRs
|
// Machine CSRs
|
||||||
localparam MVENDORID = 12'hF11;
|
localparam MVENDORID = 12'hF11;
|
||||||
@ -82,7 +80,6 @@ module csrm import cvw::*; #(parameter cvw_t P) (
|
|||||||
localparam MCAUSE = 12'h342;
|
localparam MCAUSE = 12'h342;
|
||||||
localparam MTVAL = 12'h343;
|
localparam MTVAL = 12'h343;
|
||||||
localparam MIP = 12'h344;
|
localparam MIP = 12'h344;
|
||||||
localparam MTINST = 12'h34A;
|
|
||||||
localparam PMPCFG0 = 12'h3A0;
|
localparam PMPCFG0 = 12'h3A0;
|
||||||
// .. up to 15 more at consecutive addresses
|
// .. up to 15 more at consecutive addresses
|
||||||
localparam PMPADDR0 = 12'h3B0;
|
localparam PMPADDR0 = 12'h3B0;
|
||||||
@ -146,7 +143,6 @@ module csrm import cvw::*; #(parameter cvw_t P) (
|
|||||||
assign WriteMCAUSEM = MTrapM | (CSRMWriteM & (CSRAdrM == MCAUSE));
|
assign WriteMCAUSEM = MTrapM | (CSRMWriteM & (CSRAdrM == MCAUSE));
|
||||||
assign WriteMTVALM = MTrapM | (CSRMWriteM & (CSRAdrM == MTVAL));
|
assign WriteMTVALM = MTrapM | (CSRMWriteM & (CSRAdrM == MTVAL));
|
||||||
assign WriteMCOUNTERENM = CSRMWriteM & (CSRAdrM == MCOUNTEREN);
|
assign WriteMCOUNTERENM = CSRMWriteM & (CSRAdrM == MCOUNTEREN);
|
||||||
assign WriteMENVCFGM = CSRMWriteM & (CSRAdrM == MENVCFG);
|
|
||||||
assign WriteMCOUNTINHIBITM = CSRMWriteM & (CSRAdrM == MCOUNTINHIBIT);
|
assign WriteMCOUNTINHIBITM = CSRMWriteM & (CSRAdrM == MCOUNTINHIBIT);
|
||||||
|
|
||||||
assign IllegalCSRMWriteReadonlyM = UngatedCSRMWriteM & (CSRAdrM == MVENDORID | CSRAdrM == MARCHID | CSRAdrM == MIMPID | CSRAdrM == MHARTID);
|
assign IllegalCSRMWriteReadonlyM = UngatedCSRMWriteM & (CSRAdrM == MVENDORID | CSRAdrM == MARCHID | CSRAdrM == MIMPID | CSRAdrM == MHARTID);
|
||||||
@ -168,28 +164,33 @@ module csrm import cvw::*; #(parameter cvw_t P) (
|
|||||||
flopenr #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], MCOUNTEREN_REGW);
|
flopenr #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], MCOUNTEREN_REGW);
|
||||||
end else assign MCOUNTEREN_REGW = '0;
|
end else assign MCOUNTEREN_REGW = '0;
|
||||||
|
|
||||||
// MENVCFG is always 64 bits even for RV32
|
// MENVCFG register
|
||||||
assign MENVCFG_WriteValM = {
|
if (P.U_SUPPORTED) begin // menvcfg only exists if there is a lower privilege to control
|
||||||
MENVCFG_PreWriteValM[63] & P.SSTC_SUPPORTED,
|
logic WriteMENVCFGM;
|
||||||
MENVCFG_PreWriteValM[62] & P.SVPBMT_SUPPORTED,
|
logic [63:0] MENVCFG_PreWriteValM, MENVCFG_WriteValM;
|
||||||
54'b0,
|
assign WriteMENVCFGM = CSRMWriteM & (CSRAdrM == MENVCFG);
|
||||||
MENVCFG_PreWriteValM[7] & P.ZICBOZ_SUPPORTED,
|
// MENVCFG is always 64 bits even for RV32
|
||||||
MENVCFG_PreWriteValM[6:4] & {3{P.ZICBOM_SUPPORTED}},
|
assign MENVCFG_WriteValM = {
|
||||||
3'b0,
|
MENVCFG_PreWriteValM[63] & P.SSTC_SUPPORTED,
|
||||||
MENVCFG_PreWriteValM[0] & P.S_SUPPORTED & P.VIRTMEM_SUPPORTED
|
MENVCFG_PreWriteValM[62] & P.SVPBMT_SUPPORTED,
|
||||||
};
|
54'b0,
|
||||||
|
MENVCFG_PreWriteValM[7] & P.ZICBOZ_SUPPORTED,
|
||||||
if (P.XLEN == 64) begin
|
MENVCFG_PreWriteValM[6:4] & {3{P.ZICBOM_SUPPORTED}},
|
||||||
assign MENVCFG_PreWriteValM = CSRWriteValM;
|
3'b0,
|
||||||
flopenr #(P.XLEN) MENVCFGreg(clk, reset, WriteMENVCFGM, MENVCFG_WriteValM, MENVCFG_REGW);
|
MENVCFG_PreWriteValM[0] & P.S_SUPPORTED & P.VIRTMEM_SUPPORTED
|
||||||
assign MENVCFGH_REGW = 0;
|
};
|
||||||
end else begin
|
if (P.XLEN == 64) begin
|
||||||
logic WriteMENVCFGHM;
|
assign MENVCFG_PreWriteValM = CSRWriteValM;
|
||||||
assign MENVCFG_PreWriteValM = {CSRWriteValM, CSRWriteValM};
|
flopenr #(P.XLEN) MENVCFGreg(clk, reset, WriteMENVCFGM, MENVCFG_WriteValM, MENVCFG_REGW);
|
||||||
assign WriteMENVCFGHM = CSRMWriteM & (CSRAdrM == MENVCFGH) & (P.XLEN==32);
|
assign MENVCFGH_REGW = 0;
|
||||||
flopenr #(P.XLEN) MENVCFGreg(clk, reset, WriteMENVCFGM, MENVCFG_WriteValM[31:0], MENVCFG_REGW[31:0]);
|
end else begin // RV32 has high and low halves
|
||||||
flopenr #(P.XLEN) MENVCFGHreg(clk, reset, WriteMENVCFGHM, MENVCFG_WriteValM[63:32], MENVCFG_REGW[63:32]);
|
logic WriteMENVCFGHM;
|
||||||
assign MENVCFGH_REGW = MENVCFG_REGW[63:32];
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
// Read machine mode CSRs
|
// Read machine mode CSRs
|
||||||
@ -197,6 +198,7 @@ module csrm import cvw::*; #(parameter cvw_t P) (
|
|||||||
logic [5:0] entry;
|
logic [5:0] entry;
|
||||||
always_comb begin
|
always_comb begin
|
||||||
entry = '0;
|
entry = '0;
|
||||||
|
CSRMReadValM = 0;
|
||||||
IllegalCSRMAccessM = !(P.S_SUPPORTED) & (CSRAdrM == MEDELEG | CSRAdrM == MIDELEG); // trap on DELEG register access when no S or N-mode
|
IllegalCSRMAccessM = !(P.S_SUPPORTED) & (CSRAdrM == MEDELEG | CSRAdrM == MIDELEG); // trap on DELEG register access when no S or N-mode
|
||||||
if (CSRAdrM >= PMPADDR0 & CSRAdrM < PMPADDR0 + P.PMP_ENTRIES) // reading a PMP entry
|
if (CSRAdrM >= PMPADDR0 & CSRAdrM < PMPADDR0 + P.PMP_ENTRIES) // reading a PMP entry
|
||||||
CSRMReadValM = {{(P.XLEN-(P.PA_BITS-2)){1'b0}}, PMPADDR_ARRAY_REGW[CSRAdrM - PMPADDR0]};
|
CSRMReadValM = {{(P.XLEN-(P.PA_BITS-2)){1'b0}}, PMPADDR_ARRAY_REGW[CSRAdrM - PMPADDR0]};
|
||||||
@ -219,7 +221,8 @@ module csrm import cvw::*; #(parameter cvw_t P) (
|
|||||||
MHARTID: CSRMReadValM = MHARTID_REGW; // hardwired to 0
|
MHARTID: CSRMReadValM = MHARTID_REGW; // hardwired to 0
|
||||||
MCONFIGPTR: CSRMReadValM = 0; // hardwired to 0
|
MCONFIGPTR: CSRMReadValM = 0; // hardwired to 0
|
||||||
MSTATUS: CSRMReadValM = MSTATUS_REGW;
|
MSTATUS: CSRMReadValM = MSTATUS_REGW;
|
||||||
MSTATUSH: CSRMReadValM = MSTATUSH_REGW;
|
MSTATUSH: if (P.XLEN==32) CSRMReadValM = MSTATUSH_REGW;
|
||||||
|
else IllegalCSRMAccessM = 1;
|
||||||
MTVEC: CSRMReadValM = MTVEC_REGW;
|
MTVEC: CSRMReadValM = MTVEC_REGW;
|
||||||
MEDELEG: CSRMReadValM = {{(P.XLEN-16){1'b0}}, MEDELEG_REGW};
|
MEDELEG: CSRMReadValM = {{(P.XLEN-16){1'b0}}, MEDELEG_REGW};
|
||||||
MIDELEG: CSRMReadValM = {{(P.XLEN-12){1'b0}}, MIDELEG_REGW};
|
MIDELEG: CSRMReadValM = {{(P.XLEN-12){1'b0}}, MIDELEG_REGW};
|
||||||
@ -229,16 +232,13 @@ module csrm import cvw::*; #(parameter cvw_t P) (
|
|||||||
MEPC: CSRMReadValM = MEPC_REGW;
|
MEPC: CSRMReadValM = MEPC_REGW;
|
||||||
MCAUSE: CSRMReadValM = MCAUSE_REGW;
|
MCAUSE: CSRMReadValM = MCAUSE_REGW;
|
||||||
MTVAL: CSRMReadValM = MTVAL_REGW;
|
MTVAL: CSRMReadValM = MTVAL_REGW;
|
||||||
MTINST: CSRMReadValM = 0; // implemented as trivial zero
|
|
||||||
MCOUNTEREN: CSRMReadValM = {{(P.XLEN-32){1'b0}}, MCOUNTEREN_REGW};
|
MCOUNTEREN: CSRMReadValM = {{(P.XLEN-32){1'b0}}, MCOUNTEREN_REGW};
|
||||||
MENVCFG: CSRMReadValM = MENVCFG_REGW[P.XLEN-1:0];
|
MENVCFG: if (P.U_SUPPORTED) CSRMReadValM = MENVCFG_REGW[P.XLEN-1:0];
|
||||||
MENVCFGH: CSRMReadValM = MENVCFGH_REGW;
|
else IllegalCSRMAccessM = 1;
|
||||||
|
MENVCFGH: if (P.U_SUPPORTED & P.XLEN==32) CSRMReadValM = MENVCFGH_REGW;
|
||||||
|
else IllegalCSRMAccessM = 1;
|
||||||
MCOUNTINHIBIT: CSRMReadValM = {{(P.XLEN-32){1'b0}}, MCOUNTINHIBIT_REGW};
|
MCOUNTINHIBIT: CSRMReadValM = {{(P.XLEN-32){1'b0}}, MCOUNTINHIBIT_REGW};
|
||||||
|
default: IllegalCSRMAccessM = 1;
|
||||||
default: begin
|
|
||||||
CSRMReadValM = 0;
|
|
||||||
IllegalCSRMAccessM = 1;
|
|
||||||
end
|
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
// verilator lint_on WIDTH
|
// verilator lint_on WIDTH
|
||||||
|
@ -54,7 +54,6 @@ module csrsr import cvw::*; #(parameter cvw_t P) (
|
|||||||
// STATUS REGISTER FIELD
|
// STATUS REGISTER FIELD
|
||||||
// See Privileged Spec Section 3.1.6
|
// See Privileged Spec Section 3.1.6
|
||||||
// Lower privilege status registers are a subset of the full status register
|
// 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
|
if (P.XLEN==64) begin: csrsr64 // RV64
|
||||||
assign MSTATUS_REGW = {STATUS_SD, 25'b0, STATUS_MBE, STATUS_SBE, STATUS_SXL, STATUS_UXL, 9'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_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV,
|
||||||
|
Loading…
Reference in New Issue
Block a user