mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Major cleanup of branch predictor.
This commit is contained in:
parent
42828e6ec4
commit
a15889e0aa
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user