diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR5.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR5.cpp index 417a0249..dcf670a9 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR5.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR5.cpp @@ -99,7 +99,10 @@ MemSpecLPDDR5::MemSpecLPDDR5(const DRAMSysConfiguration::MemSpec &memSpec) tWCK2DQO(tCK * memSpec.memTimingSpec.entries.at("WCK2DQO")), tpbR2act(tCK * memSpec.memTimingSpec.entries.at("pbR2act")), tpbR2pbR(tCK * memSpec.memTimingSpec.entries.at("pbR2pbR")), - tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")) + tRTRS (tCK * memSpec.memTimingSpec.entries.at("RTRS")), + tBURST16(tCK * 16 / dataRate), + tBURST32(tCK * 32 / dataRate), + bankMode(groupsPerRank != 1 ? BankMode::MBG : (banksPerRank == 16 ? BankMode::M16B : BankMode::M8B)) { commandLengthInCycles[Command::ACT] = 2; @@ -143,7 +146,7 @@ unsigned MemSpecLPDDR5::getPer2BankOffset() const return per2BankOffset; } -sc_time MemSpecLPDDR5::getExecutionTime(Command command, const tlm_generic_payload &) const +sc_time MemSpecLPDDR5::getExecutionTime(Command command, const tlm_generic_payload& trans) const { if (command == Command::PREPB) return tRPpb; @@ -152,13 +155,44 @@ sc_time MemSpecLPDDR5::getExecutionTime(Command command, const tlm_generic_paylo else if (command == Command::ACT) return tRCD + tCK; else if (command == Command::RD) - return tRL + burstDuration; + { + if (ControllerExtension::getBurstLength(trans) == 32) + { + // TODO: model BG mode BL32 interleaved burst + if (bankMode == BankMode::MBG) + return tRL + 2 * tCK + tBURST32; + else + return tRL + tBURST32; + } + else + return tRL + tBURST16; + } else if (command == Command::RDA) - return burstDuration + tRBTP + tRPpb; + { + if (ControllerExtension::getBurstLength(trans) == 32) + return BL_n_min_32 + tRBTP + tRPpb; + else + return BL_n_min_16 + tRBTP + tRPpb; + } else if (command == Command::WR) - return tWL + burstDuration; + { + if (ControllerExtension::getBurstLength(trans) == 32) + { + if (bankMode == BankMode::MBG) + return tWL + 2 * tCK + tBURST32; + else + return tWL + tBURST32; + } + else + return tWL + tBURST16; + } else if (command == Command::WRA) - return tWL + burstDuration + tWR + tRPpb; + { + if (ControllerExtension::getBurstLength(trans) == 32) + return tWL + BL_n_min_32 + tCK + tWR + tRPpb; + else + return tWL + BL_n_min_16 + tCK + tWR + tRPpb; + } else if (command == Command::REFAB) return tRFCab; else if (command == Command::REFPB || command == Command::REFP2B) @@ -171,12 +205,32 @@ sc_time MemSpecLPDDR5::getExecutionTime(Command command, const tlm_generic_paylo } } -TimeInterval MemSpecLPDDR5::getIntervalOnDataStrobe(Command command, const tlm_generic_payload &) const +TimeInterval MemSpecLPDDR5::getIntervalOnDataStrobe(Command command, const tlm_generic_payload& trans) const { if (command == Command::RD || command == Command::RDA) - return {tRL, tRL + burstDuration}; + { + if (ControllerExtension::getBurstLength(trans) == 32) + { + if (bankMode == BankMode::MBG) + return {tRL + 2 * tCK, tRL + 2 * tCK + tBURST32}; + else + return {tRL, tRL + tBURST32}; + } + else + return {tRL, tRL + tBURST16}; + } else if (command == Command::WR || command == Command::WRA) - return {tWL, tWL + burstDuration}; + { + if (ControllerExtension::getBurstLength(trans) == 32) + { + if (bankMode == BankMode::MBG) + return {tWL + 2 * tCK, tWL + 2 * tCK + tBURST32}; + else + return {tWL, tWL + tBURST32}; + } + else + return {tWL, tWL + tBURST16}; + } else { SC_REPORT_FATAL("MemSpecLPDDR5", "Method was called with invalid argument"); diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR5.h b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR5.h index 1635b384..1a356ecc 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR5.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR5.h @@ -95,6 +95,11 @@ public: const sc_core::sc_time tpbR2act; const sc_core::sc_time tpbR2pbR; + const sc_core::sc_time tBURST16; + const sc_core::sc_time tBURST32; + + const enum class BankMode {M16B, MBG, M8B} bankMode; + // Currents and Voltages: // TODO: to be completed diff --git a/DRAMSys/library/src/controller/checker/CheckerLPDDR4.cpp b/DRAMSys/library/src/controller/checker/CheckerLPDDR4.cpp index eaa26001..8f0d6622 100644 --- a/DRAMSys/library/src/controller/checker/CheckerLPDDR4.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerLPDDR4.cpp @@ -90,7 +90,7 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, const tlm_gener lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST); lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : sc_max_time(); if (lastCommandStart != sc_max_time()) @@ -98,7 +98,7 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, const tlm_gener lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST); lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : sc_max_time(); if (lastCommandStart != sc_max_time()) @@ -159,7 +159,7 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, const tlm_gener lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST); lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : sc_max_time(); if (lastCommandStart != sc_max_time()) @@ -167,7 +167,7 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, const tlm_gener lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; if (lastCommandStart != sc_max_time()) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST); lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : sc_max_time(); if (lastCommandStart != sc_max_time()) diff --git a/DRAMSys/library/src/controller/checker/CheckerLPDDR5.cpp b/DRAMSys/library/src/controller/checker/CheckerLPDDR5.cpp index 790a2d5a..59e1c1ee 100644 --- a/DRAMSys/library/src/controller/checker/CheckerLPDDR5.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerLPDDR5.cpp @@ -79,11 +79,12 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener sc_time lastCommandStart; sc_time earliestTimeToStart = sc_time_stamp(); + // TODO: model BG mode BL32 interleaved burst if (command == Command::RD || command == Command::RDA) { unsigned burstLength = ControllerExtension::getBurstLength(payload); - assert(!(memSpec->bitWidth == 8) || (burstLength == 32)); // x8 device -> BL32 - assert(!(memSpec->groupsPerRank > 1) || (burstLength == 16)); // BG mode -> BL16 (TODO: BL32) + assert(!(memSpec->bankMode == MemSpecLPDDR5::BankMode::M8B) || (burstLength == 32)); // 8B mode -> BL32 + assert(!(memSpec->bankMode == MemSpecLPDDR5::BankMode::MBG) || (memSpec->dataRate == 8)); // BG mode -> 4:1 ratio assert(burstLength <= memSpec->maxBurstLength); lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; @@ -103,7 +104,13 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndRank[Command::RD][rank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_S_32); + { + // TODO: model BG mode BL32 interleaved burst, remove this fix + if (memSpec->bankMode == MemSpecLPDDR5::BankMode::MBG) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_S_32 + 2 * memSpec->tCK); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_S_32); + } else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_S_16); } @@ -131,7 +138,13 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndRank[Command::RDA][rank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_S_32); + { + // TODO: model BG mode BL32 interleaved burst, remove this fix + if (memSpec->bankMode == MemSpecLPDDR5::BankMode::MBG) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_S_32 + 2 * memSpec->tCK); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_S_32); + } else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_S_16); } @@ -194,8 +207,8 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener else if (command == Command::WR || command == Command::WRA) { unsigned burstLength = ControllerExtension::getBurstLength(payload); - assert(!(memSpec->bitWidth == 8) || (burstLength == 32)); // x8 device -> BL32 - assert(!(memSpec->groupsPerRank > 1) || (burstLength == 16)); // BG mode -> BL16 (TODO: BL32) + assert(!(memSpec->bankMode == MemSpecLPDDR5::BankMode::M8B) || (burstLength == 32)); // 8B mode -> BL32 + assert(!(memSpec->bankMode == MemSpecLPDDR5::BankMode::MBG) || (memSpec->dataRate == 8)); // BG mode -> 4:1 ratio assert(burstLength <= memSpec->maxBurstLength); lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; @@ -259,7 +272,13 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndRank[Command::WR][rank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_S_32); + { + // TODO: model BG mode BL32 interleaved burst, remove this fix + if (memSpec->bankMode == MemSpecLPDDR5::BankMode::MBG) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_S_32 + 2 * memSpec->tCK); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_S_32); + } else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_S_16); } @@ -288,7 +307,13 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndRank[Command::WRA][rank.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_S_32); + { + // TODO: model BG mode BL32 interleaved burst, remove this fix + if (memSpec->bankMode == MemSpecLPDDR5::BankMode::MBG) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_S_32 + 2 * memSpec->tCK); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_S_32); + } else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_S_16); }