diff --git a/DRAMSys/simulator/src/common/TlmRecorder.cpp b/DRAMSys/simulator/src/common/TlmRecorder.cpp index c254fc78..5c6f8697 100644 --- a/DRAMSys/simulator/src/common/TlmRecorder.cpp +++ b/DRAMSys/simulator/src/common/TlmRecorder.cpp @@ -48,7 +48,7 @@ using namespace std; -TlmRecorder::TlmRecorder(string uri, string dbname, bool recenable) : sqlScriptURI(uri), dbName(dbname), senderName("TlmRecorder"), recordingEnabled(recenable), totalNumTransactions(1), simulationTimeCoveredByRecording(SC_ZERO_TIME) +TlmRecorder::TlmRecorder(sc_module_name /*name*/, string uri, string dbname, bool recenable) : sqlScriptURI(uri), dbName(dbname), recordingEnabled(recenable), totalNumTransactions(1), simulationTimeCoveredByRecording(SC_ZERO_TIME) { if (TlmRecorder::recordingEnabled == true) { recordedData.reserve(transactionCommitRate); @@ -141,6 +141,8 @@ void TlmRecorder::introduceTransactionSystem(tlm::tlm_generic_payload& trans) else currentTransactionsInSystem[&trans].timeOfGeneration = GenerationExtension::getExtension(&trans).TimeOfGeneration(); + printDebugMessage("New transaction #" + to_string(id) + " generation time " + currentTransactionsInSystem[&trans].timeOfGeneration.to_string()); + if (id % transactionCommitRate == 0) { printDebugMessage( @@ -154,6 +156,8 @@ void TlmRecorder::removeTransactionFromSystem(tlm::tlm_generic_payload& trans) { assert(currentTransactionsInSystem.count(&trans) != 0); + printDebugMessage("Removing transaction #" + to_string(currentTransactionsInSystem[&trans].id)); + Transaction& recordingData = currentTransactionsInSystem[&trans]; recordedData.push_back(recordingData); currentTransactionsInSystem.erase(&trans); @@ -226,13 +230,21 @@ void TlmRecorder::createTables(string pathToURI) void TlmRecorder::setUpTransactionTerminatingPhases() { transactionTerminatingPhases.push_back(tlm::END_RESP); + + // Refresh All transactionTerminatingPhases.push_back(static_cast(END_REFA)); + + // Refresh Bank transactionTerminatingPhases.push_back(static_cast(END_REFB)); - transactionTerminatingPhases.push_back(static_cast(END_PDNP)); + + // Phases for Power Down transactionTerminatingPhases.push_back(static_cast(END_PDNA)); + transactionTerminatingPhases.push_back(static_cast(END_PDNP)); transactionTerminatingPhases.push_back(static_cast(END_SREF)); - transactionTerminatingPhases.push_back(static_cast(END_PDNPB)); + + // Phases for Power Down Bankwise transactionTerminatingPhases.push_back(static_cast(END_PDNAB)); + transactionTerminatingPhases.push_back(static_cast(END_PDNPB)); transactionTerminatingPhases.push_back(static_cast(END_SREFB)); } @@ -348,7 +360,7 @@ void TlmRecorder::executeSqlCommand(string command) void TlmRecorder::printDebugMessage(std::string message) { - DebugManager::getInstance().printDebugMessage(TlmRecorder::senderName, message); + DebugManager::getInstance().printDebugMessage(this->name(), message); } void TlmRecorder::closeConnection() diff --git a/DRAMSys/simulator/src/common/TlmRecorder.h b/DRAMSys/simulator/src/common/TlmRecorder.h index f302042c..2f5cb087 100644 --- a/DRAMSys/simulator/src/common/TlmRecorder.h +++ b/DRAMSys/simulator/src/common/TlmRecorder.h @@ -55,14 +55,13 @@ using namespace std; -class TlmRecorder { +class TlmRecorder : public sc_module { public: std::string sqlScriptURI; std::string dbName; - std::string senderName; bool recordingEnabled; - TlmRecorder(string uri, string dbname, bool recenable); + TlmRecorder(sc_module_name /*name*/, string uri, string dbname, bool recenable); ~TlmRecorder(); void recordMemconfig(string memconfig){this->memconfig = memconfig;} diff --git a/DRAMSys/simulator/src/common/third_party/icewrapper b/DRAMSys/simulator/src/common/third_party/icewrapper index 37cde24d..f252aff3 160000 --- a/DRAMSys/simulator/src/common/third_party/icewrapper +++ b/DRAMSys/simulator/src/common/third_party/icewrapper @@ -1 +1 @@ -Subproject commit 37cde24d8fee904e8875ec48dc0b0ebe87fd2d9a +Subproject commit f252aff3b10ad00cba2ca855659c5fd84d566c08 diff --git a/DRAMSys/simulator/src/controller/Command.cpp b/DRAMSys/simulator/src/controller/Command.cpp index e85f4d91..4c5f4aa2 100644 --- a/DRAMSys/simulator/src/controller/Command.cpp +++ b/DRAMSys/simulator/src/controller/Command.cpp @@ -87,6 +87,10 @@ std::string commandToString(Command command) return "SREFX"; break; + case Command::NOP: + return "NOP"; + break; + default: SC_REPORT_FATAL("command", "commandToString was called with unknown command"); break; diff --git a/DRAMSys/simulator/src/controller/Controller.h b/DRAMSys/simulator/src/controller/Controller.h index e081b518..38a8142e 100644 --- a/DRAMSys/simulator/src/controller/Controller.h +++ b/DRAMSys/simulator/src/controller/Controller.h @@ -79,7 +79,7 @@ public: Controller(sc_module_name /*name*/, TlmRecorder *rec) : frontendPEQ(this, &Controller::frontendPEQCallback), dramPEQ(this, &Controller::dramPEQCallback), controllerCorePEQ(this, &Controller::controllerCorePEQCallback), debugManager(DebugManager::getInstance()), tlmRecorder(rec) { - controllerCore = new ControllerCore(*this, numberOfPayloadsInSystem); + controllerCore = new ControllerCore("core", *this, numberOfPayloadsInSystem); buildScheduler(); iSocket.register_nb_transport_bw(this, &Controller::nb_transport_bw); tSocket.register_nb_transport_fw(this, &Controller::nb_transport_fw); @@ -342,17 +342,27 @@ void Controller::controllerCorePEQCallback(tlm_generic_payload &payloa template tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload &payload, tlm_phase &phase, sc_time &fwDelay) { + sc_time recTime; + sc_time notDelay; if (phase == BEGIN_REQ) { - tlmRecorder->recordPhase(payload, phase, fwDelay + sc_time_stamp()); - frontendPEQ.notify(payload, phase, - clkAlign(sc_time_stamp() + fwDelay) - (sc_time_stamp() + fwDelay) + Configuration::getInstance().memSpec.clk); + recTime = fwDelay + sc_time_stamp(); + notDelay = clkAlign(sc_time_stamp() + fwDelay) - (sc_time_stamp() + fwDelay) + Configuration::getInstance().memSpec.clk; + + printDebugMessage("[fw] Recording " + phaseNameToString(phase) + " at " + recTime.to_string() + " notification in " + notDelay.to_string()); + + tlmRecorder->recordPhase(payload, phase, recTime); + frontendPEQ.notify(payload, phase, notDelay); } else if (phase == END_RESP) { - tlmRecorder->recordPhase(payload, phase, - fwDelay + sc_time_stamp() + Configuration::getInstance().memSpec.clk); - frontendPEQ.notify(payload, phase, clkAlign(sc_time_stamp() + fwDelay) - (sc_time_stamp() + fwDelay)); + recTime = fwDelay + sc_time_stamp() + Configuration::getInstance().memSpec.clk; + notDelay = clkAlign(sc_time_stamp() + fwDelay) - (sc_time_stamp() + fwDelay); + + printDebugMessage("[fw] Recording " + phaseNameToString(phase) + " at " + recTime.to_string() + " notification in " + notDelay.to_string()); + + tlmRecorder->recordPhase(payload, phase, recTime); + frontendPEQ.notify(payload, phase, notDelay); } return TLM_ACCEPTED; } @@ -450,7 +460,7 @@ void Controller::scheduleNextFromScheduler(Bank bank) { controllerCore->powerDownManager->wakeUp(DramExtension::getExtension(nextRequest.second).getBank(), sc_time_stamp()); controllerCore->scheduleRequest(nextRequest.first, *nextRequest.second); - printDebugMessage("\t-> Next payload was scheduled by core"); + printDebugMessage("\t-> Next payload was scheduled by core [" + commandToString(nextRequest.first) + "]"); } while (!blockedRequests.empty()) { @@ -461,7 +471,7 @@ void Controller::scheduleNextFromScheduler(Bank bank) if (nextRequest.second != NULL) { controllerCore->powerDownManager->wakeUp(DramExtension::getExtension(nextRequest.second).getBank(), sc_time_stamp()); controllerCore->scheduleRequest(nextRequest.first, *nextRequest.second); - printDebugMessage("\t-> Next payload was scheduled by core"); + printDebugMessage("\t-> Next payload was scheduled by core [" + commandToString(nextRequest.first) + "] (unblocked)"); } } @@ -478,8 +488,14 @@ void Controller::sendToFrontend(tlm_generic_payload &payload, const tl template tlm_sync_enum Controller::nb_transport_bw(tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay) { - dramPEQ.notify(payload, phase, bwDelay); - tlmRecorder->recordPhase(payload, phase, bwDelay + sc_time_stamp()); + sc_time recTime = bwDelay + sc_time_stamp(); + sc_time notDelay = bwDelay; + + printDebugMessage("[bw] Recording " + phaseNameToString(phase) + " at " + recTime.to_string() + " notification in " + notDelay.to_string()); + + dramPEQ.notify(payload, phase, notDelay); + tlmRecorder->recordPhase(payload, phase, recTime); + return TLM_ACCEPTED; } diff --git a/DRAMSys/simulator/src/controller/ControllerState.cpp b/DRAMSys/simulator/src/controller/ControllerState.cpp index 9d53f08e..2f97d2d6 100644 --- a/DRAMSys/simulator/src/controller/ControllerState.cpp +++ b/DRAMSys/simulator/src/controller/ControllerState.cpp @@ -73,6 +73,8 @@ const ScheduledCommand ControllerState::getLastScheduledCommand() } } + printDebugMessage("Last scheduled command was " + commandToString(lastCommand.getCommand())); + return lastCommand; } @@ -87,6 +89,8 @@ const ScheduledCommand ControllerState::getLastScheduledCommand(Bank bank) lastCommand = current; } + printDebugMessage("Last scheduled command on bank " + to_string(bank.ID()) + " was " + commandToString(lastCommand.getCommand())); + return lastCommand; } @@ -94,6 +98,7 @@ void ControllerState::change(const ScheduledCommand& scheduledCommand) { bus.blockSlot(scheduledCommand.getStart()); + printDebugMessage("Changing state on bank " + to_string(scheduledCommand.getBank().ID()) + " command is " + commandToString(scheduledCommand.getCommand())); lastScheduledByCommandAndBank[scheduledCommand.getCommand()][scheduledCommand.getBank()] = scheduledCommand; switch (scheduledCommand.getCommand()) @@ -102,30 +107,30 @@ void ControllerState::change(const ScheduledCommand& scheduledCommand) lastDataStrobeCommands.emplace_back(scheduledCommand); break; case Command::ReadA: - rowBufferStates.closeRowBuffer(scheduledCommand.getBank()); + rowBufferStates->closeRowBuffer(scheduledCommand.getBank()); lastDataStrobeCommands.emplace_back(scheduledCommand); break; case Command::Write: lastDataStrobeCommands.emplace_back(scheduledCommand); break; case Command::WriteA: - rowBufferStates.closeRowBuffer(scheduledCommand.getBank()); + rowBufferStates->closeRowBuffer(scheduledCommand.getBank()); lastDataStrobeCommands.emplace_back(scheduledCommand); break; case Command::AutoRefresh: break; case Command::Activate: - rowBufferStates.openRowInRowBuffer(scheduledCommand.getBank(), scheduledCommand.getRow()); + rowBufferStates->openRowInRowBuffer(scheduledCommand.getBank(), scheduledCommand.getRow()); lastActivates.emplace(scheduledCommand.getStart(), scheduledCommand); break; case Command::Precharge: - rowBufferStates.closeRowBuffer(scheduledCommand.getBank()); + rowBufferStates->closeRowBuffer(scheduledCommand.getBank()); break; case Command::PrechargeAll: - rowBufferStates.closeAllRowBuffers(); + rowBufferStates->closeAllRowBuffers(); break; case Command::SREF: - rowBufferStates.closeRowBuffer(scheduledCommand.getBank()); + rowBufferStates->closeRowBuffer(scheduledCommand.getBank()); break; default: break; @@ -145,3 +150,9 @@ void ControllerState::cleanUp(sc_time time) if(time >= config->memSpec.tActHistory()) lastActivates.erase(lastActivates.begin(), lastActivates.lower_bound(time - config->memSpec.tActHistory())); } + +void ControllerState::printDebugMessage(std::string message) +{ + DebugManager::getInstance().printDebugMessage(ownerName, message); +} + diff --git a/DRAMSys/simulator/src/controller/ControllerState.h b/DRAMSys/simulator/src/controller/ControllerState.h index 81946528..38f1941b 100644 --- a/DRAMSys/simulator/src/controller/ControllerState.h +++ b/DRAMSys/simulator/src/controller/ControllerState.h @@ -48,13 +48,11 @@ class ControllerState { public: - ControllerState(Configuration* config) : - rowBufferStates(), bus(config->memSpec.clk), config(config) - { - } - virtual ~ControllerState() + ControllerState(std::string ownerName, Configuration *config) : bus(config->memSpec.clk), ownerName(ownerName), config(config) { + rowBufferStates = new RowBufferState(ownerName); } + virtual ~ControllerState(){} const ScheduledCommand getLastCommand(Command command, Bank bank); const ScheduledCommand getLastCommand(Command command); @@ -64,7 +62,7 @@ public: void change(const ScheduledCommand& scheduledCommand); void cleanUp(sc_time time); - RowBufferState rowBufferStates; + RowBufferState *rowBufferStates; //used by the various checkers std::map > lastScheduledByCommandAndBank; @@ -77,8 +75,10 @@ public: std::map lastActivates; private: + std::string ownerName; Configuration* config; + void printDebugMessage(std::string message); }; - #endif /* CONTROLLER_STATE_H_ */ + diff --git a/DRAMSys/simulator/src/controller/RowBufferStates.cpp b/DRAMSys/simulator/src/controller/RowBufferStates.cpp index 69086e7e..a8ab5aa1 100644 --- a/DRAMSys/simulator/src/controller/RowBufferStates.cpp +++ b/DRAMSys/simulator/src/controller/RowBufferStates.cpp @@ -41,9 +41,9 @@ using namespace std; -RowBufferState::RowBufferState() +RowBufferState::RowBufferState(std::string ownerName) : ownerName(ownerName) { - closeAllRowBuffers(); + closeAllRowBuffers(); } RowBufferState::~RowBufferState() @@ -62,13 +62,13 @@ Row RowBufferState::getRowInRowBuffer(Bank bank) const void RowBufferState::openRowInRowBuffer(Bank bank,Row row) { - DebugManager::getInstance().printDebugMessage(ControllerCore::senderName, "Row buffer for bank " + to_string(bank.ID()) + " is now open"); + printDebugMessage("Row buffer for bank " + to_string(bank.ID()) + " is now open"); rowsInRowBuffers[bank] = row; } void RowBufferState::closeRowBuffer(Bank bank) { - DebugManager::getInstance().printDebugMessage(ControllerCore::senderName, "Row buffer for bank " + to_string(bank.ID()) + " is now closed"); + printDebugMessage("Row buffer for bank " + to_string(bank.ID()) + " is now closed"); rowsInRowBuffers[bank] = Row::NO_ROW; } @@ -90,4 +90,8 @@ void RowBufferState::closeAllRowBuffers() } } +void RowBufferState::printDebugMessage(std::string message) +{ + DebugManager::getInstance().printDebugMessage(ownerName, message); +} diff --git a/DRAMSys/simulator/src/controller/RowBufferStates.h b/DRAMSys/simulator/src/controller/RowBufferStates.h index 7a2e7fbd..8b964ee0 100644 --- a/DRAMSys/simulator/src/controller/RowBufferStates.h +++ b/DRAMSys/simulator/src/controller/RowBufferStates.h @@ -36,12 +36,13 @@ #ifndef ROWBUFFERSTATES_H_ #define ROWBUFFERSTATES_H_ + #include #include "../common/dramExtension.h" class RowBufferState { public: - RowBufferState(); + RowBufferState(std::string ownerName); virtual ~RowBufferState(); bool rowBufferIsOpen(Bank bank) const; @@ -53,7 +54,10 @@ public: void closeAllRowBuffers(); private: + std::string ownerName; std::map rowsInRowBuffers; + void printDebugMessage(std::string message); }; #endif /* BANKSTATES_H_ */ + diff --git a/DRAMSys/simulator/src/controller/core/ControllerCore.cpp b/DRAMSys/simulator/src/controller/core/ControllerCore.cpp index 32b47d86..f18c1630 100644 --- a/DRAMSys/simulator/src/controller/core/ControllerCore.cpp +++ b/DRAMSys/simulator/src/controller/core/ControllerCore.cpp @@ -55,25 +55,21 @@ #include "powerdown/NoPowerDown.h" #include "../../common/DebugManager.h" - - -std::string ControllerCore::senderName = "Controller Core"; - -ControllerCore::ControllerCore(IController& wrapperConnector, std::map& numberOfPayloads) : - config(Configuration::getInstance()), state(&config), controller(wrapperConnector), numberOfPayloads( - numberOfPayloads), commandChecker() - +ControllerCore::ControllerCore(sc_module_name /*name*/, IController& wrapperConnector, std::map& numberOfPayloads) : + config(Configuration::getInstance()), controller(wrapperConnector), numberOfPayloads(numberOfPayloads), commandChecker() { - commandChecker[Command::Activate] = new ActivateChecker(config, state); - commandChecker[Command::Precharge] = new PrechargeChecker(config, state); - commandChecker[Command::PrechargeAll] = new PrechargeAllChecker(config, state); - commandChecker[Command::Read] = new ReadChecker(config, state); + state = new ControllerState(name(), &config); + + commandChecker[Command::Activate] = new ActivateChecker(config, *state); + commandChecker[Command::Precharge] = new PrechargeChecker(config, *state); + commandChecker[Command::PrechargeAll] = new PrechargeAllChecker(config, *state); + commandChecker[Command::Read] = new ReadChecker(config, *state); commandChecker[Command::ReadA] = commandChecker[Command::Read]; - commandChecker[Command::Write] = new WriteChecker(config, state); + commandChecker[Command::Write] = new WriteChecker(config, *state); commandChecker[Command::WriteA] = commandChecker[Command::Write]; - commandChecker[Command::AutoRefresh] = new RefreshChecker(config, state); - commandChecker[Command::PDNA] = new PowerDownChecker(config, state); + commandChecker[Command::AutoRefresh] = new RefreshChecker(config, *state); + commandChecker[Command::PDNA] = new PowerDownChecker(config, *state); commandChecker[Command::PDNP] = commandChecker[Command::PDNA]; commandChecker[Command::SREF] = commandChecker[Command::PDNA]; commandChecker[Command::PDNAX] = commandChecker[Command::PDNA]; @@ -82,20 +78,20 @@ ControllerCore::ControllerCore(IController& wrapperConnector, std::mapcleanUp(time); if (!refreshManager->isInvalidated(payload, time) && !powerDownManager->isInSelfRefresh(bank)) { @@ -142,10 +139,10 @@ void ControllerCore::triggerRefresh(tlm::tlm_generic_payload& payload) void ControllerCore::scheduleRequest(Command command, tlm::tlm_generic_payload &payload) { sc_time start = clkAlign(sc_time_stamp()); - state.cleanUp(start); + state->cleanUp(start); ScheduledCommand scheduledCommand = schedule(command, start, payload); - state.change(scheduledCommand); + state->change(scheduledCommand); controller.send(scheduledCommand, payload); } @@ -164,7 +161,7 @@ ScheduledCommand ControllerCore::schedule(Command command, sc_time start, bool ControllerCore::bankIsBusy(Bank bank) { sc_time time = sc_time_stamp(); - ScheduledCommand lastScheduledCommand = state.getLastScheduledCommand(bank); + ScheduledCommand lastScheduledCommand = state->getLastScheduledCommand(bank); if (lastScheduledCommand.isNoCommand()) return false; @@ -227,6 +224,6 @@ ICommandChecker& ControllerCore::getCommandChecker(Command command) void ControllerCore::printDebugMessage(string message) { - DebugManager::getInstance().printDebugMessage(ControllerCore::senderName, message); + DebugManager::getInstance().printDebugMessage(this->name(), message); } diff --git a/DRAMSys/simulator/src/controller/core/ControllerCore.h b/DRAMSys/simulator/src/controller/core/ControllerCore.h index cae3758d..7f32e805 100644 --- a/DRAMSys/simulator/src/controller/core/ControllerCore.h +++ b/DRAMSys/simulator/src/controller/core/ControllerCore.h @@ -51,10 +51,10 @@ using namespace std; -class ControllerCore +class ControllerCore : public sc_module { public: - ControllerCore(IController& controller, std::map& numberOfPayloads); + ControllerCore(sc_module_name /*name*/, IController& controller, std::map& numberOfPayloads); virtual ~ControllerCore() ; void scheduleRequest(Command command, tlm::tlm_generic_payload& payload); @@ -62,23 +62,23 @@ public: const std::vector& getBanks(); std::vector getFreeBanks(); - const RowBufferState& getRowBufferStates(){return state.rowBufferStates;} + const RowBufferState& getRowBufferStates(){return *(state->rowBufferStates);} bool bankIsBusy(Bank bank); - ICommandChecker& getCommandChecker(Command command); static void printDebugMessage(string message); + ICommandChecker& getCommandChecker(Command command); Configuration config; - ControllerState state; + ControllerState *state; IController& controller; IPowerDownManager* powerDownManager; IRefreshManager* refreshManager; std::map& numberOfPayloads; - static std::string senderName; private: ScheduledCommand schedule(Command command, sc_time start, tlm::tlm_generic_payload &payload); std::map commandChecker; + void printDebugMessage(string message); }; #endif /* CONTROLLER_H_ */ diff --git a/DRAMSys/simulator/src/controller/core/Slots.cpp b/DRAMSys/simulator/src/controller/core/Slots.cpp index 4bc524e0..87909571 100644 --- a/DRAMSys/simulator/src/controller/core/Slots.cpp +++ b/DRAMSys/simulator/src/controller/core/Slots.cpp @@ -81,10 +81,8 @@ void Slots::blockSlots(sc_time begin, sc_time end, bool excludeBorders) end -= clk; } - for (sc_time time = begin; time <= end; time += clk) - { - slotSet.insert(time); + for (sc_time time = begin; time <= end; time += clk) { + blockSlot(time); } - } diff --git a/DRAMSys/simulator/src/controller/core/Slots.h b/DRAMSys/simulator/src/controller/core/Slots.h index 0f4bbed3..49b03b5b 100644 --- a/DRAMSys/simulator/src/controller/core/Slots.h +++ b/DRAMSys/simulator/src/controller/core/Slots.h @@ -46,15 +46,16 @@ class Slots public: Slots(sc_time clk); virtual ~Slots(); + void moveCommandToNextFreeSlot(ScheduledCommand& command); void cleanUpSlots(sc_time time); - void blockSlots(sc_time begin, sc_time end, bool excludeBorders); void blockSlot(sc_time time); bool isFree(sc_time); - std::set slotSet; private: sc_time clk; + std::set slotSet; + void blockSlots(sc_time begin, sc_time end, bool excludeBorders); }; diff --git a/DRAMSys/simulator/src/controller/core/TimingCalculation.cpp b/DRAMSys/simulator/src/controller/core/TimingCalculation.cpp index d52b4aac..d20e7ba9 100644 --- a/DRAMSys/simulator/src/controller/core/TimingCalculation.cpp +++ b/DRAMSys/simulator/src/controller/core/TimingCalculation.cpp @@ -65,6 +65,7 @@ const sc_time clkAlign(sc_time time, Alignment alignment) return floor(time / clk) * clk; } +// Returns the execution time for commands that have a fixed execution time sc_time getExecutionTime(Command command, tlm::tlm_generic_payload& payload) { MemSpec& config = Configuration::getInstance().memSpec; @@ -101,7 +102,6 @@ sc_time getExecutionTime(Command command, tlm::tlm_generic_payload& payload) { return getElementFromMap(config.refreshTimings, DramExtension::getExtension(payload).getBank()).tRFC; } - else if (command == Command::PDNAX || command == Command::PDNPX || command == Command::SREFX) { return config.clk; @@ -113,6 +113,7 @@ sc_time getExecutionTime(Command command, tlm::tlm_generic_payload& payload) } } +// Returns the minimum execution time for commands that have a variable execution time sc_time getMinExecutionTimeForPowerDownCmd(Command command) { MemSpec& config = Configuration::getInstance().memSpec; diff --git a/DRAMSys/simulator/src/controller/core/powerdown/IPowerDownManager.h b/DRAMSys/simulator/src/controller/core/powerdown/IPowerDownManager.h index b74ff975..48972149 100644 --- a/DRAMSys/simulator/src/controller/core/powerdown/IPowerDownManager.h +++ b/DRAMSys/simulator/src/controller/core/powerdown/IPowerDownManager.h @@ -82,6 +82,7 @@ inline Command IPowerDownManager::getSleepCommand(PowerDownState state) break; default: SC_REPORT_FATAL("In PowerDownManager sendPowerdownBegin", "invalid powerDownState"); + break; } return cmd; } diff --git a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManager.cpp b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManager.cpp index 7d49b1b7..80493bb4 100644 --- a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManager.cpp +++ b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManager.cpp @@ -47,7 +47,7 @@ using namespace tlm; using namespace std; -PowerDownManager::PowerDownManager(ControllerCore& controller) : +PowerDownManager::PowerDownManager(sc_module_name /*name*/, ControllerCore& controller) : controllerCore(controller) { powerDownState = PowerDownState::Awake; @@ -71,14 +71,14 @@ void PowerDownManager::sleep(Bank bank, sc_time time) if (state == PowerDownState::Awake) //coming from active { - state = controllerCore.state.rowBufferStates.allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive; + state = controllerCore.state->rowBufferStates->allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive; } else if (state == PowerDownState::AwakeForRefresh) //coming from refresh interrupting power down { - sc_assert(controllerCore.state.rowBufferStates.allRowBuffersAreClosed()); + sc_assert(controllerCore.state->rowBufferStates->allRowBuffersAreClosed()); - if (controllerCore.state.getLastCommand(Command::PDNA).getStart() - >= controllerCore.state.getLastCommand(Command::PDNP).getStart()) + if (controllerCore.state->getLastCommand(Command::PDNA).getStart() + >= controllerCore.state->getLastCommand(Command::PDNP).getStart()) state = PowerDownState::PDNPrecharge; else { @@ -105,6 +105,8 @@ void PowerDownManager::sleep(Bank bank, sc_time time) void PowerDownManager::wakeUp(Bank bank, sc_time time) { + printDebugMessage("Waking up at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState)); + if (isAwakeForRefresh()) //Request enters system during Refresh { setPowerDownState(PowerDownState::Awake); @@ -116,16 +118,25 @@ void PowerDownManager::wakeUp(Bank bank, sc_time time) DramExtension::getExtension(powerDownPayloads[bank])); controllerCore.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); - if (cmd == Command::SREFX) + if (cmd == Command::SREFX) { + // Leaving Self Refresh. Plan the next refresh. controllerCore.refreshManager->reInitialize(bank, pdn.getEnd()); + printDebugMessage("Waking up. Leaving Self Refresh at " + time.to_string() + " next refresh planned to " + pdn.getEnd().to_string()); + } setPowerDownState(PowerDownState::Awake); + + printDebugMessage("Sending power down exit command " + commandToString(cmd) + " on all banks"); sendPowerDownPayloads(pdn); } + + printDebugMessage("Awaken at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState)); } void PowerDownManager::wakeUpForRefresh(Bank bank, sc_time time) { + printDebugMessage("Waking up for refresh at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState)); + if (isInPowerDown()) { Command cmd = IPowerDownManager::getWakeUpCommand(powerDownState); @@ -133,20 +144,24 @@ void PowerDownManager::wakeUpForRefresh(Bank bank, sc_time time) DramExtension::getExtension(powerDownPayloads[bank])); setPowerDownState(PowerDownState::AwakeForRefresh); + + printDebugMessage("Sending power down exit command " + commandToString(cmd) + " on all banks"); sendPowerDownPayloads(pdn); } + + printDebugMessage("Awaken for refresh at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState)); } void PowerDownManager::sendPowerDownPayloads(ScheduledCommand& cmd) { - controllerCore.state.bus.moveCommandToNextFreeSlot(cmd); + controllerCore.state->bus.moveCommandToNextFreeSlot(cmd); for (Bank bank : controllerCore.getBanks()) { tlm_generic_payload& payloadToSend = powerDownPayloads[bank]; - ScheduledCommand pdnToSend(cmd.getCommand(), cmd.getStart(), cmd.getExecutionTime(), - DramExtension::getExtension(payloadToSend)); - controllerCore.state.change(pdnToSend); + ScheduledCommand pdnToSend(cmd.getCommand(), cmd.getStart(), cmd.getExecutionTime(), DramExtension::getExtension(payloadToSend)); + controllerCore.state->change(pdnToSend); + printDebugMessage("Sending power down command " + commandToString(pdnToSend.getCommand()) + " on bank " + to_string(pdnToSend.getBank().ID()) + " start time " + pdnToSend.getStart().to_string() + " end time " + pdnToSend.getEnd().to_string()); controllerCore.controller.send(pdnToSend, payloadToSend); } } @@ -154,8 +169,7 @@ void PowerDownManager::sendPowerDownPayloads(ScheduledCommand& cmd) void PowerDownManager::setPowerDownState(PowerDownState state) { powerDownState = state; - DebugManager::getInstance().printDebugMessage(PowerDownManagerBankwise::senderName, - "Is now in state " + powerDownStateToString(powerDownState) + " on all banks"); + printDebugMessage("Is now in state " + powerDownStateToString(powerDownState) + " on all banks"); } bool PowerDownManager::isInPowerDown() @@ -189,5 +203,8 @@ void PowerDownManager::triggerSleep(Bank bank, sc_time time) sleep(bank, time); } - +void PowerDownManager::printDebugMessage(std::string message) +{ + DebugManager::getInstance().printDebugMessage(this->name(), message); +} diff --git a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManager.h b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManager.h index c6cbe919..2eabdadc 100644 --- a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManager.h +++ b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManager.h @@ -42,10 +42,10 @@ class ControllerCore; -class PowerDownManager: public IPowerDownManager +class PowerDownManager: public IPowerDownManager, public sc_module { public: - PowerDownManager(ControllerCore& controllerCore); + PowerDownManager(sc_module_name /*name*/, ControllerCore& controllerCore); virtual ~PowerDownManager(); virtual void triggerSleep(Bank bank, sc_time time) override; @@ -64,6 +64,7 @@ private: PowerDownState powerDownState; std::map powerDownPayloads; ControllerCore& controllerCore; + void printDebugMessage(std::string message); }; diff --git a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerBankwise.cpp b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerBankwise.cpp index 6237fe6d..266c4f26 100644 --- a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerBankwise.cpp +++ b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerBankwise.cpp @@ -42,11 +42,7 @@ using namespace tlm; - -std::string PowerDownManagerBankwise::senderName = "pdn manager"; - -PowerDownManagerBankwise::PowerDownManagerBankwise(ControllerCore& controller) : - controllerCore(controller) +PowerDownManagerBankwise::PowerDownManagerBankwise(sc_module_name /*name*/, ControllerCore& controller) : controllerCore(controller) { for (Bank bank : controller.getBanks()) { @@ -65,14 +61,14 @@ void PowerDownManagerBankwise::sleep(Bank bank, sc_time time) PowerDownState state = powerDownStates[bank]; if (state == PowerDownState::Awake) //coming from active { - state = controllerCore.state.rowBufferStates.rowBufferIsOpen(bank) ? PowerDownState::PDNActive : PowerDownState::PDNPrecharge; + state = controllerCore.state->rowBufferStates->rowBufferIsOpen(bank) ? PowerDownState::PDNActive : PowerDownState::PDNPrecharge; } else if (state == PowerDownState::AwakeForRefresh) //coming from refresh interrupting power down { - sc_assert(!controllerCore.state.rowBufferStates.rowBufferIsOpen(bank)); + sc_assert(!controllerCore.state->rowBufferStates->rowBufferIsOpen(bank)); - if (controllerCore.state.getLastCommand(Command::PDNA, bank).getStart() - >= controllerCore.state.getLastCommand(Command::PDNP, bank).getStart()) + if (controllerCore.state->getLastCommand(Command::PDNA, bank).getStart() + >= controllerCore.state->getLastCommand(Command::PDNP, bank).getStart()) state = PowerDownState::PDNPrecharge; else { @@ -97,43 +93,58 @@ void PowerDownManagerBankwise::sleep(Bank bank, sc_time time) void PowerDownManagerBankwise::wakeUp(Bank bank, sc_time time) { - if (isAwakeForRefresh(bank)) - { - setState(PowerDownState::Awake, bank); - } - else if (isInPowerDown(bank)) - { - //Request wakes up power down - Command cmd = IPowerDownManager::getWakeUpCommand(powerDownStates[bank]); - ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]), - DramExtension::getExtension(powerDownPayloads[bank])); - controllerCore.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); + printDebugMessage("Waking up on bank " + to_string(bank.ID()) + " at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownStates[bank])); - if (cmd == Command::SREFX) - controllerCore.refreshManager->reInitialize(bank, pdn.getEnd()); + if (isAwakeForRefresh(bank)) { + printDebugMessage("It was already awake for refresh on bank " + to_string(bank.ID()) + " at " + time.to_string()); + setState(PowerDownState::Awake, bank); + } else if (isInPowerDown(bank)) { + // Request wake up from power down. A Power Down Exit request will be generated (PDNAX, PDNPX, SREFX). + Command pdnExitCmd = IPowerDownManager::getWakeUpCommand(powerDownStates[bank]); + // Mount the command to be scheduled + ScheduledCommand pdnExit(pdnExitCmd, time, getExecutionTime(pdnExitCmd, powerDownPayloads[bank]), DramExtension::getExtension(powerDownPayloads[bank])); + // Ensure that time constraints are respected + controllerCore.getCommandChecker(pdnExitCmd).delayToSatisfyConstraints(pdnExit); - setState(PowerDownState::Awake, bank); - sendPowerDownPayload(pdn); - } + if (pdnExitCmd == Command::SREFX) { + // Leaving Self Refresh. Plan the next refresh. + controllerCore.refreshManager->reInitialize(bank, pdnExit.getEnd()); + printDebugMessage("Waking up. Leaving Self Refresh on Bank " + to_string(bank.ID()) + " at " + time.to_string() + " next refresh planned to " + pdnExit.getEnd().to_string()); + } + + setState(PowerDownState::Awake, bank); + + printDebugMessage("Sending power down exit command " + commandToString(pdnExitCmd) + " on bank " + to_string(bank.ID()) + " at " + time.to_string() + " start time " + pdnExit.getStart().to_string() + " end time " + pdnExit.getEnd().to_string()); + sendPowerDownPayload(pdnExit); + } + + printDebugMessage("Awaken on bank " + to_string(bank.ID()) + " at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownStates[bank])); } void PowerDownManagerBankwise::wakeUpForRefresh(Bank bank, sc_time time) { - if (isInPowerDown(bank)) - { - Command cmd = IPowerDownManager::getWakeUpCommand(powerDownStates[bank]); - ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]), - DramExtension::getExtension(powerDownPayloads[bank])); + printDebugMessage("Waking up for refresh on bank " + to_string(bank.ID()) + " at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownStates[bank])); - setState(PowerDownState::AwakeForRefresh, bank); - sendPowerDownPayload(pdn); - } + if (isInPowerDown(bank)) { + // A Power Down Exit request will be generated (PDNAX, PDNPX, SREFX). + Command pdnExitCmd = IPowerDownManager::getWakeUpCommand(powerDownStates[bank]); + // Get the execution time for this request + sc_time executionTime = getExecutionTime(pdnExitCmd, powerDownPayloads[bank]); + // Mount the command to be scheduled + ScheduledCommand pdnExit(pdnExitCmd, time, executionTime, DramExtension::getExtension(powerDownPayloads[bank])); + + setState(PowerDownState::AwakeForRefresh, bank); + + printDebugMessage("Sending power down exit command " + commandToString(pdnExitCmd) + " on bank " + to_string(bank.ID()) + " at " + time.to_string() + " start time " + pdnExit.getStart().to_string() + " end time " + pdnExit.getEnd().to_string()); + sendPowerDownPayload(pdnExit); + } + + printDebugMessage("Awaken for refresh on bank " + to_string(bank.ID()) + " at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownStates[bank])); } bool PowerDownManagerBankwise::isInPowerDown(Bank bank) { - return isIn(powerDownStates[bank], - { PowerDownState::PDNActive, PowerDownState::PDNPrecharge, PowerDownState::PDNSelfRefresh }); + return isIn(powerDownStates[bank], { PowerDownState::PDNActive, PowerDownState::PDNPrecharge, PowerDownState::PDNSelfRefresh }); } bool PowerDownManagerBankwise::isInSelfRefresh(Bank bank) @@ -153,18 +164,17 @@ bool PowerDownManagerBankwise::isAwake(Bank bank) void PowerDownManagerBankwise::setState(PowerDownState state, Bank bank) { - PowerDownState& bankstate = powerDownStates[bank]; - bankstate = state; - - DebugManager::getInstance().printDebugMessage(PowerDownManagerBankwise::senderName, - "Is now in state " + powerDownStateToString(state) + " on Bank " + to_string(bank.ID())); + PowerDownState& bankstate = powerDownStates[bank]; + bankstate = state; + printDebugMessage("Is now in state " + powerDownStateToString(state) + " on Bank " + to_string(bank.ID())); } -void PowerDownManagerBankwise::sendPowerDownPayload(ScheduledCommand& pdn) +void PowerDownManagerBankwise::sendPowerDownPayload(ScheduledCommand &pdn) { - controllerCore.state.bus.moveCommandToNextFreeSlot(pdn); - controllerCore.state.change(pdn); - controllerCore.controller.send(pdn, powerDownPayloads[pdn.getBank()]); + controllerCore.state->bus.moveCommandToNextFreeSlot(pdn); + controllerCore.state->change(pdn); + printDebugMessage("Sending power down command " + commandToString(pdn.getCommand()) + " on bank " + to_string(pdn.getBank().ID()) + " start time " + pdn.getStart().to_string() + " end time " + pdn.getEnd().to_string()); + controllerCore.controller.send(pdn, powerDownPayloads[pdn.getBank()]); } bool PowerDownManagerBankwise::canSleep(Bank bank) @@ -177,5 +187,8 @@ void PowerDownManagerBankwise::triggerSleep(Bank bank, sc_time time) sleep(bank, time); } - +void PowerDownManagerBankwise::printDebugMessage(std::string message) +{ + DebugManager::getInstance().printDebugMessage(this->name(), message); +} diff --git a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerBankwise.h b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerBankwise.h index 44e8e5e7..c15ab4fd 100644 --- a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerBankwise.h +++ b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerBankwise.h @@ -49,27 +49,23 @@ class ControllerCore; -class PowerDownManagerBankwise: public IPowerDownManager +class PowerDownManagerBankwise : public sc_module, public IPowerDownManager { public: - PowerDownManagerBankwise(ControllerCore& controllerCore); - virtual ~PowerDownManagerBankwise() - { - } + PowerDownManagerBankwise(sc_module_name /*name*/, ControllerCore& controllerCore); + virtual ~PowerDownManagerBankwise(){} virtual void triggerSleep(Bank bank, sc_time time) override; virtual void sleep(Bank bank, sc_time time) override; virtual void wakeUp(Bank bank, sc_time time) override; virtual void wakeUpForRefresh(Bank bank, sc_time time) override; virtual bool isInSelfRefresh(Bank bank) override; - static std::string senderName; - private: virtual bool isInPowerDown(Bank bank); virtual bool isAwake(Bank bank); virtual bool isAwakeForRefresh(Bank bank); - ControllerCore& controllerCore; + ControllerCore &controllerCore; std::map powerDownPayloads; std::map powerDownStates; @@ -80,8 +76,10 @@ private: Command getWakeUpCommand(PowerDownState state); Command getSleepCommand(PowerDownState state); - void sendPowerDownPayload(ScheduledCommand& pdn); + void sendPowerDownPayload(ScheduledCommand &pdn); + + void printDebugMessage(std::string message); }; - #endif /* POWERDOWNMANAGERBANKWISE_H_ */ + diff --git a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerTimeout.cpp b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerTimeout.cpp index e3139b24..a1763d18 100644 --- a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerTimeout.cpp +++ b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerTimeout.cpp @@ -44,8 +44,9 @@ using namespace tlm; -PowerDownManagerTimeout::PowerDownManagerTimeout(ControllerCore& controller): controllerCore(controller) +PowerDownManagerTimeout::PowerDownManagerTimeout(sc_module_name /*name*/, ControllerCore& controller): controllerCore(controller) { + powerDownState = PowerDownState::Awake; for (Bank bank : controller.getBanks()) { setUpDummy(powerDownPayloads[bank], bank); @@ -61,7 +62,7 @@ void PowerDownManagerTimeout::sleep(Bank bank, sc_time time) { bool test_canSleep = canSleep(); bool test_isInPowerDown = isInPowerDown(); - sc_time last_scheduled_command = controllerCore.state.getLastScheduledCommand().getEnd(); + sc_time last_scheduled_command = controllerCore.state->getLastScheduledCommand().getEnd(); sc_time power_down_timeout = Configuration::getInstance().getPowerDownTimeout(); bool test_timeCondition = (time - last_scheduled_command) >= power_down_timeout; bool test_awakeForRefresh = (powerDownState == PowerDownState::AwakeForRefresh); @@ -73,7 +74,7 @@ void PowerDownManagerTimeout::sleep(Bank bank, sc_time time) PowerDownState newState; if(Configuration::getInstance().PowerDownMode == EPowerDownMode::TimeoutPDN) { - newState = controllerCore.state.rowBufferStates.allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive; + newState = controllerCore.state->rowBufferStates->allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive; } else // PowerDownMode == TimeoutSREF { @@ -108,12 +109,13 @@ bool PowerDownManagerTimeout::isInPowerDown() void PowerDownManagerTimeout::setPowerDownState(PowerDownState state) { powerDownState = state; - DebugManager::getInstance().printDebugMessage(PowerDownManagerBankwise::senderName, - "Is now in state " + powerDownStateToString(powerDownState) + " on all banks"); + printDebugMessage("Is now in state " + powerDownStateToString(powerDownState) + " on all banks"); } void PowerDownManagerTimeout::wakeUp(Bank bank, sc_time time) { + printDebugMessage("Waking up at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState)); + if (isInPowerDown()) //Request wakes up power down { Command cmd = IPowerDownManager::getWakeUpCommand(powerDownState); @@ -121,16 +123,25 @@ void PowerDownManagerTimeout::wakeUp(Bank bank, sc_time time) DramExtension::getExtension(powerDownPayloads[bank])); controllerCore.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); - if (cmd == Command::SREFX) + if (cmd == Command::SREFX) { + // Leaving Self Refresh. Plan the next refresh. controllerCore.refreshManager->reInitialize(bank, pdn.getEnd()); + printDebugMessage("Waking up. Leaving Self Refresh at " + time.to_string() + " next refresh planned to " + pdn.getEnd().to_string()); + } setPowerDownState(PowerDownState::Awake); + + printDebugMessage("Sending power down exit command " + commandToString(cmd) + " on all banks"); sendPowerDownPayloads(pdn); } + + printDebugMessage("Awaken at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState)); } void PowerDownManagerTimeout::wakeUpForRefresh(Bank bank, sc_time time) { + printDebugMessage("Waking up for refresh at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState)); + if (isInPowerDown()) { Command cmd = IPowerDownManager::getWakeUpCommand(powerDownState); @@ -138,10 +149,14 @@ void PowerDownManagerTimeout::wakeUpForRefresh(Bank bank, sc_time time) DramExtension::getExtension(powerDownPayloads[bank])); setPowerDownState(PowerDownState::AwakeForRefresh); + + printDebugMessage("Sending power down exit command " + commandToString(cmd) + " on all banks"); sendPowerDownPayloads(pdn); // Schedule Next Powerdown after Refresh: } + + printDebugMessage("Awaken for refresh at " + time.to_string() + " current power down state is " + powerDownStateToString(powerDownState)); } void PowerDownManagerTimeout::triggerSleep(Bank /*bank*/, sc_time time) @@ -169,14 +184,19 @@ bool PowerDownManagerTimeout::canSleep() void PowerDownManagerTimeout::sendPowerDownPayloads(ScheduledCommand& cmd) { - controllerCore.state.bus.moveCommandToNextFreeSlot(cmd); + controllerCore.state->bus.moveCommandToNextFreeSlot(cmd); for (Bank bank : controllerCore.getBanks()) { tlm_generic_payload& payloadToSend = powerDownPayloads[bank]; ScheduledCommand pdnToSend(cmd.getCommand(), cmd.getStart(), cmd.getExecutionTime(), DramExtension::getExtension(payloadToSend)); - controllerCore.state.change(pdnToSend); + controllerCore.state->change(pdnToSend); controllerCore.controller.send(pdnToSend, payloadToSend); } } +void PowerDownManagerTimeout::printDebugMessage(std::string message) +{ + DebugManager::getInstance().printDebugMessage(this->name(), message); +} + diff --git a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerTimeout.h b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerTimeout.h index e0b9ab0f..46dfb866 100644 --- a/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerTimeout.h +++ b/DRAMSys/simulator/src/controller/core/powerdown/PowerDownManagerTimeout.h @@ -46,10 +46,10 @@ class ControllerCore; -class PowerDownManagerTimeout: public IPowerDownManager +class PowerDownManagerTimeout: public IPowerDownManager, public sc_module { public: - PowerDownManagerTimeout(ControllerCore& controllerCore); + PowerDownManagerTimeout(sc_module_name /*name*/, ControllerCore& controllerCore); virtual ~PowerDownManagerTimeout(); virtual void triggerSleep(Bank bank, sc_time time); @@ -66,9 +66,10 @@ private: std::map powerDownPayloads; void sendPowerDownPayloads(ScheduledCommand& cmd); - PowerDownState powerDownState = PowerDownState::Awake; + PowerDownState powerDownState; void setPowerDownState(PowerDownState state); bool isInPowerDown(); + void printDebugMessage(std::string message); }; diff --git a/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.cpp b/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.cpp index 2280a230..c3acac16 100644 --- a/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.cpp +++ b/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.cpp @@ -42,7 +42,7 @@ using namespace tlm; -RefreshManager::RefreshManager(ControllerCore& controller) : +RefreshManager::RefreshManager(sc_module_name /*name*/, ControllerCore& controller) : controllerCore(controller), timing(controller.config.memSpec.refreshTimings[Bank(0)]), nextPlannedRefresh(SC_ZERO_TIME) { for (Bank bank : controller.getBanks()) @@ -58,14 +58,14 @@ RefreshManager::~RefreshManager() bool RefreshManager::hasCollision(const ScheduledCommand& command) { - return command.getStart() < controllerCore.state.getLastCommand(Command::AutoRefresh).getEnd() || command.getEnd() > nextPlannedRefresh; + return command.getStart() < controllerCore.state->getLastCommand(Command::AutoRefresh).getEnd() || command.getEnd() > nextPlannedRefresh; } void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload __attribute__((unused)), sc_time time) { sc_assert(!isInvalidated(payload, time)); - if (!controllerCore.state.rowBufferStates.allRowBuffersAreClosed()) + if (!controllerCore.state->rowBufferStates->allRowBuffersAreClosed()) { ScheduledCommand prechargeAllMaster(Command::PrechargeAll, time, getExecutionTime(Command::PrechargeAll, refreshPayloads[Bank(0)]), refreshPayloads[Bank(0)]); @@ -75,7 +75,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload __attribu { ScheduledCommand prechargeAll(Command::PrechargeAll, prechargeAllMaster.getStart(), prechargeAllMaster.getExecutionTime(), refreshPayloads[bank]); - controllerCore.state.change(prechargeAll); + controllerCore.state->change(prechargeAll); controllerCore.controller.send(prechargeAll, refreshPayloads[bank]); } } @@ -87,7 +87,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload __attribu for (Bank bank : controllerCore.getBanks()) { ScheduledCommand refresh(Command::AutoRefresh, refreshAllMaster.getStart(), refreshAllMaster.getExecutionTime(),refreshPayloads[bank]); - controllerCore.state.change(refresh); + controllerCore.state->change(refresh); controllerCore.controller.send(refresh, refreshPayloads[bank]); DramExtension::getExtension(refreshPayloads[bank]).incrementRow(); } @@ -112,3 +112,8 @@ bool RefreshManager::isInvalidated(tlm::tlm_generic_payload& payload __attribute return nextPlannedRefresh > time; } +void RefreshManager::printDebugMessage(std::string message) +{ + DebugManager::getInstance().printDebugMessage(this->name(), message); +} + diff --git a/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.h b/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.h index 7ffb3744..0b24236e 100644 --- a/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.h +++ b/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.h @@ -43,16 +43,16 @@ class ControllerCore; -class RefreshManager : public IRefreshManager +class RefreshManager : public IRefreshManager, public sc_module { public: - RefreshManager(ControllerCore& controllerCore); + RefreshManager(sc_module_name /*name*/, ControllerCore& controllerCore); virtual ~RefreshManager(); virtual bool hasCollision(const ScheduledCommand& command) override; virtual void scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time) override; void reInitialize(Bank bank, sc_time time) override; - virtual bool isInvalidated(tlm::tlm_generic_payload& payload, sc_time time) override; + virtual bool isInvalidated(tlm::tlm_generic_payload& payload, sc_time time) override; private: ControllerCore& controllerCore; @@ -61,7 +61,8 @@ private: std::map refreshPayloads; void planNextRefresh(); + void printDebugMessage(std::string message); }; - #endif /* REFRESHMANAGER_H_ */ + diff --git a/DRAMSys/simulator/src/controller/core/refresh/RefreshManagerBankwise.cpp b/DRAMSys/simulator/src/controller/core/refresh/RefreshManagerBankwise.cpp index ea7693d6..456d4530 100644 --- a/DRAMSys/simulator/src/controller/core/refresh/RefreshManagerBankwise.cpp +++ b/DRAMSys/simulator/src/controller/core/refresh/RefreshManagerBankwise.cpp @@ -42,8 +42,7 @@ using namespace std; -RefreshManagerBankwise::RefreshManagerBankwise(ControllerCore& controller) : - controllerCore(controller) +RefreshManagerBankwise::RefreshManagerBankwise(sc_module_name /*name*/, ControllerCore& controller) : controllerCore(controller) { for (Bank bank : controller.getBanks()) { @@ -58,8 +57,17 @@ RefreshManagerBankwise::~RefreshManagerBankwise() bool RefreshManagerBankwise::hasCollision(const ScheduledCommand& command) { - return command.getStart() < controllerCore.state.getLastCommand(Command::AutoRefresh, command.getBank()).getEnd() - || command.getEnd() > nextPlannedRefreshs[command.getBank()];} + Bank bank = command.getBank(); + // Get the last AutoRefresh command for this bank and the time of its end + ScheduledCommand lastAutoRefreshCmd = controllerCore.state->getLastCommand(Command::AutoRefresh, bank); + sc_time endTimeLastAutoRefreshCmd = lastAutoRefreshCmd.getEnd(); + // Get the time of the next planned refresh for this bank + sc_time timeNextPlannedRefresh = nextPlannedRefreshs[command.getBank()]; + // Collision: + // - the start time of the command is before the end time of the last auto refresh command for this bank + // - the end time of the command is after the next planned refresh for this bank + return command.getStart() < endTimeLastAutoRefreshCmd || command.getEnd() > timeNextPlannedRefresh; +} void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time) { @@ -69,18 +77,18 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload& payload, DramExtension& extension = DramExtension::getExtension(refreshPayload); - if (controllerCore.state.rowBufferStates.rowBufferIsOpen(extension.getBank())) + if (controllerCore.state->rowBufferStates->rowBufferIsOpen(extension.getBank())) { ScheduledCommand precharge(Command::Precharge, time, getExecutionTime(Command::Precharge, refreshPayload), extension); controllerCore.getCommandChecker(Command::Precharge).delayToSatisfyConstraints(precharge); - controllerCore.state.change(precharge); + controllerCore.state->change(precharge); controllerCore.controller.send(precharge, refreshPayload); } ScheduledCommand refresh(Command::AutoRefresh, time, getExecutionTime(Command::AutoRefresh, refreshPayload), extension); controllerCore.getCommandChecker(Command::AutoRefresh).delayToSatisfyConstraints(refresh); - controllerCore.state.change(refresh); + controllerCore.state->change(refresh); controllerCore.controller.send(refresh, refreshPayload); extension.incrementRow(); @@ -104,4 +112,8 @@ bool RefreshManagerBankwise::isInvalidated(tlm::tlm_generic_payload& payload, sc return nextPlannedRefreshs[DramExtension::getExtension(payload).getBank()] > time; } +void RefreshManagerBankwise::printDebugMessage(std::string message) +{ + DebugManager::getInstance().printDebugMessage(this->name(), message); +} diff --git a/DRAMSys/simulator/src/controller/core/refresh/RefreshManagerBankwise.h b/DRAMSys/simulator/src/controller/core/refresh/RefreshManagerBankwise.h index a7427d87..a026aae8 100644 --- a/DRAMSys/simulator/src/controller/core/refresh/RefreshManagerBankwise.h +++ b/DRAMSys/simulator/src/controller/core/refresh/RefreshManagerBankwise.h @@ -44,13 +44,13 @@ class ControllerCore; -class RefreshManagerBankwise : public IRefreshManager +class RefreshManagerBankwise : public IRefreshManager, public sc_module { public: - RefreshManagerBankwise(ControllerCore& controllerCore); + RefreshManagerBankwise(sc_module_name /*name*/, ControllerCore& controllerCore); virtual ~RefreshManagerBankwise(); - virtual bool hasCollision(const ScheduledCommand& command) override; + virtual bool hasCollision(const ScheduledCommand& command) override; virtual void scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time) override; void reInitialize(Bank bank, sc_time time) override; @@ -58,14 +58,15 @@ public: bool isInvalidated(tlm::tlm_generic_payload& payload,sc_time time) override; private: - - ControllerCore& controllerCore; + ControllerCore &controllerCore; std::map refreshPayloads; std::map nextPlannedRefreshs; void planNextRefresh(Bank bank); + + void printDebugMessage(std::string message); }; - #endif /* BANKWISEREFRESHMANAGER_H_ */ + diff --git a/DRAMSys/simulator/src/controller/core/scheduling/checker/PowerDownChecker.cpp b/DRAMSys/simulator/src/controller/core/scheduling/checker/PowerDownChecker.cpp index 94224017..c9a8a988 100644 --- a/DRAMSys/simulator/src/controller/core/scheduling/checker/PowerDownChecker.cpp +++ b/DRAMSys/simulator/src/controller/core/scheduling/checker/PowerDownChecker.cpp @@ -37,67 +37,75 @@ #include "PowerDownChecker.h" #include "../../TimingCalculation.h" -void PowerDownChecker::delayToSatisfyConstraints(ScheduledCommand& command) const +sc_time PowerDownChecker::getTimeConstraintToEnterPowerDown(Command lastCmd, Command pdnCmd) const { - sc_assert( - command.commandIsIn( - { Command::SREF, Command::PDNA, Command::PDNP, Command::PDNAX, Command::PDNPX, Command::SREFX })); + sc_assert(pdnCmd == Command::SREF || pdnCmd == Command::PDNA || pdnCmd == Command::PDNP); - if (command.commandIsIn( { Command::SREF, Command::PDNA, Command::PDNP })) - { - ScheduledCommand lastCommandOnBank = state.getLastScheduledCommand(command.getBank()); + sc_time constraint; - if (lastCommandOnBank.isValidCommand()) - { - if (lastCommandOnBank.getCommand() == Command::Read || lastCommandOnBank.getCommand() == Command::ReadA) - { - command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - config.memSpec.tRL + getReadAccessTime() + config.memSpec.clk); - } - else if (lastCommandOnBank.getCommand() == Command::Write) - { - command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR); - } - else if (lastCommandOnBank.getCommand() == Command::WriteA) - { - command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.clk); - } - else if (lastCommandOnBank.getCommand() == Command::AutoRefresh) - { - command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRFC); - } - else if (lastCommandOnBank.getCommand() == Command::PDNPX || lastCommandOnBank.getCommand() == Command::PDNAX) - { - command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tXP); - } + if (lastCmd == Command::Read || lastCmd == Command::ReadA) { + constraint = config.memSpec.tRL + getReadAccessTime() + config.memSpec.clk; + } else if (lastCmd == Command::Write) { + constraint = config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR; + } else if (lastCmd == Command::WriteA) { + constraint = config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.clk; + } else if (lastCmd == Command::AutoRefresh) { + constraint = config.memSpec.tRFC; + } else if (lastCmd == Command::PDNPX || lastCmd == Command::PDNAX) { + constraint = config.memSpec.tXP; + } else if (lastCmd == Command::SREFX) { + constraint = config.memSpec.tXSR; + } else { + reportFatal("Powerdown checker", commandToString(pdnCmd) + " can not follow " + commandToString(lastCmd)); + } - else if (lastCommandOnBank.getCommand() == Command::SREFX) - { - command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tXSR); - } - - else - { - reportFatal("Powerdown checker", commandToString(command.getCommand()) + " can not follow " + commandToString(lastCommandOnBank.getCommand())); - } - } - } - - else if (command.getCommand() == Command::PDNAX) - { - command.establishMinDistanceFromStart(state.getLastCommand(Command::PDNA).getStart(), config.memSpec.tCKE); - } - else if (command.getCommand() == Command::PDNPX) - { - command.establishMinDistanceFromStart(state.getLastCommand(Command::PDNP).getStart(), config.memSpec.tCKE); - } - else if (command.getCommand() == Command::SREFX) - { - command.establishMinDistanceFromStart(state.getLastCommand(Command::SREF).getStart(), config.memSpec.tCKESR); - } - - state.bus.moveCommandToNextFreeSlot(command); + return constraint; +} + +void PowerDownChecker::delayToSatisfyConstraints(ScheduledCommand &command) const +{ + sc_assert(command.commandIsIn({Command::PDNA, Command::PDNP, Command::SREF, Command::PDNAX, Command::PDNPX, Command::SREFX})); + + // Power Down commmand (one of the listed above) + Command pdnCmd = command.getCommand(); + Bank bank = command.getBank(); + + sc_time timeConstraint; + + if (pdnCmd == Command::PDNA || pdnCmd == Command::PDNP || pdnCmd == Command::SREF) { + // Entering in one of the Power Down modes: + // PDNA - Active Power Down + // PDNP - Precharge Power Down + // SREF - Self Refresh + + // Get the last scheduled command on this bank + ScheduledCommand lastSchedCmdOnBank = state.getLastScheduledCommand(bank); + + if (lastSchedCmdOnBank.isValidCommand()) { + // Get the start time for the last scheduled command on this bank + sc_time lastSchedCmdOnBankStart = lastSchedCmdOnBank.getStart(); + // Get the last command on this bank itself + Command lastCmdBank = lastSchedCmdOnBank.getCommand(); + + timeConstraint = getTimeConstraintToEnterPowerDown(lastCmdBank, pdnCmd); + + command.establishMinDistanceFromStart(lastSchedCmdOnBankStart, timeConstraint); + } + + } else if (pdnCmd == Command::PDNAX) { + // Leaving Active Power Down + timeConstraint = config.memSpec.tCKE; + command.establishMinDistanceFromStart(state.getLastCommand(Command::PDNA).getStart(), timeConstraint); + } else if (pdnCmd == Command::PDNPX) { + // Leaving Precharge Power Down + timeConstraint = config.memSpec.tCKE; + command.establishMinDistanceFromStart(state.getLastCommand(Command::PDNP).getStart(), timeConstraint); + } else if (pdnCmd == Command::SREFX) { + // Leaving Self Refresh + timeConstraint = config.memSpec.tCKESR; + command.establishMinDistanceFromStart(state.getLastCommand(Command::SREF).getStart(), timeConstraint); + } + + state.bus.moveCommandToNextFreeSlot(command); } diff --git a/DRAMSys/simulator/src/controller/core/scheduling/checker/PowerDownChecker.h b/DRAMSys/simulator/src/controller/core/scheduling/checker/PowerDownChecker.h index 3878047a..222ae31e 100644 --- a/DRAMSys/simulator/src/controller/core/scheduling/checker/PowerDownChecker.h +++ b/DRAMSys/simulator/src/controller/core/scheduling/checker/PowerDownChecker.h @@ -37,29 +37,25 @@ #ifndef POWERDOWNCHECKER_H_ #define POWERDOWNCHECKER_H_ +#include + #include "../../../ControllerState.h" #include "../../configuration/Configuration.h" #include "ICommandChecker.h" -#include - class PowerDownChecker : public ICommandChecker { public: - PowerDownChecker(const Configuration& config, ControllerState& state) : - config(config), state(state) - { - } - virtual ~PowerDownChecker() - { - } + PowerDownChecker(const Configuration &config, ControllerState &state) : config(config), state(state) {} + virtual ~PowerDownChecker() {} virtual void delayToSatisfyConstraints(ScheduledCommand& command) const override; private: - const Configuration& config; - ControllerState& state; + const Configuration &config; + ControllerState &state; + sc_time getTimeConstraintToEnterPowerDown(Command lastCmd, Command pdnCmd) const; }; - #endif /* POWERDOWNCHECKER_H_ */ + diff --git a/DRAMSys/simulator/src/simulation/Arbiter.h b/DRAMSys/simulator/src/simulation/Arbiter.h index 6aed14e6..5e190451 100644 --- a/DRAMSys/simulator/src/simulation/Arbiter.h +++ b/DRAMSys/simulator/src/simulation/Arbiter.h @@ -104,8 +104,13 @@ private: // This function is called when an arbiter's initiator socket receives a transaction from a memory controller tlm_sync_enum nb_transport_bw(int channelId, tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay) { - tlmRecorders[channelId]->recordPhase(payload, phase, bwDelay + sc_time_stamp()); - payloadEventQueue.notify(payload, phase, bwDelay); + sc_time recTime = bwDelay + sc_time_stamp(); + sc_time notDelay = bwDelay; + + printDebugMessage("[bw] Recording " + phaseNameToString(phase) + " at " + recTime.to_string() + " notification in " + notDelay.to_string()); + + tlmRecorders[channelId]->recordPhase(payload, phase, recTime); + payloadEventQueue.notify(payload, phase, notDelay); return TLM_ACCEPTED; } @@ -210,6 +215,11 @@ private: DramExtension* extension = new DramExtension(Thread(socketId+1), Channel(decodedAddress.channel), Bank(decodedAddress.bank), BankGroup(decodedAddress.bankgroup), Row(decodedAddress.row), Column(decodedAddress.column),burstlength); payload.set_auto_extension(extension); } + + void printDebugMessage(std::string message) + { + DebugManager::getInstance().printDebugMessage(this->name(), message); + } }; #endif /* ARBITER_H_ */ diff --git a/DRAMSys/simulator/src/simulation/Dram.h b/DRAMSys/simulator/src/simulation/Dram.h index f6ada6b6..cef4dcc0 100644 --- a/DRAMSys/simulator/src/simulation/Dram.h +++ b/DRAMSys/simulator/src/simulation/Dram.h @@ -200,7 +200,21 @@ struct Dram : sc_module virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& payload, tlm::tlm_phase& phase, sc_time& delay) { - tlmRecorder->recordPhase(payload, phase, sc_time_stamp() + delay); + // Recording time used by the traceAnalyzer + sc_time recTime = sc_time_stamp() + delay; + + // These are terminating phases recorded by the DRAM. The execution + // time of the related command must be taken into consideration. + if (phase == END_PDNA || phase == END_PDNAB) { + recTime += getExecutionTime(Command::PDNAX, payload); + } else if (phase == END_PDNP || phase == END_PDNPB) { + recTime += getExecutionTime(Command::PDNPX, payload); + } else if (phase == END_SREF || phase == END_SREFB) { + recTime += getExecutionTime(Command::SREFX, payload); + } + + printDebugMessage("[fw] Recording " + phaseNameToString(phase) + " at " + recTime.to_string()); + tlmRecorder->recordPhase(payload, phase, recTime); // This is only needed for power simulation: unsigned long long cycle = 0; @@ -386,6 +400,7 @@ struct Dram : sc_module { if(powerAnalysis == true){SC_REPORT_FATAL("DRAM", "DRAM PEQ was called with unknown phase");} } + return tlm::TLM_ACCEPTED; } diff --git a/DRAMSys/simulator/src/simulation/Simulation.cpp b/DRAMSys/simulator/src/simulation/Simulation.cpp index e19496e0..07832216 100644 --- a/DRAMSys/simulator/src/simulation/Simulation.cpp +++ b/DRAMSys/simulator/src/simulation/Simulation.cpp @@ -88,7 +88,8 @@ void Simulation::setupTlmRecorders(const string &traceName, const string &pathTo for (size_t i = 0; i < Configuration::getInstance().NumberOfMemChannels; i++) { std::string sqlScriptURI = pathToResources + string("scripts/createTraceDB.sql"); std::string dbName = traceName + string("_channel") + std::to_string(i) + ".tdb"; - TlmRecorder *tlmRecorder = new TlmRecorder(sqlScriptURI.c_str(), dbName.c_str(), Configuration::getInstance().DatabaseRecording); + std::string recorderName = "tlmRecorder" + std::to_string(i); + TlmRecorder *tlmRecorder = new TlmRecorder(recorderName.c_str(), sqlScriptURI.c_str(), dbName.c_str(), Configuration::getInstance().DatabaseRecording); tlmRecorder->recordMemconfig(Configuration::getInstance().memconfigUri); tlmRecorder->recordMemspec(Configuration::getInstance().memspecUri); @@ -113,7 +114,7 @@ void Simulation::instantiateModules(const string &traceName, const string &pathT TemperatureController::getInstance(); for (size_t i = 0; i < Configuration::getInstance().NumberOfTracePlayers; i++) { - std::string playerStr = "player" + std::to_string(i); + std::string playerStr = "tracePlayer" + std::to_string(i); TracePlayer<> *player; // When data should be stored during the simulation the StlDataPlayer is needed. // Else: no data should be stored, for instance to get a faster simulation diff --git a/DRAMSys/simulator/src/simulation/TracePlayer.h b/DRAMSys/simulator/src/simulation/TracePlayer.h index 1c2b250b..7a6d4523 100644 --- a/DRAMSys/simulator/src/simulation/TracePlayer.h +++ b/DRAMSys/simulator/src/simulation/TracePlayer.h @@ -136,8 +136,7 @@ void TracePlayer::peqCallback(tlm_generic_payload &payload, const tlm_ sendToTarget(payload, phase, SC_ZERO_TIME); transactionsSent++; - DebugManager::getInstance().printDebugMessage(name(), - "Sending transaction number: " + std::to_string(transactionsSent)); + DebugManager::getInstance().printDebugMessage(name(), "Performing request #" + std::to_string(transactionsSent)); } else if (phase == END_REQ) {