Merge develop

This commit is contained in:
2023-08-21 10:01:08 +02:00
117 changed files with 3036 additions and 2858 deletions

View File

@@ -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

View File

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

View File

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

View File

@@ -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

View File

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

View File

@@ -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?

View File

@@ -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

View File

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

View File

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

View File

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

View File

@@ -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()

View File

@@ -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,

View File

@@ -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

View File

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

View File

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

View File

@@ -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"

View File

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

View File

@@ -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:

View File

@@ -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

View File

@@ -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

View File

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

View File

@@ -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()
{

View File

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

View File

@@ -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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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

View File

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

View File

@@ -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

View File

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

View File

@@ -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

View File

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

View File

@@ -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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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)),

View File

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

View File

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

View File

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

View File

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

View File

@@ -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)),

View File

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

View File

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

View File

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

View File

@@ -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

View File

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

View File

@@ -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

View File

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

View File

@@ -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

View File

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

View File

@@ -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

View File

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

View File

@@ -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

View File

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

View File

@@ -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

View File

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

View File

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

View File

@@ -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

View File

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

View File

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

View File

@@ -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`.

View File

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

View File

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

View File

@@ -38,6 +38,7 @@
#include "MemoryManager.h"
#include <cstdint>
#include <list>
#include <queue>
#include <systemc>

View File

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

View 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;
}

View 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;
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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:

View File

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

View File

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

View File

@@ -51,6 +51,5 @@ public:
virtual Request nextRequest() = 0;
virtual uint64_t totalRequests() = 0;
virtual sc_core::sc_time clkPeriod() = 0;
virtual void reset(){};
};

View File

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

View File

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

View File

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

View File

@@ -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,

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

View File

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

View 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