Add new DDR5 checker and timings.

This commit is contained in:
Lukas Steiner
2020-08-25 10:16:45 +02:00
parent c15434c4fa
commit 2c15bb8f79
6 changed files with 354 additions and 343 deletions

View File

@@ -60,9 +60,9 @@ DramExtension::DramExtension(const Thread &thread, const Channel &channel, const
DramExtension &DramExtension::getExtension(const tlm_generic_payload *payload)
{
DramExtension *result = NULL;
DramExtension *result = nullptr;
payload->get_extension(result);
sc_assert(result != NULL);
sc_assert(result != nullptr);
return *result;
}
@@ -234,9 +234,9 @@ void GenerationExtension::copy_from(const tlm_extension_base &ext)
GenerationExtension &GenerationExtension::getExtension(const tlm_generic_payload *payload)
{
GenerationExtension *result = NULL;
GenerationExtension *result = nullptr;
payload->get_extension(result);
sc_assert(result != NULL);
sc_assert(result != nullptr);
return *result;
}

View File

@@ -48,23 +48,23 @@
class MemSpec
{
public:
unsigned numberOfChannels;
unsigned numberOfRanks;
unsigned banksPerRank;
unsigned groupsPerRank;
unsigned banksPerGroup;
unsigned numberOfBanks;
unsigned numberOfBankGroups;
unsigned numberOfDevicesOnDIMM;
unsigned numberOfRows;
unsigned numberOfColumns;
unsigned burstLength;
unsigned dataRate;
unsigned bitWidth;
const unsigned numberOfChannels;
const unsigned numberOfRanks;
const unsigned banksPerRank;
const unsigned groupsPerRank;
const unsigned banksPerGroup;
const unsigned numberOfBanks;
const unsigned numberOfBankGroups;
const unsigned numberOfDevicesOnDIMM;
const unsigned numberOfRows;
const unsigned numberOfColumns;
const unsigned burstLength;
const unsigned dataRate;
const unsigned bitWidth;
// Clock
double fCKMHz;
sc_time tCK;
const double fCKMHz;
const sc_time tCK;
std::string memoryId;
std::string memoryType;

View File

@@ -46,52 +46,60 @@ MemSpecDDR5::MemSpecDDR5(json &memspec)
parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"),
parseUint(memspec["memarchitecturespec"]["nbrOfBankGroups"], "nbrOfBankGroups"),
parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks")
/ parseUint(memspec["memarchitecturespec"]["nbrOfBankGroups"], "nbrOfBankGroups"),
/ parseUint(memspec["memarchitecturespec"]["nbrOfBankGroups"], "nbrOfBankGroups"),
parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks")
* parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"),
* parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"),
parseUint(memspec["memarchitecturespec"]["nbrOfBankGroups"], "nbrOfBankGroups")
* parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"),
* parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"),
parseUint(memspec["memarchitecturespec"]["nbrOfDevicesOnDIMM"],"nbrOfDevicesOnDIMM")),
tCKE (tCK * parseUint(memspec["memtimingspec"]["CKE"], "CKE")),
tPD (tCKE),
tCKESR (tCK * parseUint(memspec["memtimingspec"]["CKESR"], "CKESR")),
tRAS (tCK * parseUint(memspec["memtimingspec"]["RAS"], "RAS")),
tRC (tCK * parseUint(memspec["memtimingspec"]["RC"], "RC")),
tRCD (tCK * parseUint(memspec["memtimingspec"]["RCD"], "RCD")),
tRL (tCK * parseUint(memspec["memtimingspec"]["RL"], "RL")),
tRPRE (tCK * parseUint(memspec["memtimingspec"]["RPRE"], "RPRE")),
tRTP (tCK * parseUint(memspec["memtimingspec"]["RTP"], "RTP")),
tWL (tCK * parseUint(memspec["memtimingspec"]["WL"], "WL")),
tWPRE (tCK * parseUint(memspec["memtimingspec"]["WPRE"], "WPRE")),
tWR (tCK * parseUint(memspec["memtimingspec"]["WR"], "WR")),
tXP (tCK * parseUint(memspec["memtimingspec"]["XP"], "XP")),
tXS (tCK * parseUint(memspec["memtimingspec"]["XS"], "XS")),
tREFI ((parseUint(memspec["memtimingspec"]["REFM"], "REFM") == 4) ?
(tCK * (parseUint(memspec["memtimingspec"]["REFI"], "REFI") / 4)) :
((parseUint(memspec["memtimingspec"]["REFM"], "REFM") == 2) ?
(tCK * (parseUint(memspec["memtimingspec"]["REFI"], "REFI") / 2)) :
(tCK * parseUint(memspec["memtimingspec"]["REFI"], "REFI")))),
tRFC ((parseUint(memspec["memtimingspec"]["REFM"], "REFM") == 4) ?
(tCK * parseUint(memspec["memtimingspec"]["RFC4"], "RFC4")) :
((parseUint(memspec["memtimingspec"]["REFM"], "REFM") == 2) ?
(tCK * parseUint(memspec["memtimingspec"]["RFC2"], "RFC2")) :
(tCK * parseUint(memspec["memtimingspec"]["RFC"], "RFC")))),
tRP (tCK * parseUint(memspec["memtimingspec"]["RP"], "RP")),
tDQSCK (tCK * parseUint(memspec["memtimingspec"]["DQSCK"], "DQSCK")),
tCCD_S (tCK * parseUint(memspec["memtimingspec"]["CCD_S"], "CCD_S")),
tCCD_L (tCK * parseUint(memspec["memtimingspec"]["CCD_L"], "CCD_L")),
tFAW (tCK * parseUint(memspec["memtimingspec"]["FAW"], "FAW")),
tRRD_S (tCK * parseUint(memspec["memtimingspec"]["RRD_S"], "RRD_S")),
tRRD_L (tCK * parseUint(memspec["memtimingspec"]["RRD_L"], "RRD_L")),
tWTR_S (tCK * parseUint(memspec["memtimingspec"]["WTR_S"], "WTR_S")),
tWTR_L (tCK * parseUint(memspec["memtimingspec"]["WTR_L"], "WTR_L")),
tAL (tCK * parseUint(memspec["memtimingspec"]["AL"], "AL")),
tXPDLL (tCK * parseUint(memspec["memtimingspec"]["XPDLL"], "XPDLL")),
tXSDLL (tCK * parseUint(memspec["memtimingspec"]["XSDLL"], "XSDLL")),
tACTPDEN (tCK * parseUint(memspec["memtimingspec"]["ACTPDEN"], "ACTPDEN")),
tPRPDEN (tCK * parseUint(memspec["memtimingspec"]["PRPDEN"], "PRPDEN")),
tREFPDEN (tCK * parseUint(memspec["memtimingspec"]["REFPDEN"], "REFPDEN")),
tRTRS (tCK * parseUint(memspec["memtimingspec"]["RTRS"], "RTRS"))
numberOfDIMMRanks(parseUint(memspec["memarchitecturespec"]["nbrOfDIMMRanks"], "nbrOfDIMMRanks")),
physicalRanksPerDIMMRank(parseUint(memspec["memarchitecturespec"]["nbrOfPhysicalRanks"], "nbrOfPhysicalRanks")),
numberOfPhysicalRanks(physicalRanksPerDIMMRank * numberOfDIMMRanks),
logicalRanksPerPhysicalRank(parseUint(memspec["memarchitecturespec"]["nbrOfLogicalRanks"], "nbrOfLogicalRanks")),
numberOfLogicalRanks(logicalRanksPerPhysicalRank * numberOfPhysicalRanks),
tRCD (tCK * parseUint(memspec["memtimingspec"]["RCD"], "RCD")),
tPPD (tCK * parseUint(memspec["memtimingspec"]["PPD"], "PPD")),
tRP (tCK * parseUint(memspec["memtimingspec"]["RP"], "RP")),
tRAS (tCK * parseUint(memspec["memtimingspec"]["RAS"], "RAS")),
tRC (tRAS + tRP),
tRL (tCK * parseUint(memspec["memtimingspec"]["RL"], "RL")),
tRTP (tCK * parseUint(memspec["memtimingspec"]["RTP"], "RTP")),
tRPRE (tCK * parseUint(memspec["memtimingspec"]["RPRE"], "RPRE")),
tRPST (tCK * parseUint(memspec["memtimingspec"]["RPST"], "RPST")),
tRDDQS (tCK * parseUint(memspec["memtimingspec"]["RDDQS"], "RDDQS")),
tWL (tCK * parseUint(memspec["memtimingspec"]["WL"], "WL")),
tWPRE (tCK * parseUint(memspec["memtimingspec"]["WPRE"], "WPRE")),
tWPST (tCK * parseUint(memspec["memtimingspec"]["WPST"], "WPST")),
tWR (tCK * parseUint(memspec["memtimingspec"]["WR"], "WR")),
tCCD_L_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_L_slr"], "CCD_L_slr")),
tCCD_L_WR_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_L_WR_slr"], "CCD_L_WR_slr")),
tCCD_S_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_S_slr"], "CCD_S_slr")),
tCCD_S_WR_slr (tCK * parseUint(memspec["memtimingspec"]["CCD_S_WR_slr"], "CCD_S_WR_slr")),
tCCD_dlr (tCK * parseUint(memspec["memtimingspec"]["CCD_dlr"], "CCD_dlr")),
tCCD_WR_dlr (tCK * parseUint(memspec["memtimingspec"]["CCD_WR_dlr"], "CCD_WR_dlr")),
tCCD_WR_dpr (tCK * parseUint(memspec["memtimingspec"]["CCD_WR_dpr"], "CCD_WR_dpr")),
tRRD_L_slr (tCK * parseUint(memspec["memtimingspec"]["RRD_L_slr"], "RRD_L_slr")),
tRRD_S_slr (tCK * parseUint(memspec["memtimingspec"]["RRD_S_slr"], "RRD_S_slr")),
tRRD_dlr (tCK * parseUint(memspec["memtimingspec"]["RRD_dlr"], "RRD_dlr")),
tFAW_slr (tCK * parseUint(memspec["memtimingspec"]["FAW_slr"], "FAW_slr")),
tFAW_dlr (tCK * parseUint(memspec["memtimingspec"]["FAW_dlr"], "FAW_dlr")),
tWTR_L (tCK * parseUint(memspec["memtimingspec"]["WTR_L"], "WTR_L")),
tWTR_S (tCK * parseUint(memspec["memtimingspec"]["WTR_S"], "WTR_S")),
tRFC_slr (tCK * parseUint(memspec["memtimingspec"]["RFC_slr"], "RFC_slr")),
tRFC_dlr (tCK * parseUint(memspec["memtimingspec"]["RFC_dlr"], "RFC_dlr")),
tRFC_dpr (tCK * parseUint(memspec["memtimingspec"]["RFC_dpr"], "RFC_dpr")),
tRFCsb_slr (tCK * parseUint(memspec["memtimingspec"]["RFCsb_slr"], "RFCsb_slr")),
tRFCsb_dlr (tCK * parseUint(memspec["memtimingspec"]["RFCsb_dlr"], "RFCsb_dlr")),
tREFI (tCK * parseUint(memspec["memtimingspec"]["REFI"], "REFI")),
tREFSBRD_slr (tCK * parseUint(memspec["memtimingspec"]["REFSBRD_slr"], "REFSBRD_slr")),
tREFSBRD_dlr (tCK * parseUint(memspec["memtimingspec"]["REFSBRD_dlr"], "REFSBRD_dlr")),
tRTRS (tCK * parseUint(memspec["memtimingspec"]["RTRS"], "RTRS")),
tCPDED (tCK * parseUint(memspec["memtimingspec"]["CPDED"], "CPDED")),
tPD (tCK * parseUint(memspec["memtimingspec"]["PD"], "PD")),
tXP (tCK * parseUint(memspec["memtimingspec"]["XP"], "XP")),
tACTPDEN (tCK * parseUint(memspec["memtimingspec"]["ACTPDEN"], "ACTPDEN")),
tPRPDEN (tCK * parseUint(memspec["memtimingspec"]["PRPDEN"], "PRPDEN")),
tREFPDEN (tCK * parseUint(memspec["memtimingspec"]["REFPDEN"], "REFPDEN"))
{
commandLengthInCycles[Command::ACT] = 2;
commandLengthInCycles[Command::RD] = 2;
@@ -127,7 +135,7 @@ sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload
else if (command == Command::WRA)
return tWL + burstDuration + tWR + tRP + tCK;
else if (command == Command::REFA)
return tRFC;
return tRFC_slr;
else
{
SC_REPORT_FATAL("getExecutionTime",

View File

@@ -44,39 +44,57 @@ class MemSpecDDR5 final : public MemSpec
public:
MemSpecDDR5(nlohmann::json &memspec);
const unsigned numberOfDIMMRanks;
const unsigned physicalRanksPerDIMMRank;
const unsigned numberOfPhysicalRanks;
const unsigned logicalRanksPerPhysicalRank;
const unsigned numberOfLogicalRanks;
// Memspec Variables:
const sc_time tCKE;
const sc_time tPD;
const sc_time tCKESR;
const sc_time tRCD;
const sc_time tPPD;
const sc_time tRP;
const sc_time tRAS;
const sc_time tRC;
const sc_time tRCD;
const sc_time tRL;
const sc_time tRPRE;
const sc_time tRTP;
const sc_time tRPRE;
const sc_time tRPST;
const sc_time tRDDQS;
const sc_time tWL;
const sc_time tWPRE;
const sc_time tWPST;
const sc_time tWR;
const sc_time tXP;
const sc_time tXS;
const sc_time tREFI;
const sc_time tRFC;
const sc_time tRP;
const sc_time tDQSCK;
const sc_time tCCD_S;
const sc_time tCCD_L;
const sc_time tFAW;
const sc_time tRRD_S;
const sc_time tRRD_L;
const sc_time tWTR_S;
const sc_time tCCD_L_slr;
const sc_time tCCD_L_WR_slr;
const sc_time tCCD_S_slr;
const sc_time tCCD_S_WR_slr;
const sc_time tCCD_dlr;
const sc_time tCCD_WR_dlr;
const sc_time tCCD_WR_dpr;
const sc_time tRRD_L_slr;
const sc_time tRRD_S_slr;
const sc_time tRRD_dlr;
const sc_time tFAW_slr;
const sc_time tFAW_dlr;
const sc_time tWTR_L;
const sc_time tAL;
const sc_time tXPDLL;
const sc_time tXSDLL;
const sc_time tWTR_S;
const sc_time tRFC_slr;
const sc_time tRFC_dlr;
const sc_time tRFC_dpr;
const sc_time tRFCsb_slr;
const sc_time tRFCsb_dlr;
const sc_time tREFI;
const sc_time tREFSBRD_slr;
const sc_time tREFSBRD_dlr;
const sc_time tRTRS;
const sc_time tCPDED;
const sc_time tPD;
const sc_time tXP;
const sc_time tACTPDEN;
const sc_time tPRPDEN;
const sc_time tREFPDEN;
const sc_time tRTRS;
// Currents and Voltages:
// TODO: to be completed

View File

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

View File

@@ -51,24 +51,38 @@ public:
private:
const MemSpecDDR5 *memSpec;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBank;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndDIMMRank;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndPhysicalRank;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndLogicalRank;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBankGroup;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndRank;
std::vector<std::vector<sc_time>> lastScheduledByCommandAndBank;
std::vector<sc_time> lastScheduledByCommand;
sc_time lastCommandOnBus;
// Four activate window
std::vector<std::queue<sc_time>> last4Activates;
std::vector<std::queue<sc_time>> last4ActivatesPhysical;
std::vector<std::queue<sc_time>> last4ActivatesLogical;
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 tRD_BURST;
sc_time tWR_BURST;
sc_time tWTRA;
sc_time tWRRDA;
sc_time tWRPRE;
sc_time tRDAACT;
sc_time tWRAACT;
sc_time tCCD_L_RTW_slr;
sc_time tCCD_S_RTW_slr;
sc_time tCCD_RTW_dlr;
sc_time tRDRD_dpr;
sc_time tRDRD_ddr;
sc_time tRDWR_dpr;
sc_time tRDWR_ddr;
sc_time tCCD_L_WTR_slr;
sc_time tCCD_S_WTR_slr;
sc_time tCCD_WTR_dlr;
sc_time tWRWR_dpr;
sc_time tWRWR_ddr;
sc_time tWRRD_dpr;
sc_time tWRRD_ddr;
sc_time tRDPDEN;
sc_time tWRPDEN;
sc_time tWRAPDEN;