forked from Github_Repos/cvw
may have fixed the global branch history predictor.
The solution required a completed rewrite and understanding of how the GHR needs to be speculatively updated and repaired.
This commit is contained in:
parent
8a035104ac
commit
f6c88666cf
@ -5,5 +5,7 @@ int fail();
|
||||
int simple_csrbr_test();
|
||||
int lbu_test();
|
||||
int icache_spill_test();
|
||||
void global_hist_test();
|
||||
void global_hist_1_space_test();
|
||||
void global_hist_2_space_test();
|
||||
void global_hist_3_space_test();
|
||||
#endif
|
||||
|
@ -2,7 +2,9 @@
|
||||
|
||||
int main(){
|
||||
//int res = icache_spill_test();
|
||||
global_hist_test();
|
||||
global_hist_3_space_test();
|
||||
global_hist_2_space_test();
|
||||
global_hist_1_space_test();
|
||||
int res = 1;
|
||||
if (res < 0) {
|
||||
fail();
|
||||
|
@ -90,12 +90,13 @@ module bpred
|
||||
.reset(reset),
|
||||
.*, // Stalls and flushes
|
||||
.LookUpPC(PCNextF),
|
||||
.Prediction(BPPredF),
|
||||
.BPPredF(BPPredF),
|
||||
// update
|
||||
.UpdatePC(PCE),
|
||||
.UpdateEN(InstrClassE[0] & ~StallE),
|
||||
.SpeculativeUpdateEn(BPInstrClassF[0] & ~StallF),
|
||||
.BPPredD(BPPredD),
|
||||
.InstrClassE(InstrClassE),
|
||||
.BPInstrClassE(BPInstrClassE),
|
||||
.BPPredDirWrongE(BPPredDirWrongE),
|
||||
.UpdatePC(PCE),
|
||||
.PCSrcE(PCSrcE),
|
||||
.UpdatePrediction(UpdateBPPredE));
|
||||
end else if (`BPTYPE == "BPGSHARE") begin:Predictor
|
||||
@ -108,6 +109,8 @@ module bpred
|
||||
// update
|
||||
.UpdatePC(PCE),
|
||||
.UpdateEN(InstrClassE[0] & ~StallE),
|
||||
.SpeculativeUpdateEn(BPInstrClassF[0] & ~StallF),
|
||||
.BPPredDirWrongE(BPPredDirWrongE),
|
||||
.PCSrcE(PCSrcE),
|
||||
.UpdatePrediction(UpdateBPPredE));
|
||||
end
|
||||
|
@ -34,49 +34,108 @@ module globalHistoryPredictor
|
||||
input logic reset,
|
||||
input logic StallF, StallD, StallE, FlushF, FlushD, FlushE,
|
||||
input logic [`XLEN-1:0] LookUpPC,
|
||||
output logic [1:0] Prediction,
|
||||
output logic [1:0] BPPredF,
|
||||
// update
|
||||
input logic [1:0] BPPredD,
|
||||
input logic [4:0] InstrClassE,
|
||||
input logic [4:0] BPInstrClassE,
|
||||
input logic [4:0] BPInstrClassD,
|
||||
input logic [4:0] BPInstrClassF,
|
||||
input logic BPPredDirWrongE,
|
||||
|
||||
input logic [`XLEN-1:0] UpdatePC,
|
||||
input logic UpdateEN, PCSrcE,
|
||||
input logic SpeculativeUpdateEn, BPPredDirWrongE,
|
||||
input logic PCSrcE,
|
||||
input logic [1:0] UpdatePrediction
|
||||
|
||||
);
|
||||
logic [k-1:0] GHRF, GHRFNext, GHRD, GHRE, GHRLookup;
|
||||
logic [k+1:0] GHR, GHRNext;
|
||||
logic [k-1:0] PHTUpdateAdr, PHTUpdateAdr0, PHTUpdateAdr1;
|
||||
logic PHTUpdateEN;
|
||||
logic BPClassWrongNonCFI;
|
||||
logic BPClassWrongCFI;
|
||||
logic BPClassRightNonCFI;
|
||||
|
||||
|
||||
/* -----\/----- EXCLUDED -----\/-----
|
||||
logic [k-1:0] GHRD, GHRE, GHRLookup;
|
||||
|
||||
logic FlushedD, FlushedE;
|
||||
-----/\----- EXCLUDED -----/\----- */
|
||||
|
||||
|
||||
logic [6:0] GHRMuxSel;
|
||||
logic GHRUpdateEN;
|
||||
|
||||
assign BPClassRightNonCFI = ~BPInstrClassE[0] & ~InstrClassE[0];
|
||||
assign BPClassWrongCFI = ~BPInstrClassE[0] & InstrClassE[0];
|
||||
assign BPClassWrongNonCFI = BPInstrClassE[0] & ~InstrClassE[0];
|
||||
assign BPClassRightBPWrong = BPInstrClassE[0] & InstrClassE[0] & BPPredDirWrongE;
|
||||
assign BPClassRightBPRight = BPInstrClassE[0] & InstrClassE[0] & ~BPPredDirWrongE;
|
||||
|
||||
|
||||
// GHR update selection, 1 hot encoded.
|
||||
assign GHRMuxSel[0] = ~BPInstrClassF[0] & (BPClassRightNonCFI | BPClassRightBPRight);
|
||||
|
||||
// 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]};
|
||||
assign GHRMuxSel[1] = BPClassWrongCFI & ~BPInstrClassD[0];
|
||||
assign GHRMuxSel[3] = (BPClassRightBPWrong & ~BPInstrClassD[0]) | (BPClassWrongCFI & BPInstrClassD[0]);
|
||||
|
||||
flopenr #(k) GlobalHistoryRegister(.clk(clk),
|
||||
.reset(reset),
|
||||
.en((UpdateEN & BPPredDirWrongE) | (SpeculativeUpdateEn)),
|
||||
.d(GHRFNext),
|
||||
.q(GHRF));
|
||||
|
||||
assign GHRMuxSel[2] = BPClassWrongNonCFI & ~BPInstrClassD[0];
|
||||
|
||||
|
||||
|
||||
assign GHRMuxSel[4] = BPClassWrongNonCFI & BPInstrClassD[0];
|
||||
assign GHRMuxSel[5] = InstrClassE[0] & BPClassRightBPWrong & BPInstrClassD[0];
|
||||
assign GHRMuxSel[6] = BPInstrClassF[0] & (BPClassRightNonCFI | (InstrClassE[0] & BPClassRightBPRight));
|
||||
assign GHRUpdateEN = (| GHRMuxSel[5:1] & ~StallE) | GHRMuxSel[6] & ~StallF;
|
||||
|
||||
// hoping this created a AND-OR mux.
|
||||
always_comb begin
|
||||
case (GHRMuxSel)
|
||||
7'b000_0001: GHRNext = GHR[k-1+2:0]; // no change
|
||||
7'b000_0010: GHRNext = {GHR[k-2+2:0], PCSrcE}; // branch update
|
||||
7'b000_0100: GHRNext = {1'b0, GHR[k+1:1]}; // repair 1
|
||||
7'b000_1000: GHRNext = {GHR[k-1+2:1], PCSrcE}; // branch update with mis prediction correction
|
||||
7'b001_0000: GHRNext = {2'b00, GHR[k+1:2]}; // repair 2
|
||||
7'b010_0000: GHRNext = {1'b0, GHR[k+1:2], PCSrcE}; // branch update + repair 1
|
||||
7'b100_0000: GHRNext = {GHR[k-2+2:0], BPPredF[1]}; // speculative update
|
||||
//7'b100_0000: GHRNext = {k+1{1'bx}}; // speculative update
|
||||
default: GHRNext = GHR[k-1+2:0];
|
||||
endcase
|
||||
end
|
||||
|
||||
flopenr #(k+2) GlobalHistoryRegister(.clk(clk),
|
||||
.reset(reset),
|
||||
.en((GHRUpdateEN)),
|
||||
.d(GHRNext),
|
||||
.q(GHR));
|
||||
|
||||
// if actively updating the GHR at the time of prediction we want to us
|
||||
// GHRFNext as the lookup rather than GHRF.
|
||||
// GHRNext as the lookup rather than GHR.
|
||||
|
||||
assign GHRLookup = UpdateEN ? GHRFNext : GHRF;
|
||||
//assign GHRLookup = GHRUpdateEN ? GHRNext : GHR;
|
||||
|
||||
assign PHTUpdateAdr0 = InstrClassE[0] ? GHR[k:1] : GHR[k-1:0];
|
||||
assign PHTUpdateAdr1 = InstrClassE[0] ? GHR[k+1:2] : GHR[k:1];
|
||||
assign PHTUpdateAdr = BPInstrClassD[0] ? PHTUpdateAdr1 : PHTUpdateAdr0;
|
||||
assign PHTUpdateEN = InstrClassE[0] & ~StallE;
|
||||
|
||||
// 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),
|
||||
.RA1(GHR[k-1:0]),
|
||||
.RD1(BPPredF),
|
||||
.REN1(~StallF),
|
||||
.WA1(GHRE),
|
||||
.WA1(PHTUpdateAdr),
|
||||
.WD1(UpdatePrediction),
|
||||
.WEN1(UpdateEN),
|
||||
.WEN1(PHTUpdateEN),
|
||||
.BitWEN1(2'b11));
|
||||
|
||||
/* -----\/----- EXCLUDED -----\/-----
|
||||
flopenr #(k) GlobalHistoryRegisterD(.clk(clk),
|
||||
.reset(reset),
|
||||
.en(~StallD & ~FlushedE),
|
||||
.d(GHRF),
|
||||
.d(GHR),
|
||||
.q(GHRD));
|
||||
|
||||
flopenr #(k) GlobalHistoryRegisterE(.clk(clk),
|
||||
@ -97,6 +156,7 @@ module globalHistoryPredictor
|
||||
.en(~StallE),
|
||||
.d(FlushE | FlushedD),
|
||||
.q(FlushedE));
|
||||
-----/\----- EXCLUDED -----/\----- */
|
||||
|
||||
|
||||
endmodule
|
||||
|
@ -38,28 +38,32 @@ module gsharePredictor
|
||||
// update
|
||||
input logic [`XLEN-1:0] UpdatePC,
|
||||
input logic UpdateEN, PCSrcE,
|
||||
input logic SpeculativeUpdateEn, BPPredDirWrongE,
|
||||
input logic [1:0] UpdatePrediction
|
||||
|
||||
);
|
||||
|
||||
logic [k-1:0] GHRF, GHRFNext;
|
||||
logic [k-1:0] GHRF, GHRFNext, GHRD, GHRE;
|
||||
//logic [k-1:0] LookUpPCIndexD, LookUpPCIndexE;
|
||||
logic [k-1:0] LookUpPCIndex, UpdatePCIndex;
|
||||
logic [1:0] PredictionMemory;
|
||||
logic DoForwarding, DoForwardingF;
|
||||
logic [1:0] UpdatePredictionF;
|
||||
logic FlushedD, FlushedE;
|
||||
|
||||
assign GHRFNext = {PCSrcE, GHRF[k-1:1]};
|
||||
// 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));
|
||||
|
||||
|
||||
// for gshare xor the PC with the GHR
|
||||
assign UpdatePCIndex = GHRFNext ^ UpdatePC[k:1];
|
||||
assign UpdatePCIndex = GHRE ^ UpdatePC[k:1];
|
||||
assign LookUpPCIndex = GHRF ^ LookUpPC[k:1];
|
||||
// Make Prediction by reading the correct address in the PHT and also update the new address in the PHT
|
||||
// GHR referes to the address that the past k branches points to in the prediction stage
|
||||
@ -67,7 +71,7 @@ module gsharePredictor
|
||||
SRAM2P1R1W #(k, 2) PHT(.clk(clk),
|
||||
.reset(reset),
|
||||
.RA1(LookUpPCIndex),
|
||||
.RD1(PredictionMemory),
|
||||
.RD1(Prediction),
|
||||
.REN1(~StallF),
|
||||
.WA1(UpdatePCIndex),
|
||||
.WD1(UpdatePrediction),
|
||||
@ -75,6 +79,32 @@ module gsharePredictor
|
||||
.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));
|
||||
|
||||
/* -----\/----- EXCLUDED -----\/-----
|
||||
// need to forward when updating to the same address as reading.
|
||||
// first we compare to see if the update and lookup addreses are the same
|
||||
assign DoForwarding = LookUpPCIndex == UpdatePCIndex;
|
||||
@ -92,6 +122,7 @@ module gsharePredictor
|
||||
.q(UpdatePredictionF));
|
||||
|
||||
assign Prediction = DoForwardingF ? UpdatePredictionF : PredictionMemory;
|
||||
-----/\----- EXCLUDED -----/\----- */
|
||||
|
||||
//pipeline for GHR
|
||||
/* -----\/----- EXCLUDED -----\/-----
|
||||
|
Loading…
Reference in New Issue
Block a user