Two bit predictor cleanup.

This commit is contained in:
Ross Thompson 2023-01-05 13:27:22 -06:00
parent 87c9682311
commit bca87d326b
2 changed files with 42 additions and 55 deletions

View File

@ -67,7 +67,7 @@ module bpred (
);
logic BTBValidF;
logic [1:0] BPPredF, BPPredD, BPPredE, UpdateBPPredE;
logic [1:0] DirPredictionF, DirPredictionD, DirPredictionE, UpdateBPPredE;
logic [4:0] BPInstrClassF, BPInstrClassD, BPInstrClassE;
logic [`XLEN-1:0] BTBPredPCF, RASPCF;
@ -87,22 +87,18 @@ module bpred (
// Part 1 branch direction prediction
// look into the 2 port Sram model. something is wrong.
if (`BPTYPE == "BPTWOBIT") begin:Predictor
twoBitPredictor DirPredictor(.clk, .reset, .StallF,
.LookUpPC(PCNextF),
.Prediction(BPPredF),
// update
.UpdatePC(PCE),
.UpdateEN(InstrClassE[0] & ~StallE),
.UpdatePrediction(UpdateBPPredE));
twoBitPredictor DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
.PCNextF, .PCM, .DirPredictionF(DirPredictionF), .DirPredictionWrongE(BPPredDirWrongE),
.BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE);
end else if (`BPTYPE == "BPGLOBAL") begin:Predictor
globalhistory DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
.PCNextF, .PCM, .DirPredictionF(BPPredF), .DirPredictionWrongE(BPPredDirWrongE),
.PCNextF, .PCM, .DirPredictionF(DirPredictionF), .DirPredictionWrongE(BPPredDirWrongE),
.BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE);
end else if (`BPTYPE == "BPGSHARE") begin:Predictor
gshare DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
.PCNextF, .PCM, .DirPredictionF(BPPredF), .DirPredictionWrongE(BPPredDirWrongE),
.PCNextF, .PCM, .DirPredictionF(DirPredictionF), .DirPredictionWrongE(BPPredDirWrongE),
.BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE);
end
else if (`BPTYPE == "BPLOCALPAg") begin:Predictor
@ -110,7 +106,7 @@ module bpred (
localHistoryPredictor DirPredictor(.clk,
.reset, .StallF, .StallE,
.LookUpPC(PCNextF),
.Prediction(BPPredF),
.Prediction(DirPredictionF),
// update
.UpdatePC(PCE),
.UpdateEN(InstrClassE[0] & ~StallE),
@ -123,7 +119,7 @@ module bpred (
// 1) A direction (1 = Taken, 0 = Not Taken)
// 2) Any information which is necessary for the predictor to build its next state.
// For a 2 bit table this is the prediction count.
assign SelBPPredF = ((BPInstrClassF[0] & BPPredF[1] & BTBValidF) |
assign SelBPPredF = ((BPInstrClassF[0] & DirPredictionF[1] & BTBValidF) |
BPInstrClassF[3] |
(BPInstrClassF[2] & BTBValidF) |
BPInstrClassF[1] & BTBValidF) ;
@ -164,14 +160,14 @@ module bpred (
flopenr #(2) BPPredRegD(.clk(clk),
.reset(reset),
.en(~StallD),
.d(BPPredF),
.q(BPPredD));
.d(DirPredictionF),
.q(DirPredictionD));
flopenr #(2) BPPredRegE(.clk(clk),
.reset(reset),
.en(~StallE),
.d(BPPredD),
.q(BPPredE));
.d(DirPredictionD),
.q(DirPredictionE));
// the branch predictor needs a compact decoding of the instruction class.
@ -225,7 +221,7 @@ module bpred (
assign BPPredClassNonCFIWrongE = PredictionInstrClassWrongE & ~|InstrClassE;
// 2 bit saturating counter
satCounter2 BPDirUpdate(.BrDir(PCSrcE), .OldState(BPPredE), .NewState(UpdateBPPredE));
satCounter2 BPDirUpdate(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(UpdateBPPredE));
// Selects the BP or PC+2/4.
mux2 #(`XLEN) pcmux0(PCPlus2or4F, BPPredPCF, SelBPPredF, PCNext0F);

View File

@ -33,58 +33,49 @@
`include "wally-config.vh"
module twoBitPredictor
#(parameter int Depth = 10
#(parameter int k = 10
)
(input logic clk,
input logic reset,
input logic StallF,
input logic [`XLEN-1:0] LookUpPC,
output logic [1:0] Prediction,
// update
input logic [`XLEN-1:0] UpdatePC,
input logic UpdateEN,
input logic [1:0] UpdatePrediction
input logic StallF, StallD, StallE, StallM,
input logic FlushD, FlushE, FlushM,
input logic [`XLEN-1:0] PCNextF, PCM,
output logic [1:0] DirPredictionF,
output logic DirPredictionWrongE,
input logic BranchInstrE, BranchInstrM,
input logic PCSrcE
);
logic [Depth-1:0] LookUpPCIndex, UpdatePCIndex;
logic [k-1:0] IndexNextF, IndexM;
logic [1:0] PredictionMemory;
logic DoForwarding, DoForwardingF;
logic [1:0] UpdatePredictionF;
logic [1:0] DirPredictionD, DirPredictionE;
logic [1:0] NewDirPredictionE, NewDirPredictionM;
// hashing function for indexing the PC
// We have Depth bits to index, but XLEN bits as the input.
// We have k bits to index, but XLEN bits as the input.
// bit 0 is always 0, bit 1 is 0 if using 4 byte instructions, but is not always 0 if
// using compressed instructions. XOR bit 1 with the MSB of index.
assign UpdatePCIndex = {UpdatePC[Depth+1] ^ UpdatePC[1], UpdatePC[Depth:2]};
assign LookUpPCIndex = {LookUpPC[Depth+1] ^ LookUpPC[1], LookUpPC[Depth:2]};
assign IndexNextF = {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]};
assign IndexM = {PCM[k+1] ^ PCM[1], PCM[k:2]};
ram2p1r1wb #(Depth, 2) PHT(.clk(clk),
.reset(reset),
.ra1(LookUpPCIndex),
.rd1(PredictionMemory),
.ren1(~StallF),
.wa2(UpdatePCIndex),
.wd2(UpdatePrediction),
.wen2(UpdateEN),
.bwe2(2'b11));
ram2p1r1wbefix #(2**k, 2) PHT(.clk(clk),
.ce1(~StallF), .ce2(~StallM & ~FlushM),
.ra1(IndexNextF),
.rd1(DirPredictionF),
.wa2(IndexM),
.wd2(NewDirPredictionM),
.we2(BranchInstrM & ~StallM & ~FlushM),
.bwe2(1'b1));
// 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 = UpdatePCIndex == LookUpPCIndex;
flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD);
flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, DirPredictionD, DirPredictionE);
// register the update value and the forwarding signal into the Fetch stage
flopr #(1) DoForwardingReg(.clk(clk),
.reset(reset),
.d(DoForwarding),
.q(DoForwardingF));
assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchInstrE;
flopr #(2) UpdatePredictionReg(.clk(clk),
.reset(reset),
.d(UpdatePrediction),
.q(UpdatePredictionF));
satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE));
flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewDirPredictionE, NewDirPredictionM);
assign Prediction = DoForwardingF ? UpdatePredictionF : PredictionMemory;
endmodule