From 7347ed2527ecbb58110e7cdceb3f2cdea2335c4a Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 23 Oct 2023 15:29:50 -0500 Subject: [PATCH 01/10] Addeed script to sweep sim_bp for btb. --- bin/CModelBTBAccuracy.sh | 57 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100755 bin/CModelBTBAccuracy.sh diff --git a/bin/CModelBTBAccuracy.sh b/bin/CModelBTBAccuracy.sh new file mode 100755 index 000000000..5cde4238c --- /dev/null +++ b/bin/CModelBTBAccuracy.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +########################################### +## Written: ross1728@gmail.com +## Created: 23 October 2023 +## Modified: +## +## Purpose: Takes a directory of branch outcomes organized as 1 files per benchmark. +## Computes the geometric mean for btb accuracy +## +## A component of the CORE-V-WALLY configurable RISC-V project. +## +## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +## +## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +## +## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +## except in compliance with the License, or, at your option, the Apache License version 2.0. You +## may obtain a copy of the License at +## +## https:##solderpad.org/licenses/SHL-2.1/ +## +## Unless required by applicable law or agreed to in writing, any work distributed under the +## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. See the License for the specific language governing permissions +## and limitations under the License. +################################################################################################ + + +Directory="$1" +Files="$1/*.log" + +for Size in $(seq 6 2 16) +do + Product=1.0 + Count=0 + BMDRArray=() + for File in $Files + do + lines=`sim_bp gshare 16 16 $Size 1 $File | tail -5` + Total=`echo "$lines" | head -1 | awk '{print $5}'` + Miss=`echo "$lines" | tail -2 | head -1 | awk '{print $8}'` + BMDR=`echo "$Miss / $Total" | bc -l` + BMDRArray+=("$BMDR") + if [ $Miss -eq 0 ]; then + Product=`echo "scale=200; $Product / $Total" | bc -l` + else + Product=`echo "scale=200; $Product * $Miss / $Total" | bc -l` + fi + Count=$((Count+1)) + done + # with such long precision bc outputs onto multiple lines + # must remove \n and \ from string + Product=`echo "$Product" | tr -d '\n' | tr -d '\\\'` + GeoMean=`perl -E "say $Product**(1/$Count)"` + echo "$Pred$Size $GeoMean" +done From 2b031ea44515288f70751ee97730b8a5969d9ff2 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 23 Oct 2023 15:30:43 -0500 Subject: [PATCH 02/10] Fixed issue 250. instruction classification was not correct for jalr ra (non zero). --- src/ifu/bpred/icpred.sv | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ifu/bpred/icpred.sv b/src/ifu/bpred/icpred.sv index 65e60c59c..70136bdaf 100644 --- a/src/ifu/bpred/icpred.sv +++ b/src/ifu/bpred/icpred.sv @@ -51,20 +51,20 @@ module icpred import cvw::*; #(parameter cvw_t P, // An alternative to using the BTB to store the instruction class is to partially decode // the instructions in the Fetch stage into, Call, Return, Jump, and Branch instructions. // This logic is not described in the text book as of 23 February 2023. - logic ccall, cj, cjr, ccallr, CJumpF, CBranchF; + logic cjal, cj, cjr, cjalr, CJumpF, CBranchF; logic NCJumpF, NCBranchF; if(P.C_SUPPORTED) begin logic [4:0] CompressedOpcF; assign CompressedOpcF = {PostSpillInstrRawF[1:0], PostSpillInstrRawF[15:13]}; - assign ccall = CompressedOpcF == 5'h09 & P.XLEN == 32; + assign cjal = CompressedOpcF == 5'h09 & P.XLEN == 32; assign cj = CompressedOpcF == 5'h0d; assign cjr = CompressedOpcF == 5'h14 & ~PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0; - assign ccallr = CompressedOpcF == 5'h14 & PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0; - assign CJumpF = ccall | cj | cjr | ccallr; + assign cjalr = CompressedOpcF == 5'h14 & PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0; + assign CJumpF = cjal | cj | cjr | cjalr; assign CBranchF = CompressedOpcF[4:1] == 4'h7; end else begin - assign {ccall, cj, cjr, ccallr, CJumpF, CBranchF} = '0; + assign {cjal, cj, cjr, cjalr, CJumpF, CBranchF} = '0; end assign NCJumpF = PostSpillInstrRawF[6:0] == 7'h67 | PostSpillInstrRawF[6:0] == 7'h6F; @@ -72,11 +72,11 @@ module icpred import cvw::*; #(parameter cvw_t P, assign BPBranchF = NCBranchF | (P.C_SUPPORTED & CBranchF); assign BPJumpF = NCJumpF | (P.C_SUPPORTED & (CJumpF)); - assign BPReturnF = (NCJumpF & (PostSpillInstrRawF[19:15] & 5'h1B) == 5'h01) | // returnurn must returnurn to ra or r5 - (P.C_SUPPORTED & (ccallr | cjr) & ((PostSpillInstrRawF[11:7] & 5'h1B) == 5'h01)); + assign BPReturnF = (NCJumpF & (PostSpillInstrRawF[19:15] & 5'h1B) == 5'h01 & PostSpillInstrRawF[11:7] == 5'b0) | // return must return to ra or r5 + (P.C_SUPPORTED & cjr & ((PostSpillInstrRawF[11:7] & 5'h1B) == 5'h01)); assign BPCallF = (NCJumpF & (PostSpillInstrRawF[11:07] & 5'h1B) == 5'h01) | // call(r) must link to ra or x5 - (P.C_SUPPORTED & (ccall | (ccallr & (PostSpillInstrRawF[11:7] & 5'h1b) == 5'h01))); + (P.C_SUPPORTED & (cjal | (cjalr & (PostSpillInstrRawF[11:7] & 5'h1b) == 5'h01))); end else begin // This section connects the BTB's instruction class prediction. From bce15ce3678971a945ef5732fdb877019310fb6e Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 23 Oct 2023 15:32:03 -0500 Subject: [PATCH 03/10] Added support for branch counters when there is no branch predictor. --- src/ifu/ifu.sv | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index af6f70898..5ecc0237c 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -340,8 +340,21 @@ module ifu import cvw::*; #(parameter cvw_t P) ( end else begin : bpred mux2 #(P.XLEN) pcmux1(.d0(PCPlus2or4F), .d1(IEUAdrE), .s(PCSrcE), .y(PC1NextF)); + logic BranchM, JumpM, BranchW, JumpW; + logic CallD, CallE, CallM, CallW; + logic ReturnD, ReturnE, ReturnM, ReturnW; assign BPWrongE = PCSrcE; - assign {InstrClassM, BPDirPredWrongM, BTAWrongM, RASPredPCWrongM, IClassWrongM} = '0; + icpred #(P, 0) icpred(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, + .PostSpillInstrRawF, .InstrD, .BranchD, .BranchE, .JumpD, .JumpE, .BranchM, .BranchW, .JumpM, .JumpW, + .CallD, .CallE, .CallM, .CallW, .ReturnD, .ReturnE, .ReturnM, .ReturnW, + .BTBCallF(1'b0), .BTBReturnF(1'b0), .BTBJumpF(1'b0), + .BTBBranchF(1'b0), .BPCallF(), .BPReturnF(), .BPJumpF(), .BPBranchF(), .IClassWrongM, + .IClassWrongE(), .BPReturnWrongD()); + flopenrc #(1) PCSrcMReg(clk, reset, FlushM, ~StallM, PCSrcE, BPWrongM); + assign RASPredPCWrongM = '0; + assign BPDirPredWrongM = BPWrongM; + assign BTAWrongM = BPWrongM; + assign InstrClassM = {CallM, ReturnM, JumpM, BranchM}; assign NextValidPCE = PCE; end From c296bd3a02b2913784eee221596ec7517d1aff27 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 23 Oct 2023 16:09:40 -0500 Subject: [PATCH 04/10] Updated bpred-sim.py to take command line options to select between sweeping direction, target, class, or ras prediction. --- sim/bpred-sim.py | 117 ++++++++++++++++++++++++++--------------------- 1 file changed, 65 insertions(+), 52 deletions(-) diff --git a/sim/bpred-sim.py b/sim/bpred-sim.py index 9a59e8866..9e7ec12a6 100755 --- a/sim/bpred-sim.py +++ b/sim/bpred-sim.py @@ -11,6 +11,7 @@ # ################################## import sys,os,shutil +import argparse class bcolors: HEADER = '\033[95m' @@ -46,55 +47,6 @@ configs = [ ) ] -# bpdSize = [6, 8, 10, 12, 14, 16] -# bpdType = ['twobit', 'gshare', 'global', 'gshare_basic', 'global_basic', 'local_basic'] -# for CurrBPType in bpdType: -# for CurrBPSize in bpdSize: -# name = CurrBPType+str(CurrBPSize) -# configOptions = "+define+INSTR_CLASS_PRED=0 +define+BPRED_OVERRIDE +define+BPRED_TYPE=" + str(bpdType.index(CurrBPType)) + "+define+BPRED_SIZE=" + str(CurrBPSize) -# tc = TestCase( -# name=name, -# variant="rv32gc", -# cmd="vsim > {} -c < {} -c < {} -c < {} -c < {} -c < {} -c < {} -c < {} -c < Date: Tue, 24 Oct 2023 10:29:02 -0500 Subject: [PATCH 05/10] Fixed bug in bpred-sim.py for btb and class size sweep. --- sim/bpred-sim.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sim/bpred-sim.py b/sim/bpred-sim.py index 9e7ec12a6..209e21fc4 100755 --- a/sim/bpred-sim.py +++ b/sim/bpred-sim.py @@ -119,7 +119,7 @@ def main(): bpdSize = [6, 8, 10, 12, 14, 16] for CurrBPSize in bpdSize: name = 'BTB'+str(CurrBPSize) - configOptions = "+define+INSTR_CLASS_PRED=1 +define+BPRED_OVERRIDE +define+BPRED_TYPE=\`BP_GSHARE" + "+define+BPRED_SIZE=16" + "+define+BTB_SIZE=" + str(CurrBPSize) + "+define+BTB_OVERRIDE" + configOptions = "+define+INSTR_CLASS_PRED=1 +define+BPRED_OVERRIDE +define+BPRED_TYPE=\`BP_GSHARE" + "+define+BPRED_SIZE=16" + "+define+RAS_SIZE=16+define+BTB_SIZE=" + str(CurrBPSize) + "+define+BTB_OVERRIDE" tc = TestCase( name=name, variant="rv32gc", From bc877e9ca73d8e4028a8b8589344b1489d89f95a Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 24 Oct 2023 18:08:33 -0500 Subject: [PATCH 06/10] Possible fix for wfi. --- src/hazard/hazard.sv | 16 +++++++++++----- src/privileged/csr.sv | 6 +++++- src/wally/wallypipelinedcore.sv | 2 +- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/hazard/hazard.sv b/src/hazard/hazard.sv index 8efa454d9..b47ac410d 100644 --- a/src/hazard/hazard.sv +++ b/src/hazard/hazard.sv @@ -27,6 +27,7 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module hazard ( + input logic clk, reset, // Detect hazards input logic BPWrongE, CSRWriteFenceM, RetM, TrapM, input logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD, @@ -45,10 +46,12 @@ module hazard ( logic FlushDCause, FlushECause, FlushMCause, FlushWCause; logic WFIStallM, WFIInterruptedM; + logic wfiW; // WFI logic - assign WFIStallM = wfiM & ~IntPendingM; // WFI waiting for an interrupt or timeout - assign WFIInterruptedM = wfiM & IntPendingM; // WFI detects a pending interrupt. Retire WFI; trap if interrupt is enabled. + flopenrc #(1) wfiWReg(clk, reset, FlushW, ~StallW, wfiM, wfiW); + assign WFIStallM = wfiW & ~IntPendingM; // WFI waiting for an interrupt or timeout + assign WFIInterruptedM = wfiW & IntPendingM; // WFI detects a pending interrupt. Retire WFI; trap if interrupt is enabled. // stalls and flushes // loads: stall for one cycle if the subsequent instruction depends on the load @@ -73,7 +76,8 @@ module hazard ( assign FlushDCause = TrapM | RetM | CSRWriteFenceM | BPWrongE; assign FlushECause = TrapM | RetM | CSRWriteFenceM |(BPWrongE & ~(DivBusyE | FDivBusyE)); assign FlushMCause = TrapM | RetM | CSRWriteFenceM; - assign FlushWCause = TrapM & ~WFIInterruptedM; + //assign FlushWCause = TrapM & ~WFIInterruptedM; + assign FlushWCause = TrapM; // Stall causes // Most data depenency stalls are identified in the decode stage @@ -86,11 +90,13 @@ module hazard ( assign StallFCause = '0; assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FCvtIntStallD | FPUStallD) & ~FlushDCause; assign StallECause = (DivBusyE | FDivBusyE) & ~FlushECause; - assign StallMCause = WFIStallM & ~FlushMCause; + //assign StallMCause = WFIStallM & ~FlushMCause; + assign StallMCause = '0; // Need to gate IFUStallF when the equivalent FlushFCause = FlushDCause = 1. // assign StallWCause = ((IFUStallF & ~FlushDCause) | LSUStallM) & ~FlushWCause; // Because FlushWCause is a strict subset of FlushDCause, FlushWCause is factored out. - assign StallWCause = (IFUStallF & ~FlushDCause) | (LSUStallM & ~FlushWCause); + //assign StallWCause = (IFUStallF & ~FlushDCause) | (LSUStallM & ~FlushWCause); + assign StallWCause = (IFUStallF & ~FlushDCause) | ((LSUStallM | WFIStallM) & ~FlushWCause); // Stall each stage for cause or if the next stage is stalled // coverage off: StallFCause is always 0 diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index 4cdce4989..38e8945d9 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -200,9 +200,13 @@ module csr import cvw::*; #(parameter cvw_t P) ( /////////////////////////////////////////// // CSR Write values /////////////////////////////////////////// + logic [P.XLEN-1:0] PCW; // *** can optimize out it's just PCM for all now. + logic wfiW; + flopenr #(P.XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); + flopenrc #(1) wfiWReg(clk, reset, FlushW, ~StallW, wfiM, wfiW); assign CSRAdrM = InstrM[31:20]; - assign UnalignedNextEPCM = TrapM ? ((wfiM & IntPendingM) ? PCM+4 : PCM) : CSRWriteValM; + assign UnalignedNextEPCM = TrapM ? ((wfiW & IntPendingM) ? PCW+4 : PCM) : CSRWriteValM; assign NextEPCM = P.C_SUPPORTED ? {UnalignedNextEPCM[P.XLEN-1:1], 1'b0} : {UnalignedNextEPCM[P.XLEN-1:2], 2'b00}; // 3.1.15 alignment assign NextCauseM = TrapM ? {InterruptM, CauseM}: {CSRWriteValM[P.XLEN-1], CSRWriteValM[3:0]}; assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValM; diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index 00b348660..5df543903 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -264,7 +264,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( end // global stall and flush control - hazard hzu( + hazard hzu(.clk, .reset, .BPWrongE, .CSRWriteFenceM, .RetM, .TrapM, .LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD, .LSUStallM, .IFUStallF, From e4aebbaaa53e775136863a9fe1fa75723e33964e Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 24 Oct 2023 22:58:26 -0500 Subject: [PATCH 07/10] This version passes the regression test and solves issue #200. wfi's implemenation is changed so that wfi does not take an interrupt in the Memory stage. Instead it advances to the Writeback stage then traps. --- src/hazard/hazard.sv | 16 ++++++++-------- src/privileged/csr.sv | 6 ++---- src/privileged/privdec.sv | 4 +++- src/privileged/privileged.sv | 8 +++++--- src/privileged/trap.sv | 4 ++-- 5 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/hazard/hazard.sv b/src/hazard/hazard.sv index b47ac410d..94c967f32 100644 --- a/src/hazard/hazard.sv +++ b/src/hazard/hazard.sv @@ -50,8 +50,8 @@ module hazard ( // WFI logic flopenrc #(1) wfiWReg(clk, reset, FlushW, ~StallW, wfiM, wfiW); - assign WFIStallM = wfiW & ~IntPendingM; // WFI waiting for an interrupt or timeout - assign WFIInterruptedM = wfiW & IntPendingM; // WFI detects a pending interrupt. Retire WFI; trap if interrupt is enabled. + assign WFIStallM = wfiM & ~IntPendingM; // WFI waiting for an interrupt or timeout + assign WFIInterruptedM = wfiM & IntPendingM; // WFI detects a pending interrupt. Retire WFI; trap if interrupt is enabled. // stalls and flushes // loads: stall for one cycle if the subsequent instruction depends on the load @@ -76,8 +76,8 @@ module hazard ( assign FlushDCause = TrapM | RetM | CSRWriteFenceM | BPWrongE; assign FlushECause = TrapM | RetM | CSRWriteFenceM |(BPWrongE & ~(DivBusyE | FDivBusyE)); assign FlushMCause = TrapM | RetM | CSRWriteFenceM; - //assign FlushWCause = TrapM & ~WFIInterruptedM; - assign FlushWCause = TrapM; + assign FlushWCause = TrapM & ~WFIInterruptedM; + //assign FlushWCause = TrapM; // Stall causes // Most data depenency stalls are identified in the decode stage @@ -90,13 +90,13 @@ module hazard ( assign StallFCause = '0; assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FCvtIntStallD | FPUStallD) & ~FlushDCause; assign StallECause = (DivBusyE | FDivBusyE) & ~FlushECause; - //assign StallMCause = WFIStallM & ~FlushMCause; - assign StallMCause = '0; + assign StallMCause = WFIStallM & ~FlushMCause; + //assign StallMCause = '0; // Need to gate IFUStallF when the equivalent FlushFCause = FlushDCause = 1. // assign StallWCause = ((IFUStallF & ~FlushDCause) | LSUStallM) & ~FlushWCause; // Because FlushWCause is a strict subset of FlushDCause, FlushWCause is factored out. - //assign StallWCause = (IFUStallF & ~FlushDCause) | (LSUStallM & ~FlushWCause); - assign StallWCause = (IFUStallF & ~FlushDCause) | ((LSUStallM | WFIStallM) & ~FlushWCause); + assign StallWCause = (IFUStallF & ~FlushDCause) | (LSUStallM & ~FlushWCause); + //assign StallWCause = (IFUStallF & ~FlushDCause) | ((LSUStallM | WFIStallM) & ~FlushWCause); // Stall each stage for cause or if the next stage is stalled // coverage off: StallFCause is always 0 diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index 38e8945d9..ccd06a1ea 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -39,6 +39,7 @@ module csr import cvw::*; #(parameter cvw_t P) ( input logic CSRReadM, CSRWriteM, // read or write CSR input logic TrapM, // trap is occurring input logic mretM, sretM, wfiM, // return or WFI instruction + output logic wfiW, input logic IntPendingM, // at least one interrupt is pending and could occur if enabled input logic InterruptM, // interrupt is occurring input logic ExceptionM, // interrupt is occurring @@ -200,13 +201,10 @@ module csr import cvw::*; #(parameter cvw_t P) ( /////////////////////////////////////////// // CSR Write values /////////////////////////////////////////// - logic [P.XLEN-1:0] PCW; // *** can optimize out it's just PCM for all now. - logic wfiW; - flopenr #(P.XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); flopenrc #(1) wfiWReg(clk, reset, FlushW, ~StallW, wfiM, wfiW); assign CSRAdrM = InstrM[31:20]; - assign UnalignedNextEPCM = TrapM ? ((wfiW & IntPendingM) ? PCW+4 : PCM) : CSRWriteValM; + assign UnalignedNextEPCM = TrapM ? PCM : CSRWriteValM; assign NextEPCM = P.C_SUPPORTED ? {UnalignedNextEPCM[P.XLEN-1:1], 1'b0} : {UnalignedNextEPCM[P.XLEN-1:2], 2'b00}; // 3.1.15 alignment assign NextCauseM = TrapM ? {InterruptM, CauseM}: {CSRWriteValM[P.XLEN-1], CSRWriteValM[3:0]}; assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValM; diff --git a/src/privileged/privdec.sv b/src/privileged/privdec.sv index a0195f366..e6edbb086 100644 --- a/src/privileged/privdec.sv +++ b/src/privileged/privdec.sv @@ -29,7 +29,7 @@ module privdec import cvw::*; #(parameter cvw_t P) ( input logic clk, reset, - input logic StallM, + input logic StallM, StallW, FlushW, input logic [31:15] InstrM, // privileged instruction function field input logic PrivilegedM, // is this a privileged instruction (from IEU controller) input logic IllegalIEUFPUInstrM, // Not a legal IEU instruction @@ -75,6 +75,8 @@ module privdec import cvw::*; #(parameter cvw_t P) ( /////////////////////////////////////////// // WFI timeout Privileged Spec 3.1.6.5 /////////////////////////////////////////// + logic wfiW; // *** need to merge with others + flopenrc #(1) wfiWReg(clk, reset, FlushW, ~StallW, wfiM, wfiW); // *** remove if (P.U_SUPPORTED) begin:wfi logic [P.WFI_TIMEOUT_BIT:0] WFICount, WFICountPlus1; diff --git a/src/privileged/privileged.sv b/src/privileged/privileged.sv index fff4af8b8..c338d2475 100644 --- a/src/privileged/privileged.sv +++ b/src/privileged/privileged.sv @@ -115,12 +115,14 @@ module privileged import cvw::*; #(parameter cvw_t P) ( logic ExceptionM; // Memory stage instruction caused a fault logic HPTWInstrAccessFaultM; // Hardware page table access fault while fetching instruction PTE + logic wfiW; + // track the current privilege level privmode #(P) privmode(.clk, .reset, .StallW, .TrapM, .mretM, .sretM, .DelegateM, .STATUS_MPP, .STATUS_SPP, .NextPrivilegeModeM, .PrivilegeModeW); // decode privileged instructions - privdec #(P) pmd(.clk, .reset, .StallM, .InstrM(InstrM[31:15]), + privdec #(P) pmd(.clk, .reset, .StallM, .StallW, .FlushW, .InstrM(InstrM[31:15]), .PrivilegedM, .IllegalIEUFPUInstrM, .IllegalCSRAccessM, .PrivilegeModeW, .STATUS_TSR, .STATUS_TVM, .STATUS_TW, .IllegalInstrFaultM, .EcallFaultM, .BreakpointFaultM, .sretM, .mretM, .wfiM, .sfencevmaM); @@ -128,7 +130,7 @@ module privileged import cvw::*; #(parameter cvw_t P) ( // Control and Status Registers csr #(P) csr(.clk, .reset, .FlushM, .FlushW, .StallE, .StallM, .StallW, .InstrM, .InstrOrigM, .PCM, .SrcAM, .IEUAdrM, .PC2NextF, - .CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .wfiM, .IntPendingM, .InterruptM, + .CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .wfiM, .wfiW, .IntPendingM, .InterruptM, .MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .StoreStallD, .BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .BPWrongM, @@ -156,5 +158,5 @@ module privileged import cvw::*; #(parameter cvw_t P) ( .mretM, .sretM, .PrivilegeModeW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MEDELEG_REGW, .STATUS_MIE, .STATUS_SIE, .InstrValidM, .CommittedM, .CommittedF, - .TrapM, .RetM, .wfiM, .InterruptM, .ExceptionM, .IntPendingM, .DelegateM, .CauseM); + .TrapM, .RetM, .wfiM, .wfiW, .InterruptM, .ExceptionM, .IntPendingM, .DelegateM, .CauseM); endmodule diff --git a/src/privileged/trap.sv b/src/privileged/trap.sv index bcde634de..00ffc6617 100644 --- a/src/privileged/trap.sv +++ b/src/privileged/trap.sv @@ -33,7 +33,7 @@ module trap import cvw::*; #(parameter cvw_t P) ( input logic LoadAccessFaultM, StoreAmoAccessFaultM, EcallFaultM, InstrPageFaultM, input logic LoadPageFaultM, StoreAmoPageFaultM, // various trap sources input logic mretM, sretM, // return instructions - input logic wfiM, // wait for interrupt instruction + input logic wfiM, wfiW, // wait for interrupt instruction input logic [1:0] PrivilegeModeW, // current privilege mode input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, // interrupt pending, enabled, and delegate CSRs input logic [15:0] MEDELEG_REGW, // exception delegation SR @@ -68,7 +68,7 @@ module trap import cvw::*; #(parameter cvw_t P) ( assign Committed = CommittedM | CommittedF; assign EnabledIntsM = ({12{MIntGlobalEnM}} & PendingIntsM & ~MIDELEG_REGW | {12{SIntGlobalEnM}} & PendingIntsM & MIDELEG_REGW); assign ValidIntsM = {12{~Committed}} & EnabledIntsM; - assign InterruptM = (|ValidIntsM) & InstrValidM; // suppress interrupt if the memory system has partially processed a request. + assign InterruptM = (|ValidIntsM) & InstrValidM & (~wfiM | wfiW); // suppress interrupt if the memory system has partially processed a request. assign DelegateM = P.S_SUPPORTED & (InterruptM ? MIDELEG_REGW[CauseM] : MEDELEG_REGW[CauseM]) & (PrivilegeModeW == P.U_MODE | PrivilegeModeW == P.S_MODE); From dd9059317f16685cc2130c6b52471b19b89d54e2 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 24 Oct 2023 23:05:12 -0500 Subject: [PATCH 08/10] Cleaned up the implementation changes for wfi. --- src/hazard/hazard.sv | 6 ------ src/privileged/csr.sv | 2 -- src/privileged/privdec.sv | 6 +++--- src/privileged/privileged.sv | 4 ++-- 4 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/hazard/hazard.sv b/src/hazard/hazard.sv index 94c967f32..cb70605c0 100644 --- a/src/hazard/hazard.sv +++ b/src/hazard/hazard.sv @@ -27,7 +27,6 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module hazard ( - input logic clk, reset, // Detect hazards input logic BPWrongE, CSRWriteFenceM, RetM, TrapM, input logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD, @@ -46,10 +45,8 @@ module hazard ( logic FlushDCause, FlushECause, FlushMCause, FlushWCause; logic WFIStallM, WFIInterruptedM; - logic wfiW; // WFI logic - flopenrc #(1) wfiWReg(clk, reset, FlushW, ~StallW, wfiM, wfiW); assign WFIStallM = wfiM & ~IntPendingM; // WFI waiting for an interrupt or timeout assign WFIInterruptedM = wfiM & IntPendingM; // WFI detects a pending interrupt. Retire WFI; trap if interrupt is enabled. @@ -77,7 +74,6 @@ module hazard ( assign FlushECause = TrapM | RetM | CSRWriteFenceM |(BPWrongE & ~(DivBusyE | FDivBusyE)); assign FlushMCause = TrapM | RetM | CSRWriteFenceM; assign FlushWCause = TrapM & ~WFIInterruptedM; - //assign FlushWCause = TrapM; // Stall causes // Most data depenency stalls are identified in the decode stage @@ -91,12 +87,10 @@ module hazard ( assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FCvtIntStallD | FPUStallD) & ~FlushDCause; assign StallECause = (DivBusyE | FDivBusyE) & ~FlushECause; assign StallMCause = WFIStallM & ~FlushMCause; - //assign StallMCause = '0; // Need to gate IFUStallF when the equivalent FlushFCause = FlushDCause = 1. // assign StallWCause = ((IFUStallF & ~FlushDCause) | LSUStallM) & ~FlushWCause; // Because FlushWCause is a strict subset of FlushDCause, FlushWCause is factored out. assign StallWCause = (IFUStallF & ~FlushDCause) | (LSUStallM & ~FlushWCause); - //assign StallWCause = (IFUStallF & ~FlushDCause) | ((LSUStallM | WFIStallM) & ~FlushWCause); // Stall each stage for cause or if the next stage is stalled // coverage off: StallFCause is always 0 diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index ccd06a1ea..b25c3b905 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -39,7 +39,6 @@ module csr import cvw::*; #(parameter cvw_t P) ( input logic CSRReadM, CSRWriteM, // read or write CSR input logic TrapM, // trap is occurring input logic mretM, sretM, wfiM, // return or WFI instruction - output logic wfiW, input logic IntPendingM, // at least one interrupt is pending and could occur if enabled input logic InterruptM, // interrupt is occurring input logic ExceptionM, // interrupt is occurring @@ -201,7 +200,6 @@ module csr import cvw::*; #(parameter cvw_t P) ( /////////////////////////////////////////// // CSR Write values /////////////////////////////////////////// - flopenrc #(1) wfiWReg(clk, reset, FlushW, ~StallW, wfiM, wfiW); assign CSRAdrM = InstrM[31:20]; assign UnalignedNextEPCM = TrapM ? PCM : CSRWriteValM; diff --git a/src/privileged/privdec.sv b/src/privileged/privdec.sv index e6edbb086..eb17b8d04 100644 --- a/src/privileged/privdec.sv +++ b/src/privileged/privdec.sv @@ -39,7 +39,7 @@ module privdec import cvw::*; #(parameter cvw_t P) ( output logic IllegalInstrFaultM, // Illegal instruction output logic EcallFaultM, BreakpointFaultM, // Ecall or breakpoint; must retire, so don't flush it when the trap occurs output logic sretM, mretM, // return instructions - output logic wfiM, sfencevmaM // wfi / sfence.vma / sinval.vma instructions + output logic wfiM, wfiW, sfencevmaM // wfi / sfence.vma / sinval.vma instructions ); logic rs1zeroM; // rs1 field = 0 @@ -75,8 +75,6 @@ module privdec import cvw::*; #(parameter cvw_t P) ( /////////////////////////////////////////// // WFI timeout Privileged Spec 3.1.6.5 /////////////////////////////////////////// - logic wfiW; // *** need to merge with others - flopenrc #(1) wfiWReg(clk, reset, FlushW, ~StallW, wfiM, wfiW); // *** remove if (P.U_SUPPORTED) begin:wfi logic [P.WFI_TIMEOUT_BIT:0] WFICount, WFICountPlus1; @@ -88,6 +86,8 @@ module privdec import cvw::*; #(parameter cvw_t P) ( // coverage on end else assign WFITimeoutM = 0; + flopenrc #(1) wfiWReg(clk, reset, FlushW, ~StallW, wfiM, wfiW); + /////////////////////////////////////////// // Extract exceptions by name and handle them /////////////////////////////////////////// diff --git a/src/privileged/privileged.sv b/src/privileged/privileged.sv index c338d2475..d777e0bf9 100644 --- a/src/privileged/privileged.sv +++ b/src/privileged/privileged.sv @@ -125,12 +125,12 @@ module privileged import cvw::*; #(parameter cvw_t P) ( privdec #(P) pmd(.clk, .reset, .StallM, .StallW, .FlushW, .InstrM(InstrM[31:15]), .PrivilegedM, .IllegalIEUFPUInstrM, .IllegalCSRAccessM, .PrivilegeModeW, .STATUS_TSR, .STATUS_TVM, .STATUS_TW, .IllegalInstrFaultM, - .EcallFaultM, .BreakpointFaultM, .sretM, .mretM, .wfiM, .sfencevmaM); + .EcallFaultM, .BreakpointFaultM, .sretM, .mretM, .wfiM, .wfiW, .sfencevmaM); // Control and Status Registers csr #(P) csr(.clk, .reset, .FlushM, .FlushW, .StallE, .StallM, .StallW, .InstrM, .InstrOrigM, .PCM, .SrcAM, .IEUAdrM, .PC2NextF, - .CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .wfiM, .wfiW, .IntPendingM, .InterruptM, + .CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .wfiM, .IntPendingM, .InterruptM, .MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .StoreStallD, .BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .BPWrongM, From 63bcc7655ca99bf6bdfdfc2ce639b7393a0b4668 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Thu, 26 Oct 2023 12:20:42 -0500 Subject: [PATCH 09/10] Forgot to include this file in the last commit. --- src/wally/wallypipelinedcore.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index 5df543903..00b348660 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -264,7 +264,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( end // global stall and flush control - hazard hzu(.clk, .reset, + hazard hzu( .BPWrongE, .CSRWriteFenceM, .RetM, .TrapM, .LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD, .LSUStallM, .IFUStallF, From 9ca3bfc2c8dcbd570673c0166823e3ae0b87b01b Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Thu, 26 Oct 2023 12:24:36 -0500 Subject: [PATCH 10/10] Updated comments about Interrupt and wfi. --- src/privileged/trap.sv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/privileged/trap.sv b/src/privileged/trap.sv index 00ffc6617..bfbbeb65f 100644 --- a/src/privileged/trap.sv +++ b/src/privileged/trap.sv @@ -68,7 +68,8 @@ module trap import cvw::*; #(parameter cvw_t P) ( assign Committed = CommittedM | CommittedF; assign EnabledIntsM = ({12{MIntGlobalEnM}} & PendingIntsM & ~MIDELEG_REGW | {12{SIntGlobalEnM}} & PendingIntsM & MIDELEG_REGW); assign ValidIntsM = {12{~Committed}} & EnabledIntsM; - assign InterruptM = (|ValidIntsM) & InstrValidM & (~wfiM | wfiW); // suppress interrupt if the memory system has partially processed a request. + assign InterruptM = (|ValidIntsM) & InstrValidM & (~wfiM | wfiW); // suppress interrupt if the memory system has partially processed a request. Delay interrupt until wfi is in the W stage. + // wfiW is to support possible but unlikely back to back wfi instructions. wfiM would be high in the M stage, while also in the W stage. assign DelegateM = P.S_SUPPORTED & (InterruptM ? MIDELEG_REGW[CauseM] : MEDELEG_REGW[CauseM]) & (PrivilegeModeW == P.U_MODE | PrivilegeModeW == P.S_MODE);