Merge pull request #114 from ross144/main

Fix the branch predictor's gshare and btb critical path issue
This commit is contained in:
David Harris 2023-02-24 16:55:34 -08:00 committed by GitHub
commit be5bf22469
7 changed files with 144 additions and 123 deletions

View File

@ -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()

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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);