Fixed bug with CSRRS/CSRRC for MIP/SIP

This commit is contained in:
David Harris 2022-04-03 20:18:25 +00:00
parent d135866098
commit 6966554ee8
2 changed files with 14 additions and 8 deletions

View File

@ -33,9 +33,8 @@
`include "wally-config.vh"
module csr #(parameter
// Constants
UIP_REGW = 12'b0, // N user-mode exceptions not supported
UIE_REGW = 12'b0
MIP = 12'h344,
SIP = 12'h144
) (
input logic clk, reset,
input logic FlushE, FlushM, FlushW,
@ -95,6 +94,8 @@ module csr #(parameter
//logic [11:0] UIP_REGW, UIE_REGW = 0; // N user-mode exceptions not supported
logic IllegalCSRCAccessM, IllegalCSRMAccessM, IllegalCSRSAccessM, IllegalCSRUAccessM, InsufficientCSRPrivilegeM;
logic IllegalCSRMWriteReadonlyM;
logic [`XLEN-1:0] CSRReadVal2M;
logic [11:0] IP_REGW_writeable;
logic InstrValidNotFlushedM;
assign InstrValidNotFlushedM = ~StallW & ~FlushW;
@ -103,10 +104,15 @@ module csr #(parameter
always_comb begin
// Choose either rs1 or uimm[4:0] as source
CSRSrcM = InstrM[14] ? {{(`XLEN-5){1'b0}}, InstrM[19:15]} : SrcAM;
// CSR set and clear for MIP/SIP should only touch internal state, not interrupt inputs
if (CSRAdrM == MIP | CSRAdrM == SIP) CSRReadVal2M = {{(`XLEN-12){1'b0}}, IP_REGW_writeable};
else CSRReadVal2M = CSRReadValM;
// Compute AND/OR modification
CSRRWM = CSRSrcM;
CSRRSM = CSRReadValM | CSRSrcM;
CSRRCM = CSRReadValM & ~CSRSrcM;
CSRRSM = CSRReadVal2M | CSRSrcM;
CSRRCM = CSRReadVal2M & ~CSRSrcM;
case (InstrM[13:12])
2'b01: CSRWriteValM = CSRRWM;
2'b10: CSRWriteValM = CSRRSM;
@ -128,7 +134,7 @@ module csr #(parameter
csri csri(.clk, .reset, .InstrValidNotFlushedM, .StallW,
.CSRMWriteM, .CSRSWriteM, .CSRWriteValM, .CSRAdrM,
.MExtIntM, .SExtIntM, .TimerIntM, .SwIntM,
.MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIDELEG_REGW);
.MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIDELEG_REGW, .IP_REGW_writeable);
csrsr csrsr(.clk, .reset, .StallW,
.WriteMSTATUSM, .WriteSSTATUSM,
.TrapM, .FRegWriteM, .NextPrivilegeModeM, .PrivilegeModeW,

View File

@ -44,10 +44,10 @@ module csri #(parameter
input logic [11:0] CSRAdrM,
(* mark_debug = "true" *) input logic MExtIntM, SExtIntM, TimerIntM, SwIntM,
input logic [11:0] MIDELEG_REGW,
output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW
output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW,
(* mark_debug = "true" *) output logic [11:0] IP_REGW_writeable // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0
);
(* mark_debug = "true" *) logic [11:0] IP_REGW_writeable; // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0
logic [11:0] IP_REGW, IE_REGW;
logic [11:0] MIP_WRITE_MASK, SIP_WRITE_MASK, MIE_WRITE_MASK;
logic WriteMIPM, WriteMIEM, WriteSIPM, WriteSIEM;