From 1982c66b72591c42b7495832e810256ad314af1d Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 20 Feb 2023 15:39:42 -0600 Subject: [PATCH 1/7] Simiplified BTB. --- src/ifu/bpred/bpred.sv | 10 +++++----- src/ifu/bpred/btb.sv | 33 +++++++++++++++++++-------------- src/ifu/ifu.sv | 3 ++- src/wally/wallypipelinedcore.sv | 2 +- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index 2b4156cfb..e7bf1be13 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -56,6 +56,7 @@ module bpred ( input logic JumpD, JumpE, input logic PCSrcE, // Executation stage branch is taken 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 @@ -143,14 +144,13 @@ module bpred ( // BTB contains target address for all CFI btb #(`BTB_SIZE) - TargetPredictor(.clk, .reset, .StallF, .StallD, .StallM, .FlushD, .FlushM, - .PCNextF, .PCF, .PCD, .PCE, + TargetPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM, + .PCNextF, .PCF, .PCD, .PCE, .PCM, .PredPCF, .BTBPredInstrClassF, .AnyWrongPredInstrClassE, - .IEUAdrE, - .InstrClassD, - .InstrClassE); + .IEUAdrE, .IEUAdrM, + .InstrClassD, .InstrClassE, .InstrClassM); // the branch predictor needs a compact decoding of the instruction class. if (`INSTR_CLASS_PRED == 0) begin : DirectClassDecode diff --git a/src/ifu/bpred/btb.sv b/src/ifu/bpred/btb.sv index 8f7b3a2b8..1dae8c890 100644 --- a/src/ifu/bpred/btb.sv +++ b/src/ifu/bpred/btb.sv @@ -31,22 +31,24 @@ `include "wally-config.vh" module btb #(parameter Depth = 10 ) ( - input logic clk, - input logic reset, - input logic StallF, StallD, StallM, FlushD, FlushM, - input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, // PC at various stages - output logic [`XLEN-1:0] PredPCF, // BTB's guess at PC - output logic [3:0] BTBPredInstrClassF, // BTB's guess at instruction class + input logic clk, + input logic reset, + input logic StallF, StallD, StallE, StallM, FlushD, FlushE, FlushM, + input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, // PC at various stages + output logic [`XLEN-1:0] PredPCF, // BTB's guess at PC + output logic [3:0] BTBPredInstrClassF, // BTB's guess at instruction class // update - input logic AnyWrongPredInstrClassE, // BTB's instruction class guess was wrong - input logic [`XLEN-1:0] IEUAdrE, // Branch/jump target address to insert into btb - input logic [3:0] InstrClassD, // Instruction class to insert into btb - input logic [3:0] InstrClassE // Instruction class to insert into btb + input logic AnyWrongPredInstrClassE, // 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 [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 ); - logic [Depth-1:0] PCNextFIndex, PCFIndex, PCDIndex, PCEIndex; + logic [Depth-1:0] PCNextFIndex, PCFIndex, PCDIndex, PCEIndex, PCMIndex; logic [`XLEN-1:0] ResetPC; - logic MatchF, MatchD, MatchE, MatchNextX, MatchXF; + logic MatchF, MatchD, MatchE, MatchM, MatchNextX, MatchXF; logic [`XLEN+3:0] ForwardBTBPrediction, ForwardBTBPredictionF; logic [`XLEN+3:0] TableBTBPredictionF; logic [`XLEN-1:0] PredPCD; @@ -59,6 +61,7 @@ module btb #(parameter Depth = 10 ) ( assign PCFIndex = {PCF[Depth+1] ^ PCF[1], PCF[Depth:2]}; assign PCDIndex = {PCD[Depth+1] ^ PCD[1], PCD[Depth:2]}; assign PCEIndex = {PCE[Depth+1] ^ PCE[1], PCE[Depth:2]}; + assign PCMIndex = {PCM[Depth+1] ^ PCM[1], PCM[Depth:2]}; // must output a valid PC and valid bit during reset. Because only PCF, not PCNextF is reset, PCNextF is invalid // during reset. The BTB must produce a non X PC1NextF to allow the simulation to run. @@ -70,13 +73,15 @@ module btb #(parameter Depth = 10 ) ( assign MatchF = PCNextFIndex == PCFIndex; assign MatchD = PCNextFIndex == PCDIndex; assign MatchE = PCNextFIndex == PCEIndex; + assign MatchM = PCNextFIndex == PCMIndex; assign MatchNextX = MatchF | MatchD | MatchE; flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF); assign ForwardBTBPrediction = MatchF ? {BTBPredInstrClassF, PredPCF} : MatchD ? {InstrClassD, PredPCD} : - {InstrClassE, IEUAdrE} ; + MatchE ? {InstrClassE, IEUAdrE} : + {InstrClassM, IEUAdrM} ; flopenr #(`XLEN+4) ForwardBTBPredicitonReg(clk, reset, ~StallF, ForwardBTBPrediction, ForwardBTBPredictionF); @@ -90,6 +95,6 @@ module btb #(parameter Depth = 10 ) ( .clk, .ce1(~StallF | reset), .ra1(PCNextFIndex), .rd1(TableBTBPredictionF), .ce2(~StallM & ~FlushM), .wa2(PCEIndex), .wd2({InstrClassE, IEUAdrE}), .we2(UpdateEn), .bwe2('1)); - flopenrc #(`XLEN) BTBD(clk, reset, FlushD, ~StallD, {PredPCF}, {PredPCD}); + flopenrc #(`XLEN) BTBD(clk, reset, FlushD, ~StallD, PredPCF, PredPCD); endmodule diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index 51317e0b0..3c6cd9414 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -52,6 +52,7 @@ module ifu ( output logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address) input logic PCSrcE, // Executation stage branch is taken 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 BPPredWrongM, // Prediction is wrong @@ -327,7 +328,7 @@ 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, .PCF, .NextValidPCE, + .InstrD, .PCNextF, .PCPlus2or4F, .PCNext1F, .PCE, .PCM, .PCSrcE, .IEUAdrE, .IEUAdrM, .PCF, .NextValidPCE, .PCD, .PCLinkE, .InstrClassM, .BPPredWrongE, .PostSpillInstrRawF, .JumpOrTakenBranchM, .BPPredWrongM, .DirPredictionWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM); diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index a03caea15..c26ffb3a4 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -174,7 +174,7 @@ module wallypipelinedcore ( .IFUStallF, .IFUHBURST, .IFUHTRANS, .IFUHSIZE, .IFUHREADY, .IFUHWRITE, .ICacheAccess, .ICacheMiss, // Execute - .PCLinkE, .PCSrcE, .IEUAdrE, .PCE, .BPPredWrongE, .BPPredWrongM, + .PCLinkE, .PCSrcE, .IEUAdrE, .IEUAdrM, .PCE, .BPPredWrongE, .BPPredWrongM, // Mem .CommittedF, .UnalignedPCNextF, .InvalidateICacheM, .CSRWriteFenceM, .InstrD, .InstrM, .PCM, .InstrClassM, .DirPredictionWrongM, .JumpOrTakenBranchM, From d887124837e4105ae050fbae2fc315b2b4a60362 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 20 Feb 2023 16:00:29 -0600 Subject: [PATCH 2/7] Found a bug where the d and i cache misses were not recorded in the performance counters. --- src/privileged/csrc.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/privileged/csrc.sv b/src/privileged/csrc.sv index ad9475d32..d61835826 100644 --- a/src/privileged/csrc.sv +++ b/src/privileged/csrc.sv @@ -94,9 +94,9 @@ module csrc #(parameter assign CounterEvent[9] = InstrClassM[2] & InstrValidNotFlushedM; // return instructions assign CounterEvent[10] = PredictionInstrClassWrongM & InstrValidNotFlushedM; // instruction class predictor wrong assign CounterEvent[11] = DCacheAccess & InstrValidNotFlushedM; // data cache access - assign CounterEvent[12] = DCacheMiss & InstrValidNotFlushedM; // data cache miss + 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 & InstrValidNotFlushedM; // instruction cache miss + 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[`COUNTERS-1:16] = 0; // eventually give these sources, including FP instructions, I$/D$ misses, branches and mispredictions end From 5187c781844344195138f2ca4ffe51237f5fc262 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 20 Feb 2023 16:18:04 -0600 Subject: [PATCH 3/7] Fixed forwarding bug in the BTB. --- 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 e7bf1be13..97101a3ea 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -148,7 +148,7 @@ module bpred ( .PCNextF, .PCF, .PCD, .PCE, .PCM, .PredPCF, .BTBPredInstrClassF, - .AnyWrongPredInstrClassE, + .PredictionInstrClassWrongM, .IEUAdrE, .IEUAdrM, .InstrClassD, .InstrClassE, .InstrClassM); diff --git a/src/ifu/bpred/btb.sv b/src/ifu/bpred/btb.sv index 1dae8c890..a8f67efeb 100644 --- a/src/ifu/bpred/btb.sv +++ b/src/ifu/bpred/btb.sv @@ -38,7 +38,7 @@ module btb #(parameter Depth = 10 ) ( output logic [`XLEN-1:0] PredPCF, // BTB's guess at PC output logic [3:0] BTBPredInstrClassF, // BTB's guess at instruction class // update - input logic AnyWrongPredInstrClassE, // BTB's instruction class guess was wrong + 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 [3:0] InstrClassD, // Instruction class to insert into btb @@ -74,7 +74,7 @@ module btb #(parameter Depth = 10 ) ( assign MatchD = PCNextFIndex == PCDIndex; assign MatchE = PCNextFIndex == PCEIndex; assign MatchM = PCNextFIndex == PCMIndex; - assign MatchNextX = MatchF | MatchD | MatchE; + assign MatchNextX = MatchF | MatchD | MatchE | MatchM; flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF); @@ -88,12 +88,12 @@ module btb #(parameter Depth = 10 ) ( assign {BTBPredInstrClassF, PredPCF} = MatchXF ? ForwardBTBPredictionF : {TableBTBPredictionF}; - assign UpdateEn = |InstrClassE | AnyWrongPredInstrClassE; + 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), - .ce2(~StallM & ~FlushM), .wa2(PCEIndex), .wd2({InstrClassE, IEUAdrE}), .we2(UpdateEn), .bwe2('1)); + .ce2(~StallM & ~FlushM), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(UpdateEn), .bwe2('1)); flopenrc #(`XLEN) BTBD(clk, reset, FlushD, ~StallD, PredPCF, PredPCD); From 68e39eeb6675f3475bc79f1eb9ec1db4018de5ab Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 20 Feb 2023 17:54:22 -0600 Subject: [PATCH 4/7] Fixed another bug in the btb. --- src/ifu/bpred/bpred.sv | 2 +- src/ifu/bpred/btb.sv | 4 ++-- src/ifu/bpred/gshareForward.sv | 4 ++-- testbench/tests.vh | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index 97101a3ea..b0ea2683b 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -144,7 +144,7 @@ module bpred ( // BTB contains target address for all CFI btb #(`BTB_SIZE) - TargetPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM, + TargetPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCF, .PCD, .PCE, .PCM, .PredPCF, .BTBPredInstrClassF, diff --git a/src/ifu/bpred/btb.sv b/src/ifu/bpred/btb.sv index a8f67efeb..8e2d0e259 100644 --- a/src/ifu/bpred/btb.sv +++ b/src/ifu/bpred/btb.sv @@ -33,7 +33,7 @@ module btb #(parameter Depth = 10 ) ( input logic clk, input logic reset, - input logic StallF, StallD, StallE, StallM, FlushD, FlushE, FlushM, + 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] PredPCF, // BTB's guess at PC output logic [3:0] BTBPredInstrClassF, // BTB's guess at instruction class @@ -93,7 +93,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(TableBTBPredictionF), - .ce2(~StallM & ~FlushM), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(UpdateEn), .bwe2('1)); + .ce2(~StallW & ~FlushW), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(UpdateEn), .bwe2('1)); flopenrc #(`XLEN) BTBD(clk, reset, FlushD, ~StallD, PredPCF, PredPCD); diff --git a/src/ifu/bpred/gshareForward.sv b/src/ifu/bpred/gshareForward.sv index 77ab90fba..57bcd4bee 100644 --- a/src/ifu/bpred/gshareForward.sv +++ b/src/ifu/bpred/gshareForward.sv @@ -83,7 +83,7 @@ module gshareForward #(parameter k = 10) ( .rd1(TableDirPredictionF), .wa2(IndexM), .wd2(NewDirPredictionM), - .we2(BranchInstrM & ~StallW & ~FlushW), + .we2(BranchInstrM), .bwe2(1'b1)); flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD); @@ -102,7 +102,7 @@ module gshareForward #(parameter k = 10) ( assign GHRNext = BranchInstrM ? {PCSrcM, GHR[k-1:1]} : GHR; assign GHRM = GHR; - flopenr #(k) GHRReg(clk, reset, ~StallM & ~FlushM & BranchInstrM, GHRNext, GHR); + flopenr #(k) GHRReg(clk, reset, ~StallW & ~FlushW & BranchInstrM, GHRNext, GHR); flopenrc #(1) PCSrcMReg(clk, reset, FlushM, ~StallM, PCSrcE, PCSrcM); endmodule diff --git a/testbench/tests.vh b/testbench/tests.vh index 6ab4533fa..2ec4e43fc 100644 --- a/testbench/tests.vh +++ b/testbench/tests.vh @@ -50,8 +50,8 @@ string tvpaths[] = '{ string embench[] = '{ `EMBENCH, - "bd_speedopt_speed/src/cubic/cubic", // cubic is likely going to removed when embench 2.0 launches "bd_speedopt_speed/src/nsichneu/nsichneu", + "bd_speedopt_speed/src/cubic/cubic", // cubic is likely going to removed when embench 2.0 launches "bd_speedopt_speed/src/aha-mont64/aha-mont64", "bd_speedopt_speed/src/crc32/crc32", "bd_speedopt_speed/src/edn/edn", From a14c71bd9597dfa4e1a41f61d974197349e14abf Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 20 Feb 2023 18:36:33 -0600 Subject: [PATCH 5/7] Renamed branch predictors and consolidated global and gshare predictors. --- config/buildroot/wally-config.vh | 2 +- config/fpga/wally-config.vh | 4 +- config/rv32e/wally-config.vh | 2 +- config/rv32gc/wally-config.vh | 2 +- config/rv32i/wally-config.vh | 2 +- config/rv32imc/wally-config.vh | 2 +- config/rv64fpquad/wally-config.vh | 2 +- config/rv64gc/wally-config.vh | 2 +- config/rv64i/wally-config.vh | 2 +- sim/wave.do | 117 ++++++++++-------- src/ifu/bpred/bpred.sv | 40 +++--- src/ifu/bpred/gshare.sv | 73 ++++++++--- .../{gshareForward.sv => gsharebasic.sv} | 69 ++++------- 13 files changed, 167 insertions(+), 152 deletions(-) rename src/ifu/bpred/{gshareForward.sv => gsharebasic.sv} (53%) diff --git a/config/buildroot/wally-config.vh b/config/buildroot/wally-config.vh index 813566a20..12c7db2d0 100644 --- a/config/buildroot/wally-config.vh +++ b/config/buildroot/wally-config.vh @@ -130,7 +130,7 @@ `define PLIC_GPIO_ID 3 `define BPRED_SUPPORTED 1 -`define BPRED_TYPE "BP_GSHARE_FORWARD" // BPLOCALPAg or BPGLOBAL or BPTWOBIT or BPGSHARE +`define BPRED_TYPE "BP_GSHARE" // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT `define BPRED_SIZE 10 `define BTB_SIZE 10 diff --git a/config/fpga/wally-config.vh b/config/fpga/wally-config.vh index 00b84f23f..a2488c060 100644 --- a/config/fpga/wally-config.vh +++ b/config/fpga/wally-config.vh @@ -139,8 +139,8 @@ `define PLIC_GPIO_ID 3 `define BPRED_SUPPORTED 1 -`define BPRED_TYPE "BP_GSHARE_FORWARD" // BPLOCALPAg or BPGLOBAL or BPTWOBIT or BPGSHARE or BPSPECULATIVEGLOBAL or BPSPECULATIVEGSHARE or BPOLDGSHARE or BPOLDGSHARE2 -`define BPRED_SIZE 10 +`define BPRED_TYPE "BP_GSHARE" // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT +`define BPRED_SIZE 12 `define BTB_SIZE 10 diff --git a/config/rv32e/wally-config.vh b/config/rv32e/wally-config.vh index bda7b4492..6e0de3347 100644 --- a/config/rv32e/wally-config.vh +++ b/config/rv32e/wally-config.vh @@ -134,7 +134,7 @@ `define PLIC_UART_ID 10 `define BPRED_SUPPORTED 0 -`define BPRED_TYPE "BP_GSHARE_FORWARD" // BPLOCALPAg or BPGLOBAL or BPTWOBIT or BPGSHARE +`define BPRED_TYPE "BP_GSHARE" // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT `define BPRED_SIZE 10 `define BTB_SIZE 10 diff --git a/config/rv32gc/wally-config.vh b/config/rv32gc/wally-config.vh index 88fc70ade..57857f3be 100644 --- a/config/rv32gc/wally-config.vh +++ b/config/rv32gc/wally-config.vh @@ -133,7 +133,7 @@ `define PLIC_UART_ID 10 `define BPRED_SUPPORTED 1 -`define BPRED_TYPE "BP_GSHARE_FORWARD" // BPLOCALPAg or BPGLOBAL or BPTWOBIT or BPGSHARE +`define BPRED_TYPE "BP_GSHARE" // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT `define BPRED_SIZE 10 `define BTB_SIZE 10 diff --git a/config/rv32i/wally-config.vh b/config/rv32i/wally-config.vh index 86bad6f91..efbf6e7c0 100644 --- a/config/rv32i/wally-config.vh +++ b/config/rv32i/wally-config.vh @@ -134,7 +134,7 @@ `define PLIC_UART_ID 10 `define BPRED_SUPPORTED 0 -`define BPRED_TYPE "BP_GSHARE_FORWARD" // BPLOCALPAg or BPGLOBAL or BPTWOBIT or BPGSHARE +`define BPRED_TYPE "BP_GSHARE" // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT `define BPRED_SIZE 10 `define BTB_SIZE 10 diff --git a/config/rv32imc/wally-config.vh b/config/rv32imc/wally-config.vh index eb9ce6528..8fb29a678 100644 --- a/config/rv32imc/wally-config.vh +++ b/config/rv32imc/wally-config.vh @@ -133,7 +133,7 @@ `define PLIC_UART_ID 10 `define BPRED_SUPPORTED 0 -`define BPRED_TYPE "BP_GSHARE_FORWARD" // BPLOCALPAg or BPGLOBAL or BPTWOBIT or BPGSHARE +`define BPRED_TYPE "BP_GSHARE" // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT `define BPRED_SIZE 10 `define BTB_SIZE 10 diff --git a/config/rv64fpquad/wally-config.vh b/config/rv64fpquad/wally-config.vh index ea36327d3..dd8058c28 100644 --- a/config/rv64fpquad/wally-config.vh +++ b/config/rv64fpquad/wally-config.vh @@ -136,7 +136,7 @@ `define PLIC_UART_ID 10 `define BPRED_SUPPORTED 1 -`define BPRED_TYPE "BP_GSHARE_FORWARD" // BPLOCALPAg or BPGLOBAL or BPTWOBIT or BPGSHARE +`define BPRED_TYPE "BP_GSHARE" // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT `define BPRED_SIZE 10 `define BTB_SIZE 10 diff --git a/config/rv64gc/wally-config.vh b/config/rv64gc/wally-config.vh index c323a9f0e..4100f4c08 100644 --- a/config/rv64gc/wally-config.vh +++ b/config/rv64gc/wally-config.vh @@ -136,7 +136,7 @@ `define PLIC_UART_ID 10 `define BPRED_SUPPORTED 1 -`define BPRED_TYPE "BP_GSHARE_FORWARD" // BPLOCALPAg or BPGLOBAL or BPTWOBIT or BPGSHARE or BPSPECULATIVEGLOBAL or BPSPECULATIVEGSHARE or BPOLDGSHARE or BPOLDGSHARE2 +`define BPRED_TYPE "BP_GSHARE" // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT `define BPRED_SIZE 10 `define BTB_SIZE 10 diff --git a/config/rv64i/wally-config.vh b/config/rv64i/wally-config.vh index 7cc8d887e..a3702c3fd 100644 --- a/config/rv64i/wally-config.vh +++ b/config/rv64i/wally-config.vh @@ -136,7 +136,7 @@ `define PLIC_UART_ID 10 `define BPRED_SUPPORTED 0 -`define BPRED_TYPE "BPGSHARE" // BPLOCALPAg or BPGLOBAL or BPTWOBIT or BPGSHARE +`define BPRED_TYPE "BP_GSHARE" // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT `define BPRED_SIZE 10 `define BTB_SIZE 10 diff --git a/sim/wave.do b/sim/wave.do index 6564e6549..23413957d 100644 --- a/sim/wave.do +++ b/sim/wave.do @@ -37,17 +37,17 @@ add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/ add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/core/StallE add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/core/StallM add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/core/StallW -add wave -noupdate -expand -group {instruction pipeline} /testbench/InstrFName -add wave -noupdate -expand -group {instruction pipeline} /testbench/dut/core/ifu/PostSpillInstrRawF -add wave -noupdate -expand -group {instruction pipeline} /testbench/dut/core/ifu/InstrD -add wave -noupdate -expand -group {instruction pipeline} /testbench/dut/core/ifu/InstrE -add wave -noupdate -expand -group {instruction pipeline} /testbench/dut/core/ifu/InstrM -add wave -noupdate -expand -group PCS /testbench/dut/core/ifu/PCNextF -add wave -noupdate -expand -group PCS /testbench/dut/core/ifu/PCF -add wave -noupdate -expand -group PCS /testbench/dut/core/ifu/PCD -add wave -noupdate -expand -group PCS /testbench/dut/core/PCE -add wave -noupdate -expand -group PCS /testbench/dut/core/PCM -add wave -noupdate -expand -group PCS /testbench/PCW +add wave -noupdate -group {instruction pipeline} /testbench/InstrFName +add wave -noupdate -group {instruction pipeline} /testbench/dut/core/ifu/PostSpillInstrRawF +add wave -noupdate -group {instruction pipeline} /testbench/dut/core/ifu/InstrD +add wave -noupdate -group {instruction pipeline} /testbench/dut/core/ifu/InstrE +add wave -noupdate -group {instruction pipeline} /testbench/dut/core/ifu/InstrM +add wave -noupdate -group PCS /testbench/dut/core/ifu/PCNextF +add wave -noupdate -group PCS /testbench/dut/core/ifu/PCF +add wave -noupdate -group PCS /testbench/dut/core/ifu/PCD +add wave -noupdate -group PCS /testbench/dut/core/PCE +add wave -noupdate -group PCS /testbench/dut/core/PCM +add wave -noupdate -group PCS /testbench/PCW add wave -noupdate -group {Decode Stage} /testbench/dut/core/ifu/PCD add wave -noupdate -group {Decode Stage} /testbench/dut/core/ifu/InstrD add wave -noupdate -group {Decode Stage} /testbench/InstrDName @@ -95,15 +95,15 @@ add wave -noupdate -group Bpred -group {bp wrong} /testbench/dut/core/ifu/bpred/ add wave -noupdate -group Bpred -group {bp wrong} /testbench/dut/core/ifu/bpred/bpred/InstrClassE add wave -noupdate -group Bpred -group {bp wrong} /testbench/dut/core/ifu/bpred/bpred/BPPredWrongE add wave -noupdate -group Bpred /testbench/dut/core/ifu/bpred/bpred/BPPredWrongE -add wave -noupdate -expand -group {PCNext Generation} /testbench/dut/core/ifu/PCNextF -add wave -noupdate -expand -group {PCNext Generation} /testbench/dut/core/ifu/bpred/bpred/NextValidPCE -add wave -noupdate -expand -group {PCNext Generation} /testbench/dut/core/ifu/PCF -add wave -noupdate -expand -group {PCNext Generation} /testbench/dut/core/ifu/PCPlus2or4F -add wave -noupdate -expand -group {PCNext Generation} /testbench/dut/core/ifu/bpred/bpred/BPPredPCF -add wave -noupdate -expand -group {PCNext Generation} /testbench/dut/core/ifu/bpred/bpred/SelBPPredF -add wave -noupdate -expand -group {PCNext Generation} /testbench/dut/core/ifu/bpred/bpred/PCNext0F -add wave -noupdate -expand -group {PCNext Generation} /testbench/dut/core/ifu/PCNext1F -add wave -noupdate -expand -group {PCNext Generation} /testbench/dut/core/ifu/BPPredWrongE +add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/PCNextF +add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/bpred/bpred/NextValidPCE +add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/PCF +add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/PCPlus2or4F +add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/bpred/bpred/BPPredPCF +add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/bpred/bpred/SelBPPredF +add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/bpred/bpred/PCNext0F +add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/PCNext1F +add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/BPPredWrongE add wave -noupdate -group RegFile -expand /testbench/dut/core/ieu/dp/regf/rf add wave -noupdate -group RegFile /testbench/dut/core/ieu/dp/regf/a1 add wave -noupdate -group RegFile /testbench/dut/core/ieu/dp/regf/a2 @@ -556,21 +556,21 @@ add wave -noupdate -group ifu -group itlb -expand -group key19 {/testbench/dut/c add wave -noupdate -group ifu -group itlb -expand -group key19 {/testbench/dut/core/ifu/immu/immu/tlb/tlb/tlbcam/camlines[19]/Key1} add wave -noupdate -group ifu -group itlb -expand -group key19 {/testbench/dut/core/ifu/immu/immu/tlb/tlb/tlbcam/camlines[19]/Query0} add wave -noupdate -group ifu -group itlb -expand -group key19 {/testbench/dut/core/ifu/immu/immu/tlb/tlb/tlbcam/camlines[19]/Query1} -add wave -noupdate -group {Performance Counters} -label MCYCLE -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[0]} -add wave -noupdate -group {Performance Counters} -label MINSTRET -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[2]} -add wave -noupdate -group {Performance Counters} -label {LOAD STORE HAZARD} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[3]} -add wave -noupdate -group {Performance Counters} -expand -group BRP -label {BP DIRECTION WRONG} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[4]} -add wave -noupdate -group {Performance Counters} -expand -group BRP -label {BP INSTRUCTION} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[5]} -add wave -noupdate -group {Performance Counters} -expand -group BRP -label {BTA/JTA WRONG} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[6]} -add wave -noupdate -group {Performance Counters} -expand -group BRP -label {JAL(R) INSTRUCTION} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[7]} -add wave -noupdate -group {Performance Counters} -expand -group BRP -label {RAS WRONG} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[8]} -add wave -noupdate -group {Performance Counters} -expand -group BRP -label {RETURN INSTRUCTION} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[9]} -add wave -noupdate -group {Performance Counters} -expand -group BRP -label {BP CLASS WRONG} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[10]} -add wave -noupdate -group {Performance Counters} -expand -group BRP -label {Branch Predictor Wrong} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[15]} -add wave -noupdate -group {Performance Counters} -expand -group ICACHE -label {ICACHE ACCESS} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[13]} -add wave -noupdate -group {Performance Counters} -expand -group ICACHE -label {ICACHE MISS} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[14]} -add wave -noupdate -group {Performance Counters} -expand -group DCACHE -label {DCACHE ACCESS} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[11]} -add wave -noupdate -group {Performance Counters} -expand -group DCACHE -label {DCACHE MISS} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[12]} +add wave -noupdate -expand -group {Performance Counters} -label MCYCLE -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[0]} +add wave -noupdate -expand -group {Performance Counters} -label MINSTRET -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[2]} +add wave -noupdate -expand -group {Performance Counters} -label {LOAD STORE HAZARD} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[3]} +add wave -noupdate -expand -group {Performance Counters} -expand -group BRP -label {BP DIRECTION WRONG} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[4]} +add wave -noupdate -expand -group {Performance Counters} -expand -group BRP -label {BP INSTRUCTION} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[5]} +add wave -noupdate -expand -group {Performance Counters} -expand -group BRP -label {BTA/JTA WRONG} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[6]} +add wave -noupdate -expand -group {Performance Counters} -expand -group BRP -label {JAL(R) INSTRUCTION} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[7]} +add wave -noupdate -expand -group {Performance Counters} -expand -group BRP -label {RAS WRONG} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[8]} +add wave -noupdate -expand -group {Performance Counters} -expand -group BRP -label {RETURN INSTRUCTION} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[9]} +add wave -noupdate -expand -group {Performance Counters} -expand -group BRP -label {BP CLASS WRONG} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[10]} +add wave -noupdate -expand -group {Performance Counters} -expand -group BRP -label {Branch Predictor Wrong} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[15]} +add wave -noupdate -expand -group {Performance Counters} -expand -group ICACHE -label {ICACHE ACCESS} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[13]} +add wave -noupdate -expand -group {Performance Counters} -expand -group ICACHE -label {ICACHE MISS} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[14]} +add wave -noupdate -expand -group {Performance Counters} -expand -group DCACHE -label {DCACHE ACCESS} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[11]} +add wave -noupdate -expand -group {Performance Counters} -expand -group DCACHE -label {DCACHE MISS} -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[12]} add wave -noupdate -group {ifu } -color Gold /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm/CurrState add wave -noupdate -group {ifu } /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm/HREADY add wave -noupdate -group {ifu } /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/FetchBuffer @@ -602,23 +602,23 @@ add wave -noupdate -group uncore /testbench/dut/uncore/uncore/HSELNoneD add wave -noupdate -group uncore /testbench/dut/uncore/uncore/HSELPLICD add wave -noupdate -group uncore /testbench/dut/uncore/uncore/HRDATA add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/rd -add wave -noupdate -expand -group {branch direction} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/IndexNextF -add wave -noupdate -expand -group {branch direction} -expand -group {branch outcome} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/PCSrcE -add wave -noupdate -expand -group {branch direction} -expand -group {branch outcome} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/DirPredictionE -add wave -noupdate -expand -group {branch direction} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/TableDirPredictionF -add wave -noupdate -expand -group {branch direction} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/MatchXF -add wave -noupdate -expand -group {branch direction} -expand -group conditions /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/DirPredictionWrongE -add wave -noupdate -expand -group {branch direction} -expand -group conditions /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/FlushM -add wave -noupdate -expand -group {branch direction} -expand -group conditions /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/FlushE -add wave -noupdate -expand -group {branch direction} -expand -group ghr /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/GHRF -add wave -noupdate -expand -group {branch direction} -expand -group ghr /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/GHRD -add wave -noupdate -expand -group {branch direction} -expand -group ghr /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/GHRE -add wave -noupdate -expand -group {branch direction} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/FlushD -add wave -noupdate -expand -group {branch direction} -expand -group nextghr2 /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/GHRNextF -add wave -noupdate -expand -group {branch direction} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/NewDirPredictionE -add wave -noupdate -expand -group {branch direction} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/IndexE -add wave -noupdate -expand -group {branch direction} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/StallM -add wave -noupdate -expand -group {branch direction} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/FlushM +add wave -noupdate -group {branch direction} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/IndexNextF +add wave -noupdate -group {branch direction} -expand -group {branch outcome} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/PCSrcE +add wave -noupdate -group {branch direction} -expand -group {branch outcome} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/DirPredictionE +add wave -noupdate -group {branch direction} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/TableDirPredictionF +add wave -noupdate -group {branch direction} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/MatchXF +add wave -noupdate -group {branch direction} -expand -group conditions /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/DirPredictionWrongE +add wave -noupdate -group {branch direction} -expand -group conditions /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/FlushM +add wave -noupdate -group {branch direction} -expand -group conditions /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/FlushE +add wave -noupdate -group {branch direction} -expand -group ghr /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/GHRF +add wave -noupdate -group {branch direction} -expand -group ghr /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/GHRD +add wave -noupdate -group {branch direction} -expand -group ghr /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/GHRE +add wave -noupdate -group {branch direction} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/FlushD +add wave -noupdate -group {branch direction} -expand -group nextghr2 /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/GHRNextF +add wave -noupdate -group {branch direction} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/NewDirPredictionE +add wave -noupdate -group {branch direction} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/IndexE +add wave -noupdate -group {branch direction} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/StallM +add wave -noupdate -group {branch direction} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/FlushM add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/GHR add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/GHRF add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/PCNextF @@ -627,9 +627,16 @@ add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/In add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/DirPredictionF add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/BranchInstrF add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/MatchNextX +add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/PredInstrClassF +add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/PredValidF +add wave -noupdate /testbench/dut/core/priv/priv/csr/counters/counters/DCacheAccess +add wave -noupdate /testbench/dut/core/priv/priv/csr/counters/counters/ICacheMiss +add wave -noupdate /testbench/dut/core/priv/priv/csr/counters/counters/ICacheAccess +add wave -noupdate /testbench/dut/core/priv/priv/csr/counters/counters/DCacheMiss +add wave -noupdate /testbench/dut/core/priv/priv/csr/counters/counters/InstrValidNotFlushedM TreeUpdate [SetDefaultTree] -WaveRestoreCursors {{Cursor 2} {314596 ns} 1} {{Cursor 3} {314460 ns} 1} {{Cursor 4} {391801 ns} 1} {{Cursor 4} {1156601 ns} 1} {{Cursor 5} {394986 ns} 0} -quietly wave cursor active 5 +WaveRestoreCursors {{Cursor 2} {314596 ns} 1} {{Cursor 3} {314460 ns} 1} {{Cursor 4} {391801 ns} 1} {{Cursor 4} {368581 ns} 0} {{Cursor 5} {394987 ns} 1} +quietly wave cursor active 4 configure wave -namecolwidth 250 configure wave -valuecolwidth 194 configure wave -justifyvalue left @@ -644,4 +651,4 @@ configure wave -griddelta 40 configure wave -timeline 0 configure wave -timelineunits ns update -WaveRestoreZoom {394883 ns} {395051 ns} +WaveRestoreZoom {368125 ns} {368797 ns} diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index b0ea2683b..da4070e14 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -94,36 +94,32 @@ module bpred ( // Part 1 branch direction prediction // look into the 2 port Sram model. something is wrong. - if (`BPRED_TYPE == "BPTWOBIT") begin:Predictor + if (`BPRED_TYPE == "BP_TWOBIT") begin:Predictor twoBitPredictor #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM, .PCNextF, .PCM, .DirPredictionF, .DirPredictionWrongE, .BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE); - end else if (`BPRED_TYPE == "BPGLOBAL") begin:Predictor - globalhistory #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, - .DirPredictionF, .DirPredictionWrongE, - .BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE); - - end else if (`BPRED_TYPE == "BPSPECULATIVEGLOBAL") begin:Predictor - speculativeglobalhistory #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, - .DirPredictionF, .DirPredictionWrongE, - .PredInstrClassF, .InstrClassD, .InstrClassE, .InstrClassM, .WrongPredInstrClassD, .PCSrcE); - - end else if (`BPRED_TYPE == "BPGSHARE") begin:Predictor + 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, .PCM, .DirPredictionF, .DirPredictionWrongE, - .BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE); - - end else if (`BPRED_TYPE == "BPSPECULATIVEGSHARE") begin:Predictor - speculativegshare #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, - .PCNextF, .PCF, .PCD, .PCE, .DirPredictionF, .DirPredictionWrongE, - .PredInstrClassF, .InstrClassD, .InstrClassE, .InstrClassM, .WrongPredInstrClassD, .PCSrcE); - - end else if (`BPRED_TYPE == "BP_GSHARE_FORWARD") begin:Predictor - gshareForward #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCF, .PCD, .PCE, .PCM, .DirPredictionF, .DirPredictionWrongE, .BranchInstrF(PredInstrClassF[0]), .BranchInstrD(InstrClassD[0]), .BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE); + + end else if (`BPRED_TYPE == "BP_GLOBAL") begin:Predictor + gshare #(`BPRED_SIZE, "global") DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, + .PCNextF, .PCF, .PCD, .PCE, .PCM, .DirPredictionF, .DirPredictionWrongE, + .BranchInstrF(PredInstrClassF[0]), .BranchInstrD(InstrClassD[0]), .BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), + .PCSrcE); + + end else if (`BPRED_TYPE == "BP_GSHARE_BASIC") begin:Predictor + gsharebasic #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, + .PCNextF, .PCM, .DirPredictionF, .DirPredictionWrongE, + .BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE); + + end else if (`BPRED_TYPE == "BP_GLOBAL_BASIC") begin:Predictor + gsharebasic #(`BPRED_SIZE, "global") DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, + .PCNextF, .PCM, .DirPredictionF, .DirPredictionWrongE, + .BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE); end else if (`BPRED_TYPE == "BPLOCALPAg") begin:Predictor // *** Fix me diff --git a/src/ifu/bpred/gshare.sv b/src/ifu/bpred/gshare.sv index 35a73fb04..bb9d25f49 100644 --- a/src/ifu/bpred/gshare.sv +++ b/src/ifu/bpred/gshare.sv @@ -28,7 +28,8 @@ `include "wally-config.vh" -module gshare #(parameter k = 10) ( +module gshare #(parameter k = 10, + parameter string TYPE = "gshare") ( input logic clk, input logic reset, input logic StallF, StallD, StallE, StallM, StallW, @@ -36,28 +37,60 @@ module gshare #(parameter k = 10) ( output logic [1:0] DirPredictionF, output logic DirPredictionWrongE, // update - input logic [`XLEN-1:0] PCNextF, PCM, - input logic BranchInstrE, BranchInstrM, PCSrcE + input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, + input logic BranchInstrF, BranchInstrD, BranchInstrE, BranchInstrM, PCSrcE ); - logic [k-1:0] IndexNextF, IndexE; - logic [1:0] DirPredictionD, DirPredictionE; + logic MatchF, MatchD, MatchE, MatchM; + logic MatchNextX, MatchXF; + + logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE, ForwardNewDirPrediction, ForwardDirPredictionF; logic [1:0] NewDirPredictionE, NewDirPredictionM; - logic [k-1:0] GHRF, GHRD, GHRE, GHRM, GHR; - logic [k-1:0] GHRNext; + logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE, IndexM; + + logic [k-1:0] GHRF, GHRD, GHRE, GHRM; + logic [k-1:0] GHRNextM, GHRNextF; logic PCSrcM; - assign IndexNextF = GHR ^ {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]}; - assign IndexE = GHRM ^ {PCM[k+1] ^ PCM[1], PCM[k:2]}; + if(TYPE == "gshare") begin + 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 ^ {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]}; + end else if(TYPE == "global") begin + assign IndexNextF = {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]}; + assign IndexF = {PCF[k+1] ^ PCF[1], PCF[k:2]}; + assign IndexD = {PCD[k+1] ^ PCD[1], PCD[k:2]}; + assign IndexE = {PCE[k+1] ^ PCE[1], PCE[k:2]}; + assign IndexM = {PCM[k+1] ^ PCM[1], PCM[k:2]}; + end + + assign MatchF = BranchInstrF & ~FlushD & (IndexNextF == IndexF); + assign MatchD = BranchInstrD & ~FlushE & (IndexNextF == IndexD); + assign MatchE = BranchInstrE & ~FlushM & (IndexNextF == IndexE); + assign MatchM = BranchInstrM & ~FlushW & (IndexNextF == IndexM); + assign MatchNextX = MatchF | MatchD | MatchE | MatchM; + + flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF); + + assign ForwardNewDirPrediction = MatchF ? {2{DirPredictionF[1]}} : + MatchD ? {2{DirPredictionD[1]}} : + MatchE ? {NewDirPredictionE} : + NewDirPredictionM ; + flopenr #(2) ForwardDirPredicitonReg(clk, reset, ~StallF, ForwardNewDirPrediction, ForwardDirPredictionF); + + assign DirPredictionF = MatchXF ? ForwardDirPredictionF : TableDirPredictionF; + ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), .ce1(~StallF), .ce2(~StallM & ~FlushM), .ra1(IndexNextF), - .rd1(DirPredictionF), - .wa2(IndexE), + .rd1(TableDirPredictionF), + .wa2(IndexM), .wd2(NewDirPredictionM), - .we2(BranchInstrM & ~StallW & ~FlushW), + .we2(BranchInstrM), .bwe2(1'b1)); flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD); @@ -68,14 +101,14 @@ module gshare #(parameter k = 10) ( assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchInstrE; - assign GHRNext = BranchInstrM ? {PCSrcM, GHR[k-1:1]} : GHR; - flopenr #(k) GHRReg(clk, reset, ~StallM & ~FlushM & BranchInstrM, GHRNext, GHR); + assign GHRNextF = BranchInstrF ? {DirPredictionF[1], GHRF[k-1:1]} : GHRF; + assign GHRF = BranchInstrD ? {DirPredictionD[1], GHRD[k-1:1]} : GHRD; + assign GHRD = BranchInstrE ? {PCSrcE, GHRE[k-1:1]} : GHRE; + assign GHRE = BranchInstrM ? {PCSrcM, GHRM[k-1:1]} : GHRM; + + assign GHRNextM = {PCSrcM, GHRM[k-1:1]}; + + flopenr #(k) GHRReg(clk, reset, ~StallW & ~FlushW & BranchInstrM, GHRNextM, GHRM); flopenrc #(1) PCSrcMReg(clk, reset, FlushM, ~StallM, PCSrcE, PCSrcM); - flopenrc #(k) GHRFReg(clk, reset, FlushD, ~StallF, GHR, GHRF); - flopenrc #(k) GHRDReg(clk, reset, FlushD, ~StallD, GHRF, GHRD); - flopenrc #(k) GHREReg(clk, reset, FlushE, ~StallE, GHRD, GHRE); - flopenrc #(k) GHRMReg(clk, reset, FlushM, ~StallM, GHRE, GHRM); - - endmodule diff --git a/src/ifu/bpred/gshareForward.sv b/src/ifu/bpred/gsharebasic.sv similarity index 53% rename from src/ifu/bpred/gshareForward.sv rename to src/ifu/bpred/gsharebasic.sv index 57bcd4bee..45438b856 100644 --- a/src/ifu/bpred/gshareForward.sv +++ b/src/ifu/bpred/gsharebasic.sv @@ -28,7 +28,8 @@ `include "wally-config.vh" -module gshareForward #(parameter k = 10) ( +module gsharebasic #(parameter k = 10, + parameter string TYPE = "global") ( input logic clk, input logic reset, input logic StallF, StallD, StallE, StallM, StallW, @@ -36,54 +37,33 @@ module gshareForward #(parameter k = 10) ( output logic [1:0] DirPredictionF, output logic DirPredictionWrongE, // update - input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, - input logic BranchInstrF, BranchInstrD, BranchInstrE, BranchInstrM, PCSrcE + input logic [`XLEN-1:0] PCNextF, PCM, + input logic BranchInstrE, BranchInstrM, PCSrcE ); - logic MatchF, MatchD, MatchE, MatchM; - logic MatchNextX, MatchXF; - - logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE, ForwardNewDirPrediction, ForwardDirPredictionF; + logic [k-1:0] IndexNextF, IndexE; + logic [1:0] DirPredictionD, DirPredictionE; logic [1:0] NewDirPredictionE, NewDirPredictionM; - - logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE, IndexM; - logic [k-1:0] GHRF, GHRD, GHRE, GHRM, GHR; - logic [k-1:0] GHRNext, GHRNextF; + logic [k-1:0] GHRNext; logic PCSrcM; - 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 ^ {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 MatchF = BranchInstrF & ~FlushD & (IndexNextF == IndexF); - assign MatchD = BranchInstrD & ~FlushE & (IndexNextF == IndexD); - assign MatchE = BranchInstrE & ~FlushM & (IndexNextF == IndexE); - assign MatchM = BranchInstrM & ~FlushW & (IndexNextF == IndexM); - assign MatchNextX = MatchF | MatchD | MatchE | MatchM; - - flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF); - - assign ForwardNewDirPrediction = MatchF ? {2{DirPredictionF[1]}} : - MatchD ? {2{DirPredictionD[1]}} : - MatchE ? {NewDirPredictionE} : - NewDirPredictionM ; + if(TYPE == "gshare") begin + assign IndexNextF = GHR ^ {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]}; + assign IndexE = GHRM ^ {PCM[k+1] ^ PCM[1], PCM[k:2]}; + end else if(TYPE == "global") begin + assign IndexNextF = {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]}; + assign IndexE = {PCM[k+1] ^ PCM[1], PCM[k:2]}; + end - flopenr #(2) ForwardDirPredicitonReg(clk, reset, ~StallF, ForwardNewDirPrediction, ForwardDirPredictionF); - - assign DirPredictionF = MatchXF ? ForwardDirPredictionF : TableDirPredictionF; - ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), .ce1(~StallF), .ce2(~StallM & ~FlushM), .ra1(IndexNextF), - .rd1(TableDirPredictionF), - .wa2(IndexM), + .rd1(DirPredictionF), + .wa2(IndexE), .wd2(NewDirPredictionM), - .we2(BranchInstrM), + .we2(BranchInstrM & ~StallW & ~FlushW), .bwe2(1'b1)); flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD); @@ -94,15 +74,14 @@ module gshareForward #(parameter k = 10) ( assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchInstrE; - assign GHRNextF = BranchInstrF ? {DirPredictionF[1], GHRF[k-1:1]} : GHRF; - assign GHRF = BranchInstrD ? {DirPredictionD[1], GHRD[k-1:1]} : GHRD; - assign GHRD = BranchInstrE ? {PCSrcE, GHRE[k-1:1]} : GHRE; - assign GHRE = BranchInstrM ? {PCSrcM, GHRM[k-1:1]} : GHRM; - assign GHRNext = BranchInstrM ? {PCSrcM, GHR[k-1:1]} : GHR; - assign GHRM = GHR; - - flopenr #(k) GHRReg(clk, reset, ~StallW & ~FlushW & BranchInstrM, GHRNext, GHR); + flopenr #(k) GHRReg(clk, reset, ~StallM & ~FlushM & BranchInstrM, GHRNext, GHR); flopenrc #(1) PCSrcMReg(clk, reset, FlushM, ~StallM, PCSrcE, PCSrcM); + flopenrc #(k) GHRFReg(clk, reset, FlushD, ~StallF, GHR, GHRF); + flopenrc #(k) GHRDReg(clk, reset, FlushD, ~StallD, GHRF, GHRD); + flopenrc #(k) GHREReg(clk, reset, FlushE, ~StallE, GHRD, GHRE); + flopenrc #(k) GHRMReg(clk, reset, FlushM, ~StallM, GHRE, GHRM); + + endmodule From d2e06d9ef0aef9b52a11a4ff4751114761c68ddc Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 20 Feb 2023 18:45:45 -0600 Subject: [PATCH 6/7] Cleanup branch predictor files. --- src/ifu/bpred/foldedgshare.sv | 146 --------------- src/ifu/bpred/globalhistory.sv | 80 -------- src/ifu/bpred/gshare.sv | 13 +- src/ifu/bpred/gsharebasic.sv | 11 +- src/ifu/bpred/optgshare.sv | 219 ---------------------- src/ifu/bpred/speculativeglobalhistory.sv | 136 -------------- src/ifu/bpred/speculativegshare.sv | 137 -------------- 7 files changed, 13 insertions(+), 729 deletions(-) delete mode 100644 src/ifu/bpred/foldedgshare.sv delete mode 100644 src/ifu/bpred/globalhistory.sv delete mode 100644 src/ifu/bpred/optgshare.sv delete mode 100644 src/ifu/bpred/speculativeglobalhistory.sv delete mode 100644 src/ifu/bpred/speculativegshare.sv diff --git a/src/ifu/bpred/foldedgshare.sv b/src/ifu/bpred/foldedgshare.sv deleted file mode 100644 index 85b7db383..000000000 --- a/src/ifu/bpred/foldedgshare.sv +++ /dev/null @@ -1,146 +0,0 @@ -/////////////////////////////////////////// -// gsharePredictor.sv -// -// Written: Shreya Sanghai -// Email: ssanghai@hmc.edu -// Created: March 16, 2021 -// Modified: -// -// Purpose: Global History Branch predictor with parameterized global history register -// -// 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" - -module foldedgshare #(parameter k = 16, depth = 10) ( - input logic clk, - input logic reset, - input logic StallF, StallD, StallE, StallM, StallW, - input logic FlushD, FlushE, FlushM, FlushW, -// input logic [`XLEN-1:0] LookUpPC, - output logic [1:0] DirPredictionF, - output logic DirPredictionWrongE, - // update - input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, - input logic BranchInstrF, BranchInstrD, BranchInstrE, BranchInstrM, BranchInstrW, - input logic PCSrcE -); - - logic MatchF, MatchD, MatchE, MatchM, MatchW; - logic MatchNextX, MatchXF; - - 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 [depth-1:0] FinalIndexNextF, FinalIndexW; - - logic PCSrcM, PCSrcW; - logic [`XLEN-1:0] PCW; - - logic [1:0] ForwardNewDirPrediction, ForwardDirPredictionF; - localparam delta = 2 * depth - k; - - 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]}; - - // just be dumb for now. - //localparam int kToDepthRatio = (k+depth) / depth; - assign FinalIndexNextF = IndexNextF[depth-1:0] ^ {{delta{1'b0}} , IndexNextF[k-1:depth]}; - assign FinalIndexW = IndexW[depth-1:0] ^ {{delta{1'b0}} , IndexW[k-1:depth]}; - - ram2p1r1wbe #(2**depth, 2) PHT(.clk(clk), - .ce1(~StallF | reset), .ce2(~StallW & ~FlushW), - .ra1(FinalIndexNextF), - .rd1(TableDirPredictionF), - .wa2(FinalIndexW), - .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 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); - flopenr #(2) PredictionRegE(clk, reset, ~StallE, DirPredictionD, DirPredictionE); - - // New prediction pipeline - satCounter2 BPDirUpdateF(.BrDir(DirPredictionF[1]), .OldState(DirPredictionF), .NewState(NewDirPredictionF)); - flopenr #(2) NewPredDReg(clk, reset, ~StallD, NewDirPredictionF, NewDirPredictionD); - 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 ? 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; - - flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); - -endmodule diff --git a/src/ifu/bpred/globalhistory.sv b/src/ifu/bpred/globalhistory.sv deleted file mode 100644 index a88804773..000000000 --- a/src/ifu/bpred/globalhistory.sv +++ /dev/null @@ -1,80 +0,0 @@ -/////////////////////////////////////////// -// globalHistoryPredictor.sv -// -// Written: Shreya Sanghai -// Email: ssanghai@hmc.edu -// Created: March 16, 2021 -// Modified: -// -// Purpose: Global History Branch predictor with parameterized global history register -// -// 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" - -module globalhistory #(parameter k = 10) ( - input logic clk, - input logic reset, - input logic StallF, StallD, StallE, StallM, StallW, - input logic FlushD, FlushE, FlushM, FlushW, - output logic [1:0] DirPredictionF, - output logic DirPredictionWrongE, - // update - input logic BranchInstrE, BranchInstrM, PCSrcE -); - - logic [k-1:0] IndexNextF, IndexE; - logic [1:0] DirPredictionD, DirPredictionE; - logic [1:0] NewDirPredictionE, NewDirPredictionM; - - logic [k-1:0] GHRF, GHRD, GHRE, GHRM, GHR; - logic [k-1:0] GHRNext; - logic PCSrcM; - - assign IndexNextF = GHR; - assign IndexE = GHRM; - - ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), - .ce1(~StallF), .ce2(~StallM & ~FlushM), - .ra1(IndexNextF), - .rd1(DirPredictionF), - .wa2(IndexE), - .wd2(NewDirPredictionM), - .we2(BranchInstrM & ~StallW & ~FlushW), - .bwe2(1'b1)); - - flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD); - flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, DirPredictionD, DirPredictionE); - - satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE)); - flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewDirPredictionE, NewDirPredictionM); - - assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchInstrE; - - assign GHRNext = BranchInstrM ? {PCSrcM, GHR[k-1:1]} : GHR; - flopenr #(k) GHRReg(clk, reset, ~StallM & ~FlushM & BranchInstrM, GHRNext, GHR); - flopenrc #(1) PCSrcMReg(clk, reset, FlushM, ~StallM, PCSrcE, PCSrcM); - - flopenrc #(k) GHRFReg(clk, reset, FlushD, ~StallF, GHR, GHRF); - flopenrc #(k) GHRDReg(clk, reset, FlushD, ~StallD, GHRF, GHRD); - flopenrc #(k) GHREReg(clk, reset, FlushE, ~StallE, GHRD, GHRE); - flopenrc #(k) GHRMReg(clk, reset, FlushM, ~StallM, GHRE, GHRM); - - -endmodule diff --git a/src/ifu/bpred/gshare.sv b/src/ifu/bpred/gshare.sv index bb9d25f49..c13bce943 100644 --- a/src/ifu/bpred/gshare.sv +++ b/src/ifu/bpred/gshare.sv @@ -1,12 +1,13 @@ /////////////////////////////////////////// -// globalHistoryPredictor.sv +// gshare.sv // -// Written: Shreya Sanghai -// Email: ssanghai@hmc.edu -// Created: March 16, 2021 -// Modified: +// Written: Ross Thompson +// Email: ross1728@gmail.com +// Created: 16 March 2021 +// Adapted from ssanghai@hmc.edu (Shreya Sanghai) +// Modified: 20 February 2023 // -// Purpose: Global History Branch predictor with parameterized global history register +// Purpose: gshare and Global History Branch predictors // // A component of the CORE-V-WALLY configurable RISC-V project. // diff --git a/src/ifu/bpred/gsharebasic.sv b/src/ifu/bpred/gsharebasic.sv index 45438b856..d73797275 100644 --- a/src/ifu/bpred/gsharebasic.sv +++ b/src/ifu/bpred/gsharebasic.sv @@ -1,10 +1,11 @@ /////////////////////////////////////////// -// globalHistoryPredictor.sv +// gsharebasic.sv // -// Written: Shreya Sanghai -// Email: ssanghai@hmc.edu -// Created: March 16, 2021 -// Modified: +// Written: Ross Thompson +// Email: ross1728@gmail.com +// Created: 16 March 2021 +// Adapted from ssanghai@hmc.edu (Shreya Sanghai) global history predictor implementation. +// Modified: 20 February 2023 // // Purpose: Global History Branch predictor with parameterized global history register // diff --git a/src/ifu/bpred/optgshare.sv b/src/ifu/bpred/optgshare.sv deleted file mode 100644 index 78c98c5e6..000000000 --- a/src/ifu/bpred/optgshare.sv +++ /dev/null @@ -1,219 +0,0 @@ -/////////////////////////////////////////// -// gsharePredictor.sv -// -// Written: Shreya Sanghai -// Email: ssanghai@hmc.edu -// Created: March 16, 2021 -// Modified: -// -// Purpose: Global History Branch predictor with parameterized global history register -// -// A component of the Wally configurable RISC-V project. -// -// Copyright (C) 2021 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" - -module optgshare #(parameter k = 10) ( - input logic clk, - input logic reset, - input logic StallF, StallD, StallE, StallM, StallW, - input logic FlushD, FlushE, FlushM, FlushW, -// input logic [`XLEN-1:0] LookUpPC, - output logic [1:0] DirPredictionF, - output logic DirPredictionWrongE, - // update - input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, - input logic BranchInstrF, BranchInstrD, BranchInstrE, BranchInstrM, BranchInstrW, - input logic PCSrcE -); - - logic MatchF, MatchD, MatchE, MatchM, MatchW; - logic MatchNextX, MatchXF; - - 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 [1:0] ForwardNewDirPrediction, ForwardDirPredictionF; - - logic [k+4:0] GHRNext, GHR; - logic GHRUpdateEn; - - assign GHRUpdateEn = BranchInstrF | (DirPredictionWrongE & BranchInstrE) | - FlushD | FlushE | FlushM | FlushW; - - // it doesn't work this way. Instead we need to see how many branch instructions are flushed. - // then shift over by that amount. - logic RemoveBrW, RemoveBrM, RemoveBrE, RemoveBrD, RemoveBrF, RemoveBrNextF; - - assign RemoveBrW = '0; - assign RemoveBrM = BranchInstrM & FlushW; - assign RemoveBrE = BranchInstrE & FlushM; - assign RemoveBrD = BranchInstrD & FlushE; - assign RemoveBrF = BranchInstrF & FlushD; - assign RemoveBrNextF = BranchInstrF & FlushD; - - always_comb begin - casez ({BranchInstrF, DirPredictionWrongE, RemoveBrF, RemoveBrD, RemoveBrE, RemoveBrM}) - 6'b00_0000: GHRNext = GHR; // no change - 6'b00_0001: GHRNext = {GHR[k+4:k+1], GHR[k-1:0], 1'b0}; // RemoveBrM - 6'b0?_0010: GHRNext = {GHR[k+4:k+2], GHR[k:0], 1'b0}; // RemoveBrE - 6'b0?_0011: GHRNext = {GHR[k+4:k+2], GHR[k-1:0], 2'b0}; // RemoveBrE, RemoveBrM - - 6'b00_0100: GHRNext = {GHR[k+4:k+2], GHR[k-1:0], 2'b0}; // RemoveBrD - 6'b00_0101: GHRNext = {GHR[k+4:k+3], GHR[k+1:0], 1'b0}; // RemoveBrD, RemoveBrM - 6'b0?_0110: GHRNext = {GHR[k+4:k+3], GHR[k+1], GHR[k-1:0], 2'b0}; // RemoveBrD, RemoveBrE - 6'b0?_0111: GHRNext = {GHR[k+4:k+3], GHR[k-1:0], 3'b0}; // RemoveBrD, RemoveBrE, RemoveBrM - - 6'b?0_1000: GHRNext = {GHR[k+2:0], 2'b0}; // RemoveBrF, - 6'b?0_1001: GHRNext = {GHR[k+2:k+1], GHR[k-1:0], 3'b0}; // RemoveBrF, RemoveBrM - 6'b??_1010: GHRNext = {GHR[k+2], GHR[k:0], 3'b0}; // RemoveBrF, RemoveBrE - 6'b??_1011: GHRNext = {GHR[k+2], GHR[k-1:0], 4'b0}; // RemoveBrF, RemoveBrE, RemoveBrM - - 6'b?0_1100: GHRNext = {GHR[k+1:0], 3'b0}; // RemoveBrF, RemoveBrD - 6'b?0_1101: GHRNext = {GHR[k+1], GHR[k-1:0], 4'b0}; // RemoveBrF, RemoveBrD, RemoveBrM - 6'b??_1110: GHRNext = {GHR[k:0], 4'b0}; // RemoveBrF, RemoveBrD, RemoveBrE - 6'b??_1111: GHRNext = {GHR[k-1:0], 5'b0}; // RemoveBrF, RemoveBrD, RemoveBrE, RemoveBrM - - 6'b?1_0000: GHRNext = {PCSrcE, GHR[k+3:0]}; // Miss prediction, no branches to flushes - 6'b?1_0001: GHRNext = {PCSrcE, GHR[k+3:k], GHR[k-1:1], 1'b0}; // Miss prediction, branch in Memory stage dropped - - 6'b?1_1100: GHRNext = {PCSrcE, GHR[k+1:0], 2'b00}; // Miss prediction, cannot have RemoveBrE - 6'b?1_1101: GHRNext = {PCSrcE, GHR[k+1], GHR[k-1:0], 3'b0}; // Miss prediction, cannot have RemoveBrE - 6'b10_0000: GHRNext = {DirPredictionF[1], GHR[k+4:1]}; - 6'b10_0001: GHRNext = {DirPredictionF[1], GHR[k+4:k+1], GHR[k-1:1], 1'b0}; - 6'b10_0010: GHRNext = {DirPredictionF[1], GHR[k+4:k+2], GHR[k:1], 1'b0}; - 6'b10_0011: GHRNext = {DirPredictionF[1], GHR[k+4:k+2], GHR[k-1:1], 2'b0}; - 6'b10_0100: GHRNext = {DirPredictionF[1], GHR[k+4:k+3], GHR[k+1:1], 1'b0}; - 6'b10_0101: GHRNext = {DirPredictionF[1], GHR[k+4:k+3], GHR[k+1], GHR[k-1:1], 2'b0}; - 6'b10_0110: GHRNext = {DirPredictionF[1], GHR[k+4:k+3], GHR[k], GHR[k-1:1], 2'b0}; - 6'b10_0111: GHRNext = {DirPredictionF[1], GHR[k+4:k+3], GHR[k-1:1], 3'b0}; - - default: GHRNext = GHR; - endcase - end - - flopenr #(k+5) GHRReg(clk, reset, GHRUpdateEn, GHRNext, GHR); - logic [k-1:0] GHRNextF_temp, GHRF_temp; - logic [k:0] GHRD_temp, GHRE_temp, GHRM_temp, GHRW_temp; - logic GHRFExtra_temp; - - // these are also in the ieu controller. should create inputs. - logic InstrValidF, InstrValidD, InstrValidE, InstrValidM, InstrValidW; - flopenrc #(1) InstrValidFReg(clk, reset, FlushD, ~StallF, 1'b1, InstrValidF); - flopenrc #(1) InstrValidDReg(clk, reset, FlushD, ~StallD, InstrValidF, InstrValidD); - flopenrc #(1) InstrValidEReg(clk, reset, FlushE, ~StallE, InstrValidD, InstrValidE); - flopenrc #(1) InstrValidMReg(clk, reset, FlushM, ~StallM, InstrValidE, InstrValidM); - flopenrc #(1) InstrValidWReg(clk, reset, FlushW, ~StallW, InstrValidM, InstrValidW); - - - assign GHRNextF_temp = GHRNext[k+4:5]; - assign GHRF_temp = InstrValidF ? GHR[k+3:4] : GHRNextF_temp; - assign GHRFExtra_temp = InstrValidF ? 1'b0 : GHR[k+4]; - assign GHRD_temp = InstrValidD ? GHR[k+3:3] : {GHRFExtra_temp, GHRF_temp}; - assign GHRE_temp = InstrValidE ? GHR[k+2:2] : GHRD_temp; - assign GHRM_temp = InstrValidM ? GHR[k+1:1] : GHRE_temp; - assign GHRW_temp = InstrValidW ? GHR[k:0] : GHRM_temp; - - - 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]}; - - ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), - .ce1(~StallF | reset), .ce2(~StallW & ~FlushW), - .ra1(IndexNextF), - .rd1(TableDirPredictionF), - .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 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); - flopenr #(2) PredictionRegE(clk, reset, ~StallE, DirPredictionD, DirPredictionE); - - // New prediction pipeline - satCounter2 BPDirUpdateF(.BrDir(DirPredictionF[1]), .OldState(DirPredictionF), .NewState(NewDirPredictionF)); - flopenr #(2) NewPredDReg(clk, reset, ~StallD, NewDirPredictionF, NewDirPredictionD); - 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 ? 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; - - flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); - -endmodule diff --git a/src/ifu/bpred/speculativeglobalhistory.sv b/src/ifu/bpred/speculativeglobalhistory.sv deleted file mode 100644 index ca36a19f1..000000000 --- a/src/ifu/bpred/speculativeglobalhistory.sv +++ /dev/null @@ -1,136 +0,0 @@ -/////////////////////////////////////////// -// speculativeglobalhistory.sv -// -// Written: Shreya Sanghai -// Email: ssanghai@hmc.edu -// Created: March 16, 2021 -// Modified: -// -// Purpose: Global History Branch predictor with parameterized global history register -// -// 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" - -module speculativeglobalhistory #(parameter int k = 10 ) ( - input logic clk, - input logic reset, - input logic StallF, StallD, StallE, StallM, StallW, - input logic FlushD, FlushE, FlushM, FlushW, - output logic [1:0] DirPredictionF, - output logic DirPredictionWrongE, - // update - input logic [3:0] PredInstrClassF, - input logic [3:0] InstrClassD, InstrClassE, InstrClassM, - input logic [3:0] WrongPredInstrClassD, - input logic PCSrcE -); - - logic MatchF, MatchD, MatchE; - logic MatchNextX, MatchXF; - - logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE; - logic [1:0] NewDirPredictionE; - - logic [k-1:0] GHRF, GHRD, GHRE, GHRM; - logic GHRLastF; - logic [k-1:0] GHRNextF, GHRNextD, GHRNextE, GHRNextM; - logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE; - logic [1:0] ForwardNewDirPrediction, ForwardDirPredictionF; - - logic FlushDOrDirWrong; - - assign IndexNextF = GHRNextF; - assign IndexF = GHRF ; - assign IndexD = GHRD[k-1:0] ; - assign IndexE = GHRE[k-1:0] ; - - ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), - .ce1(~StallF | reset), .ce2(~StallM & ~FlushM), - .ra1(IndexNextF), - .rd1(TableDirPredictionF), - .wa2(IndexE), - .wd2(NewDirPredictionE), - .we2(InstrClassE[0]), - .bwe2(1'b1)); - - // 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 = PredInstrClassF[0] & ~FlushD & (IndexNextF == IndexF); - assign MatchD = InstrClassD[0] & ~FlushE & (IndexNextF == IndexD); - assign MatchE = InstrClassE[0] & ~FlushM & (IndexNextF == IndexE); - assign MatchNextX = MatchF | MatchD | MatchE; - - flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF); - - assign ForwardNewDirPrediction = MatchF ? {2{DirPredictionF[1]}} : - MatchD ? {2{DirPredictionD[1]}} : - NewDirPredictionE ; - - flopenr #(2) ForwardDirPredicitonReg(clk, reset, ~StallF, ForwardNewDirPrediction, ForwardDirPredictionF); - - assign DirPredictionF = MatchXF ? ForwardDirPredictionF : TableDirPredictionF; - - // DirPrediction pipeline - flopenr #(2) PredictionRegD(clk, reset, ~StallD, DirPredictionF, DirPredictionD); - flopenr #(2) PredictionRegE(clk, reset, ~StallE, DirPredictionD, DirPredictionE); - - - satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE)); - - // GHR pipeline - - // If Fetch has a branch, speculatively insert prediction into the GHR - // If the front end is flushed or the direction prediction is wrong, reset to - // most recent valid GHR. For a BP wrong this is GHRD with the correct prediction shifted in. - // For FlushE this is GHRE. GHRNextE is both. - logic [k-1:0] GHRClassWrongAndPredF; - logic [k-1:0] GHRClassWrong; - mux2 #(k) GHRClassWrongAndPredFMux({DirPredictionF[1], DirPredictionD[1], GHRF[k-1:2]}, {DirPredictionF[1], GHRF[k-2:0]}, ~InstrClassD[0], GHRClassWrongAndPredF); - - assign FlushDOrDirWrong = FlushD | DirPredictionWrongE; -// mux3 #(k) GHRFMux(GHRF, {DirPredictionF[1], GHRF[k-1:1]}, GHRNextE[k-1:0], -// {FlushDOrDirWrong, PredInstrClassF[0]}, GHRNextF); - - mux5 #(k) GHRFMux(GHRF, {DirPredictionF[1], GHRF[k-1:1]}, GHRClassWrong, GHRClassWrongAndPredF, GHRNextE[k-1:0], - {FlushDOrDirWrong, WrongPredInstrClassD[0], PredInstrClassF[0]}, GHRNextF); - - // Need 1 extra bit to store the shifted out GHRF if repair needs to back shift. - flopenr #(k) GHRFReg(clk, reset, ~StallF | FlushDOrDirWrong, GHRNextF, GHRF); - flopenr #(1) GHRFLastReg(clk, reset, ~StallF | FlushDOrDirWrong, GHRF[0], GHRLastF); - - // With instruction class prediction, the class could be wrong and is checked in Decode. - // If it is wrong and branch does exist then shift right and insert the prediction. - // If the branch does not exist then shift left and use GHRLastF to restore the LSB. - mux2 #(k) GHRClassWrongMux({DirPredictionD[1], GHRF[k-1:1]}, {GHRF[k-2:0], GHRLastF}, ~InstrClassD[0], GHRClassWrong); - // As with GHRF FlushD and wrong direction prediction flushes the pipeline and restores to GHRNextE. - mux3 #(k) GHRDMux(GHRF, GHRClassWrong, GHRNextE, {FlushDOrDirWrong, WrongPredInstrClassD[0]}, GHRNextD); - - flopenr #(k) GHRDReg(clk, reset, ~StallD | FlushDOrDirWrong, GHRNextD, GHRD); - - mux3 #(k) GHREMux(GHRD, GHRNextM, {PCSrcE, GHRD[k-2:0]}, {InstrClassE[0] & ~FlushM, FlushE}, GHRNextE); - - flopenr #(k) GHREReg(clk, reset, (~StallE) | FlushE, GHRNextE, GHRE); - - assign GHRNextM = FlushM ? GHRM : GHRE; - flopenr #(k) GHRMReg(clk, reset, (InstrClassM[0] & ~StallM) | FlushM, GHRNextM, GHRM); - - assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & InstrClassE[0]; - -endmodule diff --git a/src/ifu/bpred/speculativegshare.sv b/src/ifu/bpred/speculativegshare.sv deleted file mode 100644 index 48601021a..000000000 --- a/src/ifu/bpred/speculativegshare.sv +++ /dev/null @@ -1,137 +0,0 @@ -/////////////////////////////////////////// -// gsharePredictor.sv -// -// Written: Shreya Sanghai -// Email: ssanghai@hmc.edu -// Created: March 16, 2021 -// Modified: -// -// Purpose: Global History Branch predictor with parameterized global history register -// -// 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" - -module speculativegshare #(parameter int k = 10 ) ( - input logic clk, - input logic reset, - input logic StallF, StallD, StallE, StallM, StallW, - input logic FlushD, FlushE, FlushM, FlushW, - output logic [1:0] DirPredictionF, - output logic DirPredictionWrongE, - // update - input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, - input logic [3:0] PredInstrClassF, - input logic [3:0] InstrClassD, InstrClassE, InstrClassM, - input logic [3:0] WrongPredInstrClassD, - input logic PCSrcE -); - - logic MatchF, MatchD, MatchE; - logic MatchNextX, MatchXF; - - logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE; - logic [1:0] NewDirPredictionE; - - logic [k-1:0] GHRF, GHRD, GHRE, GHRM; - logic GHRLastF; - logic [k-1:0] GHRNextF, GHRNextD, GHRNextE, GHRNextM; - logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE; - logic [1:0] ForwardNewDirPrediction, ForwardDirPredictionF; - - logic FlushDOrDirWrong; - - 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]}; - - ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), - .ce1(~StallF | reset), .ce2(~StallM & ~FlushM), - .ra1(IndexNextF), - .rd1(TableDirPredictionF), - .wa2(IndexE), - .wd2(NewDirPredictionE), - .we2(InstrClassE[0]), - .bwe2(1'b1)); - - // 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 = PredInstrClassF[0] & ~FlushD & (IndexNextF == IndexF); - assign MatchD = InstrClassD[0] & ~FlushE & (IndexNextF == IndexD); - assign MatchE = InstrClassE[0] & ~FlushM & (IndexNextF == IndexE); - assign MatchNextX = MatchF | MatchD | MatchE; - - flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF); - - assign ForwardNewDirPrediction = MatchF ? {2{DirPredictionF[1]}} : - MatchD ? {2{DirPredictionD[1]}} : - NewDirPredictionE ; - - flopenr #(2) ForwardDirPredicitonReg(clk, reset, ~StallF, ForwardNewDirPrediction, ForwardDirPredictionF); - - assign DirPredictionF = MatchXF ? ForwardDirPredictionF : TableDirPredictionF; - - // DirPrediction pipeline - flopenr #(2) PredictionRegD(clk, reset, ~StallD, DirPredictionF, DirPredictionD); - flopenr #(2) PredictionRegE(clk, reset, ~StallE, DirPredictionD, DirPredictionE); - - - satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE)); - - // GHR pipeline - - // If Fetch has a branch, speculatively insert prediction into the GHR - // If the front end is flushed or the direction prediction is wrong, reset to - // most recent valid GHR. For a BP wrong this is GHRD with the correct prediction shifted in. - // For FlushE this is GHRE. GHRNextE is both. - logic [k-1:0] GHRClassWrongAndPredF; - logic [k-1:0] GHRClassWrong; - mux2 #(k) GHRClassWrongAndPredFMux({DirPredictionF[1], DirPredictionD[1], GHRF[k-1:2]}, {DirPredictionF[1], GHRF[k-2:0]}, ~InstrClassD[0], GHRClassWrongAndPredF); - - assign FlushDOrDirWrong = FlushD | DirPredictionWrongE; -// mux3 #(k) GHRFMux(GHRF, {DirPredictionF[1], GHRF[k-1:1]}, GHRNextE[k-1:0], -// {FlushDOrDirWrong, PredInstrClassF[0]}, GHRNextF); - - mux5 #(k) GHRFMux(GHRF, {DirPredictionF[1], GHRF[k-1:1]}, GHRClassWrong, GHRClassWrongAndPredF, GHRNextE[k-1:0], - {FlushDOrDirWrong, WrongPredInstrClassD[0], PredInstrClassF[0]}, GHRNextF); - - // Need 1 extra bit to store the shifted out GHRF if repair needs to back shift. - flopenr #(k) GHRFReg(clk, reset, ~StallF | FlushDOrDirWrong, GHRNextF, GHRF); - flopenr #(1) GHRFLastReg(clk, reset, ~StallF | FlushDOrDirWrong, GHRF[0], GHRLastF); - - // With instruction class prediction, the class could be wrong and is checked in Decode. - // If it is wrong and branch does exist then shift right and insert the prediction. - // If the branch does not exist then shift left and use GHRLastF to restore the LSB. - mux2 #(k) GHRClassWrongMux({DirPredictionD[1], GHRF[k-1:1]}, {GHRF[k-2:0], GHRLastF}, ~InstrClassD[0], GHRClassWrong); - // As with GHRF FlushD and wrong direction prediction flushes the pipeline and restores to GHRNextE. - mux3 #(k) GHRDMux(GHRF, GHRClassWrong, GHRNextE, {FlushDOrDirWrong, WrongPredInstrClassD[0]}, GHRNextD); - - flopenr #(k) GHRDReg(clk, reset, ~StallD | FlushDOrDirWrong, GHRNextD, GHRD); - - mux3 #(k) GHREMux(GHRD, GHRNextM, {PCSrcE, GHRD[k-2:0]}, {InstrClassE[0] & ~FlushM, FlushE}, GHRNextE); - - flopenr #(k) GHREReg(clk, reset, (~StallE) | FlushE, GHRNextE, GHRE); - - assign GHRNextM = FlushM ? GHRM : GHRE; - flopenr #(k) GHRMReg(clk, reset, (InstrClassM[0] & ~StallM) | FlushM, GHRNextM, GHRM); - - assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & InstrClassE[0]; - -endmodule From fd5c12431e31f9255695e716f2cb92d591ae789f Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 20 Feb 2023 18:48:02 -0600 Subject: [PATCH 7/7] Fixed typo in the global branch predictor. --- src/ifu/bpred/gshare.sv | 10 +++++----- src/ifu/bpred/gsharebasic.sv | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ifu/bpred/gshare.sv b/src/ifu/bpred/gshare.sv index c13bce943..d996b5b62 100644 --- a/src/ifu/bpred/gshare.sv +++ b/src/ifu/bpred/gshare.sv @@ -61,11 +61,11 @@ module gshare #(parameter k = 10, assign IndexE = GHRE ^ {PCE[k+1] ^ PCE[1], PCE[k:2]}; assign IndexM = GHRM ^ {PCM[k+1] ^ PCM[1], PCM[k:2]}; end else if(TYPE == "global") begin - assign IndexNextF = {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]}; - assign IndexF = {PCF[k+1] ^ PCF[1], PCF[k:2]}; - assign IndexD = {PCD[k+1] ^ PCD[1], PCD[k:2]}; - assign IndexE = {PCE[k+1] ^ PCE[1], PCE[k:2]}; - assign IndexM = {PCM[k+1] ^ PCM[1], PCM[k:2]}; + assign IndexNextF = GHRNextF; + assign IndexF = GHRF; + assign IndexD = GHRD; + assign IndexE = GHRE; + assign IndexM = GHRM; end assign MatchF = BranchInstrF & ~FlushD & (IndexNextF == IndexF); diff --git a/src/ifu/bpred/gsharebasic.sv b/src/ifu/bpred/gsharebasic.sv index d73797275..6446ecbc3 100644 --- a/src/ifu/bpred/gsharebasic.sv +++ b/src/ifu/bpred/gsharebasic.sv @@ -54,8 +54,8 @@ module gsharebasic #(parameter k = 10, assign IndexNextF = GHR ^ {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]}; assign IndexE = GHRM ^ {PCM[k+1] ^ PCM[1], PCM[k:2]}; end else if(TYPE == "global") begin - assign IndexNextF = {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]}; - assign IndexE = {PCM[k+1] ^ PCM[1], PCM[k:2]}; + assign IndexNextF = GHRNext; + assign IndexE = GHRE; end ram2p1r1wbe #(2**k, 2) PHT(.clk(clk),