cpu: Restructure BTB
- A new abstract BTB class is created to enable different BTB implementations. The new BTB class gets its own parameter and stats. - An enum is added to differentiate branch instruction types. This enum is used to enhance statistics and BPU management. - The existing BTB is moved into `simple_btb` as default. - An additional function is added to store the static instruction in the BTB. This function is used for the decoupled front-end. - Update configs to match new BTB parameters. Change-Id: I99b29a19a1b57e59ea2b188ed7d62a8b79426529 Signed-off-by: David Schall <david.schall@ed.ac.uk>
This commit is contained in:
@@ -1679,7 +1679,13 @@ class HPI_MMU(ArmMMU):
|
|||||||
dtb = ArmTLB(entry_type="data", size=256)
|
dtb = ArmTLB(entry_type="data", size=256)
|
||||||
|
|
||||||
|
|
||||||
|
class HPI_BTB(SimpleBTB):
|
||||||
|
numEntries = 128
|
||||||
|
tagBits = 18
|
||||||
|
|
||||||
|
|
||||||
class HPI_BP(TournamentBP):
|
class HPI_BP(TournamentBP):
|
||||||
|
btb = HPI_BTB()
|
||||||
localPredictorSize = 64
|
localPredictorSize = 64
|
||||||
localCtrBits = 2
|
localCtrBits = 2
|
||||||
localHistoryTableSize = 64
|
localHistoryTableSize = 64
|
||||||
@@ -1687,8 +1693,6 @@ class HPI_BP(TournamentBP):
|
|||||||
globalCtrBits = 2
|
globalCtrBits = 2
|
||||||
choicePredictorSize = 1024
|
choicePredictorSize = 1024
|
||||||
choiceCtrBits = 2
|
choiceCtrBits = 2
|
||||||
BTBEntries = 128
|
|
||||||
BTBTagSize = 18
|
|
||||||
RASSize = 8
|
RASSize = 8
|
||||||
instShiftAmt = 2
|
instShiftAmt = 2
|
||||||
|
|
||||||
|
|||||||
@@ -107,14 +107,18 @@ class O3_ARM_v7a_FUP(FUPool):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class O3_ARM_v7a_BTB(SimpleBTB):
|
||||||
|
numEntries = 2048
|
||||||
|
tagBits = 18
|
||||||
|
|
||||||
|
|
||||||
# Bi-Mode Branch Predictor
|
# Bi-Mode Branch Predictor
|
||||||
class O3_ARM_v7a_BP(BiModeBP):
|
class O3_ARM_v7a_BP(BiModeBP):
|
||||||
|
btb = O3_ARM_v7a_BTB()
|
||||||
globalPredictorSize = 8192
|
globalPredictorSize = 8192
|
||||||
globalCtrBits = 2
|
globalCtrBits = 2
|
||||||
choicePredictorSize = 8192
|
choicePredictorSize = 8192
|
||||||
choiceCtrBits = 2
|
choiceCtrBits = 2
|
||||||
BTBEntries = 2048
|
|
||||||
BTBTagSize = 18
|
|
||||||
RASSize = 16
|
RASSize = 16
|
||||||
instShiftAmt = 2
|
instShiftAmt = 2
|
||||||
|
|
||||||
|
|||||||
@@ -104,14 +104,18 @@ class ex5_big_FUP(FUPool):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ex5_big_BTB(SimpleBTB):
|
||||||
|
numEntries = 4096
|
||||||
|
tagBits = 18
|
||||||
|
|
||||||
|
|
||||||
# Bi-Mode Branch Predictor
|
# Bi-Mode Branch Predictor
|
||||||
class ex5_big_BP(BiModeBP):
|
class ex5_big_BP(BiModeBP):
|
||||||
|
btb = ex5_big_BTB()
|
||||||
globalPredictorSize = 4096
|
globalPredictorSize = 4096
|
||||||
globalCtrBits = 2
|
globalCtrBits = 2
|
||||||
choicePredictorSize = 1024
|
choicePredictorSize = 1024
|
||||||
choiceCtrBits = 3
|
choiceCtrBits = 3
|
||||||
BTBEntries = 4096
|
|
||||||
BTBTagSize = 18
|
|
||||||
RASSize = 48
|
RASSize = 48
|
||||||
instShiftAmt = 2
|
instShiftAmt = 2
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
# Copyright (c) 2022-2023 The University of Edinburgh
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# The license below extends only to copyright in the software and shall
|
||||||
|
# not be construed as granting a license to any other intellectual
|
||||||
|
# property including but not limited to intellectual property relating
|
||||||
|
# to a hardware implementation of the functionality of the software
|
||||||
|
# licensed hereunder. You may use the software subject to the license
|
||||||
|
# terms below provided that you ensure that this notice is replicated
|
||||||
|
# unmodified and in its entirety in all distributions of the software,
|
||||||
|
# modified or unmodified, in source code or in binary form.
|
||||||
|
#
|
||||||
# Copyright (c) 2012 Mark D. Hill and David A. Wood
|
# Copyright (c) 2012 Mark D. Hill and David A. Wood
|
||||||
# Copyright (c) 2015 The University of Wisconsin
|
# Copyright (c) 2015 The University of Wisconsin
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
@@ -25,10 +37,46 @@
|
|||||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
from m5.SimObject import SimObject
|
from m5.SimObject import *
|
||||||
from m5.params import *
|
from m5.params import *
|
||||||
from m5.proxy import *
|
from m5.proxy import *
|
||||||
|
|
||||||
|
from m5.objects.ClockedObject import ClockedObject
|
||||||
|
|
||||||
|
|
||||||
|
class BranchType(Enum):
|
||||||
|
vals = [
|
||||||
|
"NoBranch",
|
||||||
|
"Return",
|
||||||
|
"CallDirect",
|
||||||
|
"CallIndirect", # 'Call',
|
||||||
|
"DirectCond",
|
||||||
|
"DirectUncond", # 'Direct',
|
||||||
|
"IndirectCond",
|
||||||
|
"IndirectUncond", #'Indirect',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class BranchTargetBuffer(ClockedObject):
|
||||||
|
type = "BranchTargetBuffer"
|
||||||
|
cxx_class = "gem5::branch_prediction::BranchTargetBuffer"
|
||||||
|
cxx_header = "cpu/pred/btb.hh"
|
||||||
|
abstract = True
|
||||||
|
|
||||||
|
numThreads = Param.Unsigned(Parent.numThreads, "Number of threads")
|
||||||
|
|
||||||
|
|
||||||
|
class SimpleBTB(BranchTargetBuffer):
|
||||||
|
type = "SimpleBTB"
|
||||||
|
cxx_class = "gem5::branch_prediction::SimpleBTB"
|
||||||
|
cxx_header = "cpu/pred/simple_btb.hh"
|
||||||
|
|
||||||
|
numEntries = Param.Unsigned(4096, "Number of BTB entries")
|
||||||
|
tagBits = Param.Unsigned(16, "Size of the BTB tags, in bits")
|
||||||
|
instShiftAmt = Param.Unsigned(
|
||||||
|
Parent.instShiftAmt, "Number of bits to shift instructions by"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class IndirectPredictor(SimObject):
|
class IndirectPredictor(SimObject):
|
||||||
type = "IndirectPredictor"
|
type = "IndirectPredictor"
|
||||||
@@ -63,11 +111,12 @@ class BranchPredictor(SimObject):
|
|||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
numThreads = Param.Unsigned(Parent.numThreads, "Number of threads")
|
numThreads = Param.Unsigned(Parent.numThreads, "Number of threads")
|
||||||
BTBEntries = Param.Unsigned(4096, "Number of BTB entries")
|
|
||||||
BTBTagSize = Param.Unsigned(16, "Size of the BTB tags, in bits")
|
|
||||||
RASSize = Param.Unsigned(16, "RAS size")
|
|
||||||
instShiftAmt = Param.Unsigned(2, "Number of bits to shift instructions by")
|
instShiftAmt = Param.Unsigned(2, "Number of bits to shift instructions by")
|
||||||
|
|
||||||
|
RASSize = Param.Unsigned(16, "RAS size")
|
||||||
|
|
||||||
|
btb = Param.BranchTargetBuffer(SimpleBTB(), "Branch target buffer (BTB)")
|
||||||
|
|
||||||
indirectBranchPred = Param.IndirectPredictor(
|
indirectBranchPred = Param.IndirectPredictor(
|
||||||
SimpleIndirectPredictor(),
|
SimpleIndirectPredictor(),
|
||||||
"Indirect branch predictor, set to NULL to disable indirect predictions",
|
"Indirect branch predictor, set to NULL to disable indirect predictions",
|
||||||
|
|||||||
@@ -1,5 +1,17 @@
|
|||||||
# -*- mode:python -*-
|
# -*- mode:python -*-
|
||||||
|
|
||||||
|
# Copyright (c) 2022-2023 The University of Edinburgh
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# The license below extends only to copyright in the software and shall
|
||||||
|
# not be construed as granting a license to any other intellectual
|
||||||
|
# property including but not limited to intellectual property relating
|
||||||
|
# to a hardware implementation of the functionality of the software
|
||||||
|
# licensed hereunder. You may use the software subject to the license
|
||||||
|
# terms below provided that you ensure that this notice is replicated
|
||||||
|
# unmodified and in its entirety in all distributions of the software,
|
||||||
|
# modified or unmodified, in source code or in binary form.
|
||||||
|
#
|
||||||
# Copyright (c) 2006 The Regents of The University of Michigan
|
# Copyright (c) 2006 The Regents of The University of Michigan
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
@@ -28,8 +40,12 @@
|
|||||||
|
|
||||||
Import('*')
|
Import('*')
|
||||||
|
|
||||||
SimObject('BranchPredictor.py', sim_objects=[
|
|
||||||
'IndirectPredictor', 'SimpleIndirectPredictor', 'BranchPredictor',
|
SimObject('BranchPredictor.py',
|
||||||
|
sim_objects=[
|
||||||
|
'BranchPredictor',
|
||||||
|
'IndirectPredictor', 'SimpleIndirectPredictor',
|
||||||
|
'BranchTargetBuffer', 'SimpleBTB',
|
||||||
'LocalBP', 'TournamentBP', 'BiModeBP', 'TAGEBase', 'TAGE', 'LoopPredictor',
|
'LocalBP', 'TournamentBP', 'BiModeBP', 'TAGEBase', 'TAGE', 'LoopPredictor',
|
||||||
'TAGE_SC_L_TAGE', 'TAGE_SC_L_TAGE_64KB', 'TAGE_SC_L_TAGE_8KB',
|
'TAGE_SC_L_TAGE', 'TAGE_SC_L_TAGE_64KB', 'TAGE_SC_L_TAGE_8KB',
|
||||||
'LTAGE', 'TAGE_SC_L_LoopPredictor', 'StatisticalCorrector', 'TAGE_SC_L',
|
'LTAGE', 'TAGE_SC_L_LoopPredictor', 'StatisticalCorrector', 'TAGE_SC_L',
|
||||||
@@ -41,17 +57,16 @@ SimObject('BranchPredictor.py', sim_objects=[
|
|||||||
'MultiperspectivePerceptronTAGE', 'MPP_StatisticalCorrector_64KB',
|
'MultiperspectivePerceptronTAGE', 'MPP_StatisticalCorrector_64KB',
|
||||||
'MultiperspectivePerceptronTAGE64KB', 'MPP_TAGE_8KB',
|
'MultiperspectivePerceptronTAGE64KB', 'MPP_TAGE_8KB',
|
||||||
'MPP_LoopPredictor_8KB', 'MPP_StatisticalCorrector_8KB',
|
'MPP_LoopPredictor_8KB', 'MPP_StatisticalCorrector_8KB',
|
||||||
'MultiperspectivePerceptronTAGE8KB'])
|
'MultiperspectivePerceptronTAGE8KB'],
|
||||||
|
enums=['BranchType'])
|
||||||
|
|
||||||
DebugFlag('Indirect')
|
|
||||||
Source('bpred_unit.cc')
|
Source('bpred_unit.cc')
|
||||||
Source('2bit_local.cc')
|
Source('2bit_local.cc')
|
||||||
Source('btb.cc')
|
|
||||||
Source('simple_indirect.cc')
|
Source('simple_indirect.cc')
|
||||||
Source('indirect.cc')
|
Source('indirect.cc')
|
||||||
Source('ras.cc')
|
Source('ras.cc')
|
||||||
Source('tournament.cc')
|
Source('tournament.cc')
|
||||||
Source ('bi_mode.cc')
|
Source('bi_mode.cc')
|
||||||
Source('tage_base.cc')
|
Source('tage_base.cc')
|
||||||
Source('tage.cc')
|
Source('tage.cc')
|
||||||
Source('loop_predictor.cc')
|
Source('loop_predictor.cc')
|
||||||
@@ -66,6 +81,10 @@ Source('statistical_corrector.cc')
|
|||||||
Source('tage_sc_l.cc')
|
Source('tage_sc_l.cc')
|
||||||
Source('tage_sc_l_8KB.cc')
|
Source('tage_sc_l_8KB.cc')
|
||||||
Source('tage_sc_l_64KB.cc')
|
Source('tage_sc_l_64KB.cc')
|
||||||
|
Source('btb.cc')
|
||||||
|
Source('simple_btb.cc')
|
||||||
|
DebugFlag('Indirect')
|
||||||
|
DebugFlag('BTB')
|
||||||
DebugFlag('FreeList')
|
DebugFlag('FreeList')
|
||||||
DebugFlag('Branch')
|
DebugFlag('Branch')
|
||||||
DebugFlag('Tage')
|
DebugFlag('Tage')
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011-2012, 2014 ARM Limited
|
* Copyright (c) 2011-2012, 2014 ARM Limited
|
||||||
* Copyright (c) 2010 The University of Edinburgh
|
* Copyright (c) 2010,2022-2023 The University of Edinburgh
|
||||||
* Copyright (c) 2012 Mark D. Hill and David A. Wood
|
* Copyright (c) 2012 Mark D. Hill and David A. Wood
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
*
|
*
|
||||||
@@ -59,10 +59,7 @@ BPredUnit::BPredUnit(const Params ¶ms)
|
|||||||
: SimObject(params),
|
: SimObject(params),
|
||||||
numThreads(params.numThreads),
|
numThreads(params.numThreads),
|
||||||
predHist(numThreads),
|
predHist(numThreads),
|
||||||
BTB(params.BTBEntries,
|
btb(params.btb),
|
||||||
params.BTBTagSize,
|
|
||||||
params.instShiftAmt,
|
|
||||||
params.numThreads),
|
|
||||||
RAS(numThreads),
|
RAS(numThreads),
|
||||||
iPred(params.indirectBranchPred),
|
iPred(params.indirectBranchPred),
|
||||||
stats(this),
|
stats(this),
|
||||||
@@ -218,10 +215,13 @@ BPredUnit::predict(const StaticInstPtr &inst, const InstSeqNum &seqNum,
|
|||||||
if (inst->isDirectCtrl() || !iPred) {
|
if (inst->isDirectCtrl() || !iPred) {
|
||||||
++stats.BTBLookups;
|
++stats.BTBLookups;
|
||||||
// Check BTB on direct branches
|
// Check BTB on direct branches
|
||||||
if (BTB.valid(pc.instAddr(), tid)) {
|
const PCStateBase * btb_target = btb->lookup(tid,
|
||||||
|
pc.instAddr(),
|
||||||
|
getBranchType(inst));
|
||||||
|
if (btb_target) {
|
||||||
++stats.BTBHits;
|
++stats.BTBHits;
|
||||||
// If it's not a return, use the BTB to get target addr.
|
// If it's not a return, use the BTB to get target addr.
|
||||||
set(target, BTB.lookup(pc.instAddr(), tid));
|
set(target, btb_target);
|
||||||
DPRINTF(Branch,
|
DPRINTF(Branch,
|
||||||
"[tid:%i] [sn:%llu] Instruction %s predicted "
|
"[tid:%i] [sn:%llu] Instruction %s predicted "
|
||||||
"target is %s\n",
|
"target is %s\n",
|
||||||
@@ -482,7 +482,8 @@ BPredUnit::squash(const InstSeqNum &squashed_sn,
|
|||||||
hist_it->seqNum, hist_it->pc);
|
hist_it->seqNum, hist_it->pc);
|
||||||
|
|
||||||
++stats.BTBUpdates;
|
++stats.BTBUpdates;
|
||||||
BTB.update(hist_it->pc, corr_target, tid);
|
btb->update(tid, hist_it->pc, corr_target,
|
||||||
|
getBranchType(hist_it->inst));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//Actually not Taken
|
//Actually not Taken
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011-2012, 2014 ARM Limited
|
* Copyright (c) 2011-2012, 2014 ARM Limited
|
||||||
* Copyright (c) 2010 The University of Edinburgh
|
* Copyright (c) 2010,2022-2023 The University of Edinburgh
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
*
|
*
|
||||||
* The license below extends only to copyright in the software and shall
|
* The license below extends only to copyright in the software and shall
|
||||||
@@ -46,6 +46,7 @@
|
|||||||
|
|
||||||
#include "base/statistics.hh"
|
#include "base/statistics.hh"
|
||||||
#include "base/types.hh"
|
#include "base/types.hh"
|
||||||
|
#include "cpu/pred/branch_type.hh"
|
||||||
#include "cpu/pred/btb.hh"
|
#include "cpu/pred/btb.hh"
|
||||||
#include "cpu/pred/indirect.hh"
|
#include "cpu/pred/indirect.hh"
|
||||||
#include "cpu/pred/ras.hh"
|
#include "cpu/pred/ras.hh"
|
||||||
@@ -152,7 +153,14 @@ class BPredUnit : public SimObject
|
|||||||
* @param inst_PC The PC to look up.
|
* @param inst_PC The PC to look up.
|
||||||
* @return Whether the BTB contains the given PC.
|
* @return Whether the BTB contains the given PC.
|
||||||
*/
|
*/
|
||||||
bool BTBValid(Addr instPC) { return BTB.valid(instPC, 0); }
|
bool BTBValid(ThreadID tid, Addr instPC)
|
||||||
|
{
|
||||||
|
return btb->valid(tid, instPC);
|
||||||
|
}
|
||||||
|
bool BTBValid(ThreadID tid, PCStateBase &instPC)
|
||||||
|
{
|
||||||
|
return BTBValid(tid, instPC.instAddr());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Looks up a given PC in the BTB to get the predicted target. The PC may
|
* Looks up a given PC in the BTB to get the predicted target. The PC may
|
||||||
@@ -162,9 +170,9 @@ class BPredUnit : public SimObject
|
|||||||
* @return The address of the target of the branch.
|
* @return The address of the target of the branch.
|
||||||
*/
|
*/
|
||||||
const PCStateBase *
|
const PCStateBase *
|
||||||
BTBLookup(Addr inst_pc)
|
BTBLookup(ThreadID tid, PCStateBase &instPC)
|
||||||
{
|
{
|
||||||
return BTB.lookup(inst_pc, 0);
|
return btb->lookup(tid, instPC.instAddr());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -189,10 +197,10 @@ class BPredUnit : public SimObject
|
|||||||
* @param target_PC The branch's target that will be added to the BTB.
|
* @param target_PC The branch's target that will be added to the BTB.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
BTBUpdate(Addr instPC, const PCStateBase &target)
|
BTBUpdate(ThreadID tid, Addr instPC, const PCStateBase &target)
|
||||||
{
|
{
|
||||||
++stats.BTBUpdates;
|
++stats.BTBUpdates;
|
||||||
BTB.update(instPC, target, 0);
|
return btb->update(tid, instPC, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -295,7 +303,7 @@ class BPredUnit : public SimObject
|
|||||||
std::vector<History> predHist;
|
std::vector<History> predHist;
|
||||||
|
|
||||||
/** The BTB. */
|
/** The BTB. */
|
||||||
DefaultBTB BTB;
|
BranchTargetBuffer* btb;
|
||||||
|
|
||||||
/** The per-thread return address stack. */
|
/** The per-thread return address stack. */
|
||||||
std::vector<ReturnAddrStack> RAS;
|
std::vector<ReturnAddrStack> RAS;
|
||||||
|
|||||||
91
src/cpu/pred/branch_type.hh
Normal file
91
src/cpu/pred/branch_type.hh
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-2023 The University of Edinburgh
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* The license below extends only to copyright in the software and shall
|
||||||
|
* not be construed as granting a license to any other intellectual
|
||||||
|
* property including but not limited to intellectual property relating
|
||||||
|
* to a hardware implementation of the functionality of the software
|
||||||
|
* licensed hereunder. You may use the software subject to the license
|
||||||
|
* terms below provided that you ensure that this notice is replicated
|
||||||
|
* unmodified and in its entirety in all distributions of the software,
|
||||||
|
* modified or unmodified, in source code or in binary form.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met: redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer;
|
||||||
|
* redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution;
|
||||||
|
* neither the name of the copyright holders nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* @file
|
||||||
|
* A helper for branch type information
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __CPU_PRED_BRANCH_TYPE_HH__
|
||||||
|
#define __CPU_PRED_BRANCH_TYPE_HH__
|
||||||
|
|
||||||
|
#include "cpu/static_inst.hh"
|
||||||
|
#include "enums/BranchType.hh"
|
||||||
|
|
||||||
|
namespace gem5
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace branch_prediction
|
||||||
|
{
|
||||||
|
|
||||||
|
typedef enums::BranchType BranchType;
|
||||||
|
|
||||||
|
inline BranchType getBranchType(StaticInstPtr inst)
|
||||||
|
{
|
||||||
|
if (inst->isReturn()) {
|
||||||
|
return BranchType::Return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inst->isCall()) {
|
||||||
|
return inst->isDirectCtrl()
|
||||||
|
? BranchType::CallDirect
|
||||||
|
: BranchType::CallIndirect;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inst->isDirectCtrl()) {
|
||||||
|
return inst->isCondCtrl()
|
||||||
|
? BranchType::DirectCond
|
||||||
|
: BranchType::DirectUncond;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inst->isIndirectCtrl()) {
|
||||||
|
return inst->isCondCtrl()
|
||||||
|
? BranchType::IndirectCond
|
||||||
|
: BranchType::IndirectUncond;
|
||||||
|
}
|
||||||
|
return BranchType::NoBranch;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string toString(BranchType type)
|
||||||
|
{
|
||||||
|
return std::string(enums::BranchTypeStrings[type]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace branch_prediction
|
||||||
|
} // namespace gem5
|
||||||
|
|
||||||
|
#endif // __CPU_PRED_BRANCH_TYPE_HH__
|
||||||
@@ -1,4 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (c) 2022-2023 The University of Edinburgh
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* The license below extends only to copyright in the software and shall
|
||||||
|
* not be construed as granting a license to any other intellectual
|
||||||
|
* property including but not limited to intellectual property relating
|
||||||
|
* to a hardware implementation of the functionality of the software
|
||||||
|
* licensed hereunder. You may use the software subject to the license
|
||||||
|
* terms below provided that you ensure that this notice is replicated
|
||||||
|
* unmodified and in its entirety in all distributions of the software,
|
||||||
|
* modified or unmodified, in source code or in binary form.
|
||||||
|
*
|
||||||
* Copyright (c) 2004-2005 The Regents of The University of Michigan
|
* Copyright (c) 2004-2005 The Regents of The University of Michigan
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -28,119 +40,59 @@
|
|||||||
|
|
||||||
#include "cpu/pred/btb.hh"
|
#include "cpu/pred/btb.hh"
|
||||||
|
|
||||||
#include "base/intmath.hh"
|
|
||||||
#include "base/trace.hh"
|
|
||||||
#include "debug/Fetch.hh"
|
|
||||||
|
|
||||||
namespace gem5
|
namespace gem5
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace branch_prediction
|
namespace branch_prediction
|
||||||
{
|
{
|
||||||
|
|
||||||
DefaultBTB::DefaultBTB(unsigned _numEntries,
|
BranchTargetBuffer::BranchTargetBuffer(const Params ¶ms)
|
||||||
unsigned _tagBits,
|
: ClockedObject(params),
|
||||||
unsigned _instShiftAmt,
|
numThreads(params.numThreads),
|
||||||
unsigned _num_threads)
|
stats(this)
|
||||||
: numEntries(_numEntries),
|
|
||||||
tagBits(_tagBits),
|
|
||||||
instShiftAmt(_instShiftAmt),
|
|
||||||
log2NumThreads(floorLog2(_num_threads))
|
|
||||||
{
|
{
|
||||||
DPRINTF(Fetch, "BTB: Creating BTB object.\n");
|
}
|
||||||
|
|
||||||
if (!isPowerOf2(numEntries)) {
|
BranchTargetBuffer::BranchTargetBufferStats::BranchTargetBufferStats(
|
||||||
fatal("BTB entries is not a power of 2!");
|
statistics::Group *parent)
|
||||||
|
: statistics::Group(parent),
|
||||||
|
ADD_STAT(lookups, statistics::units::Count::get(),
|
||||||
|
"Number of BTB lookups"),
|
||||||
|
ADD_STAT(misses, statistics::units::Count::get(),
|
||||||
|
"Number of BTB misses"),
|
||||||
|
ADD_STAT(updates, statistics::units::Count::get(),
|
||||||
|
"Number of BTB updates"),
|
||||||
|
ADD_STAT(mispredict, statistics::units::Count::get(),
|
||||||
|
"Number of BTB mispredictions. "
|
||||||
|
"No target found or target wrong."),
|
||||||
|
ADD_STAT(evictions, statistics::units::Count::get(),
|
||||||
|
"Number of BTB evictions")
|
||||||
|
{
|
||||||
|
using namespace statistics;
|
||||||
|
lookups
|
||||||
|
.init(enums::Num_BranchType)
|
||||||
|
.flags(total | pdf);
|
||||||
|
|
||||||
|
misses
|
||||||
|
.init(enums::Num_BranchType)
|
||||||
|
.flags(total | pdf);
|
||||||
|
|
||||||
|
updates
|
||||||
|
.init(enums::Num_BranchType)
|
||||||
|
.flags(total | pdf);
|
||||||
|
|
||||||
|
mispredict
|
||||||
|
.init(enums::Num_BranchType)
|
||||||
|
.flags(total | pdf);
|
||||||
|
|
||||||
|
evictions.flags(nozero);
|
||||||
|
|
||||||
|
for (int i = 0; i < enums::Num_BranchType; i++) {
|
||||||
|
lookups.subname(i, enums::BranchTypeStrings[i]);
|
||||||
|
misses.subname(i, enums::BranchTypeStrings[i]);
|
||||||
|
updates.subname(i, enums::BranchTypeStrings[i]);
|
||||||
|
mispredict.subname(i, enums::BranchTypeStrings[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
btb.resize(numEntries);
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < numEntries; ++i) {
|
|
||||||
btb[i].valid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
idxMask = numEntries - 1;
|
|
||||||
|
|
||||||
tagMask = (1 << tagBits) - 1;
|
|
||||||
|
|
||||||
tagShiftAmt = instShiftAmt + floorLog2(numEntries);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DefaultBTB::reset()
|
|
||||||
{
|
|
||||||
for (unsigned i = 0; i < numEntries; ++i) {
|
|
||||||
btb[i].valid = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
unsigned
|
|
||||||
DefaultBTB::getIndex(Addr instPC, ThreadID tid)
|
|
||||||
{
|
|
||||||
// Need to shift PC over by the word offset.
|
|
||||||
return ((instPC >> instShiftAmt)
|
|
||||||
^ (tid << (tagShiftAmt - instShiftAmt - log2NumThreads)))
|
|
||||||
& idxMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
Addr
|
|
||||||
DefaultBTB::getTag(Addr instPC)
|
|
||||||
{
|
|
||||||
return (instPC >> tagShiftAmt) & tagMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
DefaultBTB::valid(Addr instPC, ThreadID tid)
|
|
||||||
{
|
|
||||||
unsigned btb_idx = getIndex(instPC, tid);
|
|
||||||
|
|
||||||
Addr inst_tag = getTag(instPC);
|
|
||||||
|
|
||||||
assert(btb_idx < numEntries);
|
|
||||||
|
|
||||||
if (btb[btb_idx].valid
|
|
||||||
&& inst_tag == btb[btb_idx].tag
|
|
||||||
&& btb[btb_idx].tid == tid) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// @todo Create some sort of return struct that has both whether or not the
|
|
||||||
// address is valid, and also the address. For now will just use addr = 0 to
|
|
||||||
// represent invalid entry.
|
|
||||||
const PCStateBase *
|
|
||||||
DefaultBTB::lookup(Addr inst_pc, ThreadID tid)
|
|
||||||
{
|
|
||||||
unsigned btb_idx = getIndex(inst_pc, tid);
|
|
||||||
|
|
||||||
Addr inst_tag = getTag(inst_pc);
|
|
||||||
|
|
||||||
assert(btb_idx < numEntries);
|
|
||||||
|
|
||||||
if (btb[btb_idx].valid
|
|
||||||
&& inst_tag == btb[btb_idx].tag
|
|
||||||
&& btb[btb_idx].tid == tid) {
|
|
||||||
return btb[btb_idx].target.get();
|
|
||||||
} else {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DefaultBTB::update(Addr inst_pc, const PCStateBase &target, ThreadID tid)
|
|
||||||
{
|
|
||||||
unsigned btb_idx = getIndex(inst_pc, tid);
|
|
||||||
|
|
||||||
assert(btb_idx < numEntries);
|
|
||||||
|
|
||||||
btb[btb_idx].tid = tid;
|
|
||||||
btb[btb_idx].valid = true;
|
|
||||||
set(btb[btb_idx].target, target);
|
|
||||||
btb[btb_idx].tag = getTag(inst_pc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace branch_prediction
|
} // namespace branch_prediction
|
||||||
|
|||||||
@@ -1,4 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (c) 2022-2023 The University of Edinburgh
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* The license below extends only to copyright in the software and shall
|
||||||
|
* not be construed as granting a license to any other intellectual
|
||||||
|
* property including but not limited to intellectual property relating
|
||||||
|
* to a hardware implementation of the functionality of the software
|
||||||
|
* licensed hereunder. You may use the software subject to the license
|
||||||
|
* terms below provided that you ensure that this notice is replicated
|
||||||
|
* unmodified and in its entirety in all distributions of the software,
|
||||||
|
* modified or unmodified, in source code or in binary form.
|
||||||
|
*
|
||||||
* Copyright (c) 2004-2005 The Regents of The University of Michigan
|
* Copyright (c) 2004-2005 The Regents of The University of Michigan
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -29,9 +41,13 @@
|
|||||||
#ifndef __CPU_PRED_BTB_HH__
|
#ifndef __CPU_PRED_BTB_HH__
|
||||||
#define __CPU_PRED_BTB_HH__
|
#define __CPU_PRED_BTB_HH__
|
||||||
|
|
||||||
|
|
||||||
#include "arch/generic/pcstate.hh"
|
#include "arch/generic/pcstate.hh"
|
||||||
#include "base/logging.hh"
|
#include "base/statistics.hh"
|
||||||
#include "base/types.hh"
|
#include "cpu/pred/branch_type.hh"
|
||||||
|
#include "cpu/static_inst.hh"
|
||||||
|
#include "params/BranchTargetBuffer.hh"
|
||||||
|
#include "sim/clocked_object.hh"
|
||||||
|
|
||||||
namespace gem5
|
namespace gem5
|
||||||
{
|
{
|
||||||
@@ -39,93 +55,73 @@ namespace gem5
|
|||||||
namespace branch_prediction
|
namespace branch_prediction
|
||||||
{
|
{
|
||||||
|
|
||||||
class DefaultBTB
|
class BranchTargetBuffer : public ClockedObject
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
struct BTBEntry
|
|
||||||
{
|
|
||||||
/** The entry's tag. */
|
|
||||||
Addr tag = 0;
|
|
||||||
|
|
||||||
/** The entry's target. */
|
|
||||||
std::unique_ptr<PCStateBase> target;
|
|
||||||
|
|
||||||
/** The entry's thread id. */
|
|
||||||
ThreadID tid;
|
|
||||||
|
|
||||||
/** Whether or not the entry is valid. */
|
|
||||||
bool valid = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Creates a BTB with the given number of entries, number of bits per
|
typedef BranchTargetBufferParams Params;
|
||||||
* tag, and instruction offset amount.
|
typedef enums::BranchType BranchType;
|
||||||
* @param numEntries Number of entries for the BTB.
|
|
||||||
* @param tagBits Number of bits for each tag in the BTB.
|
|
||||||
* @param instShiftAmt Offset amount for instructions to ignore alignment.
|
|
||||||
*/
|
|
||||||
DefaultBTB(unsigned numEntries, unsigned tagBits,
|
|
||||||
unsigned instShiftAmt, unsigned numThreads);
|
|
||||||
|
|
||||||
void reset();
|
BranchTargetBuffer(const Params ¶ms);
|
||||||
|
|
||||||
/** Looks up an address in the BTB. Must call valid() first on the address.
|
virtual void memInvalidate() override = 0;
|
||||||
|
|
||||||
|
/** Checks if a branch address is in the BTB. Intended as a quick check
|
||||||
|
* before calling lookup. Does not update statistics.
|
||||||
* @param inst_PC The address of the branch to look up.
|
* @param inst_PC The address of the branch to look up.
|
||||||
* @param tid The thread id.
|
|
||||||
* @return Returns the target of the branch.
|
|
||||||
*/
|
|
||||||
const PCStateBase *lookup(Addr instPC, ThreadID tid);
|
|
||||||
|
|
||||||
/** Checks if a branch is in the BTB.
|
|
||||||
* @param inst_PC The address of the branch to look up.
|
|
||||||
* @param tid The thread id.
|
|
||||||
* @return Whether or not the branch exists in the BTB.
|
* @return Whether or not the branch exists in the BTB.
|
||||||
*/
|
*/
|
||||||
bool valid(Addr instPC, ThreadID tid);
|
virtual bool valid(ThreadID tid, Addr instPC) = 0;
|
||||||
|
|
||||||
|
/** Looks up an address in the BTB to get the target of the branch.
|
||||||
|
* @param inst_PC The address of the branch to look up.
|
||||||
|
* @param type Optional type of the branch to look up.
|
||||||
|
* @return The target of the branch or nullptr if the branch is not
|
||||||
|
* in the BTB.
|
||||||
|
*/
|
||||||
|
virtual const PCStateBase *lookup(ThreadID tid, Addr instPC,
|
||||||
|
BranchType type = BranchType::NoBranch) = 0;
|
||||||
|
|
||||||
|
/** Looks up an address in the BTB and return the instruction
|
||||||
|
* information if existant. Does not update statistics.
|
||||||
|
* @param inst_PC The address of the branch to look up.
|
||||||
|
* @return Returns the target of the branch.
|
||||||
|
*/
|
||||||
|
virtual const StaticInstPtr getInst(ThreadID tid, Addr instPC) = 0;
|
||||||
|
|
||||||
|
|
||||||
/** Updates the BTB with the target of a branch.
|
/** Updates the BTB with the target of a branch.
|
||||||
* @param inst_pc The address of the branch being updated.
|
* @param inst_pc The address of the branch being updated.
|
||||||
* @param target_pc The target address of the branch.
|
* @param target_pc The target address of the branch.
|
||||||
* @param tid The thread id.
|
|
||||||
*/
|
*/
|
||||||
void update(Addr inst_pc, const PCStateBase &target_pc, ThreadID tid);
|
virtual void update(ThreadID tid, Addr inst_pc,
|
||||||
|
const PCStateBase &target_pc,
|
||||||
|
BranchType type = BranchType::NoBranch,
|
||||||
|
StaticInstPtr inst = nullptr) = 0;
|
||||||
|
|
||||||
private:
|
/** Update BTB statistics
|
||||||
/** Returns the index into the BTB, based on the branch's PC.
|
|
||||||
* @param inst_PC The branch to look up.
|
|
||||||
* @return Returns the index into the BTB.
|
|
||||||
*/
|
*/
|
||||||
inline unsigned getIndex(Addr instPC, ThreadID tid);
|
virtual void incorrectTarget(Addr inst_pc,
|
||||||
|
BranchType type = BranchType::NoBranch)
|
||||||
|
{
|
||||||
|
stats.mispredict[type]++;
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the tag bits of a given address.
|
protected:
|
||||||
* @param inst_PC The branch's address.
|
/** Number of the threads for which the branch history is maintained. */
|
||||||
* @return Returns the tag bits.
|
const unsigned numThreads;
|
||||||
*/
|
|
||||||
inline Addr getTag(Addr instPC);
|
|
||||||
|
|
||||||
/** The actual BTB. */
|
struct BranchTargetBufferStats : public statistics::Group
|
||||||
std::vector<BTBEntry> btb;
|
{
|
||||||
|
BranchTargetBufferStats(statistics::Group *parent);
|
||||||
|
|
||||||
/** The number of entries in the BTB. */
|
statistics::Vector lookups;
|
||||||
unsigned numEntries;
|
statistics::Vector misses;
|
||||||
|
statistics::Vector updates;
|
||||||
|
statistics::Vector mispredict;
|
||||||
|
statistics::Scalar evictions;
|
||||||
|
|
||||||
/** The index mask. */
|
} stats;
|
||||||
unsigned idxMask;
|
|
||||||
|
|
||||||
/** The number of tag bits per entry. */
|
|
||||||
unsigned tagBits;
|
|
||||||
|
|
||||||
/** The tag mask. */
|
|
||||||
unsigned tagMask;
|
|
||||||
|
|
||||||
/** Number of bits to shift PC when calculating index. */
|
|
||||||
unsigned instShiftAmt;
|
|
||||||
|
|
||||||
/** Number of bits to shift PC when calculating tag. */
|
|
||||||
unsigned tagShiftAmt;
|
|
||||||
|
|
||||||
/** Log2 NumThreads used for hashing threadid */
|
|
||||||
unsigned log2NumThreads;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace branch_prediction
|
} // namespace branch_prediction
|
||||||
|
|||||||
176
src/cpu/pred/simple_btb.cc
Normal file
176
src/cpu/pred/simple_btb.cc
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-2023 The University of Edinburgh
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* The license below extends only to copyright in the software and shall
|
||||||
|
* not be construed as granting a license to any other intellectual
|
||||||
|
* property including but not limited to intellectual property relating
|
||||||
|
* to a hardware implementation of the functionality of the software
|
||||||
|
* licensed hereunder. You may use the software subject to the license
|
||||||
|
* terms below provided that you ensure that this notice is replicated
|
||||||
|
* unmodified and in its entirety in all distributions of the software,
|
||||||
|
* modified or unmodified, in source code or in binary form.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004-2005 The Regents of The University of Michigan
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met: redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer;
|
||||||
|
* redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution;
|
||||||
|
* neither the name of the copyright holders nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cpu/pred/simple_btb.hh"
|
||||||
|
|
||||||
|
#include "base/intmath.hh"
|
||||||
|
#include "base/trace.hh"
|
||||||
|
#include "debug/BTB.hh"
|
||||||
|
|
||||||
|
namespace gem5
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace branch_prediction
|
||||||
|
{
|
||||||
|
|
||||||
|
SimpleBTB::SimpleBTB(const SimpleBTBParams &p)
|
||||||
|
: BranchTargetBuffer(p),
|
||||||
|
numEntries(p.numEntries),
|
||||||
|
tagBits(p.tagBits),
|
||||||
|
instShiftAmt(p.instShiftAmt),
|
||||||
|
log2NumThreads(floorLog2(p.numThreads))
|
||||||
|
{
|
||||||
|
DPRINTF(BTB, "BTB: Creating BTB object.\n");
|
||||||
|
|
||||||
|
if (!isPowerOf2(numEntries)) {
|
||||||
|
fatal("BTB entries is not a power of 2!");
|
||||||
|
}
|
||||||
|
|
||||||
|
btb.resize(numEntries);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < numEntries; ++i) {
|
||||||
|
btb[i].valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
idxMask = numEntries - 1;
|
||||||
|
|
||||||
|
tagMask = (1 << tagBits) - 1;
|
||||||
|
|
||||||
|
tagShiftAmt = instShiftAmt + floorLog2(numEntries);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SimpleBTB::memInvalidate()
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < numEntries; ++i) {
|
||||||
|
btb[i].valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
unsigned
|
||||||
|
SimpleBTB::getIndex(Addr instPC, ThreadID tid)
|
||||||
|
{
|
||||||
|
// Need to shift PC over by the word offset.
|
||||||
|
return ((instPC >> instShiftAmt)
|
||||||
|
^ (tid << (tagShiftAmt - instShiftAmt - log2NumThreads)))
|
||||||
|
& idxMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
Addr
|
||||||
|
SimpleBTB::getTag(Addr instPC)
|
||||||
|
{
|
||||||
|
return (instPC >> tagShiftAmt) & tagMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleBTB::BTBEntry *
|
||||||
|
SimpleBTB::findEntry(Addr instPC, ThreadID tid)
|
||||||
|
{
|
||||||
|
unsigned btb_idx = getIndex(instPC, tid);
|
||||||
|
Addr inst_tag = getTag(instPC);
|
||||||
|
|
||||||
|
assert(btb_idx < numEntries);
|
||||||
|
|
||||||
|
if (btb[btb_idx].valid
|
||||||
|
&& inst_tag == btb[btb_idx].tag
|
||||||
|
&& btb[btb_idx].tid == tid) {
|
||||||
|
return &btb[btb_idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SimpleBTB::valid(ThreadID tid, Addr instPC)
|
||||||
|
{
|
||||||
|
BTBEntry *entry = findEntry(instPC, tid);
|
||||||
|
|
||||||
|
return entry != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @todo Create some sort of return struct that has both whether or not the
|
||||||
|
// address is valid, and also the address. For now will just use addr = 0 to
|
||||||
|
// represent invalid entry.
|
||||||
|
const PCStateBase *
|
||||||
|
SimpleBTB::lookup(ThreadID tid, Addr instPC, BranchType type)
|
||||||
|
{
|
||||||
|
stats.lookups[type]++;
|
||||||
|
|
||||||
|
BTBEntry *entry = findEntry(instPC, tid);
|
||||||
|
|
||||||
|
if (entry) {
|
||||||
|
return entry->target.get();
|
||||||
|
}
|
||||||
|
stats.misses[type]++;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const StaticInstPtr
|
||||||
|
SimpleBTB::getInst(ThreadID tid, Addr instPC)
|
||||||
|
{
|
||||||
|
BTBEntry *entry = findEntry(instPC, tid);
|
||||||
|
|
||||||
|
if (entry) {
|
||||||
|
return entry->inst;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SimpleBTB::update(ThreadID tid, Addr instPC,
|
||||||
|
const PCStateBase &target,
|
||||||
|
BranchType type, StaticInstPtr inst)
|
||||||
|
{
|
||||||
|
unsigned btb_idx = getIndex(instPC, tid);
|
||||||
|
|
||||||
|
assert(btb_idx < numEntries);
|
||||||
|
|
||||||
|
stats.updates[type]++;
|
||||||
|
|
||||||
|
btb[btb_idx].tid = tid;
|
||||||
|
btb[btb_idx].valid = true;
|
||||||
|
set(btb[btb_idx].target, target);
|
||||||
|
btb[btb_idx].tag = getTag(instPC);
|
||||||
|
btb[btb_idx].inst = inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace branch_prediction
|
||||||
|
} // namespace gem5
|
||||||
136
src/cpu/pred/simple_btb.hh
Normal file
136
src/cpu/pred/simple_btb.hh
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-2023 The University of Edinburgh
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* The license below extends only to copyright in the software and shall
|
||||||
|
* not be construed as granting a license to any other intellectual
|
||||||
|
* property including but not limited to intellectual property relating
|
||||||
|
* to a hardware implementation of the functionality of the software
|
||||||
|
* licensed hereunder. You may use the software subject to the license
|
||||||
|
* terms below provided that you ensure that this notice is replicated
|
||||||
|
* unmodified and in its entirety in all distributions of the software,
|
||||||
|
* modified or unmodified, in source code or in binary form.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004-2005 The Regents of The University of Michigan
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met: redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer;
|
||||||
|
* redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution;
|
||||||
|
* neither the name of the copyright holders nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __CPU_PRED_SIMPLE_BTB_HH__
|
||||||
|
#define __CPU_PRED_SIMPLE_BTB_HH__
|
||||||
|
|
||||||
|
#include "base/logging.hh"
|
||||||
|
#include "base/types.hh"
|
||||||
|
#include "cpu/pred/btb.hh"
|
||||||
|
#include "params/SimpleBTB.hh"
|
||||||
|
|
||||||
|
namespace gem5
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace branch_prediction
|
||||||
|
{
|
||||||
|
|
||||||
|
class SimpleBTB : public BranchTargetBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SimpleBTB(const SimpleBTBParams ¶ms);
|
||||||
|
|
||||||
|
void memInvalidate() override;
|
||||||
|
bool valid(ThreadID tid, Addr instPC) override;
|
||||||
|
const PCStateBase *lookup(ThreadID tid, Addr instPC,
|
||||||
|
BranchType type = BranchType::NoBranch) override;
|
||||||
|
void update(ThreadID tid, Addr instPC, const PCStateBase &target_pc,
|
||||||
|
BranchType type = BranchType::NoBranch,
|
||||||
|
StaticInstPtr inst = nullptr) override;
|
||||||
|
const StaticInstPtr getInst(ThreadID tid, Addr instPC) override;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct BTBEntry
|
||||||
|
{
|
||||||
|
/** The entry's tag. */
|
||||||
|
Addr tag = 0;
|
||||||
|
|
||||||
|
/** The entry's target. */
|
||||||
|
std::unique_ptr<PCStateBase> target;
|
||||||
|
|
||||||
|
/** The entry's thread id. */
|
||||||
|
ThreadID tid;
|
||||||
|
|
||||||
|
/** Whether or not the entry is valid. */
|
||||||
|
bool valid = false;
|
||||||
|
|
||||||
|
/** Pointer to the static branch instruction at this address */
|
||||||
|
StaticInstPtr inst = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** Returns the index into the BTB, based on the branch's PC.
|
||||||
|
* @param inst_PC The branch to look up.
|
||||||
|
* @return Returns the index into the BTB.
|
||||||
|
*/
|
||||||
|
inline unsigned getIndex(Addr instPC, ThreadID tid);
|
||||||
|
|
||||||
|
/** Returns the tag bits of a given address.
|
||||||
|
* @param inst_PC The branch's address.
|
||||||
|
* @return Returns the tag bits.
|
||||||
|
*/
|
||||||
|
inline Addr getTag(Addr instPC);
|
||||||
|
|
||||||
|
/** Internal call to find an address in the BTB
|
||||||
|
* @param instPC The branch's address.
|
||||||
|
* @return Returns a pointer to the BTB entry if found, nullptr otherwise.
|
||||||
|
*/
|
||||||
|
BTBEntry *findEntry(Addr instPC, ThreadID tid);
|
||||||
|
|
||||||
|
/** The actual BTB. */
|
||||||
|
std::vector<BTBEntry> btb;
|
||||||
|
|
||||||
|
/** The number of entries in the BTB. */
|
||||||
|
unsigned numEntries;
|
||||||
|
|
||||||
|
/** The index mask. */
|
||||||
|
unsigned idxMask;
|
||||||
|
|
||||||
|
/** The number of tag bits per entry. */
|
||||||
|
unsigned tagBits;
|
||||||
|
|
||||||
|
/** The tag mask. */
|
||||||
|
unsigned tagMask;
|
||||||
|
|
||||||
|
/** Number of bits to shift PC when calculating index. */
|
||||||
|
unsigned instShiftAmt;
|
||||||
|
|
||||||
|
/** Number of bits to shift PC when calculating tag. */
|
||||||
|
unsigned tagShiftAmt;
|
||||||
|
|
||||||
|
/** Log2 NumThreads used for hashing threadid */
|
||||||
|
unsigned log2NumThreads;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace branch_prediction
|
||||||
|
} // namespace gem5
|
||||||
|
|
||||||
|
#endif // __CPU_PRED_SIMPLE_BTB_HH__
|
||||||
@@ -95,7 +95,7 @@ class U74FUPool(MinorFUPool):
|
|||||||
|
|
||||||
|
|
||||||
class U74BP(TournamentBP):
|
class U74BP(TournamentBP):
|
||||||
BTBEntries = 32
|
btb = SimpleBTB(numEntries=32)
|
||||||
RASSize = 12
|
RASSize = 12
|
||||||
localHistoryTableSize = 4096 # is 3.6 KiB but gem5 requires power of 2
|
localHistoryTableSize = 4096 # is 3.6 KiB but gem5 requires power of 2
|
||||||
localPredictorSize = 16384
|
localPredictorSize = 16384
|
||||||
|
|||||||
Reference in New Issue
Block a user