mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-03 10:15:19 +00:00
Merge pull request #114 from ross144/main
Fix the branch predictor's gshare and btb critical path issue
This commit is contained in:
commit
be5bf22469
@ -247,13 +247,25 @@ if(sys.argv[1] == '-b'):
|
||||
currPercent.append(percent)
|
||||
dct[PredType] = (currSize, currPercent)
|
||||
print(dct)
|
||||
fig, axes = plt.subplots()
|
||||
marker={'twobit' : '^', 'gshare' : 'o', 'global' : 's', 'gshareBasic' : '*', 'globalBasic' : 'x'}
|
||||
colors={'twobit' : 'black', 'gshare' : 'blue', 'global' : 'dodgerblue', 'gshareBasic' : 'turquoise', 'globalBasic' : 'lightsteelblue'}
|
||||
for cat in dct:
|
||||
(x, y) = dct[cat]
|
||||
plt.scatter(x, y, label='k')
|
||||
plt.plot(x, y)
|
||||
plt.ylabel('Prediction Accuracy')
|
||||
plt.xlabel('Size (b or k)')
|
||||
plt.legend(loc='upper left')
|
||||
x=[int(2**int(v)/4) for v in x]
|
||||
print(x, y)
|
||||
axes.plot(x,y, color=colors[cat])
|
||||
axes.scatter(x,y, label=cat, marker=marker[cat], color=colors[cat])
|
||||
#plt.scatter(x, y, label=cat)
|
||||
#plt.plot(x, y)
|
||||
#axes.set_xticks([4, 6, 8, 10, 12, 14])
|
||||
axes.legend(loc='upper left')
|
||||
axes.set_xscale("log")
|
||||
axes.set_ylabel('Prediction Accuracy')
|
||||
axes.set_xlabel('Size (bytes)')
|
||||
axes.set_xticks([16, 64, 256, 1024, 4096, 16384])
|
||||
axes.set_xticklabels([16, 64, 256, 1024, 4096, 16384])
|
||||
axes.grid(color='b', alpha=0.5, linestyle='dashed', linewidth=0.5)
|
||||
plt.show()
|
||||
|
||||
|
||||
|
@ -33,10 +33,10 @@ module RASPredictor #(parameter int StackSize = 16 )(
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
input logic StallF, StallD, StallE, StallM, FlushD, FlushE, FlushM,
|
||||
input logic [3:0] WrongPredInstrClassD, // Prediction class is wrong
|
||||
input logic [3:0] InstrClassD,
|
||||
input logic [3:0] InstrClassE, // Instr class
|
||||
input logic [3:0] PredInstrClassF,
|
||||
input logic WrongBPRetD, // Prediction class is wrong
|
||||
input logic RetD,
|
||||
input logic RetE, JalE, // Instr class
|
||||
input logic BPRetF,
|
||||
input logic [`XLEN-1:0] PCLinkE, // PC of instruction after a jal
|
||||
output logic [`XLEN-1:0] RASPCF // Top of the stack
|
||||
);
|
||||
@ -58,17 +58,17 @@ module RASPredictor #(parameter int StackSize = 16 )(
|
||||
logic WrongPredRetD;
|
||||
|
||||
|
||||
assign PopF = PredInstrClassF[2] & ~StallD & ~FlushD;
|
||||
assign PushE = InstrClassE[3] & ~StallM & ~FlushM;
|
||||
assign PopF = BPRetF & ~StallD & ~FlushD;
|
||||
assign PushE = JalE & ~StallM & ~FlushM;
|
||||
|
||||
assign WrongPredRetD = (WrongPredInstrClassD[2]) & ~StallE & ~FlushE;
|
||||
assign FlushedRetDE = (~StallE & FlushE & InstrClassD[2]) | (~StallM & FlushM & InstrClassE[2]); // flushed ret
|
||||
assign WrongPredRetD = (WrongBPRetD) & ~StallE & ~FlushE;
|
||||
assign FlushedRetDE = (~StallE & FlushE & RetD) | (~StallM & FlushM & RetE); // flushed ret
|
||||
|
||||
assign RepairD = WrongPredRetD | FlushedRetDE ;
|
||||
|
||||
assign IncrRepairD = FlushedRetDE | (WrongPredRetD & ~InstrClassD[2]); // Guessed it was a ret, but its not
|
||||
assign IncrRepairD = FlushedRetDE | (WrongPredRetD & ~RetD); // Guessed it was a ret, but its not
|
||||
|
||||
assign DecRepairD = WrongPredRetD & InstrClassD[2]; // Guessed non ret but is a ret.
|
||||
assign DecRepairD = WrongPredRetD & RetD; // Guessed non ret but is a ret.
|
||||
|
||||
assign CounterEn = PopF | PushE | RepairD;
|
||||
|
||||
|
@ -72,15 +72,12 @@ module bpred (
|
||||
|
||||
logic [1:0] DirPredictionF;
|
||||
|
||||
logic [3:0] BTBPredInstrClassF, PredInstrClassF, PredInstrClassD;
|
||||
logic [`XLEN-1:0] BTAF, RASPCF;
|
||||
logic PredictionPCWrongE;
|
||||
logic AnyWrongPredInstrClassD, AnyWrongPredInstrClassE;
|
||||
logic [3:0] InstrClassD;
|
||||
logic [3:0] InstrClassE;
|
||||
logic DirPredictionWrongE;
|
||||
|
||||
logic SelBPPredF;
|
||||
logic BPPCSrcF;
|
||||
logic [`XLEN-1:0] BPPredPCF;
|
||||
logic [`XLEN-1:0] PCNext0F;
|
||||
logic [`XLEN-1:0] PCCorrectE;
|
||||
@ -91,34 +88,45 @@ module bpred (
|
||||
|
||||
logic [`XLEN-1:0] BTAD;
|
||||
|
||||
logic BTBJalF, BTBRetF, BTBJumpF, BTBBranchF;
|
||||
logic BPBranchF, BPJumpF, BPRetF, BPJalF;
|
||||
logic BPBranchD, BPJumpD, BPRetD, BPJalD;
|
||||
logic RetD, JalD;
|
||||
logic RetE, JalE;
|
||||
logic BranchM, JumpM, RetM, JalM;
|
||||
logic BranchW, JumpW, RetW, JalW;
|
||||
logic WrongBPRetD;
|
||||
logic [`XLEN-1:0] PCW, IEUAdrW;
|
||||
|
||||
// Part 1 branch direction prediction
|
||||
// look into the 2 port Sram model. something is wrong.
|
||||
if (`BPRED_TYPE == "BP_TWOBIT") begin:Predictor
|
||||
twoBitPredictor #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
|
||||
twoBitPredictor #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW,
|
||||
.FlushD, .FlushE, .FlushM, .FlushW,
|
||||
.PCNextF, .PCM, .DirPredictionF, .DirPredictionWrongE,
|
||||
.BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE);
|
||||
.BranchE, .BranchM, .PCSrcE);
|
||||
|
||||
end else if (`BPRED_TYPE == "BP_GSHARE") begin:Predictor
|
||||
gshare #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
||||
.PCNextF, .PCF, .PCD, .PCE, .PCM, .DirPredictionF, .DirPredictionWrongE,
|
||||
.BranchInstrF(PredInstrClassF[0]), .BranchInstrD(InstrClassD[0]), .BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]),
|
||||
.PCNextF, .PCF, .PCD, .PCE, .PCM, .PCW, .DirPredictionF, .DirPredictionWrongE,
|
||||
.BPBranchF, .BranchD, .BranchE, .BranchM, .BranchW,
|
||||
.PCSrcE);
|
||||
|
||||
end else if (`BPRED_TYPE == "BP_GLOBAL") begin:Predictor
|
||||
gshare #(`BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
||||
.PCNextF, .PCF, .PCD, .PCE, .PCM, .DirPredictionF, .DirPredictionWrongE,
|
||||
.BranchInstrF(PredInstrClassF[0]), .BranchInstrD(InstrClassD[0]), .BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]),
|
||||
.PCNextF, .PCF, .PCD, .PCE, .PCM, .PCW, .DirPredictionF, .DirPredictionWrongE,
|
||||
.BPBranchF, .BranchD, .BranchE, .BranchM, .BranchW,
|
||||
.PCSrcE);
|
||||
|
||||
end else if (`BPRED_TYPE == "BP_GSHARE_BASIC") begin:Predictor
|
||||
gsharebasic #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
||||
.PCNextF, .PCM, .DirPredictionF, .DirPredictionWrongE,
|
||||
.BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE);
|
||||
.BranchE, .BranchM, .PCSrcE);
|
||||
|
||||
end else if (`BPRED_TYPE == "BP_GLOBAL_BASIC") begin:Predictor
|
||||
gsharebasic #(`BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
||||
.PCNextF, .PCM, .DirPredictionF, .DirPredictionWrongE,
|
||||
.BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE);
|
||||
.BranchE, .BranchM, .PCSrcE);
|
||||
|
||||
end else if (`BPRED_TYPE == "BPLOCALPAg") begin:Predictor
|
||||
// *** Fix me
|
||||
@ -140,18 +148,21 @@ module bpred (
|
||||
|
||||
btb #(`BTB_SIZE)
|
||||
TargetPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
||||
.PCNextF, .PCF, .PCD, .PCE, .PCM,
|
||||
.PCNextF, .PCF, .PCD, .PCE, .PCM, .PCW,
|
||||
.BTAF, .BTAD,
|
||||
.BTBPredInstrClassF,
|
||||
.BTBPredInstrClassF({BTBJalF, BTBRetF, BTBJumpF, BTBBranchF}),
|
||||
.PredictionInstrClassWrongM,
|
||||
.IEUAdrE, .IEUAdrM,
|
||||
.InstrClassD, .InstrClassE, .InstrClassM);
|
||||
.IEUAdrE, .IEUAdrM, .IEUAdrW,
|
||||
.InstrClassD({JalD, RetD, JumpD, BranchD}), .InstrClassE({JalE, RetE, JumpE, BranchE}), .InstrClassM({JalM, RetM, JumpM, BranchM}),
|
||||
.InstrClassW({JalW, RetW, JumpW, BranchW}));
|
||||
|
||||
// the branch predictor needs a compact decoding of the instruction class.
|
||||
if (`INSTR_CLASS_PRED == 0) begin : DirectClassDecode
|
||||
logic [3:0] InstrClassF;
|
||||
if (!`INSTR_CLASS_PRED) begin : DirectClassDecode
|
||||
// This section is mainly for testing, verification, and PPA comparison.
|
||||
// An alternative to using the BTB to store the instruction class is to partially decode
|
||||
// the instructions in the Fetch stage into, Jal, Ret, Jump, and Branch instructions.
|
||||
// This logic is not described in the text book as of 23 February 2023.
|
||||
logic cjal, cj, cjr, cjalr, CJumpF, CBranchF;
|
||||
logic JumpF, BranchF;
|
||||
logic NCJumpF, NCBranchF;
|
||||
|
||||
if(`C_SUPPORTED) begin
|
||||
logic [4:0] CompressedOpcF;
|
||||
@ -166,48 +177,44 @@ module bpred (
|
||||
assign {cjal, cj, cjr, cjalr, CJumpF, CBranchF} = '0;
|
||||
end
|
||||
|
||||
assign JumpF = PostSpillInstrRawF[6:0] == 7'h67 | PostSpillInstrRawF[6:0] == 7'h6F;
|
||||
assign BranchF = PostSpillInstrRawF[6:0] == 7'h63;
|
||||
assign NCJumpF = PostSpillInstrRawF[6:0] == 7'h67 | PostSpillInstrRawF[6:0] == 7'h6F;
|
||||
assign NCBranchF = PostSpillInstrRawF[6:0] == 7'h63;
|
||||
|
||||
assign InstrClassF[0] = BranchF | (`C_SUPPORTED & CBranchF);
|
||||
assign InstrClassF[1] = JumpF | (`C_SUPPORTED & (CJumpF));
|
||||
assign InstrClassF[2] = (JumpF & (PostSpillInstrRawF[19:15] & 5'h1B) == 5'h01) | // return must return to ra or r5
|
||||
(`C_SUPPORTED & (cjalr | cjr) & ((PostSpillInstrRawF[11:7] & 5'h1B) == 5'h01));
|
||||
assign BPBranchF = NCBranchF | (`C_SUPPORTED & CBranchF);
|
||||
assign BPJumpF = NCJumpF | (`C_SUPPORTED & (CJumpF));
|
||||
assign BPRetF = (NCJumpF & (PostSpillInstrRawF[19:15] & 5'h1B) == 5'h01) | // return must return to ra or r5
|
||||
(`C_SUPPORTED & (cjalr | cjr) & ((PostSpillInstrRawF[11:7] & 5'h1B) == 5'h01));
|
||||
|
||||
assign InstrClassF[3] = (JumpF & (PostSpillInstrRawF[11:07] & 5'h1B) == 5'h01) | // jal(r) must link to ra or x5
|
||||
assign BPJalF = (NCJumpF & (PostSpillInstrRawF[11:07] & 5'h1B) == 5'h01) | // jal(r) must link to ra or x5
|
||||
(`C_SUPPORTED & (cjal | (cjalr & (PostSpillInstrRawF[11:7] & 5'h1b) == 5'h01)));
|
||||
|
||||
assign PredInstrClassF = InstrClassF;
|
||||
assign SelBPPredF = (PredInstrClassF[0] & DirPredictionF[1]) |
|
||||
PredInstrClassF[1];
|
||||
end else begin
|
||||
assign PredInstrClassF = BTBPredInstrClassF;
|
||||
assign SelBPPredF = (PredInstrClassF[0] & DirPredictionF[1]) |
|
||||
PredInstrClassF[1];
|
||||
// This section connects the BTB's instruction class prediction.
|
||||
assign {BPJalF, BPRetF, BPJumpF, BPBranchF} = {BTBJalF, BTBRetF, BTBJumpF, BTBBranchF};
|
||||
end
|
||||
assign BPPCSrcF = (BPBranchF & DirPredictionF[1]) | BPJumpF;
|
||||
|
||||
// Part 3 RAS
|
||||
RASPredictor RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
|
||||
.PredInstrClassF, .InstrClassD, .InstrClassE,
|
||||
.WrongPredInstrClassD, .RASPCF, .PCLinkE);
|
||||
.BPRetF, .RetD, .RetE, .JalE,
|
||||
.WrongBPRetD, .RASPCF, .PCLinkE);
|
||||
|
||||
assign BPPredPCF = PredInstrClassF[2] ? RASPCF : BTAF;
|
||||
assign BPPredPCF = BPRetF ? RASPCF : BTAF;
|
||||
|
||||
assign InstrClassD[0] = BranchD;
|
||||
assign InstrClassD[1] = JumpD ;
|
||||
assign InstrClassD[2] = JumpD & (InstrD[19:15] & 5'h1B) == 5'h01; // return must return to ra or x5
|
||||
assign InstrClassD[3] = JumpD & (InstrD[11:7] & 5'h1B) == 5'h01; // jal(r) must link to ra or x5
|
||||
assign RetD = JumpD & (InstrD[19:15] & 5'h1B) == 5'h01; // return must return to ra or x5
|
||||
assign JalD = JumpD & (InstrD[11:7] & 5'h1B) == 5'h01; // jal(r) must link to ra or x5
|
||||
|
||||
flopenrc #(4) InstrClassRegE(clk, reset, FlushE, ~StallE, InstrClassD, InstrClassE);
|
||||
flopenrc #(4) InstrClassRegM(clk, reset, FlushM, ~StallM, InstrClassE, InstrClassM);
|
||||
flopenrc #(2) InstrClassRegE(clk, reset, FlushE, ~StallE, {JalD, RetD}, {JalE, RetE});
|
||||
flopenrc #(4) InstrClassRegM(clk, reset, FlushM, ~StallM, {JalE, RetE, JumpE, BranchE}, {JalM, RetM, JumpM, BranchM});
|
||||
flopenrc #(4) InstrClassRegW(clk, reset, FlushM, ~StallW, {JalM, RetM, JumpM, BranchM}, {JalW, RetW, JumpW, BranchW});
|
||||
flopenrc #(1) BPPredWrongMReg(clk, reset, FlushM, ~StallM, BPPredWrongE, BPPredWrongM);
|
||||
|
||||
// branch predictor
|
||||
flopenrc #(1) BPClassWrongRegM(clk, reset, FlushM, ~StallM, AnyWrongPredInstrClassE, PredictionInstrClassWrongM);
|
||||
|
||||
// pipeline the class
|
||||
flopenrc #(4) PredInstrClassRegD(clk, reset, FlushD, ~StallD, PredInstrClassF, PredInstrClassD);
|
||||
flopenrc #(1) WrongInstrClassRegE(clk, reset, FlushE, ~StallE, AnyWrongPredInstrClassD, AnyWrongPredInstrClassE);
|
||||
|
||||
// pipeline the predicted class
|
||||
flopenrc #(4) PredInstrClassRegD(clk, reset, FlushD, ~StallD, {BPJalF, BPRetF, BPJumpF, BPBranchF}, {BPJalD, BPRetD, BPJumpD, BPBranchD});
|
||||
|
||||
// Check the prediction
|
||||
// if it is a CFI then check if the next instruction address (PCD) matches the branch's target or fallthrough address.
|
||||
@ -218,11 +225,10 @@ module bpred (
|
||||
assign PredictionPCWrongE = PCCorrectE != PCD;
|
||||
|
||||
// branch class prediction wrong.
|
||||
assign WrongPredInstrClassD = PredInstrClassD ^ InstrClassD[3:0];
|
||||
assign AnyWrongPredInstrClassD = |WrongPredInstrClassD;
|
||||
assign AnyWrongPredInstrClassD = |({BPJalD, BPRetD, BPJumpD, BPBranchD} ^ {JalD, RetD, JumpD, BranchD});
|
||||
assign WrongBPRetD = BPRetD ^ RetD;
|
||||
|
||||
// branch is wrong only if the PC does not match and both the Decode and Fetch stages have valid instructions.
|
||||
//assign BPPredWrongE = (PredictionPCWrongE & |InstrClassE | (AnyWrongPredInstrClassE & ~|InstrClassE));
|
||||
assign BPPredWrongE = PredictionPCWrongE & InstrValidE & InstrValidD;
|
||||
|
||||
logic BPPredWrongEAlt;
|
||||
@ -232,7 +238,7 @@ module bpred (
|
||||
|
||||
// Output the predicted PC or corrected PC on miss-predict.
|
||||
// Selects the BP or PC+2/4.
|
||||
mux2 #(`XLEN) pcmux0(PCPlus2or4F, BPPredPCF, SelBPPredF, PCNext0F);
|
||||
mux2 #(`XLEN) pcmux0(PCPlus2or4F, BPPredPCF, BPPCSrcF, PCNext0F);
|
||||
// If the prediction is wrong select the correct address.
|
||||
mux2 #(`XLEN) pcmux1(PCNext0F, PCCorrectE, BPPredWrongE, PCNext1F);
|
||||
// Correct branch/jump target.
|
||||
@ -257,10 +263,10 @@ module bpred (
|
||||
// could be wrong or the fall through address selected for branch predict not taken.
|
||||
// By pipeline the BTB's PC and RAS address through the pipeline we can measure the accuracy of
|
||||
// both without the above inaccuracies.
|
||||
assign BTBPredPCWrongE = (BTAE != IEUAdrE) & (InstrClassE[0] | InstrClassE[1] & ~InstrClassE[2]) & PCSrcE;
|
||||
assign RASPredPCWrongE = (RASPCE != IEUAdrE) & InstrClassE[2] & PCSrcE;
|
||||
assign BTBPredPCWrongE = (BTAE != IEUAdrE) & (BranchE | JumpE & ~RetE) & PCSrcE;
|
||||
assign RASPredPCWrongE = (RASPCE != IEUAdrE) & RetE & PCSrcE;
|
||||
|
||||
assign JumpOrTakenBranchE = (InstrClassE[0] & PCSrcE) | InstrClassE[1];
|
||||
assign JumpOrTakenBranchE = (BranchE & PCSrcE) | JumpE;
|
||||
|
||||
flopenrc #(1) JumpOrTakenBranchMReg(clk, reset, FlushM, ~StallM, JumpOrTakenBranchE, JumpOrTakenBranchM);
|
||||
|
||||
@ -275,5 +281,11 @@ module bpred (
|
||||
end else begin
|
||||
assign {BTBPredPCWrongM, RASPredPCWrongM, JumpOrTakenBranchM} = '0;
|
||||
end
|
||||
|
||||
// **** Fix me
|
||||
assign InstrClassM = {JalM, RetM, JumpM, BranchM};
|
||||
flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW);
|
||||
flopenr #(`XLEN) IEUAdrWReg(clk, reset, ~StallW, IEUAdrM, IEUAdrW);
|
||||
|
||||
|
||||
endmodule
|
||||
|
@ -34,7 +34,7 @@ module btb #(parameter Depth = 10 ) (
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
input logic StallF, StallD, StallE, StallM, StallW, FlushD, FlushE, FlushM, FlushW,
|
||||
input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, // PC at various stages
|
||||
input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, PCW,// PC at various stages
|
||||
output logic [`XLEN-1:0] BTAF, // BTB's guess at PC
|
||||
output logic [`XLEN-1:0] BTAD,
|
||||
output logic [3:0] BTBPredInstrClassF, // BTB's guess at instruction class
|
||||
@ -42,14 +42,16 @@ module btb #(parameter Depth = 10 ) (
|
||||
input logic PredictionInstrClassWrongM, // BTB's instruction class guess was wrong
|
||||
input logic [`XLEN-1:0] IEUAdrE, // Branch/jump target address to insert into btb
|
||||
input logic [`XLEN-1:0] IEUAdrM, // Branch/jump target address to insert into btb
|
||||
input logic [`XLEN-1:0] IEUAdrW,
|
||||
input logic [3:0] InstrClassD, // Instruction class to insert into btb
|
||||
input logic [3:0] InstrClassE, // Instruction class to insert into btb
|
||||
input logic [3:0] InstrClassM // Instruction class to insert into btb
|
||||
input logic [3:0] InstrClassM, // Instruction class to insert into btb
|
||||
input logic [3:0] InstrClassW
|
||||
);
|
||||
|
||||
logic [Depth-1:0] PCNextFIndex, PCFIndex, PCDIndex, PCEIndex, PCMIndex;
|
||||
logic [Depth-1:0] PCNextFIndex, PCFIndex, PCDIndex, PCEIndex, PCMIndex, PCWIndex;
|
||||
logic [`XLEN-1:0] ResetPC;
|
||||
logic MatchF, MatchD, MatchE, MatchM, MatchNextX, MatchXF;
|
||||
logic MatchD, MatchE, MatchM, MatchW, MatchX;
|
||||
logic [`XLEN+3:0] ForwardBTBPrediction, ForwardBTBPredictionF;
|
||||
logic [`XLEN+3:0] TableBTBPredictionF;
|
||||
logic UpdateEn;
|
||||
@ -62,6 +64,7 @@ module btb #(parameter Depth = 10 ) (
|
||||
assign PCDIndex = {PCD[Depth+1] ^ PCD[1], PCD[Depth:2]};
|
||||
assign PCEIndex = {PCE[Depth+1] ^ PCE[1], PCE[Depth:2]};
|
||||
assign PCMIndex = {PCM[Depth+1] ^ PCM[1], PCM[Depth:2]};
|
||||
assign PCWIndex = {PCW[Depth+1] ^ PCW[1], PCW[Depth:2]};
|
||||
|
||||
// must output a valid PC and valid bit during reset. Because only PCF, not PCNextF is reset, PCNextF is invalid
|
||||
// during reset. The BTB must produce a non X PC1NextF to allow the simulation to run.
|
||||
@ -70,23 +73,18 @@ module btb #(parameter Depth = 10 ) (
|
||||
assign ResetPC = `RESET_VECTOR;
|
||||
assign PCNextFIndex = reset ? ResetPC[Depth+1:2] : {PCNextF[Depth+1] ^ PCNextF[1], PCNextF[Depth:2]};
|
||||
|
||||
assign MatchF = PCNextFIndex == PCFIndex;
|
||||
assign MatchD = PCNextFIndex == PCDIndex;
|
||||
assign MatchE = PCNextFIndex == PCEIndex;
|
||||
assign MatchM = PCNextFIndex == PCMIndex;
|
||||
assign MatchNextX = MatchF | MatchD | MatchE | MatchM;
|
||||
|
||||
flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF);
|
||||
assign MatchD = PCFIndex == PCDIndex;
|
||||
assign MatchE = PCFIndex == PCEIndex;
|
||||
assign MatchM = PCFIndex == PCMIndex;
|
||||
assign MatchW = PCFIndex == PCWIndex;
|
||||
assign MatchX = MatchD | MatchE | MatchM | MatchW;
|
||||
|
||||
assign ForwardBTBPrediction = MatchF ? {BTBPredInstrClassF, BTAF} :
|
||||
MatchD ? {InstrClassD, BTAD} :
|
||||
MatchE ? {InstrClassE, IEUAdrE} :
|
||||
{InstrClassM, IEUAdrM} ;
|
||||
|
||||
flopenr #(`XLEN+4) ForwardBTBPredicitonReg(clk, reset, ~StallF, ForwardBTBPrediction, ForwardBTBPredictionF);
|
||||
|
||||
assign {BTBPredInstrClassF, BTAF} = MatchXF ? ForwardBTBPredictionF : {TableBTBPredictionF};
|
||||
assign ForwardBTBPredictionF = MatchD ? {InstrClassD, BTAD} :
|
||||
MatchE ? {InstrClassE, IEUAdrE} :
|
||||
MatchM ? {InstrClassM, IEUAdrM} :
|
||||
{InstrClassW, IEUAdrW} ;
|
||||
|
||||
assign {BTBPredInstrClassF, BTAF} = MatchX ? ForwardBTBPredictionF : {TableBTBPredictionF};
|
||||
|
||||
assign UpdateEn = |InstrClassM | PredictionInstrClassWrongM;
|
||||
|
||||
|
@ -38,17 +38,17 @@ module gshare #(parameter k = 10,
|
||||
output logic [1:0] DirPredictionF,
|
||||
output logic DirPredictionWrongE,
|
||||
// update
|
||||
input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM,
|
||||
input logic BranchInstrF, BranchInstrD, BranchInstrE, BranchInstrM, PCSrcE
|
||||
input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, PCW,
|
||||
input logic BPBranchF, BranchD, BranchE, BranchM, BranchW, PCSrcE
|
||||
);
|
||||
|
||||
logic MatchF, MatchD, MatchE, MatchM;
|
||||
logic MatchNextX, MatchXF;
|
||||
logic MatchF, MatchD, MatchE, MatchM, MatchW;
|
||||
logic MatchX;
|
||||
|
||||
logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE, ForwardNewDirPrediction, ForwardDirPredictionF;
|
||||
logic [1:0] NewDirPredictionE, NewDirPredictionM;
|
||||
logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE, ForwardNewDirPredictionF;
|
||||
logic [1:0] NewDirPredictionE, NewDirPredictionM, NewDirPredictionW;
|
||||
|
||||
logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE, IndexM;
|
||||
logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE, IndexM, IndexW;
|
||||
|
||||
logic [k-1:0] GHRF, GHRD, GHRE, GHRM;
|
||||
logic [k-1:0] GHRNextM, GHRNextF;
|
||||
@ -68,22 +68,20 @@ module gshare #(parameter k = 10,
|
||||
assign IndexM = GHRM;
|
||||
end
|
||||
|
||||
assign MatchF = BranchInstrF & ~FlushD & (IndexNextF == IndexF);
|
||||
assign MatchD = BranchInstrD & ~FlushE & (IndexNextF == IndexD);
|
||||
assign MatchE = BranchInstrE & ~FlushM & (IndexNextF == IndexE);
|
||||
assign MatchM = BranchInstrM & ~FlushW & (IndexNextF == IndexM);
|
||||
assign MatchNextX = MatchF | MatchD | MatchE | MatchM;
|
||||
flopenrc #(k) IndexWReg(clk, reset, FlushW, ~StallW, IndexM, IndexW);
|
||||
|
||||
flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF);
|
||||
assign MatchD = BranchD & ~FlushE & (IndexF == IndexD);
|
||||
assign MatchE = BranchE & ~FlushM & (IndexF == IndexE);
|
||||
assign MatchM = BranchM & ~FlushW & (IndexF == IndexM);
|
||||
assign MatchW = BranchW & ~FlushW & (IndexF == IndexW);
|
||||
assign MatchX = MatchD | MatchE | MatchM | MatchW;
|
||||
|
||||
assign ForwardNewDirPrediction = MatchF ? {2{DirPredictionF[1]}} :
|
||||
MatchD ? {2{DirPredictionD[1]}} :
|
||||
assign ForwardNewDirPredictionF = MatchD ? {2{DirPredictionD[1]}} :
|
||||
MatchE ? {NewDirPredictionE} :
|
||||
NewDirPredictionM ;
|
||||
MatchM ? {NewDirPredictionM} :
|
||||
NewDirPredictionW ;
|
||||
|
||||
flopenr #(2) ForwardDirPredicitonReg(clk, reset, ~StallF, ForwardNewDirPrediction, ForwardDirPredictionF);
|
||||
|
||||
assign DirPredictionF = MatchXF ? ForwardDirPredictionF : TableDirPredictionF;
|
||||
assign DirPredictionF = MatchX ? ForwardNewDirPredictionF : TableDirPredictionF;
|
||||
|
||||
ram2p1r1wbe #(2**k, 2) PHT(.clk(clk),
|
||||
.ce1(~StallF), .ce2(~StallM & ~FlushM),
|
||||
@ -91,7 +89,7 @@ module gshare #(parameter k = 10,
|
||||
.rd1(TableDirPredictionF),
|
||||
.wa2(IndexM),
|
||||
.wd2(NewDirPredictionM),
|
||||
.we2(BranchInstrM),
|
||||
.we2(BranchM),
|
||||
.bwe2(1'b1));
|
||||
|
||||
flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD);
|
||||
@ -99,17 +97,18 @@ module gshare #(parameter k = 10,
|
||||
|
||||
satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE));
|
||||
flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewDirPredictionE, NewDirPredictionM);
|
||||
flopenrc #(2) NewPredictionRegW(clk, reset, FlushW, ~StallW, NewDirPredictionM, NewDirPredictionW);
|
||||
|
||||
assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchInstrE;
|
||||
assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchE;
|
||||
|
||||
assign GHRNextF = BranchInstrF ? {DirPredictionF[1], GHRF[k-1:1]} : GHRF;
|
||||
assign GHRF = BranchInstrD ? {DirPredictionD[1], GHRD[k-1:1]} : GHRD;
|
||||
assign GHRD = BranchInstrE ? {PCSrcE, GHRE[k-1:1]} : GHRE;
|
||||
assign GHRE = BranchInstrM ? {PCSrcM, GHRM[k-1:1]} : GHRM;
|
||||
assign GHRNextF = BPBranchF ? {DirPredictionF[1], GHRF[k-1:1]} : GHRF;
|
||||
assign GHRF = BranchD ? {DirPredictionD[1], GHRD[k-1:1]} : GHRD;
|
||||
assign GHRD = BranchE ? {PCSrcE, GHRE[k-1:1]} : GHRE;
|
||||
assign GHRE = BranchM ? {PCSrcM, GHRM[k-1:1]} : GHRM;
|
||||
|
||||
assign GHRNextM = {PCSrcM, GHRM[k-1:1]};
|
||||
|
||||
flopenr #(k) GHRReg(clk, reset, ~StallW & ~FlushW & BranchInstrM, GHRNextM, GHRM);
|
||||
flopenr #(k) GHRReg(clk, reset, ~StallW & ~FlushW & BranchM, GHRNextM, GHRM);
|
||||
flopenrc #(1) PCSrcMReg(clk, reset, FlushM, ~StallM, PCSrcE, PCSrcM);
|
||||
|
||||
endmodule
|
||||
|
@ -39,7 +39,7 @@ module gsharebasic #(parameter k = 10,
|
||||
output logic DirPredictionWrongE,
|
||||
// update
|
||||
input logic [`XLEN-1:0] PCNextF, PCM,
|
||||
input logic BranchInstrE, BranchInstrM, PCSrcE
|
||||
input logic BranchE, BranchM, PCSrcE
|
||||
);
|
||||
|
||||
logic [k-1:0] IndexNextF, IndexM;
|
||||
@ -64,7 +64,7 @@ module gsharebasic #(parameter k = 10,
|
||||
.rd1(DirPredictionF),
|
||||
.wa2(IndexM),
|
||||
.wd2(NewDirPredictionM),
|
||||
.we2(BranchInstrM),
|
||||
.we2(BranchM),
|
||||
.bwe2(1'b1));
|
||||
|
||||
flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD);
|
||||
@ -73,10 +73,10 @@ module gsharebasic #(parameter k = 10,
|
||||
satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE));
|
||||
flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewDirPredictionE, NewDirPredictionM);
|
||||
|
||||
assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchInstrE;
|
||||
assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchE;
|
||||
|
||||
assign GHRNext = BranchInstrM ? {PCSrcM, GHR[k-1:1]} : GHR;
|
||||
flopenr #(k) GHRReg(clk, reset, ~StallM & ~FlushM & BranchInstrM, GHRNext, GHR);
|
||||
assign GHRNext = BranchM ? {PCSrcM, GHR[k-1:1]} : GHR;
|
||||
flopenr #(k) GHRReg(clk, reset, ~StallM & ~FlushM & BranchM, GHRNext, GHR);
|
||||
flopenrc #(1) PCSrcMReg(clk, reset, FlushM, ~StallM, PCSrcE, PCSrcM);
|
||||
|
||||
flopenrc #(k) GHRFReg(clk, reset, FlushD, ~StallF, GHR, GHRF);
|
||||
|
@ -31,12 +31,12 @@
|
||||
module twoBitPredictor #(parameter k = 10) (
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
input logic StallF, StallD, StallE, StallM,
|
||||
input logic FlushD, FlushE, FlushM,
|
||||
input logic StallF, StallD, StallE, StallM, StallW,
|
||||
input logic FlushD, FlushE, FlushM, FlushW,
|
||||
input logic [`XLEN-1:0] PCNextF, PCM,
|
||||
output logic [1:0] DirPredictionF,
|
||||
output logic DirPredictionWrongE,
|
||||
input logic BranchInstrE, BranchInstrM,
|
||||
input logic BranchE, BranchM,
|
||||
input logic PCSrcE
|
||||
);
|
||||
|
||||
@ -55,18 +55,18 @@ module twoBitPredictor #(parameter k = 10) (
|
||||
|
||||
|
||||
ram2p1r1wbe #(2**k, 2) PHT(.clk(clk),
|
||||
.ce1(~StallF), .ce2(~StallM & ~FlushM),
|
||||
.ce1(~StallF), .ce2(~StallW & ~FlushW),
|
||||
.ra1(IndexNextF),
|
||||
.rd1(DirPredictionF),
|
||||
.wa2(IndexM),
|
||||
.wd2(NewDirPredictionM),
|
||||
.we2(BranchInstrM & ~StallM & ~FlushM),
|
||||
.we2(BranchM),
|
||||
.bwe2(1'b1));
|
||||
|
||||
flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD);
|
||||
flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, DirPredictionD, DirPredictionE);
|
||||
|
||||
assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchInstrE;
|
||||
assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchE;
|
||||
|
||||
satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE));
|
||||
flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewDirPredictionE, NewDirPredictionM);
|
||||
|
Loading…
Reference in New Issue
Block a user