From 6326e6984caab98713184ad1f713a47d87d6e5b5 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 9 Jan 2023 00:11:25 -0600 Subject: [PATCH] Might have actually solved the gshare bug. --- pipelined/config/rv64gc/wally-config.vh | 4 +- pipelined/src/ifu/speculativegshare.sv | 118 +++++++++++++----------- 2 files changed, 66 insertions(+), 56 deletions(-) diff --git a/pipelined/config/rv64gc/wally-config.vh b/pipelined/config/rv64gc/wally-config.vh index 70ce1938..8db37f58 100644 --- a/pipelined/config/rv64gc/wally-config.vh +++ b/pipelined/config/rv64gc/wally-config.vh @@ -135,8 +135,8 @@ `define PLIC_UART_ID 10 `define BPRED_ENABLED 1 -//`define BPTYPE "BPSPECULATIVEGSHARE" // BPLOCALPAg or BPGLOBAL or BPTWOBIT or BPGSHARE or BPSPECULATIVEGLOBAL or BPSPECULATIVEGSHARE or BPOLDGSHARE or BPOLDGSHARE2 -`define BPTYPE "BPSPECULATIVEGLOBAL" // BPLOCALPAg or BPGLOBAL or BPTWOBIT or BPGSHARE or BPSPECULATIVEGLOBAL or BPSPECULATIVEGSHARE or BPOLDGSHARE or BPOLDGSHARE2 +`define BPTYPE "BPSPECULATIVEGSHARE" // BPLOCALPAg or BPGLOBAL or BPTWOBIT or BPGSHARE or BPSPECULATIVEGLOBAL or BPSPECULATIVEGSHARE or BPOLDGSHARE or BPOLDGSHARE2 +//`define BPTYPE "BPSPECULATIVEGLOBAL" // BPLOCALPAg or BPGLOBAL or BPTWOBIT or BPGSHARE or BPSPECULATIVEGLOBAL or BPSPECULATIVEGSHARE or BPOLDGSHARE or BPOLDGSHARE2 `define TESTSBP 0 `define BPRED_SIZE 10 diff --git a/pipelined/src/ifu/speculativegshare.sv b/pipelined/src/ifu/speculativegshare.sv index a4e69219..61613227 100644 --- a/pipelined/src/ifu/speculativegshare.sv +++ b/pipelined/src/ifu/speculativegshare.sv @@ -1,12 +1,12 @@ /////////////////////////////////////////// -// globalHistoryPredictor.sv +// gsharePredictor.sv // // Written: Shreya Sanghai // Email: ssanghai@hmc.edu // Created: March 16, 2021 // Modified: // -// Purpose: Gshare History Branch predictor with parameterized global history register +// Purpose: Global History Branch predictor with parameterized global history register // // A component of the Wally configurable RISC-V project. // @@ -48,49 +48,60 @@ module speculativegshare input logic PCSrcE ); - logic MatchD, MatchE, MatchM, MatchW, MatchX, MatchXF; -// logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE, IndexM, IndexW; - logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE; - logic [1:0] NewDirPredictionF, NewDirPredictionD, NewDirPredictionE, NewDirPredictionM, NewDirPredictionW, NewDirPredictionX, NewDirPredictionXF; + logic MatchF, MatchD, MatchE, MatchM, MatchW; + logic MatchNextX, MatchXF; - logic [k-1:0] GHRF, GHRD, GHRE, GHRM, GHRW, GHRNextF, GHRCurrentF, GHRCurrentE; - logic [k-1:0] NewGHRF, NewGHRD, NewGHRE, NewGHRM, NewGHRW; + logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE; + logic [1:0] NewDirPredictionF, NewDirPredictionD, NewDirPredictionE, NewDirPredictionM, NewDirPredictionW; + + logic [k-1:0] GHRF; + logic [k:0] GHRD, OldGHRE, GHRE, GHRM, GHRW; + logic [k-1:0] GHRNextF; + logic [k:0] GHRNextD, GHRNextE, GHRNextM, GHRNextW; + logic [k-1:0] IndexNextF, IndexF; + logic [k-1:0] IndexD, IndexE, IndexM, IndexW; + logic PCSrcM, PCSrcW; logic [`XLEN-1:0] PCW; - logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE, IndexM, IndexW; - - assign IndexNextF = NewGHRF & {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]}; - assign IndexF = GHRF & {PCF[k+1] ^ PCF[1], PCF[k:2]}; - assign IndexD = GHRD & {PCD[k+1] ^ PCD[1], PCD[k:2]}; - assign IndexE = GHRE & {PCE[k+1] ^ PCE[1], PCE[k:2]}; - assign IndexM = GHRM & {PCM[k+1] ^ PCM[1], PCM[k:2]}; - assign IndexW = GHRW & {PCW[k+1] ^ PCW[1], PCW[k:2]}; + logic [1:0] ForwardNewDirPrediction, ForwardDirPredictionF; + + assign IndexNextF = GHRNextF ^ {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]}; + assign IndexF = GHRF ^ {PCF[k+1] ^ PCF[1], PCF[k:2]}; + assign IndexD = GHRD[k-1:0] ^ {PCD[k+1] ^ PCD[1], PCD[k:2]}; + assign IndexE = GHRE[k-1:0] ^ {PCE[k+1] ^ PCE[1], PCE[k:2]}; + assign IndexM = GHRM[k-1:0] ^ {PCM[k+1] ^ PCM[1], PCM[k:2]}; + assign IndexW = GHRW[k-1:0] ^ {PCW[k+1] ^ PCW[1], PCW[k:2]}; + ram2p1r1wbefix #(2**k, 2) PHT(.clk(clk), - .ce1(~StallF | reset), .ce2(~StallM & ~FlushM), + .ce1(~StallF | reset), .ce2(~StallW & ~FlushW), .ra1(IndexNextF), .rd1(TableDirPredictionF), - .wa2(IndexM), - .wd2(NewDirPredictionM), - .we2(BranchInstrM & ~StallM & ~FlushM), + .wa2(IndexW), + .wd2(NewDirPredictionW), + .we2(BranchInstrW & ~StallW & ~FlushW), .bwe2(1'b1)); - // if there are non-flushed branches in the pipeline we need to forward the prediction from that stage to the demi stage NextF and then - // register for use in the Fetch stage. - assign MatchD = BranchInstrD & (IndexD == IndexF); - assign MatchE = BranchInstrE & (IndexE == IndexF); - assign MatchM = BranchInstrM & (IndexM == IndexF); - assign MatchW = BranchInstrW & (IndexW == IndexF); - assign MatchX = MatchD | MatchE | MatchM | MatchW; - - assign NewDirPredictionX = MatchD ? NewDirPredictionD : - MatchE ? NewDirPredictionE : - MatchM ? NewDirPredictionM : - MatchW ? NewDirPredictionW : '0; - flopenr #(2) NewPredXReg(clk, reset, ~StallF, NewDirPredictionX, NewDirPredictionXF); - flopenrc #(1) DoForwardReg(clk, reset, FlushD, ~StallF, MatchX, MatchXF); - - assign DirPredictionF = MatchXF ? NewDirPredictionXF : TableDirPredictionF; + // if there are non-flushed branches in the pipeline we need to forward the prediction from that stage to the NextF demi stage + // and then register for use in the Fetch stage. + assign MatchF = BranchInstrF & ~FlushD & (IndexNextF == IndexF); + assign MatchD = BranchInstrD & ~FlushE & (IndexNextF == IndexD); + assign MatchE = BranchInstrE & ~FlushM & (IndexNextF == IndexE); + assign MatchM = BranchInstrM & ~FlushW & (IndexNextF == IndexM); + assign MatchW = BranchInstrW & (IndexNextF == IndexW); + assign MatchNextX = MatchF | MatchD | MatchE | MatchM | MatchW; + + flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF); + + assign ForwardNewDirPrediction = MatchF ? NewDirPredictionF : + MatchD ? NewDirPredictionD : + MatchE ? NewDirPredictionE : + MatchM ? NewDirPredictionM : + NewDirPredictionW; + + flopenr #(2) ForwardDirPredicitonReg(clk, reset, ~StallF, ForwardNewDirPrediction, ForwardDirPredictionF); + + assign DirPredictionF = MatchXF ? ForwardDirPredictionF : TableDirPredictionF; // DirPrediction pipeline flopenr #(2) PredictionRegD(clk, reset, ~StallD, DirPredictionF, DirPredictionD); @@ -102,31 +113,30 @@ module speculativegshare satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE)); flopenr #(2) NewPredMReg(clk, reset, ~StallM, NewDirPredictionE, NewDirPredictionM); flopenr #(2) NewPredWReg(clk, reset, ~StallW, NewDirPredictionM, NewDirPredictionW); - // PCSrc pipeline flopenrc #(1) PCSrcMReg(clk, reset, FlushM, ~StallM, PCSrcE, PCSrcM); flopenrc #(1) PCSrcWReg(clk, reset, FlushW, ~StallW, PCSrcM, PCSrcW); // GHR pipeline - assign GHRNextF = FlushD & BranchInstrD & ~FlushE & ~FlushM & ~FlushW ? NewGHRD : - FlushE & BranchInstrE & ~FlushM & ~FlushW ? NewGHRE : - FlushM & BranchInstrM & ~FlushW ? NewGHRM : - FlushW & BranchInstrW ? NewGHRW : - NewGHRF; - - flopenr #(k) GHRFReg(clk, reset, ~StallF, GHRNextF, GHRF); - //assign GHRF = BranchInstrF ? {NewDirPredictionF[1], GHRCurrentF[k-1:1]} : GHRCurrentF; - assign NewGHRF = BranchInstrF ? {NewDirPredictionF[1], GHRF[k-1:1]} : GHRF; - flopenr #(k) GHRDReg(clk, reset, ~StallD, GHRF, GHRD); - assign NewGHRD = BranchInstrD ? {NewDirPredictionD[1], GHRD[k-1:1]} : GHRD; - flopenr #(k) GHREReg(clk, reset, ~StallE, GHRD, GHRE); - assign NewGHRE = BranchInstrE ? {PCSrcE, GHRE[k-1:1]} : GHRE; - flopenr #(k) GHRMReg(clk, reset, ~StallM, GHRE, GHRM); - assign NewGHRM = BranchInstrM ? {PCSrcM, GHRM[k-1:1]} : GHRM; - flopenr #(k) GHRWReg(clk, reset, ~StallW, GHRM, GHRW); - assign NewGHRW = BranchInstrW ? {PCSrcW, GHRW[k-1:1]} : GHRW; + assign GHRNextF = FlushD ? GHRNextD[k:1] : + BranchInstrF ? {DirPredictionF[1], GHRF[k-1:1]} : + GHRF; + flopenr #(k) GHRFReg(clk, reset, (~StallF) | FlushD, GHRNextF, GHRF); + + assign GHRNextD = FlushD ? GHRNextE : {DirPredictionF[1], GHRF}; + flopenr #(k+1) GHRDReg(clk, reset, (~StallD) | FlushD, GHRNextD, GHRD); + + assign GHRNextE = FlushE ? GHRNextM : GHRD; + flopenr #(k+1) GHREReg(clk, reset, (~StallE) | FlushE, GHRNextE, OldGHRE); + assign GHRE = BranchInstrE ? {PCSrcE, OldGHRE[k-1:0]} : OldGHRE; + + assign GHRNextM = FlushM ? GHRNextW : GHRE; + flopenr #(k+1) GHRMReg(clk, reset, (~StallM) | FlushM, GHRNextM, GHRM); + + assign GHRNextW = FlushW ? GHRW : GHRM; + flopenr #(k+1) GHRWReg(clk, reset, (BranchInstrM & ~StallW) | FlushW, GHRNextW, GHRW); assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchInstrE;