cvw/pipelined/src/privileged/csr.sv

245 lines
11 KiB
Systemverilog
Raw Normal View History

2021-01-15 04:37:51 +00:00
///////////////////////////////////////////
// csr.sv
//
// Written: David_Harris@hmc.edu 9 January 2021
// Modified:
// dottolia@hmc.edu 7 April 2021
2021-01-15 04:37:51 +00:00
//
// Purpose: Counter Control and Status Registers
// See RISC-V Privileged Mode Specification 20190608
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// MIT LICENSE
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
2021-01-15 04:37:51 +00:00
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
2021-01-15 04:37:51 +00:00
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////////////////////
2021-01-15 04:37:51 +00:00
`include "wally-config.vh"
2021-01-15 04:37:51 +00:00
module csr #(parameter
2022-04-03 20:18:25 +00:00
MIP = 12'h344,
SIP = 12'h144
) (
input logic clk, reset,
2021-10-23 18:41:20 +00:00
input logic FlushE, FlushM, FlushW,
input logic StallE, StallM, StallW,
2021-10-23 16:41:24 +00:00
input logic [31:0] InstrM,
2022-05-12 21:50:15 +00:00
input logic [`XLEN-1:0] PCM, SrcAM, IEUAdrM,
2022-05-12 22:04:20 +00:00
input logic CSRReadM, CSRWriteM, TrapM, mretM, sretM, wfiM, InterruptM,
input logic MTimerInt, MExtInt, SExtInt, MSwInt,
2021-12-31 06:40:21 +00:00
input logic [63:0] MTIME_CLINT,
2021-07-13 17:22:04 +00:00
input logic InstrValidM, FRegWriteM, LoadStallD,
2022-03-25 00:08:10 +00:00
input logic BPPredDirWrongM,
input logic BTBPredPCWrongM,
input logic RASPredPCWrongM,
input logic BPPredClassNonCFIWrongM,
input logic [4:0] InstrClassM,
input logic DCacheMiss,
input logic DCacheAccess,
input logic ICacheMiss,
input logic ICacheAccess,
input logic [1:0] NextPrivilegeModeM, PrivilegeModeW,
2022-05-12 23:33:35 +00:00
input logic [`XLEN-1:0] CauseM,
input logic SelHPTW,
output logic [1:0] STATUS_MPP,
output logic STATUS_SPP, STATUS_TSR, STATUS_TVM,
2022-03-30 20:22:41 +00:00
output logic [`XLEN-1:0] MEDELEG_REGW,
output logic [`XLEN-1:0] SATP_REGW,
output logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW,
output logic STATUS_MIE, STATUS_SIE,
output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, STATUS_TW,
output logic [1:0] STATUS_FS,
output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
2021-10-24 13:47:35 +00:00
output var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0],
input logic [4:0] SetFflagsM,
output logic [2:0] FRM_REGW,
2022-05-12 21:50:15 +00:00
output logic [`XLEN-1:0] CSRReadValW, PrivilegedNextPCM,
output logic IllegalCSRAccessM, BigEndianM
2021-01-15 04:37:51 +00:00
);
localparam NOP = 32'h13;
2022-04-02 21:39:45 +00:00
logic [`XLEN-1:0] CSRMReadValM, CSRSReadValM, CSRUReadValM, CSRCReadValM;
(* mark_debug = "true" *) logic [`XLEN-1:0] CSRReadValM;
(* mark_debug = "true" *) logic [`XLEN-1:0] CSRSrcM;
logic [`XLEN-1:0] CSRRWM, CSRRSM, CSRRCM;
(* mark_debug = "true" *) logic [`XLEN-1:0] CSRWriteValM;
2021-01-15 04:37:51 +00:00
(* mark_debug = "true" *) logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, MSTATUSH_REGW;
2022-05-12 22:00:23 +00:00
logic [`XLEN-1:0] STVEC_REGW, MTVEC_REGW;
2022-05-12 22:26:21 +00:00
logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW;
2021-01-15 04:37:51 +00:00
logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW;
logic WriteMSTATUSM, WriteMSTATUSHM, WriteSSTATUSM;
2021-01-15 04:37:51 +00:00
logic CSRMWriteM, CSRSWriteM, CSRUWriteM;
2021-07-13 17:20:30 +00:00
logic WriteFRMM, WriteFFLAGSM;
2021-01-15 04:37:51 +00:00
logic [`XLEN-1:0] UnalignedNextEPCM, NextEPCM, NextCauseM, NextMtvalM;
2021-01-15 04:37:51 +00:00
logic [11:0] CSRAdrM;
logic IllegalCSRCAccessM, IllegalCSRMAccessM, IllegalCSRSAccessM, IllegalCSRUAccessM, InsufficientCSRPrivilegeM;
logic IllegalCSRMWriteReadonlyM;
2022-04-03 20:18:25 +00:00
logic [`XLEN-1:0] CSRReadVal2M;
logic [11:0] MIP_REGW_writeable;
2022-05-12 21:50:15 +00:00
logic [`XLEN-1:0] PrivilegedTrapVector, PrivilegedVectoredTrapVector, NextFaultMtvalM;
2022-05-12 22:04:20 +00:00
logic MTrapM, STrapM;
2022-05-12 21:50:15 +00:00
logic InstrValidNotFlushedM;
assign InstrValidNotFlushedM = ~StallW & ~FlushW;
2022-05-12 21:50:15 +00:00
///////////////////////////////////////////
// MTVAL
///////////////////////////////////////////
always_comb
2022-05-12 23:37:40 +00:00
if (InterruptM) NextFaultMtvalM = 0;
else case (CauseM)
2022-05-12 21:50:15 +00:00
12, 1, 3: NextFaultMtvalM = PCM; // Instruction page/access faults, breakpoint
2: NextFaultMtvalM = {{(`XLEN-32){1'b0}}, InstrM}; // Illegal instruction fault
0, 4, 6, 13, 15, 5, 7: NextFaultMtvalM = IEUAdrM; // Instruction misaligned, Load/Store Misaligned/page/access faults
default: NextFaultMtvalM = 0; // Ecall, interrupts
endcase
///////////////////////////////////////////
// Trap Vectoring
///////////////////////////////////////////
//
// POSSIBLE OPTIMIZATION:
// From 20190608 privielegd spec page 27 (3.1.7)
// > Allowing coarser alignments in Vectored mode enables vectoring to be
// > implemented without a hardware adder circuit.
// For example, we could require m/stvec be aligned on 7 bits to let us replace the adder directly below with
// [untested] PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:7], CauseM[3:0], 4'b0000}
// However, this is program dependent, so not implemented at this time.
always_comb
if (NextPrivilegeModeM == `S_MODE) PrivilegedTrapVector = STVEC_REGW;
else PrivilegedTrapVector = MTVEC_REGW;
if(`VECTORED_INTERRUPTS_SUPPORTED) begin:vec
always_comb
2022-05-12 23:29:35 +00:00
if (PrivilegedTrapVector[1:0] == 2'b01 & InterruptM)
2022-05-12 21:50:15 +00:00
PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2] + CauseM[`XLEN-3:0], 2'b00};
else
PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2], 2'b00};
end
else begin
assign PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2], 2'b00};
end
always_comb
if (TrapM) PrivilegedNextPCM = PrivilegedVectoredTrapVector;
else if (mretM) PrivilegedNextPCM = MEPC_REGW;
else PrivilegedNextPCM = SEPC_REGW;
2022-05-12 21:55:50 +00:00
///////////////////////////////////////////
// CSRWriteValM
///////////////////////////////////////////
always_comb begin
// Choose either rs1 or uimm[4:0] as source
CSRSrcM = InstrM[14] ? {{(`XLEN-5){1'b0}}, InstrM[19:15]} : SrcAM;
2022-04-03 20:18:25 +00:00
// 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}}, MIP_REGW_writeable};
2022-04-03 20:18:25 +00:00
else CSRReadVal2M = CSRReadValM;
// Compute AND/OR modification
CSRRWM = CSRSrcM;
2022-04-03 20:18:25 +00:00
CSRRSM = CSRReadVal2M | CSRSrcM;
CSRRCM = CSRReadVal2M & ~CSRSrcM;
case (InstrM[13:12])
2'b01: CSRWriteValM = CSRRWM;
2'b10: CSRWriteValM = CSRRSM;
2'b11: CSRWriteValM = CSRRCM;
default: CSRWriteValM = CSRReadValM;
endcase
end
2021-01-15 04:37:51 +00:00
2022-05-12 21:55:50 +00:00
///////////////////////////////////////////
// CSR Write values
///////////////////////////////////////////
assign CSRAdrM = InstrM[31:20];
assign UnalignedNextEPCM = TrapM ? ((wfiM & InterruptM) ? PCM+4 : PCM) : CSRWriteValM;
assign NextEPCM = `C_SUPPORTED ? {UnalignedNextEPCM[`XLEN-1:1], 1'b0} : {UnalignedNextEPCM[`XLEN-1:2], 2'b00}; // 3.1.15 alignment
2022-05-12 23:29:35 +00:00
assign NextCauseM = TrapM ? {InterruptM, CauseM[`XLEN-2:0]}: CSRWriteValM;
assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValM;
assign CSRMWriteM = CSRWriteM & (PrivilegeModeW == `M_MODE);
assign CSRSWriteM = CSRWriteM & (|PrivilegeModeW);
assign CSRUWriteM = CSRWriteM;
2022-05-12 22:04:20 +00:00
assign MTrapM = TrapM & (NextPrivilegeModeM == `M_MODE);
assign STrapM = TrapM & (NextPrivilegeModeM == `S_MODE) & `S_SUPPORTED;
2021-01-15 04:37:51 +00:00
2022-05-12 21:55:50 +00:00
///////////////////////////////////////////
// CSRs
///////////////////////////////////////////
2022-03-30 20:22:41 +00:00
csri csri(.clk, .reset, .InstrValidNotFlushedM, .StallW,
.CSRMWriteM, .CSRSWriteM, .CSRWriteValM, .CSRAdrM,
.MExtInt, .SExtInt, .MTimerInt, .MSwInt,
.MIP_REGW, .MIE_REGW, .MIP_REGW_writeable);
2021-12-31 07:11:03 +00:00
csrsr csrsr(.clk, .reset, .StallW,
.WriteMSTATUSM, .WriteMSTATUSHM, .WriteSSTATUSM,
2021-12-31 07:11:03 +00:00
.TrapM, .FRegWriteM, .NextPrivilegeModeM, .PrivilegeModeW,
.mretM, .sretM, .WriteFRMM, .WriteFFLAGSM, .CSRWriteValM, .SelHPTW,
.MSTATUS_REGW, .SSTATUS_REGW, .MSTATUSH_REGW,
2021-12-31 07:11:03 +00:00
.STATUS_MPP, .STATUS_SPP, .STATUS_TSR, .STATUS_TW,
.STATUS_MIE, .STATUS_SIE, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TVM,
.STATUS_FS, .BigEndianM);
2021-12-31 07:11:03 +00:00
csrc counters(.clk, .reset,
2022-05-12 14:49:58 +00:00
.StallE, .StallM, .StallW, .FlushM, .FlushW,
2021-12-31 07:11:03 +00:00
.InstrValidM, .LoadStallD, .CSRMWriteM,
.BPPredDirWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .BPPredClassNonCFIWrongM,
.InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess,
2021-12-31 07:11:03 +00:00
.CSRAdrM, .PrivilegeModeW, .CSRWriteValM,
.MCOUNTINHIBIT_REGW, .MCOUNTEREN_REGW, .SCOUNTEREN_REGW,
.MTIME_CLINT, .CSRCReadValM, .IllegalCSRCAccessM);
csrm csrm(.clk, .reset, .InstrValidNotFlushedM, .StallW,
2021-12-31 07:11:03 +00:00
.CSRMWriteM, .MTrapM, .CSRAdrM,
.NextEPCM, .NextCauseM, .NextMtvalM, .MSTATUS_REGW, .MSTATUSH_REGW,
2021-12-31 07:11:03 +00:00
.CSRWriteValM, .CSRMReadValM, .MTVEC_REGW,
.MEPC_REGW, .MCOUNTEREN_REGW, .MCOUNTINHIBIT_REGW,
.MEDELEG_REGW, .MIDELEG_REGW,.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
.MIP_REGW, .MIE_REGW, .WriteMSTATUSM, .WriteMSTATUSHM,
2021-12-31 07:11:03 +00:00
.IllegalCSRMAccessM, .IllegalCSRMWriteReadonlyM);
csrs csrs(.clk, .reset, .InstrValidNotFlushedM, .StallW,
2021-12-31 07:11:03 +00:00
.CSRSWriteM, .STrapM, .CSRAdrM,
.NextEPCM, .NextCauseM, .NextMtvalM, .SSTATUS_REGW,
.STATUS_TVM, .CSRWriteValM, .PrivilegeModeW,
.CSRSReadValM, .STVEC_REGW, .SEPC_REGW,
.SCOUNTEREN_REGW,
.SATP_REGW, .MIP_REGW, .MIE_REGW,
2021-12-31 07:11:03 +00:00
.WriteSSTATUSM, .IllegalCSRSAccessM);
csru csru(.clk, .reset, .InstrValidNotFlushedM, .StallW,
.CSRUWriteM, .CSRAdrM, .CSRWriteValM, .STATUS_FS, .CSRUReadValM,
2021-12-31 07:11:03 +00:00
.SetFflagsM, .FRM_REGW, .WriteFRMM, .WriteFFLAGSM,
.IllegalCSRUAccessM);
2021-01-15 04:37:51 +00:00
// merge CSR Reads
assign CSRReadValM = CSRUReadValM | CSRSReadValM | CSRMReadValM | CSRCReadValM;
flopenrc #(`XLEN) CSRValWReg(clk, reset, FlushW, ~StallW, CSRReadValM, CSRReadValW);
2021-01-15 04:37:51 +00:00
// merge illegal accesses: illegal if none of the CSR addresses is legal or privilege is insufficient
assign InsufficientCSRPrivilegeM = (CSRAdrM[9:8] == 2'b11 & PrivilegeModeW != `M_MODE) |
2022-03-25 00:08:10 +00:00
(CSRAdrM[9:8] == 2'b01 & PrivilegeModeW == `U_MODE);
assign IllegalCSRAccessM = ((IllegalCSRCAccessM & IllegalCSRMAccessM &
IllegalCSRSAccessM & IllegalCSRUAccessM |
InsufficientCSRPrivilegeM) & CSRReadM) | IllegalCSRMWriteReadonlyM;
2021-01-15 04:37:51 +00:00
endmodule