Merge pull request #508 from ross144/main

fixes to branch predictor post processing scripts. ch 21 instructions work in newly cloned repo
This commit is contained in:
David Harris 2023-11-27 20:02:21 -05:00 committed by GitHub
commit d1876f4edb
20 changed files with 106 additions and 95 deletions

2
.gitignore vendored
View File

@ -180,3 +180,5 @@ sim/branch*.log
benchmarks/embench/wally*.json
benchmarks/embench/run*
sim/cfi.log
sim/cfi/*
sim/branch/*

View File

@ -43,6 +43,7 @@ sim: modelsim_build_memfile modelsim_run speed
# launches modelsim to simulate tests on wally
modelsim_run:
mkdir -p ../../sim/wkdir
(cd ../../sim/ && vsim -c -do "do wally-batch.do rv32gc embench")
cd ../../benchmarks/embench/

View File

@ -40,18 +40,18 @@ 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`
BMDR=`echo "100.0 * $Miss / $Total" | bc -l`
BMDRArray+=("$BMDR")
if [ $Miss -eq 0 ]; then
Product=`echo "scale=200; $Product / $Total" | bc -l`
Product=`echo "scale=200; $Product * 100 / $Total" | bc -l`
else
Product=`echo "scale=200; $Product * $Miss / $Total" | bc -l`
Product=`echo "scale=200; $Product * $BMDR" | 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) * 100"`
GeoMean=`perl -E "say $Product**(1/$Count)"`
echo "$Pred$Size $GeoMean"
done

View File

@ -46,7 +46,7 @@ do
do
#echo "sim_bp $Pred $Size $Size 18 1 $File | tail -1 | awk '{print $4}'"
#echo "sim_bp $Pred $SizeString $File | tail -1 | awk '{print $4}'"
BMDR=`sim_bp $Pred $SizeString $File | tail -1 | awk '{print $4}'`
BMDR=`sim_bp -c $Pred $SizeString $File | tail -1 | awk '{print $4}'`
Product=`echo "$Product * $BMDR" | bc`
Count=$((Count+1))
done

View File

@ -32,12 +32,13 @@ import math
import numpy as np
import argparse
RefDataBP = [('twobitCModel6', 'twobitCModel', 64, 9.65280765420711), ('twobitCModel8', 'twobitCModel', 256, 8.75120245829945), ('twobitCModel10', 'twobitCModel', 1024, 8.1318382397263),
('twobitCModel12', 'twobitCModel', 4096, 7.53026646633342), ('twobitCModel14', 'twobitCModel', 16384, 6.07679338544009), ('twobitCModel16', 'twobitCModel', 65536, 6.07679338544009),
('gshareCModel6', 'gshareCModel', 64, 10.6602835418646), ('gshareCModel8', 'gshareCModel', 256, 8.38384710559667), ('gshareCModel10', 'gshareCModel', 1024, 6.36847432155534),
('gshareCModel12', 'gshareCModel', 4096, 3.91108491151983), ('gshareCModel14', 'gshareCModel', 16384, 2.83926519215395), ('gshareCModel16', 'gshareCModel', 65536, .60213659066941)]
RefDataBTB = [('BTBCModel6', 'BTBCModel', 64, 1.11806778745097), ('BTBCModel8', 'BTBCModel', 256, 0.183833943219956), ('BTBCModel10', 'BTBCModel', 1024, 0.0109271020749376),
('BTBCModel12', 'BTBCModel', 4096, 0.00437600802791213), ('BTBCModel14', 'BTBCModel', 16384, 0.00188756234204305), ('BTBCModel16', 'BTBCModel', 65536, 0.00188756234204305)]
RefDataBP = [('twobitCModel6', 'twobitCModel', 64, 10.0060297551637), ('twobitCModel8', 'twobitCModel', 256, 8.4320392215602), ('twobitCModel10', 'twobitCModel', 1024, 7.29493318805151),
('twobitCModel12', 'twobitCModel', 4096, 6.84739616147794), ('twobitCModel14', 'twobitCModel', 16384, 5.68432926870082), ('twobitCModel16', 'twobitCModel', 65536, 5.68432926870082),
('gshareCModel6', 'gshareCModel', 64, 11.4737703417701), ('gshareCModel8', 'gshareCModel', 256, 8.52341470761974), ('gshareCModel10', 'gshareCModel', 1024, 6.32975690693015),
('gshareCModel12', 'gshareCModel', 4096, 4.55424632377659), ('gshareCModel14', 'gshareCModel', 16384, 3.54251547725509), ('gshareCModel16', 'gshareCModel', 65536, 1.90424999467293)]
RefDataBTB = [('BTBCModel6', 'BTBCModel', 64, 1.51480272475844), ('BTBCModel8', 'BTBCModel', 256, 0.209057900418965), ('BTBCModel10', 'BTBCModel', 1024, 0.0117345454469572),
('BTBCModel12', 'BTBCModel', 4096, 0.00125540990359826), ('BTBCModel14', 'BTBCModel', 16384, 0.000732471628510962), ('BTBCModel16', 'BTBCModel', 65536, 0.000732471628510962)]
def ParseBranchListFile(path):
'''Take the path to the list of Questa Sim log files containing the performance counters outputs. File
@ -254,9 +255,9 @@ def BarGraph(seriesDict, xlabelList, BenchPerRow, FileName, IncludeLegend):
fig = plt.subplots(figsize = (EffectiveNumInGroup*BenchPerRow/8, 4))
colors = ['blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'black', 'black', 'black', 'black', 'black', 'black']
for name in seriesDict:
xpos = np.arange(BenchPerRow)
xpos = [x + index*barWidth for x in xpos]
values = seriesDict[name]
xpos = np.arange(len(values))
xpos = [x + index*barWidth for x in xpos]
plt.bar(xpos, Inversion(values), width=barWidth, edgecolor='grey', label=name, color=colors[index%len(colors)])
index += 1
plt.xticks([r + barWidth*(NumberInGroup/2-0.5) for r in range(0, BenchPerRow)], xlabelList)
@ -275,7 +276,7 @@ def SelectPartition(xlabelListBig, seriesDictBig, group, BenchPerRow):
return(xlabelListTrunk, seriesDictTrunk)
def ReportAsGraph(benchmarkDict, bar):
def ReportAsGraph(benchmarkDict, bar, FileName):
def FormatToPlot(currBenchmark):
names = []
sizes = []
@ -329,8 +330,8 @@ def ReportAsGraph(benchmarkDict, bar):
axes.set_xticks(xdata)
axes.set_xticklabels(xdata)
axes.grid(color='b', alpha=0.5, linestyle='dashed', linewidth=0.5)
plt.show()
if(FileName == None): plt.show()
else: plt.savefig(FileName)
# if(not args.summary):
# size = len(benchmarkDict)
@ -389,7 +390,7 @@ def ReportAsGraph(benchmarkDict, bar):
# on each piece.
for row in range(0, math.ceil(NumBenchmarks / BenchPerRow)):
(xlabelListTrunk, seriesDictTrunk) = SelectPartition(xlabelListBig, seriesDictBig, row, BenchPerRow)
FileName = 'barSegment%d.png' % row
FileName = 'barSegment%d.svg' % row
groupLen = len(xlabelListTrunk)
BarGraph(seriesDictTrunk, xlabelListTrunk, groupLen, FileName, (row == 0))
@ -414,7 +415,8 @@ displayMode.add_argument('--text', action='store_const', help='Display in text f
displayMode.add_argument('--table', action='store_const', help='Display in text format only.', default=False, const=True)
displayMode.add_argument('--gui', action='store_const', help='Display in text format only.', default=False, const=True)
displayMode.add_argument('--debug', action='store_const', help='Display in text format only.', default=False, const=True)
parser.add_argument('sources', nargs=1)
parser.add_argument('sources', nargs=1, help='File lists the input Questa transcripts to process.')
parser.add_argument('FileName', metavar='FileName', type=str, nargs='?', help='output graph to file <name>.png If not included outputs to screen.', default=None)
args = parser.parse_args()
@ -454,7 +456,7 @@ if(ReportMode == 'text'):
ReportAsText(benchmarkDict)
if(ReportMode == 'gui'):
ReportAsGraph(benchmarkDict, args.bar)
ReportAsGraph(benchmarkDict, args.bar, args.FileName)
# *** this is only needed of -b (no -s)

View File

@ -1,12 +1,12 @@
gshare6.log gshare 6
gshare8.log gshare 8
gshare10.log gshare 10
gshare12.log gshare 12
gshare14.log gshare 14
gshare16.log gshare 16
twobit6.log twobit 6
twobit8.log twobit 8
twobit10.log twobit 10
twobit12.log twobit 12
twobit14.log twobit 14
twobit16.log twobit 16
../logs/rv32gc_gshare6.log gshare 6
../logs/rv32gc_gshare8.log gshare 8
../logs/rv32gc_gshare10.log gshare 10
../logs/rv32gc_gshare12.log gshare 12
../logs/rv32gc_gshare14.log gshare 14
../logs/rv32gc_gshare16.log gshare 16
../logs/rv32gc_twobit6.log twobit 6
../logs/rv32gc_twobit8.log twobit 8
../logs/rv32gc_twobit10.log twobit 10
../logs/rv32gc_twobit12.log twobit 12
../logs/rv32gc_twobit14.log twobit 14
../logs/rv32gc_twobit16.log twobit 16

View File

@ -1,6 +1,6 @@
btb6.log btb 6
btb8.log btb 8
btb10.log btb 10
btb12.log btb 12
btb14.log btb 14
btb16.log btb 16
../logs/rv32gc_BTB6.log btb 6
../logs/rv32gc_BTB8.log btb 8
../logs/rv32gc_BTB10.log btb 10
../logs/rv32gc_BTB12.log btb 12
../logs/rv32gc_BTB14.log btb 14
../logs/rv32gc_BTB16.log btb 16

View File

@ -1,6 +1,6 @@
class6.log class 6
class8.log class 8
class10.log class 10
class12.log class 12
class14.log class 14
class16.log class 16
../logs/rv32gc_class6.log class 6
../logs/rv32gc_class8.log class 8
../logs/rv32gc_class10.log class 10
../logs/rv32gc_class12.log class 12
../logs/rv32gc_class14.log class 14
../logs/rv32gc_class16.log class 16

View File

@ -1,5 +1,5 @@
ras3.log ras 3
ras4.log ras 4
ras6.log ras 6
ras10.log ras 10
ras16.log ras 16
../logs/rv32gc_RAS3.log ras 3
../logs/rv32gc_RAS4.log ras 4
../logs/rv32gc_RAS6.log ras 6
../logs/rv32gc_RAS10.log ras 10
../logs/rv32gc_RAS16.log ras 16

View File

@ -132,7 +132,7 @@ def main():
# BTB and class size sweep
bpdSize = [6, 8, 10, 12, 14, 16]
for CurrBPSize in bpdSize:
name = 'BTB'+str(CurrBPSize)
name = 'class'+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,

View File

@ -63,10 +63,10 @@ if {$2 eq "buildroot"} {
# start and run simulation
if { $coverage } {
echo "wally-batch buildroot coverage"
vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -G -o testbenchopt +cover=sbecf
vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -o testbenchopt +cover=sbecf
vsim -lib wkdir/work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3691,13286 -fatal 7 -cover
} else {
vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -G -o testbenchopt
vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -o testbenchopt
vsim -lib wkdir/work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3691,13286 -fatal 7
}
@ -76,7 +76,7 @@ if {$2 eq "buildroot"} {
} elseif {$2 eq "buildroot-no-trace"} {
vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583
# start and run simulation
vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -G -G NO_SPOOFING=1 -o testbenchopt
vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -G NO_SPOOFING=1 -o testbenchopt
vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829,13286 -fatal 7
#-- Run the Simulation

13
src/cache/cache.sv vendored
View File

@ -98,8 +98,6 @@ module cache import cvw::*; #(parameter cvw_t P,
logic SelWay;
logic [LINELEN/8-1:0] LineByteMask;
logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1:0] WordOffsetAddr;
logic ZeroCacheLine;
logic [LINELEN-1:0] PreLineWriteData;
genvar index;
/////////////////////////////////////////////////////////////////////////////////////////////
@ -161,11 +159,6 @@ module cache import cvw::*; #(parameter cvw_t P,
/////////////////////////////////////////////////////////////////////////////////////////////
// Write Path
/////////////////////////////////////////////////////////////////////////////////////////////
if(P.ZICBOZ_SUPPORTED) begin : cboz_supported
mux2 #(LINELEN) WriteDataMux(FetchBuffer, '0, ZeroCacheLine, PreLineWriteData);
end else begin
assign PreLineWriteData = FetchBuffer;
end
if(!READ_ONLY_CACHE) begin:WriteSelLogic
logic [LINELEN/8-1:0] DemuxedByteMask, FetchBufferByteSel;
@ -185,14 +178,14 @@ module cache import cvw::*; #(parameter cvw_t P,
// Merge write data into fetched cache line for store miss
for(index = 0; index < LINELEN/8; index++) begin
mux2 #(8) WriteDataMux(.d0(CacheWriteData[(8*index)%WORDLEN+7:(8*index)%WORDLEN]),
.d1(PreLineWriteData[8*index+7:8*index]), .s(FetchBufferByteSel[index] | ZeroCacheLine), .y(LineWriteData[8*index+7:8*index]));
.d1(FetchBuffer[8*index+7:8*index]), .s(FetchBufferByteSel[index] & ~CMOp[3]), .y(LineWriteData[8*index+7:8*index]));
end
assign LineByteMask = SetValid ? '1 : SetDirty ? DemuxedByteMask : '0;
end
else
begin:WriteSelLogic
// No need for this mux if the cache does not handle writes.
assign LineWriteData = PreLineWriteData;
assign LineWriteData = FetchBuffer;
assign LineByteMask = '1;
end
@ -227,7 +220,7 @@ module cache import cvw::*; #(parameter cvw_t P,
.FlushStage, .CacheRW, .Stall,
.CacheHit, .LineDirty, .CacheStall, .CacheCommitted,
.CacheMiss, .CacheAccess, .SelAdr, .SelWay,
.ClearDirty, .SetDirty, .SetValid, .ClearValid, .ZeroCacheLine, .SelWriteback, .SelFlush,
.ClearDirty, .SetDirty, .SetValid, .ClearValid, .SelWriteback, .SelFlush,
.FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst,
.FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer,
.InvalidateCache, .CMOp, .CacheEn, .LRUWriteEn);

View File

@ -58,7 +58,6 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
output logic ClearValid, // Clear the valid bit in the selected way and set
output logic SetDirty, // Set the dirty bit in the selected way and set
output logic ClearDirty, // Clear the dirty bit in the selected way and set
output logic ZeroCacheLine, // Write zeros to all bytes of cacheline
output logic SelWriteback, // Overrides cached tag check to select a specific way and set for writeback
output logic LRUWriteEn, // Update the LRU state
output logic SelFlush, // [0] Use SelAdr, [1] SRAM reads/writes from FlushAdr
@ -130,8 +129,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
STATE_READ_HOLD: if(Stall) NextState = STATE_READ_HOLD;
else NextState = STATE_READY;
// exclusion-tag-start: icache case
STATE_WRITEBACK: if (CacheBusAck & (CMOp[1] | CMOp[2])) NextState = STATE_READ_HOLD;
else if(CacheBusAck & ~CMOp[3]) NextState = STATE_FETCH;
STATE_WRITEBACK: if(CacheBusAck & ~CMOp[3]) NextState = STATE_FETCH;
else if(CacheBusAck) NextState = STATE_READ_HOLD;
else NextState = STATE_WRITEBACK;
// eviction needs a delay as the bus fsm does not correctly handle sending the write command at the same time as getting back the bus ack.
@ -175,8 +173,6 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
assign SelWay = (CurrState == STATE_WRITEBACK & ((~CacheBusAck & ~(CMOp[1] | CMOp[2])) | (P.ZICBOZ_SUPPORTED & CacheBusAck & CMOp[3]))) |
(CurrState == STATE_READY & ((AnyMiss & LineDirty) | (P.ZICBOZ_SUPPORTED & CMOZeroNoEviction & ~CacheHit))) |
(CurrState == STATE_WRITE_LINE);
assign ZeroCacheLine = P.ZICBOZ_SUPPORTED & ((CurrState == STATE_READY & CMOZeroNoEviction) |
(CurrState == STATE_WRITEBACK & (CMOp[3] & CacheBusAck)));
assign SelWriteback = (CurrState == STATE_WRITEBACK & (CMOp[1] | CMOp[2] | ~CacheBusAck)) |
(CurrState == STATE_READY & AnyMiss & LineDirty);
assign SelFlush = (CurrState == STATE_READY & FlushCache) |

16
src/cache/cacheway.sv vendored
View File

@ -65,10 +65,10 @@ module cacheway import cvw::*; #(parameter cvw_t P,
logic [LINELEN-1:0] ReadDataLine;
logic [TAGLEN-1:0] ReadTag;
logic Dirty;
logic SelTag;
logic SelDirty;
logic SelectedWriteWordEn;
logic [LINELEN/8-1:0] FinalByteMask;
logic SetValidEN;
logic SetValidEN, ClearValidEN;
logic SetValidWay;
logic ClearValidWay;
logic SetDirtyWay;
@ -78,7 +78,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
if (!READ_ONLY_CACHE) begin:flushlogic
logic FlushWayEn;
mux2 #(1) seltagmux(VictimWay, FlushWay, SelFlush, SelTag);
mux2 #(1) seltagmux(VictimWay, FlushWay, SelFlush, SelDirty);
// FlushWay is part of a one hot way selection. Must clear it if FlushWay not selected.
// coverage off -item e 1 -fecexprrow 3
@ -86,11 +86,11 @@ module cacheway import cvw::*; #(parameter cvw_t P,
assign FlushWayEn = FlushWay & SelFlush;
assign SelNonHit = FlushWayEn | SelWay;
end else begin:flushlogic // no flush operation for read-only caches.
assign SelTag = VictimWay;
assign SelDirty = VictimWay;
assign SelNonHit = SelWay;
end
mux2 #(1) selectedwaymux(HitWay, SelTag, SelNonHit , SelData);
mux2 #(1) selectedwaymux(HitWay, SelDirty, SelNonHit , SelData);
/////////////////////////////////////////////////////////////////////////////////////////////
// Write Enable demux
@ -102,6 +102,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
assign ClearDirtyWay = ClearDirty & SelData;
assign SelectedWriteWordEn = (SetValidWay | SetDirtyWay) & ~FlushStage; // exclusion-tag: icache SelectedWiteWordEn
assign SetValidEN = SetValidWay & ~FlushStage; // exclusion-tag: cache SetValidEN
assign ClearValidEN = ClearValidWay & ~FlushStage; // exclusion-tag: cache SetValidEN
// If writing the whole line set all write enables to 1, else only set the correct word.
assign FinalByteMask = SetValidWay ? '1 : LineByteMask; // OR
@ -116,7 +117,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
// AND portion of distributed tag multiplexer
assign TagWay = SelData ? ReadTag : '0; // AND part of AOMux
assign DirtyWay = SelTag & Dirty & ValidWay;
assign DirtyWay = SelDirty & Dirty & ValidWay;
assign HitWay = ValidWay & (ReadTag == PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]);
/////////////////////////////////////////////////////////////////////////////////////////////
@ -156,7 +157,8 @@ module cacheway import cvw::*; #(parameter cvw_t P,
if(CacheEn) begin
ValidWay <= #1 ValidBits[CacheSet];
if(InvalidateCache) ValidBits <= #1 '0; // exclusion-tag: dcache invalidateway
else if (SetValidEN | (ClearValidWay & ~FlushStage)) ValidBits[CacheSet] <= #1 SetValidWay;
else if (SetValidEN) ValidBits[CacheSet] <= #1 SetValidWay;
else if (ClearValidEN) ValidBits[CacheSet] <= #1 '0;
end
end

View File

@ -182,7 +182,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
.InstrAccessFaultF, .LoadAccessFaultM(), .StoreAmoAccessFaultM(),
.InstrPageFaultF, .LoadPageFaultM(), .StoreAmoPageFaultM(),
.LoadMisalignedFaultM(), .StoreAmoMisalignedFaultM(),
.UpdateDA(InstrUpdateDAF),
.UpdateDA(InstrUpdateDAF), .CMOp(4'b0),
.AtomicAccessM(1'b0),.ExecuteAccessF(1'b1), .WriteAccessM(1'b0), .ReadAccessM(1'b0),
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW);

View File

@ -148,6 +148,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
logic IgnoreRequestTLB; // On either ITLB or DTLB miss, ignore miss so HPTW can handle
logic IgnoreRequest; // On FlushM or TLB miss ignore memory operation
logic SelDTIM; // Select DTIM rather than bus or D$
logic [P.XLEN-1:0] WriteDataZM;
/////////////////////////////////////////////////////////////////////////////////////////////
// Pipeline for IEUAdr E to M
@ -176,6 +177,12 @@ module lsu import cvw::*; #(parameter cvw_t P) (
assign {SpillStallM, SelStoreDelay} = '0;
end
if(P.ZICBOZ_SUPPORTED) begin : cboz
mux2 #(P.XLEN) writedatacbozmux(WriteDataM, '0, CMOpM[3], WriteDataZM);
end else begin : cboz
assign WriteDataZM = WriteDataM;
end
/////////////////////////////////////////////////////////////////////////////////////////////
// HPTW (only needed if VM supported)
// MMU include PMP and is needed if any privileged supported
@ -187,7 +194,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
.FlushW, .DCacheStallM, .SATP_REGW, .PCSpillF,
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_HADE, .PrivilegeModeW,
.ReadDataM(ReadDataM[P.XLEN-1:0]), // ReadDataM is LLEN, but HPTW only needs XLEN
.WriteDataM, .Funct3M, .LSUFunct3M, .Funct7M, .LSUFunct7M,
.WriteDataM(WriteDataZM), .Funct3M, .LSUFunct3M, .Funct7M, .LSUFunct7M,
.IEUAdrExtM, .PTE, .IHWriteDataM, .PageType, .PreLSURWM, .LSUAtomicM,
.IHAdrM, .HPTWStall, .SelHPTW,
.IgnoreRequestTLB, .LSULoadAccessFaultM, .LSUStoreAmoAccessFaultM,
@ -198,7 +205,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
assign LSUFunct3M = Funct3M;
assign LSUFunct7M = Funct7M;
assign LSUAtomicM = AtomicM;
assign IHWriteDataM = WriteDataM;
assign IHWriteDataM = WriteDataZM;
assign LoadAccessFaultM = LSULoadAccessFaultM;
assign StoreAmoAccessFaultM = LSUStoreAmoAccessFaultM;
assign {HPTWStall, SelHPTW, PTE, PageType, DTLBWriteM, ITLBWriteF, IgnoreRequestTLB} = '0;
@ -221,7 +228,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
logic DisableTranslation; // During HPTW walk or D$ flush disable virtual memory address translation
logic WriteAccessM;
assign DisableTranslation = SelHPTW | FlushDCacheM;
assign WriteAccessM = PreLSURWM[0] | (|CMOpM);
assign WriteAccessM = PreLSURWM[0];
mmu #(.P(P), .TLB_ENTRIES(P.DTLB_ENTRIES), .IMMU(0))
dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_HADE,
.PrivilegeModeW, .DisableTranslation, .VAdr(IHAdrM), .Size(LSUFunct3M[1:0]),
@ -231,7 +238,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
.StoreAmoAccessFaultM(LSUStoreAmoAccessFaultM), .InstrPageFaultF(), .LoadPageFaultM,
.StoreAmoPageFaultM,
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, // *** these faults need to be supressed during hptw.
.UpdateDA(DataUpdateDAM),
.UpdateDA(DataUpdateDAM), .CMOp(CMOpM),
.AtomicAccessM(|LSUAtomicM), .ExecuteAccessF(1'b0),
.WriteAccessM, .ReadAccessM(PreLSURWM[1]),
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW);
@ -295,7 +302,11 @@ module lsu import cvw::*; #(parameter cvw_t P) (
logic CacheStall;
logic [1:0] CacheBusRWTemp;
assign BusRW = ~CacheableM & ~SelDTIM ? LSURWM : '0;
if(P.ZICBOZ_SUPPORTED) begin
assign BusRW = ~CacheableM & ~SelDTIM ? CMOpM[3] ? 2'b01 : LSURWM : '0;
end else begin
assign BusRW = ~CacheableM & ~SelDTIM ? LSURWM : '0;
end
assign CacheableOrFlushCacheM = CacheableM | FlushDCacheM;
assign CacheRWM = CacheableM & ~SelDTIM ? LSURWM : '0;
assign FlushDCache = FlushDCacheM & ~(SelHPTW);

View File

@ -30,18 +30,18 @@
module adrdecs import cvw::*; #(parameter cvw_t P) (
input logic [P.PA_BITS-1:0] PhysicalAddress,
input logic AccessRW, AccessRX, AccessRWX,
input logic AccessRW, AccessRX, AccessRWXZ, AccessRWZ, AccessRXZ,
input logic [1:0] Size,
output logic [11:0] SelRegions
);
localparam logic [3:0] SUPPORTED_SIZE = (P.LLEN == 32 ? 4'b0111 : 4'b1111);
// Determine which region of physical memory (if any) is being accessed
adrdec #(P.PA_BITS) dtimdec(PhysicalAddress, P.DTIM_BASE[P.PA_BITS-1:0], P.DTIM_RANGE[P.PA_BITS-1:0], P.DTIM_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE, SelRegions[11]);
adrdec #(P.PA_BITS) iromdec(PhysicalAddress, P.IROM_BASE[P.PA_BITS-1:0], P.IROM_RANGE[P.PA_BITS-1:0], P.IROM_SUPPORTED, AccessRX, Size, SUPPORTED_SIZE, SelRegions[10]);
adrdec #(P.PA_BITS) ddr4dec(PhysicalAddress, P.EXT_MEM_BASE[P.PA_BITS-1:0], P.EXT_MEM_RANGE[P.PA_BITS-1:0], P.EXT_MEM_SUPPORTED, AccessRWX, Size, SUPPORTED_SIZE, SelRegions[9]);
adrdec #(P.PA_BITS) bootromdec(PhysicalAddress, P.BOOTROM_BASE[P.PA_BITS-1:0], P.BOOTROM_RANGE[P.PA_BITS-1:0], P.BOOTROM_SUPPORTED, AccessRX, Size, SUPPORTED_SIZE, SelRegions[8]);
adrdec #(P.PA_BITS) uncoreramdec(PhysicalAddress, P.UNCORE_RAM_BASE[P.PA_BITS-1:0], P.UNCORE_RAM_RANGE[P.PA_BITS-1:0], P.UNCORE_RAM_SUPPORTED, AccessRWX, Size, SUPPORTED_SIZE, SelRegions[7]);
adrdec #(P.PA_BITS) dtimdec(PhysicalAddress, P.DTIM_BASE[P.PA_BITS-1:0], P.DTIM_RANGE[P.PA_BITS-1:0], P.DTIM_SUPPORTED, AccessRWZ, Size, SUPPORTED_SIZE, SelRegions[11]);
adrdec #(P.PA_BITS) iromdec(PhysicalAddress, P.IROM_BASE[P.PA_BITS-1:0], P.IROM_RANGE[P.PA_BITS-1:0], P.IROM_SUPPORTED, AccessRXZ, Size, SUPPORTED_SIZE, SelRegions[10]);
adrdec #(P.PA_BITS) ddr4dec(PhysicalAddress, P.EXT_MEM_BASE[P.PA_BITS-1:0], P.EXT_MEM_RANGE[P.PA_BITS-1:0], P.EXT_MEM_SUPPORTED, AccessRWXZ, Size, SUPPORTED_SIZE, SelRegions[9]);
adrdec #(P.PA_BITS) bootromdec(PhysicalAddress, P.BOOTROM_BASE[P.PA_BITS-1:0], P.BOOTROM_RANGE[P.PA_BITS-1:0], P.BOOTROM_SUPPORTED, AccessRXZ, Size, SUPPORTED_SIZE, SelRegions[8]);
adrdec #(P.PA_BITS) uncoreramdec(PhysicalAddress, P.UNCORE_RAM_BASE[P.PA_BITS-1:0], P.UNCORE_RAM_RANGE[P.PA_BITS-1:0], P.UNCORE_RAM_SUPPORTED, AccessRWXZ, Size, SUPPORTED_SIZE, SelRegions[7]);
adrdec #(P.PA_BITS) clintdec(PhysicalAddress, P.CLINT_BASE[P.PA_BITS-1:0], P.CLINT_RANGE[P.PA_BITS-1:0], P.CLINT_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE, SelRegions[6]);
adrdec #(P.PA_BITS) gpiodec(PhysicalAddress, P.GPIO_BASE[P.PA_BITS-1:0], P.GPIO_RANGE[P.PA_BITS-1:0], P.GPIO_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[5]);
adrdec #(P.PA_BITS) uartdec(PhysicalAddress, P.UART_BASE[P.PA_BITS-1:0], P.UART_RANGE[P.PA_BITS-1:0], P.UART_SUPPORTED, AccessRW, Size, 4'b0001, SelRegions[4]);

View File

@ -55,6 +55,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
output logic UpdateDA, // page fault due to setting dirty or access bit
output logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM, // misaligned fault sources
// PMA checker signals
input logic [3:0] CMOp, // Cache management instructions
input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, // access type
input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration
input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0] // PMP addresses
@ -106,7 +107,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
// Check physical memory accesses
///////////////////////////////////////////
pmachecker #(P) pmachecker(.PhysicalAddress, .Size,
pmachecker #(P) pmachecker(.PhysicalAddress, .Size, .CMOp,
.AtomicAccessM, .ExecuteAccessF, .WriteAccessM, .ReadAccessM, .PBMemoryType,
.Cacheable, .Idempotent, .SelTIM,
.PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM);

View File

@ -31,6 +31,7 @@
module pmachecker import cvw::*; #(parameter cvw_t P) (
input logic [P.PA_BITS-1:0] PhysicalAddress,
input logic [1:0] Size,
input logic [3:0] CMOp,
input logic AtomicAccessM, // Atomic access
input logic ExecuteAccessF, // Execute access
input logic WriteAccessM, // Write access
@ -43,18 +44,20 @@ module pmachecker import cvw::*; #(parameter cvw_t P) (
);
logic PMAAccessFault;
logic AccessRW, AccessRWX, AccessRX;
logic AccessRW, AccessRWXZ, AccessRX, AccessRWZ, AccessRXZ;
logic [11:0] SelRegions;
logic AtomicAllowed;
logic CacheableRegion, IdempotentRegion;
// Determine what type of access is being made
assign AccessRW = ReadAccessM | WriteAccessM;
assign AccessRWX = ReadAccessM | WriteAccessM | ExecuteAccessF;
assign AccessRWZ = AccessRW | (P.ZICBOM_SUPPORTED & (|CMOp[2:0]));
assign AccessRWXZ = ReadAccessM | WriteAccessM | ExecuteAccessF | (P.ZICBOM_SUPPORTED & (|CMOp[2:0])) | (P.ZICBOZ_SUPPORTED & (CMOp[3]));
assign AccessRX = ReadAccessM | ExecuteAccessF;
assign AccessRXZ = AccessRX | (P.ZICBOM_SUPPORTED & (|CMOp[2:0]));
// Determine which region of physical memory (if any) is being accessed
adrdecs #(P) adrdecs(PhysicalAddress, AccessRW, AccessRX, AccessRWX, Size, SelRegions);
adrdecs #(P) adrdecs(PhysicalAddress, AccessRW, AccessRX, AccessRWXZ, AccessRWZ, AccessRXZ, Size, SelRegions);
// Only non-core RAM/ROM memory regions are cacheable. PBMT can override cachable; NC and IO are uncachable
assign CacheableRegion = SelRegions[9] | SelRegions[8] | SelRegions[7]; // exclusion-tag: unused-cachable
@ -71,7 +74,7 @@ module pmachecker import cvw::*; #(parameter cvw_t P) (
assign SelTIM = SelRegions[11] | SelRegions[10]; // exclusion-tag: unused-idempotent
// Detect access faults
assign PMAAccessFault = (SelRegions[0]) & AccessRWX | AtomicAccessM & ~AtomicAllowed;
assign PMAAccessFault = (SelRegions[0]) & AccessRWXZ | AtomicAccessM & ~AtomicAllowed;
assign PMAInstrAccessFaultF = ExecuteAccessF & PMAAccessFault;
assign PMALoadAccessFaultM = ReadAccessM & PMAAccessFault;
assign PMAStoreAmoAccessFaultM = WriteAccessM & PMAAccessFault;

View File

@ -88,7 +88,7 @@ module uncore import cvw::*; #(parameter cvw_t P)(
// Determine which region of physical memory (if any) is being accessed
// Use a trimmed down portion of the PMA checker - only the address decoders
// Set access types to all 1 as don't cares because the MMU has already done access checking
adrdecs #(P) adrdecs(HADDR, 1'b1, 1'b1, 1'b1, HSIZE[1:0], HSELRegions);
adrdecs #(P) adrdecs(HADDR, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, HSIZE[1:0], HSELRegions);
// unswizzle HSEL signals
assign {HSELDTIM, HSELIROM, HSELEXT, HSELBootRom, HSELRam, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC, HSELEXTSDC, HSELSPI} = HSELRegions[11:1];