diff --git a/configs/memspec/JEDEC_2x8x2Gbx4_DDR5-3200A.json b/configs/memspec/JEDEC_2x8x2Gbx4_DDR5-3200A.json index 9b3e1e4e..8f72eba6 100644 --- a/configs/memspec/JEDEC_2x8x2Gbx4_DDR5-3200A.json +++ b/configs/memspec/JEDEC_2x8x2Gbx4_DDR5-3200A.json @@ -39,6 +39,8 @@ "CCD_L_slr": 8, "CCD_L_WR_slr": 32, "CCD_L_WR2_slr": 16, + "CCD_M_slr": 8, + "CCD_M_WR_slr": 32, "CCD_S_slr": 8, "CCD_S_WR_slr": 8, "CCD_dlr": 0, @@ -50,6 +52,7 @@ "FAW_slr": 32, "FAW_dlr": 0, "WTR_L": 16, + "WTR_M": 16, "WTR_S": 4, "RFC1_slr": 312, "RFC2_slr": 208, diff --git a/extensions/standards/DDR5/DRAMSys/configuration/memspec/MemSpecDDR5.cpp b/extensions/standards/DDR5/DRAMSys/configuration/memspec/MemSpecDDR5.cpp index 1558946a..f58f086b 100644 --- a/extensions/standards/DDR5/DRAMSys/configuration/memspec/MemSpecDDR5.cpp +++ b/extensions/standards/DDR5/DRAMSys/configuration/memspec/MemSpecDDR5.cpp @@ -84,6 +84,8 @@ MemSpecDDR5::MemSpecDDR5(const DRAMSys::Config::MemSpec &memSpec) tCCD_L_slr (tCK * memSpec.memTimingSpec.entries.at("CCD_L_slr")), tCCD_L_WR_slr (tCK * memSpec.memTimingSpec.entries.at("CCD_L_WR_slr")), tCCD_L_WR2_slr (tCK * memSpec.memTimingSpec.entries.at("CCD_L_WR2_slr")), + tCCD_M_slr (tCK * memSpec.memTimingSpec.entries.at("CCD_M_slr")), + tCCD_M_WR_slr (tCK * memSpec.memTimingSpec.entries.at("CCD_M_WR_slr")), tCCD_S_slr (tCK * memSpec.memTimingSpec.entries.at("CCD_S_slr")), tCCD_S_WR_slr (tCK * memSpec.memTimingSpec.entries.at("CCD_S_WR_slr")), tCCD_dlr (tCK * memSpec.memTimingSpec.entries.at("CCD_dlr")), @@ -95,6 +97,7 @@ MemSpecDDR5::MemSpecDDR5(const DRAMSys::Config::MemSpec &memSpec) tFAW_slr (tCK * memSpec.memTimingSpec.entries.at("FAW_slr")), tFAW_dlr (tCK * memSpec.memTimingSpec.entries.at("FAW_dlr")), tWTR_L (tCK * memSpec.memTimingSpec.entries.at("WTR_L")), + tWTR_M (tCK * memSpec.memTimingSpec.entries.at("WTR_M")), tWTR_S (tCK * memSpec.memTimingSpec.entries.at("WTR_S")), tRFC_slr ((refMode == 1) ? tCK * memSpec.memTimingSpec.entries.at("RFC1_slr") : tCK * memSpec.memTimingSpec.entries.at("RFC2_slr")), diff --git a/extensions/standards/DDR5/DRAMSys/configuration/memspec/MemSpecDDR5.h b/extensions/standards/DDR5/DRAMSys/configuration/memspec/MemSpecDDR5.h index 156d2a96..485d229b 100644 --- a/extensions/standards/DDR5/DRAMSys/configuration/memspec/MemSpecDDR5.h +++ b/extensions/standards/DDR5/DRAMSys/configuration/memspec/MemSpecDDR5.h @@ -74,6 +74,8 @@ public: const sc_core::sc_time tCCD_L_slr; const sc_core::sc_time tCCD_L_WR_slr; const sc_core::sc_time tCCD_L_WR2_slr; + const sc_core::sc_time tCCD_M_slr; + const sc_core::sc_time tCCD_M_WR_slr; const sc_core::sc_time tCCD_S_slr; const sc_core::sc_time tCCD_S_WR_slr; const sc_core::sc_time tCCD_dlr; @@ -85,6 +87,7 @@ public: const sc_core::sc_time tFAW_slr; const sc_core::sc_time tFAW_dlr; const sc_core::sc_time tWTR_L; + const sc_core::sc_time tWTR_M; const sc_core::sc_time tWTR_S; const sc_core::sc_time tRFC_slr; const sc_core::sc_time tRFC_dlr; diff --git a/extensions/standards/DDR5/DRAMSys/controller/checker/CheckerDDR5.cpp b/extensions/standards/DDR5/DRAMSys/controller/checker/CheckerDDR5.cpp index d1c9d87b..15d53f92 100644 --- a/extensions/standards/DDR5/DRAMSys/controller/checker/CheckerDDR5.cpp +++ b/extensions/standards/DDR5/DRAMSys/controller/checker/CheckerDDR5.cpp @@ -104,6 +104,7 @@ CheckerDDR5::CheckerDDR5(const Configuration& config) 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_M_WTR_slr = memSpec->tWL + tBURST16 + memSpec->tWTR_M; // tWTR_M is max(16nck, 10ns) 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); @@ -140,10 +141,14 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, const tlm_generic if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD); - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup.ID()]; + lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_slr); + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup.ID()]; + if (lastCommandStart != sc_max_time()) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_M_slr); + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalRank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_slr); @@ -176,10 +181,14 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, const tlm_generic } } - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup.ID()]; - if (lastCommandStart != sc_max_time()) + lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_slr); + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_M_slr); + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalRank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_slr); @@ -224,13 +233,22 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, const tlm_generic } } + lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; + if (lastCommandStart != sc_max_time()) + { + if (lastBurstLengthByCommandAndBank[Command::WR][bank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr + tBURST16); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr); + } + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()]; if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankGroup.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr + tBURST16); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_M_WTR_slr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_M_WTR_slr); } lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalRank.ID()]; @@ -270,13 +288,22 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, const tlm_generic } } + lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()]; + if (lastCommandStart != sc_max_time()) + { + if (lastBurstLengthByCommandAndBank[Command::WRA][bank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr + tBURST16); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr); + } + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup.ID()]; if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndBankGroup[Command::WRA][bankGroup.ID()] == 32) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr + tBURST16); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_M_WTR_slr + tBURST16); else - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_M_WTR_slr); } lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalRank.ID()]; @@ -419,10 +446,10 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, const tlm_generic } } - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()]; + lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; if (lastCommandStart != sc_max_time()) { - if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankGroup.ID()] == 32) + if (lastBurstLengthByCommandAndBank[Command::WR][bank.ID()] == 32) { if (burstLength == 16 && memSpec->bitWidth == 4) // second WR requires RMW earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_L_WR_slr); @@ -438,6 +465,19 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, const tlm_generic } } + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()]; + if (lastCommandStart != sc_max_time()) + { + if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankGroup.ID()] == 32) + { + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_M_WR_slr); + } + else + { + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_M_WR_slr); + } + } + lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalRank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_WR_slr); @@ -470,20 +510,32 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, const tlm_generic } } + lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()]; + if (lastCommandStart != sc_max_time()) + { + if (burstLength == 16 && memSpec->bitWidth == 4) // second WR requires RMW + { + if (lastBurstLengthByCommandAndBank[Command::WRA][bank.ID()] == 32) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_L_WR_slr); + else + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr); + } + } + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup.ID()]; if (lastCommandStart != sc_max_time()) { if (lastBurstLengthByCommandAndBankGroup[Command::WRA][bankGroup.ID()] == 32) { if (burstLength == 16 && memSpec->bitWidth == 4) // second WR requires RMW - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_L_WR_slr); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_M_WR_slr); else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST16 + memSpec->tCCD_L_WR2_slr); } else { if (burstLength == 16 && memSpec->bitWidth == 4) // second WR requires RMW - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_M_WR_slr); else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR2_slr); } diff --git a/extensions/standards/DDR5/DRAMSys/controller/checker/CheckerDDR5.h b/extensions/standards/DDR5/DRAMSys/controller/checker/CheckerDDR5.h index c03cd051..a9f2e3e0 100644 --- a/extensions/standards/DDR5/DRAMSys/controller/checker/CheckerDDR5.h +++ b/extensions/standards/DDR5/DRAMSys/controller/checker/CheckerDDR5.h @@ -96,6 +96,7 @@ private: sc_core::sc_time tRDWR_dpr; sc_core::sc_time tRDWR_ddr; sc_core::sc_time tCCD_L_WTR_slr; + sc_core::sc_time tCCD_M_WTR_slr; sc_core::sc_time tCCD_S_WTR_slr; sc_core::sc_time tCCD_WTR_dlr; sc_core::sc_time tWRWR_dpr;