From b3937cf63add7b9606c2763595e7d07a9d143e56 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Wed, 16 Aug 2023 11:21:45 +0200 Subject: [PATCH] Add LPDDR5 Partial Write Support --- .../configuration/memspec/MemSpecLPDDR5.cpp | 6 -- .../configuration/memspec/MemSpecLPDDR5.h | 2 - .../controller/checker/CheckerLPDDR5.cpp | 78 ++++++++++++++----- 3 files changed, 57 insertions(+), 29 deletions(-) diff --git a/extensions/standards/LPDDR5/DRAMSys/configuration/memspec/MemSpecLPDDR5.cpp b/extensions/standards/LPDDR5/DRAMSys/configuration/memspec/MemSpecLPDDR5.cpp index 2ccee628..66144e80 100644 --- a/extensions/standards/LPDDR5/DRAMSys/configuration/memspec/MemSpecLPDDR5.cpp +++ b/extensions/standards/LPDDR5/DRAMSys/configuration/memspec/MemSpecLPDDR5.cpp @@ -248,10 +248,4 @@ TimeInterval MemSpecLPDDR5::getIntervalOnDataStrobe(Command command, const tlm_g } } -bool MemSpecLPDDR5::requiresMaskedWrite(const tlm::tlm_generic_payload& payload) const -{ - // assert(false); // TODO - return payload.get_byte_enable_ptr() != nullptr; -} - } // namespace DRAMSys diff --git a/extensions/standards/LPDDR5/DRAMSys/configuration/memspec/MemSpecLPDDR5.h b/extensions/standards/LPDDR5/DRAMSys/configuration/memspec/MemSpecLPDDR5.h index 570ae949..5091bc98 100644 --- a/extensions/standards/LPDDR5/DRAMSys/configuration/memspec/MemSpecLPDDR5.h +++ b/extensions/standards/LPDDR5/DRAMSys/configuration/memspec/MemSpecLPDDR5.h @@ -120,8 +120,6 @@ public: sc_core::sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override; TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override; - bool requiresMaskedWrite(const tlm::tlm_generic_payload& payload) const override; - private: unsigned per2BankOffset; }; diff --git a/extensions/standards/LPDDR5/DRAMSys/controller/checker/CheckerLPDDR5.cpp b/extensions/standards/LPDDR5/DRAMSys/controller/checker/CheckerLPDDR5.cpp index cbece361..65566e11 100644 --- a/extensions/standards/LPDDR5/DRAMSys/controller/checker/CheckerLPDDR5.cpp +++ b/extensions/standards/LPDDR5/DRAMSys/controller/checker/CheckerLPDDR5.cpp @@ -321,13 +321,35 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener + memSpec->tRL + memSpec->BL_n_min_16 + memSpec->tWCK2DQO + memSpec->tRPST - memSpec->tWL); } + lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank]; + if (lastCommandStart != scMaxTime) + { + if (command == Command::MWR || command == Command::MWRA) + { + if (lastBurstLengthByCommandAndBank[Command::WR][bank] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 2.5 * memSpec->BL_n_max_32); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 4 * memSpec->BL_n_max_16); + } + } + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup]; if (lastCommandStart != scMaxTime) { - if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankGroup] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_L_32); - else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_L_16); + if (command == Command::WR || command == Command::WRA) + { + if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankGroup] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_L_32); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_L_16); + } + else if (command == Command::MWR || command == Command::MWRA) + { + if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankGroup] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_max_32); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_max_16); + } } lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank]; @@ -345,24 +367,36 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_S_16); } - lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank] ? - lastScheduledByCommand[Command::WR] : scMaxTime; + lastCommandStart = lastScheduledByCommand[Command::WR]; if (lastCommandStart != scMaxTime) { - // TODO: BG mode with BL32 - if (lastBurstLengthByCommand[Command::WR] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_min_32 + memSpec->tCK); - else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_min_16 + memSpec->tCK); + if (lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank]) + { + // TODO: BG mode with BL32 + if (lastBurstLengthByCommand[Command::WR] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_min_32 + memSpec->tCK); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_min_16 + memSpec->tCK); + } } lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup]; if (lastCommandStart != scMaxTime) { - if (lastBurstLengthByCommandAndBankGroup[Command::WRA][bankGroup] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_L_32); - else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_L_16); + if (command == Command::WR || command == Command::WRA) + { + if (lastBurstLengthByCommandAndBankGroup[Command::WRA][bankGroup] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_L_32); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_L_16); + } + else if (command == Command::MWR || command == Command::MWRA) + { + if (lastBurstLengthByCommandAndBankGroup[Command::WRA][bankGroup] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_max_32); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_max_16); + } } lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank]; @@ -380,14 +414,16 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_S_16); } - lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank] ? - lastScheduledByCommand[Command::WRA] : scMaxTime; + lastCommandStart = lastScheduledByCommand[Command::WRA]; if (lastCommandStart != scMaxTime) { - if (lastBurstLengthByCommand[Command::WRA] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_min_32 + memSpec->tCK); - else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_min_16 + memSpec->tCK); + if (lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank]) + { + if (lastBurstLengthByCommand[Command::WRA] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_min_32 + memSpec->tCK); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_min_16 + memSpec->tCK); + } } } else if (command == Command::ACT)