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:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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()))
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -70,7 +70,6 @@ public:
|
||||
const sc_core::sc_time &playerClk,
|
||||
unsigned int maxPendingReadRequests,
|
||||
unsigned int maxPendingWriteRequests,
|
||||
bool addLengthConverter,
|
||||
TraceSetup& setup,
|
||||
bool relative);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 + "\",";
|
||||
|
||||
@@ -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 + "\",";
|
||||
|
||||
@@ -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 + "\",";
|
||||
|
||||
@@ -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 + "\",";
|
||||
|
||||
@@ -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 + "\",";
|
||||
|
||||
@@ -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 + "\",";
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 "
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ×pan)
|
||||
void TransactionTreeWidget::TransactionTreeItem::AppendTimespan(QTreeWidgetItem *parent, const Timespan ×pan)
|
||||
{
|
||||
parent->setText(1, prettyFormatTime(timespan.Begin()));
|
||||
parent->setText(2, prettyFormatTime(timespan.End()));
|
||||
|
||||
@@ -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 ×pan);
|
||||
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 ×pan);
|
||||
void AppendPhase(QTreeWidgetItem *parent, const Phase &phase);
|
||||
static void AppendTimespan(QTreeWidgetItem *parent, const Timespan ×pan);
|
||||
static void AppendPhase(QTreeWidgetItem *parent, const Phase &phase);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user