Major cleanup of branch predictor.

This commit is contained in:
Ross Thompson 2023-01-30 23:37:34 -06:00
parent 42828e6ec4
commit a15889e0aa

View File

@ -48,18 +48,14 @@ module speculativegshare #(parameter int k = 10 ) (
logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE; logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE;
logic [1:0] NewDirPredictionF, NewDirPredictionD, NewDirPredictionE; logic [1:0] NewDirPredictionF, NewDirPredictionD, NewDirPredictionE;
logic [k-1:0] GHRF; logic [k-1:0] GHRF, GHRD, GHRE;
logic GHRExtraF; logic GHRLastF;
logic [k-1:0] GHRD, GHRE, GHRM, GHRW; logic [k-1:0] GHRNextF, GHRNextD, GHRNextE;
logic [k-1:0] GHRNextF; logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE;
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 [1:0] ForwardNewDirPrediction, ForwardDirPredictionF; logic [1:0] ForwardNewDirPrediction, ForwardDirPredictionF;
logic FlushDOrDirWrong;
assign IndexNextF = GHRNextF ^ {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]}; assign IndexNextF = GHRNextF ^ {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]};
assign IndexF = GHRF ^ {PCF[k+1] ^ PCF[1], PCF[k:2]}; assign IndexF = GHRF ^ {PCF[k+1] ^ PCF[1], PCF[k:2]};
assign IndexD = GHRD[k-1:0] ^ {PCD[k+1] ^ PCD[1], PCD[k:2]}; assign IndexD = GHRD[k-1:0] ^ {PCD[k+1] ^ PCD[1], PCD[k:2]};
@ -102,42 +98,33 @@ module speculativegshare #(parameter int k = 10 ) (
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 ? GHRNextE[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 = GHRNextE[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, BranchInstrF}, GHRNextF);
// Need 1 extra bit to store the shifted out GHRF if repair needs to back shift.
flopenr #(k) GHRFReg(clk, reset, (~StallF) | FlushD, GHRNextF, GHRF); flopenr #(k) GHRFReg(clk, reset, (~StallF) | FlushD, GHRNextF, GHRF);
flopenr #(1) GHRFExtraReg(clk, reset, (~StallF) | FlushD, GHRF[0], GHRExtraF); flopenr #(1) GHRFLastReg(clk, reset, (~StallF) | FlushD, 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}, BranchInstrD, 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) | FlushD, 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]}, {BranchInstrE & ~FlushM, FlushE}, GHRNextE);
FlushE ? GHRE : // branch is flushed
GHRD;
flopenr #(k) GHREReg(clk, reset, (BranchInstrE & ~StallE) | FlushE, GHRNextE, GHRE); flopenr #(k) GHREReg(clk, reset, (BranchInstrE & ~StallE) | FlushE, GHRNextE, GHRE);
//assign GHRNextM = FlushM ? GHRM : GHRE;
//flopenr #(k) GHRMReg(clk, reset, (BranchInstrM & ~StallM) | FlushM, GHRNextM, GHRM);
//assign GHRNextW = FlushW ? GHRW : GHRM;
//flopenr #(k) GHRWReg(clk, reset, (BranchInstrW & ~StallW) | FlushW, GHRNextW, GHRW);
assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchInstrE; assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchInstrE;
endmodule endmodule