Updated DDR3, DDR4, WIO1, WIO2.

This commit is contained in:
Lukas Steiner
2020-05-20 17:16:00 +02:00
parent 86ecc103c1
commit e193fb3f74
14 changed files with 1135 additions and 456 deletions

View File

@@ -267,6 +267,10 @@ void ConfigurationLoader::loadDDR3(Configuration &config, XMLElement *xmlSpec)
memSpec->tAL = memSpec->tCK * queryUIntParameter(timings, "AL");
memSpec->tXPDLL = memSpec->tCK * queryUIntParameter(timings, "XPDLL");
memSpec->tXSDLL = memSpec->tCK * queryUIntParameter(timings, "XSDLL");
memSpec->tACTPDEN = memSpec->tCK * queryUIntParameter(timings, "ACTPDEN");
memSpec->tPRPDEN = memSpec->tCK * queryUIntParameter(timings, "PRPDEN");
memSpec->tREFPDEN = memSpec->tCK * queryUIntParameter(timings, "REFPDEN");
memSpec->tRTRS = memSpec->tCK * queryUIntParameter(timings, "RTRS");
// Currents and voltages
XMLElement *powers = xmlSpec->FirstChildElement("mempowerspec");
@@ -302,8 +306,9 @@ void ConfigurationLoader::loadDDR4(Configuration &config, XMLElement *xmlSpec)
// MemTimings specific for DDR4
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE");
memSpec->tPD = memSpec->tCK * queryUIntParameter(timings, "PD");
memSpec->tCKESR = memSpec->tCK * queryUIntParameter(timings, "CKESR");
//memSpec->tDQSCK = memSpec->tCK * queryUIntParameter(timings, "DQSCK");
memSpec->tDQSCK = memSpec->tCK * queryUIntParameter(timings, "DQSCK");
memSpec->tRAS = memSpec->tCK * queryUIntParameter(timings, "RAS");
memSpec->tRC = memSpec->tCK * queryUIntParameter(timings, "RC");
memSpec->tRCD = memSpec->tCK * queryUIntParameter(timings, "RCD");
@@ -341,7 +346,11 @@ void ConfigurationLoader::loadDDR4(Configuration &config, XMLElement *xmlSpec)
memSpec->tWTR_L = memSpec->tCK * queryUIntParameter(timings, "WTR_L");
memSpec->tAL = memSpec->tCK * queryUIntParameter(timings, "AL");
memSpec->tXPDLL = memSpec->tCK * queryUIntParameter(timings, "XPDLL");
memSpec->tXSDLL = memSpec->tCK * queryUIntParameter(timings, "XSDLL");
memSpec->tXSDLL = memSpec->tCK * queryUIntParameter(timings, "XSDLL");
memSpec->tACTPDEN = memSpec->tCK * queryUIntParameter(timings, "ACTPDEN");
memSpec->tPRPDEN = memSpec->tCK * queryUIntParameter(timings, "PRPDEN");
memSpec->tREFPDEN = memSpec->tCK * queryUIntParameter(timings, "REFPDEN");
memSpec->tRTRS = memSpec->tCK * queryUIntParameter(timings, "RTRS");
// Currents and voltages
XMLElement *powers = xmlSpec->FirstChildElement("mempowerspec");
@@ -440,7 +449,7 @@ void ConfigurationLoader::loadWideIO(Configuration &config, XMLElement *xmlSpec)
memSpec->tWL = memSpec->tCK * queryUIntParameter(timings, "WL");
memSpec->tWR = memSpec->tCK * queryUIntParameter(timings, "WR");
memSpec->tXP = memSpec->tCK * queryUIntParameter(timings, "XP");
memSpec->tXS = memSpec->tCK * queryUIntParameter(timings, "XS");
memSpec->tXSR = memSpec->tCK * queryUIntParameter(timings, "XSR");
memSpec->tCCD_R = memSpec->tCK * queryUIntParameter(timings, "CCD_R");
memSpec->tCCD_W = memSpec->tCK * queryUIntParameter(timings, "CCD_W");
memSpec->tREFI = memSpec->tCK * queryUIntParameter(timings, "REFI");
@@ -449,6 +458,7 @@ void ConfigurationLoader::loadWideIO(Configuration &config, XMLElement *xmlSpec)
memSpec->tRRD = memSpec->tCK * queryUIntParameter(timings, "RRD");
memSpec->tTAW = memSpec->tCK * queryUIntParameter(timings, "TAW");
memSpec->tWTR = memSpec->tCK * queryUIntParameter(timings, "WTR");
memSpec->tRTRS = memSpec->tCK * queryUIntParameter(timings, "RTRS");
// Currents and voltages
XMLElement *powers = xmlSpec->FirstChildElement("mempowerspec");
@@ -519,6 +529,7 @@ void ConfigurationLoader::loadWideIO2(Configuration &config, XMLElement *xmlSpec
memSpec->tREFIpb = memSpec->tCK * queryUIntParameter(timings, "REFIPB");
memSpec->tRFCab = memSpec->tCK * queryUIntParameter(timings, "RFCAB");
memSpec->tRFCpb = memSpec->tCK * queryUIntParameter(timings, "RFCPB");
memSpec->tRTRS = memSpec->tCK * queryUIntParameter(timings, "RTRS");
// Currents and voltages
// TODO: to be completed

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

@@ -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,71 +275,112 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGr
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
}
else if (command == Command::PDEA)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tACTPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
+ memSpec->tRL + 5 * memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
+ memSpec->tRL + 5 * memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
+ memSpec->tWL + 4 * memSpec->tCK + memSpec->tWR);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
+ memSpec->tWL + 5 * memSpec->tCK + memSpec->tWR);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
}
else if (command == Command::PDXA)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
}
else if (command == Command::PDEP)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
+ memSpec->tRL + 5 * memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
+ memSpec->tRL + 5 * memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
+ memSpec->tWL + 5 * memSpec->tCK + memSpec->tWR);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
}
else if (command == Command::SREFEN)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, memSpec->tAL + memSpec->tRTP + memSpec->tRP));
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRP));
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
@@ -316,39 +389,13 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGr
{
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
}
else if (command == Command::SREFEN)
else if (command == Command::PDXA)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
+ std::max(memSpec->tRL + 5 * memSpec->tCK, memSpec->tAL + memSpec->tRTP + memSpec->tRP));
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart
+ std::max(memSpec->tWL + 5 * memSpec->tCK + memSpec->tWR, memSpec->tWL + memSpec->burstDuration + memSpec->tWR + memSpec->tRP));
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
}
else if (command == Command::SREFEX)
{
@@ -359,7 +406,6 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGr
else
reportFatal("CheckerDDR3", "Unknown command!");
// Check if command bus is free
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
return earliestTimeToStart;
@@ -367,18 +413,19 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, Rank rank, BankGr
void CheckerDDR3::insert(Command command, Rank rank, BankGroup, Bank bank)
{
PRINTDEBUGMESSAGE("CheckerDDR3", "Changing state on bank " + std::to_string(bank.ID())
PRINTDEBUGMESSAGE("CheckerDDR3", "Changing state on bank " + bank.ID()
+ " command is " + commandToString(command));
lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp();
lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp();
lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp();
lastScheduledByCommand[command] = sc_time_stamp();
lastCommandOnBus = sc_time_stamp();
if (command == Command::ACT)
{
if (lastActivates[rank.ID()].size() == 4)
lastActivates[rank.ID()].pop();
lastActivates[rank.ID()].push(sc_time_stamp());
if (last4Activates[rank.ID()].size() == 4)
last4Activates[rank.ID()].pop();
last4Activates[rank.ID()].push(sc_time_stamp());
}
}

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::PDEP)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
}
else if (command == Command::SREFEN)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, memSpec->tAL + memSpec->tRTP + memSpec->tRP));
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRP));
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
}
else if (command == Command::PDXP)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
}
else if (command == Command::PDXA)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
}
else if (command == Command::SREFEX)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR);
}
else
reportFatal("CheckerDDR4", "Unknown command!");
// Check if command bus is free
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
return earliestTimeToStart;
@@ -261,8 +455,8 @@ void CheckerDDR4::insert(Command command, Rank rank, BankGroup bankgroup, Bank b
if (command == Command::ACT)
{
if (lastActivates[rank.ID()].size() == 4)
lastActivates[rank.ID()].pop();
lastActivates[rank.ID()].push(sc_time_stamp());
if (last4Activates[rank.ID()].size() == 4)
last4Activates[rank.ID()].pop();
last4Activates[rank.ID()].push(sc_time_stamp());
}
}

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

@@ -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,121 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, Rank rank, Bank
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
}
else if (command == Command::PDEA)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
}
else if (command == Command::PDEP)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
}
else if (command == Command::SREFEN)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, tBURST + memSpec->tRP));
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRP));
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
}
else if (command == Command::PDXP)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
}
else if (command == Command::PDXA)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
}
else if (command == Command::SREFEX)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR);
}
else
{
reportFatal("CheckerWideIO", "Unknown command!");
}
// Check if command bus is free
earliestTimeToStart = std::max(earliestTimeToStart, lastScheduled + memSpec->tCK);
@@ -229,8 +403,8 @@ void CheckerWideIO::insert(Command command, Rank rank, BankGroup, Bank bank)
if (command == Command::ACT)
{
if (lastActivates[rank.ID()].size() == 2)
lastActivates[rank.ID()].pop();
lastActivates[rank.ID()].push(sc_time_stamp());
if (last2Activates[rank.ID()].size() == 2)
last2Activates[rank.ID()].pop();
last2Activates[rank.ID()].push(sc_time_stamp());
}
}

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::PDEP)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
}
else if (command == Command::SREFEN)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, tRDPRE + memSpec->tRPpb));
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRPpb));
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb);
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
}
else if (command == Command::PDXP)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
}
else if (command == Command::PDXA)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
}
else if (command == Command::SREFEX)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR);
}
else
{
reportFatal("CheckerWideIO2", "Unknown command!");
}
// Check if command bus is free
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
@@ -277,8 +474,8 @@ void CheckerWideIO2::insert(Command command, Rank rank, BankGroup, Bank bank)
if (command == Command::ACT || command == Command::REFB)
{
if (lastActivates[rank.ID()].size() == 4)
lastActivates[rank.ID()].pop();
lastActivates[rank.ID()].push(sc_time_stamp());
if (last4Activates[rank.ID()].size() == 4)
last4Activates[rank.ID()].pop();
last4Activates[rank.ID()].push(sc_time_stamp());
}
}

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;