diff --git a/bin/parseHPMC.py b/bin/parseHPMC.py index 0cc75e10..0156dc9f 100755 --- a/bin/parseHPMC.py +++ b/bin/parseHPMC.py @@ -124,8 +124,9 @@ def ProcessFile(fileName): benchmarks.append((testName, opt, HPMClist)) return benchmarks -def ComputeAverage(benchmarks): +def ComputeArithmeticAverage(benchmarks): average = {} + index = 0 for (testName, opt, HPMClist) in benchmarks: for field in HPMClist: value = HPMClist[field] @@ -133,17 +134,40 @@ def ComputeAverage(benchmarks): average[field] = value else: average[field] += value + index += 1 benchmarks.append(('All', '', average)) def FormatToPlot(currBenchmark): names = [] values = [] for config in currBenchmark: - print ('config' , config) + #print ('config' , config) names.append(config[0]) values.append(config[1]) return (names, values) +def GeometricAverage(benchmarks, field): + Product = 1 + index = 0 + for (testName, opt, HPMCList) in benchmarks: + #print(HPMCList) + Product *= HPMCList[field] + index += 1 + return Product ** (1.0/index) + +def ComputeGeometricAverage(benchmarks): + fields = ['BDMR', 'BTMR', 'RASMPR', 'ClassMPR', 'ICacheMR', 'DCacheMR'] + AllAve = {} + for field in fields: + Product = 1 + index = 0 + for (testName, opt, HPMCList) in benchmarks: + #print(HPMCList) + Product *= HPMCList[field] + index += 1 + AllAve[field] = Product ** (1.0/index) + benchmarks.append(('All', '', AllAve)) + if(sys.argv[1] == '-b'): configList = [] summery = 0 @@ -152,22 +176,24 @@ if(sys.argv[1] == '-b'): sys.argv = sys.argv[1::] for config in sys.argv[2::]: benchmarks = ProcessFile(config) - ComputeAverage(benchmarks) + #ComputeArithmeticAverage(benchmarks) ComputeAll(benchmarks) + ComputeGeometricAverage(benchmarks) + #print('CONFIG: %s GEO MEAN: %f' % (config, GeometricAverage(benchmarks, 'BDMR'))) configList.append((config.split('.')[0], benchmarks)) # Merge all configruations into a single list benchmarkAll = [] for (config, benchmarks) in configList: - print(config) + #print(config) for benchmark in benchmarks: (nameString, opt, dataDict) = benchmark - print("BENCHMARK") - print(nameString) - print(opt) - print(dataDict) + #print("BENCHMARK") + #print(nameString) + #print(opt) + #print(dataDict) benchmarkAll.append((nameString, opt, config, dataDict)) - print('ALL!!!!!!!!!!') + #print('ALL!!!!!!!!!!') #for bench in benchmarkAll: # print('BENCHMARK') # print(bench) @@ -186,7 +212,7 @@ if(sys.argv[1] == '-b'): size = len(benchmarkDict) index = 1 if(summery == 0): - print('Number of plots', size) + #print('Number of plots', size) for benchmarkName in benchmarkDict: currBenchmark = benchmarkDict[benchmarkName] (names, values) = FormatToPlot(currBenchmark) @@ -223,7 +249,7 @@ if(sys.argv[1] == '-b'): print(dct) for cat in dct: (x, y) = dct[cat] - plt.scatter(x, y, label=cat) + plt.scatter(x, y, label='k') plt.plot(x, y) plt.ylabel('Prediction Accuracy') plt.xlabel('Size (b or k)') diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index 71077596..ec974d14 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -73,12 +73,12 @@ module bpred ( logic [1:0] DirPredictionF; logic [3:0] BTBPredInstrClassF, PredInstrClassF, PredInstrClassD; - logic [`XLEN-1:0] PredPCF, RASPCF; + logic [`XLEN-1:0] BTAF, RASPCF; logic PredictionPCWrongE; logic AnyWrongPredInstrClassD, AnyWrongPredInstrClassE; logic [3:0] InstrClassD; logic [3:0] InstrClassE; - logic DirPredictionWrongE, BTBPredPCWrongE, RASPredPCWrongE; + logic DirPredictionWrongE; logic SelBPPredF; logic [`XLEN-1:0] BPPredPCF; @@ -88,9 +88,8 @@ module bpred ( logic BTBTargetWrongE; logic RASTargetWrongE; - logic JumpOrTakenBranchE; - logic [`XLEN-1:0] PredPCD, PredPCE, RASPCD, RASPCE; + logic [`XLEN-1:0] BTAD; // Part 1 branch direction prediction // look into the 2 port Sram model. something is wrong. @@ -142,7 +141,7 @@ module bpred ( btb #(`BTB_SIZE) TargetPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCF, .PCD, .PCE, .PCM, - .PredPCF, + .BTAF, .BTAD, .BTBPredInstrClassF, .PredictionInstrClassWrongM, .IEUAdrE, .IEUAdrM, @@ -150,25 +149,28 @@ module bpred ( // the branch predictor needs a compact decoding of the instruction class. if (`INSTR_CLASS_PRED == 0) begin : DirectClassDecode - logic [4:0] CompressedOpcF; logic [3:0] InstrClassF; logic cjal, cj, cjr, cjalr, CJumpF, CBranchF; logic JumpF, BranchF; - - assign CompressedOpcF = {PostSpillInstrRawF[1:0], PostSpillInstrRawF[15:13]}; - assign cjal = CompressedOpcF == 5'h09 & `XLEN == 32; - assign cj = CompressedOpcF == 5'h0d; - assign cjr = CompressedOpcF == 5'h14 & ~PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0; - assign cjalr = CompressedOpcF == 5'h14 & PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0; - assign CJumpF = cjal | cj | cjr | cjalr; - assign CBranchF = CompressedOpcF[4:1] == 4'h7; + if(`C_SUPPORTED) begin + logic [4:0] CompressedOpcF; + assign CompressedOpcF = {PostSpillInstrRawF[1:0], PostSpillInstrRawF[15:13]}; + assign cjal = CompressedOpcF == 5'h09 & `XLEN == 32; + assign cj = CompressedOpcF == 5'h0d; + assign cjr = CompressedOpcF == 5'h14 & ~PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0; + assign cjalr = CompressedOpcF == 5'h14 & PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0; + assign CJumpF = cjal | cj | cjr | cjalr; + assign CBranchF = CompressedOpcF[4:1] == 4'h7; + end else begin + assign {cjal, cj, cjr, cjalr, CJumpF, CBranchF} = '0; + end assign JumpF = PostSpillInstrRawF[6:0] == 7'h67 | PostSpillInstrRawF[6:0] == 7'h6F; assign BranchF = PostSpillInstrRawF[6:0] == 7'h63; assign InstrClassF[0] = BranchF | (`C_SUPPORTED & CBranchF); - assign InstrClassF[1] = JumpF | (`C_SUPPORTED & (cjal | cj | cj | cjalr)); + assign InstrClassF[1] = JumpF | (`C_SUPPORTED & (CJumpF)); assign InstrClassF[2] = (JumpF & (PostSpillInstrRawF[19:15] & 5'h1B) == 5'h01) | // return must return to ra or r5 (`C_SUPPORTED & (cjalr | cjr) & ((PostSpillInstrRawF[11:7] & 5'h1B) == 5'h01)); @@ -189,7 +191,7 @@ module bpred ( .PredInstrClassF, .InstrClassD, .InstrClassE, .WrongPredInstrClassD, .RASPCF, .PCLinkE); - assign BPPredPCF = PredInstrClassF[2] ? RASPCF : PredPCF; + assign BPPredPCF = PredInstrClassF[2] ? RASPCF : BTAF; assign InstrClassD[0] = BranchD; assign InstrClassD[1] = JumpD ; @@ -201,9 +203,7 @@ module bpred ( flopenrc #(1) BPPredWrongMReg(clk, reset, FlushM, ~StallM, BPPredWrongE, BPPredWrongM); // branch predictor - flopenrc #(4) BPPredWrongRegM(clk, reset, FlushM, ~StallM, - {DirPredictionWrongE, BTBPredPCWrongE, RASPredPCWrongE, AnyWrongPredInstrClassE}, - {DirPredictionWrongM, BTBPredPCWrongM, RASPredPCWrongM, PredictionInstrClassWrongM}); + flopenrc #(1) BPClassWrongRegM(clk, reset, FlushM, ~StallM, AnyWrongPredInstrClassE, PredictionInstrClassWrongM); // pipeline the class flopenrc #(4) PredInstrClassRegD(clk, reset, FlushD, ~StallD, PredInstrClassF, PredInstrClassD); @@ -243,27 +243,37 @@ module bpred ( if(`INSTR_CLASS_PRED) mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPPredWrongM, NextValidPCE); else assign NextValidPCE = PCE; - // performance counters - // 1. class (class wrong / minstret) (PredictionInstrClassWrongM / csr) // Correct now - // 2. target btb (btb target wrong / class[0,1,3]) (btb target wrong / (br + j + jal) - // 3. target ras (ras target wrong / class[2]) - // 4. direction (br dir wrong / class[0]) + if(`ZICOUNTERS_SUPPORTED) begin + logic JumpOrTakenBranchE; + logic [`XLEN-1:0] BTAE, RASPCD, RASPCE; + logic BTBPredPCWrongE, RASPredPCWrongE; + // performance counters + // 1. class (class wrong / minstret) (PredictionInstrClassWrongM / csr) // Correct now + // 2. target btb (btb target wrong / class[0,1,3]) (btb target wrong / (br + j + jal) + // 3. target ras (ras target wrong / class[2]) + // 4. direction (br dir wrong / class[0]) - // Unforuantely we can't relay on PCD to infer the correctness of the BTB or RAS because the class prediction - // could be wrong or the fall through address selected for branch predict not taken. - // By pipeline the BTB's PC and RAS address through the pipeline we can measure the accuracy of - // both without the above inaccuracies. - assign BTBPredPCWrongE = (PredPCE != IEUAdrE) & (InstrClassE[0] | InstrClassE[1] & ~InstrClassE[2]) & PCSrcE; - assign RASPredPCWrongE = (RASPCE != IEUAdrE) & InstrClassE[2] & PCSrcE; + // Unforuantely we can't use PCD to infer the correctness of the BTB or RAS because the class prediction + // could be wrong or the fall through address selected for branch predict not taken. + // By pipeline the BTB's PC and RAS address through the pipeline we can measure the accuracy of + // both without the above inaccuracies. + assign BTBPredPCWrongE = (BTAE != IEUAdrE) & (InstrClassE[0] | InstrClassE[1] & ~InstrClassE[2]) & PCSrcE; + assign RASPredPCWrongE = (RASPCE != IEUAdrE) & InstrClassE[2] & PCSrcE; - assign JumpOrTakenBranchE = (InstrClassE[0] & PCSrcE) | InstrClassE[1]; + assign JumpOrTakenBranchE = (InstrClassE[0] & PCSrcE) | InstrClassE[1]; + + flopenrc #(1) JumpOrTakenBranchMReg(clk, reset, FlushM, ~StallM, JumpOrTakenBranchE, JumpOrTakenBranchM); + + flopenrc #(`XLEN) BTBTargetEReg(clk, reset, FlushE, ~StallE, BTAD, BTAE); + + flopenrc #(`XLEN) RASTargetDReg(clk, reset, FlushD, ~StallD, RASPCF, RASPCD); + flopenrc #(`XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE); + flopenrc #(3) BPPredWrongRegM(clk, reset, FlushM, ~StallM, + {DirPredictionWrongE, BTBPredPCWrongE, RASPredPCWrongE}, + {DirPredictionWrongM, BTBPredPCWrongM, RASPredPCWrongM}); - flopenrc #(1) JumpOrTakenBranchMReg(clk, reset, FlushM, ~StallM, JumpOrTakenBranchE, JumpOrTakenBranchM); - - flopenrc #(`XLEN) BTBTargetDReg(clk, reset, FlushD, ~StallD, PredPCF, PredPCD); - flopenrc #(`XLEN) BTBTargetEReg(clk, reset, FlushE, ~StallE, PredPCD, PredPCE); - - flopenrc #(`XLEN) RASTargetDReg(clk, reset, FlushD, ~StallD, RASPCF, RASPCD); - flopenrc #(`XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE); + end else begin + assign {BTBPredPCWrongM, RASPredPCWrongM, JumpOrTakenBranchM} = '0; + end endmodule diff --git a/src/ifu/bpred/btb.sv b/src/ifu/bpred/btb.sv index 8e2d0e25..2bb00671 100644 --- a/src/ifu/bpred/btb.sv +++ b/src/ifu/bpred/btb.sv @@ -31,19 +31,20 @@ `include "wally-config.vh" module btb #(parameter Depth = 10 ) ( - input logic clk, - input logic reset, - input logic StallF, StallD, StallE, StallM, StallW, FlushD, FlushE, FlushM, FlushW, - input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, // PC at various stages - output logic [`XLEN-1:0] PredPCF, // BTB's guess at PC + input logic clk, + input logic reset, + input logic StallF, StallD, StallE, StallM, StallW, FlushD, FlushE, FlushM, FlushW, + input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, // PC at various stages + output logic [`XLEN-1:0] BTAF, // BTB's guess at PC + output logic [`XLEN-1:0] BTAD, output logic [3:0] BTBPredInstrClassF, // BTB's guess at instruction class // update - input logic PredictionInstrClassWrongM, // BTB's instruction class guess was wrong - input logic [`XLEN-1:0] IEUAdrE, // Branch/jump target address to insert into btb - input logic [`XLEN-1:0] IEUAdrM, // Branch/jump target address to insert into btb - input logic [3:0] InstrClassD, // Instruction class to insert into btb - input logic [3:0] InstrClassE, // Instruction class to insert into btb - input logic [3:0] InstrClassM // Instruction class to insert into btb + input logic PredictionInstrClassWrongM, // BTB's instruction class guess was wrong + input logic [`XLEN-1:0] IEUAdrE, // Branch/jump target address to insert into btb + input logic [`XLEN-1:0] IEUAdrM, // Branch/jump target address to insert into btb + input logic [3:0] InstrClassD, // Instruction class to insert into btb + input logic [3:0] InstrClassE, // Instruction class to insert into btb + input logic [3:0] InstrClassM // Instruction class to insert into btb ); logic [Depth-1:0] PCNextFIndex, PCFIndex, PCDIndex, PCEIndex, PCMIndex; @@ -51,7 +52,6 @@ module btb #(parameter Depth = 10 ) ( logic MatchF, MatchD, MatchE, MatchM, MatchNextX, MatchXF; logic [`XLEN+3:0] ForwardBTBPrediction, ForwardBTBPredictionF; logic [`XLEN+3:0] TableBTBPredictionF; - logic [`XLEN-1:0] PredPCD; logic UpdateEn; // hashing function for indexing the PC @@ -78,14 +78,14 @@ module btb #(parameter Depth = 10 ) ( flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF); - assign ForwardBTBPrediction = MatchF ? {BTBPredInstrClassF, PredPCF} : - MatchD ? {InstrClassD, PredPCD} : + assign ForwardBTBPrediction = MatchF ? {BTBPredInstrClassF, BTAF} : + MatchD ? {InstrClassD, BTAD} : MatchE ? {InstrClassE, IEUAdrE} : {InstrClassM, IEUAdrM} ; flopenr #(`XLEN+4) ForwardBTBPredicitonReg(clk, reset, ~StallF, ForwardBTBPrediction, ForwardBTBPredictionF); - assign {BTBPredInstrClassF, PredPCF} = MatchXF ? ForwardBTBPredictionF : {TableBTBPredictionF}; + assign {BTBPredInstrClassF, BTAF} = MatchXF ? ForwardBTBPredictionF : {TableBTBPredictionF}; assign UpdateEn = |InstrClassM | PredictionInstrClassWrongM; @@ -95,6 +95,6 @@ module btb #(parameter Depth = 10 ) ( .clk, .ce1(~StallF | reset), .ra1(PCNextFIndex), .rd1(TableBTBPredictionF), .ce2(~StallW & ~FlushW), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(UpdateEn), .bwe2('1)); - flopenrc #(`XLEN) BTBD(clk, reset, FlushD, ~StallD, PredPCF, PredPCD); + flopenrc #(`XLEN) BTBD(clk, reset, FlushD, ~StallD, BTAF, BTAD); endmodule diff --git a/src/ifu/bpred/gsharebasic.sv b/src/ifu/bpred/gsharebasic.sv index ccad0e3c..cb0bbe9e 100644 --- a/src/ifu/bpred/gsharebasic.sv +++ b/src/ifu/bpred/gsharebasic.sv @@ -42,7 +42,7 @@ module gsharebasic #(parameter k = 10, input logic BranchInstrE, BranchInstrM, PCSrcE ); - logic [k-1:0] IndexNextF, IndexE; + logic [k-1:0] IndexNextF, IndexM; logic [1:0] DirPredictionD, DirPredictionE; logic [1:0] NewDirPredictionE, NewDirPredictionM; @@ -52,19 +52,19 @@ module gsharebasic #(parameter k = 10, if(TYPE == 1) begin assign IndexNextF = GHR ^ {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]}; - assign IndexE = GHRM ^ {PCM[k+1] ^ PCM[1], PCM[k:2]}; + assign IndexM = GHRM ^ {PCM[k+1] ^ PCM[1], PCM[k:2]}; end else if(TYPE == 0) begin assign IndexNextF = GHRNext; - assign IndexE = GHRE; + assign IndexM = GHRM; end ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), - .ce1(~StallF), .ce2(~StallM & ~FlushM), + .ce1(~StallF), .ce2(~StallW & ~FlushW), .ra1(IndexNextF), .rd1(DirPredictionF), - .wa2(IndexE), + .wa2(IndexM), .wd2(NewDirPredictionM), - .we2(BranchInstrM & ~StallW & ~FlushW), + .we2(BranchInstrM), .bwe2(1'b1)); flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD);