Merge pull request #18 from fzeder/master

Multiple TLM recorders based on the number of channels. It looks reasonable to me however I will test it :)
This commit is contained in:
Matthias Jung
2015-06-28 13:59:10 +02:00
21 changed files with 102 additions and 86 deletions

View File

@@ -33,31 +33,24 @@
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Eder F. Zulian
*/
#include <iostream>
#include <algorithm>
#include <boost/filesystem.hpp>
#include "TlmRecorder.h"
#include "protocol.h"
#include "dramExtension.h"
#include "xmlAddressdecoder.h"
#include "../controller/core/configuration/Configuration.h"
#include <iostream>
#include <algorithm>
#include <boost/filesystem.hpp>
using namespace std;
string TlmRecorder::dbName = "";
string TlmRecorder::sqlScriptURI = "";
string TlmRecorder::senderName = "TlmRecorder";
bool TlmRecorder::recordingEnabled = true;
// ------------- public -----------------------
TlmRecorder::TlmRecorder() :
totalNumTransactions(1), simulationTimeCoveredByRecording(SC_ZERO_TIME)
TlmRecorder::TlmRecorder(string uri, string dbname, bool recenable) : sqlScriptURI(uri), dbName(dbname), senderName("TlmRecorder"), recordingEnabled(recenable), totalNumTransactions(1), simulationTimeCoveredByRecording(SC_ZERO_TIME)
{
if(recordingEnabled)
{
if (TlmRecorder::recordingEnabled == true) {
recordedData.reserve(transactionCommitRate);
setUpTransactionTerminatingPhases();
openDB(TlmRecorder::dbName.c_str());

View File

@@ -33,6 +33,7 @@
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Eder F. Zulian
*/
#ifndef TLMPHASERECORDER_H
@@ -52,22 +53,17 @@
#include "DebugManager.h"
#include "Utils.h"
using namespace std;
class TlmRecorder
{
class TlmRecorder {
public:
static std::string sqlScriptURI;
static std::string dbName;
static std::string senderName;
static bool recordingEnabled;
std::string sqlScriptURI;
std::string dbName;
std::string senderName;
bool recordingEnabled;
static inline TlmRecorder& getInstance()
{
static TlmRecorder decoder;
return decoder;
}
TlmRecorder(string uri, string dbname, bool recenable);
~TlmRecorder();
void recordMemconfig(string memconfig){this->memconfig = memconfig;}
void recordMemspec(string memspec){this->memspec = memspec;}
@@ -106,9 +102,6 @@ private:
std::string memconfig,memspec,traces;
TlmRecorder();
~TlmRecorder();
void prepareSqlStatements();
void executeSqlCommand(std::string command);
void executeSqlStatement(sqlite3_stmt* statement);
@@ -143,4 +136,6 @@ private:
std::string insertTransactionString, insertRangeString, updateRangeString, insertPhaseString, updatePhaseString, insertGeneralInfoString,
insertDebugMessageString, updateDataStrobeString;
};
#endif

View File

@@ -32,6 +32,7 @@
* Authors:
* Robert Gernhardt
* Matthias Jung
* Eder F. Zulian
*/
#ifndef CONTROLLERWRAPPER_H_
@@ -74,9 +75,8 @@ template<unsigned int BUSWIDTH = 128>
struct Controller: public sc_module, public IController
{
public:
Controller(sc_module_name /*name*/) :
frontendPEQ(this, &Controller<BUSWIDTH>::frontendPEQCallback), dramPEQ(this, &Controller<BUSWIDTH>::dramPEQCallback), controllerCorePEQ(
this, &Controller<BUSWIDTH>::controllerCorePEQCallback), debugManager(DebugManager::getInstance())
Controller(sc_module_name /*name*/, TlmRecorder *rec) :
frontendPEQ(this, &Controller<BUSWIDTH>::frontendPEQCallback), dramPEQ(this, &Controller<BUSWIDTH>::dramPEQCallback), controllerCorePEQ(this, &Controller<BUSWIDTH>::controllerCorePEQCallback), debugManager(DebugManager::getInstance()), tlmRecorder(rec)
{
controllerCore = new ControllerCore(*this, numberOfPayloadsInSystem);
buildScheduler();
@@ -91,7 +91,6 @@ public:
delete scheduler;
}
void terminateSimulation();
// ------- CONTROLLER CORE ---------
virtual void send(const ScheduledCommand& command, tlm_generic_payload& payload) override;
@@ -137,6 +136,7 @@ private:
tlm_utils::peq_with_cb_and_phase<Controller> controllerCorePEQ;
DebugManager& debugManager;
TlmRecorder *tlmRecorder;
};
// --- IMPLEMENTATION -----
@@ -181,22 +181,22 @@ void Controller<BUSWIDTH>::send(const ScheduledCommand &command, tlm_generic_pay
//TODO: refactor tlm recorder
case Command::Read:
dataStrobe = command.getIntervalOnDataStrobe();
TlmRecorder::getInstance().updateDataStrobe(dataStrobe.start, dataStrobe.end, payload);
tlmRecorder->updateDataStrobe(dataStrobe.start, dataStrobe.end, payload);
controllerCorePEQ.notify(payload, BEGIN_RD, command.getStart() - sc_time_stamp());
break;
case Command::ReadA:
dataStrobe = command.getIntervalOnDataStrobe();
TlmRecorder::getInstance().updateDataStrobe(dataStrobe.start, dataStrobe.end, payload);
tlmRecorder->updateDataStrobe(dataStrobe.start, dataStrobe.end, payload);
controllerCorePEQ.notify(payload, BEGIN_RDA, command.getStart() - sc_time_stamp());
break;
case Command::Write:
dataStrobe = command.getIntervalOnDataStrobe();
TlmRecorder::getInstance().updateDataStrobe(dataStrobe.start, dataStrobe.end, payload);
tlmRecorder->updateDataStrobe(dataStrobe.start, dataStrobe.end, payload);
controllerCorePEQ.notify(payload, BEGIN_WR, command.getStart() - sc_time_stamp());
break;
case Command::WriteA:
dataStrobe = command.getIntervalOnDataStrobe();
TlmRecorder::getInstance().updateDataStrobe(dataStrobe.start, dataStrobe.end, payload);
tlmRecorder->updateDataStrobe(dataStrobe.start, dataStrobe.end, payload);
controllerCorePEQ.notify(payload, BEGIN_WRA, command.getStart() - sc_time_stamp());
break;
case Command::AutoRefresh:
@@ -352,13 +352,13 @@ tlm_sync_enum Controller<BUSWIDTH>::nb_transport_fw(tlm_generic_payload &payload
{
if (phase == BEGIN_REQ)
{
TlmRecorder::getInstance().recordPhase(payload, phase, fwDelay + sc_time_stamp());
tlmRecorder->recordPhase(payload, phase, fwDelay + sc_time_stamp());
frontendPEQ.notify(payload, phase,
clkAlign(sc_time_stamp() + fwDelay) - (sc_time_stamp() + fwDelay) + Configuration::getInstance().memSpec.clk);
}
else if (phase == END_RESP)
{
TlmRecorder::getInstance().recordPhase(payload, phase,
tlmRecorder->recordPhase(payload, phase,
fwDelay + sc_time_stamp() + Configuration::getInstance().memSpec.clk);
frontendPEQ.notify(payload, phase, clkAlign(sc_time_stamp() + fwDelay) - (sc_time_stamp() + fwDelay));
}
@@ -473,7 +473,7 @@ template<unsigned int BUSWIDTH>
tlm_sync_enum Controller<BUSWIDTH>::nb_transport_bw(tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay)
{
dramPEQ.notify(payload, phase, bwDelay);
TlmRecorder::getInstance().recordPhase(payload, phase, bwDelay + sc_time_stamp());
tlmRecorder->recordPhase(payload, phase, bwDelay + sc_time_stamp());
return TLM_ACCEPTED;
}
@@ -573,3 +573,4 @@ void Controller<BUSWIDTH>::terminateSimulation()
}
#endif /* CONTROLLERWRAPPER_H_ */

View File

@@ -38,6 +38,7 @@
#include <algorithm>
#include "core/TimingCalculation.h"
using namespace std;
const ScheduledCommand ControllerState::getLastCommand(Command command, Bank bank) //TODO const reference? and make const
{

View File

@@ -40,15 +40,16 @@
#include <tlm.h>
#include <map>
#include <utility>
#include <string>
#include "../IController.h"
#include "configuration/Configuration.h"
#include "powerdown/PowerDownManager.h"
#include "refresh/IRefreshManager.h"
#include "scheduling/checker/ICommandChecker.h"
#include "../../common/TlmRecorder.h"
#include "../RowBufferStates.h"
#include "../ControllerState.h"
using namespace std;
class ControllerCore
{

View File

@@ -93,3 +93,4 @@ private:
};
#endif /* CONFIGURATION_H_ */

View File

@@ -149,6 +149,5 @@ struct MemSpec
sc_time tDataStrobeHistory(){return tWTR_L;}
};
#endif /* MemSpec_H_ */

View File

@@ -37,6 +37,7 @@
#include "PowerDownManager.h"
#include "../ControllerCore.h"
#include "../../../common/Utils.h"
#include "../../../common/DebugManager.h"
#include "../TimingCalculation.h"
using namespace tlm;

View File

@@ -38,6 +38,7 @@
#include "PowerDownManagerTimeout.h"
#include "../ControllerCore.h"
#include "../../../common/Utils.h"
#include "../../../common/DebugManager.h"
#include "../TimingCalculation.h"
using namespace tlm;

View File

@@ -41,10 +41,8 @@
#include <tlm.h>
#include "../../Command.h"
#include "../../../common/dramExtension.h"
#include "../../../common/TlmRecorder.h"
#include "../../../common/Utils.h"
class ScheduledCommand
{
public:
@@ -88,7 +86,6 @@ public:
TimeInterval getIntervalOnDataStrobe() const;
private:
Command command;
sc_time start;
@@ -98,3 +95,4 @@ private:
};
#endif /* SCHEDULEDCOMMAND_H_ */

View File

@@ -34,6 +34,7 @@
* Matthias Jung
*/
#include <iostream>
#include <algorithm>
#include <set>
#include "ActivateChecker.h"
@@ -41,7 +42,8 @@
#include "../../../../common/DebugManager.h"
#include "../../../Command.h"
#include "../../../../common/Utils.h"
#include <iostream>
using namespace std;
void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
{

View File

@@ -39,6 +39,8 @@
#include "../../../../common/Utils.h"
#include "WriteChecker.h"
using namespace std;
void ReadChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
{
sc_assert(command.getCommand() == Command::Read || command.getCommand() == Command::ReadA);
@@ -132,4 +134,3 @@ sc_time ReadChecker::writeToRead(ScheduledCommand& write, ScheduledCommand& read
return config.tWL + getWriteAccessTime() + tWTR;
}

View File

@@ -41,7 +41,6 @@
#include "../../configuration/Configuration.h"
#include "../../../ControllerState.h"
class ReadChecker: public ICommandChecker
{
public:
@@ -62,5 +61,5 @@ private:
bool collidesWithStrobeCommand(ScheduledCommand& read, ScheduledCommand& strobeCommand) const;
};
#endif /* READCHECKER_H_ */

View File

@@ -39,6 +39,7 @@
#include "../../../../common/Utils.h"
#include "ReadChecker.h"
using namespace std;
void WriteChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
{

View File

@@ -81,6 +81,11 @@ public:
}
}
void setTlmRecorders(std::vector<TlmRecorder*> recorders)
{
tlmRecorders = recorders;
}
private:
tlm_utils::peq_with_cb_and_phase<Arbiter> payloadEventQueue;
@@ -93,11 +98,13 @@ private:
// This is a queue of responses comming from the memory side. The phase of these transactions is BEGIN_RESP.
vector<queue<tlm_generic_payload*>> receivedResponses;
std::vector<TlmRecorder*> tlmRecorders;
// Initiated by dram side
// This function is called when an arbiter's initiator socket receives a transaction from a memory controller
tlm_sync_enum nb_transport_bw(__attribute__((unused)) int id, tlm_generic_payload& payload, tlm_phase& phase, sc_time& bwDelay)
tlm_sync_enum nb_transport_bw(int channelId, tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay)
{
TlmRecorder::getInstance().recordPhase(payload, phase, bwDelay + sc_time_stamp());
tlmRecorders[channelId]->recordPhase(payload, phase, bwDelay + sc_time_stamp());
payloadEventQueue.notify(payload, phase, bwDelay);
return TLM_ACCEPTED;
}

View File

@@ -59,7 +59,7 @@ using namespace Data;
template<unsigned int BUSWIDTH = 128, unsigned int WORDS = 4096, bool STORE = true, bool FIXED_BL = false,
unsigned int FIXED_BL_VALUE = 0>
struct Dram: sc_module
struct Dram : sc_module
{
// TLM Related:
tlm_utils::simple_target_socket<Dram, BUSWIDTH, tlm::tlm_base_protocol_types> tSocket;
@@ -75,6 +75,8 @@ struct Dram: sc_module
// Data Storage:
map< unsigned long int, unsigned char[BUSWIDTH/2] > memory;
TlmRecorder *tlmRecorder;
SC_CTOR(Dram) : tSocket("socket")
{
tSocket.register_nb_transport_fw(this, &Dram::nb_transport_fw);
@@ -194,7 +196,7 @@ struct Dram: sc_module
virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& payload, tlm::tlm_phase& phase, sc_time& delay)
{
TlmRecorder::getInstance().recordPhase(payload, phase, sc_time_stamp() + delay);
tlmRecorder->recordPhase(payload, phase, sc_time_stamp() + delay);
// This is only needed for power simulation:
unsigned long long cycle = 0;
@@ -437,6 +439,10 @@ struct Dram: sc_module
DebugManager::getInstance().printDebugMessage(name(), message);
}
void setTlmRecorder(TlmRecorder *rec)
{
tlmRecorder = rec;
}
};
#endif /* DRAM_H_ */

View File

@@ -52,9 +52,7 @@
using namespace std;
Simulation::Simulation(sc_module_name __attribute__((unused)) name, string pathToResources, string traceName, DramSetup setup,
std::vector<Device> devices) :
traceName(traceName), dramSetup(setup)
std::vector<Device> devices) : traceName(traceName), dramSetup(setup)
{
SC_THREAD(stop);
@@ -65,8 +63,7 @@ Simulation::Simulation(sc_module_name __attribute__((unused)) name, string pathT
ConfigurationLoader::loadMemSpec(Configuration::getInstance(), setup.memspec);//pathToResources + string("configs/memspecs/") + setup.memspec);
ConfigurationLoader::loadSimConfig(Configuration::getInstance(), setup.simconfig);
setupTlmRecorder(traceName, pathToResources, devices);
instantiateModules(pathToResources, devices);
instantiateModules(traceName, pathToResources, devices);
bindSockets();
setupDebugManager(traceName);
}
@@ -81,15 +78,20 @@ void Simulation::setupDebugManager(const string& traceName)
dbg.openDebugFile(traceName + ".txt");
}
void Simulation::setupTlmRecorder(const string &traceName, const string &pathToResources, const std::vector<Device> &devices)
void Simulation::setupTlmRecorders(const string &traceName, const string &pathToResources, const std::vector<Device> &devices)
{
if(Configuration::getInstance().DatabaseRecording)
{
TlmRecorder::recordingEnabled = true;
TlmRecorder::dbName = traceName;
TlmRecorder::sqlScriptURI = pathToResources + string("scripts/createTraceDB.sql");
TlmRecorder::getInstance().recordMemconfig(Configuration::getInstance().memconfigUri);
TlmRecorder::getInstance().recordMemspec(Configuration::getInstance().memspecUri);
// Create TLM Recorders, one per channel.
for (size_t i = 0; i < Configuration::getInstance().NumberOfMemChannels; i++) {
std::string sqlScriptURI = pathToResources + string("scripts/createTraceDB.sql");
std::string dbName = traceName + string("_channel") + std::to_string(i) + ".tdb";
TlmRecorder *tlmRecorder = new TlmRecorder(sqlScriptURI.c_str(), dbName.c_str(), Configuration::getInstance().DatabaseRecording);
tlmRecorder->recordMemconfig(Configuration::getInstance().memconfigUri);
tlmRecorder->recordMemspec(Configuration::getInstance().memspecUri);
tlmRecorders.push_back(tlmRecorder);
std::string traceNames;
for (size_t i = 0; i < devices.size(); i++) {
traceNames.append(devices[i].trace);
@@ -97,15 +99,11 @@ void Simulation::setupTlmRecorder(const string &traceName, const string &pathToR
continue;
traceNames.append(",");
}
TlmRecorder::getInstance().recordTracenames(traceNames);
}
else
{
TlmRecorder::recordingEnabled = false;
tlmRecorder->recordTracenames(traceNames);
}
}
void Simulation::instantiateModules(const string &pathToResources, const std::vector<Device>& devices)
void Simulation::instantiateModules(const string &traceName, const string &pathToResources, const std::vector<Device> &devices)
{
for (size_t i = 0; i < Configuration::getInstance().NumberOfTracePlayers; i++) {
std::string playerStr = "player" + std::to_string(i);
@@ -113,15 +111,20 @@ void Simulation::instantiateModules(const string &pathToResources, const std::ve
players.push_back(player);
}
// Create and properly initialize TLM recorders. They need to be ready before creating some modules.
setupTlmRecorders(traceName, pathToResources, devices);
arbiter = new Arbiter<128>("arbiter");
arbiter->setTlmRecorders(tlmRecorders);
for (size_t i = 0; i < Configuration::getInstance().NumberOfMemChannels; i++) {
std::string str = "controller" + std::to_string(i);
Controller<> *controller = new Controller<>(str.c_str());
Controller<> *controller = new Controller<>(str.c_str(), tlmRecorders[i]);
controllers.push_back(controller);
str = "dram" + std::to_string(i);
Dram<> *dram = new Dram<>(str.c_str());
dram->setTlmRecorder(tlmRecorders[i]);
drams.push_back(dram);
}
}
@@ -153,6 +156,10 @@ Simulation::~Simulation()
for (auto dram : drams) {
delete dram;
}
for (auto rec : tlmRecorders) {
delete rec;
}
}
void Simulation::start()
@@ -189,7 +196,9 @@ void Simulation::stop()
controller->terminateSimulation();
}
wait(sc_time(200, SC_NS));
TlmRecorder::getInstance().closeConnection();
for (auto rec : tlmRecorders) {
rec->closeConnection();
}
sc_stop();
double elapsed_secs = double(clock() - simulationStartTime) / CLOCKS_PER_SEC;

View File

@@ -104,13 +104,16 @@ private:
ReorderBuffer<> *reorder;
// DRAM units
std::vector<Dram<>*> drams;
// Transaction Recorders (one per channel). They generate the output databases.
std::vector<TlmRecorder*> tlmRecorders;
clock_t simulationStartTime;
void report(std::string message);
void setupDebugManager(const string& traceName);
void setupTlmRecorder(const string &traceName, const string &pathToResources, const std::vector<Device> &devices);
void instantiateModules(const string &pathToResources, const std::vector<Device> &devices);
void setupTlmRecorders(const string &traceName, const string &pathToResources, const std::vector<Device> &devices);
void instantiateModules(const string &traceName, const string &pathToResources, const std::vector<Device> &devices);
void bindSockets();
void setupDebugManager(const string& traceName);
};
#endif /* SIMULATIONMANAGER_H_ */

View File

@@ -87,7 +87,7 @@ void SimulationManager::runSimulations()
{
for (auto& traceSetup : batch.traceSetups)
{
string exportname = exportPath + "/" + traceSetup.first + ".tdb";
string exportname = exportPath + "/" + traceSetup.first;
runSimulation(exportname, dramSetup, traceSetup.second);
}
}

View File

@@ -48,7 +48,6 @@
#include "../controller/core/configuration/Configuration.h"
#include "../common/DebugManager.h"
#include "../common/xmlAddressdecoder.h"
#include "../common/TlmRecorder.h"
#include "../common/dramExtension.h"
#include "../controller/core/TimingCalculation.h"
#include "TracePlayerListener.h"
@@ -81,8 +80,6 @@ private:
TracePlayerListener* listener;
};
template<unsigned int BUSWIDTH>
TracePlayer<BUSWIDTH>::TracePlayer(TracePlayerListener* listener) :
payloadEventQueue(this, &TracePlayer<BUSWIDTH>::peqCallback), transactionsSent(0), listener(listener)
@@ -90,7 +87,6 @@ TracePlayer<BUSWIDTH>::TracePlayer(TracePlayerListener* listener) :
iSocket.register_nb_transport_bw(this, &TracePlayer<BUSWIDTH>::nb_transport_bw);
}
template<unsigned int BUSWIDTH>
gp *TracePlayer<BUSWIDTH>::allocatePayload()
{

View File

@@ -322,9 +322,10 @@ Below are listed the configuration sections and configuration fields.
- **Trace setups**
- *id* (string)
- Trace setup id. Two files are generated by DRAMSys: an SQLite database
file (.tdb) and a text file (.txt) containing the program output. The
name of these files comes from this field.
- Trace setup id. Two kinds of output files are generated by DRAMSys:
SQLite databases containing transactions related to each memory channel
(.tdb) and a text file (.txt) with the program output. The base name for
these files comes from this field.
- *clkMhz* (unsigned int)
- Speed of the trace player
- *bl* (unsigned int)