generated from riscv-software-src/template-riscv-code
-
Notifications
You must be signed in to change notification settings - Fork 69
Branch Prediction Unit #243
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
dragon540
wants to merge
16
commits into
riscv-software-src:master
Choose a base branch
from
dragon540:shobhit/bpu
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from 9 commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
1f8800a
Add Basic BPU testbench structure
dragon540 7067ae1
added operator overload for bpu types to facilitate building
dragon540 e1b343d
Added BPU counters
dragon540 3c7204e
test executable name update
dragon540 efa02d3
Added BPU parameters
dragon540 c7f74fb
Added high level structure of the BasePredictor
dragon540 68e0381
Functions of BasePredictor
dragon540 304ae3c
Added skeleton body of TAGE
dragon540 e076b56
Added generic prediction and more constructor parameters for TAGE
dragon540 a9f46d6
Minimally working BPU testbench
dragon540 45e4878
Merge branch 'riscv-software-src:master' into shobhit/bpu
dragon540 4d95561
removed stf test for now
dragon540 7207d5b
Basic Tage internal logic
dragon540 9536aa6
Added logic to find hash address and tag for TAGE, pass function para…
dragon540 df674df
Handle mismatch between First and Second prediction
dragon540 1bc59f7
Reset useful bits after interval
dragon540 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
|
||
#include "fetch/BPU.hpp" | ||
|
||
namespace olympia | ||
{ | ||
namespace BranchPredictor | ||
{ | ||
const char* BPU::name = "BPU"; | ||
|
||
BPU::BPU(sparta::TreeNode* node, const BPUParameterSet* p) : | ||
sparta::Unit(node), | ||
ghr_size_(p->ghr_size), | ||
ghr_hash_bits_(p->ghr_hash_bits), | ||
pht_size_(p->pht_size), | ||
ctr_bits_(p->ctr_bits), | ||
btb_size_(p->btb_size), | ||
ras_size_(p->ras_size), | ||
ras_enable_overwrite_(p->ras_enable_overwrite), | ||
tage_bim_table_size_(p->tage_bim_table_size), | ||
tage_bim_ctr_bits_(p->tage_bim_ctr_bits), | ||
tage_tagged_table_num_(p->tage_tagged_table_num), | ||
logical_table_num_(p->logical_table_num), | ||
loop_pred_table_size_(p->loop_pred_table_size), | ||
loop_pred_table_way_(p->loop_pred_table_way), | ||
base_predictor_(pht_size_, ctr_bits_, btb_size_, ras_size_) | ||
{ | ||
in_fetch_predictionRequest_.registerConsumerHandler( | ||
CREATE_SPARTA_HANDLER_WITH_DATA(BPU, recievePredictionRequest_, PredictionRequest)); | ||
|
||
in_fetch_predictionOutput_credits_.registerConsumerHandler( | ||
CREATE_SPARTA_HANDLER_WITH_DATA(BPU, receivePredictionOutputCredits_, uint32_t)); | ||
} | ||
|
||
PredictionOutput BPU::getPrediction(const PredictionRequest & pred) | ||
{ | ||
PredictionOutput output; | ||
output.predDirection_ = true; | ||
output.predPC_ = 0x0220; | ||
|
||
return output; | ||
} | ||
|
||
void BPU::updatePredictor(const UpdateInput & update) {} | ||
|
||
BPU::~BPU() {} | ||
|
||
void BPU::sendPredictionRequestCredits_(uint32_t credits) | ||
{ | ||
ILOG("Send prediction request credits to Fetch"); | ||
out_fetch_predictionRequest_credits_.send(credits); | ||
} | ||
|
||
void BPU::sendInitialPredictionRequestCredits_() | ||
{ | ||
ILOG("Sending initial prediction request credits to Fetch"); | ||
sendPredictionRequestCredits_(1); | ||
} | ||
|
||
void BPU::recievePredictionRequest_(const PredictionRequest & predReq) | ||
{ | ||
ILOG("Received prediction request from Fetch"); | ||
predictionRequestBuffer_.push_back(predReq); | ||
} | ||
|
||
// void BPU::recievePredictionUpdate_() | ||
//{} | ||
|
||
void BPU::receivePredictionOutputCredits_(const uint32_t & credits) | ||
{ | ||
ILOG("Recieve prediction output credits from Fetch"); | ||
predictionOutputCredits_ += credits; | ||
} | ||
|
||
void BPU::makePrediction_() | ||
{ | ||
PredictionOutput output; | ||
output.predDirection_ = true; | ||
output.predPC_ = 100000; | ||
generatedPredictionOutputBuffer_.push_back(output); | ||
} | ||
|
||
void BPU::sendPrediction_() | ||
{ | ||
if (predictionOutputCredits_ > 0) | ||
{ | ||
ILOG("Sending prediction output to fetch"); | ||
auto predOutput = generatedPredictionOutputBuffer_.front(); | ||
generatedPredictionOutputBuffer_.pop_front(); | ||
out_fetch_predictionOutput_.send(predOutput); | ||
predictionOutputCredits_--; | ||
} | ||
} | ||
|
||
} // namespace BranchPredictor | ||
} // namespace olympia |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,215 @@ | ||
#pragma once | ||
|
||
#include "sparta/ports/DataPort.hpp" | ||
#include "sparta/events/SingleCycleUniqueEvent.hpp" | ||
#include "sparta/simulation/Unit.hpp" | ||
#include "sparta/simulation/TreeNode.hpp" | ||
#include "sparta/simulation/ParameterSet.hpp" | ||
#include "sparta/utils/LogUtils.hpp" | ||
|
||
#include "BranchPredIF.hpp" | ||
#include "BasePredictor.hpp" | ||
#include "TAGE_SC_L.hpp" | ||
|
||
#include <list> | ||
|
||
namespace olympia | ||
{ | ||
namespace BranchPredictor | ||
{ | ||
class PredictionRequest | ||
{ | ||
public: | ||
PredictionRequest() {} | ||
|
||
uint64_t PC_; | ||
uint8_t instType_; | ||
|
||
friend std::ostream & operator<<(std::ostream & os, const PredictionRequest &) | ||
{ | ||
return os; | ||
} | ||
}; | ||
|
||
class PredictionOutput | ||
{ | ||
public: | ||
PredictionOutput() {} | ||
|
||
bool predDirection_; | ||
uint64_t predPC_; | ||
|
||
friend std::ostream & operator<<(std::ostream & os, const PredictionOutput &) | ||
{ | ||
return os; | ||
} | ||
}; | ||
|
||
class UpdateInput | ||
{ | ||
public: | ||
UpdateInput(uint64_t instrPC, bool correctedDirection, uint64_t correctedTargetPC) {} | ||
|
||
uint64_t instrPC_; | ||
bool correctedDirection_; | ||
uint64_t correctedTargetPC_; | ||
|
||
friend std::ostream & operator<<(std::ostream & os, const UpdateInput &) { return os; } | ||
}; | ||
|
||
class BPU : | ||
public BranchPredictorIF<PredictionOutput, UpdateInput, PredictionRequest>, | ||
public sparta::Unit | ||
{ | ||
public: | ||
class BPUParameterSet : public sparta::ParameterSet | ||
{ | ||
public: | ||
BPUParameterSet(sparta::TreeNode* n) : sparta::ParameterSet(n) {} | ||
|
||
// TODO: choose default values properly | ||
// currently values were chosen randomly | ||
PARAMETER(uint32_t, ghr_size, 1024, "Number of branch history bits stored in GHR"); | ||
PARAMETER(uint32_t, ghr_hash_bits, 4, | ||
"Number of bits from GHR used for hashing with PC, to index PHT") | ||
PARAMETER(uint32_t, pht_size, 1024, "Number of entries stored in PHT") | ||
PARAMETER(uint32_t, ctr_bits, 8, | ||
"Number of bits used by counter in PHT to make prediction") | ||
PARAMETER(uint32_t, btb_size, 512, "Maximum possible number of entries in BTB") | ||
PARAMETER(uint32_t, ras_size, 128, "Maximum possible number of entries in RAS") | ||
PARAMETER(bool, ras_enable_overwrite, true, | ||
"New entries on maximum capacity overwrite") | ||
PARAMETER(uint32_t, tage_bim_table_size, 1024, "Size of TAGE bimodal table") | ||
PARAMETER(uint32_t, tage_bim_ctr_bits, 8, | ||
"Number of bits used by TAGE bimodal table to make prediction") | ||
PARAMETER(uint32_t, tage_tagged_table_num, 6, | ||
"Number of tagged components in TAGE predictor") | ||
PARAMETER(uint32_t, logical_table_num, 8, "Number of logical table in SC") | ||
PARAMETER(uint32_t, loop_pred_table_size, 64, | ||
"Maximum possible entries in loop predictor table") | ||
PARAMETER(uint32_t, loop_pred_table_way, 4, "Way size of loop predictor table") | ||
}; | ||
|
||
BPU(sparta::TreeNode* node, const BPUParameterSet* p); | ||
|
||
PredictionOutput getPrediction(const PredictionRequest &); | ||
void updatePredictor(const UpdateInput &); | ||
|
||
~BPU(); | ||
|
||
//! \brief Name of this resource. Required by sparta::UnitFactory | ||
static const char* name; | ||
|
||
private: | ||
void sendPredictionRequestCredits_(uint32_t credits); | ||
void sendInitialPredictionRequestCredits_(); | ||
void recievePredictionRequest_(const PredictionRequest & predReq); | ||
// void recievePredictionUpdate_(); | ||
void receivePredictionOutputCredits_(const uint32_t & credits); | ||
void makePrediction_(); | ||
void sendPrediction_(); | ||
|
||
uint32_t ghr_size_; | ||
uint32_t ghr_hash_bits_; | ||
uint32_t pht_size_; | ||
uint32_t ctr_bits_; | ||
uint32_t btb_size_; | ||
uint32_t ras_size_; | ||
bool ras_enable_overwrite_; | ||
uint32_t tage_bim_table_size_; | ||
uint32_t tage_bim_ctr_bits_; | ||
uint32_t tage_tagged_table_num_; | ||
uint32_t logical_table_num_; | ||
uint32_t loop_pred_table_size_; | ||
uint32_t loop_pred_table_way_; | ||
|
||
std::list<PredictionRequest> predictionRequestBuffer_; | ||
std::list<PredictionOutput> generatedPredictionOutputBuffer_; | ||
uint32_t predictionRequestCredits_ = 0; | ||
uint32_t predictionOutputCredits_ = 0; | ||
|
||
BasePredictor base_predictor_; | ||
|
||
/////////////////////////////////////////////////////////////////////////////// | ||
// Ports | ||
/////////////////////////////////////////////////////////////////////////////// | ||
|
||
// Internal DataInPort from fetch unit for prediction request | ||
sparta::DataInPort<PredictionRequest> in_fetch_predictionRequest_{ | ||
&unit_port_set_, "in_fetch_predictionRequest", sparta::SchedulingPhase::Tick, 0}; | ||
|
||
// Internal DataInPort from fetch unit for credits to indicate | ||
// availabilty of slots for sending prediction output | ||
sparta::DataInPort<uint32_t> in_fetch_predictionOutput_credits_{ | ||
&unit_port_set_, "in_fetch_predictionOutput_credits", sparta::SchedulingPhase::Tick, | ||
0}; | ||
|
||
// TODO | ||
|
||
// DataOutPort to fetch unit to send credits to indicate availability | ||
// of slots to receive prediction request | ||
sparta::DataOutPort<uint32_t> out_fetch_predictionRequest_credits_{ | ||
&unit_port_set_, "out_fetch_predictionRequest_credits"}; | ||
|
||
// DataOutPort to fetch unit to send prediction output | ||
sparta::DataOutPort<PredictionOutput> out_fetch_predictionOutput_{ | ||
&unit_port_set_, "out_fetch_predictionOutput"}; | ||
|
||
////////////////////////////////////////////////////////////////////////////// | ||
// Events | ||
////////////////////////////////////////////////////////////////////////////// | ||
/***sparta::PayloadEvent<PredictionOutput> ev_sendPrediction_{ | ||
&unit_event_set_, "ev_sendPrediction", | ||
CREATE_SPARTA_HANDLER_WITH_DATA(BPU, sendPrediction_, PredictionOutput)}; | ||
***/ | ||
|
||
////////////////////////////////////////////////////////////////////////////// | ||
// Counters | ||
////////////////////////////////////////////////////////////////////////////// | ||
sparta::Counter pred_req_num_{getStatisticSet(), "pred_req_num", | ||
"Number of prediction requests", | ||
sparta::Counter::COUNT_NORMAL}; | ||
sparta::Counter mispred_num_{getStatisticSet(), "mispred_num", | ||
"Number of mis-predictions", | ||
sparta::Counter::COUNT_NORMAL}; | ||
sparta::StatisticDef mispred_ratio_{getStatisticSet(), "mispred_ratio", | ||
"Percenatge of mis-prediction", getStatisticSet(), | ||
"mispred_num/pred_req_num"}; | ||
sparta::Counter branch_req_num_{getStatisticSet(), "branch_req_num", | ||
"Number of branch requests", | ||
sparta::Counter::COUNT_NORMAL}; | ||
sparta::Counter call_req_num_{getStatisticSet(), "call_req_num", | ||
"Number of call requests", sparta::Counter::COUNT_NORMAL}; | ||
sparta::Counter return_req_num_{getStatisticSet(), "return_req_num", | ||
"Number of return requests", | ||
sparta::Counter::COUNT_NORMAL}; | ||
sparta::Counter pht_req_num_{getStatisticSet(), "pht_req_num", | ||
"Number of requests made to PHT", | ||
sparta::Counter::COUNT_NORMAL}; | ||
sparta::Counter pht_hit_num_{getStatisticSet(), "pht_hit_num", "Number of hits on PHT", | ||
sparta::Counter::COUNT_NORMAL}; | ||
sparta::Counter pht_miss_num_{getStatisticSet(), "pht_miss_num", | ||
"Number of misses on PHT", sparta::Counter::COUNT_NORMAL}; | ||
sparta::StatisticDef pht_mispred_ratio_{getStatisticSet(), "pht_mispred_ratio", | ||
"Percentage of PHT mis-prediction", | ||
getStatisticSet(), "pht_miss_num/pht_req_num"}; | ||
sparta::Counter btb_req_num_{getStatisticSet(), "btb_req_num", | ||
"Number of requests to BTB", | ||
sparta::Counter::COUNT_NORMAL}; | ||
sparta::Counter btb_hit_num_{getStatisticSet(), "btb_hit_num", "NUmber of BTB hits", | ||
sparta::Counter::COUNT_NORMAL}; | ||
sparta::Counter btb_miss_num_{getStatisticSet(), "btb_miss_num", "Number of BTB misses", | ||
sparta::Counter::COUNT_NORMAL}; | ||
sparta::StatisticDef btb_hit_rate_{getStatisticSet(), "btb_hit_rate", | ||
"Rate of BTB hits", getStatisticSet(), | ||
"btb_hit_num/btb_req_num"}; | ||
sparta::StatisticDef btb_miss_rate_{getStatisticSet(), "btb_miss_rate", | ||
"Rate of BTB misses", getStatisticSet(), | ||
"btb_miss_num/btb_req_num"}; | ||
sparta::Counter ras_high_mark_{getStatisticSet(), "ras_high_mark", "RAS high mark", | ||
sparta::Counter::COUNT_NORMAL}; | ||
sparta::Counter ras_low_mark_{getStatisticSet(), "ras_low_mark", "RAS low mark", | ||
sparta::Counter::COUNT_NORMAL}; | ||
}; | ||
} // namespace BranchPredictor | ||
} // namespace olympia |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please provide default initializations OR make these
const