Merge branch 'feat/internal_length_conv2' into 'develop'

Internal length conversion and new database format.

See merge request ems/astdm/modeling.dram/dram.sys!363
This commit is contained in:
2022-08-25 15:31:57 +00:00
94 changed files with 1951 additions and 1608 deletions

View File

@@ -65,8 +65,10 @@ public:
private:
DebugManager();
DebugManager(const DebugManager &);
DebugManager & operator = (const DebugManager &);
public:
DebugManager(const DebugManager&) = delete;
DebugManager& operator=(const DebugManager&) = delete;
public:
void setup(bool _debugEnabled, bool _writeToConsole, bool _writeToFile);

View File

@@ -51,7 +51,8 @@ using namespace sc_core;
using namespace tlm;
TlmRecorder::TlmRecorder(const std::string& name, const Configuration& config, const std::string& dbName) :
name(name), config(config), totalNumTransactions(0), simulationTimeCoveredByRecording(SC_ZERO_TIME)
name(name), config(config), memSpec(*config.memSpec), totalNumTransactions(0),
simulationTimeCoveredByRecording(SC_ZERO_TIME)
{
currentDataBuffer = &recordingDataBuffer[0];
storageDataBuffer = &recordingDataBuffer[1];
@@ -85,7 +86,6 @@ void TlmRecorder::finalize()
sqlite3_finalize(insertGeneralInfoStatement);
sqlite3_finalize(insertCommandLengthsStatement);
sqlite3_finalize(insertDebugMessageStatement);
sqlite3_finalize(updateDataStrobeStatement);
sqlite3_finalize(insertPowerStatement);
sqlite3_finalize(insertBufferDepthStatement);
sqlite3_finalize(insertBandwidthStatement);
@@ -116,57 +116,86 @@ void TlmRecorder::recordBandwidth(double timeInSeconds, double averageBandwidth)
executeSqlStatement(insertBandwidthStatement);
}
void TlmRecorder::recordPhase(tlm_generic_payload &trans,
const tlm_phase &phase, const sc_time &time)
void TlmRecorder::recordPhase(tlm_generic_payload& trans, const tlm_phase& phase, const sc_time& delay)
{
if (currentTransactionsInSystem.find(&trans) == currentTransactionsInSystem.end())
introduceTransactionSystem(trans);
const sc_time& currentTime = sc_time_stamp();
if (phase == END_REQ || phase == END_RESP || phase >= END_PDNA)
if (phase == BEGIN_REQ)
{
assert(getPhaseName(phase).substr(4) == currentTransactionsInSystem[&trans].recordedPhases.back().name);
currentTransactionsInSystem[&trans].recordedPhases.back().interval.end = time;
introduceTransactionToSystem(trans);
std::string phaseName = getPhaseName(phase).substr(6);
currentTransactionsInSystem.at(&trans).recordedPhases.emplace_back(phaseName, currentTime + delay);
}
else
if (phase == BEGIN_RESP)
{
std::string phaseName = getPhaseName(phase).substr(6);
currentTransactionsInSystem.at(&trans).recordedPhases.emplace_back(phaseName, currentTime + delay);
}
else if (phase == END_REQ)
{
// BEGIN_REQ is always the first phase of a normal transaction
currentTransactionsInSystem.at(&trans).recordedPhases.front().interval.end = currentTime + delay;
}
else if (phase == END_RESP)
{
// BEGIN_RESP is always the last phase of a normal transaction at this point
currentTransactionsInSystem.at(&trans).recordedPhases.back().interval.end = currentTime + delay;
removeTransactionFromSystem(trans);
}
else if (isFixedCommandPhase(phase))
{
tlm_generic_payload* keyTrans;
if (ChildExtension::isChildTrans(trans))
{
keyTrans = &ChildExtension::getParentTrans(trans);
}
else
{
if (currentTransactionsInSystem.find(&trans) == currentTransactionsInSystem.end())
introduceTransactionToSystem(trans);
keyTrans = &trans;
}
std::string phaseName = getPhaseName(phase).substr(6); // remove "BEGIN_"
currentTransactionsInSystem[&trans].recordedPhases.emplace_back(phaseName, time);
}
const ControllerExtension& extension = ControllerExtension::getExtension(trans);
TimeInterval intervalOnDataStrobe;
if (phaseHasDataStrobe(phase))
{
intervalOnDataStrobe = memSpec.getIntervalOnDataStrobe(Command(phase), trans);
intervalOnDataStrobe.start = currentTime + intervalOnDataStrobe.start;
intervalOnDataStrobe.end = currentTime + intervalOnDataStrobe.end;
}
if (currentTransactionsInSystem[&trans].cmd == 'X')
{
if (phase == END_REFAB
|| phase == END_RFMAB
|| phase == END_REFPB
|| phase == END_RFMPB
|| phase == END_REFP2B
|| phase == END_RFMP2B
|| phase == END_REFSB
|| phase == END_RFMSB
|| phase == END_PDNA
|| phase == END_PDNP
|| phase == END_SREF)
currentTransactionsInSystem.at(keyTrans).recordedPhases.emplace_back(std::move(phaseName),
std::move(TimeInterval(currentTime + delay,
currentTime + delay + memSpec.getExecutionTime(Command(phase), trans))),
std::move(intervalOnDataStrobe), extension.getRank(), extension.getBankGroup(), extension.getBank(),
extension.getRow(), extension.getColumn(), extension.getBurstLength());
if (isRefreshCommandPhase(phase))
removeTransactionFromSystem(trans);
}
else
else if (isPowerDownEntryPhase(phase))
{
if (phase == END_RESP)
removeTransactionFromSystem(trans);
introduceTransactionToSystem(trans);
std::string phaseName = getPhaseName(phase).substr(6); // remove "BEGIN_"
const ControllerExtension& extension = ControllerExtension::getExtension(trans);
currentTransactionsInSystem.at(&trans).recordedPhases.emplace_back(std::move(phaseName),
std::move(TimeInterval(currentTime + delay, SC_ZERO_TIME)),
std::move(TimeInterval(SC_ZERO_TIME, SC_ZERO_TIME)),
extension.getRank(), extension.getBankGroup(), extension.getBank(),
extension.getRow(), extension.getColumn(), extension.getBurstLength());
}
else if (isPowerDownExitPhase(phase))
{
currentTransactionsInSystem.at(&trans).recordedPhases.back().interval.end = currentTime + delay
+ memSpec.getCommandLength(Command(phase));
removeTransactionFromSystem(trans);
}
simulationTimeCoveredByRecording = time;
simulationTimeCoveredByRecording = currentTime + delay;
}
void TlmRecorder::updateDataStrobe(const sc_time &begin, const sc_time &end,
tlm_generic_payload &trans)
{
assert(currentTransactionsInSystem.count(&trans) != 0);
currentTransactionsInSystem[&trans].timeOnDataStrobe.start = begin;
currentTransactionsInSystem[&trans].timeOnDataStrobe.end = end;
}
void TlmRecorder::recordDebugMessage(const std::string &message, const sc_time &time)
{
insertDebugMessageInDB(message, time);
@@ -175,24 +204,27 @@ void TlmRecorder::recordDebugMessage(const std::string &message, const sc_time &
// ------------- internal -----------------------
void TlmRecorder::introduceTransactionSystem(tlm_generic_payload &trans)
void TlmRecorder::introduceTransactionToSystem(tlm_generic_payload& trans)
{
totalNumTransactions++;
currentTransactionsInSystem[&trans].id = totalNumTransactions;
char commandChar;
tlm_command command = trans.get_command();
if (command == TLM_READ_COMMAND)
currentTransactionsInSystem[&trans].cmd = 'R';
commandChar = 'R';
else if (command == TLM_WRITE_COMMAND)
currentTransactionsInSystem[&trans].cmd = 'W';
commandChar = 'W';
else
currentTransactionsInSystem[&trans].cmd = 'X';
currentTransactionsInSystem[&trans].address = trans.get_address();
currentTransactionsInSystem[&trans].burstLength = DramExtension::getBurstLength(trans);
currentTransactionsInSystem[&trans].dramExtension = DramExtension::getExtension(trans);
currentTransactionsInSystem[&trans].timeOfGeneration = GenerationExtension::getTimeOfGeneration(trans);
commandChar = 'X';
const ArbiterExtension& extension = ArbiterExtension::getExtension(trans);
currentTransactionsInSystem.insert({&trans, Transaction(totalNumTransactions, trans.get_address(),
trans.get_data_length(), commandChar, extension.getTimeOfGeneration(), extension.getThread(),
extension.getChannel())});
PRINTDEBUGMESSAGE(name, "New transaction #" + std::to_string(totalNumTransactions) + " generation time " +
currentTransactionsInSystem[&trans].timeOfGeneration.to_string());
currentTransactionsInSystem.at(&trans).timeOfGeneration.to_string());
}
void TlmRecorder::removeTransactionFromSystem(tlm_generic_payload &trans)
@@ -200,9 +232,9 @@ void TlmRecorder::removeTransactionFromSystem(tlm_generic_payload &trans)
assert(currentTransactionsInSystem.count(&trans) != 0);
PRINTDEBUGMESSAGE(name, "Removing transaction #" +
std::to_string(currentTransactionsInSystem[&trans].id));
std::to_string(currentTransactionsInSystem.at(&trans).id));
Transaction &recordingData = currentTransactionsInSystem[&trans];
Transaction& recordingData = currentTransactionsInSystem.at(&trans);
currentDataBuffer->push_back(recordingData);
currentTransactionsInSystem.erase(&trans);
@@ -230,11 +262,11 @@ void TlmRecorder::terminateRemainingTransactions()
{
std::string beginPhase = transaction->second.recordedPhases.front().name;
if (beginPhase == "PDNA")
recordPhase(*(transaction->first), END_PDNA, sc_time_stamp());
recordPhase(*(transaction->first), END_PDNA, SC_ZERO_TIME);
else if (beginPhase == "PDNP")
recordPhase(*(transaction->first), END_PDNP, sc_time_stamp());
recordPhase(*(transaction->first), END_PDNP, SC_ZERO_TIME);
else if (beginPhase == "SREF")
recordPhase(*(transaction->first), END_SREF, sc_time_stamp());
recordPhase(*(transaction->first), END_SREF, SC_ZERO_TIME);
else
removeTransactionFromSystem(*transaction->first);
}
@@ -243,7 +275,7 @@ void TlmRecorder::terminateRemainingTransactions()
std::string beginPhase = transaction->second.recordedPhases.back().name;
if (beginPhase == "RESP")
recordPhase(*(transaction->first), END_RESP, sc_time_stamp());
recordPhase(*(transaction->first), END_RESP, SC_ZERO_TIME);
else
{
// Do not terminate transaction as it is not ready to be completed.
@@ -259,23 +291,22 @@ void TlmRecorder::terminateRemainingTransactions()
void TlmRecorder::commitRecordedDataToDB()
{
sqlite3_exec(db, "BEGIN;", nullptr, nullptr, nullptr);
for (Transaction &recordingData : *storageDataBuffer)
for (const Transaction& transaction : *storageDataBuffer)
{
assert(!recordingData.recordedPhases.empty());
insertTransactionInDB(recordingData);
for (Transaction::Phase &phaseData : recordingData.recordedPhases)
assert(!transaction.recordedPhases.empty());
insertTransactionInDB(transaction);
for (const Transaction::Phase& phase : transaction.recordedPhases)
{
insertPhaseInDB(phaseData.name, phaseData.interval.start,
phaseData.interval.end, recordingData.id);
insertPhaseInDB(phase, transaction.id);
}
sc_time rangeBegin = recordingData.recordedPhases.front().interval.start;
sc_time rangeBegin = transaction.recordedPhases.front().interval.start;
sc_time rangeEnd = rangeBegin;
for (auto &it : recordingData.recordedPhases)
for (const Transaction::Phase& phase : transaction.recordedPhases)
{
rangeEnd = std::max(rangeEnd, it.interval.end);
rangeEnd = std::max(rangeEnd, phase.interval.end);
}
insertRangeInDB(recordingData.id, rangeBegin, rangeEnd);
insertRangeInDB(transaction.id, rangeBegin, rangeEnd);
}
sqlite3_exec(db, "COMMIT;", nullptr, nullptr, nullptr);
@@ -302,18 +333,17 @@ void TlmRecorder::openDB(const std::string &dbName)
void TlmRecorder::prepareSqlStatements()
{
insertTransactionString =
"INSERT INTO Transactions VALUES (:id,:rangeID,:address,:burstlength,:thread,:channel,:rank,"
":bankgroup,:bank,:row,:column,:dataStrobeBegin,:dataStrobeEnd, :timeOfGeneration,:command)";
"INSERT INTO Transactions VALUES (:id,:rangeID,:address,:dataLength,:thread,:channel,"
":timeOfGeneration,:command)";
insertRangeString = "INSERT INTO Ranges VALUES (:id,:begin,:end)";
updateRangeString = "UPDATE Ranges SET End = :end WHERE ID = :id";
updateDataStrobeString =
"UPDATE Transactions SET DataStrobeBegin = :begin, DataStrobeEnd = :end WHERE ID = :id";
insertPhaseString =
"INSERT INTO Phases (PhaseName,PhaseBegin,PhaseEnd,Transact) VALUES (:name,:begin,:end,:transaction)";
"INSERT INTO Phases (PhaseName,PhaseBegin,PhaseEnd,DataStrobeBegin,DataStrobeEnd,Rank,BankGroup,Bank,"
"Row,Column,BurstLength,Transact) VALUES (:name,:begin,:end,:strobeBegin,:strobeEnd,:rank,:bankGroup,:bank,"
":row,:column,:burstLength,:transaction)";
updatePhaseString =
"UPDATE Phases SET PhaseEnd = :end WHERE Transact = :trans AND PhaseName = :name";
@@ -339,7 +369,6 @@ void TlmRecorder::prepareSqlStatements()
sqlite3_prepare_v2(db, updateRangeString.c_str(), -1, &updateRangeStatement, nullptr);
sqlite3_prepare_v2(db, insertPhaseString.c_str(), -1, &insertPhaseStatement, nullptr);
sqlite3_prepare_v2(db, updatePhaseString.c_str(), -1, &updatePhaseStatement, nullptr);
sqlite3_prepare_v2(db, updateDataStrobeString.c_str(), -1, &updateDataStrobeStatement, nullptr);
sqlite3_prepare_v2(db, insertGeneralInfoString.c_str(), -1, &insertGeneralInfoStatement, nullptr);
sqlite3_prepare_v2(db, insertCommandLengthsString.c_str(), -1, &insertCommandLengthsStatement, nullptr);
sqlite3_prepare_v2(db, insertDebugMessageString.c_str(), -1, &insertDebugMessageStatement, nullptr);
@@ -375,7 +404,7 @@ void TlmRecorder::insertGeneralInfo()
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_int64(insertGeneralInfoStatement, 14, static_cast<int64_t>(UINT64_MAX));
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()));
@@ -404,7 +433,7 @@ void TlmRecorder::insertCommandLengths()
auto commandName = command.toString();
sqlite3_bind_text(insertCommandLengthsStatement, 1, commandName.c_str(), commandName.length(), nullptr);
sqlite3_bind_double(insertCommandLengthsStatement, 2, memSpec.getCommandLengthInCylcles(command));
sqlite3_bind_double(insertCommandLengthsStatement, 2, memSpec.getCommandLengthInCycles(command));
executeSqlStatement(insertCommandLengthsStatement);
};
@@ -412,33 +441,19 @@ void TlmRecorder::insertCommandLengths()
insertCommandLength(static_cast<Command::Type>(command));
}
void TlmRecorder::insertTransactionInDB(Transaction &recordingData)
void TlmRecorder::insertTransactionInDB(const Transaction &recordingData)
{
sqlite3_bind_int(insertTransactionStatement, 1, static_cast<int>(recordingData.id));
sqlite3_bind_int(insertTransactionStatement, 2, static_cast<int>(recordingData.id));
sqlite3_bind_int64(insertTransactionStatement, 3, static_cast<int64_t>(recordingData.address));
sqlite3_bind_int(insertTransactionStatement, 4, static_cast<int>(recordingData.burstLength));
sqlite3_bind_int(insertTransactionStatement, 4, static_cast<int>(recordingData.dataLength));
sqlite3_bind_int(insertTransactionStatement, 5,
static_cast<int>(recordingData.dramExtension.getThread().ID()));
static_cast<int>(recordingData.thread.ID()));
sqlite3_bind_int(insertTransactionStatement, 6,
static_cast<int>(recordingData.dramExtension.getChannel().ID()));
sqlite3_bind_int(insertTransactionStatement, 7,
static_cast<int>(recordingData.dramExtension.getRank().ID()));
sqlite3_bind_int(insertTransactionStatement, 8,
static_cast<int>(recordingData.dramExtension.getBankGroup().ID()));
sqlite3_bind_int(insertTransactionStatement, 9,
static_cast<int>(recordingData.dramExtension.getBank().ID()));
sqlite3_bind_int(insertTransactionStatement, 10,
static_cast<int>(recordingData.dramExtension.getRow().ID()));
sqlite3_bind_int(insertTransactionStatement, 11,
static_cast<int>(recordingData.dramExtension.getColumn().ID()));
sqlite3_bind_int64(insertTransactionStatement, 12,
static_cast<int64_t>(recordingData.timeOnDataStrobe.start.value()));
sqlite3_bind_int64(insertTransactionStatement, 13,
static_cast<int64_t>(recordingData.timeOnDataStrobe.end.value()));
sqlite3_bind_int64(insertTransactionStatement, 14,
static_cast<int>(recordingData.channel.ID()));
sqlite3_bind_int64(insertTransactionStatement, 7,
static_cast<int64_t>(recordingData.timeOfGeneration.value()));
sqlite3_bind_text(insertTransactionStatement, 15,
sqlite3_bind_text(insertTransactionStatement, 8,
&recordingData.cmd, 1, nullptr);
executeSqlStatement(insertTransactionStatement);
@@ -453,15 +468,20 @@ void TlmRecorder::insertRangeInDB(uint64_t id, const sc_time &begin,
executeSqlStatement(insertRangeStatement);
}
void TlmRecorder::insertPhaseInDB(const std::string &phaseName, const sc_time &begin,
const sc_time &end,
uint64_t transactionID)
void TlmRecorder::insertPhaseInDB(const Transaction::Phase& phase, uint64_t transactionID)
{
sqlite3_bind_text(insertPhaseStatement, 1, phaseName.c_str(),
static_cast<int>(phaseName.length()), nullptr);
sqlite3_bind_int64(insertPhaseStatement, 2, static_cast<int64_t>(begin.value()));
sqlite3_bind_int64(insertPhaseStatement, 3, static_cast<int64_t>(end.value()));
sqlite3_bind_int64(insertPhaseStatement, 4, static_cast<int64_t>(transactionID));
sqlite3_bind_text(insertPhaseStatement, 1, phase.name.c_str(), static_cast<int>(phase.name.length()), nullptr);
sqlite3_bind_int64(insertPhaseStatement, 2, static_cast<int64_t>(phase.interval.start.value()));
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, 11, static_cast<int>(phase.burstLength));
sqlite3_bind_int64(insertPhaseStatement, 12, static_cast<int64_t>(transactionID));
executeSqlStatement(insertPhaseStatement);
}

View File

@@ -46,6 +46,7 @@
#include <thread>
#include <tlm>
#include <unordered_map>
#include <utility>
#include <vector>
#include "../configuration/Configuration.h"
@@ -77,37 +78,52 @@ public:
traces = std::move(_traces);
}
void recordPhase(tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase, const sc_core::sc_time &time);
void recordPhase(tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase, const sc_core::sc_time& delay);
void recordPower(double timeInSeconds, double averagePower);
void recordBufferDepth(double timeInSeconds, const std::vector<double> &averageBufferDepth);
void recordBandwidth(double timeInSeconds, double averageBandwidth);
void recordDebugMessage(const std::string &message, const sc_core::sc_time &time);
void updateDataStrobe(const sc_core::sc_time &begin, const sc_core::sc_time &end,
tlm::tlm_generic_payload &trans);
void finalize();
private:
const Configuration& config;
const MemSpec& memSpec;
struct Transaction
{
Transaction() = default;
explicit Transaction(uint64_t id) : id(id) {}
Transaction(const Transaction& other) = default;
Transaction(uint64_t id, uint64_t address, unsigned int dataLength, char cmd,
const sc_core::sc_time& timeOfGeneration, Thread thread, Channel channel) :
id(id), address(address), dataLength(dataLength), cmd(cmd), timeOfGeneration(timeOfGeneration),
thread(thread), channel(channel) {}
uint64_t id = 0;
uint64_t address = 0;
unsigned int burstLength = 0;
unsigned int dataLength = 0;
char cmd = 'X';
DramExtension dramExtension;
sc_core::sc_time timeOfGeneration;
TimeInterval timeOnDataStrobe;
Thread thread;
Channel channel;
struct Phase
{
Phase(std::string name, const sc_core::sc_time& begin): name(std::move(name)),
// for BEGIN_REQ and BEGIN_RESP
Phase(std::string name, const sc_core::sc_time& begin) : name(std::move(name)),
interval(begin, sc_core::SC_ZERO_TIME) {}
Phase(std::string name, TimeInterval interval, TimeInterval intervalOnDataStrobe, Rank rank,
BankGroup bankGroup, Bank bank, Row row, Column column, unsigned int burstLength) :
name(std::move(name)), interval(std::move(interval)),
intervalOnDataStrobe(std::move(intervalOnDataStrobe)), rank(rank), bankGroup(bankGroup), bank(bank),
row(row), column(column), burstLength(burstLength) {}
std::string name;
TimeInterval interval;
TimeInterval intervalOnDataStrobe = {sc_core::SC_ZERO_TIME, sc_core::SC_ZERO_TIME};
Rank rank = Rank(0);
BankGroup bankGroup = BankGroup(0);
Bank bank = Bank(0);
Row row = Row(0);
Column column = Column(0);
unsigned int burstLength = 0;
};
std::vector<Phase> recordedPhases;
};
@@ -123,17 +139,16 @@ private:
void openDB(const std::string &dbName);
void closeConnection();
void introduceTransactionSystem(tlm::tlm_generic_payload &trans);
void introduceTransactionToSystem(tlm::tlm_generic_payload &trans);
void removeTransactionFromSystem(tlm::tlm_generic_payload &trans);
void terminateRemainingTransactions();
void commitRecordedDataToDB();
void insertGeneralInfo();
void insertCommandLengths();
void insertTransactionInDB(Transaction &recordingData);
void insertTransactionInDB(const Transaction& recordingData);
void insertRangeInDB(uint64_t id, const sc_core::sc_time &begin, const sc_core::sc_time &end);
void insertPhaseInDB(const std::string &phaseName, const sc_core::sc_time &begin, const sc_core::sc_time &end,
uint64_t transactionID);
void insertPhaseInDB(const Transaction::Phase& phase, uint64_t transactionID);
void insertDebugMessageInDB(const std::string &message, const sc_core::sc_time &time);
static constexpr unsigned transactionCommitRate = 8192;
@@ -142,7 +157,7 @@ private:
std::vector<Transaction> *storageDataBuffer;
std::thread storageThread;
std::unordered_map<tlm::tlm_generic_payload *, Transaction> currentTransactionsInSystem;
std::unordered_map<tlm::tlm_generic_payload*, Transaction> currentTransactionsInSystem;
uint64_t totalNumTransactions;
sc_core::sc_time simulationTimeCoveredByRecording;
@@ -151,11 +166,11 @@ private:
sqlite3_stmt *insertTransactionStatement = nullptr, *insertRangeStatement = nullptr,
*updateRangeStatement = nullptr, *insertPhaseStatement = nullptr, *updatePhaseStatement = nullptr,
*insertGeneralInfoStatement = nullptr, *insertCommandLengthsStatement = nullptr,
*insertDebugMessageStatement = nullptr, *updateDataStrobeStatement = nullptr,
*insertPowerStatement = nullptr, *insertBufferDepthStatement = nullptr, *insertBandwidthStatement = nullptr;
*insertDebugMessageStatement = nullptr, *insertPowerStatement = nullptr,
*insertBufferDepthStatement = nullptr, *insertBandwidthStatement = nullptr;
std::string insertTransactionString, insertRangeString, updateRangeString, insertPhaseString,
updatePhaseString, insertGeneralInfoString, insertCommandLengthsString,
insertDebugMessageString, updateDataStrobeString, insertPowerString,
insertDebugMessageString, insertPowerString,
insertBufferDepthString, insertBandwidthString;
std::string initialCommand =
@@ -175,6 +190,14 @@ private:
" PhaseName TEXT, \n"
" PhaseBegin INTEGER, \n"
" PhaseEnd INTEGER, \n"
" DataStrobeBegin INTEGER, \n"
" DataStrobeEnd INTEGER, \n"
" Rank INTEGER, \n"
" BankGroup INTEGER, \n"
" Bank INTEGER, \n"
" Row INTEGER, \n"
" Column INTEGER, \n"
" BurstLength INTEGER, \n"
" Transact INTEGER \n"
"); \n"
" \n"
@@ -240,16 +263,9 @@ private:
" ID INTEGER, \n"
" Range INTEGER, \n"
" Address INTEGER, \n"
" Burstlength INTEGER, \n"
" TThread INTEGER, \n"
" TChannel INTEGER, \n"
" TRank INTEGER, \n"
" TBankgroup INTEGER, \n"
" TBank INTEGER, \n"
" TRow INTEGER, \n"
" TColumn INTEGER, \n"
" DataStrobeBegin INTEGER, \n"
" DataStrobeEnd INTEGER, \n"
" DataLength INTEGER, \n"
" Thread INTEGER, \n"
" Channel INTEGER, \n"
" TimeOfGeneration INTEGER, \n"
" Command TEXT \n"
"); \n"

View File

@@ -64,7 +64,6 @@ void to_json(json &j, const TraceSetup &c)
initiator_j["clkMhz"] = initiator.clkMhz;
initiator_j["maxPendingReadRequests"] = initiator.maxPendingReadRequests;
initiator_j["maxPendingWriteRequests"] = initiator.maxPendingWriteRequests;
initiator_j["addLengthConverter"] = initiator.addLengthConverter;
using T = std::decay_t<decltype(initiator)>;
if constexpr (std::is_same_v<T, TraceGenerator>)
@@ -292,9 +291,6 @@ void from_json(const json &j, TraceSetup &c)
if (initiator_j.contains("maxPendingWriteRequests"))
initiator_j.at("maxPendingWriteRequests").get_to(initiator.maxPendingWriteRequests);
if (initiator_j.contains("addLengthConverter"))
initiator_j.at("addLengthConverter").get_to(initiator.addLengthConverter);
},
initiator);

View File

@@ -78,7 +78,6 @@ struct TrafficInitiator
std::string name;
std::optional<unsigned int> maxPendingReadRequests;
std::optional<unsigned int> maxPendingWriteRequests;
std::optional<bool> addLengthConverter;
};
struct TracePlayer : public TrafficInitiator

View File

@@ -41,199 +41,151 @@
using namespace sc_core;
using namespace tlm;
DramExtension::DramExtension() :
thread(0), channel(0), rank(0), bankGroup(0), bank(0),
row(0), column(0), burstLength(0),
threadPayloadID(0), channelPayloadID(0) {}
ArbiterExtension::ArbiterExtension(Thread thread, Channel channel, uint64_t threadPayloadID,
const sc_core::sc_time& timeOfGeneration) :
thread(thread), channel(channel), threadPayloadID(threadPayloadID), timeOfGeneration(timeOfGeneration)
{}
DramExtension::DramExtension(Thread thread, Channel channel, Rank rank,
BankGroup bankGroup, Bank bank, Row row,
Column column, unsigned int burstLength,
uint64_t threadPayloadID, uint64_t channelPayloadID) :
thread(thread), channel(channel), rank(rank), bankGroup(bankGroup), bank(bank),
row(row), column(column), burstLength(burstLength),
threadPayloadID(threadPayloadID), channelPayloadID(channelPayloadID) {}
void DramExtension::setExtension(tlm_generic_payload *payload,
Thread thread, Channel channel, Rank rank,
BankGroup bankGroup, Bank bank, Row row,
Column column, unsigned int burstLength,
uint64_t threadPayloadID, uint64_t channelPayloadID)
void ArbiterExtension::setAutoExtension(tlm::tlm_generic_payload& trans, Thread thread, Channel channel)
{
DramExtension *extension = nullptr;
payload->get_extension(extension);
auto* extension = trans.get_extension<ArbiterExtension>();
if (extension != nullptr)
{
extension->thread = thread;
extension->channel = channel;
extension->threadPayloadID = 0;
extension->timeOfGeneration = SC_ZERO_TIME;
}
else
{
extension = new ArbiterExtension(thread, channel, 0, SC_ZERO_TIME);
trans.set_auto_extension(extension);
}
}
void ArbiterExtension::setExtension(tlm::tlm_generic_payload& trans, Thread thread, Channel channel,
uint64_t threadPayloadID, const sc_core::sc_time& timeOfGeneration)
{
assert(trans.get_extension<ArbiterExtension>() == nullptr);
auto* extension = new ArbiterExtension(thread, channel, threadPayloadID, timeOfGeneration);
trans.set_extension(extension);
}
void ArbiterExtension::setIDAndTimeOfGeneration(tlm::tlm_generic_payload& trans, uint64_t threadPayloadID,
const sc_core::sc_time& timeOfGeneration)
{
assert(trans.get_extension<ArbiterExtension>() != nullptr);
auto* extension = trans.get_extension<ArbiterExtension>();
extension->threadPayloadID = threadPayloadID;
extension->timeOfGeneration = timeOfGeneration;
}
tlm_extension_base* ArbiterExtension::clone() const
{
return new ArbiterExtension(thread, channel, threadPayloadID, timeOfGeneration);
}
void ArbiterExtension::copy_from(const tlm_extension_base& ext)
{
const auto& cpyFrom = dynamic_cast<const ArbiterExtension&>(ext);
thread = cpyFrom.thread;
channel = cpyFrom.channel;
threadPayloadID = cpyFrom.threadPayloadID;
timeOfGeneration = cpyFrom.timeOfGeneration;
}
Thread ArbiterExtension::getThread() const
{
return thread;
}
Channel ArbiterExtension::getChannel() const
{
return channel;
}
uint64_t ArbiterExtension::getThreadPayloadID() const
{
return threadPayloadID;
}
sc_core::sc_time ArbiterExtension::getTimeOfGeneration() const
{
return timeOfGeneration;
}
const ArbiterExtension& ArbiterExtension::getExtension(const tlm::tlm_generic_payload& trans)
{
return *trans.get_extension<ArbiterExtension>();
}
Thread ArbiterExtension::getThread(const tlm::tlm_generic_payload& trans)
{
return trans.get_extension<ArbiterExtension>()->thread;
}
Channel ArbiterExtension::getChannel(const tlm::tlm_generic_payload& trans)
{
return trans.get_extension<ArbiterExtension>()->channel;
}
uint64_t ArbiterExtension::getThreadPayloadID(const tlm::tlm_generic_payload& trans)
{
return trans.get_extension<ArbiterExtension>()->threadPayloadID;
}
sc_time ArbiterExtension::getTimeOfGeneration(const tlm::tlm_generic_payload& trans)
{
return trans.get_extension<ArbiterExtension>()->timeOfGeneration;
}
ControllerExtension::ControllerExtension(uint64_t channelPayloadID, Rank rank, BankGroup bankGroup, Bank bank, Row row,
Column column, unsigned int burstLength) :
channelPayloadID(channelPayloadID), rank(rank), bankGroup(bankGroup), bank(bank), row(row), column(column),
burstLength(burstLength)
{}
void ControllerExtension::setAutoExtension(tlm::tlm_generic_payload& trans, uint64_t channelPayloadID, Rank rank,
BankGroup bankGroup, Bank bank, Row row, Column column, unsigned int burstLength)
{
auto* extension = trans.get_extension<ControllerExtension>();
if (extension != nullptr)
{
extension->channelPayloadID = channelPayloadID;
extension->rank = rank;
extension->bankGroup = bankGroup;
extension->bank = bank;
extension->row = row;
extension->column = column;
extension->burstLength = burstLength;
extension->threadPayloadID = threadPayloadID;
extension->channelPayloadID = channelPayloadID;
}
else
{
extension = new DramExtension(thread, channel, rank, bankGroup,
bank, row, column, burstLength,
threadPayloadID, channelPayloadID);
payload->set_auto_extension(extension);
extension = new ControllerExtension(channelPayloadID, rank, bankGroup, bank, row, column, burstLength);
trans.set_auto_extension(extension);
}
}
void DramExtension::setExtension(tlm_generic_payload &payload,
Thread thread, Channel channel, Rank rank,
BankGroup bankGroup, Bank bank, Row row,
Column column, unsigned int burstLength,
uint64_t threadPayloadID, uint64_t channelPayloadID)
void ControllerExtension::setExtension(tlm::tlm_generic_payload& trans, uint64_t channelPayloadID, Rank rank,
BankGroup bankGroup, Bank bank, Row row, Column column, unsigned int burstLength)
{
setExtension(&payload, thread, channel, rank, bankGroup,
bank, row, column, burstLength,
threadPayloadID, channelPayloadID);
assert(trans.get_extension<ControllerExtension>() == nullptr);
auto* extension = new ControllerExtension(channelPayloadID, rank, bankGroup, bank, row, column, burstLength);
trans.set_extension(extension);
}
void DramExtension::setPayloadIDs(tlm_generic_payload *payload, uint64_t threadPayloadID, uint64_t channelPayloadID)
tlm_extension_base* ControllerExtension::clone() const
{
DramExtension *extension;
payload->get_extension(extension);
extension->threadPayloadID = threadPayloadID;
extension->channelPayloadID = channelPayloadID;
return new ControllerExtension(channelPayloadID, rank, bankGroup, bank, row, column, burstLength);
}
void DramExtension::setPayloadIDs(tlm_generic_payload &payload, uint64_t threadPayloadID, uint64_t channelPayloadID)
void ControllerExtension::copy_from(const tlm_extension_base& ext)
{
DramExtension::setPayloadIDs(&payload, threadPayloadID, channelPayloadID);
}
DramExtension &DramExtension::getExtension(const tlm_generic_payload *payload)
{
DramExtension *result = nullptr;
payload->get_extension(result);
sc_assert(result != nullptr);
return *result;
}
DramExtension &DramExtension::getExtension(const tlm_generic_payload &payload)
{
return DramExtension::getExtension(&payload);
}
Thread DramExtension::getThread(const tlm_generic_payload *payload)
{
return DramExtension::getExtension(payload).getThread();
}
Thread DramExtension::getThread(const tlm_generic_payload &payload)
{
return DramExtension::getThread(&payload);
}
Channel DramExtension::getChannel(const tlm_generic_payload *payload)
{
return DramExtension::getExtension(payload).getChannel();
}
Channel DramExtension::getChannel(const tlm_generic_payload &payload)
{
return DramExtension::getChannel(&payload);
}
Rank DramExtension::getRank(const tlm_generic_payload *payload)
{
return DramExtension::getExtension(payload).getRank();
}
Rank DramExtension::getRank(const tlm_generic_payload &payload)
{
return DramExtension::getRank(&payload);
}
BankGroup DramExtension::getBankGroup(const tlm_generic_payload *payload)
{
return DramExtension::getExtension(payload).getBankGroup();
}
BankGroup DramExtension::getBankGroup(const tlm_generic_payload &payload)
{
return DramExtension::getBankGroup(&payload);
}
Bank DramExtension::getBank(const tlm_generic_payload *payload)
{
return DramExtension::getExtension(payload).getBank();
}
Bank DramExtension::getBank(const tlm_generic_payload &payload)
{
return DramExtension::getBank(&payload);
}
Row DramExtension::getRow(const tlm_generic_payload *payload)
{
return DramExtension::getExtension(payload).getRow();
}
Row DramExtension::getRow(const tlm_generic_payload &payload)
{
return DramExtension::getRow(&payload);
}
Column DramExtension::getColumn(const tlm_generic_payload *payload)
{
return DramExtension::getExtension(payload).getColumn();
}
Column DramExtension::getColumn(const tlm_generic_payload &payload)
{
return DramExtension::getColumn(&payload);
}
unsigned DramExtension::getBurstLength(const tlm_generic_payload *payload)
{
return DramExtension::getExtension(payload).getBurstLength();
}
unsigned DramExtension::getBurstLength(const tlm_generic_payload &payload)
{
return DramExtension::getBurstLength(&payload);
}
uint64_t DramExtension::getThreadPayloadID(const tlm_generic_payload *payload)
{
return DramExtension::getExtension(payload).getThreadPayloadID();
}
uint64_t DramExtension::getThreadPayloadID(const tlm_generic_payload &payload)
{
return DramExtension::getThreadPayloadID(&payload);
}
uint64_t DramExtension::getChannelPayloadID(const tlm_generic_payload *payload)
{
return DramExtension::getExtension(payload).getChannelPayloadID();
}
uint64_t DramExtension::getChannelPayloadID(const tlm_generic_payload &payload)
{
return DramExtension::getChannelPayloadID(&payload);
}
tlm_extension_base *DramExtension::clone() const
{
return new DramExtension(thread, channel, rank, bankGroup, bank, row, column,
burstLength, threadPayloadID, channelPayloadID);
}
void DramExtension::copy_from(const tlm_extension_base &ext)
{
const auto &cpyFrom = dynamic_cast<const DramExtension &>(ext);
thread = cpyFrom.thread;
channel = cpyFrom.channel;
const auto& cpyFrom = dynamic_cast<const ControllerExtension&>(ext);
channelPayloadID = cpyFrom.channelPayloadID;
rank = cpyFrom.rank;
bankGroup = cpyFrom.bankGroup;
bank = cpyFrom.bank;
@@ -242,110 +194,79 @@ void DramExtension::copy_from(const tlm_extension_base &ext)
burstLength = cpyFrom.burstLength;
}
Thread DramExtension::getThread() const
{
return thread;
}
Channel DramExtension::getChannel() const
{
return channel;
}
Rank DramExtension::getRank() const
{
return rank;
}
BankGroup DramExtension::getBankGroup() const
{
return bankGroup;
}
Bank DramExtension::getBank() const
{
return bank;
}
Row DramExtension::getRow() const
{
return row;
}
Column DramExtension::getColumn() const
{
return column;
}
unsigned int DramExtension::getBurstLength() const
{
return burstLength;
}
uint64_t DramExtension::getThreadPayloadID() const
{
return threadPayloadID;
}
uint64_t DramExtension::getChannelPayloadID() const
uint64_t ControllerExtension::getChannelPayloadID() const
{
return channelPayloadID;
}
tlm_extension_base *GenerationExtension::clone() const
Rank ControllerExtension::getRank() const
{
return new GenerationExtension(timeOfGeneration);
return rank;
}
void GenerationExtension::copy_from(const tlm_extension_base &ext)
BankGroup ControllerExtension::getBankGroup() const
{
const auto &cpyFrom = dynamic_cast<const GenerationExtension &>(ext);
timeOfGeneration = cpyFrom.timeOfGeneration;
return bankGroup;
}
void GenerationExtension::setExtension(tlm_generic_payload *payload, const sc_time &timeOfGeneration)
Bank ControllerExtension::getBank() const
{
GenerationExtension *extension = nullptr;
payload->get_extension(extension);
if (extension != nullptr)
{
extension->timeOfGeneration = timeOfGeneration;
}
else
{
extension = new GenerationExtension(timeOfGeneration);
payload->set_auto_extension(extension);
}
return bank;
}
void GenerationExtension::setExtension(tlm_generic_payload &payload, const sc_time &timeOfGeneration)
Row ControllerExtension::getRow() const
{
GenerationExtension::setExtension(&payload, timeOfGeneration);
return row;
}
GenerationExtension &GenerationExtension::getExtension(const tlm_generic_payload *payload)
Column ControllerExtension::getColumn() const
{
GenerationExtension *result = nullptr;
payload->get_extension(result);
sc_assert(result != nullptr);
return *result;
return column;
}
GenerationExtension &GenerationExtension::getExtension(const tlm_generic_payload &payload)
unsigned ControllerExtension::getBurstLength() const
{
return GenerationExtension::getExtension(&payload);
return burstLength;
}
sc_time GenerationExtension::getTimeOfGeneration(const tlm_generic_payload *payload)
const ControllerExtension& ControllerExtension::getExtension(const tlm::tlm_generic_payload& trans)
{
return GenerationExtension::getExtension(payload).timeOfGeneration;
return *trans.get_extension<ControllerExtension>();
}
sc_time GenerationExtension::getTimeOfGeneration(const tlm_generic_payload &payload)
uint64_t ControllerExtension::getChannelPayloadID(const tlm::tlm_generic_payload& trans)
{
return GenerationExtension::getTimeOfGeneration(&payload);
return trans.get_extension<ControllerExtension>()->channelPayloadID;
}
Rank ControllerExtension::getRank(const tlm::tlm_generic_payload& trans)
{
return trans.get_extension<ControllerExtension>()->rank;
}
BankGroup ControllerExtension::getBankGroup(const tlm::tlm_generic_payload& trans)
{
return trans.get_extension<ControllerExtension>()->bankGroup;
}
Bank ControllerExtension::getBank(const tlm::tlm_generic_payload& trans)
{
return trans.get_extension<ControllerExtension>()->bank;
}
Row ControllerExtension::getRow(const tlm::tlm_generic_payload& trans)
{
return trans.get_extension<ControllerExtension>()->row;
}
Column ControllerExtension::getColumn(const tlm::tlm_generic_payload& trans)
{
return trans.get_extension<ControllerExtension>()->column;
}
unsigned ControllerExtension::getBurstLength(const tlm::tlm_generic_payload& trans)
{
return trans.get_extension<ControllerExtension>()->burstLength;
}
//THREAD
@@ -439,3 +360,101 @@ bool operator !=(const Column &lhs, const Column &rhs)
{
return !(lhs == rhs);
}
tlm::tlm_extension_base* ChildExtension::clone() const
{
return new ChildExtension(*parentTrans);
}
void ChildExtension::copy_from(const tlm::tlm_extension_base& ext)
{
const auto& cpyFrom = dynamic_cast<const ChildExtension&>(ext);
parentTrans = cpyFrom.parentTrans;
}
tlm::tlm_generic_payload& ChildExtension::getParentTrans()
{
return *parentTrans;
}
tlm::tlm_generic_payload& ChildExtension::getParentTrans(tlm::tlm_generic_payload& childTrans)
{
return childTrans.get_extension<ChildExtension>()->getParentTrans();
}
void ChildExtension::setExtension(tlm::tlm_generic_payload& childTrans, tlm::tlm_generic_payload& parentTrans)
{
auto* extension = childTrans.get_extension<ChildExtension>();
if (extension != nullptr)
{
extension->parentTrans = &parentTrans;
}
else
{
extension = new ChildExtension(parentTrans);
childTrans.set_auto_extension(extension);
}
}
bool ChildExtension::isChildTrans(const tlm::tlm_generic_payload& trans)
{
if (trans.get_extension<ChildExtension>() != nullptr)
return true;
else
return false;
}
tlm_extension_base* ParentExtension::clone() const
{
return new ParentExtension(childTranses);
}
void ParentExtension::copy_from(const tlm_extension_base& ext)
{
const auto& cpyFrom = dynamic_cast<const ParentExtension&>(ext);
childTranses = cpyFrom.childTranses;
}
void ParentExtension::setExtension(tlm::tlm_generic_payload& parentTrans, std::vector<tlm::tlm_generic_payload*> childTranses)
{
auto* extension = parentTrans.get_extension<ParentExtension>();
if (extension != nullptr)
{
extension->childTranses = std::move(childTranses);
extension->completedChildTranses = 0;
}
else
{
extension = new ParentExtension(std::move(childTranses));
parentTrans.set_auto_extension(extension);
}
}
const std::vector<tlm::tlm_generic_payload*>& ParentExtension::getChildTranses()
{
return childTranses;
}
bool ParentExtension::notifyChildTransCompletion()
{
completedChildTranses++;
if (completedChildTranses == childTranses.size())
{
std::for_each(childTranses.begin(), childTranses.end(),
[](tlm::tlm_generic_payload* childTrans){childTrans->release();});
childTranses.clear();
return true;
}
else
{
return false;
}
}
bool ParentExtension::notifyChildTransCompletion(tlm::tlm_generic_payload& trans)
{
return trans.get_extension<ParentExtension>()->notifyChildTransCompletion();
}

View File

@@ -154,104 +154,78 @@ private:
unsigned int id;
};
class DramExtension : public tlm::tlm_extension<DramExtension>
class ArbiterExtension : public tlm::tlm_extension<ArbiterExtension>
{
public:
DramExtension();
DramExtension(Thread thread, Channel channel, Rank rank,
BankGroup bankGroup, Bank bank, Row row,
Column column, unsigned int burstLength,
uint64_t threadPayloadID, uint64_t channelPayloadID);
tlm::tlm_extension_base *clone() const override;
void copy_from(const tlm::tlm_extension_base &ext) override;
static void setAutoExtension(tlm::tlm_generic_payload& trans, Thread thread, Channel channel);
static void setExtension(tlm::tlm_generic_payload& trans, Thread thread, Channel channel,
uint64_t threadPayloadID, const sc_core::sc_time& timeOfGeneration);
static void setIDAndTimeOfGeneration(tlm::tlm_generic_payload& trans, uint64_t threadPayloadID,
const sc_core::sc_time& timeOfGeneration);
static void setExtension(tlm::tlm_generic_payload *payload,
Thread thread, Channel channel, Rank rank,
BankGroup bankGroup, Bank bank, Row row,
Column column, unsigned int burstLength,
uint64_t threadPayloadID, uint64_t channelPayloadID);
static void setExtension(tlm::tlm_generic_payload &payload,
Thread thread, Channel channel, Rank rank,
BankGroup bankGroup, Bank bank, Row row,
Column column, unsigned int burstLength,
uint64_t threadPayloadID, uint64_t channelPayloadID);
static DramExtension &getExtension(const tlm::tlm_generic_payload *payload);
static DramExtension &getExtension(const tlm::tlm_generic_payload &payload);
static void setPayloadIDs(tlm::tlm_generic_payload *payload,
uint64_t threadPayloadID, uint64_t channelPayloadID);
static void setPayloadIDs(tlm::tlm_generic_payload &payload,
uint64_t threadPayloadID, uint64_t channelPayloadID);
// Used for convience, caller could also use getExtension(..) to access these field
static Thread getThread(const tlm::tlm_generic_payload *payload);
static Thread getThread(const tlm::tlm_generic_payload &payload);
static Channel getChannel(const tlm::tlm_generic_payload *payload);
static Channel getChannel(const tlm::tlm_generic_payload &payload);
static Rank getRank(const tlm::tlm_generic_payload *payload);
static Rank getRank(const tlm::tlm_generic_payload &payload);
static BankGroup getBankGroup(const tlm::tlm_generic_payload *payload);
static BankGroup getBankGroup(const tlm::tlm_generic_payload &payload);
static Bank getBank(const tlm::tlm_generic_payload *payload);
static Bank getBank(const tlm::tlm_generic_payload &payload);
static Row getRow(const tlm::tlm_generic_payload *payload);
static Row getRow(const tlm::tlm_generic_payload &payload);
static Column getColumn(const tlm::tlm_generic_payload *payload);
static Column getColumn(const tlm::tlm_generic_payload &payload);
static unsigned getBurstLength(const tlm::tlm_generic_payload *payload);
static unsigned getBurstLength(const tlm::tlm_generic_payload &payload);
static uint64_t getThreadPayloadID(const tlm::tlm_generic_payload *payload);
static uint64_t getThreadPayloadID(const tlm::tlm_generic_payload &payload);
static uint64_t getChannelPayloadID(const tlm::tlm_generic_payload *payload);
static uint64_t getChannelPayloadID(const tlm::tlm_generic_payload &payload);
tlm::tlm_extension_base* clone() const override;
void copy_from(const tlm::tlm_extension_base& ext) override;
Thread getThread() const;
Channel getChannel() const;
uint64_t getThreadPayloadID() const;
sc_core::sc_time getTimeOfGeneration() const;
static const ArbiterExtension& getExtension(const tlm::tlm_generic_payload& trans);
static Thread getThread(const tlm::tlm_generic_payload& trans);
static Channel getChannel(const tlm::tlm_generic_payload& trans);
static uint64_t getThreadPayloadID(const tlm::tlm_generic_payload& trans);
static sc_core::sc_time getTimeOfGeneration(const tlm::tlm_generic_payload& trans);
private:
ArbiterExtension(Thread thread, Channel channel, uint64_t threadPayloadID, const sc_core::sc_time& timeOfGeneration);
Thread thread;
Channel channel;
uint64_t threadPayloadID;
sc_core::sc_time timeOfGeneration;
};
class ControllerExtension : public tlm::tlm_extension<ControllerExtension>
{
public:
static void setAutoExtension(tlm::tlm_generic_payload& trans, uint64_t channelPayloadID, Rank rank, BankGroup bankGroup,
Bank bank, Row row, Column column, unsigned burstLength);
static void setExtension(tlm::tlm_generic_payload& trans, uint64_t channelPayloadID, Rank rank, BankGroup bankGroup,
Bank bank, Row row, Column column, unsigned burstLength);
//static ControllerExtension& getExtension(const tlm::tlm_generic_payload& trans);
tlm::tlm_extension_base* clone() const override;
void copy_from(const tlm::tlm_extension_base& ext) override;
uint64_t getChannelPayloadID() const;
Rank getRank() const;
BankGroup getBankGroup() const;
Bank getBank() const;
Row getRow() const;
Column getColumn() const;
unsigned getBurstLength() const;
unsigned int getBurstLength() const;
uint64_t getThreadPayloadID() const;
uint64_t getChannelPayloadID() const;
static const ControllerExtension& getExtension(const tlm::tlm_generic_payload& trans);
static uint64_t getChannelPayloadID(const tlm::tlm_generic_payload& trans);
static Rank getRank(const tlm::tlm_generic_payload& trans);
static BankGroup getBankGroup(const tlm::tlm_generic_payload& trans);
static Bank getBank(const tlm::tlm_generic_payload& trans);
static Row getRow(const tlm::tlm_generic_payload& trans);
static Column getColumn(const tlm::tlm_generic_payload& trans);
static unsigned getBurstLength(const tlm::tlm_generic_payload& trans);
private:
Thread thread;
Channel channel;
ControllerExtension(uint64_t channelPayloadID, Rank rank, BankGroup bankGroup, Bank bank, Row row, Column column,
unsigned burstLength);
uint64_t channelPayloadID;
Rank rank;
BankGroup bankGroup;
Bank bank;
Row row;
Column column;
unsigned int burstLength;
uint64_t threadPayloadID;
uint64_t channelPayloadID;
};
// Used to indicate the time when a payload is created (in a traceplayer or in a core)
// Note that this time can be different from the time the payload enters the DRAM system
//(at that time the phase BEGIN_REQ is recorded), so timeOfGeneration =< time(BEGIN_REQ)
class GenerationExtension : public tlm::tlm_extension<GenerationExtension>
{
public:
explicit GenerationExtension(const sc_core::sc_time &timeOfGeneration)
: timeOfGeneration(timeOfGeneration) {}
tlm::tlm_extension_base *clone() const override;
void copy_from(const tlm::tlm_extension_base &ext) override;
static void setExtension(tlm::tlm_generic_payload *payload, const sc_core::sc_time &timeOfGeneration);
static void setExtension(tlm::tlm_generic_payload &payload, const sc_core::sc_time &timeOfGeneration);
static GenerationExtension &getExtension(const tlm::tlm_generic_payload *payload);
static GenerationExtension &getExtension(const tlm::tlm_generic_payload &payload);
static sc_core::sc_time getTimeOfGeneration(const tlm::tlm_generic_payload *payload);
static sc_core::sc_time getTimeOfGeneration(const tlm::tlm_generic_payload &payload);
private:
sc_core::sc_time timeOfGeneration;
unsigned burstLength;
};
@@ -278,4 +252,40 @@ 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:
tlm::tlm_generic_payload* parentTrans;
explicit ChildExtension(tlm::tlm_generic_payload& parentTrans) : parentTrans(&parentTrans) {}
public:
//ChildExtension() = delete;
tlm::tlm_extension_base* clone() const override;
void copy_from(const tlm::tlm_extension_base& ext) override;
tlm::tlm_generic_payload& getParentTrans();
static tlm::tlm_generic_payload& getParentTrans(tlm::tlm_generic_payload& childTrans);
static void setExtension(tlm::tlm_generic_payload& childTrans, tlm::tlm_generic_payload& parentTrans);
static bool isChildTrans(const tlm::tlm_generic_payload& trans);
};
class ParentExtension : public tlm::tlm_extension<ParentExtension>
{
private:
std::vector<tlm::tlm_generic_payload*> childTranses;
unsigned completedChildTranses = 0;
explicit ParentExtension(std::vector<tlm::tlm_generic_payload*> _childTranses)
: childTranses(std::move(_childTranses)) {}
public:
ParentExtension() = delete;
tlm_extension_base* clone() const override;
void copy_from(const tlm_extension_base& ext) override;
static void setExtension(tlm::tlm_generic_payload& parentTrans, std::vector<tlm::tlm_generic_payload*> childTranses);
const std::vector<tlm::tlm_generic_payload*>& getChildTranses();
bool notifyChildTransCompletion();
static bool notifyChildTransCompletion(tlm::tlm_generic_payload& trans);
};
#endif // DRAMEXTENSIONS_H

View File

@@ -80,7 +80,6 @@ void setUpDummy(tlm_generic_payload &payload, uint64_t channelPayloadID, Rank ra
payload.set_dmi_allowed(false);
payload.set_byte_enable_length(0);
payload.set_streaming_width(0);
payload.set_extension(new DramExtension(Thread(UINT_MAX), Channel(0), rank,
bankGroup, bank, Row(0), Column(0), 0, 0, channelPayloadID));
payload.set_extension(new GenerationExtension(SC_ZERO_TIME));
ControllerExtension::setExtension(payload, channelPayloadID, rank, bankGroup, bank, Row(0), Column(0), 0);
ArbiterExtension::setExtension(payload, Thread(UINT_MAX), Channel(0), 0, SC_ZERO_TIME);
}

View File

@@ -65,6 +65,7 @@ MemSpec::MemSpec(const DRAMSysConfiguration::MemSpec &memSpec,
dataRate(memSpec.memArchitectureSpec.entries.at("dataRate")),
bitWidth(memSpec.memArchitectureSpec.entries.at("width")),
dataBusWidth(bitWidth * devicesPerRank),
bytesPerBeat(dataBusWidth / 8),
defaultBytesPerBurst((defaultBurstLength * dataBusWidth) / 8),
maxBytesPerBurst((maxBurstLength * dataBusWidth) / 8),
fCKMHz(memSpec.memTimingSpec.entries.at("clkMhz")),
@@ -82,7 +83,7 @@ sc_time MemSpec::getCommandLength(Command command) const
return tCK * commandLengthInCycles[command];
}
double MemSpec::getCommandLengthInCylcles(Command command) const
double MemSpec::getCommandLengthInCycles(Command command) const
{
return commandLengthInCycles[command];
}

View File

@@ -66,6 +66,7 @@ public:
const unsigned dataRate;
const unsigned bitWidth;
const unsigned dataBusWidth;
const unsigned bytesPerBeat;
const unsigned defaultBytesPerBurst;
const unsigned maxBytesPerBurst;
@@ -96,7 +97,7 @@ public:
virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const = 0;
sc_core::sc_time getCommandLength(Command) const;
double getCommandLengthInCylcles(Command) const;
double getCommandLengthInCycles(Command) const;
uint64_t getSimMemSizeInBytes() const;
protected:

View File

@@ -216,7 +216,7 @@ sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload
return tRCD + longCmdOffset;
else if (command == Command::RD)
{
if (DramExtension::getBurstLength(payload) == 32)
if (ControllerExtension::getBurstLength(payload) == 32)
return tRL + tBURST32 + longCmdOffset;
else
return tRL + tBURST16 + longCmdOffset;
@@ -225,14 +225,14 @@ sc_time MemSpecDDR5::getExecutionTime(Command command, const tlm_generic_payload
return tRTP + tRP + longCmdOffset;
else if (command == Command::WR)
{
if (DramExtension::getBurstLength(payload) == 32)
if (ControllerExtension::getBurstLength(payload) == 32)
return tWL + tBURST32 + longCmdOffset;
else
return tWL + tBURST16 + longCmdOffset;
}
else if (command == Command::WRA)
{
if (DramExtension::getBurstLength(payload) == 32)
if (ControllerExtension::getBurstLength(payload) == 32)
return tWL + tBURST32 + tWR + tRP + longCmdOffset;
else
return tWL + tBURST16 + tWR + tRP + longCmdOffset;
@@ -253,14 +253,14 @@ TimeInterval MemSpecDDR5::getIntervalOnDataStrobe(Command command, const tlm_gen
{
if (command == Command::RD || command == Command::RDA)
{
if (DramExtension::getBurstLength(payload) == 32)
if (ControllerExtension::getBurstLength(payload) == 32)
return {tRL + longCmdOffset, tRL + tBURST32 + longCmdOffset};
else
return {tRL + longCmdOffset, tRL + tBURST16 + longCmdOffset};
}
else if (command == Command::WR || command == Command::WRA)
{
if (DramExtension::getBurstLength(payload) == 32)
if (ControllerExtension::getBurstLength(payload) == 32)
return {tWL + longCmdOffset, tWL + tBURST32 + longCmdOffset};
else
return {tWL + longCmdOffset, tWL + tBURST16 + longCmdOffset};

View File

@@ -57,7 +57,7 @@ void BankMachine::updateState(Command command)
{
case Command::ACT:
state = State::Activated;
openRow = DramExtension::getRow(currentPayload);
openRow = ControllerExtension::getRow(*currentPayload);
keepTrans = true;
refreshManagementCounter++;
break;
@@ -180,7 +180,7 @@ sc_time BankMachineOpen::start()
assert(!keepTrans || currentPayload != nullptr);
if (keepTrans)
{
if (DramExtension::getRow(newPayload) == openRow)
if (ControllerExtension::getRow(*newPayload) == openRow)
currentPayload = newPayload;
}
else
@@ -192,7 +192,7 @@ sc_time BankMachineOpen::start()
nextCommand = Command::ACT;
else if (state == State::Activated)
{
if (DramExtension::getRow(currentPayload) == openRow) // row hit
if (ControllerExtension::getRow(*currentPayload) == openRow) // row hit
{
assert(currentPayload->is_read() || currentPayload->is_write());
if (currentPayload->is_read())
@@ -232,7 +232,7 @@ sc_time BankMachineClosed::start()
assert(!keepTrans || currentPayload != nullptr);
if (keepTrans)
{
if (DramExtension::getRow(newPayload) == openRow)
if (ControllerExtension::getRow(*newPayload) == openRow)
currentPayload = newPayload;
}
else
@@ -279,7 +279,7 @@ sc_time BankMachineOpenAdaptive::start()
assert(!keepTrans || currentPayload != nullptr);
if (keepTrans)
{
if (DramExtension::getRow(newPayload) == openRow)
if (ControllerExtension::getRow(*newPayload) == openRow)
currentPayload = newPayload;
}
else
@@ -291,7 +291,7 @@ sc_time BankMachineOpenAdaptive::start()
nextCommand = Command::ACT;
else if (state == State::Activated)
{
if (DramExtension::getRow(currentPayload) == openRow) // row hit
if (ControllerExtension::getRow(*currentPayload) == openRow) // row hit
{
if (scheduler.hasFurtherRequest(bank, currentPayload->get_command())
&& !scheduler.hasFurtherRowHit(bank, openRow, currentPayload->get_command()))
@@ -343,7 +343,7 @@ sc_time BankMachineClosedAdaptive::start()
assert(!keepTrans || currentPayload != nullptr);
if (keepTrans)
{
if (DramExtension::getRow(newPayload) == openRow)
if (ControllerExtension::getRow(*newPayload) == openRow)
currentPayload = newPayload;
}
else
@@ -355,7 +355,7 @@ sc_time BankMachineClosedAdaptive::start()
nextCommand = Command::ACT;
else if (state == State::Activated)
{
if (DramExtension::getRow(currentPayload) == openRow) // row hit
if (ControllerExtension::getRow(*currentPayload) == openRow) // row hit
{
if (scheduler.hasFurtherRowHit(bank, openRow, currentPayload->get_command()))
{

View File

@@ -45,6 +45,33 @@ using namespace tlm;
using namespace DRAMPower;
#endif
bool phaseHasDataStrobe(tlm::tlm_phase phase)
{
return (phase >= BEGIN_RD && phase <= BEGIN_WRA);
}
bool isPowerDownEntryPhase(tlm::tlm_phase phase)
{
return (phase >= BEGIN_PDNA && phase <= BEGIN_SREF);
}
bool isPowerDownExitPhase(tlm::tlm_phase phase)
{
return (phase >= END_PDNA && phase <= END_SREF);
}
bool isFixedCommandPhase(tlm::tlm_phase phase)
{
return (phase >= BEGIN_NOP && phase <= BEGIN_RFMAB);
}
bool isRefreshCommandPhase(tlm::tlm_phase phase)
{
return (phase == BEGIN_REFPB || phase == BEGIN_REFP2B || phase == BEGIN_REFSB || phase == BEGIN_REFAB
|| phase == BEGIN_RFMPB || phase == BEGIN_RFMP2B || phase == BEGIN_RFMSB || phase == BEGIN_RFMAB);
}
Command::Command(Command::Type type) : type(type) {}
Command::Command(tlm_phase phase)
@@ -121,29 +148,29 @@ tlm_phase Command::toPhase() const
assert(type >= Command::NOP && type <= Command::SREFEX);
static std::array<tlm_phase, Command::Type::END_ENUM> phaseOfCommand =
{
BEGIN_NOP, // 0
BEGIN_RD, // 1
BEGIN_WR, // 2
BEGIN_RDA, // 3
BEGIN_WRA, // 4
BEGIN_ACT, // 5
BEGIN_PREPB, // 6
BEGIN_REFPB, // 7
BEGIN_RFMPB, // 8
BEGIN_REFP2B, // 9
BEGIN_RFMP2B, // 10
BEGIN_PRESB, // 11
BEGIN_REFSB, // 12
BEGIN_RFMSB, // 13
BEGIN_PREAB, // 14
BEGIN_REFAB, // 15
BEGIN_RFMAB, // 16
BEGIN_PDNA, // 17
BEGIN_PDNP, // 18
BEGIN_SREF, // 19
END_PDNA, // 20
END_PDNP, // 21
END_SREF // 22
BEGIN_NOP, // 0
BEGIN_RD, // 1
BEGIN_WR, // 2
BEGIN_RDA, // 3
BEGIN_WRA, // 4
BEGIN_ACT, // 5
BEGIN_PREPB, // 6
BEGIN_REFPB, // 7
BEGIN_RFMPB, // 8
BEGIN_REFP2B, // 9
BEGIN_RFMP2B, // 10
BEGIN_PRESB, // 11
BEGIN_REFSB, // 12
BEGIN_RFMSB, // 13
BEGIN_PREAB, // 14
BEGIN_REFAB, // 15
BEGIN_RFMAB, // 16
BEGIN_PDNA, // 17
BEGIN_PDNP, // 18
BEGIN_SREF, // 19
END_PDNA, // 20
END_PDNP, // 21
END_SREF // 22
};
return phaseOfCommand[type];
}
@@ -183,17 +210,6 @@ MemCommand::cmds phaseToDRAMPowerCommand(tlm_phase phase)
}
#endif
bool phaseNeedsEnd(tlm_phase phase)
{
return (phase >= BEGIN_NOP && phase <= BEGIN_RFMAB);
}
tlm_phase getEndPhase(tlm_phase phase)
{
assert(phase >= BEGIN_NOP && phase <= BEGIN_RFMAB);
return (phase + Command::Type::END_ENUM);
}
bool Command::isBankCommand() const
{
assert(type >= Command::NOP && type <= Command::SREFEX);

View File

@@ -72,6 +72,7 @@ DECLARE_EXTENDED_PHASE(BEGIN_RFMSB); // 18
DECLARE_EXTENDED_PHASE(BEGIN_PREAB); // 19
DECLARE_EXTENDED_PHASE(BEGIN_REFAB); // 20
DECLARE_EXTENDED_PHASE(BEGIN_RFMAB); // 21
DECLARE_EXTENDED_PHASE(BEGIN_PDNA); // 22
DECLARE_EXTENDED_PHASE(BEGIN_PDNP); // 23
DECLARE_EXTENDED_PHASE(BEGIN_SREF); // 24
@@ -80,23 +81,14 @@ DECLARE_EXTENDED_PHASE(END_PDNA); // 25
DECLARE_EXTENDED_PHASE(END_PDNP); // 26
DECLARE_EXTENDED_PHASE(END_SREF); // 27
DECLARE_EXTENDED_PHASE(END_NOP); // 28
DECLARE_EXTENDED_PHASE(END_RD); // 29
DECLARE_EXTENDED_PHASE(END_WR); // 30
DECLARE_EXTENDED_PHASE(END_RDA); // 31
DECLARE_EXTENDED_PHASE(END_WRA); // 32
DECLARE_EXTENDED_PHASE(END_ACT); // 33
DECLARE_EXTENDED_PHASE(END_PREPB); // 34
DECLARE_EXTENDED_PHASE(END_REFPB); // 35
DECLARE_EXTENDED_PHASE(END_RFMPB); // 36
DECLARE_EXTENDED_PHASE(END_REFP2B); // 37
DECLARE_EXTENDED_PHASE(END_RFMP2B); // 38
DECLARE_EXTENDED_PHASE(END_PRESB); // 39
DECLARE_EXTENDED_PHASE(END_REFSB); // 40
DECLARE_EXTENDED_PHASE(END_RFMSB); // 41
DECLARE_EXTENDED_PHASE(END_PREAB); // 42
DECLARE_EXTENDED_PHASE(END_REFAB); // 43
DECLARE_EXTENDED_PHASE(END_RFMAB); // 44
#ifdef DRAMPOWER
DRAMPower::MemCommand::cmds phaseToDRAMPowerCommand(tlm::tlm_phase);
#endif
bool phaseHasDataStrobe(tlm::tlm_phase phase);
bool isPowerDownEntryPhase(tlm::tlm_phase phase);
bool isPowerDownExitPhase(tlm::tlm_phase phase);
bool isFixedCommandPhase(tlm::tlm_phase phase);
bool isRefreshCommandPhase(tlm::tlm_phase phase);
class Command
{
@@ -153,13 +145,6 @@ public:
}
};
#ifdef DRAMPOWER
DRAMPower::MemCommand::cmds phaseToDRAMPowerCommand(tlm::tlm_phase);
#endif
bool phaseNeedsEnd(tlm::tlm_phase);
tlm::tlm_phase getEndPhase(tlm::tlm_phase);
struct CommandTuple
{
using Type = std::tuple<::Command, tlm::tlm_generic_payload *, sc_core::sc_time>;

View File

@@ -77,9 +77,12 @@
using namespace sc_core;
using namespace tlm;
Controller::Controller(const sc_module_name& name, const Configuration& config) :
ControllerIF(name, config), thinkDelayFw(config.thinkDelayFw), thinkDelayBw(config.thinkDelayBw),
phyDelayFw(config.phyDelayFw), phyDelayBw(config.phyDelayBw)
Controller::Controller(const sc_module_name& name, const Configuration& config, const AddressDecoder& addressDecoder) :
ControllerIF(name, config), addressDecoder(addressDecoder),
thinkDelayFw(config.thinkDelayFw), thinkDelayBw(config.thinkDelayBw),
phyDelayFw(config.phyDelayFw), phyDelayBw(config.phyDelayBw),
minBytesPerBurst(config.memSpec->defaultBytesPerBurst),
maxBytesPerBurst(config.memSpec->maxBytesPerBurst)
{
SC_METHOD(controllerMethod);
sensitive << beginReqEvent << endRespEvent << controllerEvent << dataResponseEvent;
@@ -303,8 +306,8 @@ void Controller::controllerMethod()
tlm_generic_payload *payload = std::get<CommandTuple::Payload>(commandTuple);
if (command != Command::NOP) // can happen with FIFO strict
{
Rank rank = DramExtension::getRank(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(*payload);
Bank bank = ControllerExtension::getBank(*payload);
if (command.isRankCommand())
{
@@ -348,8 +351,8 @@ void Controller::controllerMethod()
powerDownManagers[rank.ID()]->triggerEntry();
sc_time fwDelay = thinkDelayFw + phyDelayFw;
sendToDram(command, *payload, fwDelay);
tlm_phase phase = command.toPhase();
iSocket->nb_transport_fw(*payload, phase, fwDelay);
}
else
readyCmdBlocked = true;
@@ -420,26 +423,58 @@ void Controller::manageRequests(const sc_time &delay)
{
if (transToAcquire.payload != nullptr && transToAcquire.time <= sc_time_stamp())
{
// TODO: here we assume that the scheduler always has space not only for a single burst transaction
// but for a maximum size transaction
if (scheduler->hasBufferSpace())
{
NDEBUG_UNUSED(uint64_t id) = DramExtension::getChannelPayloadID(transToAcquire.payload);
PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " entered system.");
if (totalNumberOfPayloads == 0)
idleTimeCollector.end();
totalNumberOfPayloads++;
totalNumberOfPayloads++; // seems to be ok
Rank rank = DramExtension::getRank(transToAcquire.payload);
if (ranksNumberOfPayloads[rank.ID()] == 0)
powerDownManagers[rank.ID()]->triggerExit();
ranksNumberOfPayloads[rank.ID()]++;
scheduler->storeRequest(*transToAcquire.payload);
transToAcquire.payload->acquire();
Bank bank = DramExtension::getBank(transToAcquire.payload);
bankMachines[bank.ID()]->start();
// Align address to minimum burst length
uint64_t alignedAddress = transToAcquire.payload->get_address() & ~(minBytesPerBurst - UINT64_C(1));
transToAcquire.payload->set_address(alignedAddress);
// continuous block of data that can be fetched with a single burst
if ((alignedAddress / maxBytesPerBurst)
== ((alignedAddress + transToAcquire.payload->get_data_length() - 1) / maxBytesPerBurst))
{
DecodedAddress decodedAddress = addressDecoder.decodeAddress(transToAcquire.payload->get_address());
ControllerExtension::setAutoExtension(*transToAcquire.payload, nextChannelPayloadIDToAppend++,
Rank(decodedAddress.rank), BankGroup(decodedAddress.bankgroup),
Bank(decodedAddress.bank), Row(decodedAddress.row),
Column(decodedAddress.column),
transToAcquire.payload->get_data_length() / memSpec.bytesPerBeat);
Rank rank = Rank(decodedAddress.rank);
if (ranksNumberOfPayloads[rank.ID()] == 0)
powerDownManagers[rank.ID()]->triggerExit();
ranksNumberOfPayloads[rank.ID()]++;
scheduler->storeRequest(*transToAcquire.payload);
Bank bank = Bank(decodedAddress.bank);
bankMachines[bank.ID()]->start();
}
else
{
createChildTranses(*transToAcquire.payload);
const std::vector<tlm_generic_payload*>& childTranses =
transToAcquire.payload->get_extension<ParentExtension>()->getChildTranses();
for (auto* childTrans : childTranses)
{
Rank rank = ControllerExtension::getRank(*childTrans);
if (ranksNumberOfPayloads[rank.ID()] == 0)
powerDownManagers[rank.ID()]->triggerExit();
ranksNumberOfPayloads[rank.ID()]++;
scheduler->storeRequest(*childTrans);
Bank bank = ControllerExtension::getBank(*childTrans);
bankMachines[bank.ID()]->start();
}
nextChannelPayloadIDToAppend++;
}
transToAcquire.payload->set_response_status(TLM_OK_RESPONSE);
tlm_phase bwPhase = END_REQ;
@@ -459,12 +494,8 @@ void Controller::manageResponses()
if (transToRelease.payload != nullptr)
{
assert(transToRelease.time >= sc_time_stamp());
if (transToRelease.time == sc_time_stamp())
if (transToRelease.time == sc_time_stamp()) // END_RESP completed
{
NDEBUG_UNUSED(uint64_t id) = DramExtension::getChannelPayloadID(transToRelease.payload);
PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " left system.");
numberOfBeatsServed += DramExtension::getBurstLength(transToRelease.payload);
transToRelease.payload->release();
transToRelease.payload = nullptr;
totalNumberOfPayloads--;
@@ -473,33 +504,41 @@ void Controller::manageResponses()
{
idleTimeCollector.start();
}
}
else
return; // END_RESP not completed
}
tlm_generic_payload* nextPayloadInRespQueue = respQueue->nextPayload();
if (nextPayloadInRespQueue != nullptr)
{
numberOfBeatsServed += ControllerExtension::getBurstLength(*nextPayloadInRespQueue);
if (ChildExtension::isChildTrans(*nextPayloadInRespQueue))
{
tlm_generic_payload& parentTrans = ChildExtension::getParentTrans(*nextPayloadInRespQueue);
if (ParentExtension::notifyChildTransCompletion(parentTrans))
{
transToRelease.payload = &parentTrans;
tlm_phase bwPhase = BEGIN_RESP;
sc_time bwDelay;
if (transToRelease.time == sc_time_stamp()) // last payload was released in this cycle
bwDelay = memSpec.tCK;
else
bwDelay = SC_ZERO_TIME;
sendToFrontend(*transToRelease.payload, bwPhase, bwDelay);
transToRelease.time = sc_max_time();
}
else
{
transToRelease.payload = respQueue->nextPayload();
if (transToRelease.payload != nullptr)
{
// last payload was released in this cycle
tlm_phase bwPhase = BEGIN_RESP;
sc_time bwDelay = memSpec.tCK;
sendToFrontend(*transToRelease.payload, bwPhase, bwDelay);
transToRelease.time = sc_max_time();
}
else
{
sc_time triggerTime = respQueue->getTriggerTime();
if (triggerTime != sc_max_time())
dataResponseEvent.notify(triggerTime - sc_time_stamp());
}
sc_time triggerTime = respQueue->getTriggerTime();
if (triggerTime != sc_max_time())
dataResponseEvent.notify(triggerTime - sc_time_stamp());
}
}
}
else
{
transToRelease.payload = respQueue->nextPayload();
if (transToRelease.payload != nullptr)
else
{
transToRelease.payload = nextPayloadInRespQueue;
tlm_phase bwPhase = BEGIN_RESP;
sc_time bwDelay;
if (transToRelease.time == sc_time_stamp()) // last payload was released in this cycle
@@ -510,12 +549,12 @@ void Controller::manageResponses()
sendToFrontend(*transToRelease.payload, bwPhase, bwDelay);
transToRelease.time = sc_max_time();
}
else
{
sc_time triggerTime = respQueue->getTriggerTime();
if (triggerTime != sc_max_time())
dataResponseEvent.notify(triggerTime - sc_time_stamp());
}
}
else
{
sc_time triggerTime = respQueue->getTriggerTime();
if (triggerTime != sc_max_time())
dataResponseEvent.notify(triggerTime - sc_time_stamp());
}
}
@@ -524,14 +563,88 @@ void Controller::sendToFrontend(tlm_generic_payload& payload, tlm_phase& phase,
tSocket->nb_transport_bw(payload, phase, delay);
}
void Controller::sendToDram(Command command, tlm_generic_payload& payload, sc_time& delay)
Controller::MemoryManager::~MemoryManager()
{
tlm_phase phase = command.toPhase();
iSocket->nb_transport_fw(payload, phase, delay);
while (!freePayloads.empty())
{
tlm_generic_payload* payload = freePayloads.top();
freePayloads.pop();
payload->reset();
delete payload;
}
}
tlm::tlm_generic_payload& Controller::MemoryManager::allocate()
{
if (freePayloads.empty())
{
return *new tlm_generic_payload(this);
}
else
{
tlm_generic_payload* result = freePayloads.top();
freePayloads.pop();
return *result;
}
}
void Controller::MemoryManager::free(tlm::tlm_generic_payload* payload)
{
freePayloads.push(payload);
}
void Controller::createChildTranses(tlm::tlm_generic_payload& parentTrans)
{
std::vector<tlm_generic_payload*> childTranses;
uint64_t startAddress = parentTrans.get_address() & ~(maxBytesPerBurst - UINT64_C(1));
unsigned char* startDataPtr = parentTrans.get_data_ptr();
unsigned numChildTranses = parentTrans.get_data_length() / maxBytesPerBurst;
for (unsigned childId = 0; childId < numChildTranses; childId++)
{
tlm_generic_payload& childTrans = memoryManager.allocate();
childTrans.acquire();
childTrans.set_command(parentTrans.get_command());
childTrans.set_address(startAddress + childId * maxBytesPerBurst);
childTrans.set_data_length(maxBytesPerBurst);
childTrans.set_data_ptr(startDataPtr + childId * maxBytesPerBurst);
ChildExtension::setExtension(childTrans, parentTrans);
childTranses.push_back(&childTrans);
}
if (startAddress != parentTrans.get_address())
{
tlm_generic_payload& firstChildTrans = *childTranses.front();
firstChildTrans.set_address(firstChildTrans.get_address() + minBytesPerBurst);
firstChildTrans.set_data_ptr(firstChildTrans.get_data_ptr() + minBytesPerBurst);
firstChildTrans.set_data_length(minBytesPerBurst);
tlm_generic_payload& lastChildTrans = memoryManager.allocate();
lastChildTrans.acquire();
lastChildTrans.set_command(parentTrans.get_command());
lastChildTrans.set_address(startAddress + numChildTranses * maxBytesPerBurst);
lastChildTrans.set_data_length(minBytesPerBurst);
lastChildTrans.set_data_ptr(startDataPtr + numChildTranses * maxBytesPerBurst);
ChildExtension::setExtension(lastChildTrans, parentTrans);
childTranses.push_back(&lastChildTrans);
}
for (auto* childTrans : childTranses)
{
DecodedAddress decodedAddress = addressDecoder.decodeAddress(childTrans->get_address());
ControllerExtension::setAutoExtension(*childTrans, nextChannelPayloadIDToAppend,
Rank(decodedAddress.rank), BankGroup(decodedAddress.bankgroup),
Bank(decodedAddress.bank), Row(decodedAddress.row),
Column(decodedAddress.column),
childTrans->get_data_length() / memSpec.bytesPerBeat);
}
nextChannelPayloadIDToAppend++;
ParentExtension::setExtension(parentTrans, std::move(childTranses));
}
bool Controller::isFullCycle(const sc_core::sc_time& time) const
{
sc_time aligedAtHalfCycle = std::floor((time * 2 / memSpec.tCK + 0.5)) / 2 * memSpec.tCK;
return sc_time::from_value(aligedAtHalfCycle.value() % memSpec.tCK.value()) == SC_ZERO_TIME;
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;
}

View File

@@ -37,6 +37,7 @@
#include <vector>
#include <stack>
#include <systemc>
#include <tlm>
@@ -48,11 +49,12 @@
#include "refresh/RefreshManagerIF.h"
#include "powerdown/PowerDownManagerIF.h"
#include "respqueue/RespQueueIF.h"
#include "../simulation/AddressDecoder.h"
class Controller : public ControllerIF
{
public:
Controller(const sc_core::sc_module_name& name, const Configuration& config);
Controller(const sc_core::sc_module_name& name, const Configuration& config, const AddressDecoder& addressDecoder);
SC_HAS_PROCESS(Controller);
protected:
@@ -63,7 +65,6 @@ protected:
unsigned int transport_dbg(tlm::tlm_generic_payload& trans) override;
virtual void sendToFrontend(tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay);
virtual void sendToDram(Command, tlm::tlm_generic_payload& trans, sc_core::sc_time& delay);
virtual void controllerMethod();
@@ -87,6 +88,9 @@ private:
std::vector<std::unique_ptr<RefreshManagerIF>> refreshManagers;
std::vector<std::unique_ptr<PowerDownManagerIF>> powerDownManagers;
const AddressDecoder& addressDecoder;
uint64_t nextChannelPayloadIDToAppend = 1;
struct Transaction
{
tlm::tlm_generic_payload *payload = nullptr;
@@ -99,6 +103,22 @@ private:
bool isFullCycle(const sc_core::sc_time& time) const;
sc_core::sc_event beginReqEvent, endRespEvent, controllerEvent, dataResponseEvent;
const unsigned minBytesPerBurst;
const unsigned maxBytesPerBurst;
void createChildTranses(tlm::tlm_generic_payload& parentTrans);
class MemoryManager : public tlm::tlm_mm_interface
{
public:
~MemoryManager() override;
tlm::tlm_generic_payload& allocate();
void free(tlm::tlm_generic_payload* payload) override;
private:
std::stack<tlm::tlm_generic_payload*> freePayloads;
} memoryManager;
};
#endif // CONTROLLER_H

View File

@@ -40,8 +40,8 @@ using namespace sc_core;
using namespace tlm;
ControllerRecordable::ControllerRecordable(const sc_module_name &name, const Configuration& config,
TlmRecorder& tlmRecorder)
: Controller(name, config), tlmRecorder(tlmRecorder),
const AddressDecoder& addressDecoder, TlmRecorder& tlmRecorder)
: Controller(name, config, addressDecoder), tlmRecorder(tlmRecorder),
activeTimeMultiplier(config.memSpec->tCK / config.memSpec->dataRate), enableWindowing(config.enableWindowing),
windowSizeTime(config.windowSize * memSpec.tCK)
{
@@ -58,7 +58,7 @@ ControllerRecordable::ControllerRecordable(const sc_module_name &name, const Con
tlm_sync_enum ControllerRecordable::nb_transport_fw(tlm_generic_payload &trans,
tlm_phase &phase, sc_time &delay)
{
recordPhase(trans, phase, delay);
tlmRecorder.recordPhase(trans, phase, delay);
return Controller::nb_transport_fw(trans, phase, delay);
}
@@ -71,43 +71,10 @@ tlm_sync_enum ControllerRecordable::nb_transport_bw(tlm_generic_payload &,
void ControllerRecordable::sendToFrontend(tlm_generic_payload& payload, tlm_phase& phase, sc_time& delay)
{
recordPhase(payload, phase, delay);
tlmRecorder.recordPhase(payload, phase, delay);
tSocket->nb_transport_bw(payload, phase, delay);
}
void ControllerRecordable::sendToDram(Command command, tlm_generic_payload& payload, sc_time& delay)
{
if (command.isCasCommand())
{
TimeInterval dataStrobe = memSpec.getIntervalOnDataStrobe(command, payload);
tlmRecorder.updateDataStrobe(sc_time_stamp() + delay + dataStrobe.start,
sc_time_stamp() + delay + dataStrobe.end, payload);
}
tlm_phase phase = command.toPhase();
iSocket->nb_transport_fw(payload, phase, delay);
}
void ControllerRecordable::recordPhase(tlm_generic_payload &trans, const tlm_phase &phase, const sc_time &delay)
{
sc_time recTime = delay + sc_time_stamp();
NDEBUG_UNUSED(unsigned thr) = DramExtension::getExtension(trans).getThread().ID();
NDEBUG_UNUSED(unsigned ch) = DramExtension::getExtension(trans).getChannel().ID();
NDEBUG_UNUSED(unsigned bg) = DramExtension::getExtension(trans).getBankGroup().ID();
NDEBUG_UNUSED(unsigned bank) = DramExtension::getExtension(trans).getBank().ID();
NDEBUG_UNUSED(unsigned row) = DramExtension::getExtension(trans).getRow().ID();
NDEBUG_UNUSED(unsigned col) = DramExtension::getExtension(trans).getColumn().ID();
NDEBUG_UNUSED(uint64_t id) = DramExtension::getExtension(trans).getChannelPayloadID();
PRINTDEBUGMESSAGE(name(), "Recording " + getPhaseName(phase) + " thread " +
std::to_string(thr) + " channel " + std::to_string(ch) + " bank group " + std::to_string(
bg) + " bank " + std::to_string(bank) + " row " + std::to_string(row) + " column " +
std::to_string(col) + " id " + std::to_string(id) + " at " + recTime.to_string());
tlmRecorder.recordPhase(trans, phase, recTime);
}
void ControllerRecordable::controllerMethod()
{
if (enableWindowing)

View File

@@ -43,7 +43,8 @@
class ControllerRecordable final : public Controller
{
public:
ControllerRecordable(const sc_core::sc_module_name &name, const Configuration& config, TlmRecorder& tlmRecorder);
ControllerRecordable(const sc_core::sc_module_name &name, const Configuration& config,
const AddressDecoder& addressDecoder, TlmRecorder& tlmRecorder);
~ControllerRecordable() override = default;
protected:
@@ -53,12 +54,10 @@ protected:
sc_core::sc_time &delay) override;
void sendToFrontend(tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay) override;
void sendToDram(Command command, tlm::tlm_generic_payload& trans, sc_core::sc_time& delay) override;
void controllerMethod() override;
private:
void recordPhase(tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase, const sc_core::sc_time &delay);
TlmRecorder& tlmRecorder;
sc_core::sc_event windowEvent;

View File

@@ -66,15 +66,15 @@ CheckerDDR3::CheckerDDR3(const Configuration& config)
sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, const tlm_generic_payload& payload) const
{
Rank rank = DramExtension::getRank(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(payload);
Bank bank = ControllerExtension::getBank(payload);
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
if (command == Command::RD || command == Command::RDA)
{
assert(DramExtension::getBurstLength(payload) == 8);
assert(ControllerExtension::getBurstLength(payload) == 8);
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != sc_max_time())
@@ -129,7 +129,7 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, const tlm_generic
}
else if (command == Command::WR || command == Command::WRA)
{
assert(DramExtension::getBurstLength(payload) == 8);
assert(ControllerExtension::getBurstLength(payload) == 8);
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != sc_max_time())
@@ -425,8 +425,8 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, const tlm_generic
void CheckerDDR3::insert(Command command, const tlm_generic_payload& payload)
{
Rank rank = DramExtension::getRank(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(payload);
Bank bank = ControllerExtension::getBank(payload);
PRINTDEBUGMESSAGE("CheckerDDR3", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + command.toString());

View File

@@ -69,16 +69,16 @@ CheckerDDR4::CheckerDDR4(const Configuration& config)
sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, const tlm_generic_payload& payload) const
{
Rank rank = DramExtension::getRank(payload);
BankGroup bankGroup = DramExtension::getBankGroup(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(payload);
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
Bank bank = ControllerExtension::getBank(payload);
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
if (command == Command::RD || command == Command::RDA)
{
assert(DramExtension::getBurstLength(payload) == 8);
assert(ControllerExtension::getBurstLength(payload) == 8);
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != sc_max_time())
@@ -149,7 +149,7 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, const tlm_generic
}
else if (command == Command::WR || command == Command::WRA)
{
assert(DramExtension::getBurstLength(payload) == 8);
assert(ControllerExtension::getBurstLength(payload) == 8);
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != sc_max_time())
@@ -457,9 +457,9 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, const tlm_generic
void CheckerDDR4::insert(Command command, const tlm_generic_payload& payload)
{
Rank rank = DramExtension::getRank(payload);
BankGroup bankGroup = DramExtension::getBankGroup(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(payload);
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
Bank bank = ControllerExtension::getBank(payload);
PRINTDEBUGMESSAGE("CheckerDDR4", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + command.toString());

View File

@@ -117,11 +117,11 @@ CheckerDDR5::CheckerDDR5(const Configuration& config)
sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, const tlm_generic_payload& payload) const
{
Rank logicalRank = DramExtension::getRank(payload);
Rank logicalRank = ControllerExtension::getRank(payload);
Rank physicalRank = Rank(logicalRank.ID() / memSpec->logicalRanksPerPhysicalRank);
Rank dimmRank = Rank(physicalRank.ID() / memSpec->physicalRanksPerDimmRank);
BankGroup bankGroup = DramExtension::getBankGroup(payload);
Bank bank = DramExtension::getBank(payload);
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
Bank bank = ControllerExtension::getBank(payload);
Bank bankInGroup = Bank(logicalRank.ID() * memSpec->banksPerGroup + bank.ID() % memSpec->banksPerGroup);
sc_time lastCommandStart;
@@ -129,7 +129,7 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, const tlm_generic
if (command == Command::RD || command == Command::RDA)
{
unsigned burstLength = DramExtension::getBurstLength(payload);
unsigned burstLength = ControllerExtension::getBurstLength(payload);
assert((burstLength == 16) || (burstLength == 32));
assert(!(burstLength == 32) || (memSpec->bitWidth == 4));
assert(burstLength <= memSpec->maxBurstLength);
@@ -316,7 +316,7 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, const tlm_generic
}
else if (command == Command::WR || command == Command::WRA)
{
unsigned burstLength = DramExtension::getBurstLength(payload);
unsigned burstLength = ControllerExtension::getBurstLength(payload);
assert((burstLength == 16) || (burstLength == 32));
assert(!(burstLength == 32) || (memSpec->bitWidth == 4));
assert(burstLength <= memSpec->maxBurstLength);
@@ -879,13 +879,13 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, const tlm_generic
void CheckerDDR5::insert(Command command, const tlm_generic_payload& payload)
{
Rank logicalRank = DramExtension::getRank(payload);
Rank logicalRank = ControllerExtension::getRank(payload);
Rank physicalRank = Rank(logicalRank.ID() / memSpec->logicalRanksPerPhysicalRank);
Rank dimmRank = Rank(physicalRank.ID() / memSpec->physicalRanksPerDimmRank);
BankGroup bankGroup = DramExtension::getBankGroup(payload);
Bank bank = DramExtension::getBank(payload);
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
Bank bank = ControllerExtension::getBank(payload);
Bank bankInGroup = Bank(logicalRank.ID() * memSpec->banksPerGroup + bank.ID() % memSpec->banksPerGroup);
unsigned burstLength = DramExtension::getBurstLength(payload);
unsigned burstLength = ControllerExtension::getBurstLength(payload);
PRINTDEBUGMESSAGE("CheckerDDR5", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + command.toString());

View File

@@ -70,16 +70,16 @@ CheckerGDDR5::CheckerGDDR5(const Configuration& config)
sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, const tlm_generic_payload& payload) const
{
Rank rank = DramExtension::getRank(payload);
BankGroup bankGroup = DramExtension::getBankGroup(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(payload);
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
Bank bank = ControllerExtension::getBank(payload);
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
if (command == Command::RD || command == Command::RDA)
{
assert(DramExtension::getBurstLength(payload) == 8);
assert(ControllerExtension::getBurstLength(payload) == 8);
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != sc_max_time())
@@ -150,7 +150,7 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, const tlm_generi
}
else if (command == Command::WR || command == Command::WRA)
{
assert(DramExtension::getBurstLength(payload) == 8);
assert(ControllerExtension::getBurstLength(payload) == 8);
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != sc_max_time())
@@ -539,9 +539,9 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, const tlm_generi
void CheckerGDDR5::insert(Command command, const tlm_generic_payload& payload)
{
Rank rank = DramExtension::getRank(payload);
BankGroup bankGroup = DramExtension::getBankGroup(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(payload);
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
Bank bank = ControllerExtension::getBank(payload);
PRINTDEBUGMESSAGE("CheckerGDDR5", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + command.toString());

View File

@@ -70,16 +70,16 @@ CheckerGDDR5X::CheckerGDDR5X(const Configuration& config)
sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, const tlm_generic_payload& payload) const
{
Rank rank = DramExtension::getRank(payload);
BankGroup bankGroup = DramExtension::getBankGroup(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(payload);
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
Bank bank = ControllerExtension::getBank(payload);
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
if (command == Command::RD || command == Command::RDA)
{
unsigned burstLength = DramExtension::getBurstLength(payload);
unsigned burstLength = ControllerExtension::getBurstLength(payload);
assert(!(memSpec->dataRate == 4) || (burstLength == 8)); // DDR mode (QDR wrt CK)
assert(!(memSpec->dataRate == 8) || (burstLength == 16)); // QDR mode (ODR wrt CK)
@@ -152,7 +152,7 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, const tlm_gener
}
else if (command == Command::WR || command == Command::WRA)
{
unsigned burstLength = DramExtension::getBurstLength(payload);
unsigned burstLength = ControllerExtension::getBurstLength(payload);
assert(!(memSpec->dataRate == 4) || (burstLength == 8)); // DDR mode (QDR wrt CK)
assert(!(memSpec->dataRate == 8) || (burstLength == 16)); // QDR mode (ODR wrt CK)
@@ -543,9 +543,9 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, const tlm_gener
void CheckerGDDR5X::insert(Command command, const tlm_generic_payload& payload)
{
Rank rank = DramExtension::getRank(payload);
BankGroup bankGroup = DramExtension::getBankGroup(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(payload);
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
Bank bank = ControllerExtension::getBank(payload);
PRINTDEBUGMESSAGE("CheckerGDDR5X", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + command.toString());

View File

@@ -69,16 +69,16 @@ CheckerGDDR6::CheckerGDDR6(const Configuration& config)
sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, const tlm_generic_payload& payload) const
{
Rank rank = DramExtension::getRank(payload);
BankGroup bankGroup = DramExtension::getBankGroup(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(payload);
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
Bank bank = ControllerExtension::getBank(payload);
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
if (command == Command::RD || command == Command::RDA)
{
assert(DramExtension::getBurstLength(payload) == 16);
assert(ControllerExtension::getBurstLength(payload) == 16);
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != sc_max_time())
@@ -149,7 +149,7 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, const tlm_generi
}
else if (command == Command::WR || command == Command::WRA)
{
assert(DramExtension::getBurstLength(payload) == 16);
assert(ControllerExtension::getBurstLength(payload) == 16);
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != sc_max_time())
@@ -560,9 +560,9 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, const tlm_generi
void CheckerGDDR6::insert(Command command, const tlm_generic_payload& payload)
{
Rank rank = DramExtension::getRank(payload);
BankGroup bankGroup = DramExtension::getBankGroup(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(payload);
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
Bank bank = ControllerExtension::getBank(payload);
PRINTDEBUGMESSAGE("CheckerGDDR6", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + command.toString());

View File

@@ -70,16 +70,16 @@ CheckerHBM2::CheckerHBM2(const Configuration& config)
sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, const tlm_generic_payload& payload) const
{
Rank rank = DramExtension::getRank(payload);
BankGroup bankGroup = DramExtension::getBankGroup(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(payload);
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
Bank bank = ControllerExtension::getBank(payload);
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
if (command == Command::RD || command == Command::RDA)
{
unsigned burstLength = DramExtension::getBurstLength(payload);
unsigned burstLength = ControllerExtension::getBurstLength(payload);
assert(!(memSpec->ranksPerChannel == 1) || (burstLength == 2 || burstLength == 4)); // Legacy mode
assert(!(memSpec->ranksPerChannel == 2) || (burstLength == 4)); // Pseudo-channel mode
@@ -134,8 +134,8 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, const tlm_generic
}
else if (command == Command::WR || command == Command::WRA)
{
unsigned burstLength = DramExtension::getBurstLength(payload);
assert(!(memSpec->ranksPerChannel == 1) || (burstLength == 2)); // Legacy mode
unsigned burstLength = ControllerExtension::getBurstLength(payload);
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()];
@@ -518,9 +518,9 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, const tlm_generic
void CheckerHBM2::insert(Command command, const tlm_generic_payload& payload)
{
Rank rank = DramExtension::getRank(payload);
BankGroup bankGroup = DramExtension::getBankGroup(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(payload);
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
Bank bank = ControllerExtension::getBank(payload);
PRINTDEBUGMESSAGE("CheckerHBM2", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + command.toString());

View File

@@ -69,9 +69,9 @@ CheckerHBM3::CheckerHBM3(const Configuration &config)
sc_time CheckerHBM3::timeToSatisfyConstraints(Command command, const tlm_generic_payload &payload) const
{
Rank rank = DramExtension::getRank(payload);
BankGroup bankGroup = DramExtension::getBankGroup(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(payload);
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
Bank bank = ControllerExtension::getBank(payload);
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
@@ -769,9 +769,9 @@ sc_time CheckerHBM3::timeToSatisfyConstraints(Command command, const tlm_generic
void CheckerHBM3::insert(Command command, const tlm_generic_payload &payload)
{
Rank rank = DramExtension::getRank(payload);
BankGroup bankGroup = DramExtension::getBankGroup(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(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());

View File

@@ -72,15 +72,15 @@ CheckerLPDDR4::CheckerLPDDR4(const Configuration& config)
sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, const tlm_generic_payload& payload) const
{
Rank rank = DramExtension::getRank(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(payload);
Bank bank = ControllerExtension::getBank(payload);
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
if (command == Command::RD || command == Command::RDA)
{
unsigned burstLength = DramExtension::getBurstLength(payload);
unsigned burstLength = ControllerExtension::getBurstLength(payload);
assert((burstLength == 16) || (burstLength == 32)); // TODO: BL16/32 OTF
assert(burstLength <= memSpec->maxBurstLength);
@@ -133,7 +133,7 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, const tlm_gener
}
else if (command == Command::WR || command == Command::WRA)
{
unsigned burstLength = DramExtension::getBurstLength(payload);
unsigned burstLength = ControllerExtension::getBurstLength(payload);
assert((burstLength == 16) || (burstLength == 32));
assert(burstLength <= memSpec->maxBurstLength);
@@ -513,8 +513,8 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, const tlm_gener
void CheckerLPDDR4::insert(Command command, const tlm_generic_payload& payload)
{
Rank rank = DramExtension::getRank(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(payload);
Bank bank = ControllerExtension::getBank(payload);
PRINTDEBUGMESSAGE("CheckerLPDDR4", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + command.toString());

View File

@@ -72,16 +72,16 @@ CheckerLPDDR5::CheckerLPDDR5(const Configuration& config)
sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_generic_payload& payload) const
{
Rank rank = DramExtension::getRank(payload);
BankGroup bankGroup = DramExtension::getBankGroup(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(payload);
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
Bank bank = ControllerExtension::getBank(payload);
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
if (command == Command::RD || command == Command::RDA)
{
unsigned burstLength = DramExtension::getBurstLength(payload);
unsigned burstLength = ControllerExtension::getBurstLength(payload);
assert(!(memSpec->bitWidth == 8) || (burstLength == 32)); // x8 device -> BL32
assert(!(memSpec->groupsPerRank > 1) || (burstLength == 16)); // BG mode -> BL16 (TODO: BL32)
assert(burstLength <= memSpec->maxBurstLength);
@@ -193,7 +193,7 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
}
else if (command == Command::WR || command == Command::WRA)
{
unsigned burstLength = DramExtension::getBurstLength(payload);
unsigned burstLength = ControllerExtension::getBurstLength(payload);
assert(!(memSpec->bitWidth == 8) || (burstLength == 32)); // x8 device -> BL32
assert(!(memSpec->groupsPerRank > 1) || (burstLength == 16)); // BG mode -> BL16 (TODO: BL32)
assert(burstLength <= memSpec->maxBurstLength);
@@ -638,10 +638,10 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, const tlm_gener
void CheckerLPDDR5::insert(Command command, const tlm_generic_payload& payload)
{
Rank rank = DramExtension::getRank(payload);
BankGroup bankGroup = DramExtension::getBankGroup(payload);
Bank bank = DramExtension::getBank(payload);
unsigned burstLength = DramExtension::getBurstLength(payload);
Rank rank = ControllerExtension::getRank(payload);
BankGroup bankGroup = ControllerExtension::getBankGroup(payload);
Bank bank = ControllerExtension::getBank(payload);
unsigned burstLength = ControllerExtension::getBurstLength(payload);
PRINTDEBUGMESSAGE("CheckerLPDDR5", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + command.toString());

View File

@@ -66,15 +66,15 @@ CheckerSTTMRAM::CheckerSTTMRAM(const Configuration& config)
sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, const tlm_generic_payload& payload) const
{
Rank rank = DramExtension::getRank(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(payload);
Bank bank = ControllerExtension::getBank(payload);
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
if (command == Command::RD || command == Command::RDA)
{
assert(DramExtension::getBurstLength(payload) == 8);
assert(ControllerExtension::getBurstLength(payload) == 8);
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != sc_max_time())
@@ -131,7 +131,7 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, const tlm_gene
}
else if (command == Command::WR || command == Command::WRA)
{
assert(DramExtension::getBurstLength(payload) == 8);
assert(ControllerExtension::getBurstLength(payload) == 8);
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != sc_max_time())
@@ -381,8 +381,8 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, const tlm_gene
void CheckerSTTMRAM::insert(Command command, const tlm_generic_payload& payload)
{
Rank rank = DramExtension::getRank(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(payload);
Bank bank = ControllerExtension::getBank(payload);
PRINTDEBUGMESSAGE("CheckerSTTMRAM", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + command.toString());

View File

@@ -66,15 +66,15 @@ CheckerWideIO::CheckerWideIO(const Configuration& config)
sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, const tlm_generic_payload& payload) const
{
Rank rank = DramExtension::getRank(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(payload);
Bank bank = ControllerExtension::getBank(payload);
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
if (command == Command::RD || command == Command::RDA)
{
unsigned burstLength = DramExtension::getBurstLength(payload);
unsigned burstLength = ControllerExtension::getBurstLength(payload);
assert((burstLength == 2) || (burstLength == 4));
assert(burstLength <= memSpec->maxBurstLength);
@@ -127,7 +127,7 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, const tlm_gener
}
else if (command == Command::WR || command == Command::WRA)
{
unsigned burstLength = DramExtension::getBurstLength(payload);
unsigned burstLength = ControllerExtension::getBurstLength(payload);
assert((burstLength == 2) || (burstLength == 4));
assert(burstLength <= memSpec->maxBurstLength);
@@ -402,8 +402,8 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, const tlm_gener
void CheckerWideIO::insert(Command command, const tlm_generic_payload& payload)
{
Rank rank = DramExtension::getRank(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(payload);
Bank bank = ControllerExtension::getBank(payload);
PRINTDEBUGMESSAGE("CheckerWideIO", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + command.toString());

View File

@@ -67,15 +67,15 @@ CheckerWideIO2::CheckerWideIO2(const Configuration& config)
sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, const tlm_generic_payload& payload) const
{
Rank rank = DramExtension::getRank(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(payload);
Bank bank = ControllerExtension::getBank(payload);
sc_time lastCommandStart;
sc_time earliestTimeToStart = sc_time_stamp();
if (command == Command::RD || command == Command::RDA)
{
unsigned burstLength = DramExtension::getBurstLength(payload);
unsigned burstLength = ControllerExtension::getBurstLength(payload);
assert((burstLength == 4) || (burstLength == 8)); // TODO: BL4/8 OTF
assert(burstLength <= memSpec->maxBurstLength);
@@ -128,7 +128,7 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, const tlm_gene
}
else if (command == Command::WR || command == Command::WRA)
{
unsigned burstLength = DramExtension::getBurstLength(payload);
unsigned burstLength = ControllerExtension::getBurstLength(payload);
assert((burstLength == 4) || (burstLength == 8));
assert(burstLength <= memSpec->maxBurstLength);
@@ -480,8 +480,8 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, const tlm_gene
void CheckerWideIO2::insert(Command command, const tlm_generic_payload& payload)
{
Rank rank = DramExtension::getRank(payload);
Bank bank = DramExtension::getBank(payload);
Rank rank = ControllerExtension::getRank(payload);
Bank bank = ControllerExtension::getBank(payload);
PRINTDEBUGMESSAGE("CheckerWideIO2", "Changing state on bank " + std::to_string(bank.ID())
+ " command is " + command.toString());

View File

@@ -52,7 +52,7 @@ CommandTuple::Type CmdMuxOldest::selectCommand(const ReadyCommands &readyCommand
{
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
memSpec.getCommandLength(std::get<CommandTuple::Command>(*it));
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
newPayloadID = ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
if (newTimestamp < lastTimestamp)
{
@@ -108,7 +108,7 @@ CommandTuple::Type CmdMuxOldestRasCas::selectCommand(const ReadyCommands &readyC
{
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
memSpec.getCommandLength(std::get<CommandTuple::Command>(*it));
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
newPayloadID = ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
if (newTimestamp < lastTimestamp)
{
@@ -130,7 +130,7 @@ CommandTuple::Type CmdMuxOldestRasCas::selectCommand(const ReadyCommands &readyC
{
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
memSpec.getCommandLength(std::get<CommandTuple::Command>(*it));
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
newPayloadID = ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
if (newTimestamp < lastTimestamp)
{
@@ -158,7 +158,7 @@ CommandTuple::Type CmdMuxOldestRasCas::selectCommand(const ReadyCommands &readyC
for (auto it = readyRasCasCommands.cbegin(); it != readyRasCasCommands.cend(); it++)
{
newTimestamp = std::get<CommandTuple::Timestamp>(*it);
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
newPayloadID = ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
if (newTimestamp < lastTimestamp)
{

View File

@@ -52,7 +52,7 @@ CommandTuple::Type CmdMuxStrict::selectCommand(const ReadyCommands &readyCommand
{
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
memSpec.getCommandLength(std::get<CommandTuple::Command>(*it));
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
newPayloadID = ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
if (newTimestamp < lastTimestamp)
{
@@ -118,7 +118,7 @@ CommandTuple::Type CmdMuxStrictRasCas::selectCommand(const ReadyCommands &readyC
{
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
memSpec.getCommandLength(std::get<CommandTuple::Command>(*it));
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
newPayloadID = ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
if (newTimestamp < lastTimestamp)
{
@@ -135,7 +135,7 @@ CommandTuple::Type CmdMuxStrictRasCas::selectCommand(const ReadyCommands &readyC
for (auto it = readyCasCommands.cbegin(); it != readyCasCommands.cend(); it++)
{
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
newPayloadID = ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
if (newPayloadID == nextPayloadID)
{
@@ -157,7 +157,7 @@ CommandTuple::Type CmdMuxStrictRasCas::selectCommand(const ReadyCommands &readyC
for (auto it = readyRasCasCommands.cbegin(); it != readyRasCasCommands.cend(); it++)
{
newTimestamp = std::get<CommandTuple::Timestamp>(*it);
newPayloadID = DramExtension::getChannelPayloadID(std::get<CommandTuple::Payload>(*it));
newPayloadID = ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
if (newTimestamp < lastTimestamp)
{

View File

@@ -40,7 +40,7 @@ using namespace tlm;
void RespQueueReorder::insertPayload(tlm_generic_payload *payload, sc_time strobeEnd)
{
buffer[DramExtension::getChannelPayloadID(payload)] = {payload, strobeEnd};
buffer[ControllerExtension::getChannelPayloadID(*payload)] = {payload, strobeEnd};
}
tlm_generic_payload *RespQueueReorder::nextPayload()

View File

@@ -50,7 +50,7 @@ bool BufferCounterBankwise::hasBufferSpace() const
void BufferCounterBankwise::storeRequest(const tlm_generic_payload& trans)
{
lastBankID = DramExtension::getBank(trans).ID();
lastBankID = ControllerExtension::getBank(trans).ID();
numRequestsOnBank[lastBankID]++;
if (trans.is_read())
numReadRequests++;
@@ -60,7 +60,7 @@ void BufferCounterBankwise::storeRequest(const tlm_generic_payload& trans)
void BufferCounterBankwise::removeRequest(const tlm_generic_payload& trans)
{
numRequestsOnBank[DramExtension::getBank(trans).ID()]--;
numRequestsOnBank[ControllerExtension::getBank(trans).ID()]--;
if (trans.is_read())
numReadRequests--;
else

View File

@@ -59,13 +59,13 @@ bool SchedulerFifo::hasBufferSpace() const
void SchedulerFifo::storeRequest(tlm_generic_payload& payload)
{
buffer[DramExtension::getBank(payload).ID()].push_back(&payload);
buffer[ControllerExtension::getBank(payload).ID()].push_back(&payload);
bufferCounter->storeRequest(payload);
}
void SchedulerFifo::removeRequest(tlm_generic_payload& payload)
{
buffer[DramExtension::getBank(payload).ID()].pop_front();
buffer[ControllerExtension::getBank(payload).ID()].pop_front();
bufferCounter->removeRequest(payload);
}
@@ -82,8 +82,8 @@ bool SchedulerFifo::hasFurtherRowHit(Bank bank, Row row, tlm_command command) co
{
if (buffer[bank.ID()].size() >= 2)
{
tlm_generic_payload *nextRequest = buffer[bank.ID()][1];
if (DramExtension::getRow(nextRequest) == row)
tlm_generic_payload& nextRequest = *buffer[bank.ID()][1];
if (ControllerExtension::getRow(nextRequest) == row)
return true;
}
return false;

View File

@@ -59,14 +59,14 @@ bool SchedulerFrFcfs::hasBufferSpace() const
void SchedulerFrFcfs::storeRequest(tlm_generic_payload& trans)
{
buffer[DramExtension::getBank(trans).ID()].push_back(&trans);
buffer[ControllerExtension::getBank(trans).ID()].push_back(&trans);
bufferCounter->storeRequest(trans);
}
void SchedulerFrFcfs::removeRequest(tlm_generic_payload& trans)
{
bufferCounter->removeRequest(trans);
unsigned bankID = DramExtension::getBank(trans).ID();
unsigned bankID = ControllerExtension::getBank(trans).ID();
for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++)
{
if (*it == &trans)
@@ -88,7 +88,7 @@ tlm_generic_payload *SchedulerFrFcfs::getNextRequest(const BankMachine& bankMach
Row openRow = bankMachine.getOpenRow();
for (auto it : buffer[bankID])
{
if (DramExtension::getRow(it) == openRow)
if (ControllerExtension::getRow(*it) == openRow)
return it;
}
}
@@ -103,7 +103,7 @@ bool SchedulerFrFcfs::hasFurtherRowHit(Bank bank, Row row, tlm_command command)
unsigned rowHitCounter = 0;
for (auto it : buffer[bank.ID()])
{
if (DramExtension::getRow(it) == row)
if (ControllerExtension::getRow(*it) == row)
{
rowHitCounter++;
if (rowHitCounter == 2)

View File

@@ -59,7 +59,7 @@ bool SchedulerFrFcfsGrp::hasBufferSpace() const
void SchedulerFrFcfsGrp::storeRequest(tlm_generic_payload& trans)
{
buffer[DramExtension::getBank(trans).ID()].push_back(&trans);
buffer[ControllerExtension::getBank(trans).ID()].push_back(&trans);
bufferCounter->storeRequest(trans);
}
@@ -67,7 +67,7 @@ void SchedulerFrFcfsGrp::removeRequest(tlm_generic_payload& trans)
{
bufferCounter->removeRequest(trans);
lastCommand = trans.get_command();
unsigned bankID = DramExtension::getBank(trans).ID();
unsigned bankID = ControllerExtension::getBank(trans).ID();
for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++)
{
if (*it == &trans)
@@ -90,7 +90,7 @@ tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(const BankMachine& bankM
std::list<tlm_generic_payload *> rowHits;
for (auto it : buffer[bankID])
{
if (DramExtension::getRow(it) == openRow)
if (ControllerExtension::getRow(*it) == openRow)
rowHits.push_back(it);
}
@@ -128,7 +128,7 @@ bool SchedulerFrFcfsGrp::hasFurtherRowHit(Bank bank, Row row, tlm_command comman
unsigned rowHitCounter = 0;
for (auto it : buffer[bank.ID()])
{
if (DramExtension::getRow(it) == row)
if (ControllerExtension::getRow(*it) == row)
{
rowHitCounter++;
if (rowHitCounter == 2)

View File

@@ -63,9 +63,9 @@ bool SchedulerGrpFrFcfs::hasBufferSpace() const
void SchedulerGrpFrFcfs::storeRequest(tlm_generic_payload& trans)
{
if (trans.is_read())
readBuffer[DramExtension::getBank(trans).ID()].push_back(&trans);
readBuffer[ControllerExtension::getBank(trans).ID()].push_back(&trans);
else
writeBuffer[DramExtension::getBank(trans).ID()].push_back(&trans);
writeBuffer[ControllerExtension::getBank(trans).ID()].push_back(&trans);
bufferCounter->storeRequest(trans);
}
@@ -73,7 +73,7 @@ void SchedulerGrpFrFcfs::removeRequest(tlm_generic_payload& trans)
{
bufferCounter->removeRequest(trans);
lastCommand = trans.get_command();
unsigned bankID = DramExtension::getBank(trans).ID();
unsigned bankID = ControllerExtension::getBank(trans).ID();
if (trans.is_read())
readBuffer[bankID].remove(&trans);
@@ -97,7 +97,7 @@ tlm_generic_payload *SchedulerGrpFrFcfs::getNextRequest(const BankMachine& bankM
Row openRow = bankMachine.getOpenRow();
for (auto it : readBuffer[bankID])
{
if (DramExtension::getRow(it) == openRow)
if (ControllerExtension::getRow(*it) == openRow)
return it;
}
}
@@ -112,7 +112,7 @@ tlm_generic_payload *SchedulerGrpFrFcfs::getNextRequest(const BankMachine& bankM
Row openRow = bankMachine.getOpenRow();
for (auto it : writeBuffer[bankID])
{
if (DramExtension::getRow(it) == openRow)
if (ControllerExtension::getRow(*it) == openRow)
return it;
}
}
@@ -132,7 +132,7 @@ tlm_generic_payload *SchedulerGrpFrFcfs::getNextRequest(const BankMachine& bankM
Row openRow = bankMachine.getOpenRow();
for (auto it : writeBuffer[bankID])
{
if (DramExtension::getRow(it) == openRow)
if (ControllerExtension::getRow(*it) == openRow)
return it;
}
}
@@ -147,7 +147,7 @@ tlm_generic_payload *SchedulerGrpFrFcfs::getNextRequest(const BankMachine& bankM
Row openRow = bankMachine.getOpenRow();
for (auto it : readBuffer[bankID])
{
if (DramExtension::getRow(it) == openRow)
if (ControllerExtension::getRow(*it) == openRow)
return it;
}
}
@@ -167,7 +167,7 @@ bool SchedulerGrpFrFcfs::hasFurtherRowHit(Bank bank, Row row, tlm_command comman
{
for (auto it : readBuffer[bank.ID()])
{
if (DramExtension::getRow(it) == row)
if (ControllerExtension::getRow(*it) == row)
{
rowHitCounter++;
if (rowHitCounter == 2)
@@ -180,7 +180,7 @@ bool SchedulerGrpFrFcfs::hasFurtherRowHit(Bank bank, Row row, tlm_command comman
{
for (auto it : writeBuffer[bank.ID()])
{
if (DramExtension::getRow(it) == row)
if (ControllerExtension::getRow(*it) == row)
{
rowHitCounter++;
if (rowHitCounter == 2)

View File

@@ -67,9 +67,9 @@ bool SchedulerGrpFrFcfsWm::hasBufferSpace() const
void SchedulerGrpFrFcfsWm::storeRequest(tlm_generic_payload& trans)
{
if (trans.is_read())
readBuffer[DramExtension::getBank(trans).ID()].push_back(&trans);
readBuffer[ControllerExtension::getBank(trans).ID()].push_back(&trans);
else
writeBuffer[DramExtension::getBank(trans).ID()].push_back(&trans);
writeBuffer[ControllerExtension::getBank(trans).ID()].push_back(&trans);
bufferCounter->storeRequest(trans);
evaluateWriteMode();
}
@@ -77,7 +77,7 @@ void SchedulerGrpFrFcfsWm::storeRequest(tlm_generic_payload& trans)
void SchedulerGrpFrFcfsWm::removeRequest(tlm_generic_payload& trans)
{
bufferCounter->removeRequest(trans);
unsigned bankID = DramExtension::getBank(trans).ID();
unsigned bankID = ControllerExtension::getBank(trans).ID();
if (trans.is_read())
readBuffer[bankID].remove(&trans);
@@ -101,7 +101,7 @@ tlm_generic_payload *SchedulerGrpFrFcfsWm::getNextRequest(const BankMachine& ban
Row openRow = bankMachine.getOpenRow();
for (auto it : readBuffer[bankID])
{
if (DramExtension::getRow(it) == openRow)
if (ControllerExtension::getRow(*it) == openRow)
return it;
}
}
@@ -121,7 +121,7 @@ tlm_generic_payload *SchedulerGrpFrFcfsWm::getNextRequest(const BankMachine& ban
Row openRow = bankMachine.getOpenRow();
for (auto it : writeBuffer[bankID])
{
if (DramExtension::getRow(it) == openRow)
if (ControllerExtension::getRow(*it) == openRow)
return it;
}
}
@@ -140,7 +140,7 @@ bool SchedulerGrpFrFcfsWm::hasFurtherRowHit(Bank bank, Row row, tlm::tlm_command
{
for (const auto* it : readBuffer[bank.ID()])
{
if (DramExtension::getRow(it) == row)
if (ControllerExtension::getRow(*it) == row)
{
rowHitCounter++;
if (rowHitCounter == 2)
@@ -153,7 +153,7 @@ bool SchedulerGrpFrFcfsWm::hasFurtherRowHit(Bank bank, Row row, tlm::tlm_command
{
for (auto it : writeBuffer[bank.ID()])
{
if (DramExtension::getRow(it) == row)
if (ControllerExtension::getRow(*it) == row)
{
rowHitCounter++;
if (rowHitCounter == 2)

View File

@@ -162,11 +162,13 @@ void errorModel::store(tlm::tlm_generic_payload &trans)
markBitFlips();
// Get the key for the dataMap from the transaction's dram extension:
DramExtension &ext = DramExtension::getExtension(trans);
DecodedAddress key = DecodedAddress(ext.getChannel().ID(), ext.getRank().ID(),
ext.getBankGroup().ID(), ext.getBank().ID(),
ext.getRow().ID(), ext.getColumn().ID(), 0);
// Set context:
// FIXME
// ControllerExtension &ext = ControllerExtension::getExtension(trans);
// DecodedAddress key = DecodedAddress(ext.getChannel().ID(), ext.getRank().ID(),
// ext.getBankGroup().ID(), ext.getBank().ID(),
// ext.getRow().ID(), ext.getColumn().ID(), 0);
DecodedAddress key;
// Set context:
setContext(key);
std::stringstream msg;
@@ -230,11 +232,12 @@ void errorModel::load(tlm::tlm_generic_payload &trans)
markBitFlips();
// Get the key for the dataMap from the transaction's dram extension:
DramExtension &ext = DramExtension::getExtension(trans);
DecodedAddress key = DecodedAddress(ext.getChannel().ID(), ext.getRank().ID(),
ext.getBankGroup().ID(), ext.getBank().ID(),
ext.getRow().ID(), ext.getColumn().ID(), 0);
// FIXME
// DramExtension &ext = DramExtension::getExtension(trans);
// DecodedAddress key = DecodedAddress(ext.getChannel().ID(), ext.getRank().ID(),
// ext.getBankGroup().ID(), ext.getBank().ID(),
// ext.getRow().ID(), ext.getColumn().ID(), 0);
DecodedAddress key;
// Set context:
setContext(key);

View File

@@ -101,14 +101,44 @@ AddressDecoder::AddressDecoder(const Configuration& config, const DRAMSysConfigu
maximumAddress = static_cast<uint64_t>(bytes) * columns * rows * banks
* bankGroups * ranks * channels - 1;
auto totalAddressBits = static_cast<unsigned>(std::log2(maximumAddress));
for (unsigned bitPosition = 0; bitPosition < totalAddressBits; bitPosition++)
{
if (std::count(vChannelBits.begin(), vChannelBits.end(), bitPosition)
+ std::count(vRankBits.begin(), vRankBits.end(), bitPosition)
+ std::count(vBankGroupBits.begin(), vBankGroupBits.end(), bitPosition)
+ std::count(vBankBits.begin(), vBankBits.end(), bitPosition)
+ std::count(vRowBits.begin(), vRowBits.end(), bitPosition)
+ std::count(vColumnBits.begin(), vColumnBits.end(), bitPosition)
+ std::count(vByteBits.begin(), vByteBits.end(), bitPosition)
!= 1)
SC_REPORT_FATAL("AddressDecoder", "Not all address bits occur exactly once");
}
const MemSpec& memSpec = *config.memSpec;
unsigned highestByteBit = *std::max_element(vByteBits.begin(), vByteBits.end());
for (unsigned bitPosition = 0; bitPosition <= highestByteBit; bitPosition++)
{
if (std::find(vByteBits.begin(), vByteBits.end(), bitPosition) == vByteBits.end())
SC_REPORT_FATAL("AddressDecoder", "Byte bits are not continuous starting from 0");
}
auto maxBurstLengthBits = static_cast<unsigned>(std::log2(memSpec.maxBurstLength));
for (unsigned bitPosition = highestByteBit + 1; bitPosition < highestByteBit + 1 + maxBurstLengthBits; bitPosition++)
{
if (std::find(vColumnBits.begin(), vColumnBits.end(), bitPosition) == vColumnBits.end())
SC_REPORT_FATAL("AddressDecoder", "No continuous column bits for maximum burst length");
}
bankgroupsPerRank = bankGroups;
bankGroups = bankgroupsPerRank * ranks;
banksPerGroup = banks;
banks = banksPerGroup * bankGroups;
const MemSpec& memSpec = *config.memSpec;
if (memSpec.numberOfChannels != channels || memSpec.ranksPerChannel != ranks
|| memSpec.bankGroupsPerChannel != bankGroups || memSpec.banksPerChannel != banks
|| memSpec.rowsPerBank != rows || memSpec.columnsPerRow != columns
@@ -116,7 +146,7 @@ AddressDecoder::AddressDecoder(const Configuration& config, const DRAMSysConfigu
SC_REPORT_FATAL("AddressDecoder", "Memspec and address mapping do not match");
}
DecodedAddress AddressDecoder::decodeAddress(uint64_t encAddr)
DecodedAddress AddressDecoder::decodeAddress(uint64_t encAddr) const
{
if (encAddr > maximumAddress)
SC_REPORT_WARNING("AddressDecoder", ("Address " + std::to_string(encAddr) + " out of range (maximum address is " + std::to_string(maximumAddress) + ")").c_str());
@@ -161,7 +191,31 @@ DecodedAddress AddressDecoder::decodeAddress(uint64_t encAddr)
return decAddr;
}
void AddressDecoder::print()
unsigned AddressDecoder::decodeChannel(uint64_t encAddr) const
{
if (encAddr > maximumAddress)
SC_REPORT_WARNING("AddressDecoder", ("Address " + std::to_string(encAddr) + " out of range (maximum address is " + std::to_string(maximumAddress) + ")").c_str());
// Apply XOR
// For each used xor:
// Get the first bit and second bit. Apply a bitwise xor operator and save it back to the first bit.
for (auto &it : vXor)
{
uint64_t xoredBit;
xoredBit = (((encAddr >> it.first) & UINT64_C(1)) ^ ((encAddr >> it.second) & UINT64_C(1)));
encAddr &= ~(UINT64_C(1) << it.first);
encAddr |= xoredBit << it.first;
}
unsigned channel = 0;
for (unsigned it = 0; it < vChannelBits.size(); it++)
channel |= ((encAddr >> vChannelBits[it]) & UINT64_C(1)) << it;
return channel;
}
void AddressDecoder::print() const
{
std::cout << headline << std::endl;
std::cout << "Used Address Mapping:" << std::endl;

View File

@@ -68,8 +68,9 @@ class AddressDecoder
{
public:
AddressDecoder(const Configuration& config, const DRAMSysConfiguration::AddressMapping &addressMapping);
DecodedAddress decodeAddress(uint64_t addr);
void print();
DecodedAddress decodeAddress(uint64_t encAddr) const;
unsigned decodeChannel(uint64_t encAddr) const;
void print() const;
private:
unsigned banksPerGroup;

View File

@@ -47,8 +47,8 @@ using namespace sc_core;
using namespace tlm;
Arbiter::Arbiter(const sc_module_name &name, const Configuration& config,
const DRAMSysConfiguration::AddressMapping& addressMapping) :
sc_module(name), addressDecoder(config, addressMapping), payloadEventQueue(this, &Arbiter::peqCallback),
const AddressDecoder& addressDecoder) :
sc_module(name), addressDecoder(addressDecoder), payloadEventQueue(this, &Arbiter::peqCallback),
tCK(config.memSpec->tCK),
arbitrationDelayFw(config.arbitrationDelayFw),
arbitrationDelayBw(config.arbitrationDelayBw),
@@ -58,22 +58,20 @@ Arbiter::Arbiter(const sc_module_name &name, const Configuration& config,
iSocket.register_nb_transport_bw(this, &Arbiter::nb_transport_bw);
tSocket.register_nb_transport_fw(this, &Arbiter::nb_transport_fw);
tSocket.register_transport_dbg(this, &Arbiter::transport_dbg);
addressDecoder.print();
}
ArbiterSimple::ArbiterSimple(const sc_module_name& name, const Configuration& config,
const DRAMSysConfiguration::AddressMapping &addressMapping) :
Arbiter(name, config, addressMapping) {}
const AddressDecoder& addressDecoder) :
Arbiter(name, config, addressDecoder) {}
ArbiterFifo::ArbiterFifo(const sc_module_name &name, const Configuration& config,
const DRAMSysConfiguration::AddressMapping &addressMapping) :
Arbiter(name, config, addressMapping),
const AddressDecoder& addressDecoder) :
Arbiter(name, config, addressDecoder),
maxActiveTransactions(config.maxActiveTransactions) {}
ArbiterReorder::ArbiterReorder(const sc_module_name &name, const Configuration& config,
const DRAMSysConfiguration::AddressMapping &addressMapping) :
Arbiter(name, config, addressMapping),
const AddressDecoder& addressDecoder) :
Arbiter(name, config, addressDecoder),
maxActiveTransactions(config.maxActiveTransactions) {}
void Arbiter::end_of_elaboration()
@@ -140,12 +138,9 @@ tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload &payload,
uint64_t adjustedAddress = payload.get_address() - addressOffset;
payload.set_address(adjustedAddress);
DecodedAddress decodedAddress = addressDecoder.decodeAddress(adjustedAddress);
DramExtension::setExtension(payload, Thread(static_cast<unsigned int>(id)), Channel(decodedAddress.channel),
Rank(decodedAddress.rank),
BankGroup(decodedAddress.bankgroup), Bank(decodedAddress.bank),
Row(decodedAddress.row), Column(decodedAddress.column),
payload.get_data_length() / bytesPerBeat, 0, 0);
unsigned channel = addressDecoder.decodeChannel(adjustedAddress);
assert(addressDecoder.decodeChannel(adjustedAddress + payload.get_data_length() - 1) == channel);
ArbiterExtension::setAutoExtension(payload, Thread(id), Channel(channel));
payload.acquire();
}
@@ -174,14 +169,12 @@ unsigned int Arbiter::transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans)
void ArbiterSimple::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &cbPhase)
{
unsigned int threadId = DramExtension::getExtension(cbPayload).getThread().ID();
unsigned int channelId = DramExtension::getExtension(cbPayload).getChannel().ID();
unsigned int threadId = ArbiterExtension::getThread(cbPayload).ID();
unsigned int channelId = ArbiterExtension::getChannel(cbPayload).ID();
if (cbPhase == BEGIN_REQ) // from initiator
{
GenerationExtension::setExtension(cbPayload, sc_time_stamp());
DramExtension::setPayloadIDs(cbPayload,
nextThreadPayloadIDToAppend[threadId]++, nextChannelPayloadIDToAppend[channelId]++);
ArbiterExtension::setIDAndTimeOfGeneration(cbPayload, nextThreadPayloadIDToAppend[threadId]++, sc_time_stamp());
if (!channelIsBusy[channelId])
{
@@ -265,8 +258,8 @@ void ArbiterSimple::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase
void ArbiterFifo::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &cbPhase)
{
unsigned int threadId = DramExtension::getExtension(cbPayload).getThread().ID();
unsigned int channelId = DramExtension::getExtension(cbPayload).getChannel().ID();
unsigned int threadId = ArbiterExtension::getThread(cbPayload).ID();
unsigned int channelId = ArbiterExtension::getChannel(cbPayload).ID();
if (cbPhase == BEGIN_REQ) // from initiator
{
@@ -274,9 +267,8 @@ void ArbiterFifo::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &c
{
activeTransactions[threadId]++;
GenerationExtension::setExtension(cbPayload, sc_time_stamp());
DramExtension::setPayloadIDs(cbPayload,
nextThreadPayloadIDToAppend[threadId]++, nextChannelPayloadIDToAppend[channelId]++);
ArbiterExtension::setIDAndTimeOfGeneration(cbPayload, nextThreadPayloadIDToAppend[threadId]++,
sc_time_stamp());
tlm_phase tPhase = END_REQ;
sc_time tDelay = SC_ZERO_TIME;
@@ -327,11 +319,9 @@ void ArbiterFifo::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &c
outstandingEndReq[threadId] = nullptr;
tlm_phase tPhase = END_REQ;
sc_time tDelay = SC_ZERO_TIME;
unsigned int tChannelId = DramExtension::getExtension(tPayload).getChannel().ID();
GenerationExtension::setExtension(tPayload, sc_time_stamp());
DramExtension::setPayloadIDs(tPayload,
nextThreadPayloadIDToAppend[threadId]++, nextChannelPayloadIDToAppend[tChannelId]++);
ArbiterExtension::setIDAndTimeOfGeneration(tPayload, nextThreadPayloadIDToAppend[threadId]++,
sc_time_stamp());
tSocket[static_cast<int>(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay);
@@ -396,8 +386,8 @@ void ArbiterFifo::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &c
void ArbiterReorder::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &cbPhase)
{
unsigned int threadId = DramExtension::getExtension(cbPayload).getThread().ID();
unsigned int channelId = DramExtension::getExtension(cbPayload).getChannel().ID();
unsigned int threadId = ArbiterExtension::getThread(cbPayload).ID();
unsigned int channelId = ArbiterExtension::getChannel(cbPayload).ID();
if (cbPhase == BEGIN_REQ) // from initiator
{
@@ -405,9 +395,8 @@ void ArbiterReorder::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase
{
activeTransactions[threadId]++;
GenerationExtension::setExtension(cbPayload, sc_time_stamp());
DramExtension::setPayloadIDs(cbPayload,
nextThreadPayloadIDToAppend[threadId]++, nextChannelPayloadIDToAppend[channelId]++);
ArbiterExtension::setIDAndTimeOfGeneration(cbPayload, nextThreadPayloadIDToAppend[threadId]++,
sc_time_stamp());
tlm_phase tPhase = END_REQ;
sc_time tDelay = SC_ZERO_TIME;
@@ -457,11 +446,9 @@ void ArbiterReorder::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase
outstandingEndReq[threadId] = nullptr;
tlm_phase tPhase = END_REQ;
sc_time tDelay = SC_ZERO_TIME;
unsigned int tChannelId = DramExtension::getExtension(tPayload).getChannel().ID();
GenerationExtension::setExtension(tPayload, sc_time_stamp());
DramExtension::setPayloadIDs(tPayload,
nextThreadPayloadIDToAppend[threadId]++, nextChannelPayloadIDToAppend[tChannelId]++);
ArbiterExtension::setIDAndTimeOfGeneration(tPayload, nextThreadPayloadIDToAppend[threadId]++,
sc_time_stamp());
tSocket[static_cast<int>(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay);
@@ -473,7 +460,7 @@ void ArbiterReorder::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase
tlm_generic_payload &tPayload = **pendingResponses[threadId].begin();
if (!pendingResponses[threadId].empty() &&
DramExtension::getThreadPayloadID(tPayload) == nextThreadPayloadIDToReturn[threadId])
ArbiterExtension::getThreadPayloadID(tPayload) == nextThreadPayloadIDToReturn[threadId])
{
nextThreadPayloadIDToReturn[threadId]++;
pendingResponses[threadId].erase(pendingResponses[threadId].begin());
@@ -513,7 +500,7 @@ void ArbiterReorder::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase
{
tlm_generic_payload &tPayload = **pendingResponses[threadId].begin();
if (DramExtension::getThreadPayloadID(tPayload) == nextThreadPayloadIDToReturn[threadId])
if (ArbiterExtension::getThreadPayloadID(tPayload) == nextThreadPayloadIDToReturn[threadId])
{
threadIsBusy[threadId] = true;

View File

@@ -64,12 +64,12 @@ public:
protected:
Arbiter(const sc_core::sc_module_name &name, const Configuration& config,
const DRAMSysConfiguration::AddressMapping &addressMapping);
const AddressDecoder& addressDecoder);
SC_HAS_PROCESS(Arbiter);
void end_of_elaboration() override;
AddressDecoder addressDecoder;
const AddressDecoder& addressDecoder;
tlm_utils::peq_with_cb_and_phase<Arbiter> payloadEventQueue;
virtual void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase) = 0;
@@ -100,7 +100,7 @@ class ArbiterSimple final : public Arbiter
{
public:
ArbiterSimple(const sc_core::sc_module_name &name, const Configuration& config,
const DRAMSysConfiguration::AddressMapping &addressMapping);
const AddressDecoder& addressDecoder);
SC_HAS_PROCESS(ArbiterSimple);
private:
@@ -114,7 +114,7 @@ class ArbiterFifo final : public Arbiter
{
public:
ArbiterFifo(const sc_core::sc_module_name &name, const Configuration& config,
const DRAMSysConfiguration::AddressMapping &addressMapping);
const AddressDecoder& addressDecoder);
SC_HAS_PROCESS(ArbiterFifo);
private:
@@ -135,7 +135,7 @@ class ArbiterReorder final : public Arbiter
{
public:
ArbiterReorder(const sc_core::sc_module_name &name, const Configuration& config,
const DRAMSysConfiguration::AddressMapping &addressMapping);
const AddressDecoder& addressDecoder);
SC_HAS_PROCESS(ArbiterReorder);
private:
@@ -149,7 +149,7 @@ private:
{
bool operator() (const tlm::tlm_generic_payload *lhs, const tlm::tlm_generic_payload *rhs) const
{
return DramExtension::getThreadPayloadID(lhs) < DramExtension::getThreadPayloadID(rhs);
return ArbiterExtension::getThreadPayloadID(*lhs) < ArbiterExtension::getThreadPayloadID(*rhs);
}
};

View File

@@ -144,7 +144,7 @@ void DRAMSys::logo()
#undef BOLDTXT
}
void DRAMSys::setupDebugManager(NDEBUG_UNUSED(const std::string &traceName))
void DRAMSys::setupDebugManager(NDEBUG_UNUSED(const std::string &traceName)) const
{
#ifndef NDEBUG
auto& dbg = DebugManager::getInstance();
@@ -157,23 +157,27 @@ void DRAMSys::setupDebugManager(NDEBUG_UNUSED(const std::string &traceName))
#endif
}
void DRAMSys::instantiateModules(const DRAMSysConfiguration::AddressMapping &addressMapping)
void DRAMSys::instantiateModules(const DRAMSysConfiguration::AddressMapping& addressMapping)
{
temperatureController = std::make_unique<TemperatureController>("TemperatureController", config);
addressDecoder = std::make_unique<AddressDecoder>(config, addressMapping);
addressDecoder->print();
// Create arbiter
if (config.arbiter == Configuration::Arbiter::Simple)
arbiter = std::make_unique<ArbiterSimple>("arbiter", config, addressMapping);
arbiter = std::make_unique<ArbiterSimple>("arbiter", config, *addressDecoder);
else if (config.arbiter == Configuration::Arbiter::Fifo)
arbiter = std::make_unique<ArbiterFifo>("arbiter", config, addressMapping);
arbiter = std::make_unique<ArbiterFifo>("arbiter", config, *addressDecoder);
else if (config.arbiter == Configuration::Arbiter::Reorder)
arbiter = std::make_unique<ArbiterReorder>("arbiter", config, addressMapping);
arbiter = std::make_unique<ArbiterReorder>("arbiter", config, *addressDecoder);
// Create controllers and DRAMs
MemSpec::MemoryType memoryType = config.memSpec->memoryType;
for (std::size_t i = 0; i < config.memSpec->numberOfChannels; i++)
{
controllers.emplace_back(std::make_unique<Controller>(("controller" + std::to_string(i)).c_str(), config));
controllers.emplace_back(std::make_unique<Controller>(("controller" + std::to_string(i)).c_str(), config,
*addressDecoder));
if (memoryType == MemSpec::MemoryType::DDR3)
drams.emplace_back(std::make_unique<DramDDR3>(("dram" + std::to_string(i)).c_str(), config,

View File

@@ -48,6 +48,7 @@
#include "../error/eccbaseclass.h"
#include "../controller/ControllerIF.h"
#include "TemperatureController.h"
#include "AddressDecoder.h"
#include <DRAMSysConfiguration.h>
#include <string>
@@ -94,6 +95,8 @@ protected:
// DRAM units
std::vector<std::unique_ptr<Dram>> drams;
std::unique_ptr<AddressDecoder> addressDecoder;
void report(const std::string &message);
void bindSockets();
@@ -102,7 +105,7 @@ private:
void instantiateModules(const DRAMSysConfiguration::AddressMapping &addressMapping);
void setupDebugManager(const std::string &traceName);
void setupDebugManager(const std::string &traceName) const;
};
#endif // DRAMSYS_H

View File

@@ -101,9 +101,13 @@ void DRAMSysRecordable::end_of_simulation()
void DRAMSysRecordable::setupTlmRecorders(const std::string& traceName, const DRAMSysConfiguration::Configuration& configLib)
{
// Create TLM Recorders, one per channel.
// Reserve is required because the recorders use double buffers that are accessed with pointers.
// Without a reserve, the vector reallocates storage before inserting a second
// element and the pointers are not valid anymore.
tlmRecorders.reserve(config.memSpec->numberOfChannels);
for (std::size_t i = 0; i < config.memSpec->numberOfChannels; i++)
{
std::string dbName = traceName + std::string("_ch") + std::to_string(i) + ".tdb";
std::string dbName = std::string(name()) + "_" + traceName + "_ch" + std::to_string(i) + ".tdb";
std::string recorderName = "tlmRecorder" + std::to_string(i);
tlmRecorders.emplace_back(recorderName, config, dbName);
@@ -118,24 +122,27 @@ void DRAMSysRecordable::instantiateModules(const std::string &traceName,
{
temperatureController = std::make_unique<TemperatureController>("TemperatureController", config);
addressDecoder = std::make_unique<AddressDecoder>(config, configLib.addressMapping);
addressDecoder->print();
// Create and properly initialize TLM recorders.
// They need to be ready before creating some modules.
setupTlmRecorders(traceName, configLib);
// Create arbiter
if (config.arbiter == Configuration::Arbiter::Simple)
arbiter = std::make_unique<ArbiterSimple>("arbiter", config, configLib.addressMapping);
arbiter = std::make_unique<ArbiterSimple>("arbiter", config, *addressDecoder);
else if (config.arbiter == Configuration::Arbiter::Fifo)
arbiter = std::make_unique<ArbiterFifo>("arbiter", config, configLib.addressMapping);
arbiter = std::make_unique<ArbiterFifo>("arbiter", config, *addressDecoder);
else if (config.arbiter == Configuration::Arbiter::Reorder)
arbiter = std::make_unique<ArbiterReorder>("arbiter", config, configLib.addressMapping);
arbiter = std::make_unique<ArbiterReorder>("arbiter", config, *addressDecoder);
// Create controllers and DRAMs
MemSpec::MemoryType memoryType = config.memSpec->memoryType;
for (std::size_t i = 0; i < config.memSpec->numberOfChannels; i++)
{
controllers.emplace_back(std::make_unique<ControllerRecordable>(("controller" + std::to_string(i)).c_str(),
config, tlmRecorders[i]));
config, *addressDecoder, tlmRecorders[i]));
if (memoryType == MemSpec::MemoryType::DDR3)
drams.emplace_back(std::make_unique<DramRecordable<DramDDR3>>(("dram" + std::to_string(i)).c_str(),

View File

@@ -57,7 +57,6 @@ private:
void setupTlmRecorders(const std::string &traceName, const DRAMSysConfiguration::Configuration &configLib);
void instantiateModules(const std::string &traceName, const DRAMSysConfiguration::Configuration &configLib);
};
#endif // DRAMSYSRECORDABLE_H

View File

@@ -133,7 +133,7 @@ tlm_sync_enum Dram::nb_transport_fw(tlm_generic_payload &payload,
if (powerAnalysis)
{
int bank = static_cast<int>(DramExtension::getExtension(payload).getBank().ID());
int bank = static_cast<int>(ControllerExtension::getBank(payload).ID());
int64_t cycle = std::lround((sc_time_stamp() + delay) / memSpec.tCK);
#ifdef DRAMPOWER

View File

@@ -91,42 +91,10 @@ template<class BaseDram>
tlm_sync_enum DramRecordable<BaseDram>::nb_transport_fw(tlm_generic_payload &payload,
tlm_phase &phase, sc_time &delay)
{
recordPhase(payload, phase, delay);
tlmRecorder.recordPhase(payload, phase, delay);
return BaseDram::nb_transport_fw(payload, phase, delay);
}
template<class BaseDram>
void DramRecordable<BaseDram>::recordPhase(tlm_generic_payload &trans, const tlm_phase &phase, const sc_time &delay)
{
sc_time recTime = sc_time_stamp() + delay;
// These are terminating phases recorded by the DRAM. The execution
// time of the related command must be taken into consideration.
if (phase == END_PDNA || phase == END_PDNP || phase == END_SREF)
recTime += this->memSpec.getCommandLength(Command(phase));
NDEBUG_UNUSED(unsigned thr) = DramExtension::getExtension(trans).getThread().ID();
NDEBUG_UNUSED(unsigned ch) = DramExtension::getExtension(trans).getChannel().ID();
NDEBUG_UNUSED(unsigned bg) = DramExtension::getExtension(trans).getBankGroup().ID();
NDEBUG_UNUSED(unsigned bank) = DramExtension::getExtension(trans).getBank().ID();
NDEBUG_UNUSED(unsigned row) = DramExtension::getExtension(trans).getRow().ID();
NDEBUG_UNUSED(unsigned col) = DramExtension::getExtension(trans).getColumn().ID();
PRINTDEBUGMESSAGE(this->name(), "Recording " + getPhaseName(phase) + " thread " +
std::to_string(thr) + " channel " + std::to_string(ch) + " bank group " + std::to_string(
bg) + " bank " + std::to_string(bank) + " row " + std::to_string(row) + " column " +
std::to_string(col) + " at " + recTime.to_string());
tlmRecorder.recordPhase(trans, phase, recTime);
if (phaseNeedsEnd(phase))
{
recTime += this->memSpec.getExecutionTime(Command(phase), trans);
tlmRecorder.recordPhase(trans, getEndPhase(phase), recTime);
}
}
#ifdef DRAMPOWER
// This Thread is only triggered when Power Simulation is enabled.
// It estimates the current average power which will be stored in the trace database for visualization purposes.

View File

@@ -60,8 +60,6 @@ private:
tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &payload,
tlm::tlm_phase &phase, sc_core::sc_time &delay) override;
void recordPhase(tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase, const sc_core::sc_time &delay);
TlmRecorder& tlmRecorder;
sc_core::sc_time powerWindowSize;

View File

@@ -184,7 +184,7 @@ tlm_sync_enum DramWideIO::nb_transport_fw(tlm_generic_payload &payload,
#ifdef DRAMPOWER
if (powerAnalysis)
{
int bank = static_cast<int>(DramExtension::getExtension(payload).getBank().ID());
int bank = static_cast<int>(ControllerExtension::getBank(payload).ID());
int64_t cycle = std::lround((sc_time_stamp() + delay) / memSpec.tCK);
DRAMPower->doCommand(phaseToDRAMPowerCommand(phase), bank, cycle);
}
@@ -206,16 +206,16 @@ tlm_sync_enum DramWideIO::nb_transport_fw(tlm_generic_payload &payload,
else if (storeMode == Configuration::StoreMode::ErrorModel)
{
// TODO: delay should be considered here!
unsigned bank = DramExtension::getExtension(payload).getBank().ID();
unsigned bank = ControllerExtension::getBank(payload).ID();
if (phase == BEGIN_ACT)
ememory[bank]->activate(DramExtension::getExtension(payload).getRow().ID());
ememory[bank]->activate(ControllerExtension::getRow(payload).ID());
else if (phase == BEGIN_RD || phase == BEGIN_RDA)
ememory[bank]->load(payload);
else if (phase == BEGIN_WR || phase == BEGIN_WRA)
ememory[bank]->store(payload);
else if (phase == BEGIN_REFAB)
ememory[bank]->refresh(DramExtension::getExtension(payload).getRow().ID());
ememory[bank]->refresh(ControllerExtension::getRow(payload).ID());
}
return TLM_ACCEPTED;

View File

@@ -143,6 +143,7 @@ void LengthConverter::peqCallback(tlm_generic_payload &cbTrans, const tlm_phase
tlm_generic_payload* parentTrans = cbTrans.get_extension<ChildExtension>()->getParentTrans();
tlm_phase bwPhase = BEGIN_RESP;
sc_time bwDelay = SC_ZERO_TIME;
parentTrans->set_response_status(tlm::TLM_OK_RESPONSE);
tlm_sync_enum returnStatus = tSocket->nb_transport_bw(*parentTrans, bwPhase, bwDelay);
}
}
@@ -150,6 +151,7 @@ void LengthConverter::peqCallback(tlm_generic_payload &cbTrans, const tlm_phase
{
tlm_phase bwPhase = BEGIN_RESP;
sc_time bwDelay = SC_ZERO_TIME;
cbTrans.set_response_status(tlm::TLM_OK_RESPONSE);
tlm_sync_enum returnStatus = tSocket->nb_transport_bw(cbTrans, bwPhase, bwDelay);
}
}

View File

@@ -45,9 +45,9 @@ using namespace tlm;
StlPlayer::StlPlayer(const sc_module_name &name, const Configuration& config, const std::string &pathToTrace,
const sc_time &playerClk, unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests,
bool addLengthConverter, TraceSetup& setup, bool relative) :
TraceSetup& setup, bool relative) :
TrafficInitiator(name, config, setup, maxPendingReadRequests, maxPendingWriteRequests,
config.memSpec->defaultBytesPerBurst, addLengthConverter),
config.memSpec->defaultBytesPerBurst),
file(pathToTrace), relative(relative), playerClk(playerClk)
{
currentBuffer = &lineContents[0];

View File

@@ -70,7 +70,6 @@ public:
const sc_core::sc_time &playerClk,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
bool addLengthConverter,
TraceSetup& setup,
bool relative);

View File

@@ -79,14 +79,6 @@ TraceSetup::TraceSetup(const Configuration& config,
return 0;
}();
bool addLengthConverter = [=]() -> bool
{
if (const auto &addLengthConverter = initiator.addLengthConverter)
return *addLengthConverter;
else
return false;
}();
using T = std::decay_t<decltype(initiator)>;
if constexpr (std::is_same_v<T, DRAMSysConfiguration::TracePlayer>)
{
@@ -109,10 +101,10 @@ TraceSetup::TraceSetup(const Configuration& config,
StlPlayer *player;
if (ext == "stl")
player = new StlPlayer(moduleName.c_str(), config, stlFile, playerClk, maxPendingReadRequests,
maxPendingWriteRequests, addLengthConverter, *this, false);
maxPendingWriteRequests, *this, false);
else if (ext == "rstl")
player = new StlPlayer(moduleName.c_str(), config, stlFile, playerClk, maxPendingReadRequests,
maxPendingWriteRequests, addLengthConverter, *this, true);
maxPendingWriteRequests, *this, true);
else
throw std::runtime_error("Unsupported file extension in " + name);

View File

@@ -47,9 +47,8 @@ using namespace tlm;
TrafficGeneratorIf::TrafficGeneratorIf(const sc_core::sc_module_name& name, const Configuration& config,
TraceSetup& setup,
unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests,
unsigned int dataLength, bool addLengthConverter)
: TrafficInitiator(name, config, setup, maxPendingReadRequests, maxPendingWriteRequests, dataLength,
addLengthConverter)
unsigned int dataLength)
: TrafficInitiator(name, config, setup, maxPendingReadRequests, maxPendingWriteRequests, dataLength)
{
}
@@ -99,8 +98,7 @@ TrafficGenerator::TrafficGenerator(const sc_module_name& name, const Configurati
const DRAMSysConfiguration::TraceGenerator& conf, TraceSetup& setup)
: TrafficGeneratorIf(name, config, setup, conf.maxPendingReadRequests.value_or(defaultMaxPendingReadRequests),
conf.maxPendingWriteRequests.value_or(defaultMaxPendingWriteRequests),
conf.dataLength.value_or(config.memSpec->defaultBytesPerBurst),
conf.addLengthConverter.value_or(false)),
conf.dataLength.value_or(config.memSpec->defaultBytesPerBurst)),
generatorClk(TrafficInitiator::evaluateGeneratorClk(conf)), conf(conf),
maxTransactions(conf.maxTransactions.value_or(std::numeric_limits<uint64_t>::max())),
simMemSizeInBytes(config.memSpec->getSimMemSizeInBytes()),
@@ -381,7 +379,7 @@ uint64_t TrafficGenerator::evaluateMaxAddress(const DRAMSysConfiguration::TraceG
TrafficGeneratorHammer::TrafficGeneratorHammer(const sc_core::sc_module_name &name, const Configuration& config,
const DRAMSysConfiguration::TraceHammer &conf, TraceSetup& setup)
: TrafficGeneratorIf(name, config, setup, 1, 1, config.memSpec->defaultBytesPerBurst, false),
: TrafficGeneratorIf(name, config, setup, 1, 1, config.memSpec->defaultBytesPerBurst),
generatorClk(evaluateGeneratorClk(conf)), rowIncrement(conf.rowIncrement), numRequests(conf.numRequests)
{
}

View File

@@ -51,7 +51,7 @@ class TrafficGeneratorIf : public TrafficInitiator
public:
TrafficGeneratorIf(const sc_core::sc_module_name &name, const Configuration& config, TraceSetup& setup,
unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests,
unsigned int dataLength, bool addLengthConverter);
unsigned int dataLength);
private:
void sendNextPayload() override;

View File

@@ -44,10 +44,8 @@ using namespace sc_core;
using namespace tlm;
TrafficInitiator::TrafficInitiator(const sc_module_name &name, const Configuration& config, TraceSetup& setup,
unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests,
unsigned int defaultDataLength, bool addLengthConverter) :
unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests, unsigned int defaultDataLength) :
sc_module(name),
addLengthConverter(addLengthConverter),
payloadEventQueue(this, &TrafficInitiator::peqCallback),
setup(setup),
maxPendingReadRequests(maxPendingReadRequests),

View File

@@ -57,11 +57,9 @@ class TrafficInitiator : public sc_core::sc_module
public:
tlm_utils::simple_initiator_socket<TrafficInitiator> iSocket;
TrafficInitiator(const sc_core::sc_module_name &name, const Configuration& config, TraceSetup& setup,
unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests,
unsigned int defaultDataLength, bool addLengthConverter);
unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests, unsigned int defaultDataLength);
SC_HAS_PROCESS(TrafficInitiator);
virtual void sendNextPayload() = 0;
const bool addLengthConverter = false;
protected:
static sc_core::sc_time evaluateGeneratorClk(const DRAMSysConfiguration::TrafficInitiator &conf);

View File

@@ -51,7 +51,6 @@
#include "simulation/DRAMSys.h"
#include "TraceSetup.h"
#include "TrafficInitiator.h"
#include "LengthConverter.h"
#ifdef RECORDING
#include "simulation/DRAMSysRecordable.h"
@@ -99,7 +98,6 @@ int sc_main(int argc, char **argv)
}
std::vector<std::unique_ptr<TrafficInitiator>> players;
std::vector<std::unique_ptr<LengthConverter>> lengthConverters;
DRAMSysConfiguration::Configuration configLib = DRAMSysConfiguration::from_path(simulationJson, resources);
@@ -121,21 +119,7 @@ int sc_main(int argc, char **argv)
// Bind STL Players with DRAMSys:
for (auto& player : players)
{
if (player->addLengthConverter)
{
std::string converterName("Converter_");
lengthConverters.emplace_back(std::make_unique<LengthConverter>(converterName.append(player->name()).c_str(),
dramSys->getConfig().memSpec->maxBytesPerBurst,
dramSys->getConfig().storeMode != Configuration::StoreMode::NoStorage));
player->iSocket.bind(lengthConverters.back()->tSocket);
lengthConverters.back()->iSocket.bind(dramSys->tSocket);
}
else
{
player->iSocket.bind(dramSys->tSocket);
}
}
// Store the starting of the simulation in wallclock time:
auto start = std::chrono::high_resolution_clock::now();

View File

@@ -6,6 +6,7 @@ example_DDR3:
- export GCOV_PREFIX_STRIP=$(pwd | awk -F"/" '{print NF-1}')
- cd build/simulator
- ./DRAMSys ../../DRAMSys/tests/DDR3/simulations/ddr3-example.json ../../DRAMSys/tests/DDR3/
- mv DRAMSys_ddr3-dual-rank_ddr3_ch0.tdb ddr3-dual-rank_ddr3_ch0.tdb
- ls -lah
- ls -lah ../../DRAMSys/tests/DDR3/expected/
- sqldiff ../../DRAMSys/tests/DDR3/expected/ddr3-dual-rank_ddr3_ch0.tdb ddr3-dual-rank_ddr3_ch0.tdb

View File

@@ -6,6 +6,7 @@ example_DDR4:
- export GCOV_PREFIX_STRIP=$(pwd | awk -F"/" '{print NF-1}')
- cd build/simulator
- ./DRAMSys ../../DRAMSys/tests/DDR4/simulations/ddr4-example.json ../../DRAMSys/tests/DDR4/
- mv DRAMSys_ddr4-bankgrp_ddr4_ch0.tdb ddr4-bankgrp_ddr4_ch0.tdb
- ls -lah
- ls -lah ../../DRAMSys/tests/DDR4/expected/
- sqldiff ../../DRAMSys/tests/DDR4/expected/ddr4-bankgrp_ddr4_ch0.tdb ddr4-bankgrp_ddr4_ch0.tdb

View File

@@ -5,6 +5,8 @@ example_HBM2:
- export GCOV_PREFIX_STRIP=$(pwd | awk -F"/" '{print NF-1}')
- cd build/simulator
- ./DRAMSys ../../DRAMSys/tests/HBM2/simulations/hbm2-example.json ../../DRAMSys/tests/HBM2/
- mv DRAMSys_hbm2-example_hbm2_ch0.tdb hbm2-example_hbm2_ch0.tdb
- mv DRAMSys_hbm2-example_hbm2_ch1.tdb hbm2-example_hbm2_ch1.tdb
- ls -lah
- ls -lah ../../DRAMSys/tests/HBM2/expected/
- sqldiff ../../DRAMSys/tests/HBM2/expected/hbm2-example_hbm2_ch0.tdb hbm2-example_hbm2_ch0.tdb

View File

@@ -6,6 +6,7 @@ example_LPDDR4:
- export GCOV_PREFIX_STRIP=$(pwd | awk -F"/" '{print NF-1}')
- cd build/simulator
- ./DRAMSys ../../DRAMSys/tests/LPDDR4/simulations/lpddr4-example.json ../../DRAMSys/tests/LPDDR4/
- mv DRAMSys_lpddr4-example_lpddr4_ch0.tdb lpddr4-example_lpddr4_ch0.tdb
- ls -lah
- ls -lah ../../DRAMSys/tests/LPDDR4/expected/
- sqldiff ../../DRAMSys/tests/LPDDR4/expected/lpddr4-example_lpddr4_ch0.tdb lpddr4-example_lpddr4_ch0.tdb

View File

@@ -41,16 +41,11 @@ DDR3Configuration::DDR3Configuration(const TraceDB& tdb) {
}
QString DDR3Configuration::getQueryStr(const std::vector<QString>& commands) const {
// TODO update query text when feature is ready
// QString queryStr = "SELECT Phases.ID, Phases.PhaseName, Phases.PhaseBegin, Phases.PhaseEnd, Phases.Transact, Phases.Bank, Phases.Rank "
// " FROM Phases "
// " WHERE PhaseName IN (";
QString queryStr = "SELECT Phases.*, Transactions.TBank, Transactions.TRank "
" FROM Phases "
" INNER JOIN Transactions "
" ON Phases.Transact=Transactions.ID "
" WHERE PhaseName IN (";
QString DDR3Configuration::getQueryStr(const std::vector<QString>& commands) const
{
QString queryStr = "SELECT Phases.ID, Phases.PhaseName, Phases.PhaseBegin, Phases.PhaseEnd, Phases.Transact, Phases.Bank, Phases.Rank "
" FROM Phases "
" WHERE PhaseName IN (";
for (const auto& cmd : commands) {
queryStr = queryStr + '\"' + cmd + "\",";

View File

@@ -35,21 +35,16 @@
#include "DDR4Configuration.h"
DDR4Configuration::DDR4Configuration(const TraceDB& tdb) {
DDR4Configuration::DDR4Configuration(const TraceDB& tdb)
{
mDeviceDeps = std::make_shared<TimeDependenciesInfoDDR4>(std::forward<const QJsonObject>(mGetMemspec(tdb)), mGetClk(tdb));
}
QString DDR4Configuration::getQueryStr(const std::vector<QString>& commands) const {
// TODO update query text when feature is ready
// QString queryStr = "SELECT Phases.ID, Phases.PhaseName, Phases.PhaseBegin, Phases.PhaseEnd, Phases.Transact, Phases.Bank, Phases.Bankgroup, Phases.Rank "
// " FROM Phases "
// " WHERE PhaseName IN (";
QString queryStr = "SELECT Phases.*, Transactions.TBank, Transactions.TBankgroup, Transactions.TRank "
" FROM Phases "
" INNER JOIN Transactions "
" ON Phases.Transact=Transactions.ID "
" WHERE PhaseName IN (";
QString DDR4Configuration::getQueryStr(const std::vector<QString>& commands) const
{
QString queryStr = "SELECT Phases.ID, Phases.PhaseName, Phases.PhaseBegin, Phases.PhaseEnd, Phases.Transact, Phases.Bank, Phases.Bankgroup, Phases.Rank "
" FROM Phases "
" WHERE PhaseName IN (";
for (const auto& cmd : commands) {
queryStr = queryStr + '\"' + cmd + "\",";

View File

@@ -41,16 +41,11 @@ DDR5Configuration::DDR5Configuration(const TraceDB& tdb) {
}
QString DDR5Configuration::getQueryStr(const std::vector<QString>& commands) const {
// TODO update query text when feature is ready
// QString queryStr = "SELECT Phases.ID, Phases.PhaseName, Phases.PhaseBegin, Phases.PhaseEnd, Phases.Transact, Phases.Bank, Phases.Bankgroup, Phases.Rank, Phases.BurstLength "
// " FROM Phases "
// " WHERE PhaseName IN (";
QString queryStr = "SELECT Phases.*, Transactions.TBank, Transactions.TBankgroup, Transactions.TRank, Transactions.BurstLength "
" FROM Phases "
" INNER JOIN Transactions "
" ON Phases.Transact=Transactions.ID "
" WHERE PhaseName IN (";
QString DDR5Configuration::getQueryStr(const std::vector<QString>& commands) const
{
QString queryStr = "SELECT Phases.ID, Phases.PhaseName, Phases.PhaseBegin, Phases.PhaseEnd, Phases.Transact, Phases.Bank, Phases.Bankgroup, Phases.Rank, Phases.BurstLength "
" FROM Phases "
" WHERE PhaseName IN (";
for (const auto& cmd : commands) {
queryStr = queryStr + '\"' + cmd + "\",";

View File

@@ -40,16 +40,11 @@ HBM2Configuration::HBM2Configuration(const TraceDB& tdb) {
}
QString HBM2Configuration::getQueryStr(const std::vector<QString>& commands) const {
// TODO update query text when feature is ready
// QString queryStr = "SELECT Phases.ID, Phases.PhaseName, Phases.PhaseBegin, Phases.PhaseEnd, Phases.Transact, Phases.Bank, Phases.Bankgroup, Phases.Rank "
// " FROM Phases "
// " WHERE PhaseName IN (";
QString queryStr = "SELECT Phases.*, Transactions.TBank, Transactions.TBankgroup, Transactions.TRank "
" FROM Phases "
" INNER JOIN Transactions "
" ON Phases.Transact=Transactions.ID "
" WHERE PhaseName IN (";
QString HBM2Configuration::getQueryStr(const std::vector<QString>& commands) const
{
QString queryStr = "SELECT Phases.ID, Phases.PhaseName, Phases.PhaseBegin, Phases.PhaseEnd, Phases.Transact, Phases.Bank, Phases.Bankgroup, Phases.Rank "
" FROM Phases "
" WHERE PhaseName IN (";
for (const auto& cmd : commands) {
queryStr = queryStr + '\"' + cmd + "\",";

View File

@@ -41,16 +41,11 @@ LPDDR4Configuration::LPDDR4Configuration(const TraceDB& tdb) {
}
QString LPDDR4Configuration::getQueryStr(const std::vector<QString>& commands) const {
// TODO update query text when feature is ready
// QString queryStr = "SELECT Phases.ID, Phases.PhaseName, Phases.PhaseBegin, Phases.PhaseEnd, Phases.Transact, Phases.Bank, Phases.Rank "
// " FROM Phases "
// " WHERE PhaseName IN (";
QString queryStr = "SELECT Phases.*, Transactions.TBank, Transactions.TRank "
" FROM Phases "
" INNER JOIN Transactions "
" ON Phases.Transact=Transactions.ID "
" WHERE PhaseName IN (";
QString LPDDR4Configuration::getQueryStr(const std::vector<QString>& commands) const
{
QString queryStr = "SELECT Phases.ID, Phases.PhaseName, Phases.PhaseBegin, Phases.PhaseEnd, Phases.Transact, Phases.Bank, Phases.Rank "
" FROM Phases "
" WHERE PhaseName IN (";
for (const auto& cmd : commands) {
queryStr = queryStr + '\"' + cmd + "\",";

View File

@@ -41,16 +41,11 @@ LPDDR5Configuration::LPDDR5Configuration(const TraceDB& tdb) {
}
QString LPDDR5Configuration::getQueryStr(const std::vector<QString>& commands) const {
// TODO update query text when feature is ready
// QString queryStr = "SELECT Phases.ID, Phases.PhaseName, Phases.PhaseBegin, Phases.PhaseEnd, Phases.Transact, Phases.Bank, Phases.Bankgroup, Phases.Rank, Phases.BurstLength "
// " FROM Phases "
// " WHERE PhaseName IN (";
QString queryStr = "SELECT Phases.*, Transactions.TBank, Transactions.TBankgroup, Transactions.TRank, Transactions.BurstLength "
" FROM Phases "
" INNER JOIN Transactions "
" ON Phases.Transact=Transactions.ID "
" WHERE PhaseName IN (";
QString LPDDR5Configuration::getQueryStr(const std::vector<QString>& commands) const
{
QString queryStr = "SELECT Phases.ID, Phases.PhaseName, Phases.PhaseBegin, Phases.PhaseEnd, Phases.Transact, Phases.Bank, Phases.Bankgroup, Phases.Rank, Phases.BurstLength "
" FROM Phases "
" WHERE PhaseName IN (";
for (const auto& cmd : commands) {
queryStr = queryStr + '\"' + cmd + "\",";

View File

@@ -153,11 +153,10 @@ void PhaseDependenciesTracker::mInsertIntoTable(TraceDB& tdb, const std::vector<
}
const std::vector<std::shared_ptr<DBPhaseEntryBase>>
PhaseDependenciesTracker::mGetFilteredPhases(const std::shared_ptr<ConfigurationBase> deviceConfig, TraceDB& tdb, const std::vector<QString>& commands) {
PhaseDependenciesTracker::mGetFilteredPhases(const std::shared_ptr<ConfigurationBase> deviceConfig, TraceDB& tdb, const std::vector<QString>& commands)
{
std::vector<std::shared_ptr<DBPhaseEntryBase>> phases;
QString queryStr = deviceConfig->getQueryStr(commands);
auto query = mExecuteQuery(tdb, queryStr);
if (!query.next())

View File

@@ -41,12 +41,13 @@
#include "timespan.h"
#include <QString>
#include <climits>
struct GeneralInfo
{
uint64_t numberOfTransactions = 0;
uint64_t numberOfPhases = 0;
Timespan span = 0;
Timespan span = Timespan();
unsigned int numberOfRanks = 1;
unsigned int numberOfBankGroups = 1;
unsigned int numberOfBanks = 1;
@@ -59,7 +60,7 @@ struct GeneralInfo
uint64_t windowSize = 0;
unsigned int refreshMaxPostponed = 0;
unsigned int refreshMaxPulledin = 0;
uint64_t controllerThread = UINT64_MAX;
unsigned int controllerThread = UINT_MAX;
unsigned int maxBufferDepth = 8;
unsigned int per2BankOffset = 1;
bool rowColumnCommandBus = false;
@@ -69,7 +70,7 @@ struct GeneralInfo
GeneralInfo(uint64_t numberOfTransactions, uint64_t numberOfPhases, Timespan span, unsigned int numberOfRanks,
unsigned int numberOfBankgroups, unsigned int numberOfBanks, QString description, QString unitOfTime,
uint64_t clkPeriod, uint64_t windowSize, unsigned int refreshMaxPostponed,
unsigned int refreshMaxPulledin, uint64_t controllerThread, unsigned int maxBufferDepth,
unsigned int refreshMaxPulledin, unsigned int controllerThread, unsigned int maxBufferDepth,
unsigned int per2BankOffset, bool rowColumnCommandBus, bool pseudoChannelMode)
: numberOfTransactions(numberOfTransactions), numberOfPhases(numberOfPhases), span(span),
numberOfRanks(numberOfRanks), numberOfBankGroups(numberOfBankgroups), numberOfBanks(numberOfBanks),

View File

@@ -81,7 +81,7 @@ void Phase::draw(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &
}
}
for (Timespan span : spansOnCommandBus)
for (Timespan spanOnCommandBus : spansOnCommandBus)
{
for (const auto &line : drawingProperties.getTracePlotLines())
{
@@ -98,36 +98,36 @@ void Phase::draw(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &
else if (line->data.type != AbstractTracePlotLineModel::CommandBusLine)
continue;
drawPhaseSymbol(span.Begin(), span.End(), line->data.yVal, false, PhaseSymbol::Hexagon, painter, xMap, yMap,
drawPhaseSymbol(spanOnCommandBus.Begin(), spanOnCommandBus.End(), line->data.yVal, false, PhaseSymbol::Hexagon, painter, xMap, yMap,
drawingProperties.textColor);
}
}
if (spanOnDataBus)
if (spanOnDataStrobe.End() != 0)
{
for (const auto &line : drawingProperties.getTracePlotLines())
{
if (line->data.type == AbstractTracePlotLineModel::PseudoChannel0Line)
{
if (transaction.lock()->rank != 0)
if (rank != 0)
continue;
}
else if (line->data.type == AbstractTracePlotLineModel::PseudoChannel1Line)
{
if (transaction.lock()->rank != 1)
if (rank != 1)
continue;
}
else if (line->data.type != AbstractTracePlotLineModel::DataBusLine)
continue;
drawPhaseSymbol(spanOnDataBus->Begin(), spanOnDataBus->End(), line->data.yVal, false, PhaseSymbol::Hexagon,
painter, xMap, yMap, drawingProperties.textColor);
drawPhaseSymbol(spanOnDataStrobe.Begin(), spanOnDataStrobe.End(), line->data.yVal, false,
PhaseSymbol::Hexagon, painter, xMap, yMap, drawingProperties.textColor);
}
}
}
void Phase::drawPhaseSymbol(traceTime begin, traceTime end, double y, bool drawtext, PhaseSymbol symbol,
QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, QColor textColor) const
QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QColor& textColor) const
{
double yVal = yMap.transform(y);
double symbolHeight = yMap.transform(0) - yMap.transform(hexagonHeight);
@@ -174,7 +174,7 @@ void Phase::drawPhaseDependencies(traceTime begin, traceTime end, double y,
QPoint depLineTo(static_cast<int>(xMap.transform(begin /* + (end + offset - begin)/4*/)), static_cast<int>(yVal));
for (auto dep : mDependencies)
for (const auto& dep : mDependencies)
{
bool visible = false;
if (dep->isVisible())
@@ -204,9 +204,6 @@ std::vector<int> Phase::getYVals(const TraceDrawingProperties &drawingProperties
{
std::vector<int> yVals;
unsigned int transactionRank = transaction.lock()->rank;
unsigned int transactionBank = transaction.lock()->bank;
for (const auto &line : drawingProperties.getTracePlotLines())
{
if (line->data.type != AbstractTracePlotLineModel::BankLine)
@@ -214,26 +211,26 @@ std::vector<int> Phase::getYVals(const TraceDrawingProperties &drawingProperties
unsigned int yVal = line->data.yVal;
unsigned int rank = line->data.rank;
unsigned int bank = line->data.bank;
unsigned int drawnRank = line->data.rank;
unsigned int drawnBank = line->data.bank;
bool shouldBeDrawn = false;
switch (getGranularity())
{
case Granularity::Rankwise:
shouldBeDrawn = (transactionRank == rank);
shouldBeDrawn = (rank == drawnRank);
break;
case Granularity::Groupwise:
shouldBeDrawn = (transactionRank == rank) && (transactionBank % drawingProperties.banksPerGroup ==
bank % drawingProperties.banksPerGroup);
shouldBeDrawn = (rank == drawnRank) && (bank % drawingProperties.banksPerGroup ==
drawnBank % drawingProperties.banksPerGroup);
break;
case Granularity::Bankwise:
shouldBeDrawn = (transactionBank == bank);
shouldBeDrawn = (bank == drawnBank);
break;
case Granularity::TwoBankwise:
shouldBeDrawn = (transactionBank == bank) || ((transactionBank + drawingProperties.per2BankOffset) == bank);
shouldBeDrawn = (bank == drawnBank) || ((bank + drawingProperties.per2BankOffset) == drawnBank);
break;
}
@@ -307,9 +304,9 @@ bool Phase::isSelected(Timespan timespan, double yVal, const TraceDrawingPropert
return true;
}
for (Timespan span : spansOnCommandBus)
for (Timespan _span : spansOnCommandBus)
{
if (span.overlaps(timespan))
if (_span.overlaps(timespan))
{
for (const auto &line : drawingProperties.getTracePlotLines())
{
@@ -332,18 +329,18 @@ bool Phase::isSelected(Timespan timespan, double yVal, const TraceDrawingPropert
}
}
if (spanOnDataBus && spanOnDataBus->overlaps(timespan))
if (spanOnDataStrobe.End() != 0 && spanOnDataStrobe.overlaps(timespan))
{
for (const auto &line : drawingProperties.getTracePlotLines())
{
if (line->data.type == AbstractTracePlotLineModel::PseudoChannel0Line)
{
if (transaction.lock()->rank != 0)
if (rank != 0)
continue;
}
else if (line->data.type == AbstractTracePlotLineModel::PseudoChannel1Line)
{
if (transaction.lock()->rank != 1)
if (rank != 1)
continue;
}
else if (line->data.type != AbstractTracePlotLineModel::DataBusLine)
@@ -371,7 +368,7 @@ Phase::PhaseSymbol Phase::getPhaseSymbol() const
return PhaseSymbol::Hexagon;
}
void Phase::addDependency(std::shared_ptr<PhaseDependency> dependency)
void Phase::addDependency(const std::shared_ptr<PhaseDependency>& dependency)
{
mDependencies.push_back(dependency);
}

View File

@@ -47,20 +47,44 @@
#include <QString>
#include <memory>
#include <qwt_scale_map.h>
#include <utility>
#include <vector>
typedef unsigned int ID;
//enum TextPositioning;
class Transaction;
enum class RelevantAttributes
{
Rank = 0x01,
BankGroup = 0x02,
Bank = 0x04,
Row = 0x08,
Column = 0x10,
BurstLength = 0x20
};
inline RelevantAttributes operator|(RelevantAttributes a, RelevantAttributes b)
{
return static_cast<RelevantAttributes>(static_cast<int>(a) | static_cast<int>(b));
}
inline RelevantAttributes operator&(RelevantAttributes a, RelevantAttributes b)
{
return static_cast<RelevantAttributes>(static_cast<int>(a) & static_cast<int>(b));
}
class Phase
{
public:
Phase(ID id, Timespan span, traceTime clk, const std::shared_ptr<Transaction> &transaction,
std::vector<Timespan> spansOnCommandBus,
std::shared_ptr<Timespan> spanOnDataBus):
id(id), span(span), clk(clk), transaction(transaction),
spansOnCommandBus(spansOnCommandBus), spanOnDataBus(spanOnDataBus),
Phase(ID id, Timespan span, Timespan spanOnDataStrobe, unsigned int rank, unsigned int bankGroup,
unsigned int bank, unsigned int row, unsigned int column, unsigned int burstLength,
traceTime clk, const std::shared_ptr<Transaction> &transaction, std::vector<Timespan> spansOnCommandBus,
unsigned int groupsPerRank, unsigned int banksPerGroup) :
id(id), span(span), spanOnDataStrobe(spanOnDataStrobe),
rank(rank), bankGroup(bankGroup), bank(bank), row(row), column(column), burstLength(burstLength),
clk(clk), transaction(transaction), spansOnCommandBus(std::move(spansOnCommandBus)),
groupsPerRank(groupsPerRank), banksPerGroup(banksPerGroup),
hexagonHeight(0.6), captionPosition(TextPositioning::bottomRight) {}
void draw(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap,
@@ -68,25 +92,62 @@ public:
const TraceDrawingProperties &drawingProperties) const;
bool isSelected(Timespan timespan, double yVal, const TraceDrawingProperties &drawingproperties) const;
bool isColumnCommand() const;
const Timespan &Span() const
{
return span;
}
ID Id() const
{
return id;
}
unsigned int getRank() const
{
return rank;
}
unsigned int getBankGroup() const
{
return bankGroup % groupsPerRank;
}
unsigned int getBank() const
{
return bank % banksPerGroup;
}
unsigned int getRow() const
{
return row;
}
unsigned int getColumn() const
{
return column;
}
unsigned int getBurstLength() const
{
return burstLength;
}
virtual RelevantAttributes getRelevantAttributes() const = 0;
virtual QString Name() const = 0;
void addDependency(std::shared_ptr<PhaseDependency> dependency);
void addDependency(const std::shared_ptr<PhaseDependency>& dependency);
protected:
ID id;
Timespan span;
Timespan spanOnDataStrobe;
unsigned int rank, bankGroup, bank, row, column, burstLength;
unsigned int groupsPerRank, banksPerGroup;
traceTime clk;
std::weak_ptr<Transaction> transaction;
std::vector<Timespan> spansOnCommandBus;
std::shared_ptr<Timespan> spanOnDataBus;
std::vector<std::shared_ptr<PhaseDependency>> mDependencies;
double hexagonHeight;
@@ -101,7 +162,7 @@ protected:
virtual std::vector<int> getYVals(const TraceDrawingProperties &drawingProperties) const;
virtual void drawPhaseSymbol(traceTime begin, traceTime end, double y,
bool drawtext, PhaseSymbol symbol, QPainter *painter, const QwtScaleMap &xMap,
const QwtScaleMap &yMap, QColor textColor) const;
const QwtScaleMap &yMap, const QColor& textColor) const;
virtual void drawPhaseDependencies(traceTime begin, traceTime end, double y,
const TraceDrawingProperties &drawingProperties, QPainter *painter,
const QwtScaleMap &xMap, const QwtScaleMap &yMap) const;
@@ -120,6 +181,7 @@ class REQ final : public Phase
{
public:
using Phase::Phase;
protected:
QColor getPhaseColor() const override
{
@@ -130,6 +192,11 @@ protected:
return "REQ";
}
RelevantAttributes getRelevantAttributes() const override
{
return static_cast<RelevantAttributes>(0);
}
std::vector<int> getYVals(const TraceDrawingProperties &drawingProperties) const override;
};
@@ -137,6 +204,7 @@ class RESP final : public Phase
{
public:
using Phase::Phase;
protected:
QColor getPhaseColor() const override
{
@@ -147,6 +215,11 @@ protected:
return "RESP";
}
RelevantAttributes getRelevantAttributes() const override
{
return static_cast<RelevantAttributes>(0);
}
std::vector<int> getYVals(const TraceDrawingProperties &drawingProperties) const override;
};
/*
@@ -169,6 +242,7 @@ class PREPB final : public Phase
{
public:
using Phase::Phase;
protected:
QColor getPhaseColor() const override
{
@@ -178,12 +252,18 @@ protected:
{
return "PREPB";
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank;
}
};
class PRESB final : public Phase
{
public:
using Phase::Phase;
protected:
QString Name() const override
{
@@ -193,10 +273,10 @@ protected:
{
return {span.Begin()};
}
QColor getColor(const TraceDrawingProperties &drawingProperties) const
override
QColor getColor(const TraceDrawingProperties &drawingProperties) const override
{
Q_UNUSED(drawingProperties) return getPhaseColor();
Q_UNUSED(drawingProperties)
return getPhaseColor();
}
QColor getPhaseColor() const override
{
@@ -206,12 +286,18 @@ protected:
{
return Granularity::Groupwise;
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::Bank;
}
};
class PREAB final : public Phase
{
public:
using Phase::Phase;
protected:
QString Name() const override
{
@@ -221,10 +307,10 @@ protected:
{
return {span.Begin()};
}
QColor getColor(const TraceDrawingProperties &drawingProperties) const
override
QColor getColor(const TraceDrawingProperties &drawingProperties) const override
{
Q_UNUSED(drawingProperties) return getPhaseColor();
Q_UNUSED(drawingProperties)
return getPhaseColor();
}
QColor getPhaseColor() const override
{
@@ -234,6 +320,11 @@ protected:
{
return Granularity::Rankwise;
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank;
}
};
/*
class ACTB final : public Phase
@@ -255,6 +346,7 @@ class ACT final : public Phase
{
public:
using Phase::Phase;
protected:
QColor getPhaseColor() const override
{
@@ -264,12 +356,19 @@ protected:
{
return "ACT";
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank |
RelevantAttributes::Row;
}
};
class RD final : public Phase
{
public:
using Phase::Phase;
protected:
QColor getPhaseColor() const override
{
@@ -279,12 +378,19 @@ protected:
{
return "RD";
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank |
RelevantAttributes::Column | RelevantAttributes::BurstLength;
}
};
class RDA final : public Phase
{
public:
using Phase::Phase;
protected:
QColor getPhaseColor() const override
{
@@ -294,12 +400,19 @@ protected:
{
return "RDA";
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank |
RelevantAttributes::Column | RelevantAttributes::BurstLength;
}
};
class WR final : public Phase
{
public:
using Phase::Phase;
protected:
QColor getPhaseColor() const override
{
@@ -309,12 +422,19 @@ protected:
{
return "WR";
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank |
RelevantAttributes::Column | RelevantAttributes::BurstLength;
}
};
class WRA final : public Phase
{
public:
using Phase::Phase;
protected:
QColor getPhaseColor() const override
{
@@ -324,12 +444,19 @@ protected:
{
return "WRA";
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank |
RelevantAttributes::Column | RelevantAttributes::BurstLength;
}
};
class AUTO_REFRESH : public Phase
{
public:
using Phase::Phase;
protected:
QString Name() const override
{
@@ -339,14 +466,14 @@ protected:
{
return {span.Begin()};
}
QColor getColor(const TraceDrawingProperties &drawingProperties) const
override
QColor getColor(const TraceDrawingProperties &drawingProperties) const override
{
Q_UNUSED(drawingProperties) return getPhaseColor();
Q_UNUSED(drawingProperties)
return getPhaseColor();
}
QColor getPhaseColor() const override
{
QColor phaseColor = QColor(Qt::darkCyan);
auto phaseColor = QColor(Qt::darkCyan);
phaseColor.setAlpha(130);
return phaseColor;
}
@@ -356,6 +483,7 @@ class REFAB final : public AUTO_REFRESH
{
public:
using AUTO_REFRESH::AUTO_REFRESH;
protected:
QString Name() const override
{
@@ -365,12 +493,18 @@ protected:
{
return Granularity::Rankwise;
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank;
}
};
class RFMAB final : public AUTO_REFRESH
{
public:
using AUTO_REFRESH::AUTO_REFRESH;
protected:
QString Name() const override
{
@@ -382,27 +516,62 @@ protected:
}
QColor getPhaseColor() const override
{
QColor phaseColor = QColor(Qt::darkRed);
auto phaseColor = QColor(Qt::darkRed);
phaseColor.setAlpha(130);
return phaseColor;
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank;
}
};
class REFPB final : public AUTO_REFRESH
{
public:
using AUTO_REFRESH::AUTO_REFRESH;
protected:
QString Name() const override
{
return "REFPB";
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank;
}
};
class RFMPB final : public AUTO_REFRESH
{
public:
using AUTO_REFRESH::AUTO_REFRESH;
protected:
QString Name() const override
{
return "RFMPB";
}
QColor getPhaseColor() const override
{
auto phaseColor = QColor(Qt::darkRed);
phaseColor.setAlpha(130);
return phaseColor;
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank;
}
};
class REFP2B final : public AUTO_REFRESH
{
public:
using AUTO_REFRESH::AUTO_REFRESH;
protected:
QString Name() const override
{
@@ -412,12 +581,18 @@ protected:
{
return Granularity::TwoBankwise;
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank;
}
};
class RFMP2B final : public AUTO_REFRESH
{
public:
using AUTO_REFRESH::AUTO_REFRESH;
protected:
QString Name() const override
{
@@ -429,16 +604,22 @@ protected:
}
QColor getPhaseColor() const override
{
QColor phaseColor = QColor(Qt::darkRed);
auto phaseColor = QColor(Qt::darkRed);
phaseColor.setAlpha(130);
return phaseColor;
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank;
}
};
class REFSB final : public AUTO_REFRESH
{
public:
using AUTO_REFRESH::AUTO_REFRESH;
protected:
QString Name() const override
{
@@ -448,12 +629,18 @@ protected:
{
return Granularity::Groupwise;
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::Bank;
}
};
class RFMSB final : public AUTO_REFRESH
{
public:
using AUTO_REFRESH::AUTO_REFRESH;
protected:
QString Name() const override
{
@@ -465,10 +652,15 @@ protected:
}
QColor getPhaseColor() const override
{
QColor phaseColor = QColor(Qt::darkRed);
auto phaseColor = QColor(Qt::darkRed);
phaseColor.setAlpha(130);
return phaseColor;
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::Bank;
}
};
class PDNAB : public Phase
@@ -486,10 +678,10 @@ protected:
{
return Qt::Dense6Pattern;
}
QColor getColor(const TraceDrawingProperties &drawingProperties) const
override
QColor getColor(const TraceDrawingProperties &drawingProperties) const override
{
Q_UNUSED(drawingProperties) return getPhaseColor();
Q_UNUSED(drawingProperties)
return getPhaseColor();
}
QColor getPhaseColor() const override
{
@@ -499,12 +691,18 @@ protected:
{
return PhaseSymbol::Rect;
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank;
}
};
class PDNA final : public PDNAB
{
public:
using PDNAB::PDNAB;
protected:
QString Name() const override
{
@@ -514,6 +712,11 @@ protected:
{
return Granularity::Rankwise;
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank;
}
};
class PDNPB : public Phase
@@ -531,10 +734,10 @@ protected:
{
return Qt::Dense4Pattern;
}
QColor getColor(const TraceDrawingProperties &drawingProperties) const
override
QColor getColor(const TraceDrawingProperties &drawingProperties) const override
{
Q_UNUSED(drawingProperties) return getPhaseColor();
Q_UNUSED(drawingProperties)
return getPhaseColor();
}
QColor getPhaseColor() const override
{
@@ -544,12 +747,18 @@ protected:
{
return PhaseSymbol::Rect;
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank;
}
};
class PDNP final : public PDNPB
{
public:
using PDNPB::PDNPB;
protected:
QString Name() const override
{
@@ -559,6 +768,10 @@ protected:
{
return Granularity::Rankwise;
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank;
}
};
class SREFB : public Phase
@@ -576,10 +789,10 @@ protected:
{
return Qt::Dense1Pattern;
}
QColor getColor(const TraceDrawingProperties &drawingProperties) const
override
QColor getColor(const TraceDrawingProperties &drawingProperties) const override
{
Q_UNUSED(drawingProperties) return getPhaseColor();
Q_UNUSED(drawingProperties)
return getPhaseColor();
}
QColor getPhaseColor() const override
{
@@ -589,12 +802,18 @@ protected:
{
return PhaseSymbol::Rect;
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank | RelevantAttributes::BankGroup | RelevantAttributes::Bank;
}
};
class SREF : public SREFB
{
public:
using SREFB::SREFB;
protected:
QString Name() const override
{
@@ -604,7 +823,10 @@ protected:
{
return Granularity::Rankwise;
}
RelevantAttributes getRelevantAttributes() const override
{
return RelevantAttributes::Rank;
}
};
#endif // BANKPHASE_H

View File

@@ -42,89 +42,82 @@
#include "data/tracedb.h"
#include "businessObjects/timespan.h"
std::shared_ptr<Phase> PhaseFactory::CreatePhase(ID id, const QString &dbPhaseName,
const Timespan &span, const std::shared_ptr<Transaction> &trans,
TraceDB &database)
std::shared_ptr<Phase> PhaseFactory::createPhase(ID id, const QString &dbPhaseName,
Timespan span, Timespan spanOnDataStrobe,
unsigned int rank, unsigned int bankGroup, unsigned int bank, unsigned int row, unsigned int column,
unsigned int burstLength, const std::shared_ptr<Transaction> &trans, TraceDB &database)
{
traceTime clk = database.getGeneralInfo().clkPeriod;
auto clk = static_cast<traceTime>(database.getGeneralInfo().clkPeriod);
unsigned int groupsPerRank = database.getGeneralInfo().groupsPerRank;
unsigned int banksPerGroup = database.getGeneralInfo().banksPerGroup;
const CommandLengths &cl = database.getCommandLengths();
if (dbPhaseName == "REQ")
return std::shared_ptr<Phase>(new REQ(id, span, clk, trans, {}, std::shared_ptr<Timespan>()));
return std::shared_ptr<Phase>(new REQ(id, span, spanOnDataStrobe, rank, bankGroup, bank, row, column,
burstLength, clk, trans, {}, groupsPerRank, banksPerGroup));
else if (dbPhaseName == "RESP")
return std::shared_ptr<Phase>(new RESP(id, span, clk, trans, {}, std::shared_ptr<Timespan>()));
/*else if (dbPhaseName == "PREB")
return shared_ptr<Phase>(new PREB(id, span, clk, trans,
{Timespan(span.Begin(), span.Begin() + clk)}, std::shared_ptr<Timespan>()));*/
else if (dbPhaseName == "PREPB" || dbPhaseName == "PRE") // for backwards compatibility
return std::shared_ptr<Phase>(new PREPB(id, span, clk, trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.PREPB)}, std::shared_ptr<Timespan>()));
/*else if (dbPhaseName == "ACTB")
return std::shared_ptr<Phase>(new ACTB(id, span, clk, trans,
{Timespan(span.Begin(), span.Begin() + clk)}, std::shared_ptr<Timespan>()));*/
return std::shared_ptr<Phase>(new RESP(id, span, spanOnDataStrobe, rank, bankGroup, bank, row, column,
burstLength, clk, trans, {}, groupsPerRank, banksPerGroup));
else if (dbPhaseName == "PREPB")
return std::shared_ptr<Phase>(new PREPB(id, span, spanOnDataStrobe, rank, bankGroup, bank, row, column,
burstLength, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.PREPB)}, groupsPerRank, banksPerGroup));
else if (dbPhaseName == "ACT")
return std::shared_ptr<Phase>(new ACT(id, span, clk, trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.ACT)}, std::shared_ptr<Timespan>()));
else if (dbPhaseName == "PREAB" || dbPhaseName == "PREA") // for backwards compatibility
return std::shared_ptr<Phase>(new PREAB(id, span, clk, trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.PREAB)}, std::shared_ptr<Timespan>()));
else if (dbPhaseName == "REFAB" || dbPhaseName == "REFA") // for backwards compatibility
return std::shared_ptr<Phase>(new REFAB(id, span, clk, trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.REFAB)}, std::shared_ptr<Timespan>()));
return std::shared_ptr<Phase>(new ACT(id, span, spanOnDataStrobe, rank, bankGroup, bank, row, column,
burstLength, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.ACT)}, groupsPerRank, banksPerGroup));
else if (dbPhaseName == "PREAB")
return std::shared_ptr<Phase>(new PREAB(id, span, spanOnDataStrobe, rank, bankGroup, bank, row, column,
burstLength, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.PREAB)}, groupsPerRank, banksPerGroup));
else if (dbPhaseName == "REFAB")
return std::shared_ptr<Phase>(new REFAB(id, span, spanOnDataStrobe, rank, bankGroup, bank, row, column,
burstLength, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.REFAB)}, groupsPerRank, banksPerGroup));
else if (dbPhaseName == "RFMAB")
return std::shared_ptr<Phase>(new RFMAB(id, span, clk, trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.RFMAB)}, std::shared_ptr<Timespan>()));
else if (dbPhaseName == "REFPB" || dbPhaseName == "REFB") // for backwards compatibility
return std::shared_ptr<Phase>(new REFPB(id, span, clk, trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.REFPB)}, std::shared_ptr<Timespan>()));
return std::shared_ptr<Phase>(new RFMAB(id, span, spanOnDataStrobe, rank, bankGroup, bank, row, column,
burstLength, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.RFMAB)}, groupsPerRank, banksPerGroup));
else if (dbPhaseName == "REFPB")
return std::shared_ptr<Phase>(new REFPB(id, span, spanOnDataStrobe, rank, bankGroup, bank, row, column,
burstLength, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.REFPB)}, groupsPerRank, banksPerGroup));
else if (dbPhaseName == "RFMPB")
return std::shared_ptr<Phase>(new REFPB(id, span, clk, trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.RFMPB)}, std::shared_ptr<Timespan>()));
return std::shared_ptr<Phase>(new RFMPB(id, span, spanOnDataStrobe, rank, bankGroup, bank, row, column,
burstLength, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.RFMPB)}, groupsPerRank, banksPerGroup));
else if (dbPhaseName == "REFP2B")
return std::shared_ptr<Phase>(new REFP2B(id, span, clk, trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.REFP2B)}, std::shared_ptr<Timespan>()));
return std::shared_ptr<Phase>(new REFP2B(id, span, spanOnDataStrobe, rank, bankGroup, bank, row, column,
burstLength, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.REFP2B)}, groupsPerRank, banksPerGroup));
else if (dbPhaseName == "RFMP2B")
return std::shared_ptr<Phase>(new REFP2B(id, span, clk, trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.RFMP2B)}, std::shared_ptr<Timespan>()));
return std::shared_ptr<Phase>(new RFMP2B(id, span, spanOnDataStrobe, rank, bankGroup, bank, row, column,
burstLength, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.RFMP2B)}, groupsPerRank, banksPerGroup));
else if (dbPhaseName == "PRESB")
return std::shared_ptr<Phase>(new PRESB(id, span, clk, trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.PRESB)}, std::shared_ptr<Timespan>()));
return std::shared_ptr<Phase>(new PRESB(id, span, spanOnDataStrobe, rank, bankGroup, bank, row, column,
burstLength, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.PRESB)}, groupsPerRank, banksPerGroup));
else if (dbPhaseName == "REFSB")
return std::shared_ptr<Phase>(new REFSB(id, span, clk, trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.REFSB)}, std::shared_ptr<Timespan>()));
return std::shared_ptr<Phase>(new REFSB(id, span, spanOnDataStrobe, rank, bankGroup, bank, row, column,
burstLength, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.REFSB)}, groupsPerRank, banksPerGroup));
else if (dbPhaseName == "RFMSB")
return std::shared_ptr<Phase>(new RFMSB(id, span, clk, trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.RFMSB)}, std::shared_ptr<Timespan>()));
return std::shared_ptr<Phase>(new RFMSB(id, span, spanOnDataStrobe, rank, bankGroup, bank, row, column,
burstLength, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.RFMSB)}, groupsPerRank, banksPerGroup));
else if (dbPhaseName == "RD")
return std::shared_ptr<Phase>(new RD(id, span, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.RD)},
std::shared_ptr<Timespan>(new Timespan(trans->spanOnDataStrobe))));
return std::shared_ptr<Phase>(new RD(id, span, spanOnDataStrobe, rank, bankGroup, bank, row, column,
burstLength, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.RD)}, groupsPerRank, banksPerGroup));
else if (dbPhaseName == "RDA")
return std::shared_ptr<Phase>(new RDA(id, span, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.RDA)},
std::shared_ptr<Timespan>(new Timespan(trans->spanOnDataStrobe))));
return std::shared_ptr<Phase>(new RDA(id, span, spanOnDataStrobe, rank, bankGroup, bank, row, column,
burstLength, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.RDA)}, groupsPerRank, banksPerGroup));
else if (dbPhaseName == "WR")
return std::shared_ptr<Phase>(new WR(id, span, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.WR)},
std::shared_ptr<Timespan>(new Timespan(trans->spanOnDataStrobe))));
return std::shared_ptr<Phase>(new WR(id, span, spanOnDataStrobe, rank, bankGroup, bank, row, column,
burstLength, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.WR)}, groupsPerRank, banksPerGroup));
else if (dbPhaseName == "WRA")
return std::shared_ptr<Phase>(new WRA(id, span, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.WRA)},
std::shared_ptr<Timespan>(new Timespan(trans->spanOnDataStrobe))));
return std::shared_ptr<Phase>(new WRA(id, span, spanOnDataStrobe, rank, bankGroup, bank, row, column,
burstLength, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.WRA)}, groupsPerRank, banksPerGroup));
else if (dbPhaseName == "PDNA")
return std::shared_ptr<Phase>(new PDNA(id, span, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.PDEA),
Timespan(span.End() - clk * cl.PDXA, span.End())}, std::shared_ptr<Timespan>()));
else if (dbPhaseName == "PDNAB")
return std::shared_ptr<Phase>(new PDNAB(id, span, clk, trans, {Timespan(span.Begin(), span.Begin() + clk),
Timespan(span.End() - clk, span.End())}, std::shared_ptr<Timespan>()));
return std::shared_ptr<Phase>(new PDNA(id, span, spanOnDataStrobe, rank, bankGroup, bank, row, column,
burstLength, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.PDEA),
Timespan(span.End() - clk * cl.PDXA, span.End())}, groupsPerRank, banksPerGroup));
else if (dbPhaseName == "PDNP")
return std::shared_ptr<Phase>(new PDNP(id, span, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.PDEP),
Timespan(span.End() - clk * cl.PDXP, span.End())}, std::shared_ptr<Timespan>()));
else if (dbPhaseName == "PDNPB")
return std::shared_ptr<Phase>(new PDNPB(id, span, clk, trans, {Timespan(span.Begin(), span.Begin() + clk),
Timespan(span.End() - clk, span.End())}, std::shared_ptr<Timespan>()));
return std::shared_ptr<Phase>(new PDNP(id, span, spanOnDataStrobe, rank, bankGroup, bank, row, column,
burstLength, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.PDEP),
Timespan(span.End() - clk * cl.PDXP, span.End())}, groupsPerRank, banksPerGroup));
else if (dbPhaseName == "SREF")
return std::shared_ptr<Phase>(new SREF(id, span, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.SREFEN),
Timespan(span.End() - clk * cl.SREFEX, span.End())}, std::shared_ptr<Timespan>()));
else if (dbPhaseName == "SREFB")
return std::shared_ptr<Phase>(new SREFB(id, span, clk, trans, {Timespan(span.Begin(), span.Begin() + clk),
Timespan(span.End() - clk, span.End())}, std::shared_ptr<Timespan>()));
return std::shared_ptr<Phase>(new SREF(id, span, spanOnDataStrobe, rank, bankGroup, bank, row, column,
burstLength, clk, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.SREFEN),
Timespan(span.End() - clk * cl.SREFEX, span.End())}, groupsPerRank, banksPerGroup));
else
throw std::runtime_error("DB phasename " + dbPhaseName.toStdString() + " unkown to phasefactory");
}

View File

@@ -49,9 +49,10 @@ class PhaseFactory
{
public:
PhaseFactory() = delete;
static std::shared_ptr<Phase> CreatePhase(ID id, const QString &dbPhaseName,
const Timespan &span, const std::shared_ptr<Transaction> &trans,
TraceDB &database);
static std::shared_ptr<Phase> createPhase(ID id, const QString &dbPhaseName,
Timespan span, Timespan spanOnDataStrobe,
unsigned int rank, unsigned int bankGroup, unsigned int bank, unsigned int row, unsigned int column,
unsigned int burstLength, const std::shared_ptr<Transaction> &trans, TraceDB &database);
};
#endif // PHASEFACTORY_H

View File

@@ -47,7 +47,7 @@ class Timespan
traceTime end;
public:
Timespan(traceTime begin = 0, traceTime end = 0) : begin(begin), end(end) {}
explicit Timespan(traceTime begin = 0, traceTime end = 0) : begin(begin), end(end) {}
traceTime timeCovered() const
{
return std::abs(End() - Begin());

View File

@@ -38,19 +38,18 @@
#include "transaction.h"
#include <utility>
using namespace std;
unsigned int Transaction::mSNumTransactions = 0;
Transaction::Transaction(ID id, unsigned int address, unsigned int burstlength,
unsigned int thread, unsigned int channel, unsigned int rank,
unsigned int bankgroup, unsigned int bank, unsigned int row, unsigned int column,
Timespan span, Timespan spanOnDataStrobe, traceTime clk)
: clk(clk), address(address), burstlength(burstlength), thread(thread), channel(channel),
rank(rank), bankgroup(bankgroup), bank(bank), row(row), column(column), span(span),
spanOnDataStrobe(spanOnDataStrobe), id(id) {}
Transaction::Transaction(ID id, QString command, unsigned int address, unsigned int dataLength,
unsigned int thread, unsigned int channel, Timespan span, traceTime clk)
: clk(clk), command(std::move(command)), address(address), dataLength(dataLength), thread(thread), channel(channel),
span(span), id(id) {}
void Transaction::addPhase(shared_ptr<Phase> phase)
void Transaction::addPhase(const shared_ptr<Phase>& phase)
{
phases.push_back(phase);
}
@@ -59,7 +58,7 @@ void Transaction::draw(QPainter *painter, const QwtScaleMap &xMap,
const QwtScaleMap &yMap, const QRectF &canvasRect, bool highlight,
const TraceDrawingProperties &drawingProperties) const
{
for (shared_ptr<Phase> phase : phases)
for (const shared_ptr<Phase>& phase : phases)
phase->draw(painter, xMap, yMap, canvasRect, highlight, drawingProperties);
}
@@ -67,7 +66,7 @@ bool Transaction::isSelected(Timespan timespan, double yVal, const TraceDrawingP
{
if (span.overlaps(timespan))
{
for (shared_ptr<Phase> phase : phases)
for (const shared_ptr<Phase>& phase : phases)
{
if (phase->isSelected(timespan, yVal, drawingproperties))
return true;

View File

@@ -53,21 +53,19 @@ private:
traceTime clk;
public:
const unsigned int address, burstlength, thread, channel, rank,
bankgroup, bank, row, column;
const QString command;
const uint64_t address;
const unsigned int dataLength, thread, channel;
const Timespan span;
const Timespan spanOnDataStrobe;
const ID id;
Transaction(ID id, unsigned int address, unsigned int burstlength,
unsigned int thread, unsigned int channel, unsigned int rank,
unsigned int bankgroup, unsigned int bank, unsigned int row, unsigned int column,
Timespan span, Timespan spanOnDataStrobe, traceTime clk);
Transaction(ID id, QString command, unsigned int address, unsigned int dataLength, unsigned int thread,
unsigned int channel, Timespan span, traceTime clk);
void draw(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap,
const QRectF &canvasRect, bool highlight,
const TraceDrawingProperties &drawingProperties) const;
void addPhase(std::shared_ptr<Phase> phase);
void addPhase(const std::shared_ptr<Phase>& phase);
bool isSelected(Timespan timespan, double yVal, const TraceDrawingProperties &drawingproperties) const;

View File

@@ -50,11 +50,10 @@ struct TransactionQueryTexts {
TransactionQueryTexts()
{
queryHead =
"SELECT Transactions.ID AS TransactionID, Ranges.begin, Ranges.end,DataStrobeBegin,DataStrobeEnd, Address,Burstlength, TThread, TChannel, TRank, TBankgroup, TBank, TRow, TColumn,Phases.ID AS PhaseID, PhaseName, PhaseBegin, PhaseEnd "
"SELECT Transactions.ID AS TransactionID, Ranges.begin, Ranges.end, Address, DataLength, Thread, Channel, Command, Phases.ID AS PhaseID, PhaseName, PhaseBegin, PhaseEnd, DataStrobeBegin, DataStrobeEnd, Rank, BankGroup, Bank, Row, Column, BurstLength "
" FROM Transactions INNER JOIN Phases ON Phases.Transact = Transactions.ID INNER JOIN Ranges ON Transactions.Range = Ranges.ID ";
selectTransactionsByTimespan = queryHead +
" WHERE Ranges.end >= :begin AND Ranges.begin <= :end";
selectTransactionsByTimespan = queryHead + " WHERE Ranges.end >= :begin AND Ranges.begin <= :end";
selectTransactionById = queryHead + " WHERE Transactions.ID = :id";
checkDependenciesExist = "SELECT CASE WHEN 0 < (SELECT count(*) FROM sqlite_master WHERE type = 'table' AND "

View File

@@ -52,7 +52,7 @@
//define symbol printqueries if all queries should be printed to the console
//#define printqueries
TraceDB::TraceDB(QString path, bool openExisting)
TraceDB::TraceDB(const QString& path, bool openExisting)
{
this->pathToDB = path;
@@ -136,8 +136,7 @@ void TraceDB::refreshData()
//QueryText must select the fields
//TransactionID, Ranges.begin, Ranges.end, Address, TThread, TChannel, TBank, TRow, TColumn, Phases.ID AS PhaseID, PhaseName, PhaseBegin, PhaseEnd
std::vector<std::shared_ptr<Transaction>> TraceDB::getTransactionsWithCustomQuery(
QString queryText)
std::vector<std::shared_ptr<Transaction>> TraceDB::getTransactionsWithCustomQuery(const QString& queryText)
{
QSqlQuery query(database);
query.prepare(queryText);
@@ -294,7 +293,7 @@ GeneralInfo TraceDB::getGeneralInfoFromDB()
parameter = getParameterFromTable("NumberOfTransactions", "GeneralInfo");
uint64_t numberOfTransactions = parameter.isValid() ? parameter.toULongLong() : 0;
parameter = getParameterFromTable("TraceEnd", "GeneralInfo");
traceTime traceEnd = parameter.isValid() ? parameter.toULongLong() : 0;
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");
@@ -318,15 +317,15 @@ GeneralInfo TraceDB::getGeneralInfoFromDB()
parameter = getParameterFromTable("RefreshMaxPulledin", "GeneralInfo");
unsigned refreshMaxPulledin = parameter.isValid() ? parameter.toUInt() : 0;
parameter = getParameterFromTable("ControllerThread", "GeneralInfo");
uint64_t controllerThread = parameter.isValid() ? parameter.toULongLong() : UINT64_MAX;
unsigned controllerThread = parameter.isValid() ? parameter.toUInt() : UINT_MAX;
parameter = getParameterFromTable("MaxBufferDepth", "GeneralInfo");
unsigned maxBufferDepth = parameter.isValid() ? parameter.toUInt() : 8;
parameter = getParameterFromTable("Per2BankOffset", "GeneralInfo");
unsigned per2BankOffset = parameter.isValid() ? parameter.toUInt() : 1;
parameter = getParameterFromTable("RowColumnCommandBus", "GeneralInfo");
bool rowColumnCommandBus = parameter.isValid() ? parameter.toBool() : false;
bool rowColumnCommandBus = parameter.isValid() && parameter.toBool();
parameter = getParameterFromTable("PseudoChannelMode", "GeneralInfo");
bool pseudoChannelMode = parameter.isValid() ? parameter.toBool() : false;
bool pseudoChannelMode = parameter.isValid() && parameter.toBool();
uint64_t numberOfPhases = getNumberOfPhases();
@@ -374,27 +373,6 @@ CommandLengths TraceDB::getCommandLengthsFromDB()
}
};
auto getCommandLengthOrElse = [=, &table](const std::string &command, const std::string &elseCommand) -> double
{
QVariant length = getLengthFromDb(command);
if (length.isValid())
return length.toDouble();
else
{
length = getLengthFromDb(command);
if (length.isValid())
return length.toUInt();
else
{
qDebug() << "CommandLength for" << command.c_str() << "and" << elseCommand.c_str()
<< "not present in table" << table.c_str() << ". Defaulting to 1.";
return 1;
}
}
};
double NOP = getCommandLength("NOP");
double RD = getCommandLength("RD");
double WR = getCommandLength("RD");
@@ -402,8 +380,8 @@ CommandLengths TraceDB::getCommandLengthsFromDB()
double WRA = getCommandLength("WRA");
double ACT = getCommandLength("ACT");
double PREPB = getCommandLengthOrElse("PREPB", "PRE");
double REFPB = getCommandLengthOrElse("REFPB", "REFB");
double PREPB = getCommandLength("PREPB");
double REFPB = getCommandLength("REFPB");
double RFMPB = getCommandLength("RFMPB");
double REFP2B = getCommandLength("REFP2B");
@@ -412,8 +390,8 @@ CommandLengths TraceDB::getCommandLengthsFromDB()
double REFSB = getCommandLength("REFSB");
double RFMSB = getCommandLength("RFMSB");
double PREAB = getCommandLengthOrElse("PREAB", "PREA");
double REFAB = getCommandLengthOrElse("REFAB", "REFA");
double PREAB = getCommandLength("PREAB");
double REFAB = getCommandLength("REFAB");
double RFMAB = getCommandLength("RFMAB");
double PDEA = getCommandLength("PDEA");
@@ -566,34 +544,37 @@ std::vector<std::shared_ptr<Transaction>> TraceDB::parseTransactionsFromQuery(QS
ID currentID = 0;
int i = -1;
while (query.next()) {
while (query.next())
{
ID id = query.value(0).toInt();
if (currentID != id || firstIteration) {
if (currentID != id || firstIteration)
{
++i;
firstIteration = false;
currentID = id;
Timespan span(query.value(1).toLongLong(), query.value(2).toLongLong());
Timespan spanOnStrobe(query.value(3).toLongLong(), query.value(4).toLongLong());
unsigned int address = query.value(5).toInt();
unsigned int burstlength = query.value(6).toInt();
unsigned int thread = query.value(7).toInt();
unsigned int channel = query.value(8).toInt();
unsigned int rank = query.value(9).toInt();
unsigned int bankgroup = query.value(10).toInt();
unsigned int bank = query.value(11).toInt();
unsigned int row = query.value(12).toInt();
unsigned int column = query.value(13).toInt();
result.push_back(std::make_shared<Transaction>(id, address, burstlength,
thread, channel, rank, bankgroup, bank, row, column,
span, spanOnStrobe, generalInfo.clkPeriod));
uint64_t address = query.value(3).toULongLong();
unsigned int dataLength = query.value(4).toUInt();
unsigned int thread = query.value(5).toUInt();
unsigned int channel = query.value(6).toUInt();
QString command = query.value(7).toString();
result.push_back(std::make_shared<Transaction>(id, std::move(command), address, dataLength, thread, channel,
span, generalInfo.clkPeriod));
}
unsigned int phaseID = query.value(14).toInt();
QString phaseName = query.value(15).toString();
Timespan span(query.value(16).toLongLong(), query.value(17).toLongLong());
auto phase = PhaseFactory::CreatePhase(phaseID, phaseName, span, result.at(result.size() - 1), *this);
unsigned int phaseID = query.value(8).toInt();
QString phaseName = query.value(9).toString();
Timespan span(query.value(10).toLongLong(), query.value(11).toLongLong());
Timespan spanOnDataStrobe(query.value(12).toLongLong(), query.value(13).toLongLong());
unsigned int rank = query.value(14).toUInt();
unsigned int bankGroup = query.value(15).toUInt();
unsigned int bank = query.value(16).toUInt();
unsigned int row = query.value(17).toUInt();
unsigned int column = query.value(18).toUInt();
unsigned int burstLength = query.value(19).toUInt();
auto phase = PhaseFactory::createPhase(phaseID, phaseName, span, spanOnDataStrobe, rank, bankGroup, bank,
row, column, burstLength, result.at(result.size() - 1), *this);
result.at(result.size() - 1)->addPhase(phase);
if (updateVisiblePhases)
@@ -694,7 +675,7 @@ void TraceDB::executeQuery(QSqlQuery query)
}
}
QString TraceDB::queryToString(QSqlQuery query)
QString TraceDB::queryToString(const QSqlQuery& query)
{
QString str = query.lastQuery();
QMapIterator<QString, QVariant> it(query.boundValues());
@@ -711,7 +692,7 @@ void TraceDB::dropAndCreateTables()
executeScriptFile("common/static/createTraceDB.sql");
}
void TraceDB::executeScriptFile(QString fileName)
void TraceDB::executeScriptFile(const QString& fileName)
{
QSqlQuery query(database);
QFile scriptFile(fileName);

View File

@@ -64,7 +64,7 @@ class TraceDB : public QObject
Q_OBJECT
public:
TraceDB(QString path, bool openExisting);
TraceDB(const QString& path, bool openExisting);
const QString &getPathToDB() const
{
return pathToDB;
@@ -86,7 +86,7 @@ public:
}
std::vector<std::shared_ptr<Transaction>> getTransactionsWithCustomQuery(
QString queryText);
const QString& queryText);
std::vector<std::shared_ptr<Transaction>> getTransactionsInTimespan(const Timespan &span,
bool updateVisiblePhases = false);
std::shared_ptr<Transaction> getNextPrecharge(traceTime time);
@@ -133,7 +133,7 @@ private:
TransactionQueryTexts queryTexts;
void prepareQueries();
void executeQuery(QSqlQuery query);
static QString queryToString(QSqlQuery query);
static QString queryToString(const QSqlQuery& query);
std::shared_ptr<Transaction> parseTransactionFromQuery(QSqlQuery &query);
std::vector<std::shared_ptr<Transaction>> parseTransactionsFromQuery(QSqlQuery &query,
bool updateVisiblePhases = false);
@@ -142,7 +142,7 @@ private:
void mUpdateDependenciesFromQuery(QSqlQuery &query);
static DependencyInfos parseDependencyInfos(QSqlQuery &query, const DependencyInfos::Type infoType);
void executeScriptFile(QString fileName);
void executeScriptFile(const QString& fileName);
void dropAndCreateTables();
uint64_t getNumberOfPhases();

View File

@@ -46,6 +46,22 @@ void SelectedTransactionTreeWidget::selectedTransactionsChanged()
AppendTransaction(transaction);
}
expandAll();
for (size_t k = 0; k < topLevelItemCount(); k++)
{
auto node = topLevelItem(k);
for (size_t i = 0; i < node->childCount(); i++)
{
if (node->child(i)->text(0) == "Phases")
{
auto phaseNode = node->child(i);
for (size_t j = 0; j < phaseNode->childCount(); j++)
phaseNode->child(j)->setExpanded(false);
}
}
}
resizeColumnToContents(0);
}

View File

@@ -46,7 +46,7 @@ class TraceMetricTreeWidget : public QTreeWidget
{
Q_OBJECT
public:
TraceMetricTreeWidget(QWidget *parent = 0);
explicit TraceMetricTreeWidget(QWidget *parent = nullptr);
void addTraceMetricResults(const TraceCalculatedMetrics &result);
void addTracePlotResults(QString traceName, QString outputFiles);

View File

@@ -311,9 +311,9 @@ void TracePlot::setUpDrawingProperties()
drawingProperties.numberOfRanks = navigator->GeneralTraceInfo().numberOfRanks;
drawingProperties.numberOfBankGroups = navigator->GeneralTraceInfo().numberOfBankGroups;
drawingProperties.numberOfBanks = navigator->GeneralTraceInfo().numberOfBanks;
drawingProperties.banksPerRank = drawingProperties.numberOfBanks / drawingProperties.numberOfRanks;
drawingProperties.groupsPerRank = drawingProperties.numberOfBankGroups / drawingProperties.numberOfRanks;
drawingProperties.banksPerGroup = drawingProperties.numberOfBanks / drawingProperties.numberOfBankGroups;
drawingProperties.banksPerRank = navigator->GeneralTraceInfo().banksPerRank;
drawingProperties.groupsPerRank = navigator->GeneralTraceInfo().groupsPerRank;
drawingProperties.banksPerGroup = navigator->GeneralTraceInfo().banksPerGroup;
drawingProperties.per2BankOffset = navigator->GeneralTraceInfo().per2BankOffset;
}

View File

@@ -38,102 +38,124 @@
#include "transactiontreewidget.h"
#include "data/tracedb.h"
#include <QHeaderView>
#include <vector>
#include <memory>
#include <vector>
using namespace std;
TransactionTreeWidget::TransactionTreeWidget(QWidget *parent) : QTreeWidget(
parent), isInitialized(false)
TransactionTreeWidget::TransactionTreeWidget(QWidget *parent) : QTreeWidget(parent), isInitialized(false)
{
QObject::connect(this, SIGNAL(customContextMenuRequested(QPoint)), this,
SLOT(ContextMenuRequested(QPoint)));
QObject::connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(ContextMenuRequested(QPoint)));
setContextMenuPolicy(Qt::CustomContextMenu);
goToTransaction = new QAction("Move to", this);
}
void TransactionTreeWidget::init(TraceNavigator *navigator)
void TransactionTreeWidget::init(TraceNavigator *_navigator)
{
Q_ASSERT(isInitialized == false);
isInitialized = true;
this->navigator = navigator;
this->navigator = _navigator;
setColumnCount(3);
setHeaderLabels(QStringList({"Transaction", "Value", "Value"}));
}
void TransactionTreeWidget::AppendTransaction(const shared_ptr<Transaction>
&transaction)
void TransactionTreeWidget::AppendTransaction(const shared_ptr<Transaction> &transaction)
{
QTreeWidgetItem *node = new TransactionTreeItem(this, transaction,
navigator->GeneralTraceInfo());
QTreeWidgetItem *node = new TransactionTreeItem(this, transaction, navigator->GeneralTraceInfo());
addTopLevelItem(node);
}
void TransactionTreeWidget::ContextMenuRequested(QPoint point)
{
if (selectedItems().count() > 0
&& selectedItems().at(0)->type() ==
TransactionTreeWidget::TransactionTreeItem::transactionTreeItemType) {
if (selectedItems().count() > 0 &&
selectedItems().at(0)->type() == TransactionTreeWidget::TransactionTreeItem::transactionTreeItemType)
{
QMenu contextMenu;
contextMenu.addActions({goToTransaction});
QAction *selectedContextMenuItems = contextMenu.exec(mapToGlobal(point));
if (selectedContextMenuItems) {
TransactionTreeItem *item = static_cast<TransactionTreeItem *>
(selectedItems().at(0));
if (selectedContextMenuItems)
{
TransactionTreeItem *item = dynamic_cast<TransactionTreeItem *>(selectedItems().at(0));
navigator->selectTransaction(item->Id());
}
}
}
TransactionTreeWidget::TransactionTreeItem::TransactionTreeItem(
QTreeWidget *parent, const shared_ptr<Transaction> &transaction,
const GeneralInfo &generalInfo)
TransactionTreeWidget::TransactionTreeItem::TransactionTreeItem(QTreeWidget *parent,
const shared_ptr<Transaction> &transaction,
const GeneralInfo &generalInfo)
: QTreeWidgetItem(parent, transactionTreeItemType)
{
this->setText(0, QString::number(transaction->id));
this->id = transaction->id;
QTreeWidgetItem *time = new QTreeWidgetItem({"Timespan"});
bool isControllerTransaction = (transaction->thread == generalInfo.controllerThread);
auto *time = new QTreeWidgetItem({"Timespan"});
AppendTimespan(time, transaction->span);
this->addChild(time);
this->addChild(new QTreeWidgetItem({"Length", prettyFormatTime(transaction->span.timeCovered())}));
this->addChild(new QTreeWidgetItem({"Channel", QString::number(transaction->channel)}));
this->addChild(new QTreeWidgetItem({"Rank", QString::number(transaction->rank)}));
this->addChild(new QTreeWidgetItem({"Bankgroup", QString::number(transaction->bankgroup % generalInfo.groupsPerRank)}));
this->addChild(new QTreeWidgetItem({"Bank", QString::number(transaction->bank % generalInfo.banksPerGroup)}));
this->addChild(new QTreeWidgetItem({"Row", QString::number(transaction->row)}));
this->addChild(new QTreeWidgetItem({"Column", QString::number(transaction->column)}));
this->addChild(new QTreeWidgetItem({"Address", QString("0x") + QString::number(transaction->address, 16)}));
if (transaction->thread != generalInfo.controllerThread)
if (!isControllerTransaction)
{
this->addChild(new QTreeWidgetItem({"Burstlength", QString::number(transaction->burstlength)}));
this->addChild(new QTreeWidgetItem({"Thread", QString::number(transaction->thread)}));
if (transaction->command == "R")
this->addChild(new QTreeWidgetItem({"Command", "Read"}));
else // if (transaction->command == "W")
this->addChild(new QTreeWidgetItem({"Command", "Write"}));
}
this->addChild(new QTreeWidgetItem({"Length", prettyFormatTime(transaction->span.timeCovered())}));
if (!isControllerTransaction)
this->addChild(new QTreeWidgetItem({"Address", QString("0x") + QString::number(transaction->address, 16)}));
if (!isControllerTransaction)
this->addChild(new QTreeWidgetItem({"Data Length", QString::number(transaction->dataLength)}));
this->addChild(new QTreeWidgetItem({"Channel", QString::number(transaction->channel)}));
if (!isControllerTransaction)
this->addChild(new QTreeWidgetItem({"Thread", QString::number(transaction->thread)}));
QTreeWidgetItem *phasesNode = new QTreeWidgetItem(this);
auto *phasesNode = new QTreeWidgetItem(this);
phasesNode->setText(0, "Phases");
phasesNode->addChild(new QTreeWidgetItem({"", "Begin", "End"}));
for (std::shared_ptr<Phase> phase : transaction->Phases()) {
for (const std::shared_ptr<Phase> &phase : transaction->Phases())
AppendPhase(phasesNode, *phase);
}
void TransactionTreeWidget::TransactionTreeItem::AppendPhase(QTreeWidgetItem *parent, const Phase &phase)
{
auto *node = new QTreeWidgetItem(parent);
node->setText(0, phase.Name() + QString(" [") + QString::number(phase.Id()) + QString("]"));
AppendTimespan(node, phase.Span());
auto addMapping = [node](std::string_view label, unsigned value)
{
auto *mappingNode = new QTreeWidgetItem(node);
mappingNode->setText(0, label.data());
mappingNode->setText(1, QString::number(value));
};
{
if (static_cast<int>(phase.getRelevantAttributes() & RelevantAttributes::Rank))
addMapping("Rank", phase.getRank());
if (static_cast<int>(phase.getRelevantAttributes() & RelevantAttributes::BankGroup))
addMapping("Bank Group", phase.getBankGroup());
if (static_cast<int>(phase.getRelevantAttributes() & RelevantAttributes::Bank))
addMapping("Bank", phase.getBank());
if (static_cast<int>(phase.getRelevantAttributes() & RelevantAttributes::Row))
addMapping("Row", phase.getRow());
if (static_cast<int>(phase.getRelevantAttributes() & RelevantAttributes::Column))
addMapping("Column", phase.getColumn());
if (static_cast<int>(phase.getRelevantAttributes() & RelevantAttributes::BurstLength))
addMapping("Burst Length", phase.getBurstLength());
}
}
void TransactionTreeWidget::TransactionTreeItem::AppendPhase(
QTreeWidgetItem *parent, const Phase &phase)
{
QTreeWidgetItem *node = new QTreeWidgetItem(parent);
node->setText(0, phase.Name() + QString(" [") + QString::number(
phase.Id()) + QString("]"));
AppendTimespan(node, phase.Span());
}
void TransactionTreeWidget::TransactionTreeItem::AppendTimespan(
QTreeWidgetItem *parent, const Timespan &timespan)
void TransactionTreeWidget::TransactionTreeItem::AppendTimespan(QTreeWidgetItem *parent, const Timespan &timespan)
{
parent->setText(1, prettyFormatTime(timespan.Begin()));
parent->setText(2, prettyFormatTime(timespan.End()));

View File

@@ -49,10 +49,10 @@ class TransactionTreeWidget : public QTreeWidget
Q_OBJECT
public:
TransactionTreeWidget(QWidget *parent);
explicit TransactionTreeWidget(QWidget *parent);
void AppendTransaction(const std::shared_ptr<Transaction> &transaction);
virtual void init(TraceNavigator *navigator);
virtual void init(TraceNavigator *_navigator);
public Q_SLOTS:
void ContextMenuRequested(QPoint point);
@@ -62,8 +62,6 @@ protected:
private:
bool isInitialized;
void AppendTimespan(QTreeWidgetItem *parent, const Timespan &timespan);
void AppendPhase(QTreeWidgetItem *parent, const Phase &phase);
QAction *goToTransaction;
class TransactionTreeItem : public QTreeWidgetItem
@@ -72,14 +70,14 @@ private:
static constexpr int transactionTreeItemType = 1001;
TransactionTreeItem(QTreeWidget *parent,
const std::shared_ptr<Transaction> &trans, const GeneralInfo &generalInfo);
ID Id()
ID Id() const
{
return id;
}
private:
ID id;
void AppendTimespan(QTreeWidgetItem *parent, const Timespan &timespan);
void AppendPhase(QTreeWidgetItem *parent, const Phase &phase);
static void AppendTimespan(QTreeWidgetItem *parent, const Timespan &timespan);
static void AppendPhase(QTreeWidgetItem *parent, const Phase &phase);
};
};

View File

@@ -53,23 +53,26 @@ QueryEditor::~QueryEditor()
delete ui;
}
void QueryEditor::init(TraceNavigator *navigator)
void QueryEditor::init(TraceNavigator* _navigator)
{
this->navigator = navigator;
ui->transactiontreeWidget->init(navigator);
this->navigator = _navigator;
ui->transactiontreeWidget->init(_navigator);
}
void QueryEditor::on_executeQuery_clicked()
{
try {
std::vector<std::shared_ptr<Transaction>> result =
navigator->TraceFile().getTransactionsWithCustomQuery(queryTexts.queryHead + " "
+ ui->queryEdit->toPlainText());
try
{
std::vector<std::shared_ptr<Transaction>> result = navigator->TraceFile().getTransactionsWithCustomQuery(
queryTexts.queryHead + " " + ui->queryEdit->toPlainText());
ui->transactiontreeWidget->clear();
for (const auto &trans : result) {
for (const auto& trans : result)
{
ui->transactiontreeWidget->AppendTransaction(trans);
}
} catch (sqlException ex) {
}
catch (const sqlException& ex)
{
QMessageBox::warning(this, "Query failed", ex.what());
}
}

View File

@@ -53,7 +53,7 @@ class QueryEditor : public QWidget
public:
explicit QueryEditor(QWidget *parent = 0);
~QueryEditor();
void init(TraceNavigator *navigator);
void init(TraceNavigator *_navigator);
private Q_SLOTS:
void on_executeQuery_clicked();

View File

@@ -140,25 +140,26 @@ def getControllerThread(connection):
def get_phase_occurrences(connection, phase):
cursor = connection.cursor()
query = "select count(*) from Phases where PhaseName = :phase"
query = "SELECT count(*) FROM Phases WHERE PhaseName = :phase"
cursor.execute(query, {"phase": phase})
r = cursor.fetchone()
cnt = r[0]
if (cnt is None):
if cnt is None:
cnt = 0
return cnt
def get_total_time_in_phase(connection, phase):
cursor = connection.cursor()
query = "select sum(PhaseEnd - PhaseBegin) / 1000 from Phases where PhaseName = :phase"
query = "SELECT SUM(PhaseEnd - PhaseBegin) / 1000 FROM Phases WHERE PhaseName = :phase"
cursor.execute(query, {"phase": phase})
time = cursor.fetchone()
totalTime = time[0]
if (totalTime is None):
if totalTime is None:
totalTime = 0.0
return totalTime
def getCommandLengthForPhase(connection, phase):
cursor = connection.cursor()
cursor.execute("SELECT " + phase + " FROM CommandLengths")

File diff suppressed because it is too large Load Diff

View File

@@ -122,8 +122,7 @@ The JSON code below shows an example configuration:
"tracesetup": [
{
"clkMhz": 300,
"name": "ddr3_example.stl",
"addLengthConverter": true
"name": "ddr3_example.stl"
},
{
"clkMhz": 2000,
@@ -160,7 +159,6 @@ Field Descriptions:
Each **trace setup** device configuration can be a **trace player** ("type": "player"), a **traffic generator** ("type": "generator") or a **row hammer generator** ("type": "hammer"). By not specifing the **type** parameter, the device will act as a **trace player**.
All device configurations must define a **clkMhz** (operation frequency of the **traffic initiator**) and a **name** (in case of a trace player this specifies the **trace file** to play; in case of a generator this field is only for identification purposes).
The optional parameter **addLengthConverter** adds a transaction length converter between initiator and DRAMSys. This unit divides a large transaction up into several smaller transactions with the maximum length of one DRAM burst access.
The **maxPendingReadRequests** and **maxPendingWriteRequests** parameters define the maximum number of outstanding read/write requests. The current implementation delays all memory accesses if one limit is reached. The default value (0) disables the limit.
A **traffic generator** can be configured to generate **numRequests** requests in total, of which the **rwRatio** field defines the probability of one request being a read request. The length of a request (in bytes) can be specified with the **dataLength** parameter. The **seed** parameter can be used to produce identical results for all simulations. **minAddress** and **maxAddress** specify the address range, by default the whole address range is used. The parameter **addressDistribution** can either be set to **random** or **sequential**. In case of **sequential** the additional **addressIncrement** field must be specified, defining the address increment after each request.