From 71551db4e3491db203b3f9da395d6762c33567d5 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Wed, 5 May 2021 16:13:44 +0200 Subject: [PATCH 1/7] Implement a more advanced TraceGenerator Implementation of a more advanced TraceGenerator that can be configured using the Json config file. The new TraceGenerator is capable of specifing the number of requests to make, the ratio of read and write accesses, the distribution of the addresses, the address increment value in case of a sequential address distribution, a seed in case of a random address distribution and the maximum number of pending read or write requests. The maximum number of pending requests was also implemented for the StlPlayer. --- .../simulations/ddr5-generator-example.json | 34 +++++ DRAMSys/simulator/StlPlayer.cpp | 15 +- DRAMSys/simulator/StlPlayer.h | 6 +- DRAMSys/simulator/TraceGenerator.cpp | 70 ++++++++-- DRAMSys/simulator/TraceGenerator.h | 27 +++- DRAMSys/simulator/TracePlayer.cpp | 37 ++++- DRAMSys/simulator/TracePlayer.h | 10 +- DRAMSys/simulator/TraceSetup.cpp | 128 ++++++++++++++---- DRAMSys/simulator/TraceSetup.h | 6 +- DRAMSys/simulator/main.cpp | 2 +- 10 files changed, 284 insertions(+), 51 deletions(-) create mode 100644 DRAMSys/library/resources/simulations/ddr5-generator-example.json diff --git a/DRAMSys/library/resources/simulations/ddr5-generator-example.json b/DRAMSys/library/resources/simulations/ddr5-generator-example.json new file mode 100644 index 00000000..1835e48b --- /dev/null +++ b/DRAMSys/library/resources/simulations/ddr5-generator-example.json @@ -0,0 +1,34 @@ +{ + "simulation": { + "addressmapping": "am_ddr5_2x8x2Gbx4_dimm_p1KB_rbc.json", + "mcconfig": "fr_fcfs.json", + "memspec": "JEDEC_2x8x2Gbx4_DDR5-3200A.json", + "simconfig": "ddr5.json", + "simulationid": "ddr5-example", + "thermalconfig": "config.json", + "tracesetup": [ + { + "clkMhz": 2000, + "type": "generator", + "name": "gen0", + "numRequests": 2000, + "rwRatio": 0.85, + "addressDistribution": "sequential", + "addressIncrement": 256, + "maxPendingReadRequests": 8, + "maxPendingWriteRequests": 8 + }, + { + "clkMhz": 2000, + "type": "generator", + "name": "gen1", + "numRequests": 2000, + "rwRatio": 0.85, + "addressDistribution": "random", + "seed": 123456, + "maxPendingReadRequests": 8, + "maxPendingWriteRequests": 8 + } + ] + } +} diff --git a/DRAMSys/simulator/StlPlayer.cpp b/DRAMSys/simulator/StlPlayer.cpp index 4880b5b0..5303be41 100644 --- a/DRAMSys/simulator/StlPlayer.cpp +++ b/DRAMSys/simulator/StlPlayer.cpp @@ -41,9 +41,11 @@ using namespace tlm; -StlPlayer::StlPlayer(sc_module_name name, - std::string pathToTrace, +StlPlayer::StlPlayer(const sc_module_name &name, + const std::string &pathToTrace, sc_time playerClk, + unsigned int maxPendingReadRequests, + unsigned int maxPendingWriteRequests, TraceSetup *setup, bool relative) : TracePlayer(name, setup), file(pathToTrace), @@ -54,6 +56,9 @@ StlPlayer::StlPlayer(sc_module_name name, if (!file.is_open()) SC_REPORT_FATAL("StlPlayer", (std::string("Could not open trace ") + pathToTrace).c_str()); + this->maxPendingReadRequests = maxPendingReadRequests; + this->maxPendingWriteRequests = maxPendingWriteRequests; + this->playerClk = playerClk; burstlength = Configuration::getInstance().memSpec->burstLength; dataLength = Configuration::getInstance().memSpec->bytesPerBurst; @@ -117,6 +122,12 @@ void StlPlayer::nextPayload() sendToTarget(*payload, BEGIN_REQ, sendingTime - sc_time_stamp()); transactionsSent++; + + if (payload->get_command() == tlm::TLM_READ_COMMAND) + pendingReadRequests++; + else if (payload->get_command() == tlm::TLM_WRITE_COMMAND) + pendingWriteRequests++; + PRINTDEBUGMESSAGE(name(), "Performing request #" + std::to_string(transactionsSent)); lineIterator++; } diff --git a/DRAMSys/simulator/StlPlayer.h b/DRAMSys/simulator/StlPlayer.h index 27081d41..45a1769b 100644 --- a/DRAMSys/simulator/StlPlayer.h +++ b/DRAMSys/simulator/StlPlayer.h @@ -58,9 +58,11 @@ struct LineContent class StlPlayer : public TracePlayer { public: - StlPlayer(sc_module_name name, - std::string pathToTrace, + StlPlayer(const sc_module_name &name, + const std::string &pathToTrace, sc_time playerClk, + unsigned int maxPendingReadRequests, + unsigned int maxPendingWriteRequests, TraceSetup *setup, bool relative); diff --git a/DRAMSys/simulator/TraceGenerator.cpp b/DRAMSys/simulator/TraceGenerator.cpp index b08080ee..8620d0e5 100644 --- a/DRAMSys/simulator/TraceGenerator.cpp +++ b/DRAMSys/simulator/TraceGenerator.cpp @@ -37,40 +37,84 @@ #include "TraceGenerator.h" -TraceGenerator::TraceGenerator(sc_module_name name, - unsigned int fCKMhz, TraceSetup *setup) - : TracePlayer(name, setup), transCounter(0) +TraceGenerator::TraceGenerator(const sc_module_name &name, + const sc_time &tCK, + uint64_t numRequests, + unsigned int maxPendingReadRequests, + unsigned int maxPendingWriteRequests, + float rwRatio, + AddressDistribution addressDistribution, + unsigned int addressIncrement, + unsigned int seed, + TraceSetup *setup) : + TracePlayer(name, setup), tCK(tCK), numRequests(numRequests), + rwRatio(rwRatio), addressDistribution(addressDistribution), + addressIncrement(addressIncrement) { - if (fCKMhz == 0) - tCK = Configuration::getInstance().memSpec->tCK; - else - tCK = sc_time(1.0 / fCKMhz, SC_US); - burstlenght = Configuration::getInstance().memSpec->burstLength; + + this->maxPendingReadRequests = maxPendingReadRequests; + this->maxPendingWriteRequests = maxPendingWriteRequests; + + randomGenerator = std::default_random_engine(seed); + randomAddressDistribution = std::uniform_int_distribution( + 0, Configuration::getInstance().memSpec->getSimMemSizeInBytes()); + } void TraceGenerator::nextPayload() { - if (transCounter >= 1000) // TODO set limit! - terminate(); + if (transCounter >= numRequests) { + finished = true; + return; + } tlm::tlm_generic_payload *payload = setup->allocatePayload(); payload->acquire(); unsigned char *dataElement = new unsigned char[16]; // TODO: column / burst breite - payload->set_address(0x0); + uint64_t address; + if (addressDistribution == AddressDistribution::Sequential) { + address = currentAddress; + currentAddress += addressIncrement; + } else { + // AddressDistribution::Random + address = randomAddressDistribution(randomGenerator); + } + + tlm::tlm_command command; + if (randomRwDistribution(randomGenerator) < rwRatio) { + command = tlm::TLM_READ_COMMAND; + } else { + command = tlm::TLM_WRITE_COMMAND; + } + + payload->set_address(address); payload->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); payload->set_dmi_allowed(false); payload->set_byte_enable_length(0); payload->set_streaming_width(burstlenght); payload->set_data_ptr(dataElement); payload->set_data_length(16); - payload->set_command(tlm::TLM_READ_COMMAND); + payload->set_command(command); transCounter++; + sc_time sendingOffset; + if (lastEndReq == sc_time_stamp()) + sendingOffset = tCK; + else + sendingOffset = SC_ZERO_TIME; + // TODO: do not send two requests in the same cycle - sendToTarget(*payload, tlm::BEGIN_REQ, SC_ZERO_TIME); + 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)); } diff --git a/DRAMSys/simulator/TraceGenerator.h b/DRAMSys/simulator/TraceGenerator.h index 8993e8d3..58cc9006 100644 --- a/DRAMSys/simulator/TraceGenerator.h +++ b/DRAMSys/simulator/TraceGenerator.h @@ -41,16 +41,39 @@ #include "TracePlayer.h" #include "TraceSetup.h" +#include + +enum class AddressDistribution {Sequential, Random}; + class TraceGenerator : public TracePlayer { public: - TraceGenerator(sc_module_name name, unsigned int fCKMhz, TraceSetup *setup); + TraceGenerator(const sc_module_name &name, + const sc_time &tCK, + uint64_t numRequests, + unsigned int maxPendingReadRequests, + unsigned int maxPendingWriteRequests, + float rwRatio, + AddressDistribution addressDistribution, + unsigned int addressIncrement, + unsigned int seed, + TraceSetup *setup); + virtual void nextPayload() override; private: unsigned int burstlenght; sc_time tCK; - unsigned int transCounter; + unsigned int numRequests; + float rwRatio; + AddressDistribution addressDistribution; + unsigned int addressIncrement; + unsigned int transCounter = 0; + unsigned int currentAddress = 0x0; + + std::default_random_engine randomGenerator; + std::uniform_int_distribution randomAddressDistribution; + std::uniform_real_distribution randomRwDistribution = std::uniform_real_distribution(0.0f, 1.0f); }; #endif // TRACEGENERATOR_H diff --git a/DRAMSys/simulator/TracePlayer.cpp b/DRAMSys/simulator/TracePlayer.cpp index 4c588668..393673b6 100644 --- a/DRAMSys/simulator/TracePlayer.cpp +++ b/DRAMSys/simulator/TracePlayer.cpp @@ -74,7 +74,11 @@ void TracePlayer::peqCallback(tlm_generic_payload &payload, if (phase == END_REQ) { lastEndReq = sc_time_stamp(); - nextPayload(); + + if (nextPayloadSendable()) + nextPayload(); + else + payloadPostponed = true; } else if (phase == BEGIN_RESP) { @@ -85,8 +89,19 @@ void TracePlayer::peqCallback(tlm_generic_payload &payload, transactionsReceived++; + if (payload.get_command() == tlm::TLM_READ_COMMAND) + pendingReadRequests--; + else if (payload.get_command() == tlm::TLM_WRITE_COMMAND) + pendingWriteRequests--; + + // If the initiator wasn't able to send the next payload in the END_REQ phase, do it now. + if (payloadPostponed) { + nextPayload(); + payloadPostponed = false; + } + // If all answers were received: - if (finished == true && numberOfTransactions == transactionsReceived) + if (finished == true && transactionsSent == transactionsReceived) terminate(); } else @@ -128,3 +143,21 @@ uint64_t TracePlayer::getNumberOfLines(std::string pathToTrace) return 0; } } + +bool TracePlayer::nextPayloadSendable() +{ + 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; +} diff --git a/DRAMSys/simulator/TracePlayer.h b/DRAMSys/simulator/TracePlayer.h index 7144c95a..c1e15dd5 100644 --- a/DRAMSys/simulator/TracePlayer.h +++ b/DRAMSys/simulator/TracePlayer.h @@ -66,16 +66,24 @@ protected: TraceSetup *setup; void sendToTarget(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase, const sc_time &delay); + uint64_t numberOfTransactions = 0; + uint64_t transactionsReceived = 0; uint64_t transactionsSent = 0; + unsigned int pendingReadRequests = 0; + unsigned int pendingWriteRequests = 0; + unsigned int maxPendingReadRequests = 0; + unsigned int maxPendingWriteRequests = 0; + bool payloadPostponed = false; bool finished = false; sc_time lastEndReq = sc_max_time(); + 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); - uint64_t transactionsReceived = 0; + bool nextPayloadSendable(); }; #endif // TRACEPLAYER_H diff --git a/DRAMSys/simulator/TraceSetup.cpp b/DRAMSys/simulator/TraceSetup.cpp index 871be829..015bd163 100644 --- a/DRAMSys/simulator/TraceSetup.cpp +++ b/DRAMSys/simulator/TraceSetup.cpp @@ -36,12 +36,13 @@ #include "TraceSetup.h" #include "StlPlayer.h" +#include "TraceGenerator.h" using namespace tlm; -TraceSetup::TraceSetup(std::string uri, - std::string pathToResources, - std::vector *players) +TraceSetup::TraceSetup(const std::string &uri, + const std::string &pathToResources, + std::vector &players) { // Load Simulation: nlohmann::json simulationdoc = parseJSON(uri); @@ -53,52 +54,129 @@ TraceSetup::TraceSetup(std::string uri, // Load TracePlayers: if (simulationdoc["simulation"]["tracesetup"].empty()) SC_REPORT_FATAL("TraceSetup", "tracesetup is empty"); - for (auto it : simulationdoc["simulation"]["tracesetup"].items()) + for (auto &it : simulationdoc["simulation"]["tracesetup"].items()) { auto value = it.value(); if (!value.empty()) { sc_time playerClk; + if (!value["clkMhz"].is_number_unsigned()) + SC_REPORT_FATAL("TraceSetup", "Frequency is not a number."); + unsigned int frequencyMHz = value["clkMhz"]; if (frequencyMHz == 0) - SC_REPORT_FATAL("TraceSetup", "No frequency defined"); + SC_REPORT_FATAL("TraceSetup", "Frequency must not be zero."); else playerClk = sc_time(1.0 / frequencyMHz, SC_US); + if (!value["name"].is_string()) + SC_REPORT_FATAL("TraceSetup", "No trace name defined."); + std::string name = value["name"]; - size_t pos = name.rfind('.'); - if (pos == std::string::npos) - throw std::runtime_error("Name of the trace file does not contain a valid extension."); + unsigned int maxPendingReadRequests = 0; + unsigned int maxPendingWriteRequests = 0; - // Get the extension and make it lower case - std::string ext = name.substr(pos + 1); - std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower); + if (value["maxPendingReadRequests"].is_number_unsigned()) + maxPendingReadRequests = value["maxPendingReadRequests"]; - std::string stlFile = pathToResources + std::string("traces/") + name; - std::string moduleName = name; + if (value["maxPendingWriteRequests"].is_number_unsigned()) + maxPendingWriteRequests = value["maxPendingWriteRequests"]; - // replace all '.' to '_' - std::replace(moduleName.begin(), moduleName.end(), '.', '_'); + std::string type; - TracePlayer *player; - if (ext == "stl") - player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, this, false); - else if (ext == "rstl") - player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, this, true); + // Defaulting to type "player" when not specified + if (!value["type"].is_string()) + type = "player"; else - throw std::runtime_error("Unsupported file extension in " + name); + type = value["type"]; - players->push_back(player); + if (type == "player") + { + size_t pos = name.rfind('.'); + if (pos == std::string::npos) + throw std::runtime_error("Name of the trace file does not contain a valid extension."); - if (Configuration::getInstance().simulationProgressBar) - totalTransactions += player->getNumberOfLines(stlFile); + // Get the extension and make it lower case + 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::string moduleName = name; + + // replace all '.' to '_' + std::replace(moduleName.begin(), moduleName.end(), '.', '_'); + + TracePlayer *player; + if (ext == "stl") + player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, + maxPendingReadRequests, maxPendingWriteRequests, this, false); + else if (ext == "rstl") + player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, + maxPendingReadRequests, maxPendingWriteRequests, this, true); + else + throw std::runtime_error("Unsupported file extension in " + name); + + players.push_back(player); + + if (Configuration::getInstance().simulationProgressBar) + totalTransactions += player->getNumberOfLines(stlFile); + } + else if (type == "generator") + { + if (!value["numRequests"].is_number_unsigned()) + SC_REPORT_FATAL("TraceSetup", "Number of requests is not a number."); + + uint64_t numRequests = value["numRequests"]; + + if (!value["rwRatio"].is_number_float()) + SC_REPORT_FATAL("TraceSetup", "Read/Write ratio is not a floating point number."); + + float rwRatio = value["rwRatio"]; + + if (!value["addressDistribution"].is_string()) + SC_REPORT_FATAL("TraceSetup", "Address distribution not defined."); + + AddressDistribution addressDistribution = AddressDistribution::Sequential; + std::string addressDistributionString = value["addressDistribution"]; + if (addressDistributionString == "sequential") + addressDistribution = AddressDistribution::Sequential; + else if (addressDistributionString == "random") + addressDistribution = AddressDistribution::Random; + else + SC_REPORT_FATAL("TraceSetup", "Address distribution must either be sequential or random."); + + unsigned int addressIncrement = 0x0; + unsigned int seed = 0; + if (addressDistribution == AddressDistribution::Sequential) { + if (!value["addressIncrement"].is_number_unsigned()) + SC_REPORT_FATAL("TraceSetup", "Address increment is not a number."); + + addressIncrement = value["addressIncrement"]; + } else { + // addressDistribution == AddressDistribution::Random + if (!value["seed"].is_number_unsigned()) + SC_REPORT_FATAL("TraceSetup", "Seed is not a number."); + + seed = value["seed"]; + } + + TracePlayer *player = new TraceGenerator(name.c_str(), playerClk, numRequests, + maxPendingReadRequests, maxPendingWriteRequests, + rwRatio, addressDistribution, + addressIncrement, seed, this); + + players.push_back(player); + + if (Configuration::getInstance().simulationProgressBar) + totalTransactions += numRequests; + } } } remainingTransactions = totalTransactions; - numberOfTracePlayers = players->size(); + numberOfTracePlayers = players.size(); } void TraceSetup::tracePlayerTerminates() diff --git a/DRAMSys/simulator/TraceSetup.h b/DRAMSys/simulator/TraceSetup.h index 5194c29a..52df9157 100644 --- a/DRAMSys/simulator/TraceSetup.h +++ b/DRAMSys/simulator/TraceSetup.h @@ -46,9 +46,9 @@ class TracePlayer; class TraceSetup { public: - TraceSetup(std::string uri, - std::string pathToResources, - std::vector *devices); + TraceSetup(const std::string &uri, + const std::string &pathToResources, + std::vector &devices); void tracePlayerTerminates(); void transactionFinished(); diff --git a/DRAMSys/simulator/main.cpp b/DRAMSys/simulator/main.cpp index c742527a..40f7fe83 100644 --- a/DRAMSys/simulator/main.cpp +++ b/DRAMSys/simulator/main.cpp @@ -109,7 +109,7 @@ int sc_main(int argc, char **argv) dramSys = new DRAMSys("DRAMSys", simulationJson, resources); // Instantiate STL Players: - TraceSetup *setup = new TraceSetup(simulationJson, resources, &players); + TraceSetup *setup = new TraceSetup(simulationJson, resources, players); // Bind STL Players with DRAMSys: for (size_t i = 0; i < players.size(); i++) From 1a7450386d056997ccad2d63db5e4b367ac840c4 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Fri, 7 May 2021 12:14:38 +0200 Subject: [PATCH 2/7] Remove redundant TracePlayer member variables --- DRAMSys/simulator/StlPlayer.cpp | 2 -- DRAMSys/simulator/TraceGenerator.cpp | 3 +-- DRAMSys/simulator/TraceGenerator.h | 1 - DRAMSys/simulator/TracePlayer.h | 1 - 4 files changed, 1 insertion(+), 6 deletions(-) diff --git a/DRAMSys/simulator/StlPlayer.cpp b/DRAMSys/simulator/StlPlayer.cpp index 5303be41..581fa3e4 100644 --- a/DRAMSys/simulator/StlPlayer.cpp +++ b/DRAMSys/simulator/StlPlayer.cpp @@ -90,8 +90,6 @@ void StlPlayer::nextPayload() } } - numberOfTransactions++; - // Allocate a generic payload for this request. tlm_generic_payload *payload = setup->allocatePayload(); payload->acquire(); diff --git a/DRAMSys/simulator/TraceGenerator.cpp b/DRAMSys/simulator/TraceGenerator.cpp index 8620d0e5..b517aca4 100644 --- a/DRAMSys/simulator/TraceGenerator.cpp +++ b/DRAMSys/simulator/TraceGenerator.cpp @@ -64,7 +64,7 @@ TraceGenerator::TraceGenerator(const sc_module_name &name, void TraceGenerator::nextPayload() { - if (transCounter >= numRequests) { + if (transactionsSent >= numRequests) { finished = true; return; } @@ -98,7 +98,6 @@ void TraceGenerator::nextPayload() payload->set_data_ptr(dataElement); payload->set_data_length(16); payload->set_command(command); - transCounter++; sc_time sendingOffset; if (lastEndReq == sc_time_stamp()) diff --git a/DRAMSys/simulator/TraceGenerator.h b/DRAMSys/simulator/TraceGenerator.h index 58cc9006..8de4db88 100644 --- a/DRAMSys/simulator/TraceGenerator.h +++ b/DRAMSys/simulator/TraceGenerator.h @@ -68,7 +68,6 @@ private: float rwRatio; AddressDistribution addressDistribution; unsigned int addressIncrement; - unsigned int transCounter = 0; unsigned int currentAddress = 0x0; std::default_random_engine randomGenerator; diff --git a/DRAMSys/simulator/TracePlayer.h b/DRAMSys/simulator/TracePlayer.h index c1e15dd5..05076114 100644 --- a/DRAMSys/simulator/TracePlayer.h +++ b/DRAMSys/simulator/TracePlayer.h @@ -67,7 +67,6 @@ protected: void sendToTarget(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase, const sc_time &delay); - uint64_t numberOfTransactions = 0; uint64_t transactionsReceived = 0; uint64_t transactionsSent = 0; unsigned int pendingReadRequests = 0; From 119c4b89297fe7f2752746a422c062181e18d7b3 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Fri, 7 May 2021 12:39:19 +0200 Subject: [PATCH 3/7] Restructure class hierarchy for TrafficInitiators The hierarchy for all TrafficInitiators was reorganized into a more general structure. All TracePlayers and TrafficGenerators inherit from the TrafficInitiator class. The classes TrafficGeneratorSequential and TrafficGeneratorRandom both inherit from the TrafficGenerator class and the StlPlayer inherits from the TracePlayer class. --- DRAMSys/simulator/CMakeLists.txt | 3 +- DRAMSys/simulator/StlPlayer.cpp | 27 ++++ DRAMSys/simulator/StlPlayer.h | 2 + DRAMSys/simulator/TracePlayer.cpp | 132 +---------------- DRAMSys/simulator/TracePlayer.h | 52 +------ DRAMSys/simulator/TraceSetup.cpp | 56 ++++---- DRAMSys/simulator/TraceSetup.h | 10 +- ...raceGenerator.cpp => TrafficGenerator.cpp} | 80 +++++++---- .../{TraceGenerator.h => TrafficGenerator.h} | 76 +++++++--- DRAMSys/simulator/TrafficInitiator.cpp | 136 ++++++++++++++++++ DRAMSys/simulator/TrafficInitiator.h | 87 +++++++++++ DRAMSys/simulator/main.cpp | 4 +- 12 files changed, 408 insertions(+), 257 deletions(-) rename DRAMSys/simulator/{TraceGenerator.cpp => TrafficGenerator.cpp} (58%) rename DRAMSys/simulator/{TraceGenerator.h => TrafficGenerator.h} (55%) create mode 100644 DRAMSys/simulator/TrafficInitiator.cpp create mode 100644 DRAMSys/simulator/TrafficInitiator.h diff --git a/DRAMSys/simulator/CMakeLists.txt b/DRAMSys/simulator/CMakeLists.txt index 1b3a9851..99bf9328 100644 --- a/DRAMSys/simulator/CMakeLists.txt +++ b/DRAMSys/simulator/CMakeLists.txt @@ -46,8 +46,9 @@ add_executable(DRAMSys ExampleInitiator.h MemoryManager.cpp StlPlayer.cpp - TraceGenerator.cpp TracePlayer.cpp + TrafficGenerator.cpp + TrafficInitiator.cpp TraceSetup.cpp ) diff --git a/DRAMSys/simulator/StlPlayer.cpp b/DRAMSys/simulator/StlPlayer.cpp index 581fa3e4..bdae637d 100644 --- a/DRAMSys/simulator/StlPlayer.cpp +++ b/DRAMSys/simulator/StlPlayer.cpp @@ -230,3 +230,30 @@ std::vector::const_iterator StlPlayer::swapBuffers() return currentBuffer->cbegin(); } + +uint64_t StlPlayer::getNumberOfLines(const std::string &pathToTrace) +{ + 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; + } +} diff --git a/DRAMSys/simulator/StlPlayer.h b/DRAMSys/simulator/StlPlayer.h index 45a1769b..d203963d 100644 --- a/DRAMSys/simulator/StlPlayer.h +++ b/DRAMSys/simulator/StlPlayer.h @@ -70,6 +70,8 @@ public: virtual void nextPayload() override; + uint64_t getNumberOfLines(const std::string &pathToTrace); + private: void parseTraceFile(); std::vector::const_iterator swapBuffers(); diff --git a/DRAMSys/simulator/TracePlayer.cpp b/DRAMSys/simulator/TracePlayer.cpp index 393673b6..b262bd1c 100644 --- a/DRAMSys/simulator/TracePlayer.cpp +++ b/DRAMSys/simulator/TracePlayer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Technische Universität Kaiserslautern + * Copyright (c) 2021, Technische Universität Kaiserslautern * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,135 +29,13 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Authors: - * Robert Gernhardt - * Matthias Jung - * Éder F. Zulian - * Felipe S. Prado + * Author: + * Derek Christ */ #include "TracePlayer.h" -#include "TraceSetup.h" -using namespace tlm; - -TracePlayer::TracePlayer(sc_module_name name, TraceSetup *setup) : - sc_module(name), - payloadEventQueue(this, &TracePlayer::peqCallback), - setup(setup) +TracePlayer::TracePlayer(const sc_core::sc_module_name &name, TraceSetup *setup) : + TrafficInitiator(name, setup) { - SC_METHOD(nextPayload); - iSocket.register_nb_transport_bw(this, &TracePlayer::nb_transport_bw); - - if (Configuration::getInstance().storeMode == Configuration::StoreMode::NoStorage) - storageEnabled = false; - else - storageEnabled = true; -} - -void TracePlayer::terminate() -{ - std::cout << sc_time_stamp() << " " << this->name() << " terminated " << std::endl; - setup->tracePlayerTerminates(); -} - -tlm_sync_enum TracePlayer::nb_transport_bw(tlm_generic_payload &payload, - tlm_phase &phase, sc_time &bwDelay) -{ - payloadEventQueue.notify(payload, phase, bwDelay); - return TLM_ACCEPTED; -} - -void TracePlayer::peqCallback(tlm_generic_payload &payload, - const tlm_phase &phase) -{ - if (phase == END_REQ) - { - lastEndReq = sc_time_stamp(); - - if (nextPayloadSendable()) - nextPayload(); - else - payloadPostponed = true; - } - else if (phase == BEGIN_RESP) - { - payload.release(); - sendToTarget(payload, END_RESP, SC_ZERO_TIME); - if (Configuration::getInstance().simulationProgressBar) - setup->transactionFinished(); - - transactionsReceived++; - - if (payload.get_command() == tlm::TLM_READ_COMMAND) - pendingReadRequests--; - else if (payload.get_command() == tlm::TLM_WRITE_COMMAND) - pendingWriteRequests--; - - // If the initiator wasn't able to send the next payload in the END_REQ phase, do it now. - if (payloadPostponed) { - nextPayload(); - payloadPostponed = false; - } - - // If all answers were received: - if (finished == true && transactionsSent == transactionsReceived) - terminate(); - } - else - { - SC_REPORT_FATAL("TracePlayer", "PEQ was triggered with unknown phase"); - } -} - -void TracePlayer::sendToTarget(tlm_generic_payload &payload, const tlm_phase &phase, const sc_time &delay) -{ - tlm_phase TPhase = phase; - sc_time TDelay = delay; - iSocket->nb_transport_fw(payload, TPhase, TDelay); -} - -uint64_t TracePlayer::getNumberOfLines(std::string pathToTrace) -{ - 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("TracePlayer", "Trace file is empty"); - return lineCount; - } - else - { - SC_REPORT_FATAL("TracePlayer", "Unable to open trace file"); - return 0; - } -} - -bool TracePlayer::nextPayloadSendable() -{ - 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; } diff --git a/DRAMSys/simulator/TracePlayer.h b/DRAMSys/simulator/TracePlayer.h index 05076114..23f0729b 100644 --- a/DRAMSys/simulator/TracePlayer.h +++ b/DRAMSys/simulator/TracePlayer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Technische Universität Kaiserslautern + * Copyright (c) 2021, Technische Universität Kaiserslautern * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,60 +29,20 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Authors: - * Robert Gernhardt - * Matthias Jung - * Éder F. Zulian - * Felipe S. Prado + * Author: + * Derek Christ */ #ifndef TRACEPLAYER_H #define TRACEPLAYER_H -#include -#include #include -#include -#include -#include -#include -#include "configuration/Configuration.h" -#include "common/DebugManager.h" -#include "TraceSetup.h" +#include "TrafficInitiator.h" -class TracePlayer : public sc_module +class TracePlayer : public TrafficInitiator { -public: - tlm_utils::simple_initiator_socket iSocket; - TracePlayer(sc_module_name name, TraceSetup *setup); - SC_HAS_PROCESS(TracePlayer); - virtual void nextPayload() = 0; - uint64_t getNumberOfLines(std::string pathToTrace); - protected: - tlm_utils::peq_with_cb_and_phase payloadEventQueue; - void terminate(); - bool storageEnabled = false; - TraceSetup *setup; - void sendToTarget(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase, - const sc_time &delay); - - uint64_t transactionsReceived = 0; - uint64_t transactionsSent = 0; - unsigned int pendingReadRequests = 0; - unsigned int pendingWriteRequests = 0; - unsigned int maxPendingReadRequests = 0; - unsigned int maxPendingWriteRequests = 0; - bool payloadPostponed = false; - bool finished = false; - sc_time lastEndReq = sc_max_time(); - 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(); + TracePlayer(const sc_module_name &name, TraceSetup *setup); }; #endif // TRACEPLAYER_H diff --git a/DRAMSys/simulator/TraceSetup.cpp b/DRAMSys/simulator/TraceSetup.cpp index 015bd163..64676389 100644 --- a/DRAMSys/simulator/TraceSetup.cpp +++ b/DRAMSys/simulator/TraceSetup.cpp @@ -36,13 +36,13 @@ #include "TraceSetup.h" #include "StlPlayer.h" -#include "TraceGenerator.h" +#include "TrafficGenerator.h" using namespace tlm; TraceSetup::TraceSetup(const std::string &uri, const std::string &pathToResources, - std::vector &players) + std::vector &players) { // Load Simulation: nlohmann::json simulationdoc = parseJSON(uri); @@ -51,7 +51,7 @@ TraceSetup::TraceSetup(const std::string &uri, SC_REPORT_FATAL("TraceSetup", "Cannot load simulation: simulation node expected"); - // Load TracePlayers: + // Load TrafficInitiators: if (simulationdoc["simulation"]["tracesetup"].empty()) SC_REPORT_FATAL("TraceSetup", "tracesetup is empty"); for (auto &it : simulationdoc["simulation"]["tracesetup"].items()) @@ -108,7 +108,7 @@ TraceSetup::TraceSetup(const std::string &uri, // replace all '.' to '_' std::replace(moduleName.begin(), moduleName.end(), '.', '_'); - TracePlayer *player; + StlPlayer *player; if (ext == "stl") player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, maxPendingReadRequests, maxPendingWriteRequests, this, false); @@ -138,36 +138,36 @@ TraceSetup::TraceSetup(const std::string &uri, if (!value["addressDistribution"].is_string()) SC_REPORT_FATAL("TraceSetup", "Address distribution not defined."); - AddressDistribution addressDistribution = AddressDistribution::Sequential; - std::string addressDistributionString = value["addressDistribution"]; - if (addressDistributionString == "sequential") - addressDistribution = AddressDistribution::Sequential; - else if (addressDistributionString == "random") - addressDistribution = AddressDistribution::Random; - else + std::string addressDistribution = value["addressDistribution"]; + if (addressDistribution != "sequential" && addressDistribution != "random") SC_REPORT_FATAL("TraceSetup", "Address distribution must either be sequential or random."); - unsigned int addressIncrement = 0x0; unsigned int seed = 0; - if (addressDistribution == AddressDistribution::Sequential) { + if (value["seed"].is_number_unsigned()) + seed = value["seed"]; + + TrafficGenerator *generator; + + if (addressDistribution == "sequential") + { + unsigned int addressIncrement = 0x0; if (!value["addressIncrement"].is_number_unsigned()) SC_REPORT_FATAL("TraceSetup", "Address increment is not a number."); addressIncrement = value["addressIncrement"]; - } else { - // addressDistribution == AddressDistribution::Random - if (!value["seed"].is_number_unsigned()) - SC_REPORT_FATAL("TraceSetup", "Seed is not a number."); - seed = value["seed"]; + generator = new TrafficGeneratorSequential(name.c_str(), playerClk, numRequests, + maxPendingReadRequests, maxPendingWriteRequests, + rwRatio, addressIncrement, seed, this); + } + else + { + generator = new TrafficGeneratorRandom(name.c_str(), playerClk, numRequests, + maxPendingReadRequests, maxPendingWriteRequests, + rwRatio, seed, this); } - TracePlayer *player = new TraceGenerator(name.c_str(), playerClk, numRequests, - maxPendingReadRequests, maxPendingWriteRequests, - rwRatio, addressDistribution, - addressIncrement, seed, this); - - players.push_back(player); + players.push_back(generator); if (Configuration::getInstance().simulationProgressBar) totalTransactions += numRequests; @@ -176,14 +176,14 @@ TraceSetup::TraceSetup(const std::string &uri, } remainingTransactions = totalTransactions; - numberOfTracePlayers = players.size(); + numberOfTrafficInitiators = players.size(); } -void TraceSetup::tracePlayerTerminates() +void TraceSetup::trafficInitiatorTerminates() { - finishedTracePlayers++; + finishedTrafficInitiators++; - if (finishedTracePlayers == numberOfTracePlayers) + if (finishedTrafficInitiators == numberOfTrafficInitiators) sc_stop(); } diff --git a/DRAMSys/simulator/TraceSetup.h b/DRAMSys/simulator/TraceSetup.h index 52df9157..2a0964ec 100644 --- a/DRAMSys/simulator/TraceSetup.h +++ b/DRAMSys/simulator/TraceSetup.h @@ -41,24 +41,24 @@ #include #include "MemoryManager.h" -class TracePlayer; +class TrafficInitiator; class TraceSetup { public: TraceSetup(const std::string &uri, const std::string &pathToResources, - std::vector &devices); + std::vector &devices); - void tracePlayerTerminates(); + void trafficInitiatorTerminates(); void transactionFinished(); tlm::tlm_generic_payload *allocatePayload(); private: - unsigned int numberOfTracePlayers; + unsigned int numberOfTrafficInitiators; uint64_t totalTransactions = 0; uint64_t remainingTransactions; - unsigned int finishedTracePlayers = 0; + unsigned int finishedTrafficInitiators = 0; MemoryManager memoryManager; void loadbar(uint64_t x, uint64_t n, unsigned int w = 50, unsigned int granularity = 1); diff --git a/DRAMSys/simulator/TraceGenerator.cpp b/DRAMSys/simulator/TrafficGenerator.cpp similarity index 58% rename from DRAMSys/simulator/TraceGenerator.cpp rename to DRAMSys/simulator/TrafficGenerator.cpp index b517aca4..6ab72320 100644 --- a/DRAMSys/simulator/TraceGenerator.cpp +++ b/DRAMSys/simulator/TrafficGenerator.cpp @@ -35,21 +35,18 @@ * Matthias Jung */ -#include "TraceGenerator.h" +#include "TrafficGenerator.h" -TraceGenerator::TraceGenerator(const sc_module_name &name, - const sc_time &tCK, - uint64_t numRequests, - unsigned int maxPendingReadRequests, - unsigned int maxPendingWriteRequests, - float rwRatio, - AddressDistribution addressDistribution, - unsigned int addressIncrement, - unsigned int seed, - TraceSetup *setup) : - TracePlayer(name, setup), tCK(tCK), numRequests(numRequests), - rwRatio(rwRatio), addressDistribution(addressDistribution), - addressIncrement(addressIncrement) +TrafficGenerator::TrafficGenerator(const sc_module_name &name, + const sc_time &tCK, + 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) { burstlenght = Configuration::getInstance().memSpec->burstLength; @@ -57,12 +54,9 @@ TraceGenerator::TraceGenerator(const sc_module_name &name, this->maxPendingWriteRequests = maxPendingWriteRequests; randomGenerator = std::default_random_engine(seed); - randomAddressDistribution = std::uniform_int_distribution( - 0, Configuration::getInstance().memSpec->getSimMemSizeInBytes()); - } -void TraceGenerator::nextPayload() +void TrafficGenerator::nextPayload() { if (transactionsSent >= numRequests) { finished = true; @@ -74,14 +68,7 @@ void TraceGenerator::nextPayload() unsigned char *dataElement = new unsigned char[16]; // TODO: column / burst breite - uint64_t address; - if (addressDistribution == AddressDistribution::Sequential) { - address = currentAddress; - currentAddress += addressIncrement; - } else { - // AddressDistribution::Random - address = randomAddressDistribution(randomGenerator); - } + uint64_t address = getNextAddress(); tlm::tlm_command command; if (randomRwDistribution(randomGenerator) < rwRatio) { @@ -117,3 +104,44 @@ void TraceGenerator::nextPayload() PRINTDEBUGMESSAGE(name(), "Performing request #" + std::to_string(transactionsSent)); } + +TrafficGeneratorRandom::TrafficGeneratorRandom(const sc_core::sc_module_name &name, + const sc_core::sc_time &tCK, + uint64_t numRequests, + unsigned int maxPendingReadRequests, + unsigned int maxPendingWriteRequests, + float rwRatio, + unsigned int seed, + TraceSetup *setup) : + TrafficGenerator(name, tCK, numRequests, maxPendingReadRequests, + maxPendingWriteRequests, rwRatio, seed, setup) +{ + randomAddressDistribution = std::uniform_int_distribution( + 0, Configuration::getInstance().memSpec->getSimMemSizeInBytes()); +} + +uint64_t TrafficGeneratorRandom::getNextAddress() +{ + return randomAddressDistribution(randomGenerator); +} + +TrafficGeneratorSequential::TrafficGeneratorSequential(const sc_core::sc_module_name &name, + const sc_core::sc_time &tCK, + uint64_t numRequests, + unsigned int maxPendingReadRequests, + unsigned int maxPendingWriteRequests, + float rwRatio, unsigned int addressIncrement, + unsigned int seed, + TraceSetup *setup) : + TrafficGenerator(name, tCK, numRequests, maxPendingReadRequests, + maxPendingWriteRequests, rwRatio, seed, setup), + addressIncrement(addressIncrement) +{ +} + +uint64_t TrafficGeneratorSequential::getNextAddress() +{ + uint64_t address = currentAddress; + currentAddress += addressIncrement; + return address; +} diff --git a/DRAMSys/simulator/TraceGenerator.h b/DRAMSys/simulator/TrafficGenerator.h similarity index 55% rename from DRAMSys/simulator/TraceGenerator.h rename to DRAMSys/simulator/TrafficGenerator.h index 8de4db88..828faaad 100644 --- a/DRAMSys/simulator/TraceGenerator.h +++ b/DRAMSys/simulator/TrafficGenerator.h @@ -35,45 +35,77 @@ * Matthias Jung */ -#ifndef TRACEGENERATOR_H -#define TRACEGENERATOR_H +#ifndef TRAFFICGENERATOR_H +#define TRAFFICGENERATOR_H -#include "TracePlayer.h" +#include "TrafficInitiator.h" #include "TraceSetup.h" #include -enum class AddressDistribution {Sequential, Random}; - -class TraceGenerator : public TracePlayer +class TrafficGenerator : public TrafficInitiator { -public: - TraceGenerator(const sc_module_name &name, - const sc_time &tCK, - uint64_t numRequests, - unsigned int maxPendingReadRequests, - unsigned int maxPendingWriteRequests, - float rwRatio, - AddressDistribution addressDistribution, - unsigned int addressIncrement, - unsigned int seed, - TraceSetup *setup); +protected: + TrafficGenerator(const sc_module_name &name, + const sc_time &tCK, + uint64_t numRequests, + unsigned int maxPendingReadRequests, + unsigned int maxPendingWriteRequests, + float rwRatio, + unsigned int seed, + TraceSetup *setup); virtual void nextPayload() override; + virtual uint64_t getNextAddress() = 0; + + std::default_random_engine randomGenerator; private: unsigned int burstlenght; sc_time tCK; unsigned int numRequests; float rwRatio; - AddressDistribution addressDistribution; unsigned int addressIncrement; - unsigned int currentAddress = 0x0; - std::default_random_engine randomGenerator; - std::uniform_int_distribution randomAddressDistribution; std::uniform_real_distribution randomRwDistribution = std::uniform_real_distribution(0.0f, 1.0f); }; -#endif // TRACEGENERATOR_H +class TrafficGeneratorRandom final : public TrafficGenerator +{ +public: + TrafficGeneratorRandom(const sc_module_name &name, + const sc_time &tCK, + uint64_t numRequests, + unsigned int maxPendingReadRequests, + unsigned int maxPendingWriteRequests, + float rwRatio, + unsigned int seed, + TraceSetup *setup); +private: + virtual uint64_t getNextAddress() override; + + std::uniform_int_distribution randomAddressDistribution; +}; + +class TrafficGeneratorSequential final : public TrafficGenerator +{ +public: + TrafficGeneratorSequential(const sc_module_name &name, + const sc_time &tCK, + uint64_t numRequests, + unsigned int maxPendingReadRequests, + unsigned int maxPendingWriteRequests, + float rwRatio, + unsigned int addressIncrement, + unsigned int seed, + TraceSetup *setup); + +private: + virtual uint64_t getNextAddress() override; + + unsigned int currentAddress = 0x0; + unsigned int addressIncrement; +}; + +#endif // TRAFFICGENERATOR_H diff --git a/DRAMSys/simulator/TrafficInitiator.cpp b/DRAMSys/simulator/TrafficInitiator.cpp new file mode 100644 index 00000000..f646e0c9 --- /dev/null +++ b/DRAMSys/simulator/TrafficInitiator.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2015, Technische Universität Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Robert Gernhardt + * Matthias Jung + * Éder F. Zulian + * Felipe S. Prado + */ + +#include "TrafficInitiator.h" +#include "TraceSetup.h" + +using namespace tlm; + +TrafficInitiator::TrafficInitiator(const sc_module_name &name, TraceSetup *setup) : + sc_module(name), + payloadEventQueue(this, &TrafficInitiator::peqCallback), + setup(setup) +{ + SC_METHOD(nextPayload); + iSocket.register_nb_transport_bw(this, &TrafficInitiator::nb_transport_bw); + + if (Configuration::getInstance().storeMode == Configuration::StoreMode::NoStorage) + storageEnabled = false; + else + storageEnabled = true; +} + +void TrafficInitiator::terminate() +{ + std::cout << sc_time_stamp() << " " << this->name() << " terminated " << std::endl; + setup->trafficInitiatorTerminates(); +} + +tlm_sync_enum TrafficInitiator::nb_transport_bw(tlm_generic_payload &payload, + tlm_phase &phase, sc_time &bwDelay) +{ + payloadEventQueue.notify(payload, phase, bwDelay); + return TLM_ACCEPTED; +} + +void TrafficInitiator::peqCallback(tlm_generic_payload &payload, + const tlm_phase &phase) +{ + if (phase == END_REQ) + { + lastEndReq = sc_time_stamp(); + + if (nextPayloadSendable()) + nextPayload(); + else + payloadPostponed = true; + } + else if (phase == BEGIN_RESP) + { + payload.release(); + sendToTarget(payload, END_RESP, SC_ZERO_TIME); + if (Configuration::getInstance().simulationProgressBar) + setup->transactionFinished(); + + transactionsReceived++; + + if (payload.get_command() == tlm::TLM_READ_COMMAND) + pendingReadRequests--; + else if (payload.get_command() == tlm::TLM_WRITE_COMMAND) + pendingWriteRequests--; + + // If the initiator wasn't able to send the next payload in the END_REQ phase, do it now. + if (payloadPostponed) { + nextPayload(); + payloadPostponed = false; + } + + // If all answers were received: + if (finished == true && transactionsSent == transactionsReceived) + terminate(); + } + else + { + SC_REPORT_FATAL("TrafficInitiator", "PEQ was triggered with unknown phase"); + } +} + +void TrafficInitiator::sendToTarget(tlm_generic_payload &payload, const tlm_phase &phase, const sc_time &delay) +{ + tlm_phase TPhase = phase; + sc_time TDelay = delay; + iSocket->nb_transport_fw(payload, TPhase, TDelay); +} + +bool TrafficInitiator::nextPayloadSendable() +{ + 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; +} diff --git a/DRAMSys/simulator/TrafficInitiator.h b/DRAMSys/simulator/TrafficInitiator.h new file mode 100644 index 00000000..ae75f76e --- /dev/null +++ b/DRAMSys/simulator/TrafficInitiator.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2015, Technische Universität Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Robert Gernhardt + * Matthias Jung + * Éder F. Zulian + * Felipe S. Prado + */ + +#ifndef TRAFFICINITIATOR_H +#define TRAFFICINITIATOR_H + +#include +#include +#include +#include +#include +#include +#include +#include "configuration/Configuration.h" +#include "common/DebugManager.h" +#include "TraceSetup.h" + +class TrafficInitiator : public sc_module +{ +public: + tlm_utils::simple_initiator_socket iSocket; + TrafficInitiator(const sc_module_name &name, TraceSetup *setup); + SC_HAS_PROCESS(TrafficInitiator); + virtual void nextPayload() = 0; + +protected: + tlm_utils::peq_with_cb_and_phase payloadEventQueue; + void terminate(); + bool storageEnabled = false; + TraceSetup *setup; + void sendToTarget(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase, + const sc_time &delay); + + uint64_t transactionsReceived = 0; + uint64_t transactionsSent = 0; + unsigned int pendingReadRequests = 0; + unsigned int pendingWriteRequests = 0; + unsigned int maxPendingReadRequests = 0; + unsigned int maxPendingWriteRequests = 0; + bool payloadPostponed = false; + bool finished = false; + sc_time lastEndReq = sc_max_time(); + 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(); +}; + +#endif // TRAFFICINITIATOR_H diff --git a/DRAMSys/simulator/main.cpp b/DRAMSys/simulator/main.cpp index 40f7fe83..3050f15c 100644 --- a/DRAMSys/simulator/main.cpp +++ b/DRAMSys/simulator/main.cpp @@ -45,7 +45,7 @@ #include "simulation/DRAMSys.h" #include "TraceSetup.h" -#include "TracePlayer.h" +#include "TrafficInitiator.h" #ifdef RECORDING #include "simulation/DRAMSysRecordable.h" @@ -93,7 +93,7 @@ int sc_main(int argc, char **argv) resources = argv[2]; } - std::vector players; + std::vector players; // Instantiate DRAMSys: DRAMSys *dramSys; From fdacb97c9b000638c8a211769ceaac9a6152e36f Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Mon, 17 May 2021 10:29:05 +0200 Subject: [PATCH 4/7] Update authors in TrafficInitiator sources --- DRAMSys/simulator/CMakeLists.txt | 1 + DRAMSys/simulator/StlPlayer.cpp | 1 + DRAMSys/simulator/StlPlayer.h | 1 + DRAMSys/simulator/TraceSetup.cpp | 1 + DRAMSys/simulator/TraceSetup.h | 1 + DRAMSys/simulator/TrafficGenerator.cpp | 1 + DRAMSys/simulator/TrafficGenerator.h | 1 + DRAMSys/simulator/TrafficInitiator.cpp | 1 + DRAMSys/simulator/TrafficInitiator.h | 1 + 9 files changed, 9 insertions(+) diff --git a/DRAMSys/simulator/CMakeLists.txt b/DRAMSys/simulator/CMakeLists.txt index 99bf9328..ff12803b 100644 --- a/DRAMSys/simulator/CMakeLists.txt +++ b/DRAMSys/simulator/CMakeLists.txt @@ -31,6 +31,7 @@ # Authors: # Matthias Jung # Lukas Steiner +# Derek Christ cmake_minimum_required(VERSION 3.10) diff --git a/DRAMSys/simulator/StlPlayer.cpp b/DRAMSys/simulator/StlPlayer.cpp index bdae637d..f0b5e48e 100644 --- a/DRAMSys/simulator/StlPlayer.cpp +++ b/DRAMSys/simulator/StlPlayer.cpp @@ -35,6 +35,7 @@ * Matthias Jung * Éder F. Zulian * Felipe S. Prado + * Derek Christ */ #include "StlPlayer.h" diff --git a/DRAMSys/simulator/StlPlayer.h b/DRAMSys/simulator/StlPlayer.h index d203963d..76c3199f 100644 --- a/DRAMSys/simulator/StlPlayer.h +++ b/DRAMSys/simulator/StlPlayer.h @@ -35,6 +35,7 @@ * Matthias Jung * Éder F. Zulian * Felipe S. Prado + * Derek Christ */ #ifndef STLPLAYER_H diff --git a/DRAMSys/simulator/TraceSetup.cpp b/DRAMSys/simulator/TraceSetup.cpp index 64676389..855581c7 100644 --- a/DRAMSys/simulator/TraceSetup.cpp +++ b/DRAMSys/simulator/TraceSetup.cpp @@ -32,6 +32,7 @@ * Authors: * Matthias Jung * Luiza Correa + * Derek Christ */ #include "TraceSetup.h" diff --git a/DRAMSys/simulator/TraceSetup.h b/DRAMSys/simulator/TraceSetup.h index 2a0964ec..da328b6f 100644 --- a/DRAMSys/simulator/TraceSetup.h +++ b/DRAMSys/simulator/TraceSetup.h @@ -31,6 +31,7 @@ * * Authors: * Matthias Jung + * Derek Christ */ #ifndef TRACESETUP_H diff --git a/DRAMSys/simulator/TrafficGenerator.cpp b/DRAMSys/simulator/TrafficGenerator.cpp index 6ab72320..84855284 100644 --- a/DRAMSys/simulator/TrafficGenerator.cpp +++ b/DRAMSys/simulator/TrafficGenerator.cpp @@ -33,6 +33,7 @@ * Janik Schlemminger * Robert Gernhardt * Matthias Jung + * Derek Christ */ #include "TrafficGenerator.h" diff --git a/DRAMSys/simulator/TrafficGenerator.h b/DRAMSys/simulator/TrafficGenerator.h index 828faaad..d7732d09 100644 --- a/DRAMSys/simulator/TrafficGenerator.h +++ b/DRAMSys/simulator/TrafficGenerator.h @@ -33,6 +33,7 @@ * Janik Schlemminger * Robert Gernhardt * Matthias Jung + * Derek Christ */ #ifndef TRAFFICGENERATOR_H diff --git a/DRAMSys/simulator/TrafficInitiator.cpp b/DRAMSys/simulator/TrafficInitiator.cpp index f646e0c9..865da77e 100644 --- a/DRAMSys/simulator/TrafficInitiator.cpp +++ b/DRAMSys/simulator/TrafficInitiator.cpp @@ -34,6 +34,7 @@ * Matthias Jung * Éder F. Zulian * Felipe S. Prado + * Derek Christ */ #include "TrafficInitiator.h" diff --git a/DRAMSys/simulator/TrafficInitiator.h b/DRAMSys/simulator/TrafficInitiator.h index ae75f76e..c0408385 100644 --- a/DRAMSys/simulator/TrafficInitiator.h +++ b/DRAMSys/simulator/TrafficInitiator.h @@ -34,6 +34,7 @@ * Matthias Jung * Éder F. Zulian * Felipe S. Prado + * Derek Christ */ #ifndef TRAFFICINITIATOR_H From 1d5bd72c603cf5ad2e343b565c41634d8c291386 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Wed, 19 May 2021 11:37:05 +0200 Subject: [PATCH 5/7] Apply minor changes to TrafficInitiator and TrafficGenerator --- DRAMSys/simulator/CMakeLists.txt | 1 - DRAMSys/simulator/StlPlayer.cpp | 2 +- DRAMSys/simulator/StlPlayer.h | 4 +-- DRAMSys/simulator/TracePlayer.cpp | 41 ---------------------- DRAMSys/simulator/TracePlayer.h | 48 -------------------------- DRAMSys/simulator/TraceSetup.cpp | 2 +- DRAMSys/simulator/TrafficGenerator.cpp | 13 ++++--- DRAMSys/simulator/TrafficGenerator.h | 9 +++-- DRAMSys/simulator/TrafficInitiator.cpp | 3 +- 9 files changed, 19 insertions(+), 104 deletions(-) delete mode 100644 DRAMSys/simulator/TracePlayer.cpp delete mode 100644 DRAMSys/simulator/TracePlayer.h diff --git a/DRAMSys/simulator/CMakeLists.txt b/DRAMSys/simulator/CMakeLists.txt index ff12803b..dac282fe 100644 --- a/DRAMSys/simulator/CMakeLists.txt +++ b/DRAMSys/simulator/CMakeLists.txt @@ -47,7 +47,6 @@ add_executable(DRAMSys ExampleInitiator.h MemoryManager.cpp StlPlayer.cpp - TracePlayer.cpp TrafficGenerator.cpp TrafficInitiator.cpp TraceSetup.cpp diff --git a/DRAMSys/simulator/StlPlayer.cpp b/DRAMSys/simulator/StlPlayer.cpp index f0b5e48e..24e4a5d6 100644 --- a/DRAMSys/simulator/StlPlayer.cpp +++ b/DRAMSys/simulator/StlPlayer.cpp @@ -49,7 +49,7 @@ StlPlayer::StlPlayer(const sc_module_name &name, unsigned int maxPendingWriteRequests, TraceSetup *setup, bool relative) - : TracePlayer(name, setup), file(pathToTrace), + : TrafficInitiator(name, setup), file(pathToTrace), currentBuffer(&lineContents[0]), parseBuffer(&lineContents[1]), relative(relative) diff --git a/DRAMSys/simulator/StlPlayer.h b/DRAMSys/simulator/StlPlayer.h index 76c3199f..ba48619d 100644 --- a/DRAMSys/simulator/StlPlayer.h +++ b/DRAMSys/simulator/StlPlayer.h @@ -46,7 +46,7 @@ #include #include #include "TraceSetup.h" -#include "TracePlayer.h" +#include "TrafficInitiator.h" struct LineContent { @@ -56,7 +56,7 @@ struct LineContent std::vector data; }; -class StlPlayer : public TracePlayer +class StlPlayer : public TrafficInitiator { public: StlPlayer(const sc_module_name &name, diff --git a/DRAMSys/simulator/TracePlayer.cpp b/DRAMSys/simulator/TracePlayer.cpp deleted file mode 100644 index b262bd1c..00000000 --- a/DRAMSys/simulator/TracePlayer.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2021, Technische Universität Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Author: - * Derek Christ - */ - -#include "TracePlayer.h" - -TracePlayer::TracePlayer(const sc_core::sc_module_name &name, TraceSetup *setup) : - TrafficInitiator(name, setup) -{ -} diff --git a/DRAMSys/simulator/TracePlayer.h b/DRAMSys/simulator/TracePlayer.h deleted file mode 100644 index 23f0729b..00000000 --- a/DRAMSys/simulator/TracePlayer.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2021, Technische Universität Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Author: - * Derek Christ - */ - -#ifndef TRACEPLAYER_H -#define TRACEPLAYER_H - -#include -#include "TrafficInitiator.h" - -class TracePlayer : public TrafficInitiator -{ -protected: - TracePlayer(const sc_module_name &name, TraceSetup *setup); -}; - -#endif // TRACEPLAYER_H diff --git a/DRAMSys/simulator/TraceSetup.cpp b/DRAMSys/simulator/TraceSetup.cpp index 855581c7..ba23072e 100644 --- a/DRAMSys/simulator/TraceSetup.cpp +++ b/DRAMSys/simulator/TraceSetup.cpp @@ -151,7 +151,7 @@ TraceSetup::TraceSetup(const std::string &uri, if (addressDistribution == "sequential") { - unsigned int addressIncrement = 0x0; + uint64_t addressIncrement = 0x0; if (!value["addressIncrement"].is_number_unsigned()) SC_REPORT_FATAL("TraceSetup", "Address increment is not a number."); diff --git a/DRAMSys/simulator/TrafficGenerator.cpp b/DRAMSys/simulator/TrafficGenerator.cpp index 84855284..51c7751f 100644 --- a/DRAMSys/simulator/TrafficGenerator.cpp +++ b/DRAMSys/simulator/TrafficGenerator.cpp @@ -59,7 +59,8 @@ TrafficGenerator::TrafficGenerator(const sc_module_name &name, void TrafficGenerator::nextPayload() { - if (transactionsSent >= numRequests) { + if (transactionsSent >= numRequests) + { finished = true; return; } @@ -72,9 +73,12 @@ void TrafficGenerator::nextPayload() uint64_t address = getNextAddress(); tlm::tlm_command command; - if (randomRwDistribution(randomGenerator) < rwRatio) { + if (randomRwDistribution(randomGenerator) < rwRatio) + { command = tlm::TLM_READ_COMMAND; - } else { + } + else + { command = tlm::TLM_WRITE_COMMAND; } @@ -131,7 +135,8 @@ TrafficGeneratorSequential::TrafficGeneratorSequential(const sc_core::sc_module_ uint64_t numRequests, unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests, - float rwRatio, unsigned int addressIncrement, + float rwRatio, + uint64_t addressIncrement, unsigned int seed, TraceSetup *setup) : TrafficGenerator(name, tCK, numRequests, maxPendingReadRequests, diff --git a/DRAMSys/simulator/TrafficGenerator.h b/DRAMSys/simulator/TrafficGenerator.h index d7732d09..583bf8b6 100644 --- a/DRAMSys/simulator/TrafficGenerator.h +++ b/DRAMSys/simulator/TrafficGenerator.h @@ -64,9 +64,8 @@ protected: private: unsigned int burstlenght; sc_time tCK; - unsigned int numRequests; + uint64_t numRequests; float rwRatio; - unsigned int addressIncrement; std::uniform_real_distribution randomRwDistribution = std::uniform_real_distribution(0.0f, 1.0f); }; @@ -98,15 +97,15 @@ public: unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests, float rwRatio, - unsigned int addressIncrement, + uint64_t addressIncrement, unsigned int seed, TraceSetup *setup); private: virtual uint64_t getNextAddress() override; - unsigned int currentAddress = 0x0; - unsigned int addressIncrement; + uint64_t currentAddress = 0x0; + uint64_t addressIncrement; }; #endif // TRAFFICGENERATOR_H diff --git a/DRAMSys/simulator/TrafficInitiator.cpp b/DRAMSys/simulator/TrafficInitiator.cpp index 865da77e..9b54943f 100644 --- a/DRAMSys/simulator/TrafficInitiator.cpp +++ b/DRAMSys/simulator/TrafficInitiator.cpp @@ -96,7 +96,8 @@ 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) + { nextPayload(); payloadPostponed = false; } From 73d767c6f0d9c18ce21ea4e6500ee90dbb6b6929 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Wed, 19 May 2021 15:23:55 +0200 Subject: [PATCH 6/7] Set dataLength in TrafficGenerator to bytesPerBurst MemSpec --- DRAMSys/simulator/StlPlayer.h | 2 -- DRAMSys/simulator/TrafficGenerator.cpp | 10 +++++----- DRAMSys/simulator/TrafficGenerator.h | 1 - DRAMSys/simulator/TrafficInitiator.h | 3 +++ 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/DRAMSys/simulator/StlPlayer.h b/DRAMSys/simulator/StlPlayer.h index 31b2f4e9..5af48844 100644 --- a/DRAMSys/simulator/StlPlayer.h +++ b/DRAMSys/simulator/StlPlayer.h @@ -80,8 +80,6 @@ private: std::ifstream file; uint64_t lineCnt; - unsigned int burstLength; - unsigned int dataLength; sc_time playerClk; // May be different from the memory clock! static constexpr unsigned lineBufferSize = 10000; diff --git a/DRAMSys/simulator/TrafficGenerator.cpp b/DRAMSys/simulator/TrafficGenerator.cpp index 8b373f2d..be98e831 100644 --- a/DRAMSys/simulator/TrafficGenerator.cpp +++ b/DRAMSys/simulator/TrafficGenerator.cpp @@ -49,7 +49,8 @@ TrafficGenerator::TrafficGenerator(const sc_module_name &name, TrafficInitiator(name, setup), tCK(tCK), numRequests(numRequests), rwRatio(rwRatio) { - burstlenght = Configuration::getInstance().memSpec->burstLength; + burstLength = Configuration::getInstance().memSpec->burstLength; + dataLength = Configuration::getInstance().memSpec->bytesPerBurst; this->maxPendingReadRequests = maxPendingReadRequests; this->maxPendingWriteRequests = maxPendingWriteRequests; @@ -67,7 +68,7 @@ void TrafficGenerator::nextPayload() tlm::tlm_generic_payload *payload = setup->allocatePayload(); payload->acquire(); - unsigned char *dataElement = new unsigned char[16]; + // TODO: column / burst breite uint64_t address = getNextAddress(); @@ -86,9 +87,8 @@ void TrafficGenerator::nextPayload() payload->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); payload->set_dmi_allowed(false); payload->set_byte_enable_length(0); - payload->set_streaming_width(burstlenght); - payload->set_data_ptr(dataElement); - payload->set_data_length(16); + payload->set_streaming_width(burstLength); + payload->set_data_length(dataLength); payload->set_command(command); sc_time sendingOffset; diff --git a/DRAMSys/simulator/TrafficGenerator.h b/DRAMSys/simulator/TrafficGenerator.h index 583bf8b6..c2cd3fd7 100644 --- a/DRAMSys/simulator/TrafficGenerator.h +++ b/DRAMSys/simulator/TrafficGenerator.h @@ -62,7 +62,6 @@ protected: std::default_random_engine randomGenerator; private: - unsigned int burstlenght; sc_time tCK; uint64_t numRequests; float rwRatio; diff --git a/DRAMSys/simulator/TrafficInitiator.h b/DRAMSys/simulator/TrafficInitiator.h index 84978da2..aa22403c 100644 --- a/DRAMSys/simulator/TrafficInitiator.h +++ b/DRAMSys/simulator/TrafficInitiator.h @@ -76,6 +76,9 @@ protected: bool payloadPostponed = false; bool finished = false; + unsigned int burstLength; + unsigned int dataLength; + sc_event transactionFinished; private: From dd5707ec3e9d6ba473570972aa7a0363ad43ed7d Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Thu, 27 May 2021 10:20:37 +0200 Subject: [PATCH 7/7] Small bugfix in TrafficInitiator, code refactoring. --- DRAMSys/simulator/StlPlayer.cpp | 70 ++++++++++---------------- DRAMSys/simulator/StlPlayer.h | 23 +++------ DRAMSys/simulator/TraceSetup.cpp | 14 +++--- DRAMSys/simulator/TraceSetup.h | 2 +- DRAMSys/simulator/TrafficGenerator.cpp | 33 +++++------- DRAMSys/simulator/TrafficGenerator.h | 17 ++++--- DRAMSys/simulator/TrafficInitiator.cpp | 38 ++++++-------- DRAMSys/simulator/TrafficInitiator.h | 9 ++-- 8 files changed, 84 insertions(+), 122 deletions(-) diff --git a/DRAMSys/simulator/StlPlayer.cpp b/DRAMSys/simulator/StlPlayer.cpp index 59c917eb..109309bd 100644 --- a/DRAMSys/simulator/StlPlayer.cpp +++ b/DRAMSys/simulator/StlPlayer.cpp @@ -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 - (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::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; } diff --git a/DRAMSys/simulator/StlPlayer.h b/DRAMSys/simulator/StlPlayer.h index 5af48844..45c883a7 100644 --- a/DRAMSys/simulator/StlPlayer.h +++ b/DRAMSys/simulator/StlPlayer.h @@ -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::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; }; diff --git a/DRAMSys/simulator/TraceSetup.cpp b/DRAMSys/simulator/TraceSetup.cpp index ba23072e..cff6e372 100644 --- a/DRAMSys/simulator/TraceSetup.cpp +++ b/DRAMSys/simulator/TraceSetup.cpp @@ -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; diff --git a/DRAMSys/simulator/TraceSetup.h b/DRAMSys/simulator/TraceSetup.h index da328b6f..b2aab202 100644 --- a/DRAMSys/simulator/TraceSetup.h +++ b/DRAMSys/simulator/TraceSetup.h @@ -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 diff --git a/DRAMSys/simulator/TrafficGenerator.cpp b/DRAMSys/simulator/TrafficGenerator.cpp index be98e831..0011b064 100644 --- a/DRAMSys/simulator/TrafficGenerator.cpp +++ b/DRAMSys/simulator/TrafficGenerator.cpp @@ -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( - 0, Configuration::getInstance().memSpec->getSimMemSizeInBytes()); + randomAddressDistribution = std::uniform_int_distribution + (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) { diff --git a/DRAMSys/simulator/TrafficGenerator.h b/DRAMSys/simulator/TrafficGenerator.h index c2cd3fd7..16f574a4 100644 --- a/DRAMSys/simulator/TrafficGenerator.h +++ b/DRAMSys/simulator/TrafficGenerator.h @@ -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 randomRwDistribution = std::uniform_real_distribution(0.0f, 1.0f); + std::uniform_real_distribution randomRwDistribution + = std::uniform_real_distribution(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 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; diff --git a/DRAMSys/simulator/TrafficInitiator.cpp b/DRAMSys/simulator/TrafficInitiator.cpp index df779f72..ed54a77c 100644 --- a/DRAMSys/simulator/TrafficInitiator.cpp +++ b/DRAMSys/simulator/TrafficInitiator.cpp @@ -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; } diff --git a/DRAMSys/simulator/TrafficInitiator.h b/DRAMSys/simulator/TrafficInitiator.h index aa22403c..1c10e04f 100644 --- a/DRAMSys/simulator/TrafficInitiator.h +++ b/DRAMSys/simulator/TrafficInitiator.h @@ -55,9 +55,10 @@ class TrafficInitiator : public sc_module { public: tlm_utils::simple_initiator_socket 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 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