diff --git a/bin/CModelBranchAccuracy.sh b/bin/CModelBranchAccuracy.sh index 2fb7b164a..5e0e7bc01 100755 --- a/bin/CModelBranchAccuracy.sh +++ b/bin/CModelBranchAccuracy.sh @@ -31,7 +31,7 @@ Directory="$1" Files="$1/*.log" -for Pred in "bimodal" "gshare" +for Pred in "bimodal" "gshare" "local4" "local8" "local10" do for Size in $(seq 6 2 16) do @@ -39,6 +39,15 @@ do SizeString="$Size $Size 18 1" elif [ $Pred = "bimodal" ]; then SizeString="$Size 18 1" + elif [ $Pred = "local4" ]; then + SizeString="$Size 4 18 1" + Pred="yehpatt" + elif [ $Pred = "local8" ]; then + SizeString="$Size 8 18 1" + Pred="yehpatt" + elif [ $Pred = "local10" ]; then + SizeString="$Size 10 18 1" + Pred="yehpatt" fi Product=1.0 diff --git a/bin/parseHPMC.py b/bin/parseHPMC.py index 73535c430..fd4efe20e 100755 --- a/bin/parseHPMC.py +++ b/bin/parseHPMC.py @@ -34,12 +34,12 @@ import numpy as np import argparse -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)] +RefDataBP = [('twobitCModel6', 'twobitCModel', 64, 128, 10.0060297551637), ('twobitCModel8', 'twobitCModel', 256, 512, 8.4320392215602), ('twobitCModel10', 'twobitCModel', 1024, 2048, 7.29493318805151), + ('twobitCModel12', 'twobitCModel', 4096, 8192, 6.84739616147794), ('twobitCModel14', 'twobitCModel', 16384, 32768, 5.68432926870082), ('twobitCModel16', 'twobitCModel', 65536, 131072, 5.68432926870082), + ('gshareCModel6', 'gshareCModel', 64, 128, 11.4737703417701), ('gshareCModel8', 'gshareCModel', 256, 512, 8.52341470761974), ('gshareCModel10', 'gshareCModel', 1024, 2048, 6.32975690693015), + ('gshareCModel12', 'gshareCModel', 4096, 8192, 4.55424632377659), ('gshareCModel14', 'gshareCModel', 16384, 32768, 3.54251547725509), ('gshareCModel16', 'gshareCModel', 65536, 131072, 1.90424999467293)] +RefDataBTB = [('BTBCModel6', 'BTBCModel', 64, 128, 1.51480272475844), ('BTBCModel8', 'BTBCModel', 256, 512, 0.209057900418965), ('BTBCModel10', 'BTBCModel', 1024, 2048, 0.0117345454469572), + ('BTBCModel12', 'BTBCModel', 4096, 8192, 0.00125540990359826), ('BTBCModel14', 'BTBCModel', 16384, 32768, 0.000732471628510962), ('BTBCModel16', 'BTBCModel', 65536, 131072, 0.000732471628510962)] def ParseBranchListFile(path): '''Take the path to the list of Questa Sim log files containing the performance counters outputs. File @@ -120,25 +120,45 @@ def ComputeGeometricAverage(benchmarks): benchmarks.append(('Mean', '', AllAve)) def GenerateName(predictorType, predictorParams): - if(predictorType == 'gshare' or predictorType == 'twobit' or predictorType == 'btb' or predictorType == 'class' or predictorType == 'ras'): + if(predictorType == 'gshare' or predictorType == 'twobit' or predictorType == 'btb' or predictorType == 'class' or predictorType == 'ras' or predictorType == 'global'): return predictorType + predictorParams[0] - elif(predictorParams == 'local'): + elif(predictorType == 'local'): return predictorType + predictorParams[0] + '_' + predictorParams[1] else: print(f'Error unsupported predictor type {predictorType}') sys.exit(-1) +def GenerateDisplayName(predictorType, predictorParams): + if(predictorType == 'gshare' or predictorType == 'twobit' or predictorType == 'btb' or predictorType == 'class' or predictorType == 'ras' or predictorType == 'global'): + return predictorType + elif(predictorType == 'local'): + return predictorType + predictorParams[0] + else: + print(f'Error unsupported predictor type {predictorType}') + sys.exit(-1) + def ComputePredNumEntries(predictorType, predictorParams): - if(predictorType == 'gshare' or predictorType == 'twobit' or predictorType == 'btb' or predictorType == 'class'): + if(predictorType == 'gshare' or predictorType == 'twobit' or predictorType == 'btb' or predictorType == 'class' or predictorType == 'global'): return 2**int(predictorParams[0]) elif(predictorType == 'ras'): return int(predictorParams[0]) - elif(predictorParams == 'local'): + elif(predictorType == 'local'): return 2**int(predictorParams[0]) * int(predictorParams[1]) + 2**int(predictorParams[1]) else: print(f'Error unsupported predictor type {predictorType}') sys.exit(-1) +def ComputePredSize(predictorType, predictorParams): + if(predictorType == 'gshare' or predictorType == 'twobit' or predictorType == 'btb' or predictorType == 'class' or predictorType == 'global'): + return 2*2**int(predictorParams[0]) + elif(predictorType == 'ras'): + return int(predictorParams[0]) + elif(predictorType == 'local'): + return 2**int(predictorParams[0]) * int(predictorParams[1]) + 2*2**int(predictorParams[1]) + else: + print(f'Error unsupported predictor type {predictorType}') + sys.exit(-1) + def BuildDataBase(predictorLogs): # Once done with the following loop, performanceCounterList will contain the predictor type and size along with the # raw performance counter data and the processed data on a per benchmark basis. It also includes the geometric mean. @@ -164,16 +184,16 @@ def BuildDataBase(predictorLogs): ComputeStats(performanceCounters) ComputeGeometricAverage(performanceCounters) #print(performanceCounters) - performanceCounterList.append([GenerateName(predictorType, predictorParams), predictorType, performanceCounters, ComputePredNumEntries(predictorType, predictorParams)]) + performanceCounterList.append([GenerateName(predictorType, predictorParams), GenerateDisplayName(predictorType, predictorParams), performanceCounters, ComputePredNumEntries(predictorType, predictorParams), ComputePredSize(predictorType, predictorParams)]) return performanceCounterList def ReorderDataBase(performanceCounterList): # Reorder the data so the benchmark name comes first, then the branch predictor configuration benchmarkFirstList = [] - for (predictorName, predictorPrefixName, benchmarks, entries) in performanceCounterList: + for (predictorName, predictorPrefixName, benchmarks, entries, size) in performanceCounterList: for benchmark in benchmarks: (nameString, opt, dataDict) = benchmark - benchmarkFirstList.append((nameString, opt, predictorName, predictorPrefixName, entries, dataDict)) + benchmarkFirstList.append((nameString, opt, predictorName, predictorPrefixName, entries, size, dataDict)) return benchmarkFirstList def ExtractSelectedData(benchmarkFirstList): @@ -181,7 +201,8 @@ def ExtractSelectedData(benchmarkFirstList): # namestring + opt, config benchmarkDict = { } for benchmark in benchmarkFirstList: - (name, opt, config, prefixName, entries, dataDict) = benchmark + (name, opt, config, prefixName, entries, size, dataDict) = benchmark + #print(f'config = {config}, prefixName = {prefixName} entries = {entries}') # use this code to distinguish speed opt and size opt. #if opt == 'bd_speedopt_speed': NewName = name+'Sp' #elif opt == 'bd_sizeopt_speed': NewName = name+'Sz' @@ -190,18 +211,19 @@ def ExtractSelectedData(benchmarkFirstList): #print(NewName) #NewName = name+'_'+opt if NewName in benchmarkDict: - benchmarkDict[NewName].append((config, prefixName, entries, dataDict[ReportPredictorType])) + benchmarkDict[NewName].append((config, prefixName, entries, size, dataDict[ReportPredictorType])) else: - benchmarkDict[NewName] = [(config, prefixName, entries, dataDict[ReportPredictorType])] + benchmarkDict[NewName] = [(config, prefixName, entries, size, dataDict[ReportPredictorType])] return benchmarkDict def ReportAsTable(benchmarkDict): refLine = benchmarkDict['Mean'] FirstLine = [] SecondLine = [] - for (name, typ, size, val) in refLine: + for Elements in refLine: + (name, typ, size, entries, val) = Elements FirstLine.append(name) - SecondLine.append(size) + SecondLine.append(entries if not args.size else size) sys.stdout.write('benchmark\t\t') for name in FirstLine: @@ -216,7 +238,7 @@ def ReportAsTable(benchmarkDict): if(args.summary): sys.stdout.write('Mean\t\t\t') - for (name, typ, size, val) in refLine: + for (name, typ, size, entries, val) in refLine: sys.stdout.write('%0.2f\t\t' % (val if not args.invert else 100 - val)) sys.stdout.write('\n') @@ -226,7 +248,7 @@ def ReportAsTable(benchmarkDict): if(length < 8): sys.stdout.write('%s\t\t\t' % benchmark) elif(length < 16): sys.stdout.write('%s\t\t' % benchmark) else: sys.stdout.write('%s\t' % benchmark) - for (name, typ, size, val) in benchmarkDict[benchmark]: + for (name, typ, entries, size, val) in benchmarkDict[benchmark]: sys.stdout.write('%0.2f\t\t' % (val if not args.invert else 100 -val)) sys.stdout.write('\n') @@ -234,14 +256,14 @@ def ReportAsText(benchmarkDict): if(args.summary): mean = benchmarkDict['Mean'] print('Mean') - for (name, typ, size, val) in mean: - sys.stdout.write('%s %s %0.2f\n' % (name, size, val if not args.invert else 100 - val)) + for (name, typ, entries. size, val) in mean: + sys.stdout.write('%s %s %0.2f\n' % (name, entries if not args.size else size, val if not args.invert else 100 - val)) if(not args.summary): for benchmark in benchmarkDict: print(benchmark) - for (name, type, size, val) in benchmarkDict[benchmark]: - sys.stdout.write('%s %s %0.2f\n' % (name, size, val if not args.invert else 100 - val)) + for (name, type, entries, size, val) in benchmarkDict[benchmark]: + sys.stdout.write('%s %s %0.2f\n' % (name, entries if not args.size else size, val if not args.invert else 100 - val)) def Inversion(lst): return [x if not args.invert else 100 - x for x in lst] @@ -306,11 +328,11 @@ def ReportAsGraph(benchmarkDict, bar, FileName): # branch predictors with various parameterizations # group the parameterizations by the common typ. sequencies = {} - for (name, typ, size, value) in benchmarkDict['Mean']: + for (name, typ, entries, size, value) in benchmarkDict['Mean']: if not typ in sequencies: - sequencies[typ] = [(size, value)] + sequencies[typ] = [(entries if not args.size else int(size/8), value)] else: - sequencies[typ].append((size,value)) + sequencies[typ].append((entries if not args.size else int(size/8) ,value)) # then graph the common typ as a single line+scatter plot # finally repeat for all typs of branch predictors and overlay fig, axes = plt.subplots() @@ -327,7 +349,8 @@ def ReportAsGraph(benchmarkDict, bar, FileName): axes.legend(loc='upper left') axes.set_xscale("log") axes.set_ylabel('Prediction Accuracy') - axes.set_xlabel('Entries') + Xlabel = 'Entries' if not args.size else 'Size (bytes)' + axes.set_xlabel(Xlabel) axes.set_xticks(xdata) axes.set_xticklabels(xdata) axes.grid(color='b', alpha=0.5, linestyle='dashed', linewidth=0.5) @@ -368,7 +391,7 @@ def ReportAsGraph(benchmarkDict, bar, FileName): for benchmarkName in benchmarkDict: currBenchmark = benchmarkDict[benchmarkName] xlabelList.append(benchmarkName) - for (name, typ, size, value) in currBenchmark: + for (name, typ, entries, size, value) in currBenchmark: if(name not in seriesDict): seriesDict[name] = [value] else: @@ -381,7 +404,7 @@ def ReportAsGraph(benchmarkDict, bar, FileName): for benchmarkName in benchmarkDict: currBenchmark = benchmarkDict[benchmarkName] xlabelListBig.append(benchmarkName) - for (name, typ, size, value) in currBenchmark: + for (name, typ, entries, size, value) in currBenchmark: if(name not in seriesDictBig): seriesDictBig[name] = [value] else: @@ -410,6 +433,7 @@ parser.add_argument('-s', '--summary', action='store_const', help='Show only the parser.add_argument('-b', '--bar', action='store_const', help='Plot graphs.', default=False, const=True) parser.add_argument('-g', '--reference', action='store_const', help='Include the golden reference model from branch-predictor-simulator. Data stored statically at the top of %(prog)s. If you need to regenreate use CModelBranchAcurracy.sh', default=False, const=True) parser.add_argument('-i', '--invert', action='store_const', help='Invert metric. Example Branch miss prediction becomes prediction accuracy. 100 - miss rate', default=False, const=True) +parser.add_argument('--size', action='store_const', help='Display x-axis as size in bits rather than number of table entries', default=False, const=True) displayMode = parser.add_mutually_exclusive_group() displayMode.add_argument('--text', action='store_const', help='Display in text format only.', default=False, const=True) diff --git a/sim/bp-results/branch-list-gshare-local8.txt b/sim/bp-results/branch-list-gshare-local8.txt new file mode 100644 index 000000000..ef020fe30 --- /dev/null +++ b/sim/bp-results/branch-list-gshare-local8.txt @@ -0,0 +1,12 @@ +../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_8local_basic6.log local 8 6 +../logs/rv32gc_8local_basic8.log local 8 8 +../logs/rv32gc_8local_basic10.log local 8 10 +../logs/rv32gc_8local_basic12.log local 8 12 +../logs/rv32gc_8local_basic14.log local 8 14 +../logs/rv32gc_8local_basic16.log local 8 16 diff --git a/sim/bp-results/branch-list.txt b/sim/bp-results/branch-list.txt index 10827b3b9..41f65165d 100644 --- a/sim/bp-results/branch-list.txt +++ b/sim/bp-results/branch-list.txt @@ -1,12 +1,36 @@ -../logs/bpred_GSHARE_6_16_10_0_rv32gc_embench.log gshare 6 -../logs/bpred_GSHARE_8_16_10_0_rv32gc_embench.log gshare 8 -../logs/bpred_GSHARE_10_16_10_0_rv32gc_embench.log gshare 10 -../logs/bpred_GSHARE_12_16_10_0_rv32gc_embench.log gshare 12 -../logs/bpred_GSHARE_14_16_10_0_rv32gc_embench.log gshare 14 -../logs/bpred_GSHARE_16_16_10_0_rv32gc_embench.log gshare 16 -../logs/bpred_TWOBIT_6_16_10_0_rv32gc_embench.log twobit 6 -../logs/bpred_TWOBIT_8_16_10_0_rv32gc_embench.log twobit 8 -../logs/bpred_TWOBIT_10_16_10_0_rv32gc_embench.log twobit 10 -../logs/bpred_TWOBIT_12_16_10_0_rv32gc_embench.log twobit 12 -../logs/bpred_TWOBIT_14_16_10_0_rv32gc_embench.log twobit 14 -../logs/bpred_TWOBIT_16_16_10_0_rv32gc_embench.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 +../logs/rv32gc_global6.log global 6 +../logs/rv32gc_global8.log global 8 +../logs/rv32gc_global10.log global 10 +../logs/rv32gc_global12.log global 12 +../logs/rv32gc_global14.log global 14 +../logs/rv32gc_global16.log global 16 +../logs/rv32gc_10local_basic6.log local 10 6 +../logs/rv32gc_10local_basic8.log local 10 8 +../logs/rv32gc_10local_basic10.log local 10 10 +../logs/rv32gc_10local_basic12.log local 10 12 +../logs/rv32gc_10local_basic14.log local 10 14 +../logs/rv32gc_10local_basic16.log local 10 16 +../logs/rv32gc_4local_basic6.log local 4 6 +../logs/rv32gc_4local_basic8.log local 4 8 +../logs/rv32gc_4local_basic10.log local 4 10 +../logs/rv32gc_4local_basic12.log local 4 12 +../logs/rv32gc_4local_basic14.log local 4 14 +../logs/rv32gc_4local_basic16.log local 4 16 +../logs/rv32gc_8local_basic6.log local 8 6 +../logs/rv32gc_8local_basic8.log local 8 8 +../logs/rv32gc_8local_basic10.log local 8 10 +../logs/rv32gc_8local_basic12.log local 8 12 +../logs/rv32gc_8local_basic14.log local 8 14 +../logs/rv32gc_8local_basic16.log local 8 16 diff --git a/src/ebu/ebufsmarb.sv b/src/ebu/ebufsmarb.sv index 55ba9a506..571bdcc63 100644 --- a/src/ebu/ebufsmarb.sv +++ b/src/ebu/ebufsmarb.sv @@ -51,7 +51,7 @@ module ebufsmarb ( statetype CurrState, NextState; logic both; // Both the LSU and IFU request at the same time - logic IFUReqD; // 1 cycle delayed IFU request. Part of arbitration + logic IFUReqDelay; // 1 cycle delayed IFU request. Part of arbitration logic FinalBeat, FinalBeatD; // Indicates the last beat of a burst logic BeatCntEn; logic [3:0] BeatCount; // Position within a burst transfer @@ -85,11 +85,11 @@ module ebufsmarb ( // Controller 1 (LSU) // When both the IFU and LSU request at the same time, the FSM will go into the arbitrate state. // Once the LSU request is done the fsm returns to IDLE. To prevent the LSU from regaining - // priority and re-issuing the same memory operation, the delayed IFUReqD squashes the LSU request. + // priority and re-issuing the same memory operation, the delayed IFUReqDelay squashes the LSU request. // This is necessary because the pipeline is stalled for the entire duration of both transactions, // and the LSU memory request will stil be active. - flopr #(1) ifureqreg(HCLK, ~HRESETn, IFUReq, IFUReqD); - assign LSUDisable = (CurrState == ARBITRATE) ? 1'b0 : (IFUReqD & ~(HREADY & FinalBeatD)); + flopr #(1) ifureqreg(HCLK, ~HRESETn, IFUReq, IFUReqDelay); + assign LSUDisable = (CurrState == ARBITRATE) ? 1'b0 : (IFUReqDelay & ~(HREADY & FinalBeatD)); assign LSUSelect = (NextState == ARBITRATE) ? 1'b1: LSUReq; ////////////////////////////////////////////////////////////////////////////////////////////////////