Merge develop
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<img src="docs/images/dramsys_logo.png" width="350" style="float: left;" alt="DRAMSys Logo"/>
|
||||
|
||||
**DRAMSys** is a flexible DRAM subsystem design space exploration framework based on SystemC TLM-2.0. It was developed by the [Microelectronic Systems Design Research Group](https://eit.rptu.de/en/fgs/ems/home/seite) at [RPTU Kaiserslautern-Landau](https://rptu.de/en/) and by [Fraunhofer IESE](https://www.iese.fraunhofer.de/en.html).
|
||||
**DRAMSys** is a flexible DRAM subsystem design space exploration framework based on SystemC TLM-2.0. It was developed by the [Microelectronic Systems Design Research Group](https://eit.rptu.de/en/fgs/ems/home/seite) at [RPTU Kaiserslautern-Landau](https://rptu.de/en/), by [Fraunhofer IESE](https://www.iese.fraunhofer.de/en.html) and by the [Computer Engineering Group](https://www.informatik.uni-wuerzburg.de/ce/) at [JMU Würzburg](https://www.uni-wuerzburg.de/en/home/).
|
||||
|
||||
\>> [Official Website](https://www.iese.fraunhofer.de/en/innovation_trends/autonomous-systems/memtonomy/DRAMSys.html) <<
|
||||
|
||||
@@ -47,7 +47,7 @@ If you are interested in the Trace Analyzer, if you need support with the setup
|
||||
|
||||
## Basic Setup
|
||||
|
||||
Start using DRAMSys by cloning the repository.
|
||||
To use DRAMSys, first clone the repository. Make sure that Git LFS is installed on your machine.
|
||||
|
||||
### Dependencies
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Authors:
|
||||
# Authors:
|
||||
# Matthias Jung
|
||||
# Lukas Steiner
|
||||
# Derek Christ
|
||||
@@ -94,10 +94,9 @@ target_link_libraries(TraceAnalyzer
|
||||
|
||||
set(DRAMSYS_TRACEANALYZER_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
target_compile_definitions(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
DRAMSYS_TRACEANALYZER_DIR="${DRAMSYS_TRACEANALYZER_DIR}"
|
||||
)
|
||||
|
||||
build_source_group()
|
||||
diagnostics_print(${PROJECT_NAME})
|
||||
|
||||
@@ -290,11 +290,6 @@ ID TraceDB::getTransactionIDFromPhaseID(ID phaseID)
|
||||
GeneralInfo TraceDB::getGeneralInfoFromDB()
|
||||
{
|
||||
QVariant parameter;
|
||||
parameter = getParameterFromTable("NumberOfTransactions", "GeneralInfo");
|
||||
uint64_t numberOfTransactions = parameter.isValid() ? parameter.toULongLong() : 0;
|
||||
parameter = getParameterFromTable("TraceEnd", "GeneralInfo");
|
||||
traceTime traceEnd = parameter.isValid() ? static_cast<traceTime>(parameter.toULongLong()) : 0;
|
||||
parameter = getParameterFromTable("NumberOfRanks", "GeneralInfo");
|
||||
unsigned numberOfRanks = parameter.isValid() ? parameter.toUInt() : 1;
|
||||
parameter = getParameterFromTable("NumberOfBankgroups", "GeneralInfo");
|
||||
unsigned numberOfBankGroups = parameter.isValid() ? parameter.toUInt() : numberOfRanks;
|
||||
@@ -328,6 +323,8 @@ GeneralInfo TraceDB::getGeneralInfoFromDB()
|
||||
bool pseudoChannelMode = parameter.isValid() && parameter.toBool();
|
||||
|
||||
uint64_t numberOfPhases = getNumberOfPhases();
|
||||
uint64_t numberOfTransactions = getNumberOfTransactions();
|
||||
auto traceEnd = static_cast<traceTime>(getTraceLength());
|
||||
|
||||
QString description = (traces + "\n");
|
||||
description += mcconfig + "\n";
|
||||
@@ -417,6 +414,26 @@ QVariant TraceDB::getParameterFromTable(const std::string& parameter, const std:
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t TraceDB::getTraceLength()
|
||||
{
|
||||
QSqlQuery query(database);
|
||||
query.prepare("SELECT MAX(PhaseEnd) FROM Phases");
|
||||
executeQuery(query);
|
||||
|
||||
query.next();
|
||||
return query.value(0).toULongLong();
|
||||
}
|
||||
|
||||
uint64_t TraceDB::getNumberOfTransactions()
|
||||
{
|
||||
QSqlQuery query(database);
|
||||
query.prepare("SELECT COUNT(ID) FROM Transactions");
|
||||
executeQuery(query);
|
||||
|
||||
query.next();
|
||||
return query.value(0).toULongLong();
|
||||
}
|
||||
|
||||
uint64_t TraceDB::getNumberOfPhases()
|
||||
{
|
||||
QSqlQuery query(database);
|
||||
@@ -480,7 +497,7 @@ DependencyInfos TraceDB::getDependencyInfos(DependencyInfos::Type infoType)
|
||||
selectTimeDependencyPercentages = QSqlQuery(database);
|
||||
if (!selectTimeDependencyPercentages.prepare(queryTexts.selectTimeDependencyPercentages))
|
||||
qDebug() << database.lastError().text();
|
||||
|
||||
|
||||
executeQuery(selectTimeDependencyPercentages);
|
||||
return parseDependencyInfos(selectTimeDependencyPercentages, infoType);
|
||||
}
|
||||
@@ -714,4 +731,3 @@ void TraceDB::executeScriptFile(const QString& fileName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -145,6 +145,8 @@ private:
|
||||
void executeScriptFile(const QString& fileName);
|
||||
void dropAndCreateTables();
|
||||
|
||||
uint64_t getTraceLength();
|
||||
uint64_t getNumberOfTransactions();
|
||||
uint64_t getNumberOfPhases();
|
||||
GeneralInfo getGeneralInfoFromDB();
|
||||
CommandLengths getCommandLengthsFromDB();
|
||||
@@ -174,6 +176,3 @@ public:
|
||||
}
|
||||
};
|
||||
#endif // TRACEDB_H
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -246,7 +246,7 @@ void SimulationDialog::loadConfigurationFromTextFields()
|
||||
MemSpec memSpec;
|
||||
SimConfig simConfig;
|
||||
std::string simulationId;
|
||||
TraceSetup traceSetup;
|
||||
std::vector<Initiator> traceSetup;
|
||||
|
||||
simulationId = ui->simulationIdLineEdit->text().toStdString();
|
||||
|
||||
@@ -266,12 +266,14 @@ void SimulationDialog::loadConfigurationFromTextFields()
|
||||
return;
|
||||
}
|
||||
|
||||
configuration = DRAMSys::Config::Configuration{addressMapping,
|
||||
mcConfig,
|
||||
memSpec,
|
||||
simConfig,
|
||||
simulationId,
|
||||
std::make_optional<TraceSetup>(std::move(traceSetup))};
|
||||
configuration = DRAMSys::Config::Configuration{
|
||||
addressMapping,
|
||||
mcConfig,
|
||||
memSpec,
|
||||
simConfig,
|
||||
simulationId,
|
||||
std::make_optional<std::vector<Initiator>>(std::move(traceSetup))
|
||||
};
|
||||
|
||||
loadConfiguration();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -57,28 +57,28 @@ public:
|
||||
private:
|
||||
const MemSpecDDR5 *memSpec;
|
||||
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndDimmRank;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndPhysicalRank;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndLogicalRank;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<ControllerVector<DimmRank, sc_core::sc_time>> lastScheduledByCommandAndDimmRank;
|
||||
std::vector<ControllerVector<PhysicalRank, sc_core::sc_time>> lastScheduledByCommandAndPhysicalRank;
|
||||
std::vector<ControllerVector<LogicalRank, sc_core::sc_time>> lastScheduledByCommandAndLogicalRank;
|
||||
std::vector<ControllerVector<BankGroup, sc_core::sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<sc_core::sc_time> lastScheduledByCommand;
|
||||
sc_core::sc_time lastCommandOnBus;
|
||||
TimeInterval dummyCommandOnBus;
|
||||
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBankInGroup;
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBankInGroup;
|
||||
|
||||
std::vector<std::queue<sc_core::sc_time>> last4ActivatesPhysical;
|
||||
std::vector<std::queue<sc_core::sc_time>> last4ActivatesLogical;
|
||||
ControllerVector<PhysicalRank, std::queue<sc_core::sc_time>> last4ActivatesPhysical;
|
||||
ControllerVector<LogicalRank, std::queue<sc_core::sc_time>> last4ActivatesLogical;
|
||||
|
||||
std::vector<std::vector<uint8_t>> lastBurstLengthByCommandAndDimmRank;
|
||||
std::vector<std::vector<uint8_t>> lastBurstLengthByCommandAndPhysicalRank;
|
||||
std::vector<std::vector<uint8_t>> lastBurstLengthByCommandAndLogicalRank;
|
||||
std::vector<std::vector<uint8_t>> lastBurstLengthByCommandAndBankGroup;
|
||||
std::vector<std::vector<uint8_t>> lastBurstLengthByCommandAndBank;
|
||||
std::vector<ControllerVector<DimmRank, uint8_t>> lastBurstLengthByCommandAndDimmRank;
|
||||
std::vector<ControllerVector<PhysicalRank, uint8_t>> lastBurstLengthByCommandAndPhysicalRank;
|
||||
std::vector<ControllerVector<LogicalRank, uint8_t>> lastBurstLengthByCommandAndLogicalRank;
|
||||
std::vector<ControllerVector<BankGroup, uint8_t>> lastBurstLengthByCommandAndBankGroup;
|
||||
std::vector<ControllerVector<Bank, uint8_t>> lastBurstLengthByCommandAndBank;
|
||||
std::vector<uint8_t> lastBurstLengthByCommand;
|
||||
|
||||
std::vector<std::vector<uint8_t>> lastBurstLengthByCommandAndBankInGroup;
|
||||
std::vector<ControllerVector<Bank, uint8_t>> lastBurstLengthByCommandAndBankInGroup;
|
||||
|
||||
// TODO: store BL of last RD and WR globally or for each hierarchy?
|
||||
|
||||
|
||||
@@ -50,18 +50,18 @@ CheckerHBM3::CheckerHBM3(const Configuration &config)
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerHBM3", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>(
|
||||
Command::numberOfCommands(), std::vector<sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<std::vector<sc_time>>(
|
||||
Command::numberOfCommands(), std::vector<sc_time>(memSpec->bankGroupsPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>(
|
||||
Command::numberOfCommands(), std::vector<sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBank = std::vector<ControllerVector<Bank, sc_time>>(
|
||||
Command::numberOfCommands(), ControllerVector<Bank, sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<ControllerVector<BankGroup, sc_time>>(
|
||||
Command::numberOfCommands(), ControllerVector<BankGroup, sc_time>(memSpec->bankGroupsPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<ControllerVector<Rank, sc_time>>(
|
||||
Command::numberOfCommands(), ControllerVector<Rank, sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommand = std::vector<sc_time>(Command::numberOfCommands(), scMaxTime);
|
||||
lastCommandOnRasBus = scMaxTime;
|
||||
lastCommandOnCasBus = scMaxTime;
|
||||
last4Activates = std::vector<std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
|
||||
bankwiseRefreshCounter = std::vector<unsigned>(memSpec->ranksPerChannel);
|
||||
bankwiseRefreshCounter = ControllerVector<Rank, unsigned>(memSpec->ranksPerChannel);
|
||||
|
||||
tRDPDE = memSpec->tRL + memSpec->tPL + 2 * memSpec->tCK;
|
||||
tRDSRE = memSpec->tRL + memSpec->tPL + 3 * memSpec->tCK;
|
||||
@@ -83,682 +83,637 @@ sc_time CheckerHBM3::timeToSatisfyConstraints(Command command, const tlm_generic
|
||||
|
||||
if (command == Command::PREPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK / 2);
|
||||
if (lastCommandOnRasBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK / 2);
|
||||
}
|
||||
else if (command == Command::RD)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup.ID()];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnCasBus + memSpec->tCK);
|
||||
if (lastCommandOnCasBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnCasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::WR)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup.ID()];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnCasBus + memSpec->tCK);
|
||||
if (lastCommandOnCasBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnCasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup.ID()];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL + 2 * memSpec->tCK +
|
||||
std::max(memSpec->tWR - memSpec->tRTP, memSpec->tWTRL));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnCasBus + memSpec->tCK);
|
||||
if (lastCommandOnCasBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnCasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::WRA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup.ID()];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnCasBus + memSpec->tCK);
|
||||
if (lastCommandOnCasBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnCasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::REFPB][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::REFPB][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RFMAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RFMAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RFMPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RFMPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RFMPB][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RFMPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RFMPB][rank.ID()];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS - memSpec->tCK);
|
||||
|
||||
if (last4Activates[rank.ID()].size() >= 4)
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
|
||||
if (lastCommandOnRasBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::REFAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RFMAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RFMAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RFMPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RFMPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
if (lastCommandOnRasBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::PREAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK / 2);
|
||||
if (lastCommandOnRasBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK / 2);
|
||||
}
|
||||
else if (command == Command::REFPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDL + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::REFPB][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RFMAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RFMAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RFMPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RFMPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RFMPB][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RFMPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RFMPB][rank.ID()];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (bankwiseRefreshCounter[rank.ID()] == 0)
|
||||
if (bankwiseRefreshCounter[rank] == 0)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
}
|
||||
|
||||
if (last4Activates[rank.ID()].size() >= 4)
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
|
||||
if (lastCommandOnRasBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + std::max(memSpec->tRTP + memSpec->tRP, tRDSRE));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
if (lastCommandOnRasBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::RFMAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RFMAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RFMAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RFMPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RFMPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
if (lastCommandOnRasBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::RFMAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDL + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::REFPB][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RFMAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RFMAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RFMPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RFMPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RFMPB][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RFMPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RFMPB][rank.ID()];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
if (lastCommandOnRasBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
if (lastCommandOnRasBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
if (lastCommandOnRasBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
if (lastCommandOnRasBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
if (lastCommandOnRasBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
if (lastCommandOnRasBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -778,12 +733,12 @@ void CheckerHBM3::insert(Command command, const tlm_generic_payload &payload)
|
||||
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
|
||||
Bank bank = ControllerExtension::getBank(payload);
|
||||
|
||||
PRINTDEBUGMESSAGE("CheckerHBM3",
|
||||
"Changing state on bank " + std::to_string(bank.ID()) + " command is " + command.toString());
|
||||
PRINTDEBUGMESSAGE("CheckerHBM3", "Changing state on bank " + std::to_string(static_cast<std::size_t>(bank))
|
||||
+ " command is " + command.toString());
|
||||
|
||||
lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBankGroup[command][bankGroup.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBank[command][bank] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBankGroup[command][bankGroup] = sc_time_stamp();
|
||||
lastScheduledByCommandAndRank[command][rank] = sc_time_stamp();
|
||||
lastScheduledByCommand[command] = sc_time_stamp();
|
||||
|
||||
if (command.isCasCommand())
|
||||
@@ -795,13 +750,13 @@ void CheckerHBM3::insert(Command command, const tlm_generic_payload &payload)
|
||||
|
||||
if (command == Command::ACT || command == Command::REFPB)
|
||||
{
|
||||
if (last4Activates[rank.ID()].size() == 4)
|
||||
last4Activates[rank.ID()].pop();
|
||||
last4Activates[rank.ID()].push(lastCommandOnRasBus);
|
||||
if (last4Activates[rank].size() == 4)
|
||||
last4Activates[rank].pop();
|
||||
last4Activates[rank].push(lastCommandOnRasBus);
|
||||
}
|
||||
|
||||
if (command == Command::REFPB)
|
||||
bankwiseRefreshCounter[rank.ID()] = (bankwiseRefreshCounter[rank.ID()] + 1) % memSpec->banksPerRank;
|
||||
bankwiseRefreshCounter[rank] = (bankwiseRefreshCounter[rank] + 1) % memSpec->banksPerRank;
|
||||
}
|
||||
|
||||
bool CheckerHBM3::isFullCycle(const sc_core::sc_time& time) const
|
||||
|
||||
@@ -60,17 +60,17 @@ private:
|
||||
|
||||
const MemSpecHBM3 *memSpec;
|
||||
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<ControllerVector<BankGroup, sc_core::sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
std::vector<ControllerVector<Rank, sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<sc_core::sc_time> lastScheduledByCommand;
|
||||
|
||||
sc_core::sc_time lastCommandOnRasBus;
|
||||
sc_core::sc_time lastCommandOnCasBus;
|
||||
|
||||
// Four activate window
|
||||
std::vector<std::queue<sc_core::sc_time>> last4Activates;
|
||||
std::vector<unsigned> bankwiseRefreshCounter;
|
||||
ControllerVector<Rank, std::queue<sc_core::sc_time>> last4Activates;
|
||||
ControllerVector<Rank, unsigned> bankwiseRefreshCounter;
|
||||
|
||||
const sc_core::sc_time scMaxTime = sc_core::sc_max_time();
|
||||
sc_core::sc_time tRDPDE;
|
||||
|
||||
@@ -51,23 +51,24 @@ CheckerLPDDR5::CheckerLPDDR5(const Configuration& config)
|
||||
SC_REPORT_FATAL("CheckerLPDDR5", "Wrong MemSpec chosen");
|
||||
else
|
||||
{
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->bankGroupsPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<ControllerVector<Rank, sc_time>>
|
||||
(Command::numberOfCommands(), ControllerVector<Rank, sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<ControllerVector<BankGroup, sc_time>>
|
||||
(Command::numberOfCommands(),
|
||||
ControllerVector<BankGroup, sc_time>(memSpec->bankGroupsPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBank = std::vector<ControllerVector<Bank, sc_time>>
|
||||
(Command::numberOfCommands(), ControllerVector<Bank, sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommand = std::vector<sc_time>(Command::numberOfCommands(), scMaxTime);
|
||||
lastCommandOnBus = scMaxTime;
|
||||
|
||||
last4Activates = std::vector<std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
|
||||
lastBurstLengthByCommandAndRank = std::vector<std::vector<uint8_t>>
|
||||
(Command::WRA + 1, std::vector<uint8_t>(memSpec->ranksPerChannel));
|
||||
lastBurstLengthByCommandAndBankGroup = std::vector<std::vector<uint8_t>>
|
||||
(Command::WRA + 1, std::vector<uint8_t>(memSpec->bankGroupsPerChannel));
|
||||
lastBurstLengthByCommandAndBank = std::vector<std::vector<uint8_t>>
|
||||
(Command::WRA + 1, std::vector<uint8_t>(memSpec->banksPerChannel));
|
||||
lastBurstLengthByCommandAndRank = std::vector<ControllerVector<Rank, uint8_t>>
|
||||
(Command::WRA + 1, ControllerVector<Rank, uint8_t>(memSpec->ranksPerChannel));
|
||||
lastBurstLengthByCommandAndBankGroup = std::vector<ControllerVector<BankGroup, uint8_t>>
|
||||
(Command::WRA + 1, ControllerVector<BankGroup, uint8_t>(memSpec->bankGroupsPerChannel));
|
||||
lastBurstLengthByCommandAndBank = std::vector<ControllerVector<Bank, uint8_t>>
|
||||
(Command::WRA + 1, ControllerVector<Bank, uint8_t>(memSpec->banksPerChannel));
|
||||
lastBurstLengthByCommand = std::vector<uint8_t>(Command::WRA + 1);
|
||||
|
||||
tBURST16 = 16 / memSpec->dataRate * memSpec->tCK;
|
||||
@@ -92,23 +93,23 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
assert(!(memSpec->bankMode == MemSpecLPDDR5::BankMode::MBG) || (memSpec->dataRate == 8)); // BG mode -> 4:1 ratio
|
||||
assert(burstLength <= memSpec->maxBurstLength);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD_L + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBankGroup[Command::RD][bankGroup.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndBankGroup[Command::RD][bankGroup] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_L_32);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_L_16);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndRank[Command::RD][rank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndRank[Command::RD][rank] == 32)
|
||||
{
|
||||
// TODO: model BG mode BL32 interleaved burst, remove this fix
|
||||
if (memSpec->bankMode == MemSpecLPDDR5::BankMode::MBG)
|
||||
@@ -120,7 +121,7 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_S_16);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ?
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank] ?
|
||||
lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
@@ -132,19 +133,19 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->tCK + memSpec->tRPST + memSpec->tRPRE);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBankGroup[Command::RDA][bankGroup.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndBankGroup[Command::RDA][bankGroup] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_L_32);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_L_16);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndRank[Command::RDA][rank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndRank[Command::RDA][rank] == 32)
|
||||
{
|
||||
// TODO: model BG mode BL32 interleaved burst, remove this fix
|
||||
if (memSpec->bankMode == MemSpecLPDDR5::BankMode::MBG)
|
||||
@@ -156,7 +157,7 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_S_16);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ?
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank] ?
|
||||
lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
@@ -169,10 +170,10 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->tCK + memSpec->tRPST + memSpec->tRPRE);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankGroup.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankGroup] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
|
||||
+ memSpec->BL_n_max_32 + memSpec->tWTR_L);
|
||||
else
|
||||
@@ -180,10 +181,10 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->BL_n_max_16 + memSpec->tWTR_L);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndRank[Command::WR][rank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndRank[Command::WR][rank] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
|
||||
+ memSpec->BL_n_min_32 + memSpec->tWTR_S);
|
||||
else
|
||||
@@ -191,7 +192,7 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->BL_n_min_16 + memSpec->tWTR_S);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ?
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank] ?
|
||||
lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
@@ -204,10 +205,10 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->tWL + memSpec->BL_n_min_16 + memSpec->tCK - memSpec->tRL);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBankGroup[Command::WRA][bankGroup.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndBankGroup[Command::WRA][bankGroup] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
|
||||
+ memSpec->BL_n_max_32 + memSpec->tWTR_L);
|
||||
else
|
||||
@@ -215,10 +216,10 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->BL_n_max_16 + memSpec->tWTR_L);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndRank[Command::WRA][rank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndRank[Command::WRA][rank] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
|
||||
+ memSpec->BL_n_min_32 + memSpec->tWTR_S);
|
||||
else
|
||||
@@ -226,7 +227,7 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->BL_n_min_16 + memSpec->tWTR_S);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ?
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank] ?
|
||||
lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
@@ -246,14 +247,14 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
assert(!(memSpec->bankMode == MemSpecLPDDR5::BankMode::MBG) || (memSpec->dataRate == 8)); // BG mode -> 4:1 ratio
|
||||
assert(burstLength <= memSpec->maxBurstLength);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD_S + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBankGroup[Command::RD][bankGroup.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndBankGroup[Command::RD][bankGroup] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRL
|
||||
+ memSpec->BL_n_max_32 + memSpec->tWCK2DQO - memSpec->tWL);
|
||||
else
|
||||
@@ -261,10 +262,10 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->BL_n_max_16 + memSpec->tWCK2DQO - memSpec->tWL);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndRank[Command::RD][rank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndRank[Command::RD][rank] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRL
|
||||
+ memSpec->BL_n_min_32 + memSpec->tWCK2DQO - memSpec->tWL);
|
||||
else
|
||||
@@ -272,7 +273,7 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->BL_n_min_16 + memSpec->tWCK2DQO - memSpec->tWL);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ?
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank] ?
|
||||
lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
@@ -285,10 +286,10 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->tRL + memSpec->BL_n_min_16 + memSpec->tWCK2DQO + memSpec->tRPST - memSpec->tWL);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBankGroup[Command::RDA][bankGroup.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndBankGroup[Command::RDA][bankGroup] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRL
|
||||
+ memSpec->BL_n_max_32 + memSpec->tWCK2DQO - memSpec->tWL);
|
||||
else
|
||||
@@ -296,10 +297,10 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->BL_n_max_16 + memSpec->tWCK2DQO - memSpec->tWL);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndRank[Command::RDA][rank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndRank[Command::RDA][rank] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRL
|
||||
+ memSpec->BL_n_min_32 + memSpec->tWCK2DQO - memSpec->tWL);
|
||||
else
|
||||
@@ -307,7 +308,7 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->BL_n_min_16 + memSpec->tWCK2DQO - memSpec->tWL);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ?
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank] ?
|
||||
lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
@@ -320,19 +321,19 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->tRL + memSpec->BL_n_min_16 + memSpec->tWCK2DQO + memSpec->tRPST - memSpec->tWL);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankGroup.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndBankGroup[Command::WR][bankGroup] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_L_32);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_L_16);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndRank[Command::WR][rank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndRank[Command::WR][rank] == 32)
|
||||
{
|
||||
// TODO: model BG mode BL32 interleaved burst, remove this fix
|
||||
if (memSpec->bankMode == MemSpecLPDDR5::BankMode::MBG)
|
||||
@@ -344,7 +345,7 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_S_16);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ?
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank] ?
|
||||
lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
@@ -355,19 +356,19 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_min_16 + memSpec->tCK);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBankGroup[Command::WRA][bankGroup.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndBankGroup[Command::WRA][bankGroup] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_L_32);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_L_16);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndRank[Command::WRA][rank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndRank[Command::WRA][rank] == 32)
|
||||
{
|
||||
// TODO: model BG mode BL32 interleaved burst, remove this fix
|
||||
if (memSpec->bankMode == MemSpecLPDDR5::BankMode::MBG)
|
||||
@@ -379,7 +380,7 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_S_16);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ?
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank] ?
|
||||
lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
@@ -391,18 +392,18 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBank[Command::RDA][bank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndBank[Command::RDA][bank] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_min_32
|
||||
+ memSpec->tRBTP + memSpec->tRPpb - memSpec->tCK);
|
||||
else
|
||||
@@ -410,10 +411,10 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->tRBTP + memSpec->tRPpb - memSpec->tCK);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBank[Command::RDA][bank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndBank[Command::RDA][bank] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
|
||||
+ memSpec->BL_n_min_32 + memSpec->tCK + memSpec->tWR + memSpec->tRPpb - memSpec->tCK);
|
||||
else
|
||||
@@ -421,47 +422,47 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->BL_n_min_16 + memSpec->tCK + memSpec->tWR + memSpec->tRPpb - memSpec->tCK);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tpbR2act - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFP2B][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFP2B][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tpbR2act - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFP2B][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFP2B][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb - memSpec->tCK);
|
||||
|
||||
if (last4Activates[rank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW - memSpec->tCK);
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW - memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::PREPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBank[Command::RD][bank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndBank[Command::RD][bank] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_min_32
|
||||
+ memSpec->tRBTP);
|
||||
else
|
||||
@@ -469,10 +470,10 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->tRBTP);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBank[Command::WR][bank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndBank[Command::WR][bank] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
|
||||
+ memSpec->BL_n_min_32 + memSpec->tCK + memSpec->tWR);
|
||||
else
|
||||
@@ -480,20 +481,20 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->BL_n_min_16 + memSpec->tCK + memSpec->tWR);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
}
|
||||
else if (command == Command::PREAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndRank[Command::RD][rank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndRank[Command::RD][rank] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_min_32
|
||||
+ memSpec->tRBTP);
|
||||
else
|
||||
@@ -501,10 +502,10 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->tRBTP);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndRank[Command::RDA][rank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndRank[Command::RDA][rank] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_min_32
|
||||
+ memSpec->tRBTP);
|
||||
else
|
||||
@@ -512,10 +513,10 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->tRBTP);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndRank[Command::WR][rank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndRank[Command::WR][rank] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
|
||||
+ memSpec->BL_n_min_32 + memSpec->tCK + memSpec->tWR);
|
||||
else
|
||||
@@ -523,10 +524,10 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->BL_n_min_16 + memSpec->tCK + memSpec->tWR);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndRank[Command::WRA][rank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndRank[Command::WRA][rank] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
|
||||
+ memSpec->BL_n_min_32 + memSpec->tCK + memSpec->tWR);
|
||||
else
|
||||
@@ -534,20 +535,20 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->BL_n_min_16 + memSpec->tCK + memSpec->tWR);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
}
|
||||
else if (command == Command::REFAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndRank[Command::RDA][rank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndRank[Command::RDA][rank] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_min_32
|
||||
+ memSpec->tRBTP + memSpec->tRPpb);
|
||||
else
|
||||
@@ -555,10 +556,10 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->tRBTP + memSpec->tRPpb);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndRank[Command::WRA][rank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndRank[Command::WRA][rank] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
|
||||
+ memSpec->BL_n_min_32 + memSpec->tCK + memSpec->tWR + memSpec->tRPpb);
|
||||
else
|
||||
@@ -566,32 +567,32 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->BL_n_min_16 + memSpec->tCK + memSpec->tWR + memSpec->tRPpb);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
|
||||
}
|
||||
else if (command == Command::REFPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBank[Command::RDA][bank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndBank[Command::RDA][bank] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_min_32
|
||||
+ memSpec->tRBTP + memSpec->tRPpb);
|
||||
else
|
||||
@@ -599,10 +600,10 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->tRBTP + memSpec->tRPpb);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBank[Command::WRA][bank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndBank[Command::WRA][bank] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
|
||||
+ memSpec->BL_n_min_32 + memSpec->tCK + memSpec->tWR + memSpec->tRPpb);
|
||||
else
|
||||
@@ -610,45 +611,45 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->BL_n_min_16 + memSpec->tCK + memSpec->tWR + memSpec->tRPpb);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tpbR2pbR);
|
||||
|
||||
if (last4Activates[rank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
}
|
||||
else if (command == Command::REFP2B)
|
||||
{
|
||||
Bank secondBank = Bank(bank.ID() + memSpec->getPer2BankOffset());
|
||||
Bank secondBank = Bank(static_cast<std::size_t>(bank) + memSpec->getPer2BankOffset());
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][secondBank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][secondBank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBank[Command::RDA][bank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndBank[Command::RDA][bank] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_min_32
|
||||
+ memSpec->tRBTP + memSpec->tRPpb);
|
||||
else
|
||||
@@ -656,10 +657,10 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->tRBTP + memSpec->tRPpb);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][secondBank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][secondBank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBank[Command::RDA][secondBank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndBank[Command::RDA][secondBank] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->BL_n_min_32
|
||||
+ memSpec->tRBTP + memSpec->tRPpb);
|
||||
else
|
||||
@@ -667,10 +668,10 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->tRBTP + memSpec->tRPpb);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBank[Command::WRA][bank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndBank[Command::WRA][bank] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
|
||||
+ memSpec->BL_n_min_32 + memSpec->tCK + memSpec->tWR + memSpec->tRPpb);
|
||||
else
|
||||
@@ -678,10 +679,10 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->BL_n_min_16 + memSpec->tCK + memSpec->tWR + memSpec->tRPpb);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][secondBank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][secondBank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBank[Command::WRA][secondBank.ID()] == 32)
|
||||
if (lastBurstLengthByCommandAndBank[Command::WRA][secondBank] == 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tWL
|
||||
+ memSpec->BL_n_min_32 + memSpec->tCK + memSpec->tWR + memSpec->tRPpb);
|
||||
else
|
||||
@@ -689,28 +690,28 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
+ memSpec->BL_n_min_16 + memSpec->tCK + memSpec->tWR + memSpec->tRPpb);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][secondBank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][secondBank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFP2B][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFP2B][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFP2B][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFP2B][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tpbR2pbR);
|
||||
|
||||
if (last4Activates[rank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("CheckerLPDDR5", "Unknown command!");
|
||||
@@ -729,33 +730,36 @@ void CheckerLPDDR5::insert(Command command, const tlm_generic_payload& payload)
|
||||
Bank bank = ControllerExtension::getBank(payload);
|
||||
unsigned burstLength = ControllerExtension::getBurstLength(payload);
|
||||
|
||||
PRINTDEBUGMESSAGE("CheckerLPDDR5", "Changing state on bank " + std::to_string(bank.ID())
|
||||
PRINTDEBUGMESSAGE("CheckerLPDDR5", "Changing state on bank " + std::to_string(static_cast<std::size_t>(bank))
|
||||
+ " command is " + command.toString());
|
||||
|
||||
lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBankGroup[command][bankGroup.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndRank[command][rank] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBankGroup[command][bankGroup] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBank[command][bank] = sc_time_stamp();
|
||||
lastScheduledByCommand[command] = sc_time_stamp();
|
||||
|
||||
if (command.isCasCommand())
|
||||
{
|
||||
lastBurstLengthByCommandAndRank[command][rank.ID()] = burstLength;
|
||||
lastBurstLengthByCommandAndBankGroup[command][bankGroup.ID()] = burstLength;
|
||||
lastBurstLengthByCommandAndBank[command][bank.ID()] = burstLength;
|
||||
lastBurstLengthByCommandAndRank[command][rank] = burstLength;
|
||||
lastBurstLengthByCommandAndBankGroup[command][bankGroup] = burstLength;
|
||||
lastBurstLengthByCommandAndBank[command][bank] = burstLength;
|
||||
lastBurstLengthByCommand[command] = burstLength;
|
||||
}
|
||||
|
||||
if (command == Command::REFP2B)
|
||||
lastScheduledByCommandAndBank[command][bank.ID() + memSpec->getPer2BankOffset()] = sc_time_stamp();
|
||||
{
|
||||
Bank secondBank = Bank(static_cast<std::size_t>(bank) + memSpec->getPer2BankOffset());
|
||||
lastScheduledByCommandAndBank[command][secondBank] = sc_time_stamp();
|
||||
}
|
||||
|
||||
lastCommandOnBus = sc_time_stamp() + memSpec->getCommandLength(command) - memSpec->tCK;
|
||||
|
||||
if (command == Command::ACT || command == Command::REFPB || command == Command::REFP2B
|
||||
|| command == Command::RFMPB || command == Command::RFMP2B)
|
||||
{
|
||||
if (last4Activates[rank.ID()].size() == 4)
|
||||
last4Activates[rank.ID()].pop();
|
||||
last4Activates[rank.ID()].push(lastCommandOnBus);
|
||||
if (last4Activates[rank].size() == 4)
|
||||
last4Activates[rank].pop();
|
||||
last4Activates[rank].push(lastCommandOnBus);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,16 +57,16 @@ public:
|
||||
private:
|
||||
const MemSpecLPDDR5 *memSpec;
|
||||
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<ControllerVector<Rank, sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<ControllerVector<BankGroup, sc_core::sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<sc_core::sc_time> lastScheduledByCommand;
|
||||
sc_core::sc_time lastCommandOnBus;
|
||||
std::vector<std::queue<sc_core::sc_time>> last4Activates;
|
||||
ControllerVector<Rank, std::queue<sc_core::sc_time>> last4Activates;
|
||||
|
||||
std::vector<std::vector<uint8_t>> lastBurstLengthByCommandAndRank;
|
||||
std::vector<std::vector<uint8_t>> lastBurstLengthByCommandAndBankGroup;
|
||||
std::vector<std::vector<uint8_t>> lastBurstLengthByCommandAndBank;
|
||||
std::vector<ControllerVector<Rank, uint8_t>> lastBurstLengthByCommandAndRank;
|
||||
std::vector<ControllerVector<BankGroup, uint8_t>> lastBurstLengthByCommandAndBankGroup;
|
||||
std::vector<ControllerVector<Bank, uint8_t>> lastBurstLengthByCommandAndBank;
|
||||
std::vector<uint8_t> lastBurstLengthByCommand;
|
||||
|
||||
const sc_core::sc_time scMaxTime = sc_core::sc_max_time();
|
||||
|
||||
@@ -45,17 +45,16 @@ add_library(${PROJECT_NAME} STATIC ${SOURCE_FILES} ${HEADER_FILES})
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
DRAMSys::util
|
||||
)
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
target_compile_definitions(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
DRAMSYS_RESOURCE_DIR="${DRAMSYS_RESOURCE_DIR}"
|
||||
)
|
||||
|
||||
add_library(DRAMSys::config ALIAS ${PROJECT_NAME})
|
||||
|
||||
build_source_group()
|
||||
diagnostics_print(${PROJECT_NAME})
|
||||
build_source_group()
|
||||
@@ -62,13 +62,13 @@ namespace DRAMSys::Config {
|
||||
struct Configuration
|
||||
{
|
||||
static constexpr std::string_view KEY = "simulation";
|
||||
|
||||
|
||||
AddressMapping addressmapping;
|
||||
McConfig mcconfig;
|
||||
MemSpec memspec;
|
||||
SimConfig simconfig;
|
||||
std::string simulationid;
|
||||
std::optional<TraceSetup> tracesetup;
|
||||
std::optional<std::vector<Initiator>> tracesetup;
|
||||
};
|
||||
|
||||
NLOHMANN_JSONIFY_ALL_THINGS(Configuration,
|
||||
|
||||
@@ -129,7 +129,7 @@ struct TrafficGenerator
|
||||
std::optional<uint64_t> maxTransactions;
|
||||
std::optional<unsigned> dataLength;
|
||||
std::optional<unsigned> dataAlignment;
|
||||
|
||||
|
||||
uint64_t numRequests{};
|
||||
double rwRatio{};
|
||||
AddressDistribution addressDistribution;
|
||||
@@ -201,8 +201,7 @@ struct TraceSetupConstants
|
||||
static constexpr std::string_view SUB_DIR = "tracesetup";
|
||||
};
|
||||
|
||||
using TraceSetup = std::vector<
|
||||
std::variant<TracePlayer, TrafficGenerator, TrafficGeneratorStateMachine, RowHammer>>;
|
||||
using Initiator = std::variant<TracePlayer, TrafficGenerator, TrafficGeneratorStateMachine, RowHammer>;
|
||||
|
||||
} // namespace Configuration
|
||||
|
||||
|
||||
@@ -45,8 +45,8 @@ add_library(${PROJECT_NAME} STATIC ${SOURCE_FILES} ${HEADER_FILES})
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
SystemC::systemc
|
||||
DRAMSys::util
|
||||
DRAMSys::config
|
||||
@@ -61,4 +61,3 @@ endif ()
|
||||
add_library(DRAMSys::libdramsys ALIAS ${PROJECT_NAME})
|
||||
|
||||
build_source_group()
|
||||
diagnostics_print(${PROJECT_NAME})
|
||||
|
||||
@@ -76,6 +76,9 @@ TlmRecorder::TlmRecorder(const std::string &name,
|
||||
executeInitialSqlCommand();
|
||||
prepareSqlStatements();
|
||||
|
||||
insertGeneralInfo();
|
||||
insertCommandLengths();
|
||||
|
||||
PRINTDEBUGMESSAGE(name, "Starting new database transaction");
|
||||
}
|
||||
|
||||
@@ -355,7 +358,7 @@ void TlmRecorder::prepareSqlStatements()
|
||||
|
||||
insertGeneralInfoString =
|
||||
"INSERT INTO GeneralInfo VALUES"
|
||||
"(:numberOfTransactions, :end, :numberOfRanks, :numberOfBankGroups, :numberOfBanks, :clk, :unitOfTime, "
|
||||
"(:numberOfRanks, :numberOfBankGroups, :numberOfBanks, :clk, :unitOfTime, "
|
||||
":mcconfig, :memspec, :traces, :windowSize, :refreshMaxPostponed, :refreshMaxPulledin, :controllerThread, "
|
||||
":maxBufferDepth, :per2BankOffset, :rowColumnCommandBus, :pseudoChannelMode)";
|
||||
|
||||
@@ -391,27 +394,25 @@ void TlmRecorder::insertDebugMessageInDB(const std::string &message, const sc_ti
|
||||
|
||||
void TlmRecorder::insertGeneralInfo()
|
||||
{
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 1, static_cast<int64_t>(totalNumTransactions));
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 2, static_cast<int64_t>(simulationTimeCoveredByRecording.value()));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 3, static_cast<int>(config.memSpec->ranksPerChannel));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 4, static_cast<int>(config.memSpec->bankGroupsPerChannel));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 5, static_cast<int>(config.memSpec->banksPerChannel));
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 6, static_cast<int64_t>(config.memSpec->tCK.value()));
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 7, "PS", 2, nullptr);
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 1, static_cast<int>(config.memSpec->ranksPerChannel));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 2, static_cast<int>(config.memSpec->bankGroupsPerChannel));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 3, static_cast<int>(config.memSpec->banksPerChannel));
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 4, static_cast<int64_t>(config.memSpec->tCK.value()));
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 5, "PS", 2, nullptr);
|
||||
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 8, mcconfig.c_str(), static_cast<int>(mcconfig.length()), nullptr);
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 9, memspec.c_str(), static_cast<int>(memspec.length()), nullptr);
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 10, traces.c_str(), static_cast<int>(traces.length()), nullptr);
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 6, mcconfig.c_str(), static_cast<int>(mcconfig.length()), nullptr);
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 7, memspec.c_str(), static_cast<int>(memspec.length()), nullptr);
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 8, traces.c_str(), static_cast<int>(traces.length()), nullptr);
|
||||
if (config.enableWindowing)
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 11, static_cast<int64_t>((config.memSpec->tCK
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 9, static_cast<int64_t>((config.memSpec->tCK
|
||||
* config.windowSize).value()));
|
||||
else
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 11, 0);
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 12, static_cast<int>(config.refreshMaxPostponed));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 13, static_cast<int>(config.refreshMaxPulledin));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 14, static_cast<int>(UINT_MAX));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 15, static_cast<int>(config.requestBufferSize));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 16, static_cast<int>(config.memSpec->getPer2BankOffset()));
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 9, 0);
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 10, static_cast<int>(config.refreshMaxPostponed));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 11, static_cast<int>(config.refreshMaxPulledin));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 12, static_cast<int>(UINT_MAX));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 13, static_cast<int>(config.requestBufferSize));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 14, static_cast<int>(config.memSpec->getPer2BankOffset()));
|
||||
|
||||
const MemSpec& memSpec = *config.memSpec;
|
||||
const auto memoryType = memSpec.memoryType;
|
||||
@@ -425,8 +426,8 @@ void TlmRecorder::insertGeneralInfo()
|
||||
return memSpec.pseudoChannelsPerChannel != 1;
|
||||
}();
|
||||
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 17, static_cast<int>(rowColumnCommandBus));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 18, static_cast<int>(pseudoChannelMode));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 15, static_cast<int>(rowColumnCommandBus));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 16, static_cast<int>(pseudoChannelMode));
|
||||
executeSqlStatement(insertGeneralInfoStatement);
|
||||
}
|
||||
|
||||
@@ -453,9 +454,9 @@ void TlmRecorder::insertTransactionInDB(const Transaction &recordingData)
|
||||
sqlite3_bind_int64(insertTransactionStatement, 3, static_cast<int64_t>(recordingData.address));
|
||||
sqlite3_bind_int(insertTransactionStatement, 4, static_cast<int>(recordingData.dataLength));
|
||||
sqlite3_bind_int(insertTransactionStatement, 5,
|
||||
static_cast<int>(recordingData.thread.ID()));
|
||||
static_cast<int>(recordingData.thread));
|
||||
sqlite3_bind_int(insertTransactionStatement, 6,
|
||||
static_cast<int>(recordingData.channel.ID()));
|
||||
static_cast<int>(recordingData.channel));
|
||||
sqlite3_bind_int64(insertTransactionStatement, 7,
|
||||
static_cast<int64_t>(recordingData.timeOfGeneration.value()));
|
||||
sqlite3_bind_text(insertTransactionStatement, 8,
|
||||
@@ -480,11 +481,11 @@ void TlmRecorder::insertPhaseInDB(const Transaction::Phase& phase, uint64_t tran
|
||||
sqlite3_bind_int64(insertPhaseStatement, 3, static_cast<int64_t>(phase.interval.end.value()));
|
||||
sqlite3_bind_int64(insertPhaseStatement, 4, static_cast<int64_t>(phase.intervalOnDataStrobe.start.value()));
|
||||
sqlite3_bind_int64(insertPhaseStatement, 5, static_cast<int64_t>(phase.intervalOnDataStrobe.end.value()));
|
||||
sqlite3_bind_int(insertPhaseStatement, 6, static_cast<int>(phase.rank.ID()));
|
||||
sqlite3_bind_int(insertPhaseStatement, 7, static_cast<int>(phase.bankGroup.ID()));
|
||||
sqlite3_bind_int(insertPhaseStatement, 8, static_cast<int>(phase.bank.ID()));
|
||||
sqlite3_bind_int(insertPhaseStatement, 9, static_cast<int>(phase.row.ID()));
|
||||
sqlite3_bind_int(insertPhaseStatement, 10, static_cast<int>(phase.column.ID()));
|
||||
sqlite3_bind_int(insertPhaseStatement, 6, static_cast<int>(phase.rank));
|
||||
sqlite3_bind_int(insertPhaseStatement, 7, static_cast<int>(phase.bankGroup));
|
||||
sqlite3_bind_int(insertPhaseStatement, 8, static_cast<int>(phase.bank));
|
||||
sqlite3_bind_int(insertPhaseStatement, 9, static_cast<int>(phase.row));
|
||||
sqlite3_bind_int(insertPhaseStatement, 10, static_cast<int>(phase.column));
|
||||
sqlite3_bind_int(insertPhaseStatement, 11, static_cast<int>(phase.burstLength));
|
||||
sqlite3_bind_int64(insertPhaseStatement, 12, static_cast<int64_t>(transactionID));
|
||||
executeSqlStatement(insertPhaseStatement);
|
||||
@@ -522,8 +523,6 @@ void TlmRecorder::closeConnection()
|
||||
storageThread.join();
|
||||
std::swap(currentDataBuffer, storageDataBuffer);
|
||||
commitRecordedDataToDB();
|
||||
insertGeneralInfo();
|
||||
insertCommandLengths();
|
||||
PRINTDEBUGMESSAGE(name, "Number of transactions written to DB: "
|
||||
+ std::to_string(totalNumTransactions));
|
||||
PRINTDEBUGMESSAGE(name, "tlmPhaseRecorder:\tEnd Recording");
|
||||
|
||||
@@ -206,8 +206,6 @@ private:
|
||||
"); \n"
|
||||
" \n"
|
||||
"CREATE TABLE GeneralInfo( \n"
|
||||
" NumberOfTransactions INTEGER, \n"
|
||||
" TraceEnd INTEGER, \n"
|
||||
" NumberOfRanks INTEGER, \n"
|
||||
" NumberOfBankgroups INTEGER, \n"
|
||||
" NumberOfBanks INTEGER, \n"
|
||||
|
||||
@@ -272,99 +272,6 @@ unsigned ControllerExtension::getBurstLength(const tlm::tlm_generic_payload& tra
|
||||
return trans.get_extension<ControllerExtension>()->burstLength;
|
||||
}
|
||||
|
||||
//THREAD
|
||||
bool operator ==(const Thread &lhs, const Thread &rhs)
|
||||
{
|
||||
return lhs.ID() == rhs.ID();
|
||||
}
|
||||
|
||||
bool operator !=(const Thread &lhs, const Thread &rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
bool operator <(const Thread &lhs, const Thread &rhs)
|
||||
{
|
||||
return lhs.ID() < rhs.ID();
|
||||
}
|
||||
|
||||
//CHANNEL
|
||||
bool operator ==(const Channel &lhs, const Channel &rhs)
|
||||
{
|
||||
return lhs.ID() == rhs.ID();
|
||||
}
|
||||
|
||||
bool operator !=(const Channel &lhs, const Channel &rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
//RANK
|
||||
bool operator ==(const Rank &lhs, const Rank &rhs)
|
||||
{
|
||||
return lhs.ID() == rhs.ID();
|
||||
}
|
||||
|
||||
bool operator !=(const Rank &lhs, const Rank &rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
//BANKGROUP
|
||||
bool operator ==(const BankGroup &lhs, const BankGroup &rhs)
|
||||
{
|
||||
return lhs.ID() == rhs.ID();
|
||||
}
|
||||
|
||||
bool operator !=(const BankGroup &lhs, const BankGroup &rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
//BANK
|
||||
bool operator ==(const Bank &lhs, const Bank &rhs)
|
||||
{
|
||||
return lhs.ID() == rhs.ID();
|
||||
}
|
||||
|
||||
bool operator !=(const Bank &lhs, const Bank &rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
bool operator <(const Bank &lhs, const Bank &rhs)
|
||||
{
|
||||
return lhs.ID() < rhs.ID();
|
||||
}
|
||||
|
||||
//ROW
|
||||
const Row Row::NO_ROW;
|
||||
|
||||
bool operator ==(const Row &lhs, const Row &rhs)
|
||||
{
|
||||
if (lhs.isNoRow != rhs.isNoRow)
|
||||
return false;
|
||||
return lhs.ID() == rhs.ID();
|
||||
}
|
||||
|
||||
bool operator !=(const Row &lhs, const Row &rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
|
||||
//COLUMN
|
||||
bool operator ==(const Column &lhs, const Column &rhs)
|
||||
{
|
||||
return lhs.ID() == rhs.ID();
|
||||
}
|
||||
|
||||
bool operator !=(const Column &lhs, const Column &rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
|
||||
tlm::tlm_extension_base* ChildExtension::clone() const
|
||||
{
|
||||
return new ChildExtension(*parentTrans);
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#define DRAMEXTENSIONS_H
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include <systemc>
|
||||
#include <tlm>
|
||||
@@ -45,116 +46,36 @@
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
class Thread
|
||||
enum class Thread : std::size_t;
|
||||
enum class Channel : std::size_t;
|
||||
enum class Rank : std::size_t;
|
||||
enum class LogicalRank : std::size_t;
|
||||
enum class PhysicalRank : std::size_t;
|
||||
enum class DimmRank : std::size_t;
|
||||
enum class BankGroup : std::size_t;
|
||||
enum class Bank : std::size_t;
|
||||
enum class Row : std::size_t;
|
||||
enum class Column : std::size_t;
|
||||
|
||||
template<typename IndexType, typename ValueType>
|
||||
class ControllerVector : private std::vector<ValueType>
|
||||
{
|
||||
public:
|
||||
explicit Thread(unsigned int id) : id(id) {}
|
||||
using std::vector<ValueType>::vector;
|
||||
using std::vector<ValueType>::push_back;
|
||||
using std::vector<ValueType>::begin;
|
||||
using std::vector<ValueType>::end;
|
||||
using std::vector<ValueType>::front;
|
||||
|
||||
[[nodiscard]] unsigned int ID() const
|
||||
typename std::vector<ValueType>::const_reference operator[](IndexType index) const
|
||||
{
|
||||
return id;
|
||||
return std::vector<ValueType>::operator[](static_cast<std::size_t>(index));
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int id;
|
||||
};
|
||||
|
||||
class Channel
|
||||
{
|
||||
public:
|
||||
explicit Channel(unsigned int id) : id(id) {}
|
||||
|
||||
[[nodiscard]] unsigned int ID() const
|
||||
typename std::vector<ValueType>::reference operator[](IndexType index)
|
||||
{
|
||||
return id;
|
||||
return std::vector<ValueType>::operator[](static_cast<std::size_t>(index));
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int id;
|
||||
};
|
||||
|
||||
class Rank
|
||||
{
|
||||
public:
|
||||
explicit Rank(unsigned int id) : id(id) {}
|
||||
|
||||
[[nodiscard]] unsigned int ID() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int id;
|
||||
};
|
||||
|
||||
class BankGroup
|
||||
{
|
||||
public:
|
||||
explicit BankGroup(unsigned int id) : id(id) {}
|
||||
|
||||
[[nodiscard]] unsigned int ID() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int id;
|
||||
};
|
||||
|
||||
class Bank
|
||||
{
|
||||
public:
|
||||
explicit Bank(unsigned int id) : id(id) {}
|
||||
|
||||
[[nodiscard]] unsigned int ID() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string toString() const
|
||||
{
|
||||
return std::to_string(id);
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int id;
|
||||
};
|
||||
|
||||
class Row
|
||||
{
|
||||
public:
|
||||
static const Row NO_ROW;
|
||||
|
||||
Row() : id(0), isNoRow(true) {}
|
||||
|
||||
explicit Row(unsigned int id) : id(id), isNoRow(false) {}
|
||||
|
||||
[[nodiscard]] unsigned int ID() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
Row operator++();
|
||||
|
||||
private:
|
||||
unsigned int id;
|
||||
bool isNoRow;
|
||||
|
||||
friend bool operator==(const Row &lhs, const Row &rhs);
|
||||
};
|
||||
|
||||
class Column
|
||||
{
|
||||
public:
|
||||
explicit Column(unsigned int id) : id(id) {}
|
||||
|
||||
[[nodiscard]] unsigned int ID() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int id;
|
||||
};
|
||||
|
||||
class ArbiterExtension : public tlm::tlm_extension<ArbiterExtension>
|
||||
@@ -231,30 +152,6 @@ private:
|
||||
unsigned burstLength;
|
||||
};
|
||||
|
||||
|
||||
bool operator==(const Thread &lhs, const Thread &rhs);
|
||||
bool operator!=(const Thread &lhs, const Thread &rhs);
|
||||
bool operator<(const Thread &lhs, const Thread &rhs);
|
||||
|
||||
bool operator==(const Channel &lhs, const Channel &rhs);
|
||||
bool operator!=(const Channel &lhs, const Channel &rhs);
|
||||
|
||||
bool operator==(const Rank &lhs, const Rank &rhs);
|
||||
bool operator!=(const Rank &lhs, const Rank &rhs);
|
||||
|
||||
bool operator==(const BankGroup &lhs, const BankGroup &rhs);
|
||||
bool operator!=(const BankGroup &lhs, const BankGroup &rhs);
|
||||
|
||||
bool operator==(const Bank &lhs, const Bank &rhs);
|
||||
bool operator!=(const Bank &lhs, const Bank &rhs);
|
||||
bool operator<(const Bank &lhs, const Bank &rhs);
|
||||
|
||||
bool operator==(const Row &lhs, const Row &rhs);
|
||||
bool operator!=(const Row &lhs, const Row &rhs);
|
||||
|
||||
bool operator==(const Column &lhs, const Column &rhs);
|
||||
bool operator!=(const Column &lhs, const Column &rhs);
|
||||
|
||||
class ChildExtension : public tlm::tlm_extension<ChildExtension>
|
||||
{
|
||||
private:
|
||||
|
||||
@@ -86,4 +86,14 @@ void setUpDummy(tlm_generic_payload &payload, uint64_t channelPayloadID, Rank ra
|
||||
ArbiterExtension::setExtension(payload, Thread(UINT_MAX), Channel(0), 0, SC_ZERO_TIME);
|
||||
}
|
||||
|
||||
bool isFullCycle(sc_core::sc_time time, sc_core::sc_time cycleTime)
|
||||
{
|
||||
return alignAtNext(time, cycleTime) == time;
|
||||
}
|
||||
|
||||
sc_time alignAtNext(sc_time time, sc_time alignment)
|
||||
{
|
||||
return std::ceil(time / alignment) * alignment;
|
||||
}
|
||||
|
||||
} // namespace DRAMSys
|
||||
|
||||
@@ -69,6 +69,9 @@ std::string getPhaseName(const tlm::tlm_phase &phase);
|
||||
void setUpDummy(tlm::tlm_generic_payload &payload, uint64_t channelPayloadID,
|
||||
Rank rank = Rank(0), BankGroup bankGroup = BankGroup(0), Bank bank = Bank(0));
|
||||
|
||||
bool isFullCycle(sc_core::sc_time time, sc_core::sc_time cycleTime);
|
||||
sc_core::sc_time alignAtNext(sc_core::sc_time time, sc_core::sc_time alignment);
|
||||
|
||||
} // namespace DRAMSys
|
||||
|
||||
#endif // UTILS_H
|
||||
|
||||
@@ -93,7 +93,7 @@ enum sc_time_unit string2TimeUnit(const std::string &s)
|
||||
}
|
||||
|
||||
void Configuration::loadSimConfig(const DRAMSys::Config::SimConfig &simConfig)
|
||||
{
|
||||
{
|
||||
addressOffset = simConfig.AddressOffset.value_or(addressOffset);
|
||||
checkTLM2Protocol = simConfig.CheckTLM2Protocol.value_or(checkTLM2Protocol);
|
||||
databaseRecording = simConfig.DatabaseRecording.value_or(databaseRecording);
|
||||
|
||||
@@ -44,11 +44,15 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
BankMachine::BankMachine(const Configuration& config, const SchedulerIF& scheduler, Bank bank)
|
||||
: memSpec(*config.memSpec), scheduler(scheduler), bank(bank),
|
||||
bankgroup(BankGroup(bank.ID() / memSpec.banksPerGroup)), rank(Rank(bank.ID() / memSpec.banksPerRank)),
|
||||
BankMachine::BankMachine(const Configuration& config, const SchedulerIF& scheduler, Bank bank) :
|
||||
memSpec(*config.memSpec),
|
||||
scheduler(scheduler),
|
||||
bank(bank),
|
||||
bankgroup(BankGroup(static_cast<std::size_t>(bank) / memSpec.banksPerGroup)),
|
||||
rank(Rank(static_cast<std::size_t>(bank) / memSpec.banksPerRank)),
|
||||
refreshManagement(config.refreshManagement)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
CommandTuple::Type BankMachine::getNextCommand()
|
||||
{
|
||||
|
||||
@@ -72,7 +72,7 @@ protected:
|
||||
tlm::tlm_generic_payload* currentPayload = nullptr;
|
||||
const SchedulerIF& scheduler;
|
||||
Command nextCommand = Command::NOP;
|
||||
Row openRow;
|
||||
Row openRow = Row(0);
|
||||
const Bank bank;
|
||||
const BankGroup bankgroup;
|
||||
const Rank rank;
|
||||
|
||||
@@ -89,8 +89,8 @@ Controller::Controller(const sc_module_name& name, const Configuration& config,
|
||||
{
|
||||
SC_METHOD(controllerMethod);
|
||||
sensitive << beginReqEvent << endRespEvent << controllerEvent << dataResponseEvent;
|
||||
|
||||
ranksNumberOfPayloads = std::vector<unsigned>(memSpec.ranksPerChannel);
|
||||
|
||||
ranksNumberOfPayloads = ControllerVector<Rank, unsigned>(memSpec.ranksPerChannel);
|
||||
|
||||
// reserve buffer for command tuples
|
||||
readyCommands.reserve(memSpec.banksPerChannel);
|
||||
@@ -166,48 +166,49 @@ Controller::Controller(const sc_module_name& name, const Configuration& config,
|
||||
if (config.pagePolicy == Configuration::PagePolicy::Open)
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec.banksPerChannel; bankID++)
|
||||
bankMachines.emplace_back(std::make_unique<BankMachineOpen>
|
||||
bankMachines.push_back(std::make_unique<BankMachineOpen>
|
||||
(config, *scheduler, Bank(bankID)));
|
||||
}
|
||||
else if (config.pagePolicy == Configuration::PagePolicy::OpenAdaptive)
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec.banksPerChannel; bankID++)
|
||||
bankMachines.emplace_back(std::make_unique<BankMachineOpenAdaptive>
|
||||
bankMachines.push_back(std::make_unique<BankMachineOpenAdaptive>
|
||||
(config, *scheduler, Bank(bankID)));
|
||||
}
|
||||
else if (config.pagePolicy == Configuration::PagePolicy::Closed)
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec.banksPerChannel; bankID++)
|
||||
bankMachines.emplace_back(std::make_unique<BankMachineClosed>
|
||||
bankMachines.push_back(std::make_unique<BankMachineClosed>
|
||||
(config, *scheduler, Bank(bankID)));
|
||||
}
|
||||
else if (config.pagePolicy == Configuration::PagePolicy::ClosedAdaptive)
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec.banksPerChannel; bankID++)
|
||||
bankMachines.emplace_back(std::make_unique<BankMachineClosedAdaptive>
|
||||
bankMachines.push_back(std::make_unique<BankMachineClosedAdaptive>
|
||||
(config, *scheduler, Bank(bankID)));
|
||||
}
|
||||
|
||||
bankMachinesOnRank = std::vector<std::vector<BankMachine*>>(memSpec.ranksPerChannel,
|
||||
std::vector<BankMachine*>(memSpec.banksPerRank));
|
||||
bankMachinesOnRank = ControllerVector<Rank, ControllerVector<Bank, BankMachine*>>(memSpec.ranksPerChannel,
|
||||
ControllerVector<Bank, BankMachine*>(memSpec.banksPerRank));
|
||||
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec.banksPerRank; bankID++)
|
||||
bankMachinesOnRank[rankID][bankID] = bankMachines[rankID * memSpec.banksPerRank + bankID].get();
|
||||
bankMachinesOnRank[Rank(rankID)][Bank(bankID)]
|
||||
= bankMachines[Bank(rankID * memSpec.banksPerRank + bankID)].get();
|
||||
}
|
||||
|
||||
// instantiate power-down managers (one per rank)
|
||||
if (config.powerDownPolicy == Configuration::PowerDownPolicy::NoPowerDown)
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||
powerDownManagers.emplace_back(std::make_unique<PowerDownManagerDummy>());
|
||||
powerDownManagers.push_back(std::make_unique<PowerDownManagerDummy>());
|
||||
}
|
||||
else if (config.powerDownPolicy == Configuration::PowerDownPolicy::Staggered)
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||
{
|
||||
powerDownManagers.emplace_back(std::make_unique<PowerDownManagerStaggered>(bankMachinesOnRank[rankID],
|
||||
Rank(rankID), *checker));
|
||||
powerDownManagers.push_back(std::make_unique<PowerDownManagerStaggered>(
|
||||
bankMachinesOnRank[Rank(rankID)], Rank(rankID)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,22 +216,22 @@ Controller::Controller(const sc_module_name& name, const Configuration& config,
|
||||
if (config.refreshPolicy == Configuration::RefreshPolicy::NoRefresh)
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||
refreshManagers.emplace_back(std::make_unique<RefreshManagerDummy>());
|
||||
refreshManagers.push_back(std::make_unique<RefreshManagerDummy>());
|
||||
}
|
||||
else if (config.refreshPolicy == Configuration::RefreshPolicy::AllBank)
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||
{
|
||||
refreshManagers.emplace_back(std::make_unique<RefreshManagerAllBank>
|
||||
(config, bankMachinesOnRank[rankID], *powerDownManagers[rankID].get(), Rank(rankID)));
|
||||
refreshManagers.push_back(std::make_unique<RefreshManagerAllBank>
|
||||
(config, bankMachinesOnRank[Rank(rankID)], *powerDownManagers[Rank(rankID)], Rank(rankID)));
|
||||
}
|
||||
}
|
||||
else if (config.refreshPolicy == Configuration::RefreshPolicy::SameBank)
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||
{
|
||||
refreshManagers.emplace_back(std::make_unique<RefreshManagerSameBank>
|
||||
(config, bankMachinesOnRank[rankID], *powerDownManagers[rankID].get(), Rank(rankID)));
|
||||
refreshManagers.push_back(std::make_unique<RefreshManagerSameBank>
|
||||
(config, bankMachinesOnRank[Rank(rankID)], *powerDownManagers[Rank(rankID)], Rank(rankID)));
|
||||
}
|
||||
}
|
||||
else if (config.refreshPolicy == Configuration::RefreshPolicy::PerBank)
|
||||
@@ -238,8 +239,8 @@ Controller::Controller(const sc_module_name& name, const Configuration& config,
|
||||
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||
{
|
||||
// TODO: remove bankMachines in constructor
|
||||
refreshManagers.emplace_back(std::make_unique<RefreshManagerPerBank>
|
||||
(config, bankMachinesOnRank[rankID], *powerDownManagers[rankID], Rank(rankID)));
|
||||
refreshManagers.push_back(std::make_unique<RefreshManagerPerBank>
|
||||
(config, bankMachinesOnRank[Rank(rankID)], *powerDownManagers[Rank(rankID)], Rank(rankID)));
|
||||
}
|
||||
}
|
||||
else if (config.refreshPolicy == Configuration::RefreshPolicy::Per2Bank)
|
||||
@@ -247,8 +248,8 @@ Controller::Controller(const sc_module_name& name, const Configuration& config,
|
||||
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||
{
|
||||
// TODO: remove bankMachines in constructor
|
||||
refreshManagers.emplace_back(std::make_unique<RefreshManagerPer2Bank>
|
||||
(config, bankMachinesOnRank[rankID], *powerDownManagers[rankID], Rank(rankID)));
|
||||
refreshManagers.push_back(std::make_unique<RefreshManagerPer2Bank>
|
||||
(config, bankMachinesOnRank[Rank(rankID)], *powerDownManagers[Rank(rankID)], Rank(rankID)));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -257,7 +258,7 @@ Controller::Controller(const sc_module_name& name, const Configuration& config,
|
||||
|
||||
void Controller::controllerMethod()
|
||||
{
|
||||
if (isFullCycle(sc_time_stamp()))
|
||||
if (isFullCycle(sc_time_stamp(), memSpec.tCK))
|
||||
{
|
||||
// (1) Finish last response (END_RESP) and start new response (BEGIN_RESP)
|
||||
manageResponses();
|
||||
@@ -280,18 +281,19 @@ void Controller::controllerMethod()
|
||||
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||
{
|
||||
// (4.1) Check for power-down commands (PDEA/PDEP/SREFEN or PDXA/PDXP/SREFEX)
|
||||
commandTuple = powerDownManagers[rankID]->getNextCommand();
|
||||
Rank rank = Rank(rankID);
|
||||
commandTuple = powerDownManagers[rank]->getNextCommand();
|
||||
if (std::get<CommandTuple::Command>(commandTuple) != Command::NOP)
|
||||
readyCommands.emplace_back(commandTuple);
|
||||
else
|
||||
{
|
||||
// (4.2) Check for refresh commands (PREXX or REFXX)
|
||||
commandTuple = refreshManagers[rankID]->getNextCommand();
|
||||
commandTuple = refreshManagers[rank]->getNextCommand();
|
||||
if (std::get<CommandTuple::Command>(commandTuple) != Command::NOP)
|
||||
readyCommands.emplace_back(commandTuple);
|
||||
|
||||
// (4.3) Check for bank commands (PREPB, ACT, RD/RDA or WR/WRA)
|
||||
for (auto *it : bankMachinesOnRank[rankID])
|
||||
for (auto it : bankMachinesOnRank[rank])
|
||||
{
|
||||
commandTuple = it->getNextCommand();
|
||||
if (std::get<CommandTuple::Command>(commandTuple) != Command::NOP)
|
||||
@@ -320,25 +322,25 @@ void Controller::controllerMethod()
|
||||
|
||||
if (command.isRankCommand())
|
||||
{
|
||||
for (auto *it : bankMachinesOnRank[rank.ID()])
|
||||
for (auto it : bankMachinesOnRank[rank])
|
||||
it->update(command);
|
||||
}
|
||||
else if (command.isGroupCommand())
|
||||
{
|
||||
for (unsigned bankID = (bank.ID() % memSpec.banksPerGroup);
|
||||
for (std::size_t bankID = (static_cast<std::size_t>(bank) % memSpec.banksPerGroup);
|
||||
bankID < memSpec.banksPerRank; bankID += memSpec.banksPerGroup)
|
||||
bankMachinesOnRank[rank.ID()][bankID]->update(command);
|
||||
bankMachinesOnRank[rank][Bank(bankID)]->update(command);
|
||||
}
|
||||
else if (command.is2BankCommand())
|
||||
{
|
||||
bankMachines[bank.ID()]->update(command);
|
||||
bankMachines[bank.ID() + memSpec.getPer2BankOffset()]->update(command);
|
||||
bankMachines[bank]->update(command);
|
||||
bankMachines[Bank(static_cast<std::size_t>(bank) + memSpec.getPer2BankOffset())]->update(command);
|
||||
}
|
||||
else // if (isBankCommand(command))
|
||||
bankMachines[bank.ID()]->update(command);
|
||||
bankMachines[bank]->update(command);
|
||||
|
||||
refreshManagers[rank.ID()]->update(command);
|
||||
powerDownManagers[rank.ID()]->update(command);
|
||||
refreshManagers[rank]->update(command);
|
||||
powerDownManagers[rank]->update(command);
|
||||
checker->insert(command, *trans);
|
||||
|
||||
if (command.isCasCommand())
|
||||
@@ -354,10 +356,10 @@ void Controller::controllerMethod()
|
||||
if (triggerTime != scMaxTime)
|
||||
dataResponseEvent.notify(triggerTime - sc_time_stamp());
|
||||
|
||||
ranksNumberOfPayloads[rank.ID()]--; // TODO: move to a different place?
|
||||
ranksNumberOfPayloads[rank]--; // TODO: move to a different place?
|
||||
}
|
||||
if (ranksNumberOfPayloads[rank.ID()] == 0)
|
||||
powerDownManagers[rank.ID()]->triggerEntry();
|
||||
if (ranksNumberOfPayloads[rank] == 0)
|
||||
powerDownManagers[rank]->triggerEntry();
|
||||
|
||||
sc_time fwDelay = thinkDelayFw + phyDelayFw;
|
||||
tlm_phase phase = command.toPhase();
|
||||
@@ -489,13 +491,13 @@ void Controller::manageRequests(const sc_time& delay)
|
||||
transToAcquire.payload->get_data_length() / memSpec.bytesPerBeat);
|
||||
|
||||
Rank rank = Rank(decodedAddress.rank);
|
||||
if (ranksNumberOfPayloads[rank.ID()] == 0)
|
||||
powerDownManagers[rank.ID()]->triggerExit();
|
||||
ranksNumberOfPayloads[rank.ID()]++;
|
||||
if (ranksNumberOfPayloads[rank] == 0)
|
||||
powerDownManagers[rank]->triggerExit();
|
||||
ranksNumberOfPayloads[rank]++;
|
||||
|
||||
scheduler->storeRequest(*transToAcquire.payload);
|
||||
Bank bank = Bank(decodedAddress.bank);
|
||||
bankMachines[bank.ID()]->evaluate();
|
||||
bankMachines[bank]->evaluate();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -505,13 +507,13 @@ void Controller::manageRequests(const sc_time& delay)
|
||||
for (auto* childTrans : childTranses)
|
||||
{
|
||||
Rank rank = ControllerExtension::getRank(*childTrans);
|
||||
if (ranksNumberOfPayloads[rank.ID()] == 0)
|
||||
powerDownManagers[rank.ID()]->triggerExit();
|
||||
ranksNumberOfPayloads[rank.ID()]++;
|
||||
if (ranksNumberOfPayloads[rank] == 0)
|
||||
powerDownManagers[rank]->triggerExit();
|
||||
ranksNumberOfPayloads[rank]++;
|
||||
|
||||
scheduler->storeRequest(*childTrans);
|
||||
Bank bank = ControllerExtension::getBank(*childTrans);
|
||||
bankMachines[bank.ID()]->evaluate();
|
||||
bankMachines[bank]->evaluate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -683,10 +685,4 @@ void Controller::createChildTranses(tlm::tlm_generic_payload& parentTrans)
|
||||
ParentExtension::setExtension(parentTrans, std::move(childTranses));
|
||||
}
|
||||
|
||||
bool Controller::isFullCycle(const sc_core::sc_time& time) const
|
||||
{
|
||||
sc_time alignedAtHalfCycle = std::floor((time * 2 / memSpec.tCK + 0.5)) / 2 * memSpec.tCK;
|
||||
return sc_time::from_value(alignedAtHalfCycle.value() % memSpec.tCK.value()) == SC_ZERO_TIME;
|
||||
}
|
||||
|
||||
} // namespace DRAMSys
|
||||
|
||||
@@ -83,16 +83,16 @@ protected:
|
||||
|
||||
private:
|
||||
unsigned totalNumberOfPayloads = 0;
|
||||
std::vector<unsigned> ranksNumberOfPayloads;
|
||||
ControllerVector<Rank, unsigned> ranksNumberOfPayloads;
|
||||
ReadyCommands readyCommands;
|
||||
|
||||
std::vector<std::unique_ptr<BankMachine>> bankMachines;
|
||||
std::vector<std::vector<BankMachine*>> bankMachinesOnRank;
|
||||
ControllerVector<Bank, std::unique_ptr<BankMachine>> bankMachines;
|
||||
ControllerVector<Rank, ControllerVector<Bank, BankMachine*>> bankMachinesOnRank;
|
||||
std::unique_ptr<CmdMuxIF> cmdMux;
|
||||
std::unique_ptr<CheckerIF> checker;
|
||||
std::unique_ptr<RespQueueIF> respQueue;
|
||||
std::vector<std::unique_ptr<RefreshManagerIF>> refreshManagers;
|
||||
std::vector<std::unique_ptr<PowerDownManagerIF>> powerDownManagers;
|
||||
ControllerVector<Rank, std::unique_ptr<RefreshManagerIF>> refreshManagers;
|
||||
ControllerVector<Rank, std::unique_ptr<PowerDownManagerIF>> powerDownManagers;
|
||||
|
||||
const AddressDecoder& addressDecoder;
|
||||
uint64_t nextChannelPayloadIDToAppend = 1;
|
||||
@@ -106,8 +106,6 @@ private:
|
||||
void manageResponses();
|
||||
void manageRequests(const sc_core::sc_time& delay);
|
||||
|
||||
bool isFullCycle(const sc_core::sc_time& time) const;
|
||||
|
||||
sc_core::sc_event beginReqEvent, endRespEvent, controllerEvent, dataResponseEvent;
|
||||
|
||||
const unsigned minBytesPerBurst;
|
||||
|
||||
@@ -50,13 +50,13 @@ CheckerDDR3::CheckerDDR3(const Configuration& config) :
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerDDR3", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBank = std::vector<ControllerVector<Bank, sc_time>>
|
||||
(Command::numberOfCommands(), ControllerVector<Bank, sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<ControllerVector<Rank, sc_time>>
|
||||
(Command::numberOfCommands(), ControllerVector<Rank, sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommand = std::vector<sc_time>(Command::numberOfCommands(), scMaxTime);
|
||||
lastCommandOnBus = scMaxTime;
|
||||
last4Activates = std::vector<std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
|
||||
tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tRDWR = memSpec->tRL + tBURST + 2 * memSpec->tCK - memSpec->tWL;
|
||||
@@ -81,34 +81,34 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, const tlm_generic
|
||||
{
|
||||
assert(ControllerExtension::getBurstLength(payload) == 8);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP - memSpec->tAL);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD);
|
||||
|
||||
@@ -116,7 +116,7 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, const tlm_generic
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD);
|
||||
|
||||
@@ -124,11 +124,11 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, const tlm_generic
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL);
|
||||
}
|
||||
@@ -136,286 +136,286 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, const tlm_generic
|
||||
{
|
||||
assert(ControllerExtension::getBurstLength(payload) == 8);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL);
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
|
||||
if (last4Activates[rank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
}
|
||||
else if (command == Command::PREPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
}
|
||||
else if (command == Command::PREAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
}
|
||||
else if (command == Command::REFAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
}
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tACTPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, memSpec->tAL + memSpec->tRTP + memSpec->tRP));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRP));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR);
|
||||
}
|
||||
@@ -433,20 +433,20 @@ void CheckerDDR3::insert(Command command, const tlm_generic_payload& payload)
|
||||
Rank rank = ControllerExtension::getRank(payload);
|
||||
Bank bank = ControllerExtension::getBank(payload);
|
||||
|
||||
PRINTDEBUGMESSAGE("CheckerDDR3", "Changing state on bank " + std::to_string(bank.ID())
|
||||
PRINTDEBUGMESSAGE("CheckerDDR3", "Changing state on bank " + std::to_string(static_cast<std::size_t>(bank))
|
||||
+ " command is " + command.toString());
|
||||
|
||||
lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndRank[command][rank] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBank[command][bank] = sc_time_stamp();
|
||||
lastScheduledByCommand[command] = sc_time_stamp();
|
||||
|
||||
lastCommandOnBus = sc_time_stamp();
|
||||
|
||||
if (command == Command::ACT)
|
||||
{
|
||||
if (last4Activates[rank.ID()].size() == 4)
|
||||
last4Activates[rank.ID()].pop();
|
||||
last4Activates[rank.ID()].push(sc_time_stamp());
|
||||
if (last4Activates[rank].size() == 4)
|
||||
last4Activates[rank].pop();
|
||||
last4Activates[rank].push(sc_time_stamp());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,13 +55,13 @@ public:
|
||||
private:
|
||||
const MemSpecDDR3 *memSpec;
|
||||
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<ControllerVector<Rank, sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<sc_core::sc_time> lastScheduledByCommand;
|
||||
sc_core::sc_time lastCommandOnBus;
|
||||
|
||||
// Four activate window
|
||||
std::vector<std::queue<sc_core::sc_time>> last4Activates;
|
||||
ControllerVector<Rank, std::queue<sc_core::sc_time>> last4Activates;
|
||||
|
||||
const sc_core::sc_time scMaxTime = sc_core::sc_max_time();
|
||||
sc_core::sc_time tBURST;
|
||||
|
||||
@@ -50,15 +50,16 @@ CheckerDDR4::CheckerDDR4(const Configuration& config) :
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerDDR4", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->bankGroupsPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBank = std::vector<ControllerVector<Bank, sc_time>>
|
||||
(Command::numberOfCommands(), ControllerVector<Bank, sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<ControllerVector<BankGroup, sc_time>>
|
||||
(Command::numberOfCommands(), ControllerVector<BankGroup,
|
||||
sc_time>(memSpec->bankGroupsPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<ControllerVector<Rank, sc_time>>
|
||||
(Command::numberOfCommands(), ControllerVector<Rank, sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommand = std::vector<sc_time>(Command::numberOfCommands(), scMaxTime);
|
||||
lastCommandOnBus = scMaxTime;
|
||||
last4Activates = std::vector<std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
|
||||
tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tRDWR = memSpec->tRL + tBURST + memSpec->tCK - memSpec->tWL + memSpec->tWPRE;
|
||||
@@ -85,46 +86,46 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, const tlm_generic
|
||||
{
|
||||
assert(ControllerExtension::getBurstLength(payload) == 8);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP - memSpec->tAL);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_L);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_S);
|
||||
|
||||
@@ -132,11 +133,11 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, const tlm_generic
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_L);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_S);
|
||||
|
||||
@@ -144,11 +145,11 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, const tlm_generic
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL);
|
||||
}
|
||||
@@ -156,298 +157,298 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, const tlm_generic
|
||||
{
|
||||
assert(ControllerExtension::getBurstLength(payload) == 8);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL);
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_S);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
|
||||
if (last4Activates[rank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
}
|
||||
else if (command == Command::PREPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
}
|
||||
else if (command == Command::PREAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
}
|
||||
else if (command == Command::REFAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
}
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tACTPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, memSpec->tAL + memSpec->tRTP + memSpec->tRP));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRP));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR);
|
||||
}
|
||||
@@ -466,20 +467,20 @@ void CheckerDDR4::insert(Command command, const tlm_generic_payload& payload)
|
||||
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
|
||||
Bank bank = ControllerExtension::getBank(payload);
|
||||
|
||||
PRINTDEBUGMESSAGE("CheckerDDR4", "Changing state on bank " + std::to_string(bank.ID())
|
||||
PRINTDEBUGMESSAGE("CheckerDDR4", "Changing state on bank " + std::to_string(static_cast<std::size_t>(bank))
|
||||
+ " command is " + command.toString());
|
||||
|
||||
lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBankGroup[command][bankGroup.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBank[command][bank] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBankGroup[command][bankGroup] = sc_time_stamp();
|
||||
lastScheduledByCommandAndRank[command][rank] = sc_time_stamp();
|
||||
lastScheduledByCommand[command] = sc_time_stamp();
|
||||
lastCommandOnBus = sc_time_stamp();
|
||||
|
||||
if (command == Command::ACT)
|
||||
{
|
||||
if (last4Activates[rank.ID()].size() == 4)
|
||||
last4Activates[rank.ID()].pop();
|
||||
last4Activates[rank.ID()].push(sc_time_stamp());
|
||||
if (last4Activates[rank].size() == 4)
|
||||
last4Activates[rank].pop();
|
||||
last4Activates[rank].push(sc_time_stamp());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,14 +57,14 @@ public:
|
||||
private:
|
||||
const MemSpecDDR4 *memSpec;
|
||||
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<ControllerVector<BankGroup, sc_core::sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
std::vector<ControllerVector<Rank, sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<sc_core::sc_time> lastScheduledByCommand;
|
||||
sc_core::sc_time lastCommandOnBus;
|
||||
|
||||
// Four activate window
|
||||
std::vector<std::queue<sc_core::sc_time>> last4Activates;
|
||||
ControllerVector<Rank, std::queue<sc_core::sc_time>> last4Activates;
|
||||
|
||||
const sc_core::sc_time scMaxTime = sc_core::sc_max_time();
|
||||
sc_core::sc_time tBURST;
|
||||
|
||||
@@ -50,18 +50,19 @@ CheckerGDDR5::CheckerGDDR5(const Configuration& config) :
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerGDDR5", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->bankGroupsPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBank = std::vector<ControllerVector<Bank, sc_time>>
|
||||
(Command::numberOfCommands(), ControllerVector<Bank, sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<ControllerVector<BankGroup, sc_time>>
|
||||
(Command::numberOfCommands(),
|
||||
ControllerVector<BankGroup, sc_time>(memSpec->bankGroupsPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<ControllerVector<Rank, sc_time>>
|
||||
(Command::numberOfCommands(), ControllerVector<Rank, sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommand = std::vector<sc_time>(Command::numberOfCommands(), scMaxTime);
|
||||
lastCommandOnBus = scMaxTime;
|
||||
last4Activates = std::vector<std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last32Activates = std::vector<std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last32Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
|
||||
bankwiseRefreshCounter = std::vector<unsigned>(memSpec->ranksPerChannel);
|
||||
bankwiseRefreshCounter = ControllerVector<Rank, unsigned>(memSpec->ranksPerChannel);
|
||||
|
||||
tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tRDSRE = memSpec->tCL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK + memSpec->tWCK2DQO + tBURST;
|
||||
@@ -86,70 +87,70 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, const tlm_generi
|
||||
{
|
||||
assert(ControllerExtension::getBurstLength(payload) == 8);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_L);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_S);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_L);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_S);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tLK);
|
||||
}
|
||||
@@ -157,378 +158,378 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, const tlm_generi
|
||||
{
|
||||
assert(ControllerExtension::getBurstLength(payload) == 8);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tLK);
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
|
||||
if (last4Activates[rank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
|
||||
if (last32Activates[rank.ID()].size() >= 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank.ID()].front() + memSpec->t32AW);
|
||||
if (last32Activates[rank].size() >= 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank].front() + memSpec->t32AW);
|
||||
}
|
||||
else if (command == Command::PREPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
}
|
||||
else if (command == Command::PREAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
}
|
||||
else if (command == Command::REFAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
}
|
||||
else if (command == Command::REFPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (bankwiseRefreshCounter[rank.ID()] == 0)
|
||||
if (bankwiseRefreshCounter[rank] == 0)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
|
||||
if (last4Activates[rank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
|
||||
if (last32Activates[rank.ID()].size() >= 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank.ID()].front() + memSpec->t32AW);
|
||||
if (last32Activates[rank].size() >= 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank].front() + memSpec->t32AW);
|
||||
}
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(memSpec->tRTP + memSpec->tRP, tRDSRE));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
}
|
||||
@@ -548,28 +549,28 @@ void CheckerGDDR5::insert(Command command, const tlm_generic_payload& payload)
|
||||
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
|
||||
Bank bank = ControllerExtension::getBank(payload);
|
||||
|
||||
PRINTDEBUGMESSAGE("CheckerGDDR5", "Changing state on bank " + std::to_string(bank.ID())
|
||||
PRINTDEBUGMESSAGE("CheckerGDDR5", "Changing state on bank " + std::to_string(static_cast<std::size_t>(bank))
|
||||
+ " command is " + command.toString());
|
||||
|
||||
lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBankGroup[command][bankGroup.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBank[command][bank] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBankGroup[command][bankGroup] = sc_time_stamp();
|
||||
lastScheduledByCommandAndRank[command][rank] = sc_time_stamp();
|
||||
lastScheduledByCommand[command] = sc_time_stamp();
|
||||
lastCommandOnBus = sc_time_stamp();
|
||||
|
||||
if (command == Command::ACT || command == Command::REFPB)
|
||||
{
|
||||
if (last4Activates[rank.ID()].size() == 4)
|
||||
last4Activates[rank.ID()].pop();
|
||||
last4Activates[rank.ID()].push(lastCommandOnBus);
|
||||
if (last4Activates[rank].size() == 4)
|
||||
last4Activates[rank].pop();
|
||||
last4Activates[rank].push(lastCommandOnBus);
|
||||
|
||||
if (last32Activates[rank.ID()].size() == 32)
|
||||
last32Activates[rank.ID()].pop();
|
||||
last32Activates[rank.ID()].push(lastCommandOnBus);
|
||||
if (last32Activates[rank].size() == 32)
|
||||
last32Activates[rank].pop();
|
||||
last32Activates[rank].push(lastCommandOnBus);
|
||||
}
|
||||
|
||||
if (command == Command::REFPB)
|
||||
bankwiseRefreshCounter[rank.ID()] = (bankwiseRefreshCounter[rank.ID()] + 1) % memSpec->banksPerRank;
|
||||
bankwiseRefreshCounter[rank] = (bankwiseRefreshCounter[rank] + 1) % memSpec->banksPerRank;
|
||||
}
|
||||
|
||||
} // namespace DRAMSys
|
||||
|
||||
@@ -55,18 +55,18 @@ public:
|
||||
private:
|
||||
const MemSpecGDDR5 *memSpec;
|
||||
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<ControllerVector<BankGroup, sc_core::sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
std::vector<ControllerVector<Rank, sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<sc_core::sc_time> lastScheduledByCommand;
|
||||
|
||||
sc_core::sc_time lastCommandOnBus;
|
||||
|
||||
// 4 and 32 activate window
|
||||
std::vector<std::queue<sc_core::sc_time>> last4Activates;
|
||||
std::vector<std::queue<sc_core::sc_time>> last32Activates;
|
||||
ControllerVector<Rank, std::queue<sc_core::sc_time>> last4Activates;
|
||||
ControllerVector<Rank, std::queue<sc_core::sc_time>> last32Activates;
|
||||
|
||||
std::vector<unsigned> bankwiseRefreshCounter;
|
||||
ControllerVector<Rank, unsigned> bankwiseRefreshCounter;
|
||||
|
||||
const sc_core::sc_time scMaxTime = sc_core::sc_max_time();
|
||||
sc_core::sc_time tBURST;
|
||||
|
||||
@@ -50,18 +50,19 @@ CheckerGDDR5X::CheckerGDDR5X(const Configuration& config) :
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerGDDR5X", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->bankGroupsPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBank = std::vector<ControllerVector<Bank, sc_time>>
|
||||
(Command::numberOfCommands(), ControllerVector<Bank, sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<ControllerVector<BankGroup, sc_time>>
|
||||
(Command::numberOfCommands(),
|
||||
ControllerVector<BankGroup, sc_time>(memSpec->bankGroupsPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<ControllerVector<Rank, sc_time>>
|
||||
(Command::numberOfCommands(), ControllerVector<Rank, sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommand = std::vector<sc_time>(Command::numberOfCommands(), scMaxTime);
|
||||
lastCommandOnBus = scMaxTime;
|
||||
last4Activates = std::vector<std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last32Activates = std::vector<std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last32Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
|
||||
bankwiseRefreshCounter = std::vector<unsigned>(memSpec->ranksPerChannel);
|
||||
bankwiseRefreshCounter = ControllerVector<Rank, unsigned>(memSpec->ranksPerChannel);
|
||||
|
||||
tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tRDSRE = memSpec->tRL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK + memSpec->tWCK2DQO + tBURST;
|
||||
@@ -88,70 +89,70 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
assert(!(memSpec->dataRate == 4) || (burstLength == 8)); // DDR mode (QDR wrt CK)
|
||||
assert(!(memSpec->dataRate == 8) || (burstLength == 16)); // QDR mode (ODR wrt CK)
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_L);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_S);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_L);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_S);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tLK);
|
||||
}
|
||||
@@ -161,378 +162,378 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
assert(!(memSpec->dataRate == 4) || (burstLength == 8)); // DDR mode (QDR wrt CK)
|
||||
assert(!(memSpec->dataRate == 8) || (burstLength == 16)); // QDR mode (ODR wrt CK)
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tLK);
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
|
||||
if (last4Activates[rank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
|
||||
if (last32Activates[rank.ID()].size() >= 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank.ID()].front() + memSpec->t32AW);
|
||||
if (last32Activates[rank].size() >= 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank].front() + memSpec->t32AW);
|
||||
}
|
||||
else if (command == Command::PREPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
}
|
||||
else if (command == Command::PREAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
}
|
||||
else if (command == Command::REFAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
}
|
||||
else if (command == Command::REFPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (bankwiseRefreshCounter[rank.ID()] == 0)
|
||||
if (bankwiseRefreshCounter[rank] == 0)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
|
||||
if (last4Activates[rank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
|
||||
if (last32Activates[rank.ID()].size() >= 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank.ID()].front() + memSpec->t32AW);
|
||||
if (last32Activates[rank].size() >= 32)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last32Activates[rank].front() + memSpec->t32AW);
|
||||
}
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(memSpec->tRTP + memSpec->tRP, tRDSRE));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
}
|
||||
@@ -552,28 +553,28 @@ void CheckerGDDR5X::insert(Command command, const tlm_generic_payload& payload)
|
||||
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
|
||||
Bank bank = ControllerExtension::getBank(payload);
|
||||
|
||||
PRINTDEBUGMESSAGE("CheckerGDDR5X", "Changing state on bank " + std::to_string(bank.ID())
|
||||
PRINTDEBUGMESSAGE("CheckerGDDR5X", "Changing state on bank " + std::to_string(static_cast<std::size_t>(bank))
|
||||
+ " command is " + command.toString());
|
||||
|
||||
lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBankGroup[command][bankGroup.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBank[command][bank] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBankGroup[command][bankGroup] = sc_time_stamp();
|
||||
lastScheduledByCommandAndRank[command][rank] = sc_time_stamp();
|
||||
lastScheduledByCommand[command] = sc_time_stamp();
|
||||
lastCommandOnBus = sc_time_stamp();
|
||||
|
||||
if (command == Command::ACT || command == Command::REFPB)
|
||||
{
|
||||
if (last4Activates[rank.ID()].size() == 4)
|
||||
last4Activates[rank.ID()].pop();
|
||||
last4Activates[rank.ID()].push(lastCommandOnBus);
|
||||
if (last4Activates[rank].size() == 4)
|
||||
last4Activates[rank].pop();
|
||||
last4Activates[rank].push(lastCommandOnBus);
|
||||
|
||||
if (last32Activates[rank.ID()].size() == 32)
|
||||
last32Activates[rank.ID()].pop();
|
||||
last32Activates[rank.ID()].push(lastCommandOnBus);
|
||||
if (last32Activates[rank].size() == 32)
|
||||
last32Activates[rank].pop();
|
||||
last32Activates[rank].push(lastCommandOnBus);
|
||||
}
|
||||
|
||||
if (command == Command::REFPB)
|
||||
bankwiseRefreshCounter[rank.ID()] = (bankwiseRefreshCounter[rank.ID()] + 1) % memSpec->banksPerRank;
|
||||
bankwiseRefreshCounter[rank] = (bankwiseRefreshCounter[rank] + 1) % memSpec->banksPerRank;
|
||||
}
|
||||
|
||||
} // namespace DRAMSys
|
||||
|
||||
@@ -55,18 +55,18 @@ public:
|
||||
private:
|
||||
const MemSpecGDDR5X *memSpec;
|
||||
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<ControllerVector<BankGroup, sc_core::sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
std::vector<ControllerVector<Rank, sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<sc_core::sc_time> lastScheduledByCommand;
|
||||
|
||||
sc_core::sc_time lastCommandOnBus;
|
||||
|
||||
// 4 and 32 activate window
|
||||
std::vector<std::queue<sc_core::sc_time>> last4Activates;
|
||||
std::vector<std::queue<sc_core::sc_time>> last32Activates;
|
||||
ControllerVector<Rank, std::queue<sc_core::sc_time>> last4Activates;
|
||||
ControllerVector<Rank, std::queue<sc_core::sc_time>> last32Activates;
|
||||
|
||||
std::vector<unsigned> bankwiseRefreshCounter;
|
||||
ControllerVector<Rank, unsigned> bankwiseRefreshCounter;
|
||||
|
||||
const sc_core::sc_time scMaxTime = sc_core::sc_max_time();
|
||||
sc_core::sc_time tBURST;
|
||||
|
||||
@@ -50,17 +50,18 @@ CheckerGDDR6::CheckerGDDR6(const Configuration& config) :
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerGDDR6", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->bankGroupsPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBank = std::vector<ControllerVector<Bank, sc_time>>
|
||||
(Command::numberOfCommands(), ControllerVector<Bank, sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<ControllerVector<BankGroup, sc_time>>
|
||||
(Command::numberOfCommands(),
|
||||
ControllerVector<BankGroup, sc_time>(memSpec->bankGroupsPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<ControllerVector<Rank, sc_time>>
|
||||
(Command::numberOfCommands(), ControllerVector<Rank, sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommand = std::vector<sc_time>(Command::numberOfCommands(), scMaxTime);
|
||||
lastCommandOnBus = scMaxTime;
|
||||
last4Activates = std::vector<std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
|
||||
bankwiseRefreshCounter = std::vector<unsigned>(memSpec->ranksPerChannel);
|
||||
bankwiseRefreshCounter = ControllerVector<Rank, unsigned>(memSpec->ranksPerChannel);
|
||||
|
||||
tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tRDSRE = memSpec->tRL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK + memSpec->tWCK2DQO + tBURST;
|
||||
@@ -85,70 +86,70 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, const tlm_generi
|
||||
{
|
||||
assert(ControllerExtension::getBurstLength(payload) == 16);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_L);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_S);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_L);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_S);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tLK);
|
||||
}
|
||||
@@ -156,400 +157,400 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, const tlm_generi
|
||||
{
|
||||
assert(ControllerExtension::getBurstLength(payload) == 16);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tLK);
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
|
||||
if (last4Activates[rank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
}
|
||||
else if (command == Command::PREPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
}
|
||||
else if (command == Command::PREAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
}
|
||||
else if (command == Command::REFAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
}
|
||||
else if (command == Command::REFPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (bankwiseRefreshCounter[rank.ID()] == 0)
|
||||
if (bankwiseRefreshCounter[rank] == 0)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
|
||||
if (last4Activates[rank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
}
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tACTPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPREPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPREPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPREPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDSRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(memSpec->tRTP + memSpec->tRP, tRDSRE));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR);
|
||||
}
|
||||
@@ -569,24 +570,24 @@ void CheckerGDDR6::insert(Command command, const tlm_generic_payload& payload)
|
||||
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
|
||||
Bank bank = ControllerExtension::getBank(payload);
|
||||
|
||||
PRINTDEBUGMESSAGE("CheckerGDDR6", "Changing state on bank " + std::to_string(bank.ID())
|
||||
PRINTDEBUGMESSAGE("CheckerGDDR6", "Changing state on bank " + std::to_string(static_cast<std::size_t>(bank))
|
||||
+ " command is " + command.toString());
|
||||
|
||||
lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBankGroup[command][bankGroup.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBank[command][bank] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBankGroup[command][bankGroup] = sc_time_stamp();
|
||||
lastScheduledByCommandAndRank[command][rank] = sc_time_stamp();
|
||||
lastScheduledByCommand[command] = sc_time_stamp();
|
||||
lastCommandOnBus = sc_time_stamp();
|
||||
|
||||
if (command == Command::ACT || command == Command::REFPB)
|
||||
{
|
||||
if (last4Activates[rank.ID()].size() == 4)
|
||||
last4Activates[rank.ID()].pop();
|
||||
last4Activates[rank.ID()].push(lastCommandOnBus);
|
||||
if (last4Activates[rank].size() == 4)
|
||||
last4Activates[rank].pop();
|
||||
last4Activates[rank].push(lastCommandOnBus);
|
||||
}
|
||||
|
||||
if (command == Command::REFPB)
|
||||
bankwiseRefreshCounter[rank.ID()] = (bankwiseRefreshCounter[rank.ID()] + 1) % memSpec->banksPerRank;
|
||||
bankwiseRefreshCounter[rank] = (bankwiseRefreshCounter[rank] + 1) % memSpec->banksPerRank;
|
||||
}
|
||||
|
||||
} // namespace DRAMSys
|
||||
|
||||
@@ -55,16 +55,16 @@ public:
|
||||
private:
|
||||
const MemSpecGDDR6 *memSpec;
|
||||
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<ControllerVector<BankGroup, sc_core::sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
std::vector<ControllerVector<Rank, sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<sc_core::sc_time> lastScheduledByCommand;
|
||||
sc_core::sc_time lastCommandOnBus;
|
||||
|
||||
// four activate window
|
||||
std::vector<std::queue<sc_core::sc_time>> last4Activates;
|
||||
ControllerVector<Rank, std::queue<sc_core::sc_time>> last4Activates;
|
||||
|
||||
std::vector<unsigned> bankwiseRefreshCounter;
|
||||
ControllerVector<Rank, unsigned> bankwiseRefreshCounter;
|
||||
|
||||
const sc_core::sc_time scMaxTime = sc_core::sc_max_time();
|
||||
sc_core::sc_time tBURST;
|
||||
|
||||
@@ -50,18 +50,19 @@ CheckerHBM2::CheckerHBM2(const Configuration& config) :
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerHBM2", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->bankGroupsPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBank = std::vector<ControllerVector<Bank, sc_time>>
|
||||
(Command::numberOfCommands(), ControllerVector<Bank, sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<ControllerVector<BankGroup, sc_time>>
|
||||
(Command::numberOfCommands(),
|
||||
ControllerVector<BankGroup, sc_time>(memSpec->bankGroupsPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<ControllerVector<Rank, sc_time>>
|
||||
(Command::numberOfCommands(), ControllerVector<Rank, sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommand = std::vector<sc_time>(Command::numberOfCommands(), scMaxTime);
|
||||
lastCommandOnRasBus = scMaxTime;
|
||||
lastCommandOnCasBus = scMaxTime;
|
||||
last4Activates = std::vector<std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
|
||||
bankwiseRefreshCounter = std::vector<unsigned>(memSpec->ranksPerChannel);
|
||||
bankwiseRefreshCounter = ControllerVector<Rank, unsigned>(memSpec->ranksPerChannel);
|
||||
|
||||
tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tRDPDE = memSpec->tRL + memSpec->tPL + tBURST + memSpec->tCK;
|
||||
@@ -78,7 +79,7 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, const tlm_generic
|
||||
Rank rank = ControllerExtension::getRank(payload);
|
||||
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
|
||||
Bank bank = ControllerExtension::getBank(payload);
|
||||
|
||||
|
||||
sc_time lastCommandStart;
|
||||
sc_time earliestTimeToStart = sc_time_stamp();
|
||||
|
||||
@@ -88,54 +89,52 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, const tlm_generic
|
||||
assert(!(memSpec->ranksPerChannel == 1) || (burstLength == 2 || burstLength == 4)); // Legacy mode
|
||||
assert(!(memSpec->ranksPerChannel == 2) || (burstLength == 4)); // Pseudo-channel mode
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXA];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnCasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
{
|
||||
@@ -143,67 +142,65 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, const tlm_generic
|
||||
assert(!(memSpec->ranksPerChannel == 1) || (burstLength == 2 || burstLength == 4)); // Legacy mode
|
||||
assert(!(memSpec->ranksPerChannel == 2) || (burstLength == 4)); // Pseudo-channel mode
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXA];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnCasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->tCK);
|
||||
|
||||
@@ -215,15 +212,15 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, const tlm_generic
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCSB - memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD - memSpec->tCK);
|
||||
|
||||
@@ -231,50 +228,46 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, const tlm_generic
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS - memSpec->tCK);
|
||||
|
||||
if (last4Activates[rank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW - memSpec->tCK);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW - memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::PREPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXA];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::PREAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
@@ -282,31 +275,29 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, const tlm_generic
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCSB);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::REFAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
@@ -314,47 +305,45 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, const tlm_generic
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCSB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::SREFEX];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::REFPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDL + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS + memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
@@ -366,18 +355,18 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, const tlm_generic
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCSB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (bankwiseRefreshCounter[rank.ID()] == 0)
|
||||
if (bankwiseRefreshCounter[rank] == 0)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCSB);
|
||||
else
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
@@ -387,10 +376,8 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, const tlm_generic
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
|
||||
if (last4Activates[rank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
}
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
@@ -413,16 +400,12 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, const tlm_generic
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXA];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDEA];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
@@ -445,16 +428,12 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, const tlm_generic
|
||||
lastCommandStart = lastScheduledByCommand[Command::SREFEX];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDEP];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
@@ -493,16 +472,12 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, const tlm_generic
|
||||
lastCommandStart = lastScheduledByCommand[Command::SREFEX];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommand[Command::SREFEN];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR);
|
||||
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("CheckerHBM2", "Unknown command!");
|
||||
@@ -527,12 +502,12 @@ void CheckerHBM2::insert(Command command, const tlm_generic_payload& payload)
|
||||
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
|
||||
Bank bank = ControllerExtension::getBank(payload);
|
||||
|
||||
PRINTDEBUGMESSAGE("CheckerHBM2", "Changing state on bank " + std::to_string(bank.ID())
|
||||
PRINTDEBUGMESSAGE("CheckerHBM2", "Changing state on bank " + std::to_string(static_cast<std::size_t>(bank))
|
||||
+ " command is " + command.toString());
|
||||
|
||||
lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBankGroup[command][bankGroup.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBank[command][bank] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBankGroup[command][bankGroup] = sc_time_stamp();
|
||||
lastScheduledByCommandAndRank[command][rank] = sc_time_stamp();
|
||||
lastScheduledByCommand[command] = sc_time_stamp();
|
||||
|
||||
if (command.isCasCommand())
|
||||
@@ -544,13 +519,13 @@ void CheckerHBM2::insert(Command command, const tlm_generic_payload& payload)
|
||||
|
||||
if (command == Command::ACT || command == Command::REFPB)
|
||||
{
|
||||
if (last4Activates[rank.ID()].size() == 4)
|
||||
last4Activates[rank.ID()].pop();
|
||||
last4Activates[rank.ID()].push(lastCommandOnRasBus);
|
||||
if (last4Activates[rank].size() == 4)
|
||||
last4Activates[rank].pop();
|
||||
last4Activates[rank].push(lastCommandOnRasBus);
|
||||
}
|
||||
|
||||
if (command == Command::REFPB)
|
||||
bankwiseRefreshCounter[rank.ID()] = (bankwiseRefreshCounter[rank.ID()] + 1) % memSpec->banksPerRank;
|
||||
bankwiseRefreshCounter[rank] = (bankwiseRefreshCounter[rank] + 1) % memSpec->banksPerRank;
|
||||
}
|
||||
|
||||
} // namespace DRAMSys
|
||||
|
||||
@@ -55,17 +55,17 @@ public:
|
||||
private:
|
||||
const MemSpecHBM2 *memSpec;
|
||||
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<ControllerVector<BankGroup, sc_core::sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
std::vector<ControllerVector<Rank, sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<sc_core::sc_time> lastScheduledByCommand;
|
||||
|
||||
sc_core::sc_time lastCommandOnRasBus;
|
||||
sc_core::sc_time lastCommandOnCasBus;
|
||||
|
||||
// Four activate window
|
||||
std::vector<std::queue<sc_core::sc_time>> last4Activates;
|
||||
std::vector<unsigned> bankwiseRefreshCounter;
|
||||
ControllerVector<Rank, std::queue<sc_core::sc_time>> last4Activates;
|
||||
ControllerVector<Rank, unsigned> bankwiseRefreshCounter;
|
||||
|
||||
const sc_core::sc_time scMaxTime = sc_core::sc_max_time();
|
||||
sc_core::sc_time tBURST;
|
||||
|
||||
@@ -50,13 +50,13 @@ CheckerLPDDR4::CheckerLPDDR4(const Configuration& config) :
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerLPDDR4", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBank = std::vector<ControllerVector<Bank, sc_time>>
|
||||
(Command::numberOfCommands(), ControllerVector<Bank, sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<ControllerVector<Rank, sc_time>>
|
||||
(Command::numberOfCommands(), ControllerVector<Rank, sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommand = std::vector<sc_time>(Command::numberOfCommands(), scMaxTime);
|
||||
lastCommandOnBus = scMaxTime;
|
||||
last4Activates = std::vector<std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
|
||||
tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tRDWR = memSpec->tRL + memSpec->tDQSCK + tBURST - memSpec->tWL + memSpec->tWPRE + memSpec->tRPST;
|
||||
@@ -89,50 +89,50 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
assert((burstLength == 16) || (burstLength == 32)); // TODO: BL16/32 OTF
|
||||
assert(burstLength <= memSpec->maxBurstLength);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - tRDPRE);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
}
|
||||
@@ -142,367 +142,367 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
assert((burstLength == 16) || (burstLength == 32));
|
||||
assert(burstLength <= memSpec->maxBurstLength);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDAACT);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAACT);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb - 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab - 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab - 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb - 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD - 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR - 2 * memSpec->tCK);
|
||||
|
||||
if (last4Activates[rank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW - 3 * memSpec->tCK);
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW - 3 * memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::PREPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
}
|
||||
else if (command == Command::PREAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
}
|
||||
else if (command == Command::REFAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb + 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPRE + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
}
|
||||
else if (command == Command::REFPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb + 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD + 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPRE + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
|
||||
if (last4Activates[rank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW - memSpec->tCK);
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW - memSpec->tCK);
|
||||
}
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tACTPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tREFPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tREFPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tREFPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb + 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, tRDPRE + memSpec->tRPpb));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRPpb));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tSR);
|
||||
}
|
||||
@@ -521,20 +521,20 @@ void CheckerLPDDR4::insert(Command command, const tlm_generic_payload& payload)
|
||||
Rank rank = ControllerExtension::getRank(payload);
|
||||
Bank bank = ControllerExtension::getBank(payload);
|
||||
|
||||
PRINTDEBUGMESSAGE("CheckerLPDDR4", "Changing state on bank " + std::to_string(bank.ID())
|
||||
PRINTDEBUGMESSAGE("CheckerLPDDR4", "Changing state on bank " + std::to_string(static_cast<std::size_t>(bank))
|
||||
+ " command is " + command.toString());
|
||||
|
||||
lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBank[command][bank] = sc_time_stamp();
|
||||
lastScheduledByCommandAndRank[command][rank] = sc_time_stamp();
|
||||
lastScheduledByCommand[command] = sc_time_stamp();
|
||||
|
||||
lastCommandOnBus = sc_time_stamp() + memSpec->getCommandLength(command) - memSpec->tCK;
|
||||
|
||||
if (command == Command::ACT || command == Command::REFPB)
|
||||
{
|
||||
if (last4Activates[rank.ID()].size() == 4)
|
||||
last4Activates[rank.ID()].pop();
|
||||
last4Activates[rank.ID()].push(lastCommandOnBus);
|
||||
if (last4Activates[rank].size() == 4)
|
||||
last4Activates[rank].pop();
|
||||
last4Activates[rank].push(lastCommandOnBus);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,13 +55,13 @@ public:
|
||||
private:
|
||||
const MemSpecLPDDR4 *memSpec;
|
||||
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<ControllerVector<Rank, sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<sc_core::sc_time> lastScheduledByCommand;
|
||||
sc_core::sc_time lastCommandOnBus;
|
||||
|
||||
// Four activate window
|
||||
std::vector<std::queue<sc_core::sc_time>> last4Activates;
|
||||
ControllerVector<Rank, std::queue<sc_core::sc_time>> last4Activates;
|
||||
|
||||
const sc_core::sc_time scMaxTime = sc_core::sc_max_time();
|
||||
sc_core::sc_time tBURST;
|
||||
|
||||
@@ -50,13 +50,13 @@ CheckerSTTMRAM::CheckerSTTMRAM(const Configuration& config) :
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerSTTMRAM", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBank = std::vector<ControllerVector<Bank, sc_time>>
|
||||
(Command::numberOfCommands(), ControllerVector<Bank, sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<ControllerVector<Rank, sc_time>>
|
||||
(Command::numberOfCommands(), ControllerVector<Rank, sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommand = std::vector<sc_time>(Command::numberOfCommands(), scMaxTime);
|
||||
lastCommandOnBus = scMaxTime;
|
||||
last4Activates = std::vector<std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
|
||||
tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tRDWR = memSpec->tRL + tBURST + 2 * memSpec->tCK - memSpec->tWL;
|
||||
@@ -81,36 +81,36 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, const tlm_gene
|
||||
{
|
||||
assert(ControllerExtension::getBurstLength(payload) == 8);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ?
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank] ?
|
||||
lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ?
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank] ?
|
||||
lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP - memSpec->tAL);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD);
|
||||
|
||||
@@ -118,7 +118,7 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, const tlm_gene
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD);
|
||||
|
||||
@@ -126,11 +126,11 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, const tlm_gene
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL);
|
||||
}
|
||||
@@ -138,240 +138,240 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, const tlm_gene
|
||||
{
|
||||
assert(ControllerExtension::getBurstLength(payload) == 8);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL);
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
|
||||
if (last4Activates[rank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
}
|
||||
else if (command == Command::PREPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
}
|
||||
else if (command == Command::PREAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
}
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tACTPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, memSpec->tAL + memSpec->tRTP + memSpec->tRP));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRP));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR);
|
||||
}
|
||||
@@ -389,20 +389,20 @@ void CheckerSTTMRAM::insert(Command command, const tlm_generic_payload& payload)
|
||||
Rank rank = ControllerExtension::getRank(payload);
|
||||
Bank bank = ControllerExtension::getBank(payload);
|
||||
|
||||
PRINTDEBUGMESSAGE("CheckerSTTMRAM", "Changing state on bank " + std::to_string(bank.ID())
|
||||
PRINTDEBUGMESSAGE("CheckerSTTMRAM", "Changing state on bank " + std::to_string(static_cast<std::size_t>(bank))
|
||||
+ " command is " + command.toString());
|
||||
|
||||
lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndRank[command][rank] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBank[command][bank] = sc_time_stamp();
|
||||
lastScheduledByCommand[command] = sc_time_stamp();
|
||||
|
||||
lastCommandOnBus = sc_time_stamp();
|
||||
|
||||
if (command == Command::ACT)
|
||||
{
|
||||
if (last4Activates[rank.ID()].size() == 4)
|
||||
last4Activates[rank.ID()].pop();
|
||||
last4Activates[rank.ID()].push(sc_time_stamp());
|
||||
if (last4Activates[rank].size() == 4)
|
||||
last4Activates[rank].pop();
|
||||
last4Activates[rank].push(sc_time_stamp());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,13 +55,13 @@ public:
|
||||
private:
|
||||
const MemSpecSTTMRAM *memSpec;
|
||||
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<ControllerVector<Rank, sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<sc_core::sc_time> lastScheduledByCommand;
|
||||
sc_core::sc_time lastCommandOnBus;
|
||||
|
||||
// Four activate window
|
||||
std::vector<std::queue<sc_core::sc_time>> last4Activates;
|
||||
ControllerVector<Rank, std::queue<sc_core::sc_time>> last4Activates;
|
||||
|
||||
const sc_core::sc_time scMaxTime = sc_core::sc_max_time();
|
||||
sc_core::sc_time tBURST;
|
||||
|
||||
@@ -50,13 +50,13 @@ CheckerWideIO::CheckerWideIO(const Configuration& config) :
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerWideIO", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBank = std::vector<ControllerVector<Bank, sc_time>>
|
||||
(Command::numberOfCommands(), ControllerVector<Bank, sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<ControllerVector<Rank, sc_time>>
|
||||
(Command::numberOfCommands(), ControllerVector<Rank, sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommand = std::vector<sc_time>(Command::numberOfCommands(), scMaxTime);
|
||||
lastCommandOnBus = scMaxTime;
|
||||
last2Activates = std::vector<std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last2Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
|
||||
tBURST = memSpec->defaultBurstLength * memSpec->tCK;
|
||||
tRDWR = memSpec->tRL + tBURST + memSpec->tCK;
|
||||
@@ -83,50 +83,50 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
assert((burstLength == 2) || (burstLength == 4));
|
||||
assert(burstLength <= memSpec->maxBurstLength);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - tBURST);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
}
|
||||
@@ -136,262 +136,262 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, const tlm_gener
|
||||
assert((burstLength == 2) || (burstLength == 4));
|
||||
assert(burstLength <= memSpec->maxBurstLength);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
|
||||
if (last2Activates[rank.ID()].size() >= 2)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last2Activates[rank.ID()].front() + memSpec->tTAW);
|
||||
if (last2Activates[rank].size() >= 2)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last2Activates[rank].front() + memSpec->tTAW);
|
||||
}
|
||||
else if (command == Command::PREPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
}
|
||||
else if (command == Command::PREAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
}
|
||||
else if (command == Command::REFAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
}
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, tBURST + memSpec->tRP));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRP));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR);
|
||||
}
|
||||
@@ -410,19 +410,19 @@ void CheckerWideIO::insert(Command command, const tlm_generic_payload& payload)
|
||||
Rank rank = ControllerExtension::getRank(payload);
|
||||
Bank bank = ControllerExtension::getBank(payload);
|
||||
|
||||
PRINTDEBUGMESSAGE("CheckerWideIO", "Changing state on bank " + std::to_string(bank.ID())
|
||||
PRINTDEBUGMESSAGE("CheckerWideIO", "Changing state on bank " + std::to_string(static_cast<std::size_t>(bank))
|
||||
+ " command is " + command.toString());
|
||||
|
||||
lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBank[command][bank] = sc_time_stamp();
|
||||
lastScheduledByCommandAndRank[command][rank] = sc_time_stamp();
|
||||
lastScheduledByCommand[command] = sc_time_stamp();
|
||||
lastCommandOnBus = sc_time_stamp();
|
||||
|
||||
if (command == Command::ACT)
|
||||
{
|
||||
if (last2Activates[rank.ID()].size() == 2)
|
||||
last2Activates[rank.ID()].pop();
|
||||
last2Activates[rank.ID()].push(sc_time_stamp());
|
||||
if (last2Activates[rank].size() == 2)
|
||||
last2Activates[rank].pop();
|
||||
last2Activates[rank].push(sc_time_stamp());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,13 +55,13 @@ public:
|
||||
private:
|
||||
const MemSpecWideIO *memSpec;
|
||||
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<ControllerVector<Rank, sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<sc_core::sc_time> lastScheduledByCommand;
|
||||
sc_core::sc_time lastCommandOnBus;
|
||||
|
||||
// Four activate window
|
||||
std::vector<std::queue<sc_core::sc_time>> last2Activates;
|
||||
ControllerVector<Rank, std::queue<sc_core::sc_time>> last2Activates;
|
||||
|
||||
const sc_core::sc_time scMaxTime = sc_core::sc_max_time();
|
||||
sc_core::sc_time tBURST;
|
||||
|
||||
@@ -50,13 +50,13 @@ CheckerWideIO2::CheckerWideIO2(const Configuration& config) :
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerWideIO2", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<std::vector<sc_time>>
|
||||
(Command::numberOfCommands(), std::vector<sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBank = std::vector<ControllerVector<Bank, sc_time>>
|
||||
(Command::numberOfCommands(), ControllerVector<Bank, sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<ControllerVector<Rank, sc_time>>
|
||||
(Command::numberOfCommands(), ControllerVector<Rank, sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommand = std::vector<sc_time>(Command::numberOfCommands(), scMaxTime);
|
||||
lastCommandOnBus = scMaxTime;
|
||||
last4Activates = std::vector<std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
|
||||
tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tRDPRE = tBURST + std::max(2 * memSpec->tCK, memSpec->tRTP) - 2 * memSpec->tCK;
|
||||
@@ -84,50 +84,50 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, const tlm_gene
|
||||
assert((burstLength == 4) || (burstLength == 8)); // TODO: BL4/8 OTF
|
||||
assert(burstLength <= memSpec->maxBurstLength);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE - tRDPRE);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRRD_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
}
|
||||
@@ -137,339 +137,339 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, const tlm_gene
|
||||
assert((burstLength == 4) || (burstLength == 8));
|
||||
assert(burstLength <= memSpec->maxBurstLength);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank.ID()] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank] ? lastScheduledByCommand[Command::RD] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank.ID()] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] != lastScheduledByCommandAndRank[Command::RDA][rank] ? lastScheduledByCommand[Command::RDA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDWR_R);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank.ID()] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank] ? lastScheduledByCommand[Command::WR] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank.ID()] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] != lastScheduledByCommandAndRank[Command::WRA][rank] ? lastScheduledByCommand[Command::WRA] : scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPRE + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
|
||||
if (last4Activates[rank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
}
|
||||
else if (command == Command::PREPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
}
|
||||
else if (command == Command::PREAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + 2 * memSpec->tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
}
|
||||
else if(command == Command::REFAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPRE + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
}
|
||||
else if(command == Command::REFPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPRE + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
|
||||
if (last4Activates[rank.ID()].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
}
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tRDPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + tWRAPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, tRDPRE + memSpec->tRPpb));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRPpb));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank.ID()];
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR);
|
||||
}
|
||||
@@ -488,19 +488,19 @@ void CheckerWideIO2::insert(Command command, const tlm_generic_payload& payload)
|
||||
Rank rank = ControllerExtension::getRank(payload);
|
||||
Bank bank = ControllerExtension::getBank(payload);
|
||||
|
||||
PRINTDEBUGMESSAGE("CheckerWideIO2", "Changing state on bank " + std::to_string(bank.ID())
|
||||
PRINTDEBUGMESSAGE("CheckerWideIO2", "Changing state on bank " + std::to_string(static_cast<std::size_t>(bank))
|
||||
+ " command is " + command.toString());
|
||||
|
||||
lastScheduledByCommandAndBank[command][bank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp();
|
||||
lastScheduledByCommandAndBank[command][bank] = sc_time_stamp();
|
||||
lastScheduledByCommandAndRank[command][rank] = sc_time_stamp();
|
||||
lastScheduledByCommand[command] = sc_time_stamp();
|
||||
lastCommandOnBus = sc_time_stamp();
|
||||
|
||||
if (command == Command::ACT || command == Command::REFPB)
|
||||
{
|
||||
if (last4Activates[rank.ID()].size() == 4)
|
||||
last4Activates[rank.ID()].pop();
|
||||
last4Activates[rank.ID()].push(sc_time_stamp());
|
||||
if (last4Activates[rank].size() == 4)
|
||||
last4Activates[rank].pop();
|
||||
last4Activates[rank].push(sc_time_stamp());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,13 +55,13 @@ public:
|
||||
private:
|
||||
const MemSpecWideIO2 *memSpec;
|
||||
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<std::vector<sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<ControllerVector<Rank, sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
std::vector<sc_core::sc_time> lastScheduledByCommand;
|
||||
sc_core::sc_time lastCommandOnBus;
|
||||
|
||||
// Four activate window
|
||||
std::vector<std::queue<sc_core::sc_time>> last4Activates;
|
||||
ControllerVector<Rank, std::queue<sc_core::sc_time>> last4Activates;
|
||||
|
||||
const sc_core::sc_time scMaxTime = sc_core::sc_max_time();
|
||||
sc_core::sc_time tBURST;
|
||||
|
||||
@@ -42,9 +42,9 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
PowerDownManagerStaggered::PowerDownManagerStaggered(std::vector<BankMachine*>& bankMachinesOnRank,
|
||||
Rank rank, [[maybe_unused]] CheckerIF& checker)
|
||||
: bankMachinesOnRank(bankMachinesOnRank)
|
||||
PowerDownManagerStaggered::PowerDownManagerStaggered(
|
||||
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank, Rank rank) :
|
||||
bankMachinesOnRank(bankMachinesOnRank)
|
||||
{
|
||||
setUpDummy(powerDownPayload, UINT64_MAX - 1, rank);
|
||||
}
|
||||
|
||||
@@ -49,8 +49,7 @@ class BankMachine;
|
||||
class PowerDownManagerStaggered final : public PowerDownManagerIF
|
||||
{
|
||||
public:
|
||||
PowerDownManagerStaggered(std::vector<BankMachine*>& bankMachinesOnRank,
|
||||
Rank rank, CheckerIF& checker);
|
||||
PowerDownManagerStaggered(ControllerVector<Bank, BankMachine*>& bankMachinesOnRank, Rank rank);
|
||||
|
||||
void triggerEntry() override;
|
||||
void triggerExit() override;
|
||||
@@ -63,7 +62,7 @@ public:
|
||||
private:
|
||||
enum class State {Idle, ActivePdn, PrechargePdn, SelfRefresh, ExtraRefresh} state = State::Idle;
|
||||
tlm::tlm_generic_payload powerDownPayload;
|
||||
std::vector<BankMachine*>& bankMachinesOnRank;
|
||||
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank;
|
||||
Command nextCommand = Command::NOP;
|
||||
|
||||
bool controllerIdle = true;
|
||||
|
||||
@@ -44,7 +44,8 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
RefreshManagerAllBank::RefreshManagerAllBank(const Configuration& config, std::vector<BankMachine*>& bankMachinesOnRank,
|
||||
RefreshManagerAllBank::RefreshManagerAllBank(const Configuration& config,
|
||||
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager, Rank rank)
|
||||
: memSpec(*config.memSpec), bankMachinesOnRank(bankMachinesOnRank),
|
||||
powerDownManager(powerDownManager), maxPostponed(static_cast<int>(config.refreshMaxPostponed)),
|
||||
|
||||
@@ -53,7 +53,7 @@ class PowerDownManagerIF;
|
||||
class RefreshManagerAllBank final : public RefreshManagerIF
|
||||
{
|
||||
public:
|
||||
RefreshManagerAllBank(const Configuration& config, std::vector<BankMachine*>& bankMachinesOnRank,
|
||||
RefreshManagerAllBank(const Configuration& config, ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager, Rank rank);
|
||||
|
||||
CommandTuple::Type getNextCommand() override;
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
private:
|
||||
enum class State {Regular, Pulledin} state = State::Regular;
|
||||
const MemSpec& memSpec;
|
||||
std::vector<BankMachine*>& bankMachinesOnRank;
|
||||
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank;
|
||||
PowerDownManagerIF& powerDownManager;
|
||||
tlm::tlm_generic_payload refreshPayload;
|
||||
sc_core::sc_time timeForNextTrigger = sc_core::sc_max_time();
|
||||
|
||||
@@ -55,7 +55,7 @@ protected:
|
||||
Rank rank, unsigned numberOfRanks)
|
||||
{
|
||||
// Calculate bit-reversal rank ID
|
||||
unsigned rankID = rank.ID();
|
||||
auto rankID = static_cast<unsigned>(rank);
|
||||
unsigned reverseRankID = 0;
|
||||
unsigned rankBits = 0;
|
||||
unsigned rankShift = numberOfRanks;
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace DRAMSys
|
||||
{
|
||||
|
||||
RefreshManagerPer2Bank::RefreshManagerPer2Bank(const Configuration& config,
|
||||
std::vector<BankMachine*>& bankMachinesOnRank,
|
||||
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager, Rank rank)
|
||||
: memSpec(*config.memSpec), powerDownManager(powerDownManager),
|
||||
maxPostponed(static_cast<int>(config.refreshMaxPostponed * memSpec.banksPerRank / 2)),
|
||||
@@ -58,12 +58,13 @@ RefreshManagerPer2Bank::RefreshManagerPer2Bank(const Configuration& config,
|
||||
{
|
||||
for (unsigned bankID = outerID; bankID < (outerID + memSpec.getPer2BankOffset()); bankID++)
|
||||
{
|
||||
unsigned bankID2 = bankID + memSpec.getPer2BankOffset();
|
||||
setUpDummy(refreshPayloads[bankMachinesOnRank[bankID]], 0, rank,
|
||||
bankMachinesOnRank[bankID]->getBankGroup(), bankMachinesOnRank[bankID]->getBank());
|
||||
setUpDummy(refreshPayloads[bankMachinesOnRank[bankID2]], 0, rank,
|
||||
bankMachinesOnRank[bankID2]->getBankGroup(), bankMachinesOnRank[bankID2]->getBank());
|
||||
allBankMachines.push_back({bankMachinesOnRank[bankID], bankMachinesOnRank[bankID2]});
|
||||
Bank firstBank = Bank(bankID);
|
||||
Bank secondBank = Bank(bankID + memSpec.getPer2BankOffset());
|
||||
setUpDummy(refreshPayloads[bankMachinesOnRank[firstBank]], 0, rank,
|
||||
bankMachinesOnRank[firstBank]->getBankGroup(), bankMachinesOnRank[firstBank]->getBank());
|
||||
setUpDummy(refreshPayloads[bankMachinesOnRank[secondBank]], 0, rank,
|
||||
bankMachinesOnRank[secondBank]->getBankGroup(), bankMachinesOnRank[secondBank]->getBank());
|
||||
allBankMachines.push_back({bankMachinesOnRank[firstBank], bankMachinesOnRank[secondBank]});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ class PowerDownManagerIF;
|
||||
class RefreshManagerPer2Bank final : public RefreshManagerIF
|
||||
{
|
||||
public:
|
||||
RefreshManagerPer2Bank(const Configuration& config, std::vector<BankMachine*>& bankMachinesOnRank,
|
||||
RefreshManagerPer2Bank(const Configuration& config, ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager, Rank rank);
|
||||
|
||||
CommandTuple::Type getNextCommand() override;
|
||||
|
||||
@@ -43,7 +43,8 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
RefreshManagerPerBank::RefreshManagerPerBank(const Configuration& config, std::vector<BankMachine*>& bankMachinesOnRank,
|
||||
RefreshManagerPerBank::RefreshManagerPerBank(const Configuration& config,
|
||||
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager, Rank rank)
|
||||
: memSpec(*config.memSpec), powerDownManager(powerDownManager),
|
||||
maxPostponed(static_cast<int>(config.refreshMaxPostponed * memSpec.banksPerRank)),
|
||||
|
||||
@@ -55,7 +55,7 @@ class PowerDownManagerIF;
|
||||
class RefreshManagerPerBank final : public RefreshManagerIF
|
||||
{
|
||||
public:
|
||||
RefreshManagerPerBank(const Configuration& config, std::vector<BankMachine *>& bankMachinesOnRank,
|
||||
RefreshManagerPerBank(const Configuration& config, ControllerVector<Bank, BankMachine *>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager, Rank rank);
|
||||
|
||||
CommandTuple::Type getNextCommand() override;
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace DRAMSys
|
||||
{
|
||||
|
||||
RefreshManagerSameBank::RefreshManagerSameBank(const Configuration& config,
|
||||
std::vector<BankMachine*>& bankMachinesOnRank,
|
||||
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager, Rank rank)
|
||||
: memSpec(*config.memSpec), powerDownManager(powerDownManager),
|
||||
maxPostponed(static_cast<int>(config.refreshMaxPostponed * memSpec.banksPerGroup)),
|
||||
@@ -59,8 +59,8 @@ RefreshManagerSameBank::RefreshManagerSameBank(const Configuration& config,
|
||||
for (unsigned bankID = 0; bankID < memSpec.banksPerGroup; bankID++)
|
||||
{
|
||||
// rank 0: bank group 0, bank 0 - 3; rank 1: bank group 8, bank 32 - 35
|
||||
setUpDummy(refreshPayloads[bankID], 0, rank, bankMachinesOnRank[bankID]->getBankGroup(),
|
||||
bankMachinesOnRank[bankID]->getBank());
|
||||
setUpDummy(refreshPayloads[bankID], 0, rank, bankMachinesOnRank[Bank(bankID)]->getBankGroup(),
|
||||
bankMachinesOnRank[Bank(bankID)]->getBank());
|
||||
allBankMachines.emplace_back(std::vector<BankMachine *>(memSpec.groupsPerRank));
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ RefreshManagerSameBank::RefreshManagerSameBank(const Configuration& config,
|
||||
for (unsigned bankID = 0; bankID < memSpec.banksPerGroup; bankID++)
|
||||
{
|
||||
for (unsigned groupID = 0; groupID < memSpec.groupsPerRank; groupID++)
|
||||
(*it)[groupID] = bankMachinesOnRank[groupID * memSpec.banksPerGroup + bankID];
|
||||
(*it)[groupID] = bankMachinesOnRank[Bank(groupID * memSpec.banksPerGroup + bankID)];
|
||||
it++;
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ RefreshManagerSameBank::RefreshManagerSameBank(const Configuration& config,
|
||||
CommandTuple::Type RefreshManagerSameBank::getNextCommand()
|
||||
{
|
||||
return {nextCommand,
|
||||
&refreshPayloads[currentIterator->front()->getBank().ID() % memSpec.banksPerGroup],
|
||||
&refreshPayloads[static_cast<std::size_t>(currentIterator->front()->getBank()) % memSpec.banksPerGroup],
|
||||
SC_ZERO_TIME};
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ class PowerDownManagerIF;
|
||||
class RefreshManagerSameBank final : public RefreshManagerIF
|
||||
{
|
||||
public:
|
||||
RefreshManagerSameBank(const Configuration& config, std::vector<BankMachine *>& bankMachinesOnRank,
|
||||
RefreshManagerSameBank(const Configuration& config, ControllerVector<Bank, BankMachine *>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager, Rank rank);
|
||||
|
||||
CommandTuple::Type getNextCommand() override;
|
||||
|
||||
@@ -54,7 +54,7 @@ bool BufferCounterBankwise::hasBufferSpace() const
|
||||
|
||||
void BufferCounterBankwise::storeRequest(const tlm_generic_payload& trans)
|
||||
{
|
||||
lastBankID = ControllerExtension::getBank(trans).ID();
|
||||
lastBankID = static_cast<std::size_t>(ControllerExtension::getBank(trans));
|
||||
numRequestsOnBank[lastBankID]++;
|
||||
if (trans.is_read())
|
||||
numReadRequests++;
|
||||
@@ -64,7 +64,7 @@ void BufferCounterBankwise::storeRequest(const tlm_generic_payload& trans)
|
||||
|
||||
void BufferCounterBankwise::removeRequest(const tlm_generic_payload& trans)
|
||||
{
|
||||
numRequestsOnBank[ControllerExtension::getBank(trans).ID()]--;
|
||||
numRequestsOnBank[static_cast<std::size_t>(ControllerExtension::getBank(trans))]--;
|
||||
if (trans.is_read())
|
||||
numReadRequests--;
|
||||
else
|
||||
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
private:
|
||||
const unsigned requestBufferSize;
|
||||
std::vector<unsigned> numRequestsOnBank;
|
||||
unsigned lastBankID = 0;
|
||||
std::size_t lastBankID = 0;
|
||||
unsigned numReadRequests = 0;
|
||||
unsigned numWriteRequests = 0;
|
||||
};
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace DRAMSys
|
||||
|
||||
SchedulerFifo::SchedulerFifo(const Configuration& config)
|
||||
{
|
||||
buffer = std::vector<std::deque<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
|
||||
buffer = ControllerVector<Bank, std::deque<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
|
||||
|
||||
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
|
||||
bufferCounter = std::make_unique<BufferCounterBankwise>(config.requestBufferSize, config.memSpec->banksPerChannel);
|
||||
@@ -62,29 +62,30 @@ bool SchedulerFifo::hasBufferSpace() const
|
||||
|
||||
void SchedulerFifo::storeRequest(tlm_generic_payload& payload)
|
||||
{
|
||||
buffer[ControllerExtension::getBank(payload).ID()].push_back(&payload);
|
||||
buffer[ControllerExtension::getBank(payload)].push_back(&payload);
|
||||
bufferCounter->storeRequest(payload);
|
||||
}
|
||||
|
||||
void SchedulerFifo::removeRequest(tlm_generic_payload& payload)
|
||||
{
|
||||
buffer[ControllerExtension::getBank(payload).ID()].pop_front();
|
||||
buffer[ControllerExtension::getBank(payload)].pop_front();
|
||||
bufferCounter->removeRequest(payload);
|
||||
}
|
||||
|
||||
tlm_generic_payload* SchedulerFifo::getNextRequest(const BankMachine& bankMachine) const
|
||||
{
|
||||
unsigned bankID = bankMachine.getBank().ID();
|
||||
if (!buffer[bankID].empty())
|
||||
return buffer[bankID].front();
|
||||
Bank bank = bankMachine.getBank();
|
||||
if (!buffer[bank].empty())
|
||||
return buffer[bank].front();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool SchedulerFifo::hasFurtherRowHit(Bank bank, Row row, [[maybe_unused]] tlm_command command) const
|
||||
{
|
||||
if (buffer[bank.ID()].size() >= 2)
|
||||
if (buffer[bank].size() >= 2)
|
||||
{
|
||||
tlm_generic_payload& nextRequest = *buffer[bank.ID()][1];
|
||||
tlm_generic_payload& nextRequest = *buffer[bank][1];
|
||||
if (ControllerExtension::getRow(nextRequest) == row)
|
||||
return true;
|
||||
}
|
||||
@@ -93,7 +94,7 @@ bool SchedulerFifo::hasFurtherRowHit(Bank bank, Row row, [[maybe_unused]] tlm_co
|
||||
|
||||
bool SchedulerFifo::hasFurtherRequest(Bank bank, [[maybe_unused]] tlm_command command) const
|
||||
{
|
||||
return buffer[bank.ID()].size() >= 2;
|
||||
return buffer[bank].size() >= 2;
|
||||
}
|
||||
|
||||
const std::vector<unsigned>& SchedulerFifo::getBufferDepth() const
|
||||
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
[[nodiscard]] const std::vector<unsigned>& getBufferDepth() const override;
|
||||
|
||||
private:
|
||||
std::vector<std::deque<tlm::tlm_generic_payload*>> buffer;
|
||||
ControllerVector<Bank, std::deque<tlm::tlm_generic_payload*>> buffer;
|
||||
std::unique_ptr<BufferCounterIF> bufferCounter;
|
||||
};
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace DRAMSys
|
||||
|
||||
SchedulerFrFcfs::SchedulerFrFcfs(const Configuration& config)
|
||||
{
|
||||
buffer = std::vector<std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
|
||||
buffer = ControllerVector<Bank, std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
|
||||
|
||||
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
|
||||
bufferCounter = std::make_unique<BufferCounterBankwise>(config.requestBufferSize, config.memSpec->banksPerChannel);
|
||||
@@ -62,19 +62,19 @@ bool SchedulerFrFcfs::hasBufferSpace() const
|
||||
|
||||
void SchedulerFrFcfs::storeRequest(tlm_generic_payload& trans)
|
||||
{
|
||||
buffer[ControllerExtension::getBank(trans).ID()].push_back(&trans);
|
||||
buffer[ControllerExtension::getBank(trans)].push_back(&trans);
|
||||
bufferCounter->storeRequest(trans);
|
||||
}
|
||||
|
||||
void SchedulerFrFcfs::removeRequest(tlm_generic_payload& trans)
|
||||
{
|
||||
bufferCounter->removeRequest(trans);
|
||||
unsigned bankID = ControllerExtension::getBank(trans).ID();
|
||||
for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++)
|
||||
Bank bank = ControllerExtension::getBank(trans);
|
||||
for (auto it = buffer[bank].begin(); it != buffer[bank].end(); it++)
|
||||
{
|
||||
if (*it == &trans)
|
||||
{
|
||||
buffer[bankID].erase(it);
|
||||
buffer[bank].erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -82,21 +82,21 @@ void SchedulerFrFcfs::removeRequest(tlm_generic_payload& trans)
|
||||
|
||||
tlm_generic_payload* SchedulerFrFcfs::getNextRequest(const BankMachine& bankMachine) const
|
||||
{
|
||||
unsigned bankID = bankMachine.getBank().ID();
|
||||
if (!buffer[bankID].empty())
|
||||
Bank bank = bankMachine.getBank();
|
||||
if (!buffer[bank].empty())
|
||||
{
|
||||
if (bankMachine.isActivated())
|
||||
{
|
||||
// Search for row hit
|
||||
Row openRow = bankMachine.getOpenRow();
|
||||
for (auto *it : buffer[bankID])
|
||||
for (auto it : buffer[bank])
|
||||
{
|
||||
if (ControllerExtension::getRow(*it) == openRow)
|
||||
return it;
|
||||
}
|
||||
}
|
||||
// No row hit found or bank precharged
|
||||
return buffer[bankID].front();
|
||||
return buffer[bank].front();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -104,7 +104,7 @@ tlm_generic_payload* SchedulerFrFcfs::getNextRequest(const BankMachine& bankMach
|
||||
bool SchedulerFrFcfs::hasFurtherRowHit(Bank bank, Row row, [[maybe_unused]] tlm_command command) const
|
||||
{
|
||||
unsigned rowHitCounter = 0;
|
||||
for (auto *it : buffer[bank.ID()])
|
||||
for (auto it : buffer[bank])
|
||||
{
|
||||
if (ControllerExtension::getRow(*it) == row)
|
||||
{
|
||||
@@ -118,7 +118,7 @@ bool SchedulerFrFcfs::hasFurtherRowHit(Bank bank, Row row, [[maybe_unused]] tlm_
|
||||
|
||||
bool SchedulerFrFcfs::hasFurtherRequest(Bank bank, [[maybe_unused]] tlm_command command) const
|
||||
{
|
||||
return (buffer[bank.ID()].size() >= 2);
|
||||
return (buffer[bank].size() >= 2);
|
||||
}
|
||||
|
||||
const std::vector<unsigned>& SchedulerFrFcfs::getBufferDepth() const
|
||||
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
[[nodiscard]] const std::vector<unsigned>& getBufferDepth() const override;
|
||||
|
||||
private:
|
||||
std::vector<std::list<tlm::tlm_generic_payload*>> buffer;
|
||||
ControllerVector<Bank, std::list<tlm::tlm_generic_payload*>> buffer;
|
||||
std::unique_ptr<BufferCounterIF> bufferCounter;
|
||||
};
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace DRAMSys
|
||||
|
||||
SchedulerFrFcfsGrp::SchedulerFrFcfsGrp(const Configuration& config)
|
||||
{
|
||||
buffer = std::vector<std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
|
||||
buffer = ControllerVector<Bank, std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
|
||||
|
||||
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
|
||||
bufferCounter = std::make_unique<BufferCounterBankwise>(config.requestBufferSize, config.memSpec->banksPerChannel);
|
||||
@@ -62,7 +62,7 @@ bool SchedulerFrFcfsGrp::hasBufferSpace() const
|
||||
|
||||
void SchedulerFrFcfsGrp::storeRequest(tlm_generic_payload& trans)
|
||||
{
|
||||
buffer[ControllerExtension::getBank(trans).ID()].push_back(&trans);
|
||||
buffer[ControllerExtension::getBank(trans)].push_back(&trans);
|
||||
bufferCounter->storeRequest(trans);
|
||||
}
|
||||
|
||||
@@ -70,12 +70,12 @@ void SchedulerFrFcfsGrp::removeRequest(tlm_generic_payload& trans)
|
||||
{
|
||||
bufferCounter->removeRequest(trans);
|
||||
lastCommand = trans.get_command();
|
||||
unsigned bankID = ControllerExtension::getBank(trans).ID();
|
||||
for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++)
|
||||
Bank bank = ControllerExtension::getBank(trans);
|
||||
for (auto it = buffer[bank].begin(); it != buffer[bank].end(); it++)
|
||||
{
|
||||
if (*it == &trans)
|
||||
{
|
||||
buffer[bankID].erase(it);
|
||||
buffer[bank].erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -83,15 +83,15 @@ void SchedulerFrFcfsGrp::removeRequest(tlm_generic_payload& trans)
|
||||
|
||||
tlm_generic_payload* SchedulerFrFcfsGrp::getNextRequest(const BankMachine& bankMachine) const
|
||||
{
|
||||
unsigned bankID = bankMachine.getBank().ID();
|
||||
if (!buffer[bankID].empty())
|
||||
Bank bank = bankMachine.getBank();
|
||||
if (!buffer[bank].empty())
|
||||
{
|
||||
if (bankMachine.isActivated())
|
||||
{
|
||||
// Filter all row hits
|
||||
Row openRow = bankMachine.getOpenRow();
|
||||
std::list<tlm_generic_payload *> rowHits;
|
||||
for (auto *it : buffer[bankID])
|
||||
for (auto *it : buffer[bank])
|
||||
{
|
||||
if (ControllerExtension::getRow(*it) == openRow)
|
||||
rowHits.push_back(it);
|
||||
@@ -121,7 +121,7 @@ tlm_generic_payload* SchedulerFrFcfsGrp::getNextRequest(const BankMachine& bankM
|
||||
}
|
||||
}
|
||||
// No row hit found or bank precharged
|
||||
return buffer[bankID].front();
|
||||
return buffer[bank].front();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -129,7 +129,7 @@ tlm_generic_payload* SchedulerFrFcfsGrp::getNextRequest(const BankMachine& bankM
|
||||
bool SchedulerFrFcfsGrp::hasFurtherRowHit(Bank bank, Row row, [[maybe_unused]] tlm_command command) const
|
||||
{
|
||||
unsigned rowHitCounter = 0;
|
||||
for (auto *it : buffer[bank.ID()])
|
||||
for (auto *it : buffer[bank])
|
||||
{
|
||||
if (ControllerExtension::getRow(*it) == row)
|
||||
{
|
||||
@@ -143,7 +143,7 @@ bool SchedulerFrFcfsGrp::hasFurtherRowHit(Bank bank, Row row, [[maybe_unused]] t
|
||||
|
||||
bool SchedulerFrFcfsGrp::hasFurtherRequest(Bank bank, [[maybe_unused]] tlm_command command) const
|
||||
{
|
||||
return buffer[bank.ID()].size() >= 2;
|
||||
return buffer[bank].size() >= 2;
|
||||
}
|
||||
|
||||
const std::vector<unsigned>& SchedulerFrFcfsGrp::getBufferDepth() const
|
||||
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
[[nodiscard]] const std::vector<unsigned>& getBufferDepth() const override;
|
||||
|
||||
private:
|
||||
std::vector<std::list<tlm::tlm_generic_payload *>> buffer;
|
||||
ControllerVector<Bank, std::list<tlm::tlm_generic_payload *>> buffer;
|
||||
tlm::tlm_command lastCommand = tlm::TLM_READ_COMMAND;
|
||||
std::unique_ptr<BufferCounterIF> bufferCounter;
|
||||
};
|
||||
|
||||
@@ -45,8 +45,8 @@ namespace DRAMSys
|
||||
|
||||
SchedulerGrpFrFcfs::SchedulerGrpFrFcfs(const Configuration& config)
|
||||
{
|
||||
readBuffer = std::vector<std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
|
||||
writeBuffer = std::vector<std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
|
||||
readBuffer = ControllerVector<Bank, std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
|
||||
writeBuffer = ControllerVector<Bank, std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
|
||||
|
||||
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
|
||||
bufferCounter = std::make_unique<BufferCounterBankwise>(config.requestBufferSize, config.memSpec->banksPerChannel);
|
||||
@@ -66,9 +66,9 @@ bool SchedulerGrpFrFcfs::hasBufferSpace() const
|
||||
void SchedulerGrpFrFcfs::storeRequest(tlm_generic_payload& trans)
|
||||
{
|
||||
if (trans.is_read())
|
||||
readBuffer[ControllerExtension::getBank(trans).ID()].push_back(&trans);
|
||||
readBuffer[ControllerExtension::getBank(trans)].push_back(&trans);
|
||||
else
|
||||
writeBuffer[ControllerExtension::getBank(trans).ID()].push_back(&trans);
|
||||
writeBuffer[ControllerExtension::getBank(trans)].push_back(&trans);
|
||||
bufferCounter->storeRequest(trans);
|
||||
}
|
||||
|
||||
@@ -76,84 +76,84 @@ void SchedulerGrpFrFcfs::removeRequest(tlm_generic_payload& trans)
|
||||
{
|
||||
bufferCounter->removeRequest(trans);
|
||||
lastCommand = trans.get_command();
|
||||
unsigned bankID = ControllerExtension::getBank(trans).ID();
|
||||
Bank bank = ControllerExtension::getBank(trans);
|
||||
|
||||
if (trans.is_read())
|
||||
readBuffer[bankID].remove(&trans);
|
||||
readBuffer[bank].remove(&trans);
|
||||
else
|
||||
writeBuffer[bankID].remove(&trans);
|
||||
writeBuffer[bank].remove(&trans);
|
||||
}
|
||||
|
||||
tlm_generic_payload* SchedulerGrpFrFcfs::getNextRequest(const BankMachine& bankMachine) const
|
||||
{
|
||||
// search row hits, search wrd/wr hits
|
||||
// search rd/wr hits, search row hits
|
||||
unsigned bankID = bankMachine.getBank().ID();
|
||||
Bank bank = bankMachine.getBank();
|
||||
|
||||
if (lastCommand == tlm::TLM_READ_COMMAND)
|
||||
{
|
||||
if (!readBuffer[bankID].empty())
|
||||
if (!readBuffer[bank].empty())
|
||||
{
|
||||
if (bankMachine.isActivated())
|
||||
{
|
||||
// Search for read row hit
|
||||
Row openRow = bankMachine.getOpenRow();
|
||||
for (auto *it : readBuffer[bankID])
|
||||
for (auto *it : readBuffer[bank])
|
||||
{
|
||||
if (ControllerExtension::getRow(*it) == openRow)
|
||||
return it;
|
||||
}
|
||||
}
|
||||
// No read row hit found or bank precharged
|
||||
return readBuffer[bankID].front();
|
||||
return readBuffer[bank].front();
|
||||
}
|
||||
if (!writeBuffer[bankID].empty())
|
||||
if (!writeBuffer[bank].empty())
|
||||
{
|
||||
if (bankMachine.isActivated())
|
||||
{
|
||||
// Search for write row hit
|
||||
Row openRow = bankMachine.getOpenRow();
|
||||
for (auto *it : writeBuffer[bankID])
|
||||
for (auto *it : writeBuffer[bank])
|
||||
{
|
||||
if (ControllerExtension::getRow(*it) == openRow)
|
||||
return it;
|
||||
}
|
||||
}
|
||||
// No write row hit found or bank precharged
|
||||
return writeBuffer[bankID].front();
|
||||
return writeBuffer[bank].front();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!writeBuffer[bankID].empty())
|
||||
if (!writeBuffer[bank].empty())
|
||||
{
|
||||
if (bankMachine.isActivated())
|
||||
{
|
||||
// Search for write row hit
|
||||
Row openRow = bankMachine.getOpenRow();
|
||||
for (auto *it : writeBuffer[bankID])
|
||||
for (auto *it : writeBuffer[bank])
|
||||
{
|
||||
if (ControllerExtension::getRow(*it) == openRow)
|
||||
return it;
|
||||
}
|
||||
}
|
||||
// No write row hit found or bank precharged
|
||||
return writeBuffer[bankID].front();
|
||||
return writeBuffer[bank].front();
|
||||
}
|
||||
if (!readBuffer[bankID].empty())
|
||||
if (!readBuffer[bank].empty())
|
||||
{
|
||||
if (bankMachine.isActivated())
|
||||
{
|
||||
// Search for read row hit
|
||||
Row openRow = bankMachine.getOpenRow();
|
||||
for (auto *it : readBuffer[bankID])
|
||||
for (auto *it : readBuffer[bank])
|
||||
{
|
||||
if (ControllerExtension::getRow(*it) == openRow)
|
||||
return it;
|
||||
}
|
||||
}
|
||||
// No read row hit found or bank precharged
|
||||
return readBuffer[bankID].front();
|
||||
return readBuffer[bank].front();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -164,7 +164,7 @@ bool SchedulerGrpFrFcfs::hasFurtherRowHit(Bank bank, Row row, tlm_command comman
|
||||
unsigned rowHitCounter = 0;
|
||||
if (command == tlm::TLM_READ_COMMAND)
|
||||
{
|
||||
for (auto *it : readBuffer[bank.ID()])
|
||||
for (auto *it : readBuffer[bank])
|
||||
{
|
||||
if (ControllerExtension::getRow(*it) == row)
|
||||
{
|
||||
@@ -176,7 +176,7 @@ bool SchedulerGrpFrFcfs::hasFurtherRowHit(Bank bank, Row row, tlm_command comman
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto *it : writeBuffer[bank.ID()])
|
||||
for (auto* it : writeBuffer[bank])
|
||||
{
|
||||
if (ControllerExtension::getRow(*it) == row)
|
||||
{
|
||||
@@ -184,19 +184,20 @@ bool SchedulerGrpFrFcfs::hasFurtherRowHit(Bank bank, Row row, tlm_command comman
|
||||
if (rowHitCounter == 2)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SchedulerGrpFrFcfs::hasFurtherRequest(Bank bank, tlm_command command) const
|
||||
{
|
||||
if (command == tlm::TLM_READ_COMMAND)
|
||||
{
|
||||
return readBuffer[bank.ID()].size() >= 2;
|
||||
return readBuffer[bank].size() >= 2;
|
||||
}
|
||||
|
||||
return writeBuffer[bank.ID()].size() >= 2;
|
||||
|
||||
|
||||
return writeBuffer[bank].size() >= 2;
|
||||
|
||||
}
|
||||
|
||||
const std::vector<unsigned>& SchedulerGrpFrFcfs::getBufferDepth() const
|
||||
|
||||
@@ -61,8 +61,8 @@ public:
|
||||
[[nodiscard]] const std::vector<unsigned>& getBufferDepth() const override;
|
||||
|
||||
private:
|
||||
std::vector<std::list<tlm::tlm_generic_payload*>> readBuffer;
|
||||
std::vector<std::list<tlm::tlm_generic_payload*>> writeBuffer;
|
||||
ControllerVector<Bank, std::list<tlm::tlm_generic_payload*>> readBuffer;
|
||||
ControllerVector<Bank, std::list<tlm::tlm_generic_payload*>> writeBuffer;
|
||||
tlm::tlm_command lastCommand = tlm::TLM_READ_COMMAND;
|
||||
std::unique_ptr<BufferCounterIF> bufferCounter;
|
||||
};
|
||||
|
||||
@@ -46,8 +46,8 @@ namespace DRAMSys
|
||||
SchedulerGrpFrFcfsWm::SchedulerGrpFrFcfsWm(const Configuration& config)
|
||||
: lowWatermark(config.lowWatermark), highWatermark(config.highWatermark)
|
||||
{
|
||||
readBuffer = std::vector<std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
|
||||
writeBuffer = std::vector<std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
|
||||
readBuffer = ControllerVector<Bank, std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
|
||||
writeBuffer = ControllerVector<Bank, std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
|
||||
|
||||
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
|
||||
bufferCounter = std::make_unique<BufferCounterBankwise>(config.requestBufferSize, config.memSpec->banksPerChannel);
|
||||
@@ -70,9 +70,9 @@ bool SchedulerGrpFrFcfsWm::hasBufferSpace() const
|
||||
void SchedulerGrpFrFcfsWm::storeRequest(tlm_generic_payload& trans)
|
||||
{
|
||||
if (trans.is_read())
|
||||
readBuffer[ControllerExtension::getBank(trans).ID()].push_back(&trans);
|
||||
readBuffer[ControllerExtension::getBank(trans)].push_back(&trans);
|
||||
else
|
||||
writeBuffer[ControllerExtension::getBank(trans).ID()].push_back(&trans);
|
||||
writeBuffer[ControllerExtension::getBank(trans)].push_back(&trans);
|
||||
bufferCounter->storeRequest(trans);
|
||||
evaluateWriteMode();
|
||||
}
|
||||
@@ -80,55 +80,56 @@ void SchedulerGrpFrFcfsWm::storeRequest(tlm_generic_payload& trans)
|
||||
void SchedulerGrpFrFcfsWm::removeRequest(tlm_generic_payload& trans)
|
||||
{
|
||||
bufferCounter->removeRequest(trans);
|
||||
unsigned bankID = ControllerExtension::getBank(trans).ID();
|
||||
Bank bank = ControllerExtension::getBank(trans);
|
||||
|
||||
if (trans.is_read())
|
||||
readBuffer[bankID].remove(&trans);
|
||||
readBuffer[bank].remove(&trans);
|
||||
else
|
||||
writeBuffer[bankID].remove(&trans);
|
||||
writeBuffer[bank].remove(&trans);
|
||||
|
||||
evaluateWriteMode();
|
||||
}
|
||||
|
||||
tlm_generic_payload* SchedulerGrpFrFcfsWm::getNextRequest(const BankMachine& bankMachine) const
|
||||
{
|
||||
unsigned bankID = bankMachine.getBank().ID();
|
||||
Bank bank = bankMachine.getBank();
|
||||
|
||||
if (!writeMode)
|
||||
{
|
||||
if (!readBuffer[bankID].empty())
|
||||
if (!readBuffer[bank].empty())
|
||||
{
|
||||
if (bankMachine.isActivated())
|
||||
{
|
||||
// Search for read row hit
|
||||
Row openRow = bankMachine.getOpenRow();
|
||||
for (auto *it : readBuffer[bankID])
|
||||
for (auto *it : readBuffer[bank])
|
||||
{
|
||||
if (ControllerExtension::getRow(*it) == openRow)
|
||||
return it;
|
||||
}
|
||||
}
|
||||
// No read row hit found or bank precharged
|
||||
return readBuffer[bankID].front();
|
||||
return readBuffer[bank].front();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!writeBuffer[bankID].empty())
|
||||
if (!writeBuffer[bank].empty())
|
||||
{
|
||||
if (bankMachine.isActivated())
|
||||
{
|
||||
// Search for write row hit
|
||||
Row openRow = bankMachine.getOpenRow();
|
||||
for (auto *it : writeBuffer[bankID])
|
||||
for (auto it : writeBuffer[bank])
|
||||
{
|
||||
if (ControllerExtension::getRow(*it) == openRow)
|
||||
return it;
|
||||
}
|
||||
}
|
||||
// No row hit found or bank precharged
|
||||
return writeBuffer[bankID].front();
|
||||
return writeBuffer[bank].front();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -137,7 +138,7 @@ bool SchedulerGrpFrFcfsWm::hasFurtherRowHit(Bank bank, Row row, [[maybe_unused]]
|
||||
unsigned rowHitCounter = 0;
|
||||
if (!writeMode)
|
||||
{
|
||||
for (const auto* it : readBuffer[bank.ID()])
|
||||
for (const auto* it : readBuffer[bank])
|
||||
{
|
||||
if (ControllerExtension::getRow(*it) == row)
|
||||
{
|
||||
@@ -149,7 +150,7 @@ bool SchedulerGrpFrFcfsWm::hasFurtherRowHit(Bank bank, Row row, [[maybe_unused]]
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto *it : writeBuffer[bank.ID()])
|
||||
for (auto* it : writeBuffer[bank])
|
||||
{
|
||||
if (ControllerExtension::getRow(*it) == row)
|
||||
{
|
||||
@@ -158,14 +159,18 @@ bool SchedulerGrpFrFcfsWm::hasFurtherRowHit(Bank bank, Row row, [[maybe_unused]]
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SchedulerGrpFrFcfsWm::hasFurtherRequest(Bank bank, [[maybe_unused]] tlm::tlm_command command) const
|
||||
{
|
||||
if (!writeMode)
|
||||
return (readBuffer[bank.ID()].size() >= 2);
|
||||
return (writeBuffer[bank.ID()].size() >= 2);
|
||||
{
|
||||
return (readBuffer[bank].size() >= 2);
|
||||
}
|
||||
|
||||
return (writeBuffer[bank].size() >= 2);
|
||||
}
|
||||
|
||||
const std::vector<unsigned>& SchedulerGrpFrFcfsWm::getBufferDepth() const
|
||||
|
||||
@@ -64,8 +64,8 @@ public:
|
||||
private:
|
||||
void evaluateWriteMode();
|
||||
|
||||
std::vector<std::list<tlm::tlm_generic_payload*>> readBuffer;
|
||||
std::vector<std::list<tlm::tlm_generic_payload*>> writeBuffer;
|
||||
ControllerVector<Bank, std::list<tlm::tlm_generic_payload*>> readBuffer;
|
||||
ControllerVector<Bank, std::list<tlm::tlm_generic_payload*>> writeBuffer;
|
||||
std::unique_ptr<BufferCounterIF> bufferCounter;
|
||||
const unsigned lowWatermark;
|
||||
const unsigned highWatermark;
|
||||
|
||||
@@ -72,8 +72,8 @@ ArbiterSimple::ArbiterSimple(const sc_module_name& name, const Configuration& co
|
||||
|
||||
ArbiterFifo::ArbiterFifo(const sc_module_name& name, const Configuration& config,
|
||||
const AddressDecoder& addressDecoder) :
|
||||
Arbiter(name, config, addressDecoder),
|
||||
maxActiveTransactions(config.maxActiveTransactions) {}
|
||||
Arbiter(name, config, addressDecoder),
|
||||
maxActiveTransactionsPerThread(config.maxActiveTransactions) {}
|
||||
|
||||
ArbiterReorder::ArbiterReorder(const sc_module_name& name, const Configuration& config,
|
||||
const AddressDecoder& addressDecoder) :
|
||||
@@ -83,14 +83,14 @@ ArbiterReorder::ArbiterReorder(const sc_module_name& name, const Configuration&
|
||||
void Arbiter::end_of_elaboration()
|
||||
{
|
||||
// initiator side
|
||||
threadIsBusy = std::vector<bool>(tSocket.size(), false);
|
||||
nextThreadPayloadIDToAppend = std::vector<uint64_t>(tSocket.size(), 1);
|
||||
threadIsBusy = ControllerVector<Thread, bool>(tSocket.size(), false);
|
||||
nextThreadPayloadIDToAppend = ControllerVector<Thread, std::uint64_t>(tSocket.size(), 1);
|
||||
|
||||
// channel side
|
||||
channelIsBusy = std::vector<bool>(iSocket.size(), false);
|
||||
pendingRequests = std::vector<std::queue<tlm_generic_payload*>>(iSocket.size(),
|
||||
std::queue<tlm_generic_payload*>());
|
||||
nextChannelPayloadIDToAppend = std::vector<uint64_t>(iSocket.size(), 1);
|
||||
channelIsBusy = ControllerVector<Channel, bool>(iSocket.size(), false);
|
||||
pendingRequestsOnChannel = ControllerVector<Channel, std::queue<tlm_generic_payload*>>(
|
||||
iSocket.size(), std::queue<tlm_generic_payload*>());
|
||||
nextChannelPayloadIDToAppend = ControllerVector<Channel, std::uint64_t>(iSocket.size(), 1);
|
||||
}
|
||||
|
||||
void ArbiterSimple::end_of_elaboration()
|
||||
@@ -98,8 +98,8 @@ void ArbiterSimple::end_of_elaboration()
|
||||
Arbiter::end_of_elaboration();
|
||||
|
||||
// initiator side
|
||||
pendingResponses = std::vector<std::queue<tlm_generic_payload*>>(tSocket.size(),
|
||||
std::queue<tlm_generic_payload*>());
|
||||
pendingResponsesOnThread = ControllerVector<Thread, std::queue<tlm_generic_payload*>>(
|
||||
tSocket.size(), std::queue<tlm_generic_payload*>());
|
||||
}
|
||||
|
||||
void ArbiterFifo::end_of_elaboration()
|
||||
@@ -107,13 +107,13 @@ void ArbiterFifo::end_of_elaboration()
|
||||
Arbiter::end_of_elaboration();
|
||||
|
||||
// initiator side
|
||||
activeTransactions = std::vector<unsigned int>(tSocket.size(), 0);
|
||||
outstandingEndReq = std::vector<tlm_generic_payload*>(tSocket.size(), nullptr);
|
||||
pendingResponses = std::vector<std::queue<tlm_generic_payload*>>(tSocket.size(),
|
||||
std::queue<tlm_generic_payload*>());
|
||||
activeTransactionsOnThread = ControllerVector<Thread, unsigned int>(tSocket.size(), 0);
|
||||
outstandingEndReqOnThread = ControllerVector<Thread, tlm_generic_payload*>(tSocket.size(), nullptr);
|
||||
pendingResponsesOnThread = ControllerVector<Thread, std::queue<tlm_generic_payload*>>(
|
||||
tSocket.size(), std::queue<tlm_generic_payload*>());
|
||||
|
||||
lastEndReq = std::vector<sc_time>(iSocket.size(), sc_max_time());
|
||||
lastEndResp = std::vector<sc_time>(tSocket.size(), sc_max_time());
|
||||
lastEndReqOnChannel = ControllerVector<Channel, sc_time>(iSocket.size(), sc_max_time());
|
||||
lastEndRespOnThread = ControllerVector<Thread, sc_time>(tSocket.size(), sc_max_time());
|
||||
}
|
||||
|
||||
void ArbiterReorder::end_of_elaboration()
|
||||
@@ -121,14 +121,14 @@ void ArbiterReorder::end_of_elaboration()
|
||||
Arbiter::end_of_elaboration();
|
||||
|
||||
// initiator side
|
||||
activeTransactions = std::vector<unsigned int>(tSocket.size(), 0);
|
||||
outstandingEndReq = std::vector<tlm_generic_payload*>(tSocket.size(), nullptr);
|
||||
pendingResponses = std::vector<std::set<tlm_generic_payload*, ThreadPayloadIDCompare>>
|
||||
activeTransactionsOnThread = ControllerVector<Thread, unsigned int>(tSocket.size(), 0);
|
||||
outstandingEndReqOnThread = ControllerVector<Thread, tlm_generic_payload*>(tSocket.size(), nullptr);
|
||||
pendingResponsesOnThread = ControllerVector<Thread, std::set<tlm_generic_payload*, ThreadPayloadIDCompare>>
|
||||
(tSocket.size(), std::set<tlm_generic_payload*, ThreadPayloadIDCompare>());
|
||||
nextThreadPayloadIDToReturn = std::vector<uint64_t>(tSocket.size(), 1);
|
||||
nextThreadPayloadIDToReturn = ControllerVector<Thread, std::uint64_t>(tSocket.size(), 1);
|
||||
|
||||
lastEndReq = std::vector<sc_time>(iSocket.size(), sc_max_time());
|
||||
lastEndResp = std::vector<sc_time>(tSocket.size(), sc_max_time());
|
||||
lastEndReqOnChannel = ControllerVector<Channel, sc_time>(iSocket.size(), sc_max_time());
|
||||
lastEndRespOnThread = ControllerVector<Thread, sc_time>(tSocket.size(), sc_max_time());
|
||||
}
|
||||
|
||||
tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload& trans,
|
||||
@@ -183,24 +183,24 @@ unsigned int Arbiter::transport_dbg([[maybe_unused]] int id, tlm::tlm_generic_pa
|
||||
|
||||
void ArbiterSimple::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase& cbPhase)
|
||||
{
|
||||
unsigned int threadId = ArbiterExtension::getThread(cbTrans).ID();
|
||||
unsigned int channelId = ArbiterExtension::getChannel(cbTrans).ID();
|
||||
Thread thread = ArbiterExtension::getThread(cbTrans);
|
||||
Channel channel = ArbiterExtension::getChannel(cbTrans);
|
||||
|
||||
if (cbPhase == BEGIN_REQ) // from initiator
|
||||
{
|
||||
ArbiterExtension::setIDAndTimeOfGeneration(cbTrans, nextThreadPayloadIDToAppend[threadId]++, sc_time_stamp());
|
||||
ArbiterExtension::setIDAndTimeOfGeneration(cbTrans, nextThreadPayloadIDToAppend[thread]++, sc_time_stamp());
|
||||
|
||||
if (!channelIsBusy[channelId])
|
||||
if (!channelIsBusy[channel])
|
||||
{
|
||||
channelIsBusy[channelId] = true;
|
||||
channelIsBusy[channel] = true;
|
||||
|
||||
tlm_phase tPhase = BEGIN_REQ;
|
||||
sc_time tDelay = arbitrationDelayFw;
|
||||
|
||||
iSocket[static_cast<int>(channelId)]->nb_transport_fw(cbTrans, tPhase, tDelay);
|
||||
iSocket[static_cast<int>(channel)]->nb_transport_fw(cbTrans, tPhase, tDelay);
|
||||
}
|
||||
else
|
||||
pendingRequests[channelId].push(&cbTrans);
|
||||
pendingRequestsOnChannel[channel].push(&cbTrans);
|
||||
}
|
||||
else if (cbPhase == END_REQ) // from target
|
||||
{
|
||||
@@ -208,37 +208,37 @@ void ArbiterSimple::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase& c
|
||||
tlm_phase tPhase = END_REQ;
|
||||
sc_time tDelay = SC_ZERO_TIME;
|
||||
|
||||
tSocket[static_cast<int>(threadId)]->nb_transport_bw(cbTrans, tPhase, tDelay);
|
||||
tSocket[static_cast<int>(thread)]->nb_transport_bw(cbTrans, tPhase, tDelay);
|
||||
}
|
||||
|
||||
if (!pendingRequests[channelId].empty())
|
||||
if (!pendingRequestsOnChannel[channel].empty())
|
||||
{
|
||||
tlm_generic_payload &tPayload = *pendingRequests[channelId].front();
|
||||
pendingRequests[channelId].pop();
|
||||
tlm_generic_payload &tPayload = *pendingRequestsOnChannel[channel].front();
|
||||
pendingRequestsOnChannel[channel].pop();
|
||||
tlm_phase tPhase = BEGIN_REQ;
|
||||
// do not send two requests in the same cycle
|
||||
sc_time tDelay = tCK + arbitrationDelayFw;
|
||||
|
||||
iSocket[static_cast<int>(channelId)]->nb_transport_fw(tPayload, tPhase, tDelay);
|
||||
iSocket[static_cast<int>(channel)]->nb_transport_fw(tPayload, tPhase, tDelay);
|
||||
}
|
||||
else
|
||||
channelIsBusy[channelId] = false;
|
||||
channelIsBusy[channel] = false;
|
||||
}
|
||||
else if (cbPhase == BEGIN_RESP) // from memory controller
|
||||
{
|
||||
if (!threadIsBusy[threadId])
|
||||
if (!threadIsBusy[thread])
|
||||
{
|
||||
tlm_phase tPhase = BEGIN_RESP;
|
||||
sc_time tDelay = arbitrationDelayBw;
|
||||
|
||||
tlm_sync_enum returnValue = tSocket[static_cast<int>(threadId)]->nb_transport_bw(cbTrans, tPhase, tDelay);
|
||||
tlm_sync_enum returnValue = tSocket[static_cast<int>(thread)]->nb_transport_bw(cbTrans, tPhase, tDelay);
|
||||
// Early completion from initiator
|
||||
if (returnValue == TLM_UPDATED)
|
||||
payloadEventQueue.notify(cbTrans, tPhase, tDelay);
|
||||
threadIsBusy[threadId] = true;
|
||||
threadIsBusy[thread] = true;
|
||||
}
|
||||
else
|
||||
pendingResponses[threadId].push(&cbTrans);
|
||||
pendingResponsesOnThread[thread].push(&cbTrans);
|
||||
}
|
||||
else if (cbPhase == END_RESP) // from initiator
|
||||
{
|
||||
@@ -246,25 +246,25 @@ void ArbiterSimple::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase& c
|
||||
tlm_phase tPhase = END_RESP;
|
||||
sc_time tDelay = SC_ZERO_TIME;
|
||||
|
||||
iSocket[static_cast<int>(channelId)]->nb_transport_fw(cbTrans, tPhase, tDelay);
|
||||
iSocket[static_cast<int>(channel)]->nb_transport_fw(cbTrans, tPhase, tDelay);
|
||||
}
|
||||
cbTrans.release();
|
||||
|
||||
if (!pendingResponses[threadId].empty())
|
||||
if (!pendingResponsesOnThread[thread].empty())
|
||||
{
|
||||
tlm_generic_payload &tPayload = *pendingResponses[threadId].front();
|
||||
pendingResponses[threadId].pop();
|
||||
tlm_generic_payload &tPayload = *pendingResponsesOnThread[thread].front();
|
||||
pendingResponsesOnThread[thread].pop();
|
||||
tlm_phase tPhase = BEGIN_RESP;
|
||||
// do not send two responses in the same cycle
|
||||
sc_time tDelay = tCK + arbitrationDelayBw;
|
||||
|
||||
tlm_sync_enum returnValue = tSocket[static_cast<int>(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay);
|
||||
tlm_sync_enum returnValue = tSocket[static_cast<int>(thread)]->nb_transport_bw(tPayload, tPhase, tDelay);
|
||||
// Early completion from initiator
|
||||
if (returnValue == TLM_UPDATED)
|
||||
payloadEventQueue.notify(tPayload, tPhase, tDelay);
|
||||
}
|
||||
else
|
||||
threadIsBusy[threadId] = false;
|
||||
threadIsBusy[thread] = false;
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL(0, "Payload event queue in arbiter was triggered with unknown phase");
|
||||
@@ -272,43 +272,43 @@ void ArbiterSimple::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase& c
|
||||
|
||||
void ArbiterFifo::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase& cbPhase)
|
||||
{
|
||||
unsigned int threadId = ArbiterExtension::getThread(cbTrans).ID();
|
||||
unsigned int channelId = ArbiterExtension::getChannel(cbTrans).ID();
|
||||
Thread thread = ArbiterExtension::getThread(cbTrans);
|
||||
Channel channel = ArbiterExtension::getChannel(cbTrans);
|
||||
|
||||
if (cbPhase == BEGIN_REQ) // from initiator
|
||||
{
|
||||
if (activeTransactions[threadId] < maxActiveTransactions)
|
||||
if (activeTransactionsOnThread[thread] < maxActiveTransactionsPerThread)
|
||||
{
|
||||
activeTransactions[threadId]++;
|
||||
activeTransactionsOnThread[thread]++;
|
||||
|
||||
ArbiterExtension::setIDAndTimeOfGeneration(cbTrans, nextThreadPayloadIDToAppend[threadId]++,
|
||||
ArbiterExtension::setIDAndTimeOfGeneration(cbTrans, nextThreadPayloadIDToAppend[thread]++,
|
||||
sc_time_stamp());
|
||||
|
||||
tlm_phase tPhase = END_REQ;
|
||||
sc_time tDelay = SC_ZERO_TIME;
|
||||
|
||||
tSocket[static_cast<int>(threadId)]->nb_transport_bw(cbTrans, tPhase, tDelay);
|
||||
tSocket[static_cast<int>(thread)]->nb_transport_bw(cbTrans, tPhase, tDelay);
|
||||
|
||||
payloadEventQueue.notify(cbTrans, REQ_ARBITRATION, arbitrationDelayFw);
|
||||
}
|
||||
else
|
||||
outstandingEndReq[threadId] = &cbTrans;
|
||||
outstandingEndReqOnThread[thread] = &cbTrans;
|
||||
}
|
||||
else if (cbPhase == END_REQ) // from memory controller
|
||||
{
|
||||
lastEndReq[channelId] = sc_time_stamp();
|
||||
lastEndReqOnChannel[channel] = sc_time_stamp();
|
||||
|
||||
if (!pendingRequests[channelId].empty())
|
||||
if (!pendingRequestsOnChannel[channel].empty())
|
||||
{
|
||||
tlm_generic_payload &tPayload = *pendingRequests[channelId].front();
|
||||
pendingRequests[channelId].pop();
|
||||
tlm_generic_payload &tPayload = *pendingRequestsOnChannel[channel].front();
|
||||
pendingRequestsOnChannel[channel].pop();
|
||||
tlm_phase tPhase = BEGIN_REQ;
|
||||
sc_time tDelay = tCK;
|
||||
|
||||
iSocket[static_cast<int>(channelId)]->nb_transport_fw(tPayload, tPhase, tDelay);
|
||||
iSocket[static_cast<int>(channel)]->nb_transport_fw(tPayload, tPhase, tDelay);
|
||||
}
|
||||
else
|
||||
channelIsBusy[channelId] = false;
|
||||
channelIsBusy[channel] = false;
|
||||
}
|
||||
else if (cbPhase == BEGIN_RESP) // from memory controller
|
||||
{
|
||||
@@ -317,78 +317,78 @@ void ArbiterFifo::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase& cbP
|
||||
tlm_phase tPhase = END_RESP;
|
||||
sc_time tDelay = SC_ZERO_TIME;
|
||||
|
||||
iSocket[static_cast<int>(channelId)]->nb_transport_fw(cbTrans, tPhase, tDelay);
|
||||
iSocket[static_cast<int>(channel)]->nb_transport_fw(cbTrans, tPhase, tDelay);
|
||||
}
|
||||
|
||||
payloadEventQueue.notify(cbTrans, RESP_ARBITRATION, arbitrationDelayBw);
|
||||
}
|
||||
else if (cbPhase == END_RESP) // from initiator
|
||||
{
|
||||
lastEndResp[threadId] = sc_time_stamp();
|
||||
lastEndRespOnThread[thread] = sc_time_stamp();
|
||||
cbTrans.release();
|
||||
|
||||
if (outstandingEndReq[threadId] != nullptr)
|
||||
if (outstandingEndReqOnThread[thread] != nullptr)
|
||||
{
|
||||
tlm_generic_payload &tPayload = *outstandingEndReq[threadId];
|
||||
outstandingEndReq[threadId] = nullptr;
|
||||
tlm_generic_payload &tPayload = *outstandingEndReqOnThread[thread];
|
||||
outstandingEndReqOnThread[thread] = nullptr;
|
||||
tlm_phase tPhase = END_REQ;
|
||||
sc_time tDelay = SC_ZERO_TIME;
|
||||
|
||||
ArbiterExtension::setIDAndTimeOfGeneration(tPayload, nextThreadPayloadIDToAppend[threadId]++,
|
||||
ArbiterExtension::setIDAndTimeOfGeneration(tPayload, nextThreadPayloadIDToAppend[thread]++,
|
||||
sc_time_stamp());
|
||||
|
||||
tSocket[static_cast<int>(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay);
|
||||
tSocket[static_cast<int>(thread)]->nb_transport_bw(tPayload, tPhase, tDelay);
|
||||
|
||||
payloadEventQueue.notify(tPayload, REQ_ARBITRATION, arbitrationDelayFw);
|
||||
}
|
||||
else
|
||||
activeTransactions[threadId]--;
|
||||
activeTransactionsOnThread[thread]--;
|
||||
|
||||
if (!pendingResponses[threadId].empty())
|
||||
if (!pendingResponsesOnThread[thread].empty())
|
||||
{
|
||||
tlm_generic_payload &tPayload = *pendingResponses[threadId].front();
|
||||
pendingResponses[threadId].pop();
|
||||
tlm_generic_payload &tPayload = *pendingResponsesOnThread[thread].front();
|
||||
pendingResponsesOnThread[thread].pop();
|
||||
tlm_phase tPhase = BEGIN_RESP;
|
||||
sc_time tDelay = tCK;
|
||||
|
||||
tlm_sync_enum returnValue = tSocket[static_cast<int>(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay);
|
||||
tlm_sync_enum returnValue = tSocket[static_cast<int>(thread)]->nb_transport_bw(tPayload, tPhase, tDelay);
|
||||
// Early completion from initiator
|
||||
if (returnValue == TLM_UPDATED)
|
||||
payloadEventQueue.notify(tPayload, tPhase, tDelay);
|
||||
}
|
||||
else
|
||||
threadIsBusy[threadId] = false;
|
||||
threadIsBusy[thread] = false;
|
||||
}
|
||||
else if (cbPhase == REQ_ARBITRATION)
|
||||
{
|
||||
pendingRequests[channelId].push(&cbTrans);
|
||||
pendingRequestsOnChannel[channel].push(&cbTrans);
|
||||
|
||||
if (!channelIsBusy[channelId])
|
||||
if (!channelIsBusy[channel])
|
||||
{
|
||||
channelIsBusy[channelId] = true;
|
||||
channelIsBusy[channel] = true;
|
||||
|
||||
tlm_generic_payload &tPayload = *pendingRequests[channelId].front();
|
||||
pendingRequests[channelId].pop();
|
||||
tlm_generic_payload &tPayload = *pendingRequestsOnChannel[channel].front();
|
||||
pendingRequestsOnChannel[channel].pop();
|
||||
tlm_phase tPhase = BEGIN_REQ;
|
||||
sc_time tDelay = lastEndReq[channelId] == sc_time_stamp() ? tCK : SC_ZERO_TIME;
|
||||
sc_time tDelay = lastEndReqOnChannel[channel] == sc_time_stamp() ? tCK : SC_ZERO_TIME;
|
||||
|
||||
iSocket[static_cast<int>(channelId)]->nb_transport_fw(tPayload, tPhase, tDelay);
|
||||
iSocket[static_cast<int>(channel)]->nb_transport_fw(tPayload, tPhase, tDelay);
|
||||
}
|
||||
}
|
||||
else if (cbPhase == RESP_ARBITRATION)
|
||||
{
|
||||
pendingResponses[threadId].push(&cbTrans);
|
||||
pendingResponsesOnThread[thread].push(&cbTrans);
|
||||
|
||||
if (!threadIsBusy[threadId])
|
||||
if (!threadIsBusy[thread])
|
||||
{
|
||||
threadIsBusy[threadId] = true;
|
||||
threadIsBusy[thread] = true;
|
||||
|
||||
tlm_generic_payload &tPayload = *pendingResponses[threadId].front();
|
||||
pendingResponses[threadId].pop();
|
||||
tlm_generic_payload &tPayload = *pendingResponsesOnThread[thread].front();
|
||||
pendingResponsesOnThread[thread].pop();
|
||||
tlm_phase tPhase = BEGIN_RESP;
|
||||
sc_time tDelay = lastEndResp[threadId] == sc_time_stamp() ? tCK : SC_ZERO_TIME;
|
||||
sc_time tDelay = lastEndRespOnThread[thread] == sc_time_stamp() ? tCK : SC_ZERO_TIME;
|
||||
|
||||
tlm_sync_enum returnValue = tSocket[static_cast<int>(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay);
|
||||
tlm_sync_enum returnValue = tSocket[static_cast<int>(thread)]->nb_transport_bw(tPayload, tPhase, tDelay);
|
||||
// Early completion from initiator
|
||||
if (returnValue == TLM_UPDATED)
|
||||
payloadEventQueue.notify(tPayload, tPhase, tDelay);
|
||||
@@ -400,43 +400,43 @@ void ArbiterFifo::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase& cbP
|
||||
|
||||
void ArbiterReorder::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase& cbPhase)
|
||||
{
|
||||
unsigned int threadId = ArbiterExtension::getThread(cbTrans).ID();
|
||||
unsigned int channelId = ArbiterExtension::getChannel(cbTrans).ID();
|
||||
Thread thread = ArbiterExtension::getThread(cbTrans);
|
||||
Channel channel = ArbiterExtension::getChannel(cbTrans);
|
||||
|
||||
if (cbPhase == BEGIN_REQ) // from initiator
|
||||
{
|
||||
if (activeTransactions[threadId] < maxActiveTransactions)
|
||||
if (activeTransactionsOnThread[thread] < maxActiveTransactions)
|
||||
{
|
||||
activeTransactions[threadId]++;
|
||||
activeTransactionsOnThread[thread]++;
|
||||
|
||||
ArbiterExtension::setIDAndTimeOfGeneration(cbTrans, nextThreadPayloadIDToAppend[threadId]++,
|
||||
ArbiterExtension::setIDAndTimeOfGeneration(cbTrans, nextThreadPayloadIDToAppend[thread]++,
|
||||
sc_time_stamp());
|
||||
|
||||
tlm_phase tPhase = END_REQ;
|
||||
sc_time tDelay = SC_ZERO_TIME;
|
||||
|
||||
tSocket[static_cast<int>(threadId)]->nb_transport_bw(cbTrans, tPhase, tDelay);
|
||||
tSocket[static_cast<int>(thread)]->nb_transport_bw(cbTrans, tPhase, tDelay);
|
||||
|
||||
payloadEventQueue.notify(cbTrans, REQ_ARBITRATION, arbitrationDelayFw);
|
||||
}
|
||||
else
|
||||
outstandingEndReq[threadId] = &cbTrans;
|
||||
outstandingEndReqOnThread[thread] = &cbTrans;
|
||||
}
|
||||
else if (cbPhase == END_REQ) // from memory controller
|
||||
{
|
||||
lastEndReq[channelId] = sc_time_stamp();
|
||||
lastEndReqOnChannel[channel] = sc_time_stamp();
|
||||
|
||||
if (!pendingRequests[channelId].empty())
|
||||
if (!pendingRequestsOnChannel[channel].empty())
|
||||
{
|
||||
tlm_generic_payload &tPayload = *pendingRequests[channelId].front();
|
||||
pendingRequests[channelId].pop();
|
||||
tlm_generic_payload &tPayload = *pendingRequestsOnChannel[channel].front();
|
||||
pendingRequestsOnChannel[channel].pop();
|
||||
tlm_phase tPhase = BEGIN_REQ;
|
||||
sc_time tDelay = tCK;
|
||||
|
||||
iSocket[static_cast<int>(channelId)]->nb_transport_fw(tPayload, tPhase, tDelay);
|
||||
iSocket[static_cast<int>(channel)]->nb_transport_fw(tPayload, tPhase, tDelay);
|
||||
}
|
||||
else
|
||||
channelIsBusy[channelId] = false;
|
||||
channelIsBusy[channel] = false;
|
||||
}
|
||||
else if (cbPhase == BEGIN_RESP) // from memory controller
|
||||
{
|
||||
@@ -444,86 +444,86 @@ void ArbiterReorder::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase&
|
||||
{
|
||||
tlm_phase tPhase = END_RESP;
|
||||
sc_time tDelay = SC_ZERO_TIME;
|
||||
iSocket[static_cast<int>(channelId)]->nb_transport_fw(cbTrans, tPhase, tDelay);
|
||||
iSocket[static_cast<int>(channel)]->nb_transport_fw(cbTrans, tPhase, tDelay);
|
||||
}
|
||||
|
||||
payloadEventQueue.notify(cbTrans, RESP_ARBITRATION, arbitrationDelayBw);
|
||||
}
|
||||
else if (cbPhase == END_RESP) // from initiator
|
||||
{
|
||||
lastEndResp[threadId] = sc_time_stamp();
|
||||
lastEndRespOnThread[thread] = sc_time_stamp();
|
||||
cbTrans.release();
|
||||
|
||||
if (outstandingEndReq[threadId] != nullptr)
|
||||
if (outstandingEndReqOnThread[thread] != nullptr)
|
||||
{
|
||||
tlm_generic_payload &tPayload = *outstandingEndReq[threadId];
|
||||
outstandingEndReq[threadId] = nullptr;
|
||||
tlm_generic_payload &tPayload = *outstandingEndReqOnThread[thread];
|
||||
outstandingEndReqOnThread[thread] = nullptr;
|
||||
tlm_phase tPhase = END_REQ;
|
||||
sc_time tDelay = SC_ZERO_TIME;
|
||||
|
||||
ArbiterExtension::setIDAndTimeOfGeneration(tPayload, nextThreadPayloadIDToAppend[threadId]++,
|
||||
ArbiterExtension::setIDAndTimeOfGeneration(tPayload, nextThreadPayloadIDToAppend[thread]++,
|
||||
sc_time_stamp());
|
||||
|
||||
tSocket[static_cast<int>(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay);
|
||||
tSocket[static_cast<int>(thread)]->nb_transport_bw(tPayload, tPhase, tDelay);
|
||||
|
||||
payloadEventQueue.notify(tPayload, REQ_ARBITRATION, arbitrationDelayFw);
|
||||
}
|
||||
else
|
||||
activeTransactions[threadId]--;
|
||||
activeTransactionsOnThread[thread]--;
|
||||
|
||||
tlm_generic_payload &tPayload = **pendingResponses[threadId].begin();
|
||||
tlm_generic_payload &tPayload = **pendingResponsesOnThread[thread].begin();
|
||||
|
||||
if (!pendingResponses[threadId].empty() &&
|
||||
ArbiterExtension::getThreadPayloadID(tPayload) == nextThreadPayloadIDToReturn[threadId])
|
||||
if (!pendingResponsesOnThread[thread].empty() &&
|
||||
ArbiterExtension::getThreadPayloadID(tPayload) == nextThreadPayloadIDToReturn[thread])
|
||||
{
|
||||
nextThreadPayloadIDToReturn[threadId]++;
|
||||
pendingResponses[threadId].erase(pendingResponses[threadId].begin());
|
||||
nextThreadPayloadIDToReturn[thread]++;
|
||||
pendingResponsesOnThread[thread].erase(pendingResponsesOnThread[thread].begin());
|
||||
|
||||
tlm_phase tPhase = BEGIN_RESP;
|
||||
sc_time tDelay = tCK;
|
||||
|
||||
tlm_sync_enum returnValue = tSocket[static_cast<int>(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay);
|
||||
tlm_sync_enum returnValue = tSocket[static_cast<int>(thread)]->nb_transport_bw(tPayload, tPhase, tDelay);
|
||||
// Early completion from initiator
|
||||
if (returnValue == TLM_UPDATED)
|
||||
payloadEventQueue.notify(tPayload, tPhase, tDelay);
|
||||
}
|
||||
else
|
||||
threadIsBusy[threadId] = false;
|
||||
threadIsBusy[thread] = false;
|
||||
}
|
||||
else if (cbPhase == REQ_ARBITRATION)
|
||||
{
|
||||
pendingRequests[channelId].push(&cbTrans);
|
||||
pendingRequestsOnChannel[channel].push(&cbTrans);
|
||||
|
||||
if (!channelIsBusy[channelId])
|
||||
if (!channelIsBusy[channel])
|
||||
{
|
||||
channelIsBusy[channelId] = true;
|
||||
channelIsBusy[channel] = true;
|
||||
|
||||
tlm_generic_payload &tPayload = *pendingRequests[channelId].front();
|
||||
pendingRequests[channelId].pop();
|
||||
tlm_generic_payload &tPayload = *pendingRequestsOnChannel[channel].front();
|
||||
pendingRequestsOnChannel[channel].pop();
|
||||
tlm_phase tPhase = BEGIN_REQ;
|
||||
sc_time tDelay = lastEndReq[channelId] == sc_time_stamp() ? tCK : SC_ZERO_TIME;
|
||||
sc_time tDelay = lastEndReqOnChannel[channel] == sc_time_stamp() ? tCK : SC_ZERO_TIME;
|
||||
|
||||
iSocket[static_cast<int>(channelId)]->nb_transport_fw(tPayload, tPhase, tDelay);
|
||||
iSocket[static_cast<int>(channel)]->nb_transport_fw(tPayload, tPhase, tDelay);
|
||||
}
|
||||
}
|
||||
else if (cbPhase == RESP_ARBITRATION)
|
||||
{
|
||||
pendingResponses[threadId].insert(&cbTrans);
|
||||
pendingResponsesOnThread[thread].insert(&cbTrans);
|
||||
|
||||
if (!threadIsBusy[threadId])
|
||||
if (!threadIsBusy[thread])
|
||||
{
|
||||
tlm_generic_payload &tPayload = **pendingResponses[threadId].begin();
|
||||
tlm_generic_payload &tPayload = **pendingResponsesOnThread[thread].begin();
|
||||
|
||||
if (ArbiterExtension::getThreadPayloadID(tPayload) == nextThreadPayloadIDToReturn[threadId])
|
||||
if (ArbiterExtension::getThreadPayloadID(tPayload) == nextThreadPayloadIDToReturn[thread])
|
||||
{
|
||||
threadIsBusy[threadId] = true;
|
||||
threadIsBusy[thread] = true;
|
||||
|
||||
nextThreadPayloadIDToReturn[threadId]++;
|
||||
pendingResponses[threadId].erase(pendingResponses[threadId].begin());
|
||||
nextThreadPayloadIDToReturn[thread]++;
|
||||
pendingResponsesOnThread[thread].erase(pendingResponsesOnThread[thread].begin());
|
||||
tlm_phase tPhase = BEGIN_RESP;
|
||||
sc_time tDelay = lastEndResp[threadId] == sc_time_stamp() ? tCK : SC_ZERO_TIME;
|
||||
sc_time tDelay = lastEndRespOnThread[thread] == sc_time_stamp() ? tCK : SC_ZERO_TIME;
|
||||
|
||||
tlm_sync_enum returnValue = tSocket[static_cast<int>(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay);
|
||||
tlm_sync_enum returnValue = tSocket[static_cast<int>(thread)]->nb_transport_bw(tPayload, tPhase, tDelay);
|
||||
// Early completion from initiator
|
||||
if (returnValue == TLM_UPDATED)
|
||||
payloadEventQueue.notify(tPayload, tPhase, tDelay);
|
||||
|
||||
@@ -77,13 +77,13 @@ protected:
|
||||
tlm_utils::peq_with_cb_and_phase<Arbiter> payloadEventQueue;
|
||||
virtual void peqCallback(tlm::tlm_generic_payload& payload, const tlm::tlm_phase& phase) = 0;
|
||||
|
||||
std::vector<bool> threadIsBusy;
|
||||
std::vector<bool> channelIsBusy;
|
||||
ControllerVector<Thread, bool> threadIsBusy;
|
||||
ControllerVector<Channel, bool> channelIsBusy;
|
||||
|
||||
std::vector<std::queue<tlm::tlm_generic_payload*>> pendingRequests;
|
||||
ControllerVector<Channel, std::queue<tlm::tlm_generic_payload*>> pendingRequestsOnChannel;
|
||||
|
||||
std::vector<uint64_t> nextThreadPayloadIDToAppend;
|
||||
std::vector<uint64_t> nextChannelPayloadIDToAppend;
|
||||
ControllerVector<Thread, std::uint64_t> nextThreadPayloadIDToAppend;
|
||||
ControllerVector<Channel, std::uint64_t> nextChannelPayloadIDToAppend;
|
||||
|
||||
tlm::tlm_sync_enum nb_transport_fw(int id, tlm::tlm_generic_payload& trans,
|
||||
tlm::tlm_phase& phase, sc_core::sc_time& fwDelay);
|
||||
@@ -111,7 +111,7 @@ private:
|
||||
void end_of_elaboration() override;
|
||||
void peqCallback(tlm::tlm_generic_payload& cbTrans, const tlm::tlm_phase& phase) override;
|
||||
|
||||
std::vector<std::queue<tlm::tlm_generic_payload*>> pendingResponses;
|
||||
ControllerVector<Thread, std::queue<tlm::tlm_generic_payload*>> pendingResponsesOnThread;
|
||||
};
|
||||
|
||||
class ArbiterFifo final : public Arbiter
|
||||
@@ -125,14 +125,14 @@ private:
|
||||
void end_of_elaboration() override;
|
||||
void peqCallback(tlm::tlm_generic_payload& cbTrans, const tlm::tlm_phase& phase) override;
|
||||
|
||||
std::vector<unsigned int> activeTransactions;
|
||||
const unsigned maxActiveTransactions;
|
||||
ControllerVector<Thread, unsigned int> activeTransactionsOnThread;
|
||||
const unsigned maxActiveTransactionsPerThread;
|
||||
|
||||
std::vector<tlm::tlm_generic_payload*> outstandingEndReq;
|
||||
std::vector<std::queue<tlm::tlm_generic_payload*>> pendingResponses;
|
||||
ControllerVector<Thread, tlm::tlm_generic_payload*> outstandingEndReqOnThread;
|
||||
ControllerVector<Thread, std::queue<tlm::tlm_generic_payload*>> pendingResponsesOnThread;
|
||||
|
||||
std::vector<sc_core::sc_time> lastEndReq;
|
||||
std::vector<sc_core::sc_time> lastEndResp;
|
||||
ControllerVector<Channel, sc_core::sc_time> lastEndReqOnChannel;
|
||||
ControllerVector<Thread, sc_core::sc_time> lastEndRespOnThread;
|
||||
};
|
||||
|
||||
class ArbiterReorder final : public Arbiter
|
||||
@@ -146,7 +146,7 @@ private:
|
||||
void end_of_elaboration() override;
|
||||
void peqCallback(tlm::tlm_generic_payload& cbTrans, const tlm::tlm_phase& phase) override;
|
||||
|
||||
std::vector<unsigned int> activeTransactions;
|
||||
ControllerVector<Thread, unsigned int> activeTransactionsOnThread;
|
||||
const unsigned maxActiveTransactions;
|
||||
|
||||
struct ThreadPayloadIDCompare
|
||||
@@ -157,13 +157,13 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<tlm::tlm_generic_payload*> outstandingEndReq;
|
||||
std::vector<std::set<tlm::tlm_generic_payload*, ThreadPayloadIDCompare>> pendingResponses;
|
||||
ControllerVector<Thread, tlm::tlm_generic_payload*> outstandingEndReqOnThread;
|
||||
ControllerVector<Thread, std::set<tlm::tlm_generic_payload*, ThreadPayloadIDCompare>> pendingResponsesOnThread;
|
||||
|
||||
std::vector<sc_core::sc_time> lastEndReq;
|
||||
std::vector<sc_core::sc_time> lastEndResp;
|
||||
ControllerVector<Channel, sc_core::sc_time> lastEndReqOnChannel;
|
||||
ControllerVector<Thread, sc_core::sc_time> lastEndRespOnThread;
|
||||
|
||||
std::vector<uint64_t> nextThreadPayloadIDToReturn;
|
||||
ControllerVector<Thread, std::uint64_t> nextThreadPayloadIDToReturn;
|
||||
};
|
||||
|
||||
} // namespace DRAMSys
|
||||
|
||||
@@ -151,7 +151,7 @@ void DRAMSys::setupDebugManager([[maybe_unused]] const std::string& traceName) c
|
||||
bool writeToConsole = false;
|
||||
bool writeToFile = true;
|
||||
dbg.setup(debugEnabled, writeToConsole, writeToFile);
|
||||
if (writeToFile)
|
||||
if (debugEnabled && writeToFile)
|
||||
dbg.openDebugFile(traceName + ".txt");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ tlm_sync_enum Dram::nb_transport_fw(tlm_generic_payload& trans, tlm_phase& phase
|
||||
#ifdef DRAMPOWER
|
||||
if (powerAnalysis)
|
||||
{
|
||||
int bank = static_cast<int>(ControllerExtension::getBank(trans).ID());
|
||||
int bank = static_cast<int>(ControllerExtension::getBank(trans));
|
||||
int64_t cycle = std::lround((sc_time_stamp() + delay) / memSpec.tCK);
|
||||
DRAMPower->doCommand(phaseToDRAMPowerCommand(phase), bank, cycle);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ Initiators in the simulator are split up into two disctinct components: **Reques
|
||||
|
||||
**RequestProducers** are simple C++ classes that implement the `RequestProducer` interface. Upon calling the `nextRequest()` method of a producer, a new `Request` is either generated on-the-fly or constructed from a trace file.
|
||||
|
||||
**RequestIssuers** are the SystemC modules that connect with DRAMSys. Issuers have no knowledge of where the requests are coming from. They simply call their `nextRequest()` callback that it has been passed in the constructor to obtain the next request to be sent to DRAMSys. Using this concept, the generation and the issuing of request is completely decoupled to make very flexible initiator designs possible.
|
||||
**RequestIssuers** are the SystemC modules that connect to DRAMSys. Issuers have no knowledge of where the requests are coming from. They simply call their `nextRequest()` callback that it has been passed in the constructor to obtain the next request to be sent to DRAMSys. Using this concept, the generation and the issuing of request is completely decoupled to make very flexible initiator designs possible.
|
||||
|
||||
**Initiators** implement the `Initiator` interface, which describes how the initiator is bound to DRAMSys. This abstracts over the actual socket type used by the initiator.
|
||||
Complex initiators may implement the interface directly, but for simple cases, there exists the templated `SimpleInitiator<Producer>` class. This specialized initiator consists of only one producer and one issuer that operate together. The `StlPlayer` and `RowHammer` issuers make use of the `SimpleInitiator`.
|
||||
|
||||
@@ -33,28 +33,13 @@
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#include "simulator/Initiator.h"
|
||||
#include "simulator/MemoryManager.h"
|
||||
#include "simulator/SimpleInitiator.h"
|
||||
#include "simulator/generator/TrafficGenerator.h"
|
||||
#include "simulator/hammer/RowHammer.h"
|
||||
#include "simulator/player/StlPlayer.h"
|
||||
#include "simulator/util.h"
|
||||
#include "simulator/Simulator.h"
|
||||
|
||||
#include <DRAMSys/simulation/DRAMSysRecordable.h>
|
||||
|
||||
#include <systemc>
|
||||
#include <tlm>
|
||||
#include <tlm_utils/peq_with_cb_and_phase.h>
|
||||
#include <tlm_utils/simple_initiator_socket.h>
|
||||
#include <DRAMSys/config/DRAMSysConfiguration.h>
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <random>
|
||||
|
||||
static constexpr std::string_view TRACE_DIRECTORY = "traces";
|
||||
|
||||
int sc_main(int argc, char **argv)
|
||||
int sc_main(int argc, char** argv)
|
||||
{
|
||||
std::filesystem::path resourceDirectory = DRAMSYS_RESOURCE_DIR;
|
||||
if (argc >= 3)
|
||||
@@ -71,129 +56,8 @@ int sc_main(int argc, char **argv)
|
||||
DRAMSys::Config::Configuration configuration =
|
||||
DRAMSys::Config::from_path(baseConfig.c_str(), resourceDirectory.c_str());
|
||||
|
||||
if (!configuration.tracesetup.has_value())
|
||||
SC_REPORT_FATAL("Simulator", "No traffic initiators specified");
|
||||
|
||||
std::unique_ptr<DRAMSys::DRAMSys> dramSys;
|
||||
if (configuration.simconfig.DatabaseRecording.value_or(false))
|
||||
{
|
||||
dramSys = std::make_unique<DRAMSys::DRAMSysRecordable>("DRAMSys", configuration);
|
||||
}
|
||||
else
|
||||
{
|
||||
dramSys = std::make_unique<DRAMSys::DRAMSys>("DRAMSys", configuration);
|
||||
}
|
||||
|
||||
bool storageEnabled = dramSys->getConfig().storeMode == DRAMSys::Configuration::StoreMode::Store;
|
||||
MemoryManager memoryManager(storageEnabled);
|
||||
|
||||
std::vector<std::unique_ptr<Initiator>> initiators;
|
||||
|
||||
unsigned int terminatedInitiators = 0;
|
||||
auto termianteInitiator = [&initiators, &terminatedInitiators]()
|
||||
{
|
||||
terminatedInitiators++;
|
||||
|
||||
if (terminatedInitiators == initiators.size())
|
||||
sc_core::sc_stop();
|
||||
};
|
||||
|
||||
uint64_t totalTransactions{};
|
||||
uint64_t transactionsFinished = 0;
|
||||
auto transactionFinished = [&totalTransactions, &transactionsFinished, &configuration]()
|
||||
{
|
||||
transactionsFinished++;
|
||||
|
||||
if (configuration.simconfig.SimulationProgressBar.value_or(false))
|
||||
loadBar(transactionsFinished, totalTransactions);
|
||||
};
|
||||
|
||||
for (auto const &initiator_config : configuration.tracesetup.value())
|
||||
{
|
||||
uint64_t memorySize = dramSys->getConfig().memSpec->getSimMemSizeInBytes();
|
||||
unsigned int defaultDataLength = dramSys->getConfig().memSpec->defaultBytesPerBurst;
|
||||
|
||||
auto initiator = std::visit(
|
||||
[=, &memoryManager](auto &&config) -> std::unique_ptr<Initiator>
|
||||
{
|
||||
using T = std::decay_t<decltype(config)>;
|
||||
if constexpr (std::is_same_v<T, DRAMSys::Config::TrafficGenerator> ||
|
||||
std::is_same_v<T, DRAMSys::Config::TrafficGeneratorStateMachine>)
|
||||
{
|
||||
return std::make_unique<TrafficGenerator>(config,
|
||||
memoryManager,
|
||||
memorySize,
|
||||
defaultDataLength,
|
||||
transactionFinished,
|
||||
termianteInitiator);
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, DRAMSys::Config::TracePlayer>)
|
||||
{
|
||||
std::filesystem::path tracePath =
|
||||
resourceDirectory / TRACE_DIRECTORY / config.name;
|
||||
|
||||
StlPlayer::TraceType traceType;
|
||||
|
||||
auto extension = tracePath.extension();
|
||||
if (extension == ".stl")
|
||||
traceType = StlPlayer::TraceType::Absolute;
|
||||
else if (extension == ".rstl")
|
||||
traceType = StlPlayer::TraceType::Relative;
|
||||
else
|
||||
{
|
||||
std::string report = extension.string() + " is not a valid trace format.";
|
||||
SC_REPORT_FATAL("Simulator", report.c_str());
|
||||
}
|
||||
|
||||
StlPlayer player(
|
||||
tracePath.c_str(), config.clkMhz, defaultDataLength, traceType, false);
|
||||
|
||||
return std::make_unique<SimpleInitiator<StlPlayer>>(config.name.c_str(),
|
||||
memoryManager,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
transactionFinished,
|
||||
termianteInitiator,
|
||||
std::move(player));
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, DRAMSys::Config::RowHammer>)
|
||||
{
|
||||
RowHammer hammer(
|
||||
config.numRequests, config.clkMhz, config.rowIncrement, defaultDataLength);
|
||||
|
||||
return std::make_unique<SimpleInitiator<RowHammer>>(config.name.c_str(),
|
||||
memoryManager,
|
||||
1,
|
||||
1,
|
||||
transactionFinished,
|
||||
termianteInitiator,
|
||||
std::move(hammer));
|
||||
}
|
||||
},
|
||||
initiator_config);
|
||||
|
||||
totalTransactions += initiator->totalRequests();
|
||||
|
||||
initiator->bind(dramSys->tSocket);
|
||||
initiators.push_back(std::move(initiator));
|
||||
}
|
||||
|
||||
// Store the starting of the simulation in wall-clock time:
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
|
||||
// Start the SystemC simulation
|
||||
sc_set_stop_mode(sc_core::SC_STOP_FINISH_DELTA);
|
||||
sc_core::sc_start();
|
||||
|
||||
if (!sc_core::sc_end_of_simulation_invoked())
|
||||
{
|
||||
SC_REPORT_WARNING("sc_main", "Simulation stopped without explicit sc_stop()");
|
||||
sc_core::sc_stop();
|
||||
}
|
||||
|
||||
auto finish = std::chrono::high_resolution_clock::now();
|
||||
std::chrono::duration<double> elapsed = finish - start;
|
||||
std::cout << "Simulation took " + std::to_string(elapsed.count()) + " seconds." << std::endl;
|
||||
Simulator simulator(std::move(configuration), std::move(resourceDirectory));
|
||||
Simulator::run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -38,11 +38,6 @@
|
||||
#include "MemoryManager.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <sysc/kernel/sc_simcontext.h>
|
||||
#include <sysc/kernel/sc_time.h>
|
||||
#include <sysc/utils/sc_report.h>
|
||||
#include <tlm_core/tlm_2/tlm_generic_payload/tlm_gp.h>
|
||||
#include <tlm_core/tlm_2/tlm_generic_payload/tlm_phase.h>
|
||||
|
||||
using namespace tlm;
|
||||
using namespace sc_core;
|
||||
@@ -86,7 +81,7 @@ Cache::Cache(const sc_module_name &name,
|
||||
if (storageEnabled)
|
||||
{
|
||||
dataMemory.reserve(size);
|
||||
|
||||
|
||||
for (std::size_t set = 0; set < lineTable.size(); set++)
|
||||
{
|
||||
for (std::size_t way = 0; way < lineTable[set].size(); way++)
|
||||
@@ -593,7 +588,7 @@ void Cache::accessCacheAndSendResponse(tlm_generic_payload &trans)
|
||||
sc_time bwDelay = SC_ZERO_TIME;
|
||||
|
||||
trans.set_response_status(tlm::TLM_OK_RESPONSE);
|
||||
|
||||
|
||||
tlm_sync_enum returnValue = tSocket->nb_transport_bw(trans, bwPhase, bwDelay);
|
||||
if (returnValue == tlm::TLM_UPDATED) // TODO tlm_completed
|
||||
payloadEventQueue.notify(trans, bwPhase, bwDelay);
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
#include "MemoryManager.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <list>
|
||||
#include <queue>
|
||||
#include <systemc>
|
||||
|
||||
@@ -44,6 +44,7 @@ class SimpleInitiator : public Initiator
|
||||
public:
|
||||
SimpleInitiator(sc_core::sc_module_name const &name,
|
||||
MemoryManager &memoryManager,
|
||||
unsigned int clkMhz,
|
||||
std::optional<unsigned int> maxPendingReadRequests,
|
||||
std::optional<unsigned int> maxPendingWriteRequests,
|
||||
std::function<void()> transactionFinished,
|
||||
@@ -53,6 +54,7 @@ public:
|
||||
issuer(
|
||||
name,
|
||||
memoryManager,
|
||||
clkMhz,
|
||||
maxPendingReadRequests,
|
||||
maxPendingWriteRequests,
|
||||
[this] { return this->producer.nextRequest(); },
|
||||
|
||||
171
src/simulator/simulator/Simulator.cpp
Normal file
171
src/simulator/simulator/Simulator.cpp
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 2023, RPTU Kaiserslautern-Landau
|
||||
* 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.
|
||||
*
|
||||
* Authors:
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#include "Simulator.h"
|
||||
|
||||
#include "SimpleInitiator.h"
|
||||
#include "generator/TrafficGenerator.h"
|
||||
#include "hammer/RowHammer.h"
|
||||
#include "player/StlPlayer.h"
|
||||
#include "util.h"
|
||||
|
||||
Simulator::Simulator(DRAMSys::Config::Configuration configuration,
|
||||
std::filesystem::path resourceDirectory) :
|
||||
memoryManager(configuration.simconfig.StoreMode == DRAMSys::Config::StoreModeType::Store),
|
||||
configuration(std::move(configuration)),
|
||||
resourceDirectory(std::move(resourceDirectory))
|
||||
{
|
||||
if (this->configuration.simconfig.DatabaseRecording.value_or(false))
|
||||
{
|
||||
dramSys = std::make_unique<DRAMSys::DRAMSysRecordable>("DRAMSys", this->configuration);
|
||||
}
|
||||
else
|
||||
{
|
||||
dramSys = std::make_unique<DRAMSys::DRAMSys>("DRAMSys", this->configuration);
|
||||
}
|
||||
|
||||
terminateInitiator = [this]()
|
||||
{
|
||||
terminatedInitiators++;
|
||||
|
||||
if (terminatedInitiators == initiators.size())
|
||||
sc_core::sc_stop();
|
||||
};
|
||||
|
||||
finishTransaction = [this]()
|
||||
{
|
||||
transactionsFinished++;
|
||||
|
||||
if (this->configuration.simconfig.SimulationProgressBar.value_or(false))
|
||||
loadBar(transactionsFinished, totalTransactions);
|
||||
};
|
||||
|
||||
if (!configuration.tracesetup.has_value())
|
||||
SC_REPORT_FATAL("Simulator", "No traffic initiators specified");
|
||||
|
||||
for (const auto& initiatorConfig : *this->configuration.tracesetup)
|
||||
{
|
||||
auto initiator = instantiateInitiator(initiatorConfig);
|
||||
totalTransactions += initiator->totalRequests();
|
||||
initiator->bind(dramSys->tSocket);
|
||||
initiators.push_back(std::move(initiator));
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Initiator>
|
||||
Simulator::instantiateInitiator(const DRAMSys::Config::Initiator& initiator)
|
||||
{
|
||||
uint64_t memorySize = dramSys->getConfig().memSpec->getSimMemSizeInBytes();
|
||||
unsigned int defaultDataLength = dramSys->getConfig().memSpec->defaultBytesPerBurst;
|
||||
|
||||
return std::visit(
|
||||
[=](auto&& config) -> std::unique_ptr<Initiator>
|
||||
{
|
||||
using T = std::decay_t<decltype(config)>;
|
||||
if constexpr (std::is_same_v<T, DRAMSys::Config::TrafficGenerator> ||
|
||||
std::is_same_v<T, DRAMSys::Config::TrafficGeneratorStateMachine>)
|
||||
{
|
||||
return std::make_unique<TrafficGenerator>(config,
|
||||
memoryManager,
|
||||
memorySize,
|
||||
defaultDataLength,
|
||||
finishTransaction,
|
||||
terminateInitiator);
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, DRAMSys::Config::TracePlayer>)
|
||||
{
|
||||
std::filesystem::path tracePath = resourceDirectory / TRACE_DIRECTORY / config.name;
|
||||
|
||||
std::optional<StlPlayer::TraceType> traceType;
|
||||
|
||||
auto extension = tracePath.extension();
|
||||
if (extension == ".stl")
|
||||
traceType = StlPlayer::TraceType::Absolute;
|
||||
else if (extension == ".rstl")
|
||||
traceType = StlPlayer::TraceType::Relative;
|
||||
|
||||
if (!traceType.has_value())
|
||||
{
|
||||
std::string report = extension.string() + " is not a valid trace format.";
|
||||
SC_REPORT_FATAL("Simulator", report.c_str());
|
||||
}
|
||||
|
||||
StlPlayer player(
|
||||
tracePath.c_str(), config.clkMhz, defaultDataLength, *traceType, false);
|
||||
|
||||
return std::make_unique<SimpleInitiator<StlPlayer>>(config.name.c_str(),
|
||||
memoryManager,
|
||||
config.clkMhz,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
finishTransaction,
|
||||
terminateInitiator,
|
||||
std::move(player));
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, DRAMSys::Config::RowHammer>)
|
||||
{
|
||||
RowHammer hammer(config.numRequests, config.rowIncrement, defaultDataLength);
|
||||
|
||||
return std::make_unique<SimpleInitiator<RowHammer>>(config.name.c_str(),
|
||||
memoryManager,
|
||||
config.clkMhz,
|
||||
1,
|
||||
1,
|
||||
finishTransaction,
|
||||
terminateInitiator,
|
||||
std::move(hammer));
|
||||
}
|
||||
},
|
||||
initiator);
|
||||
}
|
||||
|
||||
void Simulator::run()
|
||||
{
|
||||
// Store the starting of the simulation in wall-clock time:
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
|
||||
// Start the SystemC simulation
|
||||
sc_core::sc_start();
|
||||
|
||||
if (!sc_core::sc_end_of_simulation_invoked())
|
||||
{
|
||||
SC_REPORT_WARNING("Simulator", "Simulation stopped without explicit sc_stop()");
|
||||
sc_core::sc_stop();
|
||||
}
|
||||
|
||||
auto finish = std::chrono::high_resolution_clock::now();
|
||||
std::chrono::duration<double> elapsed = finish - start;
|
||||
std::cout << "Simulation took " + std::to_string(elapsed.count()) + " seconds." << std::endl;
|
||||
}
|
||||
71
src/simulator/simulator/Simulator.h
Normal file
71
src/simulator/simulator/Simulator.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2023, RPTU Kaiserslautern-Landau
|
||||
* 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.
|
||||
*
|
||||
* Authors:
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Initiator.h"
|
||||
#include "MemoryManager.h"
|
||||
|
||||
#include <DRAMSys/config/DRAMSysConfiguration.h>
|
||||
#include <DRAMSys/simulation/DRAMSysRecordable.h>
|
||||
|
||||
static constexpr std::string_view TRACE_DIRECTORY = "traces";
|
||||
|
||||
class Simulator
|
||||
{
|
||||
public:
|
||||
Simulator(DRAMSys::Config::Configuration configuration,
|
||||
std::filesystem::path resourceDirectory);
|
||||
|
||||
static void run();
|
||||
|
||||
private:
|
||||
std::unique_ptr<Initiator> instantiateInitiator(const DRAMSys::Config::Initiator& initiator);
|
||||
|
||||
MemoryManager memoryManager;
|
||||
|
||||
DRAMSys::Config::Configuration configuration;
|
||||
std::filesystem::path resourceDirectory;
|
||||
|
||||
std::unique_ptr<DRAMSys::DRAMSys> dramSys;
|
||||
std::vector<std::unique_ptr<Initiator>> initiators;
|
||||
|
||||
std::function<void()> terminateInitiator;
|
||||
std::function<void()> finishTransaction;
|
||||
|
||||
unsigned int terminatedInitiators = 0;
|
||||
uint64_t totalTransactions{};
|
||||
uint64_t transactionsFinished = 0;
|
||||
};
|
||||
@@ -39,7 +39,6 @@
|
||||
RandomProducer::RandomProducer(uint64_t numRequests,
|
||||
std::optional<uint64_t> seed,
|
||||
double rwRatio,
|
||||
unsigned int clkMhz,
|
||||
std::optional<uint64_t> minAddress,
|
||||
std::optional<uint64_t> maxAddress,
|
||||
uint64_t memorySize,
|
||||
@@ -48,7 +47,6 @@ RandomProducer::RandomProducer(uint64_t numRequests,
|
||||
: numberOfRequests(numRequests),
|
||||
seed(seed.value_or(DEFAULT_SEED)),
|
||||
rwRatio(rwRatio),
|
||||
generatorPeriod(sc_core::sc_time(1.0 / static_cast<double>(clkMhz), sc_core::SC_US)),
|
||||
dataLength(dataLength),
|
||||
dataAlignment(dataAlignment),
|
||||
randomGenerator(this->seed),
|
||||
@@ -79,7 +77,7 @@ Request RandomProducer::nextRequest()
|
||||
request.command = readWriteDistribution(randomGenerator) < rwRatio ? Request::Command::Read
|
||||
: Request::Command::Write;
|
||||
request.length = dataLength;
|
||||
request.delay = generatorPeriod;
|
||||
request.delay = sc_core::SC_ZERO_TIME;
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@ public:
|
||||
RandomProducer(uint64_t numRequests,
|
||||
std::optional<uint64_t> seed,
|
||||
double rwRatio,
|
||||
unsigned int clkMhz,
|
||||
std::optional<uint64_t> minAddress,
|
||||
std::optional<uint64_t> maxAddress,
|
||||
uint64_t memorySize,
|
||||
@@ -56,12 +55,10 @@ public:
|
||||
Request nextRequest() override;
|
||||
|
||||
uint64_t totalRequests() override { return numberOfRequests; }
|
||||
sc_core::sc_time clkPeriod() override { return generatorPeriod; }
|
||||
|
||||
const uint64_t numberOfRequests;
|
||||
const uint64_t seed;
|
||||
const double rwRatio;
|
||||
const sc_core::sc_time generatorPeriod;
|
||||
const unsigned int dataLength;
|
||||
const unsigned int dataAlignment;
|
||||
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
SequentialProducer::SequentialProducer(uint64_t numRequests,
|
||||
std::optional<uint64_t> seed,
|
||||
double rwRatio,
|
||||
unsigned int clkMhz,
|
||||
std::optional<uint64_t> addressIncrement,
|
||||
std::optional<uint64_t> minAddress,
|
||||
std::optional<uint64_t> maxAddress,
|
||||
@@ -51,7 +50,6 @@ SequentialProducer::SequentialProducer(uint64_t numRequests,
|
||||
maxAddress(maxAddress.value_or(memorySize - 1)),
|
||||
seed(seed.value_or(DEFAULT_SEED)),
|
||||
rwRatio(rwRatio),
|
||||
generatorPeriod(sc_core::sc_time(1.0 / static_cast<double>(clkMhz), sc_core::SC_US)),
|
||||
dataLength(dataLength),
|
||||
randomGenerator(this->seed)
|
||||
{
|
||||
@@ -75,7 +73,7 @@ Request SequentialProducer::nextRequest()
|
||||
request.command = readWriteDistribution(randomGenerator) < rwRatio ? Request::Command::Read
|
||||
: Request::Command::Write;
|
||||
request.length = dataLength;
|
||||
request.delay = generatorPeriod;
|
||||
request.delay = sc_core::SC_ZERO_TIME;
|
||||
|
||||
generatedRequests++;
|
||||
return request;
|
||||
|
||||
@@ -46,7 +46,6 @@ public:
|
||||
SequentialProducer(uint64_t numRequests,
|
||||
std::optional<uint64_t> seed,
|
||||
double rwRatio,
|
||||
unsigned int clkMhz,
|
||||
std::optional<uint64_t> addressIncrement,
|
||||
std::optional<uint64_t> minAddress,
|
||||
std::optional<uint64_t> maxAddress,
|
||||
@@ -56,7 +55,6 @@ public:
|
||||
Request nextRequest() override;
|
||||
|
||||
uint64_t totalRequests() override { return numberOfRequests; }
|
||||
sc_core::sc_time clkPeriod() override { return generatorPeriod; }
|
||||
void reset() override { generatedRequests = 0; }
|
||||
|
||||
const uint64_t numberOfRequests;
|
||||
@@ -65,7 +63,6 @@ public:
|
||||
const uint64_t maxAddress;
|
||||
const uint64_t seed;
|
||||
const double rwRatio;
|
||||
const sc_core::sc_time generatorPeriod;
|
||||
const unsigned int dataLength;
|
||||
|
||||
std::default_random_engine randomGenerator;
|
||||
|
||||
@@ -35,43 +35,44 @@
|
||||
|
||||
#include "TrafficGenerator.h"
|
||||
|
||||
TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGeneratorStateMachine const &config,
|
||||
MemoryManager &memoryManager,
|
||||
TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGeneratorStateMachine const& config,
|
||||
MemoryManager& memoryManager,
|
||||
uint64_t memorySize,
|
||||
unsigned int defaultDataLength,
|
||||
std::function<void()> transactionFinished,
|
||||
std::function<void()> terminateInitiator)
|
||||
: stateTransistions(config.transitions),
|
||||
consumer(
|
||||
config.name.c_str(),
|
||||
memoryManager,
|
||||
config.maxPendingReadRequests,
|
||||
config.maxPendingWriteRequests,
|
||||
[this] { return nextRequest(); },
|
||||
std::move(transactionFinished),
|
||||
std::move(terminateInitiator))
|
||||
std::function<void()> terminateInitiator) :
|
||||
stateTransistions(config.transitions),
|
||||
generatorPeriod(sc_core::sc_time(1.0 / static_cast<double>(config.clkMhz), sc_core::SC_US)),
|
||||
issuer(
|
||||
config.name.c_str(),
|
||||
memoryManager,
|
||||
config.clkMhz,
|
||||
config.maxPendingReadRequests,
|
||||
config.maxPendingWriteRequests,
|
||||
[this] { return nextRequest(); },
|
||||
std::move(transactionFinished),
|
||||
std::move(terminateInitiator))
|
||||
{
|
||||
unsigned int dataLength = config.dataLength.value_or(defaultDataLength);
|
||||
unsigned int dataAlignment = config.dataAlignment.value_or(dataLength);
|
||||
|
||||
for (auto const &state : config.states)
|
||||
for (auto const& state : config.states)
|
||||
{
|
||||
std::visit(
|
||||
[=, &config](auto &&arg)
|
||||
[=, &config](auto&& arg)
|
||||
{
|
||||
using DRAMSys::Config::TrafficGeneratorActiveState;
|
||||
using DRAMSys::Config::TrafficGeneratorIdleState;
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
if constexpr (std::is_same_v<T, TrafficGeneratorActiveState>)
|
||||
{
|
||||
auto const &activeState = arg;
|
||||
auto const& activeState = arg;
|
||||
if (activeState.addressDistribution ==
|
||||
DRAMSys::Config::AddressDistribution::Random)
|
||||
{
|
||||
auto producer = std::make_unique<RandomProducer>(activeState.numRequests,
|
||||
config.seed,
|
||||
activeState.rwRatio,
|
||||
config.clkMhz,
|
||||
activeState.minAddress,
|
||||
activeState.maxAddress,
|
||||
memorySize,
|
||||
@@ -86,7 +87,6 @@ TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGeneratorStateMachine
|
||||
std::make_unique<SequentialProducer>(activeState.numRequests,
|
||||
config.seed,
|
||||
activeState.rwRatio,
|
||||
config.clkMhz,
|
||||
activeState.addressIncrement,
|
||||
activeState.minAddress,
|
||||
activeState.maxAddress,
|
||||
@@ -98,7 +98,7 @@ TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGeneratorStateMachine
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, TrafficGeneratorIdleState>)
|
||||
{
|
||||
auto const &idleState = arg;
|
||||
auto const& idleState = arg;
|
||||
idleStateClks.emplace(idleState.id, idleState.idleClks);
|
||||
}
|
||||
},
|
||||
@@ -106,20 +106,22 @@ TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGeneratorStateMachine
|
||||
}
|
||||
}
|
||||
|
||||
TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGenerator const &config,
|
||||
MemoryManager &memoryManager,
|
||||
TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGenerator const& config,
|
||||
MemoryManager& memoryManager,
|
||||
uint64_t memorySize,
|
||||
unsigned int defaultDataLength,
|
||||
std::function<void()> transactionFinished,
|
||||
std::function<void()> terminateInitiator)
|
||||
: consumer(
|
||||
config.name.c_str(),
|
||||
memoryManager,
|
||||
config.maxPendingReadRequests,
|
||||
config.maxPendingWriteRequests,
|
||||
[this] { return nextRequest(); },
|
||||
std::move(transactionFinished),
|
||||
std::move(terminateInitiator))
|
||||
std::function<void()> terminateInitiator) :
|
||||
generatorPeriod(sc_core::sc_time(1.0 / static_cast<double>(config.clkMhz), sc_core::SC_US)),
|
||||
issuer(
|
||||
config.name.c_str(),
|
||||
memoryManager,
|
||||
config.clkMhz,
|
||||
config.maxPendingReadRequests,
|
||||
config.maxPendingWriteRequests,
|
||||
[this] { return nextRequest(); },
|
||||
std::move(transactionFinished),
|
||||
std::move(terminateInitiator))
|
||||
{
|
||||
unsigned int dataLength = config.dataLength.value_or(defaultDataLength);
|
||||
unsigned int dataAlignment = config.dataAlignment.value_or(dataLength);
|
||||
@@ -129,7 +131,6 @@ TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGenerator const &conf
|
||||
auto producer = std::make_unique<RandomProducer>(config.numRequests,
|
||||
config.seed,
|
||||
config.rwRatio,
|
||||
config.clkMhz,
|
||||
config.minAddress,
|
||||
config.maxAddress,
|
||||
memorySize,
|
||||
@@ -142,7 +143,6 @@ TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGenerator const &conf
|
||||
auto producer = std::make_unique<SequentialProducer>(config.numRequests,
|
||||
config.seed,
|
||||
config.rwRatio,
|
||||
config.clkMhz,
|
||||
config.addressIncrement,
|
||||
config.minAddress,
|
||||
config.maxAddress,
|
||||
@@ -183,9 +183,9 @@ Request TrafficGenerator::nextRequest()
|
||||
}
|
||||
|
||||
requestsInState++;
|
||||
|
||||
|
||||
Request request = producers[currentState]->nextRequest();
|
||||
request.delay += producers[currentState]->clkPeriod() * clksToIdle;
|
||||
request.delay += generatorPeriod * static_cast<double>(clksToIdle);
|
||||
return request;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
std::function<void()> transactionFinished,
|
||||
std::function<void()> terminateInitiator);
|
||||
|
||||
void bind(tlm_utils::multi_target_base<> &target) override { consumer.iSocket.bind(target); }
|
||||
void bind(tlm_utils::multi_target_base<> &target) override { issuer.iSocket.bind(target); }
|
||||
|
||||
uint64_t totalRequests() override;
|
||||
Request nextRequest();
|
||||
@@ -74,9 +74,10 @@ private:
|
||||
|
||||
using IdleClks = uint64_t;
|
||||
std::unordered_map<unsigned int, IdleClks> idleStateClks;
|
||||
const sc_core::sc_time generatorPeriod;
|
||||
|
||||
std::default_random_engine randomGenerator;
|
||||
|
||||
std::unordered_map<unsigned int, std::unique_ptr<RequestProducer>> producers;
|
||||
RequestIssuer consumer;
|
||||
RequestIssuer issuer;
|
||||
};
|
||||
|
||||
@@ -36,11 +36,9 @@
|
||||
#include "RowHammer.h"
|
||||
|
||||
RowHammer::RowHammer(uint64_t numRequests,
|
||||
unsigned int clkMhz,
|
||||
uint64_t rowIncrement,
|
||||
unsigned int dataLength)
|
||||
: numberOfRequests(numRequests),
|
||||
generatorPeriod(sc_core::sc_time(1.0 / static_cast<double>(clkMhz), sc_core::SC_US)),
|
||||
dataLength(dataLength),
|
||||
rowIncrement(rowIncrement)
|
||||
{
|
||||
@@ -62,6 +60,6 @@ Request RowHammer::nextRequest()
|
||||
request.address = currentAddress;
|
||||
request.command = Request::Command::Read;
|
||||
request.length = dataLength;
|
||||
request.delay = generatorPeriod;
|
||||
request.delay = sc_core::SC_ZERO_TIME;
|
||||
return request;
|
||||
}
|
||||
|
||||
@@ -43,16 +43,13 @@ class RowHammer : public RequestProducer
|
||||
{
|
||||
public:
|
||||
RowHammer(uint64_t numRequests,
|
||||
unsigned int clkMhz,
|
||||
uint64_t rowIncrement,
|
||||
unsigned int dataLength);
|
||||
|
||||
Request nextRequest() override;
|
||||
sc_core::sc_time clkPeriod() override { return generatorPeriod; }
|
||||
uint64_t totalRequests() override { return numberOfRequests; }
|
||||
|
||||
const uint64_t numberOfRequests;
|
||||
const sc_core::sc_time generatorPeriod;
|
||||
const unsigned int dataLength;
|
||||
const uint64_t rowIncrement;
|
||||
|
||||
|
||||
@@ -71,6 +71,9 @@ StlPlayer::StlPlayer(std::string_view tracePath,
|
||||
if (line.size() > 1 && line[0] != '#')
|
||||
numberOfLines++;
|
||||
}
|
||||
if (numberOfLines == 0)
|
||||
SC_REPORT_FATAL("StlPlayer",
|
||||
(std::string("Empty trace ") + tracePath.data()).c_str());
|
||||
traceFile.clear();
|
||||
traceFile.seekg(0);
|
||||
}
|
||||
@@ -94,17 +97,15 @@ Request StlPlayer::nextRequest()
|
||||
}
|
||||
}
|
||||
|
||||
sc_core::sc_time delay = readoutIt->delay;
|
||||
sc_core::sc_time offset = playerPeriod - (sc_core::sc_time_stamp() % playerPeriod);
|
||||
|
||||
sc_core::sc_time delay;
|
||||
if (traceType == TraceType::Absolute)
|
||||
{
|
||||
delay = std::max(sc_core::sc_time_stamp() + offset, delay);
|
||||
delay -= sc_core::sc_time_stamp();
|
||||
bool behindSchedule = sc_core::sc_time_stamp() > readoutIt->delay;
|
||||
delay = behindSchedule ? sc_core::SC_ZERO_TIME : readoutIt->delay - sc_core::sc_time_stamp();
|
||||
}
|
||||
else // if (traceType == TraceType::Relative)
|
||||
{
|
||||
delay = offset + delay;
|
||||
delay = readoutIt->delay;
|
||||
}
|
||||
|
||||
Request request(*readoutIt);
|
||||
@@ -143,69 +144,78 @@ void StlPlayer::parseTraceFile()
|
||||
|
||||
iss.str(line);
|
||||
|
||||
// Get the timestamp for the transaction.
|
||||
iss >> element;
|
||||
if (element.empty())
|
||||
SC_REPORT_FATAL(
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
|
||||
content.delay = playerPeriod * static_cast<double>(std::stoull(element));
|
||||
|
||||
// Get the optional burst length and command
|
||||
iss >> element;
|
||||
if (element.empty())
|
||||
SC_REPORT_FATAL(
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
|
||||
if (element.at(0) == '(')
|
||||
try
|
||||
{
|
||||
element.erase(0, 1);
|
||||
content.length = std::stoul(element);
|
||||
// Get the timestamp for the transaction.
|
||||
iss >> element;
|
||||
if (element.empty())
|
||||
SC_REPORT_FATAL(
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
}
|
||||
else
|
||||
content.length = defaultDataLength;
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
|
||||
if (element == "read")
|
||||
content.command = Request::Command::Read;
|
||||
else if (element == "write")
|
||||
content.command = Request::Command::Write;
|
||||
else
|
||||
SC_REPORT_FATAL(
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
content.delay = playerPeriod * static_cast<double>(std::stoull(element));
|
||||
|
||||
// Get the address.
|
||||
iss >> element;
|
||||
if (element.empty())
|
||||
SC_REPORT_FATAL(
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
content.address = std::stoull(element, nullptr, 16);
|
||||
|
||||
// Get the data if necessary.
|
||||
if (storageEnabled && content.command == Request::Command::Write)
|
||||
{
|
||||
// The input trace file must provide the data to be stored into the memory.
|
||||
// Get the optional burst length and command
|
||||
iss >> element;
|
||||
|
||||
// Check if data length in the trace file is correct.
|
||||
// We need two characters to represent 1 byte in hexadecimal. Offset for 0x prefix.
|
||||
if (element.length() != (content.length * 2 + 2))
|
||||
if (element.empty())
|
||||
SC_REPORT_FATAL(
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
|
||||
if (element.at(0) == '(')
|
||||
{
|
||||
element.erase(0, 1);
|
||||
content.length = std::stoul(element);
|
||||
iss >> element;
|
||||
if (element.empty())
|
||||
SC_REPORT_FATAL(
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
}
|
||||
else
|
||||
content.length = defaultDataLength;
|
||||
|
||||
if (element == "read")
|
||||
content.command = Request::Command::Read;
|
||||
else if (element == "write")
|
||||
content.command = Request::Command::Write;
|
||||
else
|
||||
SC_REPORT_FATAL(
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
|
||||
// Get the address.
|
||||
iss >> element;
|
||||
if (element.empty())
|
||||
SC_REPORT_FATAL(
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
content.address = std::stoull(element, nullptr, 16);
|
||||
|
||||
// Get the data if necessary.
|
||||
if (storageEnabled && content.command == Request::Command::Write)
|
||||
{
|
||||
// The input trace file must provide the data to be stored into the memory.
|
||||
iss >> element;
|
||||
|
||||
// Check if data length in the trace file is correct.
|
||||
// We need two characters to represent 1 byte in hexadecimal. Offset for 0x prefix.
|
||||
if (element.length() != (content.length * 2 + 2))
|
||||
SC_REPORT_FATAL(
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
|
||||
// Set data
|
||||
for (unsigned i = 0; i < content.length; i++)
|
||||
content.data.emplace_back(static_cast<unsigned char>(
|
||||
std::stoi(element.substr(i * 2 + 2, 2), nullptr, 16)));
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
SC_REPORT_FATAL(
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
|
||||
// Set data
|
||||
for (unsigned i = 0; i < content.length; i++)
|
||||
content.data.emplace_back(static_cast<unsigned char>(
|
||||
std::stoi(element.substr(i * 2 + 2, 2), nullptr, 16)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <systemc>
|
||||
#include <tlm>
|
||||
|
||||
#include <array>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
@@ -68,7 +69,6 @@ public:
|
||||
|
||||
Request nextRequest() override;
|
||||
|
||||
sc_core::sc_time clkPeriod() override { return playerPeriod; }
|
||||
uint64_t totalRequests() override { return numberOfLines; }
|
||||
|
||||
private:
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
RequestIssuer::RequestIssuer(sc_core::sc_module_name const &name,
|
||||
MemoryManager &memoryManager,
|
||||
unsigned int clkMhz,
|
||||
std::optional<unsigned int> maxPendingReadRequests,
|
||||
std::optional<unsigned int> maxPendingWriteRequests,
|
||||
std::function<Request()> nextRequest,
|
||||
@@ -45,6 +46,7 @@ RequestIssuer::RequestIssuer(sc_core::sc_module_name const &name,
|
||||
: sc_module(name),
|
||||
payloadEventQueue(this, &RequestIssuer::peqCallback),
|
||||
memoryManager(memoryManager),
|
||||
clkPeriod(sc_core::sc_time(1.0 / static_cast<double>(clkMhz), sc_core::SC_US)),
|
||||
maxPendingReadRequests(maxPendingReadRequests),
|
||||
maxPendingWriteRequests(maxPendingWriteRequests),
|
||||
transactionFinished(std::move(transactionFinished)),
|
||||
@@ -79,11 +81,22 @@ void RequestIssuer::sendNextRequest()
|
||||
tlm::tlm_phase phase = tlm::BEGIN_REQ;
|
||||
sc_core::sc_time delay = request.delay;
|
||||
|
||||
if (transactionsSent == 0)
|
||||
delay = sc_core::SC_ZERO_TIME;
|
||||
sc_core::sc_time sendingTime = sc_core::sc_time_stamp() + delay;
|
||||
|
||||
bool needsOffset = (sendingTime % clkPeriod) != sc_core::SC_ZERO_TIME;
|
||||
if (needsOffset)
|
||||
{
|
||||
sendingTime += clkPeriod;
|
||||
sendingTime -= sendingTime % clkPeriod;
|
||||
}
|
||||
|
||||
if (sendingTime == lastEndRequest)
|
||||
{
|
||||
sendingTime += clkPeriod;
|
||||
}
|
||||
|
||||
delay = sendingTime - sc_core::sc_time_stamp();
|
||||
iSocket->nb_transport_fw(payload, phase, delay);
|
||||
transactionInProgress = true;
|
||||
|
||||
if (request.command == Request::Command::Read)
|
||||
pendingReadRequests++;
|
||||
@@ -111,6 +124,8 @@ void RequestIssuer::peqCallback(tlm::tlm_generic_payload &payload, const tlm::tl
|
||||
{
|
||||
if (phase == tlm::END_REQ)
|
||||
{
|
||||
lastEndRequest = sc_core::sc_time_stamp();
|
||||
|
||||
if (nextRequestSendable())
|
||||
sendNextRequest();
|
||||
else
|
||||
@@ -118,12 +133,11 @@ void RequestIssuer::peqCallback(tlm::tlm_generic_payload &payload, const tlm::tl
|
||||
}
|
||||
else if (phase == tlm::BEGIN_RESP)
|
||||
{
|
||||
tlm::tlm_phase phase = tlm::END_RESP;
|
||||
tlm::tlm_phase nextPhase = tlm::END_RESP;
|
||||
sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
|
||||
iSocket->nb_transport_fw(payload, phase, delay);
|
||||
iSocket->nb_transport_fw(payload, nextPhase, delay);
|
||||
|
||||
payload.release();
|
||||
transactionInProgress = false;
|
||||
|
||||
transactionFinished();
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ public:
|
||||
|
||||
RequestIssuer(sc_core::sc_module_name const &name,
|
||||
MemoryManager &memoryManager,
|
||||
unsigned int clkMhz,
|
||||
std::optional<unsigned int> maxPendingReadRequests,
|
||||
std::optional<unsigned int> maxPendingWriteRequests,
|
||||
std::function<Request()> nextRequest,
|
||||
@@ -63,20 +64,20 @@ private:
|
||||
tlm_utils::peq_with_cb_and_phase<RequestIssuer> payloadEventQueue;
|
||||
MemoryManager &memoryManager;
|
||||
|
||||
bool transactionInProgress = false;
|
||||
const sc_core::sc_time clkPeriod;
|
||||
|
||||
bool transactionPostponed = false;
|
||||
bool finished = false;
|
||||
|
||||
uint64_t transactionsSent = 0;
|
||||
uint64_t transactionsReceived = 0;
|
||||
sc_core::sc_time lastEndRequest = sc_core::sc_max_time();
|
||||
|
||||
unsigned int pendingReadRequests = 0;
|
||||
unsigned int pendingWriteRequests = 0;
|
||||
const std::optional<unsigned int> maxPendingReadRequests;
|
||||
const std::optional<unsigned int> maxPendingWriteRequests;
|
||||
|
||||
unsigned int activeProducers = 0;
|
||||
|
||||
std::function<void()> transactionFinished;
|
||||
std::function<void()> terminate;
|
||||
std::function<Request()> nextRequest;
|
||||
|
||||
@@ -51,6 +51,5 @@ public:
|
||||
|
||||
virtual Request nextRequest() = 0;
|
||||
virtual uint64_t totalRequests() = 0;
|
||||
virtual sc_core::sc_time clkPeriod() = 0;
|
||||
virtual void reset(){};
|
||||
};
|
||||
|
||||
@@ -45,13 +45,13 @@ add_library(${PROJECT_NAME} STATIC ${SOURCE_FILES} ${HEADER_FILES})
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
nlohmann_json::nlohmann_json
|
||||
)
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
target_compile_definitions(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
DRAMSYS_RESOURCE_DIR="${DRAMSYS_RESOURCE_DIR}"
|
||||
)
|
||||
|
||||
@@ -59,4 +59,3 @@ add_library(DRAMSys::util ALIAS ${PROJECT_NAME})
|
||||
|
||||
|
||||
build_source_group()
|
||||
diagnostics_print(${PROJECT_NAME})
|
||||
|
||||
@@ -41,14 +41,18 @@
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
if (argc < 2)
|
||||
{
|
||||
std::cerr << "Must specify a simulation json as single argument.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string pathToJson = argv[1];
|
||||
auto configuration = DRAMSys::Config::from_path(pathToJson);
|
||||
std::string resourceDirectory = argc <= 2 ? DRAMSYS_RESOURCE_DIR : argv[2];
|
||||
|
||||
auto configuration = DRAMSys::Config::from_path(pathToJson, resourceDirectory);
|
||||
|
||||
|
||||
nlohmann::json json;
|
||||
json["simulation"] = configuration;
|
||||
|
||||
|
||||
@@ -1,216 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021, RPTU Kaiserslautern-Landau
|
||||
* 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.
|
||||
*
|
||||
* Authors:
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#include <DRAMSys/config/DRAMSysConfiguration.h>
|
||||
|
||||
#include <DRAMSys/util/json.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
using namespace DRAMSys::Config;
|
||||
|
||||
DRAMSys::Config::AddressMapping getAddressMapping()
|
||||
{
|
||||
return DRAMSys::Config::AddressMapping{
|
||||
{{0, 1}},
|
||||
{{2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}},
|
||||
{{16}},
|
||||
{{13, 14, 15}},
|
||||
{{17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}},
|
||||
{{33}},
|
||||
{{}},
|
||||
{{}}
|
||||
};
|
||||
}
|
||||
|
||||
DRAMSys::Config::McConfig getMcConfig()
|
||||
{
|
||||
return McConfig{
|
||||
PagePolicy::Open,
|
||||
Scheduler::FrFcfs,
|
||||
0,
|
||||
0,
|
||||
SchedulerBuffer::Bankwise,
|
||||
8,
|
||||
CmdMux::Oldest,
|
||||
RespQueue::Fifo,
|
||||
RefreshPolicy::AllBank,
|
||||
0,
|
||||
0,
|
||||
PowerDownPolicy::NoPowerDown,
|
||||
Arbiter::Simple,
|
||||
128,
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
DRAMSys::Config::SimConfig getSimConfig()
|
||||
{
|
||||
return DRAMSys::Config::SimConfig{
|
||||
0, false, true, false, false, {"error.csv"},
|
||||
42, false, {"ddr5"}, true, DRAMSys::Config::StoreMode::NoStorage, false, false,
|
||||
1000};
|
||||
}
|
||||
|
||||
DRAMSys::Config::TracePlayer getTracePlayer()
|
||||
{
|
||||
DRAMSys::Config::TracePlayer player;
|
||||
player.clkMhz = 100;
|
||||
player.name = "mytrace.stl";
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
DRAMSys::Config::TraceGenerator getTraceGeneratorOneState()
|
||||
{
|
||||
DRAMSys::Config::TraceGenerator gen;
|
||||
gen.clkMhz = 100;
|
||||
gen.name = "MyTestGen";
|
||||
|
||||
DRAMSys::Config::TraceGeneratorTrafficState state0;
|
||||
state0.numRequests = 1000;
|
||||
state0.rwRatio = 0.5;
|
||||
state0.addressDistribution = DRAMSys::Config::AddressDistribution::Random;
|
||||
state0.addressIncrement = {};
|
||||
state0.minAddress = {};
|
||||
state0.maxAddress = {};
|
||||
state0.clksPerRequest = {};
|
||||
|
||||
gen.states.emplace(0, state0);
|
||||
|
||||
return gen;
|
||||
}
|
||||
|
||||
DRAMSys::Config::TraceGenerator getTraceGeneratorMultipleStates()
|
||||
{
|
||||
DRAMSys::Config::TraceGenerator gen;
|
||||
|
||||
gen.clkMhz = 100;
|
||||
gen.name = "MyTestGen";
|
||||
gen.maxPendingReadRequests = 8;
|
||||
|
||||
DRAMSys::Config::TraceGeneratorTrafficState state0;
|
||||
state0.numRequests = 1000;
|
||||
state0.rwRatio = 0.5;
|
||||
state0.addressDistribution = DRAMSys::Config::AddressDistribution::Sequential;
|
||||
state0.addressIncrement = 256;
|
||||
state0.minAddress = {};
|
||||
state0.maxAddress = 1024;
|
||||
state0.clksPerRequest = {};
|
||||
|
||||
DRAMSys::Config::TraceGeneratorTrafficState state1;
|
||||
state1.numRequests = 100;
|
||||
state1.rwRatio = 0.75;
|
||||
state1.addressDistribution = DRAMSys::Config::AddressDistribution::Sequential;
|
||||
state1.addressIncrement = 512;
|
||||
state1.minAddress = 1024;
|
||||
state1.maxAddress = 2048;
|
||||
state1.clksPerRequest = {};
|
||||
|
||||
gen.states.emplace(0, state0);
|
||||
gen.states.emplace(1, state1);
|
||||
|
||||
DRAMSys::Config::TraceGeneratorStateTransition transistion0{1, 1.0};
|
||||
|
||||
gen.transitions.emplace(0, transistion0);
|
||||
|
||||
return gen;
|
||||
}
|
||||
|
||||
DRAMSys::Config::TraceHammer getTraceHammer()
|
||||
{
|
||||
DRAMSys::Config::TraceHammer hammer;
|
||||
|
||||
hammer.clkMhz = 100;
|
||||
hammer.name = "MyTestHammer";
|
||||
hammer.numRequests = 4000;
|
||||
hammer.rowIncrement = 2097152;
|
||||
|
||||
return hammer;
|
||||
}
|
||||
|
||||
DRAMSys::Config::TraceSetup getTraceSetup()
|
||||
{
|
||||
using namespace DRAMSys::Config;
|
||||
|
||||
std::vector<std::variant<TracePlayer, TraceGenerator, TraceHammer>> initiators;
|
||||
initiators.emplace_back(getTracePlayer());
|
||||
initiators.emplace_back(getTraceGeneratorOneState());
|
||||
initiators.emplace_back(getTraceGeneratorMultipleStates());
|
||||
initiators.emplace_back(getTraceHammer());
|
||||
|
||||
return DRAMSys::Config::TraceSetup{initiators};
|
||||
}
|
||||
|
||||
DRAMSys::Config::Configuration getConfig(const DRAMSys::Config::MemSpec &memSpec)
|
||||
{
|
||||
return DRAMSys::Config::Configuration{
|
||||
getAddressMapping(),
|
||||
getMcConfig(),
|
||||
memSpec,
|
||||
getSimConfig(),
|
||||
"std::string_simulationId",
|
||||
// {{}, false}, works too
|
||||
getTraceSetup(),
|
||||
};
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
DRAMSys::Config::Configuration conf = DRAMSys::Config::from_path("ddr5.json");
|
||||
std::ofstream fileout("myjson.json");
|
||||
json_t j_my;
|
||||
j_my["simulation"] = getConfig(conf.memSpec); // just copy memspec over
|
||||
fileout << j_my.dump(4);
|
||||
|
||||
std::ifstream file2("hbm2.json");
|
||||
json_t hbm2_j = json_t::parse(file2, nullptr, false);
|
||||
json_t hbm2_config = hbm2_j.at("simulation");
|
||||
DRAMSys::Config::Configuration hbm2conf = hbm2_config.get<DRAMSys::Config::Configuration>();
|
||||
std::ofstream filehbm2("myhbm2.json");
|
||||
json_t j_myhbm2;
|
||||
j_myhbm2["simulation"] = hbm2conf;
|
||||
filehbm2 << j_myhbm2.dump(4);
|
||||
|
||||
std::ifstream file3("myjson.json");
|
||||
json_t ddr5_old = json_t::parse(file3, nullptr, false);
|
||||
json_t ddr5_old_conf = ddr5_old.at("simulation");
|
||||
DRAMSys::Config::Configuration ddr5_old_config = ddr5_old_conf.get<DRAMSys::Config::Configuration>();
|
||||
std::ofstream fileoldout("myjson2.json");
|
||||
json_t j_oldconfconv;
|
||||
j_oldconfconv["simulation"] = ddr5_old_config;
|
||||
fileoldout << j_oldconfconv.dump(4);
|
||||
}
|
||||
@@ -118,7 +118,7 @@ protected:
|
||||
DRAMSys::Config::TrafficGenerator traceGeneratorOneState;
|
||||
DRAMSys::Config::TrafficGeneratorStateMachine traceGeneratorMultipleStates;
|
||||
DRAMSys::Config::RowHammer traceHammer;
|
||||
DRAMSys::Config::TraceSetup traceSetup{{tracePlayer, traceGeneratorOneState, traceGeneratorMultipleStates, traceHammer}};
|
||||
std::vector<DRAMSys::Config::Initiator> traceSetup{{tracePlayer, traceGeneratorOneState, traceGeneratorMultipleStates, traceHammer}};
|
||||
|
||||
DRAMSys::Config::Configuration configuration{
|
||||
addressMapping,
|
||||
@@ -310,7 +310,7 @@ TEST(RefreshPolicyType, BackwardsCompatibility)
|
||||
TEST_F(ConfigurationTest, SimConfig)
|
||||
{
|
||||
std::string_view simconfig_string = R"(
|
||||
{
|
||||
{
|
||||
"simconfig": {
|
||||
"AddressOffset": 0,
|
||||
"CheckTLM2Protocol": false,
|
||||
|
||||
42
tests/tests_dramsys/test_utils.cpp
Normal file
42
tests/tests_dramsys/test_utils.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <DRAMSys/common/utils.h>
|
||||
|
||||
using sc_core::sc_time;
|
||||
using sc_core::SC_NS;
|
||||
using sc_core::SC_US;
|
||||
|
||||
TEST(AlignAtNext, FullCycle)
|
||||
{
|
||||
EXPECT_EQ(DRAMSys::alignAtNext(sc_time(5, SC_NS), sc_time(1, SC_NS)), sc_time(5, SC_NS));
|
||||
EXPECT_EQ(DRAMSys::alignAtNext(sc_time(10, SC_NS), sc_time(2, SC_NS)), sc_time(10, SC_NS));
|
||||
EXPECT_EQ(DRAMSys::alignAtNext(sc_time(10, SC_NS), sc_time(10, SC_NS)), sc_time(10, SC_NS));
|
||||
EXPECT_EQ(DRAMSys::alignAtNext(sc_time(100, SC_NS), sc_time(10, SC_NS)), sc_time(100, SC_NS));
|
||||
}
|
||||
|
||||
TEST(AlignAtNext, HalfCycle)
|
||||
{
|
||||
EXPECT_EQ(DRAMSys::alignAtNext(sc_time(0.5, SC_NS), sc_time(1, SC_NS)), sc_time(1, SC_NS));
|
||||
EXPECT_EQ(DRAMSys::alignAtNext(sc_time(5, SC_NS), sc_time(10, SC_NS)), sc_time(10, SC_NS));
|
||||
EXPECT_EQ(DRAMSys::alignAtNext(sc_time(22.5, SC_NS), sc_time(5, SC_NS)), sc_time(25, SC_NS));
|
||||
EXPECT_EQ(DRAMSys::alignAtNext(sc_time(55, SC_NS), sc_time(5, SC_NS)), sc_time(55, SC_NS));
|
||||
}
|
||||
|
||||
TEST(AlignAtNext, ArbitraryCycle)
|
||||
{
|
||||
EXPECT_EQ(DRAMSys::alignAtNext(sc_time(0.37, SC_NS), sc_time(1, SC_NS)), sc_time(1, SC_NS));
|
||||
EXPECT_EQ(DRAMSys::alignAtNext(sc_time(5, SC_NS), sc_time(6.67, SC_NS)), sc_time(6.67, SC_NS));
|
||||
EXPECT_EQ(DRAMSys::alignAtNext(sc_time(4.99, SC_NS), sc_time(5, SC_NS)), sc_time(5, SC_NS));
|
||||
EXPECT_EQ(DRAMSys::alignAtNext(sc_time(0, SC_NS), sc_time(7.77, SC_NS)), sc_time(0, SC_NS));
|
||||
EXPECT_EQ(DRAMSys::alignAtNext(sc_time(4.49, SC_US), sc_time(500, SC_NS)), sc_time(4.5, SC_US));
|
||||
}
|
||||
|
||||
TEST(IsFullCycle, IsFullCycle)
|
||||
{
|
||||
EXPECT_TRUE(DRAMSys::isFullCycle(sc_time(0, SC_NS), sc_time(1, SC_NS)));
|
||||
EXPECT_TRUE(DRAMSys::isFullCycle(sc_time(0, SC_NS), sc_time(1000, SC_US)));
|
||||
EXPECT_TRUE(DRAMSys::isFullCycle(sc_time(5, SC_NS), sc_time(1, SC_NS)));
|
||||
EXPECT_FALSE(DRAMSys::isFullCycle(sc_time(0.5, SC_NS), sc_time(1, SC_NS)));
|
||||
EXPECT_TRUE(DRAMSys::isFullCycle(sc_time(67, SC_US), sc_time(1, SC_NS)));
|
||||
EXPECT_FALSE(DRAMSys::isFullCycle(sc_time(67.05, SC_US), sc_time(100, SC_NS)));
|
||||
}
|
||||
@@ -28,7 +28,7 @@
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Authors:
|
||||
# Authors:
|
||||
# Derek Christ
|
||||
|
||||
###############################################
|
||||
@@ -39,11 +39,10 @@ cmake_minimum_required(VERSION 3.1.0)
|
||||
|
||||
project(tests_regression)
|
||||
|
||||
find_program(Bash bash)
|
||||
find_program(SqlDiff sqldiff)
|
||||
|
||||
if(NOT Bash OR NOT SqlDiff)
|
||||
message(WARNING "Regression tests require bash and sqldiff to be installed")
|
||||
if(NOT SqlDiff)
|
||||
message(WARNING "Regression tests require sqldiff to be installed")
|
||||
return()
|
||||
endif()
|
||||
|
||||
@@ -53,45 +52,53 @@ set(TABLES_TO_COMPARE
|
||||
Power
|
||||
)
|
||||
|
||||
function(test_standard standard base_config resource_dir output_filename)
|
||||
# Put all the generated files into a subdirectory
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${standard})
|
||||
function(test_standard standard test_name base_config resource_dir output_filename)
|
||||
if(NOT IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${standard})
|
||||
message(WARNING "Cannot find regression test ${standard}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
configure_file(compare.sh ${standard}/compare.sh)
|
||||
# Put all the generated files into a subdirectory
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${test_name})
|
||||
|
||||
# Test to create database
|
||||
add_test(
|
||||
NAME Regression${standard}.CreateDatabase
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${standard}
|
||||
NAME Regression${test_name}.CreateDatabase
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${test_name}
|
||||
COMMAND $<TARGET_FILE:DRAMSys> ${base_config} ${resource_dir}
|
||||
)
|
||||
set_tests_properties(Regression${standard}.CreateDatabase PROPERTIES FIXTURES_SETUP Regression${standard}.CreateDatabase)
|
||||
set_tests_properties(Regression${test_name}.CreateDatabase PROPERTIES FIXTURES_SETUP Regression${test_name}.CreateDatabase)
|
||||
|
||||
# Test to diff the whole database. This test should not fail.
|
||||
# The purpose of this test is solely to output the differences of the two databases
|
||||
# so that they can be inspected easily.
|
||||
add_test(
|
||||
NAME Regression${standard}.SqlDiff
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${standard}
|
||||
COMMAND compare.sh
|
||||
NAME Regression${test_name}.SqlDiff
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${test_name}
|
||||
COMMAND sqldiff ${CMAKE_CURRENT_SOURCE_DIR}/${standard}/expected/${output_filename} ${output_filename}
|
||||
)
|
||||
set_tests_properties(Regression${standard}.SqlDiff PROPERTIES FIXTURES_REQUIRED Regression${standard}.CreateDatabase)
|
||||
set_tests_properties(Regression${test_name}.SqlDiff PROPERTIES FIXTURES_REQUIRED Regression${test_name}.CreateDatabase)
|
||||
|
||||
# Tests to diff individual tables
|
||||
foreach(table IN LISTS TABLES_TO_COMPARE)
|
||||
configure_file(compare_table.sh ${standard}/compare_table-${table}.sh)
|
||||
|
||||
add_test(
|
||||
NAME Regression${standard}.SqlDiff.${table}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${standard}
|
||||
COMMAND compare_table-${table}.sh
|
||||
NAME Regression${test_name}.SqlDiff.${table}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${test_name}
|
||||
COMMAND sqldiff --table ${table} ${CMAKE_CURRENT_SOURCE_DIR}/${standard}/expected/${output_filename} ${output_filename}
|
||||
)
|
||||
set_tests_properties(Regression${standard}.SqlDiff.${table} PROPERTIES FIXTURES_REQUIRED Regression${standard}.CreateDatabase)
|
||||
set_tests_properties(Regression${test_name}.SqlDiff.${table} PROPERTIES FIXTURES_REQUIRED Regression${test_name}.CreateDatabase)
|
||||
|
||||
# Only pass test if output is empty
|
||||
set_tests_properties(Regression${test_name}.SqlDiff.${table} PROPERTIES PASS_REGULAR_EXPRESSION "^$")
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
test_standard(DDR3 ${CMAKE_CURRENT_SOURCE_DIR}/DDR3/ddr3-example.json ${CMAKE_CURRENT_SOURCE_DIR}/DDR3 DRAMSys_ddr3-dual-rank_ddr3_ch0.tdb)
|
||||
test_standard(DDR4 ${CMAKE_CURRENT_SOURCE_DIR}/DDR4/ddr4-example.json ${CMAKE_CURRENT_SOURCE_DIR}/DDR4 DRAMSys_ddr4-bankgrp_ddr4_ch0.tdb)
|
||||
test_standard(LPDDR4 ${CMAKE_CURRENT_SOURCE_DIR}/LPDDR4/lpddr4-example.json ${CMAKE_CURRENT_SOURCE_DIR}/LPDDR4 DRAMSys_lpddr4-example_lpddr4_ch0.tdb)
|
||||
test_standard(HBM2.Ch0 ${CMAKE_CURRENT_SOURCE_DIR}/HBM2/hbm2-example.json ${CMAKE_CURRENT_SOURCE_DIR}/HBM2 DRAMSys_hbm2-example_hbm2_ch0.tdb)
|
||||
test_standard(HBM2.Ch1 ${CMAKE_CURRENT_SOURCE_DIR}/HBM2/hbm2-example.json ${CMAKE_CURRENT_SOURCE_DIR}/HBM2 DRAMSys_hbm2-example_hbm2_ch1.tdb)
|
||||
test_standard(DDR3 DDR3 ${CMAKE_CURRENT_SOURCE_DIR}/DDR3/ddr3-example.json ${CMAKE_CURRENT_SOURCE_DIR}/DDR3 DRAMSys_ddr3-dual-rank_ddr3_ch0.tdb)
|
||||
test_standard(DDR4 DDR4 ${CMAKE_CURRENT_SOURCE_DIR}/DDR4/ddr4-example.json ${CMAKE_CURRENT_SOURCE_DIR}/DDR4 DRAMSys_ddr4-bankgrp_ddr4_ch0.tdb)
|
||||
test_standard(DDR5 DDR5.Ch0 ${CMAKE_CURRENT_SOURCE_DIR}/DDR5/ddr5-example.json ${CMAKE_CURRENT_SOURCE_DIR}/DDR5 DRAMSys_ddr5-example_ddr5_ch0.tdb)
|
||||
test_standard(DDR5 DDR5.Ch1 ${CMAKE_CURRENT_SOURCE_DIR}/DDR5/ddr5-example.json ${CMAKE_CURRENT_SOURCE_DIR}/DDR5 DRAMSys_ddr5-example_ddr5_ch1.tdb)
|
||||
test_standard(LPDDR4 LPDDR4 ${CMAKE_CURRENT_SOURCE_DIR}/LPDDR4/lpddr4-example.json ${CMAKE_CURRENT_SOURCE_DIR}/LPDDR4 DRAMSys_lpddr4-example_lpddr4_ch0.tdb)
|
||||
test_standard(LPDDR5 LPDDR5 ${CMAKE_CURRENT_SOURCE_DIR}/LPDDR5/lpddr5-example.json ${CMAKE_CURRENT_SOURCE_DIR}/LPDDR5 DRAMSys_lpddr5-example_lpddr5_ch0.tdb)
|
||||
test_standard(HBM2 HBM2.Ch0 ${CMAKE_CURRENT_SOURCE_DIR}/HBM2/hbm2-example.json ${CMAKE_CURRENT_SOURCE_DIR}/HBM2 DRAMSys_hbm2-example_hbm2_ch0.tdb)
|
||||
test_standard(HBM2 HBM2.Ch1 ${CMAKE_CURRENT_SOURCE_DIR}/HBM2/hbm2-example.json ${CMAKE_CURRENT_SOURCE_DIR}/HBM2 DRAMSys_hbm2-example_hbm2_ch1.tdb)
|
||||
test_standard(HBM3 HBM3 ${CMAKE_CURRENT_SOURCE_DIR}/HBM3/hbm3-example.json ${CMAKE_CURRENT_SOURCE_DIR}/HBM3 DRAMSys_hbm3-example_hbm3_ch0.tdb)
|
||||
|
||||
165
tests/tests_regression/DDR5/ddr5-example.json
Normal file
165
tests/tests_regression/DDR5/ddr5-example.json
Normal file
@@ -0,0 +1,165 @@
|
||||
{
|
||||
"simulation": {
|
||||
"addressmapping": {
|
||||
"BANKGROUP_BIT": [
|
||||
13,
|
||||
14,
|
||||
15
|
||||
],
|
||||
"BANK_BIT": [
|
||||
16
|
||||
],
|
||||
"BYTE_BIT": [
|
||||
0,
|
||||
1
|
||||
],
|
||||
"CHANNEL_BIT": [
|
||||
33
|
||||
],
|
||||
"COLUMN_BIT": [
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12
|
||||
],
|
||||
"ROW_BIT": [
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
31,
|
||||
32
|
||||
]
|
||||
},
|
||||
"mcconfig": {
|
||||
"Arbiter": "Simple",
|
||||
"CmdMux": "Oldest",
|
||||
"MaxActiveTransactions": 128,
|
||||
"PagePolicy": "Open",
|
||||
"PowerDownPolicy": "NoPowerDown",
|
||||
"RefreshManagement": false,
|
||||
"RefreshMaxPostponed": 0,
|
||||
"RefreshMaxPulledin": 0,
|
||||
"RefreshPolicy": "AllBank",
|
||||
"RequestBufferSize": 8,
|
||||
"RespQueue": "Fifo",
|
||||
"Scheduler": "FrFcfs",
|
||||
"SchedulerBuffer": "Bankwise"
|
||||
},
|
||||
"memspec": {
|
||||
"memarchitecturespec": {
|
||||
"RAADEC": 16,
|
||||
"RAAIMT": 32,
|
||||
"RAAMMT": 96,
|
||||
"burstLength": 16,
|
||||
"cmdMode": 1,
|
||||
"dataRate": 2,
|
||||
"nbrOfBankGroups": 8,
|
||||
"nbrOfBanks": 16,
|
||||
"nbrOfChannels": 2,
|
||||
"nbrOfColumns": 2048,
|
||||
"nbrOfDIMMRanks": 1,
|
||||
"nbrOfDevices": 8,
|
||||
"nbrOfLogicalRanks": 1,
|
||||
"nbrOfPhysicalRanks": 1,
|
||||
"nbrOfRanks": 1,
|
||||
"nbrOfRows": 65536,
|
||||
"refMode": 1,
|
||||
"width": 4
|
||||
},
|
||||
"memoryId": "JEDEC_2x8x2Gbx4_DDR5-3200A",
|
||||
"memoryType": "DDR5",
|
||||
"memtimingspec": {
|
||||
"ACTPDEN": 2,
|
||||
"CCD_L_WR2_slr": 16,
|
||||
"CCD_L_WR_slr": 32,
|
||||
"CCD_L_slr": 8,
|
||||
"CCD_M_WR_slr": 32,
|
||||
"CCD_M_slr": 8,
|
||||
"CCD_S_WR_slr": 8,
|
||||
"CCD_S_slr": 8,
|
||||
"CCD_WR_dlr": 0,
|
||||
"CCD_WR_dpr": 0,
|
||||
"CCD_dlr": 0,
|
||||
"CPDED": 8,
|
||||
"FAW_dlr": 0,
|
||||
"FAW_slr": 32,
|
||||
"PD": 12,
|
||||
"PPD": 2,
|
||||
"PRPDEN": 2,
|
||||
"RAS": 52,
|
||||
"RCD": 22,
|
||||
"RDDQS": 0,
|
||||
"REFI1": 6240,
|
||||
"REFI2": 3120,
|
||||
"REFISB": 1560,
|
||||
"REFPDEN": 2,
|
||||
"REFSBRD_dlr": 0,
|
||||
"REFSBRD_slr": 48,
|
||||
"RFC1_dlr": 0,
|
||||
"RFC1_dpr": 0,
|
||||
"RFC1_slr": 312,
|
||||
"RFC2_dlr": 0,
|
||||
"RFC2_dpr": 0,
|
||||
"RFC2_slr": 208,
|
||||
"RFCsb_dlr": 0,
|
||||
"RFCsb_slr": 184,
|
||||
"RL": 22,
|
||||
"RP": 22,
|
||||
"RPRE": 1,
|
||||
"RPST": 0,
|
||||
"RRD_L_slr": 8,
|
||||
"RRD_S_slr": 8,
|
||||
"RRD_dlr": 0,
|
||||
"RTP": 12,
|
||||
"RTRS": 2,
|
||||
"WL": 20,
|
||||
"WPRE": 2,
|
||||
"WPST": 0,
|
||||
"WR": 48,
|
||||
"WTR_L": 16,
|
||||
"WTR_M": 16,
|
||||
"WTR_S": 4,
|
||||
"XP": 12,
|
||||
"clkMhz": 1600
|
||||
}
|
||||
},
|
||||
"simconfig": {
|
||||
"AddressOffset": 0,
|
||||
"CheckTLM2Protocol": false,
|
||||
"DatabaseRecording": true,
|
||||
"Debug": false,
|
||||
"EnableWindowing": false,
|
||||
"PowerAnalysis": false,
|
||||
"SimulationName": "ddr5",
|
||||
"SimulationProgressBar": true,
|
||||
"StoreMode": "NoStorage",
|
||||
"UseMalloc": false,
|
||||
"WindowSize": 1000
|
||||
},
|
||||
"simulationid": "ddr5-example",
|
||||
"tracesetup": [
|
||||
{
|
||||
"clkMhz": 1600,
|
||||
"name": "trace_test3.stl"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user