From 24ef9971801a9dd20a99f4f8b451be2265dc1892 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Tue, 4 May 2021 10:56:45 +0200 Subject: [PATCH 01/13] Link thread library in simulator. --- DRAMSys/simulator/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/DRAMSys/simulator/CMakeLists.txt b/DRAMSys/simulator/CMakeLists.txt index 1b3a9851..2487e3af 100644 --- a/DRAMSys/simulator/CMakeLists.txt +++ b/DRAMSys/simulator/CMakeLists.txt @@ -41,6 +41,8 @@ project(DRAMSysSimulator) set(CMAKE_CXX_STANDARD 11 CACHE STRING "C++ Version") set(DCMAKE_SH="CMAKE_SH-NOTFOUND") +find_package(Threads REQUIRED) + add_executable(DRAMSys main.cpp ExampleInitiator.h @@ -61,4 +63,5 @@ target_include_directories(DRAMSys target_link_libraries(DRAMSys PRIVATE DRAMSysLibrary + PRIVATE Threads::Threads ) From 3c476f4925bd615da127ef1a246d22979258d8d3 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 5 May 2021 15:43:52 +0200 Subject: [PATCH 02/13] Simpler clock sync calculation in arbiter. --- DRAMSys/library/src/simulation/Arbiter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp index 500f098b..753af435 100644 --- a/DRAMSys/library/src/simulation/Arbiter.cpp +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -126,7 +126,8 @@ void ArbiterReorder::end_of_elaboration() tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload &payload, tlm_phase &phase, sc_time &fwDelay) { - sc_time notDelay = std::ceil((sc_time_stamp() + fwDelay) / tCK) * tCK - sc_time_stamp(); + sc_time clockOffset = (sc_time_stamp() + fwDelay) % tCK; + sc_time notDelay = (clockOffset == SC_ZERO_TIME) ? fwDelay : (fwDelay + tCK - clockOffset); if (phase == BEGIN_REQ) { From 9b7e2611ef385ea0941c98473746ad6778349bd3 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 5 May 2021 15:55:06 +0200 Subject: [PATCH 03/13] Fix clock sync in STL player. --- DRAMSys/simulator/StlPlayer.cpp | 10 +++++----- DRAMSys/simulator/TracePlayer.cpp | 3 --- DRAMSys/simulator/TracePlayer.h | 1 - 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/DRAMSys/simulator/StlPlayer.cpp b/DRAMSys/simulator/StlPlayer.cpp index 4880b5b0..8ff71bb0 100644 --- a/DRAMSys/simulator/StlPlayer.cpp +++ b/DRAMSys/simulator/StlPlayer.cpp @@ -101,18 +101,18 @@ void StlPlayer::nextPayload() payload->set_command(lineIterator->cmd); std::copy(lineIterator->data.begin(), lineIterator->data.end(), payload->get_data_ptr()); - sc_time sendingOffset; sc_time sendingTime; + sc_time sendingOffset; - if (lastEndReq == sc_time_stamp()) - sendingOffset = playerClk; - else + if (numberOfTransactions == 1) sendingOffset = SC_ZERO_TIME; + else + sendingOffset = playerClk - (sc_time_stamp() % playerClk); if (!relative) sendingTime = std::max(sc_time_stamp() + sendingOffset, lineIterator->sendingTime); else - sendingTime = sc_time_stamp() + std::max(sendingOffset, lineIterator->sendingTime); + sendingTime = sc_time_stamp() + sendingOffset + lineIterator->sendingTime; sendToTarget(*payload, BEGIN_REQ, sendingTime - sc_time_stamp()); diff --git a/DRAMSys/simulator/TracePlayer.cpp b/DRAMSys/simulator/TracePlayer.cpp index 4c588668..dd45e3e6 100644 --- a/DRAMSys/simulator/TracePlayer.cpp +++ b/DRAMSys/simulator/TracePlayer.cpp @@ -72,10 +72,7 @@ void TracePlayer::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) { if (phase == END_REQ) - { - lastEndReq = sc_time_stamp(); nextPayload(); - } else if (phase == BEGIN_RESP) { payload.release(); diff --git a/DRAMSys/simulator/TracePlayer.h b/DRAMSys/simulator/TracePlayer.h index 7144c95a..7fc4df35 100644 --- a/DRAMSys/simulator/TracePlayer.h +++ b/DRAMSys/simulator/TracePlayer.h @@ -69,7 +69,6 @@ protected: uint64_t numberOfTransactions = 0; uint64_t transactionsSent = 0; bool finished = false; - sc_time lastEndReq = sc_max_time(); private: tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase, From e38d0aae1f08fa4bb4ed05621de15803251c7ebe Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 5 May 2021 17:10:08 +0200 Subject: [PATCH 04/13] Introduce burst length parameter. --- DRAMSys/library/src/common/dramExtensions.cpp | 12 +++++++++++- DRAMSys/library/src/common/dramExtensions.h | 4 +++- DRAMSys/library/src/controller/BankMachine.cpp | 12 ++++++++---- DRAMSys/library/src/controller/Controller.cpp | 3 ++- .../library/src/controller/checker/CheckerDDR3.cpp | 4 ++-- DRAMSys/library/src/controller/checker/CheckerDDR3.h | 5 +++-- .../library/src/controller/checker/CheckerDDR4.cpp | 4 ++-- DRAMSys/library/src/controller/checker/CheckerDDR4.h | 5 +++-- .../library/src/controller/checker/CheckerDDR5.cpp | 4 ++-- DRAMSys/library/src/controller/checker/CheckerDDR5.h | 7 +++++-- .../library/src/controller/checker/CheckerGDDR5.cpp | 4 ++-- .../library/src/controller/checker/CheckerGDDR5.h | 5 +++-- .../library/src/controller/checker/CheckerGDDR5X.cpp | 4 ++-- .../library/src/controller/checker/CheckerGDDR5X.h | 5 +++-- .../library/src/controller/checker/CheckerGDDR6.cpp | 4 ++-- .../library/src/controller/checker/CheckerGDDR6.h | 5 +++-- .../library/src/controller/checker/CheckerHBM2.cpp | 4 ++-- DRAMSys/library/src/controller/checker/CheckerHBM2.h | 5 +++-- DRAMSys/library/src/controller/checker/CheckerIF.h | 5 +++-- .../library/src/controller/checker/CheckerLPDDR4.cpp | 4 ++-- .../library/src/controller/checker/CheckerLPDDR4.h | 5 +++-- .../library/src/controller/checker/CheckerWideIO.cpp | 4 ++-- .../library/src/controller/checker/CheckerWideIO.h | 5 +++-- .../src/controller/checker/CheckerWideIO2.cpp | 4 ++-- .../library/src/controller/checker/CheckerWideIO2.h | 5 +++-- DRAMSys/library/src/simulation/Arbiter.cpp | 4 +++- DRAMSys/library/src/simulation/Arbiter.h | 2 ++ 27 files changed, 84 insertions(+), 50 deletions(-) diff --git a/DRAMSys/library/src/common/dramExtensions.cpp b/DRAMSys/library/src/common/dramExtensions.cpp index 09a49be9..6104bcf4 100644 --- a/DRAMSys/library/src/common/dramExtensions.cpp +++ b/DRAMSys/library/src/common/dramExtensions.cpp @@ -194,6 +194,16 @@ Column DramExtension::getColumn(const tlm_generic_payload &payload) return DramExtension::getColumn(&payload); } +unsigned DramExtension::getBurstLength(const tlm_generic_payload *payload) +{ + return DramExtension::getExtension(payload).getBurstLength(); +} + +unsigned DramExtension::getBurstLength(const tlm_generic_payload &payload) +{ + return DramExtension::getBurstLength(&payload); +} + uint64_t DramExtension::getThreadPayloadID(const tlm_generic_payload *payload) { return DramExtension::getExtension(payload).getThreadPayloadID(); @@ -268,7 +278,7 @@ Column DramExtension::getColumn() const return column; } -unsigned int DramExtension::getBurstlength() const +unsigned int DramExtension::getBurstLength() const { return burstlength; } diff --git a/DRAMSys/library/src/common/dramExtensions.h b/DRAMSys/library/src/common/dramExtensions.h index 989bb079..896a95a8 100644 --- a/DRAMSys/library/src/common/dramExtensions.h +++ b/DRAMSys/library/src/common/dramExtensions.h @@ -205,6 +205,8 @@ public: static Row getRow(const tlm::tlm_generic_payload &payload); static Column getColumn(const tlm::tlm_generic_payload *payload); static Column getColumn(const tlm::tlm_generic_payload &payload); + static unsigned getBurstLength(const tlm::tlm_generic_payload *payload); + static unsigned getBurstLength(const tlm::tlm_generic_payload &payload); static uint64_t getThreadPayloadID(const tlm::tlm_generic_payload *payload); static uint64_t getThreadPayloadID(const tlm::tlm_generic_payload &payload); static uint64_t getChannelPayloadID(const tlm::tlm_generic_payload *payload); @@ -218,7 +220,7 @@ public: Row getRow() const; Column getColumn() const; - unsigned int getBurstlength() const; + unsigned int getBurstLength() const; uint64_t getThreadPayloadID() const; uint64_t getChannelPayloadID() const; void incrementRow(); diff --git a/DRAMSys/library/src/controller/BankMachine.cpp b/DRAMSys/library/src/controller/BankMachine.cpp index 0fab68d9..4fdecbb1 100644 --- a/DRAMSys/library/src/controller/BankMachine.cpp +++ b/DRAMSys/library/src/controller/BankMachine.cpp @@ -148,7 +148,8 @@ sc_time BankMachineOpen::start() else // row miss nextCommand = Command::PRE; } - timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, + bankgroup, bank, DramExtension::getBurstLength(currentPayload)); } } return timeToSchedule; @@ -178,7 +179,8 @@ sc_time BankMachineClosed::start() else SC_REPORT_FATAL("BankMachine", "Wrong TLM command"); } - timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, + bankgroup, bank, DramExtension::getBurstLength(currentPayload)); } } return timeToSchedule; @@ -225,7 +227,8 @@ sc_time BankMachineOpenAdaptive::start() else // row miss nextCommand = Command::PRE; } - timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, + bankgroup, bank, DramExtension::getBurstLength(currentPayload)); } } return timeToSchedule; @@ -272,7 +275,8 @@ sc_time BankMachineClosedAdaptive::start() else // row miss, should never happen SC_REPORT_FATAL("BankMachine", "Should never be reached for this policy"); } - timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, bankgroup, bank); + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank, + bankgroup, bank, DramExtension::getBurstLength(currentPayload)); } } return timeToSchedule; diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index 21355bb1..af67bdae 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -287,6 +287,7 @@ void Controller::controllerMethod() Rank rank = DramExtension::getRank(payload); BankGroup bankgroup = DramExtension::getBankGroup(payload); Bank bank = DramExtension::getBank(payload); + unsigned burstLength = DramExtension::getBurstLength(payload); if (isRankCommand(command)) { @@ -304,7 +305,7 @@ void Controller::controllerMethod() refreshManagers[rank.ID()]->updateState(command); powerDownManagers[rank.ID()]->updateState(command); - checker->insert(command, rank, bankgroup, bank); + checker->insert(command, rank, bankgroup, bank, burstLength); if (isCasCommand(command)) { diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp index 1e48ea04..0d52b904 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp @@ -60,7 +60,7 @@ CheckerDDR3::CheckerDDR3() tWRAPDEN = memSpec->tWL + tBURST + memSpec->tWR + memSpec->tCK; } -sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const +sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank, unsigned) const { sc_time lastCommandStart; sc_time earliestTimeToStart = sc_time_stamp(); @@ -412,7 +412,7 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGr return earliestTimeToStart; } -void CheckerDDR3::insert(Command command, Rank rank, BankGroup, Bank bank) +void CheckerDDR3::insert(Command command, Rank rank, BankGroup, Bank bank, unsigned) { PRINTDEBUGMESSAGE("CheckerDDR3", "Changing state on bank " + std::to_string(bank.ID()) + " command is " + commandToString(command)); diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR3.h b/DRAMSys/library/src/controller/checker/CheckerDDR3.h index efce001a..1eed6b48 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR3.h +++ b/DRAMSys/library/src/controller/checker/CheckerDDR3.h @@ -45,8 +45,9 @@ class CheckerDDR3 final : public CheckerIF { public: CheckerDDR3(); - virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override; - virtual void insert(Command, Rank, BankGroup, Bank) override; + virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0), + BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override; + virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override; private: const MemSpecDDR3 *memSpec; diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp index 1dad1943..25544d7b 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp @@ -63,7 +63,7 @@ CheckerDDR4::CheckerDDR4() tWRAPDEN = memSpec->tWL + tBURST + memSpec->tCK + memSpec->tWR; } -sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const +sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned) const { sc_time lastCommandStart; sc_time earliestTimeToStart = sc_time_stamp(); @@ -443,7 +443,7 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGr return earliestTimeToStart; } -void CheckerDDR4::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank) +void CheckerDDR4::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned) { PRINTDEBUGMESSAGE("CheckerDDR4", "Changing state on bank " + std::to_string(bank.ID()) + " command is " + commandToString(command)); diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR4.h b/DRAMSys/library/src/controller/checker/CheckerDDR4.h index 694eecd4..d2befee3 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR4.h +++ b/DRAMSys/library/src/controller/checker/CheckerDDR4.h @@ -45,8 +45,9 @@ class CheckerDDR4 final : public CheckerIF { public: CheckerDDR4(); - virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override; - virtual void insert(Command, Rank, BankGroup, Bank) override; + virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0), + BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override; + virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override; private: const MemSpecDDR4 *memSpec; diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp index a5458a3d..1de608a8 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp @@ -89,7 +89,7 @@ CheckerDDR5::CheckerDDR5() // TODO: tRTP BL 32 (similar to LPDDR4) } -sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const +sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned burstLength) const { sc_time lastCommandStart; sc_time earliestTimeToStart = sc_time_stamp(); @@ -547,7 +547,7 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr return earliestTimeToStart; } -void CheckerDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank) +void CheckerDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned) { PRINTDEBUGMESSAGE("CheckerDDR5", "Changing state on bank " + std::to_string(bank.ID()) + " command is " + commandToString(command)); diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR5.h b/DRAMSys/library/src/controller/checker/CheckerDDR5.h index caf04154..7bd2f4ad 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR5.h +++ b/DRAMSys/library/src/controller/checker/CheckerDDR5.h @@ -45,8 +45,9 @@ class CheckerDDR5 final : public CheckerIF { public: CheckerDDR5(); - virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override; - virtual void insert(Command, Rank, BankGroup, Bank) override; + virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0), + BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override; + virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override; private: const MemSpecDDR5 *memSpec; @@ -64,6 +65,8 @@ private: std::vector> last4ActivatesPhysical; std::vector> last4ActivatesLogical; + // TODO: store BL of last RD and WR globally or for each hierarchy? + sc_time cmdOffset; sc_time tRD_BURST; diff --git a/DRAMSys/library/src/controller/checker/CheckerGDDR5.cpp b/DRAMSys/library/src/controller/checker/CheckerGDDR5.cpp index fe5fc00d..a32251f1 100644 --- a/DRAMSys/library/src/controller/checker/CheckerGDDR5.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerGDDR5.cpp @@ -64,7 +64,7 @@ CheckerGDDR5::CheckerGDDR5() tWRPRE = memSpec->tWL + tBURST + memSpec->tWR; } -sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const +sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned) const { sc_time lastCommandStart; sc_time earliestTimeToStart = sc_time_stamp(); @@ -525,7 +525,7 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankG return earliestTimeToStart; } -void CheckerGDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank) +void CheckerGDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned) { PRINTDEBUGMESSAGE("CheckerGDDR5", "Changing state on bank " + std::to_string(bank.ID()) + " command is " + commandToString(command)); diff --git a/DRAMSys/library/src/controller/checker/CheckerGDDR5.h b/DRAMSys/library/src/controller/checker/CheckerGDDR5.h index 326dae75..30ab9287 100644 --- a/DRAMSys/library/src/controller/checker/CheckerGDDR5.h +++ b/DRAMSys/library/src/controller/checker/CheckerGDDR5.h @@ -45,8 +45,9 @@ class CheckerGDDR5 final : public CheckerIF { public: CheckerGDDR5(); - virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override; - virtual void insert(Command, Rank, BankGroup, Bank) override; + virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0), + BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override; + virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override; private: const MemSpecGDDR5 *memSpec; diff --git a/DRAMSys/library/src/controller/checker/CheckerGDDR5X.cpp b/DRAMSys/library/src/controller/checker/CheckerGDDR5X.cpp index bb5679a9..487184a0 100644 --- a/DRAMSys/library/src/controller/checker/CheckerGDDR5X.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerGDDR5X.cpp @@ -64,7 +64,7 @@ CheckerGDDR5X::CheckerGDDR5X() tWRPRE = memSpec->tWL + tBURST + memSpec->tWR; } -sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const +sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned) const { sc_time lastCommandStart; sc_time earliestTimeToStart = sc_time_stamp(); @@ -525,7 +525,7 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, Rank rank, Bank return earliestTimeToStart; } -void CheckerGDDR5X::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank) +void CheckerGDDR5X::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned) { PRINTDEBUGMESSAGE("CheckerGDDR5X", "Changing state on bank " + std::to_string(bank.ID()) + " command is " + commandToString(command)); diff --git a/DRAMSys/library/src/controller/checker/CheckerGDDR5X.h b/DRAMSys/library/src/controller/checker/CheckerGDDR5X.h index 39138be3..652de82b 100644 --- a/DRAMSys/library/src/controller/checker/CheckerGDDR5X.h +++ b/DRAMSys/library/src/controller/checker/CheckerGDDR5X.h @@ -45,8 +45,9 @@ class CheckerGDDR5X final : public CheckerIF { public: CheckerGDDR5X(); - virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override; - virtual void insert(Command, Rank, BankGroup, Bank) override; + virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0), + BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override; + virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override; private: const MemSpecGDDR5X *memSpec; diff --git a/DRAMSys/library/src/controller/checker/CheckerGDDR6.cpp b/DRAMSys/library/src/controller/checker/CheckerGDDR6.cpp index f0f6fa54..f50504e6 100644 --- a/DRAMSys/library/src/controller/checker/CheckerGDDR6.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerGDDR6.cpp @@ -63,7 +63,7 @@ CheckerGDDR6::CheckerGDDR6() tWRPRE = memSpec->tWL + tBURST + memSpec->tWR; } -sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const +sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned) const { sc_time lastCommandStart; sc_time earliestTimeToStart = sc_time_stamp(); @@ -546,7 +546,7 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, Rank rank, BankG return earliestTimeToStart; } -void CheckerGDDR6::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank) +void CheckerGDDR6::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned) { PRINTDEBUGMESSAGE("CheckerGDDR6", "Changing state on bank " + std::to_string(bank.ID()) + " command is " + commandToString(command)); diff --git a/DRAMSys/library/src/controller/checker/CheckerGDDR6.h b/DRAMSys/library/src/controller/checker/CheckerGDDR6.h index 202bd8d3..edd78a7c 100644 --- a/DRAMSys/library/src/controller/checker/CheckerGDDR6.h +++ b/DRAMSys/library/src/controller/checker/CheckerGDDR6.h @@ -45,8 +45,9 @@ class CheckerGDDR6 final : public CheckerIF { public: CheckerGDDR6(); - virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override; - virtual void insert(Command, Rank, BankGroup, Bank) override; + virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0), + BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override; + virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override; private: const MemSpecGDDR6 *memSpec; diff --git a/DRAMSys/library/src/controller/checker/CheckerHBM2.cpp b/DRAMSys/library/src/controller/checker/CheckerHBM2.cpp index 4ed20f3f..7472d0ad 100644 --- a/DRAMSys/library/src/controller/checker/CheckerHBM2.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerHBM2.cpp @@ -64,7 +64,7 @@ CheckerHBM2::CheckerHBM2() tWRRDL = memSpec->tWL + tBURST + memSpec->tWTRL; } -sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const +sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned) const { sc_time lastCommandStart; sc_time earliestTimeToStart = sc_time_stamp(); @@ -500,7 +500,7 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, Rank rank, BankGr return earliestTimeToStart; } -void CheckerHBM2::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank) +void CheckerHBM2::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned) { PRINTDEBUGMESSAGE("CheckerHBM2", "Changing state on bank " + std::to_string(bank.ID()) + " command is " + commandToString(command)); diff --git a/DRAMSys/library/src/controller/checker/CheckerHBM2.h b/DRAMSys/library/src/controller/checker/CheckerHBM2.h index 3578ee9b..a68a5f86 100644 --- a/DRAMSys/library/src/controller/checker/CheckerHBM2.h +++ b/DRAMSys/library/src/controller/checker/CheckerHBM2.h @@ -45,8 +45,9 @@ class CheckerHBM2 final : public CheckerIF { public: CheckerHBM2(); - virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override; - virtual void insert(Command, Rank, BankGroup, Bank) override; + virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0), + BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override; + virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override; private: const MemSpecHBM2 *memSpec; diff --git a/DRAMSys/library/src/controller/checker/CheckerIF.h b/DRAMSys/library/src/controller/checker/CheckerIF.h index b5c4d9bb..a930d797 100644 --- a/DRAMSys/library/src/controller/checker/CheckerIF.h +++ b/DRAMSys/library/src/controller/checker/CheckerIF.h @@ -46,8 +46,9 @@ class CheckerIF public: virtual ~CheckerIF() {} - virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const = 0; - virtual void insert(Command, Rank, BankGroup, Bank) = 0; + virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0), + BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const = 0; + virtual void insert(Command, Rank, BankGroup, Bank, unsigned) = 0; }; #endif // CHECKERIF_H diff --git a/DRAMSys/library/src/controller/checker/CheckerLPDDR4.cpp b/DRAMSys/library/src/controller/checker/CheckerLPDDR4.cpp index 366f9b1f..2dfc9456 100644 --- a/DRAMSys/library/src/controller/checker/CheckerLPDDR4.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerLPDDR4.cpp @@ -66,7 +66,7 @@ CheckerLPDDR4::CheckerLPDDR4() tREFPDEN = memSpec->tCK + memSpec->tCMDCKE; } -sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const +sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank, unsigned) const { sc_time lastCommandStart; sc_time earliestTimeToStart = sc_time_stamp(); @@ -496,7 +496,7 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, Bank return earliestTimeToStart; } -void CheckerLPDDR4::insert(Command command, Rank rank, BankGroup, Bank bank) +void CheckerLPDDR4::insert(Command command, Rank rank, BankGroup, Bank bank, unsigned) { PRINTDEBUGMESSAGE("CheckerLPDDR4", "Changing state on bank " + std::to_string(bank.ID()) + " command is " + commandToString(command)); diff --git a/DRAMSys/library/src/controller/checker/CheckerLPDDR4.h b/DRAMSys/library/src/controller/checker/CheckerLPDDR4.h index 5a73154a..3fe5e506 100644 --- a/DRAMSys/library/src/controller/checker/CheckerLPDDR4.h +++ b/DRAMSys/library/src/controller/checker/CheckerLPDDR4.h @@ -45,8 +45,9 @@ class CheckerLPDDR4 final : public CheckerIF { public: CheckerLPDDR4(); - virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override; - virtual void insert(Command, Rank, BankGroup, Bank) override; + virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0), + BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override; + virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override; private: const MemSpecLPDDR4 *memSpec; diff --git a/DRAMSys/library/src/controller/checker/CheckerWideIO.cpp b/DRAMSys/library/src/controller/checker/CheckerWideIO.cpp index 6f588494..16985f5d 100644 --- a/DRAMSys/library/src/controller/checker/CheckerWideIO.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerWideIO.cpp @@ -60,7 +60,7 @@ CheckerWideIO::CheckerWideIO() tWRAPDEN = memSpec->tWL + tBURST + memSpec->tWR; // + memSpec->tCK; ?? } -sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const +sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank, unsigned) const { sc_time lastCommandStart; sc_time earliestTimeToStart = sc_time_stamp(); @@ -385,7 +385,7 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, Rank rank, Bank return earliestTimeToStart; } -void CheckerWideIO::insert(Command command, Rank rank, BankGroup, Bank bank) +void CheckerWideIO::insert(Command command, Rank rank, BankGroup, Bank bank, unsigned) { PRINTDEBUGMESSAGE("CheckerWideIO", "Changing state on bank " + std::to_string(bank.ID()) + " command is " + commandToString(command)); diff --git a/DRAMSys/library/src/controller/checker/CheckerWideIO.h b/DRAMSys/library/src/controller/checker/CheckerWideIO.h index e5cdb430..c8b145a6 100644 --- a/DRAMSys/library/src/controller/checker/CheckerWideIO.h +++ b/DRAMSys/library/src/controller/checker/CheckerWideIO.h @@ -45,8 +45,9 @@ class CheckerWideIO final : public CheckerIF { public: CheckerWideIO(); - virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override; - virtual void insert(Command, Rank, BankGroup, Bank) override; + virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0), + BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override; + virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override; private: const MemSpecWideIO *memSpec; diff --git a/DRAMSys/library/src/controller/checker/CheckerWideIO2.cpp b/DRAMSys/library/src/controller/checker/CheckerWideIO2.cpp index 14818bed..10e75682 100644 --- a/DRAMSys/library/src/controller/checker/CheckerWideIO2.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerWideIO2.cpp @@ -61,7 +61,7 @@ CheckerWideIO2::CheckerWideIO2() tWRRD_R = memSpec->tWL + memSpec->tCK + tBURST + memSpec->tRTRS - memSpec->tRL; } -sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const +sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank, unsigned) const { sc_time lastCommandStart; sc_time earliestTimeToStart = sc_time_stamp(); @@ -463,7 +463,7 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, Rank rank, Ban return earliestTimeToStart; } -void CheckerWideIO2::insert(Command command, Rank rank, BankGroup, Bank bank) +void CheckerWideIO2::insert(Command command, Rank rank, BankGroup, Bank bank, unsigned) { PRINTDEBUGMESSAGE("CheckerWideIO2", "Changing state on bank " + std::to_string(bank.ID()) + " command is " + commandToString(command)); diff --git a/DRAMSys/library/src/controller/checker/CheckerWideIO2.h b/DRAMSys/library/src/controller/checker/CheckerWideIO2.h index 08d328b9..a1e32636 100644 --- a/DRAMSys/library/src/controller/checker/CheckerWideIO2.h +++ b/DRAMSys/library/src/controller/checker/CheckerWideIO2.h @@ -45,8 +45,9 @@ class CheckerWideIO2 final : public CheckerIF { public: CheckerWideIO2(); - virtual sc_time timeToSatisfyConstraints(Command, Rank, BankGroup, Bank) const override; - virtual void insert(Command, Rank, BankGroup, Bank) override; + virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0), + BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override; + virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override; private: const MemSpecWideIO2 *memSpec; diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp index 500f098b..bd8f0baa 100644 --- a/DRAMSys/library/src/simulation/Arbiter.cpp +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -54,6 +54,8 @@ Arbiter::Arbiter(sc_module_name name, std::string pathToAddressMapping) : addressDecoder = new AddressDecoder(pathToAddressMapping); addressDecoder->print(); + + burstLengthShift = std::log2(Configuration::getInstance().memSpec->dataBusWidth / 8); } ArbiterSimple::ArbiterSimple(sc_module_name name, std::string pathToAddressMapping) : @@ -140,7 +142,7 @@ tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload &payload, Channel(decodedAddress.channel), Rank(decodedAddress.rank), BankGroup(decodedAddress.bankgroup), Bank(decodedAddress.bank), Row(decodedAddress.row), Column(decodedAddress.column), - payload.get_streaming_width(), 0, 0); + payload.get_data_length() >> burstLengthShift, 0, 0); payload.acquire(); } diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index d124c466..ebd2d3bf 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -87,6 +87,8 @@ protected: sc_time tCK; sc_time arbitrationDelayFw; sc_time arbitrationDelayBw; + + unsigned burstLengthShift; }; class ArbiterSimple final : public Arbiter From fabc686e8c0a6dc241ae9a22158a5fcabbfdebf8 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Mon, 10 May 2021 14:32:05 +0200 Subject: [PATCH 05/13] Initial version of BL32 OTF. --- .../memspecs/JEDEC_2x4x1Gbx8_DDR5-3200A.json | 5 +- .../memspecs/JEDEC_2x4x1Gbx8_DDR5-3600A.json | 5 +- .../memspecs/JEDEC_2x4x1Gbx8_DDR5-4000A.json | 5 +- .../memspecs/JEDEC_2x4x1Gbx8_DDR5-4400A.json | 5 +- .../memspecs/JEDEC_2x4x1Gbx8_DDR5-4800A.json | 5 +- .../memspecs/JEDEC_2x4x1Gbx8_DDR5-5200A.json | 5 +- .../memspecs/JEDEC_2x4x1Gbx8_DDR5-5600A.json | 5 +- .../memspecs/JEDEC_2x4x1Gbx8_DDR5-6000A.json | 5 +- .../memspecs/JEDEC_2x4x1Gbx8_DDR5-6400A.json | 5 +- .../memspecs/JEDEC_2x8x2Gbx4_DDR5-3200A.json | 3 +- .../memspecs/JEDEC_2x8x2Gbx4_DDR5-3600A.json | 3 +- .../memspecs/JEDEC_2x8x2Gbx4_DDR5-4000A.json | 3 +- .../memspecs/JEDEC_2x8x2Gbx4_DDR5-4400A.json | 3 +- .../memspecs/JEDEC_2x8x2Gbx4_DDR5-4800A.json | 3 +- .../memspecs/JEDEC_2x8x2Gbx4_DDR5-5200A.json | 3 +- .../memspecs/JEDEC_2x8x2Gbx4_DDR5-5600A.json | 3 +- .../memspecs/JEDEC_2x8x2Gbx4_DDR5-6000A.json | 3 +- .../memspecs/JEDEC_2x8x2Gbx4_DDR5-6400A.json | 3 +- .../JEDEC_2x8x8x2Gbx4_DDR5-3200A.json | 1 + DRAMSys/library/src/common/TlmRecorder.cpp | 4 +- DRAMSys/library/src/common/TlmRecorder.h | 2 +- DRAMSys/library/src/common/dramExtensions.cpp | 22 +- DRAMSys/library/src/common/dramExtensions.h | 8 +- .../src/configuration/memspec/MemSpec.h | 4 +- .../src/configuration/memspec/MemSpecDDR3.cpp | 2 +- .../src/configuration/memspec/MemSpecDDR3.h | 4 +- .../src/configuration/memspec/MemSpecDDR4.cpp | 2 +- .../src/configuration/memspec/MemSpecDDR4.h | 4 +- .../src/configuration/memspec/MemSpecDDR5.cpp | 152 +++--- .../src/configuration/memspec/MemSpecDDR5.h | 12 +- .../configuration/memspec/MemSpecGDDR5.cpp | 2 +- .../src/configuration/memspec/MemSpecGDDR5.h | 4 +- .../configuration/memspec/MemSpecGDDR5X.cpp | 2 +- .../src/configuration/memspec/MemSpecGDDR5X.h | 4 +- .../configuration/memspec/MemSpecGDDR6.cpp | 2 +- .../src/configuration/memspec/MemSpecGDDR6.h | 4 +- .../src/configuration/memspec/MemSpecHBM2.cpp | 2 +- .../src/configuration/memspec/MemSpecHBM2.h | 4 +- .../configuration/memspec/MemSpecLPDDR4.cpp | 2 +- .../src/configuration/memspec/MemSpecLPDDR4.h | 4 +- .../configuration/memspec/MemSpecWideIO.cpp | 2 +- .../src/configuration/memspec/MemSpecWideIO.h | 4 +- .../configuration/memspec/MemSpecWideIO2.cpp | 2 +- .../configuration/memspec/MemSpecWideIO2.h | 4 +- DRAMSys/library/src/controller/Controller.cpp | 2 +- .../src/controller/ControllerRecordable.cpp | 2 +- .../src/controller/checker/CheckerDDR5.cpp | 458 +++++++++++++++--- .../src/controller/checker/CheckerDDR5.h | 9 + 48 files changed, 580 insertions(+), 222 deletions(-) diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3200A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3200A.json index 8bc5a428..75172a46 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3200A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3200A.json @@ -34,7 +34,8 @@ "WPST": 0, "WR": 48, "CCD_L_slr": 8, - "CCD_L_WR_slr": 16, + "CCD_L_WR_slr": 32, + "CCD_L_WR2_slr": 16, "CCD_S_slr": 8, "CCD_S_WR_slr": 8, "CCD_dlr": 0, @@ -70,4 +71,4 @@ "clkMhz": 1600 } } -} \ No newline at end of file +} diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3600A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3600A.json index 639c16a9..e35d934f 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3600A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-3600A.json @@ -34,7 +34,8 @@ "WPST": 0, "WR": 54, "CCD_L_slr": 9, - "CCD_L_WR_slr": 18, + "CCD_L_WR_slr": 36, + "CCD_L_WR2_slr": 18, "CCD_S_slr": 8, "CCD_S_WR_slr": 8, "CCD_dlr": 0, @@ -70,4 +71,4 @@ "clkMhz": 1800 } } -} \ No newline at end of file +} diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4000A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4000A.json index 98d6a123..484ba99f 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4000A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4000A.json @@ -34,7 +34,8 @@ "WPST": 0, "WR": 60, "CCD_L_slr": 10, - "CCD_L_WR_slr": 20, + "CCD_L_WR_slr": 40, + "CCD_L_WR2_slr": 20, "CCD_S_slr": 8, "CCD_S_WR_slr": 8, "CCD_dlr": 0, @@ -70,4 +71,4 @@ "clkMhz": 2000 } } -} \ No newline at end of file +} diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4400A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4400A.json index e27d625d..43b961e5 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4400A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4400A.json @@ -34,7 +34,8 @@ "WPST": 0, "WR": 66, "CCD_L_slr": 11, - "CCD_L_WR_slr": 22, + "CCD_L_WR_slr": 44, + "CCD_L_WR2_slr": 22, "CCD_S_slr": 8, "CCD_S_WR_slr": 8, "CCD_dlr": 0, @@ -70,4 +71,4 @@ "clkMhz": 2200 } } -} \ No newline at end of file +} diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4800A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4800A.json index 5fef3321..eb4a3b8c 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4800A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-4800A.json @@ -34,7 +34,8 @@ "WPST": 0, "WR": 72, "CCD_L_slr": 12, - "CCD_L_WR_slr": 24, + "CCD_L_WR_slr": 48, + "CCD_L_WR2_slr": 24, "CCD_S_slr": 8, "CCD_S_WR_slr": 8, "CCD_dlr": 0, @@ -70,4 +71,4 @@ "clkMhz": 2400 } } -} \ No newline at end of file +} diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5200A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5200A.json index 358643b8..030f4e43 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5200A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5200A.json @@ -34,7 +34,8 @@ "WPST": 0, "WR": 78, "CCD_L_slr": 13, - "CCD_L_WR_slr": 26, + "CCD_L_WR_slr": 52, + "CCD_L_WR2_slr": 26, "CCD_S_slr": 8, "CCD_S_WR_slr": 8, "CCD_dlr": 0, @@ -70,4 +71,4 @@ "clkMhz": 2600 } } -} \ No newline at end of file +} diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5600A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5600A.json index 766c837c..8de5c0f9 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5600A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-5600A.json @@ -34,7 +34,8 @@ "WPST": 0, "WR": 84, "CCD_L_slr": 14, - "CCD_L_WR_slr": 28, + "CCD_L_WR_slr": 56, + "CCD_L_WR2_slr": 28, "CCD_S_slr": 8, "CCD_S_WR_slr": 8, "CCD_dlr": 0, @@ -70,4 +71,4 @@ "clkMhz": 2800 } } -} \ No newline at end of file +} diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6000A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6000A.json index 9e387dc4..0bf780ec 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6000A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6000A.json @@ -34,7 +34,8 @@ "WPST": 0, "WR": 90, "CCD_L_slr": 15, - "CCD_L_WR_slr": 30, + "CCD_L_WR_slr": 60, + "CCD_L_WR2_slr": 30, "CCD_S_slr": 8, "CCD_S_WR_slr": 8, "CCD_dlr": 0, @@ -70,4 +71,4 @@ "clkMhz": 3000 } } -} \ No newline at end of file +} diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6400A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6400A.json index 18caa618..70d03828 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6400A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x4x1Gbx8_DDR5-6400A.json @@ -34,7 +34,8 @@ "WPST": 0, "WR": 96, "CCD_L_slr": 16, - "CCD_L_WR_slr": 32, + "CCD_L_WR_slr": 64, + "CCD_L_WR2_slr": 32, "CCD_S_slr": 8, "CCD_S_WR_slr": 8, "CCD_dlr": 0, @@ -70,4 +71,4 @@ "clkMhz": 3200 } } -} \ No newline at end of file +} diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3200A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3200A.json index aa6e82b0..635cc6cf 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3200A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3200A.json @@ -35,6 +35,7 @@ "WR": 48, "CCD_L_slr": 8, "CCD_L_WR_slr": 32, + "CCD_L_WR2_slr": 16, "CCD_S_slr": 8, "CCD_S_WR_slr": 8, "CCD_dlr": 0, @@ -70,4 +71,4 @@ "clkMhz": 1600 } } -} \ No newline at end of file +} diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3600A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3600A.json index 96359874..ac39be46 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3600A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-3600A.json @@ -35,6 +35,7 @@ "WR": 54, "CCD_L_slr": 9, "CCD_L_WR_slr": 36, + "CCD_L_WR2_slr": 18, "CCD_S_slr": 8, "CCD_S_WR_slr": 8, "CCD_dlr": 0, @@ -70,4 +71,4 @@ "clkMhz": 1800 } } -} \ No newline at end of file +} diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4000A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4000A.json index bf632566..9887512d 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4000A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4000A.json @@ -35,6 +35,7 @@ "WR": 60, "CCD_L_slr": 10, "CCD_L_WR_slr": 40, + "CCD_L_WR2_slr": 20, "CCD_S_slr": 8, "CCD_S_WR_slr": 8, "CCD_dlr": 0, @@ -70,4 +71,4 @@ "clkMhz": 2000 } } -} \ No newline at end of file +} diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4400A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4400A.json index a343598b..cd9bdced 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4400A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4400A.json @@ -35,6 +35,7 @@ "WR": 66, "CCD_L_slr": 11, "CCD_L_WR_slr": 44, + "CCD_L_WR2_slr": 22, "CCD_S_slr": 8, "CCD_S_WR_slr": 8, "CCD_dlr": 0, @@ -70,4 +71,4 @@ "clkMhz": 2200 } } -} \ No newline at end of file +} diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4800A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4800A.json index 46998d40..6215400d 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4800A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-4800A.json @@ -35,6 +35,7 @@ "WR": 72, "CCD_L_slr": 12, "CCD_L_WR_slr": 48, + "CCD_L_WR2_slr": 24, "CCD_S_slr": 8, "CCD_S_WR_slr": 8, "CCD_dlr": 0, @@ -70,4 +71,4 @@ "clkMhz": 2400 } } -} \ No newline at end of file +} diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-5200A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-5200A.json index 18e6c093..48d99a38 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-5200A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-5200A.json @@ -35,6 +35,7 @@ "WR": 78, "CCD_L_slr": 13, "CCD_L_WR_slr": 52, + "CCD_L_WR2_slr": 26, "CCD_S_slr": 8, "CCD_S_WR_slr": 8, "CCD_dlr": 0, @@ -70,4 +71,4 @@ "clkMhz": 2600 } } -} \ No newline at end of file +} diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-5600A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-5600A.json index 4891bb1b..0a46d8ed 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-5600A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-5600A.json @@ -35,6 +35,7 @@ "WR": 84, "CCD_L_slr": 14, "CCD_L_WR_slr": 56, + "CCD_L_WR2_slr": 28, "CCD_S_slr": 8, "CCD_S_WR_slr": 8, "CCD_dlr": 0, @@ -70,4 +71,4 @@ "clkMhz": 2800 } } -} \ No newline at end of file +} diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-6000A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-6000A.json index 3e26408e..ba5c81eb 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-6000A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-6000A.json @@ -35,6 +35,7 @@ "WR": 90, "CCD_L_slr": 15, "CCD_L_WR_slr": 60, + "CCD_L_WR2_slr": 30, "CCD_S_slr": 8, "CCD_S_WR_slr": 8, "CCD_dlr": 0, @@ -70,4 +71,4 @@ "clkMhz": 3000 } } -} \ No newline at end of file +} diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-6400A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-6400A.json index ca9eac9b..ea3ec632 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-6400A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x2Gbx4_DDR5-6400A.json @@ -35,6 +35,7 @@ "WR": 96, "CCD_L_slr": 16, "CCD_L_WR_slr": 64, + "CCD_L_WR2_slr": 32, "CCD_S_slr": 8, "CCD_S_WR_slr": 8, "CCD_dlr": 0, @@ -70,4 +71,4 @@ "clkMhz": 3200 } } -} \ No newline at end of file +} diff --git a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x8x2Gbx4_DDR5-3200A.json b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x8x2Gbx4_DDR5-3200A.json index 315fb976..fbbe90fe 100644 --- a/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x8x2Gbx4_DDR5-3200A.json +++ b/DRAMSys/library/resources/configs/memspecs/JEDEC_2x8x8x2Gbx4_DDR5-3200A.json @@ -35,6 +35,7 @@ "WR": 48, "CCD_L_slr": 8, "CCD_L_WR_slr": 32, + "CCD_L_WR2_slr": 16, "CCD_S_slr": 8, "CCD_S_WR_slr": 8, "CCD_dlr": 8, diff --git a/DRAMSys/library/src/common/TlmRecorder.cpp b/DRAMSys/library/src/common/TlmRecorder.cpp index 17b20a34..ca347381 100644 --- a/DRAMSys/library/src/common/TlmRecorder.cpp +++ b/DRAMSys/library/src/common/TlmRecorder.cpp @@ -162,7 +162,7 @@ void TlmRecorder::introduceTransactionSystem(tlm_generic_payload &trans) currentTransactionsInSystem[&trans].cmd = trans.get_command() == tlm::TLM_READ_COMMAND ? "R" : "W"; currentTransactionsInSystem[&trans].address = trans.get_address(); - currentTransactionsInSystem[&trans].burstlength = trans.get_streaming_width(); + currentTransactionsInSystem[&trans].burstLength = DramExtension::getBurstLength(trans); currentTransactionsInSystem[&trans].dramExtension = DramExtension::getExtension(trans); currentTransactionsInSystem[&trans].timeOfGeneration = GenerationExtension::getTimeOfGeneration(trans); @@ -406,7 +406,7 @@ void TlmRecorder::insertTransactionInDB(Transaction &recordingData) sqlite3_bind_int(insertTransactionStatement, 1, static_cast(recordingData.id)); sqlite3_bind_int(insertTransactionStatement, 2, static_cast(recordingData.id)); sqlite3_bind_int64(insertTransactionStatement, 3, static_cast(recordingData.address)); - sqlite3_bind_int(insertTransactionStatement, 4, static_cast(recordingData.burstlength)); + sqlite3_bind_int(insertTransactionStatement, 4, static_cast(recordingData.burstLength)); sqlite3_bind_int(insertTransactionStatement, 5, static_cast(recordingData.dramExtension.getThread().ID())); sqlite3_bind_int(insertTransactionStatement, 6, diff --git a/DRAMSys/library/src/common/TlmRecorder.h b/DRAMSys/library/src/common/TlmRecorder.h index d3974f1b..fd422987 100644 --- a/DRAMSys/library/src/common/TlmRecorder.h +++ b/DRAMSys/library/src/common/TlmRecorder.h @@ -92,7 +92,7 @@ private: uint64_t id; uint64_t address; - unsigned int burstlength; + unsigned int burstLength; std::string cmd; DramExtension dramExtension; sc_time timeOfGeneration; diff --git a/DRAMSys/library/src/common/dramExtensions.cpp b/DRAMSys/library/src/common/dramExtensions.cpp index 6104bcf4..44910e22 100644 --- a/DRAMSys/library/src/common/dramExtensions.cpp +++ b/DRAMSys/library/src/common/dramExtensions.cpp @@ -44,21 +44,21 @@ using namespace tlm; DramExtension::DramExtension() : thread(0), channel(0), rank(0), bankgroup(0), bank(0), - row(0), column(0), burstlength(0), + row(0), column(0), burstLength(0), threadPayloadID(0), channelPayloadID(0) {} DramExtension::DramExtension(Thread thread, Channel channel, Rank rank, BankGroup bankgroup, Bank bank, Row row, - Column column, unsigned int burstlength, + Column column, unsigned int burstLength, uint64_t threadPayloadID, uint64_t channelPayloadID) : thread(thread), channel(channel), rank(rank), bankgroup(bankgroup), bank(bank), - row(row), column(column), burstlength(burstlength), + row(row), column(column), burstLength(burstLength), threadPayloadID(threadPayloadID), channelPayloadID(channelPayloadID) {} void DramExtension::setExtension(tlm::tlm_generic_payload *payload, Thread thread, Channel channel, Rank rank, BankGroup bankgroup, Bank bank, Row row, - Column column, unsigned int burstlength, + Column column, unsigned int burstLength, uint64_t threadPayloadID, uint64_t channelPayloadID) { DramExtension *extension = nullptr; @@ -73,14 +73,14 @@ void DramExtension::setExtension(tlm::tlm_generic_payload *payload, extension->bank = bank; extension->row = row; extension->column = column; - extension->burstlength = burstlength; + extension->burstLength = burstLength; extension->threadPayloadID = threadPayloadID; extension->channelPayloadID = channelPayloadID; } else { extension = new DramExtension(thread, channel, rank, bankgroup, - bank, row, column, burstlength, + bank, row, column, burstLength, threadPayloadID, channelPayloadID); payload->set_auto_extension(extension); } @@ -89,11 +89,11 @@ void DramExtension::setExtension(tlm::tlm_generic_payload *payload, void DramExtension::setExtension(tlm::tlm_generic_payload &payload, Thread thread, Channel channel, Rank rank, BankGroup bankgroup, Bank bank, Row row, - Column column, unsigned int burstlength, + Column column, unsigned int burstLength, uint64_t threadPayloadID, uint64_t channelPayloadID) { setExtension(&payload, thread, channel, rank, bankgroup, - bank, row, column, burstlength, + bank, row, column, burstLength, threadPayloadID, channelPayloadID); } @@ -227,7 +227,7 @@ uint64_t DramExtension::getChannelPayloadID(const tlm_generic_payload &payload) tlm_extension_base *DramExtension::clone() const { return new DramExtension(thread, channel, rank, bankgroup, bank, row, column, - burstlength, threadPayloadID, channelPayloadID); + burstLength, threadPayloadID, channelPayloadID); } void DramExtension::copy_from(const tlm_extension_base &ext) @@ -240,7 +240,7 @@ void DramExtension::copy_from(const tlm_extension_base &ext) bank = cpyFrom.bank; row = cpyFrom.row; column = cpyFrom.column; - burstlength = cpyFrom.burstlength; + burstLength = cpyFrom.burstLength; } Thread DramExtension::getThread() const @@ -280,7 +280,7 @@ Column DramExtension::getColumn() const unsigned int DramExtension::getBurstLength() const { - return burstlength; + return burstLength; } uint64_t DramExtension::getThreadPayloadID() const diff --git a/DRAMSys/library/src/common/dramExtensions.h b/DRAMSys/library/src/common/dramExtensions.h index 896a95a8..462a61a8 100644 --- a/DRAMSys/library/src/common/dramExtensions.h +++ b/DRAMSys/library/src/common/dramExtensions.h @@ -165,7 +165,7 @@ public: DramExtension(); DramExtension(Thread thread, Channel channel, Rank rank, BankGroup bankgroup, Bank bank, Row row, - Column column, unsigned int burstlength, + Column column, unsigned int burstLength, uint64_t threadPayloadID, uint64_t channelPayloadID); virtual tlm::tlm_extension_base *clone() const; @@ -174,12 +174,12 @@ public: static void setExtension(tlm::tlm_generic_payload *payload, Thread thread, Channel channel, Rank rank, BankGroup bankgroup, Bank bank, Row row, - Column column, unsigned int burstlength, + Column column, unsigned int burstLength, uint64_t threadPayloadID, uint64_t channelPayloadID); static void setExtension(tlm::tlm_generic_payload &payload, Thread thread, Channel channel, Rank rank, BankGroup bankgroup, Bank bank, Row row, - Column column, unsigned int burstlength, + Column column, unsigned int burstLength, uint64_t threadPayloadID, uint64_t channelPayloadID); static DramExtension &getExtension(const tlm::tlm_generic_payload *payload); @@ -233,7 +233,7 @@ private: Bank bank; Row row; Column column; - unsigned int burstlength; + unsigned int burstLength; uint64_t threadPayloadID; uint64_t channelPayloadID; }; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.h b/DRAMSys/library/src/configuration/memspec/MemSpec.h index 4020a8ed..82c1987d 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.h @@ -79,8 +79,8 @@ public: virtual bool hasRasAndCasBus() const; - virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const = 0; - virtual TimeInterval getIntervalOnDataStrobe(Command) const = 0; + virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const = 0; + virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const = 0; sc_time getCommandLength(Command) const; virtual uint64_t getSimMemSizeInBytes() const = 0; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp index 2da79c88..5c566b46 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp @@ -120,7 +120,7 @@ sc_time MemSpecDDR3::getExecutionTime(Command command, const tlm_generic_payload } } -TimeInterval MemSpecDDR3::getIntervalOnDataStrobe(Command command) const +TimeInterval MemSpecDDR3::getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &) const { if (command == Command::RD || command == Command::RDA) return TimeInterval(tRL, tRL + burstDuration); diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h index 6c9174de..370273b0 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h @@ -89,8 +89,8 @@ public: virtual sc_time getRefreshIntervalAB() const override; - virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; - virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override; + virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override; virtual uint64_t getSimMemSizeInBytes() const override; }; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp index cd6daac4..2b6e3bfb 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp @@ -139,7 +139,7 @@ sc_time MemSpecDDR4::getExecutionTime(Command command, const tlm_generic_payload } } -TimeInterval MemSpecDDR4::getIntervalOnDataStrobe(Command command) const +TimeInterval MemSpecDDR4::getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &) const { if (command == Command::RD || command == Command::RDA) return TimeInterval(tRL, tRL + burstDuration); diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h index c63fb36f..e3a5ed9b 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h @@ -97,8 +97,8 @@ public: virtual sc_time getRefreshIntervalAB() const override; - virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; - virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override; + virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override; virtual uint64_t getSimMemSizeInBytes() const override; }; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp index 5d0353c8..fdd3f094 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp @@ -59,56 +59,59 @@ MemSpecDDR5::MemSpecDDR5(json &memspec) numberOfLogicalRanks(logicalRanksPerPhysicalRank * numberOfPhysicalRanks), cmdMode(parseUint(memspec["memarchitecturespec"]["cmdMode"], "cmdMode")), refMode(parseUint(memspec["memarchitecturespec"]["refMode"], "refMode")), - tRCD (tCK * parseUint(memspec["memtimingspec"]["RCD"], "RCD")), - tPPD (tCK * parseUint(memspec["memtimingspec"]["PPD"], "PPD")), - tRP (tCK * parseUint(memspec["memtimingspec"]["RP"], "RP")), - tRAS (tCK * parseUint(memspec["memtimingspec"]["RAS"], "RAS")), - tRC (tRAS + tRP), - tRL (tCK * parseUint(memspec["memtimingspec"]["RL"], "RL")), - tRTP (tCK * parseUint(memspec["memtimingspec"]["RTP"], "RTP")), - tRPRE (tCK * parseUint(memspec["memtimingspec"]["RPRE"], "RPRE")), - tRPST (tCK * parseUint(memspec["memtimingspec"]["RPST"], "RPST")), - tRDDQS (tCK * parseUint(memspec["memtimingspec"]["RDDQS"], "RDDQS")), - tWL (tCK * parseUint(memspec["memtimingspec"]["WL"], "WL")), - tWPRE (tCK * parseUint(memspec["memtimingspec"]["WPRE"], "WPRE")), - tWPST (tCK * parseUint(memspec["memtimingspec"]["WPST"], "WPST")), - tWR (tCK * parseUint(memspec["memtimingspec"]["WR"], "WR")), - tCCD_L_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_L_slr"], "CCD_L_slr")), - tCCD_L_WR_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_L_WR_slr"], "CCD_L_WR_slr")), - tCCD_S_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_S_slr"], "CCD_S_slr")), - tCCD_S_WR_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_S_WR_slr"], "CCD_S_WR_slr")), - tCCD_dlr (tCK * parseUint(memspec["memtimingspec"]["CCD_dlr"], "CCD_dlr")), - tCCD_WR_dlr (tCK * parseUint(memspec["memtimingspec"]["CCD_WR_dlr"], "CCD_WR_dlr")), - tCCD_WR_dpr (tCK * parseUint(memspec["memtimingspec"]["CCD_WR_dpr"], "CCD_WR_dpr")), - tRRD_L_slr (tCK * parseUint(memspec["memtimingspec"]["RRD_L_slr"], "RRD_L_slr")), - tRRD_S_slr (tCK * parseUint(memspec["memtimingspec"]["RRD_S_slr"], "RRD_S_slr")), - tRRD_dlr (tCK * parseUint(memspec["memtimingspec"]["RRD_dlr"], "RRD_dlr")), - tFAW_slr (tCK * parseUint(memspec["memtimingspec"]["FAW_slr"], "FAW_slr")), - tFAW_dlr (tCK * parseUint(memspec["memtimingspec"]["FAW_dlr"], "FAW_dlr")), - tWTR_L (tCK * parseUint(memspec["memtimingspec"]["WTR_L"], "WTR_L")), - tWTR_S (tCK * parseUint(memspec["memtimingspec"]["WTR_S"], "WTR_S")), - tRFC_slr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["RFC1_slr"], "RFC1_slr") - : tCK * parseUint(memspec["memtimingspec"]["RFC2_slr"], "RFC2_slr")), - tRFC_dlr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["RFC1_dlr"], "RFC1_dlr") - : tCK * parseUint(memspec["memtimingspec"]["RFC2_dlr"], "RFC2_dlr")), - tRFC_dpr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["RFC1_dpr"], "RFC1_dpr") - : tCK * parseUint(memspec["memtimingspec"]["RFC2_dpr"], "RFC2_dpr")), - tRFCsb_slr (tCK * parseUint(memspec["memtimingspec"]["RFCsb_slr"], "RFCsb_slr")), - tRFCsb_dlr (tCK * parseUint(memspec["memtimingspec"]["RFCsb_dlr"], "RFCsb_dlr")), - tREFI ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["REFI1"], "REFI1") - : tCK * parseUint(memspec["memtimingspec"]["REFI2"], "REFI2")), - tREFIsb (tCK * parseUint(memspec["memtimingspec"]["REFISB"], "REFISB")), - tREFSBRD_slr (tCK * parseUint(memspec["memtimingspec"]["REFSBRD_slr"], "REFSBRD_slr")), - tREFSBRD_dlr (tCK * parseUint(memspec["memtimingspec"]["REFSBRD_dlr"], "REFSBRD_dlr")), - tRTRS (tCK * parseUint(memspec["memtimingspec"]["RTRS"], "RTRS")), - tCPDED (tCK * parseUint(memspec["memtimingspec"]["CPDED"], "CPDED")), - tPD (tCK * parseUint(memspec["memtimingspec"]["PD"], "PD")), - tXP (tCK * parseUint(memspec["memtimingspec"]["XP"], "XP")), - tACTPDEN (tCK * parseUint(memspec["memtimingspec"]["ACTPDEN"], "ACTPDEN")), - tPRPDEN (tCK * parseUint(memspec["memtimingspec"]["PRPDEN"], "PRPDEN")), - tREFPDEN (tCK * parseUint(memspec["memtimingspec"]["REFPDEN"], "REFPDEN")), - cmdOffset_S (cmdMode == 2 ? 1 * tCK : 0 * tCK), - cmdOffset_L (cmdMode == 2 ? 3 * tCK : 1 * tCK) + tRCD (tCK * parseUint(memspec["memtimingspec"]["RCD"], "RCD")), + tPPD (tCK * parseUint(memspec["memtimingspec"]["PPD"], "PPD")), + tRP (tCK * parseUint(memspec["memtimingspec"]["RP"], "RP")), + tRAS (tCK * parseUint(memspec["memtimingspec"]["RAS"], "RAS")), + tRC (tRAS + tRP), + tRL (tCK * parseUint(memspec["memtimingspec"]["RL"], "RL")), + tRTP (tCK * parseUint(memspec["memtimingspec"]["RTP"], "RTP")), + tRPRE (tCK * parseUint(memspec["memtimingspec"]["RPRE"], "RPRE")), + tRPST (tCK * parseUint(memspec["memtimingspec"]["RPST"], "RPST")), + tRDDQS (tCK * parseUint(memspec["memtimingspec"]["RDDQS"], "RDDQS")), + tWL (tCK * parseUint(memspec["memtimingspec"]["WL"], "WL")), + tWPRE (tCK * parseUint(memspec["memtimingspec"]["WPRE"], "WPRE")), + tWPST (tCK * parseUint(memspec["memtimingspec"]["WPST"], "WPST")), + tWR (tCK * parseUint(memspec["memtimingspec"]["WR"], "WR")), + tCCD_L_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_L_slr"], "CCD_L_slr")), + tCCD_L_WR_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_L_WR_slr"], "CCD_L_WR_slr")), + tCCD_L_WR2_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_L_WR2_slr"], "CCD_L_WR2_slr")), + tCCD_S_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_S_slr"], "CCD_S_slr")), + tCCD_S_WR_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_S_WR_slr"], "CCD_S_WR_slr")), + tCCD_dlr (tCK * parseUint(memspec["memtimingspec"]["CCD_dlr"], "CCD_dlr")), + tCCD_WR_dlr (tCK * parseUint(memspec["memtimingspec"]["CCD_WR_dlr"], "CCD_WR_dlr")), + tCCD_WR_dpr (tCK * parseUint(memspec["memtimingspec"]["CCD_WR_dpr"], "CCD_WR_dpr")), + tRRD_L_slr (tCK * parseUint(memspec["memtimingspec"]["RRD_L_slr"], "RRD_L_slr")), + tRRD_S_slr (tCK * parseUint(memspec["memtimingspec"]["RRD_S_slr"], "RRD_S_slr")), + tRRD_dlr (tCK * parseUint(memspec["memtimingspec"]["RRD_dlr"], "RRD_dlr")), + tFAW_slr (tCK * parseUint(memspec["memtimingspec"]["FAW_slr"], "FAW_slr")), + tFAW_dlr (tCK * parseUint(memspec["memtimingspec"]["FAW_dlr"], "FAW_dlr")), + tWTR_L (tCK * parseUint(memspec["memtimingspec"]["WTR_L"], "WTR_L")), + tWTR_S (tCK * parseUint(memspec["memtimingspec"]["WTR_S"], "WTR_S")), + tRFC_slr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["RFC1_slr"], "RFC1_slr") + : tCK * parseUint(memspec["memtimingspec"]["RFC2_slr"], "RFC2_slr")), + tRFC_dlr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["RFC1_dlr"], "RFC1_dlr") + : tCK * parseUint(memspec["memtimingspec"]["RFC2_dlr"], "RFC2_dlr")), + tRFC_dpr ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["RFC1_dpr"], "RFC1_dpr") + : tCK * parseUint(memspec["memtimingspec"]["RFC2_dpr"], "RFC2_dpr")), + tRFCsb_slr (tCK * parseUint(memspec["memtimingspec"]["RFCsb_slr"], "RFCsb_slr")), + tRFCsb_dlr (tCK * parseUint(memspec["memtimingspec"]["RFCsb_dlr"], "RFCsb_dlr")), + tREFI ((refMode == 1) ? tCK * parseUint(memspec["memtimingspec"]["REFI1"], "REFI1") + : tCK * parseUint(memspec["memtimingspec"]["REFI2"], "REFI2")), + tREFIsb (tCK * parseUint(memspec["memtimingspec"]["REFISB"], "REFISB")), + tREFSBRD_slr (tCK * parseUint(memspec["memtimingspec"]["REFSBRD_slr"], "REFSBRD_slr")), + tREFSBRD_dlr (tCK * parseUint(memspec["memtimingspec"]["REFSBRD_dlr"], "REFSBRD_dlr")), + tRTRS (tCK * parseUint(memspec["memtimingspec"]["RTRS"], "RTRS")), + tCPDED (tCK * parseUint(memspec["memtimingspec"]["CPDED"], "CPDED")), + tPD (tCK * parseUint(memspec["memtimingspec"]["PD"], "PD")), + tXP (tCK * parseUint(memspec["memtimingspec"]["XP"], "XP")), + tACTPDEN (tCK * parseUint(memspec["memtimingspec"]["ACTPDEN"], "ACTPDEN")), + tPRPDEN (tCK * parseUint(memspec["memtimingspec"]["PRPDEN"], "PRPDEN")), + tREFPDEN (tCK * parseUint(memspec["memtimingspec"]["REFPDEN"], "REFPDEN")), + shortCmdOffset (cmdMode == 2 ? 1 * tCK : 0 * tCK), + longCmdOffset (cmdMode == 2 ? 3 * tCK : 1 * tCK), + shortBurstDuration(tCK * 8), + longBurstDuration(tCK * 16) { if (cmdMode == 1) { @@ -156,24 +159,39 @@ sc_time MemSpecDDR5::getRefreshIntervalSB() const } // Returns the execution time for commands that have a fixed execution time -sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload &) const +sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload &payload) const { if (command == Command::PRE || command == Command::PREA || command == Command::PRESB) - return tRP + cmdOffset_S; + return tRP + shortCmdOffset; else if (command == Command::ACT) - return tRCD + cmdOffset_L; + return tRCD + longCmdOffset; else if (command == Command::RD) - return tRL + burstDuration + cmdOffset_L; + { + if (DramExtension::getBurstLength(payload) == 32) + return tRL + longBurstDuration + longCmdOffset; + else + return tRL + shortBurstDuration + longCmdOffset; + } else if (command == Command::RDA) - return tRTP + tRP + cmdOffset_L; + return tRTP + tRP + longCmdOffset; else if (command == Command::WR) - return tWL + burstDuration + cmdOffset_L; + { + if (DramExtension::getBurstLength(payload) == 32) + return tWL + longBurstDuration + longCmdOffset; + else + return tWL + shortBurstDuration + longCmdOffset; + } else if (command == Command::WRA) - return tWL + burstDuration + tWR + tRP + cmdOffset_L; + { + if (DramExtension::getBurstLength(payload) == 32) + return tWL + longBurstDuration + tWR + tRP + longCmdOffset; + else + return tWL + shortBurstDuration + tWR + tRP + longCmdOffset; + } else if (command == Command::REFA) - return tRFC_slr + cmdOffset_S; + return tRFC_slr + shortCmdOffset; else if (command == Command::REFSB) - return tRFCsb_slr + cmdOffset_S; + return tRFCsb_slr + shortCmdOffset; else { SC_REPORT_FATAL("getExecutionTime", @@ -182,12 +200,22 @@ sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload } } -TimeInterval MemSpecDDR5::getIntervalOnDataStrobe(Command command) const +TimeInterval MemSpecDDR5::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &payload) const { if (command == Command::RD || command == Command::RDA) - return TimeInterval(tRL + cmdOffset_L, tRL + burstDuration + cmdOffset_L); + { + if (DramExtension::getBurstLength(payload) == 32) + return TimeInterval(tRL + longCmdOffset, tRL + longBurstDuration + longCmdOffset); + else + return TimeInterval(tRL + longCmdOffset, tRL + shortBurstDuration+ longCmdOffset); + } else if (command == Command::WR || command == Command::WRA) - return TimeInterval(tWL + cmdOffset_L, tWL + burstDuration + cmdOffset_L); + { + if (DramExtension::getBurstLength(payload) == 32) + return TimeInterval(tWL + longCmdOffset, tWL + longBurstDuration + longCmdOffset); + else + return TimeInterval(tWL + longCmdOffset, tWL + shortBurstDuration + longCmdOffset); + } else { SC_REPORT_FATAL("MemSpec", "Method was called with invalid argument"); diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h index 13883326..3de89eb9 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h @@ -69,6 +69,7 @@ public: const sc_time tWR; const sc_time tCCD_L_slr; const sc_time tCCD_L_WR_slr; + const sc_time tCCD_L_WR2_slr; const sc_time tCCD_S_slr; const sc_time tCCD_S_WR_slr; const sc_time tCCD_dlr; @@ -99,8 +100,11 @@ public: const sc_time tPRPDEN; const sc_time tREFPDEN; - const sc_time cmdOffset_S; - const sc_time cmdOffset_L; + const sc_time shortCmdOffset; + const sc_time longCmdOffset; + + const sc_time shortBurstDuration; + const sc_time longBurstDuration; // Currents and Voltages: // TODO: to be completed @@ -108,8 +112,8 @@ public: virtual sc_time getRefreshIntervalAB() const override; virtual sc_time getRefreshIntervalSB() const override; - virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; - virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override; + virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override; virtual uint64_t getSimMemSizeInBytes() const override; }; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.cpp index 2c27dbc3..4ae7bb17 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.cpp @@ -128,7 +128,7 @@ sc_time MemSpecGDDR5::getExecutionTime(Command command, const tlm_generic_payloa } } -TimeInterval MemSpecGDDR5::getIntervalOnDataStrobe(Command command) const +TimeInterval MemSpecGDDR5::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &) const { if (command == Command::RD || command == Command::RDA) return TimeInterval(tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO, diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h index 3abeb869..cf584c98 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h @@ -88,8 +88,8 @@ public: virtual sc_time getRefreshIntervalAB() const override; virtual sc_time getRefreshIntervalPB() const override; - virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; - virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override; + virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override; virtual uint64_t getSimMemSizeInBytes() const override; }; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.cpp index ea1dc46e..1c97fada 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.cpp @@ -128,7 +128,7 @@ sc_time MemSpecGDDR5X::getExecutionTime(Command command, const tlm_generic_paylo } } -TimeInterval MemSpecGDDR5X::getIntervalOnDataStrobe(Command command) const +TimeInterval MemSpecGDDR5X::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &) const { if (command == Command::RD || command == Command::RDA) return TimeInterval(tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO, diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h index 10fcd5b5..f507232d 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h @@ -88,8 +88,8 @@ public: virtual sc_time getRefreshIntervalAB() const override; virtual sc_time getRefreshIntervalPB() const override; - virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; - virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override; + virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override; virtual uint64_t getSimMemSizeInBytes() const override; }; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp index d296f887..c0dfd854 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp @@ -130,7 +130,7 @@ sc_time MemSpecGDDR6::getExecutionTime(Command command, const tlm_generic_payloa } } -TimeInterval MemSpecGDDR6::getIntervalOnDataStrobe(Command command) const +TimeInterval MemSpecGDDR6::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &) const { if (command == Command::RD || command == Command::RDA) return TimeInterval(tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO, diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h index c0f9f7d1..b6d86f8e 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h @@ -90,8 +90,8 @@ public: virtual sc_time getRefreshIntervalAB() const override; virtual sc_time getRefreshIntervalPB() const override; - virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; - virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override; + virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override; virtual uint64_t getSimMemSizeInBytes() const override; }; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp index c299f9d9..25f77ef9 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp @@ -130,7 +130,7 @@ sc_time MemSpecHBM2::getExecutionTime(Command command, const tlm_generic_payload } } -TimeInterval MemSpecHBM2::getIntervalOnDataStrobe(Command command) const +TimeInterval MemSpecHBM2::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &) const { if (command == Command::RD || command == Command::RDA) return TimeInterval(tRL + tDQSCK, tRL + tDQSCK + burstDuration); diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h index a56f18fb..f5c0fbb0 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h @@ -85,8 +85,8 @@ public: virtual bool hasRasAndCasBus() const override; - virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; - virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override; + virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override; virtual uint64_t getSimMemSizeInBytes() const override; }; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.cpp index a046a7d7..9e181a0d 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.cpp @@ -132,7 +132,7 @@ sc_time MemSpecLPDDR4::getExecutionTime(Command command, const tlm_generic_paylo } } -TimeInterval MemSpecLPDDR4::getIntervalOnDataStrobe(Command command) const +TimeInterval MemSpecLPDDR4::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &) const { if (command == Command::RD || command == Command::RDA) return TimeInterval(tRL + tDQSCK + 3 * tCK, diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h index 4c7d0d52..8005422e 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h @@ -83,8 +83,8 @@ public: virtual sc_time getRefreshIntervalAB() const override; virtual sc_time getRefreshIntervalPB() const override; - virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; - virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override; + virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override; virtual uint64_t getSimMemSizeInBytes() const override; }; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp index 91f9f1c8..dcbd1ae7 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp @@ -126,7 +126,7 @@ sc_time MemSpecWideIO::getExecutionTime(Command command, const tlm_generic_paylo } } -TimeInterval MemSpecWideIO::getIntervalOnDataStrobe(Command command) const +TimeInterval MemSpecWideIO::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &) const { if (command == Command::RD || command == Command::RDA) return TimeInterval(tRL + tAC, tRL + tAC + burstDuration); diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h index eb1ad7d7..79b2818c 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h @@ -95,8 +95,8 @@ public: virtual sc_time getRefreshIntervalAB() const override; - virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; - virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override; + virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override; virtual uint64_t getSimMemSizeInBytes() const override; }; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.cpp index 2b93a0cc..eb0efe10 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.cpp @@ -117,7 +117,7 @@ sc_time MemSpecWideIO2::getExecutionTime(Command command, const tlm_generic_payl } } -TimeInterval MemSpecWideIO2::getIntervalOnDataStrobe(Command command) const +TimeInterval MemSpecWideIO2::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &) const { if (command == Command::RD || command == Command::RDA) return TimeInterval(tRL + tDQSCK, tRL + tDQSCK + burstDuration); diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h index 35503a61..31b01a7d 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h @@ -77,8 +77,8 @@ public: virtual sc_time getRefreshIntervalAB() const override; virtual sc_time getRefreshIntervalPB() const override; - virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; - virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override; + virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override; virtual uint64_t getSimMemSizeInBytes() const override; }; diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index af67bdae..29269952 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -313,7 +313,7 @@ void Controller::controllerMethod() manageRequests(thinkDelayFw); respQueue->insertPayload(payload, sc_time_stamp() + thinkDelayFw + phyDelayFw - + memSpec->getIntervalOnDataStrobe(command).end + + memSpec->getIntervalOnDataStrobe(command, *payload).end + phyDelayBw + thinkDelayBw); sc_time triggerTime = respQueue->getTriggerTime(); diff --git a/DRAMSys/library/src/controller/ControllerRecordable.cpp b/DRAMSys/library/src/controller/ControllerRecordable.cpp index bd548d50..243d43e5 100644 --- a/DRAMSys/library/src/controller/ControllerRecordable.cpp +++ b/DRAMSys/library/src/controller/ControllerRecordable.cpp @@ -75,7 +75,7 @@ void ControllerRecordable::sendToDram(Command command, tlm_generic_payload *payl { if (isCasCommand(command)) { - TimeInterval dataStrobe = Configuration::getInstance().memSpec->getIntervalOnDataStrobe(command); + TimeInterval dataStrobe = Configuration::getInstance().memSpec->getIntervalOnDataStrobe(command, *payload); tlmRecorder->updateDataStrobe(sc_time_stamp() + delay + dataStrobe.start, sc_time_stamp() + delay + dataStrobe.end, *payload); } diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp index 1de608a8..67ee3b73 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp @@ -59,29 +59,50 @@ CheckerDDR5::CheckerDDR5() last4ActivatesLogical = std::vector>(memSpec->numberOfLogicalRanks); last4ActivatesPhysical = std::vector>(memSpec->numberOfPhysicalRanks); + lastBurstLengthByCommandAndDIMMRank = std::vector> + (4, std::vector(memSpec->numberOfDIMMRanks)); + lastBurstLengthByCommandAndPhysicalRank = std::vector> + (4, std::vector(memSpec->numberOfPhysicalRanks)); + lastBurstLengthByCommandAndLogicalRank = std::vector> + (4, std::vector(memSpec->numberOfLogicalRanks)); + lastBurstLengthByCommandAndBankGroup = std::vector> + (4, std::vector(memSpec->numberOfBankGroups)); + lastBurstLengthByCommandAndBank = std::vector> + (4, std::vector(memSpec->numberOfBanks)); + lastBurstLengthByCommand = std::vector(4); + lastBurstLengthByCommandAndBankInGroup = std::vector> + (4, std::vector(memSpec->numberOfRanks * memSpec->banksPerGroup)); + cmdOffset = memSpec->cmdMode * memSpec->tCK; - tRD_BURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; - tWR_BURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; + tRD_BURST = 8 * memSpec->tCK; + tWR_BURST = 8 * memSpec->tCK; tWTRA = memSpec->tWR - memSpec->tRTP; - tWRRDA = memSpec->tWL + tWR_BURST + tWTRA; + tWRRDA = memSpec->tWL + tWR_BURST + tWTRA; // tWTRA = tWR - tRTP tWRPRE = memSpec->tWL + tWR_BURST + memSpec->tWR; tRDAACT = memSpec->tRTP + memSpec->tRP; tWRAACT = tWRPRE + memSpec->tRP; - tCCD_L_RTW_slr = memSpec->tRL - memSpec->tWL + tRD_BURST + 2 * memSpec->tCK - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; - tCCD_S_RTW_slr = memSpec->tRL - memSpec->tWL + tRD_BURST + 2 * memSpec->tCK - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; - tCCD_RTW_dlr = memSpec->tRL - memSpec->tWL + tRD_BURST + 2 * memSpec->tCK - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; + tCCD_L_RTW_slr = memSpec->tRL - memSpec->tWL + tRD_BURST + 2 * memSpec->tCK + - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; + tCCD_S_RTW_slr = memSpec->tRL - memSpec->tWL + tRD_BURST + 2 * memSpec->tCK + - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; + tCCD_RTW_dlr = memSpec->tRL - memSpec->tWL + tRD_BURST + 2 * memSpec->tCK + - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; tRDRD_dpr = tRD_BURST + memSpec->tRTRS; tRDRD_ddr = tRD_BURST + memSpec->tRTRS; - tRDWR_dpr = memSpec->tRL - memSpec->tWL + tRD_BURST + memSpec->tRTRS - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; - tRDWR_ddr = memSpec->tRL - memSpec->tWL + tRD_BURST + memSpec->tRTRS - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; + tRDWR_dpr = memSpec->tRL - memSpec->tWL + tRD_BURST + memSpec->tRTRS + - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; + tRDWR_ddr = memSpec->tRL - memSpec->tWL + tRD_BURST + memSpec->tRTRS + - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; tCCD_L_WTR_slr = memSpec->tWL + tWR_BURST + memSpec->tWTR_L; tCCD_S_WTR_slr = memSpec->tWL + tWR_BURST + memSpec->tWTR_S; tCCD_WTR_dlr = memSpec->tWL + tWR_BURST + memSpec->tWTR_S; tWRWR_dpr = std::max(memSpec->tCCD_WR_dpr, tWR_BURST + memSpec->tRTRS); tWRWR_ddr = tWR_BURST + memSpec->tRTRS; - tWRRD_dpr = memSpec->tWL - memSpec->tRL + tWR_BURST + memSpec->tRTRS + memSpec->tRDDQS + memSpec->tWPST + memSpec->tRPRE; - tWRRD_ddr = memSpec->tWL - memSpec->tRL + tWR_BURST + memSpec->tRTRS + memSpec->tRDDQS + memSpec->tWPST + memSpec->tRPRE; + tWRRD_dpr = memSpec->tWL - memSpec->tRL + tWR_BURST + memSpec->tRTRS + + memSpec->tRDDQS + memSpec->tWPST + memSpec->tRPRE; + tWRRD_ddr = memSpec->tWL - memSpec->tRL + tWR_BURST + memSpec->tRTRS + + memSpec->tRDDQS + memSpec->tWPST + memSpec->tRPRE; tRDPDEN = memSpec->tRL + tRD_BURST + cmdOffset; tWRPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + cmdOffset; tWRAPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + cmdOffset; @@ -89,7 +110,8 @@ CheckerDDR5::CheckerDDR5() // TODO: tRTP BL 32 (similar to LPDDR4) } -sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned burstLength) const +sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank, + unsigned burstLength) const { sc_time lastCommandStart; sc_time earliestTimeToStart = sc_time_stamp(); @@ -108,93 +130,198 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_slr); + { + if (lastBurstLengthByCommandAndBankGroup[Command::RD][bankgroup.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_slr); // 16 tCK + } lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_slr); + { + if (lastBurstLengthByCommandAndLogicalRank[Command::RD][logicalrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_slr); // 16 tCK + } lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_dlr); + { + if (lastBurstLengthByCommandAndPhysicalRank[Command::RD][physicalrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_dlr); // 16 tCK + } lastCommandStart = lastScheduledByCommand[Command::RD]; if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]) { if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RD][dimmrank.ID()]) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr); + { + if (lastBurstLengthByCommandAndDIMMRank[Command::RD][dimmrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr + tRD_BURST); // 16 tCK + tRTRS + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr); // 16 tCK + tRTRS + } else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr); + { + if (lastBurstLengthByCommandAndPhysicalRank[Command::RD][physicalrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr + tRD_BURST); // 16 tCK + tRTRS + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr); // 16 tCK + tRTRS + } } lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_slr); + { + if (lastBurstLengthByCommandAndBankGroup[Command::RDA][bankgroup.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_slr); // 16 tCK + } lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_slr); + { + if (lastBurstLengthByCommandAndBankGroup[Command::RDA][bankgroup.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_slr); // 16 tCK + } lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_dlr); + { + if (lastBurstLengthByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_dlr); // 16 tCK + } lastCommandStart = lastScheduledByCommand[Command::RDA]; if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]) { if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RDA][dimmrank.ID()]) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr); + { + if (lastBurstLengthByCommandAndDIMMRank[Command::RDA][dimmrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr + tRD_BURST); // 16 tCK + tRTRS + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr); // 16 tCK + tRTRS + } else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr); + { + if (lastBurstLengthByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr + tRD_BURST); // 16 tCK + tRTRS + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr); // 16 tCK + tRTRS + } } if (command == Command::RDA) { lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDA); + { + if (lastBurstLengthByCommandAndBank[Command::WR][bank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDA + tWR_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDA); // + 8 tCK + } } lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr); + { + if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankgroup.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr + tWR_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr); // + 8 tCK + } lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr); + { + if (lastBurstLengthByCommandAndLogicalRank[Command::WR][logicalrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr + tWR_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr); // + 8 tCK + } lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr); + { + if (lastBurstLengthByCommandAndPhysicalRank[Command::WR][physicalrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr + tWR_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr); // + 8 tCK + } lastCommandStart = lastScheduledByCommand[Command::WR]; if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]) { if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WR][dimmrank.ID()]) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr); + { + if (lastBurstLengthByCommandAndDIMMRank[Command::WR][dimmrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr + tWR_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr); // + 8 tCK + } else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr); + { + if (lastBurstLengthByCommand[Command::WR] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr + tWR_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr); // + 8 tCK + } } lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr); + { + if (lastBurstLengthByCommandAndBankGroup[Command::WRA][bankgroup.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr + tWR_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr); // + 8 tCK + } lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr); + { + if (lastBurstLengthByCommandAndLogicalRank[Command::WRA][logicalrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr + tWR_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr); // + 8 tCK + } lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr); + { + if (lastBurstLengthByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr + tWR_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr); // + 8 tCK + } lastCommandStart = lastScheduledByCommand[Command::WRA]; if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]) { if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WRA][dimmrank.ID()]) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr); + { + if (lastBurstLengthByCommandAndDIMMRank[Command::WRA][dimmrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr + tWR_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr); // + 8 tCK + } else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr); + { + if (lastBurstLengthByCommand[Command::WRA] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr + tWR_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr); // + 8 tCK + } } } else if (command == Command::WR || command == Command::WRA) @@ -205,86 +332,206 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr); + { + if (lastBurstLengthByCommandAndBankGroup[Command::RD][bankgroup.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr + tRD_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr); // + 8 tCK + } lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr); + { + if (lastBurstLengthByCommandAndLogicalRank[Command::RD][logicalrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr + tRD_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr); // + 8 tCK + } lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr); + { + if (lastBurstLengthByCommandAndPhysicalRank[Command::RD][physicalrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr + tRD_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr); // + 8 tCK + } lastCommandStart = lastScheduledByCommand[Command::RD]; if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]) { if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RD][dimmrank.ID()]) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr); + { + if (lastBurstLengthByCommandAndDIMMRank[Command::RD][dimmrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr + tRD_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr); // + 8 tCK + } else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr); + { + if (lastBurstLengthByCommand[Command::RD] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr + tRD_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr); // + 8 tCK + } } lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr); + { + if (lastBurstLengthByCommandAndBankGroup[Command::RDA][bankgroup.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr + tRD_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr); // + 8 tCK + } lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr); + { + if (lastBurstLengthByCommandAndLogicalRank[Command::RDA][logicalrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr + tRD_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr); // + 8 tCK + } lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr); + { + if (lastBurstLengthByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr + tRD_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr); // + 8 tCK + } lastCommandStart = lastScheduledByCommand[Command::RDA]; if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]) { if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RDA][dimmrank.ID()]) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr); + { + if (lastBurstLengthByCommandAndDIMMRank[Command::RDA][dimmrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr + tRD_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr); // + 8 tCK + } else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr); + { + if (lastBurstLengthByCommand[Command::RDA] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr + tRD_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr); // + 8 tCK + } } lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr); + { + if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankgroup.ID()] == 32) + { + if (burstLength == 16 && memSpec->bitWidth == 4) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWR_BURST + memSpec->tCCD_L_WR_slr); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWR_BURST + memSpec->tCCD_L_WR2_slr); + } + else + { + if (burstLength == 16 && memSpec->bitWidth == 4) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR2_slr); + } + } lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_WR_slr); + { + if (lastBurstLengthByCommandAndLogicalRank[Command::WR][logicalrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 clocks + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_WR_slr); // 16 clocks + } lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_WR_dlr); + { + if (lastBurstLengthByCommandAndPhysicalRank[Command::WR][physicalrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 clocks + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_WR_dlr); // 16 clocks + } lastCommandStart = lastScheduledByCommand[Command::WR]; if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]) { if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WR][dimmrank.ID()]) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr); + { + if (lastBurstLengthByCommandAndDIMMRank[Command::WR][dimmrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr + tWR_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr); // + 8 tCK + } else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr); + { + if (lastBurstLengthByCommand[Command::WR] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr + tWR_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr); // + 8 tCK + } } lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr); + { + if (lastBurstLengthByCommandAndBankGroup[Command::WRA][bankgroup.ID()] == 32) + { + if (burstLength == 16 && memSpec->bitWidth == 4) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWR_BURST + memSpec->tCCD_L_WR_slr); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWR_BURST + memSpec->tCCD_L_WR2_slr); + } + else + { + if (burstLength == 16 && memSpec->bitWidth == 4) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR2_slr); + } + } lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_WR_slr); + { + if (lastBurstLengthByCommandAndLogicalRank[Command::WRA][logicalrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 clocks + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_WR_slr); // 16 clocks + } lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_WR_dlr); + { + if (lastBurstLengthByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 clocks + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_WR_dlr); // 16 clocks + } lastCommandStart = lastScheduledByCommand[Command::WRA]; if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]) { if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WRA][dimmrank.ID()]) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr); + { + if (lastBurstLengthByCommandAndDIMMRank[Command::WRA][dimmrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr + tWR_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr); // + 8 tCK + } else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr); + { + if (lastBurstLengthByCommand[Command::WRA] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr + tWR_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr); // + 8 tCK + } } } else if (command == Command::ACT) @@ -311,7 +558,12 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT); + { + if (lastBurstLengthByCommandAndBank[Command::WRA][bank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + tWR_BURST); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT); // + 8 tCK + } lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; if (lastCommandStart != sc_max_time()) @@ -347,25 +599,30 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (last4ActivatesLogical[logicalrank.ID()].size() >= 4) earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesLogical[logicalrank.ID()].front() - + memSpec->tFAW_slr - memSpec->cmdOffset_L); + + memSpec->tFAW_slr - memSpec->longCmdOffset); if (last4ActivatesPhysical[physicalrank.ID()].size() >= 4) earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesPhysical[physicalrank.ID()].front() - + memSpec->tFAW_dlr - memSpec->cmdOffset_L); + + memSpec->tFAW_dlr - memSpec->longCmdOffset); } else if (command == Command::PRE) { lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + cmdOffset); lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdOffset); lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK); + { + if (lastBurstLengthByCommandAndBank[Command::WR][bank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tWR_BURST + cmdOffset); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdOffset); // + 8 tCK + } lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()]; if (lastCommandStart != sc_max_time()) @@ -383,23 +640,33 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr { lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + cmdOffset); lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdOffset); lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdOffset); lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK); + { + if (lastBurstLengthByCommandAndLogicalRank[Command::WR][logicalrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tWR_BURST + cmdOffset); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdOffset); // + 8 tCK + } lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK); + { + if (lastBurstLengthByCommandAndLogicalRank[Command::WRA][logicalrank.ID()]) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tWR_BURST + cmdOffset); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdOffset); // + 8 tCK + } lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()]; if (lastCommandStart != sc_max_time()) @@ -415,23 +682,33 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr { lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::ACT][bankInGroup.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + cmdOffset); lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RD][bankInGroup.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdOffset); lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RDA][bankInGroup.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdOffset); lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WR][bankInGroup.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK); + { + if (lastBurstLengthByCommandAndBankInGroup[Command::WR][bankInGroup.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tWR_BURST + cmdOffset); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdOffset); // + 8 tCK + } lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK); + { + if (lastBurstLengthByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tWR_BURST + cmdOffset); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdOffset); // + 8 tCK + } lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()]; if (lastCommandStart != sc_max_time()) @@ -447,15 +724,20 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr { lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + cmdOffset); lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + cmdOffset); lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP + memSpec->tCK); + { + if (lastBurstLengthByCommandAndLogicalRank[Command::WRA][logicalrank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tWR_BURST + memSpec->tRP + cmdOffset); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP + cmdOffset); // + 8 tCK + } lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::PRE][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) @@ -484,19 +766,24 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr { lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::ACT][bankInGroup.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + cmdOffset); lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L_slr + memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L_slr + cmdOffset); lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RDA][bankInGroup.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + cmdOffset); lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + memSpec->tCK); + { + if (lastBurstLengthByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + tWR_BURST + cmdOffset); // + 8 tCK + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + cmdOffset); // + 8 tCK + } lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRE][bankInGroup.ID()]; if (lastCommandStart != sc_max_time()) @@ -532,11 +819,11 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (last4ActivatesLogical[logicalrank.ID()].size() >= 4) earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesLogical[logicalrank.ID()].front() - + memSpec->tFAW_slr - memSpec->cmdOffset_S); + + memSpec->tFAW_slr - memSpec->shortCmdOffset); if (last4ActivatesPhysical[physicalrank.ID()].size() >= 4) earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesPhysical[physicalrank.ID()].front() - + memSpec->tFAW_dlr - memSpec->cmdOffset_S); + + memSpec->tFAW_dlr - memSpec->shortCmdOffset); } else SC_REPORT_FATAL("CheckerDDR5", "Unknown command!"); @@ -547,7 +834,7 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr return earliestTimeToStart; } -void CheckerDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned) +void CheckerDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned burstLength) { PRINTDEBUGMESSAGE("CheckerDDR5", "Changing state on bank " + std::to_string(bank.ID()) + " command is " + commandToString(command)); @@ -555,6 +842,7 @@ void CheckerDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank b Rank logicalrank = rank; Rank physicalrank = Rank(logicalrank.ID() / memSpec->logicalRanksPerPhysicalRank); Rank dimmrank = Rank(physicalrank.ID() / memSpec->physicalRanksPerDIMMRank); + Bank bankingroup = Bank(rank.ID() * memSpec->banksPerGroup + bank.ID() % memSpec->banksPerGroup); lastScheduledByCommandAndDIMMRank[command][dimmrank.ID()] = sc_time_stamp(); lastScheduledByCommandAndPhysicalRank[command][physicalrank.ID()] = sc_time_stamp(); @@ -565,8 +853,18 @@ void CheckerDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank b lastCommandOnBus = sc_time_stamp() + memSpec->getCommandLength(command) - memSpec->tCK; - lastScheduledByCommandAndBankInGroup[command][rank.ID() * memSpec->banksPerGroup - + bank.ID() % memSpec->banksPerGroup] = sc_time_stamp(); + lastScheduledByCommandAndBankInGroup[command][bankingroup.ID()] = sc_time_stamp(); + + if (isCasCommand(command)) + { + lastBurstLengthByCommandAndDIMMRank[command][dimmrank.ID()] = burstLength; + lastBurstLengthByCommandAndPhysicalRank[command][physicalrank.ID()] = burstLength; + lastBurstLengthByCommandAndLogicalRank[command][logicalrank.ID()] = burstLength; + lastBurstLengthByCommandAndBankGroup[command][bankgroup.ID()] = burstLength; + lastBurstLengthByCommandAndBank[command][bank.ID()] = burstLength; + lastBurstLengthByCommand[command] = burstLength; + lastBurstLengthByCommandAndBankInGroup[command][bankingroup.ID()] = burstLength; + } if (command == Command::ACT || command == Command::REFSB) { diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR5.h b/DRAMSys/library/src/controller/checker/CheckerDDR5.h index 7bd2f4ad..ace723e4 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR5.h +++ b/DRAMSys/library/src/controller/checker/CheckerDDR5.h @@ -65,6 +65,15 @@ private: std::vector> last4ActivatesPhysical; std::vector> last4ActivatesLogical; + std::vector> lastBurstLengthByCommandAndDIMMRank; + std::vector> lastBurstLengthByCommandAndPhysicalRank; + std::vector> lastBurstLengthByCommandAndLogicalRank; + std::vector> lastBurstLengthByCommandAndBankGroup; + std::vector> lastBurstLengthByCommandAndBank; + std::vector lastBurstLengthByCommand; + + std::vector> lastBurstLengthByCommandAndBankInGroup; + // TODO: store BL of last RD and WR globally or for each hierarchy? sc_time cmdOffset; From ad6eb6c7a236e78b872ff6cbd43ba9cceff6fbda Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Mon, 10 May 2021 15:53:56 +0200 Subject: [PATCH 06/13] Adapt bandwidth calculation to OTF burst length selection. --- DRAMSys/library/src/controller/Controller.cpp | 2 +- DRAMSys/library/src/controller/ControllerIF.h | 5 +- .../src/controller/ControllerRecordable.cpp | 6 +- .../src/controller/ControllerRecordable.h | 7 +- .../src/controller/checker/CheckerDDR5.cpp | 76 +++++++++---------- .../src/controller/checker/CheckerDDR5.h | 4 +- DRAMSys/simulator/StlPlayer.cpp | 4 +- DRAMSys/simulator/StlPlayer.h | 2 +- 8 files changed, 52 insertions(+), 54 deletions(-) diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index 29269952..45b04c39 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -438,9 +438,9 @@ void Controller::manageResponses() NDEBUG_UNUSED(uint64_t id) = DramExtension::getChannelPayloadID(transToRelease.payload); PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " left system."); + numberOfBeatsServed += DramExtension::getBurstLength(transToRelease.payload); transToRelease.payload->release(); transToRelease.payload = nullptr; - numberOfTransactionsServed++; totalNumberOfPayloads--; if (totalNumberOfPayloads == 0) diff --git a/DRAMSys/library/src/controller/ControllerIF.h b/DRAMSys/library/src/controller/ControllerIF.h index b23c3a2e..aebae208 100644 --- a/DRAMSys/library/src/controller/ControllerIF.h +++ b/DRAMSys/library/src/controller/ControllerIF.h @@ -55,8 +55,7 @@ public: // Destructor virtual ~ControllerIF() { - sc_time activeTime = numberOfTransactionsServed - * Configuration::getInstance().memSpec->burstLength + sc_time activeTime = numberOfBeatsServed / Configuration::getInstance().memSpec->dataRate * Configuration::getInstance().memSpec->tCK; @@ -143,7 +142,7 @@ protected: sc_time idleStart; } idleTimeCollector; - uint64_t numberOfTransactionsServed = 0; + uint64_t numberOfBeatsServed = 0; }; diff --git a/DRAMSys/library/src/controller/ControllerRecordable.cpp b/DRAMSys/library/src/controller/ControllerRecordable.cpp index 243d43e5..34350af4 100644 --- a/DRAMSys/library/src/controller/ControllerRecordable.cpp +++ b/DRAMSys/library/src/controller/ControllerRecordable.cpp @@ -130,9 +130,9 @@ void ControllerRecordable::controllerMethod() Controller::controllerMethod(); - uint64_t windowNumberOfTransactionsServed = numberOfTransactionsServed - lastNumberOfTransactionsServed; - lastNumberOfTransactionsServed = numberOfTransactionsServed; - sc_time windowActiveTime = windowNumberOfTransactionsServed * activeTimeMultiplier; + uint64_t windowNumberOfBeatsServed = numberOfBeatsServed - lastNumberOfBeatsServed; + lastNumberOfBeatsServed = numberOfBeatsServed; + sc_time windowActiveTime = windowNumberOfBeatsServed * activeTimeMultiplier; double windowAverageBandwidth = windowActiveTime / windowSizeTime; tlmRecorder->recordBandwidth(sc_time_stamp().to_seconds(), windowAverageBandwidth); } diff --git a/DRAMSys/library/src/controller/ControllerRecordable.h b/DRAMSys/library/src/controller/ControllerRecordable.h index c2efa334..9459cd12 100644 --- a/DRAMSys/library/src/controller/ControllerRecordable.h +++ b/DRAMSys/library/src/controller/ControllerRecordable.h @@ -66,10 +66,9 @@ private: std::vector windowAverageBufferDepth; sc_time lastTimeCalled = SC_ZERO_TIME; - uint64_t lastNumberOfTransactionsServed = 0; - sc_time activeTimeMultiplier = Configuration::getInstance().memSpec->burstLength - / Configuration::getInstance().memSpec->dataRate - * Configuration::getInstance().memSpec->tCK; + uint64_t lastNumberOfBeatsServed = 0; + sc_time activeTimeMultiplier = Configuration::getInstance().memSpec->tCK + / Configuration::getInstance().memSpec->dataRate; }; #endif // CONTROLLERRECORDABLE_H diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp index 67ee3b73..353c4ebf 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp @@ -41,7 +41,7 @@ CheckerDDR5::CheckerDDR5() if (memSpec == nullptr) SC_REPORT_FATAL("CheckerDDR5", "Wrong MemSpec chosen"); - lastScheduledByCommandAndDIMMRank = std::vector> + lastScheduledByCommandAndDimmRank = std::vector> (numberOfCommands(), std::vector(memSpec->numberOfDIMMRanks, sc_max_time())); lastScheduledByCommandAndPhysicalRank = std::vector> (numberOfCommands(), std::vector(memSpec->numberOfPhysicalRanks, sc_max_time())); @@ -59,7 +59,7 @@ CheckerDDR5::CheckerDDR5() last4ActivatesLogical = std::vector>(memSpec->numberOfLogicalRanks); last4ActivatesPhysical = std::vector>(memSpec->numberOfPhysicalRanks); - lastBurstLengthByCommandAndDIMMRank = std::vector> + lastBurstLengthByCommandAndDimmRank = std::vector> (4, std::vector(memSpec->numberOfDIMMRanks)); lastBurstLengthByCommandAndPhysicalRank = std::vector> (4, std::vector(memSpec->numberOfPhysicalRanks)); @@ -158,9 +158,9 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommand[Command::RD]; if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]) { - if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RD][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RD][dimmrank.ID()]) { - if (lastBurstLengthByCommandAndDIMMRank[Command::RD][dimmrank.ID()] == 32) + if (lastBurstLengthByCommandAndDimmRank[Command::RD][dimmrank.ID()] == 32) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr + tRD_BURST); // 16 tCK + tRTRS else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr); // 16 tCK + tRTRS @@ -204,9 +204,9 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommand[Command::RDA]; if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]) { - if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RDA][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RDA][dimmrank.ID()]) { - if (lastBurstLengthByCommandAndDIMMRank[Command::RDA][dimmrank.ID()] == 32) + if (lastBurstLengthByCommandAndDimmRank[Command::RDA][dimmrank.ID()] == 32) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr + tRD_BURST); // 16 tCK + tRTRS else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr); // 16 tCK + tRTRS @@ -262,9 +262,9 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommand[Command::WR]; if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]) { - if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WR][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WR][dimmrank.ID()]) { - if (lastBurstLengthByCommandAndDIMMRank[Command::WR][dimmrank.ID()] == 32) + if (lastBurstLengthByCommandAndDimmRank[Command::WR][dimmrank.ID()] == 32) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr + tWR_BURST); // + 8 tCK else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr); // + 8 tCK @@ -308,9 +308,9 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommand[Command::WRA]; if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]) { - if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WRA][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WRA][dimmrank.ID()]) { - if (lastBurstLengthByCommandAndDIMMRank[Command::WRA][dimmrank.ID()] == 32) + if (lastBurstLengthByCommandAndDimmRank[Command::WRA][dimmrank.ID()] == 32) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr + tWR_BURST); // + 8 tCK else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr); // + 8 tCK @@ -360,9 +360,9 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommand[Command::RD]; if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]) { - if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RD][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RD][dimmrank.ID()]) { - if (lastBurstLengthByCommandAndDIMMRank[Command::RD][dimmrank.ID()] == 32) + if (lastBurstLengthByCommandAndDimmRank[Command::RD][dimmrank.ID()] == 32) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr + tRD_BURST); // + 8 tCK else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr); // + 8 tCK @@ -406,9 +406,9 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommand[Command::RDA]; if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]) { - if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::RDA][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RDA][dimmrank.ID()]) { - if (lastBurstLengthByCommandAndDIMMRank[Command::RDA][dimmrank.ID()] == 32) + if (lastBurstLengthByCommandAndDimmRank[Command::RDA][dimmrank.ID()] == 32) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr + tRD_BURST); // + 8 tCK else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr); // + 8 tCK @@ -462,9 +462,9 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommand[Command::WR]; if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]) { - if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WR][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WR][dimmrank.ID()]) { - if (lastBurstLengthByCommandAndDIMMRank[Command::WR][dimmrank.ID()] == 32) + if (lastBurstLengthByCommandAndDimmRank[Command::WR][dimmrank.ID()] == 32) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr + tWR_BURST); // + 8 tCK else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr); // + 8 tCK @@ -518,9 +518,9 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommand[Command::WRA]; if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]) { - if (lastCommandStart == lastScheduledByCommandAndDIMMRank[Command::WRA][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WRA][dimmrank.ID()]) { - if (lastBurstLengthByCommandAndDIMMRank[Command::WRA][dimmrank.ID()] == 32) + if (lastBurstLengthByCommandAndDimmRank[Command::WRA][dimmrank.ID()] == 32) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr + tWR_BURST); // + 8 tCK else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr); // + 8 tCK @@ -755,7 +755,7 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dlr); - lastCommandStart = lastScheduledByCommandAndDIMMRank[Command::REFA][dimmrank.ID()]; + lastCommandStart = lastScheduledByCommandAndDimmRank[Command::REFA][dimmrank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dpr); @@ -805,7 +805,7 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dlr); // TODO: check this - lastCommandStart = lastScheduledByCommandAndDIMMRank[Command::REFA][dimmrank.ID()]; + lastCommandStart = lastScheduledByCommandAndDimmRank[Command::REFA][dimmrank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dpr); @@ -839,41 +839,41 @@ void CheckerDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank b PRINTDEBUGMESSAGE("CheckerDDR5", "Changing state on bank " + std::to_string(bank.ID()) + " command is " + commandToString(command)); - Rank logicalrank = rank; - Rank physicalrank = Rank(logicalrank.ID() / memSpec->logicalRanksPerPhysicalRank); - Rank dimmrank = Rank(physicalrank.ID() / memSpec->physicalRanksPerDIMMRank); - Bank bankingroup = Bank(rank.ID() * memSpec->banksPerGroup + bank.ID() % memSpec->banksPerGroup); + Rank logicalRank = rank; + Rank physicalRank = Rank(logicalRank.ID() / memSpec->logicalRanksPerPhysicalRank); + Rank dimmRank = Rank(physicalRank.ID() / memSpec->physicalRanksPerDIMMRank); + Bank bankInGroup = Bank(rank.ID() * memSpec->banksPerGroup + bank.ID() % memSpec->banksPerGroup); - lastScheduledByCommandAndDIMMRank[command][dimmrank.ID()] = sc_time_stamp(); - lastScheduledByCommandAndPhysicalRank[command][physicalrank.ID()] = sc_time_stamp(); - lastScheduledByCommandAndLogicalRank[command][logicalrank.ID()] = sc_time_stamp(); + lastScheduledByCommandAndDimmRank[command][dimmRank.ID()] = sc_time_stamp(); + lastScheduledByCommandAndPhysicalRank[command][physicalRank.ID()] = sc_time_stamp(); + lastScheduledByCommandAndLogicalRank[command][logicalRank.ID()] = sc_time_stamp(); lastScheduledByCommandAndBankGroup[command][bankgroup.ID()] = sc_time_stamp(); lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp(); lastScheduledByCommand[command] = sc_time_stamp(); lastCommandOnBus = sc_time_stamp() + memSpec->getCommandLength(command) - memSpec->tCK; - lastScheduledByCommandAndBankInGroup[command][bankingroup.ID()] = sc_time_stamp(); + lastScheduledByCommandAndBankInGroup[command][bankInGroup.ID()] = sc_time_stamp(); if (isCasCommand(command)) { - lastBurstLengthByCommandAndDIMMRank[command][dimmrank.ID()] = burstLength; - lastBurstLengthByCommandAndPhysicalRank[command][physicalrank.ID()] = burstLength; - lastBurstLengthByCommandAndLogicalRank[command][logicalrank.ID()] = burstLength; + lastBurstLengthByCommandAndDimmRank[command][dimmRank.ID()] = burstLength; + lastBurstLengthByCommandAndPhysicalRank[command][physicalRank.ID()] = burstLength; + lastBurstLengthByCommandAndLogicalRank[command][logicalRank.ID()] = burstLength; lastBurstLengthByCommandAndBankGroup[command][bankgroup.ID()] = burstLength; lastBurstLengthByCommandAndBank[command][bank.ID()] = burstLength; lastBurstLengthByCommand[command] = burstLength; - lastBurstLengthByCommandAndBankInGroup[command][bankingroup.ID()] = burstLength; + lastBurstLengthByCommandAndBankInGroup[command][bankInGroup.ID()] = burstLength; } if (command == Command::ACT || command == Command::REFSB) { - if (last4ActivatesLogical[logicalrank.ID()].size() == 4) - last4ActivatesLogical[logicalrank.ID()].pop(); - last4ActivatesLogical[logicalrank.ID()].push(lastCommandOnBus); + if (last4ActivatesLogical[logicalRank.ID()].size() == 4) + last4ActivatesLogical[logicalRank.ID()].pop(); + last4ActivatesLogical[logicalRank.ID()].push(lastCommandOnBus); - if (last4ActivatesPhysical[physicalrank.ID()].size() == 4) - last4ActivatesPhysical[physicalrank.ID()].pop(); - last4ActivatesPhysical[physicalrank.ID()].push(lastCommandOnBus); + if (last4ActivatesPhysical[physicalRank.ID()].size() == 4) + last4ActivatesPhysical[physicalRank.ID()].pop(); + last4ActivatesPhysical[physicalRank.ID()].push(lastCommandOnBus); } } diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR5.h b/DRAMSys/library/src/controller/checker/CheckerDDR5.h index ace723e4..263791f9 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR5.h +++ b/DRAMSys/library/src/controller/checker/CheckerDDR5.h @@ -52,7 +52,7 @@ public: private: const MemSpecDDR5 *memSpec; - std::vector> lastScheduledByCommandAndDIMMRank; + std::vector> lastScheduledByCommandAndDimmRank; std::vector> lastScheduledByCommandAndPhysicalRank; std::vector> lastScheduledByCommandAndLogicalRank; std::vector> lastScheduledByCommandAndBankGroup; @@ -65,7 +65,7 @@ private: std::vector> last4ActivatesPhysical; std::vector> last4ActivatesLogical; - std::vector> lastBurstLengthByCommandAndDIMMRank; + std::vector> lastBurstLengthByCommandAndDimmRank; std::vector> lastBurstLengthByCommandAndPhysicalRank; std::vector> lastBurstLengthByCommandAndLogicalRank; std::vector> lastBurstLengthByCommandAndBankGroup; diff --git a/DRAMSys/simulator/StlPlayer.cpp b/DRAMSys/simulator/StlPlayer.cpp index 4880b5b0..337480a3 100644 --- a/DRAMSys/simulator/StlPlayer.cpp +++ b/DRAMSys/simulator/StlPlayer.cpp @@ -55,7 +55,7 @@ StlPlayer::StlPlayer(sc_module_name name, SC_REPORT_FATAL("StlPlayer", (std::string("Could not open trace ") + pathToTrace).c_str()); this->playerClk = playerClk; - burstlength = Configuration::getInstance().memSpec->burstLength; + burstLength = Configuration::getInstance().memSpec->burstLength; dataLength = Configuration::getInstance().memSpec->bytesPerBurst; lineCnt = 0; @@ -96,7 +96,7 @@ void StlPlayer::nextPayload() payload->set_response_status(TLM_INCOMPLETE_RESPONSE); payload->set_dmi_allowed(false); payload->set_byte_enable_length(0); - payload->set_streaming_width(burstlength); + payload->set_streaming_width(burstLength); payload->set_data_length(dataLength); payload->set_command(lineIterator->cmd); std::copy(lineIterator->data.begin(), lineIterator->data.end(), payload->get_data_ptr()); diff --git a/DRAMSys/simulator/StlPlayer.h b/DRAMSys/simulator/StlPlayer.h index 27081d41..cacf37bf 100644 --- a/DRAMSys/simulator/StlPlayer.h +++ b/DRAMSys/simulator/StlPlayer.h @@ -75,7 +75,7 @@ private: std::ifstream file; uint64_t lineCnt; - unsigned int burstlength; + unsigned int burstLength; unsigned int dataLength; sc_time playerClk; // May be different from the memory clock! From 7e05226f8cf6e32cc9daf0b57ab7c388537f499d Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Tue, 11 May 2021 17:33:46 +0200 Subject: [PATCH 07/13] Add blocked interval for dummy CAS commands to DDR5 checker. --- .../src/controller/checker/CheckerDDR5.cpp | 17 +++++++++++++++++ .../src/controller/checker/CheckerDDR5.h | 2 ++ 2 files changed, 19 insertions(+) diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp index 353c4ebf..1c5620b4 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp @@ -56,6 +56,9 @@ CheckerDDR5::CheckerDDR5() lastScheduledByCommandAndBankInGroup = std::vector>(numberOfCommands(), std::vector(memSpec->numberOfRanks * memSpec->banksPerGroup, sc_max_time())); lastCommandOnBus = sc_max_time(); + dummyCommandOnBus.start = sc_max_time(); + dummyCommandOnBus.end = sc_max_time(); + last4ActivatesLogical = std::vector>(memSpec->numberOfLogicalRanks); last4ActivatesPhysical = std::vector>(memSpec->numberOfPhysicalRanks); @@ -831,6 +834,14 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandOnBus != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK); + if (dummyCommandOnBus.start != sc_max_time()) + { + TimeInterval currentCommandOnBus(earliestTimeToStart, + earliestTimeToStart + memSpec->getCommandLength(command)); + if (currentCommandOnBus.intersects(dummyCommandOnBus)) + earliestTimeToStart = dummyCommandOnBus.end; + } + return earliestTimeToStart; } @@ -864,6 +875,12 @@ void CheckerDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank b lastBurstLengthByCommandAndBank[command][bank.ID()] = burstLength; lastBurstLengthByCommand[command] = burstLength; lastBurstLengthByCommandAndBankInGroup[command][bankInGroup.ID()] = burstLength; + + if (burstLength == 32) + { + dummyCommandOnBus.start = sc_time_stamp() + tRD_BURST; + dummyCommandOnBus.end = sc_time_stamp() + tRD_BURST + memSpec->getCommandLength(command); + } } if (command == Command::ACT || command == Command::REFSB) diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR5.h b/DRAMSys/library/src/controller/checker/CheckerDDR5.h index 263791f9..01b23fcb 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR5.h +++ b/DRAMSys/library/src/controller/checker/CheckerDDR5.h @@ -40,6 +40,7 @@ #include #include "../../configuration/memspec/MemSpecDDR5.h" #include "../../configuration/Configuration.h" +#include "../../common/utils.h" class CheckerDDR5 final : public CheckerIF { @@ -59,6 +60,7 @@ private: std::vector> lastScheduledByCommandAndBank; std::vector lastScheduledByCommand; sc_time lastCommandOnBus; + TimeInterval dummyCommandOnBus; std::vector> lastScheduledByCommandAndBankInGroup; From d84a065087512fd215dc929c3c28d6e4769b8f22 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 12 May 2021 16:10:04 +0200 Subject: [PATCH 08/13] Small improvements in DDR5 checker. --- .gitignore | 2 + .../src/configuration/memspec/MemSpecDDR5.cpp | 24 +- .../src/configuration/memspec/MemSpecDDR5.h | 4 +- .../src/controller/checker/CheckerDDR5.cpp | 391 ++++++++---------- .../src/controller/checker/CheckerDDR5.h | 6 +- DRAMSys/library/src/simulation/Arbiter.cpp | 4 +- DRAMSys/library/src/simulation/Arbiter.h | 2 +- 7 files changed, 201 insertions(+), 232 deletions(-) diff --git a/.gitignore b/.gitignore index da990e0b..97b2ac1b 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,5 @@ DRAMSys/analyzer/scripts/__pycache__/ DRAMSys/gem5/boot_linux/linux-aarch32-ael.img DRAMSys/docs/doxygen /.vscode +/cmake-build* +/.idea diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp index fdd3f094..662464d2 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp @@ -110,8 +110,8 @@ MemSpecDDR5::MemSpecDDR5(json &memspec) tREFPDEN (tCK * parseUint(memspec["memtimingspec"]["REFPDEN"], "REFPDEN")), shortCmdOffset (cmdMode == 2 ? 1 * tCK : 0 * tCK), longCmdOffset (cmdMode == 2 ? 3 * tCK : 1 * tCK), - shortBurstDuration(tCK * 8), - longBurstDuration(tCK * 16) + tBURST16(tCK * 8), + tBURST32(tCK * 16) { if (cmdMode == 1) { @@ -168,25 +168,25 @@ sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload else if (command == Command::RD) { if (DramExtension::getBurstLength(payload) == 32) - return tRL + longBurstDuration + longCmdOffset; + return tRL + tBURST32 + longCmdOffset; else - return tRL + shortBurstDuration + longCmdOffset; + return tRL + tBURST16 + longCmdOffset; } else if (command == Command::RDA) return tRTP + tRP + longCmdOffset; else if (command == Command::WR) { if (DramExtension::getBurstLength(payload) == 32) - return tWL + longBurstDuration + longCmdOffset; + return tWL + tBURST32 + longCmdOffset; else - return tWL + shortBurstDuration + longCmdOffset; + return tWL + tBURST16 + longCmdOffset; } else if (command == Command::WRA) { if (DramExtension::getBurstLength(payload) == 32) - return tWL + longBurstDuration + tWR + tRP + longCmdOffset; + return tWL + tBURST32 + tWR + tRP + longCmdOffset; else - return tWL + shortBurstDuration + tWR + tRP + longCmdOffset; + return tWL + tBURST16 + tWR + tRP + longCmdOffset; } else if (command == Command::REFA) return tRFC_slr + shortCmdOffset; @@ -205,16 +205,16 @@ TimeInterval MemSpecDDR5::getIntervalOnDataStrobe(Command command, const tlm_gen if (command == Command::RD || command == Command::RDA) { if (DramExtension::getBurstLength(payload) == 32) - return TimeInterval(tRL + longCmdOffset, tRL + longBurstDuration + longCmdOffset); + return TimeInterval(tRL + longCmdOffset, tRL + tBURST32 + longCmdOffset); else - return TimeInterval(tRL + longCmdOffset, tRL + shortBurstDuration+ longCmdOffset); + return TimeInterval(tRL + longCmdOffset, tRL + tBURST16 + longCmdOffset); } else if (command == Command::WR || command == Command::WRA) { if (DramExtension::getBurstLength(payload) == 32) - return TimeInterval(tWL + longCmdOffset, tWL + longBurstDuration + longCmdOffset); + return TimeInterval(tWL + longCmdOffset, tWL + tBURST32 + longCmdOffset); else - return TimeInterval(tWL + longCmdOffset, tWL + shortBurstDuration + longCmdOffset); + return TimeInterval(tWL + longCmdOffset, tWL + tBURST16 + longCmdOffset); } else { diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h index 3de89eb9..40de44f1 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h @@ -103,8 +103,8 @@ public: const sc_time shortCmdOffset; const sc_time longCmdOffset; - const sc_time shortBurstDuration; - const sc_time longBurstDuration; + const sc_time tBURST16; + const sc_time tBURST32; // Currents and Voltages: // TODO: to be completed diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp index 1c5620b4..775008aa 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp @@ -76,41 +76,39 @@ CheckerDDR5::CheckerDDR5() lastBurstLengthByCommandAndBankInGroup = std::vector> (4, std::vector(memSpec->numberOfRanks * memSpec->banksPerGroup)); - cmdOffset = memSpec->cmdMode * memSpec->tCK; + cmdLengthDiff = memSpec->cmdMode * memSpec->tCK; - tRD_BURST = 8 * memSpec->tCK; - tWR_BURST = 8 * memSpec->tCK; + tBURST16 = 8 * memSpec->tCK; + tBURST32 = 16 * memSpec->tCK; tWTRA = memSpec->tWR - memSpec->tRTP; - tWRRDA = memSpec->tWL + tWR_BURST + tWTRA; // tWTRA = tWR - tRTP - tWRPRE = memSpec->tWL + tWR_BURST + memSpec->tWR; + tWRRDA = memSpec->tWL + tBURST16 + tWTRA; // tWTRA = tWR - tRTP + tWRPRE = memSpec->tWL + tBURST16 + memSpec->tWR; tRDAACT = memSpec->tRTP + memSpec->tRP; tWRAACT = tWRPRE + memSpec->tRP; - tCCD_L_RTW_slr = memSpec->tRL - memSpec->tWL + tRD_BURST + 2 * memSpec->tCK - - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; - tCCD_S_RTW_slr = memSpec->tRL - memSpec->tWL + tRD_BURST + 2 * memSpec->tCK - - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; - tCCD_RTW_dlr = memSpec->tRL - memSpec->tWL + tRD_BURST + 2 * memSpec->tCK - - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; - tRDRD_dpr = tRD_BURST + memSpec->tRTRS; - tRDRD_ddr = tRD_BURST + memSpec->tRTRS; - tRDWR_dpr = memSpec->tRL - memSpec->tWL + tRD_BURST + memSpec->tRTRS - - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; - tRDWR_ddr = memSpec->tRL - memSpec->tWL + tRD_BURST + memSpec->tRTRS - - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; - tCCD_L_WTR_slr = memSpec->tWL + tWR_BURST + memSpec->tWTR_L; - tCCD_S_WTR_slr = memSpec->tWL + tWR_BURST + memSpec->tWTR_S; - tCCD_WTR_dlr = memSpec->tWL + tWR_BURST + memSpec->tWTR_S; - tWRWR_dpr = std::max(memSpec->tCCD_WR_dpr, tWR_BURST + memSpec->tRTRS); - tWRWR_ddr = tWR_BURST + memSpec->tRTRS; - tWRRD_dpr = memSpec->tWL - memSpec->tRL + tWR_BURST + memSpec->tRTRS - + memSpec->tRDDQS + memSpec->tWPST + memSpec->tRPRE; - tWRRD_ddr = memSpec->tWL - memSpec->tRL + tWR_BURST + memSpec->tRTRS - + memSpec->tRDDQS + memSpec->tWPST + memSpec->tRPRE; - tRDPDEN = memSpec->tRL + tRD_BURST + cmdOffset; - tWRPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + cmdOffset; - tWRAPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + cmdOffset; - - // TODO: tRTP BL 32 (similar to LPDDR4) + tCCD_L_RTW_slr = memSpec->tRL - memSpec->tWL + tBURST16 + 2 * memSpec->tCK + - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; + tCCD_S_RTW_slr = memSpec->tRL - memSpec->tWL + tBURST16 + 2 * memSpec->tCK + - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; + tCCD_RTW_dlr = memSpec->tRL - memSpec->tWL + tBURST16 + 2 * memSpec->tCK + - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; + tRDRD_dpr = tBURST16 + memSpec->tRTRS; + tRDRD_ddr = tBURST16 + memSpec->tRTRS; + tRDWR_dpr = memSpec->tRL - memSpec->tWL + tBURST16 + memSpec->tRTRS + - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; + tRDWR_ddr = memSpec->tRL - memSpec->tWL + tBURST16 + memSpec->tRTRS + - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE; + tCCD_L_WTR_slr = memSpec->tWL + tBURST16 + memSpec->tWTR_L; + tCCD_S_WTR_slr = memSpec->tWL + tBURST16 + memSpec->tWTR_S; + tCCD_WTR_dlr = memSpec->tWL + tBURST16 + memSpec->tWTR_S; + tWRWR_dpr = std::max(memSpec->tCCD_WR_dpr, tBURST16 + memSpec->tRTRS); + tWRWR_ddr = tBURST16 + memSpec->tRTRS; + tWRRD_dpr = memSpec->tWL - memSpec->tRL + tBURST16 + memSpec->tRTRS + + memSpec->tRDDQS + memSpec->tWPST + memSpec->tRPRE; + tWRRD_ddr = memSpec->tWL - memSpec->tRL + tBURST16 + memSpec->tRTRS + + memSpec->tRDDQS + memSpec->tWPST + memSpec->tRPRE; + tRDPDEN = memSpec->tRL + tBURST16 + cmdLengthDiff; + tWRPDEN = memSpec->tWL + tBURST16 + memSpec->tWR + cmdLengthDiff; + tWRAPDEN = memSpec->tWL + tBURST16 + memSpec->tWR + cmdLengthDiff; } sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank, @@ -133,93 +131,73 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()]; if (lastCommandStart != sc_max_time()) - { - if (lastBurstLengthByCommandAndBankGroup[Command::RD][bankgroup.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 tCK - else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_slr); // 16 tCK - } + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_slr); lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - { - if (lastBurstLengthByCommandAndLogicalRank[Command::RD][logicalrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 tCK - else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_slr); // 16 tCK - } + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_slr); lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]; if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndPhysicalRank[Command::RD][physicalrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 tCK - else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_dlr); // 16 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST32); + + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_dlr); } lastCommandStart = lastScheduledByCommand[Command::RD]; - if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]) + if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]) // different physical rank { - if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RD][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RD][dimmrank.ID()]) // same DIMM { if (lastBurstLengthByCommandAndDimmRank[Command::RD][dimmrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr + tRD_BURST); // 16 tCK + tRTRS + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr); // 16 tCK + tRTRS + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr); } - else + else // different DIMM { - if (lastBurstLengthByCommandAndPhysicalRank[Command::RD][physicalrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr + tRD_BURST); // 16 tCK + tRTRS + if (lastBurstLengthByCommand[Command::RD] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr); // 16 tCK + tRTRS + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr); } } lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()]; if (lastCommandStart != sc_max_time()) - { - if (lastBurstLengthByCommandAndBankGroup[Command::RDA][bankgroup.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 tCK - else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_slr); // 16 tCK - } + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_slr); lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - { - if (lastBurstLengthByCommandAndBankGroup[Command::RDA][bankgroup.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 tCK - else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_slr); // 16 tCK - } + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_slr); lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]; if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 tCK - else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_dlr); // 16 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST32); + + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_dlr); } lastCommandStart = lastScheduledByCommand[Command::RDA]; - if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]) + if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]) // different physical rank { - if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RDA][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RDA][dimmrank.ID()]) // same DIMM { if (lastBurstLengthByCommandAndDimmRank[Command::RDA][dimmrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr + tRD_BURST); // 16 tCK + tRTRS + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr); // 16 tCK + tRTRS + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr); } - else + else // different DIMM { - if (lastBurstLengthByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr + tRD_BURST); // 16 tCK + tRTRS + if (lastBurstLengthByCommand[Command::RDA] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr); // 16 tCK + tRTRS + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr); } } @@ -229,9 +207,9 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndBank[Command::WR][bank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDA + tWR_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDA + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDA); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDA); } } @@ -239,45 +217,45 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankgroup.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr + tWR_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr); } lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndLogicalRank[Command::WR][logicalrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr + tWR_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr); } lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]; if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndPhysicalRank[Command::WR][physicalrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr + tWR_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr); } lastCommandStart = lastScheduledByCommand[Command::WR]; - if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]) + if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]) // different physical rank { - if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WR][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WR][dimmrank.ID()]) // same DIMM { if (lastBurstLengthByCommandAndDimmRank[Command::WR][dimmrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr + tWR_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr); } - else + else // different DIMM { if (lastBurstLengthByCommand[Command::WR] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr + tWR_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr); } } @@ -285,45 +263,45 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndBankGroup[Command::WRA][bankgroup.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr + tWR_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr); } lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndLogicalRank[Command::WRA][logicalrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr + tWR_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr); } lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]; if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr + tWR_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr); } lastCommandStart = lastScheduledByCommand[Command::WRA]; - if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]) + if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]) // different physical rank { - if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WRA][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WRA][dimmrank.ID()]) // same DIMM { if (lastBurstLengthByCommandAndDimmRank[Command::WRA][dimmrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr + tWR_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr); } - else + else // different DIMM { if (lastBurstLengthByCommand[Command::WRA] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr + tWR_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr); } } } @@ -337,45 +315,45 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndBankGroup[Command::RD][bankgroup.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr + tRD_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr); } lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndLogicalRank[Command::RD][logicalrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr + tRD_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr); } lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]; if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndPhysicalRank[Command::RD][physicalrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr + tRD_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr); } lastCommandStart = lastScheduledByCommand[Command::RD]; - if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]) + if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()]) // different physical rank { - if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RD][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RD][dimmrank.ID()]) // same DIMM { if (lastBurstLengthByCommandAndDimmRank[Command::RD][dimmrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr + tRD_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr); } - else + else // different DIMM { if (lastBurstLengthByCommand[Command::RD] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr + tRD_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr); } } @@ -383,45 +361,45 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndBankGroup[Command::RDA][bankgroup.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr + tRD_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr); } lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndLogicalRank[Command::RDA][logicalrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr + tRD_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr); } lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]; if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr + tRD_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr); } lastCommandStart = lastScheduledByCommand[Command::RDA]; - if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]) + if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]) // different physical rank { - if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RDA][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RDA][dimmrank.ID()]) // same DIMM { if (lastBurstLengthByCommandAndDimmRank[Command::RDA][dimmrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr + tRD_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr); } - else + else // different DIMM { if (lastBurstLengthByCommand[Command::RDA] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr + tRD_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr); } } @@ -430,14 +408,14 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr { if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankgroup.ID()] == 32) { - if (burstLength == 16 && memSpec->bitWidth == 4) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWR_BURST + memSpec->tCCD_L_WR_slr); + if (burstLength == 16 && memSpec->bitWidth == 4) // second WR requires RMW + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_L_WR_slr); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWR_BURST + memSpec->tCCD_L_WR2_slr); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_L_WR2_slr); } else { - if (burstLength == 16 && memSpec->bitWidth == 4) + if (burstLength == 16 && memSpec->bitWidth == 4) // second WR requires RMW earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr); else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR2_slr); @@ -446,38 +424,33 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - { - if (lastBurstLengthByCommandAndLogicalRank[Command::WR][logicalrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 clocks - else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_WR_slr); // 16 clocks - } + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_WR_slr); lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]; if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndPhysicalRank[Command::WR][physicalrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 clocks - else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_WR_dlr); // 16 clocks + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST32); + + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_WR_dlr); } lastCommandStart = lastScheduledByCommand[Command::WR]; - if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]) + if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()]) // different physical rank { - if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WR][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WR][dimmrank.ID()]) // same DIMM { if (lastBurstLengthByCommandAndDimmRank[Command::WR][dimmrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr + tWR_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr); } - else + else // different DIMM { if (lastBurstLengthByCommand[Command::WR] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr + tWR_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr); } } @@ -486,14 +459,14 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr { if (lastBurstLengthByCommandAndBankGroup[Command::WRA][bankgroup.ID()] == 32) { - if (burstLength == 16 && memSpec->bitWidth == 4) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWR_BURST + memSpec->tCCD_L_WR_slr); + if (burstLength == 16 && memSpec->bitWidth == 4) // second WR requires RMW + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_L_WR_slr); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWR_BURST + memSpec->tCCD_L_WR2_slr); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_L_WR2_slr); } else { - if (burstLength == 16 && memSpec->bitWidth == 4) + if (burstLength == 16 && memSpec->bitWidth == 4) // second WR requires RMW earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr); else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR2_slr); @@ -502,38 +475,33 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - { - if (lastBurstLengthByCommandAndLogicalRank[Command::WRA][logicalrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 clocks - else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_WR_slr); // 16 clocks - } + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_WR_slr); lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]; if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 clocks - else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_WR_dlr); // 16 clocks + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST32); + + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_WR_dlr); } lastCommandStart = lastScheduledByCommand[Command::WRA]; - if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]) + if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()]) // different physical rank { - if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WRA][dimmrank.ID()]) + if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WRA][dimmrank.ID()]) // same DIMM { if (lastBurstLengthByCommandAndDimmRank[Command::WRA][dimmrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr + tWR_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr); } - else + else // different DIMM { if (lastBurstLengthByCommand[Command::WRA] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr + tWR_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr); } } } @@ -563,42 +531,42 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndBank[Command::WRA][bank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + tWR_BURST); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT); } lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdOffset); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdLengthDiff); lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::PREA][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdOffset); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdLengthDiff); lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRESB][bankInGroup.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdOffset); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdLengthDiff); lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFA][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr - cmdOffset); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr - cmdLengthDiff); // TODO: No tRFC_dlr and tRFC_dpr between REFA and ACT? lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::REFSB][bankInGroup.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCsb_slr - cmdOffset); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCsb_slr - cmdLengthDiff); // TODO: No tRFCsb_dlr between REFSB and ACT? lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFSB][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_slr - cmdOffset); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_slr - cmdLengthDiff); lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::REFSB][physicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_dlr - cmdOffset); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_dlr - cmdLengthDiff); if (last4ActivatesLogical[logicalrank.ID()].size() >= 4) earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesLogical[logicalrank.ID()].front() @@ -612,19 +580,19 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr { lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + cmdOffset); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + cmdLengthDiff); lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdOffset); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdLengthDiff); lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndBank[Command::WR][bank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tWR_BURST + cmdOffset); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tBURST16 + cmdLengthDiff); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdOffset); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdLengthDiff); } lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()]; @@ -643,32 +611,32 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr { lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + cmdOffset); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + cmdLengthDiff); lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdOffset); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdLengthDiff); lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdOffset); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdLengthDiff); lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndLogicalRank[Command::WR][logicalrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tWR_BURST + cmdOffset); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tBURST16 + cmdLengthDiff); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdOffset); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdLengthDiff); } lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndLogicalRank[Command::WRA][logicalrank.ID()]) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tWR_BURST + cmdOffset); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tBURST16 + cmdLengthDiff); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdOffset); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdLengthDiff); } lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()]; @@ -685,32 +653,32 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr { lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::ACT][bankInGroup.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + cmdOffset); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + cmdLengthDiff); lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RD][bankInGroup.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdOffset); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdLengthDiff); lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RDA][bankInGroup.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdOffset); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdLengthDiff); lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WR][bankInGroup.ID()]; if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndBankInGroup[Command::WR][bankInGroup.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tWR_BURST + cmdOffset); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tBURST16 + cmdLengthDiff); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdOffset); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdLengthDiff); } lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()]; if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tWR_BURST + cmdOffset); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tBURST16 + cmdLengthDiff); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdOffset); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdLengthDiff); } lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()]; @@ -727,19 +695,19 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr { lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + cmdOffset); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + cmdLengthDiff); lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + cmdOffset); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + cmdLengthDiff); lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndLogicalRank[Command::WRA][logicalrank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tWR_BURST + memSpec->tRP + cmdOffset); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tBURST16 + memSpec->tRP + cmdLengthDiff); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP + cmdOffset); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP + cmdLengthDiff); } lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::PRE][logicalrank.ID()]; @@ -769,23 +737,23 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr { lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::ACT][bankInGroup.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + cmdOffset); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + cmdLengthDiff); lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L_slr + cmdOffset); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L_slr + cmdLengthDiff); lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RDA][bankInGroup.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + cmdOffset); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + cmdLengthDiff); lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()]; if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + tWR_BURST + cmdOffset); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + tBURST16 + cmdLengthDiff); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + cmdOffset); // + 8 tCK + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + cmdLengthDiff); } lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRE][bankInGroup.ID()]; @@ -861,9 +829,6 @@ void CheckerDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank b lastScheduledByCommandAndBankGroup[command][bankgroup.ID()] = sc_time_stamp(); lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp(); lastScheduledByCommand[command] = sc_time_stamp(); - - lastCommandOnBus = sc_time_stamp() + memSpec->getCommandLength(command) - memSpec->tCK; - lastScheduledByCommandAndBankInGroup[command][bankInGroup.ID()] = sc_time_stamp(); if (isCasCommand(command)) @@ -878,11 +843,13 @@ void CheckerDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank b if (burstLength == 32) { - dummyCommandOnBus.start = sc_time_stamp() + tRD_BURST; - dummyCommandOnBus.end = sc_time_stamp() + tRD_BURST + memSpec->getCommandLength(command); + dummyCommandOnBus.start = sc_time_stamp() + tBURST16; + dummyCommandOnBus.end = sc_time_stamp() + tBURST16 + memSpec->getCommandLength(command); } } + lastCommandOnBus = sc_time_stamp() + memSpec->getCommandLength(command) - memSpec->tCK; + if (command == Command::ACT || command == Command::REFSB) { if (last4ActivatesLogical[logicalRank.ID()].size() == 4) diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR5.h b/DRAMSys/library/src/controller/checker/CheckerDDR5.h index 01b23fcb..7717b052 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR5.h +++ b/DRAMSys/library/src/controller/checker/CheckerDDR5.h @@ -78,10 +78,10 @@ private: // TODO: store BL of last RD and WR globally or for each hierarchy? - sc_time cmdOffset; + sc_time cmdLengthDiff; - sc_time tRD_BURST; - sc_time tWR_BURST; + sc_time tBURST16; + sc_time tBURST32; sc_time tWTRA; sc_time tWRRDA; sc_time tWRPRE; diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp index bd8f0baa..05aaacab 100644 --- a/DRAMSys/library/src/simulation/Arbiter.cpp +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -55,7 +55,7 @@ Arbiter::Arbiter(sc_module_name name, std::string pathToAddressMapping) : addressDecoder = new AddressDecoder(pathToAddressMapping); addressDecoder->print(); - burstLengthShift = std::log2(Configuration::getInstance().memSpec->dataBusWidth / 8); + bytesPerBeat = Configuration::getInstance().memSpec->dataBusWidth / 8; } ArbiterSimple::ArbiterSimple(sc_module_name name, std::string pathToAddressMapping) : @@ -142,7 +142,7 @@ tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload &payload, Channel(decodedAddress.channel), Rank(decodedAddress.rank), BankGroup(decodedAddress.bankgroup), Bank(decodedAddress.bank), Row(decodedAddress.row), Column(decodedAddress.column), - payload.get_data_length() >> burstLengthShift, 0, 0); + payload.get_data_length() / bytesPerBeat, 0, 0); payload.acquire(); } diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index ebd2d3bf..8b3f9b44 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -88,7 +88,7 @@ protected: sc_time arbitrationDelayFw; sc_time arbitrationDelayBw; - unsigned burstLengthShift; + unsigned bytesPerBeat; }; class ArbiterSimple final : public Arbiter From 77b79aac13a6396aa6064aab41da73f0e87f0f30 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Mon, 17 May 2021 14:03:34 +0200 Subject: [PATCH 09/13] Initial version of STT-MRAM. --- DRAMSys/library/CMakeLists.txt | 3 + .../src/configuration/Configuration.cpp | 3 + .../src/configuration/memspec/MemSpec.h | 3 +- .../configuration/memspec/MemSpecSTTMRAM.cpp | 141 ++++++ .../configuration/memspec/MemSpecSTTMRAM.h | 85 ++++ DRAMSys/library/src/controller/Controller.cpp | 3 + .../src/controller/checker/CheckerSTTMRAM.cpp | 432 ++++++++++++++++++ .../src/controller/checker/CheckerSTTMRAM.h | 74 +++ DRAMSys/library/src/simulation/DRAMSys.cpp | 3 + .../src/simulation/DRAMSysRecordable.cpp | 3 + .../src/simulation/dram/DramRecordable.cpp | 2 + .../src/simulation/dram/DramSTTMRAM.cpp | 52 +++ .../library/src/simulation/dram/DramSTTMRAM.h | 50 ++ 13 files changed, 853 insertions(+), 1 deletion(-) create mode 100644 DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.cpp create mode 100644 DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h create mode 100644 DRAMSys/library/src/controller/checker/CheckerSTTMRAM.cpp create mode 100644 DRAMSys/library/src/controller/checker/CheckerSTTMRAM.h create mode 100644 DRAMSys/library/src/simulation/dram/DramSTTMRAM.cpp create mode 100644 DRAMSys/library/src/simulation/dram/DramSTTMRAM.h diff --git a/DRAMSys/library/CMakeLists.txt b/DRAMSys/library/CMakeLists.txt index bf784fb5..165a3e54 100644 --- a/DRAMSys/library/CMakeLists.txt +++ b/DRAMSys/library/CMakeLists.txt @@ -97,6 +97,7 @@ add_library(DRAMSysLibrary src/configuration/memspec/MemSpecGDDR5X.cpp src/configuration/memspec/MemSpecGDDR6.cpp src/configuration/memspec/MemSpecHBM2.cpp + src/configuration/memspec/MemSpecSTTMRAM.cpp src/controller/BankMachine.cpp src/controller/Command.cpp @@ -114,6 +115,7 @@ add_library(DRAMSysLibrary src/controller/checker/CheckerGDDR5X.cpp src/controller/checker/CheckerGDDR6.cpp src/controller/checker/CheckerHBM2.cpp + src/controller/checker/CheckerSTTMRAM.cpp src/controller/cmdmux/CmdMuxIF.h src/controller/cmdmux/CmdMuxOldest.cpp @@ -168,6 +170,7 @@ add_library(DRAMSysLibrary src/simulation/dram/DramGDDR5X.cpp src/simulation/dram/DramGDDR6.cpp src/simulation/dram/DramHBM2.cpp + src/simulation/dram/DramSTTMRAM.cpp ${RECORDING_SOURCES} diff --git a/DRAMSys/library/src/configuration/Configuration.cpp b/DRAMSys/library/src/configuration/Configuration.cpp index cdcee1af..065aee78 100644 --- a/DRAMSys/library/src/configuration/Configuration.cpp +++ b/DRAMSys/library/src/configuration/Configuration.cpp @@ -51,6 +51,7 @@ #include "memspec/MemSpecGDDR5.h" #include "memspec/MemSpecGDDR5X.h" #include "memspec/MemSpecGDDR6.h" +#include "memspec/MemSpecSTTMRAM.h" using json = nlohmann::json; @@ -357,6 +358,8 @@ void Configuration::loadMemSpec(Configuration &config, std::string memspecUri) memSpec = new MemSpecGDDR5X(jMemSpec); else if (memoryType == "GDDR6") memSpec = new MemSpecGDDR6(jMemSpec); + else if (memoryType == "STT-MRAM") + memSpec = new MemSpecSTTMRAM(jMemSpec); else SC_REPORT_FATAL("Configuration", "Unsupported DRAM type"); } diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.h b/DRAMSys/library/src/configuration/memspec/MemSpec.h index 82c1987d..3e5c0c1f 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.h @@ -69,7 +69,8 @@ public: const sc_time tCK; const std::string memoryId; - const enum class MemoryType {DDR3, DDR4, DDR5, LPDDR4, WideIO, WideIO2, GDDR5, GDDR5X, GDDR6, HBM2} memoryType; + const enum class MemoryType {DDR3, DDR4, DDR5, LPDDR4, WideIO, + WideIO2, GDDR5, GDDR5X, GDDR6, HBM2, STTMRAM} memoryType; virtual ~MemSpec() {} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.cpp new file mode 100644 index 00000000..bab51776 --- /dev/null +++ b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2021, Technische Universität Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Lukas Steiner + */ + +#include "MemSpecSTTMRAM.h" + +using namespace tlm; +using json = nlohmann::json; + +MemSpecSTTMRAM::MemSpecSTTMRAM(json &memspec) + : MemSpec(memspec, MemoryType::STTMRAM, + parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"), + parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), + parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), + 1, + parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), + parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks") + * parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), + parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), + parseUint(memspec["memarchitecturespec"]["nbrOfDevicesOnDIMM"],"nbrOfDevicesOnDIMM")), + tCKE (tCK * parseUint(memspec["memtimingspec"]["CKE"], "CKE")), + tPD (tCKE), + tCKESR (tCK * parseUint(memspec["memtimingspec"]["CKESR"], "CKESR")), + tDQSCK (tCK * parseUint(memspec["memtimingspec"]["DQSCK"], "DQSCK")), + tRAS (tCK * parseUint(memspec["memtimingspec"]["RAS"], "RAS")), + tRC (tCK * parseUint(memspec["memtimingspec"]["RC"], "RC")), + tRCD (tCK * parseUint(memspec["memtimingspec"]["RCD"], "RCD")), + tRL (tCK * parseUint(memspec["memtimingspec"]["RL"], "RL")), + tRTP (tCK * parseUint(memspec["memtimingspec"]["RTP"], "RTP")), + tWL (tCK * parseUint(memspec["memtimingspec"]["WL"], "WL")), + tWR (tCK * parseUint(memspec["memtimingspec"]["WR"], "WR")), + tXP (tCK * parseUint(memspec["memtimingspec"]["XP"], "XP")), + tXS (tCK * parseUint(memspec["memtimingspec"]["XS"], "XS")), + tCCD (tCK * parseUint(memspec["memtimingspec"]["CCD"], "CCD")), + tFAW (tCK * parseUint(memspec["memtimingspec"]["FAW"], "FAW")), + tREFI (tCK * parseUint(memspec["memtimingspec"]["REFI"], "REFI")), + tRFC (tCK * parseUint(memspec["memtimingspec"]["RFC"], "RFC")), + tRP (tCK * parseUint(memspec["memtimingspec"]["RP"], "RP")), + tRRD (tCK * parseUint(memspec["memtimingspec"]["RRD"], "RRD")), + tWTR (tCK * parseUint(memspec["memtimingspec"]["WTR"], "WTR")), + tAL (tCK * parseUint(memspec["memtimingspec"]["AL"], "AL")), + tXPDLL (tCK * parseUint(memspec["memtimingspec"]["XPDLL"], "XPDLL")), + tXSDLL (tCK * parseUint(memspec["memtimingspec"]["XSDLL"], "XSDLL")), + tACTPDEN (tCK * parseUint(memspec["memtimingspec"]["ACTPDEN"], "ACTPDEN")), + tPRPDEN (tCK * parseUint(memspec["memtimingspec"]["PRPDEN"], "PRPDEN")), + tREFPDEN (tCK * parseUint(memspec["memtimingspec"]["REFPDEN"], "REFPDEN")), + tRTRS (tCK * parseUint(memspec["memtimingspec"]["RTRS"], "RTRS")) +{} + +// Returns the execution time for commands that have a fixed execution time +sc_time MemSpecSTTMRAM::getExecutionTime(Command command, const tlm_generic_payload &) const +{ + if (command == Command::PRE || command == Command::PREA) + return tRP; + else if (command == Command::ACT) + return tRCD; + else if (command == Command::RD) + return tRL + burstDuration; + else if (command == Command::RDA) + return tRTP + tRP; + else if (command == Command::WR) + return tWL + burstDuration; + else if (command == Command::WRA) + return tWL + burstDuration + tWR + tRP; + else if (command == Command::REFA) + return tRFC; + else + { + SC_REPORT_FATAL("getExecutionTime", + "command not known or command doesn't have a fixed execution time"); + return SC_ZERO_TIME; + } +} + +TimeInterval MemSpecSTTMRAM::getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &) const +{ + if (command == Command::RD || command == Command::RDA) + return TimeInterval(tRL, tRL + burstDuration); + else if (command == Command::WR || command == Command::WRA) + return TimeInterval(tWL, tWL + burstDuration); + else + { + SC_REPORT_FATAL("MemSpec", "Method was called with invalid argument"); + return TimeInterval(); + } +} + +uint64_t MemSpecSTTMRAM::getSimMemSizeInBytes() const +{ + uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; + uint64_t deviceSizeBytes = deviceSizeBits / 8; + uint64_t memorySizeBytes = deviceSizeBytes * numberOfDevicesOnDIMM * numberOfRanks; + + std::cout << headline << std::endl; + std::cout << "Per Channel Configuration:" << std::endl << std::endl; + std::cout << " Memory type: " << "STT-MRAM" << std::endl; + std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl; + std::cout << " Ranks: " << numberOfRanks << std::endl; + std::cout << " Banks per rank: " << banksPerRank << std::endl; + std::cout << " Rows per bank: " << numberOfRows << std::endl; + std::cout << " Columns per row: " << numberOfColumns << std::endl; + std::cout << " Device width in bits: " << bitWidth << std::endl; + std::cout << " Device size in bits: " << deviceSizeBits << std::endl; + std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl; + std::cout << " Devices on DIMM: " << numberOfDevicesOnDIMM << std::endl; + std::cout << std::endl; + + assert(memorySizeBytes > 0); + return memorySizeBytes; +} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h new file mode 100644 index 00000000..a8a5753f --- /dev/null +++ b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021, Technische Universität Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Lukas Steiner + */ + +#ifndef MEMSPECSTTMRAM_H +#define MEMSPECSTTMRAM_H + +#include "MemSpec.h" +#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp" + +class MemSpecSTTMRAM final : public MemSpec +{ +public: + MemSpecSTTMRAM(nlohmann::json &memspec); + + // Memspec Variables: + const sc_time tCKE; + const sc_time tPD; + const sc_time tCKESR; + const sc_time tRAS; + const sc_time tRC; + const sc_time tRCD; + const sc_time tRL; + const sc_time tRTP; + const sc_time tWL; + const sc_time tWR; + const sc_time tXP; + const sc_time tXS; + const sc_time tREFI; + const sc_time tRFC; + const sc_time tRP; + const sc_time tDQSCK; + const sc_time tCCD; + const sc_time tFAW; + const sc_time tRRD; + const sc_time tWTR; + const sc_time tXPDLL; + const sc_time tXSDLL; + const sc_time tAL; + const sc_time tACTPDEN; + const sc_time tPRPDEN; + const sc_time tREFPDEN; + const sc_time tRTRS; + + // Currents and Voltages: + // TODO: to be completed + + virtual sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override; + virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override; + + virtual uint64_t getSimMemSizeInBytes() const override; +}; + +#endif // MEMSPECSTTMRAM_H diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index 45b04c39..c9c93f05 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -47,6 +47,7 @@ #include "checker/CheckerGDDR5.h" #include "checker/CheckerGDDR5X.h" #include "checker/CheckerGDDR6.h" +#include "checker/CheckerSTTMRAM.h" #include "scheduler/SchedulerFifo.h" #include "scheduler/SchedulerFrFcfs.h" #include "scheduler/SchedulerFrFcfsGrp.h" @@ -102,6 +103,8 @@ Controller::Controller(sc_module_name name) : checker = new CheckerGDDR5X(); else if (memSpec->memoryType == MemSpec::MemoryType::GDDR6) checker = new CheckerGDDR6(); + else if (memSpec->memoryType == MemSpec::MemoryType::STTMRAM) + checker = new CheckerSTTMRAM(); // instantiate scheduler and command mux if (config.scheduler == Configuration::Scheduler::Fifo) diff --git a/DRAMSys/library/src/controller/checker/CheckerSTTMRAM.cpp b/DRAMSys/library/src/controller/checker/CheckerSTTMRAM.cpp new file mode 100644 index 00000000..99c00fe5 --- /dev/null +++ b/DRAMSys/library/src/controller/checker/CheckerSTTMRAM.cpp @@ -0,0 +1,432 @@ +/* + * Copyright (c) 2021, Technische Universität Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Author: Lukas Steiner + */ + +#include "CheckerSTTMRAM.h" + +CheckerSTTMRAM::CheckerSTTMRAM() +{ + Configuration &config = Configuration::getInstance(); + memSpec = dynamic_cast(config.memSpec); + if (memSpec == nullptr) + SC_REPORT_FATAL("CheckerSTTMRAM", "Wrong MemSpec chosen"); + + lastScheduledByCommandAndBank = std::vector> + (numberOfCommands(), std::vector(memSpec->numberOfBanks, sc_max_time())); + lastScheduledByCommandAndRank = std::vector> + (numberOfCommands(), std::vector(memSpec->numberOfRanks, sc_max_time())); + lastScheduledByCommand = std::vector(numberOfCommands(), sc_max_time()); + lastCommandOnBus = sc_max_time(); + last4Activates = std::vector>(memSpec->numberOfRanks); + + tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; + tRDWR = memSpec->tRL + tBURST + 2 * memSpec->tCK - memSpec->tWL; + tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL; + tWRRD = memSpec->tWL + tBURST + memSpec->tWTR; + tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL; + tWRPRE = memSpec->tWL + tBURST + memSpec->tWR; + tRDPDEN = memSpec->tRL + tBURST + memSpec->tCK; + tWRPDEN = memSpec->tWL + tBURST + memSpec->tWR; + tWRAPDEN = memSpec->tWL + tBURST + memSpec->tWR + memSpec->tCK; +} + +sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank, unsigned) const +{ + sc_time lastCommandStart; + sc_time earliestTimeToStart = sc_time_stamp(); + + if (command == Command::RD || command == Command::RDA) + { + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); + + lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : sc_max_time(); + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); + + lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : sc_max_time(); + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + if (command == Command::RDA) + { + lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP); + } + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD); + + lastCommandStart = lastScheduledByCommand[Command::WR]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD); + + lastCommandStart = lastScheduledByCommand[Command::WRA]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL); + } + else if (command == Command::WR || command == Command::WRA) + { + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR); + + lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : sc_max_time(); + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR); + + lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : sc_max_time(); + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); + + lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : sc_max_time(); + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); + + lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : sc_max_time(); + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL); + } + else if (command == Command::ACT) + { + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD); + + lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); + + if (last4Activates[rank.ID()].size() >= 4) + earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW); + } + else if (command == Command::PRE) + { + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); + + lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP); + + lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + } + else if (command == Command::PREA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + } + else if (command == Command::REFA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); + } + else if (command == Command::PDEA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tACTPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + } + else if (command == Command::PDXA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD); + } + else if (command == Command::PDEP) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); + } + else if (command == Command::PDXP) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD); + } + else if (command == Command::SREFEN) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, memSpec->tAL + memSpec->tRTP + memSpec->tRP)); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRP)); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); + } + else if (command == Command::SREFEX) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR); + } + else + SC_REPORT_FATAL("CheckerSTTMRAM", "Unknown command!"); + + if (lastCommandOnBus != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK); + + return earliestTimeToStart; +} + +void CheckerSTTMRAM::insert(Command command, Rank rank, BankGroup, Bank bank, unsigned) +{ + PRINTDEBUGMESSAGE("CheckerSTTMRAM", "Changing state on bank " + std::to_string(bank.ID()) + + " command is " + commandToString(command)); + + lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp(); + lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp(); + lastScheduledByCommand[command] = sc_time_stamp(); + + lastCommandOnBus = sc_time_stamp(); + + if (command == Command::ACT) + { + if (last4Activates[rank.ID()].size() == 4) + last4Activates[rank.ID()].pop(); + last4Activates[rank.ID()].push(sc_time_stamp()); + } +} diff --git a/DRAMSys/library/src/controller/checker/CheckerSTTMRAM.h b/DRAMSys/library/src/controller/checker/CheckerSTTMRAM.h new file mode 100644 index 00000000..50d48d53 --- /dev/null +++ b/DRAMSys/library/src/controller/checker/CheckerSTTMRAM.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2021, Technische Universität Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Author: Lukas Steiner + */ + +#ifndef CHECKERSTTMRAM_H +#define CHECKERSTTMRAM_H + +#include "CheckerIF.h" +#include +#include +#include "../../configuration/memspec/MemSpecSTTMRAM.h" +#include "../../configuration/Configuration.h" + +class CheckerSTTMRAM final : public CheckerIF +{ +public: + CheckerSTTMRAM(); + virtual sc_time timeToSatisfyConstraints(Command, Rank = Rank(0), + BankGroup = BankGroup(0), Bank = Bank(0), unsigned burstLength = 0) const override; + virtual void insert(Command, Rank, BankGroup, Bank, unsigned) override; + +private: + const MemSpecSTTMRAM *memSpec; + + std::vector> lastScheduledByCommandAndBank; + std::vector> lastScheduledByCommandAndRank; + std::vector lastScheduledByCommand; + sc_time lastCommandOnBus; + + // Four activate window + std::vector> last4Activates; + + sc_time tBURST; + sc_time tRDWR; + sc_time tRDWR_R; + sc_time tWRRD; + sc_time tWRPRE; + sc_time tWRRD_R; + sc_time tRDPDEN; + sc_time tWRPDEN; + sc_time tWRAPDEN; +}; + +#endif // CHECKERSTTMRAM_H diff --git a/DRAMSys/library/src/simulation/DRAMSys.cpp b/DRAMSys/library/src/simulation/DRAMSys.cpp index 1e76d1d9..395f4742 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -59,6 +59,7 @@ #include "dram/DramGDDR5.h" #include "dram/DramGDDR5X.h" #include "dram/DramGDDR6.h" +#include "dram/DramSTTMRAM.h" #include "../controller/Controller.h" DRAMSys::DRAMSys(sc_module_name name, @@ -231,6 +232,8 @@ void DRAMSys::instantiateModules(const std::string &pathToResources, dram = new DramGDDR5X(str.c_str()); else if (memoryType == MemSpec::MemoryType::GDDR6) dram = new DramGDDR6(str.c_str()); + else if (memoryType == MemSpec::MemoryType::STTMRAM) + dram = new DramSTTMRAM(str.c_str()); drams.push_back(dram); diff --git a/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp b/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp index cdc0caf5..25a89d5c 100644 --- a/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp +++ b/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp @@ -46,6 +46,7 @@ #include "dram/DramGDDR5.h" #include "dram/DramGDDR5X.h" #include "dram/DramGDDR6.h" +#include "dram/DramSTTMRAM.h" #include "../common/TlmRecorder.h" #include "../simulation/TemperatureController.h" #include "../error/ecchamming.h" @@ -172,6 +173,8 @@ void DRAMSysRecordable::instantiateModules(const std::string &traceName, dram = new DramRecordable(str.c_str(), tlmRecorders[i]); else if (memoryType == MemSpec::MemoryType::GDDR6) dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + else if (memoryType == MemSpec::MemoryType::STTMRAM) + dram = new DramRecordable(str.c_str(), tlmRecorders[i]); drams.push_back(dram); diff --git a/DRAMSys/library/src/simulation/dram/DramRecordable.cpp b/DRAMSys/library/src/simulation/dram/DramRecordable.cpp index 4c6701ce..5167bccf 100644 --- a/DRAMSys/library/src/simulation/dram/DramRecordable.cpp +++ b/DRAMSys/library/src/simulation/dram/DramRecordable.cpp @@ -49,6 +49,7 @@ #include "DramGDDR5.h" #include "DramGDDR5X.h" #include "DramGDDR6.h" +#include "DramSTTMRAM.h" using namespace tlm; @@ -156,3 +157,4 @@ template class DramRecordable; template class DramRecordable; template class DramRecordable; template class DramRecordable; +template class DramRecordable; diff --git a/DRAMSys/library/src/simulation/dram/DramSTTMRAM.cpp b/DRAMSys/library/src/simulation/dram/DramSTTMRAM.cpp new file mode 100644 index 00000000..3680ce05 --- /dev/null +++ b/DRAMSys/library/src/simulation/dram/DramSTTMRAM.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021, Technische Universität Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Lukas Steiner + */ + +#include "DramSTTMRAM.h" + +#include "Dram.h" +#include "../../configuration/Configuration.h" +#include "../../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h" +#include "../../configuration/memspec/MemSpecSTTMRAM.h" + +using namespace DRAMPower; + +DramSTTMRAM::DramSTTMRAM(sc_module_name name) : Dram(name) +{ + if (storeMode == Configuration::StoreMode::ErrorModel) + SC_REPORT_FATAL("DramSTTMRAM", "Error Model not supported for STT-MRAM"); + + if (Configuration::getInstance().powerAnalysis) + SC_REPORT_FATAL("DramSTTMRAM", "DRAMPower does not support STT-MRAM"); +} diff --git a/DRAMSys/library/src/simulation/dram/DramSTTMRAM.h b/DRAMSys/library/src/simulation/dram/DramSTTMRAM.h new file mode 100644 index 00000000..3d481be1 --- /dev/null +++ b/DRAMSys/library/src/simulation/dram/DramSTTMRAM.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021, Technische Universität Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Lukas Steiner + */ + +#ifndef DRAMSTTMRAM_H +#define DRAMSTTMRAM_H + +#include +#include "Dram.h" + +class DramSTTMRAM : public Dram +{ +public: + DramSTTMRAM(sc_module_name); + SC_HAS_PROCESS(DramSTTMRAM); + virtual ~DramSTTMRAM() {} +}; + +#endif // DRAMSTTMRAM_H From cb4455710dda9112869411f29699792489699ac1 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Mon, 17 May 2021 15:51:55 +0200 Subject: [PATCH 10/13] Add config files for STT-MRAM. --- .../am_stt-mram_8x2Gbx8_dimm_p1KB_rbc.json | 43 ++++++++++++++ .../configs/mcconfigs/fr_fcfs_noref.json | 16 ++++++ .../configs/memspecs/STT-MRAM-1.2x.json | 44 +++++++++++++++ .../configs/memspecs/STT-MRAM-1.5x.json | 44 +++++++++++++++ .../configs/memspecs/STT-MRAM-2.0x.json | 44 +++++++++++++++ .../resources/configs/simulator/stt-mram.json | 19 +++++++ .../simulations/stt-mram-example.json | 16 ++++++ .../configuration/memspec/MemSpecSTTMRAM.cpp | 5 -- .../configuration/memspec/MemSpecSTTMRAM.h | 19 +++---- .../src/controller/checker/CheckerDDR3.cpp | 4 +- .../src/controller/checker/CheckerDDR4.cpp | 6 +- .../src/controller/checker/CheckerSTTMRAM.cpp | 56 ++----------------- 12 files changed, 245 insertions(+), 71 deletions(-) create mode 100644 DRAMSys/library/resources/configs/amconfigs/am_stt-mram_8x2Gbx8_dimm_p1KB_rbc.json create mode 100644 DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_noref.json create mode 100644 DRAMSys/library/resources/configs/memspecs/STT-MRAM-1.2x.json create mode 100644 DRAMSys/library/resources/configs/memspecs/STT-MRAM-1.5x.json create mode 100644 DRAMSys/library/resources/configs/memspecs/STT-MRAM-2.0x.json create mode 100644 DRAMSys/library/resources/configs/simulator/stt-mram.json create mode 100644 DRAMSys/library/resources/simulations/stt-mram-example.json diff --git a/DRAMSys/library/resources/configs/amconfigs/am_stt-mram_8x2Gbx8_dimm_p1KB_rbc.json b/DRAMSys/library/resources/configs/amconfigs/am_stt-mram_8x2Gbx8_dimm_p1KB_rbc.json new file mode 100644 index 00000000..d1bcfe70 --- /dev/null +++ b/DRAMSys/library/resources/configs/amconfigs/am_stt-mram_8x2Gbx8_dimm_p1KB_rbc.json @@ -0,0 +1,43 @@ +{ + "CONGEN": { + "BANK_BIT": [ + 13, + 14, + 15 + ], + "BYTE_BIT": [ + 0, + 1, + 2 + ], + "COLUMN_BIT": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12 + ], + "ROW_BIT": [ + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30 + ] + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_noref.json b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_noref.json new file mode 100644 index 00000000..b0d0a554 --- /dev/null +++ b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_noref.json @@ -0,0 +1,16 @@ +{ + "mcconfig": { + "PagePolicy": "Open", + "Scheduler": "FrFcfs", + "SchedulerBuffer": "Bankwise", + "RequestBufferSize": 8, + "CmdMux": "Oldest", + "RespQueue": "Fifo", + "RefreshPolicy": "NoRefresh", + "RefreshMaxPostponed": 0, + "RefreshMaxPulledin": 0, + "PowerDownPolicy": "NoPowerDown", + "Arbiter": "Simple", + "MaxActiveTransactions": 128 + } +} diff --git a/DRAMSys/library/resources/configs/memspecs/STT-MRAM-1.2x.json b/DRAMSys/library/resources/configs/memspecs/STT-MRAM-1.2x.json new file mode 100644 index 00000000..88511099 --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/STT-MRAM-1.2x.json @@ -0,0 +1,44 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 8, + "dataRate": 2, + "nbrOfBanks": 8, + "nbrOfColumns": 1024, + "nbrOfRanks": 1, + "nbrOfRows": 32768, + "width": 8, + "nbrOfDevicesOnDIMM": 8, + "nbrOfChannels": 1 + }, + "memoryId": "STT-MRAM-1.2x", + "memoryType": "STT-MRAM", + "memtimingspec": { + "AL": 0, + "CCD": 4, + "CKE": 4, + "CKESR": 7, + "CL": 11, + "DQSCK": 0, + "FAW": 29, + "RAS": 20, + "RC": 34, + "RCD": 14, + "RL": 11, + "RP": 14, + "RRD": 6, + "RTP": 6, + "WL": 11, + "WR": 12, + "WTR": 2, + "XP": 5, + "XPDLL": 325, + "XS": 324, + "XSDLL": 512, + "ACTPDEN": 2, + "PRPDEN": 2, + "RTRS": 1, + "clkMhz": 800 + } + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/memspecs/STT-MRAM-1.5x.json b/DRAMSys/library/resources/configs/memspecs/STT-MRAM-1.5x.json new file mode 100644 index 00000000..57440f78 --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/STT-MRAM-1.5x.json @@ -0,0 +1,44 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 8, + "dataRate": 2, + "nbrOfBanks": 8, + "nbrOfColumns": 1024, + "nbrOfRanks": 1, + "nbrOfRows": 32768, + "width": 8, + "nbrOfDevicesOnDIMM": 8, + "nbrOfChannels": 1 + }, + "memoryId": "STT-MRAM-1.5x", + "memoryType": "STT-MRAM", + "memtimingspec": { + "AL": 0, + "CCD": 4, + "CKE": 4, + "CKESR": 7, + "CL": 11, + "DQSCK": 0, + "FAW": 36, + "RAS": 23, + "RC": 40, + "RCD": 14, + "RL": 11, + "RP": 17, + "RRD": 8, + "RTP": 6, + "WL": 11, + "WR": 12, + "WTR": 6, + "XP": 5, + "XPDLL": 325, + "XS": 324, + "XSDLL": 512, + "ACTPDEN": 2, + "PRPDEN": 2, + "RTRS": 1, + "clkMhz": 800 + } + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/memspecs/STT-MRAM-2.0x.json b/DRAMSys/library/resources/configs/memspecs/STT-MRAM-2.0x.json new file mode 100644 index 00000000..08d0ba9b --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/STT-MRAM-2.0x.json @@ -0,0 +1,44 @@ +{ + "memspec": { + "memarchitecturespec": { + "burstLength": 8, + "dataRate": 2, + "nbrOfBanks": 8, + "nbrOfColumns": 1024, + "nbrOfRanks": 1, + "nbrOfRows": 32768, + "width": 8, + "nbrOfDevicesOnDIMM": 8, + "nbrOfChannels": 1 + }, + "memoryId": "STT-MRAM-2.0x", + "memoryType": "STT-MRAM", + "memtimingspec": { + "AL": 0, + "CCD": 4, + "CKE": 4, + "CKESR": 7, + "CL": 11, + "DQSCK": 0, + "FAW": 36, + "RAS": 28, + "RC": 50, + "RCD": 14, + "RL": 11, + "RP": 22, + "RRD": 10, + "RTP": 6, + "WL": 11, + "WR": 48, + "WTR": 6, + "XP": 5, + "XPDLL": 325, + "XS": 324, + "XSDLL": 512, + "ACTPDEN": 2, + "PRPDEN": 2, + "RTRS": 1, + "clkMhz": 800 + } + } +} \ No newline at end of file diff --git a/DRAMSys/library/resources/configs/simulator/stt-mram.json b/DRAMSys/library/resources/configs/simulator/stt-mram.json new file mode 100644 index 00000000..3248e9f0 --- /dev/null +++ b/DRAMSys/library/resources/configs/simulator/stt-mram.json @@ -0,0 +1,19 @@ +{ + "simconfig": { + "AddressOffset": 0, + "CheckTLM2Protocol": false, + "DatabaseRecording": true, + "Debug": false, + "ECCControllerMode": "Disabled", + "EnableWindowing": false, + "ErrorCSVFile": "", + "ErrorChipSeed": 42, + "PowerAnalysis": false, + "SimulationName": "stt-mram", + "SimulationProgressBar": true, + "StoreMode": "NoStorage", + "ThermalSimulation": false, + "UseMalloc": false, + "WindowSize": 1000 + } +} diff --git a/DRAMSys/library/resources/simulations/stt-mram-example.json b/DRAMSys/library/resources/simulations/stt-mram-example.json new file mode 100644 index 00000000..fd9e3fce --- /dev/null +++ b/DRAMSys/library/resources/simulations/stt-mram-example.json @@ -0,0 +1,16 @@ +{ + "simulation": { + "addressmapping": "am_stt-mram_8x2Gbx8_dimm_p1KB_rbc.json", + "mcconfig": "fr_fcfs_noref.json", + "memspec": "STT-MRAM-1.2x.json", + "simconfig": "stt-mram.json", + "simulationid": "stt-mram-example", + "thermalconfig": "config.json", + "tracesetup": [ + { + "clkMhz": 800, + "name": "ddr3_example.stl" + } + ] + } +} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.cpp index bab51776..1d4d52c6 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.cpp @@ -64,8 +64,6 @@ MemSpecSTTMRAM::MemSpecSTTMRAM(json &memspec) tXS (tCK * parseUint(memspec["memtimingspec"]["XS"], "XS")), tCCD (tCK * parseUint(memspec["memtimingspec"]["CCD"], "CCD")), tFAW (tCK * parseUint(memspec["memtimingspec"]["FAW"], "FAW")), - tREFI (tCK * parseUint(memspec["memtimingspec"]["REFI"], "REFI")), - tRFC (tCK * parseUint(memspec["memtimingspec"]["RFC"], "RFC")), tRP (tCK * parseUint(memspec["memtimingspec"]["RP"], "RP")), tRRD (tCK * parseUint(memspec["memtimingspec"]["RRD"], "RRD")), tWTR (tCK * parseUint(memspec["memtimingspec"]["WTR"], "WTR")), @@ -74,7 +72,6 @@ MemSpecSTTMRAM::MemSpecSTTMRAM(json &memspec) tXSDLL (tCK * parseUint(memspec["memtimingspec"]["XSDLL"], "XSDLL")), tACTPDEN (tCK * parseUint(memspec["memtimingspec"]["ACTPDEN"], "ACTPDEN")), tPRPDEN (tCK * parseUint(memspec["memtimingspec"]["PRPDEN"], "PRPDEN")), - tREFPDEN (tCK * parseUint(memspec["memtimingspec"]["REFPDEN"], "REFPDEN")), tRTRS (tCK * parseUint(memspec["memtimingspec"]["RTRS"], "RTRS")) {} @@ -93,8 +90,6 @@ sc_time MemSpecSTTMRAM::getExecutionTime(Command command, const tlm_generic_payl return tWL + burstDuration; else if (command == Command::WRA) return tWL + burstDuration + tWR + tRP; - else if (command == Command::REFA) - return tRFC; else { SC_REPORT_FATAL("getExecutionTime", diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h index a8a5753f..cdd72a0f 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h @@ -46,8 +46,8 @@ public: // Memspec Variables: const sc_time tCKE; - const sc_time tPD; - const sc_time tCKESR; + const sc_time tPD;//-- + const sc_time tCKESR;//-- const sc_time tRAS; const sc_time tRC; const sc_time tRCD; @@ -56,21 +56,18 @@ public: const sc_time tWL; const sc_time tWR; const sc_time tXP; - const sc_time tXS; - const sc_time tREFI; - const sc_time tRFC; + const sc_time tXS;//-- const sc_time tRP; - const sc_time tDQSCK; + const sc_time tDQSCK;//-- const sc_time tCCD; const sc_time tFAW; const sc_time tRRD; const sc_time tWTR; - const sc_time tXPDLL; - const sc_time tXSDLL; + const sc_time tXPDLL;//-- + const sc_time tXSDLL;//-- const sc_time tAL; - const sc_time tACTPDEN; - const sc_time tPRPDEN; - const sc_time tREFPDEN; + const sc_time tACTPDEN;//-- + const sc_time tPRPDEN;//-- const sc_time tRTRS; // Currents and Voltages: diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp index 0d52b904..089a753b 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp @@ -52,7 +52,7 @@ CheckerDDR3::CheckerDDR3() tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; tRDWR = memSpec->tRL + tBURST + 2 * memSpec->tCK - memSpec->tWL; tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL; - tWRRD = memSpec->tWL + tBURST + memSpec->tWTR; + tWRRD = memSpec->tWL + tBURST + memSpec->tWTR - memSpec->tAL; tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL; tWRPRE = memSpec->tWL + tBURST + memSpec->tWR; tRDPDEN = memSpec->tRL + tBURST + memSpec->tCK; @@ -91,7 +91,7 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGr { lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP - memSpec->tAL); } lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp index 25544d7b..3dda147b 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp @@ -54,8 +54,8 @@ CheckerDDR4::CheckerDDR4() tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; tRDWR = memSpec->tRL + tBURST + memSpec->tCK - memSpec->tWL + memSpec->tWPRE; tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL + memSpec->tWPRE; - tWRRD_S = memSpec->tWL + tBURST + memSpec->tWTR_S; - tWRRD_L = memSpec->tWL + tBURST + memSpec->tWTR_L; + tWRRD_S = memSpec->tWL + tBURST + memSpec->tWTR_S - memSpec->tAL; + tWRRD_L = memSpec->tWL + tBURST + memSpec->tWTR_L - memSpec->tAL; tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL + memSpec->tRPRE; tWRPRE = memSpec->tWL + tBURST + memSpec->tWR; tRDPDEN = memSpec->tRL + tBURST + memSpec->tCK; @@ -102,7 +102,7 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGr { lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP - memSpec->tAL); } lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()]; diff --git a/DRAMSys/library/src/controller/checker/CheckerSTTMRAM.cpp b/DRAMSys/library/src/controller/checker/CheckerSTTMRAM.cpp index 99c00fe5..bb157ee7 100644 --- a/DRAMSys/library/src/controller/checker/CheckerSTTMRAM.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerSTTMRAM.cpp @@ -52,7 +52,7 @@ CheckerSTTMRAM::CheckerSTTMRAM() tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; tRDWR = memSpec->tRL + tBURST + 2 * memSpec->tCK - memSpec->tWL; tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL; - tWRRD = memSpec->tWL + tBURST + memSpec->tWTR; + tWRRD = memSpec->tWL + tBURST + memSpec->tWTR - memSpec->tAL; tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL; tWRPRE = memSpec->tWL + tBURST + memSpec->tWR; tRDPDEN = memSpec->tRL + tBURST + memSpec->tCK; @@ -75,7 +75,8 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, Rank rank, Ban if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); - lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : sc_max_time(); + lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? + lastScheduledByCommand[Command::RD] : sc_max_time(); if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); @@ -83,7 +84,8 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, Rank rank, Ban if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); - lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : sc_max_time(); + lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? + lastScheduledByCommand[Command::RDA] : sc_max_time(); if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); @@ -91,7 +93,7 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, Rank rank, Ban { lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP - memSpec->tAL); } lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; @@ -198,10 +200,6 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, Rank rank, Ban if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); - lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; - if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); - lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); @@ -253,40 +251,6 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, Rank rank, Ban if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); } - else if (command == Command::REFA) - { - lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; - if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); - - lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; - if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP); - - lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; - if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP); - - lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; - if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); - - lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; - if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); - - lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; - if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); - - lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; - if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); - - lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; - if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); - } else if (command == Command::PDEA) { lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; @@ -349,10 +313,6 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, Rank rank, Ban if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); - lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; - if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDEN); - lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); @@ -389,10 +349,6 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, Rank rank, Ban if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); - lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; - if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); - lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); From 4d8d5caf72e01ad370d66ea88744de907459c47f Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 19 May 2021 09:32:32 +0200 Subject: [PATCH 11/13] Add STT-MRAM copyright notice. --- .../configs/memspecs/COPYRIGHT_STT-MRAM.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 DRAMSys/library/resources/configs/memspecs/COPYRIGHT_STT-MRAM.md diff --git a/DRAMSys/library/resources/configs/memspecs/COPYRIGHT_STT-MRAM.md b/DRAMSys/library/resources/configs/memspecs/COPYRIGHT_STT-MRAM.md new file mode 100644 index 00000000..5ff0d2d2 --- /dev/null +++ b/DRAMSys/library/resources/configs/memspecs/COPYRIGHT_STT-MRAM.md @@ -0,0 +1,16 @@ +*The following copyright notice only applies to the files "STT-MRAM-1.2x.json", "STT-MRAM-1.5x.json" and "STT-MRAM-2.0x.json".* + + + (C) Copyright 2006-2018 Barcelona Supercomputing Center (BSC) + +The copyright holder is BSC-CNS, and the authorship correspond to Kazi Asifuzzaman, Rommel Sanchez Verdejo, and Petar Radojkovic. The complete explanation of the derivation of the data can be found in the following study: Kazi Asifuzzaman, Rommel Sanchez Verdejo, and Petar Radojkovic. 2017. Enabling a reliable STT-MRAM main memory simulation. In Proceedings of the International Symposium on Memory Systems (MEMSYS '17). Washington DC, USA, 283-292. DOI: https://doi.org/10.1145/3132402.3132416 + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.” + +The configuration files list detailed timing parameters for STT-MRAM main memory, specifying a 1.2x/1.5x/2.0x deviation from respective DRAM timing parameters. From d4609ff66958f4e738c989eb228c2e8109b2017e Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 19 May 2021 09:34:30 +0200 Subject: [PATCH 12/13] Rename copyright notice. --- .../configs/memspecs/{COPYRIGHT_STT-MRAM.md => README.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename DRAMSys/library/resources/configs/memspecs/{COPYRIGHT_STT-MRAM.md => README.md} (100%) diff --git a/DRAMSys/library/resources/configs/memspecs/COPYRIGHT_STT-MRAM.md b/DRAMSys/library/resources/configs/memspecs/README.md similarity index 100% rename from DRAMSys/library/resources/configs/memspecs/COPYRIGHT_STT-MRAM.md rename to DRAMSys/library/resources/configs/memspecs/README.md From dbe76bd906521891cdbbfe0540c332a44d1ecbc6 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 19 May 2021 09:41:45 +0200 Subject: [PATCH 13/13] Remove comments from memspec file. --- .../src/configuration/memspec/MemSpecSTTMRAM.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h index cdd72a0f..0f29a5c1 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecSTTMRAM.h @@ -46,8 +46,8 @@ public: // Memspec Variables: const sc_time tCKE; - const sc_time tPD;//-- - const sc_time tCKESR;//-- + const sc_time tPD; + const sc_time tCKESR; const sc_time tRAS; const sc_time tRC; const sc_time tRCD; @@ -56,18 +56,18 @@ public: const sc_time tWL; const sc_time tWR; const sc_time tXP; - const sc_time tXS;//-- + const sc_time tXS; const sc_time tRP; - const sc_time tDQSCK;//-- + const sc_time tDQSCK; const sc_time tCCD; const sc_time tFAW; const sc_time tRRD; const sc_time tWTR; - const sc_time tXPDLL;//-- - const sc_time tXSDLL;//-- + const sc_time tXPDLL; + const sc_time tXSDLL; const sc_time tAL; - const sc_time tACTPDEN;//-- - const sc_time tPRPDEN;//-- + const sc_time tACTPDEN; + const sc_time tPRPDEN; const sc_time tRTRS; // Currents and Voltages: