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:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user