mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
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 simple_csrbr_test();
|
||||||
int lbu_test();
|
int lbu_test();
|
||||||
int icache_spill_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
|
#endif
|
||||||
|
@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
//int res = icache_spill_test();
|
//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;
|
int res = 1;
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
fail();
|
fail();
|
||||||
|
@ -90,12 +90,13 @@ module bpred
|
|||||||
.reset(reset),
|
.reset(reset),
|
||||||
.*, // Stalls and flushes
|
.*, // Stalls and flushes
|
||||||
.LookUpPC(PCNextF),
|
.LookUpPC(PCNextF),
|
||||||
.Prediction(BPPredF),
|
.BPPredF(BPPredF),
|
||||||
// update
|
// update
|
||||||
.UpdatePC(PCE),
|
.BPPredD(BPPredD),
|
||||||
.UpdateEN(InstrClassE[0] & ~StallE),
|
.InstrClassE(InstrClassE),
|
||||||
.SpeculativeUpdateEn(BPInstrClassF[0] & ~StallF),
|
.BPInstrClassE(BPInstrClassE),
|
||||||
.BPPredDirWrongE(BPPredDirWrongE),
|
.BPPredDirWrongE(BPPredDirWrongE),
|
||||||
|
.UpdatePC(PCE),
|
||||||
.PCSrcE(PCSrcE),
|
.PCSrcE(PCSrcE),
|
||||||
.UpdatePrediction(UpdateBPPredE));
|
.UpdatePrediction(UpdateBPPredE));
|
||||||
end else if (`BPTYPE == "BPGSHARE") begin:Predictor
|
end else if (`BPTYPE == "BPGSHARE") begin:Predictor
|
||||||
@ -108,6 +109,8 @@ module bpred
|
|||||||
// update
|
// update
|
||||||
.UpdatePC(PCE),
|
.UpdatePC(PCE),
|
||||||
.UpdateEN(InstrClassE[0] & ~StallE),
|
.UpdateEN(InstrClassE[0] & ~StallE),
|
||||||
|
.SpeculativeUpdateEn(BPInstrClassF[0] & ~StallF),
|
||||||
|
.BPPredDirWrongE(BPPredDirWrongE),
|
||||||
.PCSrcE(PCSrcE),
|
.PCSrcE(PCSrcE),
|
||||||
.UpdatePrediction(UpdateBPPredE));
|
.UpdatePrediction(UpdateBPPredE));
|
||||||
end
|
end
|
||||||
|
@ -34,49 +34,108 @@ module globalHistoryPredictor
|
|||||||
input logic reset,
|
input logic reset,
|
||||||
input logic StallF, StallD, StallE, FlushF, FlushD, FlushE,
|
input logic StallF, StallD, StallE, FlushF, FlushD, FlushE,
|
||||||
input logic [`XLEN-1:0] LookUpPC,
|
input logic [`XLEN-1:0] LookUpPC,
|
||||||
output logic [1:0] Prediction,
|
output logic [1:0] BPPredF,
|
||||||
// update
|
// 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 [`XLEN-1:0] UpdatePC,
|
||||||
input logic UpdateEN, PCSrcE,
|
input logic PCSrcE,
|
||||||
input logic SpeculativeUpdateEn, BPPredDirWrongE,
|
|
||||||
input logic [1:0] UpdatePrediction
|
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;
|
logic FlushedD, FlushedE;
|
||||||
|
-----/\----- EXCLUDED -----/\----- */
|
||||||
|
|
||||||
|
|
||||||
// if the prediction is wrong we need to restore the ghr.
|
logic [6:0] GHRMuxSel;
|
||||||
assign GHRFNext = BPPredDirWrongE ? {PCSrcE, GHRE[k-1:1]} :
|
logic GHRUpdateEN;
|
||||||
{Prediction[1], GHRF[k-1:1]};
|
|
||||||
|
|
||||||
flopenr #(k) GlobalHistoryRegister(.clk(clk),
|
assign BPClassRightNonCFI = ~BPInstrClassE[0] & ~InstrClassE[0];
|
||||||
.reset(reset),
|
assign BPClassWrongCFI = ~BPInstrClassE[0] & InstrClassE[0];
|
||||||
.en((UpdateEN & BPPredDirWrongE) | (SpeculativeUpdateEn)),
|
assign BPClassWrongNonCFI = BPInstrClassE[0] & ~InstrClassE[0];
|
||||||
.d(GHRFNext),
|
assign BPClassRightBPWrong = BPInstrClassE[0] & InstrClassE[0] & BPPredDirWrongE;
|
||||||
.q(GHRF));
|
assign BPClassRightBPRight = BPInstrClassE[0] & InstrClassE[0] & ~BPPredDirWrongE;
|
||||||
|
|
||||||
|
|
||||||
|
// GHR update selection, 1 hot encoded.
|
||||||
|
assign GHRMuxSel[0] = ~BPInstrClassF[0] & (BPClassRightNonCFI | BPClassRightBPRight);
|
||||||
|
|
||||||
|
assign GHRMuxSel[1] = BPClassWrongCFI & ~BPInstrClassD[0];
|
||||||
|
assign GHRMuxSel[3] = (BPClassRightBPWrong & ~BPInstrClassD[0]) | (BPClassWrongCFI & BPInstrClassD[0]);
|
||||||
|
|
||||||
|
|
||||||
|
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
|
// 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
|
// 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),
|
SRAM2P1R1W #(k, 2) PHT(.clk(clk),
|
||||||
.reset(reset),
|
.reset(reset),
|
||||||
.RA1(GHRF),
|
.RA1(GHR[k-1:0]),
|
||||||
.RD1(Prediction),
|
.RD1(BPPredF),
|
||||||
.REN1(~StallF),
|
.REN1(~StallF),
|
||||||
.WA1(GHRE),
|
.WA1(PHTUpdateAdr),
|
||||||
.WD1(UpdatePrediction),
|
.WD1(UpdatePrediction),
|
||||||
.WEN1(UpdateEN),
|
.WEN1(PHTUpdateEN),
|
||||||
.BitWEN1(2'b11));
|
.BitWEN1(2'b11));
|
||||||
|
|
||||||
|
/* -----\/----- EXCLUDED -----\/-----
|
||||||
flopenr #(k) GlobalHistoryRegisterD(.clk(clk),
|
flopenr #(k) GlobalHistoryRegisterD(.clk(clk),
|
||||||
.reset(reset),
|
.reset(reset),
|
||||||
.en(~StallD & ~FlushedE),
|
.en(~StallD & ~FlushedE),
|
||||||
.d(GHRF),
|
.d(GHR),
|
||||||
.q(GHRD));
|
.q(GHRD));
|
||||||
|
|
||||||
flopenr #(k) GlobalHistoryRegisterE(.clk(clk),
|
flopenr #(k) GlobalHistoryRegisterE(.clk(clk),
|
||||||
@ -97,6 +156,7 @@ module globalHistoryPredictor
|
|||||||
.en(~StallE),
|
.en(~StallE),
|
||||||
.d(FlushE | FlushedD),
|
.d(FlushE | FlushedD),
|
||||||
.q(FlushedE));
|
.q(FlushedE));
|
||||||
|
-----/\----- EXCLUDED -----/\----- */
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -38,28 +38,32 @@ module gsharePredictor
|
|||||||
// update
|
// update
|
||||||
input logic [`XLEN-1:0] UpdatePC,
|
input logic [`XLEN-1:0] UpdatePC,
|
||||||
input logic UpdateEN, PCSrcE,
|
input logic UpdateEN, PCSrcE,
|
||||||
|
input logic SpeculativeUpdateEn, BPPredDirWrongE,
|
||||||
input logic [1:0] UpdatePrediction
|
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] LookUpPCIndexD, LookUpPCIndexE;
|
||||||
logic [k-1:0] LookUpPCIndex, UpdatePCIndex;
|
logic [k-1:0] LookUpPCIndex, UpdatePCIndex;
|
||||||
logic [1:0] PredictionMemory;
|
logic [1:0] PredictionMemory;
|
||||||
logic DoForwarding, DoForwardingF;
|
logic DoForwarding, DoForwardingF;
|
||||||
logic [1:0] UpdatePredictionF;
|
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),
|
flopenr #(k) GlobalHistoryRegister(.clk(clk),
|
||||||
.reset(reset),
|
.reset(reset),
|
||||||
.en(UpdateEN),
|
.en((UpdateEN & BPPredDirWrongE) | (SpeculativeUpdateEn)),
|
||||||
.d(GHRFNext),
|
.d(GHRFNext),
|
||||||
.q(GHRF));
|
.q(GHRF));
|
||||||
|
|
||||||
|
|
||||||
// for gshare xor the PC with the GHR
|
// 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];
|
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
|
// 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
|
// 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),
|
SRAM2P1R1W #(k, 2) PHT(.clk(clk),
|
||||||
.reset(reset),
|
.reset(reset),
|
||||||
.RA1(LookUpPCIndex),
|
.RA1(LookUpPCIndex),
|
||||||
.RD1(PredictionMemory),
|
.RD1(Prediction),
|
||||||
.REN1(~StallF),
|
.REN1(~StallF),
|
||||||
.WA1(UpdatePCIndex),
|
.WA1(UpdatePCIndex),
|
||||||
.WD1(UpdatePrediction),
|
.WD1(UpdatePrediction),
|
||||||
@ -75,6 +79,32 @@ module gsharePredictor
|
|||||||
.BitWEN1(2'b11));
|
.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.
|
// 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
|
// first we compare to see if the update and lookup addreses are the same
|
||||||
assign DoForwarding = LookUpPCIndex == UpdatePCIndex;
|
assign DoForwarding = LookUpPCIndex == UpdatePCIndex;
|
||||||
@ -92,6 +122,7 @@ module gsharePredictor
|
|||||||
.q(UpdatePredictionF));
|
.q(UpdatePredictionF));
|
||||||
|
|
||||||
assign Prediction = DoForwardingF ? UpdatePredictionF : PredictionMemory;
|
assign Prediction = DoForwardingF ? UpdatePredictionF : PredictionMemory;
|
||||||
|
-----/\----- EXCLUDED -----/\----- */
|
||||||
|
|
||||||
//pipeline for GHR
|
//pipeline for GHR
|
||||||
/* -----\/----- EXCLUDED -----\/-----
|
/* -----\/----- EXCLUDED -----\/-----
|
||||||
|
Loading…
Reference in New Issue
Block a user