diff --git a/DRAMSys/library/src/controller/ControllerNew.cpp b/DRAMSys/library/src/controller/ControllerNew.cpp index 8ef3bdec..9b9d8efe 100644 --- a/DRAMSys/library/src/controller/ControllerNew.cpp +++ b/DRAMSys/library/src/controller/ControllerNew.cpp @@ -129,6 +129,88 @@ ControllerNew::~ControllerNew() delete commandMux; } +void ControllerNew::controllerMethod() +{ + // (1) Release payload if arbiter has accepted the result + if (sc_time_stamp() == timeToRelease /*&& payloadToRelease != nullptr*/) + releasePayload(); + + // (2) Accept new request from arbiter + if (sc_time_stamp() >= timeToAcquire && payloadToAcquire != nullptr) + { + if (numberOfPayloads < Configuration::getInstance().MaxNrOfTransactions) + acquirePayload(); + else + PRINTDEBUGMESSAGE(name(), "Total number of payloads exceeded, backpressure!"); + } + + // (3) Send result to arbiter + if (payloadToRelease == nullptr && !responseQueue.empty()) + { + std::pair element = responseQueue.front(); + if (sc_time_stamp() >= element.first) + { + payloadToRelease = element.second; + responseQueue.pop(); + sendToFrontend(payloadToRelease, BEGIN_RESP); + } + } + + // (4) Start bank machines to issue new requests for current time + for (auto it : bankMachines) + it.second->startBankMachine(); + + // (5) Choose one request and send it to DRAM + std::pair result; + // (5.1) Check for refresh command (PREA or REFA) + result = refreshManager->getNextCommand(); + if (result.second != nullptr) + { + sc_time delay = refreshManager->updateState(); + refreshEvent.notify(delay); + if (result.first == Command::PREA) + { + bool forcedPrecharges = false; + for (auto it : bankMachines) + forcedPrecharges |= it.second->forcePrecharge(); + // Send the PREA only if at least one bank was precharged + if (forcedPrecharges) + sendToDram(result.first, result.second); + } + else + sendToDram(result.first, result.second); + } + // (5.2) Check for other commands (PRE, ACT, RD or WR) + else + { + std::vector> readyCommands; + for (auto it : bankMachines) + { + result = it.second->getNextCommand(); + if (result.second != nullptr) + readyCommands.push_back(result); + } + if (!readyCommands.empty()) + { + result = commandMux->selectCommand(readyCommands); + if (result.second != nullptr) + { + Bank bank = DramExtension::getBank(result.second); + bankMachines[bank]->updateState(result.first); + sendToDram(result.first, result.second); + } + } + } + + // (6) Restart bank machines to issue new requests for the future + for (auto it : bankMachines) + { + sc_time delay = it.second->startBankMachine(); + if (delay != SC_ZERO_TIME) // must be checked to avoid + bankMachineEvent.notify(delay); + } +} + tlm_sync_enum ControllerNew::nb_transport_fw(tlm_generic_payload &trans, tlm_phase &phase, sc_time &delay) { @@ -177,88 +259,6 @@ unsigned int ControllerNew::transport_dbg(tlm_generic_payload &) return 0; } -void ControllerNew::controllerMethod() -{ - // (1) Release payload if arbiter has accepted the result - if (sc_time_stamp() == timeToRelease /*&& payloadToRelease != nullptr*/) - releasePayload(); - - // (2) Accept new request from arbiter - if (sc_time_stamp() >= timeToAcquire && payloadToAcquire != nullptr) - { - if (numberOfPayloads < Configuration::getInstance().MaxNrOfTransactions) - acquirePayload(); - else - PRINTDEBUGMESSAGE(name(), "Total number of payloads exceeded, backpressure!"); - } - - // (3) Send result to arbiter - if (payloadToRelease == nullptr && !responseQueue.empty()) - { - std::pair element = responseQueue.front(); - if (sc_time_stamp() >= element.first) - { - payloadToRelease = element.second; - responseQueue.pop(); - sendToFrontend(payloadToRelease, BEGIN_RESP); - } - } - - // (4) Start bank machines to issue new requests for current time - for (auto it : bankMachines) - it.second->startBankMachine(); - - // (5) Choose one request and send it to DRAM - std::pair result; - // (5.1) Check for refresh command (PREA or REFA) - result = refreshManager->getNextCommand(); - if (result.second != nullptr) - { - sc_time delay = refreshManager->updateState(); - refreshEvent.notify(delay); - if (result.first == Command::PREA) - { - bool forcedPrecharges = false; - for (auto it : bankMachines) - forcedPrecharges |= it.second->forcePrecharge(); - // Send the PREA only if at least one bank was precharged - if (forcedPrecharges) - sendToDram(result.first, result.second); - } - else - sendToDram(result.first, result.second); - } - // (5.2) Check for other commands (PRE, ACT, RD or WR) - else - { - std::vector> readyCommands; - for (auto it : bankMachines) - { - result = it.second->getNextCommand(); - if (result.second != nullptr) - readyCommands.push_back(result); - } - if (!readyCommands.empty()) - { - result = commandMux->selectCommand(readyCommands); - if (result.second != nullptr) - { - Bank bank = DramExtension::getBank(result.second); - bankMachines[bank]->updateState(result.first); - sendToDram(result.first, result.second); - } - } - } - - // (6) Restart bank machines to issue new requests for the future - for (auto it : bankMachines) - { - sc_time delay = it.second->startBankMachine(); - if (delay != SC_ZERO_TIME) // must be checked to avoid - bankMachineEvent.notify(delay); - } -} - void ControllerNew::releasePayload() { uint64_t id = DramExtension::getPayloadID(payloadToRelease);