diff --git a/src/ifu/bpred/RASPredictor.sv b/src/ifu/bpred/RASPredictor.sv index 0a841ae11..40fb5bb15 100644 --- a/src/ifu/bpred/RASPredictor.sv +++ b/src/ifu/bpred/RASPredictor.sv @@ -33,8 +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, InstrClassE, PredInstrClassF, // Instr class + input logic [2:0] WrongPredInstrClassD, // Prediction class is wrong + input logic [3:0] InstrClassD, + input logic [3:0] InstrClassE, // Instr class + input logic [2:0] PredInstrClassF, input logic [`XLEN-1:0] PCLinkE, // PC of instruction after a jal output logic [`XLEN-1:0] RASPCF // Top of the stack ); diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index 0a01469d2..8a1eb801b 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -72,22 +72,24 @@ module bpred ( logic PredValidF; logic [1:0] DirPredictionF; - logic [3:0] BTBPredInstrClassF, PredInstrClassF, PredInstrClassD; + logic [2:0] BTBPredInstrClassF, PredInstrClassF, PredInstrClassD; logic [`XLEN-1:0] PredPCF, RASPCF; logic PredictionPCWrongE; logic AnyWrongPredInstrClassD, AnyWrongPredInstrClassE; - logic [3:0] InstrClassF, InstrClassD, InstrClassE; + logic [2:0] InstrClassF; + logic [3:0] InstrClassD; + logic [3:0] InstrClassE; logic DirPredictionWrongE, BTBPredPCWrongE, RASPredPCWrongE; logic SelBPPredF; logic [`XLEN-1:0] BPPredPCF; logic [`XLEN-1:0] PCNext0F; logic [`XLEN-1:0] PCCorrectE; - logic [3:0] WrongPredInstrClassD; + logic [2:0] WrongPredInstrClassD; - logic BTBTargetWrongE; - logic RASTargetWrongE; - logic JumpOrTakenBranchE; + logic BTBTargetWrongE; + logic RASTargetWrongE; + logic JumpOrTakenBranchE; logic [`XLEN-1:0] PredPCD, PredPCE, RASPCD, RASPCE; @@ -149,30 +151,31 @@ module bpred ( // the branch predictor needs a compact decoding of the instruction class. if (`INSTR_CLASS_PRED == 0) begin : DirectClassDecode logic [4:0] CompressedOpcF; - logic [3:0] InstrClassF; - logic cjal, cj, cjr, cjalr; + logic [2:0] InstrClassF; + logic cjal, cj, cjr, cjalr, CJumpF, CBranchF; + logic JumpF, BranchF; assign CompressedOpcF = {PostSpillInstrRawF[1:0], PostSpillInstrRawF[15:13]}; -// *** still need to update to use inclusive jump assign cjal = CompressedOpcF == 5'h09 & `XLEN == 32; assign cj = CompressedOpcF == 5'h0d; assign cjr = CompressedOpcF == 5'h14 & ~PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0; assign cjalr = CompressedOpcF == 5'h14 & PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0; + assign CJumpF = cjal | cj | cjr | cjalr; + assign CBranchF = CompressedOpcF[4:1] == 4'h7; + + assign JumpF = PostSpillInstrRawF[6:0] == 7'h67 | PostSpillInstrRawF[6:0] == 7'h6F; + assign BranchF = PostSpillInstrRawF[6:0] == 7'h63; - assign InstrClassF[0] = PostSpillInstrRawF[6:0] == 7'h63 | - (`C_SUPPORTED & CompressedOpcF[4:1] == 4'h7); - - //assign InstrClassF[1] = (PostSpillInstrRawF[6:0] == 7'h67 & (PostSpillInstrRawF[19:15] & 5'h1B) != 5'h01 & (PostSpillInstrRawF[11:7] & 5'h1B) != 5'h01) | // jump register, but not return - // (PostSpillInstrRawF[6:0] == 7'h6F & (PostSpillInstrRawF[11:7] & 5'h1B) != 5'h01) | // jump, RD != x1 or x5 - // (`C_SUPPORTED & (cj | (cjr & ((PostSpillInstrRawF[11:7] & 5'h1B) != 5'h01)) )); - assign InstrClassF[1] = PostSpillInstrRawF[6:0] == 7'h67 | PostSpillInstrRawF[6:0] == 7'h6F | (`C_SUPPORTED & (cjal | cj | cj | cjalr)); - - assign InstrClassF[2] = PostSpillInstrRawF[6:0] == 7'h67 & (PostSpillInstrRawF[19:15] & 5'h1B) == 5'h01 | // return must return to ra or r5 + assign InstrClassF[0] = BranchF | (`C_SUPPORTED & CBranchF); + assign InstrClassF[1] = JumpF | (`C_SUPPORTED & (cjal | cj | cj | cjalr)); + 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 InstrClassF[3] = ((PostSpillInstrRawF[6:0] & 7'h77) == 7'h67 & (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 InstrClassF[3] = (JumpF & (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]; @@ -206,7 +209,7 @@ module bpred ( {DirPredictionWrongM, BTBPredPCWrongM, RASPredPCWrongM, PredictionInstrClassWrongM}); // pipeline the class - flopenrc #(4) PredInstrClassRegD(clk, reset, FlushD, ~StallD, PredInstrClassF, PredInstrClassD); + flopenrc #(3) PredInstrClassRegD(clk, reset, FlushD, ~StallD, PredInstrClassF, PredInstrClassD); flopenrc #(1) WrongInstrClassRegE(clk, reset, FlushE, ~StallE, AnyWrongPredInstrClassD, AnyWrongPredInstrClassE); // Check the prediction @@ -218,7 +221,7 @@ module bpred ( assign PredictionPCWrongE = PCCorrectE != PCD; // branch class prediction wrong. - assign WrongPredInstrClassD = PredInstrClassD ^ InstrClassD; + assign WrongPredInstrClassD = PredInstrClassD ^ InstrClassD[2:0]; assign AnyWrongPredInstrClassD = |WrongPredInstrClassD; // branch is wrong only if the PC does not match and both the Decode and Fetch stages have valid instructions. diff --git a/src/ifu/bpred/btb.sv b/src/ifu/bpred/btb.sv index c538636df..2100eb352 100644 --- a/src/ifu/bpred/btb.sv +++ b/src/ifu/bpred/btb.sv @@ -36,7 +36,7 @@ module btb #(parameter int Depth = 10 ) ( input logic StallF, StallD, StallM, FlushD, FlushM, input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, // PC at various stages output logic [`XLEN-1:0] PredPCF, // BTB's guess at PC - output logic [3:0] BTBPredInstrClassF, // BTB's guess at instruction class + output logic [2:0] BTBPredInstrClassF, // BTB's guess at instruction class output logic PredValidF, // BTB's guess is valid // update input logic AnyWrongPredInstrClassE, // BTB's instruction class guess was wrong @@ -50,10 +50,9 @@ module btb #(parameter int Depth = 10 ) ( logic [Depth-1:0] PCNextFIndex, PCFIndex, PCDIndex, PCEIndex; logic [`XLEN-1:0] ResetPC; logic MatchF, MatchD, MatchE, MatchNextX, MatchXF; - logic [`XLEN+4:0] ForwardBTBPrediction, ForwardBTBPredictionF; - logic [`XLEN+3:0] TableBTBPredictionF; + logic [`XLEN+3:0] ForwardBTBPrediction, ForwardBTBPredictionF; + logic [`XLEN+2:0] TableBTBPredictionF; logic [`XLEN-1:0] PredPCD; - logic [3:0] PredInstrClassD; // *** copy of reg outside module logic UpdateEn; logic TablePredValidF, PredValidD; @@ -80,10 +79,10 @@ module btb #(parameter int Depth = 10 ) ( flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF); assign ForwardBTBPrediction = MatchF ? {PredValidF, BTBPredInstrClassF, PredPCF} : - MatchD ? {PredValidD, InstrClassD, PredPCD} : - {1'b1, InstrClassE, IEUAdrE} ; + MatchD ? {PredValidD, InstrClassD[2:0], PredPCD} : + {1'b1, InstrClassE[2:0], IEUAdrE} ; - flopenr #(`XLEN+5) ForwardBTBPredicitonReg(clk, reset, ~StallF, ForwardBTBPrediction, ForwardBTBPredictionF); + flopenr #(`XLEN+4) ForwardBTBPredicitonReg(clk, reset, ~StallF, ForwardBTBPrediction, ForwardBTBPredictionF); assign {PredValidF, BTBPredInstrClassF, PredPCF} = MatchXF ? ForwardBTBPredictionF : {TablePredValidF, TableBTBPredictionF}; @@ -96,14 +95,12 @@ module btb #(parameter int Depth = 10 ) ( if(~StallF | reset) TablePredValidF = ValidBits[PCNextFIndex]; end - //assign PredValidF = MatchXF ? 1'b1 : TablePredValidF; - assign UpdateEn = |InstrClassE | AnyWrongPredInstrClassE; // An optimization may be using a PC relative address. - ram2p1r1wbe #(2**Depth, `XLEN+4) memory( + ram2p1r1wbe #(2**Depth, `XLEN+3) memory( .clk, .ce1(~StallF | reset), .ra1(PCNextFIndex), .rd1(TableBTBPredictionF), - .ce2(~StallM & ~FlushM), .wa2(PCEIndex), .wd2({InstrClassE, IEUAdrE}), .we2(UpdateEn), .bwe2('1)); + .ce2(~StallM & ~FlushM), .wa2(PCEIndex), .wd2({InstrClassE[2:0], IEUAdrE}), .we2(UpdateEn), .bwe2('1)); flopenrc #(`XLEN+1) BTBD(clk, reset, FlushD, ~StallD, {PredValidF, PredPCF}, {PredValidD, PredPCD}); diff --git a/src/ifu/bpred/speculativeglobalhistory.sv b/src/ifu/bpred/speculativeglobalhistory.sv index 51dbb422b..645ac99e6 100644 --- a/src/ifu/bpred/speculativeglobalhistory.sv +++ b/src/ifu/bpred/speculativeglobalhistory.sv @@ -36,8 +36,8 @@ module speculativeglobalhistory #(parameter int k = 10 ) ( output logic [1:0] DirPredictionF, output logic DirPredictionWrongE, // update - input logic [3:0] PredInstrClassF, InstrClassD, InstrClassE, - input logic [3:0] WrongPredInstrClassD, + input logic [3:0] InstrClassD, InstrClassE, + input logic [2:0] PredInstrClassF, WrongPredInstrClassD, input logic PCSrcE ); diff --git a/src/ifu/bpred/speculativegshare.sv b/src/ifu/bpred/speculativegshare.sv index 1eb888a90..9d55dc874 100644 --- a/src/ifu/bpred/speculativegshare.sv +++ b/src/ifu/bpred/speculativegshare.sv @@ -37,8 +37,9 @@ module speculativegshare #(parameter int k = 10 ) ( output logic DirPredictionWrongE, // update input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, - input logic [3:0] PredInstrClassF, InstrClassD, InstrClassE, - input logic [3:0] WrongPredInstrClassD, + input logic [2:0] PredInstrClassF, + input logic [3:0] InstrClassD, InstrClassE, + input logic [2:0] WrongPredInstrClassD, input logic PCSrcE );