Small bugfix in TrafficInitiator, code refactoring.

This commit is contained in:
Lukas Steiner
2021-05-27 10:20:37 +02:00
parent 73d767c6f0
commit dd5707ec3e
8 changed files with 84 additions and 122 deletions

View File

@@ -44,26 +44,34 @@ using namespace tlm;
StlPlayer::StlPlayer(const sc_module_name &name,
const std::string &pathToTrace,
sc_time playerClk,
const sc_time &playerClk,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
TraceSetup *setup,
bool relative)
: TrafficInitiator(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);
this->maxPendingReadRequests = maxPendingReadRequests;
this->maxPendingWriteRequests = maxPendingWriteRequests;
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);
@@ -78,7 +86,7 @@ StlPlayer::~StlPlayer()
parserThread.join();
}
void StlPlayer::nextPayload()
void StlPlayer::sendNextPayload()
{
if (lineIterator == currentBuffer->cend())
{
@@ -138,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++;
@@ -152,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.
@@ -166,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;
@@ -190,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)
@@ -212,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)));
}
}
}
@@ -232,29 +238,7 @@ std::vector<LineContent>::const_iterator StlPlayer::swapBuffers()
return currentBuffer->cbegin();
}
uint64_t StlPlayer::getNumberOfLines(const std::string &pathToTrace)
uint64_t StlPlayer::getNumberOfLines() 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("StlPlayer", "Trace file is empty");
return lineCount;
}
else
{
SC_REPORT_FATAL("StlPlayer", "Unable to open trace file");
return 0;
}
return numberOfLines;
}

View File

@@ -61,26 +61,25 @@ class StlPlayer : public TrafficInitiator
public:
StlPlayer(const sc_module_name &name,
const std::string &pathToTrace,
sc_time playerClk,
const sc_time &playerClk,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
TraceSetup *setup,
bool relative);
virtual ~StlPlayer() override;
virtual void nextPayload() override;
uint64_t getNumberOfLines(const std::string &pathToTrace);
~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;
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;
@@ -91,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

@@ -103,7 +103,9 @@ TraceSetup::TraceSetup(const std::string &uri,
std::string ext = name.substr(pos + 1);
std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
std::string stlFile = pathToResources + std::string("traces/") + name;
std::stringstream stlFileStream;
stlFileStream << pathToResources << "traces/" << name;
std::string stlFile = stlFileStream.str();
std::string moduleName = name;
// replace all '.' to '_'
@@ -121,8 +123,7 @@ TraceSetup::TraceSetup(const std::string &uri,
players.push_back(player);
if (Configuration::getInstance().simulationProgressBar)
totalTransactions += player->getNumberOfLines(stlFile);
totalTransactions += player->getNumberOfLines();
}
else if (type == "generator")
{
@@ -170,8 +171,7 @@ TraceSetup::TraceSetup(const std::string &uri,
players.push_back(generator);
if (Configuration::getInstance().simulationProgressBar)
totalTransactions += numRequests;
totalTransactions += numRequests;
}
}
}
@@ -192,7 +192,7 @@ void TraceSetup::transactionFinished()
{
remainingTransactions--;
loadbar(totalTransactions - remainingTransactions, totalTransactions);
loadBar(totalTransactions - remainingTransactions, totalTransactions);
if (remainingTransactions == 0)
std::cout << std::endl;
@@ -203,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

@@ -62,7 +62,7 @@ private:
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

@@ -39,26 +39,23 @@
#include "TrafficGenerator.h"
TrafficGenerator::TrafficGenerator(const sc_module_name &name,
const sc_time &tCK,
const sc_time &generatorClk,
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
float rwRatio,
unsigned int seed,
TraceSetup *setup) :
TrafficInitiator(name, setup), tCK(tCK),
numRequests(numRequests), rwRatio(rwRatio)
TrafficInitiator(name, setup, maxPendingReadRequests, maxPendingWriteRequests),
generatorClk(generatorClk), numRequests(numRequests), rwRatio(rwRatio)
{
burstLength = Configuration::getInstance().memSpec->burstLength;
dataLength = Configuration::getInstance().memSpec->bytesPerBurst;
this->maxPendingReadRequests = maxPendingReadRequests;
this->maxPendingWriteRequests = maxPendingWriteRequests;
randomGenerator = std::default_random_engine(seed);
}
void TrafficGenerator::nextPayload()
void TrafficGenerator::sendNextPayload()
{
if (transactionsSent >= numRequests)
{
@@ -77,10 +74,12 @@ void TrafficGenerator::nextPayload()
if (randomRwDistribution(randomGenerator) < rwRatio)
{
command = tlm::TLM_READ_COMMAND;
pendingReadRequests++;
}
else
{
command = tlm::TLM_WRITE_COMMAND;
pendingWriteRequests++;
}
payload->set_address(address);
@@ -95,34 +94,28 @@ void TrafficGenerator::nextPayload()
if (transactionsSent == 0)
sendingOffset = SC_ZERO_TIME;
else
sendingOffset = tCK;
sendingOffset = generatorClk - (sc_time_stamp() % generatorClk);
// TODO: do not send two requests in the same cycle
sendToTarget(*payload, tlm::BEGIN_REQ, sendingOffset);
transactionsSent++;
if (command == tlm::TLM_READ_COMMAND)
pendingReadRequests++;
else if (command == tlm::TLM_WRITE_COMMAND)
pendingWriteRequests++;
PRINTDEBUGMESSAGE(name(), "Performing request #" + std::to_string(transactionsSent));
}
TrafficGeneratorRandom::TrafficGeneratorRandom(const sc_core::sc_module_name &name,
const sc_core::sc_time &tCK,
const sc_core::sc_time &generatorClk,
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
float rwRatio,
unsigned int seed,
TraceSetup *setup) :
TrafficGenerator(name, tCK, numRequests, maxPendingReadRequests,
TrafficGenerator(name, generatorClk, numRequests, maxPendingReadRequests,
maxPendingWriteRequests, rwRatio, seed, setup)
{
randomAddressDistribution = std::uniform_int_distribution<uint64_t>(
0, Configuration::getInstance().memSpec->getSimMemSizeInBytes());
randomAddressDistribution = std::uniform_int_distribution<uint64_t>
(0, Configuration::getInstance().memSpec->getSimMemSizeInBytes());
}
uint64_t TrafficGeneratorRandom::getNextAddress()
@@ -131,7 +124,7 @@ uint64_t TrafficGeneratorRandom::getNextAddress()
}
TrafficGeneratorSequential::TrafficGeneratorSequential(const sc_core::sc_module_name &name,
const sc_core::sc_time &tCK,
const sc_core::sc_time &generatorClk,
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
@@ -139,7 +132,7 @@ TrafficGeneratorSequential::TrafficGeneratorSequential(const sc_core::sc_module_
uint64_t addressIncrement,
unsigned int seed,
TraceSetup *setup) :
TrafficGenerator(name, tCK, numRequests, maxPendingReadRequests,
TrafficGenerator(name, generatorClk, numRequests, maxPendingReadRequests,
maxPendingWriteRequests, rwRatio, seed, setup),
addressIncrement(addressIncrement)
{

View File

@@ -48,7 +48,7 @@ class TrafficGenerator : public TrafficInitiator
{
protected:
TrafficGenerator(const sc_module_name &name,
const sc_time &tCK,
const sc_time &generatorClk,
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
@@ -56,24 +56,25 @@ protected:
unsigned int seed,
TraceSetup *setup);
virtual void nextPayload() override;
void sendNextPayload() override;
virtual uint64_t getNextAddress() = 0;
std::default_random_engine randomGenerator;
private:
sc_time tCK;
sc_time generatorClk;
uint64_t numRequests;
float rwRatio;
std::uniform_real_distribution<float> randomRwDistribution = std::uniform_real_distribution<float>(0.0f, 1.0f);
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 &tCK,
const sc_time &generatorClk,
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
@@ -82,7 +83,7 @@ public:
TraceSetup *setup);
private:
virtual uint64_t getNextAddress() override;
uint64_t getNextAddress() override;
std::uniform_int_distribution<uint64_t> randomAddressDistribution;
};
@@ -91,7 +92,7 @@ class TrafficGeneratorSequential final : public TrafficGenerator
{
public:
TrafficGeneratorSequential(const sc_module_name &name,
const sc_time &tCK,
const sc_time &generatorClk,
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
@@ -101,7 +102,7 @@ public:
TraceSetup *setup);
private:
virtual uint64_t getNextAddress() override;
uint64_t getNextAddress() override;
uint64_t currentAddress = 0x0;
uint64_t addressIncrement;

View File

@@ -42,12 +42,13 @@
using namespace tlm;
TrafficInitiator::TrafficInitiator(const sc_module_name &name, TraceSetup *setup) :
sc_module(name),
payloadEventQueue(this, &TrafficInitiator::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);
SC_METHOD(sendNextPayload);
iSocket.register_nb_transport_bw(this, &TrafficInitiator::nb_transport_bw);
if (Configuration::getInstance().storeMode == Configuration::StoreMode::NoStorage)
@@ -75,7 +76,7 @@ void TrafficInitiator::peqCallback(tlm_generic_payload &payload,
if (phase == END_REQ)
{
if (nextPayloadSendable())
nextPayload();
sendNextPayload();
else
payloadPostponed = true;
}
@@ -94,14 +95,14 @@ void TrafficInitiator::peqCallback(tlm_generic_payload &payload,
pendingWriteRequests--;
// If the initiator wasn't able to send the next payload in the END_REQ phase, do it now.
if (payloadPostponed)
if (payloadPostponed && nextPayloadSendable())
{
nextPayload();
sendNextPayload();
payloadPostponed = false;
}
// If all answers were received:
if (finished == true && transactionsSent == transactionsReceived)
if (finished && transactionsSent == transactionsReceived)
terminate();
}
else
@@ -117,20 +118,13 @@ void TrafficInitiator::sendToTarget(tlm_generic_payload &payload, const tlm_phas
iSocket->nb_transport_fw(payload, TPhase, TDelay);
}
bool TrafficInitiator::nextPayloadSendable()
bool TrafficInitiator::nextPayloadSendable() const
{
bool sendable = true;
// If either the maxPendingReadRequests or maxPendingWriteRequests
// limit is reached, do not send next payload.
if (pendingReadRequests >= maxPendingReadRequests && maxPendingReadRequests != 0)
{
sendable = false;
}
else if (pendingWriteRequests >= maxPendingWriteRequests && maxPendingWriteRequests != 0)
{
sendable = false;
}
return sendable;
if (((pendingReadRequests >= maxPendingReadRequests) && (maxPendingReadRequests != 0))
|| ((pendingWriteRequests >= maxPendingWriteRequests) && (maxPendingWriteRequests != 0)))
return false;
else
return true;
}

View File

@@ -55,9 +55,10 @@ class TrafficInitiator : public sc_module
{
public:
tlm_utils::simple_initiator_socket<TrafficInitiator> iSocket;
TrafficInitiator(const sc_module_name &name, TraceSetup *setup);
TrafficInitiator(const sc_module_name &name, TraceSetup *setup,
unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests);
SC_HAS_PROCESS(TrafficInitiator);
virtual void nextPayload() = 0;
virtual void sendNextPayload() = 0;
protected:
tlm_utils::peq_with_cb_and_phase<TrafficInitiator> payloadEventQueue;
@@ -79,13 +80,11 @@ protected:
unsigned int burstLength;
unsigned int dataLength;
sc_event transactionFinished;
private:
tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase,
sc_time &bwDelay);
void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase);
bool nextPayloadSendable();
bool nextPayloadSendable() const;
};
#endif // TRAFFICINITIATOR_H