Files
DRAMSys/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp

880 lines
48 KiB
C++

/*
* Copyright (c) 2020, Technische Universität Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Author: Lukas Steiner
*/
#include "CheckerDDR5.h"
CheckerDDR5::CheckerDDR5()
{
Configuration &config = Configuration::getInstance();
memSpec = dynamic_cast<const MemSpecDDR5 *>(config.memSpec);
if (memSpec == nullptr)
SC_REPORT_FATAL("CheckerDDR5", "Wrong MemSpec chosen");
lastScheduledByCommandAndDimmRank = std::vector<std::vector<sc_time>>
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfDIMMRanks, sc_max_time()));
lastScheduledByCommandAndPhysicalRank = std::vector<std::vector<sc_time>>
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfPhysicalRanks, sc_max_time()));
lastScheduledByCommandAndLogicalRank = std::vector<std::vector<sc_time>>
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfLogicalRanks, sc_max_time()));
lastScheduledByCommandAndBankGroup = std::vector<std::vector<sc_time>>
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBankGroups, sc_max_time()));
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
(numberOfCommands(), std::vector<sc_time>(memSpec->numberOfBanks, sc_max_time()));
lastScheduledByCommand = std::vector<sc_time>(numberOfCommands(), sc_max_time());
// Required for Same Bank Refresh
lastScheduledByCommandAndBankInGroup = std::vector<std::vector<sc_time>>(numberOfCommands(),
std::vector<sc_time>(memSpec->numberOfRanks * memSpec->banksPerGroup, sc_max_time()));
lastCommandOnBus = sc_max_time();
last4ActivatesLogical = std::vector<std::queue<sc_time>>(memSpec->numberOfLogicalRanks);
last4ActivatesPhysical = std::vector<std::queue<sc_time>>(memSpec->numberOfPhysicalRanks);
lastBurstLengthByCommandAndDimmRank = std::vector<std::vector<uint8_t>>
(4, std::vector<uint8_t>(memSpec->numberOfDIMMRanks));
lastBurstLengthByCommandAndPhysicalRank = std::vector<std::vector<uint8_t>>
(4, std::vector<uint8_t>(memSpec->numberOfPhysicalRanks));
lastBurstLengthByCommandAndLogicalRank = std::vector<std::vector<uint8_t>>
(4, std::vector<uint8_t>(memSpec->numberOfLogicalRanks));
lastBurstLengthByCommandAndBankGroup = std::vector<std::vector<uint8_t>>
(4, std::vector<uint8_t>(memSpec->numberOfBankGroups));
lastBurstLengthByCommandAndBank = std::vector<std::vector<uint8_t>>
(4, std::vector<uint8_t>(memSpec->numberOfBanks));
lastBurstLengthByCommand = std::vector<uint8_t>(4);
lastBurstLengthByCommandAndBankInGroup = std::vector<std::vector<uint8_t>>
(4, std::vector<uint8_t>(memSpec->numberOfRanks * memSpec->banksPerGroup));
cmdOffset = memSpec->cmdMode * memSpec->tCK;
tRD_BURST = 8 * memSpec->tCK;
tWR_BURST = 8 * memSpec->tCK;
tWTRA = memSpec->tWR - memSpec->tRTP;
tWRRDA = memSpec->tWL + tWR_BURST + tWTRA; // tWTRA = tWR - tRTP
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 + cmdOffset;
tWRPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + cmdOffset;
tWRAPDEN = memSpec->tWL + tWR_BURST + memSpec->tWR + cmdOffset;
// TODO: tRTP BL 32 (similar to LPDDR4)
}
sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, Rank rank, BankGroup bankgroup, Bank bank,
unsigned burstLength) const
{
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);
Bank bankInGroup = Bank(rank.ID() * memSpec->banksPerGroup + bank.ID() % memSpec->banksPerGroup);
if (command == Command::RD || command == Command::RDA)
{
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD);
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndBankGroup[Command::RD][bankgroup.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_slr); // 16 tCK
}
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndLogicalRank[Command::RD][logicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_slr); // 16 tCK
}
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndPhysicalRank[Command::RD][physicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_dlr); // 16 tCK
}
lastCommandStart = lastScheduledByCommand[Command::RD];
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()])
{
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RD][dimmrank.ID()])
{
if (lastBurstLengthByCommandAndDimmRank[Command::RD][dimmrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr + tRD_BURST); // 16 tCK + tRTRS
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr); // 16 tCK + tRTRS
}
else
{
if (lastBurstLengthByCommandAndPhysicalRank[Command::RD][physicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr + tRD_BURST); // 16 tCK + tRTRS
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr); // 16 tCK + tRTRS
}
}
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndBankGroup[Command::RDA][bankgroup.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_slr); // 16 tCK
}
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndBankGroup[Command::RDA][bankgroup.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_slr); // 16 tCK
}
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_dlr); // 16 tCK
}
lastCommandStart = lastScheduledByCommand[Command::RDA];
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()])
{
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RDA][dimmrank.ID()])
{
if (lastBurstLengthByCommandAndDimmRank[Command::RDA][dimmrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr + tRD_BURST); // 16 tCK + tRTRS
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_dpr); // 16 tCK + tRTRS
}
else
{
if (lastBurstLengthByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr + tRD_BURST); // 16 tCK + tRTRS
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDRD_ddr); // 16 tCK + tRTRS
}
}
if (command == Command::RDA)
{
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndBank[Command::WR][bank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDA + tWR_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDA); // + 8 tCK
}
}
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankgroup.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr + tWR_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr); // + 8 tCK
}
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndLogicalRank[Command::WR][logicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr + tWR_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr); // + 8 tCK
}
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndPhysicalRank[Command::WR][physicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr + tWR_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr); // + 8 tCK
}
lastCommandStart = lastScheduledByCommand[Command::WR];
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()])
{
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WR][dimmrank.ID()])
{
if (lastBurstLengthByCommandAndDimmRank[Command::WR][dimmrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr + tWR_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr); // + 8 tCK
}
else
{
if (lastBurstLengthByCommand[Command::WR] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr + tWR_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr); // + 8 tCK
}
}
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndBankGroup[Command::WRA][bankgroup.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr + tWR_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_WTR_slr); // + 8 tCK
}
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndLogicalRank[Command::WRA][logicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr + tWR_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_WTR_slr); // + 8 tCK
}
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr + tWR_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_WTR_dlr); // + 8 tCK
}
lastCommandStart = lastScheduledByCommand[Command::WRA];
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()])
{
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WRA][dimmrank.ID()])
{
if (lastBurstLengthByCommandAndDimmRank[Command::WRA][dimmrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr + tWR_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_dpr); // + 8 tCK
}
else
{
if (lastBurstLengthByCommand[Command::WRA] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr + tWR_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_ddr); // + 8 tCK
}
}
}
else if (command == Command::WR || command == Command::WRA)
{
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD);
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankgroup.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndBankGroup[Command::RD][bankgroup.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr + tRD_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr); // + 8 tCK
}
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndLogicalRank[Command::RD][logicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr + tRD_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr); // + 8 tCK
}
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndPhysicalRank[Command::RD][physicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr + tRD_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr); // + 8 tCK
}
lastCommandStart = lastScheduledByCommand[Command::RD];
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RD][physicalrank.ID()])
{
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RD][dimmrank.ID()])
{
if (lastBurstLengthByCommandAndDimmRank[Command::RD][dimmrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr + tRD_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr); // + 8 tCK
}
else
{
if (lastBurstLengthByCommand[Command::RD] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr + tRD_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr); // + 8 tCK
}
}
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankgroup.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndBankGroup[Command::RDA][bankgroup.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr + tRD_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_L_RTW_slr); // + 8 tCK
}
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndLogicalRank[Command::RDA][logicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr + tRD_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_S_RTW_slr); // + 8 tCK
}
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr + tRD_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tCCD_RTW_dlr); // + 8 tCK
}
lastCommandStart = lastScheduledByCommand[Command::RDA];
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()])
{
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::RDA][dimmrank.ID()])
{
if (lastBurstLengthByCommandAndDimmRank[Command::RDA][dimmrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr + tRD_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_dpr); // + 8 tCK
}
else
{
if (lastBurstLengthByCommand[Command::RDA] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr + tRD_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_ddr); // + 8 tCK
}
}
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankgroup.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankgroup.ID()] == 32)
{
if (burstLength == 16 && memSpec->bitWidth == 4)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWR_BURST + memSpec->tCCD_L_WR_slr);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWR_BURST + memSpec->tCCD_L_WR2_slr);
}
else
{
if (burstLength == 16 && memSpec->bitWidth == 4)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR2_slr);
}
}
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndLogicalRank[Command::WR][logicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 clocks
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_WR_slr); // 16 clocks
}
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndPhysicalRank[Command::WR][physicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 clocks
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_WR_dlr); // 16 clocks
}
lastCommandStart = lastScheduledByCommand[Command::WR];
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WR][physicalrank.ID()])
{
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WR][dimmrank.ID()])
{
if (lastBurstLengthByCommandAndDimmRank[Command::WR][dimmrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr + tWR_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr); // + 8 tCK
}
else
{
if (lastBurstLengthByCommand[Command::WR] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr + tWR_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr); // + 8 tCK
}
}
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankgroup.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndBankGroup[Command::WRA][bankgroup.ID()] == 32)
{
if (burstLength == 16 && memSpec->bitWidth == 4)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWR_BURST + memSpec->tCCD_L_WR_slr);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWR_BURST + memSpec->tCCD_L_WR2_slr);
}
else
{
if (burstLength == 16 && memSpec->bitWidth == 4)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR_slr);
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L_WR2_slr);
}
}
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndLogicalRank[Command::WRA][logicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 clocks
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S_WR_slr); // 16 clocks
}
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 16 * memSpec->tCK); // 16 clocks
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_WR_dlr); // 16 clocks
}
lastCommandStart = lastScheduledByCommand[Command::WRA];
if (lastCommandStart != lastScheduledByCommandAndPhysicalRank[Command::WRA][physicalrank.ID()])
{
if (lastCommandStart == lastScheduledByCommandAndDimmRank[Command::WRA][dimmrank.ID()])
{
if (lastBurstLengthByCommandAndDimmRank[Command::WRA][dimmrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr + tWR_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_dpr); // + 8 tCK
}
else
{
if (lastBurstLengthByCommand[Command::WRA] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr + tWR_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRWR_ddr); // + 8 tCK
}
}
}
else if (command == Command::ACT)
{
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankgroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L_slr);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_S_slr);
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::ACT][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_dlr);
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT);
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndBank[Command::WRA][bank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + tWR_BURST); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT); // + 8 tCK
}
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdOffset);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::PREA][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdOffset);
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRESB][bankInGroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - cmdOffset);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFA][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr - cmdOffset);
// TODO: No tRFC_dlr and tRFC_dpr between REFA and ACT?
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::REFSB][bankInGroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCsb_slr - cmdOffset);
// TODO: No tRFCsb_dlr between REFSB and ACT?
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFSB][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_slr - cmdOffset);
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::REFSB][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFSBRD_dlr - cmdOffset);
if (last4ActivatesLogical[logicalrank.ID()].size() >= 4)
earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesLogical[logicalrank.ID()].front()
+ memSpec->tFAW_slr - memSpec->longCmdOffset);
if (last4ActivatesPhysical[physicalrank.ID()].size() >= 4)
earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesPhysical[physicalrank.ID()].front()
+ memSpec->tFAW_dlr - memSpec->longCmdOffset);
}
else if (command == Command::PRE)
{
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + cmdOffset);
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdOffset);
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndBank[Command::WR][bank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tWR_BURST + cmdOffset); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdOffset); // + 8 tCK
}
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PREA][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRESB][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
}
else if (command == Command::PREA)
{
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + cmdOffset);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RD][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdOffset);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::RDA][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdOffset);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WR][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndLogicalRank[Command::WR][logicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tWR_BURST + cmdOffset); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdOffset); // + 8 tCK
}
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndLogicalRank[Command::WRA][logicalrank.ID()])
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tWR_BURST + cmdOffset); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdOffset); // + 8 tCK
}
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PREA][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
// PRESB tPPD
}
else if (command == Command::PRESB)
{
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::ACT][bankInGroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + cmdOffset);
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RD][bankInGroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdOffset);
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RDA][bankInGroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + cmdOffset);
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WR][bankInGroup.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndBankInGroup[Command::WR][bankInGroup.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tWR_BURST + cmdOffset); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdOffset); // + 8 tCK
}
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tWR_BURST + cmdOffset); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + cmdOffset); // + 8 tCK
}
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRE][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
// PREA tRP
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::PRESB][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
}
else if (command == Command::REFA)
{
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + cmdOffset);
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::RDA][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + cmdOffset);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::WRA][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndLogicalRank[Command::WRA][logicalrank.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + tWR_BURST + memSpec->tRP + cmdOffset); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP + cmdOffset); // + 8 tCK
}
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::PRE][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::PREA][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFA][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr);
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::REFA][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dlr);
lastCommandStart = lastScheduledByCommandAndDimmRank[Command::REFA][dimmrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dpr);
// REFSB tRFCsb_slr/dlr
// PRESB tRP
}
else if (command == Command::REFSB)
{
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::ACT][bankInGroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + cmdOffset);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::ACT][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L_slr + cmdOffset);
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::RDA][bankInGroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT + cmdOffset);
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()];
if (lastCommandStart != sc_max_time())
{
if (lastBurstLengthByCommandAndBankInGroup[Command::WRA][bankInGroup.ID()] == 32)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + tWR_BURST + cmdOffset); // + 8 tCK
else
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT + cmdOffset); // + 8 tCK
}
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRE][bankInGroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
// PREA tRP
lastCommandStart = lastScheduledByCommandAndBankInGroup[Command::PRESB][bankInGroup.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFA][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_slr);
// TODO: check this
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::REFA][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dlr);
// TODO: check this
lastCommandStart = lastScheduledByCommandAndDimmRank[Command::REFA][dimmrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC_dpr);
lastCommandStart = lastScheduledByCommandAndLogicalRank[Command::REFSB][logicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCsb_slr);
lastCommandStart = lastScheduledByCommandAndPhysicalRank[Command::REFSB][physicalrank.ID()];
if (lastCommandStart != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCsb_dlr);
if (last4ActivatesLogical[logicalrank.ID()].size() >= 4)
earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesLogical[logicalrank.ID()].front()
+ memSpec->tFAW_slr - memSpec->shortCmdOffset);
if (last4ActivatesPhysical[physicalrank.ID()].size() >= 4)
earliestTimeToStart = std::max(earliestTimeToStart, last4ActivatesPhysical[physicalrank.ID()].front()
+ memSpec->tFAW_dlr - memSpec->shortCmdOffset);
}
else
SC_REPORT_FATAL("CheckerDDR5", "Unknown command!");
if (lastCommandOnBus != sc_max_time())
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
return earliestTimeToStart;
}
void CheckerDDR5::insert(Command command, Rank rank, BankGroup bankgroup, Bank bank, unsigned burstLength)
{
PRINTDEBUGMESSAGE("CheckerDDR5", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + commandToString(command));
Rank logicalRank = rank;
Rank physicalRank = Rank(logicalRank.ID() / memSpec->logicalRanksPerPhysicalRank);
Rank dimmRank = Rank(physicalRank.ID() / memSpec->physicalRanksPerDIMMRank);
Bank bankInGroup = Bank(rank.ID() * memSpec->banksPerGroup + bank.ID() % memSpec->banksPerGroup);
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();
lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp();
lastScheduledByCommand[command] = sc_time_stamp();
lastCommandOnBus = sc_time_stamp() + memSpec->getCommandLength(command) - memSpec->tCK;
lastScheduledByCommandAndBankInGroup[command][bankInGroup.ID()] = sc_time_stamp();
if (isCasCommand(command))
{
lastBurstLengthByCommandAndDimmRank[command][dimmRank.ID()] = burstLength;
lastBurstLengthByCommandAndPhysicalRank[command][physicalRank.ID()] = burstLength;
lastBurstLengthByCommandAndLogicalRank[command][logicalRank.ID()] = burstLength;
lastBurstLengthByCommandAndBankGroup[command][bankgroup.ID()] = burstLength;
lastBurstLengthByCommandAndBank[command][bank.ID()] = burstLength;
lastBurstLengthByCommand[command] = burstLength;
lastBurstLengthByCommandAndBankInGroup[command][bankInGroup.ID()] = burstLength;
}
if (command == Command::ACT || command == Command::REFSB)
{
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);
}
}