diff --git a/src/simulator/README.md b/src/simulator/README.md index 8f8712b2..e2ffe592 100644 --- a/src/simulator/README.md +++ b/src/simulator/README.md @@ -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` 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`. diff --git a/src/simulator/main.cpp b/src/simulator/main.cpp index 153341ae..80563366 100644 --- a/src/simulator/main.cpp +++ b/src/simulator/main.cpp @@ -150,6 +150,7 @@ int sc_main(int argc, char **argv) return std::make_unique>(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) { RowHammer hammer( - config.numRequests, config.clkMhz, config.rowIncrement, defaultDataLength); + config.numRequests, config.rowIncrement, defaultDataLength); return std::make_unique>(config.name.c_str(), memoryManager, + config.clkMhz, 1, 1, transactionFinished, diff --git a/src/simulator/simulator/SimpleInitiator.h b/src/simulator/simulator/SimpleInitiator.h index b0c79d11..3c0a0064 100644 --- a/src/simulator/simulator/SimpleInitiator.h +++ b/src/simulator/simulator/SimpleInitiator.h @@ -44,6 +44,7 @@ class SimpleInitiator : public Initiator public: SimpleInitiator(sc_core::sc_module_name const &name, MemoryManager &memoryManager, + unsigned int clkMhz, std::optional maxPendingReadRequests, std::optional maxPendingWriteRequests, std::function transactionFinished, @@ -53,6 +54,7 @@ public: issuer( name, memoryManager, + clkMhz, maxPendingReadRequests, maxPendingWriteRequests, [this] { return this->producer.nextRequest(); }, diff --git a/src/simulator/simulator/generator/RandomProducer.cpp b/src/simulator/simulator/generator/RandomProducer.cpp index b6a7001e..2d866747 100644 --- a/src/simulator/simulator/generator/RandomProducer.cpp +++ b/src/simulator/simulator/generator/RandomProducer.cpp @@ -39,7 +39,6 @@ RandomProducer::RandomProducer(uint64_t numRequests, std::optional seed, double rwRatio, - unsigned int clkMhz, std::optional minAddress, std::optional 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(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; } diff --git a/src/simulator/simulator/generator/RandomProducer.h b/src/simulator/simulator/generator/RandomProducer.h index 299b7296..062c3acf 100644 --- a/src/simulator/simulator/generator/RandomProducer.h +++ b/src/simulator/simulator/generator/RandomProducer.h @@ -46,7 +46,6 @@ public: RandomProducer(uint64_t numRequests, std::optional seed, double rwRatio, - unsigned int clkMhz, std::optional minAddress, std::optional 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; diff --git a/src/simulator/simulator/generator/SequentialProducer.cpp b/src/simulator/simulator/generator/SequentialProducer.cpp index b39a6479..f2985ef6 100644 --- a/src/simulator/simulator/generator/SequentialProducer.cpp +++ b/src/simulator/simulator/generator/SequentialProducer.cpp @@ -39,7 +39,6 @@ SequentialProducer::SequentialProducer(uint64_t numRequests, std::optional seed, double rwRatio, - unsigned int clkMhz, std::optional addressIncrement, std::optional minAddress, std::optional 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(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; diff --git a/src/simulator/simulator/generator/SequentialProducer.h b/src/simulator/simulator/generator/SequentialProducer.h index 9c8842ce..d3f64e6e 100644 --- a/src/simulator/simulator/generator/SequentialProducer.h +++ b/src/simulator/simulator/generator/SequentialProducer.h @@ -46,7 +46,6 @@ public: SequentialProducer(uint64_t numRequests, std::optional seed, double rwRatio, - unsigned int clkMhz, std::optional addressIncrement, std::optional minAddress, std::optional 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; diff --git a/src/simulator/simulator/generator/TrafficGenerator.cpp b/src/simulator/simulator/generator/TrafficGenerator.cpp index 644f57b3..2a73e82d 100644 --- a/src/simulator/simulator/generator/TrafficGenerator.cpp +++ b/src/simulator/simulator/generator/TrafficGenerator.cpp @@ -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 transactionFinished, - std::function 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 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(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; if constexpr (std::is_same_v) { - auto const &activeState = arg; + auto const& activeState = arg; if (activeState.addressDistribution == DRAMSys::Config::AddressDistribution::Random) { auto producer = std::make_unique(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(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) { - 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 transactionFinished, - std::function terminateInitiator) - : consumer( - config.name.c_str(), - memoryManager, - config.maxPendingReadRequests, - config.maxPendingWriteRequests, - [this] { return nextRequest(); }, - std::move(transactionFinished), - std::move(terminateInitiator)) + std::function 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(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(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(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(clksToIdle); return request; } diff --git a/src/simulator/simulator/generator/TrafficGenerator.h b/src/simulator/simulator/generator/TrafficGenerator.h index ec2ec3a3..3636cc7b 100644 --- a/src/simulator/simulator/generator/TrafficGenerator.h +++ b/src/simulator/simulator/generator/TrafficGenerator.h @@ -60,7 +60,7 @@ public: std::function transactionFinished, std::function 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 idleStateClks; + const sc_core::sc_time generatorPeriod; std::default_random_engine randomGenerator; std::unordered_map> producers; - RequestIssuer consumer; + RequestIssuer issuer; }; diff --git a/src/simulator/simulator/hammer/RowHammer.cpp b/src/simulator/simulator/hammer/RowHammer.cpp index 4ca7d7b3..feb18d04 100644 --- a/src/simulator/simulator/hammer/RowHammer.cpp +++ b/src/simulator/simulator/hammer/RowHammer.cpp @@ -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(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; } diff --git a/src/simulator/simulator/hammer/RowHammer.h b/src/simulator/simulator/hammer/RowHammer.h index 218a82c7..75996299 100644 --- a/src/simulator/simulator/hammer/RowHammer.h +++ b/src/simulator/simulator/hammer/RowHammer.h @@ -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; diff --git a/src/simulator/simulator/player/StlPlayer.cpp b/src/simulator/simulator/player/StlPlayer.cpp index d80a6157..5b29e773 100644 --- a/src/simulator/simulator/player/StlPlayer.cpp +++ b/src/simulator/simulator/player/StlPlayer.cpp @@ -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); diff --git a/src/simulator/simulator/player/StlPlayer.h b/src/simulator/simulator/player/StlPlayer.h index 409b46cd..2e4b02d0 100644 --- a/src/simulator/simulator/player/StlPlayer.h +++ b/src/simulator/simulator/player/StlPlayer.h @@ -68,7 +68,6 @@ public: Request nextRequest() override; - sc_core::sc_time clkPeriod() override { return playerPeriod; } uint64_t totalRequests() override { return numberOfLines; } private: diff --git a/src/simulator/simulator/request/RequestIssuer.cpp b/src/simulator/simulator/request/RequestIssuer.cpp index 3a8bd7ba..2c96ea37 100644 --- a/src/simulator/simulator/request/RequestIssuer.cpp +++ b/src/simulator/simulator/request/RequestIssuer.cpp @@ -37,6 +37,7 @@ RequestIssuer::RequestIssuer(sc_core::sc_module_name const &name, MemoryManager &memoryManager, + unsigned int clkMhz, std::optional maxPendingReadRequests, std::optional maxPendingWriteRequests, std::function nextRequest, @@ -44,6 +45,7 @@ RequestIssuer::RequestIssuer(sc_core::sc_module_name const &name, std::function terminate) : sc_module(name), memoryManager(memoryManager), + clkPeriod(sc_core::sc_time(1.0 / static_cast(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) diff --git a/src/simulator/simulator/request/RequestIssuer.h b/src/simulator/simulator/request/RequestIssuer.h index 816f8138..2e318bfc 100644 --- a/src/simulator/simulator/request/RequestIssuer.h +++ b/src/simulator/simulator/request/RequestIssuer.h @@ -52,6 +52,7 @@ public: RequestIssuer(sc_core::sc_module_name const &name, MemoryManager &memoryManager, + unsigned int clkMhz, std::optional maxPendingReadRequests, std::optional maxPendingWriteRequests, std::function nextRequest, @@ -63,6 +64,8 @@ private: tlm_utils::peq_with_cb_and_phase payloadEventQueue; MemoryManager &memoryManager; + const sc_core::sc_time clkPeriod; + bool transactionPostponed = false; bool finished = false; diff --git a/src/simulator/simulator/request/RequestProducer.h b/src/simulator/simulator/request/RequestProducer.h index 212f14c6..a7df1935 100644 --- a/src/simulator/simulator/request/RequestProducer.h +++ b/src/simulator/simulator/request/RequestProducer.h @@ -44,6 +44,5 @@ public: virtual Request nextRequest() = 0; virtual uint64_t totalRequests() = 0; - virtual sc_core::sc_time clkPeriod() = 0; virtual void reset(){}; };