diff --git a/DRAMSys/library/src/common/utils.cpp b/DRAMSys/library/src/common/utils.cpp index 014e957f..76237841 100644 --- a/DRAMSys/library/src/common/utils.cpp +++ b/DRAMSys/library/src/common/utils.cpp @@ -140,7 +140,7 @@ std::string parseString(json &obj, std::string name) SC_REPORT_FATAL("Query json", ("Parameter '" + name + "' does not exist.").c_str()); } -void setUpDummy(tlm_generic_payload &payload, Rank rank, Bank bank) +void setUpDummy(tlm_generic_payload &payload, uint64_t payloadID, Rank rank, BankGroup bankgroup, Bank bank) { payload.set_address(bank.getStartAddress()); payload.set_command(TLM_READ_COMMAND); @@ -149,6 +149,6 @@ void setUpDummy(tlm_generic_payload &payload, Rank rank, Bank bank) payload.set_dmi_allowed(false); payload.set_byte_enable_length(0); payload.set_streaming_width(0); - payload.set_extension(new DramExtension(Thread(UINT_MAX), rank, BankGroup(0), - bank, Row(0), Column(0), 0, 0)); + payload.set_extension(new DramExtension(Thread(UINT_MAX), rank, bankgroup, + bank, Row(0), Column(0), 0, payloadID)); } diff --git a/DRAMSys/library/src/common/utils.h b/DRAMSys/library/src/common/utils.h index 872fb3ba..6a073c81 100644 --- a/DRAMSys/library/src/common/utils.h +++ b/DRAMSys/library/src/common/utils.h @@ -110,7 +110,7 @@ unsigned int parseUint(nlohmann::json &obj, std::string name); double parseUdouble(nlohmann::json &obj, std::string name); std::string parseString(nlohmann::json &obj, std::string name); -void setUpDummy(tlm::tlm_generic_payload &payload, Rank rank = Rank(0), Bank bank = Bank(0)); +void setUpDummy(tlm::tlm_generic_payload &payload, uint64_t payloadID, Rank rank = Rank(0), BankGroup bankgroup = BankGroup(0), Bank bank = Bank(0)); #endif // UTILS_H diff --git a/DRAMSys/library/src/controller/BankMachine.cpp b/DRAMSys/library/src/controller/BankMachine.cpp index 836f8d42..82259337 100644 --- a/DRAMSys/library/src/controller/BankMachine.cpp +++ b/DRAMSys/library/src/controller/BankMachine.cpp @@ -44,12 +44,9 @@ BankMachine::BankMachine(SchedulerIF *scheduler, CheckerIF *checker, Bank bank) bankgroup = BankGroup(bank.ID() / memSpec->banksPerGroup); } -std::pair BankMachine::getNextCommand() +std::tuple BankMachine::getNextCommand() { - if (sc_time_stamp() == timeToSchedule) - return std::pair(nextCommand, currentPayload); - else - return std::pair(Command::NOP, nullptr); + return std::tuple(nextCommand, currentPayload, timeToSchedule); } void BankMachine::updateState(Command command) @@ -124,6 +121,7 @@ BankMachineOpen::BankMachineOpen(SchedulerIF *scheduler, CheckerIF *checker, Ban sc_time BankMachineOpen::start() { timeToSchedule = sc_max_time(); + nextCommand = Command::NOP; if (sleeping) return timeToSchedule; @@ -134,30 +132,26 @@ sc_time BankMachineOpen::start() if (currentState == BmState::Precharged && !blocked) // row miss { - timeToSchedule = checker->timeToSatisfyConstraints(Command::ACT, rank, bankgroup, bank); nextCommand = Command::ACT; + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); } else if (currentState == BmState::Activated) { if (DramExtension::getRow(currentPayload) == currentRow) // row hit { - if (currentPayload->get_command() == TLM_READ_COMMAND) - { - timeToSchedule = checker->timeToSatisfyConstraints(Command::RD, rank, bankgroup, bank); + if (currentPayload->get_command() == TLM_READ_COMMAND) nextCommand = Command::RD; - } else if (currentPayload->get_command() == TLM_WRITE_COMMAND) - { - timeToSchedule = checker->timeToSatisfyConstraints(Command::WR, rank, bankgroup, bank); nextCommand = Command::WR; - } else SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); + + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); } else if (!blocked) // row miss { - timeToSchedule = checker->timeToSatisfyConstraints(Command::PRE, rank, bankgroup, bank); nextCommand = Command::PRE; + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); } } return timeToSchedule; @@ -169,6 +163,7 @@ BankMachineClosed::BankMachineClosed(SchedulerIF *scheduler, CheckerIF *checker, sc_time BankMachineClosed::start() { timeToSchedule = sc_max_time(); + nextCommand = Command::NOP; if (sleeping) return timeToSchedule; @@ -179,23 +174,19 @@ sc_time BankMachineClosed::start() if (currentState == BmState::Precharged && !blocked) // row miss { - timeToSchedule = checker->timeToSatisfyConstraints(Command::ACT, rank, bankgroup, bank); nextCommand = Command::ACT; + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); } else if (currentState == BmState::Activated) { if (currentPayload->get_command() == TLM_READ_COMMAND) - { - timeToSchedule = checker->timeToSatisfyConstraints(Command::RDA, rank, bankgroup, bank); nextCommand = Command::RDA; - } else if (currentPayload->get_command() == TLM_WRITE_COMMAND) - { - timeToSchedule = checker->timeToSatisfyConstraints(Command::WRA, rank, bankgroup, bank); nextCommand = Command::WRA; - } else SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); + + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); } return timeToSchedule; } @@ -206,6 +197,7 @@ BankMachineOpenAdaptive::BankMachineOpenAdaptive(SchedulerIF *scheduler, Checker sc_time BankMachineOpenAdaptive::start() { timeToSchedule = sc_max_time(); + nextCommand = Command::NOP; if (sleeping) return timeToSchedule; @@ -216,8 +208,8 @@ sc_time BankMachineOpenAdaptive::start() if (currentState == BmState::Precharged && !blocked) // row miss { - timeToSchedule = checker->timeToSatisfyConstraints(Command::ACT, rank, bankgroup, bank); nextCommand = Command::ACT; + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); } else if (currentState == BmState::Activated) { @@ -226,38 +218,27 @@ sc_time BankMachineOpenAdaptive::start() if (scheduler->hasFurtherRequest(bank) && !scheduler->hasFurtherRowHit(bank, currentRow)) { if (currentPayload->get_command() == TLM_READ_COMMAND) - { - timeToSchedule = checker->timeToSatisfyConstraints(Command::RDA, rank, bankgroup, bank); nextCommand = Command::RDA; - } else if (currentPayload->get_command() == TLM_WRITE_COMMAND) - { - timeToSchedule = checker->timeToSatisfyConstraints(Command::WRA, rank, bankgroup, bank); nextCommand = Command::WRA; - } else SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); } else { if (currentPayload->get_command() == TLM_READ_COMMAND) - { - timeToSchedule = checker->timeToSatisfyConstraints(Command::RD, rank, bankgroup, bank); nextCommand = Command::RD; - } else if (currentPayload->get_command() == TLM_WRITE_COMMAND) - { - timeToSchedule = checker->timeToSatisfyConstraints(Command::WR, rank, bankgroup, bank); nextCommand = Command::WR; - } else - SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); + SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); } + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); } else if (!blocked) // row miss { - timeToSchedule = checker->timeToSatisfyConstraints(Command::PRE, rank, bankgroup, bank); nextCommand = Command::PRE; + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); } } return timeToSchedule; @@ -269,6 +250,7 @@ BankMachineClosedAdaptive::BankMachineClosedAdaptive(SchedulerIF *scheduler, Che sc_time BankMachineClosedAdaptive::start() { timeToSchedule = sc_max_time(); + nextCommand = Command::NOP; if (sleeping) return timeToSchedule; @@ -279,8 +261,8 @@ sc_time BankMachineClosedAdaptive::start() if (currentState == BmState::Precharged && !blocked) // row miss { - timeToSchedule = checker->timeToSatisfyConstraints(Command::ACT, rank, bankgroup, bank); nextCommand = Command::ACT; + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); } else if (currentState == BmState::Activated) { @@ -289,38 +271,27 @@ sc_time BankMachineClosedAdaptive::start() if (scheduler->hasFurtherRowHit(bank, currentRow)) { if (currentPayload->get_command() == TLM_READ_COMMAND) - { - timeToSchedule = checker->timeToSatisfyConstraints(Command::RD, rank, bankgroup, bank); nextCommand = Command::RD; - } else if (currentPayload->get_command() == TLM_WRITE_COMMAND) - { - timeToSchedule = checker->timeToSatisfyConstraints(Command::WR, rank, bankgroup, bank); nextCommand = Command::WR; - } else SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); } else { if (currentPayload->get_command() == TLM_READ_COMMAND) - { - timeToSchedule = checker->timeToSatisfyConstraints(Command::RDA, rank, bankgroup, bank); nextCommand = Command::RDA; - } else if (currentPayload->get_command() == TLM_WRITE_COMMAND) - { - timeToSchedule = checker->timeToSatisfyConstraints(Command::WRA, rank, bankgroup, bank); nextCommand = Command::WRA; - } else SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); } + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); } else if (!blocked) // row miss TODO: remove this, can never happen { - timeToSchedule = checker->timeToSatisfyConstraints(Command::PRE, rank, bankgroup, bank); nextCommand = Command::PRE; + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); SC_REPORT_FATAL("BankMachine", "Should never be reached for this policy"); } } diff --git a/DRAMSys/library/src/controller/BankMachine.h b/DRAMSys/library/src/controller/BankMachine.h index 1b647417..651f8da7 100644 --- a/DRAMSys/library/src/controller/BankMachine.h +++ b/DRAMSys/library/src/controller/BankMachine.h @@ -58,7 +58,7 @@ class BankMachine public: virtual ~BankMachine() {} virtual sc_time start() = 0; - std::pair getNextCommand(); + std::tuple getNextCommand(); void updateState(Command); void block(); @@ -74,7 +74,7 @@ protected: tlm::tlm_generic_payload *currentPayload = nullptr; SchedulerIF *scheduler; CheckerIF *checker; - Command nextCommand; + Command nextCommand = Command::NOP; BmState currentState = BmState::Precharged; Row currentRow; sc_time timeToSchedule = sc_max_time(); diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index 792a383c..169e90ae 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -239,29 +239,27 @@ void Controller::controllerMethod() it->start(); // (5) Choose one request and send it to DRAM - std::pair commandPair; - std::vector> readyCommands; - // (5.1) Check for power-down commands (PDEA/PDEP/SREFEN or PDXA/PDXP/SREFEX) + std::tuple commandTuple; + std::list> readyCommands; for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++) { - commandPair = powerDownManagers[rankID]->getNextCommand(); - if (commandPair.second != nullptr) - readyCommands.push_back(commandPair); + // (5.1) Check for power-down commands (PDEA/PDEP/SREFEN or PDXA/PDXP/SREFEX) + commandTuple = powerDownManagers[rankID]->getNextCommand(); + if (std::get<0>(commandTuple) != Command::NOP) + readyCommands.push_back(commandTuple); else { // (5.2) Check for refresh commands (PREA/PRE or REFA/REFB) - commandPair = refreshManagers[rankID]->getNextCommand(); - if (commandPair.second != nullptr) - readyCommands.push_back(commandPair); - else + commandTuple = refreshManagers[rankID]->getNextCommand(); + if (std::get<0>(commandTuple) != Command::NOP) + readyCommands.push_back(commandTuple); + + // (5.3) Check for bank commands (PRE, ACT, RD/RDA or WR/WRA) + for (auto it : bankMachinesOnRank[rankID]) { - // (5.3) Check for bank commands (PRE, ACT, RD/RDA or WR/WRA) - for (auto it : bankMachinesOnRank[rankID]) - { - commandPair = it->getNextCommand(); - if (commandPair.second != nullptr) - readyCommands.push_back(commandPair); - } + commandTuple = it->getNextCommand(); + if (std::get<0>(commandTuple) != Command::NOP) + readyCommands.push_back(commandTuple); } } } @@ -269,29 +267,29 @@ void Controller::controllerMethod() bool readyCmdBlocked = false; if (!readyCommands.empty()) { - commandPair = cmdMux->selectCommand(readyCommands); - if (commandPair.second != nullptr) // can happen with FIFO strict + commandTuple = cmdMux->selectCommand(readyCommands); + if (std::get<0>(commandTuple) != Command::NOP) // can happen with FIFO strict { - Rank rank = DramExtension::getRank(commandPair.second); - BankGroup bankgroup = DramExtension::getBankGroup(commandPair.second); - Bank bank = DramExtension::getBank(commandPair.second); + Rank rank = DramExtension::getRank(std::get<1>(commandTuple)); + BankGroup bankgroup = DramExtension::getBankGroup(std::get<1>(commandTuple)); + Bank bank = DramExtension::getBank(std::get<1>(commandTuple)); - if (isRankCommand(commandPair.first)) + if (isRankCommand(std::get<0>(commandTuple))) { for (auto it : bankMachinesOnRank[rank.ID()]) - it->updateState(commandPair.first); + it->updateState(std::get<0>(commandTuple)); } else - bankMachines[bank.ID()]->updateState(commandPair.first); + bankMachines[bank.ID()]->updateState(std::get<0>(commandTuple)); - refreshManagers[rank.ID()]->updateState(commandPair.first, commandPair.second); - powerDownManagers[rank.ID()]->updateState(commandPair.first); - checker->insert(commandPair.first, rank, bankgroup, bank); + refreshManagers[rank.ID()]->updateState(std::get<0>(commandTuple)); + powerDownManagers[rank.ID()]->updateState(std::get<0>(commandTuple)); + checker->insert(std::get<0>(commandTuple), rank, bankgroup, bank); - if (isCasCommand(commandPair.first)) + if (isCasCommand(std::get<0>(commandTuple))) { - scheduler->removeRequest(commandPair.second); - respQueue->insertPayload(commandPair.second, memSpec->getIntervalOnDataStrobe(commandPair.first).end); + scheduler->removeRequest(std::get<1>(commandTuple)); + respQueue->insertPayload(std::get<1>(commandTuple), memSpec->getIntervalOnDataStrobe(std::get<0>(commandTuple)).end); sc_time triggerTime = respQueue->getTriggerTime(); if (triggerTime != sc_max_time()) @@ -302,7 +300,7 @@ void Controller::controllerMethod() if (ranksNumberOfPayloads[rank.ID()] == 0) powerDownManagers[rank.ID()]->triggerEntry(); - sendToDram(commandPair.first, commandPair.second); + sendToDram(std::get<0>(commandTuple), std::get<1>(commandTuple)); } else readyCmdBlocked = true; diff --git a/DRAMSys/library/src/controller/Controller.h b/DRAMSys/library/src/controller/Controller.h index f998afc3..bf22c2f2 100644 --- a/DRAMSys/library/src/controller/Controller.h +++ b/DRAMSys/library/src/controller/Controller.h @@ -65,9 +65,9 @@ public: virtual ~Controller(); protected: - virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &, tlm::tlm_phase &, sc_time &); - virtual tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &, tlm::tlm_phase &, sc_time &); - virtual unsigned int transport_dbg(tlm::tlm_generic_payload &); + virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &, tlm::tlm_phase &, sc_time &) override; + virtual tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &, tlm::tlm_phase &, sc_time &) override; + virtual unsigned int transport_dbg(tlm::tlm_generic_payload &) override; virtual void sendToFrontend(tlm::tlm_generic_payload *, tlm::tlm_phase); virtual void sendToDram(Command, tlm::tlm_generic_payload *); diff --git a/DRAMSys/library/src/controller/ControllerIF.h b/DRAMSys/library/src/controller/ControllerIF.h index 38f206fe..b23c3a2e 100644 --- a/DRAMSys/library/src/controller/ControllerIF.h +++ b/DRAMSys/library/src/controller/ControllerIF.h @@ -60,35 +60,35 @@ public: / Configuration::getInstance().memSpec->dataRate * Configuration::getInstance().memSpec->tCK; - double bandwidth = (activeTime / sc_time_stamp() * 100); - double bandwidthWoIdle = ((activeTime) / (sc_time_stamp() - idleTimeCollector.getIdleTime()) * 100); + double bandwidth = activeTime / sc_time_stamp(); + double bandwidthWoIdle = activeTime / (sc_time_stamp() - idleTimeCollector.getIdleTime()); double maxBandwidth = ( - // fCK in Mhz e.g. 800 [MHz]: - (1000000 / Configuration::getInstance().memSpec->tCK.to_double()) + // fCK in GHz e.g. 1 [GHz] (tCK in ps): + (1000 / Configuration::getInstance().memSpec->tCK.to_double()) // DataRate e.g. 2 * Configuration::getInstance().memSpec->dataRate // BusWidth e.g. 8 or 64 * Configuration::getInstance().memSpec->bitWidth // Number of devices on a DIMM e.g. 8 - * Configuration::getInstance().memSpec->numberOfDevicesOnDIMM ) / ( 1024 ); + * Configuration::getInstance().memSpec->numberOfDevicesOnDIMM ); std::cout << name() << std::string(" Total Time: ") << sc_time_stamp().to_string() << std::endl; std::cout << name() << std::string(" AVG BW: ") << std::fixed << std::setprecision(2) - << ((bandwidth / 100) * maxBandwidth) - << " Gibit/s (" << bandwidth << " %)" + << (bandwidth * maxBandwidth) + << " Gb/s (" << (bandwidth * 100) << " %)" << std::endl; std::cout << name() << std::string(" AVG BW\\IDLE: ") << std::fixed << std::setprecision(2) - << ((bandwidthWoIdle / 100) * maxBandwidth) - << " Gibit/s (" << bandwidthWoIdle << " %)" + << (bandwidthWoIdle * maxBandwidth) + << " Gb/s (" << (bandwidthWoIdle * 100) << " %)" << endl; std::cout << name() << std::string(" MAX BW: ") << std::fixed << std::setprecision(2) - << maxBandwidth << " Gibit/s" + << maxBandwidth << " Gb/s" << std::endl; } diff --git a/DRAMSys/library/src/controller/ControllerRecordable.h b/DRAMSys/library/src/controller/ControllerRecordable.h index a7bd6ea6..e39555f0 100644 --- a/DRAMSys/library/src/controller/ControllerRecordable.h +++ b/DRAMSys/library/src/controller/ControllerRecordable.h @@ -44,17 +44,17 @@ public: ControllerRecordable(sc_module_name name, TlmRecorder *tlmRecorder) : Controller(name), tlmRecorder(tlmRecorder) {} +protected: + virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &trans, + tlm::tlm_phase &phase, sc_time &delay) override; + virtual tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &trans, + tlm::tlm_phase &phase, sc_time &delay) override; + + virtual void sendToFrontend(tlm::tlm_generic_payload *, tlm::tlm_phase) override; + virtual void sendToDram(Command, tlm::tlm_generic_payload *) override; + private: - tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &trans, - tlm::tlm_phase &phase, sc_time &delay) override; - tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &trans, - tlm::tlm_phase &phase, sc_time &delay) override; - - void sendToFrontend(tlm::tlm_generic_payload *, tlm::tlm_phase) override; - void sendToDram(Command, tlm::tlm_generic_payload *) override; - void recordPhase(tlm::tlm_generic_payload &trans, tlm::tlm_phase phase, sc_time delay); - TlmRecorder *tlmRecorder; }; diff --git a/DRAMSys/library/src/controller/cmdmux/CmdMuxIF.h b/DRAMSys/library/src/controller/cmdmux/CmdMuxIF.h index a53b9a41..8f671327 100644 --- a/DRAMSys/library/src/controller/cmdmux/CmdMuxIF.h +++ b/DRAMSys/library/src/controller/cmdmux/CmdMuxIF.h @@ -35,17 +35,18 @@ #ifndef CMDMUXIF_H #define CMDMUXIF_H +#include #include #include -#include +#include #include "../Command.h" class CmdMuxIF { public: virtual ~CmdMuxIF() {} - virtual std::pair - selectCommand(std::vector> &) = 0; + virtual std::tuple + selectCommand(std::list> &) = 0; }; #endif // CMDMUXIF_H diff --git a/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.cpp b/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.cpp index 31c98ef2..9d002b90 100644 --- a/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.cpp +++ b/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.cpp @@ -38,23 +38,30 @@ using namespace tlm; -std::pair -CmdMuxOldest::selectCommand(std::vector> &readyCommands) -{ - auto it = readyCommands.begin(); - auto result = it; - unsigned lastPayloadID = DramExtension::getPayloadID(it->second); - it++; +std::tuple +CmdMuxOldest::selectCommand(std::list> &readyCommands) +{ + readyCommands.remove_if([](std::tuple element){return std::get<2>(element) != sc_time_stamp();}); - while (it != readyCommands.end()) + if (!readyCommands.empty()) { - unsigned newPayloadID = DramExtension::getPayloadID(it->second); - if (newPayloadID < lastPayloadID) - { - lastPayloadID = newPayloadID; - result = it; - } + auto it = readyCommands.begin(); + auto result = it; + uint64_t lastPayloadID = DramExtension::getPayloadID(std::get<1>(*it)); it++; + + while (it != readyCommands.end()) + { + uint64_t newPayloadID = DramExtension::getPayloadID(std::get<1>(*it)); + if (newPayloadID < lastPayloadID) + { + lastPayloadID = newPayloadID; + result = it; + } + it++; + } + return *result; } - return *result; + else + return std::tuple(Command::NOP, nullptr, sc_max_time()); } diff --git a/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.h b/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.h index 419479b2..40c69ff9 100644 --- a/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.h +++ b/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.h @@ -40,8 +40,8 @@ class CmdMuxOldest : public CmdMuxIF { public: - std::pair - selectCommand(std::vector> &); + std::tuple + selectCommand(std::list> &); }; #endif // CMDMUXOLDEST_H diff --git a/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.cpp b/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.cpp index 989c8d96..87c34f05 100644 --- a/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.cpp +++ b/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.cpp @@ -38,24 +38,29 @@ using namespace tlm; -std::pair -CmdMuxStrict::selectCommand(std::vector> &readyCommands) +std::tuple +CmdMuxStrict::selectCommand(std::list> &readyCommands) { - for (auto it : readyCommands) + readyCommands.remove_if([](std::tuple element){return std::get<2>(element) != sc_time_stamp();}); + + if (!readyCommands.empty()) { - if (isCasCommand(it.first)) + for (auto it : readyCommands) { - if (DramExtension::getPayloadID(it.second) == nextPayloadID) + if (isCasCommand(std::get<0>(it))) { - nextPayloadID++; - return it; + if (DramExtension::getPayloadID(std::get<1>(it)) == nextPayloadID) + { + nextPayloadID++; + return it; + } } } + for (auto it : readyCommands) + { + if (isRasCommand(std::get<0>(it))) + return it; + } } - for (auto it : readyCommands) - { - if (isRasCommand(it.first)) - return it; - } - return std::pair(Command::NOP, nullptr); + return std::tuple(Command::NOP, nullptr, sc_max_time()); } diff --git a/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.h b/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.h index 1ee53914..a0389771 100644 --- a/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.h +++ b/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.h @@ -40,8 +40,8 @@ class CmdMuxStrict : public CmdMuxIF { public: - std::pair - selectCommand(std::vector> &); + std::tuple + selectCommand(std::list> &); private: uint64_t nextPayloadID = 0; diff --git a/DRAMSys/library/src/controller/powerdown/PowerDownManagerDummy.cpp b/DRAMSys/library/src/controller/powerdown/PowerDownManagerDummy.cpp index 4124d43d..8439982f 100644 --- a/DRAMSys/library/src/controller/powerdown/PowerDownManagerDummy.cpp +++ b/DRAMSys/library/src/controller/powerdown/PowerDownManagerDummy.cpp @@ -36,9 +36,9 @@ using namespace tlm; -std::pair PowerDownManagerDummy::getNextCommand() +std::tuple PowerDownManagerDummy::getNextCommand() { - return std::pair(Command::NOP, nullptr); + return std::tuple(Command::NOP, nullptr, sc_max_time()); } sc_time PowerDownManagerDummy::start() diff --git a/DRAMSys/library/src/controller/powerdown/PowerDownManagerDummy.h b/DRAMSys/library/src/controller/powerdown/PowerDownManagerDummy.h index 354768eb..82b5e60e 100644 --- a/DRAMSys/library/src/controller/powerdown/PowerDownManagerDummy.h +++ b/DRAMSys/library/src/controller/powerdown/PowerDownManagerDummy.h @@ -46,7 +46,7 @@ public: virtual void triggerExit() override {} virtual void triggerInterruption() override {} - virtual std::pair getNextCommand() override; + virtual std::tuple getNextCommand() override; virtual void updateState(Command) override {} virtual sc_time start() override; }; diff --git a/DRAMSys/library/src/controller/powerdown/PowerDownManagerIF.h b/DRAMSys/library/src/controller/powerdown/PowerDownManagerIF.h index 41474c44..b501c10e 100644 --- a/DRAMSys/library/src/controller/powerdown/PowerDownManagerIF.h +++ b/DRAMSys/library/src/controller/powerdown/PowerDownManagerIF.h @@ -49,7 +49,7 @@ public: virtual void triggerExit() = 0; virtual void triggerInterruption() = 0; - virtual std::pair getNextCommand() = 0; + virtual std::tuple getNextCommand() = 0; virtual void updateState(Command) = 0; virtual sc_time start() = 0; }; diff --git a/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.cpp b/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.cpp index a6fb3ef5..08a57e16 100644 --- a/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.cpp +++ b/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.cpp @@ -40,7 +40,7 @@ using namespace tlm; PowerDownManagerStaggered::PowerDownManagerStaggered(Rank rank, CheckerIF *checker) : rank(rank), checker(checker) { - setUpDummy(powerDownPayload, rank); + setUpDummy(powerDownPayload, UINT64_MAX, rank); } void PowerDownManagerStaggered::triggerEntry() @@ -69,17 +69,15 @@ void PowerDownManagerStaggered::triggerInterruption() exitTriggered = true; } -std::pair PowerDownManagerStaggered::getNextCommand() +std::tuple PowerDownManagerStaggered::getNextCommand() { - if (sc_time_stamp() == timeToSchedule) - return std::pair(nextCommand, &powerDownPayload); - else - return std::pair(Command::NOP, nullptr); + return std::tuple(nextCommand, &powerDownPayload, timeToSchedule); } sc_time PowerDownManagerStaggered::start() { timeToSchedule = sc_max_time(); + nextCommand = Command::NOP; if (exitTriggered) { diff --git a/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.h b/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.h index 499ca3d4..5f4120e1 100644 --- a/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.h +++ b/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.h @@ -48,7 +48,7 @@ public: virtual void triggerExit() override; virtual void triggerInterruption() override; - virtual std::pair getNextCommand() override; + virtual std::tuple getNextCommand() override; virtual void updateState(Command) override; virtual sc_time start() override; @@ -59,7 +59,7 @@ private: CheckerIF *checker; sc_time timeToSchedule = sc_max_time(); - Command nextCommand; + Command nextCommand = Command::NOP; bool controllerIdle = true; bool entryTriggered = true; diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.cpp b/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.cpp index 7a23ca07..6acb4e6c 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.cpp +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.cpp @@ -50,27 +50,26 @@ RefreshManagerBankwise::RefreshManagerBankwise(std::vector &bankM refreshPayloads = std::vector(memSpec->banksPerRank); for (unsigned bankID = 0; bankID < memSpec->banksPerRank; bankID++) { - setUpDummy(refreshPayloads[bankID], rank, bankMachines[bankID]->getBank()); + setUpDummy(refreshPayloads[bankID], 0, rank, bankMachines[bankID]->getBankGroup(), bankMachines[bankID]->getBank()); allBankMachines.push_back(bankMachines[bankID]); } remainingBankMachines = allBankMachines; + currentBankMachine = *remainingBankMachines.begin(); maxPostponed = config.refreshMaxPostponed * memSpec->banksPerRank; maxPulledin = -(config.refreshMaxPulledin * memSpec->banksPerRank); } -std::pair RefreshManagerBankwise::getNextCommand() +std::tuple RefreshManagerBankwise::getNextCommand() { - if (sc_time_stamp() == timeToSchedule) - return std::pair - (nextCommand, &refreshPayloads[currentBankMachine->getBank().ID() % memSpec->banksPerRank]); - else - return std::pair(Command::NOP, nullptr); + return std::tuple + (nextCommand, &refreshPayloads[currentBankMachine->getBank().ID() % memSpec->banksPerRank], timeToSchedule); } sc_time RefreshManagerBankwise::start() { timeToSchedule = sc_max_time(); + nextCommand = Command::NOP; if (sc_time_stamp() >= timeForNextTrigger) { @@ -86,13 +85,14 @@ sc_time RefreshManagerBankwise::start() if (state == RmState::Regular) { - currentIterator = remainingBankMachines.begin(); - currentBankMachine = *remainingBankMachines.begin(); bool forcedRefresh = (flexibilityCounter == maxPostponed); bool allBanksBusy = true; if (!skipSelection) { + currentIterator = remainingBankMachines.begin(); + currentBankMachine = *remainingBankMachines.begin(); + for (auto it = remainingBankMachines.begin(); it != remainingBankMachines.end(); it++) { if ((*it)->isIdle()) @@ -168,7 +168,7 @@ sc_time RefreshManagerBankwise::start() return timeForNextTrigger; } -void RefreshManagerBankwise::updateState(Command command, tlm_generic_payload *payload) +void RefreshManagerBankwise::updateState(Command command) { switch (command) { diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.h b/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.h index 94b2bd08..f3b39906 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.h +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.h @@ -48,9 +48,9 @@ class RefreshManagerBankwise final : public RefreshManagerIF public: RefreshManagerBankwise(std::vector &, PowerDownManagerIF *, Rank, CheckerIF *); - virtual std::pair getNextCommand() override; + virtual std::tuple getNextCommand() override; virtual sc_time start() override; - virtual void updateState(Command, tlm::tlm_generic_payload *) override; + virtual void updateState(Command) override; private: enum class RmState {Regular, Pulledin} state = RmState::Regular; @@ -62,7 +62,7 @@ private: sc_time timeToSchedule = sc_max_time(); Rank rank; CheckerIF *checker; - Command nextCommand; + Command nextCommand = Command::NOP; std::list remainingBankMachines; std::list allBankMachines; diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerDummy.cpp b/DRAMSys/library/src/controller/refresh/RefreshManagerDummy.cpp index 6e98d9cd..33206fc6 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerDummy.cpp +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerDummy.cpp @@ -36,9 +36,9 @@ using namespace tlm; -std::pair RefreshManagerDummy::getNextCommand() +std::tuple RefreshManagerDummy::getNextCommand() { - return std::pair(Command::NOP, nullptr); + return std::tuple(Command::NOP, nullptr, sc_max_time()); } sc_time RefreshManagerDummy::start() diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerDummy.h b/DRAMSys/library/src/controller/refresh/RefreshManagerDummy.h index f543310b..a7a26f79 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerDummy.h +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerDummy.h @@ -44,9 +44,9 @@ class RefreshManagerDummy final : public RefreshManagerIF { public: - virtual std::pair getNextCommand() override; + virtual std::tuple getNextCommand() override; virtual sc_time start() override; - virtual void updateState(Command, tlm::tlm_generic_payload *) override {} + virtual void updateState(Command) override {} }; #endif // REFRESHMANAGERDUMMY_H diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerIF.h b/DRAMSys/library/src/controller/refresh/RefreshManagerIF.h index aa7bf44b..ff8bc949 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerIF.h +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerIF.h @@ -45,9 +45,9 @@ class RefreshManagerIF public: virtual ~RefreshManagerIF() {} - virtual std::pair getNextCommand() = 0; + virtual std::tuple getNextCommand() = 0; virtual sc_time start() = 0; - virtual void updateState(Command, tlm::tlm_generic_payload *) = 0; + virtual void updateState(Command) = 0; }; #endif // REFRESHMANAGERIF_H diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerRankwise.cpp b/DRAMSys/library/src/controller/refresh/RefreshManagerRankwise.cpp index 98004383..40df47e3 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerRankwise.cpp +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerRankwise.cpp @@ -46,23 +46,21 @@ RefreshManagerRankwise::RefreshManagerRankwise(std::vector &bankM Configuration &config = Configuration::getInstance(); memSpec = config.memSpec; timeForNextTrigger = memSpec->getRefreshIntervalAB(); - setUpDummy(refreshPayload, rank); + setUpDummy(refreshPayload, 0, rank); maxPostponed = config.refreshMaxPostponed; maxPulledin = -config.refreshMaxPulledin; } -std::pair RefreshManagerRankwise::getNextCommand() +std::tuple RefreshManagerRankwise::getNextCommand() { - if (sc_time_stamp() == timeToSchedule) - return std::pair(nextCommand, &refreshPayload); - else - return std::pair(Command::NOP, nullptr); + return std::tuple(nextCommand, &refreshPayload, timeToSchedule); } sc_time RefreshManagerRankwise::start() { timeToSchedule = sc_max_time(); + nextCommand = Command::NOP; if (sc_time_stamp() >= timeForNextTrigger) { @@ -130,7 +128,7 @@ sc_time RefreshManagerRankwise::start() } else { - // nextCommand stays Command::REFA + nextCommand = Command::REFA; timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0)); return timeToSchedule; } @@ -140,7 +138,7 @@ sc_time RefreshManagerRankwise::start() return timeForNextTrigger; } -void RefreshManagerRankwise::updateState(Command command, tlm_generic_payload *) +void RefreshManagerRankwise::updateState(Command command) { switch (command) { diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerRankwise.h b/DRAMSys/library/src/controller/refresh/RefreshManagerRankwise.h index 31a484ea..778e0045 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerRankwise.h +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerRankwise.h @@ -46,9 +46,9 @@ class RefreshManagerRankwise final : public RefreshManagerIF public: RefreshManagerRankwise(std::vector &, PowerDownManagerIF *, Rank, CheckerIF *); - virtual std::pair getNextCommand() override; + virtual std::tuple getNextCommand() override; virtual sc_time start() override; - virtual void updateState(Command, tlm::tlm_generic_payload *) override; + virtual void updateState(Command) override; private: enum class RmState {Regular, Pulledin} state = RmState::Regular; @@ -60,7 +60,7 @@ private: sc_time timeToSchedule = sc_max_time(); Rank rank; CheckerIF *checker; - Command nextCommand; + Command nextCommand = Command::NOP; unsigned activatedBanks = 0; diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index 09936d51..a6373b33 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -82,7 +82,7 @@ private: tlm::tlm_sync_enum nb_transport_bw(int channelId, tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase, sc_time &bwDelay); - virtual unsigned int transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans); + unsigned int transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans); void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase); diff --git a/DRAMSys/library/src/simulation/DRAMSys.cpp b/DRAMSys/library/src/simulation/DRAMSys.cpp index eae66646..fca962a1 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -143,19 +143,27 @@ DRAMSys::~DRAMSys() void DRAMSys::logo() { -#define REDTXT(s) std::string("\033[0;31m" + std::string(s) + "\033[0m") -#define BOLDBLUETXT(s) std::string("\033[1;34m" + std::string(s) + "\033[0m") - std::cout << std::endl; - std::cout << REDTXT(" |||") << std::endl; - std::cout << REDTXT(" +---+ Microelectronic Systems") << std::endl; - std::cout << REDTXT("=| |= Design Research Group") << std::endl; - std::cout << REDTXT("=| |= ") << BOLDBLUETXT("Technische Universität Kaiserslautern") +#define GREENTXT(s) std::string(("\u001b[38;5;28m"+std::string((s))+"\033[0m")) +#define DGREENTXT(s) std::string(("\u001b[38;5;22m"+std::string((s))+"\033[0m")) +#define LGREENTXT(s) std::string(("\u001b[38;5;82m"+std::string((s))+"\033[0m")) +#define BLACKTXT(s) std::string(("\u001b[38;5;232m"+std::string((s))+"\033[0m")) +#define BOLDTXT(s) std::string(("\033[1;37m"+std::string((s))+"\033[0m")) + cout << std::endl + << BLACKTXT("■ ■ ")<< DGREENTXT("■ ") + << BOLDTXT("DRAMSys4.0, Copyright (c) 2020") + << std::endl + << BLACKTXT("■ ") << DGREENTXT("■ ") << GREENTXT("■ ") + << "Technische Universitaet Kaiserslautern," + << std::endl + << DGREENTXT("■ ") << GREENTXT("■ ") << LGREENTXT("■ " ) + << "Fraunhofer IESE" + << std::endl << std::endl; - std::cout << REDTXT(" +---+ ") << std::endl; - std::cout << REDTXT(" ||| ") << "DRAMSys4.0" << std::endl; - std::cout << std::endl; -#undef REDTXT -#undef BOLDBLUETXT +#undef GREENTXT +#undef DGREENTXT +#undef LGREENTXT +#undef BLACKTXT +#undef BOLDTXT } void DRAMSys::setupDebugManager(const std::string &traceName __attribute__((unused))) diff --git a/DRAMSys/library/src/simulation/dram/DramRecordable.h b/DRAMSys/library/src/simulation/dram/DramRecordable.h index c2c901c2..e750ecfc 100644 --- a/DRAMSys/library/src/simulation/dram/DramRecordable.h +++ b/DRAMSys/library/src/simulation/dram/DramRecordable.h @@ -48,8 +48,9 @@ class DramRecordable final : public BaseDram public: DramRecordable(sc_module_name, TlmRecorder *); SC_HAS_PROCESS(DramRecordable); + virtual ~DramRecordable() {} - virtual void reportPower(); + virtual void reportPower() override; private: virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &payload, diff --git a/README.md b/README.md index b6351eb5..1f0b201e 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,18 @@ A UML diagram of the software architecture is presented below; different compone UML +## Trace Analyzer Consulting and Custom-Tailored Modifications + +To provide better analysis capabilities for DRAM subsystem design space exploration than the usual performance-related outputs to the console, DRAMSys offers the Trace Analyzer. + +All requests, responses and DRAM commands can be recorded in an SQLite trace database during a simulation and visualized with the tool afterwards. An evaluation of the trace databases can be performed with the powerful Python interface of the Trace Analyzer. Different metrics are described as SQL statements and formulas in Python, which can be customized or extended without recompilation. + +The Trace Analyzer's main window is shown below. + +If you are interested in the database recording feature and the Trace Analyzer, if you need support on how to setup DRAMSys in a virtual platform of your company, or if you require custom modifications of the simulator please contact [Matthias Jung](mailto:matthias.jung@iese.fraunhofer.de). + +![Trace Analyzer Main Window](DRAMSys/docs/images/traceanalyzer.png) + ## Basic Setup Start using DRAMSys by cloning the repository. @@ -204,7 +216,7 @@ The content of [ddr3.json](DRAMSys/library/resources/configs/simulator/ddr3.json } ``` - - *SimulationName* (boolean) + - *SimulationName* (string) - Give the name of the simulation for distinguishing from other simulations. - *Debug* (boolean) - true: enables debug output on console (only supported by a debug build) @@ -342,7 +354,7 @@ An example follows. ## DRAMSys with Thermal Simulation -The thermal simulation is performed by a **3D-ICE** [8] server accessed through the network. Therefore users interested in thermal simulation during their DRAMSys simulations need to make sure they have a 3D-ICE server up and running before starting. For more information about 3D-ICE visit the [official website](https://www.epfl.ch/labs/esl/open-source-software-projects/3d-ice/). +The thermal simulation is performed by a **3D-ICE** [8] server accessed through the network. Therefore users interested in thermal simulation during their DRAMSys simulations need to make sure they have a 3D-ICE server up and running before starting. For more information about 3D-ICE visit the [official website](https://www.epfl.ch/labs/esl/open-source-software-projects/3d-ice/). An example video that visualizes the results of a thermal simulation is provided on [Youtube](https://www.youtube.com/watch?v=Eacsq71hHtY). #### Installing 3D-ICE @@ -506,18 +518,6 @@ The content of [config.json](DRAMSys/library/resources/configs/thermalsim/config - true: generate power map files during thermal simulation - false: do not generate power map files during thermal simulation -## Trace Analyzer Consulting and Custom-Tailored Modifications - -To provide better analysis capabilities for DRAM subsystem design space exploration than the usual performance-related outputs to the console, DRAMSys offers the Trace Analyzer. - -All requests, responses and DRAM commands can be recorded in an SQLite trace database during a simulation and visualized with the tool afterwards. An evaluation of the trace databases can be performed with the powerful Python interface of the Trace Analyzer. Different metrics are described as SQL statements and formulas in Python, which can be customized or extended without recompilation. - -The Trace Analyzer's main window is shown below. - -If you are interested in the database recording feature and the Trace Analyzer, if you need support on how to setup DRAMSys in a virtual platform of your company, or if you require custom modifications of the simulator please contact [Matthias Jung](mailto:matthias.jung@iese.fraunhofer.de). - -![Trace Analyzer Main Window](DRAMSys/docs/images/traceanalyzer.png) - ## Acknowledgements The development of DRAMSys was supported by the German Research Foundation (DFG) as part of the priority program [Dependable Embedded Systems SPP1500](http://spp1500.itec.kit.edu) and the DFG grant no. [WE2442/10-1](https://www.uni-kl.de/en/3d-dram/). Furthermore, it was supported within the Fraunhofer and DFG cooperation program (grant no. [WE2442/14-1](https://www.iese.fraunhofer.de/en/innovation_trends/autonomous-systems/memtonomy.html)) and by the [Fraunhofer High Performance Center for Simulation- and Software-Based Innovation](https://www.leistungszentrum-simulation-software.de/en.html). Special thanks go to all listed contributors for their work and commitment during seven years of development.