Small bugfix in TrafficInitiator, code refactoring.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user