This commit is contained in:
robert
2014-05-10 13:02:55 +02:00
parent f7dad49f7d
commit c74b544f3e
36 changed files with 1113 additions and 952 deletions

View File

@@ -2,9 +2,10 @@
#include "protocol.h"
#include "dramExtension.h"
#include "xmlAddressdecoder.h"
#include "Utils.h"
#include "../controller/core/configuration/Configuration.h"
#include <iostream>
#include <algorithm>
#include <boost/filesystem.hpp>
using namespace std;
@@ -12,14 +13,24 @@ string TlmRecorder::dbName = "";
string TlmRecorder::sqlScriptURI = "";
string TlmRecorder::senderName = "TlmRecorder";
// ------------- public -----------------------
TlmRecorder::TlmRecorder() :
transactionIDCounter(1), recordingEndTime(SC_ZERO_TIME)
transactionIDCounter(1), recordingEndTime(SC_ZERO_TIME)
{
recordedData.reserve(transactionCommitRate);
setUpTransactionTerminatingPhases();
openDB(TlmRecorder::dbName.c_str());
char * sErrMsg;
sqlite3_exec(db, "PRAGMA main.page_size = 4096", NULL, NULL, &sErrMsg);
sqlite3_exec(db, "PRAGMA main.cache_size=10000", NULL, NULL, &sErrMsg);
sqlite3_exec(db, "PRAGMA main.locking_mode=EXCLUSIVE", NULL, NULL, &sErrMsg);
sqlite3_exec(db, "PRAGMA main.synchronous=OFF", NULL, NULL, &sErrMsg);
sqlite3_exec(db, "PRAGMA journal_mode = OFF", NULL, NULL, &sErrMsg);
createTables(TlmRecorder::sqlScriptURI);
prepareSqlStatements();
sqlite3_exec(db, "BEGIN", 0, 0, 0);
printDebugMessage("Starting new database transaction");
}
@@ -30,10 +41,30 @@ TlmRecorder::~TlmRecorder()
closeConnection();
}
void TlmRecorder::recordDummy(tlm::tlm_generic_payload& trans)
{
// static unsigned int id = 0;
// RecordingData data(id);
// insertTransactionInDB(data,trans);
// insertRangeInDB(id,SC_ZERO_TIME,SC_ZERO_TIME);
// for(int i=0;i<5;i++)
// {
// string phaseName("Phase " + to_string(id));
// sqlite3_bind_text(insertPhaseStatement, 1, phaseName.c_str(), phaseName.length(), 0);
// sqlite3_bind_int64(insertPhaseStatement, 2, 0);
// sqlite3_bind_int64(insertPhaseStatement, 3, 2);
// sqlite3_bind_int(insertPhaseStatement, 4, id);
// executeSqlStatement(insertPhaseStatement);
// }
// id++;
}
void TlmRecorder::recordPhase(tlm::tlm_generic_payload& trans, tlm::tlm_phase phase, sc_time time)
{
if (currentTransactionsInSystem.count(&trans) == 0)
introduceNewTransactionToSystem(time, trans);
introduceNewTransactionToSystem(trans);
string phaseName = phaseNameToString(phase);
string phaseBeginPrefix = "BEGIN_";
@@ -42,27 +73,125 @@ void TlmRecorder::recordPhase(tlm::tlm_generic_payload& trans, tlm::tlm_phase ph
if (phaseName.find(phaseBeginPrefix) != string::npos)
{
phaseName.erase(0, phaseBeginPrefix.length());
insertPhaseInDB(phaseName, time, time, trans);
assert(currentTransactionsInSystem.count(&trans) != 0);
currentTransactionsInSystem[&trans].insertPhase(phaseName,time);
}
else
{
phaseName.erase(0, phaseEndPrefix.length());
updatePhaseEndInDB(phaseName, time, trans);
assert(currentTransactionsInSystem.count(&trans) != 0);
currentTransactionsInSystem[&trans].setPhaseEnd(phaseName,time);
}
bool phaseTerminatesTransaction = count(transactionTerminatingPhases.begin(),
transactionTerminatingPhases.end(), phase) == 1;
transactionTerminatingPhases.end(), phase) == 1;
if (phaseTerminatesTransaction)
removeTransactionFromSystem(time, trans);
removeTransactionFromDBAndInsertInDB(trans);
recordingEndTime = time;
}
void TlmRecorder::updateDataStrobe(const sc_time& begin,const sc_time& end, tlm::tlm_generic_payload& trans)
{
assert(currentTransactionsInSystem.count(&trans) != 0);
currentTransactionsInSystem[&trans].timeOnDataStrobe.start = begin;
currentTransactionsInSystem[&trans].timeOnDataStrobe.end = end;
}
void TlmRecorder::recordDebugMessage(std::string message, sc_time time)
{
insertDebugMessageInDB(message, time);
}
// ------------- internal -----------------------
void TlmRecorder::introduceNewTransactionToSystem(tlm::tlm_generic_payload& trans)
{
unsigned int id = transactionIDCounter++;
currentTransactionsInSystem[&trans].id = id;
currentTransactionsInSystem[&trans].address = trans.get_address();
currentTransactionsInSystem[&trans].burstlength = trans.get_streaming_width();
currentTransactionsInSystem[&trans].dramExtension = DramExtension::getExtension(trans);
if(DramExtension::getExtension(trans).getThread().ID() == 0)
currentTransactionsInSystem[&trans].timeOfGeneration = SC_ZERO_TIME;
else
currentTransactionsInSystem[&trans].timeOfGeneration = GenerationExtension::getExtension(&trans).TimeOfGeneration();
if (id % transactionCommitRate == 0)
{
printDebugMessage(
"Committing transactions " + to_string(id - transactionCommitRate + 1) + " - "
+ to_string(id));
commitRecordedDataToDB();
}
}
void TlmRecorder::removeTransactionFromDBAndInsertInDB(tlm::tlm_generic_payload& trans)
{
assert(currentTransactionsInSystem.count(&trans) != 0);
RecordingData& recordingData = currentTransactionsInSystem[&trans];
recordedData.push_back(recordingData);
currentTransactionsInSystem.erase(&trans);
}
void TlmRecorder::commitRecordedDataToDB()
{
sqlite3_exec(db, "BEGIN;", 0, 0, 0);
for(RecordingData& recordingData: recordedData)
{
assert(recordingData.recordedPhases.size() > 0);
insertTransactionInDB(recordingData);
for(RecordingData::PhaseData& phaseData: recordingData.recordedPhases)
{
insertPhaseInDB(phaseData.name,phaseData.interval.start,phaseData.interval.end,recordingData.id);
}
sc_time rangeBegin = recordingData.recordedPhases.front().interval.start;
sc_time rangeEnd = recordingData.recordedPhases.back().interval.end;
insertRangeInDB(recordingData.id,rangeBegin,rangeEnd);
}
sqlite3_exec(db, "COMMIT;", 0, 0, 0);
recordedData.clear();
}
void TlmRecorder::RecordingData::insertPhase(string name, sc_time begin)
{
recordedPhases.push_back(PhaseData(name,begin));
}
void TlmRecorder::RecordingData::setPhaseEnd(string name, sc_time end)
{
for(PhaseData& data: recordedPhases)
{
if(data.name == name)
{
data.interval.end = end;
return;
}
}
SC_REPORT_FATAL("Recording Error", "While trying to set phase end: phaseBegin has not been recorded");
}
void TlmRecorder::openDB(std::string name)
{
boost::filesystem::wpath file(name);
if(boost::filesystem::exists(file))
boost::filesystem::remove(file);
if (sqlite3_open(name.c_str(), &db))
{
SC_REPORT_FATAL("Error in TraceRecorder", "Error cannot open database");
sqlite3_close(db);
}
}
void TlmRecorder::createTables(string pathToURI)
{
string initial = loadTextFileContents(pathToURI);
@@ -95,23 +224,14 @@ void TlmRecorder::prepareSqlStatements()
"(:numberOfTransactions,:end,:numberOfBanks,:clk,:unitOfTime,:memconfig,:memspec,:traces)";
insertDebugMessageString = "INSERT INTO DebugMessages (Time,Message) Values (:time,:message)";
sqlite3_prepare(db, insertTransactionString.c_str(), -1, &insertTransactionStatement, 0);
sqlite3_prepare(db, insertRangeString.c_str(), -1, &insertRangeStatement, 0);
sqlite3_prepare(db, updateRangeString.c_str(), -1, &updateRangeStatement, 0);
sqlite3_prepare(db, insertPhaseString.c_str(), -1, &insertPhaseStatement, 0);
sqlite3_prepare(db, updatePhaseString.c_str(), -1, &updatePhaseStatement, 0);
sqlite3_prepare(db, updateDataStrobeString.c_str(), -1, &updateDataStrobeStatement, 0);
sqlite3_prepare(db, insertGeneralInfoString.c_str(), -1, &insertGeneralInfoStatement, 0);
sqlite3_prepare(db, insertDebugMessageString.c_str(), -1, &insertDebugMessageStatement, 0);
}
void TlmRecorder::openDB(std::string name)
{
if (sqlite3_open(name.c_str(), &db))
{
SC_REPORT_FATAL("Error in TraceRecorder", "Error cannot open database");
sqlite3_close(db);
}
sqlite3_prepare_v2(db, insertTransactionString.c_str(), -1, &insertTransactionStatement, 0);
sqlite3_prepare_v2(db, insertRangeString.c_str(), -1, &insertRangeStatement, 0);
sqlite3_prepare_v2(db, updateRangeString.c_str(), -1, &updateRangeStatement, 0);
sqlite3_prepare_v2(db, insertPhaseString.c_str(), -1, &insertPhaseStatement, 0);
sqlite3_prepare_v2(db, updatePhaseString.c_str(), -1, &updatePhaseStatement, 0);
sqlite3_prepare_v2(db, updateDataStrobeString.c_str(), -1, &updateDataStrobeStatement, 0);
sqlite3_prepare_v2(db, insertGeneralInfoString.c_str(), -1, &insertGeneralInfoStatement, 0);
sqlite3_prepare_v2(db, insertDebugMessageString.c_str(), -1, &insertDebugMessageStatement, 0);
}
void TlmRecorder::insertDebugMessageInDB(string message, const sc_time& time)
@@ -126,7 +246,7 @@ void TlmRecorder::insertGeneralInfo()
sqlite3_bind_int64(insertGeneralInfoStatement, 1, transactionIDCounter - 1);
sqlite3_bind_int64(insertGeneralInfoStatement, 2, recordingEndTime.value());
sqlite3_bind_int(insertGeneralInfoStatement, 3,
core::Configuration::getInstance().NumberOfBanks);
core::Configuration::getInstance().NumberOfBanks);
sqlite3_bind_int(insertGeneralInfoStatement, 4, core::Configuration::getInstance().Timings.clk.value());
sqlite3_bind_text(insertGeneralInfoStatement, 5, "PS", 2, NULL);
sqlite3_bind_text(insertGeneralInfoStatement, 6, memconfig.c_str(), memconfig.length(), NULL);
@@ -134,102 +254,54 @@ void TlmRecorder::insertGeneralInfo()
sqlite3_bind_text(insertGeneralInfoStatement, 8, traces.c_str(), traces.length(), NULL);
executeSqlStatement(insertGeneralInfoStatement);
}
void TlmRecorder::insertTransactionInDB(unsigned int id, tlm::tlm_generic_payload& trans)
void TlmRecorder::insertTransactionInDB(RecordingData& recordingData)
{
sqlite3_bind_int(insertTransactionStatement, 1, id);
sqlite3_bind_int(insertTransactionStatement, 2, id);
sqlite3_bind_int(insertTransactionStatement, 3, trans.get_address());
sqlite3_bind_int(insertTransactionStatement, 4, trans.get_streaming_width());
const DramExtension& extension = DramExtension::getExtension(trans);
sqlite3_bind_int(insertTransactionStatement, 5, extension.getThread().ID());
sqlite3_bind_int(insertTransactionStatement, 6, extension.getChannel().ID());
sqlite3_bind_int(insertTransactionStatement, 7, extension.getBank().ID());
sqlite3_bind_int(insertTransactionStatement, 8, extension.getBankGroup().ID());
sqlite3_bind_int(insertTransactionStatement, 9, extension.getRow().ID());
sqlite3_bind_int(insertTransactionStatement, 10, extension.getColumn().ID());
sqlite3_bind_int(insertTransactionStatement, 11, 0);
sqlite3_bind_int(insertTransactionStatement, 12, 0);
if(extension.getThread().ID() == 0)
sqlite3_bind_int64(insertTransactionStatement, 13, 0);
else
sqlite3_bind_int64(insertTransactionStatement, 13, GenerationExtension::getExtension(&trans).TimeOfGeneration().value());
sqlite3_bind_int(insertTransactionStatement, 1, recordingData.id);
sqlite3_bind_int(insertTransactionStatement, 2, recordingData.id);
sqlite3_bind_int(insertTransactionStatement, 3, recordingData.address);
sqlite3_bind_int(insertTransactionStatement, 4, recordingData.burstlength);
sqlite3_bind_int(insertTransactionStatement, 5, recordingData.dramExtension.getThread().ID());
sqlite3_bind_int(insertTransactionStatement, 6, recordingData.dramExtension.getChannel().ID());
sqlite3_bind_int(insertTransactionStatement, 7, recordingData.dramExtension.getBank().ID());
sqlite3_bind_int(insertTransactionStatement, 8, recordingData.dramExtension.getBankGroup().ID());
sqlite3_bind_int(insertTransactionStatement, 9, recordingData.dramExtension.getRow().ID());
sqlite3_bind_int(insertTransactionStatement, 10, recordingData.dramExtension.getColumn().ID());
sqlite3_bind_int(insertTransactionStatement, 11, recordingData.timeOnDataStrobe.start.value());
sqlite3_bind_int(insertTransactionStatement, 12, recordingData.timeOnDataStrobe.end.value());
sqlite3_bind_int64(insertTransactionStatement, 13, recordingData.timeOfGeneration.value());
executeSqlStatement(insertTransactionStatement);
}
void TlmRecorder::insertRangeInDB(unsigned int id, const sc_time& time)
void TlmRecorder::insertRangeInDB(unsigned int id, const sc_time& begin, const sc_time& end)
{
sqlite3_bind_int(insertRangeStatement, 1, id);
sqlite3_bind_int64(insertRangeStatement, 2, time.value());
sqlite3_bind_int64(insertRangeStatement, 3, time.value());
sqlite3_bind_int64(insertRangeStatement, 2, begin.value());
sqlite3_bind_int64(insertRangeStatement, 3, end.value());
executeSqlStatement(insertRangeStatement);
}
void TlmRecorder::insertPhaseInDB(string phaseName, const sc_time& begin, const sc_time& end,
tlm::tlm_generic_payload& trans)
unsigned int transactionID)
{
unsigned int id = getElementFromMap(currentTransactionsInSystem, &trans);
sqlite3_bind_text(insertPhaseStatement, 1, phaseName.c_str(), phaseName.length(), 0);
sqlite3_bind_int64(insertPhaseStatement, 2, begin.value());
sqlite3_bind_int64(insertPhaseStatement, 3, end.value());
sqlite3_bind_int(insertPhaseStatement, 4, id);
sqlite3_bind_int(insertPhaseStatement, 4, transactionID);
executeSqlStatement(insertPhaseStatement);
}
void TlmRecorder::updatePhaseEndInDB(string phaseName, const sc_time& time,
tlm::tlm_generic_payload& trans)
{
unsigned int id = getElementFromMap(currentTransactionsInSystem, &trans);
sqlite3_bind_int64(updatePhaseStatement, 1, time.value());
sqlite3_bind_int(updatePhaseStatement, 2, id);
sqlite3_bind_text(updatePhaseStatement, 3, phaseName.c_str(), phaseName.length(), 0);
executeSqlStatement(updatePhaseStatement);
}
void TlmRecorder::updateDataStrobe(const sc_time& begin,const sc_time& end, tlm::tlm_generic_payload& trans)
{
unsigned int id = getElementFromMap(currentTransactionsInSystem, &trans);
sqlite3_bind_int64(updateDataStrobeStatement, 1, begin.value());
sqlite3_bind_int64(updateDataStrobeStatement, 2, end.value());
sqlite3_bind_int(updateDataStrobeStatement, 3, id);
executeSqlStatement(updateDataStrobeStatement);
}
void TlmRecorder::introduceNewTransactionToSystem(const sc_time& time,
tlm::tlm_generic_payload& trans)
{
unsigned int id = transactionIDCounter++;
currentTransactionsInSystem[&trans] = id;
insertTransactionInDB(id, trans);
insertRangeInDB(id, time);
if (id % transactionCommitRate == 0)
{
sqlite3_exec(db, "COMMIT", 0, 0, 0);
printDebugMessage(
"Committing transactions " + to_string(id - transactionCommitRate + 1) + " - "
+ to_string(id));
sqlite3_exec(db, "BEGIN", 0, 0, 0);
}
}
void TlmRecorder::removeTransactionFromSystem(const sc_time& time, tlm::tlm_generic_payload& trans)
{
unsigned int id = getElementFromMap(currentTransactionsInSystem, &trans);
currentTransactionsInSystem.erase(&trans);
sqlite3_bind_int64(updateRangeStatement, 1, time.value());
sqlite3_bind_int(updateRangeStatement, 2, id);
executeSqlStatement(updateRangeStatement);
}
void TlmRecorder::executeSqlStatement(sqlite3_stmt* statement)
{
if (sqlite3_step(statement) != SQLITE_DONE)
int errorCode = sqlite3_step(statement);
if (errorCode != SQLITE_DONE)
{
SC_REPORT_FATAL("Error in TraceRecorder", "Could not execute statement");
reportFatal("Error in TraceRecorder", string("Could not execute statement. Error code: ") + to_string(errorCode));
}
sqlite3_reset(statement);
}
void TlmRecorder::executeSqlCommand(string command)
{
printDebugMessage("Creating database by running provided sql script");
@@ -245,7 +317,6 @@ void TlmRecorder::executeSqlCommand(string command)
printDebugMessage("Database created successfully");
}
void TlmRecorder::printDebugMessage(std::string message)
{
DebugManager::getInstance().printDebugMessage(TlmRecorder::senderName, message);
@@ -253,10 +324,10 @@ void TlmRecorder::printDebugMessage(std::string message)
void TlmRecorder::closeConnection()
{
commitRecordedDataToDB();
insertGeneralInfo();
sqlite3_exec(db, "COMMIT", 0, 0, 0);
printDebugMessage(
"Number of transactions written to DB: " + std::to_string(transactionIDCounter - 1));
"Number of transactions written to DB: " + std::to_string(transactionIDCounter - 1));
printDebugMessage("tlmPhaseRecorder:\tEnd Recording");
sqlite3_close(db);
db = NULL;

View File

@@ -2,7 +2,7 @@
#define TLMPHASERECORDER_H
#include <iostream>
#include <ostream>
#include <ostream>
#include <string>
#include <map>
#include <algorithm>
@@ -13,6 +13,7 @@
#include <systemc.h>
#include "xmlAddressdecoder.h"
#include "DebugManager.h"
#include "Utils.h"
using namespace std;
@@ -20,58 +21,89 @@ using namespace std;
class TlmRecorder
{
public:
static std::string sqlScriptURI;
static std::string dbName;
static std::string senderName;
static std::string sqlScriptURI;
static std::string dbName;
static std::string senderName;
static inline TlmRecorder& getInstance()
{
static TlmRecorder decoder;
return decoder;
}
static inline TlmRecorder& getInstance()
{
static TlmRecorder decoder;
return decoder;
}
void recordPhase(tlm::tlm_generic_payload &trans, tlm::tlm_phase phase, sc_time time);
void recordDebugMessage(std::string message, sc_time time);
void updateDataStrobe(const sc_time& begin, const sc_time& end, tlm::tlm_generic_payload& trans);
void closeConnection();
void recordMemconfig(string memconfig){this->memconfig = memconfig;}
void recordMemspec(string memspec){this->memspec = memspec;}
void recordTracenames(string traces){this->traces = traces;}
void recordDummy(tlm::tlm_generic_payload& trans);
void recordPhase(tlm::tlm_generic_payload &trans, tlm::tlm_phase phase, sc_time time);
void recordDebugMessage(std::string message, sc_time time);
void updateDataStrobe(const sc_time& begin, const sc_time& end, tlm::tlm_generic_payload& trans);
void closeConnection();
void recordMemconfig(string memconfig){this->memconfig = memconfig;}
void recordMemspec(string memspec){this->memspec = memspec;}
void recordTracenames(string traces){this->traces = traces;}
private:
std::string memconfig,memspec,traces;
TlmRecorder();
~TlmRecorder();
struct RecordingData
{
RecordingData(){}
RecordingData(unsigned int id):id(id){}
void executeSqlCommand(std::string command);
void executeSqlStatement(sqlite3_stmt* statement);
void prepareSqlStatements();
void openDB(std::string name);
void setUpTransactionTerminatingPhases();
unsigned int id;
unsigned int address;
unsigned int burstlength;
DramExtension dramExtension;
sc_time timeOfGeneration;
TimeInterval timeOnDataStrobe;
void createTables(std::string pathToURI);
void insertGeneralInfo();
void introduceNewTransactionToSystem(const sc_time& time, tlm::tlm_generic_payload& trans);
void removeTransactionFromSystem(const sc_time& time, tlm::tlm_generic_payload& trans);
void insertTransactionInDB(unsigned int transactionID, tlm::tlm_generic_payload& trans);
void insertRangeInDB(unsigned int transactionID, const sc_time& time);
void insertPhaseInDB(string phaseName, const sc_time& begin, const sc_time& end, tlm::tlm_generic_payload& trans);
void updatePhaseEndInDB(string phaseName, const sc_time& time, tlm::tlm_generic_payload& trans);
void insertDebugMessageInDB(string message, const sc_time& time);
struct PhaseData
{
PhaseData(string name,sc_time begin): name(name), interval(begin,SC_ZERO_TIME){}
string name;
TimeInterval interval;
};
std::vector<PhaseData> recordedPhases;
void printDebugMessage(std::string message);
void insertPhase(string name,sc_time begin);
void setPhaseEnd(string name,sc_time end);
static const int transactionCommitRate = 10000;
map<tlm::tlm_generic_payload*, unsigned int> currentTransactionsInSystem;
unsigned int transactionIDCounter;
sc_time recordingEndTime;
};
std::vector<tlm::tlm_phase> transactionTerminatingPhases;
sqlite3 *db;
sqlite3_stmt *insertTransactionStatement, *insertRangeStatement, *updateRangeStatement,
*insertPhaseStatement, *updatePhaseStatement, *insertGeneralInfoStatement, *insertDebugMessageStatement, *updateDataStrobeStatement;
std::string insertTransactionString, insertRangeString, updateRangeString, insertPhaseString, updatePhaseString, insertGeneralInfoString,
insertDebugMessageString, updateDataStrobeString;
std::string memconfig,memspec,traces;
TlmRecorder();
~TlmRecorder();
void prepareSqlStatements();
void executeSqlCommand(std::string command);
void executeSqlStatement(sqlite3_stmt* statement);
void openDB(std::string name);
void createTables(std::string pathToURI);
void setUpTransactionTerminatingPhases();
void introduceNewTransactionToSystem(tlm::tlm_generic_payload& trans);
void removeTransactionFromDBAndInsertInDB(tlm::tlm_generic_payload& trans);
void commitRecordedDataToDB();
void insertGeneralInfo();
void insertTransactionInDB(RecordingData& recordingData);
void insertRangeInDB(unsigned int id, const sc_time& begin, const sc_time& end);
void insertPhaseInDB(string phaseName, const sc_time& begin, const sc_time& end, unsigned int transactionID);
void insertDebugMessageInDB(string message, const sc_time& time);
void printDebugMessage(std::string message);
static const int transactionCommitRate = 1000;
vector<RecordingData> recordedData;
map<tlm::tlm_generic_payload*, RecordingData> currentTransactionsInSystem;
unsigned int transactionIDCounter;
sc_time recordingEndTime;
std::vector<tlm::tlm_phase> transactionTerminatingPhases;
sqlite3 *db;
sqlite3_stmt *insertTransactionStatement, *insertRangeStatement, *updateRangeStatement,
*insertPhaseStatement, *updatePhaseStatement, *insertGeneralInfoStatement, *insertDebugMessageStatement, *updateDataStrobeStatement;
std::string insertTransactionString, insertRangeString, updateRangeString, insertPhaseString, updatePhaseString, insertGeneralInfoString,
insertDebugMessageString, updateDataStrobeString;
};
#endif

View File

@@ -8,168 +8,186 @@ using namespace std;
using namespace tinyxml2;
bool TimeInterval::timeIsInInterval(sc_time time)
{
return (start < time && time < end);
}
bool TimeInterval::intersects(TimeInterval other)
{
return other.timeIsInInterval(this->start) || this->timeIsInInterval(other.start);
}
sc_time getDistance(sc_time a, sc_time b)
{
if (a > b)
return a - b;
else
return b - a;
}
void reportFatal(std::string sender, std::string message)
{
SC_REPORT_FATAL(sender.c_str(), message.c_str());
SC_REPORT_FATAL(sender.c_str(), message.c_str());
}
std::string phaseNameToString(tlm::tlm_phase phase)
{
std::ostringstream oss;
oss << phase;
std::string str = oss.str();
return str;
std::ostringstream oss;
oss << phase;
std::string str = oss.str();
return str;
}
unsigned int queryUIntParameter(XMLElement* node, string name)
{
int result;
XMLElement* element;
for (element = node->FirstChildElement("parameter"); element != NULL;
element = element->NextSiblingElement("parameter"))
{
if (element->Attribute("id") == name)
{
sc_assert(!strcmp(element->Attribute("type"), "uint"));
XMLError error = element->QueryIntAttribute("value", &result);
sc_assert(!error);
return result;
}
}
int result;
XMLElement* element;
for (element = node->FirstChildElement("parameter"); element != NULL;
element = element->NextSiblingElement("parameter"))
{
if (element->Attribute("id") == name)
{
sc_assert(!strcmp(element->Attribute("type"), "uint"));
XMLError error = element->QueryIntAttribute("value", &result);
sc_assert(!error);
return result;
}
}
reportFatal("Query XML", "Parameter '" + name + "' does not exist.");
return 0;
reportFatal("Query XML", "Parameter '" + name + "' does not exist.");
return 0;
}
bool parameterExists(tinyxml2::XMLElement* node, std::string name)
{
XMLElement* element;
for (element = node->FirstChildElement("parameter"); element != NULL;
element = element->NextSiblingElement("parameter"))
{
if (element->Attribute("id") == name)
{
return true;
}
}
return false;
XMLElement* element;
for (element = node->FirstChildElement("parameter"); element != NULL;
element = element->NextSiblingElement("parameter"))
{
if (element->Attribute("id") == name)
{
return true;
}
}
return false;
}
double queryDoubleParameter(XMLElement* node, string name)
{
double result;
XMLElement* element;
for (element = node->FirstChildElement("parameter"); element != NULL;
element = element->NextSiblingElement("parameter"))
{
if (element->Attribute("id") == name)
{
sc_assert(!strcmp(element->Attribute("type"), "double"));
XMLError error = element->QueryDoubleAttribute("value", &result);
sc_assert(!error);
return result;
}
}
double result;
XMLElement* element;
for (element = node->FirstChildElement("parameter"); element != NULL;
element = element->NextSiblingElement("parameter"))
{
if (element->Attribute("id") == name)
{
sc_assert(!strcmp(element->Attribute("type"), "double"));
XMLError error = element->QueryDoubleAttribute("value", &result);
sc_assert(!error);
return result;
}
}
reportFatal("Query XML", "Parameter '" + name + "' does not exist.");
return 0;
reportFatal("Query XML", "Parameter '" + name + "' does not exist.");
return 0;
}
bool queryBoolParameter(XMLElement* node, string name)
{
bool result;
XMLElement* element;
for (element = node->FirstChildElement("parameter"); element != NULL;
element = element->NextSiblingElement("parameter"))
{
if (element->Attribute("id") == name)
{
sc_assert(!strcmp(element->Attribute("type"), "bool"));
XMLError error = element->QueryBoolAttribute("value", &result);
sc_assert(!error);
return result;
}
}
bool result;
XMLElement* element;
for (element = node->FirstChildElement("parameter"); element != NULL;
element = element->NextSiblingElement("parameter"))
{
if (element->Attribute("id") == name)
{
sc_assert(!strcmp(element->Attribute("type"), "bool"));
XMLError error = element->QueryBoolAttribute("value", &result);
sc_assert(!error);
return result;
}
}
reportFatal("Query XML", "Parameter '" + name + "' does not exist.");
return 0;
reportFatal("Query XML", "Parameter '" + name + "' does not exist.");
return 0;
}
string queryStringParameter(XMLElement* node, string name)
{
XMLElement* element;
for (element = node->FirstChildElement("parameter"); element != NULL;
element = element->NextSiblingElement("parameter"))
{
if (element->Attribute("id") == name)
{
return element->Attribute("value");
}
}
XMLElement* element;
for (element = node->FirstChildElement("parameter"); element != NULL;
element = element->NextSiblingElement("parameter"))
{
if (element->Attribute("id") == name)
{
return element->Attribute("value");
}
}
reportFatal("Query XML", "Parameter '" + name + "' does not exist.");
return 0;
reportFatal("Query XML", "Parameter '" + name + "' does not exist.");
return 0;
}
void loadXML(string uri, XMLDocument& doc)
{
XMLError error = doc.LoadFile(uri.c_str());
XMLError error = doc.LoadFile(uri.c_str());
if (error)
{
//TODO specify error
reportFatal("Configuration", "Error loading xml from: " + uri);
}
if (error)
{
//TODO specify error
reportFatal("Configuration", "Error loading xml from: " + uri);
}
}
string loadTextFileContents(string filename)
{
ifstream in(filename.c_str(), ios::in | ios::binary);
if (in)
{
string contents;
in.seekg(0, ios::end);
contents.resize(in.tellg());
in.seekg(0, ios::beg);
in.read(&contents[0], contents.size());
in.close();
return (contents);
}
else
{
reportFatal("Error loading file", "Could not load textfile from " + filename);
return "";
}
ifstream in(filename.c_str(), ios::in | ios::binary);
if (in)
{
string contents;
in.seekg(0, ios::end);
contents.resize(in.tellg());
in.seekg(0, ios::beg);
in.read(&contents[0], contents.size());
in.close();
return (contents);
}
else
{
reportFatal("Error loading file", "Could not load textfile from " + filename);
return "";
}
}
void setUpDummy(tlm::tlm_generic_payload& payload, Bank& bank)
{
payload.set_address(bank.getStartAddress());
payload.set_command(tlm::TLM_READ_COMMAND);
payload.set_data_length(0);
payload.set_response_status(tlm::TLM_OK_RESPONSE);
payload.set_dmi_allowed(false);
payload.set_byte_enable_length(0);
payload.set_streaming_width(0);
payload.set_extension(new DramExtension(Thread(0), bank, bank.getBankGroup(), Row(0), Column(0))); //payload takes ownership
payload.set_address(bank.getStartAddress());
payload.set_command(tlm::TLM_READ_COMMAND);
payload.set_data_length(0);
payload.set_response_status(tlm::TLM_OK_RESPONSE);
payload.set_dmi_allowed(false);
payload.set_byte_enable_length(0);
payload.set_streaming_width(0);
payload.set_extension(new DramExtension(Thread(0), bank, bank.getBankGroup(), Row(0), Column(0))); //payload takes ownership
}
std::string getFileName(std::string uri)
{
// Remove directory if present.
// Do this before extension removal incase directory has a period character.
const size_t last_slash_idx = uri.find_last_of("\\/");
if (std::string::npos != last_slash_idx)
{
uri.erase(0, last_slash_idx + 1);
}
// Remove directory if present.
// Do this before extension removal incase directory has a period character.
const size_t last_slash_idx = uri.find_last_of("\\/");
if (std::string::npos != last_slash_idx)
{
uri.erase(0, last_slash_idx + 1);
}
// Remove extension if present.
const size_t period_idx = uri.rfind('.');
if (std::string::npos != period_idx)
{
uri.erase(period_idx);
}
return uri;
// Remove extension if present.
const size_t period_idx = uri.rfind('.');
if (std::string::npos != period_idx)
{
uri.erase(period_idx);
}
return uri;
}

View File

@@ -17,7 +17,19 @@
#include "third_party/tinyxml2.h"
#include <iomanip>
constexpr const char headline[] = "=========================================================";
sc_time getDistance(sc_time a, sc_time b);
struct TimeInterval
{
sc_time start,end;
TimeInterval() : start(SC_ZERO_TIME), end(SC_ZERO_TIME){}
TimeInterval(sc_time start,sc_time end) : start(start), end(end){}
sc_time getLength() {return getDistance(start,end);}
bool timeIsInInterval(sc_time time);
bool intersects(TimeInterval other);
};
template<typename Key, typename Val>
inline Val getElementFromMap(const std::map<Key, Val>& m, Key key)
@@ -41,9 +53,11 @@ bool isIn(const T& value, const std::vector<T>& collection)
return false;
}
constexpr const char headline[] = "=========================================================";
static inline void loadbar(unsigned int x, unsigned int n, unsigned int w = 50, unsigned int granularity = 1)
{
if ((x != n) && (x % (n / 100 * granularity) != 0))
if ((n < 100) || ((x != n) && (x % (n / 100 * granularity) != 0)))
return;
float ratio = x / (float) n;

View File

@@ -161,7 +161,8 @@ const Column& DramExtension::getColumn() const
{
return column;
}
const unsigned int DramExtension::getBurstlength() const
unsigned int DramExtension::getBurstlength() const
{
return burstlength;
}

View File

@@ -15,113 +15,113 @@
class Thread
{
public:
explicit Thread(unsigned int id) :
id(id)
{
}
explicit Thread(unsigned int id) :
id(id)
{
}
unsigned int ID() const
{
return id;
}
unsigned int ID() const
{
return id;
}
private:
unsigned int id;
unsigned int id;
};
class Channel
{
public:
explicit Channel(unsigned int id) :
id(id)
{
}
unsigned int ID() const
{
return id;
}
explicit Channel(unsigned int id) :
id(id)
{
}
unsigned int ID() const
{
return id;
}
private:
unsigned int id;
unsigned int id;
};
class BankGroup
{
public:
explicit BankGroup(unsigned int id) :
id(id)
{
}
unsigned int ID() const
{
return id;
}
explicit BankGroup(unsigned int id) :
id(id)
{
}
unsigned int ID() const
{
return id;
}
private:
unsigned int id;
unsigned int id;
};
class Bank
{
public:
explicit Bank(unsigned int id) :
id(id)
{
}
unsigned int ID() const
{
return id;
}
explicit Bank(unsigned int id) :
id(id)
{
}
unsigned int ID() const
{
return id;
}
unsigned int getStartAddress()
{
return 0;
}
unsigned int getStartAddress()
{
return 0;
}
BankGroup getBankGroup();
BankGroup getBankGroup();
private:
unsigned int id;
unsigned int id;
};
class Row
{
public:
static const Row NO_ROW;
static const Row NO_ROW;
Row() :
id(0), isNoRow(true)
{
}
explicit Row(unsigned int id) :
id(id), isNoRow(false)
{
}
Row() :
id(0), isNoRow(true)
{
}
explicit Row(unsigned int id) :
id(id), isNoRow(false)
{
}
unsigned int ID() const
{
return id;
}
unsigned int ID() const
{
return id;
}
const Row operator++();
const Row operator++();
private:
unsigned int id;
bool isNoRow;
unsigned int id;
bool isNoRow;
friend bool operator==(const Row &lhs, const Row &rhs);
friend bool operator==(const Row &lhs, const Row &rhs);
};
class Column
{
public:
explicit Column(unsigned int id) :
id(id)
{
}
explicit Column(unsigned int id) :
id(id)
{
}
unsigned int ID() const
{
return id;
}
unsigned int ID() const
{
return id;
}
private:
unsigned int id;
unsigned int id;
};
bool operator==(const Thread &lhs, const Thread &rhs);
@@ -147,70 +147,70 @@ bool operator!=(const Column &lhs, const Column &rhs);
class DramExtension: public tlm::tlm_extension<DramExtension>
{
private:
Thread thread;
Channel channel;
Bank bank;
BankGroup bankgroup;
Row row;
Column column;
unsigned int burstlength;
Thread thread;
Channel channel;
Bank bank;
BankGroup bankgroup;
Row row;
Column column;
unsigned int burstlength;
public:
DramExtension() :
thread(0), channel(0), bank(0), bankgroup(0), row(0), column(0), burstlength(0)
{
}
DramExtension(const Thread& thread, const Bank& bank, const BankGroup& bankgroup, const Row& row, const Column& column,
unsigned int burstlength = 0) :
thread(thread), channel(0), bank(bank), bankgroup(bankgroup), row(row), column(column), burstlength(burstlength)
{
}
DramExtension(const Thread& thread, const Channel& channel, const Bank& bank, const BankGroup& bankgroup, const Row& row,
const Column& column, unsigned int burstlength = 0) :
thread(thread), channel(channel), bank(bank), bankgroup(bankgroup), row(row), column(column), burstlength(burstlength)
{
}
DramExtension() :
thread(0), channel(0), bank(0), bankgroup(0), row(0), column(0), burstlength(0)
{
}
DramExtension(const Thread& thread, const Bank& bank, const BankGroup& bankgroup, const Row& row, const Column& column,
unsigned int burstlength = 0) :
thread(thread), channel(0), bank(bank), bankgroup(bankgroup), row(row), column(column), burstlength(burstlength)
{
}
DramExtension(const Thread& thread, const Channel& channel, const Bank& bank, const BankGroup& bankgroup, const Row& row,
const Column& column, unsigned int burstlength = 0) :
thread(thread), channel(channel), bank(bank), bankgroup(bankgroup), row(row), column(column), burstlength(burstlength)
{
}
~DramExtension()
{
}
~DramExtension()
{
}
virtual tlm_extension_base* clone() const;
virtual void copy_from(const tlm_extension_base& ext);
virtual tlm_extension_base* clone() const;
virtual void copy_from(const tlm_extension_base& ext);
const Thread& getThread() const;
const Thread& getThread() const;
const Channel& getChannel() const;
const Channel& getChannel() const;
const Bank& getBank() const;
const Bank& getBank() const;
const BankGroup& getBankGroup() const;
const BankGroup& getBankGroup() const;
const Row& getRow() const;
const Row& getRow() const;
const Column& getColumn() const;
const Column& getColumn() const;
const unsigned int getBurstlength() const;
unsigned int getBurstlength() const;
void increaseRow();
void increaseRow();
static DramExtension& getExtension(const tlm::tlm_generic_payload *payload);
static DramExtension& getExtension(const tlm::tlm_generic_payload &payload);
static DramExtension& getExtension(const tlm::tlm_generic_payload *payload);
static DramExtension& getExtension(const tlm::tlm_generic_payload &payload);
};
class GenerationExtension : public tlm::tlm_extension<GenerationExtension>
{
public:
GenerationExtension(sc_time timeOfGeneration) : timeOfGeneration(timeOfGeneration) {}
virtual tlm_extension_base* clone() const;
virtual void copy_from(const tlm_extension_base& ext);
static GenerationExtension& getExtension(const tlm::tlm_generic_payload *payload);
GenerationExtension(sc_time timeOfGeneration) : timeOfGeneration(timeOfGeneration) {}
virtual tlm_extension_base* clone() const;
virtual void copy_from(const tlm_extension_base& ext);
static GenerationExtension& getExtension(const tlm::tlm_generic_payload *payload);
sc_time TimeOfGeneration() const {return timeOfGeneration;}
sc_time TimeOfGeneration() const {return timeOfGeneration;}
private:
sc_time timeOfGeneration;
sc_time timeOfGeneration;
};
#endif /* DRAMEXTENSION_H_ */