It's a bit sloppy, but the global history predictor is working correctly now.

There were two major bugs with the predictor.
First the update mechanism was completely wrong.  The PHT is updated with the GHR that was used to lookup the prediction.  PHT[GHR] = Sat2(PHT[GHR], branch outcome).
Second the GHR needs to be updated speculatively as the branch is predicted.  This is important so that back to back branches' GHRs are not the same.  The must be different to avoid aliasing.  Speculation of the GHR update allows them to be different.  On mis prediction the GHR must be reverted.
This implementation is a bit sloppy with names and now the GHR recovery is performed.  Updates to follow.
This commit is contained in:
Ross Thompson 2021-05-27 23:06:28 -05:00
parent 7e84c3f514
commit 8a035104ac
4 changed files with 51 additions and 17 deletions

View File

@ -110,5 +110,6 @@
`define TWO_BIT_PRELOAD "../config/rv64icfd/twoBitPredictor.txt"
`define BTB_PRELOAD "../config/rv64icfd/BTBPredictor.txt"
`define BPRED_ENABLED 1
`define BPTYPE "BPGSHARE" // BPGLOBAL or BPTWOBIT or BPGSHARE
//`define BPTYPE "BPGSHARE" // BPGLOBAL or BPTWOBIT or BPGSHARE
`define BPTYPE "BPGLOBAL" // BPTWOBIT or "BPGSHARE" or BPLOCALPAg or BPGSHARE
`define TESTSBP 1

View File

@ -30,7 +30,8 @@
module bpred
(input logic clk, reset,
input logic StallF, StallD, StallE, FlushF, FlushD, FlushE,
input logic StallF, StallD, StallE, StallM, StallW,
input logic FlushF, FlushD, FlushE, FlushM, FlushW,
// Fetch stage
// the prediction
input logic [`XLEN-1:0] PCNextF, // *** forgot to include this one on the I/O list
@ -93,6 +94,8 @@ module bpred
// update
.UpdatePC(PCE),
.UpdateEN(InstrClassE[0] & ~StallE),
.SpeculativeUpdateEn(BPInstrClassF[0] & ~StallF),
.BPPredDirWrongE(BPPredDirWrongE),
.PCSrcE(PCSrcE),
.UpdatePrediction(UpdateBPPredE));
end else if (`BPTYPE == "BPGSHARE") begin:Predictor
@ -190,14 +193,14 @@ module bpred
flopenrc #(2) BPPredRegD(.clk(clk),
.reset(reset),
.en(~StallD),
.clear(FlushD),
.clear(1'b0),
.d(BPPredF),
.q(BPPredD));
flopenrc #(2) BPPredRegE(.clk(clk),
.reset(reset),
.en(~StallE),
.clear(FlushE),
.clear(1'b0),
.d(BPPredD),
.q(BPPredE));

View File

@ -37,29 +37,66 @@ module globalHistoryPredictor
output logic [1:0] Prediction,
// update
input logic [`XLEN-1:0] UpdatePC,
input logic UpdateEN, PCSrcE,
input logic UpdateEN, PCSrcE,
input logic SpeculativeUpdateEn, BPPredDirWrongE,
input logic [1:0] UpdatePrediction
);
logic [k-1:0] GHRF, GHRFNext;
assign GHRFNext = {PCSrcE, GHRF[k-1:1]};
logic [k-1:0] GHRF, GHRFNext, GHRD, GHRE, GHRLookup;
logic FlushedD, FlushedE;
// if the prediction is wrong we need to restore the ghr.
assign GHRFNext = BPPredDirWrongE ? {PCSrcE, GHRE[k-1:1]} :
{Prediction[1], GHRF[k-1:1]};
flopenr #(k) GlobalHistoryRegister(.clk(clk),
.reset(reset),
.en(UpdateEN),
.en((UpdateEN & BPPredDirWrongE) | (SpeculativeUpdateEn)),
.d(GHRFNext),
.q(GHRF));
// if actively updating the GHR at the time of prediction we want to us
// GHRFNext as the lookup rather than GHRF.
assign GHRLookup = UpdateEN ? GHRFNext : GHRF;
// Make Prediction by reading the correct address in the PHT and also update the new address in the PHT
SRAM2P1R1W #(k, 2) PHT(.clk(clk),
.reset(reset),
.RA1(GHRF),
.RD1(Prediction),
.REN1(~StallF),
.WA1(GHRF),
.WA1(GHRE),
.WD1(UpdatePrediction),
.WEN1(UpdateEN),
.BitWEN1(2'b11));
flopenr #(k) GlobalHistoryRegisterD(.clk(clk),
.reset(reset),
.en(~StallD & ~FlushedE),
.d(GHRF),
.q(GHRD));
flopenr #(k) GlobalHistoryRegisterE(.clk(clk),
.reset(reset),
.en(~StallE & ~ FlushedE),
.d(GHRD),
.q(GHRE));
flopenr #(1) flushedDReg(.clk(clk),
.reset(reset),
.en(~StallD),
.d(FlushD),
.q(FlushedD));
flopenr #(1) flushedEReg(.clk(clk),
.reset(reset),
.en(~StallE),
.d(FlushE | FlushedD),
.q(FlushedE));
endmodule

View File

@ -153,14 +153,7 @@ module ifu (
generate
if (`BPRED_ENABLED == 1) begin : bpred
// I am making the port connection explicit for now as I want to see them and they will be changing.
bpred bpred(.clk(clk),
.reset(reset),
.StallF(StallF),
.StallD(StallD),
.StallE(StallE),
.FlushF(FlushF),
.FlushD(FlushD),
.FlushE(FlushE),
bpred bpred(.*,
.PCNextF(PCNextF),
.BPPredPCF(BPPredPCF),
.SelBPPredF(SelBPPredF),