mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Added SSTC support for supervisor timer compare, but presently disable support. Reenable for rv32gc and rv64gc after tests pass.
This commit is contained in:
parent
1c6bdbcba1
commit
5b370bdc0f
@ -40,8 +40,9 @@
|
|||||||
`define ZICSR_SUPPORTED 1
|
`define ZICSR_SUPPORTED 1
|
||||||
`define ZIFENCEI_SUPPORTED 1
|
`define ZIFENCEI_SUPPORTED 1
|
||||||
`define ZICOUNTERS_SUPPORTED 1
|
`define ZICOUNTERS_SUPPORTED 1
|
||||||
`define ZFH_SUPPORTED 0
|
|
||||||
`define COUNTERS 32
|
`define COUNTERS 32
|
||||||
|
`define ZFH_SUPPORTED 0
|
||||||
|
`define SSTC_SUPPORTED 1
|
||||||
|
|
||||||
// LSU microarchitectural Features
|
// LSU microarchitectural Features
|
||||||
`define BUS_SUPPORTED 1
|
`define BUS_SUPPORTED 1
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
`define ZICOUNTERS_SUPPORTED 1
|
`define ZICOUNTERS_SUPPORTED 1
|
||||||
`define ZFH_SUPPORTED 0
|
`define ZFH_SUPPORTED 0
|
||||||
`define COUNTERS 32
|
`define COUNTERS 32
|
||||||
|
`define SSTC_SUPPORTED 1
|
||||||
|
|
||||||
// LSU microarchitectural Features
|
// LSU microarchitectural Features
|
||||||
`define BUS_SUPPORTED 1
|
`define BUS_SUPPORTED 1
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
`define COUNTERS 0
|
`define COUNTERS 0
|
||||||
`define ZICOUNTERS_SUPPORTED 0
|
`define ZICOUNTERS_SUPPORTED 0
|
||||||
`define ZFH_SUPPORTED 0
|
`define ZFH_SUPPORTED 0
|
||||||
|
`define SSTC_SUPPORTED 0
|
||||||
|
|
||||||
// LSU microarchitectural Features
|
// LSU microarchitectural Features
|
||||||
`define BUS_SUPPORTED 1
|
`define BUS_SUPPORTED 1
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
`define COUNTERS 32
|
`define COUNTERS 32
|
||||||
`define ZICOUNTERS_SUPPORTED 1
|
`define ZICOUNTERS_SUPPORTED 1
|
||||||
`define ZFH_SUPPORTED 0
|
`define ZFH_SUPPORTED 0
|
||||||
|
`define SSTC_SUPPORTED 0
|
||||||
|
|
||||||
// LSU microarchitectural Features
|
// LSU microarchitectural Features
|
||||||
`define BUS_SUPPORTED 1
|
`define BUS_SUPPORTED 1
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
`define COUNTERS 32
|
`define COUNTERS 32
|
||||||
`define ZICOUNTERS_SUPPORTED 0
|
`define ZICOUNTERS_SUPPORTED 0
|
||||||
`define ZFH_SUPPORTED 0
|
`define ZFH_SUPPORTED 0
|
||||||
|
`define SSTC_SUPPORTED 0
|
||||||
|
|
||||||
// LSU microarchitectural Features
|
// LSU microarchitectural Features
|
||||||
`define BUS_SUPPORTED 0
|
`define BUS_SUPPORTED 0
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
`define COUNTERS 32
|
`define COUNTERS 32
|
||||||
`define ZICOUNTERS_SUPPORTED 1
|
`define ZICOUNTERS_SUPPORTED 1
|
||||||
`define ZFH_SUPPORTED 0
|
`define ZFH_SUPPORTED 0
|
||||||
|
`define SSTC_SUPPORTED 0
|
||||||
|
|
||||||
// LSU microarchitectural Features
|
// LSU microarchitectural Features
|
||||||
`define BUS_SUPPORTED 1
|
`define BUS_SUPPORTED 1
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
`define COUNTERS 32
|
`define COUNTERS 32
|
||||||
`define ZICOUNTERS_SUPPORTED 1
|
`define ZICOUNTERS_SUPPORTED 1
|
||||||
`define ZFH_SUPPORTED 1
|
`define ZFH_SUPPORTED 1
|
||||||
|
`define SSTC_SUPPORTED 0
|
||||||
|
|
||||||
// LSU microarchitectural Features
|
// LSU microarchitectural Features
|
||||||
`define BUS_SUPPORTED 1
|
`define BUS_SUPPORTED 1
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
`define COUNTERS 32
|
`define COUNTERS 32
|
||||||
`define ZICOUNTERS_SUPPORTED 1
|
`define ZICOUNTERS_SUPPORTED 1
|
||||||
`define ZFH_SUPPORTED 0
|
`define ZFH_SUPPORTED 0
|
||||||
|
`define SSTC_SUPPORTED 0
|
||||||
|
|
||||||
// LSU microarchitectural Features
|
// LSU microarchitectural Features
|
||||||
`define BUS_SUPPORTED 1
|
`define BUS_SUPPORTED 1
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
`define COUNTERS 32
|
`define COUNTERS 32
|
||||||
`define ZICOUNTERS_SUPPORTED 0
|
`define ZICOUNTERS_SUPPORTED 0
|
||||||
`define ZFH_SUPPORTED 0
|
`define ZFH_SUPPORTED 0
|
||||||
|
`define SSTC_SUPPORTED 0
|
||||||
|
|
||||||
// LSU microarchitectural Features
|
// LSU microarchitectural Features
|
||||||
`define BUS_SUPPORTED 0
|
`define BUS_SUPPORTED 0
|
||||||
|
@ -113,6 +113,7 @@ module csr #(parameter
|
|||||||
logic SelMtvecM;
|
logic SelMtvecM;
|
||||||
logic [`XLEN-1:0] TVecAlignedM;
|
logic [`XLEN-1:0] TVecAlignedM;
|
||||||
logic InstrValidNotFlushedM;
|
logic InstrValidNotFlushedM;
|
||||||
|
logic STimerInt;
|
||||||
|
|
||||||
// only valid unflushed instructions can access CSRs
|
// only valid unflushed instructions can access CSRs
|
||||||
assign InstrValidNotFlushedM = InstrValidM & ~StallW & ~FlushW;
|
assign InstrValidNotFlushedM = InstrValidM & ~StallW & ~FlushW;
|
||||||
@ -201,7 +202,7 @@ module csr #(parameter
|
|||||||
|
|
||||||
csri csri(.clk, .reset, .InstrValidNotFlushedM,
|
csri csri(.clk, .reset, .InstrValidNotFlushedM,
|
||||||
.CSRMWriteM, .CSRSWriteM, .CSRWriteValM, .CSRAdrM,
|
.CSRMWriteM, .CSRSWriteM, .CSRWriteValM, .CSRAdrM,
|
||||||
.MExtInt, .SExtInt, .MTimerInt, .MSwInt,
|
.MExtInt, .SExtInt, .MTimerInt, .STimerInt, .MSwInt,
|
||||||
.MIP_REGW, .MIE_REGW, .MIP_REGW_writeable);
|
.MIP_REGW, .MIE_REGW, .MIP_REGW_writeable);
|
||||||
|
|
||||||
csrsr csrsr(.clk, .reset, .StallW,
|
csrsr csrsr(.clk, .reset, .StallW,
|
||||||
@ -227,11 +228,12 @@ module csr #(parameter
|
|||||||
csrs csrs(.clk, .reset, .InstrValidNotFlushedM,
|
csrs csrs(.clk, .reset, .InstrValidNotFlushedM,
|
||||||
.CSRSWriteM, .STrapM, .CSRAdrM,
|
.CSRSWriteM, .STrapM, .CSRAdrM,
|
||||||
.NextEPCM, .NextCauseM, .NextMtvalM, .SSTATUS_REGW,
|
.NextEPCM, .NextCauseM, .NextMtvalM, .SSTATUS_REGW,
|
||||||
.STATUS_TVM, .CSRWriteValM, .PrivilegeModeW,
|
.STATUS_TVM, .MCOUNTEREN_TM(MCOUNTEREN_REGW[1]),
|
||||||
|
.CSRWriteValM, .PrivilegeModeW,
|
||||||
.CSRSReadValM, .STVEC_REGW, .SEPC_REGW,
|
.CSRSReadValM, .STVEC_REGW, .SEPC_REGW,
|
||||||
.SCOUNTEREN_REGW,
|
.SCOUNTEREN_REGW,
|
||||||
.SATP_REGW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW,
|
.SATP_REGW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MTIME_CLINT,
|
||||||
.WriteSSTATUSM, .IllegalCSRSAccessM);
|
.WriteSSTATUSM, .IllegalCSRSAccessM, .STimerInt);
|
||||||
end else begin
|
end else begin
|
||||||
assign WriteSSTATUSM = 0;
|
assign WriteSSTATUSM = 0;
|
||||||
assign CSRSReadValM = 0;
|
assign CSRSReadValM = 0;
|
||||||
|
@ -39,13 +39,14 @@ module csri #(parameter
|
|||||||
input logic CSRMWriteM, CSRSWriteM,
|
input logic CSRMWriteM, CSRSWriteM,
|
||||||
input logic [`XLEN-1:0] CSRWriteValM,
|
input logic [`XLEN-1:0] CSRWriteValM,
|
||||||
input logic [11:0] CSRAdrM,
|
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, 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 [11:0] MIP_WRITE_MASK, SIP_WRITE_MASK, MIE_WRITE_MASK;
|
||||||
logic WriteMIPM, WriteMIEM, WriteSIPM, WriteSIEM;
|
logic WriteMIPM, WriteMIEM, WriteSIPM, WriteSIEM;
|
||||||
|
logic STIP;
|
||||||
|
|
||||||
// Interrupt Write Enables
|
// Interrupt Write Enables
|
||||||
assign WriteMIPM = CSRMWriteM & (CSRAdrM == MIP) & InstrValidNotFlushedM;
|
assign WriteMIPM = CSRMWriteM & (CSRAdrM == MIP) & InstrValidNotFlushedM;
|
||||||
@ -58,7 +59,13 @@ module csri #(parameter
|
|||||||
// SEIP, STIP, SSIP is writable in MIP if S mode exists
|
// SEIP, STIP, SSIP is writable in MIP if S mode exists
|
||||||
// SSIP is writable in SIP if S mode exists
|
// SSIP is writable in SIP if S mode exists
|
||||||
if (`S_SUPPORTED) begin:mask
|
if (`S_SUPPORTED) begin:mask
|
||||||
|
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 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 SIP_WRITE_MASK = 12'h002; // SSIP is writeable in SIP (privileged 20210108-draft 4.1.3)
|
||||||
assign MIE_WRITE_MASK = 12'hAAA;
|
assign MIE_WRITE_MASK = 12'hAAA;
|
||||||
end else begin:mask
|
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 (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
|
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
|
endmodule
|
||||||
|
@ -41,6 +41,8 @@ module csrs #(parameter
|
|||||||
SCAUSE = 12'h142,
|
SCAUSE = 12'h142,
|
||||||
STVAL = 12'h143,
|
STVAL = 12'h143,
|
||||||
SIP= 12'h144,
|
SIP= 12'h144,
|
||||||
|
STIMECMP = 12'h14D,
|
||||||
|
STIMECMPH = 12'h15D,
|
||||||
SATP = 12'h180) (
|
SATP = 12'h180) (
|
||||||
input logic clk, reset,
|
input logic clk, reset,
|
||||||
input logic InstrValidNotFlushedM,
|
input logic InstrValidNotFlushedM,
|
||||||
@ -48,6 +50,7 @@ module csrs #(parameter
|
|||||||
input logic [11:0] CSRAdrM,
|
input logic [11:0] CSRAdrM,
|
||||||
input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, SSTATUS_REGW,
|
input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, SSTATUS_REGW,
|
||||||
input logic STATUS_TVM,
|
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 [`XLEN-1:0] CSRWriteValM,
|
||||||
input logic [1:0] PrivilegeModeW,
|
input logic [1:0] PrivilegeModeW,
|
||||||
output logic [`XLEN-1:0] CSRSReadValM, STVEC_REGW,
|
output logic [`XLEN-1:0] CSRSReadValM, STVEC_REGW,
|
||||||
@ -55,8 +58,10 @@ module csrs #(parameter
|
|||||||
output logic [31:0] SCOUNTEREN_REGW,
|
output logic [31:0] SCOUNTEREN_REGW,
|
||||||
output logic [`XLEN-1:0] SATP_REGW,
|
output logic [`XLEN-1:0] SATP_REGW,
|
||||||
input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW,
|
input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW,
|
||||||
|
input logic [63:0] MTIME_CLINT,
|
||||||
output logic WriteSSTATUSM,
|
output logic WriteSSTATUSM,
|
||||||
output logic IllegalCSRSAccessM
|
output logic IllegalCSRSAccessM,
|
||||||
|
output logic STimerInt
|
||||||
);
|
);
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
@ -66,10 +71,13 @@ module csrs #(parameter
|
|||||||
logic WriteSTVECM;
|
logic WriteSTVECM;
|
||||||
logic WriteSSCRATCHM, WriteSEPCM;
|
logic WriteSSCRATCHM, WriteSEPCM;
|
||||||
logic WriteSCAUSEM, WriteSTVALM, WriteSATPM, WriteSCOUNTERENM;
|
logic WriteSCAUSEM, WriteSTVALM, WriteSATPM, WriteSCOUNTERENM;
|
||||||
|
logic WriteSTIMECMPM, WriteSTIMECMPHM;
|
||||||
logic [`XLEN-1:0] SSCRATCH_REGW, STVAL_REGW;
|
logic [`XLEN-1:0] SSCRATCH_REGW, STVAL_REGW;
|
||||||
logic [`XLEN-1:0] SCAUSE_REGW;
|
logic [`XLEN-1:0] SCAUSE_REGW;
|
||||||
|
logic [63:0] STIMECMP_REGW;
|
||||||
|
|
||||||
// write enables
|
// write enables
|
||||||
|
// *** can InstrValidNotFlushed be factored out of all these writes into CSRWriteM?
|
||||||
assign WriteSSTATUSM = CSRSWriteM & (CSRAdrM == SSTATUS) & InstrValidNotFlushedM;
|
assign WriteSSTATUSM = CSRSWriteM & (CSRAdrM == SSTATUS) & InstrValidNotFlushedM;
|
||||||
assign WriteSTVECM = CSRSWriteM & (CSRAdrM == STVEC) & InstrValidNotFlushedM;
|
assign WriteSTVECM = CSRSWriteM & (CSRAdrM == STVEC) & InstrValidNotFlushedM;
|
||||||
assign WriteSSCRATCHM = CSRSWriteM & (CSRAdrM == SSCRATCH) & InstrValidNotFlushedM;
|
assign WriteSSCRATCHM = CSRSWriteM & (CSRAdrM == SSCRATCH) & InstrValidNotFlushedM;
|
||||||
@ -78,6 +86,8 @@ module csrs #(parameter
|
|||||||
assign WriteSTVALM = STrapM | (CSRSWriteM & (CSRAdrM == STVAL)) & InstrValidNotFlushedM;
|
assign WriteSTVALM = STrapM | (CSRSWriteM & (CSRAdrM == STVAL)) & InstrValidNotFlushedM;
|
||||||
assign WriteSATPM = CSRSWriteM & (CSRAdrM == SATP) & (PrivilegeModeW == `M_MODE | ~STATUS_TVM) & InstrValidNotFlushedM;
|
assign WriteSATPM = CSRSWriteM & (CSRAdrM == SATP) & (PrivilegeModeW == `M_MODE | ~STATUS_TVM) & InstrValidNotFlushedM;
|
||||||
assign WriteSCOUNTERENM = CSRSWriteM & (CSRAdrM == SCOUNTEREN) & 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
|
// CSRs
|
||||||
flopenr #(`XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, STVEC_REGW);
|
flopenr #(`XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, STVEC_REGW);
|
||||||
@ -90,6 +100,19 @@ module csrs #(parameter
|
|||||||
else
|
else
|
||||||
assign SATP_REGW = 0; // hardwire to zero if virtual memory not supported
|
assign SATP_REGW = 0; // hardwire to zero if virtual memory not supported
|
||||||
flopens #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, CSRWriteValM[31:0], SCOUNTEREN_REGW);
|
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
|
// CSR Reads
|
||||||
always_comb begin:csrr
|
always_comb begin:csrr
|
||||||
@ -109,6 +132,16 @@ module csrs #(parameter
|
|||||||
if (PrivilegeModeW == `S_MODE & STATUS_TVM) IllegalCSRSAccessM = 1;
|
if (PrivilegeModeW == `S_MODE & STATUS_TVM) IllegalCSRSAccessM = 1;
|
||||||
end
|
end
|
||||||
SCOUNTEREN:CSRSReadValM = {{(`XLEN-32){1'b0}}, SCOUNTEREN_REGW};
|
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
|
default: begin
|
||||||
CSRSReadValM = 0;
|
CSRSReadValM = 0;
|
||||||
IllegalCSRSAccessM = 1;
|
IllegalCSRSAccessM = 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user