From 2436534687c335518c23c2349272bafd0f80fa0e Mon Sep 17 00:00:00 2001 From: David Harris Date: Sun, 17 Apr 2022 17:20:35 +0000 Subject: [PATCH] First implementation of WFI timeout wait --- pipelined/config/buildroot/wally-config.vh | 3 ++ pipelined/config/fpga/wally-config.vh | 3 ++ pipelined/config/rv32e/wally-config.vh | 3 ++ pipelined/config/rv32gc/wally-config.vh | 3 ++ pipelined/config/rv32ia/wally-config.vh | 3 ++ pipelined/config/rv32ic/wally-config.vh | 3 ++ pipelined/config/rv64BP/wally-config.vh | 5 +++- pipelined/config/rv64fp/wally-config.vh | 3 ++ pipelined/config/rv64gc/wally-config.vh | 3 ++ pipelined/config/rv64ia/wally-config.vh | 3 ++ pipelined/config/rv64ic/wally-config.vh | 3 ++ pipelined/src/privileged/privdec.sv | 8 +++--- pipelined/src/privileged/privileged.sv | 32 ++++++++-------------- pipelined/src/privileged/trap.sv | 2 +- 14 files changed, 50 insertions(+), 27 deletions(-) diff --git a/pipelined/config/buildroot/wally-config.vh b/pipelined/config/buildroot/wally-config.vh index 7587a9f2c..543b793c0 100644 --- a/pipelined/config/buildroot/wally-config.vh +++ b/pipelined/config/buildroot/wally-config.vh @@ -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 diff --git a/pipelined/config/fpga/wally-config.vh b/pipelined/config/fpga/wally-config.vh index fc63937c1..823165127 100644 --- a/pipelined/config/fpga/wally-config.vh +++ b/pipelined/config/fpga/wally-config.vh @@ -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 diff --git a/pipelined/config/rv32e/wally-config.vh b/pipelined/config/rv32e/wally-config.vh index 42e20affe..61977f046 100644 --- a/pipelined/config/rv32e/wally-config.vh +++ b/pipelined/config/rv32e/wally-config.vh @@ -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 diff --git a/pipelined/config/rv32gc/wally-config.vh b/pipelined/config/rv32gc/wally-config.vh index 022447ff6..8c96f430a 100644 --- a/pipelined/config/rv32gc/wally-config.vh +++ b/pipelined/config/rv32gc/wally-config.vh @@ -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 diff --git a/pipelined/config/rv32ia/wally-config.vh b/pipelined/config/rv32ia/wally-config.vh index 93042b8c0..4850fe063 100644 --- a/pipelined/config/rv32ia/wally-config.vh +++ b/pipelined/config/rv32ia/wally-config.vh @@ -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 diff --git a/pipelined/config/rv32ic/wally-config.vh b/pipelined/config/rv32ic/wally-config.vh index fcd3c8e5e..0faed8fcc 100644 --- a/pipelined/config/rv32ic/wally-config.vh +++ b/pipelined/config/rv32ic/wally-config.vh @@ -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 diff --git a/pipelined/config/rv64BP/wally-config.vh b/pipelined/config/rv64BP/wally-config.vh index 005a1de3f..952741763 100644 --- a/pipelined/config/rv64BP/wally-config.vh +++ b/pipelined/config/rv64BP/wally-config.vh @@ -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 diff --git a/pipelined/config/rv64fp/wally-config.vh b/pipelined/config/rv64fp/wally-config.vh index d25827b73..b72405b58 100644 --- a/pipelined/config/rv64fp/wally-config.vh +++ b/pipelined/config/rv64fp/wally-config.vh @@ -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 diff --git a/pipelined/config/rv64gc/wally-config.vh b/pipelined/config/rv64gc/wally-config.vh index 6af3c7bd9..622cfd5da 100644 --- a/pipelined/config/rv64gc/wally-config.vh +++ b/pipelined/config/rv64gc/wally-config.vh @@ -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 diff --git a/pipelined/config/rv64ia/wally-config.vh b/pipelined/config/rv64ia/wally-config.vh index 43bd1ecd4..84289de91 100644 --- a/pipelined/config/rv64ia/wally-config.vh +++ b/pipelined/config/rv64ia/wally-config.vh @@ -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 diff --git a/pipelined/config/rv64ic/wally-config.vh b/pipelined/config/rv64ic/wally-config.vh index c46dbfe70..1c320268b 100644 --- a/pipelined/config/rv64ic/wally-config.vh +++ b/pipelined/config/rv64ic/wally-config.vh @@ -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 diff --git a/pipelined/src/privileged/privdec.sv b/pipelined/src/privileged/privdec.sv index 25e929a21..1f7ae6b11 100644 --- a/pipelined/src/privileged/privdec.sv +++ b/pipelined/src/privileged/privdec.sv @@ -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 diff --git a/pipelined/src/privileged/privileged.sv b/pipelined/src/privileged/privileged.sv index 003a84b76..c60f338e6 100644 --- a/pipelined/src/privileged/privileged.sv +++ b/pipelined/src/privileged/privileged.sv @@ -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, diff --git a/pipelined/src/privileged/trap.sv b/pipelined/src/privileged/trap.sv index a2cc6ef35..1cc21579b 100644 --- a/pipelined/src/privileged/trap.sv +++ b/pipelined/src/privileged/trap.sv @@ -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,