|
|
|
|
@@ -41,26 +41,45 @@ CheckerDDR5::CheckerDDR5()
|
|
|
|
|
if (memSpec == nullptr)
|
|
|
|
|
SC_REPORT_FATAL("CheckerDDR5", "Wrong MemSpec chosen");
|
|
|
|
|
|
|
|
|
|
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
|
|
|
|
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBanks));
|
|
|
|
|
lastScheduledByCommandAndDIMMRank = std::vector<std::vector<sc_time>>
|
|
|
|
|
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfDIMMRanks));
|
|
|
|
|
lastScheduledByCommandAndPhysicalRank = std::vector<std::vector<sc_time>>
|
|
|
|
|
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfPhysicalRanks));
|
|
|
|
|
lastScheduledByCommandAndLogicalRank = std::vector<std::vector<sc_time>>
|
|
|
|
|
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfLogicalRanks));
|
|
|
|
|
lastScheduledByCommandAndBankGroup = std::vector<std::vector<sc_time>>
|
|
|
|
|
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBankGroups));
|
|
|
|
|
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
|
|
|
|
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfRanks));
|
|
|
|
|
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
|
|
|
|
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBanks));
|
|
|
|
|
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands());
|
|
|
|
|
|
|
|
|
|
last4Activates = std::vector<std::queue<sc_time>>(memSpec->numberOfRanks);
|
|
|
|
|
last4ActivatesLogical = std::vector<std::queue<sc_time>>(memSpec->numberOfLogicalRanks);
|
|
|
|
|
last4ActivatesPhysical = std::vector<std::queue<sc_time>>(memSpec->numberOfPhysicalRanks);
|
|
|
|
|
|
|
|
|
|
tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
|
|
|
|
|
tRDWR = memSpec->tRL + tBURST + memSpec->tCK - memSpec->tWL + memSpec->tWPRE;
|
|
|
|
|
tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL + memSpec->tWPRE;
|
|
|
|
|
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 + memSpec->tRPRE;
|
|
|
|
|
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;
|
|
|
|
|
tRD_BURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
|
|
|
|
|
tWR_BURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
|
|
|
|
|
tWTRA = memSpec->tWR - memSpec->tRTP;
|
|
|
|
|
tWRRDA = memSpec->tWL + tWR_BURST + tWTRA;
|
|
|
|
|
tWRPRE = memSpec->tWL + tWR_BURST + memSpec->tWR;
|
|
|
|
|
tRDAACT = memSpec->tRTP + memSpec->tRP;
|
|
|
|
|
tWRAACT = tWRPRE + memSpec->tRP;
|
|
|
|
|
tCCD_L_RTW_slr = memSpec->tRL - memSpec->tWL + tRD_BURST + 2 * memSpec->tCK - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
|
|
|
|
|
tCCD_S_RTW_slr = memSpec->tRL - memSpec->tWL + tRD_BURST + 2 * memSpec->tCK - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
|
|
|
|
|
tCCD_RTW_dlr = memSpec->tRL - memSpec->tWL + tRD_BURST + 2 * memSpec->tCK - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
|
|
|
|
|
tRDRD_dpr = tRD_BURST + memSpec->tRTRS;
|
|
|
|
|
tRDRD_ddr = tRD_BURST + memSpec->tRTRS;
|
|
|
|
|
tRDWR_dpr = memSpec->tRL - memSpec->tWL + tRD_BURST + memSpec->tRTRS - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
|
|
|
|
|
tRDWR_ddr = memSpec->tRL - memSpec->tWL + tRD_BURST + memSpec->tRTRS - memSpec->tRDDQS + memSpec->tRPST + memSpec->tWPRE;
|
|
|
|
|
tCCD_L_WTR_slr = memSpec->tWL + tWR_BURST + memSpec->tWTR_L;
|
|
|
|
|
tCCD_S_WTR_slr = memSpec->tWL + tWR_BURST + memSpec->tWTR_S;
|
|
|
|
|
tCCD_WTR_dlr = memSpec->tWL + tWR_BURST + memSpec->tWTR_S;
|
|
|
|
|
tWRWR_dpr = std::max(memSpec->tCCD_WR_dpr, tWR_BURST + memSpec->tRTRS);
|
|
|
|
|
tWRWR_ddr = tWR_BURST + memSpec->tRTRS;
|
|
|
|
|
tWRRD_dpr = memSpec->tWL - memSpec->tRL + tWR_BURST + memSpec->tRTRS + memSpec->tRDDQS + memSpec->tWPST + memSpec->tRPRE;
|
|
|
|
|
tWRRD_ddr = memSpec->tWL - memSpec->tRL + tWR_BURST + memSpec->tRTRS + memSpec->tRDDQS + memSpec->tWPST + memSpec->tRPRE;
|
|
|
|
|
tRDPDEN = memSpec->tRL + tRD_BURST + memSpec->tCK;
|
|
|
|
|
tWRPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + memSpec->tCK;
|
|
|
|
|
tWRAPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + memSpec->tCK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank) const
|
|
|
|
|
@@ -68,128 +87,188 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
|
|
|
|
sc_time lastCommandStart;
|
|
|
|
|
sc_time earliestTimeToStart = sc_time_stamp();
|
|
|
|
|
|
|
|
|
|
Rank logicalrank = rank;
|
|
|
|
|
Rank physicalrank = Rank(logicalrank.ID() / memSpec->logicalRanksPerPhysicalRank);
|
|
|
|
|
Rank dimmrank = Rank(physicalrank.ID() / memSpec->physicalRanksPerDIMMRank);
|
|
|
|
|
|
|
|
|
|
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 - memSpec->tAL);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_slr);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_slr);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : SC_ZERO_TIME;
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_dlr);
|
|
|
|
|
|
|
|
|
|
if (lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()])
|
|
|
|
|
{
|
|
|
|
|
if (lastScheduledByCommand[Command::RD] == lastScheduledByCommandAndDIMMRank[Command::RD][dimmrank.ID()])
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr);
|
|
|
|
|
else
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_slr);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_slr);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : SC_ZERO_TIME;
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_dlr);
|
|
|
|
|
|
|
|
|
|
if (lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()])
|
|
|
|
|
{
|
|
|
|
|
if (lastScheduledByCommand[Command::RDA] == lastScheduledByCommandAndDIMMRank[Command::RDA][dimmrank.ID()])
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr);
|
|
|
|
|
else
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (command == Command::RDA)
|
|
|
|
|
{
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDA);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_L);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_S);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommand[Command::WR];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr);
|
|
|
|
|
|
|
|
|
|
if (lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()])
|
|
|
|
|
{
|
|
|
|
|
if (lastScheduledByCommand[Command::WR] == lastScheduledByCommandAndDIMMRank[Command::WR][dimmrank.ID()])
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr);
|
|
|
|
|
else
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_L);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_S);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr);
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
if (lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()])
|
|
|
|
|
{
|
|
|
|
|
if (lastScheduledByCommand[Command::WRA] == lastScheduledByCommandAndDIMMRank[Command::WRA][dimmrank.ID()])
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr);
|
|
|
|
|
else
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : SC_ZERO_TIME;
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : SC_ZERO_TIME;
|
|
|
|
|
if (lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()])
|
|
|
|
|
{
|
|
|
|
|
if (lastScheduledByCommand[Command::RD] == lastScheduledByCommandAndDIMMRank[Command::RD][dimmrank.ID()])
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr);
|
|
|
|
|
else
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr);
|
|
|
|
|
|
|
|
|
|
if (lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()])
|
|
|
|
|
{
|
|
|
|
|
if (lastScheduledByCommand[Command::RDA] == lastScheduledByCommandAndDIMMRank[Command::RDA][dimmrank.ID()])
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr);
|
|
|
|
|
else
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_WR_slr);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : SC_ZERO_TIME;
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_WR_dlr);
|
|
|
|
|
|
|
|
|
|
if (lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()])
|
|
|
|
|
{
|
|
|
|
|
if (lastScheduledByCommand[Command::WR] == lastScheduledByCommandAndDIMMRank[Command::WR][dimmrank.ID()])
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr);
|
|
|
|
|
else
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_WR_slr);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : SC_ZERO_TIME;
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_WR_dlr);
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
if (lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()])
|
|
|
|
|
{
|
|
|
|
|
if (lastScheduledByCommand[Command::WRA] == lastScheduledByCommandAndDIMMRank[Command::WRA][dimmrank.ID()])
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr);
|
|
|
|
|
else
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (command == Command::ACT)
|
|
|
|
|
{
|
|
|
|
|
@@ -199,240 +278,121 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGr
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankgroup.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L_slr);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_S);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_S_slr);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::ACT][physicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_dlr);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->tCK);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::PREA][logicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->tCK);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFA][logicalrank.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);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr);
|
|
|
|
|
}
|
|
|
|
|
else if (command == Command::PRE)
|
|
|
|
|
{
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PREA][physicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
|
|
|
|
}
|
|
|
|
|
else if (command == Command::PREA)
|
|
|
|
|
{
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tCK);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tCK);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PREA][physicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
|
|
|
|
}
|
|
|
|
|
else if (command == Command::REFA)
|
|
|
|
|
{
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + memSpec->tCK);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP + memSpec->tCK);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::PRE][logicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::PREA][logicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFA][logicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::REFA][physicalrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dlr);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndDIMMRank[Command::REFA][dimmrank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
|
|
|
|
}
|
|
|
|
|
else if (command == Command::PDEA)
|
|
|
|
|
{
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tACTPDEN);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPDEN);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
|
|
|
|
}
|
|
|
|
|
else if (command == Command::PDXA)
|
|
|
|
|
{
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
|
|
|
|
}
|
|
|
|
|
else if (command == Command::PDEP)
|
|
|
|
|
{
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDEN);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
|
|
|
|
}
|
|
|
|
|
else if (command == Command::PDXP)
|
|
|
|
|
{
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
|
|
|
|
}
|
|
|
|
|
else if (command == Command::SREFEN)
|
|
|
|
|
{
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, memSpec->tAL + memSpec->tRTP + memSpec->tRP));
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRP));
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::PRE][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
|
|
|
|
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
|
|
|
|
}
|
|
|
|
|
else if (command == Command::SREFEX)
|
|
|
|
|
{
|
|
|
|
|
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()];
|
|
|
|
|
if (lastCommandStart != SC_ZERO_TIME)
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR);
|
|
|
|
|
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dpr);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
SC_REPORT_FATAL("CheckerDDR5", "Unknown command!");
|
|
|
|
|
@@ -447,16 +407,27 @@ void CheckerDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank b
|
|
|
|
|
PRINTDEBUGMESSAGE("CheckerDDR5", "Changing state on bank " + std::to_string(bank.ID())
|
|
|
|
|
+ " command is " + commandToString(command));
|
|
|
|
|
|
|
|
|
|
lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp();
|
|
|
|
|
Rank logicalrank = rank;
|
|
|
|
|
Rank physicalrank = Rank(logicalrank.ID() / memSpec->logicalRanksPerPhysicalRank);
|
|
|
|
|
Rank dimmrank = Rank(physicalrank.ID() / memSpec->physicalRanksPerDIMMRank);
|
|
|
|
|
|
|
|
|
|
lastScheduledByCommandAndDIMMRank[command][dimmrank.ID()] = sc_time_stamp();
|
|
|
|
|
lastScheduledByCommandAndPhysicalRank[command][physicalrank.ID()] = sc_time_stamp();
|
|
|
|
|
lastScheduledByCommandAndLogicalRank[command][logicalrank.ID()] = sc_time_stamp();
|
|
|
|
|
lastScheduledByCommandAndBankGroup[command][bankgroup.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();
|
|
|
|
|
|
|
|
|
|
lastCommandOnBus = sc_time_stamp() + memSpec->getCommandLength(command) - memSpec->tCK;
|
|
|
|
|
|
|
|
|
|
if (command == Command::ACT)
|
|
|
|
|
{
|
|
|
|
|
if (last4Activates[rank.ID()].size() == 4)
|
|
|
|
|
last4Activates[rank.ID()].pop();
|
|
|
|
|
last4Activates[rank.ID()].push(sc_time_stamp());
|
|
|
|
|
if (last4ActivatesLogical[logicalrank.ID()].size() == 4)
|
|
|
|
|
last4ActivatesLogical[logicalrank.ID()].pop();
|
|
|
|
|
last4ActivatesLogical[logicalrank.ID()].push(lastCommandOnBus);
|
|
|
|
|
|
|
|
|
|
if (last4ActivatesPhysical[physicalrank.ID()].size() == 4)
|
|
|
|
|
last4ActivatesPhysical[physicalrank.ID()].pop();
|
|
|
|
|
last4ActivatesPhysical[physicalrank.ID()].push(lastCommandOnBus);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|