First implementation of WFI timeout wait

This commit is contained in:
David Harris 2022-04-17 17:20:35 +00:00
parent 83d283354c
commit 2436534687
14 changed files with 50 additions and 27 deletions

View File

@ -78,6 +78,9 @@
// Address space
`define RESET_VECTOR 64'h0000000000001000
// WFI Timeout Wait
`define WFI_TIMEOUT_BIT 20
// Peripheral Addresses
// Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits

View File

@ -79,6 +79,9 @@
// Address space
`define RESET_VECTOR 64'h0000000000001000
// WFI Timeout Wait
`define WFI_TIMEOUT_BIT 20
// Peripheral Addresses
// Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits

View File

@ -80,6 +80,9 @@
// Address space
`define RESET_VECTOR 32'h80000000
// WFI Timeout Wait
`define WFI_TIMEOUT_BIT 20
// Peripheral Addresses
// Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits

View File

@ -78,6 +78,9 @@
// Address space
`define RESET_VECTOR 32'h80000000
// WFI Timeout Wait
`define WFI_TIMEOUT_BIT 20
// Peripheral Addresses
// Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits

View File

@ -80,6 +80,9 @@
// Address space
`define RESET_VECTOR 32'h80000000
// WFI Timeout Wait
`define WFI_TIMEOUT_BIT 20
// Peripheral Addresses
// Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits

View File

@ -78,6 +78,9 @@
// Address space
`define RESET_VECTOR 32'h80000000
// WFI Timeout Wait
`define WFI_TIMEOUT_BIT 20
// Peripheral Addresses
// Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits

View File

@ -59,7 +59,7 @@
// TLB configuration. Entries should be a power of 2
`define ITLB_ENTRIES 32
`define DTLB_ENTRIES 32
`define DTLB_ENTRIES 32
// Cache configuration. Sizes should be a power of two
// typical configuration 4 ways, 4096 bytes per way, 256 bit or more lines
@ -82,6 +82,9 @@
// Bus Interface width
`define AHBW 64
// WFI Timeout Wait
`define WFI_TIMEOUT_BIT 20
// Peripheral Addresses
// Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits

View File

@ -84,6 +84,9 @@
// Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits
// WFI Timeout Wait
`define WFI_TIMEOUT_BIT 20
// *** each of these is `PA_BITS wide. is this paramaterizable INSIDE the config file?
`define BOOTROM_SUPPORTED 1'b1
`define BOOTROM_BASE 56'h00001000 // spec had been 0x1000 to 0x2FFF, but dh truncated to 0x1000 to 0x1FFF because upper half seems to be all zeros and this is easier for decoder

View File

@ -82,6 +82,9 @@
// Bus Interface width
`define AHBW 64
// WFI Timeout Wait
`define WFI_TIMEOUT_BIT 20
// Peripheral Physiccal Addresses
// Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits

View File

@ -82,6 +82,9 @@
// Bus Interface width
`define AHBW 64
// WFI Timeout Wait
`define WFI_TIMEOUT_BIT 20
// Peripheral Physiccal Addresses
// Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits

View File

@ -82,6 +82,9 @@
// Bus Interface width
`define AHBW 64
// WFI Timeout Wait
`define WFI_TIMEOUT_BIT 20
// Peripheral Physiccal Addresses
// Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits

View File

@ -33,7 +33,8 @@
module privdec (
input logic [31:20] InstrM,
input logic PrivilegedM, IllegalIEUInstrFaultM, IllegalCSRAccessM, IllegalFPUInstrM, TrappedSRETM,
input logic PrivilegedM, IllegalIEUInstrFaultM, IllegalCSRAccessM, IllegalFPUInstrM,
input logic TrappedSRETM, WFITimeoutM,
input logic [1:0] PrivilegeModeW,
input logic STATUS_TSR,
output logic IllegalInstrFaultM,
@ -51,7 +52,6 @@ module privdec (
assign wfiM = PrivilegedM & (InstrM[31:20] == 12'b000100000101);
assign sfencevmaM = PrivilegedM & (InstrM[31:25] == 7'b0001001); // *** & (PrivilegedModeW == `M_MODE | ~STATUS_TVM); // *** does this work in U mode?
assign IllegalPrivilegedInstrM = PrivilegedM & ~(sretM|mretM|ecallM|ebreakM|wfiM|sfencevmaM);
assign IllegalInstrFaultM = (IllegalIEUInstrFaultM & IllegalFPUInstrM) | IllegalPrivilegedInstrM | IllegalCSRAccessM | TrappedSRETM; // *** generalize this for other instructions
// *** initially, wfi is nop
assign IllegalInstrFaultM = (IllegalIEUInstrFaultM & IllegalFPUInstrM) | IllegalPrivilegedInstrM | IllegalCSRAccessM |
TrappedSRETM | WFITimeoutM; // *** generalize this for other instructions
endmodule

View File

@ -104,6 +104,7 @@ module privileged (
logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW;
logic md;
logic StallMQ;
logic WFITimeoutM;
///////////////////////////////////////////
@ -114,24 +115,6 @@ module privileged (
assign md = CauseM[`XLEN-1] ? MIDELEG_REGW[CauseM[3:0]] : MEDELEG_REGW[CauseM[`LOG_XLEN-1:0]];
// PrivilegeMode FSM
/* -----\/----- EXCLUDED -----\/-----
always_comb begin
TrappedSRETM = 0;
if (mretM) NextPrivilegeModeM = STATUS_MPP;
else if (sretM)
if (STATUS_TSR & PrivilegeModeW == `S_MODE) begin
TrappedSRETM = 1;
NextPrivilegeModeM = PrivilegeModeW;
end else NextPrivilegeModeM = {1'b0, STATUS_SPP};
else if (TrapM) begin // Change privilege based on DELEG registers (see 3.1.8)
if (`S_SUPPORTED & md & (PrivilegeModeW == `U_MODE | PrivilegeModeW == `S_MODE))
NextPrivilegeModeM = `S_MODE;
else NextPrivilegeModeM = `M_MODE;
end else NextPrivilegeModeM = PrivilegeModeW;
end
-----/\----- EXCLUDED -----/\----- */
always_comb begin
if (TrapM) begin // Change privilege based on DELEG registers (see 3.1.8)
if (`S_SUPPORTED & md & (PrivilegeModeW == `U_MODE | PrivilegeModeW == `S_MODE))
@ -149,14 +132,21 @@ module privileged (
flopenl #(2) privmodereg(clk, reset, ~StallW, NextPrivilegeModeM, `M_MODE, PrivilegeModeW);
// *** WFI could be implemented here and depends on TW
///////////////////////////////////////////
// WFI timeout Privileged Spec 3.1.6.5
///////////////////////////////////////////
if (`U_SUPPORTED) begin
logic [`WFI_TIMEOUT_BIT:0] WFICount;
floprc #(`WFI_TIMEOUT_BIT+1) wficountreg(clk, reset, ~wfiM, WFICount+1, WFICount); // count while in WFI
assign WFITimeoutM = STATUS_TW & PrivilegeModeW != `M_MODE & WFICount[`WFI_TIMEOUT_BIT];
end else assign WFITimeoutM = 0;
///////////////////////////////////////////
// decode privileged instructions
///////////////////////////////////////////
privdec pmd(.InstrM(InstrM[31:20]),
.PrivilegedM, .IllegalIEUInstrFaultM, .IllegalCSRAccessM, .IllegalFPUInstrM, .TrappedSRETM,
.PrivilegedM, .IllegalIEUInstrFaultM, .IllegalCSRAccessM, .IllegalFPUInstrM, .TrappedSRETM, .WFITimeoutM,
.PrivilegeModeW, .STATUS_TSR, .IllegalInstrFaultM,
.sretM, .mretM, .ecallM, .ebreakM, .wfiM, .sfencevmaM);
@ -233,7 +223,7 @@ module privileged (
.PCM,
.InstrMisalignedAdrM, .IEUAdrM,
.InstrM,
.InstrValidM, .CommittedM, .DivE,
.InstrValidM, .CommittedM, .DivE,
.TrapM, .MTrapM, .STrapM, .UTrapM, .RetM,
.InterruptM,
.ExceptionM,

View File

@ -46,7 +46,7 @@ module trap (
input logic [`XLEN-1:0] PCM,
input logic [`XLEN-1:0] InstrMisalignedAdrM, IEUAdrM,
input logic [31:0] InstrM,
input logic InstrValidM, CommittedM, DivE,
input logic InstrValidM, CommittedM, DivE,
output logic TrapM, MTrapM, STrapM, UTrapM, RetM,
output logic InterruptM,
output logic ExceptionM,