Align next request to initiator clock period

This commit is contained in:
2023-06-15 10:59:29 +02:00
parent ec731888a3
commit 20f4f111ac
16 changed files with 61 additions and 63 deletions

View File

@@ -6,7 +6,7 @@ Initiators in the simulator are split up into two disctinct components: **Reques
**RequestProducers** are simple C++ classes that implement the `RequestProducer` interface. Upon calling the `nextRequest()` method of a producer, a new `Request` is either generated on-the-fly or constructed from a trace file.
**RequestIssuers** are the SystemC modules that connect with DRAMSys. Issuers have no knowledge of where the requests are coming from. They simply call their `nextRequest()` callback that it has been passed in the constructor to obtain the next request to be sent to DRAMSys. Using this concept, the generation and the issuing of request is completely decoupled to make very flexible initiator designs possible.
**RequestIssuers** are the SystemC modules that connect to DRAMSys. Issuers have no knowledge of where the requests are coming from. They simply call their `nextRequest()` callback that it has been passed in the constructor to obtain the next request to be sent to DRAMSys. Using this concept, the generation and the issuing of request is completely decoupled to make very flexible initiator designs possible.
**Initiators** implement the `Initiator` interface, which describes how the initiator is bound to DRAMSys. This abstracts over the actual socket type used by the initiator.
Complex initiators may implement the interface directly, but for simple cases, there exists the templated `SimpleInitiator<Producer>` class. This specialized initiator consists of only one producer and one issuer that operate together. The `StlPlayer` and `RowHammer` issuers make use of the `SimpleInitiator`.

View File

@@ -150,6 +150,7 @@ int sc_main(int argc, char **argv)
return std::make_unique<SimpleInitiator<StlPlayer>>(config.name.c_str(),
memoryManager,
config.clkMhz,
std::nullopt,
std::nullopt,
transactionFinished,
@@ -159,10 +160,11 @@ int sc_main(int argc, char **argv)
else if constexpr (std::is_same_v<T, DRAMSys::Config::RowHammer>)
{
RowHammer hammer(
config.numRequests, config.clkMhz, config.rowIncrement, defaultDataLength);
config.numRequests, config.rowIncrement, defaultDataLength);
return std::make_unique<SimpleInitiator<RowHammer>>(config.name.c_str(),
memoryManager,
config.clkMhz,
1,
1,
transactionFinished,

View File

@@ -44,6 +44,7 @@ class SimpleInitiator : public Initiator
public:
SimpleInitiator(sc_core::sc_module_name const &name,
MemoryManager &memoryManager,
unsigned int clkMhz,
std::optional<unsigned int> maxPendingReadRequests,
std::optional<unsigned int> maxPendingWriteRequests,
std::function<void()> transactionFinished,
@@ -53,6 +54,7 @@ public:
issuer(
name,
memoryManager,
clkMhz,
maxPendingReadRequests,
maxPendingWriteRequests,
[this] { return this->producer.nextRequest(); },

View File

@@ -39,7 +39,6 @@
RandomProducer::RandomProducer(uint64_t numRequests,
std::optional<uint64_t> seed,
double rwRatio,
unsigned int clkMhz,
std::optional<uint64_t> minAddress,
std::optional<uint64_t> maxAddress,
uint64_t memorySize,
@@ -49,7 +48,6 @@ RandomProducer::RandomProducer(uint64_t numRequests,
seed(seed.value_or(DEFAULT_SEED)),
rwRatio(rwRatio),
randomGenerator(this->seed),
generatorPeriod(sc_core::sc_time(1.0 / static_cast<double>(clkMhz), sc_core::SC_US)),
dataLength(dataLength),
dataAlignment(dataAlignment),
randomAddressDistribution(minAddress.value_or(DEFAULT_MIN_ADDRESS),
@@ -79,7 +77,7 @@ Request RandomProducer::nextRequest()
request.command = readWriteDistribution(randomGenerator) < rwRatio ? Request::Command::Read
: Request::Command::Write;
request.length = dataLength;
request.delay = generatorPeriod;
request.delay = sc_core::SC_ZERO_TIME;
return request;
}

View File

@@ -46,7 +46,6 @@ public:
RandomProducer(uint64_t numRequests,
std::optional<uint64_t> seed,
double rwRatio,
unsigned int clkMhz,
std::optional<uint64_t> minAddress,
std::optional<uint64_t> maxAddress,
uint64_t memorySize,
@@ -56,12 +55,10 @@ public:
Request nextRequest() override;
uint64_t totalRequests() override { return numberOfRequests; }
sc_core::sc_time clkPeriod() override { return generatorPeriod; }
const uint64_t numberOfRequests;
const uint64_t seed;
const double rwRatio;
const sc_core::sc_time generatorPeriod;
const unsigned int dataLength;
const unsigned int dataAlignment;

View File

@@ -39,7 +39,6 @@
SequentialProducer::SequentialProducer(uint64_t numRequests,
std::optional<uint64_t> seed,
double rwRatio,
unsigned int clkMhz,
std::optional<uint64_t> addressIncrement,
std::optional<uint64_t> minAddress,
std::optional<uint64_t> maxAddress,
@@ -52,7 +51,6 @@ SequentialProducer::SequentialProducer(uint64_t numRequests,
seed(seed.value_or(DEFAULT_SEED)),
rwRatio(rwRatio),
randomGenerator(this->seed),
generatorPeriod(sc_core::sc_time(1.0 / static_cast<double>(clkMhz), sc_core::SC_US)),
dataLength(dataLength)
{
if (minAddress > memorySize - 1)
@@ -75,7 +73,7 @@ Request SequentialProducer::nextRequest()
request.command = readWriteDistribution(randomGenerator) < rwRatio ? Request::Command::Read
: Request::Command::Write;
request.length = dataLength;
request.delay = generatorPeriod;
request.delay = sc_core::SC_ZERO_TIME;
generatedRequests++;
return request;

View File

@@ -46,7 +46,6 @@ public:
SequentialProducer(uint64_t numRequests,
std::optional<uint64_t> seed,
double rwRatio,
unsigned int clkMhz,
std::optional<uint64_t> addressIncrement,
std::optional<uint64_t> minAddress,
std::optional<uint64_t> maxAddress,
@@ -56,7 +55,6 @@ public:
Request nextRequest() override;
uint64_t totalRequests() override { return numberOfRequests; }
sc_core::sc_time clkPeriod() override { return generatorPeriod; }
void reset() override { generatedRequests = 0; }
const uint64_t numberOfRequests;
@@ -65,7 +63,6 @@ public:
const uint64_t maxAddress;
const uint64_t seed;
const double rwRatio;
const sc_core::sc_time generatorPeriod;
const unsigned int dataLength;
std::default_random_engine randomGenerator;

View File

@@ -35,43 +35,44 @@
#include "TrafficGenerator.h"
TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGeneratorStateMachine const &config,
MemoryManager &memoryManager,
TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGeneratorStateMachine const& config,
MemoryManager& memoryManager,
uint64_t memorySize,
unsigned int defaultDataLength,
std::function<void()> transactionFinished,
std::function<void()> terminateInitiator)
: consumer(
config.name.c_str(),
memoryManager,
config.maxPendingReadRequests,
config.maxPendingWriteRequests,
[this] { return nextRequest(); },
std::move(transactionFinished),
std::move(terminateInitiator)),
stateTransistions(config.transitions)
std::function<void()> terminateInitiator) :
issuer(
config.name.c_str(),
memoryManager,
config.clkMhz,
config.maxPendingReadRequests,
config.maxPendingWriteRequests,
[this] { return nextRequest(); },
std::move(transactionFinished),
std::move(terminateInitiator)),
stateTransistions(config.transitions),
generatorPeriod(sc_core::sc_time(1.0 / static_cast<double>(config.clkMhz), sc_core::SC_US))
{
unsigned int dataLength = config.dataLength.value_or(defaultDataLength);
unsigned int dataAlignment = config.dataAlignment.value_or(dataLength);
for (auto const &state : config.states)
for (auto const& state : config.states)
{
std::visit(
[=, &config](auto &&arg)
[=, &config](auto&& arg)
{
using DRAMSys::Config::TrafficGeneratorActiveState;
using DRAMSys::Config::TrafficGeneratorIdleState;
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, TrafficGeneratorActiveState>)
{
auto const &activeState = arg;
auto const& activeState = arg;
if (activeState.addressDistribution ==
DRAMSys::Config::AddressDistribution::Random)
{
auto producer = std::make_unique<RandomProducer>(activeState.numRequests,
config.seed,
activeState.rwRatio,
config.clkMhz,
activeState.minAddress,
activeState.maxAddress,
memorySize,
@@ -86,7 +87,6 @@ TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGeneratorStateMachine
std::make_unique<SequentialProducer>(activeState.numRequests,
config.seed,
activeState.rwRatio,
config.clkMhz,
activeState.addressIncrement,
activeState.minAddress,
activeState.maxAddress,
@@ -98,7 +98,7 @@ TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGeneratorStateMachine
}
else if constexpr (std::is_same_v<T, TrafficGeneratorIdleState>)
{
auto const &idleState = arg;
auto const& idleState = arg;
idleStateClks.emplace(idleState.id, idleState.idleClks);
}
},
@@ -106,20 +106,22 @@ TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGeneratorStateMachine
}
}
TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGenerator const &config,
MemoryManager &memoryManager,
TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGenerator const& config,
MemoryManager& memoryManager,
uint64_t memorySize,
unsigned int defaultDataLength,
std::function<void()> transactionFinished,
std::function<void()> terminateInitiator)
: consumer(
config.name.c_str(),
memoryManager,
config.maxPendingReadRequests,
config.maxPendingWriteRequests,
[this] { return nextRequest(); },
std::move(transactionFinished),
std::move(terminateInitiator))
std::function<void()> terminateInitiator) :
issuer(
config.name.c_str(),
memoryManager,
config.clkMhz,
config.maxPendingReadRequests,
config.maxPendingWriteRequests,
[this] { return nextRequest(); },
std::move(transactionFinished),
std::move(terminateInitiator)),
generatorPeriod(sc_core::sc_time(1.0 / static_cast<double>(config.clkMhz), sc_core::SC_US))
{
unsigned int dataLength = config.dataLength.value_or(defaultDataLength);
unsigned int dataAlignment = config.dataAlignment.value_or(dataLength);
@@ -129,7 +131,6 @@ TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGenerator const &conf
auto producer = std::make_unique<RandomProducer>(config.numRequests,
config.seed,
config.rwRatio,
config.clkMhz,
config.minAddress,
config.maxAddress,
memorySize,
@@ -142,7 +143,6 @@ TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGenerator const &conf
auto producer = std::make_unique<SequentialProducer>(config.numRequests,
config.seed,
config.rwRatio,
config.clkMhz,
config.addressIncrement,
config.minAddress,
config.maxAddress,
@@ -183,9 +183,9 @@ Request TrafficGenerator::nextRequest()
}
requestsInState++;
Request request = producers[currentState]->nextRequest();
request.delay += producers[currentState]->clkPeriod() * clksToIdle;
request.delay += generatorPeriod * static_cast<double>(clksToIdle);
return request;
}

View File

@@ -60,7 +60,7 @@ public:
std::function<void()> transactionFinished,
std::function<void()> terminateInitiator);
void bind(tlm_utils::multi_target_base<> &target) override { consumer.iSocket.bind(target); }
void bind(tlm_utils::multi_target_base<> &target) override { issuer.iSocket.bind(target); }
uint64_t totalRequests() override;
Request nextRequest();
@@ -74,9 +74,10 @@ private:
using IdleClks = uint64_t;
std::unordered_map<unsigned int, IdleClks> idleStateClks;
const sc_core::sc_time generatorPeriod;
std::default_random_engine randomGenerator;
std::unordered_map<unsigned int, std::unique_ptr<RequestProducer>> producers;
RequestIssuer consumer;
RequestIssuer issuer;
};

View File

@@ -36,11 +36,9 @@
#include "RowHammer.h"
RowHammer::RowHammer(uint64_t numRequests,
unsigned int clkMhz,
uint64_t rowIncrement,
unsigned int dataLength)
: numberOfRequests(numRequests),
generatorPeriod(sc_core::sc_time(1.0 / static_cast<double>(clkMhz), sc_core::SC_US)),
dataLength(dataLength),
rowIncrement(rowIncrement)
{
@@ -62,6 +60,6 @@ Request RowHammer::nextRequest()
request.address = currentAddress;
request.command = Request::Command::Read;
request.length = dataLength;
request.delay = generatorPeriod;
request.delay = sc_core::SC_ZERO_TIME;
return request;
}

View File

@@ -43,16 +43,13 @@ class RowHammer : public RequestProducer
{
public:
RowHammer(uint64_t numRequests,
unsigned int clkMhz,
uint64_t rowIncrement,
unsigned int dataLength);
Request nextRequest() override;
sc_core::sc_time clkPeriod() override { return generatorPeriod; }
uint64_t totalRequests() override { return numberOfRequests; }
const uint64_t numberOfRequests;
const sc_core::sc_time generatorPeriod;
const unsigned int dataLength;
const uint64_t rowIncrement;

View File

@@ -94,17 +94,15 @@ Request StlPlayer::nextRequest()
}
}
sc_core::sc_time delay = readoutIt->delay;
sc_core::sc_time offset = playerPeriod - (sc_core::sc_time_stamp() % playerPeriod);
sc_core::sc_time delay;
if (traceType == TraceType::Absolute)
{
delay = std::max(sc_core::sc_time_stamp() + offset, delay);
delay -= sc_core::sc_time_stamp();
bool behindSchedule = sc_core::sc_time_stamp() > readoutIt->delay;
delay = behindSchedule ? sc_core::SC_ZERO_TIME : readoutIt->delay - sc_core::sc_time_stamp();
}
else // if (traceType == TraceType::Relative)
{
delay = offset + delay;
delay = readoutIt->delay;
}
Request request(*readoutIt);

View File

@@ -68,7 +68,6 @@ public:
Request nextRequest() override;
sc_core::sc_time clkPeriod() override { return playerPeriod; }
uint64_t totalRequests() override { return numberOfLines; }
private:

View File

@@ -37,6 +37,7 @@
RequestIssuer::RequestIssuer(sc_core::sc_module_name const &name,
MemoryManager &memoryManager,
unsigned int clkMhz,
std::optional<unsigned int> maxPendingReadRequests,
std::optional<unsigned int> maxPendingWriteRequests,
std::function<Request()> nextRequest,
@@ -44,6 +45,7 @@ RequestIssuer::RequestIssuer(sc_core::sc_module_name const &name,
std::function<void()> terminate)
: sc_module(name),
memoryManager(memoryManager),
clkPeriod(sc_core::sc_time(1.0 / static_cast<double>(clkMhz), sc_core::SC_US)),
maxPendingReadRequests(maxPendingReadRequests),
maxPendingWriteRequests(maxPendingWriteRequests),
nextRequest(std::move(nextRequest)),
@@ -79,6 +81,13 @@ void RequestIssuer::sendNextRequest()
tlm::tlm_phase phase = tlm::BEGIN_REQ;
sc_core::sc_time delay = request.delay;
// Align to next clock
if (delay < clkPeriod && transactionsSent != 0)
{
delay = delay + clkPeriod;
delay -= delay % clkPeriod;
}
iSocket->nb_transport_fw(payload, phase, delay);
if (request.command == Request::Command::Read)

View File

@@ -52,6 +52,7 @@ public:
RequestIssuer(sc_core::sc_module_name const &name,
MemoryManager &memoryManager,
unsigned int clkMhz,
std::optional<unsigned int> maxPendingReadRequests,
std::optional<unsigned int> maxPendingWriteRequests,
std::function<Request()> nextRequest,
@@ -63,6 +64,8 @@ private:
tlm_utils::peq_with_cb_and_phase<RequestIssuer> payloadEventQueue;
MemoryManager &memoryManager;
const sc_core::sc_time clkPeriod;
bool transactionPostponed = false;
bool finished = false;

View File

@@ -44,6 +44,5 @@ public:
virtual Request nextRequest() = 0;
virtual uint64_t totalRequests() = 0;
virtual sc_core::sc_time clkPeriod() = 0;
virtual void reset(){};
};