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-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-25 18:14:18 +00:00
logic PredValidF ;
2023-01-05 19:36:51 +00:00
logic [ 1 : 0 ] DirPredictionF ;
2021-02-14 16:47:01 +00:00
2023-01-26 01:39:18 +00:00
logic [ 3 : 0 ] BTBPredInstrClassF , PredInstrClassF , PredInstrClassD , PredInstrClassE ;
2023-01-25 22:03:02 +00:00
logic [ `XLEN - 1 : 0 ] PredPCF , RASPCF ;
2021-10-27 19:43:55 +00:00
logic TargetWrongE ;
logic FallThroughWrongE ;
logic PredictionPCWrongE ;
logic PredictionInstrClassWrongE ;
2023-01-26 01:39:18 +00:00
logic [ 3 : 0 ] InstrClassF , InstrClassD , InstrClassE , InstrClassW ;
2023-01-05 19:36:51 +00:00
logic DirPredictionWrongE , BTBPredPCWrongE , RASPredPCWrongE , BPPredClassNonCFIWrongE ;
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-01-14 00:05:47 +00:00
logic [ 3 : 0 ] WrongPredInstrClassD ;
2023-01-26 19:21:16 +00:00
logic BTBTargetWrongE ;
logic RASTargetWrongE ;
logic JumpOrTakenBranchE ;
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-01-29 22:26:44 +00:00
globalhistory # ( `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 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-01-13 18:57:18 +00:00
. BranchInstrF ( PredInstrClassF [ 0 ] ) , . BranchInstrD ( InstrClassD [ 0 ] ) , . BranchInstrE ( InstrClassE [ 0 ] ) , . BranchInstrM ( InstrClassM [ 0 ] ) ,
2023-01-25 22:03:02 +00:00
. BranchInstrW ( InstrClassW [ 0 ] ) , . WrongPredInstrClassD , . PCSrcE ) ;
2023-01-29 04:06:12 +00:00
end else if ( `BPRED_TYPE = = " BPGSHARE " ) begin : Predictor
2023-01-29 22:26:44 +00:00
gshare # ( `BPRED_SIZE ) DirPredictor ( . clk , . reset , . StallF , . StallD , . StallE , . StallM , . FlushD , . FlushE , . FlushM ,
2023-01-25 23:06:25 +00:00
. PCNextF , . PCE , . 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-01-05 20:18:00 +00:00
. PCNextF , . PCF , . PCD , . PCE , . PCM , . DirPredictionF , . DirPredictionWrongE ,
2023-01-31 05:51:04 +00:00
. InstrClassF ( PredInstrClassF ) , . InstrClassD , . InstrClassE , . WrongPredInstrClassD , . PCSrcE ) ;
2023-01-05 20:18:00 +00:00
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-02-14 16:47:01 +00:00
// this predictor will have two pieces of data,
// 1) A direction (1 = Taken, 0 = Not Taken)
2022-05-16 22:41:18 +00:00
// 2) Any information which is necessary for the predictor to build its next state.
2021-02-14 16:47:01 +00:00
// For a 2 bit table this is the prediction count.
2021-03-04 15:23:35 +00:00
// Part 2 Branch target address prediction
2021-02-14 16:47:01 +00:00
// *** For now the BTB will house the direct and indirect targets
2023-01-25 22:03:02 +00:00
btb TargetPredictor ( . clk , . reset , . StallF , . StallD , . StallM , . FlushD , . FlushM ,
. PCNextF , . PCF , . PCD , . PCE ,
. PredPCF ,
2023-01-26 01:39:18 +00:00
. BTBPredInstrClassF ,
2023-01-25 18:14:18 +00:00
. PredValidF ,
2023-01-25 21:29:55 +00:00
. PredictionInstrClassWrongE ,
2023-01-24 22:12:35 +00:00
. IEUAdrE ,
. InstrClassE ) ;
2021-02-14 16:47:01 +00:00
2021-03-04 15:23:35 +00:00
// Part 3 RAS
2021-02-15 20:51:39 +00:00
// *** need to add the logic to restore RAS on flushes. We will use incr for this.
2023-01-13 21:19:53 +00:00
// *** needs to include flushX
2023-01-25 23:10:52 +00:00
RASPredictor RASPredictor ( . clk , . reset , . StallF , . StallD , . StallE , . StallM , . FlushD , . FlushE , . FlushM ,
2023-01-25 23:06:25 +00:00
. PredInstrClassF , . InstrClassD , . InstrClassE ,
. WrongPredInstrClassD , . RASPCF , . PCLinkE ) ;
2021-02-14 16:47:01 +00:00
2023-01-25 22:03:02 +00:00
assign BPPredPCF = PredInstrClassF [ 2 ] ? RASPCF : PredPCF ;
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 ;
logic [ 3 : 0 ] InstrClassF ;
logic cjal , cj , cjr , cjalr ;
assign CompressedOpcF = { PostSpillInstrRawF [ 1 : 0 ] , PostSpillInstrRawF [ 15 : 13 ] } ;
assign cjal = CompressedOpcF = = 5 'h09 & `XLEN = = 32 ;
assign cj = CompressedOpcF = = 5 'h0d ;
assign cjr = CompressedOpcF = = 5 'h14 & ~ PostSpillInstrRawF [ 12 ] & PostSpillInstrRawF [ 6 : 2 ] = = 5 'b0 & PostSpillInstrRawF [ 11 : 7 ] ! = 5 'b0 ;
assign cjalr = CompressedOpcF = = 5 'h14 & PostSpillInstrRawF [ 12 ] & PostSpillInstrRawF [ 6 : 2 ] = = 5 'b0 & PostSpillInstrRawF [ 11 : 7 ] ! = 5 'b0 ;
assign InstrClassF [ 0 ] = PostSpillInstrRawF [ 6 : 0 ] = = 7 'h63 |
2023-01-26 18:19:33 +00:00
( `C_SUPPORTED & CompressedOpcF [ 4 : 1 ] = = 4 'h7 ) ;
2023-01-26 01:39:18 +00:00
assign InstrClassF [ 1 ] = ( PostSpillInstrRawF [ 6 : 0 ] = = 7 'h67 & ( PostSpillInstrRawF [ 19 : 15 ] & 5 'h1B ) ! = 5 'h01 & ( PostSpillInstrRawF [ 11 : 7 ] & 5 'h1B ) ! = 5 'h01 ) | // jump register, but not return
( PostSpillInstrRawF [ 6 : 0 ] = = 7 'h6F & ( PostSpillInstrRawF [ 11 : 7 ] & 5 'h1B ) ! = 5 'h01 ) | // jump, RD != x1 or x5
( `C_SUPPORTED & ( cj | ( cjr & ( ( PostSpillInstrRawF [ 11 : 7 ] & 5 'h1B ) ! = 5 'h01 ) ) ) ) ;
assign InstrClassF [ 2 ] = PostSpillInstrRawF [ 6 : 0 ] = = 7 'h67 & ( PostSpillInstrRawF [ 19 : 15 ] & 5 'h1B ) = = 5 'h01 | // return must return to ra or r5
( `C_SUPPORTED & ( cjalr | cjr ) & ( ( PostSpillInstrRawF [ 11 : 7 ] & 5 'h1B ) = = 5 'h01 ) ) ;
assign InstrClassF [ 3 ] = ( ( PostSpillInstrRawF [ 6 : 0 ] & 7 'h77 ) = = 7 'h67 & ( PostSpillInstrRawF [ 11 : 07 ] & 5 'h1B ) = = 5 'h01 ) | // jal(r) must link to ra or x5
2023-01-26 17:07:47 +00:00
( `C_SUPPORTED & ( cjal | ( cjalr & ( PostSpillInstrRawF [ 11 : 7 ] & 5 'h1b ) = = 5 'h01 ) ) ) ;
2023-01-26 01:39:18 +00:00
assign PredInstrClassF = InstrClassF ;
2023-01-26 16:54:43 +00:00
assign SelBPPredF = ( PredInstrClassF [ 0 ] & DirPredictionF [ 1 ] ) |
PredInstrClassF [ 2 ] |
( PredInstrClassF [ 1 ] ) ;
2023-01-26 01:39:18 +00:00
end else begin
assign PredInstrClassF = BTBPredInstrClassF ;
2023-01-26 16:54:43 +00:00
assign SelBPPredF = ( PredInstrClassF [ 0 ] & DirPredictionF [ 1 ] & PredValidF ) |
PredInstrClassF [ 2 ] |
( PredInstrClassF [ 1 ] & PredValidF ) ;
2023-01-26 01:39:18 +00:00
end
2023-01-13 21:19:53 +00:00
assign InstrClassD [ 3 ] = ( InstrD [ 6 : 0 ] & 7 'h77 ) = = 7 'h67 & ( InstrD [ 11 : 07 ] & 5 'h1B ) = = 5 'h01 ; // jal(r) must link to ra or x5
assign InstrClassD [ 2 ] = InstrD [ 6 : 0 ] = = 7 'h67 & ( InstrD [ 19 : 15 ] & 5 'h1B ) = = 5 'h01 ; // return must return to ra or r5
assign InstrClassD [ 1 ] = ( InstrD [ 6 : 0 ] = = 7 'h67 & ( InstrD [ 19 : 15 ] & 5 'h1B ) ! = 5 'h01 & ( InstrD [ 11 : 7 ] & 5 'h1B ) ! = 5 'h01 ) | // jump register, but not return
( InstrD [ 6 : 0 ] = = 7 'h6F & ( InstrD [ 11 : 7 ] & 5 'h1B ) ! = 5 'h01 ) ; // jump, RD != x1 or x5
2022-02-01 20:32:27 +00:00
assign InstrClassD [ 0 ] = InstrD [ 6 : 0 ] = = 7 'h63 ; // branch
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 ) ;
flopenrc # ( 4 ) InstrClassRegW ( clk , reset , FlushW , ~ StallW , InstrClassM , InstrClassW ) ;
2022-12-23 02:33:38 +00:00
flopenrc # ( 1 ) BPPredWrongMReg ( clk , reset , FlushM , ~ StallM , BPPredWrongE , BPPredWrongM ) ;
2023-01-26 19:21:16 +00:00
flopenrc # ( 1 ) JumpOrTakenBranchMReg ( clk , reset , FlushM , ~ StallM , JumpOrTakenBranchE , JumpOrTakenBranchM ) ;
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-01-05 23:19:27 +00:00
{ DirPredictionWrongE , BTBPredPCWrongE , RASPredPCWrongE , PredictionInstrClassWrongE } ,
{ DirPredictionWrongM , BTBPredPCWrongM , RASPredPCWrongM , PredictionInstrClassWrongM } ) ;
2022-02-01 20:32:27 +00:00
2021-02-14 16:47:01 +00:00
// pipeline the class
2023-01-13 21:19:53 +00:00
flopenrc # ( 4 ) PredInstrClassRegD ( clk , reset , FlushD , ~ StallD , PredInstrClassF , PredInstrClassD ) ;
flopenrc # ( 4 ) PredInstrClassRegE ( clk , reset , FlushE , ~ StallE , PredInstrClassD , PredInstrClassE ) ;
2021-03-31 16:54:02 +00:00
2022-12-23 02:33:38 +00:00
// Check the prediction
2021-03-31 16:54:02 +00:00
// first check if the target or fallthrough address matches what was predicted.
2021-12-15 20:10:45 +00:00
assign TargetWrongE = IEUAdrE ! = PCD ;
2021-02-14 16:47:01 +00:00
assign FallThroughWrongE = PCLinkE ! = PCD ;
2021-03-31 16:54:02 +00:00
// If the target is taken check the target rather than fallthrough. The instruction needs to be a branch if PCSrcE is selected
// Remember the bpred can incorrectly predict a non cfi instruction as a branch taken. If the real instruction is non cfi
2021-08-27 20:00:40 +00:00
// it must have selected the fall through.
2021-03-31 16:54:02 +00:00
assign PredictionPCWrongE = ( PCSrcE & ( | InstrClassE ) ? TargetWrongE : FallThroughWrongE ) ;
// The branch direction also need to checked.
// However if the direction is wrong then the pc will be wrong. This is only relavent to checking the
// accuracy of the direciton prediction.
2023-01-05 19:36:51 +00:00
//assign DirPredictionWrongE = (BPPredE[1] ^ PCSrcE) & InstrClassE[0];
2021-03-31 16:54:02 +00:00
// Finally we need to check if the class is wrong. When the class is wrong the BTB needs to be updated.
// Also we want to track this in a performance counter.
2023-01-13 18:57:18 +00:00
assign PredictionInstrClassWrongE = InstrClassE ! = PredInstrClassE ;
2021-02-14 16:47:01 +00:00
2021-03-31 16:54:02 +00:00
// We want to output to the instruction fetch if the PC fetched was wrong. If by chance the predictor was wrong about
// the direction or class, but correct about the target we don't have the flush the pipeline. However we still
// need this information to verify the accuracy of the predictors.
assign BPPredWrongE = ( PredictionPCWrongE & | InstrClassE ) | BPPredClassNonCFIWrongE ;
2021-02-14 16:47:01 +00:00
2021-03-31 16:54:02 +00:00
// If we have a jump, jump register or jal or jalr and the PC is wrong we need to increment the performance counter.
2023-01-26 19:21:16 +00:00
//assign BTBPredPCWrongE = (InstrClassE[3] | InstrClassE[1] | InstrClassE[0]) & PredictionPCWrongE;
//assign BTBPredPCWrongE = TargetWrongE & (InstrClassE[3] | InstrClassE[1] | InstrClassE[0]) & PCSrcE;
assign BTBPredPCWrongE = BTBTargetWrongE ;
2023-01-26 00:51:09 +00:00
// similar with RAS. Over counts ras if the class prediction was wrong.
2023-01-26 19:21:16 +00:00
//assign RASPredPCWrongE = TargetWrongE & InstrClassE[2] & PCSrcE;
assign RASPredPCWrongE = RASTargetWrongE ;
2021-03-31 16:54:02 +00:00
// Finally if the real instruction class is non CFI but the predictor said it was we need to count.
assign BPPredClassNonCFIWrongE = PredictionInstrClassWrongE & ~ | InstrClassE ;
2023-01-14 00:05:47 +00:00
// branch class prediction wrong.
assign WrongPredInstrClassD = PredInstrClassD ^ InstrClassD ;
2021-03-31 16:54:02 +00:00
2022-12-20 18:58:54 +00:00
// Selects the BP or PC+2/4.
2022-12-23 02:33:38 +00:00
mux2 # ( `XLEN ) pcmux0 ( PCPlus2or4F , BPPredPCF , SelBPPredF , PCNext0F ) ;
2022-12-20 18:58:54 +00:00
// If the prediction is wrong select the correct address.
2022-12-23 02:33:38 +00:00
mux2 # ( `XLEN ) pcmux1 ( PCNext0F , PCCorrectE , BPPredWrongE , PCNext1F ) ;
2022-12-20 18:58:54 +00:00
// Correct branch/jump target.
2022-12-23 02:33:38 +00:00
mux2 # ( `XLEN ) pccorrectemux ( PCLinkE , IEUAdrE , PCSrcE , PCCorrectE ) ;
2022-12-20 18:58:54 +00:00
2022-12-20 05:16:58 +00:00
// If the fence/csrw was predicted as a taken branch then we select PCF, rather PCE.
2022-12-23 02:33:38 +00:00
// Effectively this is PCM+4 or the non-existant PCLinkM
// if(`BPCLASS) begin
mux2 # ( `XLEN ) pcmuxBPWrongInvalidateFlush ( PCE , PCF , BPPredWrongM , NextValidPCE ) ;
// end else begin
// assign NextValidPCE = PCE;
// end
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-01-26 19:21:16 +00:00
assign BTBTargetWrongE = ( PredPCE ! = IEUAdrE ) & ( InstrClassE [ 0 ] | InstrClassE [ 1 ] | InstrClassE [ 3 ] ) & PCSrcE ;
assign RASTargetWrongE = ( RASPCE ! = IEUAdrE ) & InstrClassE [ 2 ] & PCSrcE ;
assign JumpOrTakenBranchE = ( InstrClassE [ 0 ] & PCSrcE ) | InstrClassE [ 1 ] | InstrClassE [ 3 ] ;
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