mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Two bit predictor cleanup.
This commit is contained in:
parent
87c9682311
commit
bca87d326b
@ -67,7 +67,7 @@ module bpred (
|
|||||||
);
|
);
|
||||||
|
|
||||||
logic BTBValidF;
|
logic BTBValidF;
|
||||||
logic [1:0] BPPredF, BPPredD, BPPredE, UpdateBPPredE;
|
logic [1:0] DirPredictionF, DirPredictionD, DirPredictionE, UpdateBPPredE;
|
||||||
|
|
||||||
logic [4:0] BPInstrClassF, BPInstrClassD, BPInstrClassE;
|
logic [4:0] BPInstrClassF, BPInstrClassD, BPInstrClassE;
|
||||||
logic [`XLEN-1:0] BTBPredPCF, RASPCF;
|
logic [`XLEN-1:0] BTBPredPCF, RASPCF;
|
||||||
@ -87,22 +87,18 @@ module bpred (
|
|||||||
// Part 1 branch direction prediction
|
// Part 1 branch direction prediction
|
||||||
// look into the 2 port Sram model. something is wrong.
|
// look into the 2 port Sram model. something is wrong.
|
||||||
if (`BPTYPE == "BPTWOBIT") begin:Predictor
|
if (`BPTYPE == "BPTWOBIT") begin:Predictor
|
||||||
twoBitPredictor DirPredictor(.clk, .reset, .StallF,
|
twoBitPredictor DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
|
||||||
.LookUpPC(PCNextF),
|
.PCNextF, .PCM, .DirPredictionF(DirPredictionF), .DirPredictionWrongE(BPPredDirWrongE),
|
||||||
.Prediction(BPPredF),
|
.BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE);
|
||||||
// update
|
|
||||||
.UpdatePC(PCE),
|
|
||||||
.UpdateEN(InstrClassE[0] & ~StallE),
|
|
||||||
.UpdatePrediction(UpdateBPPredE));
|
|
||||||
|
|
||||||
end else if (`BPTYPE == "BPGLOBAL") begin:Predictor
|
end else if (`BPTYPE == "BPGLOBAL") begin:Predictor
|
||||||
globalhistory DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
|
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);
|
.BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE);
|
||||||
|
|
||||||
end else if (`BPTYPE == "BPGSHARE") begin:Predictor
|
end else if (`BPTYPE == "BPGSHARE") begin:Predictor
|
||||||
gshare DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
|
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);
|
.BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE);
|
||||||
end
|
end
|
||||||
else if (`BPTYPE == "BPLOCALPAg") begin:Predictor
|
else if (`BPTYPE == "BPLOCALPAg") begin:Predictor
|
||||||
@ -110,7 +106,7 @@ module bpred (
|
|||||||
localHistoryPredictor DirPredictor(.clk,
|
localHistoryPredictor DirPredictor(.clk,
|
||||||
.reset, .StallF, .StallE,
|
.reset, .StallF, .StallE,
|
||||||
.LookUpPC(PCNextF),
|
.LookUpPC(PCNextF),
|
||||||
.Prediction(BPPredF),
|
.Prediction(DirPredictionF),
|
||||||
// update
|
// update
|
||||||
.UpdatePC(PCE),
|
.UpdatePC(PCE),
|
||||||
.UpdateEN(InstrClassE[0] & ~StallE),
|
.UpdateEN(InstrClassE[0] & ~StallE),
|
||||||
@ -123,7 +119,7 @@ module bpred (
|
|||||||
// 1) A direction (1 = Taken, 0 = Not Taken)
|
// 1) A direction (1 = Taken, 0 = Not Taken)
|
||||||
// 2) Any information which is necessary for the predictor to build its next state.
|
// 2) Any information which is necessary for the predictor to build its next state.
|
||||||
// For a 2 bit table this is the prediction count.
|
// 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[3] |
|
||||||
(BPInstrClassF[2] & BTBValidF) |
|
(BPInstrClassF[2] & BTBValidF) |
|
||||||
BPInstrClassF[1] & BTBValidF) ;
|
BPInstrClassF[1] & BTBValidF) ;
|
||||||
@ -164,14 +160,14 @@ module bpred (
|
|||||||
flopenr #(2) BPPredRegD(.clk(clk),
|
flopenr #(2) BPPredRegD(.clk(clk),
|
||||||
.reset(reset),
|
.reset(reset),
|
||||||
.en(~StallD),
|
.en(~StallD),
|
||||||
.d(BPPredF),
|
.d(DirPredictionF),
|
||||||
.q(BPPredD));
|
.q(DirPredictionD));
|
||||||
|
|
||||||
flopenr #(2) BPPredRegE(.clk(clk),
|
flopenr #(2) BPPredRegE(.clk(clk),
|
||||||
.reset(reset),
|
.reset(reset),
|
||||||
.en(~StallE),
|
.en(~StallE),
|
||||||
.d(BPPredD),
|
.d(DirPredictionD),
|
||||||
.q(BPPredE));
|
.q(DirPredictionE));
|
||||||
|
|
||||||
|
|
||||||
// the branch predictor needs a compact decoding of the instruction class.
|
// the branch predictor needs a compact decoding of the instruction class.
|
||||||
@ -225,7 +221,7 @@ module bpred (
|
|||||||
assign BPPredClassNonCFIWrongE = PredictionInstrClassWrongE & ~|InstrClassE;
|
assign BPPredClassNonCFIWrongE = PredictionInstrClassWrongE & ~|InstrClassE;
|
||||||
|
|
||||||
// 2 bit saturating counter
|
// 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.
|
// Selects the BP or PC+2/4.
|
||||||
mux2 #(`XLEN) pcmux0(PCPlus2or4F, BPPredPCF, SelBPPredF, PCNext0F);
|
mux2 #(`XLEN) pcmux0(PCPlus2or4F, BPPredPCF, SelBPPredF, PCNext0F);
|
||||||
|
@ -33,58 +33,49 @@
|
|||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
module twoBitPredictor
|
module twoBitPredictor
|
||||||
#(parameter int Depth = 10
|
#(parameter int k = 10
|
||||||
)
|
)
|
||||||
(input logic clk,
|
(input logic clk,
|
||||||
input logic reset,
|
input logic reset,
|
||||||
input logic StallF,
|
input logic StallF, StallD, StallE, StallM,
|
||||||
input logic [`XLEN-1:0] LookUpPC,
|
input logic FlushD, FlushE, FlushM,
|
||||||
output logic [1:0] Prediction,
|
input logic [`XLEN-1:0] PCNextF, PCM,
|
||||||
// update
|
output logic [1:0] DirPredictionF,
|
||||||
input logic [`XLEN-1:0] UpdatePC,
|
output logic DirPredictionWrongE,
|
||||||
input logic UpdateEN,
|
input logic BranchInstrE, BranchInstrM,
|
||||||
input logic [1:0] UpdatePrediction
|
input logic PCSrcE
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [Depth-1:0] LookUpPCIndex, UpdatePCIndex;
|
logic [k-1:0] IndexNextF, IndexM;
|
||||||
logic [1:0] PredictionMemory;
|
logic [1:0] PredictionMemory;
|
||||||
logic DoForwarding, DoForwardingF;
|
logic DoForwarding, DoForwardingF;
|
||||||
logic [1:0] UpdatePredictionF;
|
logic [1:0] DirPredictionD, DirPredictionE;
|
||||||
|
logic [1:0] NewDirPredictionE, NewDirPredictionM;
|
||||||
|
|
||||||
// hashing function for indexing the PC
|
// 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
|
// 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.
|
// using compressed instructions. XOR bit 1 with the MSB of index.
|
||||||
assign UpdatePCIndex = {UpdatePC[Depth+1] ^ UpdatePC[1], UpdatePC[Depth:2]};
|
assign IndexNextF = {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]};
|
||||||
assign LookUpPCIndex = {LookUpPC[Depth+1] ^ LookUpPC[1], LookUpPC[Depth:2]};
|
assign IndexM = {PCM[k+1] ^ PCM[1], PCM[k:2]};
|
||||||
|
|
||||||
|
|
||||||
ram2p1r1wb #(Depth, 2) PHT(.clk(clk),
|
ram2p1r1wbefix #(2**k, 2) PHT(.clk(clk),
|
||||||
.reset(reset),
|
.ce1(~StallF), .ce2(~StallM & ~FlushM),
|
||||||
.ra1(LookUpPCIndex),
|
.ra1(IndexNextF),
|
||||||
.rd1(PredictionMemory),
|
.rd1(DirPredictionF),
|
||||||
.ren1(~StallF),
|
.wa2(IndexM),
|
||||||
.wa2(UpdatePCIndex),
|
.wd2(NewDirPredictionM),
|
||||||
.wd2(UpdatePrediction),
|
.we2(BranchInstrM & ~StallM & ~FlushM),
|
||||||
.wen2(UpdateEN),
|
.bwe2(1'b1));
|
||||||
.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));
|
|
||||||
|
|
||||||
flopr #(2) UpdatePredictionReg(.clk(clk),
|
flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD);
|
||||||
.reset(reset),
|
flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, DirPredictionD, DirPredictionE);
|
||||||
.d(UpdatePrediction),
|
|
||||||
.q(UpdatePredictionF));
|
|
||||||
|
|
||||||
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
|
endmodule
|
||||||
|
Loading…
Reference in New Issue
Block a user