Implemented first version of new bankwise refresh.
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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?
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user