...
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user