From 0c51a4e1f82d71851a6c2ddaf5b80c61538c2fd4 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 24 Mar 2021 09:10:12 +0100 Subject: [PATCH] First version of RasCas command mux, not working. --- .../src/configuration/memspec/MemSpec.cpp | 5 + .../src/configuration/memspec/MemSpec.h | 2 + .../src/configuration/memspec/MemSpecHBM2.cpp | 5 + .../src/configuration/memspec/MemSpecHBM2.h | 2 + DRAMSys/library/src/controller/Controller.cpp | 14 ++- .../src/controller/cmdmux/CmdMuxOldest.cpp | 111 +++++++++++++++++ .../src/controller/cmdmux/CmdMuxOldest.h | 13 ++ .../src/controller/cmdmux/CmdMuxStrict.cpp | 114 ++++++++++++++++++ .../src/controller/cmdmux/CmdMuxStrict.h | 13 ++ 9 files changed, 277 insertions(+), 2 deletions(-) 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/CmdMuxOldest.cpp b/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.cpp index f11f597e..9bbc825b 100644 --- a/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.cpp +++ b/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.cpp @@ -76,3 +76,114 @@ CommandTuple::Type CmdMuxOldest::selectCommand(ReadyCommands &readyCommands) else return CommandTuple::Type(Command::NOP, nullptr, sc_max_time()); } + + +CmdMuxOldestRasCas::CmdMuxOldestRasCas() : memSpec(Configuration::getInstance().memSpec) +{ + readyRasCommands.reserve(memSpec->numberOfBanks); + readyCasCommands.reserve(memSpec->numberOfBanks); +} + +CommandTuple::Type CmdMuxOldestRasCas::selectCommand(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 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)) - memSpec->tCK; + newPayloadID = DramExtension::getChannelPayloadID(std::get(*it)); + + if (newTimestamp < lastTimestamp) + { + lastTimestamp = newTimestamp; + lastPayloadID = newPayloadID; + resultRas = it; + } + else if (newTimestamp == lastTimestamp) + { + if (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)) - memSpec->tCK; + newPayloadID = DramExtension::getChannelPayloadID(std::get(*it)); + + if (newTimestamp < lastTimestamp) + { + lastTimestamp = newTimestamp; + lastPayloadID = newPayloadID; + resultCas = it; + } + else if (newTimestamp == lastTimestamp) + { + if (newPayloadID < lastPayloadID) + { + lastPayloadID = newPayloadID; + resultCas = it; + } + } + } + + if (resultRas != readyRasCommands.cend() && resultCas != readyCasCommands.cend()) + { + if (std::get(*resultRas) == sc_time_stamp() + && std::get(*resultCas) == sc_time_stamp()) + { + if (DramExtension::getChannelPayloadID(std::get(*resultRas)) + <= DramExtension::getChannelPayloadID(std::get(*resultCas))) + return *resultRas; + else + return *resultCas; + } + else if (std::get(*resultRas) == sc_time_stamp()) + return *resultRas; + else if (std::get(*resultCas) == sc_time_stamp()) + return *resultCas; + else + return CommandTuple::Type(Command::NOP, nullptr, sc_max_time()); + } + else if (resultRas != readyRasCommands.cend()) + { + if (std::get(*resultRas) == sc_time_stamp()) + return *resultRas; + else + return CommandTuple::Type(Command::NOP, nullptr, sc_max_time()); + } + else if (resultCas != readyCasCommands.cend()) + { + if (std::get(*resultCas) == sc_time_stamp()) + return *resultCas; + else + return CommandTuple::Type(Command::NOP, nullptr, sc_max_time()); + } + else + return CommandTuple::Type(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 ee2c794e..06e07c44 100644 --- a/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.h +++ b/DRAMSys/library/src/controller/cmdmux/CmdMuxOldest.h @@ -48,4 +48,17 @@ private: const MemSpec *memSpec; }; + +class CmdMuxOldestRasCas : public CmdMuxIF +{ +public: + CmdMuxOldestRasCas(); + CommandTuple::Type selectCommand(ReadyCommands &); + +private: + const MemSpec *memSpec; + ReadyCommands readyRasCommands; + ReadyCommands readyCasCommands; +}; + #endif // CMDMUXOLDEST_H diff --git a/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.cpp b/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.cpp index d10f36fa..f895f635 100644 --- a/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.cpp +++ b/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.cpp @@ -103,3 +103,117 @@ 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); +} + +CommandTuple::Type CmdMuxStrictRasCas::selectCommand(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 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)) - memSpec->tCK; + newPayloadID = DramExtension::getChannelPayloadID(std::get(*it)); + + if (newTimestamp < lastTimestamp) + { + lastTimestamp = newTimestamp; + lastPayloadID = newPayloadID; + resultRas = it; + } + else if (newTimestamp == lastTimestamp) + { + if (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)) - memSpec->tCK; + newPayloadID = DramExtension::getChannelPayloadID(std::get(*it)); + + if (newPayloadID == nextPayloadID) + { + if (newTimestamp < lastTimestamp) + { + lastTimestamp = newTimestamp; + lastPayloadID = newPayloadID; + resultCas = it; + } + else if (newTimestamp == lastTimestamp) + { + if (newPayloadID < lastPayloadID) + { + lastPayloadID = newPayloadID; + resultCas = it; + } + } + } + } + + if (resultRas != readyRasCommands.cend() && resultCas != readyCasCommands.cend()) + { + if (std::get(*resultRas) == sc_time_stamp() + && std::get(*resultCas) == sc_time_stamp()) + { + if (DramExtension::getChannelPayloadID(std::get(*resultRas)) + <= DramExtension::getChannelPayloadID(std::get(*resultCas))) + return *resultRas; + else + return *resultCas; + } + else if (std::get(*resultRas) == sc_time_stamp()) + return *resultRas; + else if (std::get(*resultCas) == sc_time_stamp()) + return *resultCas; + else + return CommandTuple::Type(Command::NOP, nullptr, sc_max_time()); + } + else if (resultRas != readyRasCommands.cend()) + { + if (std::get(*resultRas) == sc_time_stamp()) + return *resultRas; + else + return CommandTuple::Type(Command::NOP, nullptr, sc_max_time()); + } + else if (resultCas != readyCasCommands.cend()) + { + if (std::get(*resultCas) == sc_time_stamp()) + return *resultCas; + else + return CommandTuple::Type(Command::NOP, nullptr, sc_max_time()); + } + 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..6ed6afd8 100644 --- a/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.h +++ b/DRAMSys/library/src/controller/cmdmux/CmdMuxStrict.h @@ -49,4 +49,17 @@ private: const MemSpec *memSpec; }; +class CmdMuxStrictRasCas : public CmdMuxIF +{ +public: + CmdMuxStrictRasCas(); + CommandTuple::Type selectCommand(ReadyCommands &); + +private: + uint64_t nextPayloadID = 1; + const MemSpec *memSpec; + ReadyCommands readyRasCommands; + ReadyCommands readyCasCommands; +}; + #endif // CMDMUXSTRICT_H