Updated globalhistory predictor.

This commit is contained in:
Ross Thompson 2023-02-09 14:48:02 -06:00
parent 2b27842d64
commit faf7cd8c8a
2 changed files with 44 additions and 61 deletions

View File

@ -103,8 +103,7 @@ module bpred (
end else if (`BPRED_TYPE == "BPSPECULATIVEGLOBAL") begin:Predictor end else if (`BPRED_TYPE == "BPSPECULATIVEGLOBAL") begin:Predictor
speculativeglobalhistory #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, speculativeglobalhistory #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.DirPredictionF, .DirPredictionWrongE, .DirPredictionF, .DirPredictionWrongE,
.BranchInstrF(PredInstrClassF[0]), .BranchInstrD(InstrClassD[0]), .BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PredInstrClassF, .InstrClassD, .InstrClassE, .WrongPredInstrClassD, .PCSrcE);
.BranchInstrW(InstrClassW[0]), .WrongPredInstrClassD, .PCSrcE);
end else if (`BPRED_TYPE == "BPGSHARE") begin:Predictor end else if (`BPRED_TYPE == "BPGSHARE") begin:Predictor
gshare #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM, gshare #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,

View File

@ -36,7 +36,7 @@ module speculativeglobalhistory #(parameter int k = 10 ) (
output logic [1:0] DirPredictionF, output logic [1:0] DirPredictionF,
output logic DirPredictionWrongE, output logic DirPredictionWrongE,
// update // update
input logic BranchInstrF, BranchInstrD, BranchInstrE, BranchInstrM, BranchInstrW, input logic [3:0] PredInstrClassF, InstrClassD, InstrClassE,
input logic [3:0] WrongPredInstrClassD, input logic [3:0] WrongPredInstrClassD,
input logic PCSrcE input logic PCSrcE
); );
@ -45,20 +45,16 @@ module speculativeglobalhistory #(parameter int k = 10 ) (
logic MatchNextX, MatchXF; logic MatchNextX, MatchXF;
logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE; logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE;
logic [1:0] NewDirPredictionF, NewDirPredictionD, NewDirPredictionE; logic [1:0] NewDirPredictionE;
logic [k-1:0] GHRF;
logic GHRExtraF;
logic [k-1:0] GHRD, GHRE, GHRM, GHRW;
logic [k-1:0] GHRNextF;
logic [k-1:0] GHRNextD;
logic [k-1:0] GHRNextE, GHRNextM, GHRNextW;
logic [k-1:0] IndexNextF, IndexF;
logic [k-1:0] IndexD, IndexE;
logic [k-1:0] GHRF, GHRD, GHRE;
logic GHRLastF;
logic [k-1:0] GHRNextF, GHRNextD, GHRNextE;
logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE;
logic [1:0] ForwardNewDirPrediction, ForwardDirPredictionF; logic [1:0] ForwardNewDirPrediction, ForwardDirPredictionF;
logic FlushDOrDirWrong;
assign IndexNextF = GHRNextF; assign IndexNextF = GHRNextF;
assign IndexF = GHRF; assign IndexF = GHRF;
assign IndexD = GHRD[k-1:0]; assign IndexD = GHRD[k-1:0];
@ -70,20 +66,20 @@ module speculativeglobalhistory #(parameter int k = 10 ) (
.rd1(TableDirPredictionF), .rd1(TableDirPredictionF),
.wa2(IndexE), .wa2(IndexE),
.wd2(NewDirPredictionE), .wd2(NewDirPredictionE),
.we2(BranchInstrE & ~StallM & ~FlushM), .we2(InstrClassE[0]),
.bwe2(1'b1)); .bwe2(1'b1));
// if there are non-flushed branches in the pipeline we need to forward the prediction from that stage to the NextF demi stage // if there are non-flushed branches in the pipeline we need to forward the prediction from that stage to the NextF demi stage
// and then register for use in the Fetch stage. // and then register for use in the Fetch stage.
assign MatchF = BranchInstrF & ~FlushD & (IndexNextF == IndexF); assign MatchF = PredInstrClassF[0] & ~FlushD & (IndexNextF == IndexF);
assign MatchD = BranchInstrD & ~FlushE & (IndexNextF == IndexD); assign MatchD = InstrClassD[0] & ~FlushE & (IndexNextF == IndexD);
assign MatchE = BranchInstrE & ~FlushM & (IndexNextF == IndexE); assign MatchE = InstrClassE[0] & ~FlushM & (IndexNextF == IndexE);
assign MatchNextX = MatchF | MatchD | MatchE; assign MatchNextX = MatchF | MatchD | MatchE;
flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF); flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF);
assign ForwardNewDirPrediction = MatchF ? NewDirPredictionF : assign ForwardNewDirPrediction = MatchF ? {2{DirPredictionF[1]}} :
MatchD ? NewDirPredictionD : MatchD ? {2{DirPredictionD[1]}} :
NewDirPredictionE ; NewDirPredictionE ;
flopenr #(2) ForwardDirPredicitonReg(clk, reset, ~StallF, ForwardNewDirPrediction, ForwardDirPredictionF); flopenr #(2) ForwardDirPredicitonReg(clk, reset, ~StallF, ForwardNewDirPrediction, ForwardDirPredictionF);
@ -94,49 +90,37 @@ module speculativeglobalhistory #(parameter int k = 10 ) (
flopenr #(2) PredictionRegD(clk, reset, ~StallD, DirPredictionF, DirPredictionD); flopenr #(2) PredictionRegD(clk, reset, ~StallD, DirPredictionF, DirPredictionD);
flopenr #(2) PredictionRegE(clk, reset, ~StallE, DirPredictionD, DirPredictionE); flopenr #(2) PredictionRegE(clk, reset, ~StallE, DirPredictionD, DirPredictionE);
// New prediction pipeline
assign NewDirPredictionF = {DirPredictionF[1], DirPredictionF[1]};
flopenr #(2) NewPredDReg(clk, reset, ~StallD, NewDirPredictionF, NewDirPredictionD);
satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE)); satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE));
// GHR pipeline // GHR pipeline
// this version fails the regression test do to pessimistic x propagation.
// assign GHRNextF = FlushD | DirPredictionWrongE ? GHRNextD[k-1:0] :
// BranchInstrF ? {DirPredictionF[1], GHRF[k-1:1]} :
// GHRF;
always_comb begin // If Fetch has a branch, speculatively insert prediction into the GHR
if(FlushD | DirPredictionWrongE) begin // If the front end is flushed or the direction prediction is wrong, reset to
GHRNextF = GHRNextD[k-1:0]; // most recent valid GHR. For a BP wrong this is GHRD with the correct prediction shifted in.
end else if(BranchInstrF) GHRNextF = {DirPredictionF[1], GHRF[k-1:1]}; // For FlushE this is GHRE. GHRNextE is both.
else GHRNextF = GHRF; assign FlushDOrDirWrong = FlushD | DirPredictionWrongE;
end mux3 #(k) GHRFMux(GHRF, {DirPredictionF[1], GHRF[k-1:1]}, GHRNextE[k-1:0],
{FlushDOrDirWrong, PredInstrClassF[0]}, GHRNextF);
flopenr #(k) GHRFReg(clk, reset, (~StallF) | FlushD, GHRNextF, GHRF); // Need 1 extra bit to store the shifted out GHRF if repair needs to back shift.
flopenr #(1) GHRFExtraReg(clk, reset, (~StallF) | FlushD, GHRF[0], GHRExtraF); flopenr #(k) GHRFReg(clk, reset, ~StallF | FlushDOrDirWrong, GHRNextF, GHRF);
flopenr #(1) GHRFLastReg(clk, reset, ~StallF | FlushDOrDirWrong, GHRF[0], GHRLastF);
// use with out instruction class prediction // With instruction class prediction, the class could be wrong and is checked in Decode.
//assign GHRNextD = FlushD ? GHRNextE[k-1:0] : GHRF[k-1:0]; // If it is wrong and branch does exist then shift right and insert the prediction.
// with instruction class prediction // If the branch does not exist then shift left and use GHRLastF to restore the LSB.
assign GHRNextD = (FlushD | DirPredictionWrongE) ? GHRNextE[k-1:0] : logic [k-1:0] GHRClassWrong;
WrongPredInstrClassD[0] & BranchInstrD ? {DirPredictionD[1], GHRF[k-1:1]} : // shift right mux2 #(k) GHRClassWrongMux({DirPredictionD[1], GHRF[k-1:1]}, {GHRF[k-2:0], GHRLastF}, InstrClassD[0], GHRClassWrong);
WrongPredInstrClassD[0] & ~BranchInstrD ? {GHRF[k-2:0], GHRExtraF}: // shift left // As with GHRF FlushD and wrong direction prediction flushes the pipeline and restores to GHRNextE.
GHRF[k-1:0]; mux3 #(k) GHRDMux(GHRF, GHRClassWrong, GHRNextE, {FlushDOrDirWrong, WrongPredInstrClassD[0]}, GHRNextD);
flopenr #(k) GHRDReg(clk, reset, (~StallD) | FlushD, GHRNextD, GHRD); flopenr #(k) GHRDReg(clk, reset, ~StallD | FlushDOrDirWrong, GHRNextD, GHRD);
assign GHRNextE = BranchInstrE & ~FlushM ? {PCSrcE, GHRD[k-2:0]} : // if the branch is not flushed mux3 #(k) GHREMux(GHRD, GHRE, {PCSrcE, GHRD[k-2:0]}, {InstrClassE[0] & ~FlushM, FlushE}, GHRNextE);
FlushE ? GHRNextM : // branch is flushed
GHRD;
flopenr #(k) GHREReg(clk, reset, (~StallE) | FlushE, GHRNextE, GHRE);
assign GHRNextM = FlushM ? GHRNextW : GHRE; flopenr #(k) GHREReg(clk, reset, ((InstrClassE[0] & ~FlushM) & ~StallE) | FlushE, GHRNextE, GHRE);
flopenr #(k) GHRMReg(clk, reset, (~StallM) | FlushM, GHRNextM, GHRM);
assign GHRNextW = FlushW ? GHRW : GHRM; assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & InstrClassE[0];
flopenr #(k) GHRWReg(clk, reset, (BranchInstrW & ~StallW) | FlushW, GHRNextW, GHRW);
assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchInstrE;
endmodule endmodule