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

@ -29,35 +29,31 @@
`include "wally-config.vh" `include "wally-config.vh"
module speculativeglobalhistory #(parameter int k = 10 ) ( module speculativeglobalhistory #(parameter int k = 10 ) (
input logic clk, input logic clk,
input logic reset, input logic reset,
input logic StallF, StallD, StallE, StallM, StallW, input logic StallF, StallD, StallE, StallM, StallW,
input logic FlushD, FlushE, FlushM, FlushW, input logic FlushD, FlushE, FlushM, FlushW,
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
); );
logic MatchF, MatchD, MatchE; logic MatchF, MatchD, MatchE;
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;
@ -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;
flopenr #(k) GHRWReg(clk, reset, (BranchInstrW & ~StallW) | FlushW, GHRNextW, GHRW);
assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchInstrE; assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & InstrClassE[0];
endmodule endmodule