From bca87d326b73b752858788f7362cd3b7255d167d Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Thu, 5 Jan 2023 13:27:22 -0600 Subject: [PATCH] Two bit predictor cleanup. --- pipelined/src/ifu/bpred.sv | 30 ++++++------- pipelined/src/ifu/twoBitPredictor.sv | 67 ++++++++++++---------------- 2 files changed, 42 insertions(+), 55 deletions(-) diff --git a/pipelined/src/ifu/bpred.sv b/pipelined/src/ifu/bpred.sv index 26f7459af..bf5582371 100644 --- a/pipelined/src/ifu/bpred.sv +++ b/pipelined/src/ifu/bpred.sv @@ -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); diff --git a/pipelined/src/ifu/twoBitPredictor.sv b/pipelined/src/ifu/twoBitPredictor.sv index 7459ea6a7..7497c880c 100644 --- a/pipelined/src/ifu/twoBitPredictor.sv +++ b/pipelined/src/ifu/twoBitPredictor.sv @@ -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)); - - // 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; - - // register the update value and the forwarding signal into the Fetch stage - flopr #(1) DoForwardingReg(.clk(clk), - .reset(reset), - .d(DoForwarding), - .q(DoForwardingF)); + 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)); - flopr #(2) UpdatePredictionReg(.clk(clk), - .reset(reset), - .d(UpdatePrediction), - .q(UpdatePredictionF)); + flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD); + flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, DirPredictionD, DirPredictionE); - assign Prediction = DoForwardingF ? UpdatePredictionF : PredictionMemory; + assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchInstrE; + + satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE)); + flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewDirPredictionE, NewDirPredictionM); + endmodule