diff --git a/DRAMSys/library/src/configuration/ConfigurationLoader.cpp b/DRAMSys/library/src/configuration/ConfigurationLoader.cpp index 7a8e9579..137dc8ab 100644 --- a/DRAMSys/library/src/configuration/ConfigurationLoader.cpp +++ b/DRAMSys/library/src/configuration/ConfigurationLoader.cpp @@ -246,6 +246,7 @@ void ConfigurationLoader::loadDDR3(Configuration &config, XMLElement *xmlSpec) // MemTimings specific for DDR3 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->tRAS = memSpec->tCK * queryUIntParameter(timings, "RAS"); @@ -267,6 +268,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 +307,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 +347,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"); @@ -383,10 +393,12 @@ void ConfigurationLoader::loadLPDDR4(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->tRAS = memSpec->tCK * queryUIntParameter(timings, "RAS"); memSpec->tRPab = memSpec->tCK * queryUIntParameter(timings, "RPAB"); memSpec->tRPpb = memSpec->tCK * queryUIntParameter(timings, "RPPB"); + memSpec->tRCab = memSpec->tCK * queryUIntParameter(timings, "RCAB"); + memSpec->tRCpb = memSpec->tCK * queryUIntParameter(timings, "RCPB"); memSpec->tPPD = memSpec->tCK * queryUIntParameter(timings, "PPD"); - memSpec->tRAS = memSpec->tCK * queryUIntParameter(timings, "RAS"); memSpec->tRCD = memSpec->tCK * queryUIntParameter(timings, "RCD"); memSpec->tFAW = memSpec->tCK * queryUIntParameter(timings, "FAW"); memSpec->tRRD = memSpec->tCK * queryUIntParameter(timings, "RRD"); @@ -407,6 +419,7 @@ void ConfigurationLoader::loadLPDDR4(Configuration &config, XMLElement *xmlSpec) memSpec->tESCKE = memSpec->tCK * queryUIntParameter(timings, "ESCKE"); memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE"); memSpec->tCMDCKE = memSpec->tCK * queryUIntParameter(timings, "CMDCKE"); + memSpec->tRTRS = memSpec->tCK * queryUIntParameter(timings, "RTRS"); // Currents and voltages // TODO: to be completed @@ -440,7 +453,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 +462,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 +533,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 @@ -565,15 +580,7 @@ void ConfigurationLoader::loadHBM2(Configuration &config, XMLElement *xmlSpec) memSpec->tXP = memSpec->tCK * queryUIntParameter(timings, "XP"); memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE"); memSpec->tPD = memSpec->tCKE; - memSpec->tRDPDE = memSpec->tRL + memSpec->tPL - + (memSpec->burstLength / memSpec->dataRate + 1) * memSpec->tCK; - memSpec->tWRPDE = memSpec->tWL + memSpec->tPL - + (memSpec->burstLength / memSpec->dataRate + 1) * memSpec->tCK + memSpec->tWR; - memSpec->tWRAPDE = memSpec->tWL + memSpec->tPL - + (memSpec->burstLength / memSpec->dataRate + 1) * memSpec->tCK + memSpec->tWR; memSpec->tCKESR = memSpec->tCKE + memSpec->tCK; - memSpec->tRDSRE = memSpec->tRL + memSpec->tPL - + (memSpec->burstLength / memSpec->dataRate + 1) * memSpec->tCK; memSpec->tXS = memSpec->tCK * queryUIntParameter(timings, "XS"); memSpec->tRFC = memSpec->tCK * queryUIntParameter(timings, "RFC"); memSpec->tRFCSB = memSpec->tCK * queryUIntParameter(timings, "RFCSB"); @@ -623,7 +630,7 @@ void ConfigurationLoader::loadGDDR5(Configuration &config, XMLElement *xmlSpec) memSpec->tWTRS = memSpec->tCK * queryUIntParameter(timings, "WTRS"); memSpec->tWTRL = memSpec->tCK * queryUIntParameter(timings, "WTRL"); memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE"); - memSpec->tPD = memSpec->tCKE; + memSpec->tPD = memSpec->tCK * queryUIntParameter(timings, "PD");; memSpec->tXPN = memSpec->tCK * queryUIntParameter(timings, "XPN"); memSpec->tREFI = memSpec->tCK * queryUIntParameter(timings, "REFI"); memSpec->tREFIPB = memSpec->tCK * queryUIntParameter(timings, "REFIPB"); @@ -633,12 +640,13 @@ void ConfigurationLoader::loadGDDR5(Configuration &config, XMLElement *xmlSpec) memSpec->tXS = memSpec->tCK * queryUIntParameter(timings, "XS"); memSpec->tFAW = memSpec->tCK * queryUIntParameter(timings, "FAW"); memSpec->t32AW = memSpec->tCK * queryUIntParameter(timings, "32AW"); - memSpec->tRDSRE = memSpec->tCL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK - + memSpec->tWCK2DQO + memSpec->burstLength / memSpec->dataRate * memSpec->tCK; - memSpec->tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK - + memSpec->tWCK2DQI + memSpec->burstLength / memSpec->dataRate * memSpec->tCK; +// memSpec->tRDSRE = memSpec->tCL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK +// + memSpec->tWCK2DQO + memSpec->burstLength / memSpec->dataRate * memSpec->tCK; +// memSpec->tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK +// + memSpec->tWCK2DQI + memSpec->burstLength / memSpec->dataRate * memSpec->tCK; memSpec->tPPD = memSpec->tCK * queryUIntParameter(timings, "PPD"); memSpec->tLK = memSpec->tCK * queryUIntParameter(timings, "LK"); + memSpec->tRTRS = memSpec->tCK * queryUIntParameter(timings, "RTRS"); // Currents and voltages // TODO: to be completed @@ -682,7 +690,7 @@ void ConfigurationLoader::loadGDDR5X(Configuration &config, XMLElement *xmlSpec) memSpec->tWTRS = memSpec->tCK * queryUIntParameter(timings, "WTRS"); memSpec->tWTRL = memSpec->tCK * queryUIntParameter(timings, "WTRL"); memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE"); - memSpec->tPD = memSpec->tCKE; + memSpec->tPD = memSpec->tCK * queryUIntParameter(timings, "PD"); memSpec->tXP = memSpec->tCK * queryUIntParameter(timings, "XP"); memSpec->tREFI = memSpec->tCK * queryUIntParameter(timings, "REFI"); memSpec->tREFIPB = memSpec->tCK * queryUIntParameter(timings, "REFIPB"); @@ -692,12 +700,13 @@ void ConfigurationLoader::loadGDDR5X(Configuration &config, XMLElement *xmlSpec) memSpec->tXS = memSpec->tCK * queryUIntParameter(timings, "XS"); memSpec->tFAW = memSpec->tCK * queryUIntParameter(timings, "FAW"); memSpec->t32AW = memSpec->tCK * queryUIntParameter(timings, "32AW"); - memSpec->tRDSRE = memSpec->tRL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK - + memSpec->tWCK2DQO + memSpec->burstLength / memSpec->dataRate * memSpec->tCK; - memSpec->tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK - + memSpec->tWCK2DQI + memSpec->burstLength / memSpec->dataRate * memSpec->tCK; +// memSpec->tRDSRE = memSpec->tRL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK +// + memSpec->tWCK2DQO + memSpec->burstLength / memSpec->dataRate * memSpec->tCK; +// memSpec->tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK +// + memSpec->tWCK2DQI + memSpec->burstLength / memSpec->dataRate * memSpec->tCK; memSpec->tPPD = memSpec->tCK * queryUIntParameter(timings, "PPD"); memSpec->tLK = memSpec->tCK * queryUIntParameter(timings, "LK"); + memSpec->tRTRS = memSpec->tCK * queryUIntParameter(timings, "RTRS"); // Currents and voltages // TODO: to be completed @@ -740,8 +749,7 @@ void ConfigurationLoader::loadGDDR6(Configuration &config, XMLElement *xmlSpec) memSpec->tWR = memSpec->tCK * queryUIntParameter(timings, "WR"); memSpec->tWTRS = memSpec->tCK * queryUIntParameter(timings, "WTRS"); memSpec->tWTRL = memSpec->tCK * queryUIntParameter(timings, "WTRL"); - memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE"); - memSpec->tPD = memSpec->tCKE; + memSpec->tPD = memSpec->tCK * queryUIntParameter(timings, "PD"); memSpec->tCKESR = memSpec->tCK * queryUIntParameter(timings, "CKESR"); memSpec->tXP = memSpec->tCK * queryUIntParameter(timings, "XP"); memSpec->tREFI = memSpec->tCK * queryUIntParameter(timings, "REFI"); @@ -751,15 +759,16 @@ void ConfigurationLoader::loadGDDR6(Configuration &config, XMLElement *xmlSpec) memSpec->tRREFD = memSpec->tCK * queryUIntParameter(timings, "RREFD"); memSpec->tXS = memSpec->tCK * queryUIntParameter(timings, "XS"); memSpec->tFAW = memSpec->tCK * queryUIntParameter(timings, "FAW"); - memSpec->tRDSRE = memSpec->tRL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK - + memSpec->tWCK2DQO + memSpec->burstLength / memSpec->dataRate * memSpec->tCK; - memSpec->tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK - + memSpec->tWCK2DQI + memSpec->burstLength / memSpec->dataRate * memSpec->tCK; +// memSpec->tRDSRE = memSpec->tRL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK +// + memSpec->tWCK2DQO + memSpec->burstLength / memSpec->dataRate * memSpec->tCK; +// memSpec->tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK +// + memSpec->tWCK2DQI + memSpec->burstLength / memSpec->dataRate * memSpec->tCK; memSpec->tPPD = memSpec->tCK * queryUIntParameter(timings, "PPD"); memSpec->tLK = memSpec->tCK * queryUIntParameter(timings, "LK"); memSpec->tACTPDE = memSpec->tCK * queryUIntParameter(timings, "ACTPDE"); memSpec->tPREPDE = memSpec->tCK * queryUIntParameter(timings, "PREPDE"); memSpec->tREFPDE = memSpec->tCK * queryUIntParameter(timings, "REFPDE"); + 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/MemSpecGDDR5.h b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h index 22fb4e38..b16f20f2 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h @@ -62,7 +62,7 @@ struct MemSpecGDDR5 final : public MemSpec sc_time tWTRS; sc_time tWTRL; sc_time tCKE; - sc_time tPD; // = tCKE; + sc_time tPD; sc_time tXPN; sc_time tREFI; sc_time tREFIPB; @@ -72,10 +72,11 @@ struct MemSpecGDDR5 final : public MemSpec sc_time tXS; sc_time tFAW; sc_time t32AW; - sc_time tRDSRE; // = tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + BurstLength / DataRate * tCK; - sc_time tWRSRE; // = tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + BurstLength / DataRate * tCK; +// sc_time tRDSRE; // = tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + BurstLength / DataRate * tCK; +// sc_time tWRSRE; // = tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + BurstLength / DataRate * tCK; sc_time tPPD; sc_time tLK; + sc_time tRTRS; // Currents and Voltages: // TODO: to be completed diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h index bfa2ece1..f0d91630 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h @@ -62,7 +62,7 @@ struct MemSpecGDDR5X final : public MemSpec sc_time tWTRS; sc_time tWTRL; sc_time tCKE; - sc_time tPD; // = tCKE; + sc_time tPD; sc_time tXP; sc_time tREFI; sc_time tREFIPB; @@ -72,10 +72,11 @@ struct MemSpecGDDR5X final : public MemSpec sc_time tXS; sc_time tFAW; sc_time t32AW; - sc_time tRDSRE; // = tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + BurstLength / DataRate * tCK; - sc_time tWRSRE; // = tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + BurstLength / DataRate * tCK; +// sc_time tRDSRE; // = tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + BurstLength / DataRate * tCK; +// sc_time tWRSRE; // = tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + BurstLength / DataRate * tCK; sc_time tPPD; sc_time tLK; + sc_time tRTRS; // Currents and Voltages: // TODO: to be completed diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h index 88b0e491..6b7f415a 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h @@ -61,8 +61,7 @@ struct MemSpecGDDR6 final : public MemSpec sc_time tWR; sc_time tWTRS; sc_time tWTRL; - sc_time tCKE; - sc_time tPD; // = tCKE; + sc_time tPD; sc_time tCKESR; sc_time tXP; sc_time tREFI; @@ -72,13 +71,14 @@ struct MemSpecGDDR6 final : public MemSpec sc_time tRREFD; sc_time tXS; sc_time tFAW; - sc_time tRDSRE; // = tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + BurstLength / DataRate * tCK; - sc_time tWRSRE; // = tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + BurstLength / DataRate * tCK; +// sc_time tRDSRE; // = tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + BurstLength / DataRate * tCK; +// sc_time tWRSRE; // = tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + BurstLength / DataRate * tCK; sc_time tPPD; sc_time tLK; sc_time tACTPDE; sc_time tPREPDE; sc_time tREFPDE; + sc_time tRTRS; // Currents and Voltages: // TODO: to be completed diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h index 13217183..65fd44f1 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h @@ -67,11 +67,7 @@ struct MemSpecHBM2 final : public MemSpec sc_time tXP; sc_time tCKE; sc_time tPD; // = tCKE; - sc_time tRDPDE; // = tRL + tPL + (BurstLength / DataRate) * tCK + tCK; - sc_time tWRPDE; // = tWL + tPL + (BurstLength / DataRate) * tCK + tCK + tWR; - sc_time tWRAPDE; // = tWL + tPL + (BurstLength / DataRate) * tCK + tCK + tWR; sc_time tCKESR; // = tCKE + tCK; - sc_time tRDSRE; // = tRL + tPL + (BurstLength / DataRate) * tCK + tCK; sc_time tXS; sc_time tRFC; sc_time tRFCSB; diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h index 5b05150a..a2c8e331 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h @@ -47,10 +47,12 @@ struct MemSpecLPDDR4 final : public MemSpec sc_time tREFIpb; sc_time tRFCab; sc_time tRFCpb; + sc_time tRAS; sc_time tRPab; sc_time tRPpb; + sc_time tRCpb; + sc_time tRCab; sc_time tPPD; - sc_time tRAS; sc_time tRCD; sc_time tFAW; sc_time tRRD; @@ -71,6 +73,7 @@ struct MemSpecLPDDR4 final : public MemSpec sc_time tESCKE; sc_time tCKE; sc_time tCMDCKE; + sc_time tRTRS; // Currents and Voltages: // TODO: to be completed 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..1a6c7b9c 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,39 +275,43 @@ 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) @@ -285,29 +321,38 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGr { lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][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::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); @@ -316,19 +361,21 @@ 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) { + 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(memSpec->tRL + 5 * memSpec->tCK, memSpec->tAL + memSpec->tRTP + memSpec->tRP)); + 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(memSpec->tWL + 5 * memSpec->tCK + memSpec->tWR, memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tRP)); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRP)); lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -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..b3b9110e 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::PDXA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD); + } + 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::PDXP) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD); + } + 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::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/CheckerGDDR5.cpp b/DRAMSys/library/src/controller/checker/CheckerGDDR5.cpp index d8b3c522..2edeb6a5 100644 --- a/DRAMSys/library/src/controller/checker/CheckerGDDR5.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerGDDR5.cpp @@ -51,6 +51,17 @@ CheckerGDDR5::CheckerGDDR5() last4Activates = std::vector>(memSpec->numberOfRanks); last32Activates = std::vector>(memSpec->numberOfRanks); + + bankwiseRefreshCounter = std::vector(memSpec->numberOfRanks); + + tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; + tRDSRE = memSpec->tCL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK + memSpec->tWCK2DQO + tBURST; + tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK + memSpec->tWCK2DQI + tBURST; + tRDWR_R = memSpec->tCL + tBURST + memSpec->tRTRS - memSpec->tWL; + tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tCL; + tWRRD_S = memSpec->tWL + tBURST + memSpec->tWTRS; + tWRRD_L = memSpec->tWL + tBURST + memSpec->tWTRL; + tWRPRE = memSpec->tWL + tBURST + memSpec->tWR; } sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const @@ -58,7 +69,130 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankG 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->tRCDRD); + + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); + + 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 = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); + + 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] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : SC_ZERO_TIME; + 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] != 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->tXPN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tLK); + } + 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->tRCDWR); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW); + + 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 + memSpec->tRTW); + + 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->tCCDL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); + + 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->tCCDL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); + + 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->tXPN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tLK); + } + else if (command == Command::ACT) { lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -78,8 +212,7 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankG lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.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 = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -89,6 +222,14 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankG 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->tXPN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN); + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); @@ -101,94 +242,21 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankG if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD); - if (last4Activates[rank.ID()].size() == 4) + 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); - if (last32Activates[rank.ID()].size() == 32) + if (last32Activates[rank.ID()].size() >= 32) earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank.ID()].front() + memSpec->t32AW); } - else if (command == Command::RD || command == Command::RDA) - { - lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); - - lastCommandStart = lastScheduledByCommand[Command::RD]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); - - lastCommandStart = lastScheduledByCommand[Command::RDA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWTRL); - - 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->tWTRS); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWTRL); - - lastCommandStart = lastScheduledByCommand[Command::WRA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWTRS); - } - else if (command == Command::WR || command == Command::WRA) - { - lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR); - - lastCommandStart = lastScheduledByCommand[Command::RD]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW); - - lastCommandStart = lastScheduledByCommand[Command::RDA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); - - lastCommandStart = lastScheduledByCommand[Command::WR]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); - - lastCommandStart = lastScheduledByCommand[Command::WRA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); - } 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) @@ -196,17 +264,21 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankG 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::PRE][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN); } 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) @@ -218,17 +290,23 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankG 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::PRE][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB); } else if (command == Command::REFA) { @@ -242,8 +320,7 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankG 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) @@ -253,9 +330,21 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankG 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->tXPN); + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); + + 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->tXS); } else if (command == Command::REFB) { @@ -277,36 +366,158 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankG lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.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 = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); -// lastCommandStart = lastScheduledByCommandAndBank[Command::REFB][bank.ID()]; -// if (lastCommandStart != SC_ZERO_TIME) -// earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCSB); + 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->tXPN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN); + + 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->tRFCPB); lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) { - if (bankwiseRefreshCounter == 0) + if (bankwiseRefreshCounter[rank.ID()] == 0) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB); else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD); } - if (last4Activates[rank.ID()].size() == 4) + 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); - if (last32Activates[rank.ID()].size() == 32) + if (last32Activates[rank.ID()].size() >= 32) earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank.ID()].front() + memSpec->t32AW); } - else + else if (command == Command::PDEA) { - reportFatal("CheckerGDDR5", "Unknown command!"); + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRSRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRSRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN); } + 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::PDEP) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRSRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN); + + 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::SREFEN) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(memSpec->tRTP + memSpec->tRP, tRDSRE)); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 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->tXPN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); + + 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->tXS); + } + else if (command == Command::SREFEX) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + } + else + reportFatal("CheckerGDDR5", "Unknown command!"); + // Check if command bus is free earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK); @@ -336,5 +547,5 @@ void CheckerGDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank } if (command == Command::REFB) - bankwiseRefreshCounter = (bankwiseRefreshCounter + 1) % memSpec->banksPerRank; + bankwiseRefreshCounter[rank.ID()] = (bankwiseRefreshCounter[rank.ID()] + 1) % memSpec->banksPerRank; } diff --git a/DRAMSys/library/src/controller/checker/CheckerGDDR5.h b/DRAMSys/library/src/controller/checker/CheckerGDDR5.h index 937fd853..45292c23 100644 --- a/DRAMSys/library/src/controller/checker/CheckerGDDR5.h +++ b/DRAMSys/library/src/controller/checker/CheckerGDDR5.h @@ -55,13 +55,23 @@ private: std::vector> lastScheduledByCommandAndBankGroup; std::vector> lastScheduledByCommandAndRank; std::vector lastScheduledByCommand; + sc_time lastCommandOnBus; // 4 and 32 activate window std::vector> last4Activates; std::vector> last32Activates; - unsigned bankwiseRefreshCounter = 0; + std::vector bankwiseRefreshCounter; + + sc_time tBURST; + sc_time tRDSRE; + sc_time tWRSRE; + sc_time tRDWR_R; + sc_time tWRRD_S; + sc_time tWRRD_L; + sc_time tWRRD_R; + sc_time tWRPRE; }; #endif // CHECKERGDDR5_H diff --git a/DRAMSys/library/src/controller/checker/CheckerGDDR5X.cpp b/DRAMSys/library/src/controller/checker/CheckerGDDR5X.cpp index 7c7d51aa..6e8a2a86 100644 --- a/DRAMSys/library/src/controller/checker/CheckerGDDR5X.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerGDDR5X.cpp @@ -51,6 +51,17 @@ CheckerGDDR5X::CheckerGDDR5X() last4Activates = std::vector>(memSpec->numberOfRanks); last32Activates = std::vector>(memSpec->numberOfRanks); + + bankwiseRefreshCounter = std::vector(memSpec->numberOfRanks); + + tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; + tRDSRE = memSpec->tRL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK + memSpec->tWCK2DQO + tBURST; + tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK + memSpec->tWCK2DQI + tBURST; + tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL; + tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL; + tWRRD_S = memSpec->tWL + tBURST + memSpec->tWTRS; + tWRRD_L = memSpec->tWL + tBURST + memSpec->tWTRL; + tWRPRE = memSpec->tWL + tBURST + memSpec->tWR; } sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const @@ -58,7 +69,130 @@ sc_time CheckerGDDR5X::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->tRCDRD); + + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); + + 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 = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); + + 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] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : SC_ZERO_TIME; + 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] != 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); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tLK); + } + 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->tRCDWR); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW); + + 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 + memSpec->tRTW); + + 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->tCCDL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); + + 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->tCCDL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); + + 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->tLK); + } + else if (command == Command::ACT) { lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -78,8 +212,7 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, Rank rank, Bank lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.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 = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -89,6 +222,14 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, Rank rank, Bank 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); @@ -101,94 +242,21 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, Rank rank, Bank if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD); - if (last4Activates[rank.ID()].size() == 4) + 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); - if (last32Activates[rank.ID()].size() == 32) + if (last32Activates[rank.ID()].size() >= 32) earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank.ID()].front() + memSpec->t32AW); } - else if (command == Command::RD || command == Command::RDA) - { - lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); - - lastCommandStart = lastScheduledByCommand[Command::RD]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); - - lastCommandStart = lastScheduledByCommand[Command::RDA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWTRL); - - 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->tWTRS); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWTRL); - - lastCommandStart = lastScheduledByCommand[Command::WRA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWTRS); - } - else if (command == Command::WR || command == Command::WRA) - { - lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR); - - lastCommandStart = lastScheduledByCommand[Command::RD]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW); - - lastCommandStart = lastScheduledByCommand[Command::RDA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); - - lastCommandStart = lastScheduledByCommand[Command::WR]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); - - lastCommandStart = lastScheduledByCommand[Command::WRA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); - } 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) @@ -196,17 +264,21 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, Rank rank, Bank 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::PRE][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD); + + 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) @@ -218,17 +290,23 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, Rank rank, Bank 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::PRE][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD); + + 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) { @@ -242,8 +320,7 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, Rank rank, Bank 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) @@ -253,9 +330,21 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, Rank rank, Bank 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::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->tXS); } else if (command == Command::REFB) { @@ -277,36 +366,158 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, Rank rank, Bank lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.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 = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); -// lastCommandStart = lastScheduledByCommandAndBank[Command::REFB][bank.ID()]; -// if (lastCommandStart != SC_ZERO_TIME) -// earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCSB); + 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 = lastScheduledByCommandAndBank[Command::REFB][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB); lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) { - if (bankwiseRefreshCounter == 0) + if (bankwiseRefreshCounter[rank.ID()] == 0) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB); else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD); } - if (last4Activates[rank.ID()].size() == 4) + 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); - if (last32Activates[rank.ID()].size() == 32) + if (last32Activates[rank.ID()].size() >= 32) earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank.ID()].front() + memSpec->t32AW); } - else + else if (command == Command::PDEA) { - reportFatal("CheckerGDDR5X", "Unknown command!"); + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRSRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRSRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); } + 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::PDEP) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRSRE); + + 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); + } + 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::SREFEN) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(memSpec->tRTP + memSpec->tRP, tRDSRE)); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 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::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->tXS); + } + else if (command == Command::SREFEX) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + } + else + reportFatal("CheckerGDDR5X", "Unknown command!"); + // Check if command bus is free earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK); @@ -336,5 +547,5 @@ void CheckerGDDR5X::insert(Command command, Rank rank, BankGroup bankgroup, Bank } if (command == Command::REFB) - bankwiseRefreshCounter = (bankwiseRefreshCounter + 1) % memSpec->banksPerRank; + bankwiseRefreshCounter[rank.ID()] = (bankwiseRefreshCounter[rank.ID()] + 1) % memSpec->banksPerRank; } diff --git a/DRAMSys/library/src/controller/checker/CheckerGDDR5X.h b/DRAMSys/library/src/controller/checker/CheckerGDDR5X.h index 8f838914..5b55d281 100644 --- a/DRAMSys/library/src/controller/checker/CheckerGDDR5X.h +++ b/DRAMSys/library/src/controller/checker/CheckerGDDR5X.h @@ -55,13 +55,23 @@ private: std::vector> lastScheduledByCommandAndBankGroup; std::vector> lastScheduledByCommandAndRank; std::vector lastScheduledByCommand; + sc_time lastCommandOnBus; // 4 and 32 activate window std::vector> last4Activates; std::vector> last32Activates; - unsigned bankwiseRefreshCounter = 0; + std::vector bankwiseRefreshCounter; + + sc_time tBURST; + sc_time tRDSRE; + sc_time tWRSRE; + sc_time tRDWR_R; + sc_time tWRRD_S; + sc_time tWRRD_L; + sc_time tWRRD_R; + sc_time tWRPRE; }; #endif // CHECKERGDDR5X_H diff --git a/DRAMSys/library/src/controller/checker/CheckerGDDR6.cpp b/DRAMSys/library/src/controller/checker/CheckerGDDR6.cpp index 74abbf99..b14d99a5 100644 --- a/DRAMSys/library/src/controller/checker/CheckerGDDR6.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerGDDR6.cpp @@ -49,7 +49,18 @@ CheckerGDDR6::CheckerGDDR6() (numberOfCommands(), std::vector(memSpec->numberOfRanks)); lastScheduledByCommand = std::vector(numberOfCommands()); - lastActivates = std::vector>(memSpec->numberOfRanks); + last4Activates = std::vector>(memSpec->numberOfRanks); + + bankwiseRefreshCounter = std::vector(memSpec->numberOfRanks); + + tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; + tRDSRE = memSpec->tRL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK + memSpec->tWCK2DQO + tBURST; + tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK + memSpec->tWCK2DQI + tBURST; + tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL; + tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL; + tWRRD_S = memSpec->tWL + tBURST + memSpec->tWTRS; + tWRRD_L = memSpec->tWL + tBURST + memSpec->tWTRL; + tWRPRE = memSpec->tWL + tBURST + memSpec->tWR; } sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const @@ -57,7 +68,130 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, Rank rank, BankG 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->tRCDRD); + + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); + + 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 = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); + + 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] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : SC_ZERO_TIME; + 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] != 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); + + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tLK); + } + 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->tRCDWR); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW); + + 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 + memSpec->tRTW); + + 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->tCCDL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); + + 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->tCCDL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); + + 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->tLK); + } + else if (command == Command::ACT) { lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -77,8 +211,7 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, Rank rank, BankG lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.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 = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -88,6 +221,14 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, Rank rank, BankG 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); @@ -100,91 +241,18 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, Rank rank, BankG if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD); - 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->tRCDRD); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()]; + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); - lastCommandStart = lastScheduledByCommand[Command::RD]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); - - lastCommandStart = lastScheduledByCommand[Command::RDA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWTRL); - - 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->tWTRS); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWTRL); - - lastCommandStart = lastScheduledByCommand[Command::WRA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWTRS); - } - else if (command == Command::WR || command == Command::WRA) - { - lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR); - - lastCommandStart = lastScheduledByCommand[Command::RD]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW); - - lastCommandStart = lastScheduledByCommand[Command::RDA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); - - lastCommandStart = lastScheduledByCommand[Command::WR]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); - - lastCommandStart = lastScheduledByCommand[Command::WRA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); + 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) @@ -192,17 +260,21 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, Rank rank, BankG 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::PRE][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD); + + 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) @@ -214,17 +286,23 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, Rank rank, BankG 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::PRE][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD); + + 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) { @@ -238,8 +316,7 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, Rank rank, BankG 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) @@ -249,9 +326,21 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, Rank rank, BankG 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::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->tXS); } else if (command == Command::REFB) { @@ -273,33 +362,183 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, Rank rank, BankG lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.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 = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); -// lastCommandStart = lastScheduledByCommandAndBank[Command::REFB][bank.ID()]; -// if (lastCommandStart != SC_ZERO_TIME) -// earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCSB); + 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 = lastScheduledByCommandAndBank[Command::REFB][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB); lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) { - if (bankwiseRefreshCounter == 0) + if (bankwiseRefreshCounter[rank.ID()] == 0) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB); else earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD); } - 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->tXS); + + if (last4Activates[rank.ID()].size() >= 4) + earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW); + } + else if (command == Command::PDEA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tACTPDE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRSRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRSRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPREPDE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + } + 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::PDEP) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRSRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPREPDE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPREPDE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDE); + + 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); + } + 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::SREFEN) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(memSpec->tRTP + memSpec->tRP, tRDSRE)); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 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::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->tXS); + } + 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("CheckerGDDR6", "Unknown command!"); - } + // Check if command bus is free earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK); @@ -319,11 +558,11 @@ void CheckerGDDR6::insert(Command command, Rank rank, BankGroup bankgroup, Bank if (command == Command::ACT || command == Command::REFB) { - if (lastActivates[rank.ID()].size() == 4) - lastActivates[rank.ID()].pop(); - lastActivates[rank.ID()].push(lastCommandOnBus); + if (last4Activates[rank.ID()].size() == 4) + last4Activates[rank.ID()].pop(); + last4Activates[rank.ID()].push(lastCommandOnBus); } if (command == Command::REFB) - bankwiseRefreshCounter = (bankwiseRefreshCounter + 1) % memSpec->banksPerRank; + bankwiseRefreshCounter[rank.ID()] = (bankwiseRefreshCounter[rank.ID()] + 1) % memSpec->banksPerRank; } diff --git a/DRAMSys/library/src/controller/checker/CheckerGDDR6.h b/DRAMSys/library/src/controller/checker/CheckerGDDR6.h index 501c0da6..57d80fbb 100644 --- a/DRAMSys/library/src/controller/checker/CheckerGDDR6.h +++ b/DRAMSys/library/src/controller/checker/CheckerGDDR6.h @@ -58,9 +58,18 @@ private: sc_time lastCommandOnBus; // four activate window - std::vector> lastActivates; + std::vector> last4Activates; - unsigned bankwiseRefreshCounter = 0; + std::vector bankwiseRefreshCounter; + + sc_time tBURST; + sc_time tRDSRE; + sc_time tWRSRE; + sc_time tRDWR_R; + sc_time tWRRD_S; + sc_time tWRRD_L; + sc_time tWRRD_R; + sc_time tWRPRE; }; #endif // CHECKERGDDR6_H diff --git a/DRAMSys/library/src/controller/checker/CheckerHBM2.cpp b/DRAMSys/library/src/controller/checker/CheckerHBM2.cpp index e2c92f9e..31c3a810 100644 --- a/DRAMSys/library/src/controller/checker/CheckerHBM2.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerHBM2.cpp @@ -49,8 +49,17 @@ CheckerHBM2::CheckerHBM2() (numberOfCommands(), std::vector(memSpec->numberOfRanks)); lastScheduledByCommand = std::vector(numberOfCommands()); - lastActivates = std::vector>(memSpec->numberOfRanks); + last4Activates = std::vector>(memSpec->numberOfRanks); bankwiseRefreshCounter = std::vector(memSpec->numberOfRanks); + + tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; + tRDPDE = memSpec->tRL + memSpec->tPL + tBURST + memSpec->tCK; + tRDSRE = tRDPDE; + tWRPRE = memSpec->tWL + tBURST + memSpec->tWR; + tWRPDE = memSpec->tWL + memSpec->tPL + tBURST + memSpec->tCK + memSpec->tWR; + tWRAPDE = memSpec->tWL + memSpec->tPL + tBURST + memSpec->tCK + memSpec->tWR; + tWRRDS = memSpec->tWL + tBURST + memSpec->tWTRS; + tWRRDL = memSpec->tWL + tBURST + memSpec->tWTRL; } sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const @@ -58,7 +67,94 @@ sc_time CheckerHBM2::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::ACT][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD + memSpec->tCK); + + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); + + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); + + 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 + tWRRDL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDS); + + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDS); + + lastCommandStart = lastScheduledByCommand[Command::PDXA]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnCasBus + memSpec->tCK); + } + 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->tRCDWR + memSpec->tCK); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW); + + lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW); + + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); + + lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); + + lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); + + lastCommandStart = lastScheduledByCommand[Command::PDXA]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnCasBus + memSpec->tCK); + } + else if (command == Command::ACT) { lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -74,13 +170,11 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tRTP + memSpec->tRP - memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP - memSpec->tCK); lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tRP - memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP - memSpec->tCK); lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -90,6 +184,14 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->tCK); + lastCommandStart = lastScheduledByCommand[Command::PDXA]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP - memSpec->tCK); + + lastCommandStart = lastScheduledByCommand[Command::PDXP]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP - memSpec->tCK); + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC - memSpec->tCK); @@ -102,98 +204,20 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD - memSpec->tCK); - if (lastActivates[rank.ID()].size() == 4) - earliestTimeToStart = std::max(earliestTimeToStart, - lastActivates[rank.ID()].front() + memSpec->tFAW - memSpec->tCK); + lastCommandStart = lastScheduledByCommand[Command::SREFEX]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS - memSpec->tCK); + + if (last4Activates[rank.ID()].size() >= 4) + earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW - memSpec->tCK); earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK); } - else if (command == Command::RD || command == Command::RDA) - { - lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD + memSpec->tCK); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); - - lastCommandStart = lastScheduledByCommand[Command::RD]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); - - lastCommandStart = lastScheduledByCommand[Command::RDA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWTRL); - - 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->tWTRS); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWTRL); - - lastCommandStart = lastScheduledByCommand[Command::WRA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart - + memSpec->tWL + memSpec->burstDuration + memSpec->tWTRS); - - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnCasBus + memSpec->tCK); - } - else if (command == Command::WR || command == Command::WRA) - { - lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR + memSpec->tCK); - - lastCommandStart = lastScheduledByCommand[Command::RD]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW); - - lastCommandStart = lastScheduledByCommand[Command::RDA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); - - lastCommandStart = lastScheduledByCommand[Command::WR]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); - - lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL); - - lastCommandStart = lastScheduledByCommand[Command::WRA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS); - - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnCasBus + memSpec->tCK); - } else if (command == Command::PRE) { lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK); + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK); lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -201,15 +225,19 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, Rank rank, BankGr 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 = lastScheduledByCommand[Command::PDXA]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK); } else if (command == Command::PREA) { lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK); + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK); lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -221,13 +249,19 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, Rank rank, BankGr 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 = lastScheduledByCommand[Command::PDXA]; + 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->tRFCSB); earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK); } @@ -243,8 +277,7 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, Rank rank, BankGr 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) @@ -254,10 +287,22 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, Rank rank, BankGr if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + lastCommandStart = lastScheduledByCommand[Command::PDXP]; + 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::REFB][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCSB); + + lastCommandStart = lastScheduledByCommand[Command::SREFEX]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK); } else if (command == Command::REFB) @@ -280,16 +325,31 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, Rank rank, BankGr lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.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 = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); -// lastCommandStart = lastScheduledByCommandAndBank[Command::REFB][bank.ID()]; -// if (lastCommandStart != SC_ZERO_TIME) -// earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCSB); + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommand[Command::PDXA]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommand[Command::PDXP]; + 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 = lastScheduledByCommandAndBank[Command::REFB][bank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCSB); lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -300,15 +360,129 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, Rank rank, BankGr earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD); } - if (lastActivates[rank.ID()].size() == 4) - earliestTimeToStart = std::max(earliestTimeToStart, lastActivates[rank.ID()].front() + memSpec->tFAW); + lastCommandStart = lastScheduledByCommand[Command::SREFEX]; + 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); + + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK); + } + else if (command == Command::PDEA) + { + lastCommandStart = lastScheduledByCommand[Command::RD]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDE); + + lastCommandStart = lastScheduledByCommand[Command::RDA]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDE); + + lastCommandStart = lastScheduledByCommand[Command::WR]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPDE); + + lastCommandStart = lastScheduledByCommand[Command::WRA]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDE); + + lastCommandStart = lastScheduledByCommand[Command::PDXA]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK); + } + else if (command == Command::PDXA) + { + lastCommandStart = lastScheduledByCommand[Command::PDEA]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD); + + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK); + } + else if (command == Command::PDEP) + { + lastCommandStart = lastScheduledByCommand[Command::RD]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDE); + + lastCommandStart = lastScheduledByCommand[Command::RDA]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDE); + + lastCommandStart = lastScheduledByCommand[Command::WRA]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDE); + + lastCommandStart = lastScheduledByCommand[Command::PDXP]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + + lastCommandStart = lastScheduledByCommand[Command::SREFEX]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); + + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK); + } + else if (command == Command::PDXP) + { + lastCommandStart = lastScheduledByCommand[Command::PDEP]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD); + + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK); + } + else if (command == Command::SREFEN) + { + lastCommandStart = lastScheduledByCommand[Command::ACT]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK); + + lastCommandStart = lastScheduledByCommand[Command::RDA]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(memSpec->tRTP + memSpec->tRP, tRDSRE)); + + lastCommandStart = lastScheduledByCommand[Command::WRA]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP); + + lastCommandStart = lastScheduledByCommand[Command::PRE]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommand[Command::PREA]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP); + + lastCommandStart = lastScheduledByCommand[Command::PDXP]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); + + lastCommandStart = lastScheduledByCommand[Command::REFA]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC); + + lastCommandStart = lastScheduledByCommand[Command::REFB]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCSB); + + lastCommandStart = lastScheduledByCommand[Command::SREFEX]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS); + + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK); + } + else if (command == Command::SREFEX) + { + lastCommandStart = lastScheduledByCommand[Command::SREFEN]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR); earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK); } else - { reportFatal("CheckerHBM2", "Unknown command!"); - } return earliestTimeToStart; } @@ -332,9 +506,9 @@ void CheckerHBM2::insert(Command command, Rank rank, BankGroup bankgroup, Bank b if (command == Command::ACT || command == Command::REFB) { - if (lastActivates[rank.ID()].size() == 4) - lastActivates[rank.ID()].pop(); - lastActivates[rank.ID()].push(lastCommandOnRasBus); + if (last4Activates[rank.ID()].size() == 4) + last4Activates[rank.ID()].pop(); + last4Activates[rank.ID()].push(lastCommandOnRasBus); } if (command == Command::REFB) diff --git a/DRAMSys/library/src/controller/checker/CheckerHBM2.h b/DRAMSys/library/src/controller/checker/CheckerHBM2.h index 77b27f64..51f7c15d 100644 --- a/DRAMSys/library/src/controller/checker/CheckerHBM2.h +++ b/DRAMSys/library/src/controller/checker/CheckerHBM2.h @@ -55,12 +55,24 @@ private: std::vector> lastScheduledByCommandAndBankGroup; std::vector> lastScheduledByCommandAndRank; std::vector lastScheduledByCommand; + sc_time lastCommandOnRasBus; sc_time lastCommandOnCasBus; // Four activate window - std::vector> lastActivates; + std::vector> last4Activates; std::vector bankwiseRefreshCounter; + + sc_time tBURST; + sc_time tRDPDE; + sc_time tRDSRE; + sc_time tWRPRE; + sc_time tWRPDE; + sc_time tWRAPDE; + sc_time tRTWR; + sc_time tWRRDS; + sc_time tWRRDL; + sc_time tWRRDR; }; #endif // CHECKERHBM2_H diff --git a/DRAMSys/library/src/controller/checker/CheckerLPDDR4.cpp b/DRAMSys/library/src/controller/checker/CheckerLPDDR4.cpp index 943298db..09a372d9 100644 --- a/DRAMSys/library/src/controller/checker/CheckerLPDDR4.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerLPDDR4.cpp @@ -47,7 +47,23 @@ CheckerLPDDR4::CheckerLPDDR4() (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 + memSpec->tDQSCK + tBURST - memSpec->tWL + memSpec->tWPRE + memSpec->tRPST; + tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL; + tWRRD = memSpec->tWL + memSpec->tCK + tBURST + memSpec->tWTR; + tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL; + tRDPRE = memSpec->tRTP + tBURST - 6 * memSpec->tCK; + tRDAACT = memSpec->tRTP + tBURST - 8 * memSpec->tCK + memSpec->tRPpb; + tWRPRE = memSpec->tWL + tBURST + memSpec->tCK + memSpec->tWR + 2 * memSpec->tCK; + tWRAACT = memSpec->tWL + tBURST + memSpec->tCK + memSpec->tWR + memSpec->tRPpb; + tACTPDEN = 3 * memSpec->tCK + memSpec->tCMDCKE; + tPRPDEN = memSpec->tCK + memSpec->tCMDCKE; + tRDPDEN = 3 * memSpec->tCK + memSpec->tRL + memSpec->tDQSCK + tBURST + memSpec->tRPST; + tWRPDEN = 3 * memSpec->tCK + memSpec->tWL + (std::ceil(memSpec->tDQSS / memSpec->tCK) + std::ceil(memSpec->tDQS2DQ / memSpec->tCK)) * memSpec->tCK + tBURST + memSpec->tWR; + tWRAPDEN = 3 * memSpec->tCK + memSpec->tWL + (std::ceil(memSpec->tDQSS / memSpec->tCK) + std::ceil(memSpec->tDQS2DQ / memSpec->tCK)) * memSpec->tCK + tBURST + memSpec->tWR + 2 * memSpec->tCK; + tREFPDEN = memSpec->tCK + memSpec->tCMDCKE; } sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const @@ -55,16 +71,114 @@ sc_time CheckerLPDDR4::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 + 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][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb); + + 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->tRTP + memSpec->tRPpb); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT); 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 + tWRAACT); lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -74,13 +188,13 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, Bank if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab - 2 * memSpec->tCK); - lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tRPpb); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); - lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP); lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -94,119 +208,82 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, Bank if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD - 2 * memSpec->tCK); - if (lastActivates[rank.ID()].size() == 4) - earliestTimeToStart = std::max(earliestTimeToStart, lastActivates[rank.ID()].front() + memSpec->tFAW - 3 * memSpec->tCK); - } - 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 - 2 * memSpec->tCK); - 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->tWL + memSpec->tWPRE + memSpec->tRPST); - - lastCommandStart = lastScheduledByCommand[Command::RDA]; - if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRL + memSpec->tDQSCK + memSpec->burstDuration - memSpec->tWL + memSpec->tWPRE + memSpec->tRPST); - - 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 - 3 * memSpec->tCK); } else if (command == Command::PRE) { lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + 2 * memSpec->tCK); + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + 2 * memSpec->tCK); lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration + memSpec->tRTP - 6 * 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 + 3 * memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD); + + 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 + 2 * memSpec->tCK); + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + 2 * memSpec->tCK); lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration + memSpec->tRTP - 6 * memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPRE); lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->burstDuration + memSpec->tRTP - 6 * memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPRE); lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + memSpec->burstDuration + memSpec->tWR + 3 * memSpec->tCK); + 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 + 3 * memSpec->tCK); - -// lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()]; -// if (lastCommandStart != SC_ZERO_TIME) -// earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE); lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD); + + 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) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tRPpb + 2 * memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb + 2 * memSpec->tCK); lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRPpb + 2 * memSpec->tCK); + 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 + 3 * memSpec->tCK + memSpec->tRPpb); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRPpb); lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -216,19 +293,27 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, Bank 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::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) { lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tRPpb + 2 * memSpec->tCK); + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb + 2 * memSpec->tCK); lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; if (lastCommandStart != SC_ZERO_TIME) @@ -236,36 +321,174 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, Bank lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()]; if (lastCommandStart != SC_ZERO_TIME) - earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRPpb + 2 * memSpec->tCK); + 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 + 3 * 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::PREA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab); -// lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; -// if (lastCommandStart != SC_ZERO_TIME) -// earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab); + 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 - memSpec->tCK); + 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 - memSpec->tCK); + } + else if (command == Command::PDEA) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 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 + tPRPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tREFPDEN); + + 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 + 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 + tPRPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tPRPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tREFPDEN); + + lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tREFPDEN); + + 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::PDXP) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + } + else if (command == Command::SREFEN) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb + 2 * memSpec->tCK); + + 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::SREFEX) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tSR); } else - { reportFatal("CheckerLPDDR4", "Unknown command!"); - } + // Check if command bus is free earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK); @@ -280,12 +503,13 @@ void CheckerLPDDR4::insert(Command command, Rank rank, BankGroup, Bank bank) lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp(); lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp(); lastScheduledByCommand[command] = sc_time_stamp(); + lastCommandOnBus = sc_time_stamp() + memSpec->getCommandLength(command) - memSpec->tCK; if (command == Command::ACT || command == Command::REFB) { - if (lastActivates[rank.ID()].size() == 4) - lastActivates[rank.ID()].pop(); - lastActivates[rank.ID()].push(lastCommandOnBus); + if (last4Activates[rank.ID()].size() == 4) + last4Activates[rank.ID()].pop(); + last4Activates[rank.ID()].push(lastCommandOnBus); } } diff --git a/DRAMSys/library/src/controller/checker/CheckerLPDDR4.h b/DRAMSys/library/src/controller/checker/CheckerLPDDR4.h index f52c732e..cddab49b 100644 --- a/DRAMSys/library/src/controller/checker/CheckerLPDDR4.h +++ b/DRAMSys/library/src/controller/checker/CheckerLPDDR4.h @@ -57,7 +57,25 @@ 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 tWRRD_R; + sc_time tRDPRE; + sc_time tRDAPRE; + sc_time tRDAACT; + sc_time tWRPRE; + sc_time tWRAPRE; + sc_time tWRAACT; + sc_time tACTPDEN; + sc_time tPRPDEN; + sc_time tRDPDEN; + sc_time tWRPDEN; + sc_time tWRAPDEN; + sc_time tREFPDEN; }; #endif // CHECKERLPDDR4_H diff --git a/DRAMSys/library/src/controller/checker/CheckerWideIO.cpp b/DRAMSys/library/src/controller/checker/CheckerWideIO.cpp index c0236fee..034c76c6 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,114 @@ 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::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 + 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::PDXP) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + } + 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::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 +396,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..59f37315 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::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 + 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::PDXP) + { + lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()]; + if (lastCommandStart != SC_ZERO_TIME) + earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE); + } + 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::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;