Merge branch 'work/tracegenerator' into 'develop'

Implement a more advanced TraceGenerator (2).

See merge request ems/astdm/dram.sys!284
This commit is contained in:
Lukas Steiner
2021-05-27 08:28:07 +00:00
13 changed files with 537 additions and 270 deletions

View File

@@ -0,0 +1,34 @@
{
"simulation": {
"addressmapping": "am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json",
"mcconfig": "fr_fcfs.json",
"memspec": "JEDEC_2x8x2Gbx4_DDR5-3200A.json",
"simconfig": "ddr5.json",
"simulationid": "ddr5-example",
"thermalconfig": "config.json",
"tracesetup": [
{
"clkMhz": 2000,
"type": "generator",
"name": "gen0",
"numRequests": 2000,
"rwRatio": 0.85,
"addressDistribution": "sequential",
"addressIncrement": 256,
"maxPendingReadRequests": 8,
"maxPendingWriteRequests": 8
},
{
"clkMhz": 2000,
"type": "generator",
"name": "gen1",
"numRequests": 2000,
"rwRatio": 0.85,
"addressDistribution": "random",
"seed": 123456,
"maxPendingReadRequests": 8,
"maxPendingWriteRequests": 8
}
]
}
}

View File

@@ -31,6 +31,7 @@
# Authors:
# Matthias Jung
# Lukas Steiner
# Derek Christ
cmake_minimum_required(VERSION 3.10)
@@ -48,8 +49,8 @@ add_executable(DRAMSys
ExampleInitiator.h
MemoryManager.cpp
StlPlayer.cpp
TraceGenerator.cpp
TracePlayer.cpp
TrafficGenerator.cpp
TrafficInitiator.cpp
TraceSetup.cpp
)

View File

@@ -35,29 +35,43 @@
* Matthias Jung
* Éder F. Zulian
* Felipe S. Prado
* Derek Christ
*/
#include "StlPlayer.h"
using namespace tlm;
StlPlayer::StlPlayer(sc_module_name name,
std::string pathToTrace,
sc_time playerClk,
StlPlayer::StlPlayer(const sc_module_name &name,
const std::string &pathToTrace,
const sc_time &playerClk,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
TraceSetup *setup,
bool relative)
: TracePlayer(name, setup), file(pathToTrace),
currentBuffer(&lineContents[0]),
parseBuffer(&lineContents[1]),
relative(relative)
bool relative) :
TrafficInitiator(name, setup, maxPendingReadRequests, maxPendingWriteRequests),
file(pathToTrace), currentBuffer(&lineContents[0]), parseBuffer(&lineContents[1]),
relative(relative), playerClk(playerClk)
{
if (!file.is_open())
SC_REPORT_FATAL("StlPlayer", (std::string("Could not open trace ") + pathToTrace).c_str());
else
{
std::string line;
while (std::getline(file, line))
{
if (line.size() > 1 && line[0] != '#')
numberOfLines++;
}
file.clear();
file.seekg(0);
if (numberOfLines == 0)
SC_REPORT_FATAL("StlPlayer", "Trace file is empty");
}
this->playerClk = playerClk;
burstLength = Configuration::getInstance().memSpec->burstLength;
dataLength = Configuration::getInstance().memSpec->bytesPerBurst;
lineCnt = 0;
currentBuffer->reserve(lineBufferSize);
parseBuffer->reserve(lineBufferSize);
@@ -72,7 +86,7 @@ StlPlayer::~StlPlayer()
parserThread.join();
}
void StlPlayer::nextPayload()
void StlPlayer::sendNextPayload()
{
if (lineIterator == currentBuffer->cend())
{
@@ -85,8 +99,6 @@ void StlPlayer::nextPayload()
}
}
numberOfTransactions++;
// Allocate a generic payload for this request.
tlm_generic_payload *payload = setup->allocatePayload();
payload->acquire();
@@ -104,7 +116,7 @@ void StlPlayer::nextPayload()
sc_time sendingTime;
sc_time sendingOffset;
if (numberOfTransactions == 1)
if (transactionsSent == 0)
sendingOffset = SC_ZERO_TIME;
else
sendingOffset = playerClk - (sc_time_stamp() % playerClk);
@@ -117,6 +129,12 @@ void StlPlayer::nextPayload()
sendToTarget(*payload, BEGIN_REQ, sendingTime - sc_time_stamp());
transactionsSent++;
if (payload->get_command() == tlm::TLM_READ_COMMAND)
pendingReadRequests++;
else if (payload->get_command() == tlm::TLM_WRITE_COMMAND)
pendingWriteRequests++;
PRINTDEBUGMESSAGE(name(), "Performing request #" + std::to_string(transactionsSent));
lineIterator++;
}
@@ -128,6 +146,7 @@ void StlPlayer::parseTraceFile()
while (file && !file.eof() && parsedLines < lineBufferSize)
{
// Get a new line from the input file.
std::string line;
std::getline(file, line);
lineCnt++;
@@ -142,12 +161,9 @@ void StlPlayer::parseTraceFile()
// Trace files MUST provide timestamp, command and address for every
// transaction. The data information depends on the storage mode
// configuration.
time.clear();
command.clear();
address.clear();
dataStr.clear();
std::string time, command, address, dataStr;
std::istringstream iss;
iss.clear();
iss.str(line);
// Get the timestamp for the transaction.
@@ -156,7 +172,7 @@ void StlPlayer::parseTraceFile()
SC_REPORT_FATAL("StlPlayer",
("Malformed trace file. Timestamp could not be found (line " + std::to_string(
lineCnt) + ").").c_str());
content.sendingTime = std::stoull(time.c_str()) * playerClk;
content.sendingTime = std::stoull(time) * playerClk;
// Get the command.
iss >> command;
@@ -180,7 +196,7 @@ void StlPlayer::parseTraceFile()
SC_REPORT_FATAL("StlPlayer",
("Malformed trace file. Address could not be found (line "
+ std::to_string(lineCnt) + ").").c_str());
content.addr = std::stoull(address.c_str(), nullptr, 16);
content.addr = std::stoull(address, nullptr, 16);
// Get the data if necessary.
if (storageEnabled && content.cmd == TLM_WRITE_COMMAND)
@@ -202,7 +218,7 @@ void StlPlayer::parseTraceFile()
// Set data
for (unsigned i = 0; i < dataLength; i++)
content.data.emplace_back(static_cast<unsigned char>
(std::stoi(dataStr.substr(i * 2 + 2, 2).c_str(), nullptr, 16)));
(std::stoi(dataStr.substr(i * 2 + 2, 2), nullptr, 16)));
}
}
}
@@ -221,3 +237,8 @@ std::vector<LineContent>::const_iterator StlPlayer::swapBuffers()
return currentBuffer->cbegin();
}
uint64_t StlPlayer::getNumberOfLines() const
{
return numberOfLines;
}

View File

@@ -35,6 +35,7 @@
* Matthias Jung
* Éder F. Zulian
* Felipe S. Prado
* Derek Christ
*/
#ifndef STLPLAYER_H
@@ -45,7 +46,7 @@
#include <array>
#include <thread>
#include "TraceSetup.h"
#include "TracePlayer.h"
#include "TrafficInitiator.h"
struct LineContent
{
@@ -55,29 +56,30 @@ struct LineContent
std::vector<unsigned char> data;
};
class StlPlayer : public TracePlayer
class StlPlayer : public TrafficInitiator
{
public:
StlPlayer(sc_module_name name,
std::string pathToTrace,
sc_time playerClk,
StlPlayer(const sc_module_name &name,
const std::string &pathToTrace,
const sc_time &playerClk,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
TraceSetup *setup,
bool relative);
virtual ~StlPlayer() override;
virtual void nextPayload() override;
~StlPlayer() override;
void sendNextPayload() override;
uint64_t getNumberOfLines() const;
private:
void parseTraceFile();
std::vector<LineContent>::const_iterator swapBuffers();
std::ifstream file;
uint64_t lineCnt;
uint64_t lineCnt = 0;
uint64_t numberOfLines = 0;
unsigned int burstLength;
unsigned int dataLength;
sc_time playerClk; // May be different from the memory clock!
const sc_time playerClk; // May be different from the memory clock!
static constexpr unsigned lineBufferSize = 10000;
@@ -88,14 +90,6 @@ private:
std::thread parserThread;
std::string time;
std::string command;
std::string address;
std::string dataStr;
std::string line;
std::istringstream iss;
const bool relative;
};

View File

@@ -1,76 +0,0 @@
/*
* Copyright (c) 2015, Technische Universität Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#include "TraceGenerator.h"
TraceGenerator::TraceGenerator(sc_module_name name,
unsigned int fCKMhz, TraceSetup *setup)
: TracePlayer(name, setup), transCounter(0)
{
if (fCKMhz == 0)
tCK = Configuration::getInstance().memSpec->tCK;
else
tCK = sc_time(1.0 / fCKMhz, SC_US);
burstlenght = Configuration::getInstance().memSpec->burstLength;
}
void TraceGenerator::nextPayload()
{
if (transCounter >= 1000) // TODO set limit!
terminate();
tlm::tlm_generic_payload *payload = setup->allocatePayload();
payload->acquire();
unsigned char *dataElement = new unsigned char[16];
// TODO: column / burst breite
payload->set_address(0x0);
payload->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
payload->set_dmi_allowed(false);
payload->set_byte_enable_length(0);
payload->set_streaming_width(burstlenght);
payload->set_data_ptr(dataElement);
payload->set_data_length(16);
payload->set_command(tlm::TLM_READ_COMMAND);
transCounter++;
// TODO: do not send two requests in the same cycle
sendToTarget(*payload, tlm::BEGIN_REQ, SC_ZERO_TIME);
transactionsSent++;
PRINTDEBUGMESSAGE(name(), "Performing request #" + std::to_string(transactionsSent));
}

View File

@@ -1,57 +0,0 @@
/*
* Copyright (c) 2015, Technische Universität Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
*/
#ifndef TRACEGENERATOR_H
#define TRACEGENERATOR_H
#include "TracePlayer.h"
#include "TraceSetup.h"
class TraceGenerator : public TracePlayer
{
public:
TraceGenerator(sc_module_name name, unsigned int fCKMhz, TraceSetup *setup);
virtual void nextPayload() override;
private:
unsigned int burstlenght;
sc_time tCK;
unsigned int transCounter;
};
#endif // TRACEGENERATOR_H

View File

@@ -32,16 +32,18 @@
* Authors:
* Matthias Jung
* Luiza Correa
* Derek Christ
*/
#include "TraceSetup.h"
#include "StlPlayer.h"
#include "TrafficGenerator.h"
using namespace tlm;
TraceSetup::TraceSetup(std::string uri,
std::string pathToResources,
std::vector<TracePlayer *> *players)
TraceSetup::TraceSetup(const std::string &uri,
const std::string &pathToResources,
std::vector<TrafficInitiator *> &players)
{
// Load Simulation:
nlohmann::json simulationdoc = parseJSON(uri);
@@ -50,62 +52,139 @@ TraceSetup::TraceSetup(std::string uri,
SC_REPORT_FATAL("TraceSetup",
"Cannot load simulation: simulation node expected");
// Load TracePlayers:
// Load TrafficInitiators:
if (simulationdoc["simulation"]["tracesetup"].empty())
SC_REPORT_FATAL("TraceSetup", "tracesetup is empty");
for (auto it : simulationdoc["simulation"]["tracesetup"].items())
for (auto &it : simulationdoc["simulation"]["tracesetup"].items())
{
auto value = it.value();
if (!value.empty())
{
sc_time playerClk;
if (!value["clkMhz"].is_number_unsigned())
SC_REPORT_FATAL("TraceSetup", "Frequency is not a number.");
unsigned int frequencyMHz = value["clkMhz"];
if (frequencyMHz == 0)
SC_REPORT_FATAL("TraceSetup", "No frequency defined");
SC_REPORT_FATAL("TraceSetup", "Frequency must not be zero.");
else
playerClk = sc_time(1.0 / frequencyMHz, SC_US);
if (!value["name"].is_string())
SC_REPORT_FATAL("TraceSetup", "No trace name defined.");
std::string name = value["name"];
size_t pos = name.rfind('.');
if (pos == std::string::npos)
throw std::runtime_error("Name of the trace file does not contain a valid extension.");
unsigned int maxPendingReadRequests = 0;
unsigned int maxPendingWriteRequests = 0;
// Get the extension and make it lower case
std::string ext = name.substr(pos + 1);
std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
if (value["maxPendingReadRequests"].is_number_unsigned())
maxPendingReadRequests = value["maxPendingReadRequests"];
std::string stlFile = pathToResources + std::string("traces/") + name;
std::string moduleName = name;
if (value["maxPendingWriteRequests"].is_number_unsigned())
maxPendingWriteRequests = value["maxPendingWriteRequests"];
// replace all '.' to '_'
std::replace(moduleName.begin(), moduleName.end(), '.', '_');
std::string type;
TracePlayer *player;
if (ext == "stl")
player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, this, false);
else if (ext == "rstl")
player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, this, true);
// Defaulting to type "player" when not specified
if (!value["type"].is_string())
type = "player";
else
throw std::runtime_error("Unsupported file extension in " + name);
type = value["type"];
players->push_back(player);
if (type == "player")
{
size_t pos = name.rfind('.');
if (pos == std::string::npos)
throw std::runtime_error("Name of the trace file does not contain a valid extension.");
if (Configuration::getInstance().simulationProgressBar)
totalTransactions += player->getNumberOfLines(stlFile);
// Get the extension and make it lower case
std::string ext = name.substr(pos + 1);
std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
std::stringstream stlFileStream;
stlFileStream << pathToResources << "traces/" << name;
std::string stlFile = stlFileStream.str();
std::string moduleName = name;
// replace all '.' to '_'
std::replace(moduleName.begin(), moduleName.end(), '.', '_');
StlPlayer *player;
if (ext == "stl")
player = new StlPlayer(moduleName.c_str(), stlFile, playerClk,
maxPendingReadRequests, maxPendingWriteRequests, this, false);
else if (ext == "rstl")
player = new StlPlayer(moduleName.c_str(), stlFile, playerClk,
maxPendingReadRequests, maxPendingWriteRequests, this, true);
else
throw std::runtime_error("Unsupported file extension in " + name);
players.push_back(player);
totalTransactions += player->getNumberOfLines();
}
else if (type == "generator")
{
if (!value["numRequests"].is_number_unsigned())
SC_REPORT_FATAL("TraceSetup", "Number of requests is not a number.");
uint64_t numRequests = value["numRequests"];
if (!value["rwRatio"].is_number_float())
SC_REPORT_FATAL("TraceSetup", "Read/Write ratio is not a floating point number.");
float rwRatio = value["rwRatio"];
if (!value["addressDistribution"].is_string())
SC_REPORT_FATAL("TraceSetup", "Address distribution not defined.");
std::string addressDistribution = value["addressDistribution"];
if (addressDistribution != "sequential" && addressDistribution != "random")
SC_REPORT_FATAL("TraceSetup", "Address distribution must either be sequential or random.");
unsigned int seed = 0;
if (value["seed"].is_number_unsigned())
seed = value["seed"];
TrafficGenerator *generator;
if (addressDistribution == "sequential")
{
uint64_t addressIncrement = 0x0;
if (!value["addressIncrement"].is_number_unsigned())
SC_REPORT_FATAL("TraceSetup", "Address increment is not a number.");
addressIncrement = value["addressIncrement"];
generator = new TrafficGeneratorSequential(name.c_str(), playerClk, numRequests,
maxPendingReadRequests, maxPendingWriteRequests,
rwRatio, addressIncrement, seed, this);
}
else
{
generator = new TrafficGeneratorRandom(name.c_str(), playerClk, numRequests,
maxPendingReadRequests, maxPendingWriteRequests,
rwRatio, seed, this);
}
players.push_back(generator);
totalTransactions += numRequests;
}
}
}
remainingTransactions = totalTransactions;
numberOfTracePlayers = players->size();
numberOfTrafficInitiators = players.size();
}
void TraceSetup::tracePlayerTerminates()
void TraceSetup::trafficInitiatorTerminates()
{
finishedTracePlayers++;
finishedTrafficInitiators++;
if (finishedTracePlayers == numberOfTracePlayers)
if (finishedTrafficInitiators == numberOfTrafficInitiators)
sc_stop();
}
@@ -113,7 +192,7 @@ void TraceSetup::transactionFinished()
{
remainingTransactions--;
loadbar(totalTransactions - remainingTransactions, totalTransactions);
loadBar(totalTransactions - remainingTransactions, totalTransactions);
if (remainingTransactions == 0)
std::cout << std::endl;
@@ -124,7 +203,7 @@ tlm_generic_payload *TraceSetup::allocatePayload()
return memoryManager.allocate();
}
void TraceSetup::loadbar(uint64_t x, uint64_t n, unsigned int w, unsigned int granularity)
void TraceSetup::loadBar(uint64_t x, uint64_t n, unsigned int w, unsigned int granularity)
{
if ((n < 100) || ((x != n) && (x % (n / 100 * granularity) != 0)))
return;

View File

@@ -31,6 +31,7 @@
*
* Authors:
* Matthias Jung
* Derek Christ
*/
#ifndef TRACESETUP_H
@@ -41,27 +42,27 @@
#include <tlm.h>
#include "MemoryManager.h"
class TracePlayer;
class TrafficInitiator;
class TraceSetup
{
public:
TraceSetup(std::string uri,
std::string pathToResources,
std::vector<TracePlayer *> *devices);
TraceSetup(const std::string &uri,
const std::string &pathToResources,
std::vector<TrafficInitiator *> &devices);
void tracePlayerTerminates();
void trafficInitiatorTerminates();
void transactionFinished();
tlm::tlm_generic_payload *allocatePayload();
private:
unsigned int numberOfTracePlayers;
unsigned int numberOfTrafficInitiators;
uint64_t totalTransactions = 0;
uint64_t remainingTransactions;
unsigned int finishedTracePlayers = 0;
unsigned int finishedTrafficInitiators = 0;
MemoryManager memoryManager;
void loadbar(uint64_t x, uint64_t n, unsigned int w = 50, unsigned int granularity = 1);
static void loadBar(uint64_t x, uint64_t n, unsigned int w = 50, unsigned int granularity = 1);
};
#endif // TRACESETUP_H

View File

@@ -0,0 +1,146 @@
/*
* Copyright (c) 2015, Technische Universität Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
*/
#include "TrafficGenerator.h"
TrafficGenerator::TrafficGenerator(const sc_module_name &name,
const sc_time &generatorClk,
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
float rwRatio,
unsigned int seed,
TraceSetup *setup) :
TrafficInitiator(name, setup, maxPendingReadRequests, maxPendingWriteRequests),
generatorClk(generatorClk), numRequests(numRequests), rwRatio(rwRatio)
{
burstLength = Configuration::getInstance().memSpec->burstLength;
dataLength = Configuration::getInstance().memSpec->bytesPerBurst;
randomGenerator = std::default_random_engine(seed);
}
void TrafficGenerator::sendNextPayload()
{
if (transactionsSent >= numRequests)
{
finished = true;
return;
}
tlm::tlm_generic_payload *payload = setup->allocatePayload();
payload->acquire();
// TODO: column / burst breite
uint64_t address = getNextAddress();
tlm::tlm_command command;
if (randomRwDistribution(randomGenerator) < rwRatio)
{
command = tlm::TLM_READ_COMMAND;
pendingReadRequests++;
}
else
{
command = tlm::TLM_WRITE_COMMAND;
pendingWriteRequests++;
}
payload->set_address(address);
payload->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
payload->set_dmi_allowed(false);
payload->set_byte_enable_length(0);
payload->set_streaming_width(burstLength);
payload->set_data_length(dataLength);
payload->set_command(command);
sc_time sendingOffset;
if (transactionsSent == 0)
sendingOffset = SC_ZERO_TIME;
else
sendingOffset = generatorClk - (sc_time_stamp() % generatorClk);
// TODO: do not send two requests in the same cycle
sendToTarget(*payload, tlm::BEGIN_REQ, sendingOffset);
transactionsSent++;
PRINTDEBUGMESSAGE(name(), "Performing request #" + std::to_string(transactionsSent));
}
TrafficGeneratorRandom::TrafficGeneratorRandom(const sc_core::sc_module_name &name,
const sc_core::sc_time &generatorClk,
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
float rwRatio,
unsigned int seed,
TraceSetup *setup) :
TrafficGenerator(name, generatorClk, numRequests, maxPendingReadRequests,
maxPendingWriteRequests, rwRatio, seed, setup)
{
randomAddressDistribution = std::uniform_int_distribution<uint64_t>
(0, Configuration::getInstance().memSpec->getSimMemSizeInBytes());
}
uint64_t TrafficGeneratorRandom::getNextAddress()
{
return randomAddressDistribution(randomGenerator);
}
TrafficGeneratorSequential::TrafficGeneratorSequential(const sc_core::sc_module_name &name,
const sc_core::sc_time &generatorClk,
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
float rwRatio,
uint64_t addressIncrement,
unsigned int seed,
TraceSetup *setup) :
TrafficGenerator(name, generatorClk, numRequests, maxPendingReadRequests,
maxPendingWriteRequests, rwRatio, seed, setup),
addressIncrement(addressIncrement)
{
}
uint64_t TrafficGeneratorSequential::getNextAddress()
{
uint64_t address = currentAddress;
currentAddress += addressIncrement;
return address;
}

View File

@@ -0,0 +1,111 @@
/*
* Copyright (c) 2015, Technische Universität Kaiserslautern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors:
* Janik Schlemminger
* Robert Gernhardt
* Matthias Jung
* Derek Christ
*/
#ifndef TRAFFICGENERATOR_H
#define TRAFFICGENERATOR_H
#include "TrafficInitiator.h"
#include "TraceSetup.h"
#include <random>
class TrafficGenerator : public TrafficInitiator
{
protected:
TrafficGenerator(const sc_module_name &name,
const sc_time &generatorClk,
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
float rwRatio,
unsigned int seed,
TraceSetup *setup);
void sendNextPayload() override;
virtual uint64_t getNextAddress() = 0;
std::default_random_engine randomGenerator;
private:
sc_time generatorClk;
uint64_t numRequests;
float rwRatio;
std::uniform_real_distribution<float> randomRwDistribution
= std::uniform_real_distribution<float>(0.0f, 1.0f);
};
class TrafficGeneratorRandom final : public TrafficGenerator
{
public:
TrafficGeneratorRandom(const sc_module_name &name,
const sc_time &generatorClk,
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
float rwRatio,
unsigned int seed,
TraceSetup *setup);
private:
uint64_t getNextAddress() override;
std::uniform_int_distribution<uint64_t> randomAddressDistribution;
};
class TrafficGeneratorSequential final : public TrafficGenerator
{
public:
TrafficGeneratorSequential(const sc_module_name &name,
const sc_time &generatorClk,
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
float rwRatio,
uint64_t addressIncrement,
unsigned int seed,
TraceSetup *setup);
private:
uint64_t getNextAddress() override;
uint64_t currentAddress = 0x0;
uint64_t addressIncrement;
};
#endif // TRAFFICGENERATOR_H

View File

@@ -34,20 +34,22 @@
* Matthias Jung
* Éder F. Zulian
* Felipe S. Prado
* Derek Christ
*/
#include "TracePlayer.h"
#include "TrafficInitiator.h"
#include "TraceSetup.h"
using namespace tlm;
TracePlayer::TracePlayer(sc_module_name name, TraceSetup *setup) :
sc_module(name),
payloadEventQueue(this, &TracePlayer::peqCallback),
setup(setup)
TrafficInitiator::TrafficInitiator(const sc_module_name &name, TraceSetup *setup,
unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests) :
sc_module(name), payloadEventQueue(this, &TrafficInitiator::peqCallback),
setup(setup),
maxPendingReadRequests(maxPendingReadRequests), maxPendingWriteRequests(maxPendingWriteRequests)
{
SC_METHOD(nextPayload);
iSocket.register_nb_transport_bw(this, &TracePlayer::nb_transport_bw);
SC_METHOD(sendNextPayload);
iSocket.register_nb_transport_bw(this, &TrafficInitiator::nb_transport_bw);
if (Configuration::getInstance().storeMode == Configuration::StoreMode::NoStorage)
storageEnabled = false;
@@ -55,24 +57,29 @@ TracePlayer::TracePlayer(sc_module_name name, TraceSetup *setup) :
storageEnabled = true;
}
void TracePlayer::terminate()
void TrafficInitiator::terminate()
{
std::cout << sc_time_stamp() << " " << this->name() << " terminated " << std::endl;
setup->tracePlayerTerminates();
setup->trafficInitiatorTerminates();
}
tlm_sync_enum TracePlayer::nb_transport_bw(tlm_generic_payload &payload,
tlm_sync_enum TrafficInitiator::nb_transport_bw(tlm_generic_payload &payload,
tlm_phase &phase, sc_time &bwDelay)
{
payloadEventQueue.notify(payload, phase, bwDelay);
return TLM_ACCEPTED;
}
void TracePlayer::peqCallback(tlm_generic_payload &payload,
void TrafficInitiator::peqCallback(tlm_generic_payload &payload,
const tlm_phase &phase)
{
if (phase == END_REQ)
nextPayload();
{
if (nextPayloadSendable())
sendNextPayload();
else
payloadPostponed = true;
}
else if (phase == BEGIN_RESP)
{
payload.release();
@@ -82,46 +89,42 @@ void TracePlayer::peqCallback(tlm_generic_payload &payload,
transactionsReceived++;
if (payload.get_command() == tlm::TLM_READ_COMMAND)
pendingReadRequests--;
else if (payload.get_command() == tlm::TLM_WRITE_COMMAND)
pendingWriteRequests--;
// If the initiator wasn't able to send the next payload in the END_REQ phase, do it now.
if (payloadPostponed && nextPayloadSendable())
{
sendNextPayload();
payloadPostponed = false;
}
// If all answers were received:
if (finished == true && numberOfTransactions == transactionsReceived)
if (finished && transactionsSent == transactionsReceived)
terminate();
}
else
{
SC_REPORT_FATAL("TracePlayer", "PEQ was triggered with unknown phase");
SC_REPORT_FATAL("TrafficInitiator", "PEQ was triggered with unknown phase");
}
}
void TracePlayer::sendToTarget(tlm_generic_payload &payload, const tlm_phase &phase, const sc_time &delay)
void TrafficInitiator::sendToTarget(tlm_generic_payload &payload, const tlm_phase &phase, const sc_time &delay)
{
tlm_phase TPhase = phase;
sc_time TDelay = delay;
iSocket->nb_transport_fw(payload, TPhase, TDelay);
}
uint64_t TracePlayer::getNumberOfLines(std::string pathToTrace)
bool TrafficInitiator::nextPayloadSendable() const
{
std::ifstream file;
file.open(pathToTrace);
if (file.is_open())
{
uint64_t lineCount = 0;
std::string line;
while (std::getline(file, line))
{
if (line.size() > 1 && line[0] != '#')
lineCount++;
}
file.close();
if (lineCount == 0)
SC_REPORT_FATAL("TracePlayer", "Trace file is empty");
return lineCount;
}
// If either the maxPendingReadRequests or maxPendingWriteRequests
// limit is reached, do not send next payload.
if (((pendingReadRequests >= maxPendingReadRequests) && (maxPendingReadRequests != 0))
|| ((pendingWriteRequests >= maxPendingWriteRequests) && (maxPendingWriteRequests != 0)))
return false;
else
{
SC_REPORT_FATAL("TracePlayer", "Unable to open trace file");
return 0;
}
return true;
}

View File

@@ -34,10 +34,11 @@
* Matthias Jung
* Éder F. Zulian
* Felipe S. Prado
* Derek Christ
*/
#ifndef TRACEPLAYER_H
#define TRACEPLAYER_H
#ifndef TRAFFICINITIATOR_H
#define TRAFFICINITIATOR_H
#include <deque>
#include <tlm.h>
@@ -50,31 +51,40 @@
#include "common/DebugManager.h"
#include "TraceSetup.h"
class TracePlayer : public sc_module
class TrafficInitiator : public sc_module
{
public:
tlm_utils::simple_initiator_socket<TracePlayer> iSocket;
TracePlayer(sc_module_name name, TraceSetup *setup);
SC_HAS_PROCESS(TracePlayer);
virtual void nextPayload() = 0;
uint64_t getNumberOfLines(std::string pathToTrace);
tlm_utils::simple_initiator_socket<TrafficInitiator> iSocket;
TrafficInitiator(const sc_module_name &name, TraceSetup *setup,
unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests);
SC_HAS_PROCESS(TrafficInitiator);
virtual void sendNextPayload() = 0;
protected:
tlm_utils::peq_with_cb_and_phase<TracePlayer> payloadEventQueue;
tlm_utils::peq_with_cb_and_phase<TrafficInitiator> payloadEventQueue;
void terminate();
bool storageEnabled = false;
TraceSetup *setup;
void sendToTarget(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase,
const sc_time &delay);
uint64_t numberOfTransactions = 0;
uint64_t transactionsReceived = 0;
uint64_t transactionsSent = 0;
unsigned int pendingReadRequests = 0;
unsigned int pendingWriteRequests = 0;
unsigned int maxPendingReadRequests = 0;
unsigned int maxPendingWriteRequests = 0;
bool payloadPostponed = false;
bool finished = false;
unsigned int burstLength;
unsigned int dataLength;
private:
tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase,
sc_time &bwDelay);
sc_time &bwDelay);
void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase);
uint64_t transactionsReceived = 0;
bool nextPayloadSendable() const;
};
#endif // TRACEPLAYER_H
#endif // TRAFFICINITIATOR_H

View File

@@ -45,7 +45,7 @@
#include "simulation/DRAMSys.h"
#include "TraceSetup.h"
#include "TracePlayer.h"
#include "TrafficInitiator.h"
#ifdef RECORDING
#include "simulation/DRAMSysRecordable.h"
@@ -93,7 +93,7 @@ int sc_main(int argc, char **argv)
resources = argv[2];
}
std::vector<TracePlayer *> players;
std::vector<TrafficInitiator *> players;
// Instantiate DRAMSys:
DRAMSys *dramSys;
@@ -109,7 +109,7 @@ int sc_main(int argc, char **argv)
dramSys = new DRAMSys("DRAMSys", simulationJson, resources);
// Instantiate STL Players:
TraceSetup *setup = new TraceSetup(simulationJson, resources, &players);
TraceSetup *setup = new TraceSetup(simulationJson, resources, players);
// Bind STL Players with DRAMSys:
for (size_t i = 0; i < players.size(); i++)