From f95f326b3dc90e82890cb3668a2874e438cf4834 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Fri, 24 Feb 2023 19:22:14 -0600 Subject: [PATCH 01/19] Renamed signals to match figure 10.18. --- src/ifu/bpred/bpred.sv | 2 +- src/ifu/bpred/btb.sv | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index c802ffb21..ddff3a04c 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -150,7 +150,7 @@ module bpred ( TargetPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCF, .PCD, .PCE, .PCM, .PCW, .BTAF, .BTAD, - .BTBPredInstrClassF({BTBJalF, BTBRetF, BTBJumpF, BTBBranchF}), + .BTBIClassF({BTBJalF, BTBRetF, BTBJumpF, BTBBranchF}), .PredictionInstrClassWrongM, .IEUAdrE, .IEUAdrM, .IEUAdrW, .InstrClassD({JalD, RetD, JumpD, BranchD}), .InstrClassE({JalE, RetE, JumpE, BranchE}), .InstrClassM({JalM, RetM, JumpM, BranchM}), diff --git a/src/ifu/bpred/btb.sv b/src/ifu/bpred/btb.sv index d2f0cb77b..5ad92517d 100644 --- a/src/ifu/bpred/btb.sv +++ b/src/ifu/bpred/btb.sv @@ -37,7 +37,7 @@ module btb #(parameter Depth = 10 ) ( 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 + output logic [3:0] BTBIClassF, // BTB's guess at instruction class // update input logic PredictionInstrClassWrongM, // BTB's instruction class guess was wrong input logic [`XLEN-1:0] IEUAdrE, // Branch/jump target address to insert into btb @@ -53,7 +53,7 @@ module btb #(parameter Depth = 10 ) ( logic [`XLEN-1:0] ResetPC; logic MatchD, MatchE, MatchM, MatchW, MatchX; logic [`XLEN+3:0] ForwardBTBPrediction, ForwardBTBPredictionF; - logic [`XLEN+3:0] TableBTBPredictionF; + logic [`XLEN+3:0] TableBTBPredF; logic UpdateEn; // hashing function for indexing the PC @@ -84,13 +84,13 @@ module btb #(parameter Depth = 10 ) ( MatchM ? {InstrClassM, IEUAdrM} : {InstrClassW, IEUAdrW} ; - assign {BTBPredInstrClassF, BTAF} = MatchX ? ForwardBTBPredictionF : {TableBTBPredictionF}; + assign {BTBIClassF, BTAF} = MatchX ? ForwardBTBPredictionF : {TableBTBPredF}; assign UpdateEn = |InstrClassM | PredictionInstrClassWrongM; // An optimization may be using a PC relative address. ram2p1r1wbe #(2**Depth, `XLEN+4) memory( - .clk, .ce1(~StallF | reset), .ra1(PCNextFIndex), .rd1(TableBTBPredictionF), + .clk, .ce1(~StallF | reset), .ra1(PCNextFIndex), .rd1(TableBTBPredF), .ce2(~StallW & ~FlushW), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(UpdateEn), .bwe2('1)); flopenrc #(`XLEN) BTBD(clk, reset, FlushD, ~StallD, BTAF, BTAD); From 8bd4a4c35b9977f76a6f6983d5eea12a5b4a7c2f Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Fri, 24 Feb 2023 19:51:47 -0600 Subject: [PATCH 02/19] Renamed signals to match new figures. --- src/ifu/bpred/bpred.sv | 24 ++++++++++---------- src/ifu/bpred/gshare.sv | 38 ++++++++++++++++---------------- src/ifu/bpred/gsharebasic.sv | 22 +++++++++--------- src/ifu/bpred/twoBitPredictor.sv | 22 +++++++++--------- src/ifu/ifu.sv | 6 ++--- src/privileged/csr.sv | 4 ++-- src/privileged/csrc.sv | 4 ++-- src/privileged/privileged.sv | 4 ++-- src/wally/wallypipelinedcore.sv | 6 ++--- 9 files changed, 65 insertions(+), 65 deletions(-) diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index ddff3a04c..015d4c908 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -64,18 +64,18 @@ module bpred ( // Report branch prediction status output logic BPPredWrongE, // Prediction is wrong output logic BPPredWrongM, // Prediction is wrong - output logic DirPredictionWrongM, // Prediction direction is wrong + output logic BPDirPredWrongM, // Prediction direction is wrong output logic BTBPredPCWrongM, // Prediction target wrong output logic RASPredPCWrongM, // RAS prediction is wrong output logic PredictionInstrClassWrongM // Class prediction is wrong ); - logic [1:0] DirPredictionF; + logic [1:0] BPDirPredF; logic [`XLEN-1:0] BTAF, RASPCF; logic PredictionPCWrongE; logic AnyWrongPredInstrClassD, AnyWrongPredInstrClassE; - logic DirPredictionWrongE; + logic BPDirPredWrongE; logic BPPCSrcF; logic [`XLEN-1:0] BPPredPCF; @@ -103,29 +103,29 @@ module bpred ( if (`BPRED_TYPE == "BP_TWOBIT") begin:Predictor twoBitPredictor #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, - .PCNextF, .PCM, .DirPredictionF, .DirPredictionWrongE, + .PCNextF, .PCM, .BPDirPredF, .BPDirPredWrongE, .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, .PCW, .DirPredictionF, .DirPredictionWrongE, + .PCNextF, .PCF, .PCD, .PCE, .PCM, .PCW, .BPDirPredF, .BPDirPredWrongE, .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, .PCW, .DirPredictionF, .DirPredictionWrongE, + .PCNextF, .PCF, .PCD, .PCE, .PCM, .PCW, .BPDirPredF, .BPDirPredWrongE, .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, + .PCNextF, .PCM, .BPDirPredF, .BPDirPredWrongE, .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, + .PCNextF, .PCM, .BPDirPredF, .BPDirPredWrongE, .BranchE, .BranchM, .PCSrcE); end else if (`BPRED_TYPE == "BPLOCALPAg") begin:Predictor @@ -134,7 +134,7 @@ module bpred ( localHistoryPredictor DirPredictor(.clk, .reset, .StallF, .StallE, .LookUpPC(PCNextF), - .Prediction(DirPredictionF), + .Prediction(BPDirPredF), // update .UpdatePC(PCE), .UpdateEN(InstrClassE[0] & ~StallE), @@ -192,7 +192,7 @@ module bpred ( // 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; + assign BPPCSrcF = (BPBranchF & BPDirPredF[1]) | BPJumpF; // Part 3 RAS RASPredictor RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM, @@ -275,8 +275,8 @@ module bpred ( flopenrc #(`XLEN) RASTargetDReg(clk, reset, FlushD, ~StallD, RASPCF, RASPCD); flopenrc #(`XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE); flopenrc #(3) BPPredWrongRegM(clk, reset, FlushM, ~StallM, - {DirPredictionWrongE, BTBPredPCWrongE, RASPredPCWrongE}, - {DirPredictionWrongM, BTBPredPCWrongM, RASPredPCWrongM}); + {BPDirPredWrongE, BTBPredPCWrongE, RASPredPCWrongE}, + {BPDirPredWrongM, BTBPredPCWrongM, RASPredPCWrongM}); end else begin assign {BTBPredPCWrongM, RASPredPCWrongM, JumpOrTakenBranchM} = '0; diff --git a/src/ifu/bpred/gshare.sv b/src/ifu/bpred/gshare.sv index 70c03afb0..596e587c8 100644 --- a/src/ifu/bpred/gshare.sv +++ b/src/ifu/bpred/gshare.sv @@ -35,8 +35,8 @@ module gshare #(parameter k = 10, input logic reset, input logic StallF, StallD, StallE, StallM, StallW, input logic FlushD, FlushE, FlushM, FlushW, - output logic [1:0] DirPredictionF, - output logic DirPredictionWrongE, + output logic [1:0] BPDirPredF, + output logic BPDirPredWrongE, // update input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, PCW, input logic BPBranchF, BranchD, BranchE, BranchM, BranchW, PCSrcE @@ -45,8 +45,8 @@ module gshare #(parameter k = 10, logic MatchF, MatchD, MatchE, MatchM, MatchW; logic MatchX; - logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE, ForwardNewDirPredictionF; - logic [1:0] NewDirPredictionE, NewDirPredictionM, NewDirPredictionW; + logic [1:0] TableBPDirPredF, BPDirPredD, BPDirPredE, ForwardNewBPDirPredF; + logic [1:0] NewBPDirPredE, NewBPDirPredM, NewBPDirPredW; logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE, IndexM, IndexW; @@ -76,33 +76,33 @@ module gshare #(parameter k = 10, assign MatchW = BranchW & ~FlushW & (IndexF == IndexW); assign MatchX = MatchD | MatchE | MatchM | MatchW; - assign ForwardNewDirPredictionF = MatchD ? {2{DirPredictionD[1]}} : - MatchE ? {NewDirPredictionE} : - MatchM ? {NewDirPredictionM} : - NewDirPredictionW ; + assign ForwardNewBPDirPredF = MatchD ? {2{BPDirPredD[1]}} : + MatchE ? {NewBPDirPredE} : + MatchM ? {NewBPDirPredM} : + NewBPDirPredW ; - assign DirPredictionF = MatchX ? ForwardNewDirPredictionF : TableDirPredictionF; + assign BPDirPredF = MatchX ? ForwardNewBPDirPredF : TableBPDirPredF; ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), .ce1(~StallF), .ce2(~StallM & ~FlushM), .ra1(IndexNextF), - .rd1(TableDirPredictionF), + .rd1(TableBPDirPredF), .wa2(IndexM), - .wd2(NewDirPredictionM), + .wd2(NewBPDirPredM), .we2(BranchM), .bwe2(1'b1)); - flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD); - flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, DirPredictionD, DirPredictionE); + flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, BPDirPredF, BPDirPredD); + flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, BPDirPredD, BPDirPredE); - 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); + satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(BPDirPredE), .NewState(NewBPDirPredE)); + flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewBPDirPredE, NewBPDirPredM); + flopenrc #(2) NewPredictionRegW(clk, reset, FlushW, ~StallW, NewBPDirPredM, NewBPDirPredW); - assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchE; + assign BPDirPredWrongE = PCSrcE != BPDirPredE[1] & BranchE; - assign GHRNextF = BPBranchF ? {DirPredictionF[1], GHRF[k-1:1]} : GHRF; - assign GHRF = BranchD ? {DirPredictionD[1], GHRD[k-1:1]} : GHRD; + assign GHRNextF = BPBranchF ? {BPDirPredF[1], GHRF[k-1:1]} : GHRF; + assign GHRF = BranchD ? {BPDirPredD[1], GHRD[k-1:1]} : GHRD; assign GHRD = BranchE ? {PCSrcE, GHRE[k-1:1]} : GHRE; assign GHRE = BranchM ? {PCSrcM, GHRM[k-1:1]} : GHRM; diff --git a/src/ifu/bpred/gsharebasic.sv b/src/ifu/bpred/gsharebasic.sv index e793e7ac6..130f17328 100644 --- a/src/ifu/bpred/gsharebasic.sv +++ b/src/ifu/bpred/gsharebasic.sv @@ -35,16 +35,16 @@ module gsharebasic #(parameter k = 10, input logic reset, input logic StallF, StallD, StallE, StallM, StallW, input logic FlushD, FlushE, FlushM, FlushW, - output logic [1:0] DirPredictionF, - output logic DirPredictionWrongE, + output logic [1:0] BPDirPredF, + output logic BPDirPredWrongE, // update input logic [`XLEN-1:0] PCNextF, PCM, input logic BranchE, BranchM, PCSrcE ); logic [k-1:0] IndexNextF, IndexM; - logic [1:0] DirPredictionD, DirPredictionE; - logic [1:0] NewDirPredictionE, NewDirPredictionM; + logic [1:0] BPDirPredD, BPDirPredE; + logic [1:0] NewBPDirPredE, NewBPDirPredM; logic [k-1:0] GHRF, GHRD, GHRE, GHRM, GHR; logic [k-1:0] GHRNext; @@ -61,19 +61,19 @@ module gsharebasic #(parameter k = 10, ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), .ce1(~StallF), .ce2(~StallW & ~FlushW), .ra1(IndexNextF), - .rd1(DirPredictionF), + .rd1(BPDirPredF), .wa2(IndexM), - .wd2(NewDirPredictionM), + .wd2(NewBPDirPredM), .we2(BranchM), .bwe2(1'b1)); - flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD); - flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, DirPredictionD, DirPredictionE); + flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, BPDirPredF, BPDirPredD); + flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, BPDirPredD, BPDirPredE); - satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE)); - flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewDirPredictionE, NewDirPredictionM); + satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(BPDirPredE), .NewState(NewBPDirPredE)); + flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewBPDirPredE, NewBPDirPredM); - assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchE; + assign BPDirPredWrongE = PCSrcE != BPDirPredE[1] & BranchE; assign GHRNext = BranchM ? {PCSrcM, GHR[k-1:1]} : GHR; flopenr #(k) GHRReg(clk, reset, ~StallM & ~FlushM & BranchM, GHRNext, GHR); diff --git a/src/ifu/bpred/twoBitPredictor.sv b/src/ifu/bpred/twoBitPredictor.sv index 58bf1c6bd..7011a0580 100644 --- a/src/ifu/bpred/twoBitPredictor.sv +++ b/src/ifu/bpred/twoBitPredictor.sv @@ -34,8 +34,8 @@ module twoBitPredictor #(parameter k = 10) ( 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, + output logic [1:0] BPDirPredF, + output logic BPDirPredWrongE, input logic BranchE, BranchM, input logic PCSrcE ); @@ -43,8 +43,8 @@ module twoBitPredictor #(parameter k = 10) ( logic [k-1:0] IndexNextF, IndexM; logic [1:0] PredictionMemory; logic DoForwarding, DoForwardingF; - logic [1:0] DirPredictionD, DirPredictionE; - logic [1:0] NewDirPredictionE, NewDirPredictionM; + logic [1:0] BPDirPredD, BPDirPredE; + logic [1:0] NewBPDirPredE, NewBPDirPredM; // hashing function for indexing the PC // We have k bits to index, but XLEN bits as the input. @@ -57,19 +57,19 @@ module twoBitPredictor #(parameter k = 10) ( ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), .ce1(~StallF), .ce2(~StallW & ~FlushW), .ra1(IndexNextF), - .rd1(DirPredictionF), + .rd1(BPDirPredF), .wa2(IndexM), - .wd2(NewDirPredictionM), + .wd2(NewBPDirPredM), .we2(BranchM), .bwe2(1'b1)); - flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD); - flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, DirPredictionD, DirPredictionE); + flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, BPDirPredF, BPDirPredD); + flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, BPDirPredD, BPDirPredE); - assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchE; + assign BPDirPredWrongE = PCSrcE != BPDirPredE[1] & BranchE; - satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE)); - flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewDirPredictionE, NewDirPredictionM); + satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(BPDirPredE), .NewState(NewBPDirPredE)); + flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewBPDirPredE, NewBPDirPredM); endmodule diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index 71221ef63..e13a08bf9 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -66,7 +66,7 @@ module ifu ( // branch predictor output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br output logic JumpOrTakenBranchM, - output logic DirPredictionWrongM, // Prediction direction is wrong + output logic BPDirPredWrongM, // Prediction direction is wrong output logic BTBPredPCWrongM, // Prediction target wrong output logic RASPredPCWrongM, // RAS prediction is wrong output logic PredictionInstrClassWrongM, // Class prediction is wrong @@ -332,12 +332,12 @@ module ifu ( .BranchD, .BranchE, .JumpD, .JumpE, .InstrD, .PCNextF, .PCPlus2or4F, .PCNext1F, .PCE, .PCM, .PCSrcE, .IEUAdrE, .IEUAdrM, .PCF, .NextValidPCE, .PCD, .PCLinkE, .InstrClassM, .BPPredWrongE, .PostSpillInstrRawF, .JumpOrTakenBranchM, .BPPredWrongM, - .DirPredictionWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM); + .BPDirPredWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM); end else begin : bpred mux2 #(`XLEN) pcmux1(.d0(PCPlus2or4F), .d1(IEUAdrE), .s(PCSrcE), .y(PCNext1F)); assign BPPredWrongE = PCSrcE; - assign {InstrClassM, DirPredictionWrongM, BTBPredPCWrongM, RASPredPCWrongM, PredictionInstrClassWrongM} = '0; + assign {InstrClassM, BPDirPredWrongM, BTBPredPCWrongM, RASPredPCWrongM, PredictionInstrClassWrongM} = '0; assign NextValidPCE = PCE; end diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index 7b765bae0..ee3d947fd 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -57,7 +57,7 @@ module csr #(parameter input logic SelHPTW, // hardware page table walker active, so base endianness on supervisor mode // inputs for performance counters input logic LoadStallD, - input logic DirPredictionWrongM, + input logic BPDirPredWrongM, input logic BTBPredPCWrongM, input logic RASPredPCWrongM, input logic PredictionInstrClassWrongM, @@ -259,7 +259,7 @@ module csr #(parameter if (`ZICOUNTERS_SUPPORTED) begin:counters csrc counters(.clk, .reset, .StallE, .StallM, .FlushM, .InstrValidNotFlushedM, .LoadStallD, .CSRMWriteM, - .DirPredictionWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM, .JumpOrTakenBranchM, .BPPredWrongM, + .BPDirPredWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM, .JumpOrTakenBranchM, .BPPredWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .CSRAdrM, .PrivilegeModeW, .CSRWriteValM, .MCOUNTINHIBIT_REGW, .MCOUNTEREN_REGW, .SCOUNTEREN_REGW, diff --git a/src/privileged/csrc.sv b/src/privileged/csrc.sv index d61835826..5cc58ce34 100644 --- a/src/privileged/csrc.sv +++ b/src/privileged/csrc.sv @@ -44,7 +44,7 @@ module csrc #(parameter input logic StallE, StallM, input logic FlushM, input logic InstrValidNotFlushedM, LoadStallD, CSRMWriteM, - input logic DirPredictionWrongM, + input logic BPDirPredWrongM, input logic BTBPredPCWrongM, input logic RASPredPCWrongM, input logic PredictionInstrClassWrongM, @@ -86,7 +86,7 @@ module csrc #(parameter assign CounterEvent[`COUNTERS-1:3] = 0; end else begin: cevent // User-defined counters assign CounterEvent[3] = LoadStallM & InstrValidNotFlushedM; // Load Stalls. don't want to suppress on flush as this only happens if flushed. - assign CounterEvent[4] = DirPredictionWrongM & InstrValidNotFlushedM; // Branch predictor wrong direction + assign CounterEvent[4] = BPDirPredWrongM & InstrValidNotFlushedM; // Branch predictor wrong direction assign CounterEvent[5] = InstrClassM[0] & InstrValidNotFlushedM; // branch instruction assign CounterEvent[6] = BTBPredPCWrongM & InstrValidNotFlushedM; // branch predictor wrong target assign CounterEvent[7] = JumpOrTakenBranchM & InstrValidNotFlushedM; // jump or taken branch instructions diff --git a/src/privileged/privileged.sv b/src/privileged/privileged.sv index 300da8a65..93b7f9729 100644 --- a/src/privileged/privileged.sv +++ b/src/privileged/privileged.sv @@ -46,7 +46,7 @@ module privileged ( // processor events for performance counter logging input logic FRegWriteM, // instruction will write floating-point registers input logic LoadStallD, // load instruction is stalling - input logic DirPredictionWrongM, // branch predictor guessed wrong directoin + input logic BPDirPredWrongM, // branch predictor guessed wrong directoin input logic BTBPredPCWrongM, // branch predictor guessed wrong target input logic RASPredPCWrongM, // return adddress stack guessed wrong target input logic PredictionInstrClassWrongM, // branch predictor guessed wrong instruction class @@ -125,7 +125,7 @@ module privileged ( .CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .wfiM, .IntPendingM, .InterruptM, .MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, - .DirPredictionWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .BPPredWrongM, + .BPDirPredWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .BPPredWrongM, .PredictionInstrClassWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .JumpOrTakenBranchM, .NextPrivilegeModeM, .PrivilegeModeW, .CauseM, .SelHPTW, .STATUS_MPP, .STATUS_SPP, .STATUS_TSR, .STATUS_TVM, diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index 02074f973..c4b83386d 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -141,7 +141,7 @@ module wallypipelinedcore ( logic LSUHREADY; logic BPPredWrongE, BPPredWrongM; - logic DirPredictionWrongM; + logic BPDirPredWrongM; logic BTBPredPCWrongM; logic RASPredPCWrongM; logic PredictionInstrClassWrongM; @@ -176,7 +176,7 @@ module wallypipelinedcore ( .PCLinkE, .PCSrcE, .IEUAdrE, .IEUAdrM, .PCE, .BPPredWrongE, .BPPredWrongM, // Mem .CommittedF, .UnalignedPCNextF, .InvalidateICacheM, .CSRWriteFenceM, - .InstrD, .InstrM, .PCM, .InstrClassM, .DirPredictionWrongM, .JumpOrTakenBranchM, + .InstrD, .InstrM, .PCM, .InstrClassM, .BPDirPredWrongM, .JumpOrTakenBranchM, .BTBPredPCWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM, // Faults out .IllegalBaseInstrD, .IllegalFPUInstrD, .InstrPageFaultF, .IllegalIEUFPUInstrD, .InstrMisalignedFaultM, @@ -289,7 +289,7 @@ module wallypipelinedcore ( .RetM, .TrapM, .sfencevmaM, .InstrValidM, .CommittedM, .CommittedF, .FRegWriteM, .LoadStallD, - .DirPredictionWrongM, .BTBPredPCWrongM, .BPPredWrongM, + .BPDirPredWrongM, .BTBPredPCWrongM, .BPPredWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM, .InstrClassM, .JumpOrTakenBranchM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .PrivilegedM, .InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM, From 9df05f0b3d01ab77809c1db53985fa3b9105c6e4 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Fri, 24 Feb 2023 19:56:55 -0600 Subject: [PATCH 03/19] More signal renames. --- src/ifu/bpred/gshare.sv | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ifu/bpred/gshare.sv b/src/ifu/bpred/gshare.sv index 596e587c8..30af1c4cf 100644 --- a/src/ifu/bpred/gshare.sv +++ b/src/ifu/bpred/gshare.sv @@ -45,7 +45,7 @@ module gshare #(parameter k = 10, logic MatchF, MatchD, MatchE, MatchM, MatchW; logic MatchX; - logic [1:0] TableBPDirPredF, BPDirPredD, BPDirPredE, ForwardNewBPDirPredF; + logic [1:0] TableBPDirPredF, BPDirPredD, BPDirPredE, FwdNewDirPredF; logic [1:0] NewBPDirPredE, NewBPDirPredM, NewBPDirPredW; logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE, IndexM, IndexW; @@ -76,12 +76,12 @@ module gshare #(parameter k = 10, assign MatchW = BranchW & ~FlushW & (IndexF == IndexW); assign MatchX = MatchD | MatchE | MatchM | MatchW; - assign ForwardNewBPDirPredF = MatchD ? {2{BPDirPredD[1]}} : + assign FwdNewDirPredF = MatchD ? {2{BPDirPredD[1]}} : MatchE ? {NewBPDirPredE} : MatchM ? {NewBPDirPredM} : NewBPDirPredW ; - assign BPDirPredF = MatchX ? ForwardNewBPDirPredF : TableBPDirPredF; + assign BPDirPredF = MatchX ? FwdNewDirPredF : TableBPDirPredF; ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), .ce1(~StallF), .ce2(~StallM & ~FlushM), From eb9dc7e67db7281a51f43400a9137449811e3f5c Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Fri, 24 Feb 2023 22:55:51 -0600 Subject: [PATCH 04/19] gshare cleanup. --- src/ifu/bpred/bpred.sv | 4 ++-- src/ifu/bpred/gshare.sv | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index 015d4c908..02e3e1aa2 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -108,13 +108,13 @@ module bpred ( 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, .PCW, .BPDirPredF, .BPDirPredWrongE, + .PCNextF, .PCF, .PCD, .PCE, .PCM, .BPDirPredF, .BPDirPredWrongE, .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, .PCW, .BPDirPredF, .BPDirPredWrongE, + .PCNextF, .PCF, .PCD, .PCE, .PCM, .BPDirPredF, .BPDirPredWrongE, .BPBranchF, .BranchD, .BranchE, .BranchM, .BranchW, .PCSrcE); diff --git a/src/ifu/bpred/gshare.sv b/src/ifu/bpred/gshare.sv index 30af1c4cf..40cd94e86 100644 --- a/src/ifu/bpred/gshare.sv +++ b/src/ifu/bpred/gshare.sv @@ -38,7 +38,7 @@ module gshare #(parameter k = 10, output logic [1:0] BPDirPredF, output logic BPDirPredWrongE, // update - input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, PCW, + input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, input logic BPBranchF, BranchD, BranchE, BranchM, BranchW, PCSrcE ); From 7f8034013d2e3e7112a30f7a8f1281e8a53f7273 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Fri, 24 Feb 2023 22:57:32 -0600 Subject: [PATCH 05/19] PHT was enabled using the wrong ~flush and ~stall. --- src/ifu/bpred/gshare.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ifu/bpred/gshare.sv b/src/ifu/bpred/gshare.sv index 40cd94e86..66b2b4842 100644 --- a/src/ifu/bpred/gshare.sv +++ b/src/ifu/bpred/gshare.sv @@ -84,7 +84,7 @@ module gshare #(parameter k = 10, assign BPDirPredF = MatchX ? FwdNewDirPredF : TableBPDirPredF; ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), - .ce1(~StallF), .ce2(~StallM & ~FlushM), + .ce1(~StallF), .ce2(~StallW & ~FlushW), .ra1(IndexNextF), .rd1(TableBPDirPredF), .wa2(IndexM), From e8c5e5b5ff137ae1574ac5dd8e2f5f5504b7de29 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Sun, 26 Feb 2023 20:20:30 -0600 Subject: [PATCH 06/19] Create module for instruction class prediction and decoding. --- src/ifu/bpred/RASPredictor.sv | 28 ++++----- src/ifu/bpred/bpred.sv | 105 +++++++++------------------------ src/ifu/bpred/icpred.sv | 107 ++++++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+), 90 deletions(-) create mode 100644 src/ifu/bpred/icpred.sv diff --git a/src/ifu/bpred/RASPredictor.sv b/src/ifu/bpred/RASPredictor.sv index 5f14a028e..72c594556 100644 --- a/src/ifu/bpred/RASPredictor.sv +++ b/src/ifu/bpred/RASPredictor.sv @@ -33,11 +33,11 @@ module RASPredictor #(parameter int StackSize = 16 )( input logic clk, input logic reset, input logic StallF, StallD, StallE, StallM, FlushD, FlushE, FlushM, - 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 + input logic WrongBPReturnD, // Prediction class is wrong + input logic ReturnD, + input logic ReturnE, CallE, // Instr class + input logic BPReturnF, + input logic [`XLEN-1:0] PCLinkE, // PC of instruction after a call output logic [`XLEN-1:0] RASPCF // Top of the stack ); @@ -54,21 +54,21 @@ module RASPredictor #(parameter int StackSize = 16 )( logic IncrRepairD, DecRepairD; logic DecrementPtr; - logic FlushedRetDE; - logic WrongPredRetD; + logic FlushedReturnDE; + logic WrongPredReturnD; - assign PopF = BPRetF & ~StallD & ~FlushD; - assign PushE = JalE & ~StallM & ~FlushM; + assign PopF = BPReturnF & ~StallD & ~FlushD; + assign PushE = CallE & ~StallM & ~FlushM; - assign WrongPredRetD = (WrongBPRetD) & ~StallE & ~FlushE; - assign FlushedRetDE = (~StallE & FlushE & RetD) | (~StallM & FlushM & RetE); // flushed ret + assign WrongPredReturnD = (WrongBPReturnD) & ~StallE & ~FlushE; + assign FlushedReturnDE = (~StallE & FlushE & ReturnD) | (~StallM & FlushM & ReturnE); // flushed return - assign RepairD = WrongPredRetD | FlushedRetDE ; + assign RepairD = WrongPredReturnD | FlushedReturnDE ; - assign IncrRepairD = FlushedRetDE | (WrongPredRetD & ~RetD); // Guessed it was a ret, but its not + assign IncrRepairD = FlushedReturnDE | (WrongPredReturnD & ~ReturnD); // Guessed it was a return, but its not - assign DecRepairD = WrongPredRetD & RetD; // Guessed non ret but is a ret. + assign DecRepairD = WrongPredReturnD & ReturnD; // Guessed non return but is a return. assign CounterEn = PopF | PushE | RepairD; diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index 02e3e1aa2..0aa1bc038 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -58,8 +58,8 @@ module bpred ( input logic [`XLEN-1:0] IEUAdrE, // The branch/jump target address input logic [`XLEN-1:0] IEUAdrM, // The branch/jump target address input logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address) - output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br - output logic JumpOrTakenBranchM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br + output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as call, return, jr (not return), j, br + output logic JumpOrTakenBranchM, // The valid instruction class. 1-hot encoded as call, return, jr (not return), j, br // Report branch prediction status output logic BPPredWrongE, // Prediction is wrong @@ -88,14 +88,14 @@ 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 BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF; + logic BPBranchF, BPJumpF, BPReturnF, BPCallF; + logic BPBranchD, BPJumpD, BPReturnD, BPCallD; + logic ReturnD, CallD; + logic ReturnE, CallE; + logic BranchM, JumpM, ReturnM, CallM; + logic BranchW, JumpW, ReturnW, CallW; + logic WrongBPReturnD; logic [`XLEN-1:0] PCW, IEUAdrW; // Part 1 branch direction prediction @@ -150,72 +150,28 @@ module bpred ( TargetPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCF, .PCD, .PCE, .PCM, .PCW, .BTAF, .BTAD, - .BTBIClassF({BTBJalF, BTBRetF, BTBJumpF, BTBBranchF}), + .BTBIClassF({BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF}), .PredictionInstrClassWrongM, .IEUAdrE, .IEUAdrM, .IEUAdrW, - .InstrClassD({JalD, RetD, JumpD, BranchD}), .InstrClassE({JalE, RetE, JumpE, BranchE}), .InstrClassM({JalM, RetM, JumpM, BranchM}), - .InstrClassW({JalW, RetW, JumpW, BranchW})); + .InstrClassD({CallD, ReturnD, JumpD, BranchD}), .InstrClassE({CallE, ReturnE, JumpE, BranchE}), .InstrClassM({CallM, ReturnM, JumpM, BranchM}), + .InstrClassW({CallW, ReturnW, JumpW, BranchW})); - 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 NCJumpF, NCBranchF; - if(`C_SUPPORTED) begin - logic [4:0] CompressedOpcF; - assign CompressedOpcF = {PostSpillInstrRawF[1:0], PostSpillInstrRawF[15:13]}; - 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; - end else begin - assign {cjal, cj, cjr, cjalr, CJumpF, CBranchF} = '0; - end + icpred icpred(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, + .PostSpillInstrRawF, .InstrD, .BranchD, .BranchE, .JumpD, .JumpE, .BranchM, .BranchW, .JumpM, .JumpW, + .CallD, .CallE, .CallM, .CallW, .ReturnD, .ReturnE, .ReturnM, .ReturnW, .BTBCallF, .BTBReturnF, .BTBJumpF, .BTBBranchF, + .BPCallF, .BPReturnF, .BPJumpF, .BPBranchF, .PredictionInstrClassWrongM, .WrongBPReturnD); - assign NCJumpF = PostSpillInstrRawF[6:0] == 7'h67 | PostSpillInstrRawF[6:0] == 7'h6F; - assign NCBranchF = PostSpillInstrRawF[6:0] == 7'h63; - - 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 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))); - - end else begin - // This section connects the BTB's instruction class prediction. - assign {BPJalF, BPRetF, BPJumpF, BPBranchF} = {BTBJalF, BTBRetF, BTBJumpF, BTBBranchF}; - end - assign BPPCSrcF = (BPBranchF & BPDirPredF[1]) | BPJumpF; - - // Part 3 RAS - RASPredictor RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM, - .BPRetF, .RetD, .RetE, .JalE, - .WrongBPRetD, .RASPCF, .PCLinkE); - - assign BPPredPCF = BPRetF ? RASPCF : BTAF; - - 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 #(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}); + assign BPPCSrcF = (BPBranchF & BPDirPredF[1]) | BPJumpF; flopenrc #(1) BPPredWrongMReg(clk, reset, FlushM, ~StallM, BPPredWrongE, BPPredWrongM); - // branch predictor - flopenrc #(1) BPClassWrongRegM(clk, reset, FlushM, ~StallM, AnyWrongPredInstrClassE, PredictionInstrClassWrongM); - flopenrc #(1) WrongInstrClassRegE(clk, reset, FlushE, ~StallE, AnyWrongPredInstrClassD, AnyWrongPredInstrClassE); + // Part 3 RAS + RASPredictor RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM, + .BPReturnF, .ReturnD, .ReturnE, .CallE, + .WrongBPReturnD, .RASPCF, .PCLinkE); + + assign BPPredPCF = BPReturnF ? RASPCF : BTAF; - // 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. // if the class prediction is wrong a regular instruction may have been predicted as a taken branch @@ -223,17 +179,14 @@ module bpred ( // The next instruction is always valid as no other flush would occur at the same time as the branch and not // also flush the branch. This will change in a superscaler cpu. assign PredictionPCWrongE = PCCorrectE != PCD; - - // branch class prediction wrong. - 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 & InstrValidE & InstrValidD; + // *** clean up old signal names for testing. logic BPPredWrongEAlt; logic NotMatch; - assign BPPredWrongEAlt = PredictionPCWrongE & InstrValidE & InstrValidD; // this does not work for cubic benchmark + assign BPPredWrongEAlt = PredictionPCWrongE & InstrValidE & InstrValidD; assign NotMatch = BPPredWrongE != BPPredWrongEAlt; // Output the predicted PC or corrected PC on miss-predict. @@ -263,8 +216,8 @@ 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) & (BranchE | JumpE & ~RetE) & PCSrcE; - assign RASPredPCWrongE = (RASPCE != IEUAdrE) & RetE & PCSrcE; + assign BTBPredPCWrongE = (BTAE != IEUAdrE) & (BranchE | JumpE & ~ReturnE) & PCSrcE; + assign RASPredPCWrongE = (RASPCE != IEUAdrE) & ReturnE & PCSrcE; assign JumpOrTakenBranchE = (BranchE & PCSrcE) | JumpE; @@ -283,7 +236,7 @@ module bpred ( end // **** Fix me - assign InstrClassM = {JalM, RetM, JumpM, BranchM}; + assign InstrClassM = {CallM, ReturnM, JumpM, BranchM}; flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); flopenr #(`XLEN) IEUAdrWReg(clk, reset, ~StallW, IEUAdrM, IEUAdrW); diff --git a/src/ifu/bpred/icpred.sv b/src/ifu/bpred/icpred.sv new file mode 100644 index 000000000..cd6772ba2 --- /dev/null +++ b/src/ifu/bpred/icpred.sv @@ -0,0 +1,107 @@ +/////////////////////////////////////////// +// icpred.sv +// +// Written: Ross Thomposn ross1728@gmail.com +// Created: February 26, 2023 +// Modified: February 26, 2023 +// +// Purpose: Partial decode of instructions into control flow instructions (cfi)P +// Call, Return, Jump, and Branch +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// +// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +`include "wally-config.vh" + +`define INSTR_CLASS_PRED 1 + +module icpred ( + input logic clk, reset, + input logic StallF, StallD, StallE, StallM, StallW, + input logic FlushD, FlushE, FlushM, FlushW, + input logic [31:0] PostSpillInstrRawF, InstrD, // Instruction + input logic BranchD, BranchE, + input logic JumpD, JumpE, + output logic BranchM, BranchW, + output logic JumpM, JumpW, + output logic CallD, CallE, CallM, CallW, + output logic ReturnD, ReturnE, ReturnM, ReturnW, + input logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF, + output logic BPCallF, BPReturnF, BPJumpF, BPBranchF, + output logic PredictionInstrClassWrongM, WrongBPReturnD +); + + logic AnyWrongPredInstrClassD, AnyWrongPredInstrClassE; + logic BPBranchD, BPJumpD, BPReturnD, BPCallD; + + 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, Call, Return, Jump, and Branch instructions. + // This logic is not described in the text book as of 23 February 2023. + logic ccall, cj, cjr, ccallr, CJumpF, CBranchF; + logic NCJumpF, NCBranchF; + + if(`C_SUPPORTED) begin + logic [4:0] CompressedOpcF; + assign CompressedOpcF = {PostSpillInstrRawF[1:0], PostSpillInstrRawF[15:13]}; + assign ccall = 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 ccallr = CompressedOpcF == 5'h14 & PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0; + assign CJumpF = ccall | cj | cjr | ccallr; + assign CBranchF = CompressedOpcF[4:1] == 4'h7; + end else begin + assign {ccall, cj, cjr, ccallr, CJumpF, CBranchF} = '0; + end + + assign NCJumpF = PostSpillInstrRawF[6:0] == 7'h67 | PostSpillInstrRawF[6:0] == 7'h6F; + assign NCBranchF = PostSpillInstrRawF[6:0] == 7'h63; + + assign BPBranchF = NCBranchF | (`C_SUPPORTED & CBranchF); + assign BPJumpF = NCJumpF | (`C_SUPPORTED & (CJumpF)); + assign BPReturnF = (NCJumpF & (PostSpillInstrRawF[19:15] & 5'h1B) == 5'h01) | // returnurn must returnurn to ra or r5 + (`C_SUPPORTED & (ccallr | cjr) & ((PostSpillInstrRawF[11:7] & 5'h1B) == 5'h01)); + + assign BPCallF = (NCJumpF & (PostSpillInstrRawF[11:07] & 5'h1B) == 5'h01) | // call(r) must link to ra or x5 + (`C_SUPPORTED & (ccall | (ccallr & (PostSpillInstrRawF[11:7] & 5'h1b) == 5'h01))); + + end else begin + // This section connects the BTB's instruction class prediction. + assign {BPCallF, BPReturnF, BPJumpF, BPBranchF} = {BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF}; + end + + assign ReturnD = JumpD & (InstrD[19:15] & 5'h1B) == 5'h01; // returnurn must returnurn to ra or x5 + assign CallD = JumpD & (InstrD[11:7] & 5'h1B) == 5'h01; // call(r) must link to ra or x5 + + flopenrc #(2) InstrClassRegE(clk, reset, FlushE, ~StallE, {CallD, ReturnD}, {CallE, ReturnE}); + flopenrc #(4) InstrClassRegM(clk, reset, FlushM, ~StallM, {CallE, ReturnE, JumpE, BranchE}, {CallM, ReturnM, JumpM, BranchM}); + flopenrc #(4) InstrClassRegW(clk, reset, FlushM, ~StallW, {CallM, ReturnM, JumpM, BranchM}, {CallW, ReturnW, JumpW, BranchW}); + + // branch predictor + flopenrc #(1) BPClassWrongRegM(clk, reset, FlushM, ~StallM, AnyWrongPredInstrClassE, PredictionInstrClassWrongM); + flopenrc #(1) WrongInstrClassRegE(clk, reset, FlushE, ~StallE, AnyWrongPredInstrClassD, AnyWrongPredInstrClassE); + + // pipeline the predicted class + flopenrc #(4) PredInstrClassRegD(clk, reset, FlushD, ~StallD, {BPCallF, BPReturnF, BPJumpF, BPBranchF}, {BPCallD, BPReturnD, BPJumpD, BPBranchD}); + + // branch class prediction wrong. + assign AnyWrongPredInstrClassD = |({BPCallD, BPReturnD, BPJumpD, BPBranchD} ^ {CallD, ReturnD, JumpD, BranchD}); + assign WrongBPReturnD = BPReturnD ^ ReturnD; + +endmodule From c89812b2d477e94283d0849a561505d7b76e35e9 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Sun, 26 Feb 2023 21:28:36 -0600 Subject: [PATCH 07/19] Branch predictor cleanup. --- src/ifu/bpred/bpred.sv | 127 ++++++++++++++++++---------------------- src/ifu/bpred/btb.sv | 22 ++++--- src/ifu/bpred/icpred.sv | 2 +- 3 files changed, 72 insertions(+), 79 deletions(-) diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index 0aa1bc038..35fb3f5b6 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -70,33 +70,32 @@ module bpred ( output logic PredictionInstrClassWrongM // Class prediction is wrong ); - logic [1:0] BPDirPredF; + logic [1:0] BPDirPredF; - logic [`XLEN-1:0] BTAF, RASPCF; - logic PredictionPCWrongE; - logic AnyWrongPredInstrClassD, AnyWrongPredInstrClassE; - logic BPDirPredWrongE; + logic [`XLEN-1:0] BTAF, RASPCF; + logic PredictionPCWrongE; + logic AnyWrongPredInstrClassD, AnyWrongPredInstrClassE; + logic BPDirPredWrongE; - logic BPPCSrcF; - logic [`XLEN-1:0] BPPredPCF; - logic [`XLEN-1:0] PCNext0F; - logic [`XLEN-1:0] PCCorrectE; - logic [3:0] WrongPredInstrClassD; + logic BPPCSrcF; + logic [`XLEN-1:0] BPPCF; + logic [`XLEN-1:0] PCNext0F; + logic [`XLEN-1:0] PCCorrectE; + logic [3:0] WrongPredInstrClassD; - logic BTBTargetWrongE; - logic RASTargetWrongE; + logic BTBTargetWrongE; + logic RASTargetWrongE; - logic [`XLEN-1:0] BTAD; + logic [`XLEN-1:0] BTAD; - logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF; - logic BPBranchF, BPJumpF, BPReturnF, BPCallF; - logic BPBranchD, BPJumpD, BPReturnD, BPCallD; - logic ReturnD, CallD; - logic ReturnE, CallE; - logic BranchM, JumpM, ReturnM, CallM; - logic BranchW, JumpW, ReturnW, CallW; - logic WrongBPReturnD; - logic [`XLEN-1:0] PCW, IEUAdrW; + logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF; + logic BPBranchF, BPJumpF, BPReturnF, BPCallF; + logic BPBranchD, BPJumpD, BPReturnD, BPCallD; + logic ReturnD, CallD; + logic ReturnE, CallE; + logic BranchM, JumpM, ReturnM, CallM; + logic BranchW, JumpW, ReturnW, CallW; + logic WrongBPReturnD; // Part 1 branch direction prediction // look into the 2 port Sram model. something is wrong. @@ -148,30 +147,27 @@ module bpred ( btb #(`BTB_SIZE) TargetPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, - .PCNextF, .PCF, .PCD, .PCE, .PCM, .PCW, + .PCNextF, .PCF, .PCD, .PCE, .PCM, .BTAF, .BTAD, .BTBIClassF({BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF}), .PredictionInstrClassWrongM, - .IEUAdrE, .IEUAdrM, .IEUAdrW, - .InstrClassD({CallD, ReturnD, JumpD, BranchD}), .InstrClassE({CallE, ReturnE, JumpE, BranchE}), .InstrClassM({CallM, ReturnM, JumpM, BranchM}), + .IEUAdrE, .IEUAdrM, + .InstrClassD({CallD, ReturnD, JumpD, BranchD}), + .InstrClassE({CallE, ReturnE, JumpE, BranchE}), + .InstrClassM({CallM, ReturnM, JumpM, BranchM}), .InstrClassW({CallW, ReturnW, JumpW, BranchW})); icpred icpred(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PostSpillInstrRawF, .InstrD, .BranchD, .BranchE, .JumpD, .JumpE, .BranchM, .BranchW, .JumpM, .JumpW, - .CallD, .CallE, .CallM, .CallW, .ReturnD, .ReturnE, .ReturnM, .ReturnW, .BTBCallF, .BTBReturnF, .BTBJumpF, .BTBBranchF, - .BPCallF, .BPReturnF, .BPJumpF, .BPBranchF, .PredictionInstrClassWrongM, .WrongBPReturnD); - - assign BPPCSrcF = (BPBranchF & BPDirPredF[1]) | BPJumpF; - flopenrc #(1) BPPredWrongMReg(clk, reset, FlushM, ~StallM, BPPredWrongE, BPPredWrongM); + .CallD, .CallE, .CallM, .CallW, .ReturnD, .ReturnE, .ReturnM, .ReturnW, .BTBCallF, .BTBReturnF, .BTBJumpF, + .BTBBranchF, .BPCallF, .BPReturnF, .BPJumpF, .BPBranchF, .PredictionInstrClassWrongM, .WrongBPReturnD); // Part 3 RAS RASPredictor RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM, .BPReturnF, .ReturnD, .ReturnE, .CallE, .WrongBPReturnD, .RASPCF, .PCLinkE); - assign BPPredPCF = BPReturnF ? RASPCF : BTAF; - // Check the prediction // if it is a CFI then check if the next instruction address (PCD) matches the branch's target or fallthrough address. // if the class prediction is wrong a regular instruction may have been predicted as a taken branch @@ -179,19 +175,15 @@ module bpred ( // The next instruction is always valid as no other flush would occur at the same time as the branch and not // also flush the branch. This will change in a superscaler cpu. assign PredictionPCWrongE = PCCorrectE != PCD; - // branch is wrong only if the PC does not match and both the Decode and Fetch stages have valid instructions. assign BPPredWrongE = PredictionPCWrongE & InstrValidE & InstrValidD; - - // *** clean up old signal names for testing. - logic BPPredWrongEAlt; - logic NotMatch; - assign BPPredWrongEAlt = PredictionPCWrongE & InstrValidE & InstrValidD; - assign NotMatch = BPPredWrongE != BPPredWrongEAlt; - + flopenrc #(1) BPPredWrongMReg(clk, reset, FlushM, ~StallM, BPPredWrongE, BPPredWrongM); + // Output the predicted PC or corrected PC on miss-predict. + assign BPPCSrcF = (BPBranchF & BPDirPredF[1]) | BPJumpF; + mux2 #(`XLEN) pcmuxbp(BTAF, RASPCF, BPReturnF, BPPCF); // Selects the BP or PC+2/4. - mux2 #(`XLEN) pcmux0(PCPlus2or4F, BPPredPCF, BPPCSrcF, PCNext0F); + mux2 #(`XLEN) pcmux0(PCPlus2or4F, BPPCF, BPPCSrcF, PCNext0F); // If the prediction is wrong select the correct address. mux2 #(`XLEN) pcmux1(PCNext0F, PCCorrectE, BPPredWrongE, PCNext1F); // Correct branch/jump target. @@ -203,42 +195,39 @@ module bpred ( else assign NextValidPCE = PCE; if(`ZICOUNTERS_SUPPORTED) begin - logic JumpOrTakenBranchE; - logic [`XLEN-1:0] BTAE, RASPCD, RASPCE; - logic BTBPredPCWrongE, RASPredPCWrongE; - // performance counters - // 1. class (class wrong / minstret) (PredictionInstrClassWrongM / csr) // Correct now - // 2. target btb (btb target wrong / class[0,1,3]) (btb target wrong / (br + j + jal) - // 3. target ras (ras target wrong / class[2]) - // 4. direction (br dir wrong / class[0]) + logic JumpOrTakenBranchE; + logic [`XLEN-1:0] BTAE, RASPCD, RASPCE; + logic BTBPredPCWrongE, RASPredPCWrongE; + // performance counters + // 1. class (class wrong / minstret) (PredictionInstrClassWrongM / csr) // Correct now + // 2. target btb (btb target wrong / class[0,1,3]) (btb target wrong / (br + j + jal) + // 3. target ras (ras target wrong / class[2]) + // 4. direction (br dir wrong / class[0]) - // Unforuantely we can't use PCD to infer the correctness of the BTB or RAS because the class prediction - // 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) & (BranchE | JumpE & ~ReturnE) & PCSrcE; - assign RASPredPCWrongE = (RASPCE != IEUAdrE) & ReturnE & PCSrcE; + // Unforuantely we can't use PCD to infer the correctness of the BTB or RAS because the class prediction + // 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) & (BranchE | JumpE & ~ReturnE) & PCSrcE; + assign RASPredPCWrongE = (RASPCE != IEUAdrE) & ReturnE & PCSrcE; - assign JumpOrTakenBranchE = (BranchE & PCSrcE) | JumpE; - - flopenrc #(1) JumpOrTakenBranchMReg(clk, reset, FlushM, ~StallM, JumpOrTakenBranchE, JumpOrTakenBranchM); + assign JumpOrTakenBranchE = (BranchE & PCSrcE) | JumpE; + + flopenrc #(1) JumpOrTakenBranchMReg(clk, reset, FlushM, ~StallM, JumpOrTakenBranchE, JumpOrTakenBranchM); - flopenrc #(`XLEN) BTBTargetEReg(clk, reset, FlushE, ~StallE, BTAD, BTAE); + flopenrc #(`XLEN) BTBTargetEReg(clk, reset, FlushE, ~StallE, BTAD, BTAE); - flopenrc #(`XLEN) RASTargetDReg(clk, reset, FlushD, ~StallD, RASPCF, RASPCD); - flopenrc #(`XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE); - flopenrc #(3) BPPredWrongRegM(clk, reset, FlushM, ~StallM, - {BPDirPredWrongE, BTBPredPCWrongE, RASPredPCWrongE}, - {BPDirPredWrongM, BTBPredPCWrongM, RASPredPCWrongM}); - + flopenrc #(`XLEN) RASTargetDReg(clk, reset, FlushD, ~StallD, RASPCF, RASPCD); + flopenrc #(`XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE); + flopenrc #(3) BPPredWrongRegM(clk, reset, FlushM, ~StallM, + {BPDirPredWrongE, BTBPredPCWrongE, RASPredPCWrongE}, + {BPDirPredWrongM, BTBPredPCWrongM, RASPredPCWrongM}); + end else begin - assign {BTBPredPCWrongM, RASPredPCWrongM, JumpOrTakenBranchM} = '0; + assign {BTBPredPCWrongM, RASPredPCWrongM, JumpOrTakenBranchM} = '0; end // **** Fix me assign InstrClassM = {CallM, ReturnM, JumpM, BranchM}; - flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); - flopenr #(`XLEN) IEUAdrWReg(clk, reset, ~StallW, IEUAdrM, IEUAdrW); - endmodule diff --git a/src/ifu/bpred/btb.sv b/src/ifu/bpred/btb.sv index 5ad92517d..b0d988943 100644 --- a/src/ifu/bpred/btb.sv +++ b/src/ifu/bpred/btb.sv @@ -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, PCW,// PC at various stages + input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM,// 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] BTBIClassF, // BTB's guess at instruction class @@ -42,20 +42,21 @@ 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] InstrClassW ); - logic [Depth-1:0] PCNextFIndex, PCFIndex, PCDIndex, PCEIndex, PCMIndex, PCWIndex; - logic [`XLEN-1:0] ResetPC; - logic MatchD, MatchE, MatchM, MatchW, MatchX; - logic [`XLEN+3:0] ForwardBTBPrediction, ForwardBTBPredictionF; - logic [`XLEN+3:0] TableBTBPredF; - logic UpdateEn; - + logic [Depth-1:0] PCNextFIndex, PCFIndex, PCDIndex, PCEIndex, PCMIndex, PCWIndex; + logic [`XLEN-1:0] ResetPC; + logic MatchD, MatchE, MatchM, MatchW, MatchX; + logic [`XLEN+3:0] ForwardBTBPrediction, ForwardBTBPredictionF; + logic [`XLEN+3:0] TableBTBPredF; + logic UpdateEn; + logic [`XLEN-1:0] IEUAdrW; + logic [`XLEN-1:0] PCW; + // hashing function for indexing the PC // We have Depth 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 @@ -94,5 +95,8 @@ module btb #(parameter Depth = 10 ) ( .ce2(~StallW & ~FlushW), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(UpdateEn), .bwe2('1)); flopenrc #(`XLEN) BTBD(clk, reset, FlushD, ~StallD, BTAF, BTAD); + flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); + flopenr #(`XLEN) IEUAdrWReg(clk, reset, ~StallW, IEUAdrM, IEUAdrW); + endmodule diff --git a/src/ifu/bpred/icpred.sv b/src/ifu/bpred/icpred.sv index cd6772ba2..78689806f 100644 --- a/src/ifu/bpred/icpred.sv +++ b/src/ifu/bpred/icpred.sv @@ -34,7 +34,7 @@ module icpred ( input logic clk, reset, input logic StallF, StallD, StallE, StallM, StallW, input logic FlushD, FlushE, FlushM, FlushW, - input logic [31:0] PostSpillInstrRawF, InstrD, // Instruction + input logic [31:0] PostSpillInstrRawF, InstrD, // Instruction input logic BranchD, BranchE, input logic JumpD, JumpE, output logic BranchM, BranchW, From 318189e5e684f6b82fce969e06f478698d3bc72c Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 27 Feb 2023 00:39:19 -0600 Subject: [PATCH 08/19] Signal name changes. --- src/hazard/hazard.sv | 6 +++--- src/ifu/bpred/bpred.sv | 13 ++++++------- src/ifu/ifu.sv | 6 +++--- src/wally/wallypipelinedcore.sv | 6 +++--- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/hazard/hazard.sv b/src/hazard/hazard.sv index 650e8367d..85d23d373 100644 --- a/src/hazard/hazard.sv +++ b/src/hazard/hazard.sv @@ -30,7 +30,7 @@ module hazard ( // Detect hazards - input logic BPPredWrongE, CSRWriteFenceM, RetM, TrapM, + input logic BPWrongE, CSRWriteFenceM, RetM, TrapM, input logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD, input logic LSUStallM, IFUStallF, input logic FCvtIntStallD, FPUStallD, @@ -65,8 +65,8 @@ module hazard ( // Similarly, CSR writes and fences flush all subsequent instructions and refetch them in light of the new operating modes and cache/TLB contents // Branch misprediction is found in the Execute stage and must flush the next two instructions. // However, an active division operation resides in the Execute stage, and when the BP incorrectly mispredicts the divide as a taken branch, the divde must still complete - assign FlushDCause = TrapM | RetM | CSRWriteFenceM | BPPredWrongE; - assign FlushECause = TrapM | RetM | CSRWriteFenceM |(BPPredWrongE & ~(DivBusyE | FDivBusyE)); + assign FlushDCause = TrapM | RetM | CSRWriteFenceM | BPWrongE; + assign FlushECause = TrapM | RetM | CSRWriteFenceM |(BPWrongE & ~(DivBusyE | FDivBusyE)); assign FlushMCause = TrapM | RetM | CSRWriteFenceM; assign FlushWCause = TrapM; diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index 35fb3f5b6..7512e2d3b 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -62,7 +62,7 @@ module bpred ( output logic JumpOrTakenBranchM, // The valid instruction class. 1-hot encoded as call, return, jr (not return), j, br // Report branch prediction status - output logic BPPredWrongE, // Prediction is wrong + output logic BPWrongE, // Prediction is wrong output logic BPPredWrongM, // Prediction is wrong output logic BPDirPredWrongM, // Prediction direction is wrong output logic BTBPredPCWrongM, // Prediction target wrong @@ -73,7 +73,7 @@ module bpred ( logic [1:0] BPDirPredF; logic [`XLEN-1:0] BTAF, RASPCF; - logic PredictionPCWrongE; + logic BPPCWrongE; logic AnyWrongPredInstrClassD, AnyWrongPredInstrClassE; logic BPDirPredWrongE; @@ -157,7 +157,6 @@ module bpred ( .InstrClassM({CallM, ReturnM, JumpM, BranchM}), .InstrClassW({CallW, ReturnW, JumpW, BranchW})); - icpred icpred(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PostSpillInstrRawF, .InstrD, .BranchD, .BranchE, .JumpD, .JumpE, .BranchM, .BranchW, .JumpM, .JumpW, .CallD, .CallE, .CallM, .CallW, .ReturnD, .ReturnE, .ReturnM, .ReturnW, .BTBCallF, .BTBReturnF, .BTBJumpF, @@ -174,10 +173,10 @@ module bpred ( // this will result in PCD not being equal to the fall through address PCLinkE (PCE+4). // The next instruction is always valid as no other flush would occur at the same time as the branch and not // also flush the branch. This will change in a superscaler cpu. - assign PredictionPCWrongE = PCCorrectE != PCD; + assign BPPCWrongE = PCCorrectE != PCD; // branch is wrong only if the PC does not match and both the Decode and Fetch stages have valid instructions. - assign BPPredWrongE = PredictionPCWrongE & InstrValidE & InstrValidD; - flopenrc #(1) BPPredWrongMReg(clk, reset, FlushM, ~StallM, BPPredWrongE, BPPredWrongM); + assign BPWrongE = BPPCWrongE & InstrValidE & InstrValidD; + flopenrc #(1) BPPredWrongMReg(clk, reset, FlushM, ~StallM, BPWrongE, BPPredWrongM); // Output the predicted PC or corrected PC on miss-predict. assign BPPCSrcF = (BPBranchF & BPDirPredF[1]) | BPJumpF; @@ -185,7 +184,7 @@ module bpred ( // Selects the BP or PC+2/4. mux2 #(`XLEN) pcmux0(PCPlus2or4F, BPPCF, BPPCSrcF, PCNext0F); // If the prediction is wrong select the correct address. - mux2 #(`XLEN) pcmux1(PCNext0F, PCCorrectE, BPPredWrongE, PCNext1F); + mux2 #(`XLEN) pcmux1(PCNext0F, PCCorrectE, BPWrongE, PCNext1F); // Correct branch/jump target. mux2 #(`XLEN) pccorrectemux(PCLinkE, IEUAdrE, PCSrcE, PCCorrectE); diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index e13a08bf9..36c8d6256 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -54,7 +54,7 @@ module ifu ( input logic [`XLEN-1:0] IEUAdrE, // The branch/jump target address input logic [`XLEN-1:0] IEUAdrM, // The branch/jump target address output logic [`XLEN-1:0] PCE, // Execution stage instruction address - output logic BPPredWrongE, // Prediction is wrong + output logic BPWrongE, // Prediction is wrong output logic BPPredWrongM, // Prediction is wrong // Mem output logic CommittedF, // I$ or bus memory operation started, delay interrupts @@ -331,12 +331,12 @@ module ifu ( .FlushD, .FlushE, .FlushM, .FlushW, .InstrValidD, .InstrValidE, .BranchD, .BranchE, .JumpD, .JumpE, .InstrD, .PCNextF, .PCPlus2or4F, .PCNext1F, .PCE, .PCM, .PCSrcE, .IEUAdrE, .IEUAdrM, .PCF, .NextValidPCE, - .PCD, .PCLinkE, .InstrClassM, .BPPredWrongE, .PostSpillInstrRawF, .JumpOrTakenBranchM, .BPPredWrongM, + .PCD, .PCLinkE, .InstrClassM, .BPWrongE, .PostSpillInstrRawF, .JumpOrTakenBranchM, .BPPredWrongM, .BPDirPredWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM); end else begin : bpred mux2 #(`XLEN) pcmux1(.d0(PCPlus2or4F), .d1(IEUAdrE), .s(PCSrcE), .y(PCNext1F)); - assign BPPredWrongE = PCSrcE; + assign BPWrongE = PCSrcE; assign {InstrClassM, BPDirPredWrongM, BTBPredPCWrongM, RASPredPCWrongM, PredictionInstrClassWrongM} = '0; assign NextValidPCE = PCE; end diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index c4b83386d..a0acb2001 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -140,7 +140,7 @@ module wallypipelinedcore ( logic LSUHWRITE; logic LSUHREADY; - logic BPPredWrongE, BPPredWrongM; + logic BPWrongE, BPPredWrongM; logic BPDirPredWrongM; logic BTBPredPCWrongM; logic RASPredPCWrongM; @@ -173,7 +173,7 @@ module wallypipelinedcore ( .IFUStallF, .IFUHBURST, .IFUHTRANS, .IFUHSIZE, .IFUHREADY, .IFUHWRITE, .ICacheAccess, .ICacheMiss, // Execute - .PCLinkE, .PCSrcE, .IEUAdrE, .IEUAdrM, .PCE, .BPPredWrongE, .BPPredWrongM, + .PCLinkE, .PCSrcE, .IEUAdrE, .IEUAdrM, .PCE, .BPWrongE, .BPPredWrongM, // Mem .CommittedF, .UnalignedPCNextF, .InvalidateICacheM, .CSRWriteFenceM, .InstrD, .InstrM, .PCM, .InstrClassM, .BPDirPredWrongM, .JumpOrTakenBranchM, @@ -268,7 +268,7 @@ module wallypipelinedcore ( // global stall and flush control hazard hzu( - .BPPredWrongE, .CSRWriteFenceM, .RetM, .TrapM, + .BPWrongE, .CSRWriteFenceM, .RetM, .TrapM, .LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD, .LSUStallM, .IFUStallF, .FCvtIntStallD, .FPUStallD, From 544abe28194cf9f1254095052c7128b35f0a7684 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 27 Feb 2023 17:37:29 -0600 Subject: [PATCH 09/19] Modified the BTB to save power by not updating when the prediction is unchanged. --- src/ifu/bpred/bpred.sv | 11 +++++------ src/ifu/bpred/btb.sv | 20 ++++++++++++++++---- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index 7512e2d3b..3ad0506c4 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -96,7 +96,8 @@ module bpred ( logic BranchM, JumpM, ReturnM, CallM; logic BranchW, JumpW, ReturnW, CallW; logic WrongBPReturnD; - + logic [`XLEN-1:0] BTAE; + // Part 1 branch direction prediction // look into the 2 port Sram model. something is wrong. if (`BPRED_TYPE == "BP_TWOBIT") begin:Predictor @@ -148,9 +149,9 @@ module bpred ( btb #(`BTB_SIZE) TargetPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCF, .PCD, .PCE, .PCM, - .BTAF, .BTAD, + .BTAF, .BTAD, .BTAE, .BTBIClassF({BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF}), - .PredictionInstrClassWrongM, + .PredictionInstrClassWrongM, .AnyWrongPredInstrClassE, .IEUAdrE, .IEUAdrM, .InstrClassD({CallD, ReturnD, JumpD, BranchD}), .InstrClassE({CallE, ReturnE, JumpE, BranchE}), @@ -195,7 +196,7 @@ module bpred ( if(`ZICOUNTERS_SUPPORTED) begin logic JumpOrTakenBranchE; - logic [`XLEN-1:0] BTAE, RASPCD, RASPCE; + logic [`XLEN-1:0] RASPCD, RASPCE; logic BTBPredPCWrongE, RASPredPCWrongE; // performance counters // 1. class (class wrong / minstret) (PredictionInstrClassWrongM / csr) // Correct now @@ -214,8 +215,6 @@ module bpred ( flopenrc #(1) JumpOrTakenBranchMReg(clk, reset, FlushM, ~StallM, JumpOrTakenBranchE, JumpOrTakenBranchM); - flopenrc #(`XLEN) BTBTargetEReg(clk, reset, FlushE, ~StallE, BTAD, BTAE); - flopenrc #(`XLEN) RASTargetDReg(clk, reset, FlushD, ~StallD, RASPCF, RASPCD); flopenrc #(`XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE); flopenrc #(3) BPPredWrongRegM(clk, reset, FlushM, ~StallM, diff --git a/src/ifu/bpred/btb.sv b/src/ifu/bpred/btb.sv index b0d988943..1d6c0ff8d 100644 --- a/src/ifu/bpred/btb.sv +++ b/src/ifu/bpred/btb.sv @@ -36,10 +36,12 @@ module btb #(parameter Depth = 10 ) ( 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 output logic [`XLEN-1:0] BTAF, // BTB's guess at PC - output logic [`XLEN-1:0] BTAD, + output logic [`XLEN-1:0] BTAD, + output logic [`XLEN-1:0] BTAE, output logic [3:0] BTBIClassF, // BTB's guess at instruction class // update input logic PredictionInstrClassWrongM, // BTB's instruction class guess was wrong + input logic AnyWrongPredInstrClassE, 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 [3:0] InstrClassD, // Instruction class to insert into btb @@ -53,9 +55,11 @@ module btb #(parameter Depth = 10 ) ( logic MatchD, MatchE, MatchM, MatchW, MatchX; logic [`XLEN+3:0] ForwardBTBPrediction, ForwardBTBPredictionF; logic [`XLEN+3:0] TableBTBPredF; - logic UpdateEn; logic [`XLEN-1:0] IEUAdrW; logic [`XLEN-1:0] PCW; + logic BTAWrongE, BTBWrongE; + logic BTBWrongM; + // hashing function for indexing the PC // We have Depth bits to index, but XLEN bits as the input. @@ -87,14 +91,22 @@ module btb #(parameter Depth = 10 ) ( assign {BTBIClassF, BTAF} = MatchX ? ForwardBTBPredictionF : {TableBTBPredF}; - assign UpdateEn = |InstrClassM | PredictionInstrClassWrongM; // An optimization may be using a PC relative address. ram2p1r1wbe #(2**Depth, `XLEN+4) memory( .clk, .ce1(~StallF | reset), .ra1(PCNextFIndex), .rd1(TableBTBPredF), - .ce2(~StallW & ~FlushW), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(UpdateEn), .bwe2('1)); + .ce2(~StallW & ~FlushW), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(BTBWrongM), .bwe2('1)); flopenrc #(`XLEN) BTBD(clk, reset, FlushD, ~StallD, BTAF, BTAD); + + // BTAE is not strickly necessary. However it is used by two parts of wally. + // 1. It gates updates to the BTB when the prediction does not change. This save power. + // 2. BTAWrongE is used by the performance counters to track when the BTB's BTA or instruction class is wrong. + flopenrc #(`XLEN) BTBTargetEReg(clk, reset, FlushE, ~StallE, BTAD, BTAE); + assign BTAWrongE = (BTAE != IEUAdrE) & (InstrClassE[0] | InstrClassE[1] & ~InstrClassE[2]); + assign BTBWrongE = BTAWrongE | AnyWrongPredInstrClassE; + flopenrc #(1) BTBWrongMReg(clk, reset, FlushM, ~StallM, BTBWrongE, BTBWrongM); + flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); flopenr #(`XLEN) IEUAdrWReg(clk, reset, ~StallW, IEUAdrM, IEUAdrW); From 9dd33797444bc91472e94c10922133239824c0ac Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 27 Feb 2023 20:00:50 -0600 Subject: [PATCH 10/19] This icpred and btb changes are causing a performance issue. --- src/ifu/bpred/bpred.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index 3ad0506c4..5c8938bca 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -174,9 +174,9 @@ module bpred ( // this will result in PCD not being equal to the fall through address PCLinkE (PCE+4). // The next instruction is always valid as no other flush would occur at the same time as the branch and not // also flush the branch. This will change in a superscaler cpu. - assign BPPCWrongE = PCCorrectE != PCD; + assign BPPCWrongE = ; // branch is wrong only if the PC does not match and both the Decode and Fetch stages have valid instructions. - assign BPWrongE = BPPCWrongE & InstrValidE & InstrValidD; + assign BPWrongE = (PCCorrectE != PCD) & InstrValidE & InstrValidD; flopenrc #(1) BPPredWrongMReg(clk, reset, FlushM, ~StallM, BPWrongE, BPPredWrongM); // Output the predicted PC or corrected PC on miss-predict. From be4823f7dd585bf8ae2a205a0ae344b963428d54 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 28 Feb 2023 15:21:56 -0600 Subject: [PATCH 11/19] Undid the btb update as it reduces performance. --- src/ifu/bpred/bpred.sv | 5 ++--- src/ifu/bpred/btb.sv | 6 +++++- src/ifu/bpred/icpred.sv | 5 ++--- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index 5c8938bca..61855055f 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -28,7 +28,7 @@ `include "wally-config.vh" -`define INSTR_CLASS_PRED 1 +`define INSTR_CLASS_PRED 0 module bpred ( input logic clk, reset, @@ -158,7 +158,7 @@ module bpred ( .InstrClassM({CallM, ReturnM, JumpM, BranchM}), .InstrClassW({CallW, ReturnW, JumpW, BranchW})); - icpred icpred(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, + icpred #(`INSTR_CLASS_PRED) icpred(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PostSpillInstrRawF, .InstrD, .BranchD, .BranchE, .JumpD, .JumpE, .BranchM, .BranchW, .JumpM, .JumpW, .CallD, .CallE, .CallM, .CallW, .ReturnD, .ReturnE, .ReturnM, .ReturnW, .BTBCallF, .BTBReturnF, .BTBJumpF, .BTBBranchF, .BPCallF, .BPReturnF, .BPJumpF, .BPBranchF, .PredictionInstrClassWrongM, .WrongBPReturnD); @@ -174,7 +174,6 @@ module bpred ( // this will result in PCD not being equal to the fall through address PCLinkE (PCE+4). // The next instruction is always valid as no other flush would occur at the same time as the branch and not // also flush the branch. This will change in a superscaler cpu. - assign BPPCWrongE = ; // branch is wrong only if the PC does not match and both the Decode and Fetch stages have valid instructions. assign BPWrongE = (PCCorrectE != PCD) & InstrValidE & InstrValidD; flopenrc #(1) BPPredWrongMReg(clk, reset, FlushM, ~StallM, BPWrongE, BPPredWrongM); diff --git a/src/ifu/bpred/btb.sv b/src/ifu/bpred/btb.sv index 1d6c0ff8d..31c3fed58 100644 --- a/src/ifu/bpred/btb.sv +++ b/src/ifu/bpred/btb.sv @@ -92,10 +92,14 @@ module btb #(parameter Depth = 10 ) ( assign {BTBIClassF, BTAF} = MatchX ? ForwardBTBPredictionF : {TableBTBPredF}; + logic UpdateEn; + // An optimization may be using a PC relative address. ram2p1r1wbe #(2**Depth, `XLEN+4) memory( .clk, .ce1(~StallF | reset), .ra1(PCNextFIndex), .rd1(TableBTBPredF), - .ce2(~StallW & ~FlushW), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(BTBWrongM), .bwe2('1)); + .ce2(~StallW & ~FlushW), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(UpdateEn), .bwe2('1)); + + assign UpdateEn = |InstrClassM | PredictionInstrClassWrongM; flopenrc #(`XLEN) BTBD(clk, reset, FlushD, ~StallD, BTAF, BTAD); diff --git a/src/ifu/bpred/icpred.sv b/src/ifu/bpred/icpred.sv index 78689806f..f6b0f7d11 100644 --- a/src/ifu/bpred/icpred.sv +++ b/src/ifu/bpred/icpred.sv @@ -28,9 +28,8 @@ `include "wally-config.vh" -`define INSTR_CLASS_PRED 1 -module icpred ( +module icpred #(parameter INSTR_CLASS_PRED = 1)( input logic clk, reset, input logic StallF, StallD, StallE, StallM, StallW, input logic FlushD, FlushE, FlushM, FlushW, @@ -49,7 +48,7 @@ module icpred ( logic AnyWrongPredInstrClassD, AnyWrongPredInstrClassE; logic BPBranchD, BPJumpD, BPReturnD, BPCallD; - if (!`INSTR_CLASS_PRED) begin : DirectClassDecode + 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, Call, Return, Jump, and Branch instructions. From 2ebe600f54fb0dfed760d5b6a041c856da3b2cee Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 28 Feb 2023 15:37:25 -0600 Subject: [PATCH 12/19] Name changes to reflect diagrams. --- src/ifu/bpred/bpred.sv | 14 +++++++------- src/ifu/ifu.sv | 16 ++++++++-------- src/privileged/csr.sv | 8 ++++---- src/privileged/csrc.sv | 4 ++-- src/privileged/privileged.sv | 8 ++++---- src/wally/wallypipelinedcore.sv | 14 +++++++------- 6 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index 61855055f..49c9a02c0 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -39,7 +39,7 @@ module bpred ( input logic [31:0] InstrD, // Decompressed decode stage instruction. Used to decode instruction class input logic [`XLEN-1:0] PCNextF, // Next Fetch Address input logic [`XLEN-1:0] PCPlus2or4F, // PCF+2/4 - output logic [`XLEN-1:0] PCNext1F, // Branch Predictor predicted or corrected fetch address on miss prediction + output logic [`XLEN-1:0] PC1NextF, // Branch Predictor predicted or corrected fetch address on miss prediction output logic [`XLEN-1:0] NextValidPCE, // Address of next valid instruction after the instruction in the Memory stage // Update Predictor @@ -63,7 +63,7 @@ module bpred ( // Report branch prediction status output logic BPWrongE, // Prediction is wrong - output logic BPPredWrongM, // Prediction is wrong + output logic BPWrongM, // Prediction is wrong output logic BPDirPredWrongM, // Prediction direction is wrong output logic BTBPredPCWrongM, // Prediction target wrong output logic RASPredPCWrongM, // RAS prediction is wrong @@ -79,7 +79,7 @@ module bpred ( logic BPPCSrcF; logic [`XLEN-1:0] BPPCF; - logic [`XLEN-1:0] PCNext0F; + logic [`XLEN-1:0] PC0NextF; logic [`XLEN-1:0] PCCorrectE; logic [3:0] WrongPredInstrClassD; @@ -176,21 +176,21 @@ module bpred ( // also flush the branch. This will change in a superscaler cpu. // branch is wrong only if the PC does not match and both the Decode and Fetch stages have valid instructions. assign BPWrongE = (PCCorrectE != PCD) & InstrValidE & InstrValidD; - flopenrc #(1) BPPredWrongMReg(clk, reset, FlushM, ~StallM, BPWrongE, BPPredWrongM); + flopenrc #(1) BPWrongMReg(clk, reset, FlushM, ~StallM, BPWrongE, BPWrongM); // Output the predicted PC or corrected PC on miss-predict. assign BPPCSrcF = (BPBranchF & BPDirPredF[1]) | BPJumpF; mux2 #(`XLEN) pcmuxbp(BTAF, RASPCF, BPReturnF, BPPCF); // Selects the BP or PC+2/4. - mux2 #(`XLEN) pcmux0(PCPlus2or4F, BPPCF, BPPCSrcF, PCNext0F); + mux2 #(`XLEN) pcmux0(PCPlus2or4F, BPPCF, BPPCSrcF, PC0NextF); // If the prediction is wrong select the correct address. - mux2 #(`XLEN) pcmux1(PCNext0F, PCCorrectE, BPWrongE, PCNext1F); + mux2 #(`XLEN) pcmux1(PC0NextF, PCCorrectE, BPWrongE, PC1NextF); // Correct branch/jump target. mux2 #(`XLEN) pccorrectemux(PCLinkE, IEUAdrE, PCSrcE, PCCorrectE); // If the fence/csrw was predicted as a taken branch then we select PCF, rather PCE. // Effectively this is PCM+4 or the non-existant PCLinkM - if(`INSTR_CLASS_PRED) mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPPredWrongM, NextValidPCE); + if(`INSTR_CLASS_PRED) mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPWrongM, NextValidPCE); else assign NextValidPCE = PCE; if(`ZICOUNTERS_SUPPORTED) begin diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index 12b1b8e8d..c85bb94d0 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -55,11 +55,11 @@ module ifu ( input logic [`XLEN-1:0] IEUAdrM, // The branch/jump target address output logic [`XLEN-1:0] PCE, // Execution stage instruction address output logic BPWrongE, // Prediction is wrong - output logic BPPredWrongM, // Prediction is wrong + output logic BPWrongM, // Prediction is wrong // Mem output logic CommittedF, // I$ or bus memory operation started, delay interrupts input logic [`XLEN-1:0] UnalignedPCNextF, // The next PCF, but not aligned to 2 bytes. - output logic [`XLEN-1:0] PCNext2F, // Selected PC between branch prediction and next valid PC if CSRWriteFence + output logic [`XLEN-1:0] PC2NextF, // Selected PC between branch prediction and next valid PC if CSRWriteFence output logic [31:0] InstrD, // The decoded instruction in Decode stage output logic [31:0] InstrM, // The decoded instruction in Memory stage output logic [`XLEN-1:0] PCM, // Memory stage instruction address @@ -132,7 +132,7 @@ module ifu ( logic IFUCacheBusStallD; // EIther I$ or bus busy with multicycle operation logic GatedStallD; // StallD gated by selected next spill // branch predictor signal - logic [`XLEN-1:0] PCNext1F; // Branch predictor next PCF + logic [`XLEN-1:0] PC1NextF; // Branch predictor next PCF logic BusCommittedF; // Bus memory operation in flight, delay interrupts logic CacheCommittedF; // I$ memory operation started, delay interrupts logic SelIROM; // PMA indicates instruction address is in the IROM @@ -297,8 +297,8 @@ module ifu ( //////////////////////////////////////////////////////////////////////////////////////////////// if(`ZICSR_SUPPORTED | `ZIFENCEI_SUPPORTED) - mux2 #(`XLEN) pcmux2(.d0(PCNext1F), .d1(NextValidPCE), .s(CSRWriteFenceM),.y(PCNext2F)); - else assign PCNext2F = PCNext1F; + mux2 #(`XLEN) pcmux2(.d0(PC1NextF), .d1(NextValidPCE), .s(CSRWriteFenceM),.y(PC2NextF)); + else assign PC2NextF = PC1NextF; assign PCNextF = {UnalignedPCNextF[`XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment flopenl #(`XLEN) pcreg(clk, reset, ~StallF, PCNextF, `RESET_VECTOR, PCF); @@ -330,12 +330,12 @@ module ifu ( .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .InstrValidD, .InstrValidE, .BranchD, .BranchE, .JumpD, .JumpE, - .InstrD, .PCNextF, .PCPlus2or4F, .PCNext1F, .PCE, .PCM, .PCSrcE, .IEUAdrE, .IEUAdrM, .PCF, .NextValidPCE, - .PCD, .PCLinkE, .InstrClassM, .BPWrongE, .PostSpillInstrRawF, .JumpOrTakenBranchM, .BPPredWrongM, + .InstrD, .PCNextF, .PCPlus2or4F, .PC1NextF, .PCE, .PCM, .PCSrcE, .IEUAdrE, .IEUAdrM, .PCF, .NextValidPCE, + .PCD, .PCLinkE, .InstrClassM, .BPWrongE, .PostSpillInstrRawF, .JumpOrTakenBranchM, .BPWrongM, .BPDirPredWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM); end else begin : bpred - mux2 #(`XLEN) pcmux1(.d0(PCPlus2or4F), .d1(IEUAdrE), .s(PCSrcE), .y(PCNext1F)); + mux2 #(`XLEN) pcmux1(.d0(PCPlus2or4F), .d1(IEUAdrE), .s(PCSrcE), .y(PC1NextF)); assign BPWrongE = PCSrcE; assign {InstrClassM, BPDirPredWrongM, BTBPredPCWrongM, RASPredPCWrongM, PredictionInstrClassWrongM} = '0; assign NextValidPCE = PCE; diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index ee3d947fd..3575a4ffc 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -37,7 +37,7 @@ module csr #(parameter input logic FlushM, FlushW, input logic StallE, StallM, StallW, input logic [31:0] InstrM, // current instruction - input logic [`XLEN-1:0] PCM, PCNext2F, // program counter, next PC going to trap/return logic + input logic [`XLEN-1:0] PCM, PC2NextF, // program counter, next PC going to trap/return logic input logic [`XLEN-1:0] SrcAM, IEUAdrM, // SrcA and memory address from IEU input logic CSRReadM, CSRWriteM, // read or write CSR input logic TrapM, // trap is occurring @@ -61,7 +61,7 @@ module csr #(parameter input logic BTBPredPCWrongM, input logic RASPredPCWrongM, input logic PredictionInstrClassWrongM, - input logic BPPredWrongM, // branch predictor is wrong + input logic BPWrongM, // branch predictor is wrong input logic [3:0] InstrClassM, input logic JumpOrTakenBranchM, // actual instruction class input logic DCacheMiss, @@ -155,7 +155,7 @@ module csr #(parameter // A return sets the PC to MEPC or SEPC assign RetM = mretM | sretM; mux2 #(`XLEN) epcmux(SEPC_REGW, MEPC_REGW, mretM, EPC); - mux3 #(`XLEN) pcmux3(PCNext2F, EPC, TrapVectorM, {TrapM, RetM}, UnalignedPCNextF); + mux3 #(`XLEN) pcmux3(PC2NextF, EPC, TrapVectorM, {TrapM, RetM}, UnalignedPCNextF); /////////////////////////////////////////// // CSRWriteValM @@ -259,7 +259,7 @@ module csr #(parameter if (`ZICOUNTERS_SUPPORTED) begin:counters csrc counters(.clk, .reset, .StallE, .StallM, .FlushM, .InstrValidNotFlushedM, .LoadStallD, .CSRMWriteM, - .BPDirPredWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM, .JumpOrTakenBranchM, .BPPredWrongM, + .BPDirPredWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM, .JumpOrTakenBranchM, .BPWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .CSRAdrM, .PrivilegeModeW, .CSRWriteValM, .MCOUNTINHIBIT_REGW, .MCOUNTEREN_REGW, .SCOUNTEREN_REGW, diff --git a/src/privileged/csrc.sv b/src/privileged/csrc.sv index 5cc58ce34..eae514433 100644 --- a/src/privileged/csrc.sv +++ b/src/privileged/csrc.sv @@ -48,7 +48,7 @@ module csrc #(parameter input logic BTBPredPCWrongM, input logic RASPredPCWrongM, input logic PredictionInstrClassWrongM, - input logic BPPredWrongM, // branch predictor is wrong + input logic BPWrongM, // branch predictor is wrong input logic [3:0] InstrClassM, input logic JumpOrTakenBranchM, // actual instruction class input logic DCacheMiss, @@ -97,7 +97,7 @@ module csrc #(parameter assign CounterEvent[12] = DCacheMiss; // data cache miss. Miss asserted 1 cycle at start of cache miss assign CounterEvent[13] = ICacheAccess & InstrValidNotFlushedM; // instruction cache access assign CounterEvent[14] = ICacheMiss; // instruction cache miss. Miss asserted 1 cycle at start of cache miss - assign CounterEvent[15] = BPPredWrongM & InstrValidNotFlushedM; // branch predictor wrong + assign CounterEvent[15] = BPWrongM & InstrValidNotFlushedM; // branch predictor wrong assign CounterEvent[`COUNTERS-1:16] = 0; // eventually give these sources, including FP instructions, I$/D$ misses, branches and mispredictions end diff --git a/src/privileged/privileged.sv b/src/privileged/privileged.sv index 93b7f9729..37904557d 100644 --- a/src/privileged/privileged.sv +++ b/src/privileged/privileged.sv @@ -38,7 +38,7 @@ module privileged ( input logic [`XLEN-1:0] SrcAM, // GPR register to write input logic [31:0] InstrM, // Instruction input logic [`XLEN-1:0] IEUAdrM, // address from IEU - input logic [`XLEN-1:0] PCM, PCNext2F, // program counter, next PC going to trap/return PC logic + input logic [`XLEN-1:0] PCM, PC2NextF, // program counter, next PC going to trap/return PC logic // control signals input logic InstrValidM, // Current instruction is valid (not flushed) input logic CommittedM, CommittedF, // current instruction is using bus; don't interrupt @@ -50,7 +50,7 @@ module privileged ( input logic BTBPredPCWrongM, // branch predictor guessed wrong target input logic RASPredPCWrongM, // return adddress stack guessed wrong target input logic PredictionInstrClassWrongM, // branch predictor guessed wrong instruction class - input logic BPPredWrongM, // branch predictor is wrong + input logic BPWrongM, // branch predictor is wrong input logic [3:0] InstrClassM, // actual instruction class input logic JumpOrTakenBranchM, // actual instruction class input logic DCacheMiss, // data cache miss @@ -121,11 +121,11 @@ module privileged ( // Control and Status Registers csr csr(.clk, .reset, .FlushM, .FlushW, .StallE, .StallM, .StallW, - .InstrM, .PCM, .SrcAM, .IEUAdrM, .PCNext2F, + .InstrM, .PCM, .SrcAM, .IEUAdrM, .PC2NextF, .CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .wfiM, .IntPendingM, .InterruptM, .MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, - .BPDirPredWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .BPPredWrongM, + .BPDirPredWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .BPWrongM, .PredictionInstrClassWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .JumpOrTakenBranchM, .NextPrivilegeModeM, .PrivilegeModeW, .CauseM, .SelHPTW, .STATUS_MPP, .STATUS_SPP, .STATUS_TSR, .STATUS_TVM, diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index 5882aa653..387212b97 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -66,7 +66,7 @@ module wallypipelinedcore ( logic [`XLEN-1:0] PCFSpill, PCE, PCLinkE; logic [`XLEN-1:0] PCM; logic [`XLEN-1:0] CSRReadValW, MDUResultW; - logic [`XLEN-1:0] UnalignedPCNextF, PCNext2F; + logic [`XLEN-1:0] UnalignedPCNextF, PC2NextF; logic [1:0] MemRWM; logic InstrValidD, InstrValidE, InstrValidM; logic InstrMisalignedFaultM; @@ -140,7 +140,7 @@ module wallypipelinedcore ( logic LSUHWRITE; logic LSUHREADY; - logic BPWrongE, BPPredWrongM; + logic BPWrongE, BPWrongM; logic BPDirPredWrongM; logic BTBPredPCWrongM; logic RASPredPCWrongM; @@ -169,11 +169,11 @@ module wallypipelinedcore ( .InstrValidM, .InstrValidE, .InstrValidD, .BranchD, .BranchE, .JumpD, .JumpE, // Fetch - .HRDATA, .PCFSpill, .IFUHADDR, .PCNext2F, + .HRDATA, .PCFSpill, .IFUHADDR, .PC2NextF, .IFUStallF, .IFUHBURST, .IFUHTRANS, .IFUHSIZE, .IFUHREADY, .IFUHWRITE, .ICacheAccess, .ICacheMiss, // Execute - .PCLinkE, .PCSrcE, .IEUAdrE, .IEUAdrM, .PCE, .BPWrongE, .BPPredWrongM, + .PCLinkE, .PCSrcE, .IEUAdrE, .IEUAdrM, .PCE, .BPWrongE, .BPWrongM, // Mem .CommittedF, .UnalignedPCNextF, .InvalidateICacheM, .CSRWriteFenceM, .InstrD, .InstrM, .PCM, .InstrClassM, .BPDirPredWrongM, .JumpOrTakenBranchM, @@ -284,12 +284,12 @@ module wallypipelinedcore ( privileged priv( .clk, .reset, .FlushD, .FlushE, .FlushM, .FlushW, .StallD, .StallE, .StallM, .StallW, - .CSRReadM, .CSRWriteM, .SrcAM, .PCM, .PCNext2F, + .CSRReadM, .CSRWriteM, .SrcAM, .PCM, .PC2NextF, .InstrM, .CSRReadValW, .UnalignedPCNextF, .RetM, .TrapM, .sfencevmaM, .InstrValidM, .CommittedM, .CommittedF, .FRegWriteM, .LoadStallD, - .BPDirPredWrongM, .BTBPredPCWrongM, .BPPredWrongM, + .BPDirPredWrongM, .BTBPredPCWrongM, .BPWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM, .InstrClassM, .JumpOrTakenBranchM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .PrivilegedM, .InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM, @@ -304,7 +304,7 @@ module wallypipelinedcore ( .FRM_REGW,.BreakpointFaultM, .EcallFaultM, .WFIStallM, .BigEndianM); end else begin assign CSRReadValW = 0; - assign UnalignedPCNextF = PCNext2F; + assign UnalignedPCNextF = PC2NextF; assign RetM = 0; assign TrapM = 0; assign WFIStallM = 0; From 4c0e7f297a580078d9568256bff464c64f098737 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 28 Feb 2023 15:57:34 -0600 Subject: [PATCH 13/19] Found the performance bug with the branch predictor btb power saving update. --- src/ifu/bpred/bpred.sv | 4 +++- src/ifu/bpred/btb.sv | 2 +- src/ifu/bpred/icpred.sv | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index 49c9a02c0..72d2f2164 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -97,6 +97,8 @@ module bpred ( logic BranchW, JumpW, ReturnW, CallW; logic WrongBPReturnD; logic [`XLEN-1:0] BTAE; + + // Part 1 branch direction prediction // look into the 2 port Sram model. something is wrong. @@ -161,7 +163,7 @@ module bpred ( icpred #(`INSTR_CLASS_PRED) icpred(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PostSpillInstrRawF, .InstrD, .BranchD, .BranchE, .JumpD, .JumpE, .BranchM, .BranchW, .JumpM, .JumpW, .CallD, .CallE, .CallM, .CallW, .ReturnD, .ReturnE, .ReturnM, .ReturnW, .BTBCallF, .BTBReturnF, .BTBJumpF, - .BTBBranchF, .BPCallF, .BPReturnF, .BPJumpF, .BPBranchF, .PredictionInstrClassWrongM, .WrongBPReturnD); + .BTBBranchF, .BPCallF, .BPReturnF, .BPJumpF, .BPBranchF, .PredictionInstrClassWrongM, .AnyWrongPredInstrClassE, .WrongBPReturnD); // Part 3 RAS RASPredictor RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM, diff --git a/src/ifu/bpred/btb.sv b/src/ifu/bpred/btb.sv index 31c3fed58..908288e2e 100644 --- a/src/ifu/bpred/btb.sv +++ b/src/ifu/bpred/btb.sv @@ -97,7 +97,7 @@ module btb #(parameter Depth = 10 ) ( // An optimization may be using a PC relative address. ram2p1r1wbe #(2**Depth, `XLEN+4) memory( .clk, .ce1(~StallF | reset), .ra1(PCNextFIndex), .rd1(TableBTBPredF), - .ce2(~StallW & ~FlushW), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(UpdateEn), .bwe2('1)); + .ce2(~StallW & ~FlushW), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(BTBWrongM), .bwe2('1)); assign UpdateEn = |InstrClassM | PredictionInstrClassWrongM; diff --git a/src/ifu/bpred/icpred.sv b/src/ifu/bpred/icpred.sv index f6b0f7d11..c37c3938c 100644 --- a/src/ifu/bpred/icpred.sv +++ b/src/ifu/bpred/icpred.sv @@ -42,10 +42,10 @@ module icpred #(parameter INSTR_CLASS_PRED = 1)( output logic ReturnD, ReturnE, ReturnM, ReturnW, input logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF, output logic BPCallF, BPReturnF, BPJumpF, BPBranchF, - output logic PredictionInstrClassWrongM, WrongBPReturnD + output logic PredictionInstrClassWrongM, WrongBPReturnD, AnyWrongPredInstrClassE ); - logic AnyWrongPredInstrClassD, AnyWrongPredInstrClassE; + logic AnyWrongPredInstrClassD; logic BPBranchD, BPJumpD, BPReturnD, BPCallD; if (!INSTR_CLASS_PRED) begin : DirectClassDecode From a6917d07f30a5a5e3f6059a5aa21ddcd6bd1b39a Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 28 Feb 2023 17:48:58 -0600 Subject: [PATCH 14/19] Name cleanup. --- src/ifu/bpred/bpred.sv | 10 +++++----- src/ifu/bpred/btb.sv | 8 ++++---- src/ifu/bpred/icpred.sv | 10 +++++----- src/ifu/ifu.sv | 6 +++--- src/privileged/csr.sv | 4 ++-- src/privileged/csrc.sv | 4 ++-- src/privileged/privileged.sv | 4 ++-- src/wally/wallypipelinedcore.sv | 6 +++--- 8 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index 72d2f2164..1074aea66 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -67,14 +67,14 @@ module bpred ( output logic BPDirPredWrongM, // Prediction direction is wrong output logic BTBPredPCWrongM, // Prediction target wrong output logic RASPredPCWrongM, // RAS prediction is wrong - output logic PredictionInstrClassWrongM // Class prediction is wrong + output logic IClassWrongM // Class prediction is wrong ); logic [1:0] BPDirPredF; logic [`XLEN-1:0] BTAF, RASPCF; logic BPPCWrongE; - logic AnyWrongPredInstrClassD, AnyWrongPredInstrClassE; + logic IClassWrongE; logic BPDirPredWrongE; logic BPPCSrcF; @@ -153,7 +153,7 @@ module bpred ( .PCNextF, .PCF, .PCD, .PCE, .PCM, .BTAF, .BTAD, .BTAE, .BTBIClassF({BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF}), - .PredictionInstrClassWrongM, .AnyWrongPredInstrClassE, + .IClassWrongM, .IClassWrongE, .IEUAdrE, .IEUAdrM, .InstrClassD({CallD, ReturnD, JumpD, BranchD}), .InstrClassE({CallE, ReturnE, JumpE, BranchE}), @@ -163,7 +163,7 @@ module bpred ( icpred #(`INSTR_CLASS_PRED) icpred(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PostSpillInstrRawF, .InstrD, .BranchD, .BranchE, .JumpD, .JumpE, .BranchM, .BranchW, .JumpM, .JumpW, .CallD, .CallE, .CallM, .CallW, .ReturnD, .ReturnE, .ReturnM, .ReturnW, .BTBCallF, .BTBReturnF, .BTBJumpF, - .BTBBranchF, .BPCallF, .BPReturnF, .BPJumpF, .BPBranchF, .PredictionInstrClassWrongM, .AnyWrongPredInstrClassE, .WrongBPReturnD); + .BTBBranchF, .BPCallF, .BPReturnF, .BPJumpF, .BPBranchF, .IClassWrongM, .IClassWrongE, .WrongBPReturnD); // Part 3 RAS RASPredictor RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM, @@ -200,7 +200,7 @@ module bpred ( logic [`XLEN-1:0] RASPCD, RASPCE; logic BTBPredPCWrongE, RASPredPCWrongE; // performance counters - // 1. class (class wrong / minstret) (PredictionInstrClassWrongM / csr) // Correct now + // 1. class (class wrong / minstret) (IClassWrongM / csr) // Correct now // 2. target btb (btb target wrong / class[0,1,3]) (btb target wrong / (br + j + jal) // 3. target ras (ras target wrong / class[2]) // 4. direction (br dir wrong / class[0]) diff --git a/src/ifu/bpred/btb.sv b/src/ifu/bpred/btb.sv index 908288e2e..19c8c221a 100644 --- a/src/ifu/bpred/btb.sv +++ b/src/ifu/bpred/btb.sv @@ -40,8 +40,8 @@ module btb #(parameter Depth = 10 ) ( output logic [`XLEN-1:0] BTAE, output logic [3:0] BTBIClassF, // BTB's guess at instruction class // update - input logic PredictionInstrClassWrongM, // BTB's instruction class guess was wrong - input logic AnyWrongPredInstrClassE, + input logic IClassWrongM, // BTB's instruction class guess was wrong + input logic IClassWrongE, 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 [3:0] InstrClassD, // Instruction class to insert into btb @@ -99,7 +99,7 @@ module btb #(parameter Depth = 10 ) ( .clk, .ce1(~StallF | reset), .ra1(PCNextFIndex), .rd1(TableBTBPredF), .ce2(~StallW & ~FlushW), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(BTBWrongM), .bwe2('1)); - assign UpdateEn = |InstrClassM | PredictionInstrClassWrongM; + assign UpdateEn = |InstrClassM | IClassWrongM; flopenrc #(`XLEN) BTBD(clk, reset, FlushD, ~StallD, BTAF, BTAD); @@ -108,7 +108,7 @@ module btb #(parameter Depth = 10 ) ( // 2. BTAWrongE is used by the performance counters to track when the BTB's BTA or instruction class is wrong. flopenrc #(`XLEN) BTBTargetEReg(clk, reset, FlushE, ~StallE, BTAD, BTAE); assign BTAWrongE = (BTAE != IEUAdrE) & (InstrClassE[0] | InstrClassE[1] & ~InstrClassE[2]); - assign BTBWrongE = BTAWrongE | AnyWrongPredInstrClassE; + assign BTBWrongE = BTAWrongE | IClassWrongE; flopenrc #(1) BTBWrongMReg(clk, reset, FlushM, ~StallM, BTBWrongE, BTBWrongM); flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); diff --git a/src/ifu/bpred/icpred.sv b/src/ifu/bpred/icpred.sv index c37c3938c..53b612cb0 100644 --- a/src/ifu/bpred/icpred.sv +++ b/src/ifu/bpred/icpred.sv @@ -42,10 +42,10 @@ module icpred #(parameter INSTR_CLASS_PRED = 1)( output logic ReturnD, ReturnE, ReturnM, ReturnW, input logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF, output logic BPCallF, BPReturnF, BPJumpF, BPBranchF, - output logic PredictionInstrClassWrongM, WrongBPReturnD, AnyWrongPredInstrClassE + output logic IClassWrongM, WrongBPReturnD, IClassWrongE ); - logic AnyWrongPredInstrClassD; + logic IClassWrongD; logic BPBranchD, BPJumpD, BPReturnD, BPCallD; if (!INSTR_CLASS_PRED) begin : DirectClassDecode @@ -93,14 +93,14 @@ module icpred #(parameter INSTR_CLASS_PRED = 1)( flopenrc #(4) InstrClassRegW(clk, reset, FlushM, ~StallW, {CallM, ReturnM, JumpM, BranchM}, {CallW, ReturnW, JumpW, BranchW}); // branch predictor - flopenrc #(1) BPClassWrongRegM(clk, reset, FlushM, ~StallM, AnyWrongPredInstrClassE, PredictionInstrClassWrongM); - flopenrc #(1) WrongInstrClassRegE(clk, reset, FlushE, ~StallE, AnyWrongPredInstrClassD, AnyWrongPredInstrClassE); + flopenrc #(1) BPClassWrongRegM(clk, reset, FlushM, ~StallM, IClassWrongE, IClassWrongM); + flopenrc #(1) WrongInstrClassRegE(clk, reset, FlushE, ~StallE, IClassWrongD, IClassWrongE); // pipeline the predicted class flopenrc #(4) PredInstrClassRegD(clk, reset, FlushD, ~StallD, {BPCallF, BPReturnF, BPJumpF, BPBranchF}, {BPCallD, BPReturnD, BPJumpD, BPBranchD}); // branch class prediction wrong. - assign AnyWrongPredInstrClassD = |({BPCallD, BPReturnD, BPJumpD, BPBranchD} ^ {CallD, ReturnD, JumpD, BranchD}); + assign IClassWrongD = |({BPCallD, BPReturnD, BPJumpD, BPBranchD} ^ {CallD, ReturnD, JumpD, BranchD}); assign WrongBPReturnD = BPReturnD ^ ReturnD; endmodule diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index c85bb94d0..b049a956f 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -69,7 +69,7 @@ module ifu ( output logic BPDirPredWrongM, // Prediction direction is wrong output logic BTBPredPCWrongM, // Prediction target wrong output logic RASPredPCWrongM, // RAS prediction is wrong - output logic PredictionInstrClassWrongM, // Class prediction is wrong + output logic IClassWrongM, // Class prediction is wrong // Faults input logic IllegalBaseInstrD, // Illegal non-compressed instruction input logic IllegalFPUInstrD, // Illegal FP instruction @@ -332,12 +332,12 @@ module ifu ( .BranchD, .BranchE, .JumpD, .JumpE, .InstrD, .PCNextF, .PCPlus2or4F, .PC1NextF, .PCE, .PCM, .PCSrcE, .IEUAdrE, .IEUAdrM, .PCF, .NextValidPCE, .PCD, .PCLinkE, .InstrClassM, .BPWrongE, .PostSpillInstrRawF, .JumpOrTakenBranchM, .BPWrongM, - .BPDirPredWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM); + .BPDirPredWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .IClassWrongM); end else begin : bpred mux2 #(`XLEN) pcmux1(.d0(PCPlus2or4F), .d1(IEUAdrE), .s(PCSrcE), .y(PC1NextF)); assign BPWrongE = PCSrcE; - assign {InstrClassM, BPDirPredWrongM, BTBPredPCWrongM, RASPredPCWrongM, PredictionInstrClassWrongM} = '0; + assign {InstrClassM, BPDirPredWrongM, BTBPredPCWrongM, RASPredPCWrongM, IClassWrongM} = '0; assign NextValidPCE = PCE; end diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index 3575a4ffc..a54c05b2a 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -60,7 +60,7 @@ module csr #(parameter input logic BPDirPredWrongM, input logic BTBPredPCWrongM, input logic RASPredPCWrongM, - input logic PredictionInstrClassWrongM, + input logic IClassWrongM, input logic BPWrongM, // branch predictor is wrong input logic [3:0] InstrClassM, input logic JumpOrTakenBranchM, // actual instruction class @@ -259,7 +259,7 @@ module csr #(parameter if (`ZICOUNTERS_SUPPORTED) begin:counters csrc counters(.clk, .reset, .StallE, .StallM, .FlushM, .InstrValidNotFlushedM, .LoadStallD, .CSRMWriteM, - .BPDirPredWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM, .JumpOrTakenBranchM, .BPWrongM, + .BPDirPredWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .IClassWrongM, .JumpOrTakenBranchM, .BPWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .CSRAdrM, .PrivilegeModeW, .CSRWriteValM, .MCOUNTINHIBIT_REGW, .MCOUNTEREN_REGW, .SCOUNTEREN_REGW, diff --git a/src/privileged/csrc.sv b/src/privileged/csrc.sv index eae514433..f2b4b0e71 100644 --- a/src/privileged/csrc.sv +++ b/src/privileged/csrc.sv @@ -47,7 +47,7 @@ module csrc #(parameter input logic BPDirPredWrongM, input logic BTBPredPCWrongM, input logic RASPredPCWrongM, - input logic PredictionInstrClassWrongM, + input logic IClassWrongM, input logic BPWrongM, // branch predictor is wrong input logic [3:0] InstrClassM, input logic JumpOrTakenBranchM, // actual instruction class @@ -92,7 +92,7 @@ module csrc #(parameter assign CounterEvent[7] = JumpOrTakenBranchM & InstrValidNotFlushedM; // jump or taken branch instructions assign CounterEvent[8] = RASPredPCWrongM & InstrValidNotFlushedM; // return address stack wrong address assign CounterEvent[9] = InstrClassM[2] & InstrValidNotFlushedM; // return instructions - assign CounterEvent[10] = PredictionInstrClassWrongM & InstrValidNotFlushedM; // instruction class predictor wrong + assign CounterEvent[10] = IClassWrongM & InstrValidNotFlushedM; // instruction class predictor wrong assign CounterEvent[11] = DCacheAccess & InstrValidNotFlushedM; // data cache access assign CounterEvent[12] = DCacheMiss; // data cache miss. Miss asserted 1 cycle at start of cache miss assign CounterEvent[13] = ICacheAccess & InstrValidNotFlushedM; // instruction cache access diff --git a/src/privileged/privileged.sv b/src/privileged/privileged.sv index 37904557d..f7a3caad6 100644 --- a/src/privileged/privileged.sv +++ b/src/privileged/privileged.sv @@ -49,7 +49,7 @@ module privileged ( input logic BPDirPredWrongM, // branch predictor guessed wrong directoin input logic BTBPredPCWrongM, // branch predictor guessed wrong target input logic RASPredPCWrongM, // return adddress stack guessed wrong target - input logic PredictionInstrClassWrongM, // branch predictor guessed wrong instruction class + input logic IClassWrongM, // branch predictor guessed wrong instruction class input logic BPWrongM, // branch predictor is wrong input logic [3:0] InstrClassM, // actual instruction class input logic JumpOrTakenBranchM, // actual instruction class @@ -126,7 +126,7 @@ module privileged ( .MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .BPDirPredWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .BPWrongM, - .PredictionInstrClassWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .JumpOrTakenBranchM, + .IClassWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .JumpOrTakenBranchM, .NextPrivilegeModeM, .PrivilegeModeW, .CauseM, .SelHPTW, .STATUS_MPP, .STATUS_SPP, .STATUS_TSR, .STATUS_TVM, .STATUS_MIE, .STATUS_SIE, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TW, .STATUS_FS, diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index 387212b97..8f8885934 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -144,7 +144,7 @@ module wallypipelinedcore ( logic BPDirPredWrongM; logic BTBPredPCWrongM; logic RASPredPCWrongM; - logic PredictionInstrClassWrongM; + logic IClassWrongM; logic [3:0] InstrClassM; logic InstrAccessFaultF, HPTWInstrAccessFaultM; logic [2:0] LSUHSIZE; @@ -177,7 +177,7 @@ module wallypipelinedcore ( // Mem .CommittedF, .UnalignedPCNextF, .InvalidateICacheM, .CSRWriteFenceM, .InstrD, .InstrM, .PCM, .InstrClassM, .BPDirPredWrongM, .JumpOrTakenBranchM, - .BTBPredPCWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM, + .BTBPredPCWrongM, .RASPredPCWrongM, .IClassWrongM, // Faults out .IllegalBaseInstrD, .IllegalFPUInstrD, .InstrPageFaultF, .IllegalIEUFPUInstrD, .InstrMisalignedFaultM, // mmu management @@ -290,7 +290,7 @@ module wallypipelinedcore ( .InstrValidM, .CommittedM, .CommittedF, .FRegWriteM, .LoadStallD, .BPDirPredWrongM, .BTBPredPCWrongM, .BPWrongM, - .RASPredPCWrongM, .PredictionInstrClassWrongM, + .RASPredPCWrongM, .IClassWrongM, .InstrClassM, .JumpOrTakenBranchM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .PrivilegedM, .InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM, .InstrMisalignedFaultM, .IllegalIEUFPUInstrD, From f86a12f282847f0e389a73d8dfb8d8800e50ab25 Mon Sep 17 00:00:00 2001 From: eroom1966 Date: Wed, 1 Mar 2023 15:37:11 +0000 Subject: [PATCH 15/19] update testbench for memory privileges also update configuration to define value of mimpid --- sim/imperas.ic | 7 +++++ testbench/testbench_imperas.sv | 57 +++++++++++++++++++++++++++++----- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/sim/imperas.ic b/sim/imperas.ic index d28234bbc..69d57f702 100644 --- a/sim/imperas.ic +++ b/sim/imperas.ic @@ -1,3 +1,7 @@ +#--showoverrides +#--help --helpall +--traceregs + --override cpu/show_c_prefix=T --override cpu/unaligned=F --override cpu/ignore_non_leaf_DAU=1 @@ -33,3 +37,6 @@ # ignore settings of bits DAU for non leaf page table walks --override cpu/ignore_non_leaf_DAU=1 + +# mimpid = 0x100 +--override cpu/mimpid=0x100 diff --git a/testbench/testbench_imperas.sv b/testbench/testbench_imperas.sv index f26339007..cbca49275 100644 --- a/testbench/testbench_imperas.sv +++ b/testbench/testbench_imperas.sv @@ -137,7 +137,12 @@ module testbench; .CMP_CSR (1) ) idv_trace2api(rvvi); + int PRIV_RWX = RVVI_MEMORY_PRIVILEGE_READ | RVVI_MEMORY_PRIVILEGE_WRITE | RVVI_MEMORY_PRIVILEGE_EXEC; + int PRIV_RW = RVVI_MEMORY_PRIVILEGE_READ | RVVI_MEMORY_PRIVILEGE_WRITE; + int PRIV_X = RVVI_MEMORY_PRIVILEGE_EXEC; + initial begin + MAX_ERRS = 3; // Initialize REF (do this before initializing the DUT) @@ -158,6 +163,41 @@ module testbench; void'(rvviRefCsrSetVolatile(0, 32'hC02)); // INSTRET void'(rvviRefCsrSetVolatile(0, 32'hB02)); // MINSTRET void'(rvviRefCsrSetVolatile(0, 32'hC01)); // TIME + + // cannot predict this register due to latency between + // pending and taken + void'(rvviRefCsrSetVolatile(0, 32'h344)); + rvviRefCsrCompareEnable(0, 32'h344, RVVI_FALSE); + + // Memory lo, hi, priv (RVVI_MEMORY_PRIVILEGE_{READ,WRITE,EXEC}) + void'(rvviRefMemorySetPrivilege(56'h0, 56'h7fffffffff, 0)); + if (`BOOTROM_SUPPORTED) + void'(rvviRefMemorySetPrivilege(`BOOTROM_BASE, (`BOOTROM_BASE + `BOOTROM_RANGE), PRIV_X)); + if (`UNCORE_RAM_SUPPORTED) + void'(rvviRefMemorySetPrivilege(`UNCORE_RAM_BASE, (`UNCORE_RAM_BASE + `UNCORE_RAM_RANGE), PRIV_RWX)); + if (`EXT_MEM_SUPPORTED) + void'(rvviRefMemorySetPrivilege(`EXT_MEM_BASE, (`EXT_MEM_BASE + `EXT_MEM_RANGE), PRIV_RWX)); + + if (`CLINT_SUPPORTED) begin + void'(rvviRefMemorySetPrivilege(`CLINT_BASE, (`CLINT_BASE + `CLINT_RANGE), PRIV_RW)); + void'(rvviRefMemorySetVolatile(`CLINT_BASE, (`CLINT_BASE + `CLINT_RANGE))); + end + if (`GPIO_SUPPORTED) begin + void'(rvviRefMemorySetPrivilege(`GPIO_BASE, (`GPIO_BASE + `GPIO_RANGE), PRIV_RW)); + void'(rvviRefMemorySetVolatile(`GPIO_BASE, (`GPIO_BASE + `GPIO_RANGE))); + end + if (`UART_SUPPORTED) begin + void'(rvviRefMemorySetVolatile(`CLINT_BASE, (`CLINT_BASE + `CLINT_RANGE))); + void'(rvviRefMemorySetPrivilege(`CLINT_BASE, (`CLINT_BASE + `CLINT_RANGE), PRIV_RW)); + end + if (`PLIC_SUPPORTED) begin + void'(rvviRefMemorySetPrivilege(`PLIC_BASE, (`PLIC_BASE + `PLIC_RANGE), PRIV_RW)); + void'(rvviRefMemorySetVolatile(`PLIC_BASE, (`PLIC_BASE + `PLIC_RANGE))); + end + if (`SDC_SUPPORTED) begin + void'(rvviRefMemorySetPrivilege(`SDC_BASE, (`SDC_BASE + `SDC_RANGE), PRIV_RW)); + void'(rvviRefMemorySetVolatile(`SDC_BASE, (`SDC_BASE + `SDC_RANGE))); + end if(`XLEN==32) begin void'(rvviRefCsrSetVolatile(0, 32'hC80)); // CYCLEH @@ -166,14 +206,15 @@ module testbench; void'(rvviRefCsrSetVolatile(0, 32'hB82)); // MINSTRETH end - // Enable the trace2log module - if ($value$plusargs("TRACE2LOG_ENABLE=%d", TRACE2LOG_ENABLE)) begin - msgnote($sformatf("%m @ t=%0t: TRACE2LOG_ENABLE is %0d", $time, TRACE2LOG_ENABLE)); - end - - if ($value$plusargs("TRACE2COV_ENABLE=%d", TRACE2COV_ENABLE)) begin - msgnote($sformatf("%m @ t=%0t: TRACE2COV_ENABLE is %0d", $time, TRACE2COV_ENABLE)); - end + // These should be done in the attached client +// // Enable the trace2log module +// if ($value$plusargs("TRACE2LOG_ENABLE=%d", TRACE2LOG_ENABLE)) begin +// msgnote($sformatf("%m @ t=%0t: TRACE2LOG_ENABLE is %0d", $time, TRACE2LOG_ENABLE)); +// end +// +// if ($value$plusargs("TRACE2COV_ENABLE=%d", TRACE2COV_ENABLE)) begin +// msgnote($sformatf("%m @ t=%0t: TRACE2COV_ENABLE is %0d", $time, TRACE2COV_ENABLE)); +// end end final begin From 554e7d09736796a77fc90a5ad103ba476c008958 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 1 Mar 2023 10:45:40 -0600 Subject: [PATCH 16/19] Minor fix to btb. --- src/ifu/bpred/btb.sv | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/ifu/bpred/btb.sv b/src/ifu/bpred/btb.sv index 19c8c221a..d0723cd9b 100644 --- a/src/ifu/bpred/btb.sv +++ b/src/ifu/bpred/btb.sv @@ -57,8 +57,8 @@ module btb #(parameter Depth = 10 ) ( logic [`XLEN+3:0] TableBTBPredF; logic [`XLEN-1:0] IEUAdrW; logic [`XLEN-1:0] PCW; - logic BTAWrongE, BTBWrongE; - logic BTBWrongM; + logic BTBWrongE, BTAWrongE; + logic BTBWrongM, BTAWrongM; // hashing function for indexing the PC @@ -108,9 +108,11 @@ module btb #(parameter Depth = 10 ) ( // 2. BTAWrongE is used by the performance counters to track when the BTB's BTA or instruction class is wrong. flopenrc #(`XLEN) BTBTargetEReg(clk, reset, FlushE, ~StallE, BTAD, BTAE); assign BTAWrongE = (BTAE != IEUAdrE) & (InstrClassE[0] | InstrClassE[1] & ~InstrClassE[2]); - assign BTBWrongE = BTAWrongE | IClassWrongE; - flopenrc #(1) BTBWrongMReg(clk, reset, FlushM, ~StallM, BTBWrongE, BTBWrongM); - + //assign BTBWrongE = BTAWrongE | IClassWrongE; + //flopenrc #(1) BTBWrongMReg(clk, reset, FlushM, ~StallM, BTBWrongE, BTBWrongM); + flopenrc #(1) BTAWrongMReg(clk, reset, FlushM, ~StallM, BTAWrongE, BTAWrongM); + assign BTBWrongM = BTAWrongM | IClassWrongM; + flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); flopenr #(`XLEN) IEUAdrWReg(clk, reset, ~StallW, IEUAdrM, IEUAdrW); From 03a6679ba0bbba3cbacf46ec9ec47257166b86ac Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 1 Mar 2023 10:47:00 -0600 Subject: [PATCH 17/19] More btb cleanup. --- src/ifu/bpred/btb.sv | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/ifu/bpred/btb.sv b/src/ifu/bpred/btb.sv index d0723cd9b..b14399704 100644 --- a/src/ifu/bpred/btb.sv +++ b/src/ifu/bpred/btb.sv @@ -92,15 +92,11 @@ module btb #(parameter Depth = 10 ) ( assign {BTBIClassF, BTAF} = MatchX ? ForwardBTBPredictionF : {TableBTBPredF}; - logic UpdateEn; - // An optimization may be using a PC relative address. ram2p1r1wbe #(2**Depth, `XLEN+4) memory( .clk, .ce1(~StallF | reset), .ra1(PCNextFIndex), .rd1(TableBTBPredF), .ce2(~StallW & ~FlushW), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(BTBWrongM), .bwe2('1)); - assign UpdateEn = |InstrClassM | IClassWrongM; - flopenrc #(`XLEN) BTBD(clk, reset, FlushD, ~StallD, BTAF, BTAD); // BTAE is not strickly necessary. However it is used by two parts of wally. @@ -108,8 +104,7 @@ module btb #(parameter Depth = 10 ) ( // 2. BTAWrongE is used by the performance counters to track when the BTB's BTA or instruction class is wrong. flopenrc #(`XLEN) BTBTargetEReg(clk, reset, FlushE, ~StallE, BTAD, BTAE); assign BTAWrongE = (BTAE != IEUAdrE) & (InstrClassE[0] | InstrClassE[1] & ~InstrClassE[2]); - //assign BTBWrongE = BTAWrongE | IClassWrongE; - //flopenrc #(1) BTBWrongMReg(clk, reset, FlushM, ~StallM, BTBWrongE, BTBWrongM); + flopenrc #(1) BTAWrongMReg(clk, reset, FlushM, ~StallM, BTAWrongE, BTAWrongM); assign BTBWrongM = BTAWrongM | IClassWrongM; From dea6b643a65e0ec6ac29930d62b87bba1773a4ab Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 1 Mar 2023 11:24:24 -0600 Subject: [PATCH 18/19] Branch predictor cleanup. I think Ch 10 is now done except for BTB performance analysis and the section on running benchmarks and collecting data. --- src/ifu/bpred/RASPredictor.sv | 4 ++-- src/ifu/bpred/bpred.sv | 6 +++--- src/ifu/bpred/icpred.sv | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ifu/bpred/RASPredictor.sv b/src/ifu/bpred/RASPredictor.sv index 72c594556..d5fd0c019 100644 --- a/src/ifu/bpred/RASPredictor.sv +++ b/src/ifu/bpred/RASPredictor.sv @@ -33,7 +33,7 @@ module RASPredictor #(parameter int StackSize = 16 )( input logic clk, input logic reset, input logic StallF, StallD, StallE, StallM, FlushD, FlushE, FlushM, - input logic WrongBPReturnD, // Prediction class is wrong + input logic BPReturnWrongD, // Prediction class is wrong input logic ReturnD, input logic ReturnE, CallE, // Instr class input logic BPReturnF, @@ -61,7 +61,7 @@ module RASPredictor #(parameter int StackSize = 16 )( assign PopF = BPReturnF & ~StallD & ~FlushD; assign PushE = CallE & ~StallM & ~FlushM; - assign WrongPredReturnD = (WrongBPReturnD) & ~StallE & ~FlushE; + assign WrongPredReturnD = (BPReturnWrongD) & ~StallE & ~FlushE; assign FlushedReturnDE = (~StallE & FlushE & ReturnD) | (~StallM & FlushM & ReturnE); // flushed return assign RepairD = WrongPredReturnD | FlushedReturnDE ; diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index 1074aea66..84a50c621 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -95,7 +95,7 @@ module bpred ( logic ReturnE, CallE; logic BranchM, JumpM, ReturnM, CallM; logic BranchW, JumpW, ReturnW, CallW; - logic WrongBPReturnD; + logic BPReturnWrongD; logic [`XLEN-1:0] BTAE; @@ -163,12 +163,12 @@ module bpred ( icpred #(`INSTR_CLASS_PRED) icpred(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PostSpillInstrRawF, .InstrD, .BranchD, .BranchE, .JumpD, .JumpE, .BranchM, .BranchW, .JumpM, .JumpW, .CallD, .CallE, .CallM, .CallW, .ReturnD, .ReturnE, .ReturnM, .ReturnW, .BTBCallF, .BTBReturnF, .BTBJumpF, - .BTBBranchF, .BPCallF, .BPReturnF, .BPJumpF, .BPBranchF, .IClassWrongM, .IClassWrongE, .WrongBPReturnD); + .BTBBranchF, .BPCallF, .BPReturnF, .BPJumpF, .BPBranchF, .IClassWrongM, .IClassWrongE, .BPReturnWrongD); // Part 3 RAS RASPredictor RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM, .BPReturnF, .ReturnD, .ReturnE, .CallE, - .WrongBPReturnD, .RASPCF, .PCLinkE); + .BPReturnWrongD, .RASPCF, .PCLinkE); // Check the prediction // if it is a CFI then check if the next instruction address (PCD) matches the branch's target or fallthrough address. diff --git a/src/ifu/bpred/icpred.sv b/src/ifu/bpred/icpred.sv index 53b612cb0..14e7c8d89 100644 --- a/src/ifu/bpred/icpred.sv +++ b/src/ifu/bpred/icpred.sv @@ -42,7 +42,7 @@ module icpred #(parameter INSTR_CLASS_PRED = 1)( output logic ReturnD, ReturnE, ReturnM, ReturnW, input logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF, output logic BPCallF, BPReturnF, BPJumpF, BPBranchF, - output logic IClassWrongM, WrongBPReturnD, IClassWrongE + output logic IClassWrongM, BPReturnWrongD, IClassWrongE ); logic IClassWrongD; @@ -101,6 +101,6 @@ module icpred #(parameter INSTR_CLASS_PRED = 1)( // branch class prediction wrong. assign IClassWrongD = |({BPCallD, BPReturnD, BPJumpD, BPBranchD} ^ {CallD, ReturnD, JumpD, BranchD}); - assign WrongBPReturnD = BPReturnD ^ ReturnD; + assign BPReturnWrongD = BPReturnD ^ ReturnD; endmodule From 90b2f0a6525c390bc5e2743e07cc79a7e1bc6aae Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 1 Mar 2023 11:52:42 -0600 Subject: [PATCH 19/19] Set bp to use instruction class prediction by default. --- src/ifu/bpred/bpred.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index 84a50c621..92da8622e 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -28,7 +28,7 @@ `include "wally-config.vh" -`define INSTR_CLASS_PRED 0 +`define INSTR_CLASS_PRED 1 module bpred ( input logic clk, reset,