From e193fb3f749eba70a0979ac5b86e0c9fd5d33cc4 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 20 May 2020 17:16:00 +0200 Subject: [PATCH] Updated DDR3, DDR4, WIO1, WIO2. --- .../src/configuration/ConfigurationLoader.cpp | 17 +- .../src/configuration/memspec/MemSpecDDR3.h | 7 +- .../src/configuration/memspec/MemSpecDDR4.h | 7 +- .../src/configuration/memspec/MemSpecWideIO.h | 3 +- .../configuration/memspec/MemSpecWideIO2.h | 1 + .../src/controller/checker/CheckerDDR3.cpp | 339 +++++++------- .../src/controller/checker/CheckerDDR3.h | 12 +- .../src/controller/checker/CheckerDDR4.cpp | 412 +++++++++++++----- .../src/controller/checker/CheckerDDR4.h | 15 +- .../src/controller/checker/CheckerWideIO.cpp | 338 ++++++++++---- .../src/controller/checker/CheckerWideIO.h | 12 +- .../src/controller/checker/CheckerWideIO2.cpp | 411 ++++++++++++----- .../src/controller/checker/CheckerWideIO2.h | 13 +- .../src/simulation/dram/DramWideIO.cpp | 4 +- 14 files changed, 1135 insertions(+), 456 deletions(-) diff --git a/DRAMSys/library/src/configuration/ConfigurationLoader.cpp b/DRAMSys/library/src/configuration/ConfigurationLoader.cpp index 7a8e9579..174682ae 100644 --- a/DRAMSys/library/src/configuration/ConfigurationLoader.cpp +++ b/DRAMSys/library/src/configuration/ConfigurationLoader.cpp @@ -267,6 +267,10 @@ void ConfigurationLoader::loadDDR3(Configuration &config, XMLElement *xmlSpec) memSpec->tAL = memSpec->tCK * queryUIntParameter(timings, "AL"); memSpec->tXPDLL = memSpec->tCK * queryUIntParameter(timings, "XPDLL"); memSpec->tXSDLL = memSpec->tCK * queryUIntParameter(timings, "XSDLL"); + memSpec->tACTPDEN = memSpec->tCK * queryUIntParameter(timings, "ACTPDEN"); + memSpec->tPRPDEN = memSpec->tCK * queryUIntParameter(timings, "PRPDEN"); + memSpec->tREFPDEN = memSpec->tCK * queryUIntParameter(timings, "REFPDEN"); + memSpec->tRTRS = memSpec->tCK * queryUIntParameter(timings, "RTRS"); // Currents and voltages XMLElement *powers = xmlSpec->FirstChildElement("mempowerspec"); @@ -302,8 +306,9 @@ void ConfigurationLoader::loadDDR4(Configuration &config, XMLElement *xmlSpec) // MemTimings specific for DDR4 XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec"); memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE"); + memSpec->tPD = memSpec->tCK * queryUIntParameter(timings, "PD"); memSpec->tCKESR = memSpec->tCK * queryUIntParameter(timings, "CKESR"); - //memSpec->tDQSCK = memSpec->tCK * queryUIntParameter(timings, "DQSCK"); + memSpec->tDQSCK = memSpec->tCK * queryUIntParameter(timings, "DQSCK"); memSpec->tRAS = memSpec->tCK * queryUIntParameter(timings, "RAS"); memSpec->tRC = memSpec->tCK * queryUIntParameter(timings, "RC"); memSpec->tRCD = memSpec->tCK * queryUIntParameter(timings, "RCD"); @@ -341,7 +346,11 @@ void ConfigurationLoader::loadDDR4(Configuration &config, XMLElement *xmlSpec) memSpec->tWTR_L = memSpec->tCK * queryUIntParameter(timings, "WTR_L"); memSpec->tAL = memSpec->tCK * queryUIntParameter(timings, "AL"); memSpec->tXPDLL = memSpec->tCK * queryUIntParameter(timings, "XPDLL"); - memSpec->tXSDLL = memSpec->tCK * queryUIntParameter(timings, "XSDLL"); + memSpec->tXSDLL = memSpec->tCK * queryUIntParameter(timings, "XSDLL"); + memSpec->tACTPDEN = memSpec->tCK * queryUIntParameter(timings, "ACTPDEN"); + memSpec->tPRPDEN = memSpec->tCK * queryUIntParameter(timings, "PRPDEN"); + memSpec->tREFPDEN = memSpec->tCK * queryUIntParameter(timings, "REFPDEN"); + memSpec->tRTRS = memSpec->tCK * queryUIntParameter(timings, "RTRS"); // Currents and voltages XMLElement *powers = xmlSpec->FirstChildElement("mempowerspec"); @@ -440,7 +449,7 @@ void ConfigurationLoader::loadWideIO(Configuration &config, XMLElement *xmlSpec) memSpec->tWL = memSpec->tCK * queryUIntParameter(timings, "WL"); memSpec->tWR = memSpec->tCK * queryUIntParameter(timings, "WR"); memSpec->tXP = memSpec->tCK * queryUIntParameter(timings, "XP"); - memSpec->tXS = memSpec->tCK * queryUIntParameter(timings, "XS"); + memSpec->tXSR = memSpec->tCK * queryUIntParameter(timings, "XSR"); memSpec->tCCD_R = memSpec->tCK * queryUIntParameter(timings, "CCD_R"); memSpec->tCCD_W = memSpec->tCK * queryUIntParameter(timings, "CCD_W"); memSpec->tREFI = memSpec->tCK * queryUIntParameter(timings, "REFI"); @@ -449,6 +458,7 @@ void ConfigurationLoader::loadWideIO(Configuration &config, XMLElement *xmlSpec) memSpec->tRRD = memSpec->tCK * queryUIntParameter(timings, "RRD"); memSpec->tTAW = memSpec->tCK * queryUIntParameter(timings, "TAW"); memSpec->tWTR = memSpec->tCK * queryUIntParameter(timings, "WTR"); + memSpec->tRTRS = memSpec->tCK * queryUIntParameter(timings, "RTRS"); // Currents and voltages XMLElement *powers = xmlSpec->FirstChildElement("mempowerspec"); @@ -519,6 +529,7 @@ void ConfigurationLoader::loadWideIO2(Configuration &config, XMLElement *xmlSpec memSpec->tREFIpb = memSpec->tCK * queryUIntParameter(timings, "REFIPB"); memSpec->tRFCab = memSpec->tCK * queryUIntParameter(timings, "RFCAB"); memSpec->tRFCpb = memSpec->tCK * queryUIntParameter(timings, "RFCPB"); + memSpec->tRTRS = memSpec->tCK * queryUIntParameter(timings, "RTRS"); // Currents and voltages // TODO: to be completed diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h index 35f861c6..27bc9c2b 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h @@ -41,7 +41,8 @@ struct MemSpecDDR3 final : public MemSpec { // Memspec Variables: - sc_time tCKE; // min time in pdna or pdnp + sc_time tCKE; // min time between pdx and pde + sc_time tPD; // min time in pdn sc_time tCKESR; // min time in sref sc_time tRAS; // active-time (act -> pre same bank) sc_time tRC; // RAS-cycle-time (min time bw 2 succesive ACT to same bank) @@ -63,6 +64,10 @@ struct MemSpecDDR3 final : public MemSpec sc_time tXPDLL; sc_time tXSDLL; sc_time tAL; + sc_time tACTPDEN; + sc_time tPRPDEN; + sc_time tREFPDEN; + sc_time tRTRS; // Currents and Voltages: double iDD0; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h index b37ff5a6..0b672b44 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h @@ -41,7 +41,8 @@ struct MemSpecDDR4 final : public MemSpec { // Memspec Variables: - sc_time tCKE; // min time in pdna or pdnp + sc_time tCKE; // min time between pdx and pde + sc_time tPD; // min time in pdn sc_time tCKESR; // min time in sref sc_time tRAS; // active-time (act -> pre same bank) sc_time tRC; // RAS-cycle-time (min time bw 2 succesive ACT to same bank) @@ -66,6 +67,10 @@ struct MemSpecDDR4 final : public MemSpec sc_time tAL; sc_time tXPDLL; sc_time tXSDLL; + sc_time tACTPDEN; + sc_time tPRPDEN; + sc_time tREFPDEN; + sc_time tRTRS; // Currents and Voltages: double iDD0; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h index 0886ef17..21aeb2cb 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h @@ -50,7 +50,7 @@ struct MemSpecWideIO final : public MemSpec sc_time tWL; // write latency sc_time tWR; // write recovery (write to precharge) sc_time tXP; // min delay to row access command after pdnpx pdnax - sc_time tXS; // min delay to row access command after srefx + sc_time tXSR; // min delay to row access command after srefx sc_time tREFI; sc_time tRFC; sc_time tRP; @@ -61,6 +61,7 @@ struct MemSpecWideIO final : public MemSpec sc_time tRRD; sc_time tTAW; sc_time tWTR; + sc_time tRTRS; // Currents and Voltages: double iDD0; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h index bd432a8f..a6cc29ed 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h @@ -65,6 +65,7 @@ struct MemSpecWideIO2 final : public MemSpec sc_time tREFIpb; sc_time tRFCab; sc_time tRFCpb; + sc_time tRTRS; // Currents and Voltages: // TODO: to be completed diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp index 1daf2dee..2102a0f5 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp @@ -47,7 +47,17 @@ CheckerDDR3::CheckerDDR3() (numberOfCommands(), std::vector(memSpec->numberOfRanks)); lastScheduledByCommand = std::vector(numberOfCommands()); - lastActivates = std::vector>(memSpec->numberOfRanks); + 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 CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const @@ -55,86 +65,50 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGr sc_time lastCommandStart; sc_time earliestTimeToStart = sc_time_stamp(); - if (command == Command::ACT) - { - lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP); - - lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tRP); - - lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); - - lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); - - lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); - - lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD); - - lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); - -// lastCommandStart = lastScheduledByCommandAndBank[Command::REFB][bank.ID()]; -// if (lastCommandStart != SC_ZERO_TIME) -// earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); - - lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); - - lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); - - lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); - - if (lastActivates[rank.ID()].size() >= 4) - earliestTimeToStart = std::max(earliestTimeToStart, lastActivates[rank.ID()].front() + memSpec->tFAW); - } - else if (command == Command::RD || command == Command::RDA) + if (command == Command::RD || command == Command::RDA) { lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD); + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL); - lastCommandStart = lastScheduledByCommand[Command::RD]; + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); - lastCommandStart = lastScheduledByCommand[Command::RDA]; + lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); - lastCommandStart = lastScheduledByCommand[Command::WR]; + lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : SC_ZERO_TIME; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWTR); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); if (command == Command::RDA) { lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWR - memSpec->tRTP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP); } + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD); + + lastCommandStart = lastScheduledByCommand[Command::WR]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD); + lastCommandStart = lastScheduledByCommand[Command::WRA]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWTR); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R); lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -147,26 +121,41 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGr else if (command == Command::WR || command == Command::WRA) { lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD); - - lastCommandStart = lastScheduledByCommand[Command::RD]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tRL + memSpec->burstDuration + 2 * memSpec->tCK - memSpec->tWL); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL); - lastCommandStart = lastScheduledByCommand[Command::RDA]; + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tRL + memSpec->burstDuration + 2 * memSpec->tCK - memSpec->tWL); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR); - lastCommandStart = lastScheduledByCommand[Command::WR]; + lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR); + + lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); - lastCommandStart = lastScheduledByCommand[Command::WRA]; + lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); + lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); @@ -175,19 +164,64 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL); } + else if (command == Command::ACT) + { + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD); + + lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_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()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP); lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWR); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -196,25 +230,24 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGr else if (command == Command::PREA) { lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP); lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP); lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWR); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWR); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -228,12 +261,11 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP); lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tRP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP); lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -243,71 +275,112 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); - lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); - lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); } else if (command == Command::PDEA) { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tACTPDEN); + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tRL + 5 * memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tRL + 5 * memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + 4 * memSpec->tCK + memSpec->tWR); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPDEN); lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + 5 * memSpec->tCK + memSpec->tWR); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN); lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); } - else if (command == Command::PDXA) - { - lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); - } else if (command == Command::PDEP) { lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tRL + 5 * memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tRL + 5 * memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + 5 * memSpec->tCK + memSpec->tWR); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN); lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); + } + else if (command == Command::SREFEN) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, memSpec->tAL + memSpec->tRTP + memSpec->tRP)); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRP)); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); @@ -316,39 +389,13 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGr { lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD); } - else if (command == Command::SREFEN) + else if (command == Command::PDXA) { - lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + std::max(memSpec->tRL + 5 * memSpec->tCK, memSpec->tAL + memSpec->tRTP + memSpec->tRP)); - - lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + std::max(memSpec->tWL + 5 * memSpec->tCK + memSpec->tWR, memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tRP)); - - lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); - - lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); - - lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); - - lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); - - lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD); } else if (command == Command::SREFEX) { @@ -359,7 +406,6 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGr else reportFatal("CheckerDDR3", "Unknown command!"); - // Check if command bus is free earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK); return earliestTimeToStart; @@ -367,18 +413,19 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGr void CheckerDDR3::insert(Command command, Rank rank, BankGroup, Bank bank) { - PRINTDEBUGMESSAGE("CheckerDDR3", "Changing state on bank " + std::to_string(bank.ID()) + PRINTDEBUGMESSAGE("CheckerDDR3", "Changing state on bank " + bank.ID() + " command is " + commandToString(command)); - lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp(); 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 (lastActivates[rank.ID()].size() == 4) - lastActivates[rank.ID()].pop(); - lastActivates[rank.ID()].push(sc_time_stamp()); + 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/CheckerDDR3.h b/DRAMSys/library/src/controller/checker/CheckerDDR3.h index bf86b726..f1fb5c2a 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR3.h +++ b/DRAMSys/library/src/controller/checker/CheckerDDR3.h @@ -57,7 +57,17 @@ private: sc_time lastCommandOnBus; // Four activate window - std::vector> lastActivates; + 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 // CHECKERDDR3_H diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp index 143d5b90..1444c621 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp @@ -49,7 +49,18 @@ CheckerDDR4::CheckerDDR4() (numberOfCommands(), std::vector(memSpec->numberOfRanks)); lastScheduledByCommand = std::vector(numberOfCommands()); - lastActivates = std::vector>(memSpec->numberOfRanks); + last4Activates = std::vector>(memSpec->numberOfRanks); + + tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; + tRDWR = memSpec->tRL + tBURST - memSpec->tWL + 2 * memSpec->tCK; + tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL; + tWRRD_S = memSpec->tWL + tBURST + memSpec->tWTR_S; + tWRRD_L = memSpec->tWL + tBURST + memSpec->tWTR_L; + 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->tCK + memSpec->tWR; } sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const @@ -57,25 +68,131 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGr sc_time lastCommandStart; sc_time earliestTimeToStart = sc_time_stamp(); - if (command == Command::ACT) + if (command == Command::RD || command == Command::RDA) { - lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()]; + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL); - lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()]; + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL - + memSpec->burstDuration + memSpec->tWR + memSpec->tRP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L); - lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S); - lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : SC_ZERO_TIME; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S); + + lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + if (command == Command::RDA) + { + lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP); + } + + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_L); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_S); + + lastCommandStart = lastScheduledByCommand[Command::WR]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R); + + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_L); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_S); + + lastCommandStart = lastScheduledByCommand[Command::WRA]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_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_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR); + + lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR); + + lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R); + + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S); + + lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S); + + lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL); + } + else if (command == Command::ACT) + { lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); @@ -88,129 +205,84 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_S); + lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); - if (lastActivates[rank.ID()].size() >= 4) - earliestTimeToStart = std::max(earliestTimeToStart, lastActivates[rank.ID()].front() + memSpec->tFAW); - } - else if (command == Command::RD || command == Command::RDA) - { - lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()]; + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); - lastCommandStart = lastScheduledByCommand[Command::RD]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L); - - lastCommandStart = lastScheduledByCommand[Command::RDA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL - + memSpec->burstDuration + memSpec->tWTR_L); - - if (command == Command::RDA) - { - lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWR - memSpec->tRTP); - } - - lastCommandStart = lastScheduledByCommand[Command::WR]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL - + memSpec->burstDuration + memSpec->tWTR_S); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL - + memSpec->burstDuration + memSpec->tWTR_L); - - lastCommandStart = lastScheduledByCommand[Command::WRA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL - + memSpec->burstDuration + memSpec->tWTR_S); - } - else if (command == Command::WR || command == Command::WRA) - { - lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD); - - lastCommandStart = lastScheduledByCommand[Command::RD]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRL - + memSpec->burstDuration + 2 * memSpec->tCK - memSpec->tWL); - - lastCommandStart = lastScheduledByCommand[Command::RDA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRL - + memSpec->burstDuration + 2 * memSpec->tCK - memSpec->tWL); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L); - - lastCommandStart = lastScheduledByCommand[Command::WR]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L); - - lastCommandStart = lastScheduledByCommand[Command::WRA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S); + 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()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP); lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL - + memSpec->burstDuration + memSpec->tWR); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); } else if (command == Command::PREA) { lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP); lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP); lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL - + memSpec->burstDuration + memSpec->tWR); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL - + memSpec->burstDuration + memSpec->tWR); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); } else if (command == Command::REFA) { @@ -220,12 +292,11 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP); lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL - + memSpec->burstDuration + memSpec->tWR + memSpec->tRP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP); lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -235,14 +306,137 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); + } + else if (command == Command::PDEA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tACTPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + } + else if (command == Command::PDEP) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); + } + else if (command == Command::SREFEN) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, memSpec->tAL + memSpec->tRTP + memSpec->tRP)); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRP)); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); + } + else if (command == Command::PDXP) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD); + } + else if (command == Command::PDXA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD); + } + else if (command == Command::SREFEX) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR); } else reportFatal("CheckerDDR4", "Unknown command!"); - // Check if command bus is free earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK); return earliestTimeToStart; @@ -261,8 +455,8 @@ void CheckerDDR4::insert(Command command, Rank rank, BankGroup bankgroup, Bank b if (command == Command::ACT) { - if (lastActivates[rank.ID()].size() == 4) - lastActivates[rank.ID()].pop(); - lastActivates[rank.ID()].push(sc_time_stamp()); + 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/CheckerDDR4.h b/DRAMSys/library/src/controller/checker/CheckerDDR4.h index 3f14d754..b8eb4017 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR4.h +++ b/DRAMSys/library/src/controller/checker/CheckerDDR4.h @@ -58,7 +58,20 @@ private: sc_time lastCommandOnBus; // Four activate window - std::vector> lastActivates; + std::vector> last4Activates; + + sc_time tBURST; + sc_time tRDWR; + sc_time tRDWR_R; + sc_time tWRRD_S; + sc_time tWRRD_L; + sc_time tWRRD_R; + sc_time tRDAACT; + sc_time tWRPRE; + sc_time tWRAACT; + sc_time tRDPDEN; + sc_time tWRPDEN; + sc_time tWRAPDEN; }; #endif // CHECKERDDR4_H diff --git a/DRAMSys/library/src/controller/checker/CheckerWideIO.cpp b/DRAMSys/library/src/controller/checker/CheckerWideIO.cpp index c0236fee..59f6cf86 100644 --- a/DRAMSys/library/src/controller/checker/CheckerWideIO.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerWideIO.cpp @@ -47,7 +47,17 @@ CheckerWideIO::CheckerWideIO() (numberOfCommands(), std::vector(memSpec->numberOfRanks)); lastScheduledByCommand = std::vector(numberOfCommands()); - lastActivates = std::vector>(memSpec->numberOfRanks); + last2Activates = std::vector>(memSpec->numberOfRanks); + + tBURST = memSpec->burstLength * memSpec->tCK; + tRDWR = memSpec->tRL + tBURST + memSpec->tCK; + tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL; + tWRPRE = memSpec->tWL + tBURST - memSpec->tCK + memSpec->tWR; + tWRRD = memSpec->tWL + tBURST - memSpec->tCK + memSpec->tWTR; + tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL; + tRDPDEN = memSpec->tRL + tBURST; // + memSpec->tCK; ?? + tWRPDEN = memSpec->tWL + tBURST + memSpec->tWR - memSpec->tCK; + tWRAPDEN = memSpec->tWL + tBURST + memSpec->tWR; // + memSpec->tCK; ?? } sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const @@ -55,16 +65,114 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, Rank rank, Bank sc_time lastCommandStart; sc_time earliestTimeToStart = sc_time_stamp(); - if (command == Command::ACT) + if (command == Command::RD || command == Command::RDA) { + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST); + + lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST); + + lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + if (command == Command::RDA) + { + lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - tBURST); + } + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD); + + lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD); + + lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + } + else if (command == Command::WR || command == Command::WRA) + { + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR); + + lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR); + + lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST); + + lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST); + + lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + } + else if (command == Command::ACT) + { + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD); + lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration + memSpec->tRP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRP); lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL - + memSpec->burstDuration - memSpec->tCK + memSpec->tWR + memSpec->tRP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP); lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -74,111 +182,68 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, Rank rank, Bank if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); - lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); - - lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD); - lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); - if (lastActivates[rank.ID()].size() >= 2) - earliestTimeToStart = std::max(earliestTimeToStart, lastActivates[rank.ID()].front() + memSpec->tTAW); - } - else if (command == Command::RD || command == Command::RDA) - { - lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD); - - lastCommandStart = lastScheduledByCommand[Command::RD]; + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); - lastCommandStart = lastScheduledByCommand[Command::RDA]; + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); - lastCommandStart = lastScheduledByCommand[Command::WR]; + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration - memSpec->tCK + memSpec->tWTR); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR); - if (command == Command::RDA) - { - lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->tCK + memSpec->tWR); - } - - lastCommandStart = lastScheduledByCommand[Command::WRA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration - memSpec->tCK + memSpec->tWTR); - } - else if (command == Command::WR || command == Command::WRA) - { - lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD); - - lastCommandStart = lastScheduledByCommand[Command::RD]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tRL + memSpec->burstDuration + memSpec->tCK); - - lastCommandStart = lastScheduledByCommand[Command::RDA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tRL + memSpec->burstDuration + memSpec->tCK); - - lastCommandStart = lastScheduledByCommand[Command::WR]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration); - - lastCommandStart = lastScheduledByCommand[Command::WRA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration); + if (last2Activates[rank.ID()].size() >= 2) + earliestTimeToStart = std::max(earliestTimeToStart, last2Activates[rank.ID()].front() + memSpec->tTAW); } else if (command == Command::PRE) { lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST); lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration - memSpec->tCK + memSpec->tWR); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); } else if (command == Command::PREA) { lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST); lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST); lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration - memSpec->tCK + memSpec->tWR); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration - memSpec->tCK + memSpec->tWR); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); } else if (command == Command::REFA) { @@ -188,12 +253,11 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, Rank rank, Bank lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration + memSpec->tRP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRP); lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration - memSpec->tCK + memSpec->tWR + memSpec->tRP); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP); lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -206,11 +270,121 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, Rank rank, Bank lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR); + + } + else if (command == Command::PDEA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + + } + else if (command == Command::PDEP) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR); + + } + else if (command == Command::SREFEN) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, tBURST + memSpec->tRP)); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRP)); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR); + + } + else if (command == Command::PDXP) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + + } + else if (command == Command::PDXA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + + } + else if (command == Command::SREFEX) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR); + } else - { reportFatal("CheckerWideIO", "Unknown command!"); - } + // Check if command bus is free earliestTimeToStart = std::max(earliestTimeToStart, lastScheduled + memSpec->tCK); @@ -229,8 +403,8 @@ void CheckerWideIO::insert(Command command, Rank rank, BankGroup, Bank bank) if (command == Command::ACT) { - if (lastActivates[rank.ID()].size() == 2) - lastActivates[rank.ID()].pop(); - lastActivates[rank.ID()].push(sc_time_stamp()); + if (last2Activates[rank.ID()].size() == 2) + last2Activates[rank.ID()].pop(); + last2Activates[rank.ID()].push(sc_time_stamp()); } } diff --git a/DRAMSys/library/src/controller/checker/CheckerWideIO.h b/DRAMSys/library/src/controller/checker/CheckerWideIO.h index 65a8adee..2ad7182d 100644 --- a/DRAMSys/library/src/controller/checker/CheckerWideIO.h +++ b/DRAMSys/library/src/controller/checker/CheckerWideIO.h @@ -57,7 +57,17 @@ private: sc_time lastScheduled; // Four activate window - std::vector> lastActivates; + std::vector> last2Activates; + + sc_time tBURST; + sc_time tRDWR; + sc_time tRDWR_R; + sc_time tWRPRE; + sc_time tWRRD; + sc_time tWRRD_R; + sc_time tRDPDEN; + sc_time tWRPDEN; + sc_time tWRAPDEN; }; #endif // CHECKERWIDEIO_H diff --git a/DRAMSys/library/src/controller/checker/CheckerWideIO2.cpp b/DRAMSys/library/src/controller/checker/CheckerWideIO2.cpp index 8a2a73fb..ab34db59 100644 --- a/DRAMSys/library/src/controller/checker/CheckerWideIO2.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerWideIO2.cpp @@ -47,7 +47,18 @@ CheckerWideIO2::CheckerWideIO2() (numberOfCommands(), std::vector(memSpec->numberOfRanks)); lastScheduledByCommand = std::vector(numberOfCommands()); - lastActivates = std::vector>(memSpec->numberOfRanks); + last4Activates = std::vector>(memSpec->numberOfRanks); + + tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; + tRDPRE = tBURST + std::max(2 * memSpec->tCK, memSpec->tRTP) - 2 * memSpec->tCK; + tRDPDEN = memSpec->tRL + memSpec->tDQSCK + tBURST + memSpec->tCK; + tRDWR = memSpec->tRL + memSpec->tDQSCK + tBURST + memSpec->tCK - memSpec->tWL; + tRDWR_R = memSpec->tRL + memSpec->tDQSCK + tBURST + memSpec->tRTRS - memSpec->tWL; + tWRPRE = memSpec->tWL + memSpec->tCK + tBURST + memSpec->tWR; + tWRPDEN = memSpec->tWL + memSpec->tCK + tBURST + memSpec->tWR; + tWRAPDEN = memSpec->tWL + memSpec->tCK + tBURST + memSpec->tWR + memSpec->tCK; + tWRRD = memSpec->tWL + memSpec->tCK + tBURST + memSpec->tWTR; + tWRRD_R = memSpec->tWL + memSpec->tCK + tBURST + memSpec->tRTRS - memSpec->tRL; } sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const @@ -55,7 +66,98 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, Rank rank, Ban sc_time lastCommandStart; sc_time earliestTimeToStart = sc_time_stamp(); - if (command == Command::ACT) + if (command == Command::RD || command == Command::RDA) + { + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); + + lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); + + lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + if (command == Command::RDA) + { + lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - tRDPRE); + } + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD); + + lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD); + + lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + } + else if (command == Command::WR || command == Command::WRA) + { + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR); + + lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR); + + lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); + + lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); + + lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : SC_ZERO_TIME; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + } + else if (command == Command::ACT) { lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -67,13 +169,11 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, Rank rank, Ban lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->burstDuration + memSpec->tRTP - 2 * memSpec->tCK + memSpec->tRPpb); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPRE + memSpec->tRPpb); lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tCK + memSpec->tRPpb); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRPpb); lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -83,6 +183,14 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, Rank rank, Ban if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab); + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab); @@ -95,108 +203,70 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, Rank rank, Ban if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD); - if (lastActivates[rank.ID()].size() == 4) - earliestTimeToStart = std::max(earliestTimeToStart, lastActivates[rank.ID()].front() + memSpec->tFAW); - } - else if (command == Command::RD || command == Command::RDA) - { - lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD); - - lastCommandStart = lastScheduledByCommand[Command::RD]; + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR); - lastCommandStart = lastScheduledByCommand[Command::RDA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); - - lastCommandStart = lastScheduledByCommand[Command::WR]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->tCK + memSpec->burstDuration + memSpec->tWTR); - - if (command == Command::RDA) - { - lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->tCK + memSpec->burstDuration + memSpec->tWR - memSpec->tRTP); - } - - lastCommandStart = lastScheduledByCommand[Command::WRA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->tCK + memSpec->burstDuration + memSpec->tWTR); - } - else if (command == Command::WR || command == Command::WRA) - { - lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD); - - lastCommandStart = lastScheduledByCommand[Command::RD]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tRL + memSpec->tDQSCK + memSpec->burstDuration + memSpec->tCK - memSpec->tWL); - - lastCommandStart = lastScheduledByCommand[Command::RDA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tRL + memSpec->tDQSCK + memSpec->burstDuration + memSpec->tCK - memSpec->tWL); - - lastCommandStart = lastScheduledByCommand[Command::WR]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); - - lastCommandStart = lastScheduledByCommand[Command::WRA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD); + 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()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->burstDuration + memSpec->tRTP - 2 * memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPRE); lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tCK); - } - else if (command == Command::PREA) - { - lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); - - lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->burstDuration + memSpec->tRTP - 2 * memSpec->tCK); - - lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->burstDuration + memSpec->tRTP - 2 * memSpec->tCK); - - lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tCK); - - lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 2 * memSpec->tCK); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); } - else if (command == Command::REFA) + else if (command == Command::PREA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 2 * memSpec->tCK); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb); + } + else if(command == Command::REFA) { lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -204,13 +274,11 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, Rank rank, Ban lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->burstDuration + memSpec->tRTP - 2 * memSpec->tCK + memSpec->tRPpb); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPRE + memSpec->tRPpb); lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tCK + memSpec->tRPpb); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRPpb); lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -220,11 +288,23 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, Rank rank, Ban if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab); + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR); } - else if (command == Command::REFB) + else if(command == Command::REFB) { lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -236,29 +316,146 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, Rank rank, Ban lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->burstDuration + memSpec->tRTP - 2 * memSpec->tCK + memSpec->tRPpb); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPRE + memSpec->tRPpb); lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tCK + memSpec->tRPpb); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRPpb); lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb); + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab); + lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb); - if (lastActivates[rank.ID()].size() == 4) - earliestTimeToStart = std::max(earliestTimeToStart, lastActivates[rank.ID()].front() + memSpec->tFAW); + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR); + + if (last4Activates[rank.ID()].size() >= 4) + earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW); + } + else if (command == Command::PDEA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + } + else if (command == Command::PDEP) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR); + } + else if (command == Command::SREFEN) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, tRDPRE + memSpec->tRPpb)); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRPpb)); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR); + } + else if (command == Command::PDXP) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + } + else if (command == Command::PDXA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + } + else if (command == Command::SREFEX) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR); } else - { reportFatal("CheckerWideIO2", "Unknown command!"); - } + // Check if command bus is free earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK); @@ -277,8 +474,8 @@ void CheckerWideIO2::insert(Command command, Rank rank, BankGroup, Bank bank) if (command == Command::ACT || command == Command::REFB) { - if (lastActivates[rank.ID()].size() == 4) - lastActivates[rank.ID()].pop(); - lastActivates[rank.ID()].push(sc_time_stamp()); + 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/CheckerWideIO2.h b/DRAMSys/library/src/controller/checker/CheckerWideIO2.h index 7068601a..b6a974cf 100644 --- a/DRAMSys/library/src/controller/checker/CheckerWideIO2.h +++ b/DRAMSys/library/src/controller/checker/CheckerWideIO2.h @@ -57,7 +57,18 @@ private: sc_time lastCommandOnBus; // Four activate window - std::vector> lastActivates; + std::vector> last4Activates; + + sc_time tBURST; + sc_time tRDPRE; + sc_time tRDPDEN; + sc_time tRDWR; + sc_time tRDWR_R; + sc_time tWRPRE; + sc_time tWRPDEN; + sc_time tWRAPDEN; + sc_time tWRRD; + sc_time tWRRD_R; }; #endif // CHECKERWIDEIO2_H diff --git a/DRAMSys/library/src/simulation/dram/DramWideIO.cpp b/DRAMSys/library/src/simulation/dram/DramWideIO.cpp index f9a25628..13ebb2ea 100644 --- a/DRAMSys/library/src/simulation/dram/DramWideIO.cpp +++ b/DRAMSys/library/src/simulation/dram/DramWideIO.cpp @@ -104,8 +104,8 @@ DramWideIO::DramWideIO(sc_module_name name) : Dram(name) memTimingSpec.WTR_S = memSpec->tWTR / memSpec->tCK; memTimingSpec.XP = memSpec->tXP / memSpec->tCK; memTimingSpec.XPDLL = memSpec->tXP / memSpec->tCK; - memTimingSpec.XS = memSpec->tXS / memSpec->tCK; - memTimingSpec.XSDLL = memSpec->tXS / memSpec->tCK; + memTimingSpec.XS = memSpec->tXSR / memSpec->tCK; + memTimingSpec.XSDLL = memSpec->tXSR / memSpec->tCK; MemPowerSpec memPowerSpec; memPowerSpec.idd0 = memSpec->iDD0;