Implemented first version of new refresh (no REFB).
This commit is contained in:
@@ -213,8 +213,11 @@ void ConfigurationLoader::loadDDR3(Configuration &config, XMLElement *xmlSpec)
|
||||
// MemArchitecture
|
||||
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
||||
memSpec->NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->NumberOfBankGroups = memSpec->NumberOfRanks;
|
||||
memSpec->NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks") * memSpec->NumberOfRanks;
|
||||
memSpec->BanksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->GroupsPerRank = 1;
|
||||
memSpec->BanksPerGroup = memSpec->BanksPerRank / memSpec->GroupsPerRank;
|
||||
memSpec->NumberOfBanks = memSpec->BanksPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->NumberOfBankGroups = memSpec->GroupsPerRank * memSpec->NumberOfRanks;
|
||||
|
||||
// MemTimings specific for DDR3
|
||||
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
||||
@@ -259,8 +262,11 @@ void ConfigurationLoader::loadDDR4(Configuration &config, XMLElement *xmlSpec)
|
||||
// MemArchitecture
|
||||
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
||||
memSpec->NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->NumberOfBankGroups = queryUIntParameter(architecture, "nbrOfBankGroups") * memSpec->NumberOfRanks;
|
||||
memSpec->NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks") * memSpec->NumberOfRanks;
|
||||
memSpec->BanksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->GroupsPerRank = queryUIntParameter(architecture, "nbrOfBankGroups");
|
||||
memSpec->BanksPerGroup = memSpec->BanksPerRank / memSpec->GroupsPerRank;
|
||||
memSpec->NumberOfBanks = memSpec->BanksPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->NumberOfBankGroups = memSpec->GroupsPerRank * memSpec->NumberOfRanks;
|
||||
|
||||
// MemTimings specific for DDR4
|
||||
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
||||
@@ -328,8 +334,11 @@ void ConfigurationLoader::loadLPDDR4(Configuration &config, XMLElement *xmlSpec)
|
||||
// MemArchitecture:
|
||||
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
||||
memSpec->NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->NumberOfBankGroups = memSpec->NumberOfRanks;
|
||||
memSpec->NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks") * memSpec->NumberOfRanks;
|
||||
memSpec->BanksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->GroupsPerRank = 1;
|
||||
memSpec->BanksPerGroup = memSpec->BanksPerRank / memSpec->GroupsPerRank;
|
||||
memSpec->NumberOfBanks = memSpec->BanksPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->NumberOfBankGroups = memSpec->GroupsPerRank * memSpec->NumberOfRanks;
|
||||
|
||||
// MemTimings specific for LPDDR4
|
||||
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
||||
@@ -383,8 +392,11 @@ void ConfigurationLoader::loadWideIO(Configuration &config, XMLElement *xmlSpec)
|
||||
// MemArchitecture
|
||||
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
||||
memSpec->NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
||||
memSpec->NumberOfBankGroups = memSpec->NumberOfRanks;
|
||||
memSpec->NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks") * memSpec->NumberOfRanks;
|
||||
memSpec->BanksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
||||
memSpec->GroupsPerRank = 1;
|
||||
memSpec->BanksPerGroup = memSpec->BanksPerRank / memSpec->GroupsPerRank;
|
||||
memSpec->NumberOfBanks = memSpec->BanksPerRank * memSpec->NumberOfRanks;
|
||||
memSpec->NumberOfBankGroups = memSpec->GroupsPerRank * memSpec->NumberOfRanks;
|
||||
|
||||
// MemTimings specific for WideIO
|
||||
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
||||
|
||||
@@ -70,14 +70,18 @@ struct MemSpec
|
||||
std::string MemoryId = "not defined.";
|
||||
std::string MemoryType = "not defined.";
|
||||
|
||||
unsigned int NumberOfBanks;
|
||||
unsigned int NumberOfRanks;
|
||||
unsigned int BurstLength;
|
||||
unsigned int DataRate;
|
||||
unsigned int NumberOfBankGroups;
|
||||
unsigned int NumberOfBanks;
|
||||
unsigned int NumberOfRows;
|
||||
unsigned int NumberOfColumns;
|
||||
unsigned int BurstLength;
|
||||
unsigned int DataRate;
|
||||
unsigned int bitWidth;
|
||||
unsigned int NumberOfBankGroups;
|
||||
|
||||
unsigned int BanksPerRank;
|
||||
unsigned int BanksPerGroup;
|
||||
unsigned int GroupsPerRank;
|
||||
|
||||
// Clock
|
||||
double clkMHz;
|
||||
|
||||
@@ -38,15 +38,13 @@ BankMachine::BankMachine(SchedulerIF *scheduler, CheckerIF *checker, Bank bank)
|
||||
: scheduler(scheduler), checker(checker), bank(bank)
|
||||
{
|
||||
MemSpec *memSpec = Configuration::getInstance().memSpec;
|
||||
unsigned banksPerRank = memSpec->NumberOfBanks / memSpec->NumberOfRanks;
|
||||
unsigned banksPerGroup = memSpec->NumberOfBanks / memSpec->NumberOfBankGroups;
|
||||
rank = Rank(bank.ID() / banksPerRank);
|
||||
bankgroup = BankGroup(bank.ID() / banksPerGroup);
|
||||
rank = Rank(bank.ID() / memSpec->BanksPerRank);
|
||||
bankgroup = BankGroup(bank.ID() / memSpec->BanksPerGroup);
|
||||
}
|
||||
|
||||
std::pair<Command, tlm_generic_payload *> BankMachine::getNextCommand()
|
||||
{
|
||||
if (sc_time_stamp() == timeToSchedule)
|
||||
if (sc_time_stamp() == timeToSchedule && !blocked)
|
||||
return std::pair<Command, tlm_generic_payload *>(nextCommand, currentPayload);
|
||||
else
|
||||
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
|
||||
@@ -59,7 +57,7 @@ void BankMachine::updateState(Command command)
|
||||
currentState = BmState::Activated;
|
||||
currentRow = nextRow;
|
||||
}
|
||||
else if (command == Command::PRE)
|
||||
else if (command == Command::PRE || command == Command::PREA)
|
||||
currentState = BmState::Precharged;
|
||||
else if (command == Command::RD || command == Command::WR)
|
||||
currentPayload = nullptr;
|
||||
@@ -68,19 +66,15 @@ void BankMachine::updateState(Command command)
|
||||
currentState = BmState::Precharged;
|
||||
currentPayload = nullptr;
|
||||
}
|
||||
else if (command == Command::REFA || command == Command::REFB)
|
||||
blocked = false;
|
||||
else
|
||||
SC_REPORT_FATAL("BankMachine", "Unknown phase");
|
||||
}
|
||||
|
||||
bool BankMachine::forcePrecharge()
|
||||
void BankMachine::block()
|
||||
{
|
||||
if (currentState != BmState::Precharged)
|
||||
{
|
||||
currentState = BmState::Precharged;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
blocked = true;
|
||||
}
|
||||
|
||||
Rank BankMachine::getRank()
|
||||
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
virtual sc_time startBankMachine() = 0;
|
||||
std::pair<Command, tlm_generic_payload *> getNextCommand();
|
||||
void updateState(Command);
|
||||
bool forcePrecharge();
|
||||
void block();
|
||||
|
||||
Rank getRank();
|
||||
Bank getBank();
|
||||
@@ -82,6 +82,7 @@ protected:
|
||||
Rank rank = Rank(0);
|
||||
BankGroup bankgroup = BankGroup(0);
|
||||
Bank bank;
|
||||
bool blocked = false;
|
||||
};
|
||||
|
||||
class BankMachineOpen final : public BankMachine
|
||||
|
||||
@@ -58,31 +58,20 @@ Controller::Controller(sc_module_name name) :
|
||||
dont_initialize();
|
||||
|
||||
Configuration config = Configuration::getInstance();
|
||||
MemSpec *memSpec = config.memSpec;
|
||||
maxNumberOfPayloads = config.MaxNrOfTransactions;
|
||||
|
||||
if (config.memSpec->MemoryType == "DDR3")
|
||||
if (memSpec->MemoryType == "DDR3")
|
||||
checker = new CheckerDDR3();
|
||||
else if (config.memSpec->MemoryType == "DDR4")
|
||||
else if (memSpec->MemoryType == "DDR4")
|
||||
checker = new CheckerDDR4();
|
||||
else if (config.memSpec->MemoryType == "WIDEIO_SDR")
|
||||
else if (memSpec->MemoryType == "WIDEIO_SDR")
|
||||
checker = new CheckerWideIO();
|
||||
else if (config.memSpec->MemoryType == "LPDDR4")
|
||||
else if (memSpec->MemoryType == "LPDDR4")
|
||||
checker = new CheckerLPDDR4();
|
||||
else
|
||||
SC_REPORT_FATAL("Controller", "Unsupported DRAM type");
|
||||
|
||||
if (config.ControllerCoreRefDisable)
|
||||
refreshManager = new RefreshManagerDummy();
|
||||
else if (config.BankwiseLogic)
|
||||
{
|
||||
refreshManager = new RefreshManagerBankwise(bankMachines);
|
||||
refreshEvent.notify(refreshManager->getTriggerDelay());
|
||||
}
|
||||
else
|
||||
{
|
||||
refreshManager = new RefreshManager(bankMachines);
|
||||
refreshEvent.notify(refreshManager->getTriggerDelay());
|
||||
}
|
||||
|
||||
if (config.Scheduler == "FifoStrict")
|
||||
{
|
||||
scheduler = new SchedulerFifo();
|
||||
@@ -100,12 +89,12 @@ Controller::Controller(sc_module_name name) :
|
||||
{
|
||||
if (config.AdaptivePagePolicy)
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < config.memSpec->NumberOfBanks; bankID++)
|
||||
for (unsigned bankID = 0; bankID < memSpec->NumberOfBanks; bankID++)
|
||||
bankMachines.push_back(new BankMachineOpenAdaptive(scheduler, checker, Bank(bankID)));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < config.memSpec->NumberOfBanks; bankID++)
|
||||
for (unsigned bankID = 0; bankID < memSpec->NumberOfBanks; bankID++)
|
||||
bankMachines.push_back(new BankMachineOpen(scheduler, checker, Bank(bankID)));
|
||||
}
|
||||
}
|
||||
@@ -113,16 +102,45 @@ Controller::Controller(sc_module_name name) :
|
||||
{
|
||||
if (config.AdaptivePagePolicy)
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < config.memSpec->NumberOfBanks; bankID++)
|
||||
for (unsigned bankID = 0; bankID < memSpec->NumberOfBanks; bankID++)
|
||||
bankMachines.push_back(new BankMachineClosedAdaptive(scheduler, checker, Bank(bankID)));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < config.memSpec->NumberOfBanks; bankID++)
|
||||
for (unsigned bankID = 0; bankID < memSpec->NumberOfBanks; bankID++)
|
||||
bankMachines.push_back(new BankMachineClosed(scheduler, checker, Bank(bankID)));
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned rankID = 0; rankID < memSpec->NumberOfRanks; rankID++)
|
||||
{
|
||||
bankMachinesOnRank.push_back(std::vector<BankMachine *>(bankMachines.begin() + rankID * memSpec->BanksPerRank,
|
||||
bankMachines.begin() + (rankID + 1) * memSpec->BanksPerRank));
|
||||
}
|
||||
|
||||
if (config.ControllerCoreRefDisable)
|
||||
refreshManagers.push_back(new RefreshManagerDummy());
|
||||
else if (config.BankwiseLogic)
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec->NumberOfRanks; rankID++)
|
||||
{
|
||||
RefreshManagerIF *manager = new RefreshManagerBankwise
|
||||
(bankMachinesOnRank[rankID], Rank(rankID), checker);
|
||||
refreshManagers.push_back(manager);
|
||||
refreshEvent.notify(manager->startRefreshManager());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec->NumberOfRanks; rankID++)
|
||||
{
|
||||
RefreshManagerIF *manager = new RefreshManager
|
||||
(bankMachinesOnRank[rankID], Rank(rankID), checker);
|
||||
refreshManagers.push_back(manager);
|
||||
refreshEvent.notify(manager->startRefreshManager());
|
||||
}
|
||||
}
|
||||
|
||||
startBandwidthIdleCollector();
|
||||
}
|
||||
|
||||
@@ -130,18 +148,19 @@ Controller::~Controller()
|
||||
{
|
||||
endBandwithIdleCollector();
|
||||
|
||||
for (auto it : refreshManagers)
|
||||
delete it;
|
||||
for (auto it : bankMachines)
|
||||
delete it;
|
||||
delete commandMux;
|
||||
delete scheduler;
|
||||
delete refreshManager;
|
||||
delete checker;
|
||||
}
|
||||
|
||||
void Controller::controllerMethod()
|
||||
{
|
||||
// (1) Release payload if arbiter has accepted the result
|
||||
if (sc_time_stamp() == timeToRelease /*&& payloadToRelease != nullptr*/)
|
||||
if (sc_time_stamp() == timeToRelease && payloadToRelease != nullptr)
|
||||
releasePayload();
|
||||
|
||||
// (2) Accept new request from arbiter
|
||||
@@ -170,39 +189,51 @@ void Controller::controllerMethod()
|
||||
it->startBankMachine();
|
||||
|
||||
// (5) Choose one request and send it to DRAM
|
||||
std::pair<Command, tlm_generic_payload *> result;
|
||||
// (5.1) Check for refresh command (PREA or REFA)
|
||||
result = refreshManager->getNextCommand();
|
||||
refreshEvent.notify(refreshManager->getTriggerDelay());
|
||||
if (result.second != nullptr)
|
||||
sendToDram(result.first, result.second);
|
||||
// (5.2) Check for other commands (PRE, ACT, RD or WR)
|
||||
else
|
||||
std::pair<Command, tlm_generic_payload *> commandPair;
|
||||
std::vector<std::pair<Command, tlm_generic_payload *>> readyCommands;
|
||||
// (5.1) Check for refresh command (PREA/PRE or REFA/REFB)
|
||||
for (auto it : refreshManagers)
|
||||
{
|
||||
std::vector<std::pair<Command, tlm_generic_payload *>> readyCommands;
|
||||
for (auto it : bankMachines)
|
||||
commandPair = it->getNextCommand();
|
||||
if (commandPair.second != nullptr)
|
||||
readyCommands.push_back(commandPair);
|
||||
}
|
||||
// (5.2) Check for other commands (PRE, ACT, RD or WR)
|
||||
for (auto it : bankMachines)
|
||||
{
|
||||
commandPair = it->getNextCommand();
|
||||
if (commandPair.second != nullptr)
|
||||
readyCommands.push_back(commandPair);
|
||||
}
|
||||
if (!readyCommands.empty())
|
||||
{
|
||||
commandPair = commandMux->selectCommand(readyCommands);
|
||||
if (commandPair.second != nullptr) // TODO: can happen with FIFO strict
|
||||
{
|
||||
result = it->getNextCommand();
|
||||
if (result.second != nullptr)
|
||||
readyCommands.push_back(result);
|
||||
}
|
||||
if (!readyCommands.empty())
|
||||
{
|
||||
result = commandMux->selectCommand(readyCommands);
|
||||
if (result.second != nullptr)
|
||||
Rank rank = DramExtension::getRank(commandPair.second);
|
||||
if (commandPair.first == Command::PREA || commandPair.first == Command::REFA)
|
||||
{
|
||||
unsigned bankID = DramExtension::getBank(result.second).ID();
|
||||
bankMachines[bankID]->updateState(result.first);
|
||||
sendToDram(result.first, result.second);
|
||||
for (auto it : bankMachinesOnRank[rank.ID()])
|
||||
it->updateState(commandPair.first);
|
||||
}
|
||||
else
|
||||
{
|
||||
Bank bank = DramExtension::getBank(commandPair.second);
|
||||
bankMachines[bank.ID()]->updateState(commandPair.first);
|
||||
}
|
||||
refreshManagers[rank.ID()]->updateState(commandPair.first, commandPair.second);
|
||||
sendToDram(commandPair.first, commandPair.second);
|
||||
}
|
||||
}
|
||||
|
||||
// (6) Restart bank machines to issue new requests for the future
|
||||
// (6) Restart bank machines and refresh managers to issue new requests for the future
|
||||
for (auto it : refreshManagers)
|
||||
bankMachineEvent.notify(it->startRefreshManager());
|
||||
|
||||
for (auto it : bankMachines)
|
||||
{
|
||||
sc_time delay = it->startBankMachine();
|
||||
if (delay != SC_ZERO_TIME) // must be checked to avoid livelock
|
||||
if (delay != SC_ZERO_TIME) // TODO: must be checked to avoid livelock
|
||||
bankMachineEvent.notify(delay);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,7 @@ protected:
|
||||
|
||||
private:
|
||||
unsigned numberOfPayloads = 0;
|
||||
unsigned maxNumberOfPayloads;
|
||||
tlm_generic_payload *payloadToAcquire = nullptr;
|
||||
sc_time timeToAcquire = SC_ZERO_TIME;
|
||||
tlm_generic_payload *payloadToRelease = nullptr;
|
||||
@@ -80,10 +81,11 @@ private:
|
||||
std::queue<std::pair<sc_time, tlm_generic_payload *>> responseQueue;
|
||||
|
||||
std::vector<BankMachine *> bankMachines;
|
||||
std::vector<std::vector<BankMachine *>> bankMachinesOnRank;
|
||||
CmdMuxIF *commandMux;
|
||||
SchedulerIF *scheduler;
|
||||
CheckerIF *checker;
|
||||
RefreshManagerIF *refreshManager;
|
||||
std::vector<RefreshManagerIF *> refreshManagers;
|
||||
|
||||
void releasePayload();
|
||||
void acquirePayload();
|
||||
|
||||
@@ -41,13 +41,6 @@ CheckerDDR3::CheckerDDR3()
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerDDR3", "Wrong MemSpec chosen");
|
||||
|
||||
if (config.ControllerCoreRefDisable)
|
||||
refreshChecker = new RefreshCheckerDDR3Dummy(memSpec);
|
||||
else if (config.BankwiseLogic)
|
||||
refreshChecker = new RefreshCheckerDDR3Bankwise(memSpec);
|
||||
else
|
||||
refreshChecker = new RefreshCheckerDDR3(memSpec);
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(numberOfCommands(), std::vector<sc_time>(memSpec->NumberOfBanks));
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
||||
@@ -57,11 +50,6 @@ CheckerDDR3::CheckerDDR3()
|
||||
lastActivates = std::vector<std::queue<sc_time>>(memSpec->NumberOfRanks);
|
||||
}
|
||||
|
||||
CheckerDDR3::~CheckerDDR3()
|
||||
{
|
||||
delete refreshChecker;
|
||||
}
|
||||
|
||||
sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
|
||||
{
|
||||
sc_time lastCommandStart;
|
||||
@@ -75,12 +63,17 @@ sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->tCCD + memSpec->tWR + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + memSpec->BurstLength / 2 * memSpec->clk + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
@@ -93,14 +86,12 @@ sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFB][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
// lastCommandStart = lastScheduledByCommandAndBank[Command::REFB][bank.ID()];
|
||||
// if (lastCommandStart != SC_ZERO_TIME)
|
||||
// earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
if (lastActivates[rank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastActivates[rank.ID()].front() + memSpec->tFAW);
|
||||
|
||||
refreshChecker->delayToSatisfyACT(bank, earliestTimeToStart);
|
||||
}
|
||||
else if (command == Command::RD || command == Command::RDA)
|
||||
{
|
||||
@@ -117,13 +108,13 @@ sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->tCCD + memSpec->tWTR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + memSpec->BurstLength / 2 * memSpec->clk + memSpec->tWTR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->tCCD + memSpec->tWTR);
|
||||
|
||||
refreshChecker->delayToSatisfyRD(bank, earliestTimeToStart);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + memSpec->BurstLength / 2 * memSpec->clk + memSpec->tWTR);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
{
|
||||
@@ -132,11 +123,13 @@ sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRL + memSpec->tCCD + 2 * memSpec->clk - memSpec->tWL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tRL + memSpec->BurstLength / 2 * memSpec->clk + 2 * memSpec->clk - memSpec->tWL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRL + memSpec->tCCD + 2 * memSpec->clk - memSpec->tWL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tRL + memSpec->BurstLength / 2 * memSpec->clk + 2 * memSpec->clk - memSpec->tWL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
@@ -145,8 +138,6 @@ sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
|
||||
refreshChecker->delayToSatisfyWR(bank, earliestTimeToStart);
|
||||
}
|
||||
else if (command == Command::PRE)
|
||||
{
|
||||
@@ -159,9 +150,58 @@ sc_time CheckerDDR3::delayToSatisfyConstraints(Command command, Rank rank, BankG
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->tCCD + memSpec->tWR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + memSpec->BurstLength / 2 * memSpec->clk + memSpec->tWR);
|
||||
}
|
||||
else if (command == Command::PREA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
refreshChecker->delayToSatisfyPRE(bank, earliestTimeToStart);
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + memSpec->BurstLength / 2 * memSpec->clk + memSpec->tWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + memSpec->BurstLength / 2 * memSpec->clk + memSpec->tWR);
|
||||
}
|
||||
else if (command == Command::REFA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
|
||||
+ memSpec->tWL + memSpec->BurstLength / 2 * memSpec->clk + memSpec->tWR + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
|
||||
if (lastCommandStart != SC_ZERO_TIME)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -189,75 +229,4 @@ void CheckerDDR3::insert(Command command, Rank rank, BankGroup, Bank bank)
|
||||
lastActivates[rank.ID()].pop();
|
||||
lastActivates[rank.ID()].push(sc_time_stamp());
|
||||
}
|
||||
else if (command == Command::REFA || command == Command::REFB)
|
||||
refreshChecker->insert(bank);
|
||||
}
|
||||
|
||||
// TODO: max(earliestTimeToStart, ...) needed?
|
||||
void RefreshCheckerDDR3::delayToSatisfyACT(Bank, sc_time &earliestTimeToStart)
|
||||
{
|
||||
if (earliestTimeToStart >= (timeForNextPREA - memSpec->tRAS))
|
||||
earliestTimeToStart = timeForNextREFA + memSpec->tRFC;
|
||||
}
|
||||
|
||||
void RefreshCheckerDDR3::delayToSatisfyRD(Bank, sc_time &earliestTimeToStart)
|
||||
{
|
||||
if (earliestTimeToStart >= (timeForNextPREA - memSpec->tRTP))
|
||||
earliestTimeToStart = timeForNextREFA + memSpec->tRFC;
|
||||
}
|
||||
|
||||
void RefreshCheckerDDR3::delayToSatisfyWR(Bank, sc_time &earliestTimeToStart)
|
||||
{
|
||||
if (earliestTimeToStart >= (timeForNextPREA - memSpec->tWL - memSpec->tCCD - memSpec->tWR))
|
||||
earliestTimeToStart = timeForNextREFA + memSpec->tRFC;
|
||||
}
|
||||
|
||||
void RefreshCheckerDDR3::delayToSatisfyPRE(Bank, sc_time &earliestTimeToStart)
|
||||
{
|
||||
if (earliestTimeToStart >= timeForNextPREA)
|
||||
earliestTimeToStart = timeForNextREFA + memSpec->tRFC;
|
||||
}
|
||||
|
||||
void RefreshCheckerDDR3::insert(Bank)
|
||||
{
|
||||
timeForNextREFA += memSpec->tREFI;
|
||||
timeForNextPREA += memSpec->tREFI;
|
||||
}
|
||||
|
||||
RefreshCheckerDDR3Bankwise::RefreshCheckerDDR3Bankwise(const MemSpecDDR3 *memSpec)
|
||||
: RefreshCheckerDDR3Dummy(memSpec)
|
||||
{
|
||||
sc_time currentREFB = memSpec->tREFI - memSpec->clk * (memSpec->NumberOfBanks - 1);
|
||||
sc_time currentPRE = currentREFB - std::max(memSpec->clk * memSpec->NumberOfBanks, memSpec->tRP);
|
||||
for (unsigned bankID = 0; bankID < memSpec->NumberOfBanks; bankID++)
|
||||
{
|
||||
timesForNextREFB.push_back(currentREFB);
|
||||
timesForNextPRE.push_back(currentPRE);
|
||||
currentREFB += memSpec->clk;
|
||||
currentPRE += memSpec->clk;
|
||||
}
|
||||
}
|
||||
|
||||
void RefreshCheckerDDR3Bankwise::delayToSatisfyACT(Bank bank, sc_time &earliestTimeToStart)
|
||||
{
|
||||
if (earliestTimeToStart >= (timesForNextPRE[bank.ID()] - memSpec->tRAS))
|
||||
earliestTimeToStart = timesForNextREFB[bank.ID()] + memSpec->tRFC;
|
||||
}
|
||||
|
||||
void RefreshCheckerDDR3Bankwise::delayToSatisfyRD(Bank bank, sc_time &earliestTimeToStart)
|
||||
{
|
||||
if (earliestTimeToStart >= (timesForNextPRE[bank.ID()] - memSpec->tRTP))
|
||||
earliestTimeToStart = timesForNextREFB[bank.ID()] + memSpec->tRFC;
|
||||
}
|
||||
|
||||
void RefreshCheckerDDR3Bankwise::delayToSatisfyWR(Bank bank, sc_time &earliestTimeToStart)
|
||||
{
|
||||
if (earliestTimeToStart >= (timesForNextPRE[bank.ID()] - memSpec->tWL - memSpec->tCCD - memSpec->tWR))
|
||||
earliestTimeToStart = timesForNextREFB[bank.ID()] + memSpec->tRFC;
|
||||
}
|
||||
|
||||
void RefreshCheckerDDR3Bankwise::insert(Bank bank)
|
||||
{
|
||||
timesForNextREFB[bank.ID()] += memSpec->tREFI;
|
||||
timesForNextPRE[bank.ID()] += memSpec->tREFI;
|
||||
}
|
||||
|
||||
@@ -41,13 +41,10 @@
|
||||
#include "../../configuration/memspec/MemSpecDDR3.h"
|
||||
#include "../../configuration/Configuration.h"
|
||||
|
||||
class RefreshCheckerDDR3Dummy;
|
||||
|
||||
class CheckerDDR3 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
CheckerDDR3();
|
||||
~CheckerDDR3();
|
||||
sc_time delayToSatisfyConstraints(Command, Rank, BankGroup, Bank) const;
|
||||
void insert(Command, Rank, BankGroup, Bank);
|
||||
|
||||
@@ -62,58 +59,8 @@ private:
|
||||
// Four activate window
|
||||
std::vector<std::queue<sc_time>> lastActivates;
|
||||
|
||||
RefreshCheckerDDR3Dummy *refreshChecker;
|
||||
|
||||
// PowerDown TODO: Implement this method?
|
||||
//sc_time getTimeConstraintToEnterPowerDown(Command lastCmd, Command pdnCmd) const;
|
||||
};
|
||||
|
||||
class RefreshCheckerDDR3Dummy
|
||||
{
|
||||
protected:
|
||||
friend class CheckerDDR3;
|
||||
RefreshCheckerDDR3Dummy(const MemSpecDDR3 *memSpec) : memSpec(memSpec) {}
|
||||
virtual ~RefreshCheckerDDR3Dummy() {}
|
||||
|
||||
virtual void delayToSatisfyACT(Bank, sc_time &) {}
|
||||
virtual void delayToSatisfyRD(Bank, sc_time &) {}
|
||||
virtual void delayToSatisfyWR(Bank, sc_time &) {}
|
||||
virtual void delayToSatisfyPRE(Bank, sc_time &) {}
|
||||
virtual void insert(Bank) {}
|
||||
|
||||
const MemSpecDDR3 *memSpec;
|
||||
};
|
||||
|
||||
class RefreshCheckerDDR3 final : public RefreshCheckerDDR3Dummy
|
||||
{
|
||||
private:
|
||||
friend class CheckerDDR3;
|
||||
RefreshCheckerDDR3(const MemSpecDDR3 *memSpec)
|
||||
: RefreshCheckerDDR3Dummy(memSpec) {}
|
||||
|
||||
void delayToSatisfyACT(Bank, sc_time &);
|
||||
void delayToSatisfyRD(Bank, sc_time &);
|
||||
void delayToSatisfyWR(Bank, sc_time &);
|
||||
void delayToSatisfyPRE(Bank, sc_time &);
|
||||
void insert(Bank);
|
||||
|
||||
sc_time timeForNextREFA = memSpec->tREFI;
|
||||
sc_time timeForNextPREA = timeForNextREFA - memSpec->tRP;
|
||||
};
|
||||
|
||||
class RefreshCheckerDDR3Bankwise final : public RefreshCheckerDDR3Dummy
|
||||
{
|
||||
private:
|
||||
friend class CheckerDDR3;
|
||||
RefreshCheckerDDR3Bankwise(const MemSpecDDR3 *);
|
||||
|
||||
void delayToSatisfyACT(Bank, sc_time &);
|
||||
void delayToSatisfyRD(Bank, sc_time &);
|
||||
void delayToSatisfyWR(Bank, sc_time &);
|
||||
void insert(Bank);
|
||||
|
||||
std::vector<sc_time> timesForNextREFB;
|
||||
std::vector<sc_time> timesForNextPRE;
|
||||
};
|
||||
|
||||
#endif // CHECKERDDR3_H
|
||||
|
||||
@@ -39,11 +39,6 @@
|
||||
std::pair<Command, tlm_generic_payload *>
|
||||
CmdMuxStrict::selectCommand(std::vector<std::pair<Command, tlm_generic_payload *>> &readyCommands)
|
||||
{
|
||||
for (auto it : readyCommands)
|
||||
{
|
||||
if (it.first == Command::ACT || it.first == Command::PRE)
|
||||
return it;
|
||||
}
|
||||
for (auto it : readyCommands)
|
||||
{
|
||||
if (commandIsIn(it.first, {Command::RD, Command::RDA, Command::WR, Command::WRA}))
|
||||
@@ -55,5 +50,11 @@ CmdMuxStrict::selectCommand(std::vector<std::pair<Command, tlm_generic_payload *
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto it : readyCommands)
|
||||
{
|
||||
if (commandIsIn(it.first, {Command::ACT, Command::PRE,
|
||||
Command::PREA, Command::REFA, Command::REFB}))
|
||||
return it;
|
||||
}
|
||||
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
|
||||
}
|
||||
|
||||
@@ -37,41 +37,69 @@
|
||||
#include "../../configuration/Configuration.h"
|
||||
#include "../../common/utils.h"
|
||||
|
||||
RefreshManager::RefreshManager(std::vector<BankMachine *> &bankMachines) : bankMachines(bankMachines)
|
||||
RefreshManager::RefreshManager(std::vector<BankMachine *> &bankMachines, Rank rank, CheckerIF *checker)
|
||||
: bankMachines(bankMachines), rank(rank), checker(checker)
|
||||
{
|
||||
memSpec = Configuration::getInstance().memSpec;
|
||||
setUpDummy(refreshPayload);
|
||||
setUpDummy(refreshPayload, rank);
|
||||
timeForNextTrigger = memSpec->getRefreshIntervalAB() - memSpec->getExecutionTime(Command::PREA);
|
||||
}
|
||||
|
||||
std::pair<Command, tlm_generic_payload *> RefreshManager::getNextCommand()
|
||||
{
|
||||
if (sc_time_stamp() == timeForNextTrigger)
|
||||
{
|
||||
if (state == RmState::IDLE)
|
||||
{
|
||||
state = RmState::REFRESHING;
|
||||
timeForNextTrigger += memSpec->getExecutionTime(Command::PREA);
|
||||
bool forcedPrecharges = false;
|
||||
for (auto it : bankMachines)
|
||||
forcedPrecharges |= it->forcePrecharge();
|
||||
if (forcedPrecharges)
|
||||
return std::pair<Command, tlm_generic_payload *>(Command::PREA, &refreshPayload);
|
||||
else
|
||||
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
state = RmState::IDLE;
|
||||
timeForNextTrigger += (memSpec->getRefreshIntervalAB() - memSpec->getExecutionTime(Command::PREA));
|
||||
return std::pair<Command, tlm_generic_payload *>(Command::REFA, &refreshPayload);
|
||||
}
|
||||
}
|
||||
if (sc_time_stamp() == timeToSchedule)
|
||||
return std::pair<Command, tlm_generic_payload *>(nextCommand, &refreshPayload);
|
||||
else
|
||||
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
|
||||
}
|
||||
|
||||
sc_time RefreshManager::getTriggerDelay()
|
||||
sc_time RefreshManager::startRefreshManager()
|
||||
{
|
||||
return timeForNextTrigger - sc_time_stamp();
|
||||
if (sc_time_stamp() >= timeForNextTrigger)
|
||||
{
|
||||
sc_time delay;
|
||||
if (state == RmState::IDLE)
|
||||
{
|
||||
// TODO: If we do not block the bankmachines we have to check this each time
|
||||
bool doPrecharge = false;
|
||||
for (auto it : bankMachines)
|
||||
{
|
||||
it->block();
|
||||
if (it->getState() == BmState::Activated)
|
||||
doPrecharge = true;
|
||||
}
|
||||
|
||||
if (doPrecharge)
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::PREA, rank, BankGroup(0), Bank(0));
|
||||
nextCommand = Command::PREA;
|
||||
}
|
||||
else
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::REFA, rank, BankGroup(0), Bank(0));
|
||||
nextCommand = Command::REFA;
|
||||
state = RmState::PRECHARGED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
delay = checker->delayToSatisfyConstraints(Command::REFA, rank, BankGroup(0), Bank(0));
|
||||
nextCommand = Command::REFA;
|
||||
}
|
||||
timeToSchedule = sc_time_stamp() + delay;
|
||||
return delay;
|
||||
}
|
||||
else
|
||||
return timeForNextTrigger - sc_time_stamp();
|
||||
}
|
||||
|
||||
void RefreshManager::updateState(Command command, tlm_generic_payload *)
|
||||
{
|
||||
if (command == Command::REFA)
|
||||
{
|
||||
state = RmState::IDLE;
|
||||
timeForNextTrigger += memSpec->getRefreshIntervalAB();
|
||||
}
|
||||
else if (command == Command::PREA)
|
||||
state = RmState::PRECHARGED;
|
||||
}
|
||||
|
||||
@@ -38,23 +38,29 @@
|
||||
#include "RefreshManagerIF.h"
|
||||
#include "../../configuration/memspec/MemSpec.h"
|
||||
#include "../BankMachine.h"
|
||||
#include "../checker/CheckerIF.h"
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
class RefreshManager final : public RefreshManagerIF
|
||||
{
|
||||
public:
|
||||
RefreshManager(std::vector<BankMachine *> &);
|
||||
RefreshManager(std::vector<BankMachine *> &, Rank, CheckerIF *);
|
||||
|
||||
std::pair<Command, tlm_generic_payload *> getNextCommand();
|
||||
sc_time getTriggerDelay();
|
||||
sc_time startRefreshManager();
|
||||
void updateState(Command, tlm_generic_payload *);
|
||||
|
||||
private:
|
||||
enum class RmState {IDLE, REFRESHING} state = RmState::IDLE;
|
||||
enum class RmState {IDLE, PRECHARGED} state = RmState::IDLE;
|
||||
const MemSpec *memSpec;
|
||||
std::vector<BankMachine *> &bankMachines;
|
||||
std::vector<BankMachine *> bankMachines;
|
||||
tlm_generic_payload refreshPayload;
|
||||
sc_time timeForNextTrigger;
|
||||
sc_time timeToSchedule = SC_ZERO_TIME;
|
||||
CheckerIF *checker;
|
||||
Rank rank;
|
||||
Command nextCommand;
|
||||
};
|
||||
|
||||
#endif // REFRESHMANAGER_H
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
#include "../../common/utils.h"
|
||||
#include "../../common/dramExtensions.h"
|
||||
|
||||
RefreshManagerBankwise::RefreshManagerBankwise(std::vector<BankMachine *> &bankMachines)
|
||||
: bankMachines(bankMachines)
|
||||
RefreshManagerBankwise::RefreshManagerBankwise(std::vector<BankMachine *> &bankMachines, Rank, CheckerIF *checker)
|
||||
: bankMachines(bankMachines), checker(checker)
|
||||
{
|
||||
memSpec = Configuration::getInstance().memSpec;
|
||||
// TODO: implement for multiple ranks
|
||||
@@ -70,7 +70,7 @@ std::pair<Command, tlm_generic_payload *> RefreshManagerBankwise::getNextCommand
|
||||
if (states[bank.ID()] == RmState::IDLE)
|
||||
{
|
||||
states[bank.ID()] = RmState::REFRESHING;
|
||||
bool forcedPrecharge = bankMachines[bank.ID()]->forcePrecharge();
|
||||
bool forcedPrecharge = true;/*= bankMachines[bank.ID()]->forcePrecharge();*/
|
||||
if (forcedPrecharge)
|
||||
return std::pair<Command, tlm_generic_payload *>(Command::PRE, &refreshPayloads[bank.ID()]);
|
||||
else
|
||||
@@ -86,7 +86,12 @@ std::pair<Command, tlm_generic_payload *> RefreshManagerBankwise::getNextCommand
|
||||
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
|
||||
}
|
||||
|
||||
sc_time RefreshManagerBankwise::getTriggerDelay()
|
||||
sc_time RefreshManagerBankwise::startRefreshManager()
|
||||
{
|
||||
return timeForNextTrigger - sc_time_stamp();
|
||||
}
|
||||
|
||||
void RefreshManagerBankwise::updateState(Command, tlm_generic_payload *)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -45,19 +45,21 @@
|
||||
class RefreshManagerBankwise final : public RefreshManagerIF
|
||||
{
|
||||
public:
|
||||
RefreshManagerBankwise(std::vector<BankMachine *> &);
|
||||
RefreshManagerBankwise(std::vector<BankMachine *> &, Rank, CheckerIF *);
|
||||
|
||||
std::pair<Command, tlm_generic_payload *> getNextCommand();
|
||||
sc_time getTriggerDelay();
|
||||
sc_time startRefreshManager();
|
||||
void updateState(Command, tlm_generic_payload *);
|
||||
|
||||
private:
|
||||
const MemSpec *memSpec;
|
||||
std::vector<BankMachine *> &bankMachines;
|
||||
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;
|
||||
CheckerIF *checker;
|
||||
};
|
||||
|
||||
#endif // REFRESHMANAGERBANKWISE_H
|
||||
|
||||
@@ -39,7 +39,7 @@ std::pair<Command, tlm_generic_payload *> RefreshManagerDummy::getNextCommand()
|
||||
return std::pair<Command, tlm_generic_payload *>(Command::NOP, nullptr);
|
||||
}
|
||||
|
||||
sc_time RefreshManagerDummy::getTriggerDelay()
|
||||
sc_time RefreshManagerDummy::startRefreshManager()
|
||||
{
|
||||
return sc_max_time() - sc_time_stamp();
|
||||
}
|
||||
|
||||
@@ -47,7 +47,8 @@ class RefreshManagerDummy final : public RefreshManagerIF
|
||||
{
|
||||
public:
|
||||
std::pair<Command, tlm_generic_payload *> getNextCommand();
|
||||
sc_time getTriggerDelay();
|
||||
sc_time startRefreshManager();
|
||||
void updateState(Command, tlm_generic_payload *) {}
|
||||
};
|
||||
|
||||
#endif // REFRESHMANAGERDUMMY_H
|
||||
|
||||
@@ -48,7 +48,8 @@ public:
|
||||
virtual ~RefreshManagerIF() {}
|
||||
|
||||
virtual std::pair<Command, tlm_generic_payload *> getNextCommand() = 0;
|
||||
virtual sc_time getTriggerDelay() = 0;
|
||||
virtual sc_time startRefreshManager() = 0;
|
||||
virtual void updateState(Command, tlm_generic_payload *) = 0;
|
||||
};
|
||||
|
||||
#endif // REFRESHMANAGERIF_H
|
||||
|
||||
@@ -349,14 +349,18 @@ def timing_constraint(FirstPhase, SecondPhase):
|
||||
return max(dramconfig.tCCD_L, burstlength/dramconfig.dataRate)
|
||||
|
||||
elif (FirstPhaseName == "RDA"):
|
||||
if (SecondPhaseName in ["ACT", "PREA", "REFA"]):
|
||||
if (SecondPhaseName in ["ACT", "REFA"]):
|
||||
return dramconfig.tRTP + dramconfig.tRP
|
||||
elif (SecondPhaseName == "PREA"):
|
||||
return dramconfig.tRTP
|
||||
elif (SecondPhaseName in ["PDNA", "PDNP"]):
|
||||
return dramconfig.tRL + dramconfig.getReadAccessTime() + dramconfig.clk
|
||||
|
||||
elif (FirstPhaseName == "WRA"):
|
||||
if (SecondPhaseName in ["ACT", "PREA", "REFA"]):
|
||||
if (SecondPhaseName in ["ACT", "REFA"]):
|
||||
return dramconfig.tWL + dramconfig.getWriteAccessTime() + dramconfig.tWR + dramconfig.tRP
|
||||
elif (SecondPhaseName == "PREA"):
|
||||
return dramconfig.tWL + dramconfig.getWriteAccessTime() + dramconfig.tWR
|
||||
elif (SecondPhaseName in ["PDNA", "PDNP"]):
|
||||
return dramconfig.tWL + dramconfig.getWriteAccessTime() + dramconfig.tWR + dramconfig.clk
|
||||
|
||||
|
||||
Reference in New Issue
Block a user