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/wally*.json
benchmarks/embench/run* benchmarks/embench/run*
sim/cfi.log 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 # launches modelsim to simulate tests on wally
modelsim_run: modelsim_run:
mkdir -p ../../sim/wkdir
(cd ../../sim/ && vsim -c -do "do wally-batch.do rv32gc embench") (cd ../../sim/ && vsim -c -do "do wally-batch.do rv32gc embench")
cd ../../benchmarks/embench/ cd ../../benchmarks/embench/

View File

@ -40,18 +40,18 @@ do
lines=`sim_bp gshare 16 16 $Size 1 $File | tail -5` lines=`sim_bp gshare 16 16 $Size 1 $File | tail -5`
Total=`echo "$lines" | head -1 | awk '{print $5}'` Total=`echo "$lines" | head -1 | awk '{print $5}'`
Miss=`echo "$lines" | tail -2 | head -1 | awk '{print $8}'` 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") BMDRArray+=("$BMDR")
if [ $Miss -eq 0 ]; then if [ $Miss -eq 0 ]; then
Product=`echo "scale=200; $Product / $Total" | bc -l` Product=`echo "scale=200; $Product * 100 / $Total" | bc -l`
else else
Product=`echo "scale=200; $Product * $Miss / $Total" | bc -l` Product=`echo "scale=200; $Product * $BMDR" | bc -l`
fi fi
Count=$((Count+1)) Count=$((Count+1))
done done
# with such long precision bc outputs onto multiple lines # with such long precision bc outputs onto multiple lines
# must remove \n and \ from string # must remove \n and \ from string
Product=`echo "$Product" | tr -d '\n' | tr -d '\\\'` 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" echo "$Pred$Size $GeoMean"
done done

View File

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

View File

@ -32,12 +32,13 @@ import math
import numpy as np import numpy as np
import argparse 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), RefDataBP = [('twobitCModel6', 'twobitCModel', 64, 10.0060297551637), ('twobitCModel8', 'twobitCModel', 256, 8.4320392215602), ('twobitCModel10', 'twobitCModel', 1024, 7.29493318805151),
('gshareCModel6', 'gshareCModel', 64, 10.6602835418646), ('gshareCModel8', 'gshareCModel', 256, 8.38384710559667), ('gshareCModel10', 'gshareCModel', 1024, 6.36847432155534), ('twobitCModel12', 'twobitCModel', 4096, 6.84739616147794), ('twobitCModel14', 'twobitCModel', 16384, 5.68432926870082), ('twobitCModel16', 'twobitCModel', 65536, 5.68432926870082),
('gshareCModel12', 'gshareCModel', 4096, 3.91108491151983), ('gshareCModel14', 'gshareCModel', 16384, 2.83926519215395), ('gshareCModel16', 'gshareCModel', 65536, .60213659066941)] ('gshareCModel6', 'gshareCModel', 64, 11.4737703417701), ('gshareCModel8', 'gshareCModel', 256, 8.52341470761974), ('gshareCModel10', 'gshareCModel', 1024, 6.32975690693015),
RefDataBTB = [('BTBCModel6', 'BTBCModel', 64, 1.11806778745097), ('BTBCModel8', 'BTBCModel', 256, 0.183833943219956), ('BTBCModel10', 'BTBCModel', 1024, 0.0109271020749376), ('gshareCModel12', 'gshareCModel', 4096, 4.55424632377659), ('gshareCModel14', 'gshareCModel', 16384, 3.54251547725509), ('gshareCModel16', 'gshareCModel', 65536, 1.90424999467293)]
('BTBCModel12', 'BTBCModel', 4096, 0.00437600802791213), ('BTBCModel14', 'BTBCModel', 16384, 0.00188756234204305), ('BTBCModel16', 'BTBCModel', 65536, 0.00188756234204305)] 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): def ParseBranchListFile(path):
'''Take the path to the list of Questa Sim log files containing the performance counters outputs. File '''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)) fig = plt.subplots(figsize = (EffectiveNumInGroup*BenchPerRow/8, 4))
colors = ['blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'black', 'black', 'black', 'black', 'black', 'black'] colors = ['blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'black', 'black', 'black', 'black', 'black', 'black']
for name in seriesDict: for name in seriesDict:
xpos = np.arange(BenchPerRow)
xpos = [x + index*barWidth for x in xpos]
values = seriesDict[name] 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)]) plt.bar(xpos, Inversion(values), width=barWidth, edgecolor='grey', label=name, color=colors[index%len(colors)])
index += 1 index += 1
plt.xticks([r + barWidth*(NumberInGroup/2-0.5) for r in range(0, BenchPerRow)], xlabelList) 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) return(xlabelListTrunk, seriesDictTrunk)
def ReportAsGraph(benchmarkDict, bar): def ReportAsGraph(benchmarkDict, bar, FileName):
def FormatToPlot(currBenchmark): def FormatToPlot(currBenchmark):
names = [] names = []
sizes = [] sizes = []
@ -329,8 +330,8 @@ def ReportAsGraph(benchmarkDict, bar):
axes.set_xticks(xdata) axes.set_xticks(xdata)
axes.set_xticklabels(xdata) axes.set_xticklabels(xdata)
axes.grid(color='b', alpha=0.5, linestyle='dashed', linewidth=0.5) 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): # if(not args.summary):
# size = len(benchmarkDict) # size = len(benchmarkDict)
@ -389,7 +390,7 @@ def ReportAsGraph(benchmarkDict, bar):
# on each piece. # on each piece.
for row in range(0, math.ceil(NumBenchmarks / BenchPerRow)): for row in range(0, math.ceil(NumBenchmarks / BenchPerRow)):
(xlabelListTrunk, seriesDictTrunk) = SelectPartition(xlabelListBig, seriesDictBig, row, BenchPerRow) (xlabelListTrunk, seriesDictTrunk) = SelectPartition(xlabelListBig, seriesDictBig, row, BenchPerRow)
FileName = 'barSegment%d.png' % row FileName = 'barSegment%d.svg' % row
groupLen = len(xlabelListTrunk) groupLen = len(xlabelListTrunk)
BarGraph(seriesDictTrunk, xlabelListTrunk, groupLen, FileName, (row == 0)) 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('--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('--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) 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() args = parser.parse_args()
@ -454,7 +456,7 @@ if(ReportMode == 'text'):
ReportAsText(benchmarkDict) ReportAsText(benchmarkDict)
if(ReportMode == 'gui'): if(ReportMode == 'gui'):
ReportAsGraph(benchmarkDict, args.bar) ReportAsGraph(benchmarkDict, args.bar, args.FileName)
# *** this is only needed of -b (no -s) # *** this is only needed of -b (no -s)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -63,10 +63,10 @@ if {$2 eq "buildroot"} {
# start and run simulation # start and run simulation
if { $coverage } { if { $coverage } {
echo "wally-batch buildroot 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 vsim -lib wkdir/work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3691,13286 -fatal 7 -cover
} else { } 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 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"} { } 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 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 # 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 vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829,13286 -fatal 7
#-- Run the Simulation #-- 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 SelWay;
logic [LINELEN/8-1:0] LineByteMask; logic [LINELEN/8-1:0] LineByteMask;
logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1:0] WordOffsetAddr; logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1:0] WordOffsetAddr;
logic ZeroCacheLine;
logic [LINELEN-1:0] PreLineWriteData;
genvar index; genvar index;
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
@ -161,11 +159,6 @@ module cache import cvw::*; #(parameter cvw_t P,
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Write Path // 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 if(!READ_ONLY_CACHE) begin:WriteSelLogic
logic [LINELEN/8-1:0] DemuxedByteMask, FetchBufferByteSel; 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 // Merge write data into fetched cache line for store miss
for(index = 0; index < LINELEN/8; index++) begin for(index = 0; index < LINELEN/8; index++) begin
mux2 #(8) WriteDataMux(.d0(CacheWriteData[(8*index)%WORDLEN+7:(8*index)%WORDLEN]), 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 end
assign LineByteMask = SetValid ? '1 : SetDirty ? DemuxedByteMask : '0; assign LineByteMask = SetValid ? '1 : SetDirty ? DemuxedByteMask : '0;
end end
else else
begin:WriteSelLogic begin:WriteSelLogic
// No need for this mux if the cache does not handle writes. // No need for this mux if the cache does not handle writes.
assign LineWriteData = PreLineWriteData; assign LineWriteData = FetchBuffer;
assign LineByteMask = '1; assign LineByteMask = '1;
end end
@ -227,7 +220,7 @@ module cache import cvw::*; #(parameter cvw_t P,
.FlushStage, .CacheRW, .Stall, .FlushStage, .CacheRW, .Stall,
.CacheHit, .LineDirty, .CacheStall, .CacheCommitted, .CacheHit, .LineDirty, .CacheStall, .CacheCommitted,
.CacheMiss, .CacheAccess, .SelAdr, .SelWay, .CacheMiss, .CacheAccess, .SelAdr, .SelWay,
.ClearDirty, .SetDirty, .SetValid, .ClearValid, .ZeroCacheLine, .SelWriteback, .SelFlush, .ClearDirty, .SetDirty, .SetValid, .ClearValid, .SelWriteback, .SelFlush,
.FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst, .FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst,
.FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer, .FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer,
.InvalidateCache, .CMOp, .CacheEn, .LRUWriteEn); .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 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 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 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 SelWriteback, // Overrides cached tag check to select a specific way and set for writeback
output logic LRUWriteEn, // Update the LRU state output logic LRUWriteEn, // Update the LRU state
output logic SelFlush, // [0] Use SelAdr, [1] SRAM reads/writes from FlushAdr 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; STATE_READ_HOLD: if(Stall) NextState = STATE_READ_HOLD;
else NextState = STATE_READY; else NextState = STATE_READY;
// exclusion-tag-start: icache case // exclusion-tag-start: icache case
STATE_WRITEBACK: if (CacheBusAck & (CMOp[1] | CMOp[2])) NextState = STATE_READ_HOLD; STATE_WRITEBACK: if(CacheBusAck & ~CMOp[3]) NextState = STATE_FETCH;
else if(CacheBusAck & ~CMOp[3]) NextState = STATE_FETCH;
else if(CacheBusAck) NextState = STATE_READ_HOLD; else if(CacheBusAck) NextState = STATE_READ_HOLD;
else NextState = STATE_WRITEBACK; 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. // 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]))) | 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_READY & ((AnyMiss & LineDirty) | (P.ZICBOZ_SUPPORTED & CMOZeroNoEviction & ~CacheHit))) |
(CurrState == STATE_WRITE_LINE); (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)) | assign SelWriteback = (CurrState == STATE_WRITEBACK & (CMOp[1] | CMOp[2] | ~CacheBusAck)) |
(CurrState == STATE_READY & AnyMiss & LineDirty); (CurrState == STATE_READY & AnyMiss & LineDirty);
assign SelFlush = (CurrState == STATE_READY & FlushCache) | 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 [LINELEN-1:0] ReadDataLine;
logic [TAGLEN-1:0] ReadTag; logic [TAGLEN-1:0] ReadTag;
logic Dirty; logic Dirty;
logic SelTag; logic SelDirty;
logic SelectedWriteWordEn; logic SelectedWriteWordEn;
logic [LINELEN/8-1:0] FinalByteMask; logic [LINELEN/8-1:0] FinalByteMask;
logic SetValidEN; logic SetValidEN, ClearValidEN;
logic SetValidWay; logic SetValidWay;
logic ClearValidWay; logic ClearValidWay;
logic SetDirtyWay; logic SetDirtyWay;
@ -78,7 +78,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
if (!READ_ONLY_CACHE) begin:flushlogic if (!READ_ONLY_CACHE) begin:flushlogic
logic FlushWayEn; 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. // FlushWay is part of a one hot way selection. Must clear it if FlushWay not selected.
// coverage off -item e 1 -fecexprrow 3 // coverage off -item e 1 -fecexprrow 3
@ -86,11 +86,11 @@ module cacheway import cvw::*; #(parameter cvw_t P,
assign FlushWayEn = FlushWay & SelFlush; assign FlushWayEn = FlushWay & SelFlush;
assign SelNonHit = FlushWayEn | SelWay; assign SelNonHit = FlushWayEn | SelWay;
end else begin:flushlogic // no flush operation for read-only caches. end else begin:flushlogic // no flush operation for read-only caches.
assign SelTag = VictimWay; assign SelDirty = VictimWay;
assign SelNonHit = SelWay; assign SelNonHit = SelWay;
end end
mux2 #(1) selectedwaymux(HitWay, SelTag, SelNonHit , SelData); mux2 #(1) selectedwaymux(HitWay, SelDirty, SelNonHit , SelData);
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Write Enable demux // Write Enable demux
@ -102,6 +102,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
assign ClearDirtyWay = ClearDirty & SelData; assign ClearDirtyWay = ClearDirty & SelData;
assign SelectedWriteWordEn = (SetValidWay | SetDirtyWay) & ~FlushStage; // exclusion-tag: icache SelectedWiteWordEn assign SelectedWriteWordEn = (SetValidWay | SetDirtyWay) & ~FlushStage; // exclusion-tag: icache SelectedWiteWordEn
assign SetValidEN = SetValidWay & ~FlushStage; // exclusion-tag: cache SetValidEN 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. // If writing the whole line set all write enables to 1, else only set the correct word.
assign FinalByteMask = SetValidWay ? '1 : LineByteMask; // OR assign FinalByteMask = SetValidWay ? '1 : LineByteMask; // OR
@ -116,7 +117,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
// AND portion of distributed tag multiplexer // AND portion of distributed tag multiplexer
assign TagWay = SelData ? ReadTag : '0; // AND part of AOMux 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]); 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 if(CacheEn) begin
ValidWay <= #1 ValidBits[CacheSet]; ValidWay <= #1 ValidBits[CacheSet];
if(InvalidateCache) ValidBits <= #1 '0; // exclusion-tag: dcache invalidateway 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
end end

View File

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

View File

@ -30,18 +30,18 @@
module adrdecs import cvw::*; #(parameter cvw_t P) ( module adrdecs import cvw::*; #(parameter cvw_t P) (
input logic [P.PA_BITS-1:0] PhysicalAddress, 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, input logic [1:0] Size,
output logic [11:0] SelRegions output logic [11:0] SelRegions
); );
localparam logic [3:0] SUPPORTED_SIZE = (P.LLEN == 32 ? 4'b0111 : 4'b1111); localparam logic [3:0] SUPPORTED_SIZE = (P.LLEN == 32 ? 4'b0111 : 4'b1111);
// Determine which region of physical memory (if any) is being accessed // 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) 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, AccessRX, Size, SUPPORTED_SIZE, SelRegions[10]); 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, AccessRWX, Size, SUPPORTED_SIZE, SelRegions[9]); 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, AccessRX, Size, SUPPORTED_SIZE, SelRegions[8]); 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, AccessRWX, Size, SUPPORTED_SIZE, SelRegions[7]); 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) 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) 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]); 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 UpdateDA, // page fault due to setting dirty or access bit
output logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM, // misaligned fault sources output logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM, // misaligned fault sources
// PMA checker signals // PMA checker signals
input logic [3:0] CMOp, // Cache management instructions
input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, // access type 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 [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 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 // Check physical memory accesses
/////////////////////////////////////////// ///////////////////////////////////////////
pmachecker #(P) pmachecker(.PhysicalAddress, .Size, pmachecker #(P) pmachecker(.PhysicalAddress, .Size, .CMOp,
.AtomicAccessM, .ExecuteAccessF, .WriteAccessM, .ReadAccessM, .PBMemoryType, .AtomicAccessM, .ExecuteAccessF, .WriteAccessM, .ReadAccessM, .PBMemoryType,
.Cacheable, .Idempotent, .SelTIM, .Cacheable, .Idempotent, .SelTIM,
.PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM); .PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM);

View File

@ -31,6 +31,7 @@
module pmachecker import cvw::*; #(parameter cvw_t P) ( module pmachecker import cvw::*; #(parameter cvw_t P) (
input logic [P.PA_BITS-1:0] PhysicalAddress, input logic [P.PA_BITS-1:0] PhysicalAddress,
input logic [1:0] Size, input logic [1:0] Size,
input logic [3:0] CMOp,
input logic AtomicAccessM, // Atomic access input logic AtomicAccessM, // Atomic access
input logic ExecuteAccessF, // Execute access input logic ExecuteAccessF, // Execute access
input logic WriteAccessM, // Write access input logic WriteAccessM, // Write access
@ -43,18 +44,20 @@ module pmachecker import cvw::*; #(parameter cvw_t P) (
); );
logic PMAAccessFault; logic PMAAccessFault;
logic AccessRW, AccessRWX, AccessRX; logic AccessRW, AccessRWXZ, AccessRX, AccessRWZ, AccessRXZ;
logic [11:0] SelRegions; logic [11:0] SelRegions;
logic AtomicAllowed; logic AtomicAllowed;
logic CacheableRegion, IdempotentRegion; logic CacheableRegion, IdempotentRegion;
// Determine what type of access is being made // Determine what type of access is being made
assign AccessRW = ReadAccessM | WriteAccessM; 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 AccessRX = ReadAccessM | ExecuteAccessF;
assign AccessRXZ = AccessRX | (P.ZICBOM_SUPPORTED & (|CMOp[2:0]));
// Determine which region of physical memory (if any) is being accessed // 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 // 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 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 assign SelTIM = SelRegions[11] | SelRegions[10]; // exclusion-tag: unused-idempotent
// Detect access faults // Detect access faults
assign PMAAccessFault = (SelRegions[0]) & AccessRWX | AtomicAccessM & ~AtomicAllowed; assign PMAAccessFault = (SelRegions[0]) & AccessRWXZ | AtomicAccessM & ~AtomicAllowed;
assign PMAInstrAccessFaultF = ExecuteAccessF & PMAAccessFault; assign PMAInstrAccessFaultF = ExecuteAccessF & PMAAccessFault;
assign PMALoadAccessFaultM = ReadAccessM & PMAAccessFault; assign PMALoadAccessFaultM = ReadAccessM & PMAAccessFault;
assign PMAStoreAmoAccessFaultM = WriteAccessM & 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 // Determine which region of physical memory (if any) is being accessed
// Use a trimmed down portion of the PMA checker - only the address decoders // 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 // 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 // unswizzle HSEL signals
assign {HSELDTIM, HSELIROM, HSELEXT, HSELBootRom, HSELRam, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC, HSELEXTSDC, HSELSPI} = HSELRegions[11:1]; assign {HSELDTIM, HSELIROM, HSELEXT, HSELBootRom, HSELRam, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC, HSELEXTSDC, HSELSPI} = HSELRegions[11:1];