From 0c789c2fbda255884ebf0cbdc0189bff51eead73 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Sun, 26 Nov 2023 15:34:40 -0600 Subject: [PATCH 01/12] Fixed subtle bug in the embench makefile if the sim/wkdir directory did not exist. --- benchmarks/embench/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/benchmarks/embench/Makefile b/benchmarks/embench/Makefile index d7a18b7e2..d8fbddae9 100644 --- a/benchmarks/embench/Makefile +++ b/benchmarks/embench/Makefile @@ -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/ @@ -82,4 +83,4 @@ clean: allclean: clean rm -rf $(embench_dir)/logs/ -# riscv64-unknown-elf-gcc -O2 -g -nostartfiles -I/home/harris/riscv-wally/addins/embench-iot/support -I/home/harris/riscv-wally/addins/embench-iot/config/riscv32/boards/ri5cyverilator -I/home/harris/riscv-wally/addins/embench-iot/config/riscv32/chips/generic -I/home/harris/riscv-wally/addins/embench-iot/config/riscv32 -DCPU_MHZ=1 -DWARMUP_HEAT=1 -o main.o /home/harris/riscv-wally/addins/embench-iot/support/main.c \ No newline at end of file +# riscv64-unknown-elf-gcc -O2 -g -nostartfiles -I/home/harris/riscv-wally/addins/embench-iot/support -I/home/harris/riscv-wally/addins/embench-iot/config/riscv32/boards/ri5cyverilator -I/home/harris/riscv-wally/addins/embench-iot/config/riscv32/chips/generic -I/home/harris/riscv-wally/addins/embench-iot/config/riscv32 -DCPU_MHZ=1 -DWARMUP_HEAT=1 -o main.o /home/harris/riscv-wally/addins/embench-iot/support/main.c From e747f97dceb1ba23d45217f660cf508a06fe0e0c Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Sun, 26 Nov 2023 17:30:11 -0600 Subject: [PATCH 02/12] Fixed repeatability issues with the branch predictor simulator results generation. I reran using a clean clone of the repo so this should be working now. --- bin/CModelBTBAccuracy.sh | 8 ++++---- bin/CModelBranchAccuracy.sh | 2 +- bin/parseHPMC.py | 13 +++++++------ 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/bin/CModelBTBAccuracy.sh b/bin/CModelBTBAccuracy.sh index e4a26fb85..479340eb2 100755 --- a/bin/CModelBTBAccuracy.sh +++ b/bin/CModelBTBAccuracy.sh @@ -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 diff --git a/bin/CModelBranchAccuracy.sh b/bin/CModelBranchAccuracy.sh index 1b94f7c9a..8253891bb 100755 --- a/bin/CModelBranchAccuracy.sh +++ b/bin/CModelBranchAccuracy.sh @@ -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 diff --git a/bin/parseHPMC.py b/bin/parseHPMC.py index a11296b3e..f9a961c18 100755 --- a/bin/parseHPMC.py +++ b/bin/parseHPMC.py @@ -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 From 93c356d50dd4953fd3d648df103f9a26209371b9 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Sun, 26 Nov 2023 17:31:23 -0600 Subject: [PATCH 03/12] Added files to ignore file. --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index f0afc3a98..1664b939f 100644 --- a/.gitignore +++ b/.gitignore @@ -180,3 +180,5 @@ sim/branch*.log benchmarks/embench/wally*.json benchmarks/embench/run* sim/cfi.log +sim/cfi/* +sim/branch/* From 3dfca61c3fbf081d1844fa851dbfebfe4cd224e3 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Sun, 26 Nov 2023 22:19:34 -0600 Subject: [PATCH 04/12] Changes to support concurrent simulation of all the branch predictor sweeps. --- bin/parseHPMC.py | 13 +++++++------ sim/bp-results/branch-list.txt | 24 ++++++++++++------------ sim/bp-results/btb-list.txt | 12 ++++++------ sim/bp-results/class-list.txt | 12 ++++++------ sim/bpred-sim.py | 2 +- 5 files changed, 32 insertions(+), 31 deletions(-) diff --git a/bin/parseHPMC.py b/bin/parseHPMC.py index f9a961c18..d76a52d29 100755 --- a/bin/parseHPMC.py +++ b/bin/parseHPMC.py @@ -276,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 = [] @@ -330,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) @@ -390,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)) @@ -415,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 .png If not included outputs to screen.', default=None) args = parser.parse_args() @@ -455,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) diff --git a/sim/bp-results/branch-list.txt b/sim/bp-results/branch-list.txt index c241610d3..956fc9847 100644 --- a/sim/bp-results/branch-list.txt +++ b/sim/bp-results/branch-list.txt @@ -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 diff --git a/sim/bp-results/btb-list.txt b/sim/bp-results/btb-list.txt index 741efdf24..30811459e 100644 --- a/sim/bp-results/btb-list.txt +++ b/sim/bp-results/btb-list.txt @@ -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 diff --git a/sim/bp-results/class-list.txt b/sim/bp-results/class-list.txt index 0d24aa6ee..3926af969 100644 --- a/sim/bp-results/class-list.txt +++ b/sim/bp-results/class-list.txt @@ -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 diff --git a/sim/bpred-sim.py b/sim/bpred-sim.py index 60af41298..c04b9bd51 100755 --- a/sim/bpred-sim.py +++ b/sim/bpred-sim.py @@ -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, From 7b0e29c9f7f1af7dffcb48e83cc0efd4b3a81e62 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Sun, 26 Nov 2023 23:13:14 -0600 Subject: [PATCH 05/12] Fixed subtle bug in branch prediction post processing script. --- bin/parseHPMC.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/parseHPMC.py b/bin/parseHPMC.py index d76a52d29..7e8eb7cde 100755 --- a/bin/parseHPMC.py +++ b/bin/parseHPMC.py @@ -255,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) From 35a7b2bd24184100a9c74612509c273d6c2cac9f Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 27 Nov 2023 00:35:22 -0600 Subject: [PATCH 06/12] Last little hickups out of the branch predictor results parsing. --- sim/bp-results/ras-list.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sim/bp-results/ras-list.txt b/sim/bp-results/ras-list.txt index b3e273a3d..c7628ffaa 100644 --- a/sim/bp-results/ras-list.txt +++ b/sim/bp-results/ras-list.txt @@ -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 From d918791a6078deeb98a1a21eef667bbc05812993 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 27 Nov 2023 01:26:49 -0600 Subject: [PATCH 07/12] Fixed bug in the wally do script. --- sim/wally-batch.do | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sim/wally-batch.do b/sim/wally-batch.do index df34aa0b3..b117e1691 100644 --- a/sim/wally-batch.do +++ b/sim/wally-batch.do @@ -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 From d7ef490c125c385130b8f0dab6a22142122e8289 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 27 Nov 2023 01:27:09 -0600 Subject: [PATCH 08/12] Sutble bug in the cacheway logic for cacheline invalidation. --- src/cache/cacheway.sv | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cache/cacheway.sv b/src/cache/cacheway.sv index 9fb836e93..67f4f5a74 100644 --- a/src/cache/cacheway.sv +++ b/src/cache/cacheway.sv @@ -68,7 +68,7 @@ module cacheway import cvw::*; #(parameter cvw_t P, logic SelTag; logic SelectedWriteWordEn; logic [LINELEN/8-1:0] FinalByteMask; - logic SetValidEN; + logic SetValidEN, ClearValidEN; logic SetValidWay; logic ClearValidWay; logic SetDirtyWay; @@ -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 @@ -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 From c3da4c3c31fa133567f31e7ca99766728d0fcb7f Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 27 Nov 2023 12:56:11 -0600 Subject: [PATCH 09/12] Clarified names in cacheway. --- src/cache/cacheway.sv | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cache/cacheway.sv b/src/cache/cacheway.sv index 67f4f5a74..382d9ae6d 100644 --- a/src/cache/cacheway.sv +++ b/src/cache/cacheway.sv @@ -65,7 +65,7 @@ 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, ClearValidEN; @@ -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 @@ -117,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]); ///////////////////////////////////////////////////////////////////////////////////////////// From 08549446ef576c5bee9143a1ef18a2bb7a01e49b Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 27 Nov 2023 13:13:36 -0600 Subject: [PATCH 10/12] Reduced cache fsm complexity. --- src/cache/cachefsm.sv | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cache/cachefsm.sv b/src/cache/cachefsm.sv index 8a11dd735..0e07793d6 100644 --- a/src/cache/cachefsm.sv +++ b/src/cache/cachefsm.sv @@ -130,8 +130,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. From 337903d8dd7019f7201e5e4c615bc914015990fc Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 27 Nov 2023 14:59:42 -0600 Subject: [PATCH 11/12] More cache simplifications. --- src/cache/cache.sv | 13 +++---------- src/cache/cachefsm.sv | 3 --- src/lsu/lsu.sv | 13 ++++++++++--- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/cache/cache.sv b/src/cache/cache.sv index 4701fc4c7..c527f0eae 100644 --- a/src/cache/cache.sv +++ b/src/cache/cache.sv @@ -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); diff --git a/src/cache/cachefsm.sv b/src/cache/cachefsm.sv index 0e07793d6..e7e5e0306 100644 --- a/src/cache/cachefsm.sv +++ b/src/cache/cachefsm.sv @@ -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 @@ -174,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) | diff --git a/src/lsu/lsu.sv b/src/lsu/lsu.sv index 5c21d7ecd..d82c9c02d 100644 --- a/src/lsu/lsu.sv +++ b/src/lsu/lsu.sv @@ -148,7 +148,8 @@ 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 // Zero-extend address to 34 bits for XLEN=32 @@ -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; From beb95dd592431023408113658263a6613c9b3333 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 27 Nov 2023 17:44:11 -0600 Subject: [PATCH 12/12] Modified the pmachecker to correctly check the permissions for cmo instructions. However this isn't fully tested. --- src/ifu/ifu.sv | 2 +- src/lsu/lsu.sv | 12 ++++++++---- src/mmu/adrdecs.sv | 12 ++++++------ src/mmu/mmu.sv | 3 ++- src/mmu/pmachecker.sv | 11 +++++++---- src/uncore/uncore.sv | 2 +- 6 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index 831d9e6bb..7d61bd4db 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -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); diff --git a/src/lsu/lsu.sv b/src/lsu/lsu.sv index d82c9c02d..2bb604d39 100644 --- a/src/lsu/lsu.sv +++ b/src/lsu/lsu.sv @@ -228,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]), @@ -238,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); @@ -301,8 +301,12 @@ module lsu import cvw::*; #(parameter cvw_t P) ( logic FlushDCache; // Suppress d cache flush if there is an ITLB miss. 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); diff --git a/src/mmu/adrdecs.sv b/src/mmu/adrdecs.sv index 3ee9c23d5..69b3a8c1d 100644 --- a/src/mmu/adrdecs.sv +++ b/src/mmu/adrdecs.sv @@ -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]); diff --git a/src/mmu/mmu.sv b/src/mmu/mmu.sv index a497b6da7..16016ac47 100644 --- a/src/mmu/mmu.sv +++ b/src/mmu/mmu.sv @@ -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); diff --git a/src/mmu/pmachecker.sv b/src/mmu/pmachecker.sv index 7aa20fc2f..1ccf6501c 100644 --- a/src/mmu/pmachecker.sv +++ b/src/mmu/pmachecker.sv @@ -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; diff --git a/src/uncore/uncore.sv b/src/uncore/uncore.sv index 60d197f78..ee93c2904 100644 --- a/src/uncore/uncore.sv +++ b/src/uncore/uncore.sv @@ -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];