forked from Github_Repos/cvw
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:
parent
7e84c3f514
commit
8a035104ac
@ -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
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user