From db615eb6a469a494a0df3fd116739667a4cc8555 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Wed, 26 Mar 2025 15:10:56 +0100 Subject: [PATCH 1/3] Fix LPDDR5 AllBank and Per2Bank Refresh --- .../controller/checker/CheckerLPDDR5.cpp | 65 ++++++++++++++----- .../controller/checker/CheckerLPDDR5.h | 1 - 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/extensions/standards/LPDDR5/DRAMSys/controller/checker/CheckerLPDDR5.cpp b/extensions/standards/LPDDR5/DRAMSys/controller/checker/CheckerLPDDR5.cpp index 233f8877..54027f15 100644 --- a/extensions/standards/LPDDR5/DRAMSys/controller/checker/CheckerLPDDR5.cpp +++ b/extensions/standards/LPDDR5/DRAMSys/controller/checker/CheckerLPDDR5.cpp @@ -1839,8 +1839,12 @@ void CheckerLPDDR5::insert(Command command, const tlm_generic_payload& payload) if (burstLength == 32) { const sc_time constraint = currentTime + ((memSpec.BL_n_min_32 + memSpec.tRBTP) + memSpec.tRPpb); - sc_time &earliestTimeToStart = nextCommandByBank[Command::REFP2B][bank]; - earliestTimeToStart = std::max(earliestTimeToStart, constraint); + for (unsigned int i = static_cast(bank) + memSpec.banksPerRank * static_cast(rank); i < memSpec.banksPerRank * (1 + static_cast(rank)); i += memSpec.getPer2BankOffset()) + { + Bank currentBank{i}; + sc_time &earliestTimeToStart = nextCommandByBank[Command::REFP2B][currentBank]; + earliestTimeToStart = std::max(earliestTimeToStart, constraint); + } } } @@ -1849,8 +1853,12 @@ void CheckerLPDDR5::insert(Command command, const tlm_generic_payload& payload) if (burstLength != 32) { const sc_time constraint = currentTime + ((memSpec.BL_n_min_16 + memSpec.tRBTP) + memSpec.tRPpb); - sc_time &earliestTimeToStart = nextCommandByBank[Command::REFP2B][bank]; - earliestTimeToStart = std::max(earliestTimeToStart, constraint); + for (unsigned int i = static_cast(bank) + memSpec.banksPerRank * static_cast(rank); i < memSpec.banksPerRank * (1 + static_cast(rank)); i += memSpec.getPer2BankOffset()) + { + Bank currentBank{i}; + sc_time &earliestTimeToStart = nextCommandByBank[Command::REFP2B][currentBank]; + earliestTimeToStart = std::max(earliestTimeToStart, constraint); + } } } @@ -2448,8 +2456,12 @@ void CheckerLPDDR5::insert(Command command, const tlm_generic_payload& payload) if (burstLength == 32) { const sc_time constraint = currentTime + ((((memSpec.tWL + memSpec.BL_n_min_32) + memSpec.tCK) + memSpec.tWR) + memSpec.tRPpb); - sc_time &earliestTimeToStart = nextCommandByBank[Command::REFP2B][bank]; - earliestTimeToStart = std::max(earliestTimeToStart, constraint); + for (unsigned int i = static_cast(bank) + memSpec.banksPerRank * static_cast(rank); i < memSpec.banksPerRank * (1 + static_cast(rank)); i += memSpec.getPer2BankOffset()) + { + Bank currentBank{i}; + sc_time &earliestTimeToStart = nextCommandByBank[Command::REFP2B][currentBank]; + earliestTimeToStart = std::max(earliestTimeToStart, constraint); + } } } @@ -2458,8 +2470,12 @@ void CheckerLPDDR5::insert(Command command, const tlm_generic_payload& payload) if (burstLength != 32) { const sc_time constraint = currentTime + ((((memSpec.tWL + memSpec.BL_n_min_16) + memSpec.tCK) + memSpec.tWR) + memSpec.tRPpb); - sc_time &earliestTimeToStart = nextCommandByBank[Command::REFP2B][bank]; - earliestTimeToStart = std::max(earliestTimeToStart, constraint); + for (unsigned int i = static_cast(bank) + memSpec.banksPerRank * static_cast(rank); i < memSpec.banksPerRank * (1 + static_cast(rank)); i += memSpec.getPer2BankOffset()) + { + Bank currentBank{i}; + sc_time &earliestTimeToStart = nextCommandByBank[Command::REFP2B][currentBank]; + earliestTimeToStart = std::max(earliestTimeToStart, constraint); + } } } @@ -3650,8 +3666,12 @@ void CheckerLPDDR5::insert(Command command, const tlm_generic_payload& payload) // Bank (ACT,REFP2B) (memSpec.tRCpb + memSpec.tCK) [] Per2ComponentsIn(level=) { const sc_time constraint = currentTime + (memSpec.tRCpb + memSpec.tCK); - sc_time &earliestTimeToStart = nextCommandByBank[Command::REFP2B][bank]; - earliestTimeToStart = std::max(earliestTimeToStart, constraint); + for (unsigned int i = static_cast(bank) + memSpec.banksPerRank * static_cast(rank); i < memSpec.banksPerRank * (1 + static_cast(rank)); i += memSpec.getPer2BankOffset()) + { + Bank currentBank{i}; + sc_time &earliestTimeToStart = nextCommandByBank[Command::REFP2B][currentBank]; + earliestTimeToStart = std::max(earliestTimeToStart, constraint); + } } // Rank (ACT,ACT) memSpec.tRRD [] SameComponent() @@ -3813,13 +3833,6 @@ void CheckerLPDDR5::insert(Command command, const tlm_generic_payload& payload) } case Command::REFP2B: { - // Bank (REFP2B,ACT) (memSpec.tRFCpb - memSpec.tCK) [] SameComponent() - { - const sc_time constraint = currentTime + (memSpec.tRFCpb - memSpec.tCK); - sc_time &earliestTimeToStart = nextCommandByBank[Command::ACT][bank]; - earliestTimeToStart = std::max(earliestTimeToStart, constraint); - } - // Bank (REFP2B,REFP2B) memSpec.tRFCpb [] SameComponent() { const sc_time constraint = currentTime + memSpec.tRFCpb; @@ -3827,6 +3840,17 @@ void CheckerLPDDR5::insert(Command command, const tlm_generic_payload& payload) earliestTimeToStart = std::max(earliestTimeToStart, constraint); } + // Bank (REFP2B,ACT) (memSpec.tRFCpb - memSpec.tCK) [] Per2ComponentsIn(level=) + { + const sc_time constraint = currentTime + (memSpec.tRFCpb - memSpec.tCK); + for (unsigned int i = static_cast(bank) + memSpec.banksPerRank * static_cast(rank); i < memSpec.banksPerRank * (1 + static_cast(rank)); i += memSpec.getPer2BankOffset()) + { + Bank currentBank{i}; + sc_time &earliestTimeToStart = nextCommandByBank[Command::ACT][currentBank]; + earliestTimeToStart = std::max(earliestTimeToStart, constraint); + } + } + // Rank (REFP2B,ACT) (memSpec.tpbR2act - memSpec.tCK) [] SameComponent() { const sc_time constraint = currentTime + (memSpec.tpbR2act - memSpec.tCK); @@ -3872,6 +3896,13 @@ void CheckerLPDDR5::insert(Command command, const tlm_generic_payload& payload) } case Command::REFAB: { + // Rank (REFAB,ACT) (memSpec.tRFCab - memSpec.tCK) [] SameComponent() + { + const sc_time constraint = currentTime + (memSpec.tRFCab - memSpec.tCK); + sc_time &earliestTimeToStart = nextCommandByRank[Command::ACT][rank]; + earliestTimeToStart = std::max(earliestTimeToStart, constraint); + } + // Rank (REFAB,REFAB) memSpec.tRFCab [] SameComponent() { const sc_time constraint = currentTime + memSpec.tRFCab; diff --git a/extensions/standards/LPDDR5/DRAMSys/controller/checker/CheckerLPDDR5.h b/extensions/standards/LPDDR5/DRAMSys/controller/checker/CheckerLPDDR5.h index fa6a4d1b..19e2c787 100644 --- a/extensions/standards/LPDDR5/DRAMSys/controller/checker/CheckerLPDDR5.h +++ b/extensions/standards/LPDDR5/DRAMSys/controller/checker/CheckerLPDDR5.h @@ -41,7 +41,6 @@ #include "DRAMSys/configuration/memspec/MemSpecLPDDR5.h" #include -#include namespace DRAMSys { From 8268f2e33ba605e48ffda151763a31182e30b60e Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Tue, 8 Apr 2025 12:39:38 +0200 Subject: [PATCH 2/3] Fix issue with REFP2B with multiple ranks --- .../DRAMSys/controller/checker/CheckerLPDDR5.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/extensions/standards/LPDDR5/DRAMSys/controller/checker/CheckerLPDDR5.cpp b/extensions/standards/LPDDR5/DRAMSys/controller/checker/CheckerLPDDR5.cpp index 54027f15..bbd8e8ee 100644 --- a/extensions/standards/LPDDR5/DRAMSys/controller/checker/CheckerLPDDR5.cpp +++ b/extensions/standards/LPDDR5/DRAMSys/controller/checker/CheckerLPDDR5.cpp @@ -1839,7 +1839,7 @@ void CheckerLPDDR5::insert(Command command, const tlm_generic_payload& payload) if (burstLength == 32) { const sc_time constraint = currentTime + ((memSpec.BL_n_min_32 + memSpec.tRBTP) + memSpec.tRPpb); - for (unsigned int i = static_cast(bank) + memSpec.banksPerRank * static_cast(rank); i < memSpec.banksPerRank * (1 + static_cast(rank)); i += memSpec.getPer2BankOffset()) + for (unsigned int i = static_cast(bank); i < memSpec.banksPerRank * (1 + static_cast(rank)); i += memSpec.getPer2BankOffset()) { Bank currentBank{i}; sc_time &earliestTimeToStart = nextCommandByBank[Command::REFP2B][currentBank]; @@ -1853,7 +1853,7 @@ void CheckerLPDDR5::insert(Command command, const tlm_generic_payload& payload) if (burstLength != 32) { const sc_time constraint = currentTime + ((memSpec.BL_n_min_16 + memSpec.tRBTP) + memSpec.tRPpb); - for (unsigned int i = static_cast(bank) + memSpec.banksPerRank * static_cast(rank); i < memSpec.banksPerRank * (1 + static_cast(rank)); i += memSpec.getPer2BankOffset()) + for (unsigned int i = static_cast(bank); i < memSpec.banksPerRank * (1 + static_cast(rank)); i += memSpec.getPer2BankOffset()) { Bank currentBank{i}; sc_time &earliestTimeToStart = nextCommandByBank[Command::REFP2B][currentBank]; @@ -2456,7 +2456,7 @@ void CheckerLPDDR5::insert(Command command, const tlm_generic_payload& payload) if (burstLength == 32) { const sc_time constraint = currentTime + ((((memSpec.tWL + memSpec.BL_n_min_32) + memSpec.tCK) + memSpec.tWR) + memSpec.tRPpb); - for (unsigned int i = static_cast(bank) + memSpec.banksPerRank * static_cast(rank); i < memSpec.banksPerRank * (1 + static_cast(rank)); i += memSpec.getPer2BankOffset()) + for (unsigned int i = static_cast(bank); i < memSpec.banksPerRank * (1 + static_cast(rank)); i += memSpec.getPer2BankOffset()) { Bank currentBank{i}; sc_time &earliestTimeToStart = nextCommandByBank[Command::REFP2B][currentBank]; @@ -2470,7 +2470,7 @@ void CheckerLPDDR5::insert(Command command, const tlm_generic_payload& payload) if (burstLength != 32) { const sc_time constraint = currentTime + ((((memSpec.tWL + memSpec.BL_n_min_16) + memSpec.tCK) + memSpec.tWR) + memSpec.tRPpb); - for (unsigned int i = static_cast(bank) + memSpec.banksPerRank * static_cast(rank); i < memSpec.banksPerRank * (1 + static_cast(rank)); i += memSpec.getPer2BankOffset()) + for (unsigned int i = static_cast(bank); i < memSpec.banksPerRank * (1 + static_cast(rank)); i += memSpec.getPer2BankOffset()) { Bank currentBank{i}; sc_time &earliestTimeToStart = nextCommandByBank[Command::REFP2B][currentBank]; @@ -3666,7 +3666,7 @@ void CheckerLPDDR5::insert(Command command, const tlm_generic_payload& payload) // Bank (ACT,REFP2B) (memSpec.tRCpb + memSpec.tCK) [] Per2ComponentsIn(level=) { const sc_time constraint = currentTime + (memSpec.tRCpb + memSpec.tCK); - for (unsigned int i = static_cast(bank) + memSpec.banksPerRank * static_cast(rank); i < memSpec.banksPerRank * (1 + static_cast(rank)); i += memSpec.getPer2BankOffset()) + for (unsigned int i = static_cast(bank); i < memSpec.banksPerRank * (1 + static_cast(rank)); i += memSpec.getPer2BankOffset()) { Bank currentBank{i}; sc_time &earliestTimeToStart = nextCommandByBank[Command::REFP2B][currentBank]; @@ -3843,7 +3843,7 @@ void CheckerLPDDR5::insert(Command command, const tlm_generic_payload& payload) // Bank (REFP2B,ACT) (memSpec.tRFCpb - memSpec.tCK) [] Per2ComponentsIn(level=) { const sc_time constraint = currentTime + (memSpec.tRFCpb - memSpec.tCK); - for (unsigned int i = static_cast(bank) + memSpec.banksPerRank * static_cast(rank); i < memSpec.banksPerRank * (1 + static_cast(rank)); i += memSpec.getPer2BankOffset()) + for (unsigned int i = static_cast(bank); i < memSpec.banksPerRank * (1 + static_cast(rank)); i += memSpec.getPer2BankOffset()) { Bank currentBank{i}; sc_time &earliestTimeToStart = nextCommandByBank[Command::ACT][currentBank]; From 330d5c77b62aadc15e8cb0ca9085feabb49b8cde Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Tue, 8 Apr 2025 17:42:30 +0200 Subject: [PATCH 3/3] Fix LPDDR5 regression test --- .../LPDDR5/expected/DRAMSys_lpddr5-example_example_ch0.tdb | 3 --- .../LPDDR5/expected/DRAMSys_lpddr5-example_lpddr5_ch0.tdb | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) delete mode 100644 tests/tests_regression/LPDDR5/expected/DRAMSys_lpddr5-example_example_ch0.tdb diff --git a/tests/tests_regression/LPDDR5/expected/DRAMSys_lpddr5-example_example_ch0.tdb b/tests/tests_regression/LPDDR5/expected/DRAMSys_lpddr5-example_example_ch0.tdb deleted file mode 100644 index 41e0c57c..00000000 --- a/tests/tests_regression/LPDDR5/expected/DRAMSys_lpddr5-example_example_ch0.tdb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0224d8e5daa7bd509951a7cf61dbac80bb9747a4773d30da64f08b5a31c7de3a -size 3727360 diff --git a/tests/tests_regression/LPDDR5/expected/DRAMSys_lpddr5-example_lpddr5_ch0.tdb b/tests/tests_regression/LPDDR5/expected/DRAMSys_lpddr5-example_lpddr5_ch0.tdb index 38a44b6b..cb0da6fa 100644 --- a/tests/tests_regression/LPDDR5/expected/DRAMSys_lpddr5-example_lpddr5_ch0.tdb +++ b/tests/tests_regression/LPDDR5/expected/DRAMSys_lpddr5-example_lpddr5_ch0.tdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:71a8255356e9cde53dc7fa07bbe71e96249035372294364db47ae3b733827052 -size 3723264 +oid sha256:c5874d19a9faf39a42e6acecaeb892f208f60c1e5cc9a833186c4709ef4c0f12 +size 3760128