Introduce a state machine design for TrafficGenerators

Its now possible to design TrafficGenerators in a state machine style.
Each state can have different configurations and the transitions are
defined as propabilities, which makes the design very flexible.
This commit is contained in:
2021-12-13 16:08:01 +01:00
parent 7127a753af
commit 696e9c17d7
8 changed files with 328 additions and 237 deletions

View File

@@ -96,9 +96,9 @@ void to_json(json &j, const TraceSetup &c)
for (const auto &transition : generator->transitions)
{
json transition_j;
transition_j["from"] = transition.from;
transition_j["to"] = transition.to;
transition_j["propability"] = transition.propability;
transition_j["from"] = transition.first;
transition_j["to"] = transition.second.to;
transition_j["propability"] = transition.second.propability;
remove_null_values(transition_j);
transitions_j.insert(transitions_j.end(), transition_j);
}
@@ -137,8 +137,9 @@ void from_json(const json &j, TraceSetup &c)
{
TraceGenerator *generator = new TraceGenerator;
auto process_state = [](const json &state_j) -> std::pair<unsigned int, TraceGeneratorState> {
TraceGeneratorState state {};
auto process_state = [](const json &state_j) -> std::pair<unsigned int, TraceGeneratorState>
{
TraceGeneratorState state{};
state_j.at("numRequests").get_to(state.numRequests);
state_j.at("rwRatio").get_to(state.rwRatio);
@@ -173,10 +174,10 @@ void from_json(const json &j, TraceSetup &c)
for (const auto &transition_j : initiator_j.at("transitions"))
{
TraceGeneratorStateTransition transition;
transition.from = transition_j.at("from");
unsigned int from = transition_j.at("from");
transition.to = transition_j.at("to");
transition.propability = transition_j.at("propability");
generator->transitions.push_back(transition);
generator->transitions.emplace(from, transition);
}
}
else // Only one state will be created
@@ -185,6 +186,9 @@ void from_json(const json &j, TraceSetup &c)
generator->states[state.first] = state.second;
}
if (initiator_j.contains("seed"))
initiator_j.at("seed").get_to(generator->seed);
initiator = std::unique_ptr<TraceGenerator>(generator);
}
else if (type == TrafficInitiatorType::Hammer)

View File

@@ -95,7 +95,6 @@ struct TraceGeneratorState
struct TraceGeneratorStateTransition
{
unsigned int from;
unsigned int to;
float propability;
};
@@ -104,7 +103,7 @@ struct TraceGenerator : public TrafficInitiator
{
Optional<uint64_t> seed;
std::map<unsigned int, TraceGeneratorState> states;
std::vector<TraceGeneratorStateTransition> transitions;
std::multimap<unsigned int, TraceGeneratorStateTransition> transitions;
};
struct TraceHammer : public TrafficInitiator

View File

@@ -111,14 +111,8 @@ std::unique_ptr<DRAMSysConfiguration::TraceGenerator> getTraceGeneratorOneState(
gen->clkMhz = 100;
gen->name = "MyTestGen";
DRAMSysConfiguration::TraceGeneratorState state0 {
1000,
0.5,
DRAMSysConfiguration::AddressDistribution::Random,
{},
{},
{}
};
DRAMSysConfiguration::TraceGeneratorState state0{1000, 0.5, DRAMSysConfiguration::AddressDistribution::Random,
{}, {}, {}};
gen->states[0] = state0;
@@ -133,34 +127,18 @@ std::unique_ptr<DRAMSysConfiguration::TraceGenerator> getTraceGeneratorMultipleS
gen->name = "MyTestGen";
gen->maxPendingReadRequests = 8;
DRAMSysConfiguration::TraceGeneratorState state0 {
1000,
0.5,
DRAMSysConfiguration::AddressDistribution::Sequential,
{256},
{},
{1024}
};
DRAMSysConfiguration::TraceGeneratorState state0{1000, 0.5, DRAMSysConfiguration::AddressDistribution::Sequential,
{256}, {}, {1024}};
DRAMSysConfiguration::TraceGeneratorState state1 {
100,
0.75,
DRAMSysConfiguration::AddressDistribution::Sequential,
{512},
{1024},
{2048}
};
DRAMSysConfiguration::TraceGeneratorState state1{
100, 0.75, DRAMSysConfiguration::AddressDistribution::Sequential, {512}, {1024}, {2048}};
gen->states[0] = state0;
gen->states[1] = state1;
DRAMSysConfiguration::TraceGeneratorStateTransition transistion0 {
0,
1,
1.0
};
DRAMSysConfiguration::TraceGeneratorStateTransition transistion0{1, 1.0};
gen->transitions.push_back(transistion0);
gen->transitions.emplace(0, transistion0);
return std::unique_ptr<DRAMSysConfiguration::TraceGenerator>(gen);
}

View File

@@ -104,72 +104,18 @@ TraceSetup::TraceSetup(const DRAMSysConfiguration::TraceSetup &traceSetup,
}
else if (auto generator = std::dynamic_pointer_cast<DRAMSysConfiguration::TraceGenerator>(inititator))
{
uint64_t numRequests = generator->numRequests;
double rwRatio = generator->rwRatio;
TrafficGenerator *trafficGenerator = new TrafficGenerator(name.c_str(), *generator, this);
players.push_back(trafficGenerator);
if (rwRatio < 0 || rwRatio > 1)
SC_REPORT_FATAL("TraceSetup", "Read/Write ratio is not a number between 0 and 1.");
uint64_t minAddress = [=]() -> uint64_t {
if (generator->minAddress.isValid())
return generator->minAddress.getValue();
else
return 0;
}();
if (minAddress > Configuration::getInstance().memSpec->getSimMemSizeInBytes() - 1)
SC_REPORT_FATAL("TraceSetup", "minAddress is out of range.");
uint64_t maxAddress = [=]() -> uint64_t {
if (generator->maxAddress.isValid())
return generator->maxAddress.getValue();
else
return Configuration::getInstance().memSpec->getSimMemSizeInBytes() - 1;
}();
if (maxAddress > Configuration::getInstance().memSpec->getSimMemSizeInBytes() - 1)
SC_REPORT_FATAL("TraceSetup", "minAddress is out of range.");
if (maxAddress < minAddress)
SC_REPORT_FATAL("TraceSetup", "maxAddress is smaller than minAddress.");
unsigned int seed = [=]() -> unsigned int {
if (generator->seed.isValid())
return generator->seed.getValue();
else
return 0;
}();
if (generator->addressDistribution == DRAMSysConfiguration::AddressDistribution::Sequential)
{
uint64_t addressIncrement = [=]() -> uint64_t {
if (generator->addressIncrement.isValid())
return generator->addressIncrement.getValue();
else
return 0x0;
}();
players.push_back(new TrafficGeneratorSequential(name.c_str(), playerClk, numRequests,
maxPendingReadRequests, maxPendingWriteRequests,
minAddress, maxAddress, rwRatio, addressIncrement, seed,
this));
}
else if (generator->addressDistribution == DRAMSysConfiguration::AddressDistribution::Random)
{
players.push_back(new TrafficGeneratorRandom(name.c_str(), playerClk, numRequests,
maxPendingReadRequests, maxPendingWriteRequests,
minAddress, maxAddress, rwRatio, seed, this));
}
totalTransactions += numRequests;
totalTransactions += trafficGenerator->getTotalTransactions();
}
else if (auto hammer = std::dynamic_pointer_cast<DRAMSysConfiguration::TraceHammer>(inititator))
{
uint64_t numRequests = hammer->numRequests;
uint64_t rowIncrement = hammer->rowIncrement;
players.push_back(new TrafficGeneratorHammer(name.c_str(), playerClk, numRequests,
rowIncrement, this));
players.push_back(new TrafficGeneratorHammer(name.c_str(), *hammer, this));
totalTransactions += numRequests;
}
}

View File

@@ -41,50 +41,34 @@
using namespace sc_core;
using namespace tlm;
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)
TrafficGeneratorIf::TrafficGeneratorIf(const sc_core::sc_module_name &name, TraceSetup *setup,
unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests)
: TrafficInitiator(name, setup, maxPendingReadRequests, maxPendingWriteRequests)
{
burstLength = Configuration::getInstance().memSpec->burstLength;
dataLength = Configuration::getInstance().memSpec->bytesPerBurst;
randomGenerator = std::default_random_engine(seed);
}
void TrafficGenerator::sendNextPayload()
void TrafficGeneratorIf::sendNextPayload()
{
if (transactionsSent >= numRequests)
{
finished = true;
return;
}
prepareNextPayload();
tlm_generic_payload *payload = setup->allocatePayload();
payload->acquire();
if (finished)
return;
// TODO: column / burst breite
uint64_t address = getNextAddress();
tlm_command command;
if (randomRwDistribution(randomGenerator) < rwRatio)
{
command = tlm::TLM_READ_COMMAND;
pendingReadRequests++;
}
else
{
command = tlm::TLM_WRITE_COMMAND;
pendingWriteRequests++;
}
tlm_command command = getNextCommand();
if (command == tlm::TLM_READ_COMMAND)
pendingReadRequests++;
else if (command == tlm::TLM_WRITE_COMMAND)
pendingWriteRequests++;
tlm_generic_payload *payload = setup->allocatePayload();
payload->acquire();
payload->set_address(address);
payload->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
payload->set_dmi_allowed(false);
@@ -93,6 +77,7 @@ void TrafficGenerator::sendNextPayload()
payload->set_data_length(dataLength);
payload->set_command(command);
sc_time generatorClk = getGeneratorClk();
sc_time sendingOffset;
if (transactionsSent == 0)
sendingOffset = SC_ZERO_TIME;
@@ -104,65 +89,226 @@ void TrafficGenerator::sendNextPayload()
transactionsSent++;
PRINTDEBUGMESSAGE(name(), "Performing request #" + std::to_string(transactionsSent));
payloadSent();
}
TrafficGeneratorRandom::TrafficGeneratorRandom(const sc_core::sc_module_name &name,
const sc_core::sc_time &generatorClk,
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
uint64_t minAddress,
uint64_t maxAddress,
float rwRatio,
unsigned int seed,
TraceSetup *setup) :
TrafficGenerator(name, generatorClk, numRequests, maxPendingReadRequests, maxPendingWriteRequests, rwRatio, seed,
setup)
TrafficGenerator::TrafficGenerator(const sc_module_name &name, const DRAMSysConfiguration::TraceGenerator &conf,
TraceSetup *setup)
: TrafficGeneratorIf(name, setup, evaluateMaxPendingReadRequests(conf), evaluateMaxPendingWriteRequests(conf)),
generatorClk(TrafficInitiator::evaluateGeneratorClk(conf)), conf(conf),
randomGenerator(std::default_random_engine(evaluateSeed(conf)))
{
// Perform checks for all states
for (const auto &state : conf.states)
{
uint64_t minAddress = evaluateMinAddress(state.second);
uint64_t maxAddress = evaluateMaxAddress(state.second);
double rwRatio = state.second.rwRatio;
if (minAddress > Configuration::getInstance().memSpec->getSimMemSizeInBytes() - 1)
SC_REPORT_FATAL("TrafficGenerator", "minAddress is out of range.");
if (maxAddress > Configuration::getInstance().memSpec->getSimMemSizeInBytes() - 1)
SC_REPORT_FATAL("TrafficGenerator", "minAddress is out of range.");
if (maxAddress < minAddress)
SC_REPORT_FATAL("TrafficGenerator", "maxAddress is smaller than minAddress.");
if (rwRatio < 0 || rwRatio > 1)
SC_REPORT_FATAL("TraceSetup", "Read/Write ratio is not a number between 0 and 1.");
}
uint64_t minAddress = evaluateMinAddress(conf.states.at(currentState));
uint64_t maxAddress = evaluateMaxAddress(conf.states.at(currentState));
randomAddressDistribution = std::uniform_int_distribution<uint64_t>(minAddress, maxAddress);
calculateTransitions();
}
void TrafficGenerator::calculateTransitions()
{
unsigned int state = 0;
stateSequence.push_back(state);
while (true)
{
auto transitionsIt = conf.transitions.equal_range(state);
float propabilityAccumulated = 0.0f;
std::map<unsigned int, std::pair<float, float>> transitionsDistribution;
for (auto it = transitionsIt.first; it != transitionsIt.second; ++it)
{
float lowerLimit = propabilityAccumulated;
propabilityAccumulated += it->second.propability;
float upperLimit = propabilityAccumulated;
transitionsDistribution[it->second.to] = {lowerLimit, upperLimit};
}
if (propabilityAccumulated > 1.001f)
SC_REPORT_WARNING("TrafficGenerator", "Sum of transition propabilities greater than 1.");
float random = randomDistribution(randomGenerator);
bool transitionFound = false;
for (const auto &transition : transitionsDistribution)
{
auto to = transition.first;
auto limits = transition.second;
if (limits.first < random && limits.second > random)
{
state = to;
stateSequence.push_back(state);
transitionFound = true;
break;
}
}
if (transitionFound)
continue;
break;
}
stateIt = stateSequence.cbegin();
}
uint64_t TrafficGenerator::getTotalTransactions() const
{
uint64_t totalTransactions = 0;
for (auto state : stateSequence)
{
totalTransactions += conf.states.at(state).numRequests;
}
return totalTransactions;
}
void TrafficGenerator::transitionToNextState()
{
++stateIt;
if (stateIt == stateSequence.cend())
{
// No transition performed.
finished = true;
return;
}
currentState = *stateIt;
uint64_t minAddress = evaluateMinAddress(conf.states.at(currentState));
uint64_t maxAddress = evaluateMaxAddress(conf.states.at(currentState));
randomAddressDistribution = std::uniform_int_distribution<uint64_t> (minAddress, maxAddress);
currentAddress = 0x00;
transactionsSentInCurrentState = 0;
}
uint64_t TrafficGeneratorRandom::getNextAddress()
void TrafficGenerator::prepareNextPayload()
{
return randomAddressDistribution(randomGenerator);
if (transactionsSentInCurrentState >= conf.states.at(currentState).numRequests)
transitionToNextState();
}
TrafficGeneratorSequential::TrafficGeneratorSequential(const sc_core::sc_module_name &name,
const sc_core::sc_time &generatorClk,
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
uint64_t minAddress,
uint64_t maxAddress,
float rwRatio,
uint64_t addressIncrement,
unsigned int seed,
TraceSetup *setup) :
TrafficGenerator(name, generatorClk, numRequests, maxPendingReadRequests, maxPendingWriteRequests, rwRatio, seed,
setup), minAddress(minAddress), maxAddress(maxAddress), addressIncrement(addressIncrement),
currentAddress(minAddress)
void TrafficGenerator::payloadSent()
{
transactionsSentInCurrentState++;
}
uint64_t TrafficGeneratorSequential::getNextAddress()
tlm::tlm_command TrafficGenerator::getNextCommand()
{
uint64_t address = currentAddress;
currentAddress += addressIncrement;
if (currentAddress > maxAddress)
currentAddress = minAddress;
return address;
tlm_command command;
if (randomDistribution(randomGenerator) < conf.states.at(currentState).rwRatio)
command = tlm::TLM_READ_COMMAND;
else
command = tlm::TLM_WRITE_COMMAND;
return command;
}
sc_core::sc_time TrafficGenerator::getGeneratorClk()
{
return generatorClk;
}
uint64_t TrafficGenerator::getNextAddress()
{
using DRAMSysConfiguration::AddressDistribution;
uint64_t minAddress = evaluateMinAddress(conf.states.at(currentState));
uint64_t maxAddress = evaluateMaxAddress(conf.states.at(currentState));
if (conf.states.at(currentState).addressDistribution == AddressDistribution::Sequential)
{
uint64_t addressIncrement = evaluateAddressIncrement(conf.states.at(currentState));
uint64_t address = currentAddress;
currentAddress += addressIncrement;
if (currentAddress > maxAddress)
currentAddress = minAddress;
return address;
}
else if (conf.states.at(currentState).addressDistribution == AddressDistribution::Random)
{
return randomAddressDistribution(randomGenerator);
}
else
{
return 0x00;
}
}
unsigned int TrafficGenerator::evaluateSeed(const DRAMSysConfiguration::TraceGenerator &conf)
{
if (conf.seed.isValid())
return conf.seed.getValue();
else
return 0;
}
unsigned int TrafficGenerator::evaluateMinAddress(const DRAMSysConfiguration::TraceGeneratorState &state)
{
if (state.minAddress.isValid())
return state.minAddress.getValue();
else
return 0x00;
}
unsigned int TrafficGenerator::evaluateMaxAddress(const DRAMSysConfiguration::TraceGeneratorState &state)
{
if (state.maxAddress.isValid())
return state.maxAddress.getValue();
else
return Configuration::getInstance().memSpec->getSimMemSizeInBytes() - 1;
}
unsigned int TrafficGenerator::evaluateAddressIncrement(const DRAMSysConfiguration::TraceGeneratorState &state)
{
if (state.addressIncrement.isValid())
return state.addressIncrement.getValue();
else
return 0x00;
}
TrafficGeneratorHammer::TrafficGeneratorHammer(const sc_core::sc_module_name &name,
const sc_core::sc_time &generatorClk,
uint64_t numRequests,
uint64_t rowIncrement,
TraceSetup *setup) :
TrafficGenerator(name, generatorClk, numRequests, 1, 1, 1.0f, 1, setup), rowIncrement(rowIncrement)
const DRAMSysConfiguration::TraceHammer &conf, TraceSetup *setup)
: TrafficGeneratorIf(name, setup, 1, 1), generatorClk(evaluateGeneratorClk(conf)), rowIncrement(conf.rowIncrement),
numRequests(conf.numRequests)
{
}
tlm::tlm_command TrafficGeneratorHammer::getNextCommand()
{
return tlm::TLM_READ_COMMAND;
}
sc_core::sc_time TrafficGeneratorHammer::getGeneratorClk()
{
return generatorClk;
}
uint64_t TrafficGeneratorHammer::getNextAddress()
{
if (currentAddress == 0x0)
@@ -172,3 +318,9 @@ uint64_t TrafficGeneratorHammer::getNextAddress()
return currentAddress;
}
void TrafficGeneratorHammer::prepareNextPayload()
{
if (transactionsSent >= numRequests)
finished = true;
}

View File

@@ -44,90 +44,75 @@
#include "TrafficInitiator.h"
#include "TraceSetup.h"
class TrafficGenerator : public TrafficInitiator
{
protected:
TrafficGenerator(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);
void sendNextPayload() override;
virtual uint64_t getNextAddress() = 0;
std::default_random_engine randomGenerator;
private:
sc_core::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
class TrafficGeneratorIf : public TrafficInitiator
{
public:
TrafficGeneratorRandom(const sc_core::sc_module_name &name,
const sc_core::sc_time &generatorClk,
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
uint64_t minAddress,
uint64_t maxAddress,
float rwRatio,
unsigned int seed,
TraceSetup *setup);
TrafficGeneratorIf(const sc_core::sc_module_name &name, TraceSetup *setup, unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests);
private:
uint64_t getNextAddress() override;
void sendNextPayload() override;
virtual void prepareNextPayload(){};
virtual uint64_t getNextAddress() = 0;
virtual tlm::tlm_command getNextCommand() = 0;
virtual sc_core::sc_time getGeneratorClk() = 0;
virtual void payloadSent(){};
};
class TrafficGenerator : public TrafficGeneratorIf
{
public:
TrafficGenerator(const sc_core::sc_module_name &name, const DRAMSysConfiguration::TraceGenerator &conf,
TraceSetup *setup);
uint64_t getTotalTransactions() const;
private:
static unsigned int evaluateSeed(const DRAMSysConfiguration::TraceGenerator &conf);
static unsigned int evaluateMinAddress(const DRAMSysConfiguration::TraceGeneratorState &state);
static unsigned int evaluateMaxAddress(const DRAMSysConfiguration::TraceGeneratorState &state);
static unsigned int evaluateAddressIncrement(const DRAMSysConfiguration::TraceGeneratorState &state);
void prepareNextPayload() override;
uint64_t getNextAddress() override;
tlm::tlm_command getNextCommand() override;
sc_core::sc_time getGeneratorClk() override;
void payloadSent() override;
void calculateTransitions();
void transitionToNextState();
sc_core::sc_time generatorClk;
const DRAMSysConfiguration::TraceGenerator &conf;
unsigned int currentState = 0;
uint64_t currentAddress = 0x00;
uint64_t transactionsSentInCurrentState = 0;
std::vector<unsigned int> stateSequence;
std::vector<unsigned int>::const_iterator stateIt;
std::default_random_engine randomGenerator;
std::uniform_real_distribution<float> randomDistribution = std::uniform_real_distribution<float>(0.0f, 1.0f);
std::uniform_int_distribution<uint64_t> randomAddressDistribution;
};
class TrafficGeneratorSequential final : public TrafficGenerator
class TrafficGeneratorHammer final : public TrafficGeneratorIf
{
public:
TrafficGeneratorSequential(const sc_core::sc_module_name &name,
const sc_core::sc_time &generatorClk,
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
uint64_t minAddress,
uint64_t maxAddress,
float rwRatio,
uint64_t addressIncrement,
unsigned int seed,
TraceSetup *setup);
private:
uint64_t getNextAddress() override;
uint64_t currentAddress;
uint64_t addressIncrement;
uint64_t minAddress;
uint64_t maxAddress;
};
class TrafficGeneratorHammer final : public TrafficGenerator
{
public:
TrafficGeneratorHammer(const sc_core::sc_module_name &name,
const sc_core::sc_time &generatorClk,
uint64_t numRequests,
uint64_t rowIncrement,
TrafficGeneratorHammer(const sc_core::sc_module_name &name, const DRAMSysConfiguration::TraceHammer &conf,
TraceSetup *setup);
private:
void prepareNextPayload() override;
uint64_t getNextAddress() override;
tlm::tlm_command getNextCommand() override;
sc_core::sc_time getGeneratorClk() override;
sc_core::sc_time generatorClk;
uint64_t rowIncrement;
uint64_t currentAddress = 0x0;
uint64_t numRequests;
};
#endif // TRAFFICGENERATOR_H

View File

@@ -129,3 +129,26 @@ bool TrafficInitiator::nextPayloadSendable() const
else
return true;
}
sc_core::sc_time TrafficInitiator::evaluateGeneratorClk(const DRAMSysConfiguration::TrafficInitiator &conf)
{
double frequencyMHz = conf.clkMhz;
sc_time playerClk = sc_time(1.0 / frequencyMHz, SC_US);
return playerClk;
}
unsigned int TrafficInitiator::evaluateMaxPendingReadRequests(const DRAMSysConfiguration::TrafficInitiator &conf)
{
if (conf.maxPendingReadRequests.isValid())
return conf.maxPendingReadRequests.getValue();
else
return 0;
}
unsigned int TrafficInitiator::evaluateMaxPendingWriteRequests(const DRAMSysConfiguration::TrafficInitiator &conf)
{
if (conf.maxPendingWriteRequests.isValid())
return conf.maxPendingWriteRequests.getValue();
else
return 0;
}

View File

@@ -62,6 +62,10 @@ public:
virtual void sendNextPayload() = 0;
protected:
static sc_core::sc_time evaluateGeneratorClk(const DRAMSysConfiguration::TrafficInitiator &conf);
static unsigned int evaluateMaxPendingReadRequests(const DRAMSysConfiguration::TrafficInitiator &conf);
static unsigned int evaluateMaxPendingWriteRequests(const DRAMSysConfiguration::TrafficInitiator &conf);
tlm_utils::peq_with_cb_and_phase<TrafficInitiator> payloadEventQueue;
void terminate();
bool storageEnabled = false;
@@ -73,8 +77,8 @@ protected:
uint64_t transactionsSent = 0;
unsigned int pendingReadRequests = 0;
unsigned int pendingWriteRequests = 0;
unsigned int maxPendingReadRequests = 0;
unsigned int maxPendingWriteRequests = 0;
const unsigned int maxPendingReadRequests;
const unsigned int maxPendingWriteRequests;
bool payloadPostponed = false;
bool finished = false;