Add flexible same-bank refresh management.

This commit is contained in:
Lukas Steiner
2021-09-03 14:25:26 +02:00
parent 97f5169b38
commit 56fe13dbce
8 changed files with 94 additions and 53 deletions

View File

@@ -140,16 +140,21 @@ Row BankMachine::getOpenRow() const
return openRow;
}
BankMachine::State BankMachine::getState() const
{
return state;
}
bool BankMachine::isIdle() const
{
return (currentPayload == nullptr);
}
bool BankMachine::isActivated() const
{
return state == State::Activated;
}
bool BankMachine::isPrecharged() const
{
return state == State::Precharged;
}
BankMachineOpen::BankMachineOpen(SchedulerIF *scheduler, CheckerIF *checker, Bank bank)
: BankMachine(scheduler, checker, bank) {}

View File

@@ -52,24 +52,23 @@ public:
void updateState(Command);
void block();
enum class State {Precharged, Activated};
Rank getRank() const;
BankGroup getBankGroup() const;
Bank getBank() const;
Row getOpenRow() const;
State getState() const;
bool isIdle() const;
bool isActivated() const;
bool isPrecharged() const;
uint64_t getRefreshManagementCounter() const;
protected:
enum class State {Precharged, Activated} state = State::Precharged;
BankMachine(SchedulerIF *, CheckerIF *, Bank);
const MemSpec* memSpec;
tlm::tlm_generic_payload *currentPayload = nullptr;
SchedulerIF *scheduler;
CheckerIF *checker;
Command nextCommand = Command::NOP;
State state = State::Precharged;
Row openRow;
sc_core::sc_time timeToSchedule = sc_core::sc_max_time();
Rank rank = Rank(0);

View File

@@ -99,7 +99,7 @@ sc_time PowerDownManagerStaggered::start()
nextCommand = Command::PDEP;
for (auto it : bankMachinesOnRank)
{
if (it->getState() == BankMachine::State::Activated)
if (it->isActivated())
{
nextCommand = Command::PDEA;
break;

View File

@@ -117,7 +117,7 @@ sc_time RefreshManagerPerBank::start()
}
else
{
if (currentBankMachine->getState() == BankMachine::State::Activated)
if (currentBankMachine->isActivated())
nextCommand = Command::PRE;
else
{
@@ -158,7 +158,7 @@ sc_time RefreshManagerPerBank::start()
}
else
{
if (currentBankMachine->getState() == BankMachine::State::Activated)
if (currentBankMachine->isActivated())
nextCommand = Command::PRE;
else
nextCommand = Command::REFB;

View File

@@ -73,6 +73,8 @@ RefreshManagerSameBank::RefreshManagerSameBank(std::vector<BankMachine *> &bankM
maxPostponed = static_cast<int>(config.refreshMaxPostponed * memSpec->banksPerGroup);
maxPulledin = -static_cast<int>(config.refreshMaxPulledin * memSpec->banksPerGroup);
refreshManagement = config.refreshManagement;
}
CommandTuple::Type RefreshManagerSameBank::getNextCommand()
@@ -102,7 +104,7 @@ sc_time RefreshManagerSameBank::start()
if (state == State::Regular)
{
bool forcedRefresh = (flexibilityCounter == maxPostponed);
bool allBanksBusy = true;
bool allGroupsBusy = true;
if (!skipSelection)
{
@@ -120,31 +122,31 @@ sc_time RefreshManagerSameBank::start()
}
if (!groupIsBusy)
{
allBanksBusy = false;
allGroupsBusy = false;
currentIterator = bankIt;
break;
}
}
}
if (allBanksBusy && !forcedRefresh)
if (allGroupsBusy && !forcedRefresh)
{
flexibilityCounter++;
timeForNextTrigger += memSpec->getRefreshIntervalSB();
return timeForNextTrigger;
}
else
{
nextCommand = Command::REFSB;
for (auto it : *currentIterator)
{
if (it->getState() == BankMachine::State::Activated)
if (it->isActivated())
{
nextCommand = Command::PRESB;
break;
}
}
// only check for forced refresh, also block for PRESB
if (nextCommand == Command::REFSB && forcedRefresh)
{
for (auto it : *currentIterator)
@@ -159,7 +161,7 @@ sc_time RefreshManagerSameBank::start()
}
else // if (state == RmState::Pulledin)
{
bool allBanksBusy = true;
bool allGroupsBusy = true;
currentIterator = remainingBankMachines.begin();
for (auto bankIt = remainingBankMachines.begin(); bankIt != remainingBankMachines.end(); bankIt++)
@@ -175,24 +177,23 @@ sc_time RefreshManagerSameBank::start()
}
if (!groupIsBusy)
{
allBanksBusy = false;
allGroupsBusy = false;
currentIterator = bankIt;
break;
}
}
if (allBanksBusy)
if (allGroupsBusy)
{
state = State::Regular;
timeForNextTrigger += memSpec->getRefreshIntervalSB();
return timeForNextTrigger;
}
else
{
nextCommand = Command::REFSB;
for (auto it : *currentIterator)
{
if (it->getState() == BankMachine::State::Activated)
if (it->isActivated())
{
nextCommand = Command::PRESB;
break;
@@ -205,49 +206,83 @@ sc_time RefreshManagerSameBank::start()
}
}
}
else
if (refreshManagement)
{
bool RFMRequired = false;
if (Configuration::getInstance().refreshManagement == true)
bool mmtReached = false;
std::vector<std::list<std::vector<BankMachine*>>::iterator> imtCandidates;
for (auto bankIt = allBankMachines.begin(); bankIt != allBankMachines.end(); bankIt++)
{
for (auto bankIt = allBankMachines.begin(); bankIt != allBankMachines.end(); bankIt++)
for (auto groupIt: *bankIt)
{
for (auto bm : *bankIt)
if (groupIt->getRefreshManagementCounter() >= memSpec->getRAAMMT())
{
uint64_t threshold = memSpec->getRAAIMT() * memSpec->getRAAMMT();
if (bm->getRefreshManagementCounter() >= threshold)
mmtReached = true;
currentIterator = bankIt;
break;
}
else if (groupIt->getRefreshManagementCounter() >= memSpec->getRAAMMT())
{
imtCandidates.emplace_back(currentIterator);
}
}
}
if (mmtReached)
{
nextCommand = Command::RFMSB;
for (auto groupIt: *currentIterator)
{
groupIt->block();
if (groupIt->isActivated())
nextCommand = Command::PRESB;
}
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand,
&refreshPayloads[currentIterator->front()->getBank().ID() % memSpec->banksPerGroup]);
return timeToSchedule;
}
else if (!imtCandidates.empty())
{
// search for IMT candidates and check if all banks idle
bool allGroupsBusy = true;
for (auto candidateIt: imtCandidates)
{
bool groupIsBusy = false;
for (auto groupIt: *candidateIt)
{
if (!groupIt->isIdle())
{
RFMRequired = true;
currentIterator = bankIt;
groupIsBusy = true;
break;
}
}
}
}
if (RFMRequired)
{
nextCommand = Command::RFMSB;
for (auto it : *currentIterator)
{
if (it->getState() == BankMachine::State::Activated)
if (!groupIsBusy)
{
nextCommand = Command::PRESB;
allGroupsBusy = false;
currentIterator = candidateIt;
break;
}
}
for (auto it : *currentIterator)
it->block();
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, &refreshPayloads[currentIterator->front()->getBank().ID() % memSpec->banksPerGroup]);
return timeToSchedule;
}
else
{
return timeForNextTrigger;
if (!allGroupsBusy)
{
nextCommand = Command::RFMSB;
for (auto it: *currentIterator)
{
if (it->isActivated())
{
nextCommand = Command::PRESB;
break;
}
}
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand,
&refreshPayloads[currentIterator->front()->getBank().ID() % memSpec->banksPerGroup]);
return timeToSchedule;
}
}
}
return timeForNextTrigger;
}
void RefreshManagerSameBank::updateState(Command command)

View File

@@ -74,6 +74,8 @@ private:
bool sleeping = false;
bool skipSelection = false;
bool refreshManagement = false;
};
#endif // REFRESHMANAGERSAMEBANK_H

View File

@@ -88,7 +88,7 @@ tlm_generic_payload *SchedulerFrFcfs::getNextRequest(BankMachine *bankMachine) c
unsigned bankID = bankMachine->getBank().ID();
if (!buffer[bankID].empty())
{
if (bankMachine->getState() == BankMachine::State::Activated)
if (bankMachine->isActivated())
{
// Search for row hit
Row openRow = bankMachine->getOpenRow();

View File

@@ -89,7 +89,7 @@ tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine
unsigned bankID = bankMachine->getBank().ID();
if (!buffer[bankID].empty())
{
if (bankMachine->getState() == BankMachine::State::Activated)
if (bankMachine->isActivated())
{
// Filter all row hits
Row openRow = bankMachine->getOpenRow();