Added SSTC support for supervisor timer compare, but presently disable support. Reenable for rv32gc and rv64gc after tests pass.

This commit is contained in:
David Harris 2023-02-16 07:37:12 -08:00
parent 1c6bdbcba1
commit 5b370bdc0f
13 changed files with 76 additions and 22 deletions

View File

@ -40,8 +40,9 @@
`define ZICSR_SUPPORTED 1
`define ZIFENCEI_SUPPORTED 1
`define ZICOUNTERS_SUPPORTED 1
`define ZFH_SUPPORTED 0
`define COUNTERS 32
`define ZFH_SUPPORTED 0
`define SSTC_SUPPORTED 1
// LSU microarchitectural Features
`define BUS_SUPPORTED 1

View File

@ -43,6 +43,7 @@
`define ZICOUNTERS_SUPPORTED 1
`define ZFH_SUPPORTED 0
`define COUNTERS 32
`define SSTC_SUPPORTED 1
// LSU microarchitectural Features
`define BUS_SUPPORTED 1

View File

@ -44,6 +44,7 @@
`define COUNTERS 0
`define ZICOUNTERS_SUPPORTED 0
`define ZFH_SUPPORTED 0
`define SSTC_SUPPORTED 0
// LSU microarchitectural Features
`define BUS_SUPPORTED 1

View File

@ -43,6 +43,7 @@
`define COUNTERS 32
`define ZICOUNTERS_SUPPORTED 1
`define ZFH_SUPPORTED 0
`define SSTC_SUPPORTED 0
// LSU microarchitectural Features
`define BUS_SUPPORTED 1

View File

@ -44,6 +44,7 @@
`define COUNTERS 32
`define ZICOUNTERS_SUPPORTED 0
`define ZFH_SUPPORTED 0
`define SSTC_SUPPORTED 0
// LSU microarchitectural Features
`define BUS_SUPPORTED 0

View File

@ -43,6 +43,7 @@
`define COUNTERS 32
`define ZICOUNTERS_SUPPORTED 1
`define ZFH_SUPPORTED 0
`define SSTC_SUPPORTED 0
// LSU microarchitectural Features
`define BUS_SUPPORTED 1

View File

@ -44,6 +44,7 @@
`define COUNTERS 32
`define ZICOUNTERS_SUPPORTED 1
`define ZFH_SUPPORTED 1
`define SSTC_SUPPORTED 0
// LSU microarchitectural Features
`define BUS_SUPPORTED 1

View File

@ -44,6 +44,7 @@
`define COUNTERS 32
`define ZICOUNTERS_SUPPORTED 1
`define ZFH_SUPPORTED 0
`define SSTC_SUPPORTED 0
// LSU microarchitectural Features
`define BUS_SUPPORTED 1

View File

@ -44,6 +44,7 @@
`define COUNTERS 32
`define ZICOUNTERS_SUPPORTED 0
`define ZFH_SUPPORTED 0
`define SSTC_SUPPORTED 0
// LSU microarchitectural Features
`define BUS_SUPPORTED 0

View File

@ -113,6 +113,7 @@ module csr #(parameter
logic SelMtvecM;
logic [`XLEN-1:0] TVecAlignedM;
logic InstrValidNotFlushedM;
logic STimerInt;
// only valid unflushed instructions can access CSRs
assign InstrValidNotFlushedM = InstrValidM & ~StallW & ~FlushW;
@ -201,7 +202,7 @@ module csr #(parameter
csri csri(.clk, .reset, .InstrValidNotFlushedM,
.CSRMWriteM, .CSRSWriteM, .CSRWriteValM, .CSRAdrM,
.MExtInt, .SExtInt, .MTimerInt, .MSwInt,
.MExtInt, .SExtInt, .MTimerInt, .STimerInt, .MSwInt,
.MIP_REGW, .MIE_REGW, .MIP_REGW_writeable);
csrsr csrsr(.clk, .reset, .StallW,
@ -227,11 +228,12 @@ module csr #(parameter
csrs csrs(.clk, .reset, .InstrValidNotFlushedM,
.CSRSWriteM, .STrapM, .CSRAdrM,
.NextEPCM, .NextCauseM, .NextMtvalM, .SSTATUS_REGW,
.STATUS_TVM, .CSRWriteValM, .PrivilegeModeW,
.STATUS_TVM, .MCOUNTEREN_TM(MCOUNTEREN_REGW[1]),
.CSRWriteValM, .PrivilegeModeW,
.CSRSReadValM, .STVEC_REGW, .SEPC_REGW,
.SCOUNTEREN_REGW,
.SATP_REGW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW,
.WriteSSTATUSM, .IllegalCSRSAccessM);
.SATP_REGW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MTIME_CLINT,
.WriteSSTATUSM, .IllegalCSRSAccessM, .STimerInt);
end else begin
assign WriteSSTATUSM = 0;
assign CSRSReadValM = 0;

View File

@ -39,13 +39,14 @@ module csri #(parameter
input logic CSRMWriteM, CSRSWriteM,
input logic [`XLEN-1:0] CSRWriteValM,
input logic [11:0] CSRAdrM,
input logic MExtInt, SExtInt, MTimerInt, MSwInt,
input logic MExtInt, SExtInt, MTimerInt, STimerInt, MSwInt,
output logic [11:0] MIP_REGW, MIE_REGW,
output logic [11:0] MIP_REGW_writeable // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0
output logic [11:0] MIP_REGW_writeable // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0
);
logic [11:0] MIP_WRITE_MASK, SIP_WRITE_MASK, MIE_WRITE_MASK;
logic WriteMIPM, WriteMIEM, WriteSIPM, WriteSIEM;
logic STIP;
// Interrupt Write Enables
assign WriteMIPM = CSRMWriteM & (CSRAdrM == MIP) & InstrValidNotFlushedM;
@ -58,7 +59,13 @@ module csri #(parameter
// SEIP, STIP, SSIP is writable in MIP if S mode exists
// SSIP is writable in SIP if S mode exists
if (`S_SUPPORTED) begin:mask
assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writeable in MIP (20210108-draft 3.1.9)
if (`SSTC_SUPPORTED) begin
assign MIP_WRITE_MASK = 12'h202; // SEIP and SSIP are writable, but STIP is not writable when STIMECMP is implemented (see SSTC spec)
assign STIP = STimerInt;
end else begin
assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writeable in MIP (20210108-draft 3.1.9)
assign STIP = MIP_REGW_writeable[5];
end
assign SIP_WRITE_MASK = 12'h002; // SSIP is writeable in SIP (privileged 20210108-draft 4.1.3)
assign MIE_WRITE_MASK = 12'hAAA;
end else begin:mask
@ -75,5 +82,8 @@ module csri #(parameter
else if (WriteMIEM) MIE_REGW <= (CSRWriteValM[11:0] & MIE_WRITE_MASK); // MIE controls M and S fields
else if (WriteSIEM) MIE_REGW <= (CSRWriteValM[11:0] & 12'h222) | (MIE_REGW & 12'h888); // only S fields
assign MIP_REGW = {MExtInt,1'b0,SExtInt|MIP_REGW_writeable[9],1'b0,MTimerInt,1'b0,MIP_REGW_writeable[5],1'b0,MSwInt,1'b0,MIP_REGW_writeable[1],1'b0};
assign MIP_REGW = {MExtInt, 1'b0, SExtInt|MIP_REGW_writeable[9], 1'b0,
MTimerInt, 1'b0, STIP, 1'b0,
MSwInt, 1'b0, MIP_REGW_writeable[1], 1'b0};
endmodule

View File

@ -41,22 +41,27 @@ module csrs #(parameter
SCAUSE = 12'h142,
STVAL = 12'h143,
SIP= 12'h144,
STIMECMP = 12'h14D,
STIMECMPH = 12'h15D,
SATP = 12'h180) (
input logic clk, reset,
input logic InstrValidNotFlushedM,
input logic CSRSWriteM, STrapM,
input logic [11:0] CSRAdrM,
input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, SSTATUS_REGW,
input logic STATUS_TVM,
input logic [`XLEN-1:0] CSRWriteValM,
input logic [1:0] PrivilegeModeW,
input logic clk, reset,
input logic InstrValidNotFlushedM,
input logic CSRSWriteM, STrapM,
input logic [11:0] CSRAdrM,
input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, SSTATUS_REGW,
input logic STATUS_TVM,
input logic MCOUNTEREN_TM, // TM bit (1) of MCOUNTEREN; cause illegal instruction when trying to access STIMECMP if clear
input logic [`XLEN-1:0] CSRWriteValM,
input logic [1:0] PrivilegeModeW,
output logic [`XLEN-1:0] CSRSReadValM, STVEC_REGW,
output logic [`XLEN-1:0] SEPC_REGW,
output logic [31:0] SCOUNTEREN_REGW,
output logic [`XLEN-1:0] SATP_REGW,
input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW,
output logic WriteSSTATUSM,
output logic IllegalCSRSAccessM
input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW,
input logic [63:0] MTIME_CLINT,
output logic WriteSSTATUSM,
output logic IllegalCSRSAccessM,
output logic STimerInt
);
// Constants
@ -66,10 +71,13 @@ module csrs #(parameter
logic WriteSTVECM;
logic WriteSSCRATCHM, WriteSEPCM;
logic WriteSCAUSEM, WriteSTVALM, WriteSATPM, WriteSCOUNTERENM;
logic WriteSTIMECMPM, WriteSTIMECMPHM;
logic [`XLEN-1:0] SSCRATCH_REGW, STVAL_REGW;
logic [`XLEN-1:0] SCAUSE_REGW;
logic [63:0] STIMECMP_REGW;
// write enables
// *** can InstrValidNotFlushed be factored out of all these writes into CSRWriteM?
assign WriteSSTATUSM = CSRSWriteM & (CSRAdrM == SSTATUS) & InstrValidNotFlushedM;
assign WriteSTVECM = CSRSWriteM & (CSRAdrM == STVEC) & InstrValidNotFlushedM;
assign WriteSSCRATCHM = CSRSWriteM & (CSRAdrM == SSCRATCH) & InstrValidNotFlushedM;
@ -78,6 +86,8 @@ module csrs #(parameter
assign WriteSTVALM = STrapM | (CSRSWriteM & (CSRAdrM == STVAL)) & InstrValidNotFlushedM;
assign WriteSATPM = CSRSWriteM & (CSRAdrM == SATP) & (PrivilegeModeW == `M_MODE | ~STATUS_TVM) & InstrValidNotFlushedM;
assign WriteSCOUNTERENM = CSRSWriteM & (CSRAdrM == SCOUNTEREN) & InstrValidNotFlushedM;
assign WriteSTIMECMPM = CSRSWriteM & (CSRAdrM == STIMECMP) & MCOUNTEREN_TM & InstrValidNotFlushedM;
assign WriteSTIMECMPHM = CSRSWriteM & (CSRAdrM == STIMECMPH) & MCOUNTEREN_TM & (`XLEN == 32) & InstrValidNotFlushedM;
// CSRs
flopenr #(`XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, STVEC_REGW);
@ -90,7 +100,20 @@ module csrs #(parameter
else
assign SATP_REGW = 0; // hardwire to zero if virtual memory not supported
flopens #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, CSRWriteValM[31:0], SCOUNTEREN_REGW);
if (`XLEN == 64)
flopenr #(`XLEN) STIMECMPreg(clk, reset, WriteSTIMECMPM, CSRWriteValM, STIMECMP_REGW);
else begin
flopenr #(`XLEN) STIMECMPreg(clk, reset, WriteSTIMECMPM, CSRWriteValM, STIMECMP_REGW[31:0]);
flopenr #(`XLEN) STIMECMPHreg(clk, reset, WriteSTIMECMPHM, CSRWriteValM, STIMECMP_REGW[63:32]);
end
// Supervisor timer interrupt logic
// Spec is a bit peculiar - Machine timer interrupts are produced in CLINT, while Supervisor timer interrupts are in CSRs
if (`SSTC_SUPPORTED)
assign STimerInt = ({1'b0, MTIME_CLINT} >= {1'b0, STIMECMP_REGW}); // unsigned comparison
else
assign STimerInt = 0;
// CSR Reads
always_comb begin:csrr
IllegalCSRSAccessM = 0;
@ -109,10 +132,20 @@ module csrs #(parameter
if (PrivilegeModeW == `S_MODE & STATUS_TVM) IllegalCSRSAccessM = 1;
end
SCOUNTEREN:CSRSReadValM = {{(`XLEN-32){1'b0}}, SCOUNTEREN_REGW};
STIMECMP: if (MCOUNTEREN_TM) CSRSReadValM = STIMECMP_REGW[`XLEN-1:0];
else begin
CSRSReadValM = 0;
IllegalCSRSAccessM = 1;
end
STIMECMPH: if (MCOUNTEREN_TM & (`XLEN == 32)) CSRSReadValM[31:0] = STIMECMP_REGW[63:32];
else begin // not supported for RV64
CSRSReadValM = 0;
IllegalCSRSAccessM = 1;
end
default: begin
CSRSReadValM = 0;
IllegalCSRSAccessM = 1;
end
end
endcase
end
endmodule

View File

@ -68,7 +68,7 @@ module csrsr (
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.
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,