mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge branch 'main' of https://github.com/openhwgroup/cvw into dev
This commit is contained in:
commit
d5d196b870
57
bin/CModelBTBAccuracy.sh
Executable file
57
bin/CModelBTBAccuracy.sh
Executable file
@ -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
|
117
sim/bpred-sim.py
117
sim/bpred-sim.py
@ -11,6 +11,7 @@
|
|||||||
#
|
#
|
||||||
##################################
|
##################################
|
||||||
import sys,os,shutil
|
import sys,os,shutil
|
||||||
|
import argparse
|
||||||
|
|
||||||
class bcolors:
|
class bcolors:
|
||||||
HEADER = '\033[95m'
|
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 <<!\ndo wally-batch.do rv32gc configOptions " + name + " embench " + configOptions,
|
|
||||||
# grepstr="")
|
|
||||||
# configs.append(tc)
|
|
||||||
|
|
||||||
# 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"
|
|
||||||
# tc = TestCase(
|
|
||||||
# name=name,
|
|
||||||
# variant="rv32gc",
|
|
||||||
# cmd="vsim > {} -c <<!\ndo wally-batch.do rv32gc configOptions " + name + " embench " + configOptions,
|
|
||||||
# grepstr="")
|
|
||||||
# configs.append(tc)
|
|
||||||
|
|
||||||
bpdSize = [2, 3, 4, 6, 10, 16]
|
|
||||||
for CurrBPSize in bpdSize:
|
|
||||||
name = 'RAS'+str(CurrBPSize)
|
|
||||||
configOptions = "+define+INSTR_CLASS_PRED=0 +define+BPRED_OVERRIDE +define+BPRED_TYPE=\`BP_GSHARE" + "+define+BPRED_SIZE=16" + "+define+BTB_SIZE=16" + "+define+RAS_SIZE=" + str(CurrBPSize) + "+define+BTB_OVERRIDE+define+RAS_OVERRIDE"
|
|
||||||
tc = TestCase(
|
|
||||||
name=name,
|
|
||||||
variant="rv32gc",
|
|
||||||
cmd="vsim > {} -c <<!\ndo wally-batch.do rv32gc configOptions " + name + " embench " + configOptions,
|
|
||||||
grepstr="")
|
|
||||||
configs.append(tc)
|
|
||||||
|
|
||||||
# bpdSize = [6, 8, 10, 12, 14, 16]
|
|
||||||
# LHRSize = [4, 8, 10]
|
|
||||||
# bpdType = ['local_repair']
|
|
||||||
# for CurrBPType in bpdType:
|
|
||||||
# for CurrBPSize in bpdSize:
|
|
||||||
# for CurrLHRSize in LHRSize:
|
|
||||||
# name = str(CurrLHRSize)+CurrBPType+str(CurrBPSize)
|
|
||||||
# configOptions = "+define+INSTR_CLASS_PRED=0 +define+BPRED_TYPE=\"BP_" + CurrBPType.upper() + "\" +define+BPRED_SIZE=" + str(CurrBPSize) + " +define+BPRED_NUM_LHR=" + str(CurrLHRSize) + " "
|
|
||||||
# tc = TestCase(
|
|
||||||
# name=name,
|
|
||||||
# variant="rv32gc",
|
|
||||||
# cmd="vsim > {} -c <<!\ndo wally-batch.do rv32gc configOptions " + name + " embench " + configOptions,
|
|
||||||
# grepstr="")
|
|
||||||
# configs.append(tc)
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from multiprocessing import Pool, TimeoutError
|
from multiprocessing import Pool, TimeoutError
|
||||||
@ -138,9 +90,70 @@ def main():
|
|||||||
finally:
|
finally:
|
||||||
os.mkdir("wkdir")
|
os.mkdir("wkdir")
|
||||||
|
|
||||||
if '-makeTests' in sys.argv:
|
parser = argparse.ArgumentParser(description='Runs embench with sweeps of branch predictor sizes and types.')
|
||||||
os.chdir(regressionDir)
|
mode = parser.add_mutually_exclusive_group()
|
||||||
os.system('./make-tests.sh | tee ./logs/make-tests.log')
|
mode.add_argument('-r', '--ras', action='store_const', help='Sweep size of return address stack (RAS).', default=False, const=True)
|
||||||
|
mode.add_argument('-d', '--direction', action='store_const', help='Sweep size of direction prediction (2-bit, Gshare, local, etc).', default=False, const=True)
|
||||||
|
mode.add_argument('-t', '--target', action='store_const', help='Sweep size of branch target buffer (BTB).', default=False, const=True)
|
||||||
|
mode.add_argument('-c', '--iclass', action='store_const', help='Sweep size of classification (BTB) Same as -t.', default=False, const=True)
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if(args.direction):
|
||||||
|
# for direction predictor size sweep
|
||||||
|
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 <<!\ndo wally-batch.do rv32gc configOptions " + name + " embench " + configOptions,
|
||||||
|
grepstr="")
|
||||||
|
configs.append(tc)
|
||||||
|
|
||||||
|
if(args.target or args.iclass):
|
||||||
|
# BTB and class size sweep
|
||||||
|
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+RAS_SIZE=16+define+BTB_SIZE=" + str(CurrBPSize) + "+define+BTB_OVERRIDE"
|
||||||
|
tc = TestCase(
|
||||||
|
name=name,
|
||||||
|
variant="rv32gc",
|
||||||
|
cmd="vsim > {} -c <<!\ndo wally-batch.do rv32gc configOptions " + name + " embench " + configOptions,
|
||||||
|
grepstr="")
|
||||||
|
configs.append(tc)
|
||||||
|
|
||||||
|
# ras size sweep
|
||||||
|
if(args.ras):
|
||||||
|
bpdSize = [2, 3, 4, 6, 10, 16]
|
||||||
|
for CurrBPSize in bpdSize:
|
||||||
|
name = 'RAS'+str(CurrBPSize)
|
||||||
|
configOptions = "+define+INSTR_CLASS_PRED=0 +define+BPRED_OVERRIDE +define+BPRED_TYPE=\`BP_GSHARE" + "+define+BPRED_SIZE=16" + "+define+BTB_SIZE=16" + "+define+RAS_SIZE=" + str(CurrBPSize) + "+define+BTB_OVERRIDE+define+RAS_OVERRIDE"
|
||||||
|
tc = TestCase(
|
||||||
|
name=name,
|
||||||
|
variant="rv32gc",
|
||||||
|
cmd="vsim > {} -c <<!\ndo wally-batch.do rv32gc configOptions " + name + " embench " + configOptions,
|
||||||
|
grepstr="")
|
||||||
|
configs.append(tc)
|
||||||
|
|
||||||
|
# bpdSize = [6, 8, 10, 12, 14, 16]
|
||||||
|
# LHRSize = [4, 8, 10]
|
||||||
|
# bpdType = ['local_repair']
|
||||||
|
# for CurrBPType in bpdType:
|
||||||
|
# for CurrBPSize in bpdSize:
|
||||||
|
# for CurrLHRSize in LHRSize:
|
||||||
|
# name = str(CurrLHRSize)+CurrBPType+str(CurrBPSize)
|
||||||
|
# configOptions = "+define+INSTR_CLASS_PRED=0 +define+BPRED_TYPE=\"BP_" + CurrBPType.upper() + "\" +define+BPRED_SIZE=" + str(CurrBPSize) + " +define+BPRED_NUM_LHR=" + str(CurrLHRSize) + " "
|
||||||
|
# tc = TestCase(
|
||||||
|
# name=name,
|
||||||
|
# variant="rv32gc",
|
||||||
|
# cmd="vsim > {} -c <<!\ndo wally-batch.do rv32gc configOptions " + name + " embench " + configOptions,
|
||||||
|
# grepstr="")
|
||||||
|
# configs.append(tc)
|
||||||
|
|
||||||
# Scale the number of concurrent processes to the number of test cases, but
|
# Scale the number of concurrent processes to the number of test cases, but
|
||||||
# max out at a limited number of concurrent processes to not overwhelm the system
|
# max out at a limited number of concurrent processes to not overwhelm the system
|
||||||
|
@ -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
|
// 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.
|
// 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.
|
// 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;
|
logic NCJumpF, NCBranchF;
|
||||||
|
|
||||||
if(P.C_SUPPORTED) begin
|
if(P.C_SUPPORTED) begin
|
||||||
logic [4:0] CompressedOpcF;
|
logic [4:0] CompressedOpcF;
|
||||||
assign CompressedOpcF = {PostSpillInstrRawF[1:0], PostSpillInstrRawF[15:13]};
|
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 cj = CompressedOpcF == 5'h0d;
|
||||||
assign cjr = CompressedOpcF == 5'h14 & ~PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0;
|
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 cjalr = CompressedOpcF == 5'h14 & PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0;
|
||||||
assign CJumpF = ccall | cj | cjr | ccallr;
|
assign CJumpF = cjal | cj | cjr | cjalr;
|
||||||
assign CBranchF = CompressedOpcF[4:1] == 4'h7;
|
assign CBranchF = CompressedOpcF[4:1] == 4'h7;
|
||||||
end else begin
|
end else begin
|
||||||
assign {ccall, cj, cjr, ccallr, CJumpF, CBranchF} = '0;
|
assign {cjal, cj, cjr, cjalr, CJumpF, CBranchF} = '0;
|
||||||
end
|
end
|
||||||
|
|
||||||
assign NCJumpF = PostSpillInstrRawF[6:0] == 7'h67 | PostSpillInstrRawF[6:0] == 7'h6F;
|
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 BPBranchF = NCBranchF | (P.C_SUPPORTED & CBranchF);
|
||||||
assign BPJumpF = NCJumpF | (P.C_SUPPORTED & (CJumpF));
|
assign BPJumpF = NCJumpF | (P.C_SUPPORTED & (CJumpF));
|
||||||
assign BPReturnF = (NCJumpF & (PostSpillInstrRawF[19:15] & 5'h1B) == 5'h01) | // returnurn must returnurn to ra or r5
|
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 & (ccallr | cjr) & ((PostSpillInstrRawF[11:7] & 5'h1B) == 5'h01));
|
(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
|
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
|
end else begin
|
||||||
// This section connects the BTB's instruction class prediction.
|
// This section connects the BTB's instruction class prediction.
|
||||||
|
@ -340,8 +340,21 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||||||
|
|
||||||
end else begin : bpred
|
end else begin : bpred
|
||||||
mux2 #(P.XLEN) pcmux1(.d0(PCPlus2or4F), .d1(IEUAdrE), .s(PCSrcE), .y(PC1NextF));
|
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 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;
|
assign NextValidPCE = PCE;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -202,7 +202,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
|
|||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
|
|
||||||
assign CSRAdrM = InstrM[31:20];
|
assign CSRAdrM = InstrM[31:20];
|
||||||
assign UnalignedNextEPCM = TrapM ? ((wfiM & IntPendingM) ? PCM+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 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 NextCauseM = TrapM ? {InterruptM, CauseM}: {CSRWriteValM[P.XLEN-1], CSRWriteValM[3:0]};
|
||||||
assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValM;
|
assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValM;
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
module privdec import cvw::*; #(parameter cvw_t P) (
|
module privdec import cvw::*; #(parameter cvw_t P) (
|
||||||
input logic clk, reset,
|
input logic clk, reset,
|
||||||
input logic StallM,
|
input logic StallM, StallW, FlushW,
|
||||||
input logic [31:15] InstrM, // privileged instruction function field
|
input logic [31:15] InstrM, // privileged instruction function field
|
||||||
input logic PrivilegedM, // is this a privileged instruction (from IEU controller)
|
input logic PrivilegedM, // is this a privileged instruction (from IEU controller)
|
||||||
input logic IllegalIEUFPUInstrM, // Not a legal IEU instruction
|
input logic IllegalIEUFPUInstrM, // Not a legal IEU instruction
|
||||||
@ -39,7 +39,7 @@ module privdec import cvw::*; #(parameter cvw_t P) (
|
|||||||
output logic IllegalInstrFaultM, // Illegal instruction
|
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 EcallFaultM, BreakpointFaultM, // Ecall or breakpoint; must retire, so don't flush it when the trap occurs
|
||||||
output logic sretM, mretM, // return instructions
|
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
|
logic rs1zeroM; // rs1 field = 0
|
||||||
@ -86,6 +86,8 @@ module privdec import cvw::*; #(parameter cvw_t P) (
|
|||||||
// coverage on
|
// coverage on
|
||||||
end else assign WFITimeoutM = 0;
|
end else assign WFITimeoutM = 0;
|
||||||
|
|
||||||
|
flopenrc #(1) wfiWReg(clk, reset, FlushW, ~StallW, wfiM, wfiW);
|
||||||
|
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
// Extract exceptions by name and handle them
|
// Extract exceptions by name and handle them
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
|
@ -115,15 +115,17 @@ module privileged import cvw::*; #(parameter cvw_t P) (
|
|||||||
logic ExceptionM; // Memory stage instruction caused a fault
|
logic ExceptionM; // Memory stage instruction caused a fault
|
||||||
logic HPTWInstrAccessFaultM; // Hardware page table access fault while fetching instruction PTE
|
logic HPTWInstrAccessFaultM; // Hardware page table access fault while fetching instruction PTE
|
||||||
|
|
||||||
|
logic wfiW;
|
||||||
|
|
||||||
// track the current privilege level
|
// track the current privilege level
|
||||||
privmode #(P) privmode(.clk, .reset, .StallW, .TrapM, .mretM, .sretM, .DelegateM,
|
privmode #(P) privmode(.clk, .reset, .StallW, .TrapM, .mretM, .sretM, .DelegateM,
|
||||||
.STATUS_MPP, .STATUS_SPP, .NextPrivilegeModeM, .PrivilegeModeW);
|
.STATUS_MPP, .STATUS_SPP, .NextPrivilegeModeM, .PrivilegeModeW);
|
||||||
|
|
||||||
// decode privileged instructions
|
// 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,
|
.PrivilegedM, .IllegalIEUFPUInstrM, .IllegalCSRAccessM,
|
||||||
.PrivilegeModeW, .STATUS_TSR, .STATUS_TVM, .STATUS_TW, .IllegalInstrFaultM,
|
.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
|
// Control and Status Registers
|
||||||
csr #(P) csr(.clk, .reset, .FlushM, .FlushW, .StallE, .StallM, .StallW,
|
csr #(P) csr(.clk, .reset, .FlushM, .FlushW, .StallE, .StallM, .StallW,
|
||||||
@ -156,5 +158,5 @@ module privileged import cvw::*; #(parameter cvw_t P) (
|
|||||||
.mretM, .sretM, .PrivilegeModeW,
|
.mretM, .sretM, .PrivilegeModeW,
|
||||||
.MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MEDELEG_REGW, .STATUS_MIE, .STATUS_SIE,
|
.MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MEDELEG_REGW, .STATUS_MIE, .STATUS_SIE,
|
||||||
.InstrValidM, .CommittedM, .CommittedF,
|
.InstrValidM, .CommittedM, .CommittedF,
|
||||||
.TrapM, .RetM, .wfiM, .InterruptM, .ExceptionM, .IntPendingM, .DelegateM, .CauseM);
|
.TrapM, .RetM, .wfiM, .wfiW, .InterruptM, .ExceptionM, .IntPendingM, .DelegateM, .CauseM);
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -33,7 +33,7 @@ module trap import cvw::*; #(parameter cvw_t P) (
|
|||||||
input logic LoadAccessFaultM, StoreAmoAccessFaultM, EcallFaultM, InstrPageFaultM,
|
input logic LoadAccessFaultM, StoreAmoAccessFaultM, EcallFaultM, InstrPageFaultM,
|
||||||
input logic LoadPageFaultM, StoreAmoPageFaultM, // various trap sources
|
input logic LoadPageFaultM, StoreAmoPageFaultM, // various trap sources
|
||||||
input logic mretM, sretM, // return instructions
|
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 [1:0] PrivilegeModeW, // current privilege mode
|
||||||
input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, // interrupt pending, enabled, and delegate CSRs
|
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
|
input logic [15:0] MEDELEG_REGW, // exception delegation SR
|
||||||
@ -68,7 +68,8 @@ module trap import cvw::*; #(parameter cvw_t P) (
|
|||||||
assign Committed = CommittedM | CommittedF;
|
assign Committed = CommittedM | CommittedF;
|
||||||
assign EnabledIntsM = ({12{MIntGlobalEnM}} & PendingIntsM & ~MIDELEG_REGW | {12{SIntGlobalEnM}} & PendingIntsM & MIDELEG_REGW);
|
assign EnabledIntsM = ({12{MIntGlobalEnM}} & PendingIntsM & ~MIDELEG_REGW | {12{SIntGlobalEnM}} & PendingIntsM & MIDELEG_REGW);
|
||||||
assign ValidIntsM = {12{~Committed}} & EnabledIntsM;
|
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. 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]) &
|
assign DelegateM = P.S_SUPPORTED & (InterruptM ? MIDELEG_REGW[CauseM] : MEDELEG_REGW[CauseM]) &
|
||||||
(PrivilegeModeW == P.U_MODE | PrivilegeModeW == P.S_MODE);
|
(PrivilegeModeW == P.U_MODE | PrivilegeModeW == P.S_MODE);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user