Implemented first version of new bankwise refresh.

This commit is contained in:
Lukas Steiner
2019-10-02 21:55:19 +02:00
parent 4328f4550b
commit 6e71e435c5
5 changed files with 47 additions and 48 deletions

View File

@@ -41,8 +41,8 @@ RefreshManager::RefreshManager(std::vector<BankMachine *> &bankMachines, Rank ra
: bankMachines(bankMachines), rank(rank), checker(checker)
{
memSpec = Configuration::getInstance().memSpec;
timeForNextTrigger = memSpec->getRefreshIntervalAB();
setUpDummy(refreshPayload, rank);
timeForNextTrigger = memSpec->getRefreshIntervalAB() - memSpec->getExecutionTime(Command::PREA);
}
std::pair<Command, tlm_generic_payload *> RefreshManager::getNextCommand()

View File

@@ -58,8 +58,8 @@ private:
tlm_generic_payload refreshPayload;
sc_time timeForNextTrigger;
sc_time timeToSchedule = SC_ZERO_TIME;
CheckerIF *checker;
Rank rank;
CheckerIF *checker;
Command nextCommand;
};

View File

@@ -37,61 +37,58 @@
#include "../../common/utils.h"
#include "../../common/dramExtensions.h"
RefreshManagerBankwise::RefreshManagerBankwise(std::vector<BankMachine *> &bankMachines, Rank, CheckerIF *checker)
: bankMachines(bankMachines), checker(checker)
RefreshManagerBankwise::RefreshManagerBankwise(std::vector<BankMachine *> &bankMachines, Rank rank, CheckerIF *checker)
: bankMachines(bankMachines), rank(rank), checker(checker)
{
memSpec = Configuration::getInstance().memSpec;
// TODO: implement for multiple ranks
sc_time currentREFB = memSpec->getRefreshIntervalPB() - memSpec->clk * (memSpec->NumberOfBanks - 1);
sc_time currentPRE = currentREFB - std::max(memSpec->clk * memSpec->NumberOfBanks, memSpec->getExecutionTime(Command::PRE));
timeForNextTrigger = currentPRE;
memSpec = Configuration::getInstance().memSpec;
timeForNextTrigger = memSpec->getRefreshIntervalPB();
refreshPayloads = std::vector<tlm_generic_payload>(memSpec->NumberOfBanks);
states = std::vector<RmState>(memSpec->NumberOfBanks, RmState::IDLE);
for (unsigned bankID = 0; bankID < memSpec->NumberOfBanks; bankID++)
{
setUpDummy(refreshPayloads[bankID], Rank(0), Bank(bankID));
triggerTimes.insert(std::pair<sc_time, Bank>(currentREFB, Bank(bankID)));
triggerTimes.insert(std::pair<sc_time, Bank>(currentPRE, Bank(bankID)));
currentREFB += memSpec->clk;
currentPRE += memSpec->clk;
}
refreshPayloads = std::vector<tlm_generic_payload>(memSpec->BanksPerRank);
//states = std::vector<RmState>(memSpec->NumberOfBanks, RmState::IDLE);
for (unsigned bankID = 0; bankID < memSpec->BanksPerRank; bankID++)
setUpDummy(refreshPayloads[bankID], rank, bankMachines[bankID]->getBank());
}
std::pair<Command, tlm_generic_payload *> RefreshManagerBankwise::getNextCommand()
{
if (sc_time_stamp() == timeForNextTrigger)
{
auto it = triggerTimes.begin();
Bank bank = it->second;
triggerTimes.erase(it);
triggerTimes.insert(std::pair<sc_time, Bank>(timeForNextTrigger + memSpec->getRefreshIntervalPB(), bank));
timeForNextTrigger = triggerTimes.begin()->first;
if (states[bank.ID()] == RmState::IDLE)
{
states[bank.ID()] = RmState::REFRESHING;
bool forcedPrecharge = true;/*= bankMachines[bank.ID()]->forcePrecharge();*/
if (forcedPrecharge)
return std::pair<Command, tlm_generic_payload *>(Command::PRE, &refreshPayloads[bank.ID()]);
else
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
}
else
{
states[bank.ID()] = RmState::IDLE;
return std::pair<Command, tlm_generic_payload *>(Command::REFB, &refreshPayloads[bank.ID()]);
}
}
if (sc_time_stamp() == timeToSchedule)
return std::pair<Command, tlm_generic_payload *>(nextCommand, &refreshPayloads[nextBankID]);
else
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
}
sc_time RefreshManagerBankwise::startRefreshManager()
{
return timeForNextTrigger - sc_time_stamp();
if (sc_time_stamp() >= timeForNextTrigger)
{
sc_time delay;
bankMachines[nextBankID]->block();
if (bankMachines[nextBankID]->getState() == BmState::Activated)
{
delay = checker->delayToSatisfyConstraints(Command::PRE, rank, BankGroup(0),
bankMachines[nextBankID]->getBank());
nextCommand = Command::PRE;
}
else
{
delay = checker->delayToSatisfyConstraints(Command::REFB, rank, BankGroup(0),
bankMachines[nextBankID]->getBank());
nextCommand = Command::REFB;
}
timeToSchedule = sc_time_stamp() + delay;
return delay;
}
else
return timeForNextTrigger - sc_time_stamp();
}
void RefreshManagerBankwise::updateState(Command, tlm_generic_payload *)
void RefreshManagerBankwise::updateState(Command command, tlm_generic_payload *)
{
if (command == Command::REFB)
{
//state = RmState::IDLE;
nextBankID = (nextBankID + 1) % memSpec->BanksPerRank;
timeForNextTrigger += memSpec->getRefreshIntervalPB();
}
//else if (command == Command::PRE) do nothing?
}

View File

@@ -52,14 +52,16 @@ public:
void updateState(Command, tlm_generic_payload *);
private:
enum class RmState {IDLE, PRECHARGED} state = RmState::IDLE;
const MemSpec *memSpec;
std::vector<BankMachine *> bankMachines;
std::vector<tlm_generic_payload> refreshPayloads;
std::map<sc_time, Bank> triggerTimes;
sc_time timeForNextTrigger;
enum class RmState {IDLE, REFRESHING};
std::vector<RmState> states;
sc_time timeToSchedule = SC_ZERO_TIME;
Rank rank;
CheckerIF *checker;
Command nextCommand;
unsigned nextBankID = 0;
};
#endif // REFRESHMANAGERBANKWISE_H

View File

@@ -195,7 +195,7 @@ tlm_sync_enum Dram::nb_transport_fw(tlm_generic_payload &payload,
{
DRAMPower->doCommand(MemCommand::REFB, bank, cycle);
sendToController(payload, END_REFB,
delay + memSpec->getExecutionTime(Command::REFA));
delay + memSpec->getExecutionTime(Command::REFB));
}
// Powerdown phases have to be started and ended by the controller, because they do not have a fixed length
else if (phase == BEGIN_PDNA)