diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.cpp b/DRAMSys/library/src/configuration/memspec/MemSpec.cpp index c3a73127..0ab6486c 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.cpp @@ -95,3 +95,8 @@ sc_time MemSpec::getRefreshIntervalSB() const SC_REPORT_FATAL("MemSpec", "Same bank refresh not supported"); return SC_ZERO_TIME; } + +bool MemSpec::hasRasAndCasBus() const +{ + return false; +} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.h b/DRAMSys/library/src/configuration/memspec/MemSpec.h index 5aa935f9..4020a8ed 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.h @@ -77,6 +77,8 @@ public: virtual sc_time getRefreshIntervalPB() const; virtual sc_time getRefreshIntervalSB() const; + virtual bool hasRasAndCasBus() const; + virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const = 0; virtual TimeInterval getIntervalOnDataStrobe(Command) const = 0; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp index ea91854b..c299f9d9 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp @@ -94,6 +94,11 @@ sc_time MemSpecHBM2::getRefreshIntervalPB() const return tREFISB; } +bool MemSpecHBM2::hasRasAndCasBus() const +{ + return true; +} + sc_time MemSpecHBM2::getExecutionTime(Command command, const tlm_generic_payload &payload) const { if (command == Command::PRE || command == Command::PREA) diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h index 618f40db..a56f18fb 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h @@ -83,6 +83,8 @@ public: virtual sc_time getRefreshIntervalAB() const override; virtual sc_time getRefreshIntervalPB() const override; + virtual bool hasRasAndCasBus() const override; + virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index d74f2b71..21355bb1 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -112,9 +112,19 @@ Controller::Controller(sc_module_name name) : scheduler = new SchedulerFrFcfsGrp(); if (config.cmdMux == Configuration::CmdMux::Oldest) - cmdMux = new CmdMuxOldest(); + { + if (memSpec->hasRasAndCasBus()) + cmdMux = new CmdMuxOldestRasCas(); + else + cmdMux = new CmdMuxOldest(); + } else if (config.cmdMux == Configuration::CmdMux::Strict) - cmdMux = new CmdMuxStrict(); + { + if (memSpec->hasRasAndCasBus()) + cmdMux = new CmdMuxStrictRasCas(); + else + cmdMux = new CmdMuxStrict(); + } if (config.respQueue == Configuration::RespQueue::Fifo) respQueue = new RespQueueFifo(); diff --git a/DRAMSys/library/src/controller/cmdmux/CmdMuxIF.h b/DRAMSys/library/src/controller/cmdmux/CmdMuxIF.h index 49e0318c..7134f3cb 100644 --- a/DRAMSys/library/src/controller/cmdmux/CmdMuxIF.h +++ b/DRAMSys/library/src/controller/cmdmux/CmdMuxIF.h @@ -45,7 +45,7 @@ class CmdMuxIF { public: virtual ~CmdMuxIF() {} - virtual CommandTuple::Type selectCommand(ReadyCommands &) = 0; + virtual CommandTuple::Type selectCommand(const ReadyCommands &) = 0; }; #endif // CMDMUXIF_H diff --git a/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.cpp b/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.cpp index f11f597e..a64bde58 100644 --- a/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.cpp +++ b/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.cpp @@ -40,7 +40,7 @@ using namespace tlm; CmdMuxOldest::CmdMuxOldest() : memSpec(Configuration::getInstance().memSpec) {} -CommandTuple::Type CmdMuxOldest::selectCommand(ReadyCommands &readyCommands) +CommandTuple::Type CmdMuxOldest::selectCommand(const ReadyCommands &readyCommands) { auto result = readyCommands.cend(); uint64_t lastPayloadID = UINT64_MAX; @@ -51,7 +51,7 @@ CommandTuple::Type CmdMuxOldest::selectCommand(ReadyCommands &readyCommands) for (auto it = readyCommands.cbegin(); it != readyCommands.cend(); it++) { newTimestamp = std::get(*it) + - memSpec->getCommandLength(std::get(*it)) - memSpec->tCK; + memSpec->getCommandLength(std::get(*it)); newPayloadID = DramExtension::getChannelPayloadID(std::get(*it)); if (newTimestamp < lastTimestamp) @@ -60,13 +60,116 @@ CommandTuple::Type CmdMuxOldest::selectCommand(ReadyCommands &readyCommands) lastPayloadID = newPayloadID; result = it; } - else if (newTimestamp == lastTimestamp) + else if ((newTimestamp == lastTimestamp) && (newPayloadID < lastPayloadID)) { - if (newPayloadID < lastPayloadID) - { - lastPayloadID = newPayloadID; - result = it; - } + lastPayloadID = newPayloadID; + result = it; + } + } + + if (result != readyCommands.cend() && + std::get(*result) == sc_time_stamp()) + return *result; + else + return CommandTuple::Type(Command::NOP, nullptr, sc_max_time()); +} + + +CmdMuxOldestRasCas::CmdMuxOldestRasCas() : memSpec(Configuration::getInstance().memSpec) +{ + readyRasCommands.reserve(memSpec->numberOfBanks); + readyCasCommands.reserve(memSpec->numberOfBanks); + readyRasCasCommands.reserve(2); +} + +CommandTuple::Type CmdMuxOldestRasCas::selectCommand(const ReadyCommands &readyCommands) +{ + readyRasCommands.clear(); + readyCasCommands.clear(); + + for (auto it : readyCommands) + { + if (isRasCommand(std::get(it))) + readyRasCommands.emplace_back(it); + else + readyCasCommands.emplace_back(it); + } + + auto result = readyCommands.cend(); + auto resultRas = readyRasCommands.cend(); + auto resultCas = readyCasCommands.cend(); + + uint64_t lastPayloadID = UINT64_MAX; + uint64_t newPayloadID; + sc_time lastTimestamp = sc_max_time(); + sc_time newTimestamp; + + for (auto it = readyRasCommands.cbegin(); it != readyRasCommands.cend(); it++) + { + newTimestamp = std::get(*it) + + memSpec->getCommandLength(std::get(*it)); + newPayloadID = DramExtension::getChannelPayloadID(std::get(*it)); + + if (newTimestamp < lastTimestamp) + { + lastTimestamp = newTimestamp; + lastPayloadID = newPayloadID; + resultRas = it; + } + else if ((newTimestamp == lastTimestamp) && (newPayloadID < lastPayloadID)) + { + lastPayloadID = newPayloadID; + resultRas = it; + } + } + + lastPayloadID = UINT64_MAX; + lastTimestamp = sc_max_time(); + + for (auto it = readyCasCommands.cbegin(); it != readyCasCommands.cend(); it++) + { + newTimestamp = std::get(*it) + + memSpec->getCommandLength(std::get(*it)); + newPayloadID = DramExtension::getChannelPayloadID(std::get(*it)); + + if (newTimestamp < lastTimestamp) + { + lastTimestamp = newTimestamp; + lastPayloadID = newPayloadID; + resultCas = it; + } + else if ((newTimestamp == lastTimestamp) && (newPayloadID < lastPayloadID)) + { + lastPayloadID = newPayloadID; + resultCas = it; + } + } + + readyRasCasCommands.clear(); + + if (resultRas != readyRasCommands.cend()) + readyRasCasCommands.emplace_back(*resultRas); + if (resultCas != readyCasCommands.cend()) + readyRasCasCommands.emplace_back(*resultCas); + + lastPayloadID = UINT64_MAX; + lastTimestamp = sc_max_time(); + + for (auto it = readyRasCasCommands.cbegin(); it != readyRasCasCommands.cend(); it++) + { + newTimestamp = std::get(*it); + newPayloadID = DramExtension::getChannelPayloadID(std::get(*it)); + + if (newTimestamp < lastTimestamp) + { + lastTimestamp = newTimestamp; + lastPayloadID = newPayloadID; + result = it; + } + else if ((newTimestamp == lastTimestamp) && (newPayloadID < lastPayloadID)) + { + lastPayloadID = newPayloadID; + result = it; } } diff --git a/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.h b/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.h index ee2c794e..5f8ce661 100644 --- a/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.h +++ b/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.h @@ -42,10 +42,24 @@ class CmdMuxOldest : public CmdMuxIF { public: CmdMuxOldest(); - CommandTuple::Type selectCommand(ReadyCommands &); + virtual CommandTuple::Type selectCommand(const ReadyCommands &) override; private: const MemSpec *memSpec; }; + +class CmdMuxOldestRasCas : public CmdMuxIF +{ +public: + CmdMuxOldestRasCas(); + virtual CommandTuple::Type selectCommand(const ReadyCommands &) override; + +private: + const MemSpec *memSpec; + ReadyCommands readyRasCommands; + ReadyCommands readyCasCommands; + ReadyCommands readyRasCasCommands; +}; + #endif // CMDMUXOLDEST_H diff --git a/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.cpp b/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.cpp index d10f36fa..ce9e97d6 100644 --- a/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.cpp +++ b/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.cpp @@ -40,7 +40,7 @@ using namespace tlm; CmdMuxStrict::CmdMuxStrict() : memSpec(Configuration::getInstance().memSpec) {} -CommandTuple::Type CmdMuxStrict::selectCommand(ReadyCommands &readyCommands) +CommandTuple::Type CmdMuxStrict::selectCommand(const ReadyCommands &readyCommands) { auto result = readyCommands.cend(); uint64_t lastPayloadID = UINT64_MAX; @@ -51,44 +51,24 @@ CommandTuple::Type CmdMuxStrict::selectCommand(ReadyCommands &readyCommands) for (auto it = readyCommands.cbegin(); it != readyCommands.cend(); it++) { newTimestamp = std::get(*it) + - memSpec->getCommandLength(std::get(*it)) - memSpec->tCK; + memSpec->getCommandLength(std::get(*it)); newPayloadID = DramExtension::getChannelPayloadID(std::get(*it)); if (newTimestamp < lastTimestamp) { - if (isCasCommand(std::get(*it))) - { - if (newPayloadID == nextPayloadID) - { - lastTimestamp = newTimestamp; - lastPayloadID = newPayloadID; - result = it; - } - } - else + if (isRasCommand(std::get(*it)) || newPayloadID == nextPayloadID) { lastTimestamp = newTimestamp; lastPayloadID = newPayloadID; result = it; - } + } } - else if (newTimestamp == lastTimestamp) + else if ((newTimestamp == lastTimestamp) && (newPayloadID < lastPayloadID)) { - if (isCasCommand(std::get(*it))) + if (isRasCommand(std::get(*it)) || newPayloadID == nextPayloadID) { - if ((newPayloadID < lastPayloadID) && (newPayloadID == nextPayloadID)) - { - lastPayloadID = newPayloadID; - result = it; - } - } - else - { - if (newPayloadID < lastPayloadID) - { - lastPayloadID = newPayloadID; - result = it; - } + lastPayloadID = newPayloadID; + result = it; } } } @@ -103,3 +83,102 @@ CommandTuple::Type CmdMuxStrict::selectCommand(ReadyCommands &readyCommands) else return CommandTuple::Type(Command::NOP, nullptr, sc_max_time()); } + + +CmdMuxStrictRasCas::CmdMuxStrictRasCas() : memSpec(Configuration::getInstance().memSpec) +{ + readyRasCommands.reserve(memSpec->numberOfBanks); + readyCasCommands.reserve(memSpec->numberOfBanks); + readyRasCasCommands.reserve(2); +} + +CommandTuple::Type CmdMuxStrictRasCas::selectCommand(const ReadyCommands &readyCommands) +{ + readyRasCommands.clear(); + readyCasCommands.clear(); + + for (auto it : readyCommands) + { + if (isRasCommand(std::get(it))) + readyRasCommands.emplace_back(it); + else + readyCasCommands.emplace_back(it); + } + + auto result = readyCommands.cend(); + auto resultRas = readyRasCommands.cend(); + auto resultCas = readyCasCommands.cend(); + + uint64_t lastPayloadID = UINT64_MAX; + uint64_t newPayloadID; + sc_time lastTimestamp = sc_max_time(); + sc_time newTimestamp; + + for (auto it = readyRasCommands.cbegin(); it != readyRasCommands.cend(); it++) + { + newTimestamp = std::get(*it) + + memSpec->getCommandLength(std::get(*it)); + newPayloadID = DramExtension::getChannelPayloadID(std::get(*it)); + + if (newTimestamp < lastTimestamp) + { + lastTimestamp = newTimestamp; + lastPayloadID = newPayloadID; + resultRas = it; + } + else if ((newTimestamp == lastTimestamp) && (newPayloadID < lastPayloadID)) + { + lastPayloadID = newPayloadID; + resultRas = it; + } + } + + for (auto it = readyCasCommands.cbegin(); it != readyCasCommands.cend(); it++) + { + newPayloadID = DramExtension::getChannelPayloadID(std::get(*it)); + + if (newPayloadID == nextPayloadID) + { + resultCas = it; + break; + } + } + + readyRasCasCommands.clear(); + + if (resultRas != readyRasCommands.cend()) + readyRasCasCommands.emplace_back(*resultRas); + if (resultCas != readyCasCommands.cend()) + readyRasCasCommands.emplace_back(*resultCas); + + lastPayloadID = UINT64_MAX; + lastTimestamp = sc_max_time(); + + for (auto it = readyRasCasCommands.cbegin(); it != readyRasCasCommands.cend(); it++) + { + newTimestamp = std::get(*it); + newPayloadID = DramExtension::getChannelPayloadID(std::get(*it)); + + if (newTimestamp < lastTimestamp) + { + lastTimestamp = newTimestamp; + lastPayloadID = newPayloadID; + result = it; + } + else if ((newTimestamp == lastTimestamp) && (newPayloadID < lastPayloadID)) + { + lastPayloadID = newPayloadID; + result = it; + } + } + + if (result != readyCommands.cend() && + std::get(*result) == sc_time_stamp()) + { + if (isCasCommand(std::get(*result))) + nextPayloadID++; + return *result; + } + else + return CommandTuple::Type(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 2cd2a372..f7c42380 100644 --- a/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.h +++ b/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.h @@ -42,11 +42,25 @@ class CmdMuxStrict : public CmdMuxIF { public: CmdMuxStrict(); - CommandTuple::Type selectCommand(ReadyCommands &); + virtual CommandTuple::Type selectCommand(const ReadyCommands &) override; private: uint64_t nextPayloadID = 1; const MemSpec *memSpec; }; +class CmdMuxStrictRasCas : public CmdMuxIF +{ +public: + CmdMuxStrictRasCas(); + virtual CommandTuple::Type selectCommand(const ReadyCommands &) override; + +private: + uint64_t nextPayloadID = 1; + const MemSpec *memSpec; + ReadyCommands readyRasCommands; + ReadyCommands readyCasCommands; + ReadyCommands readyRasCasCommands; +}; + #endif // CMDMUXSTRICT_H