2021-02-14 16:47:01 +00:00
|
|
|
///////////////////////////////////////////
|
|
|
|
// bpred.sv
|
|
|
|
//
|
2023-01-19 21:06:37 +00:00
|
|
|
// Written: Ross Thomposn ross1728@gmail.com
|
|
|
|
// Created: 12 February 2021
|
|
|
|
// Modified: 19 January 2023
|
2021-02-14 16:47:01 +00:00
|
|
|
//
|
2023-01-19 21:06:37 +00:00
|
|
|
// Purpose: Branch direction prediction and jump/branch target prediction.
|
|
|
|
// Prediction made during the fetch stage and corrected in the execution stage.
|
2021-02-14 16:47:01 +00:00
|
|
|
//
|
2023-01-11 23:15:08 +00:00
|
|
|
// A component of the CORE-V-WALLY configurable RISC-V project.
|
2021-02-14 16:47:01 +00:00
|
|
|
//
|
2023-01-10 19:35:20 +00:00
|
|
|
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
2021-02-14 16:47:01 +00:00
|
|
|
//
|
2023-01-10 19:35:20 +00:00
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
2021-02-14 16:47:01 +00:00
|
|
|
//
|
2023-01-10 19:35:20 +00:00
|
|
|
// 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
|
2021-02-14 16:47:01 +00:00
|
|
|
//
|
2023-01-10 19:35:20 +00:00
|
|
|
// 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.
|
2022-01-07 12:58:40 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
2021-02-14 16:47:01 +00:00
|
|
|
|
|
|
|
`include "wally-config.vh"
|
|
|
|
|
2023-01-29 21:03:25 +00:00
|
|
|
`define INSTR_CLASS_PRED 1
|
2023-01-26 01:39:18 +00:00
|
|
|
|
2022-12-23 03:36:49 +00:00
|
|
|
module bpred (
|
2023-01-24 14:14:31 +00:00
|
|
|
input logic clk, reset,
|
|
|
|
input logic StallF, StallD, StallE, StallM, StallW,
|
|
|
|
input logic FlushD, FlushE, FlushM, FlushW,
|
2023-01-24 13:42:34 +00:00
|
|
|
// Fetch stage
|
|
|
|
// the prediction
|
2023-01-24 14:14:31 +00:00
|
|
|
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
|
2023-01-24 13:42:34 +00:00
|
|
|
output logic [`XLEN-1:0] PCNext1F, // 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
|
2022-12-20 04:51:55 +00:00
|
|
|
|
2023-01-24 13:42:34 +00:00
|
|
|
// Update Predictor
|
2023-01-24 14:14:31 +00:00
|
|
|
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
|
2022-12-20 04:51:55 +00:00
|
|
|
|
2023-01-29 21:24:20 +00:00
|
|
|
input logic [31:0] PostSpillInstrRawF, // Instruction
|
|
|
|
|
2023-01-24 13:42:34 +00:00
|
|
|
// Branch and jump outcome
|
2023-02-10 16:33:10 +00:00
|
|
|
input logic InstrValidD, InstrValidE,
|
2023-02-10 21:45:56 +00:00
|
|
|
input logic BranchD, BranchE,
|
|
|
|
input logic JumpD, JumpE,
|
2023-01-29 21:24:20 +00:00
|
|
|
input logic PCSrcE, // Executation stage branch is taken
|
|
|
|
input logic [`XLEN-1:0] IEUAdrE, // The branch/jump target address
|
|
|
|
input logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
|
2023-01-24 13:42:34 +00:00
|
|
|
output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br
|
2023-01-29 21:24:20 +00:00
|
|
|
output logic JumpOrTakenBranchM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br
|
2022-12-23 03:36:49 +00:00
|
|
|
|
2023-01-24 13:42:34 +00:00
|
|
|
// Report branch prediction status
|
|
|
|
output logic BPPredWrongE, // Prediction is wrong
|
2023-01-29 21:24:20 +00:00
|
|
|
output logic BPPredWrongM, // Prediction is wrong
|
2023-01-24 13:42:34 +00:00
|
|
|
output logic DirPredictionWrongM, // Prediction direction is wrong
|
|
|
|
output logic BTBPredPCWrongM, // Prediction target wrong
|
|
|
|
output logic RASPredPCWrongM, // RAS prediction is wrong
|
|
|
|
output logic PredictionInstrClassWrongM // Class prediction is wrong
|
2023-01-29 21:24:20 +00:00
|
|
|
);
|
2021-02-14 16:47:01 +00:00
|
|
|
|
2023-01-05 19:36:51 +00:00
|
|
|
logic [1:0] DirPredictionF;
|
2021-02-14 16:47:01 +00:00
|
|
|
|
2023-02-18 13:59:25 +00:00
|
|
|
logic [3:0] BTBPredInstrClassF, PredInstrClassF, PredInstrClassD;
|
2023-01-25 22:03:02 +00:00
|
|
|
logic [`XLEN-1:0] PredPCF, RASPCF;
|
2021-10-27 19:43:55 +00:00
|
|
|
logic PredictionPCWrongE;
|
2023-02-09 00:24:38 +00:00
|
|
|
logic AnyWrongPredInstrClassD, AnyWrongPredInstrClassE;
|
2023-02-12 17:33:43 +00:00
|
|
|
logic [3:0] InstrClassD;
|
|
|
|
logic [3:0] InstrClassE;
|
2023-02-09 00:24:38 +00:00
|
|
|
logic DirPredictionWrongE, BTBPredPCWrongE, RASPredPCWrongE;
|
2021-03-24 02:49:16 +00:00
|
|
|
|
2022-12-20 04:46:11 +00:00
|
|
|
logic SelBPPredF;
|
|
|
|
logic [`XLEN-1:0] BPPredPCF;
|
2022-12-20 05:16:58 +00:00
|
|
|
logic [`XLEN-1:0] PCNext0F;
|
2022-12-20 18:58:54 +00:00
|
|
|
logic [`XLEN-1:0] PCCorrectE;
|
2023-02-13 22:14:17 +00:00
|
|
|
logic [3:0] WrongPredInstrClassD;
|
2023-01-26 19:21:16 +00:00
|
|
|
|
2023-02-12 17:33:43 +00:00
|
|
|
logic BTBTargetWrongE;
|
|
|
|
logic RASTargetWrongE;
|
|
|
|
logic JumpOrTakenBranchE;
|
2023-01-26 19:21:16 +00:00
|
|
|
|
|
|
|
logic [`XLEN-1:0] PredPCD, PredPCE, RASPCD, RASPCE;
|
|
|
|
|
2021-03-04 15:23:35 +00:00
|
|
|
// Part 1 branch direction prediction
|
2022-12-20 18:58:54 +00:00
|
|
|
// look into the 2 port Sram model. something is wrong.
|
2023-01-29 04:06:12 +00:00
|
|
|
if (`BPRED_TYPE == "BPTWOBIT") begin:Predictor
|
2023-01-29 22:26:44 +00:00
|
|
|
twoBitPredictor #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
|
2023-01-05 19:36:51 +00:00
|
|
|
.PCNextF, .PCM, .DirPredictionF, .DirPredictionWrongE,
|
2023-01-05 19:27:22 +00:00
|
|
|
.BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE);
|
2021-03-16 20:06:40 +00:00
|
|
|
|
2023-01-29 04:06:12 +00:00
|
|
|
end else if (`BPRED_TYPE == "BPGLOBAL") begin:Predictor
|
2023-02-19 05:55:46 +00:00
|
|
|
globalhistory #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
2023-02-17 22:05:48 +00:00
|
|
|
.DirPredictionF, .DirPredictionWrongE,
|
2023-01-05 05:41:55 +00:00
|
|
|
.BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE);
|
2021-03-16 20:06:40 +00:00
|
|
|
|
2023-01-29 04:06:12 +00:00
|
|
|
end else if (`BPRED_TYPE == "BPSPECULATIVEGLOBAL") begin:Predictor
|
2023-01-29 22:26:44 +00:00
|
|
|
speculativeglobalhistory #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
|
|
|
.DirPredictionF, .DirPredictionWrongE,
|
2023-02-14 00:08:51 +00:00
|
|
|
.PredInstrClassF, .InstrClassD, .InstrClassE, .InstrClassM, .WrongPredInstrClassD, .PCSrcE);
|
2023-01-25 22:03:02 +00:00
|
|
|
|
2023-01-29 04:06:12 +00:00
|
|
|
end else if (`BPRED_TYPE == "BPGSHARE") begin:Predictor
|
2023-02-14 00:52:52 +00:00
|
|
|
gshare #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
|
|
|
.PCNextF, .PCM, .DirPredictionF, .DirPredictionWrongE,
|
2023-01-05 05:51:09 +00:00
|
|
|
.BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE);
|
2023-01-05 20:18:00 +00:00
|
|
|
|
2023-01-29 04:06:12 +00:00
|
|
|
end else if (`BPRED_TYPE == "BPSPECULATIVEGSHARE") begin:Predictor
|
2023-01-29 22:26:44 +00:00
|
|
|
speculativegshare #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
2023-02-01 16:27:58 +00:00
|
|
|
.PCNextF, .PCF, .PCD, .PCE, .DirPredictionF, .DirPredictionWrongE,
|
2023-02-13 17:57:25 +00:00
|
|
|
.PredInstrClassF, .InstrClassD, .InstrClassE, .InstrClassM, .WrongPredInstrClassD, .PCSrcE);
|
2023-01-05 20:18:00 +00:00
|
|
|
|
2023-02-20 04:49:48 +00:00
|
|
|
end else if (`BPRED_TYPE == "BP_GSHARE_FORWARD") begin:Predictor
|
2023-02-19 06:17:37 +00:00
|
|
|
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);
|
|
|
|
|
2023-01-29 04:06:12 +00:00
|
|
|
end else if (`BPRED_TYPE == "BPLOCALPAg") begin:Predictor
|
2023-01-05 20:04:09 +00:00
|
|
|
// *** Fix me
|
|
|
|
/* -----\/----- EXCLUDED -----\/-----
|
2022-02-01 20:32:27 +00:00
|
|
|
localHistoryPredictor DirPredictor(.clk,
|
2022-12-11 22:28:11 +00:00
|
|
|
.reset, .StallF, .StallE,
|
2022-01-05 16:25:08 +00:00
|
|
|
.LookUpPC(PCNextF),
|
2023-01-05 19:27:22 +00:00
|
|
|
.Prediction(DirPredictionF),
|
2022-01-05 16:25:08 +00:00
|
|
|
// update
|
|
|
|
.UpdatePC(PCE),
|
|
|
|
.UpdateEN(InstrClassE[0] & ~StallE),
|
2022-02-01 20:32:27 +00:00
|
|
|
.PCSrcE,
|
2023-01-05 20:04:09 +00:00
|
|
|
.UpdatePrediction(InstrClassE[0]));
|
|
|
|
-----/\----- EXCLUDED -----/\----- */
|
2022-01-05 16:25:08 +00:00
|
|
|
end
|
2021-03-16 20:06:40 +00:00
|
|
|
|
2021-03-04 15:23:35 +00:00
|
|
|
// Part 2 Branch target address prediction
|
2023-02-09 00:24:38 +00:00
|
|
|
// BTB contains target address for all CFI
|
2021-02-14 16:47:01 +00:00
|
|
|
|
2023-02-20 04:13:50 +00:00
|
|
|
btb #(`BTB_SIZE)
|
2023-02-20 03:59:07 +00:00
|
|
|
TargetPredictor(.clk, .reset, .StallF, .StallD, .StallM, .FlushD, .FlushM,
|
2023-01-25 22:03:02 +00:00
|
|
|
.PCNextF, .PCF, .PCD, .PCE,
|
|
|
|
.PredPCF,
|
2023-01-26 01:39:18 +00:00
|
|
|
.BTBPredInstrClassF,
|
2023-02-09 00:24:38 +00:00
|
|
|
.AnyWrongPredInstrClassE,
|
2023-01-24 22:12:35 +00:00
|
|
|
.IEUAdrE,
|
2023-02-01 04:03:51 +00:00
|
|
|
.InstrClassD,
|
2023-01-24 22:12:35 +00:00
|
|
|
.InstrClassE);
|
2021-02-14 16:47:01 +00:00
|
|
|
|
2022-02-01 20:32:27 +00:00
|
|
|
// the branch predictor needs a compact decoding of the instruction class.
|
2023-01-26 01:39:18 +00:00
|
|
|
if (`INSTR_CLASS_PRED == 0) begin : DirectClassDecode
|
|
|
|
logic [4:0] CompressedOpcF;
|
2023-02-13 23:23:56 +00:00
|
|
|
logic [3:0] InstrClassF;
|
2023-02-12 17:33:43 +00:00
|
|
|
logic cjal, cj, cjr, cjalr, CJumpF, CBranchF;
|
|
|
|
logic JumpF, BranchF;
|
2023-01-26 01:39:18 +00:00
|
|
|
|
|
|
|
assign CompressedOpcF = {PostSpillInstrRawF[1:0], PostSpillInstrRawF[15:13]};
|
|
|
|
|
|
|
|
assign cjal = CompressedOpcF == 5'h09 & `XLEN == 32;
|
|
|
|
assign cj = CompressedOpcF == 5'h0d;
|
|
|
|
assign cjr = CompressedOpcF == 5'h14 & ~PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0;
|
|
|
|
assign cjalr = CompressedOpcF == 5'h14 & PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0;
|
2023-02-12 17:33:43 +00:00
|
|
|
assign CJumpF = cjal | cj | cjr | cjalr;
|
|
|
|
assign CBranchF = CompressedOpcF[4:1] == 4'h7;
|
|
|
|
|
|
|
|
assign JumpF = PostSpillInstrRawF[6:0] == 7'h67 | PostSpillInstrRawF[6:0] == 7'h6F;
|
|
|
|
assign BranchF = PostSpillInstrRawF[6:0] == 7'h63;
|
2023-01-26 01:39:18 +00:00
|
|
|
|
2023-02-12 17:33:43 +00:00
|
|
|
assign InstrClassF[0] = BranchF | (`C_SUPPORTED & CBranchF);
|
|
|
|
assign InstrClassF[1] = JumpF | (`C_SUPPORTED & (cjal | cj | cj | cjalr));
|
|
|
|
assign InstrClassF[2] = (JumpF & (PostSpillInstrRawF[19:15] & 5'h1B) == 5'h01) | // return must return to ra or r5
|
2023-01-26 01:39:18 +00:00
|
|
|
(`C_SUPPORTED & (cjalr | cjr) & ((PostSpillInstrRawF[11:7] & 5'h1B) == 5'h01));
|
|
|
|
|
2023-02-13 23:23:56 +00:00
|
|
|
assign InstrClassF[3] = (JumpF & (PostSpillInstrRawF[11:07] & 5'h1B) == 5'h01) | // jal(r) must link to ra or x5
|
2023-02-13 22:14:17 +00:00
|
|
|
(`C_SUPPORTED & (cjal | (cjalr & (PostSpillInstrRawF[11:7] & 5'h1b) == 5'h01)));
|
2023-02-13 23:23:56 +00:00
|
|
|
|
2023-02-13 22:14:17 +00:00
|
|
|
assign PredInstrClassF = InstrClassF;
|
|
|
|
assign SelBPPredF = (PredInstrClassF[0] & DirPredictionF[1]) |
|
2023-02-13 23:29:51 +00:00
|
|
|
PredInstrClassF[1];
|
2023-02-13 22:14:17 +00:00
|
|
|
end else begin
|
|
|
|
assign PredInstrClassF = BTBPredInstrClassF;
|
2023-02-20 05:53:10 +00:00
|
|
|
assign SelBPPredF = (PredInstrClassF[0] & DirPredictionF[1]) |
|
|
|
|
PredInstrClassF[1];
|
2023-02-13 22:14:17 +00:00
|
|
|
end
|
2023-01-26 01:39:18 +00:00
|
|
|
|
2023-01-31 05:55:52 +00:00
|
|
|
// Part 3 RAS
|
|
|
|
RASPredictor RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
|
|
|
|
.PredInstrClassF, .InstrClassD, .InstrClassE,
|
|
|
|
.WrongPredInstrClassD, .RASPCF, .PCLinkE);
|
|
|
|
|
|
|
|
assign BPPredPCF = PredInstrClassF[2] ? RASPCF : PredPCF;
|
2023-01-26 01:39:18 +00:00
|
|
|
|
2023-02-10 21:45:56 +00:00
|
|
|
assign InstrClassD[0] = BranchD;
|
|
|
|
assign InstrClassD[1] = JumpD ;
|
|
|
|
assign InstrClassD[2] = JumpD & (InstrD[19:15] & 5'h1B) == 5'h01; // return must return to ra or x5
|
|
|
|
assign InstrClassD[3] = JumpD & (InstrD[11:7] & 5'h1B) == 5'h01; // jal(r) must link to ra or x5
|
2023-02-13 23:10:24 +00:00
|
|
|
|
2023-01-13 21:19:53 +00:00
|
|
|
flopenrc #(4) InstrClassRegE(clk, reset, FlushE, ~StallE, InstrClassD, InstrClassE);
|
|
|
|
flopenrc #(4) InstrClassRegM(clk, reset, FlushM, ~StallM, InstrClassE, InstrClassM);
|
2022-12-23 02:33:38 +00:00
|
|
|
flopenrc #(1) BPPredWrongMReg(clk, reset, FlushM, ~StallM, BPPredWrongE, BPPredWrongM);
|
2022-02-01 20:32:27 +00:00
|
|
|
|
|
|
|
// branch predictor
|
2022-12-23 02:33:38 +00:00
|
|
|
flopenrc #(4) BPPredWrongRegM(clk, reset, FlushM, ~StallM,
|
2023-02-09 00:24:38 +00:00
|
|
|
{DirPredictionWrongE, BTBPredPCWrongE, RASPredPCWrongE, AnyWrongPredInstrClassE},
|
2023-01-05 23:19:27 +00:00
|
|
|
{DirPredictionWrongM, BTBPredPCWrongM, RASPredPCWrongM, PredictionInstrClassWrongM});
|
2022-02-01 20:32:27 +00:00
|
|
|
|
2021-02-14 16:47:01 +00:00
|
|
|
// pipeline the class
|
2023-02-13 22:14:17 +00:00
|
|
|
flopenrc #(4) PredInstrClassRegD(clk, reset, FlushD, ~StallD, PredInstrClassF, PredInstrClassD);
|
2023-02-13 23:23:56 +00:00
|
|
|
flopenrc #(1) WrongInstrClassRegE(clk, reset, FlushE, ~StallE, AnyWrongPredInstrClassD, AnyWrongPredInstrClassE);
|
2023-02-18 13:59:25 +00:00
|
|
|
|
2022-12-23 02:33:38 +00:00
|
|
|
// Check the prediction
|
2023-02-07 20:01:59 +00:00
|
|
|
// if it is a CFI then check if the next instruction address (PCD) matches the branch's target or fallthrough address.
|
|
|
|
// if the class prediction is wrong a regular instruction may have been predicted as a taken branch
|
|
|
|
// this will result in PCD not being equal to the fall through address PCLinkE (PCE+4).
|
|
|
|
// The next instruction is always valid as no other flush would occur at the same time as the branch and not
|
|
|
|
// also flush the branch. This will change in a superscaler cpu.
|
|
|
|
assign PredictionPCWrongE = PCCorrectE != PCD;
|
|
|
|
|
2023-02-09 00:24:38 +00:00
|
|
|
// branch class prediction wrong.
|
2023-02-13 22:14:17 +00:00
|
|
|
assign WrongPredInstrClassD = PredInstrClassD ^ InstrClassD[3:0];
|
2023-02-09 00:24:38 +00:00
|
|
|
assign AnyWrongPredInstrClassD = |WrongPredInstrClassD;
|
|
|
|
|
2023-02-10 16:33:10 +00:00
|
|
|
// branch is wrong only if the PC does not match and both the Decode and Fetch stages have valid instructions.
|
2023-02-17 21:37:03 +00:00
|
|
|
//assign BPPredWrongE = (PredictionPCWrongE & |InstrClassE | (AnyWrongPredInstrClassE & ~|InstrClassE));
|
2023-02-17 16:57:50 +00:00
|
|
|
assign BPPredWrongE = PredictionPCWrongE & InstrValidE & InstrValidD;
|
2023-02-07 20:01:59 +00:00
|
|
|
|
2023-02-17 21:37:03 +00:00
|
|
|
logic BPPredWrongEAlt;
|
|
|
|
logic NotMatch;
|
|
|
|
assign BPPredWrongEAlt = PredictionPCWrongE & InstrValidE & InstrValidD; // this does not work for cubic benchmark
|
|
|
|
assign NotMatch = BPPredWrongE != BPPredWrongEAlt;
|
|
|
|
|
2023-02-07 20:01:59 +00:00
|
|
|
// Output the predicted PC or corrected PC on miss-predict.
|
|
|
|
// Selects the BP or PC+2/4.
|
|
|
|
mux2 #(`XLEN) pcmux0(PCPlus2or4F, BPPredPCF, SelBPPredF, PCNext0F);
|
|
|
|
// If the prediction is wrong select the correct address.
|
|
|
|
mux2 #(`XLEN) pcmux1(PCNext0F, PCCorrectE, BPPredWrongE, PCNext1F);
|
|
|
|
// Correct branch/jump target.
|
|
|
|
mux2 #(`XLEN) pccorrectemux(PCLinkE, IEUAdrE, PCSrcE, PCCorrectE);
|
2021-03-31 16:54:02 +00:00
|
|
|
|
2023-02-07 20:01:59 +00:00
|
|
|
// If the fence/csrw was predicted as a taken branch then we select PCF, rather PCE.
|
|
|
|
// Effectively this is PCM+4 or the non-existant PCLinkM
|
|
|
|
if(`INSTR_CLASS_PRED) mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPPredWrongM, NextValidPCE);
|
|
|
|
else assign NextValidPCE = PCE;
|
|
|
|
|
2023-01-25 23:06:25 +00:00
|
|
|
// performance counters
|
2023-01-26 19:21:16 +00:00
|
|
|
// 1. class (class wrong / minstret) (PredictionInstrClassWrongM / csr) // Correct now
|
2023-01-25 23:06:25 +00:00
|
|
|
// 2. target btb (btb target wrong / class[0,1,3]) (btb target wrong / (br + j + jal)
|
|
|
|
// 3. target ras (ras target wrong / class[2])
|
|
|
|
// 4. direction (br dir wrong / class[0])
|
|
|
|
|
2023-02-09 00:24:38 +00:00
|
|
|
// Unforuantely we can't relay on PCD to infer the correctness of the BTB or RAS because the class prediction
|
|
|
|
// could be wrong or the fall through address selected for branch predict not taken.
|
|
|
|
// By pipeline the BTB's PC and RAS address through the pipeline we can measure the accuracy of
|
|
|
|
// both without the above inaccuracies.
|
2023-02-10 21:45:56 +00:00
|
|
|
assign BTBPredPCWrongE = (PredPCE != IEUAdrE) & (InstrClassE[0] | InstrClassE[1] & ~InstrClassE[2]) & PCSrcE;
|
2023-02-09 00:24:38 +00:00
|
|
|
assign RASPredPCWrongE = (RASPCE != IEUAdrE) & InstrClassE[2] & PCSrcE;
|
2023-01-26 19:21:16 +00:00
|
|
|
|
2023-02-10 21:45:56 +00:00
|
|
|
assign JumpOrTakenBranchE = (InstrClassE[0] & PCSrcE) | InstrClassE[1];
|
2023-01-26 19:21:16 +00:00
|
|
|
|
2023-02-09 00:24:38 +00:00
|
|
|
flopenrc #(1) JumpOrTakenBranchMReg(clk, reset, FlushM, ~StallM, JumpOrTakenBranchE, JumpOrTakenBranchM);
|
|
|
|
|
2023-01-26 19:21:16 +00:00
|
|
|
flopenrc #(`XLEN) BTBTargetDReg(clk, reset, FlushD, ~StallD, PredPCF, PredPCD);
|
|
|
|
flopenrc #(`XLEN) BTBTargetEReg(clk, reset, FlushE, ~StallE, PredPCD, PredPCE);
|
|
|
|
|
|
|
|
flopenrc #(`XLEN) RASTargetDReg(clk, reset, FlushD, ~StallD, RASPCF, RASPCD);
|
|
|
|
flopenrc #(`XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE);
|
2022-12-20 18:58:54 +00:00
|
|
|
|
2021-02-14 21:06:53 +00:00
|
|
|
endmodule
|