From fa49de8391a59c8286fce265c7447ff7f085e597 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Thu, 23 Feb 2023 15:55:34 -0600 Subject: [PATCH 1/8] Partial replacement of InstrClassX with {JalX, RetX, JumpX, and BranchX}. --- src/ifu/bpred/RASPredictor.sv | 4 +- src/ifu/bpred/bpred.sv | 92 +++++++++++++++++--------------- src/ifu/bpred/twoBitPredictor.sv | 8 +-- 3 files changed, 56 insertions(+), 48 deletions(-) diff --git a/src/ifu/bpred/RASPredictor.sv b/src/ifu/bpred/RASPredictor.sv index 330607af4..3f72c4fab 100644 --- a/src/ifu/bpred/RASPredictor.sv +++ b/src/ifu/bpred/RASPredictor.sv @@ -33,7 +33,7 @@ module RASPredictor #(parameter int StackSize = 16 )( input logic clk, input logic reset, input logic StallF, StallD, StallE, StallM, FlushD, FlushE, FlushM, - input logic [3:0] WrongPredInstrClassD, // Prediction class is wrong + input logic WrongBPRetD, // Prediction class is wrong input logic [3:0] InstrClassD, input logic [3:0] InstrClassE, // Instr class input logic [3:0] PredInstrClassF, @@ -61,7 +61,7 @@ module RASPredictor #(parameter int StackSize = 16 )( assign PopF = PredInstrClassF[2] & ~StallD & ~FlushD; assign PushE = InstrClassE[3] & ~StallM & ~FlushM; - assign WrongPredRetD = (WrongPredInstrClassD[2]) & ~StallE & ~FlushE; + assign WrongPredRetD = (WrongBPRetD) & ~StallE & ~FlushE; assign FlushedRetDE = (~StallE & FlushE & InstrClassD[2]) | (~StallM & FlushM & InstrClassE[2]); // flushed ret assign RepairD = WrongPredRetD | FlushedRetDE ; diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index ec974d14c..27ee6bc10 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -72,12 +72,9 @@ module bpred ( logic [1:0] DirPredictionF; - logic [3:0] BTBPredInstrClassF, PredInstrClassF, PredInstrClassD; logic [`XLEN-1:0] BTAF, RASPCF; logic PredictionPCWrongE; logic AnyWrongPredInstrClassD, AnyWrongPredInstrClassE; - logic [3:0] InstrClassD; - logic [3:0] InstrClassE; logic DirPredictionWrongE; logic SelBPPredF; @@ -91,34 +88,44 @@ module bpred ( logic [`XLEN-1:0] BTAD; + logic BTBJalF, BTBRetF, BTBJumpF, BTBBranchF; + logic BPBranchF, BPJumpF, BPRetF, BPJalF; + logic BPBranchD, BPJumpD, BPRetD, BPJalD; + logic RetD, JalD; + logic RetE, JalE; + logic BranchM, JumpM, RetM, JalM; + logic WrongBPRetD; + + // Part 1 branch direction prediction // look into the 2 port Sram model. something is wrong. if (`BPRED_TYPE == "BP_TWOBIT") begin:Predictor - twoBitPredictor #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM, + twoBitPredictor #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, + .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCM, .DirPredictionF, .DirPredictionWrongE, - .BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE); + .BranchInstrE(BranchE), .BranchInstrM(BranchM), .PCSrcE); end else if (`BPRED_TYPE == "BP_GSHARE") begin:Predictor gshare #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCF, .PCD, .PCE, .PCM, .DirPredictionF, .DirPredictionWrongE, - .BranchInstrF(PredInstrClassF[0]), .BranchInstrD(InstrClassD[0]), .BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), + .BranchInstrF(BPBranchF), .BranchInstrD(BranchD), .BranchInstrE(BranchE), .BranchInstrM(BranchM), .PCSrcE); end else if (`BPRED_TYPE == "BP_GLOBAL") begin:Predictor gshare #(`BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCF, .PCD, .PCE, .PCM, .DirPredictionF, .DirPredictionWrongE, - .BranchInstrF(PredInstrClassF[0]), .BranchInstrD(InstrClassD[0]), .BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), + .BranchInstrF(BPBranchF), .BranchInstrD(BranchD), .BranchInstrE(BranchE), .BranchInstrM(BranchM), .PCSrcE); end else if (`BPRED_TYPE == "BP_GSHARE_BASIC") begin:Predictor gsharebasic #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCM, .DirPredictionF, .DirPredictionWrongE, - .BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE); + .BranchInstrE(BranchE), .BranchInstrM(BranchM), .PCSrcE); end else if (`BPRED_TYPE == "BP_GLOBAL_BASIC") begin:Predictor gsharebasic #(`BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCM, .DirPredictionF, .DirPredictionWrongE, - .BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE); + .BranchInstrE(BranchE), .BranchInstrM(BranchM), .PCSrcE); end else if (`BPRED_TYPE == "BPLOCALPAg") begin:Predictor // *** Fix me @@ -142,16 +149,16 @@ module bpred ( TargetPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCF, .PCD, .PCE, .PCM, .BTAF, .BTAD, - .BTBPredInstrClassF, + .BTBPredInstrClassF({BTBJalF, BTBRetF, BTBJumpF, BTBBranchF}), .PredictionInstrClassWrongM, .IEUAdrE, .IEUAdrM, - .InstrClassD, .InstrClassE, .InstrClassM); + .InstrClassD({JalD, RetD, JumpD, BranchD}), .InstrClassE({JalE, RetE, JumpE, BranchE}), .InstrClassM({JalM, RetM, JumpM, BranchM})); // the branch predictor needs a compact decoding of the instruction class. if (`INSTR_CLASS_PRED == 0) begin : DirectClassDecode logic [3:0] InstrClassF; logic cjal, cj, cjr, cjalr, CJumpF, CBranchF; - logic JumpF, BranchF; + logic NCJumpF, NCBranchF; if(`C_SUPPORTED) begin logic [4:0] CompressedOpcF; @@ -166,48 +173,46 @@ module bpred ( 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 NCJumpF = PostSpillInstrRawF[6:0] == 7'h67 | PostSpillInstrRawF[6:0] == 7'h6F; + assign NCBranchF = PostSpillInstrRawF[6:0] == 7'h63; - assign InstrClassF[0] = BranchF | (`C_SUPPORTED & CBranchF); - 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)); + assign BPBranchF = NCBranchF | (`C_SUPPORTED & CBranchF); + assign BPJumpF = NCJumpF | (`C_SUPPORTED & (CJumpF)); + assign BPRetF = (NCJumpF & (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)); - assign InstrClassF[3] = (JumpF & (PostSpillInstrRawF[11:07] & 5'h1B) == 5'h01) | // jal(r) must link to ra or x5 + assign BPJalF = (NCJumpF & (PostSpillInstrRawF[11:07] & 5'h1B) == 5'h01) | // jal(r) must link to ra or x5 (`C_SUPPORTED & (cjal | (cjalr & (PostSpillInstrRawF[11:7] & 5'h1b) == 5'h01))); - assign PredInstrClassF = InstrClassF; - assign SelBPPredF = (PredInstrClassF[0] & DirPredictionF[1]) | - PredInstrClassF[1]; end else begin - assign PredInstrClassF = BTBPredInstrClassF; - assign SelBPPredF = (PredInstrClassF[0] & DirPredictionF[1]) | - PredInstrClassF[1]; + assign {BPJalF, BPRetF, BPJumpF, BPBranchF} = {BTBJalF, BTBRetF, BTBJumpF, BTBBranchF}; end + assign SelBPPredF = (BPBranchF & DirPredictionF[1]) | BPJumpF; // Part 3 RAS RASPredictor RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM, - .PredInstrClassF, .InstrClassD, .InstrClassE, - .WrongPredInstrClassD, .RASPCF, .PCLinkE); + .PredInstrClassF({BPJalF, BPRetF, BPJumpF, BPBranchF}), .InstrClassD({JalD, RetD, JumpD, BranchD}), .InstrClassE({JalE, RetE, JumpE, BranchE}), + .WrongBPRetD, .RASPCF, .PCLinkE); - assign BPPredPCF = PredInstrClassF[2] ? RASPCF : BTAF; + assign BPPredPCF = BPRetF ? RASPCF : BTAF; - assign InstrClassD[0] = BranchD; - assign InstrClassD[1] = JumpD ; - assign InstrClassD[2] = JumpD & (InstrD[19:15] & 5'h1B) == 5'h01; // return must return to ra or x5 - assign InstrClassD[3] = JumpD & (InstrD[11:7] & 5'h1B) == 5'h01; // jal(r) must link to ra or x5 + //assign InstrClassD[0] = BranchD; + //assign InstrClassD[1] = JumpD ; + //assign InstrClassD[2] = JumpD & (InstrD[19:15] & 5'h1B) == 5'h01; // return must return to ra or x5 + assign RetD = JumpD & (InstrD[19:15] & 5'h1B) == 5'h01; // return must return to ra or x5 + //assign InstrClassD[3] = JumpD & (InstrD[11:7] & 5'h1B) == 5'h01; // jal(r) must link to ra or x5 + assign JalD = JumpD & (InstrD[11:7] & 5'h1B) == 5'h01; // jal(r) must link to ra or x5 - flopenrc #(4) InstrClassRegE(clk, reset, FlushE, ~StallE, InstrClassD, InstrClassE); - flopenrc #(4) InstrClassRegM(clk, reset, FlushM, ~StallM, InstrClassE, InstrClassM); + flopenrc #(2) InstrClassRegE(clk, reset, FlushE, ~StallE, {JalD, RetD}, {JalE, RetE}); + flopenrc #(4) InstrClassRegM(clk, reset, FlushM, ~StallM, {JalE, RetE, JumpE, BranchE}, {JalM, RetM, JumpM, BranchM}); flopenrc #(1) BPPredWrongMReg(clk, reset, FlushM, ~StallM, BPPredWrongE, BPPredWrongM); // branch predictor flopenrc #(1) BPClassWrongRegM(clk, reset, FlushM, ~StallM, AnyWrongPredInstrClassE, PredictionInstrClassWrongM); - - // pipeline the class - flopenrc #(4) PredInstrClassRegD(clk, reset, FlushD, ~StallD, PredInstrClassF, PredInstrClassD); flopenrc #(1) WrongInstrClassRegE(clk, reset, FlushE, ~StallE, AnyWrongPredInstrClassD, AnyWrongPredInstrClassE); + + // pipeline the predicted class + flopenrc #(4) PredInstrClassRegD(clk, reset, FlushD, ~StallD, {BPJalF, BPRetF, BPJumpF, BPBranchF}, {BPJalD, BPRetD, BPJumpD, BPBranchD}); // Check the prediction // if it is a CFI then check if the next instruction address (PCD) matches the branch's target or fallthrough address. @@ -218,8 +223,8 @@ module bpred ( assign PredictionPCWrongE = PCCorrectE != PCD; // branch class prediction wrong. - assign WrongPredInstrClassD = PredInstrClassD ^ InstrClassD[3:0]; - assign AnyWrongPredInstrClassD = |WrongPredInstrClassD; + assign AnyWrongPredInstrClassD = |({BPJalD, BPRetD, BPJumpD, BPBranchD} ^ {JalD, RetD, JumpD, BranchD}); + assign WrongBPRetD = BPRetD ^ RetD; // branch is wrong only if the PC does not match and both the Decode and Fetch stages have valid instructions. //assign BPPredWrongE = (PredictionPCWrongE & |InstrClassE | (AnyWrongPredInstrClassE & ~|InstrClassE)); @@ -257,10 +262,10 @@ module bpred ( // 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 BTBPredPCWrongE = (BTAE != IEUAdrE) & (BranchE | JumpE & ~RetE) & PCSrcE; + assign RASPredPCWrongE = (RASPCE != IEUAdrE) & RetE & PCSrcE; - assign JumpOrTakenBranchE = (InstrClassE[0] & PCSrcE) | InstrClassE[1]; + assign JumpOrTakenBranchE = (BranchE & PCSrcE) | JumpE; flopenrc #(1) JumpOrTakenBranchMReg(clk, reset, FlushM, ~StallM, JumpOrTakenBranchE, JumpOrTakenBranchM); @@ -275,5 +280,8 @@ module bpred ( end else begin assign {BTBPredPCWrongM, RASPredPCWrongM, JumpOrTakenBranchM} = '0; end + + // **** Fix me + assign InstrClassM = {JalM, RetM, JumpM, BranchM}; endmodule diff --git a/src/ifu/bpred/twoBitPredictor.sv b/src/ifu/bpred/twoBitPredictor.sv index 4a7be674d..37405ab42 100644 --- a/src/ifu/bpred/twoBitPredictor.sv +++ b/src/ifu/bpred/twoBitPredictor.sv @@ -31,8 +31,8 @@ module twoBitPredictor #(parameter k = 10) ( input logic clk, input logic reset, - input logic StallF, StallD, StallE, StallM, - input logic FlushD, FlushE, FlushM, + input logic StallF, StallD, StallE, StallM, StallW, + input logic FlushD, FlushE, FlushM, FlushW, input logic [`XLEN-1:0] PCNextF, PCM, output logic [1:0] DirPredictionF, output logic DirPredictionWrongE, @@ -55,12 +55,12 @@ module twoBitPredictor #(parameter k = 10) ( ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), - .ce1(~StallF), .ce2(~StallM & ~FlushM), + .ce1(~StallF), .ce2(~StallW & ~FlushW), .ra1(IndexNextF), .rd1(DirPredictionF), .wa2(IndexM), .wd2(NewDirPredictionM), - .we2(BranchInstrM & ~StallM & ~FlushM), + .we2(BranchInstrM), .bwe2(1'b1)); flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD); From 292017943583363d6661dda55f93a676bd81b73c Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Thu, 23 Feb 2023 16:19:03 -0600 Subject: [PATCH 2/8] Major cleanup of bp. --- src/ifu/bpred/RASPredictor.sv | 16 ++++++++-------- src/ifu/bpred/bpred.sv | 12 ++++++------ src/ifu/bpred/gshare.sv | 24 ++++++++++++------------ src/ifu/bpred/gsharebasic.sv | 10 +++++----- src/ifu/bpred/twoBitPredictor.sv | 6 +++--- 5 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/ifu/bpred/RASPredictor.sv b/src/ifu/bpred/RASPredictor.sv index 3f72c4fab..5f14a028e 100644 --- a/src/ifu/bpred/RASPredictor.sv +++ b/src/ifu/bpred/RASPredictor.sv @@ -34,9 +34,9 @@ module RASPredictor #(parameter int StackSize = 16 )( input logic reset, input logic StallF, StallD, StallE, StallM, FlushD, FlushE, FlushM, input logic WrongBPRetD, // Prediction class is wrong - input logic [3:0] InstrClassD, - input logic [3:0] InstrClassE, // Instr class - input logic [3:0] PredInstrClassF, + input logic RetD, + input logic RetE, JalE, // Instr class + input logic BPRetF, input logic [`XLEN-1:0] PCLinkE, // PC of instruction after a jal output logic [`XLEN-1:0] RASPCF // Top of the stack ); @@ -58,17 +58,17 @@ module RASPredictor #(parameter int StackSize = 16 )( logic WrongPredRetD; - assign PopF = PredInstrClassF[2] & ~StallD & ~FlushD; - assign PushE = InstrClassE[3] & ~StallM & ~FlushM; + assign PopF = BPRetF & ~StallD & ~FlushD; + assign PushE = JalE & ~StallM & ~FlushM; assign WrongPredRetD = (WrongBPRetD) & ~StallE & ~FlushE; - assign FlushedRetDE = (~StallE & FlushE & InstrClassD[2]) | (~StallM & FlushM & InstrClassE[2]); // flushed ret + assign FlushedRetDE = (~StallE & FlushE & RetD) | (~StallM & FlushM & RetE); // flushed ret assign RepairD = WrongPredRetD | FlushedRetDE ; - assign IncrRepairD = FlushedRetDE | (WrongPredRetD & ~InstrClassD[2]); // Guessed it was a ret, but its not + assign IncrRepairD = FlushedRetDE | (WrongPredRetD & ~RetD); // Guessed it was a ret, but its not - assign DecRepairD = WrongPredRetD & InstrClassD[2]; // Guessed non ret but is a ret. + assign DecRepairD = WrongPredRetD & RetD; // Guessed non ret but is a ret. assign CounterEn = PopF | PushE | RepairD; diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index 27ee6bc10..fc6721ce5 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -103,29 +103,29 @@ module bpred ( twoBitPredictor #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCM, .DirPredictionF, .DirPredictionWrongE, - .BranchInstrE(BranchE), .BranchInstrM(BranchM), .PCSrcE); + .BranchE, .BranchM, .PCSrcE); end else if (`BPRED_TYPE == "BP_GSHARE") begin:Predictor gshare #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCF, .PCD, .PCE, .PCM, .DirPredictionF, .DirPredictionWrongE, - .BranchInstrF(BPBranchF), .BranchInstrD(BranchD), .BranchInstrE(BranchE), .BranchInstrM(BranchM), + .BPBranchF, .BranchD, .BranchE, .BranchM, .PCSrcE); end else if (`BPRED_TYPE == "BP_GLOBAL") begin:Predictor gshare #(`BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCF, .PCD, .PCE, .PCM, .DirPredictionF, .DirPredictionWrongE, - .BranchInstrF(BPBranchF), .BranchInstrD(BranchD), .BranchInstrE(BranchE), .BranchInstrM(BranchM), + .BPBranchF, .BranchD, .BranchE, .BranchM, .PCSrcE); end else if (`BPRED_TYPE == "BP_GSHARE_BASIC") begin:Predictor gsharebasic #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCM, .DirPredictionF, .DirPredictionWrongE, - .BranchInstrE(BranchE), .BranchInstrM(BranchM), .PCSrcE); + .BranchE, .BranchM, .PCSrcE); end else if (`BPRED_TYPE == "BP_GLOBAL_BASIC") begin:Predictor gsharebasic #(`BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCM, .DirPredictionF, .DirPredictionWrongE, - .BranchInstrE(BranchE), .BranchInstrM(BranchM), .PCSrcE); + .BranchE, .BranchM, .PCSrcE); end else if (`BPRED_TYPE == "BPLOCALPAg") begin:Predictor // *** Fix me @@ -191,7 +191,7 @@ module bpred ( // Part 3 RAS RASPredictor RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM, - .PredInstrClassF({BPJalF, BPRetF, BPJumpF, BPBranchF}), .InstrClassD({JalD, RetD, JumpD, BranchD}), .InstrClassE({JalE, RetE, JumpE, BranchE}), + .BPRetF, .RetD, .RetE, .JalE, .WrongBPRetD, .RASPCF, .PCLinkE); assign BPPredPCF = BPRetF ? RASPCF : BTAF; diff --git a/src/ifu/bpred/gshare.sv b/src/ifu/bpred/gshare.sv index 5332ce5cd..2523693cf 100644 --- a/src/ifu/bpred/gshare.sv +++ b/src/ifu/bpred/gshare.sv @@ -39,7 +39,7 @@ module gshare #(parameter k = 10, output logic DirPredictionWrongE, // update input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, - input logic BranchInstrF, BranchInstrD, BranchInstrE, BranchInstrM, PCSrcE + input logic BPBranchF, BranchD, BranchE, BranchM, PCSrcE ); logic MatchF, MatchD, MatchE, MatchM; @@ -68,10 +68,10 @@ module gshare #(parameter k = 10, assign IndexM = GHRM; end - assign MatchF = BranchInstrF & ~FlushD & (IndexNextF == IndexF); - assign MatchD = BranchInstrD & ~FlushE & (IndexNextF == IndexD); - assign MatchE = BranchInstrE & ~FlushM & (IndexNextF == IndexE); - assign MatchM = BranchInstrM & ~FlushW & (IndexNextF == IndexM); + assign MatchF = BPBranchF & ~FlushD & (IndexNextF == IndexF); + assign MatchD = BranchD & ~FlushE & (IndexNextF == IndexD); + assign MatchE = BranchE & ~FlushM & (IndexNextF == IndexE); + assign MatchM = BranchM & ~FlushW & (IndexNextF == IndexM); assign MatchNextX = MatchF | MatchD | MatchE | MatchM; flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF); @@ -91,7 +91,7 @@ module gshare #(parameter k = 10, .rd1(TableDirPredictionF), .wa2(IndexM), .wd2(NewDirPredictionM), - .we2(BranchInstrM), + .we2(BranchM), .bwe2(1'b1)); flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD); @@ -100,16 +100,16 @@ module gshare #(parameter k = 10, satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE)); flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewDirPredictionE, NewDirPredictionM); - assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchInstrE; + assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchE; - assign GHRNextF = BranchInstrF ? {DirPredictionF[1], GHRF[k-1:1]} : GHRF; - assign GHRF = BranchInstrD ? {DirPredictionD[1], GHRD[k-1:1]} : GHRD; - assign GHRD = BranchInstrE ? {PCSrcE, GHRE[k-1:1]} : GHRE; - assign GHRE = BranchInstrM ? {PCSrcM, GHRM[k-1:1]} : GHRM; + assign GHRNextF = BPBranchF ? {DirPredictionF[1], GHRF[k-1:1]} : GHRF; + assign GHRF = BranchD ? {DirPredictionD[1], GHRD[k-1:1]} : GHRD; + assign GHRD = BranchE ? {PCSrcE, GHRE[k-1:1]} : GHRE; + assign GHRE = BranchM ? {PCSrcM, GHRM[k-1:1]} : GHRM; assign GHRNextM = {PCSrcM, GHRM[k-1:1]}; - flopenr #(k) GHRReg(clk, reset, ~StallW & ~FlushW & BranchInstrM, GHRNextM, GHRM); + flopenr #(k) GHRReg(clk, reset, ~StallW & ~FlushW & BranchM, GHRNextM, GHRM); flopenrc #(1) PCSrcMReg(clk, reset, FlushM, ~StallM, PCSrcE, PCSrcM); endmodule diff --git a/src/ifu/bpred/gsharebasic.sv b/src/ifu/bpred/gsharebasic.sv index cb0bbe9eb..e793e7ac6 100644 --- a/src/ifu/bpred/gsharebasic.sv +++ b/src/ifu/bpred/gsharebasic.sv @@ -39,7 +39,7 @@ module gsharebasic #(parameter k = 10, output logic DirPredictionWrongE, // update input logic [`XLEN-1:0] PCNextF, PCM, - input logic BranchInstrE, BranchInstrM, PCSrcE + input logic BranchE, BranchM, PCSrcE ); logic [k-1:0] IndexNextF, IndexM; @@ -64,7 +64,7 @@ module gsharebasic #(parameter k = 10, .rd1(DirPredictionF), .wa2(IndexM), .wd2(NewDirPredictionM), - .we2(BranchInstrM), + .we2(BranchM), .bwe2(1'b1)); flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD); @@ -73,10 +73,10 @@ module gsharebasic #(parameter k = 10, satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE)); flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewDirPredictionE, NewDirPredictionM); - assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchInstrE; + assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchE; - assign GHRNext = BranchInstrM ? {PCSrcM, GHR[k-1:1]} : GHR; - flopenr #(k) GHRReg(clk, reset, ~StallM & ~FlushM & BranchInstrM, GHRNext, GHR); + assign GHRNext = BranchM ? {PCSrcM, GHR[k-1:1]} : GHR; + flopenr #(k) GHRReg(clk, reset, ~StallM & ~FlushM & BranchM, GHRNext, GHR); flopenrc #(1) PCSrcMReg(clk, reset, FlushM, ~StallM, PCSrcE, PCSrcM); flopenrc #(k) GHRFReg(clk, reset, FlushD, ~StallF, GHR, GHRF); diff --git a/src/ifu/bpred/twoBitPredictor.sv b/src/ifu/bpred/twoBitPredictor.sv index 37405ab42..58bf1c6bd 100644 --- a/src/ifu/bpred/twoBitPredictor.sv +++ b/src/ifu/bpred/twoBitPredictor.sv @@ -36,7 +36,7 @@ module twoBitPredictor #(parameter k = 10) ( input logic [`XLEN-1:0] PCNextF, PCM, output logic [1:0] DirPredictionF, output logic DirPredictionWrongE, - input logic BranchInstrE, BranchInstrM, + input logic BranchE, BranchM, input logic PCSrcE ); @@ -60,13 +60,13 @@ module twoBitPredictor #(parameter k = 10) ( .rd1(DirPredictionF), .wa2(IndexM), .wd2(NewDirPredictionM), - .we2(BranchInstrM), + .we2(BranchM), .bwe2(1'b1)); flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD); flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, DirPredictionD, DirPredictionE); - assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchInstrE; + assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchE; satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE)); flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewDirPredictionE, NewDirPredictionM); From cbc5de1ebd200f7d74184a0233d393032d57ab4a Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Thu, 23 Feb 2023 20:44:47 -0600 Subject: [PATCH 3/8] Improved branch predictor graph generation. --- bin/parseHPMC.py | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/bin/parseHPMC.py b/bin/parseHPMC.py index 0156dc9fd..7b695d34d 100755 --- a/bin/parseHPMC.py +++ b/bin/parseHPMC.py @@ -247,13 +247,25 @@ if(sys.argv[1] == '-b'): currPercent.append(percent) dct[PredType] = (currSize, currPercent) print(dct) + fig, axes = plt.subplots() + marker={'twobit' : '^', 'gshare' : 'o', 'global' : 's', 'gshareBasic' : '*', 'globalBasic' : 'x'} + colors={'twobit' : 'black', 'gshare' : 'blue', 'global' : 'dodgerblue', 'gshareBasic' : 'turquoise', 'globalBasic' : 'lightsteelblue'} for cat in dct: (x, y) = dct[cat] - plt.scatter(x, y, label='k') - plt.plot(x, y) - plt.ylabel('Prediction Accuracy') - plt.xlabel('Size (b or k)') - plt.legend(loc='upper left') + x=[int(2**int(v)/4) for v in x] + print(x, y) + axes.plot(x,y, color=colors[cat]) + axes.scatter(x,y, label=cat, marker=marker[cat], color=colors[cat]) + #plt.scatter(x, y, label=cat) + #plt.plot(x, y) + #axes.set_xticks([4, 6, 8, 10, 12, 14]) + axes.legend(loc='upper left') + axes.set_xscale("log") + axes.set_ylabel('Prediction Accuracy') + axes.set_xlabel('Size (bytes)') + axes.set_xticks([16, 64, 256, 1024, 4096, 16384]) + axes.set_xticklabels([16, 64, 256, 1024, 4096, 16384]) + axes.grid(color='b', alpha=0.5, linestyle='dashed', linewidth=0.5) plt.show() From 5db56460b9f184e68afcc104746a2c41f63c86af Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Fri, 24 Feb 2023 17:47:43 -0600 Subject: [PATCH 4/8] Modified btb forwarding logic to reduce critical path. --- src/ifu/bpred/bpred.sv | 24 ++++++++++++------------ src/ifu/bpred/btb.sv | 32 ++++++++++++++++++++------------ 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index fc6721ce5..aee8c4912 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -77,7 +77,7 @@ module bpred ( logic AnyWrongPredInstrClassD, AnyWrongPredInstrClassE; logic DirPredictionWrongE; - logic SelBPPredF; + logic BPPCSrcF; logic [`XLEN-1:0] BPPredPCF; logic [`XLEN-1:0] PCNext0F; logic [`XLEN-1:0] PCCorrectE; @@ -96,6 +96,7 @@ module bpred ( logic BranchM, JumpM, RetM, JalM; logic WrongBPRetD; + logic [`XLEN-1:0] PCW; // Part 1 branch direction prediction // look into the 2 port Sram model. something is wrong. @@ -147,16 +148,18 @@ module bpred ( btb #(`BTB_SIZE) TargetPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, - .PCNextF, .PCF, .PCD, .PCE, .PCM, + .PCNextF, .PCF, .PCD, .PCE, .PCM, .PCW, .BTAF, .BTAD, .BTBPredInstrClassF({BTBJalF, BTBRetF, BTBJumpF, BTBBranchF}), .PredictionInstrClassWrongM, .IEUAdrE, .IEUAdrM, .InstrClassD({JalD, RetD, JumpD, BranchD}), .InstrClassE({JalE, RetE, JumpE, BranchE}), .InstrClassM({JalM, RetM, JumpM, BranchM})); - // the branch predictor needs a compact decoding of the instruction class. - if (`INSTR_CLASS_PRED == 0) begin : DirectClassDecode - logic [3:0] InstrClassF; + if (!`INSTR_CLASS_PRED) begin : DirectClassDecode + // This section is mainly for testing, verification, and PPA comparison. + // An alternative to using the BTB to store the instruction class is to partially decode + // the instructions in the Fetch stage into, Jal, Ret, Jump, and Branch instructions. + // This logic is not described in the text book as of 23 February 2023. logic cjal, cj, cjr, cjalr, CJumpF, CBranchF; logic NCJumpF, NCBranchF; @@ -185,9 +188,10 @@ module bpred ( (`C_SUPPORTED & (cjal | (cjalr & (PostSpillInstrRawF[11:7] & 5'h1b) == 5'h01))); end else begin + // This section connects the BTB's instruction class prediction. assign {BPJalF, BPRetF, BPJumpF, BPBranchF} = {BTBJalF, BTBRetF, BTBJumpF, BTBBranchF}; end - assign SelBPPredF = (BPBranchF & DirPredictionF[1]) | BPJumpF; + assign BPPCSrcF = (BPBranchF & DirPredictionF[1]) | BPJumpF; // Part 3 RAS RASPredictor RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM, @@ -196,11 +200,7 @@ module bpred ( assign BPPredPCF = BPRetF ? RASPCF : BTAF; - //assign InstrClassD[0] = BranchD; - //assign InstrClassD[1] = JumpD ; - //assign InstrClassD[2] = JumpD & (InstrD[19:15] & 5'h1B) == 5'h01; // return must return to ra or x5 assign RetD = JumpD & (InstrD[19:15] & 5'h1B) == 5'h01; // return must return to ra or x5 - //assign InstrClassD[3] = JumpD & (InstrD[11:7] & 5'h1B) == 5'h01; // jal(r) must link to ra or x5 assign JalD = JumpD & (InstrD[11:7] & 5'h1B) == 5'h01; // jal(r) must link to ra or x5 flopenrc #(2) InstrClassRegE(clk, reset, FlushE, ~StallE, {JalD, RetD}, {JalE, RetE}); @@ -227,7 +227,6 @@ module bpred ( assign WrongBPRetD = BPRetD ^ RetD; // branch is wrong only if the PC does not match and both the Decode and Fetch stages have valid instructions. - //assign BPPredWrongE = (PredictionPCWrongE & |InstrClassE | (AnyWrongPredInstrClassE & ~|InstrClassE)); assign BPPredWrongE = PredictionPCWrongE & InstrValidE & InstrValidD; logic BPPredWrongEAlt; @@ -237,7 +236,7 @@ module bpred ( // Output the predicted PC or corrected PC on miss-predict. // Selects the BP or PC+2/4. - mux2 #(`XLEN) pcmux0(PCPlus2or4F, BPPredPCF, SelBPPredF, PCNext0F); + mux2 #(`XLEN) pcmux0(PCPlus2or4F, BPPredPCF, BPPCSrcF, PCNext0F); // If the prediction is wrong select the correct address. mux2 #(`XLEN) pcmux1(PCNext0F, PCCorrectE, BPPredWrongE, PCNext1F); // Correct branch/jump target. @@ -283,5 +282,6 @@ module bpred ( // **** Fix me assign InstrClassM = {JalM, RetM, JumpM, BranchM}; + flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); endmodule diff --git a/src/ifu/bpred/btb.sv b/src/ifu/bpred/btb.sv index 2bb006714..888287bcf 100644 --- a/src/ifu/bpred/btb.sv +++ b/src/ifu/bpred/btb.sv @@ -34,7 +34,7 @@ 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 + input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, PCW,// 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 @@ -47,12 +47,14 @@ module btb #(parameter Depth = 10 ) ( input logic [3:0] InstrClassM // Instruction class to insert into btb ); - logic [Depth-1:0] PCNextFIndex, PCFIndex, PCDIndex, PCEIndex, PCMIndex; + logic [Depth-1:0] PCNextFIndex, PCFIndex, PCDIndex, PCEIndex, PCMIndex, PCWIndex; logic [`XLEN-1:0] ResetPC; - logic MatchF, MatchD, MatchE, MatchM, MatchNextX, MatchXF; + logic MatchF, MatchD, MatchE, MatchM, MatchW, MatchNextX, MatchX; logic [`XLEN+3:0] ForwardBTBPrediction, ForwardBTBPredictionF; logic [`XLEN+3:0] TableBTBPredictionF; logic UpdateEn; + logic [3:0] InstrClassW; + logic [`XLEN-1:0] IEUAdrW; // hashing function for indexing the PC // We have Depth bits to index, but XLEN bits as the input. @@ -62,6 +64,7 @@ module btb #(parameter Depth = 10 ) ( assign PCDIndex = {PCD[Depth+1] ^ PCD[1], PCD[Depth:2]}; assign PCEIndex = {PCE[Depth+1] ^ PCE[1], PCE[Depth:2]}; assign PCMIndex = {PCM[Depth+1] ^ PCM[1], PCM[Depth:2]}; + assign PCWIndex = {PCW[Depth+1] ^ PCW[1], PCW[Depth:2]}; // must output a valid PC and valid bit during reset. Because only PCF, not PCNextF is reset, PCNextF is invalid // during reset. The BTB must produce a non X PC1NextF to allow the simulation to run. @@ -71,21 +74,24 @@ module btb #(parameter Depth = 10 ) ( assign PCNextFIndex = reset ? ResetPC[Depth+1:2] : {PCNextF[Depth+1] ^ PCNextF[1], PCNextF[Depth:2]}; assign MatchF = PCNextFIndex == PCFIndex; - assign MatchD = PCNextFIndex == PCDIndex; - assign MatchE = PCNextFIndex == PCEIndex; - assign MatchM = PCNextFIndex == PCMIndex; - assign MatchNextX = MatchF | MatchD | MatchE | MatchM; + assign MatchD = PCFIndex == PCDIndex; + assign MatchE = PCFIndex == PCEIndex; + assign MatchM = PCFIndex == PCMIndex; + assign MatchW = PCFIndex == PCWIndex; + assign MatchX = MatchD | MatchE | MatchM | MatchW; - flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF); +// flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF); - assign ForwardBTBPrediction = MatchF ? {BTBPredInstrClassF, BTAF} : - MatchD ? {InstrClassD, BTAD} : + assign ForwardBTBPredictionF = MatchD ? {InstrClassD, BTAD} : MatchE ? {InstrClassE, IEUAdrE} : - {InstrClassM, IEUAdrM} ; + MatchM ? {InstrClassM, IEUAdrM} : + {InstrClassW, IEUAdrW} ; +/* -----\/----- EXCLUDED -----\/----- flopenr #(`XLEN+4) ForwardBTBPredicitonReg(clk, reset, ~StallF, ForwardBTBPrediction, ForwardBTBPredictionF); + -----/\----- EXCLUDED -----/\----- */ - assign {BTBPredInstrClassF, BTAF} = MatchXF ? ForwardBTBPredictionF : {TableBTBPredictionF}; + assign {BTBPredInstrClassF, BTAF} = MatchX ? ForwardBTBPredictionF : {TableBTBPredictionF}; assign UpdateEn = |InstrClassM | PredictionInstrClassWrongM; @@ -97,4 +103,6 @@ module btb #(parameter Depth = 10 ) ( flopenrc #(`XLEN) BTBD(clk, reset, FlushD, ~StallD, BTAF, BTAD); + flopenrc #(`XLEN+4) IEUAdrWReg(clk, reset, FlushW, ~StallW, {InstrClassM, IEUAdrM}, {InstrClassW, IEUAdrW}); + endmodule From 31d6531af20f062185858e8f63732e14fb975070 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Fri, 24 Feb 2023 17:54:48 -0600 Subject: [PATCH 5/8] Prep to fix gshare critical path. --- src/ifu/bpred/bpred.sv | 12 ++++++++---- src/ifu/bpred/btb.sv | 8 +++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index aee8c4912..39ced3d92 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -94,9 +94,9 @@ module bpred ( logic RetD, JalD; logic RetE, JalE; logic BranchM, JumpM, RetM, JalM; + logic BranchW, JumpW, RetW, JalW; logic WrongBPRetD; - - logic [`XLEN-1:0] PCW; + logic [`XLEN-1:0] PCW, IEUAdrW; // Part 1 branch direction prediction // look into the 2 port Sram model. something is wrong. @@ -152,8 +152,9 @@ module bpred ( .BTAF, .BTAD, .BTBPredInstrClassF({BTBJalF, BTBRetF, BTBJumpF, BTBBranchF}), .PredictionInstrClassWrongM, - .IEUAdrE, .IEUAdrM, - .InstrClassD({JalD, RetD, JumpD, BranchD}), .InstrClassE({JalE, RetE, JumpE, BranchE}), .InstrClassM({JalM, RetM, JumpM, BranchM})); + .IEUAdrE, .IEUAdrM, .IEUAdrW, + .InstrClassD({JalD, RetD, JumpD, BranchD}), .InstrClassE({JalE, RetE, JumpE, BranchE}), .InstrClassM({JalM, RetM, JumpM, BranchM}), + .InstrClassW({JalW, RetW, JumpW, BranchW})); if (!`INSTR_CLASS_PRED) begin : DirectClassDecode // This section is mainly for testing, verification, and PPA comparison. @@ -205,6 +206,7 @@ module bpred ( flopenrc #(2) InstrClassRegE(clk, reset, FlushE, ~StallE, {JalD, RetD}, {JalE, RetE}); flopenrc #(4) InstrClassRegM(clk, reset, FlushM, ~StallM, {JalE, RetE, JumpE, BranchE}, {JalM, RetM, JumpM, BranchM}); + flopenrc #(4) InstrClassRegW(clk, reset, FlushM, ~StallW, {JalM, RetM, JumpM, BranchM}, {JalW, RetW, JumpW, BranchW}); flopenrc #(1) BPPredWrongMReg(clk, reset, FlushM, ~StallM, BPPredWrongE, BPPredWrongM); // branch predictor @@ -283,5 +285,7 @@ module bpred ( // **** Fix me assign InstrClassM = {JalM, RetM, JumpM, BranchM}; flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); + flopenrc #(`XLEN) IEUAdrWReg(clk, reset, FlushW, ~StallW, IEUAdrM, IEUAdrW); + endmodule diff --git a/src/ifu/bpred/btb.sv b/src/ifu/bpred/btb.sv index 888287bcf..362e416b4 100644 --- a/src/ifu/bpred/btb.sv +++ b/src/ifu/bpred/btb.sv @@ -42,9 +42,11 @@ module btb #(parameter Depth = 10 ) ( 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 [`XLEN-1:0] IEUAdrW, 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 [3:0] InstrClassM, // Instruction class to insert into btb + input logic [3:0] InstrClassW ); logic [Depth-1:0] PCNextFIndex, PCFIndex, PCDIndex, PCEIndex, PCMIndex, PCWIndex; @@ -53,8 +55,6 @@ module btb #(parameter Depth = 10 ) ( logic [`XLEN+3:0] ForwardBTBPrediction, ForwardBTBPredictionF; logic [`XLEN+3:0] TableBTBPredictionF; logic UpdateEn; - logic [3:0] InstrClassW; - logic [`XLEN-1:0] IEUAdrW; // hashing function for indexing the PC // We have Depth bits to index, but XLEN bits as the input. @@ -103,6 +103,4 @@ module btb #(parameter Depth = 10 ) ( flopenrc #(`XLEN) BTBD(clk, reset, FlushD, ~StallD, BTAF, BTAD); - flopenrc #(`XLEN+4) IEUAdrWReg(clk, reset, FlushW, ~StallW, {InstrClassM, IEUAdrM}, {InstrClassW, IEUAdrW}); - endmodule From a14dcaa2412bff84a37bf949dc4783b50240e390 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Fri, 24 Feb 2023 18:02:00 -0600 Subject: [PATCH 6/8] Completed critical path gshare fix. --- src/ifu/bpred/bpred.sv | 8 ++++---- src/ifu/bpred/gshare.sv | 40 ++++++++++++++++++++++------------------ 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index 39ced3d92..599b8853f 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -108,14 +108,14 @@ module bpred ( end else if (`BPRED_TYPE == "BP_GSHARE") begin:Predictor gshare #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, - .PCNextF, .PCF, .PCD, .PCE, .PCM, .DirPredictionF, .DirPredictionWrongE, - .BPBranchF, .BranchD, .BranchE, .BranchM, + .PCNextF, .PCF, .PCD, .PCE, .PCM, .PCW, .DirPredictionF, .DirPredictionWrongE, + .BPBranchF, .BranchD, .BranchE, .BranchM, .BranchW, .PCSrcE); end else if (`BPRED_TYPE == "BP_GLOBAL") begin:Predictor gshare #(`BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, - .PCNextF, .PCF, .PCD, .PCE, .PCM, .DirPredictionF, .DirPredictionWrongE, - .BPBranchF, .BranchD, .BranchE, .BranchM, + .PCNextF, .PCF, .PCD, .PCE, .PCM, .PCW, .DirPredictionF, .DirPredictionWrongE, + .BPBranchF, .BranchD, .BranchE, .BranchM, .BranchW, .PCSrcE); end else if (`BPRED_TYPE == "BP_GSHARE_BASIC") begin:Predictor diff --git a/src/ifu/bpred/gshare.sv b/src/ifu/bpred/gshare.sv index 2523693cf..e14f960f3 100644 --- a/src/ifu/bpred/gshare.sv +++ b/src/ifu/bpred/gshare.sv @@ -38,17 +38,17 @@ module gshare #(parameter k = 10, output logic [1:0] DirPredictionF, output logic DirPredictionWrongE, // update - input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, - input logic BPBranchF, BranchD, BranchE, BranchM, PCSrcE + input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, PCW, + input logic BPBranchF, BranchD, BranchE, BranchM, BranchW, PCSrcE ); - logic MatchF, MatchD, MatchE, MatchM; - logic MatchNextX, MatchXF; + logic MatchF, MatchD, MatchE, MatchM, MatchW; + logic MatchX, MatchXF; - logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE, ForwardNewDirPrediction, ForwardDirPredictionF; - logic [1:0] NewDirPredictionE, NewDirPredictionM; + logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE, ForwardNewDirPredictionF, ForwardDirPredictionF; + logic [1:0] NewDirPredictionE, NewDirPredictionM, NewDirPredictionW; - logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE, IndexM; + logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE, IndexM, IndexW; logic [k-1:0] GHRF, GHRD, GHRE, GHRM; logic [k-1:0] GHRNextM, GHRNextF; @@ -68,22 +68,25 @@ module gshare #(parameter k = 10, assign IndexM = GHRM; end - assign MatchF = BPBranchF & ~FlushD & (IndexNextF == IndexF); - assign MatchD = BranchD & ~FlushE & (IndexNextF == IndexD); - assign MatchE = BranchE & ~FlushM & (IndexNextF == IndexE); - assign MatchM = BranchM & ~FlushW & (IndexNextF == IndexM); - assign MatchNextX = MatchF | MatchD | MatchE | MatchM; + flopenrc #(k) IndexWReg(clk, reset, FlushW, ~StallW, IndexM, IndexW); - flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF); + //assign MatchF = BPBranchF & ~FlushD & (IndexNextF == IndexF); + assign MatchD = BranchD & ~FlushE & (IndexF == IndexD); + assign MatchE = BranchE & ~FlushM & (IndexF == IndexE); + assign MatchM = BranchM & ~FlushW & (IndexF == IndexM); + assign MatchW = BranchW & ~FlushW & (IndexF == IndexW); + assign MatchX = MatchD | MatchE | MatchM | MatchW; - assign ForwardNewDirPrediction = MatchF ? {2{DirPredictionF[1]}} : - MatchD ? {2{DirPredictionD[1]}} : +// flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF); + + assign ForwardNewDirPredictionF = MatchD ? {2{DirPredictionD[1]}} : MatchE ? {NewDirPredictionE} : - NewDirPredictionM ; + MatchM ? {NewDirPredictionM} : + NewDirPredictionW ; - flopenr #(2) ForwardDirPredicitonReg(clk, reset, ~StallF, ForwardNewDirPrediction, ForwardDirPredictionF); + //flopenr #(2) ForwardDirPredicitonReg(clk, reset, ~StallF, ForwardNewDirPrediction, ForwardDirPredictionF); - assign DirPredictionF = MatchXF ? ForwardDirPredictionF : TableDirPredictionF; + assign DirPredictionF = MatchX ? ForwardNewDirPredictionF : TableDirPredictionF; ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), .ce1(~StallF), .ce2(~StallM & ~FlushM), @@ -99,6 +102,7 @@ module gshare #(parameter k = 10, satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE)); flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewDirPredictionE, NewDirPredictionM); + flopenrc #(2) NewPredictionRegW(clk, reset, FlushW, ~StallW, NewDirPredictionM, NewDirPredictionW); assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchE; From ea8cb7dd78345480c7b95c3b320f5ec337d6f48a Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Fri, 24 Feb 2023 18:20:42 -0600 Subject: [PATCH 7/8] Cleanup. --- src/ifu/bpred/btb.sv | 9 +-------- src/ifu/bpred/gshare.sv | 9 ++------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/src/ifu/bpred/btb.sv b/src/ifu/bpred/btb.sv index 362e416b4..e70716144 100644 --- a/src/ifu/bpred/btb.sv +++ b/src/ifu/bpred/btb.sv @@ -51,7 +51,7 @@ module btb #(parameter Depth = 10 ) ( logic [Depth-1:0] PCNextFIndex, PCFIndex, PCDIndex, PCEIndex, PCMIndex, PCWIndex; logic [`XLEN-1:0] ResetPC; - logic MatchF, MatchD, MatchE, MatchM, MatchW, MatchNextX, MatchX; + logic MatchF, MatchD, MatchE, MatchM, MatchW, MatchX; logic [`XLEN+3:0] ForwardBTBPrediction, ForwardBTBPredictionF; logic [`XLEN+3:0] TableBTBPredictionF; logic UpdateEn; @@ -79,21 +79,14 @@ module btb #(parameter Depth = 10 ) ( assign MatchM = PCFIndex == PCMIndex; assign MatchW = PCFIndex == PCWIndex; assign MatchX = MatchD | MatchE | MatchM | MatchW; - -// flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF); assign ForwardBTBPredictionF = MatchD ? {InstrClassD, BTAD} : MatchE ? {InstrClassE, IEUAdrE} : MatchM ? {InstrClassM, IEUAdrM} : {InstrClassW, IEUAdrW} ; -/* -----\/----- EXCLUDED -----\/----- - flopenr #(`XLEN+4) ForwardBTBPredicitonReg(clk, reset, ~StallF, ForwardBTBPrediction, ForwardBTBPredictionF); - -----/\----- EXCLUDED -----/\----- */ - assign {BTBPredInstrClassF, BTAF} = MatchX ? ForwardBTBPredictionF : {TableBTBPredictionF}; - assign UpdateEn = |InstrClassM | PredictionInstrClassWrongM; // An optimization may be using a PC relative address. diff --git a/src/ifu/bpred/gshare.sv b/src/ifu/bpred/gshare.sv index e14f960f3..70c03afb0 100644 --- a/src/ifu/bpred/gshare.sv +++ b/src/ifu/bpred/gshare.sv @@ -43,9 +43,9 @@ module gshare #(parameter k = 10, ); logic MatchF, MatchD, MatchE, MatchM, MatchW; - logic MatchX, MatchXF; + logic MatchX; - logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE, ForwardNewDirPredictionF, ForwardDirPredictionF; + logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE, ForwardNewDirPredictionF; logic [1:0] NewDirPredictionE, NewDirPredictionM, NewDirPredictionW; logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE, IndexM, IndexW; @@ -70,22 +70,17 @@ module gshare #(parameter k = 10, flopenrc #(k) IndexWReg(clk, reset, FlushW, ~StallW, IndexM, IndexW); - //assign MatchF = BPBranchF & ~FlushD & (IndexNextF == IndexF); assign MatchD = BranchD & ~FlushE & (IndexF == IndexD); assign MatchE = BranchE & ~FlushM & (IndexF == IndexE); assign MatchM = BranchM & ~FlushW & (IndexF == IndexM); assign MatchW = BranchW & ~FlushW & (IndexF == IndexW); assign MatchX = MatchD | MatchE | MatchM | MatchW; -// flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF); - assign ForwardNewDirPredictionF = MatchD ? {2{DirPredictionD[1]}} : MatchE ? {NewDirPredictionE} : MatchM ? {NewDirPredictionM} : NewDirPredictionW ; - //flopenr #(2) ForwardDirPredicitonReg(clk, reset, ~StallF, ForwardNewDirPrediction, ForwardDirPredictionF); - assign DirPredictionF = MatchX ? ForwardNewDirPredictionF : TableDirPredictionF; ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), From 4031b89f183ce5650c50e00922263d037e3a6e01 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Fri, 24 Feb 2023 18:36:41 -0600 Subject: [PATCH 8/8] Possible fix to btb performance issue. --- src/ifu/bpred/bpred.sv | 2 +- src/ifu/bpred/btb.sv | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index 599b8853f..c802ffb21 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -285,7 +285,7 @@ module bpred ( // **** Fix me assign InstrClassM = {JalM, RetM, JumpM, BranchM}; flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); - flopenrc #(`XLEN) IEUAdrWReg(clk, reset, FlushW, ~StallW, IEUAdrM, IEUAdrW); + flopenr #(`XLEN) IEUAdrWReg(clk, reset, ~StallW, IEUAdrM, IEUAdrW); endmodule diff --git a/src/ifu/bpred/btb.sv b/src/ifu/bpred/btb.sv index e70716144..d2f0cb77b 100644 --- a/src/ifu/bpred/btb.sv +++ b/src/ifu/bpred/btb.sv @@ -51,7 +51,7 @@ module btb #(parameter Depth = 10 ) ( logic [Depth-1:0] PCNextFIndex, PCFIndex, PCDIndex, PCEIndex, PCMIndex, PCWIndex; logic [`XLEN-1:0] ResetPC; - logic MatchF, MatchD, MatchE, MatchM, MatchW, MatchX; + logic MatchD, MatchE, MatchM, MatchW, MatchX; logic [`XLEN+3:0] ForwardBTBPrediction, ForwardBTBPredictionF; logic [`XLEN+3:0] TableBTBPredictionF; logic UpdateEn; @@ -73,7 +73,6 @@ module btb #(parameter Depth = 10 ) ( assign ResetPC = `RESET_VECTOR; assign PCNextFIndex = reset ? ResetPC[Depth+1:2] : {PCNextF[Depth+1] ^ PCNextF[1], PCNextF[Depth:2]}; - assign MatchF = PCNextFIndex == PCFIndex; assign MatchD = PCFIndex == PCDIndex; assign MatchE = PCFIndex == PCEIndex; assign MatchM = PCFIndex == PCMIndex; @@ -81,9 +80,9 @@ module btb #(parameter Depth = 10 ) ( assign MatchX = MatchD | MatchE | MatchM | MatchW; assign ForwardBTBPredictionF = MatchD ? {InstrClassD, BTAD} : - MatchE ? {InstrClassE, IEUAdrE} : - MatchM ? {InstrClassM, IEUAdrM} : - {InstrClassW, IEUAdrW} ; + MatchE ? {InstrClassE, IEUAdrE} : + MatchM ? {InstrClassM, IEUAdrM} : + {InstrClassW, IEUAdrW} ; assign {BTBPredInstrClassF, BTAF} = MatchX ? ForwardBTBPredictionF : {TableBTBPredictionF};