Merge branch 'development' into xml_to_json

# Conflicts:
#	DRAMSys/library/src/configuration/ConfigurationLoader.cpp
This commit is contained in:
Lukas Steiner
2020-05-26 16:04:13 +02:00
29 changed files with 3009 additions and 1222 deletions

View File

@@ -33,6 +33,7 @@
* Janik Schlemminger
* Matthias Jung
* Lukas Steiner
* Luiza Correa
*/
#include "ConfigurationLoader.h"
@@ -42,7 +43,6 @@ using json = nlohmann::json;
void ConfigurationLoader::loadSimConfig(Configuration &config,
std::string simconfigUri)
{
json doc = parseJSON(simconfigUri);
auto simconfig = doc["simconfig"].get_ptr<json::object_t*>();
loadConfigJson(config, simconfig);
@@ -55,7 +55,6 @@ void ConfigurationLoader::loadTemperatureSimConfig(Configuration &config,
json doc = parseJSON(thermalsimconfigUri);
auto thermalconfig = doc["thermalsimconfig"].get_ptr<json::object_t*>();
loadConfigJson(config, thermalconfig);
}
@@ -191,27 +190,33 @@ void ConfigurationLoader::loadDDR3(Configuration &config, json::object_t *jsonSp
// MemTimings specific for DDR3
std::string timings = "memtimingspec";
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
memSpec->tCKESR = memSpec->tCK * uIntParameter(j[timings]["CKESR"], "CKESR");
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
memSpec->tRC = memSpec->tCK * uIntParameter(j[timings]["RC"], "RC");
memSpec->tRCD = memSpec->tCK * uIntParameter(j[timings]["RCD"], "RCD");
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");
memSpec->tRTP = memSpec->tCK * uIntParameter(j[timings]["RTP"], "RTP");
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
memSpec->tXP = memSpec->tCK * uIntParameter(j[timings]["XP"], "XP");
memSpec->tXS = memSpec->tCK * uIntParameter(j[timings]["XS"], "XS");
memSpec->tCCD = memSpec->tCK * uIntParameter(j[timings]["CCD"], "CCD");
memSpec->tFAW = memSpec->tCK * uIntParameter(j[timings]["FAW"], "FAW");
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC"], "RFC");
memSpec->tRP = memSpec->tCK * uIntParameter(j[timings]["RP"], "RP");
memSpec->tRRD = memSpec->tCK * uIntParameter(j[timings]["RRD"], "RRD");
memSpec->tWTR = memSpec->tCK * uIntParameter(j[timings]["WTR"], "WTR");
memSpec->tAL = memSpec->tCK * uIntParameter(j[timings]["AL"], "AL");
memSpec->tXPDLL = memSpec->tCK * uIntParameter(j[timings]["XPDLL"], "XPDLL");
memSpec->tXSDLL = memSpec->tCK * uIntParameter(j[timings]["XSDLL"], "XSDLL");
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
memSpec->tPD = memSpec->tCKE;
memSpec->tCKESR = memSpec->tCK * uIntParameter(j[timings]["CKESR"], "CKESR");
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["DQSCK"], "DQSCK");
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
memSpec->tRC = memSpec->tCK * uIntParameter(j[timings]["RC"], "RC");
memSpec->tRCD = memSpec->tCK * uIntParameter(j[timings]["RCD"], "RCD");
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");
memSpec->tRTP = memSpec->tCK * uIntParameter(j[timings]["RTP"], "RTP");
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
memSpec->tXP = memSpec->tCK * uIntParameter(j[timings]["XP"], "XP");
memSpec->tXS = memSpec->tCK * uIntParameter(j[timings]["XS"], "XS");
memSpec->tCCD = memSpec->tCK * uIntParameter(j[timings]["CCD"], "CCD");
memSpec->tFAW = memSpec->tCK * uIntParameter(j[timings]["FAW"], "FAW");
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC"], "RFC");
memSpec->tRP = memSpec->tCK * uIntParameter(j[timings]["RP"], "RP");
memSpec->tRRD = memSpec->tCK * uIntParameter(j[timings]["RRD"], "RRD");
memSpec->tWTR = memSpec->tCK * uIntParameter(j[timings]["WTR"], "WTR");
memSpec->tAL = memSpec->tCK * uIntParameter(j[timings]["AL"], "AL");
memSpec->tXPDLL = memSpec->tCK * uIntParameter(j[timings]["XPDLL"], "XPDLL");
memSpec->tXSDLL = memSpec->tCK * uIntParameter(j[timings]["XSDLL"], "XSDLL");
memSpec->tACTPDEN = memSpec->tCK * uIntParameter(j[timings]["ACTPDEN"], "ACTPDEN");
memSpec->tPRPDEN = memSpec->tCK * uIntParameter(j[timings]["PRPDEN"], "PRPDEN");
memSpec->tREFPDEN = memSpec->tCK * uIntParameter(j[timings]["REFPDEN"], "REFPDEN");
memSpec->tRTRS = memSpec->tCK * uIntParameter(j[timings]["RTRS"], "RTRS");
// Currents and voltages
std::string power = "mempowerspec";
@@ -248,11 +253,14 @@ void ConfigurationLoader::loadDDR4(Configuration &config, json::object_t *jsonSp
// MemTimings specific for DDR4
std::string timings = "memtimingspec";
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
memSpec->tPD = memSpec->tCKE;
memSpec->tCKESR = memSpec->tCK * uIntParameter(j[timings]["CKESR"], "CKESR");
memSpec->tDQSCK = memSpec->tCK * uIntParameter(j[timings]["DQSCK"], "DQSCK");
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
memSpec->tRC = memSpec->tCK * uIntParameter(j[timings]["RC"], "RC");
memSpec->tRCD = memSpec->tCK * uIntParameter(j[timings]["RCD"], "RCD");
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");;
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");
memSpec->tRTP = memSpec->tCK * uIntParameter(j[timings]["RTP"], "RTP");
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
memSpec->tXP = memSpec->tCK * uIntParameter(j[timings]["XP"], "XP");
@@ -260,32 +268,38 @@ void ConfigurationLoader::loadDDR4(Configuration &config, json::object_t *jsonSp
memSpec->tCCD_S = memSpec->tCK * uIntParameter(j[timings]["CCD_S"], "CCD_S");
memSpec->tCCD_L = memSpec->tCK * uIntParameter(j[timings]["CCD_L"], "CCD_L");
memSpec->tFAW = memSpec->tCK * uIntParameter(j[timings]["FAW"], "FAW");
unsigned refreshMode = Configuration::getInstance().refreshMode;
if (refreshMode == 1)
{
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC"], "RFC");
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC"], "RFC");
}
else if (refreshMode == 2)
{
memSpec->tREFI = memSpec->tCK * (uIntParameter(j[timings]["REFI"], "REFI")/ 2);
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC2"], "RFC2");
memSpec->tREFI = memSpec->tCK * (uIntParameter(j[timings]["REFI"], "REFI") / 2);
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC2"], "RFC2");
}
else if (refreshMode == 4)
{
memSpec->tREFI = memSpec->tCK * (uIntParameter(j[timings]["REFI"], "REFI")/ 2);
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC4"], "RFC4");
memSpec->tREFI = memSpec->tCK * (uIntParameter(j[timings]["REFI"], "REFI") / 2);
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC4"], "RFC4");
}
else
SC_REPORT_FATAL("ConfigurationLoader", "Refresh Mode not supported");
memSpec->tRP = memSpec->tCK * uIntParameter(j[timings]["RP"], "RP");
memSpec->tRRD_S = memSpec->tCK * uIntParameter(j[timings]["RRD_S"], "RRD_S");
memSpec->tRRD_L = memSpec->tCK * uIntParameter(j[timings]["RRD_L"], "RRD_L");
memSpec->tWTR_S = memSpec->tCK * uIntParameter(j[timings]["WTR_S"], "WTR_S");
memSpec->tWTR_L = memSpec->tCK * uIntParameter(j[timings]["WTR_L"], "WTR_L");
memSpec->tAL = memSpec->tCK * uIntParameter(j[timings]["AL"], "AL");
memSpec->tXPDLL = memSpec->tCK * uIntParameter(j[timings]["XPDLL"], "XPDLL");
memSpec->tXSDLL = memSpec->tCK * uIntParameter(j[timings]["XSDLL"], "XSDLL");
memSpec->tRP = memSpec->tCK * uIntParameter(j[timings]["RP"], "RP");
memSpec->tRRD_S = memSpec->tCK * uIntParameter(j[timings]["RRD_S"], "RRD_S");
memSpec->tRRD_L = memSpec->tCK * uIntParameter(j[timings]["RRD_L"], "RRD_L");
memSpec->tWTR_S = memSpec->tCK * uIntParameter(j[timings]["WTR_S"], "WTR_S");
memSpec->tWTR_L = memSpec->tCK * uIntParameter(j[timings]["WTR_L"], "WTR_L");
memSpec->tAL = memSpec->tCK * uIntParameter(j[timings]["AL"], "AL");
memSpec->tXPDLL = memSpec->tCK * uIntParameter(j[timings]["XPDLL"], "XPDLL");
memSpec->tXSDLL = memSpec->tCK * uIntParameter(j[timings]["XSDLL"], "XSDLL");
memSpec->tACTPDEN = memSpec->tCK * uIntParameter(j[timings]["ACTPDEN"], "ACTPDEN");
memSpec->tPRPDEN = memSpec->tCK * uIntParameter(j[timings]["PRPDEN"], "PRPDEN");
memSpec->tREFPDEN = memSpec->tCK * uIntParameter(j[timings]["REFPDEN"], "REFPDEN");
memSpec->tRTRS = memSpec->tCK * uIntParameter(j[timings]["RTRS"], "RTRS");
// Currents and voltages
std::string power = "mempowerspec";
@@ -324,35 +338,38 @@ void ConfigurationLoader::loadLPDDR4(Configuration &config, json::object_t *jso
// MemTimings specific for LPDDR4
std::string timings = "memtimingspec";
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
memSpec->tREFIpb = memSpec->tCK * uIntParameter(j[timings]["REFIPB"], "REFIPB");
memSpec->tRFCab = memSpec->tCK * uIntParameter(j[timings]["RFCAB"], "RFCAB");
memSpec->tRFCpb = memSpec->tCK * uIntParameter(j[timings]["RFCPB"], "RFCPB");
memSpec->tRPab = memSpec->tCK * uIntParameter(j[timings]["RPAB"], "RPAB");
memSpec->tRPpb = memSpec->tCK * uIntParameter(j[timings]["RPPB"], "RPPB");
memSpec->tPPD = memSpec->tCK * uIntParameter(j[timings]["PPD"], "PPD");
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
memSpec->tRCD = memSpec->tCK * uIntParameter(j[timings]["RCD"], "RCD");
memSpec->tFAW = memSpec->tCK * uIntParameter(j[timings]["FAW"], "FAW");
memSpec->tRRD = memSpec->tCK * uIntParameter(j[timings]["RRD"], "RRD");
memSpec->tCCD = memSpec->tCK * uIntParameter(j[timings]["CCD"], "CCD");
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");
memSpec->tRPST = memSpec->tCK * uIntParameter(j[timings]["RPST"], "RPST");
memSpec->tDQSCK = memSpec->tCK * uIntParameter(j[timings]["DQSCK"], "DQSCK");
memSpec->tRTP = memSpec->tCK * uIntParameter(j[timings]["RTP"], "RTP");
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
memSpec->tDQSS = memSpec->tCK * uIntParameter(j[timings]["DQSS"], "DQSS");
memSpec->tRFCab = memSpec->tCK * uIntParameter(j[timings]["RFCAB"], "RFCAB");
memSpec->tRFCpb = memSpec->tCK * uIntParameter(j[timings]["RFCPB"], "RFCPB");
memSpec->tRPab = memSpec->tCK * uIntParameter(j[timings]["RPAB"], "RPAB");
memSpec->tRPpb = memSpec->tCK * uIntParameter(j[timings]["RPPB"], "RPPB");
memSpec->tRCab = memSpec->tCK * uIntParameter(j[timings]["RCAB"], "RCAB");
memSpec->tRCpb = memSpec->tCK * uIntParameter(j[timings]["RCPB"], "RCPB");
memSpec->tPPD = memSpec->tCK * uIntParameter(j[timings]["PPD"], "PPD");
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
memSpec->tRCD = memSpec->tCK * uIntParameter(j[timings]["RCD"], "RCD");
memSpec->tFAW = memSpec->tCK * uIntParameter(j[timings]["FAW"], "FAW");
memSpec->tRRD = memSpec->tCK * uIntParameter(j[timings]["RRD"], "RRD");
memSpec->tCCD = memSpec->tCK * uIntParameter(j[timings]["CCD"], "CCD");
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");
memSpec->tRPST = memSpec->tCK * uIntParameter(j[timings]["RPST"], "RPST");
memSpec->tDQSCK = memSpec->tCK * uIntParameter(j[timings]["DQSCK"], "DQSCK");
memSpec->tRTP = memSpec->tCK * uIntParameter(j[timings]["RTP"], "RTP");
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
memSpec->tDQSS = memSpec->tCK * uIntParameter(j[timings]["DQSS"], "DQSS");
memSpec->tDQS2DQ = memSpec->tCK * uIntParameter(j[timings]["DQS2DQ"], "DQS2DQ");
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
memSpec->tWPRE = memSpec->tCK * uIntParameter(j[timings]["WPRE"], "WPRE");
memSpec->tWTR = memSpec->tCK * uIntParameter(j[timings]["WTR"], "WTR");
memSpec->tXP = memSpec->tCK * uIntParameter(j[timings]["XP"], "XP");
memSpec->tSR = memSpec->tCK * uIntParameter(j[timings]["SR"], "SR");
memSpec->tXSR = memSpec->tCK * uIntParameter(j[timings]["XSR"], "XSR");
memSpec->tESCKE = memSpec->tCK * uIntParameter(j[timings]["ESCKE"], "ESCKE");
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
memSpec->tWPRE = memSpec->tCK * uIntParameter(j[timings]["WPRE"], "WPRE");
memSpec->tWTR = memSpec->tCK * uIntParameter(j[timings]["WTR"], "WTR");
memSpec->tXP = memSpec->tCK * uIntParameter(j[timings]["XP"], "XP");
memSpec->tSR = memSpec->tCK * uIntParameter(j[timings]["SR"], "SR");
memSpec->tXSR = memSpec->tCK * uIntParameter(j[timings]["XSR"], "XSR");
memSpec->tESCKE = memSpec->tCK * uIntParameter(j[timings]["ESCKE"], "ESCKE");
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
memSpec->tCMDCKE = memSpec->tCK * uIntParameter(j[timings]["CMDCKE"], "CMDCKE");
memSpec->tRTRS = memSpec->tCK * uIntParameter(j[timings]["RTRS"], "RTRS");
// Currents and voltages
// TODO: to be completed
}
@@ -365,7 +382,6 @@ void ConfigurationLoader::loadWideIO(Configuration &config, json::object_t *jso
json j = *jsonSpec;
// MemArchitecture
std::string arch = "memarchitecturespec";
memSpec->numberOfRanks = uIntParameter(j[arch]["nbrOfRanks"], "nbrOfRanks");
memSpec->banksPerRank = uIntParameter(j[arch]["nbrOfBanks"], "nbrOfBanks");
@@ -376,26 +392,27 @@ void ConfigurationLoader::loadWideIO(Configuration &config, json::object_t *jso
// MemTimings specific for WideIO
std::string timings = "memtimingspec";
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
memSpec->tCKESR = memSpec->tCK * uIntParameter(j[timings]["CKESR"], "CKESR");
memSpec->tDQSCK = memSpec->tCK * uIntParameter(j[timings]["DQSCK"], "DQSCK");
memSpec->tAC = memSpec->tCK * uIntParameter(j[timings]["AC"], "AC");
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
memSpec->tRC = memSpec->tCK * uIntParameter(j[timings]["RC"], "RC");
memSpec->tRCD = memSpec->tCK * uIntParameter(j[timings]["RCD"], "RCD");
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
memSpec->tXP = memSpec->tCK * uIntParameter(j[timings]["XP"], "XP");
memSpec->tXS = memSpec->tCK * uIntParameter(j[timings]["XS"], "XS");
memSpec->tAC = memSpec->tCK * uIntParameter(j[timings]["AC"], "AC");
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
memSpec->tRC = memSpec->tCK * uIntParameter(j[timings]["RC"], "RC");
memSpec->tRCD = memSpec->tCK * uIntParameter(j[timings]["RCD"], "RCD");
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
memSpec->tXP = memSpec->tCK * uIntParameter(j[timings]["XP"], "XP");
memSpec->tXSR = memSpec->tCK * uIntParameter(j[timings]["XSR"], "XSR");
memSpec->tCCD_R = memSpec->tCK * uIntParameter(j[timings]["CCD_R"], "CCD_R");
memSpec->tCCD_W = memSpec->tCK * uIntParameter(j[timings]["CCD_W"], "CCD_W");
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC"], "RFC");
memSpec->tRP = memSpec->tCK * uIntParameter(j[timings]["RP"], "RP");
memSpec->tRRD = memSpec->tCK * uIntParameter(j[timings]["RRD"], "RRD");
memSpec->tTAW = memSpec->tCK * uIntParameter(j[timings]["TAW"], "TAW");
memSpec->tWTR = memSpec->tCK * uIntParameter(j[timings]["WTR"], "WTR");
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC"], "RFC");
memSpec->tRP = memSpec->tCK * uIntParameter(j[timings]["RP"], "RP");
memSpec->tRRD = memSpec->tCK * uIntParameter(j[timings]["RRD"], "RRD");
memSpec->tTAW = memSpec->tCK * uIntParameter(j[timings]["TAW"], "TAW");
memSpec->tWTR = memSpec->tCK * uIntParameter(j[timings]["WTR"], "WTR");
memSpec->tRTRS = memSpec->tCK * uIntParameter(j[timings]["RTRS"], "RTRS");
// Currents and voltages
std::string power = "mempowerspec";
@@ -433,7 +450,6 @@ void ConfigurationLoader::loadWideIO2(Configuration &config, json::object_t *js
json j = *jsonSpec;
// MemArchitecture
std::string arch = "memarchitecturespec";
memSpec->numberOfRanks = uIntParameter(j[arch]["nbrOfRanks"], "nbrOfRanks");
memSpec->banksPerRank = uIntParameter(j[arch]["nbrOfBanks"], "nbrOfBanks");
@@ -444,30 +460,31 @@ void ConfigurationLoader::loadWideIO2(Configuration &config, json::object_t *js
// MemTimings specific for WideIO
std::string timings = "memtimingspec";
memSpec->tDQSCK = memSpec->tCK * uIntParameter(j[timings]["DQSCK"], "DQSCK");
memSpec->tDQSS = memSpec->tCK * uIntParameter(j[timings]["DQSS"], "DQSS");
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
memSpec->tRCpb = memSpec->tCK * uIntParameter(j[timings]["RCPB"], "RCPB");
memSpec->tRCab = memSpec->tCK * uIntParameter(j[timings]["RCAB"], "RCAB");
memSpec->tCKESR = memSpec->tCK * uIntParameter(j[timings]["CKESR"], "CKESR");
memSpec->tXSR = memSpec->tCK * uIntParameter(j[timings]["XSR"], "XSR");
memSpec->tXP = memSpec->tCK * uIntParameter(j[timings]["XP"], "XP");
memSpec->tCCD = memSpec->tCK * uIntParameter(j[timings]["CCD"], "CCD");
memSpec->tRTP = memSpec->tCK * uIntParameter(j[timings]["RTP"], "RTP");
memSpec->tRCD = memSpec->tCK * uIntParameter(j[timings]["RCD"], "RCD");
memSpec->tRPpb = memSpec->tCK * uIntParameter(j[timings]["RPPB"], "RPPB");
memSpec->tRPab = memSpec->tCK * uIntParameter(j[timings]["RPAB"], "RPAB");
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
memSpec->tWTR = memSpec->tCK * uIntParameter(j[timings]["WTR"], "WTR");
memSpec->tRRD = memSpec->tCK * uIntParameter(j[timings]["RRD"], "RRD");
memSpec->tFAW = memSpec->tCK * uIntParameter(j[timings]["FAW"], "FAW");
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
memSpec->tDQSCK = memSpec->tCK * uIntParameter(j[timings]["DQSCK"], "DQSCK");
memSpec->tDQSS = memSpec->tCK * uIntParameter(j[timings]["DQSS"], "DQSS");
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
memSpec->tRCpb = memSpec->tCK * uIntParameter(j[timings]["RCPB"], "RCPB");
memSpec->tRCab = memSpec->tCK * uIntParameter(j[timings]["RCAB"], "RCAB");
memSpec->tCKESR = memSpec->tCK * uIntParameter(j[timings]["CKESR"], "CKESR");
memSpec->tXSR = memSpec->tCK * uIntParameter(j[timings]["XSR"], "XSR");
memSpec->tXP = memSpec->tCK * uIntParameter(j[timings]["XP"], "XP");
memSpec->tCCD = memSpec->tCK * uIntParameter(j[timings]["CCD"], "CCD");
memSpec->tRTP = memSpec->tCK * uIntParameter(j[timings]["RTP"], "RTP");
memSpec->tRCD = memSpec->tCK * uIntParameter(j[timings]["RCD"], "RCD");
memSpec->tRPpb = memSpec->tCK * uIntParameter(j[timings]["RPPB"], "RPPB");
memSpec->tRPab = memSpec->tCK * uIntParameter(j[timings]["RPAB"], "RPAB");
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
memSpec->tWTR = memSpec->tCK * uIntParameter(j[timings]["WTR"], "WTR");
memSpec->tRRD = memSpec->tCK * uIntParameter(j[timings]["RRD"], "RRD");
memSpec->tFAW = memSpec->tCK * uIntParameter(j[timings]["FAW"], "FAW");
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
memSpec->tREFIpb = memSpec->tCK * uIntParameter(j[timings]["REFIPB"], "REFIPB");
memSpec->tRFCab = memSpec->tCK * uIntParameter(j[timings]["RFCAB"], "RFCAB");
memSpec->tRFCpb = memSpec->tCK * uIntParameter(j[timings]["RFCPB"], "RFCPB");
memSpec->tRFCab = memSpec->tCK * uIntParameter(j[timings]["RFCAB"], "RFCAB");
memSpec->tRFCpb = memSpec->tCK * uIntParameter(j[timings]["RFCPB"], "RFCPB");
memSpec->tRTRS = memSpec->tCK * uIntParameter(j[timings]["RTRS"], "RTRS");
// Currents and voltages
// TODO: to be completed
@@ -481,7 +498,6 @@ void ConfigurationLoader::loadHBM2(Configuration &config, json::object_t *jsonS
json j = *jsonSpec;
// MemArchitecture
std::string arch = "memarchitecturespec";
memSpec->numberOfRanks = uIntParameter(j[arch]["nbrOfRanks"], "nbrOfRanks");
memSpec->banksPerRank = uIntParameter(j[arch]["nbrOfBanks"], "nbrOfBanks");
@@ -492,42 +508,34 @@ void ConfigurationLoader::loadHBM2(Configuration &config, json::object_t *jsonS
// MemTimings specific for HBM2
std::string timings = "memtimingspec";
memSpec->tDQSCK = memSpec->tCK * uIntParameter(j[timings]["DQSCK"], "DQSCK");
memSpec->tRC = memSpec->tCK * uIntParameter(j[timings]["RC"], "RC");
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
memSpec->tRCDRD = memSpec->tCK * uIntParameter(j[timings]["RCDRD"], "RCDRD");
memSpec->tRCDWR = memSpec->tCK * uIntParameter(j[timings]["RCDWR"], "RCDWR");
memSpec->tRRDL = memSpec->tCK * uIntParameter(j[timings]["RRDL"], "RRDL");
memSpec->tRRDS = memSpec->tCK * uIntParameter(j[timings]["RRDS"], "RRDS");
memSpec->tFAW = memSpec->tCK * uIntParameter(j[timings]["FAW"], "FAW");
memSpec->tRTP = memSpec->tCK * uIntParameter(j[timings]["RTP"], "RTP");
memSpec->tRP = memSpec->tCK * uIntParameter(j[timings]["RP"], "RP");
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
memSpec->tPL = memSpec->tCK * uIntParameter(j[timings]["PL"], "PL");
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
memSpec->tCCDL = memSpec->tCK * uIntParameter(j[timings]["CCDL"], "CCDL");
memSpec->tCCDS = memSpec->tCK * uIntParameter(j[timings]["CCDS"], "CCDS");
memSpec->tWTRL = memSpec->tCK * uIntParameter(j[timings]["WTRL"], "WTRL");
memSpec->tWTRS = memSpec->tCK * uIntParameter(j[timings]["WTRS"], "WTRS");
memSpec->tRTW = memSpec->tCK * uIntParameter(j[timings]["RTW"], "RTW");
memSpec->tXP = memSpec->tCK * uIntParameter(j[timings]["XP"], "XP");
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "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 * uIntParameter(j[timings]["XS"], "XS");
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC"], "RFC");
memSpec->tRFCSB = memSpec->tCK * uIntParameter(j[timings]["RFCSB"], "RFCSB");
memSpec->tRREFD = memSpec->tCK * uIntParameter(j[timings]["RREFD"], "RREFD");
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
memSpec->tDQSCK = memSpec->tCK * uIntParameter(j[timings]["DQSCK"], "DQSCK");
memSpec->tRC = memSpec->tCK * uIntParameter(j[timings]["RC"], "RC");
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
memSpec->tRCDRD = memSpec->tCK * uIntParameter(j[timings]["RCDRD"], "RCDRD");
memSpec->tRCDWR = memSpec->tCK * uIntParameter(j[timings]["RCDWR"], "RCDWR");
memSpec->tRRDL = memSpec->tCK * uIntParameter(j[timings]["RRDL"], "RRDL");
memSpec->tRRDS = memSpec->tCK * uIntParameter(j[timings]["RRDS"], "RRDS");
memSpec->tFAW = memSpec->tCK * uIntParameter(j[timings]["FAW"], "FAW");
memSpec->tRTP = memSpec->tCK * uIntParameter(j[timings]["RTP"], "RTP");
memSpec->tRP = memSpec->tCK * uIntParameter(j[timings]["RP"], "RP");
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
memSpec->tPL = memSpec->tCK * uIntParameter(j[timings]["PL"], "PL");
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
memSpec->tCCDL = memSpec->tCK * uIntParameter(j[timings]["CCDL"], "CCDL");
memSpec->tCCDS = memSpec->tCK * uIntParameter(j[timings]["CCDS"], "CCDS");
memSpec->tWTRL = memSpec->tCK * uIntParameter(j[timings]["WTRL"], "WTRL");
memSpec->tWTRS = memSpec->tCK * uIntParameter(j[timings]["WTRS"], "WTRS");
memSpec->tRTW = memSpec->tCK * uIntParameter(j[timings]["RTW"], "RTW");
memSpec->tXP = memSpec->tCK * uIntParameter(j[timings]["XP"], "XP");
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
memSpec->tPD = memSpec->tCKE;
memSpec->tCKESR = memSpec->tCKE + memSpec->tCK;
memSpec->tXS = memSpec->tCK * uIntParameter(j[timings]["XS"], "XS");
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC"], "RFC");
memSpec->tRFCSB = memSpec->tCK * uIntParameter(j[timings]["RFCSB"], "RFCSB");
memSpec->tRREFD = memSpec->tCK * uIntParameter(j[timings]["RREFD"], "RREFD");
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
memSpec->tREFISB = memSpec->tCK * uIntParameter(j[timings]["REFISB"], "REFISB");
// Currents and voltages
@@ -542,7 +550,6 @@ void ConfigurationLoader::loadGDDR5(Configuration &config, json::object_t *json
json j = *jsonSpec;
// MemArchitecture
std::string arch = "memarchitecturespec";
memSpec->numberOfRanks = uIntParameter(j[arch]["nbrOfRanks"], "nbrOfRanks");
memSpec->banksPerRank = uIntParameter(j[arch]["nbrOfBanks"], "nbrOfBanks");
@@ -553,43 +560,44 @@ void ConfigurationLoader::loadGDDR5(Configuration &config, json::object_t *json
// MemTimings specific for GDDR5
std::string timings = "memtimingspec";
memSpec->tRP = memSpec->tCK * uIntParameter(j[timings]["RP"], "RP");
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
memSpec->tRC = memSpec->tCK * uIntParameter(j[timings]["RC"], "RC");
memSpec->tRCDRD = memSpec->tCK * uIntParameter(j[timings]["RCDRD"], "RCDRD");
memSpec->tRCDWR = memSpec->tCK * uIntParameter(j[timings]["RCDWR"], "RCDWR");
memSpec->tRTP = memSpec->tCK * uIntParameter(j[timings]["RTP"], "RTP");
memSpec->tRRDS = memSpec->tCK * uIntParameter(j[timings]["RRDS"], "RRDS");
memSpec->tRRDL = memSpec->tCK * uIntParameter(j[timings]["RRDL"], "RRDL");
memSpec->tCCDS = memSpec->tCK * uIntParameter(j[timings]["CCDS"], "CCDS");
memSpec->tCCDL = memSpec->tCK * uIntParameter(j[timings]["CCDL"], "CCDL");
memSpec->tCL = memSpec->tCK * uIntParameter(j[timings]["CL"], "CL");
memSpec->tRP = memSpec->tCK * uIntParameter(j[timings]["RP"], "RP");
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
memSpec->tRC = memSpec->tCK * uIntParameter(j[timings]["RC"], "RC");
memSpec->tRCDRD = memSpec->tCK * uIntParameter(j[timings]["RCDRD"], "RCDRD");
memSpec->tRCDWR = memSpec->tCK * uIntParameter(j[timings]["RCDWR"], "RCDWR");
memSpec->tRTP = memSpec->tCK * uIntParameter(j[timings]["RTP"], "RTP");
memSpec->tRRDS = memSpec->tCK * uIntParameter(j[timings]["RRDS"], "RRDS");
memSpec->tRRDL = memSpec->tCK * uIntParameter(j[timings]["RRDL"], "RRDL");
memSpec->tCCDS = memSpec->tCK * uIntParameter(j[timings]["CCDS"], "CCDS");
memSpec->tCCDL = memSpec->tCK * uIntParameter(j[timings]["CCDL"], "CCDL");
memSpec->tCL = memSpec->tCK * uIntParameter(j[timings]["CL"], "CL");
memSpec->tWCK2CKPIN = memSpec->tCK * uIntParameter(j[timings]["WCK2CKPIN"], "WCK2CKPIN");
memSpec->tWCK2CK = memSpec->tCK * uIntParameter(j[timings]["WCK2CK"], "WCK2CK");
memSpec->tWCK2DQO = memSpec->tCK * uIntParameter(j[timings]["WCK2DQO"], "WCK2DQO");
memSpec->tRTW = memSpec->tCK * uIntParameter(j[timings]["RTW"], "RTW");
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
memSpec->tWCK2DQI = memSpec->tCK * uIntParameter(j[timings]["WCK2DQI"], "WCK2DQI");
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
memSpec->tWTRS = memSpec->tCK * uIntParameter(j[timings]["WTRS"], "WTRS");
memSpec->tWTRL = memSpec->tCK * uIntParameter(j[timings]["WTRL"], "WTRL");
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
memSpec->tPD = memSpec->tCKE;
memSpec->tXPN = memSpec->tCK * uIntParameter(j[timings]["XPN"], "XPN");
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
memSpec->tREFIPB = memSpec->tCK * uIntParameter(j[timings]["REFIPB"], "REFIPB");
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC"], "RFC");
memSpec->tRFCPB = memSpec->tCK * uIntParameter(j[timings]["RFCPB"], "RFCPB");
memSpec->tRREFD = memSpec->tCK * uIntParameter(j[timings]["RREFD"], "RREFD");
memSpec->tXS = memSpec->tCK * uIntParameter(j[timings]["XS"], "XS");
memSpec->tFAW = memSpec->tCK * uIntParameter(j[timings]["FAW"], "FAW");
memSpec->t32AW = memSpec->tCK * uIntParameter(j[timings]["32AW"], "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->tPPD = memSpec->tCK * uIntParameter(j[timings]["PPD"], "PPD");
memSpec->tLK = memSpec->tCK * uIntParameter(j[timings]["LK"], "LK");
memSpec->tWCK2CK = memSpec->tCK * uIntParameter(j[timings]["WCK2CK"], "WCK2CK");
memSpec->tWCK2DQO = memSpec->tCK * uIntParameter(j[timings]["WCK2DQO"], "WCK2DQO");
memSpec->tRTW = memSpec->tCK * uIntParameter(j[timings]["RTW"], "RTW");
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
memSpec->tWCK2DQI = memSpec->tCK * uIntParameter(j[timings]["WCK2DQI"], "WCK2DQI");
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
memSpec->tWTRS = memSpec->tCK * uIntParameter(j[timings]["WTRS"], "WTRS");
memSpec->tWTRL = memSpec->tCK * uIntParameter(j[timings]["WTRL"], "WTRL");
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
memSpec->tPD = memSpec->tCK * uIntParameter(j[timings]["PD"], "PD");
memSpec->tXPN = memSpec->tCK * uIntParameter(j[timings]["XPN"], "XPN");
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
memSpec->tREFIPB = memSpec->tCK * uIntParameter(j[timings]["REFIPB"], "REFIPB");
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC"], "RFC");
memSpec->tRFCPB = memSpec->tCK * uIntParameter(j[timings]["RFCPB"], "RFCPB");
memSpec->tRREFD = memSpec->tCK * uIntParameter(j[timings]["RREFD"], "RREFD");
memSpec->tXS = memSpec->tCK * uIntParameter(j[timings]["XS"], "XS");
memSpec->tFAW = memSpec->tCK * uIntParameter(j[timings]["FAW"], "FAW");
memSpec->t32AW = memSpec->tCK * uIntParameter(j[timings]["32AW"], "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->tPPD = memSpec->tCK * uIntParameter(j[timings]["PPD"], "PPD");
memSpec->tLK = memSpec->tCK * uIntParameter(j[timings]["LK"], "LK");
memSpec->tRTRS = memSpec->tCK * uIntParameter(j[timings]["RTRS"], "RTRS");
// Currents and voltages
// TODO: to be completed
@@ -603,7 +611,6 @@ void ConfigurationLoader::loadGDDR5X(Configuration &config, json::object_t *jso
json j = *jsonSpec;
// MemArchitecture
std::string arch = "memarchitecturespec";
memSpec->numberOfRanks = uIntParameter(j[arch]["nbrOfRanks"], "nbrOfRanks");
memSpec->banksPerRank = uIntParameter(j[arch]["nbrOfBanks"], "nbrOfBanks");
@@ -614,43 +621,44 @@ void ConfigurationLoader::loadGDDR5X(Configuration &config, json::object_t *jso
// MemTimings specific for GDDR5X
std::string timings = "memtimingspec";
memSpec->tRP = memSpec->tCK * uIntParameter(j[timings]["RP"], "RP");
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
memSpec->tRC = memSpec->tCK * uIntParameter(j[timings]["RC"], "RC");
memSpec->tRCDRD = memSpec->tCK * uIntParameter(j[timings]["RCDRD"], "RCDRD");
memSpec->tRCDWR = memSpec->tCK * uIntParameter(j[timings]["RCDWR"], "RCDWR");
memSpec->tRTP = memSpec->tCK * uIntParameter(j[timings]["RTP"], "RTP");
memSpec->tRRDS = memSpec->tCK * uIntParameter(j[timings]["RRDS"], "RRDS");
memSpec->tRRDL = memSpec->tCK * uIntParameter(j[timings]["RRDL"], "RRDL");
memSpec->tCCDS = memSpec->tCK * uIntParameter(j[timings]["CCDS"], "CCDS");
memSpec->tCCDL = memSpec->tCK * uIntParameter(j[timings]["CCDL"], "CCDL");
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");
memSpec->tRP = memSpec->tCK * uIntParameter(j[timings]["RP"], "RP");
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
memSpec->tRC = memSpec->tCK * uIntParameter(j[timings]["RC"], "RC");
memSpec->tRCDRD = memSpec->tCK * uIntParameter(j[timings]["RCDRD"], "RCDRD");
memSpec->tRCDWR = memSpec->tCK * uIntParameter(j[timings]["RCDWR"], "RCDWR");
memSpec->tRTP = memSpec->tCK * uIntParameter(j[timings]["RTP"], "RTP");
memSpec->tRRDS = memSpec->tCK * uIntParameter(j[timings]["RRDS"], "RRDS");
memSpec->tRRDL = memSpec->tCK * uIntParameter(j[timings]["RRDL"], "RRDL");
memSpec->tCCDS = memSpec->tCK * uIntParameter(j[timings]["CCDS"], "CCDS");
memSpec->tCCDL = memSpec->tCK * uIntParameter(j[timings]["CCDL"], "CCDL");
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");
memSpec->tWCK2CKPIN = memSpec->tCK * uIntParameter(j[timings]["WCK2CKPIN"], "WCK2CKPIN");
memSpec->tWCK2CK = memSpec->tCK * uIntParameter(j[timings]["WCK2CK"], "WCK2CK");
memSpec->tWCK2DQO = memSpec->tCK * uIntParameter(j[timings]["WCK2DQO"], "WCK2DQO");
memSpec->tRTW = memSpec->tCK * uIntParameter(j[timings]["RTW"], "RTW");
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
memSpec->tWCK2DQI = memSpec->tCK * uIntParameter(j[timings]["WCK2DQI"], "WCK2DQI");
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
memSpec->tWTRS = memSpec->tCK * uIntParameter(j[timings]["WTRS"], "WTRS");
memSpec->tWTRL = memSpec->tCK * uIntParameter(j[timings]["WTRL"], "WTRL");
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
memSpec->tPD = memSpec->tCKE;
memSpec->tXP = memSpec->tCK * uIntParameter(j[timings]["XP"], "XP");
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
memSpec->tREFIPB = memSpec->tCK * uIntParameter(j[timings]["REFIPB"], "REFIPB");
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC"], "RFC");
memSpec->tRFCPB = memSpec->tCK * uIntParameter(j[timings]["RFCPB"], "RFCPB");
memSpec->tRREFD = memSpec->tCK * uIntParameter(j[timings]["RREFD"], "RREFD");
memSpec->tXS = memSpec->tCK * uIntParameter(j[timings]["XS"], "XS");
memSpec->tFAW = memSpec->tCK * uIntParameter(j[timings]["FAW"], "FAW");
memSpec->t32AW = memSpec->tCK * uIntParameter(j[timings]["32AW"], "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->tPPD = memSpec->tCK * uIntParameter(j[timings]["PPD"], "PPD");
memSpec->tLK = memSpec->tCK * uIntParameter(j[timings]["LK"], "LK");
memSpec->tWCK2CK = memSpec->tCK * uIntParameter(j[timings]["WCK2CK"], "WCK2CK");
memSpec->tWCK2DQO = memSpec->tCK * uIntParameter(j[timings]["WCK2DQO"], "WCK2DQO");
memSpec->tRTW = memSpec->tCK * uIntParameter(j[timings]["RTW"], "RTW");
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
memSpec->tWCK2DQI = memSpec->tCK * uIntParameter(j[timings]["WCK2DQI"], "WCK2DQI");
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
memSpec->tWTRS = memSpec->tCK * uIntParameter(j[timings]["WTRS"], "WTRS");
memSpec->tWTRL = memSpec->tCK * uIntParameter(j[timings]["WTRL"], "WTRL");
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
memSpec->tPD = memSpec->tCK * uIntParameter(j[timings]["PD"], "PD");
memSpec->tXP = memSpec->tCK * uIntParameter(j[timings]["XP"], "XP");
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
memSpec->tREFIPB = memSpec->tCK * uIntParameter(j[timings]["REFIPB"], "REFIPB");
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC"], "RFC");
memSpec->tRFCPB = memSpec->tCK * uIntParameter(j[timings]["RFCPB"], "RFCPB");
memSpec->tRREFD = memSpec->tCK * uIntParameter(j[timings]["RREFD"], "RREFD");
memSpec->tXS = memSpec->tCK * uIntParameter(j[timings]["XS"], "XS");
memSpec->tFAW = memSpec->tCK * uIntParameter(j[timings]["FAW"], "FAW");
memSpec->t32AW = memSpec->tCK * uIntParameter(j[timings]["32AW"], "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->tPPD = memSpec->tCK * uIntParameter(j[timings]["PPD"], "PPD");
memSpec->tLK = memSpec->tCK * uIntParameter(j[timings]["LK"], "LK");
memSpec->tRTRS = memSpec->tCK * uIntParameter(j[timings]["RTRS"], "RTRS");
// Currents and voltages
// TODO: to be completed
@@ -664,7 +672,6 @@ void ConfigurationLoader::loadGDDR6(Configuration &config, json::object_t *json
json j = *jsonSpec;
// MemArchitecture
std::string arch = "memarchitecturespec";
memSpec->numberOfRanks = uIntParameter(j[arch]["nbrOfRanks"], "nbrOfRanks");
memSpec->banksPerRank = uIntParameter(j[arch]["nbrOfBanks"], "nbrOfBanks");
@@ -675,46 +682,46 @@ void ConfigurationLoader::loadGDDR6(Configuration &config, json::object_t *json
// MemTimings specific for GDDR6
std::string timings = "memtimingspec";
memSpec->tRP = memSpec->tCK * uIntParameter(j[timings]["RP"], "RP");
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
memSpec->tRC = memSpec->tCK * uIntParameter(j[timings]["RC"], "RC");
memSpec->tRCDRD = memSpec->tCK * uIntParameter(j[timings]["RCDRD"], "RCDRD");
memSpec->tRCDWR = memSpec->tCK * uIntParameter(j[timings]["RCDWR"], "RCDWR");
memSpec->tRTP = memSpec->tCK * uIntParameter(j[timings]["RTP"], "RTP");
memSpec->tRRDS = memSpec->tCK * uIntParameter(j[timings]["RRDS"], "RRDS");
memSpec->tRRDL = memSpec->tCK * uIntParameter(j[timings]["RRDL"], "RRDL");
memSpec->tCCDS = memSpec->tCK * uIntParameter(j[timings]["CCDS"], "CCDS");
memSpec->tCCDL = memSpec->tCK * uIntParameter(j[timings]["CCDL"], "CCDL");
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");
memSpec->tRP = memSpec->tCK * uIntParameter(j[timings]["RP"], "RP");
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
memSpec->tRC = memSpec->tCK * uIntParameter(j[timings]["RC"], "RC");
memSpec->tRCDRD = memSpec->tCK * uIntParameter(j[timings]["RCDRD"], "RCDRD");
memSpec->tRCDWR = memSpec->tCK * uIntParameter(j[timings]["RCDWR"], "RCDWR");
memSpec->tRTP = memSpec->tCK * uIntParameter(j[timings]["RTP"], "RTP");
memSpec->tRRDS = memSpec->tCK * uIntParameter(j[timings]["RRDS"], "RRDS");
memSpec->tRRDL = memSpec->tCK * uIntParameter(j[timings]["RRDL"], "RRDL");
memSpec->tCCDS = memSpec->tCK * uIntParameter(j[timings]["CCDS"], "CCDS");
memSpec->tCCDL = memSpec->tCK * uIntParameter(j[timings]["CCDL"], "CCDL");
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");
memSpec->tWCK2CKPIN = memSpec->tCK * uIntParameter(j[timings]["WCK2CKPIN"], "WCK2CKPIN");
memSpec->tWCK2CK = memSpec->tCK * uIntParameter(j[timings]["WCK2CK"], "WCK2CK");
memSpec->tWCK2DQO = memSpec->tCK * uIntParameter(j[timings]["WCK2DQO"], "WCK2DQO");
memSpec->tRTW = memSpec->tCK * uIntParameter(j[timings]["RTW"], "RTW");
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
memSpec->tWCK2DQI = memSpec->tCK * uIntParameter(j[timings]["WCK2DQI"], "WCK2DQI");
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
memSpec->tWTRS = memSpec->tCK * uIntParameter(j[timings]["WTRS"], "WTRS");
memSpec->tWTRL = memSpec->tCK * uIntParameter(j[timings]["WTRL"], "WTRL");
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
memSpec->tPD = memSpec->tCKE;
memSpec->tCKESR = memSpec->tCK * uIntParameter(j[timings]["CKESR"], "CKESR");
memSpec->tXP = memSpec->tCK * uIntParameter(j[timings]["XP"], "XP");
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
memSpec->tREFIPB = memSpec->tCK * uIntParameter(j[timings]["REFIPB"], "REFIPB");
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC"], "RFC");
memSpec->tRFCPB = memSpec->tCK * uIntParameter(j[timings]["RFCPB"], "RFCPB");
memSpec->tRREFD = memSpec->tCK * uIntParameter(j[timings]["RREFD"], "RREFD");
memSpec->tXS = memSpec->tCK * uIntParameter(j[timings]["XS"], "XS");
memSpec->tFAW = memSpec->tCK * uIntParameter(j[timings]["FAW"], "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->tPPD = memSpec->tCK * uIntParameter(j[timings]["PPD"], "PPD");
memSpec->tLK = memSpec->tCK * uIntParameter(j[timings]["LK"], "LK");
memSpec->tACTPDE = memSpec->tCK * uIntParameter(j[timings]["ACTPDE"], "ACTPDE");
memSpec->tPREPDE = memSpec->tCK * uIntParameter(j[timings]["PREPDE"], "PREPDE");
memSpec->tREFPDE = memSpec->tCK * uIntParameter(j[timings]["REFPDE"], "REFPDE");
memSpec->tWCK2CK = memSpec->tCK * uIntParameter(j[timings]["WCK2CK"], "WCK2CK");
memSpec->tWCK2DQO = memSpec->tCK * uIntParameter(j[timings]["WCK2DQO"], "WCK2DQO");
memSpec->tRTW = memSpec->tCK * uIntParameter(j[timings]["RTW"], "RTW");
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
memSpec->tWCK2DQI = memSpec->tCK * uIntParameter(j[timings]["WCK2DQI"], "WCK2DQI");
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
memSpec->tWTRS = memSpec->tCK * uIntParameter(j[timings]["WTRS"], "WTRS");
memSpec->tWTRL = memSpec->tCK * uIntParameter(j[timings]["WTRL"], "WTRL");
memSpec->tPD = memSpec->tCK * uIntParameter(j[timings]["PD"], "PD");
memSpec->tCKESR = memSpec->tCK * uIntParameter(j[timings]["CKESR"], "CKESR");
memSpec->tXP = memSpec->tCK * uIntParameter(j[timings]["XP"], "XP");
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
memSpec->tREFIPB = memSpec->tCK * uIntParameter(j[timings]["REFIPB"], "REFIPB");
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC"], "RFC");
memSpec->tRFCPB = memSpec->tCK * uIntParameter(j[timings]["RFCPB"], "RFCPB");
memSpec->tRREFD = memSpec->tCK * uIntParameter(j[timings]["RREFD"], "RREFD");
memSpec->tXS = memSpec->tCK * uIntParameter(j[timings]["XS"], "XS");
memSpec->tFAW = memSpec->tCK * uIntParameter(j[timings]["FAW"], "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->tPPD = memSpec->tCK * uIntParameter(j[timings]["PPD"], "PPD");
memSpec->tLK = memSpec->tCK * uIntParameter(j[timings]["LK"], "LK");
memSpec->tACTPDE = memSpec->tCK * uIntParameter(j[timings]["ACTPDE"], "ACTPDE");
memSpec->tPREPDE = memSpec->tCK * uIntParameter(j[timings]["PREPDE"], "PREPDE");
memSpec->tREFPDE = memSpec->tCK * uIntParameter(j[timings]["REFPDE"], "REFPDE");
memSpec->tRTRS = memSpec->tCK * uIntParameter(j[timings]["RTRS"], "RTRS");
// Currents and voltages
// TODO: to be completed

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -47,7 +47,17 @@ CheckerDDR3::CheckerDDR3()
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfRanks));
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands());
lastActivates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
last4Activates = std::vector<std::queue<sc_time>>(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());
}
}

View File

@@ -57,7 +57,17 @@ private:
sc_time lastCommandOnBus;
// Four activate window
std::vector<std::queue<sc_time>> lastActivates;
std::vector<std::queue<sc_time>> 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

View File

@@ -49,7 +49,18 @@ CheckerDDR4::CheckerDDR4()
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfRanks));
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands());
lastActivates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
last4Activates = std::vector<std::queue<sc_time>>(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());
}
}

View File

@@ -58,7 +58,20 @@ private:
sc_time lastCommandOnBus;
// Four activate window
std::vector<std::queue<sc_time>> lastActivates;
std::vector<std::queue<sc_time>> 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

View File

@@ -51,6 +51,17 @@ CheckerGDDR5::CheckerGDDR5()
last4Activates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
last32Activates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
bankwiseRefreshCounter = std::vector<unsigned>(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;
}

View File

@@ -55,13 +55,23 @@ private:
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBankGroup;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndRank;
std::vector<sc_time> lastScheduledByCommand;
sc_time lastCommandOnBus;
// 4 and 32 activate window
std::vector<std::queue<sc_time>> last4Activates;
std::vector<std::queue<sc_time>> last32Activates;
unsigned bankwiseRefreshCounter = 0;
std::vector<unsigned> 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

View File

@@ -51,6 +51,17 @@ CheckerGDDR5X::CheckerGDDR5X()
last4Activates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
last32Activates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
bankwiseRefreshCounter = std::vector<unsigned>(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;
}

View File

@@ -55,13 +55,23 @@ private:
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBankGroup;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndRank;
std::vector<sc_time> lastScheduledByCommand;
sc_time lastCommandOnBus;
// 4 and 32 activate window
std::vector<std::queue<sc_time>> last4Activates;
std::vector<std::queue<sc_time>> last32Activates;
unsigned bankwiseRefreshCounter = 0;
std::vector<unsigned> 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

View File

@@ -49,7 +49,18 @@ CheckerGDDR6::CheckerGDDR6()
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfRanks));
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands());
lastActivates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
last4Activates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
bankwiseRefreshCounter = std::vector<unsigned>(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;
}

View File

@@ -58,9 +58,18 @@ private:
sc_time lastCommandOnBus;
// four activate window
std::vector<std::queue<sc_time>> lastActivates;
std::vector<std::queue<sc_time>> last4Activates;
unsigned bankwiseRefreshCounter = 0;
std::vector<unsigned> 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

View File

@@ -49,8 +49,17 @@ CheckerHBM2::CheckerHBM2()
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfRanks));
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands());
lastActivates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
last4Activates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
bankwiseRefreshCounter = std::vector<unsigned>(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)

View File

@@ -55,12 +55,24 @@ private:
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBankGroup;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndRank;
std::vector<sc_time> lastScheduledByCommand;
sc_time lastCommandOnRasBus;
sc_time lastCommandOnCasBus;
// Four activate window
std::vector<std::queue<sc_time>> lastActivates;
std::vector<std::queue<sc_time>> last4Activates;
std::vector<unsigned> 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

View File

@@ -47,7 +47,23 @@ CheckerLPDDR4::CheckerLPDDR4()
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfRanks));
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands());
lastActivates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
last4Activates = std::vector<std::queue<sc_time>>(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);
}
}

View File

@@ -57,7 +57,25 @@ private:
sc_time lastCommandOnBus;
// Four activate window
std::vector<std::queue<sc_time>> lastActivates;
std::vector<std::queue<sc_time>> 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

View File

@@ -47,7 +47,17 @@ CheckerWideIO::CheckerWideIO()
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfRanks));
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands());
lastActivates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
last2Activates = std::vector<std::queue<sc_time>>(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());
}
}

View File

@@ -57,7 +57,17 @@ private:
sc_time lastScheduled;
// Four activate window
std::vector<std::queue<sc_time>> lastActivates;
std::vector<std::queue<sc_time>> 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

View File

@@ -47,7 +47,18 @@ CheckerWideIO2::CheckerWideIO2()
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfRanks));
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands());
lastActivates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
last4Activates = std::vector<std::queue<sc_time>>(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());
}
}

View File

@@ -57,7 +57,18 @@ private:
sc_time lastCommandOnBus;
// Four activate window
std::vector<std::queue<sc_time>> lastActivates;
std::vector<std::queue<sc_time>> 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

View File

@@ -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;