Got the branch predictor parameterized using Lim's method. Also had to add a global enum included in both cvw.sv and the configs which defines the branch predictor types. This should be synthesizable, but I'll need to double check.

This commit is contained in:
Ross Thompson 2023-05-26 16:00:14 -05:00
parent f1b8689955
commit 1315a0bf4a
25 changed files with 132 additions and 129 deletions

View File

@ -27,6 +27,7 @@
// include shared configuration
`include "wally-shared.vh"
`include "BranchPredictorType.vh"
localparam FPGA = 1;
localparam QEMU = 0;
@ -131,7 +132,7 @@ localparam PLIC_UART_ID = 32'd10;
localparam PLIC_GPIO_ID = 32'd3;
localparam BPRED_SUPPORTED = 1;
localparam BPRED_TYPE = "GSHARE_N"; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT;
localparam BranchPredictorType BPRED_TYPE = BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
localparam BPRED_SIZE = 32'd10;
localparam BPRED_NUM_LHR = 32'd6;
localparam BTB_SIZE = 32'd10;

View File

@ -25,6 +25,8 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "BranchPredictorType.vh"
localparam FPGA = 0;
localparam QEMU = 0;
@ -131,7 +133,7 @@ localparam PLIC_GPIO_ID = 32'd3;
localparam PLIC_UART_ID = 32'd10;
localparam BPRED_SUPPORTED = 0;
localparam BPRED_TYPE = "GSHARE_N"; // GSHARE_B, GLOBAL_N, GLOBAL_B, TWOBIT_N
localparam BranchPredictorType BPRED_TYPE = BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
localparam BPRED_SIZE = 32'd10;
localparam BPRED_NUM_LHR = 32'd6;
localparam BTB_SIZE = 32'd10;

View File

@ -27,6 +27,7 @@
// include shared configuration
// `include "wally-shared.vh"
`include "BranchPredictorType.vh"
localparam FPGA = 0;
localparam QEMU = 0;
@ -133,10 +134,9 @@ localparam PLIC_GPIO_ID = 32'd3;
localparam PLIC_UART_ID = 32'd10;
localparam BPRED_SUPPORTED = 1;
// BP_GSHARE, BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
// GSHARE_N, GSHARE_B, GLOBAL_N, GLOBAL_B, TWOBIT_N
localparam BPRED_TYPE = "GSHARE_N"; // GSHARE_B, GLOBAL_N, GLOBAL_B, TWOBIT_N
localparam BranchPredictorType BPRED_TYPE = BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
localparam BPRED_SIZE = 32'd16;
localparam BPRED_NUM_LHR = 32'd6;
localparam BTB_SIZE = 32'd10;
localparam SVADU_SUPPORTED = 1;

View File

@ -25,6 +25,8 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "BranchPredictorType.vh"
localparam FPGA = 0;
localparam QEMU = 0;
@ -131,7 +133,7 @@ localparam PLIC_GPIO_ID = 32'd3;
localparam PLIC_UART_ID = 32'd10;
localparam BPRED_SUPPORTED = 0;
localparam BPRED_TYPE = "GSHARE_N"; // GSHARE_B, GLOBAL_N, GLOBAL_B, TWOBIT_N
localparam BranchPredictorType BPRED_TYPE = BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
localparam BPRED_SIZE = 32'd10;
localparam BPRED_NUM_LHR = 32'd6;
localparam BTB_SIZE = 32'd10;

View File

@ -25,6 +25,8 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "BranchPredictorType.vh"
localparam FPGA = 0;
localparam QEMU = 0;
@ -130,7 +132,7 @@ localparam PLIC_GPIO_ID = 32'd3;
localparam PLIC_UART_ID = 32'd10;
localparam BPRED_SUPPORTED = 0;
localparam BPRED_TYPE = "GSHARE_N"; // GSHARE_B, GLOBAL_N, GLOBAL_B, TWOBIT_N
localparam BranchPredictorType BPRED_TYPE = BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
localparam BPRED_SIZE = 32'd10;
localparam BPRED_NUM_LHR = 32'd6;
localparam BTB_SIZE = 32'd10;

View File

@ -25,6 +25,8 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "BranchPredictorType.vh"
localparam FPGA = 0;
localparam QEMU = 0;
@ -133,7 +135,7 @@ localparam PLIC_GPIO_ID = 32'd3;
localparam PLIC_UART_ID = 32'd10;
localparam BPRED_SUPPORTED = 1;
localparam BPRED_TYPE = "GSHARE_N"; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
localparam BranchPredictorType BPRED_TYPE = BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
localparam BPRED_SIZE = 32'd10;
localparam BPRED_NUM_LHR = 32'd6;
localparam BTB_SIZE = 32'd10;

View File

@ -28,6 +28,8 @@
// include shared configuration
// `include "wally-shared.vh"
`include "BranchPredictorType.vh"
localparam FPGA = 0;
localparam QEMU = 0;
@ -136,7 +138,8 @@ localparam PLIC_GPIO_ID = 32'd3;
localparam PLIC_UART_ID = 32'd10;
localparam BPRED_SUPPORTED = 1;
localparam BPRED_TYPE = "GSHARE_N"; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
localparam BranchPredictorType BPRED_TYPE = BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
localparam BPRED_NUM_LHR = 32'd6;
localparam BPRED_SIZE = 32'd10;
localparam BTB_SIZE = 32'd10;

View File

@ -138,7 +138,7 @@
`define BPRED_SUPPORTED 1
//`define BPRED_TYPE "BP_GLOBAL_BASIC" // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
`define BPRED_TYPE "BP_GSHARE" // "BP_LOCAL_REPAIR" // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
`define BPRED_SIZE 6
`define BPRED_SIZE 10
`define BPRED_NUM_LHR 4
`define BTB_SIZE 10

View File

@ -25,6 +25,8 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "BranchPredictorType.vh"
localparam FPGA = 0;
localparam QEMU = 0;
@ -133,7 +135,7 @@ localparam PLIC_GPIO_ID = 32'd3;
localparam PLIC_UART_ID = 32'd10;
localparam BPRED_SUPPORTED = 0;
localparam BPRED_TYPE = "GSHARE_N"; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
localparam BranchPredictorType BPRED_TYPE = BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
localparam BPRED_SIZE = 32'd10;
localparam BPRED_NUM_LHR = 32'd6;
localparam BTB_SIZE = 32'd10;

View File

@ -0,0 +1,3 @@
typedef enum {BP_TWOBIT, BP_GSHARE, BP_GLOBAL, BP_GSHARE_BASIC,
BP_GLOBAL_BASIC, BP_LOCAL_BASIC, BP_LOCAL_AHEAD, BP_LOCAL_REPAIR} BranchPredictorType;

View File

@ -74,6 +74,7 @@ parameter cvw_t P = '{
BPRED_SUPPORTED : BPRED_SUPPORTED,
BPRED_TYPE : BPRED_TYPE,
BPRED_SIZE : BPRED_SIZE,
BPRED_NUM_LHR : BPRED_NUM_LHR,
BTB_SIZE : BTB_SIZE,
RADIX : RADIX,
DIVCOPIES : DIVCOPIES,

View File

@ -26,7 +26,6 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
module round import cvw::*; #(parameter cvw_t P) (
input logic [P.FMTBITS-1:0] OutFmt, // output format
input logic [2:0] Frm, // rounding mode

View File

@ -27,9 +27,7 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module RASPredictor #(parameter int StackSize = 16 )(
module RASPredictor import cvw::*; #(parameter cvw_t P, StackSize = 16 )(
input logic clk,
input logic reset,
input logic StallF, StallD, StallE, StallM, FlushD, FlushE, FlushM,
@ -37,15 +35,15 @@ module RASPredictor #(parameter int StackSize = 16 )(
input logic ReturnD,
input logic ReturnE, CallE, // Instr class
input logic BPReturnF,
input logic [`XLEN-1:0] PCLinkE, // PC of instruction after a call
output logic [`XLEN-1:0] RASPCF // Top of the stack
input logic [P.XLEN-1:0] PCLinkE, // PC of instruction after a call
output logic [P.XLEN-1:0] RASPCF // Top of the stack
);
logic CounterEn;
localparam Depth = $clog2(StackSize);
logic [Depth-1:0] NextPtr, Ptr, P1, M1, IncDecPtr;
logic [StackSize-1:0] [`XLEN-1:0] memory;
logic [StackSize-1:0] [P.XLEN-1:0] memory;
integer index;
logic PopF;
@ -85,7 +83,7 @@ module RASPredictor #(parameter int StackSize = 16 )(
always_ff @ (posedge clk) begin
if(reset) begin
for(index=0; index<StackSize; index++)
memory[index] <= {`XLEN{1'b0}};
memory[index] <= {P.XLEN{1'b0}};
end else if(PushE) begin
memory[NextPtr] <= #1 PCLinkE;
end

View File

@ -26,27 +26,25 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
`define INSTR_CLASS_PRED 1
module bpred (
module bpred import cvw::*; #(parameter cvw_t P) (
input logic clk, reset,
input logic StallF, StallD, StallE, StallM, StallW,
input logic FlushD, FlushE, FlushM, FlushW,
// Fetch stage
// the prediction
input logic [31:0] InstrD, // Decompressed decode stage instruction. Used to decode instruction class
input logic [`XLEN-1:0] PCNextF, // Next Fetch Address
input logic [`XLEN-1:0] PCPlus2or4F, // PCF+2/4
output logic [`XLEN-1:0] PC1NextF, // Branch Predictor predicted or corrected fetch address on miss prediction
output logic [`XLEN-1:0] NextValidPCE, // Address of next valid instruction after the instruction in the Memory stage
input logic [P.XLEN-1:0] PCNextF, // Next Fetch Address
input logic [P.XLEN-1:0] PCPlus2or4F, // PCF+2/4
output logic [P.XLEN-1:0] PC1NextF, // Branch Predictor predicted or corrected fetch address on miss prediction
output logic [P.XLEN-1:0] NextValidPCE, // Address of next valid instruction after the instruction in the Memory stage
// Update Predictor
input logic [`XLEN-1:0] PCF, // Fetch stage instruction address
input logic [`XLEN-1:0] PCD, // Decode stage instruction address. Also the address the branch predictor took
input logic [`XLEN-1:0] PCE, // Execution stage instruction address
input logic [`XLEN-1:0] PCM, // Memory stage instruction address
input logic [P.XLEN-1:0] PCF, // Fetch stage instruction address
input logic [P.XLEN-1:0] PCD, // Decode stage instruction address. Also the address the branch predictor took
input logic [P.XLEN-1:0] PCE, // Execution stage instruction address
input logic [P.XLEN-1:0] PCM, // Memory stage instruction address
input logic [31:0] PostSpillInstrRawF, // Instruction
@ -55,9 +53,9 @@ module bpred (
input logic BranchD, BranchE,
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)
input logic [P.XLEN-1:0] IEUAdrE, // The branch/jump target address
input logic [P.XLEN-1:0] IEUAdrM, // The branch/jump target address
input logic [P.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 call, return, jr (not return), j, br
// Report branch prediction status
@ -71,21 +69,21 @@ module bpred (
logic [1:0] BPDirPredF;
logic [`XLEN-1:0] BPBTAF, RASPCF;
logic [P.XLEN-1:0] BPBTAF, RASPCF;
logic BPPCWrongE;
logic IClassWrongE;
logic BPDirPredWrongE;
logic BPPCSrcF;
logic [`XLEN-1:0] BPPCF;
logic [`XLEN-1:0] PC0NextF;
logic [`XLEN-1:0] PCCorrectE;
logic [P.XLEN-1:0] BPPCF;
logic [P.XLEN-1:0] PC0NextF;
logic [P.XLEN-1:0] PCCorrectE;
logic [3:0] WrongPredInstrClassD;
logic BTBTargetWrongE;
logic RASTargetWrongE;
logic [`XLEN-1:0] BPBTAD;
logic [P.XLEN-1:0] BPBTAD;
logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF;
logic BPBranchF, BPJumpF, BPReturnF, BPCallF;
@ -95,50 +93,49 @@ module bpred (
logic BranchM, JumpM, ReturnM, CallM;
logic BranchW, JumpW, ReturnW, CallW;
logic BPReturnWrongD;
logic [`XLEN-1:0] BPBTAE;
logic [P.XLEN-1:0] BPBTAE;
// Part 1 branch direction prediction
// look into the 2 port Sram model. something is wrong.
if (`BPRED_TYPE == "BP_TWOBIT") begin:Predictor
twoBitPredictor #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW,
if (P.BPRED_TYPE == BP_TWOBIT) begin:Predictor
twoBitPredictor #(P.XLEN, P.BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW,
.FlushD, .FlushE, .FlushM, .FlushW,
.PCNextF, .PCM, .BPDirPredF, .BPDirPredWrongE,
.BranchE, .BranchM, .PCSrcE);
end else if (`BPRED_TYPE == "BP_GSHARE") begin:Predictor
gshare #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
end else if (P.BPRED_TYPE == BP_GSHARE) begin:Predictor
gshare #(P.XLEN, P.BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.PCNextF, .PCF, .PCD, .PCE, .PCM, .BPDirPredF, .BPDirPredWrongE,
.BPBranchF, .BranchD, .BranchE, .BranchM, .BranchW,
.PCSrcE);
end else if (`BPRED_TYPE == "BP_GLOBAL") begin:Predictor
gshare #(`BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
end else if (P.BPRED_TYPE == BP_GLOBAL) begin:Predictor
gshare #(P.XLEN, P.BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.PCNextF, .PCF, .PCD, .PCE, .PCM, .BPDirPredF, .BPDirPredWrongE,
.BPBranchF, .BranchD, .BranchE, .BranchM, .BranchW,
.PCSrcE);
end else if (`BPRED_TYPE == "BP_GSHARE_BASIC") begin:Predictor
gsharebasic #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
end else if (P.BPRED_TYPE == BP_GSHARE_BASIC) begin:Predictor
gsharebasic #(P.XLEN, P.BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.PCNextF, .PCM, .BPDirPredF, .BPDirPredWrongE,
.BranchE, .BranchM, .PCSrcE);
end else if (`BPRED_TYPE == "BP_GLOBAL_BASIC") begin:Predictor
gsharebasic #(`BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
end else if (P.BPRED_TYPE == BP_GLOBAL_BASIC) begin:Predictor
gsharebasic #(P.XLEN, P.BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.PCNextF, .PCM, .BPDirPredF, .BPDirPredWrongE,
.BranchE, .BranchM, .PCSrcE);
end else if (`BPRED_TYPE == "BP_LOCAL_BASIC") begin:Predictor
localbpbasic #(`BPRED_NUM_LHR, `BPRED_SIZE) DirPredictor(.clk, .reset,
end else if (P.BPRED_TYPE == BP_LOCAL_BASIC) begin:Predictor
localbpbasic #(P.XLEN, P.BPRED_NUM_LHR, P.BPRED_SIZE) DirPredictor(.clk, .reset,
.StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.PCNextF, .PCM, .BPDirPredF, .BPDirPredWrongE,
.BranchE, .BranchM, .PCSrcE);
end else if (`BPRED_TYPE == "BP_LOCAL_AHEAD") begin:Predictor
localaheadbp #(`BPRED_NUM_LHR, `BPRED_SIZE) DirPredictor(.clk, .reset,
end else if (P.BPRED_TYPE == BP_LOCAL_AHEAD) begin:Predictor
localaheadbp #(P.XLEN, P.BPRED_NUM_LHR, P.BPRED_SIZE) DirPredictor(.clk, .reset,
.StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.PCNextF, .PCM, .BPDirPredD(BPDirPredF), .BPDirPredWrongE,
.BranchE, .BranchM, .PCSrcE);
end else if (`BPRED_TYPE == "BP_LOCAL_REPAIR") begin:Predictor
localreapirbp #(`BPRED_NUM_LHR, `BPRED_SIZE) DirPredictor(.clk, .reset,
end else if (P.BPRED_TYPE == BP_LOCAL_REPAIR) begin:Predictor
localrepairbp #(P.XLEN, P.BPRED_NUM_LHR, P.BPRED_SIZE) DirPredictor(.clk, .reset,
.StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.PCNextF, .PCE, .PCM, .BPDirPredD(BPDirPredF), .BPDirPredWrongE,
.BranchD, .BranchE, .BranchM, .PCSrcE);
@ -147,7 +144,7 @@ module bpred (
// Part 2 Branch target address prediction
// BTB contains target address for all CFI
btb #(`BTB_SIZE)
btb #(P, P.BTB_SIZE)
TargetPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.PCNextF, .PCF, .PCD, .PCE, .PCM,
.BPBTAF, .BPBTAD, .BPBTAE,
@ -159,13 +156,13 @@ module bpred (
.InstrClassM({CallM, ReturnM, JumpM, BranchM}),
.InstrClassW({CallW, ReturnW, JumpW, BranchW}));
icpred #(`INSTR_CLASS_PRED) icpred(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
icpred #(P, `INSTR_CLASS_PRED) icpred(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.PostSpillInstrRawF, .InstrD, .BranchD, .BranchE, .JumpD, .JumpE, .BranchM, .BranchW, .JumpM, .JumpW,
.CallD, .CallE, .CallM, .CallW, .ReturnD, .ReturnE, .ReturnM, .ReturnW, .BTBCallF, .BTBReturnF, .BTBJumpF,
.BTBBranchF, .BPCallF, .BPReturnF, .BPJumpF, .BPBranchF, .IClassWrongM, .IClassWrongE, .BPReturnWrongD);
// Part 3 RAS
RASPredictor RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
RASPredictor #(P) RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
.BPReturnF, .ReturnD, .ReturnE, .CallE,
.BPReturnWrongD, .RASPCF, .PCLinkE);
@ -181,21 +178,21 @@ module bpred (
// Output the predicted PC or corrected PC on miss-predict.
assign BPPCSrcF = (BPBranchF & BPDirPredF[1]) | BPJumpF;
mux2 #(`XLEN) pcmuxbp(BPBTAF, RASPCF, BPReturnF, BPPCF);
mux2 #(P.XLEN) pcmuxbp(BPBTAF, RASPCF, BPReturnF, BPPCF);
// Selects the BP or PC+2/4.
mux2 #(`XLEN) pcmux0(PCPlus2or4F, BPPCF, BPPCSrcF, PC0NextF);
mux2 #(P.XLEN) pcmux0(PCPlus2or4F, BPPCF, BPPCSrcF, PC0NextF);
// If the prediction is wrong select the correct address.
mux2 #(`XLEN) pcmux1(PC0NextF, PCCorrectE, BPWrongE, PC1NextF);
mux2 #(P.XLEN) pcmux1(PC0NextF, PCCorrectE, BPWrongE, PC1NextF);
// Correct branch/jump target.
mux2 #(`XLEN) pccorrectemux(PCLinkE, IEUAdrE, PCSrcE, PCCorrectE);
mux2 #(P.XLEN) pccorrectemux(PCLinkE, IEUAdrE, PCSrcE, PCCorrectE);
// If the fence/csrw was predicted as a taken branch then we select PCF, rather than PCE.
// Effectively this is PCM+4 or the non-existant PCLinkM
if(`INSTR_CLASS_PRED) mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPWrongM, NextValidPCE);
if(`INSTR_CLASS_PRED) mux2 #(P.XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPWrongM, NextValidPCE);
else assign NextValidPCE = PCE;
if(`ZICOUNTERS_SUPPORTED) begin
logic [`XLEN-1:0] RASPCD, RASPCE;
if(P.ZICOUNTERS_SUPPORTED) begin
logic [P.XLEN-1:0] RASPCD, RASPCE;
logic BTAWrongE, RASPredPCWrongE;
// performance counters
// 1. class (class wrong / minstret) (IClassWrongM / csr) // Correct now
@ -211,8 +208,8 @@ module bpred (
assign BTAWrongE = (BPBTAE != IEUAdrE) & (BranchE | JumpE & ~ReturnE) & PCSrcE;
assign RASPredPCWrongE = (RASPCE != IEUAdrE) & ReturnE & PCSrcE;
flopenrc #(`XLEN) RASTargetDReg(clk, reset, FlushD, ~StallD, RASPCF, RASPCD);
flopenrc #(`XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE);
flopenrc #(P.XLEN) RASTargetDReg(clk, reset, FlushD, ~StallD, RASPCF, RASPCD);
flopenrc #(P.XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE);
flopenrc #(3) BPPredWrongRegM(clk, reset, FlushM, ~StallM,
{BPDirPredWrongE, BTAWrongE, RASPredPCWrongE},
{BPDirPredWrongM, BTAWrongM, RASPredPCWrongM});

View File

@ -28,22 +28,20 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module btb #(parameter Depth = 10 ) (
module btb import cvw::*; #(parameter cvw_t P, Depth = 10 ) (
input logic clk,
input logic reset,
input logic StallF, StallD, StallE, StallM, StallW, FlushD, FlushE, FlushM, FlushW,
input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, // PC at various stages
output logic [`XLEN-1:0] BPBTAF, // BTB's guess at PC
output logic [`XLEN-1:0] BPBTAD,
output logic [`XLEN-1:0] BPBTAE,
input logic [P.XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, // PC at various stages
output logic [P.XLEN-1:0] BPBTAF, // BTB's guess at PC
output logic [P.XLEN-1:0] BPBTAD,
output logic [P.XLEN-1:0] BPBTAE,
output logic [3:0] BTBIClassF, // BTB's guess at instruction class
// update
input logic IClassWrongM, // BTB's instruction class guess was wrong
input logic IClassWrongE,
input logic [`XLEN-1:0] IEUAdrE, // Branch/jump target address to insert into btb
input logic [`XLEN-1:0] IEUAdrM, // Branch/jump target address to insert into btb
input logic [P.XLEN-1:0] IEUAdrE, // Branch/jump target address to insert into btb
input logic [P.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
@ -51,12 +49,12 @@ module btb #(parameter Depth = 10 ) (
);
logic [Depth-1:0] PCNextFIndex, PCFIndex, PCDIndex, PCEIndex, PCMIndex, PCWIndex;
logic [`XLEN-1:0] ResetPC;
logic [P.XLEN-1:0] ResetPC;
logic MatchD, MatchE, MatchM, MatchW, MatchX;
logic [`XLEN+3:0] ForwardBTBPrediction, ForwardBTBPredictionF;
logic [`XLEN+3:0] TableBTBPredF;
logic [`XLEN-1:0] IEUAdrW;
logic [`XLEN-1:0] PCW;
logic [P.XLEN+3:0] ForwardBTBPrediction, ForwardBTBPredictionF;
logic [P.XLEN+3:0] TableBTBPredF;
logic [P.XLEN-1:0] IEUAdrW;
logic [P.XLEN-1:0] PCW;
logic BTBWrongE, BPBTAWrongE;
logic BTBWrongM, BPBTAWrongM;
@ -75,7 +73,7 @@ module btb #(parameter Depth = 10 ) (
// during reset. The BTB must produce a non X PC1NextF to allow the simulation to run.
// While the mux could be included in IFU it is not necessary for the IROM/I$/bus.
// For now it is optimal to leave it here.
assign ResetPC = `RESET_VECTOR;
assign ResetPC = P.RESET_VECTOR[P.XLEN-1:0];
assign PCNextFIndex = reset ? ResetPC[Depth+1:2] : {PCNextF[Depth+1] ^ PCNextF[1], PCNextF[Depth:2]};
assign MatchD = PCFIndex == PCDIndex;
@ -93,22 +91,22 @@ module btb #(parameter Depth = 10 ) (
// An optimization may be using a PC relative address.
ram2p1r1wbe #(2**Depth, `XLEN+4) memory(
ram2p1r1wbe #(2**Depth, P.XLEN+4) memory(
.clk, .ce1(~StallF | reset), .ra1(PCNextFIndex), .rd1(TableBTBPredF),
.ce2(~StallW & ~FlushW), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(BTBWrongM), .bwe2('1));
flopenrc #(`XLEN) BTBD(clk, reset, FlushD, ~StallD, BPBTAF, BPBTAD);
flopenrc #(P.XLEN) BTBD(clk, reset, FlushD, ~StallD, BPBTAF, BPBTAD);
// BPBTAE is not strickly necessary. However it is used by two parts of wally.
// 1. It gates updates to the BTB when the prediction does not change. This save power.
// 2. BPBTAWrongE is used by the performance counters to track when the BTB's BPBTA or instruction class is wrong.
flopenrc #(`XLEN) BTBTargetEReg(clk, reset, FlushE, ~StallE, BPBTAD, BPBTAE);
flopenrc #(P.XLEN) BTBTargetEReg(clk, reset, FlushE, ~StallE, BPBTAD, BPBTAE);
assign BPBTAWrongE = (BPBTAE != IEUAdrE) & (InstrClassE[0] | InstrClassE[1] & ~InstrClassE[2]);
flopenrc #(1) BPBTAWrongMReg(clk, reset, FlushM, ~StallM, BPBTAWrongE, BPBTAWrongM);
assign BTBWrongM = BPBTAWrongM | IClassWrongM;
flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW);
flopenr #(`XLEN) IEUAdrWReg(clk, reset, ~StallW, IEUAdrM, IEUAdrW);
flopenr #(P.XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW);
flopenr #(P.XLEN) IEUAdrWReg(clk, reset, ~StallW, IEUAdrM, IEUAdrW);
endmodule

View File

@ -27,9 +27,9 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module gshare #(parameter k = 10,
module gshare #(parameter XLEN,
parameter k = 10,
parameter integer TYPE = 1) (
input logic clk,
input logic reset,
@ -38,7 +38,7 @@ module gshare #(parameter k = 10,
output logic [1:0] BPDirPredF,
output logic BPDirPredWrongE,
// update
input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM,
input logic [XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM,
input logic BPBranchF, BranchD, BranchE, BranchM, BranchW, PCSrcE
);

View File

@ -27,9 +27,8 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module gsharebasic #(parameter k = 10,
module gsharebasic #(parameter XLEN,
parameter k = 10,
parameter TYPE = 1) (
input logic clk,
input logic reset,
@ -38,7 +37,7 @@ module gsharebasic #(parameter k = 10,
output logic [1:0] BPDirPredF,
output logic BPDirPredWrongE,
// update
input logic [`XLEN-1:0] PCNextF, PCM,
input logic [XLEN-1:0] PCNextF, PCM,
input logic BranchE, BranchM, PCSrcE
);

View File

@ -26,10 +26,7 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module icpred #(parameter INSTR_CLASS_PRED = 1)(
module icpred import cvw::*; #(parameter cvw_t P, INSTR_CLASS_PRED = 1)(
input logic clk, reset,
input logic StallF, StallD, StallE, StallM, StallW,
input logic FlushD, FlushE, FlushM, FlushW,
@ -56,10 +53,10 @@ module icpred #(parameter INSTR_CLASS_PRED = 1)(
logic ccall, cj, cjr, ccallr, CJumpF, CBranchF;
logic NCJumpF, NCBranchF;
if(`C_SUPPORTED) begin
if(P.C_SUPPORTED) begin
logic [4:0] CompressedOpcF;
assign CompressedOpcF = {PostSpillInstrRawF[1:0], PostSpillInstrRawF[15:13]};
assign ccall = CompressedOpcF == 5'h09 & `XLEN == 32;
assign ccall = CompressedOpcF == 5'h09 & P.XLEN == 32;
assign cj = CompressedOpcF == 5'h0d;
assign cjr = CompressedOpcF == 5'h14 & ~PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0;
assign ccallr = CompressedOpcF == 5'h14 & PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0;
@ -72,13 +69,13 @@ module icpred #(parameter INSTR_CLASS_PRED = 1)(
assign NCJumpF = PostSpillInstrRawF[6:0] == 7'h67 | PostSpillInstrRawF[6:0] == 7'h6F;
assign NCBranchF = PostSpillInstrRawF[6:0] == 7'h63;
assign BPBranchF = NCBranchF | (`C_SUPPORTED & CBranchF);
assign BPJumpF = NCJumpF | (`C_SUPPORTED & (CJumpF));
assign BPBranchF = NCBranchF | (P.C_SUPPORTED & CBranchF);
assign BPJumpF = NCJumpF | (P.C_SUPPORTED & (CJumpF));
assign BPReturnF = (NCJumpF & (PostSpillInstrRawF[19:15] & 5'h1B) == 5'h01) | // returnurn must returnurn to ra or r5
(`C_SUPPORTED & (ccallr | cjr) & ((PostSpillInstrRawF[11:7] & 5'h1B) == 5'h01));
(P.C_SUPPORTED & (ccallr | cjr) & ((PostSpillInstrRawF[11:7] & 5'h1B) == 5'h01));
assign BPCallF = (NCJumpF & (PostSpillInstrRawF[11:07] & 5'h1B) == 5'h01) | // call(r) must link to ra or x5
(`C_SUPPORTED & (ccall | (ccallr & (PostSpillInstrRawF[11:7] & 5'h1b) == 5'h01)));
(P.C_SUPPORTED & (ccall | (ccallr & (PostSpillInstrRawF[11:7] & 5'h1b) == 5'h01)));
end else begin
// This section connects the BTB's instruction class prediction.

View File

@ -27,9 +27,8 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module localaheadbp #(parameter m = 6, // 2^m = number of local history branches
module localaheadbp #(parameter XLEN,
parameter m = 6, // 2^m = number of local history branches
parameter k = 10) ( // number of past branches stored
input logic clk,
input logic reset,
@ -38,7 +37,7 @@ module localaheadbp #(parameter m = 6, // 2^m = number of local history branches
output logic [1:0] BPDirPredD,
output logic BPDirPredWrongE,
// update
input logic [`XLEN-1:0] PCNextF, PCM,
input logic [XLEN-1:0] PCNextF, PCM,
input logic BranchE, BranchM, PCSrcE
);
@ -53,7 +52,7 @@ module localaheadbp #(parameter m = 6, // 2^m = number of local history branches
logic PCSrcM;
logic [2**m-1:0][k-1:0] LHRArray;
logic [m-1:0] IndexLHRNextF, IndexLHRM;
logic [`XLEN-1:0] PCW;
logic [XLEN-1:0] PCW;
logic UpdateM;
@ -112,6 +111,6 @@ module localaheadbp #(parameter m = 6, // 2^m = number of local history branches
flopenrc #(k) LHRMReg(clk, reset, FlushM, ~StallM, LHRE, LHRM);
flopenrc #(k) LHRWReg(clk, reset, FlushW, ~StallW, LHRM, LHRW);
flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW);
flopenr #(XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW);
endmodule

View File

@ -27,9 +27,8 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module localbpbasic #(parameter m = 6, // 2^m = number of local history branches
module localbpbasic #(parameter XLEN,
parameter m = 6, // 2^m = number of local history branches
parameter k = 10) ( // number of past branches stored
input logic clk,
input logic reset,
@ -38,7 +37,7 @@ module localbpbasic #(parameter m = 6, // 2^m = number of local history branches
output logic [1:0] BPDirPredF,
output logic BPDirPredWrongE,
// update
input logic [`XLEN-1:0] PCNextF, PCM,
input logic [XLEN-1:0] PCNextF, PCM,
input logic BranchE, BranchM, PCSrcE
);

View File

@ -27,9 +27,8 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module localreapirbp #(parameter m = 6, // 2^m = number of local history branches
module localrepairbp #(parameter XLEN,
parameter m = 6, // 2^m = number of local history branches
parameter k = 10) ( // number of past branches stored
input logic clk,
input logic reset,
@ -38,7 +37,7 @@ module localreapirbp #(parameter m = 6, // 2^m = number of local history branche
output logic [1:0] BPDirPredD,
output logic BPDirPredWrongE,
// update
input logic [`XLEN-1:0] PCNextF, PCE, PCM,
input logic [XLEN-1:0] PCNextF, PCE, PCM,
input logic BranchD, BranchE, BranchM, PCSrcE
);
@ -52,7 +51,7 @@ module localreapirbp #(parameter m = 6, // 2^m = number of local history branche
logic PCSrcM;
logic [2**m-1:0][k-1:0] LHRArray;
logic [m-1:0] IndexLHRNextF, IndexLHRM;
logic [`XLEN-1:0] PCW;
logic [XLEN-1:0] PCW;
logic [k-1:0] LHRCommittedF, LHRSpeculativeF;
logic [m-1:0] IndexLHRD;
@ -133,6 +132,6 @@ module localreapirbp #(parameter m = 6, // 2^m = number of local history branche
flopenrc #(k) LHRMReg(clk, reset, FlushM, ~StallM, LHRE, LHRM);
flopenrc #(k) LHRWReg(clk, reset, FlushW, ~StallW, LHRM, LHRW);
flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW);
flopenr #(XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW);
endmodule

View File

@ -26,8 +26,6 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module satCounter2
(input logic BrDir,
input logic [1:0] OldState,

View File

@ -26,14 +26,13 @@
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module twoBitPredictor #(parameter k = 10) (
module twoBitPredictor #(parameter XLEN,
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] PCNextF, PCM,
input logic [XLEN-1:0] PCNextF, PCM,
output logic [1:0] BPDirPredF,
output logic BPDirPredWrongE,
input logic BranchE, BranchM,

View File

@ -326,7 +326,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
// Branch and Jump Predictor
////////////////////////////////////////////////////////////////////////////////////////////////
if (P.BPRED_SUPPORTED) begin : bpred
bpred bpred(.clk, .reset,
bpred #(P) bpred(.clk, .reset,
.StallF, .StallD, .StallE, .StallM, .StallW,
.FlushD, .FlushE, .FlushM, .FlushW, .InstrValidD, .InstrValidE,
.BranchD, .BranchE, .JumpD, .JumpE,

View File

@ -34,6 +34,8 @@
package cvw;
`include "BranchPredictorType.vh"
typedef struct packed {
logic FPGA; // Modifications to tare
logic QEMU; // Hacks to agree with QEMU during Linux boot
@ -136,7 +138,8 @@ typedef struct packed {
int PLIC_UART_ID;
logic BPRED_SUPPORTED;
longint BPRED_TYPE;
BranchPredictorType BPRED_TYPE;
int BPRED_NUM_LHR;
int BPRED_SIZE;
int BTB_SIZE;