diff --git a/CMakeLists.txt b/CMakeLists.txt index c1be0376..0cdf6184 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,7 +77,7 @@ endif() set(DRAMSYS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src") set(DRAMSYS_LIBRARY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lib") set(DRAMSYS_TESTS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/tests") -set(DRAMSYS_RESOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/resources") +set(DRAMSYS_RESOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/configs") set(DRAMSYS_EXTENSIONS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extensions") ### Build options ### @@ -137,6 +137,7 @@ FetchContent_Declare( GIT_REPOSITORY https://github.com/accellera-official/systemc.git GIT_TAG 2.3.4) +set(DISABLE_COPYRIGHT_MESSAGE True) FetchContent_MakeAvailable(systemc) set_target_properties(systemc PROPERTIES FOLDER lib) diff --git a/src/configuration/DRAMSys/config/TraceSetup.h b/src/configuration/DRAMSys/config/TraceSetup.h index cff510f1..af100b30 100644 --- a/src/configuration/DRAMSys/config/TraceSetup.h +++ b/src/configuration/DRAMSys/config/TraceSetup.h @@ -89,8 +89,6 @@ struct TrafficGeneratorActiveState std::optional addressIncrement; std::optional minAddress; std::optional maxAddress; - std::optional clksPerRequest; - std::optional notify; }; NLOHMANN_JSONIFY_ALL_THINGS(TrafficGeneratorActiveState, @@ -100,9 +98,7 @@ NLOHMANN_JSONIFY_ALL_THINGS(TrafficGeneratorActiveState, addressDistribution, addressIncrement, minAddress, - maxAddress, - clksPerRequest, - notify) + maxAddress) struct TrafficGeneratorIdleState { @@ -139,9 +135,6 @@ struct TrafficGenerator std::optional addressIncrement; std::optional minAddress; std::optional maxAddress; - std::optional clksPerRequest; - - std::optional idleUntil; }; NLOHMANN_JSONIFY_ALL_THINGS(TrafficGenerator, @@ -157,9 +150,7 @@ NLOHMANN_JSONIFY_ALL_THINGS(TrafficGenerator, addressDistribution, addressIncrement, minAddress, - maxAddress, - clksPerRequest, - idleUntil) + maxAddress) struct TrafficGeneratorStateMachine { @@ -173,7 +164,6 @@ struct TrafficGeneratorStateMachine std::optional dataLength; std::vector> states; std::vector transitions; - std::optional idleUntil; }; NLOHMANN_JSONIFY_ALL_THINGS(TrafficGeneratorStateMachine, @@ -185,10 +175,9 @@ NLOHMANN_JSONIFY_ALL_THINGS(TrafficGeneratorStateMachine, maxTransactions, dataLength, states, - transitions, - idleUntil) + transitions) -struct TraceHammer +struct RowHammer { uint64_t clkMhz; std::string name; @@ -200,7 +189,7 @@ struct TraceHammer }; NLOHMANN_JSONIFY_ALL_THINGS( - TraceHammer, clkMhz, name, maxPendingReadRequests, maxPendingWriteRequests, numRequests, rowIncrement) + RowHammer, clkMhz, name, maxPendingReadRequests, maxPendingWriteRequests, numRequests, rowIncrement) struct TraceSetupConstants { @@ -209,7 +198,7 @@ struct TraceSetupConstants }; using TraceSetup = std::vector< - std::variant>; + std::variant>; } // namespace Configuration diff --git a/src/configuration/Notes.txt b/src/configuration/Notes.txt new file mode 100644 index 00000000..122aab7b --- /dev/null +++ b/src/configuration/Notes.txt @@ -0,0 +1,6 @@ +Things to refactor in the configuration format: + - Embed the resource directory directly into the base configuration OR + - Specify the full (relative) path to each sub-configuration + + - Remove diverging sub-config base key names in base config and in the sub-config (i.e. remove the INNER_KEYs in the code) + - Remove redundant CONGEN type from the addressmapping diff --git a/src/simulator/CMakeLists.txt b/src/simulator/CMakeLists.txt index 9c2f9032..bae5c739 100644 --- a/src/simulator/CMakeLists.txt +++ b/src/simulator/CMakeLists.txt @@ -54,4 +54,3 @@ target_link_libraries(DRAMSys ) build_source_group() -diagnostics_print(DRAMSys) \ No newline at end of file diff --git a/src/simulator/simulator/Initiator.h b/src/simulator/simulator/Initiator.h new file mode 100644 index 00000000..817fb00e --- /dev/null +++ b/src/simulator/simulator/Initiator.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023, 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: + * Derek Christ + */ + +#pragma once + +#include + +class Initiator +{ +public: + virtual ~Initiator() = default; + + virtual void bind(tlm_utils::multi_target_base<> &target) = 0; + virtual uint64_t totalRequests() = 0; +}; diff --git a/src/simulator/simulator/SimpleInitiator.h b/src/simulator/simulator/SimpleInitiator.h new file mode 100644 index 00000000..3286ac5e --- /dev/null +++ b/src/simulator/simulator/SimpleInitiator.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2023, 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: + * Derek Christ + */ + +#pragma once + +#include "Initiator.h" +#include "request/RequestIssuer.h" + +template +class SimpleInitiator : public Initiator +{ +public: + SimpleInitiator(sc_core::sc_module_name const &name, + MemoryManager &memoryManager, + std::optional maxPendingReadRequests, + std::optional maxPendingWriteRequests, + std::function transactionFinished, + std::function terminate, + Producer &&producer) + : producer(std::forward(producer)), + issuer( + name, + memoryManager, + maxPendingReadRequests, + maxPendingWriteRequests, + [this] { return this->producer.nextRequest(); }, + std::move(transactionFinished), + std::move(terminate)) + { + } + + void bind(tlm_utils::multi_target_base<> &target) override { issuer.iSocket.bind(target); } + uint64_t totalRequests() override { return producer.totalRequests(); }; + +private: + Producer producer; + RequestIssuer issuer; +}; diff --git a/src/simulator/simulator/StlPlayer.cpp b/src/simulator/simulator/StlPlayer.cpp deleted file mode 100644 index 967206c5..00000000 --- a/src/simulator/simulator/StlPlayer.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/* - * 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: - * Janik Schlemminger - * Robert Gernhardt - * Matthias Jung - * Éder F. Zulian - * Felipe S. Prado - * Derek Christ - */ - -#include "StlPlayer.h" - -using namespace sc_core; -using namespace tlm; - -StlPlayer::StlPlayer(const sc_module_name &name, const Configuration& config, const std::string &pathToTrace, - const sc_time &playerClk, unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests, - TraceSetup& setup, bool relative) : - TrafficInitiator(name, config, setup, maxPendingReadRequests, maxPendingWriteRequests, - config.memSpec->defaultBytesPerBurst), - file(pathToTrace), relative(relative), playerClk(playerClk) -{ - currentBuffer = &lineContents[0]; - parseBuffer = &lineContents[1]; - - 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); - - if (numberOfLines == 0) - SC_REPORT_FATAL("StlPlayer", "Trace file is empty"); - } - - currentBuffer->reserve(lineBufferSize); - parseBuffer->reserve(lineBufferSize); - - parseTraceFile(); - lineIterator = currentBuffer->cend(); -} - -StlPlayer::~StlPlayer() -{ - if (parserThread.joinable()) - parserThread.join(); -} - -void StlPlayer::sendNextPayload() -{ - if (lineIterator == currentBuffer->cend()) - { - lineIterator = swapBuffers(); - if (lineIterator == currentBuffer->cend()) - { - // The file is empty. Nothing more to do. - finished = true; - return; - } - } - - // Allocate a generic payload for this request. - tlm_generic_payload& payload = setup.allocatePayload(lineIterator->dataLength); - payload.acquire(); - - // Fill up the payload. - payload.set_address(lineIterator->address); - payload.set_response_status(TLM_INCOMPLETE_RESPONSE); - payload.set_dmi_allowed(false); - payload.set_byte_enable_length(0); - payload.set_data_length(lineIterator->dataLength); - payload.set_command(lineIterator->command); - std::copy(lineIterator->data.begin(), lineIterator->data.end(), payload.get_data_ptr()); - - sc_time sendingTime; - sc_time sendingOffset; - - if (transactionsSent == 0) - sendingOffset = SC_ZERO_TIME; - else - sendingOffset = playerClk - (sc_time_stamp() % playerClk); - - if (!relative) - sendingTime = std::max(sc_time_stamp() + sendingOffset, lineIterator->sendingTime); - else - sendingTime = sc_time_stamp() + sendingOffset + lineIterator->sendingTime; - - 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++; -} - -void StlPlayer::parseTraceFile() -{ - unsigned parsedLines = 0; - parseBuffer->clear(); - while (file && !file.eof() && parsedLines < lineBufferSize) - { - // Get a new line from the input file. - std::string line; - std::getline(file, line); - lineCnt++; - - // If the line is empty (\n or \r\n) or starts with '#' (comment) the transaction is ignored. - if (line.size() <= 1 || line.at(0) == '#') - continue; - - parsedLines++; - parseBuffer->emplace_back(); - LineContent &content = parseBuffer->back(); - - // Trace files MUST provide timestamp, command and address for every - // transaction. The data information depends on the storage mode - // configuration. - std::string element; - std::istringstream iss; - - iss.str(line); - - // Get the timestamp for the transaction. - iss >> element; - if (element.empty()) - SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ".").c_str()); - content.sendingTime = playerClk * static_cast(std::stoull(element)); - - // Get the optional burst length and command - iss >> element; - if (element.empty()) - SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ".").c_str()); - if (element.at(0) == '(') - { - element.erase(0, 1); - content.dataLength = std::stoul(element); - iss >> element; - if (element.empty()) - SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ".").c_str()); - } - else - content.dataLength = defaultDataLength; - - if (element == "read") - content.command = TLM_READ_COMMAND; - else if (element == "write") - content.command = TLM_WRITE_COMMAND; - else - SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ".").c_str()); - - // Get the address. - iss >> element; - if (element.empty()) - SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ".").c_str()); - content.address = std::stoull(element, nullptr, 16); - - // Get the data if necessary. - if (storageEnabled && content.command == TLM_WRITE_COMMAND) - { - // The input trace file must provide the data to be stored into the memory. - iss >> element; - - // Check if data length in the trace file is correct. - // We need two characters to represent 1 byte in hexadecimal. Offset for 0x prefix. - if (element.length() != (content.dataLength * 2 + 2)) - SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ".").c_str()); - - // Set data - for (unsigned i = 0; i < content.dataLength; i++) - content.data.emplace_back(static_cast - (std::stoi(element.substr(i * 2 + 2, 2), nullptr, 16))); - } - } -} - -std::vector::const_iterator StlPlayer::swapBuffers() -{ - // Wait for parser to finish - if (parserThread.joinable()) - parserThread.join(); - - // Swap buffers - std::swap(currentBuffer, parseBuffer); - - // Start new parser thread - parserThread = std::thread(&StlPlayer::parseTraceFile, this); - - return currentBuffer->cbegin(); -} - -uint64_t StlPlayer::getNumberOfLines() const -{ - return numberOfLines; -} diff --git a/src/simulator/simulator/TraceSetup.cpp b/src/simulator/simulator/TraceSetup.cpp deleted file mode 100644 index 2af57f0a..00000000 --- a/src/simulator/simulator/TraceSetup.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (c) 2017, 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: - * Matthias Jung - * Luiza Correa - * Derek Christ - */ - -#include "TraceSetup.h" - -#include "simulator/StlPlayer.h" -#include "simulator/TrafficGenerator.h" - -#include -#include -#include - -using namespace sc_core; -using namespace tlm; - -TraceSetup::TraceSetup(const Configuration& config, - const DRAMSys::Config::TraceSetup& traceSetup, - const std::string& pathToResources, - std::vector>& players) - : memoryManager(config.storeMode != Configuration::StoreMode::NoStorage) -{ - if (traceSetup.initiators.empty()) - SC_REPORT_FATAL("TraceSetup", "No traffic initiators specified"); - - for (const auto &initiator : traceSetup.initiators) - { - std::visit( - [&](auto &&initiator) - { - std::string name = initiator.name; - double frequencyMHz = initiator.clkMhz; - sc_time playerClk = sc_time(1.0 / frequencyMHz, SC_US); - - unsigned int maxPendingReadRequests = [=]() -> unsigned int - { - if (const auto &maxPendingReadRequests = initiator.maxPendingReadRequests) - return *maxPendingReadRequests; - else - return 0; - }(); - - unsigned int maxPendingWriteRequests = [=]() -> unsigned int - { - if (const auto &maxPendingWriteRequests = initiator.maxPendingWriteRequests) - return *maxPendingWriteRequests; - else - return 0; - }(); - - using T = std::decay_t; - if constexpr (std::is_same_v) - { - 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."); - - // 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::stringstream stlFileStream; - stlFileStream << pathToResources << "/traces/" << name; - std::string stlFile = stlFileStream.str(); - std::string moduleName = name; - - // replace all '.' to '_' - std::replace(moduleName.begin(), moduleName.end(), '.', '_'); - - StlPlayer *player; - if (ext == "stl") - player = new StlPlayer(moduleName.c_str(), config, stlFile, playerClk, maxPendingReadRequests, - maxPendingWriteRequests, *this, false); - else if (ext == "rstl") - player = new StlPlayer(moduleName.c_str(), config, stlFile, playerClk, maxPendingReadRequests, - maxPendingWriteRequests, *this, true); - else - throw std::runtime_error("Unsupported file extension in " + name); - - players.push_back(std::unique_ptr(player)); - totalTransactions += player->getNumberOfLines(); - } - else if constexpr (std::is_same_v) - { - auto* trafficGenerator = new TrafficGenerator(name.c_str(), config, initiator, *this); - players.push_back(std::unique_ptr(trafficGenerator)); - - totalTransactions += trafficGenerator->getTotalTransactions(); - } - else // if constexpr (std::is_same_v) - { - uint64_t numRequests = initiator.numRequests; - uint64_t rowIncrement = initiator.rowIncrement; - - players.push_back( - std::unique_ptr(new TrafficGeneratorHammer(name.c_str(), config, initiator, *this))); - totalTransactions += numRequests; - } - }, - initiator); - } - - for (const auto &inititatorConf : traceSetup.initiators) - { - if (auto generatorConf = std::get_if(&inititatorConf)) - { - if (const auto &idleUntil = generatorConf->idleUntil) - { - const std::string name = generatorConf->name; - auto listenerIt = std::find_if(players.begin(), players.end(), - [&name](const std::unique_ptr &initiator) - { return initiator->name() == name; }); - - // Should be found - auto listener = dynamic_cast(listenerIt->get()); - - auto notifierIt = - std::find_if(players.begin(), players.end(), - [&idleUntil](const std::unique_ptr &initiator) - { - if (auto generator = dynamic_cast(initiator.get())) - { - if (generator->hasStateTransitionEvent(*idleUntil)) - return true; - } - - return false; - }); - - if (notifierIt == players.end()) - SC_REPORT_FATAL("TraceSetup", "Event to listen on not found."); - - auto notifier = dynamic_cast(notifierIt->get()); - listener->waitUntil(¬ifier->getStateTransitionEvent(*idleUntil)); - } - } - } - - remainingTransactions = totalTransactions; - numberOfTrafficInitiators = players.size(); - defaultDataLength = config.memSpec->defaultBytesPerBurst; -} - -void TraceSetup::trafficInitiatorTerminates() -{ - finishedTrafficInitiators++; - - if (finishedTrafficInitiators == numberOfTrafficInitiators) - sc_stop(); -} - -void TraceSetup::transactionFinished() -{ - remainingTransactions--; - - loadBar(totalTransactions - remainingTransactions, totalTransactions); - - if (remainingTransactions == 0) - std::cout << std::endl; -} - -tlm_generic_payload& TraceSetup::allocatePayload(unsigned dataLength) -{ - return memoryManager.allocate(dataLength); -} - -tlm_generic_payload& TraceSetup::allocatePayload() -{ - return allocatePayload(defaultDataLength); -} - -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; - - float ratio = x / (float)n; - unsigned int c = (ratio * w); - float rest = (ratio * w) - c; - std::cout << std::setw(3) << round(ratio * 100) << "% |"; - for (unsigned int x = 0; x < c; x++) - std::cout << "█"; - - if (rest >= 0 && rest < 0.125f && c != w) - std::cout << " "; - if (rest >= 0.125f && rest < 2 * 0.125f) - std::cout << "▏"; - if (rest >= 2 * 0.125f && rest < 3 * 0.125f) - std::cout << "▎"; - if (rest >= 3 * 0.125f && rest < 4 * 0.125f) - std::cout << "▍"; - if (rest >= 4 * 0.125f && rest < 5 * 0.125f) - std::cout << "▌"; - if (rest >= 5 * 0.125f && rest < 6 * 0.125f) - std::cout << "▋"; - if (rest >= 6 * 0.125f && rest < 7 * 0.125f) - std::cout << "▊"; - if (rest >= 7 * 0.125f && rest < 8 * 0.125f) - std::cout << "▉"; - - for (unsigned int x = c; x < (w - 1); x++) - std::cout << " "; - std::cout << "|\r" << std::flush; -} diff --git a/src/simulator/simulator/TrafficGenerator.cpp b/src/simulator/simulator/TrafficGenerator.cpp deleted file mode 100644 index abcc5878..00000000 --- a/src/simulator/simulator/TrafficGenerator.cpp +++ /dev/null @@ -1,412 +0,0 @@ -/* - * 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: - * Janik Schlemminger - * Robert Gernhardt - * Matthias Jung - * Derek Christ - */ - -#include "TrafficGenerator.h" - -#include "simulator/TraceSetup.h" - -#include - -using namespace sc_core; -using namespace tlm; - -TrafficGeneratorIf::TrafficGeneratorIf(const sc_core::sc_module_name& name, const Configuration& config, - TraceSetup& setup, - unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests, - unsigned int dataLength) - : TrafficInitiator(name, config, setup, maxPendingReadRequests, maxPendingWriteRequests, dataLength) -{ -} - -void TrafficGeneratorIf::sendNextPayload() -{ - prepareNextPayload(); - - if (finished) - return; - - // TODO: column / burst breite - - uint64_t address = getNextAddress(); - - tlm_command command = getNextCommand(); - - if (command == tlm::TLM_READ_COMMAND) - pendingReadRequests++; - else if (command == tlm::TLM_WRITE_COMMAND) - pendingWriteRequests++; - - tlm_generic_payload& payload = setup.allocatePayload(); - payload.acquire(); - payload.set_address(address); - payload.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); - payload.set_dmi_allowed(false); - payload.set_byte_enable_length(0); - payload.set_data_length(defaultDataLength); - payload.set_command(command); - - sc_time generatorClk = getGeneratorClk(); - sc_time sendingOffset; - if (transactionsSent == 0) - sendingOffset = SC_ZERO_TIME + generatorClk * clksToIdle(); - else - sendingOffset = (generatorClk * clksPerRequest()) - (sc_time_stamp() % generatorClk) + generatorClk * clksToIdle(); - - // TODO: do not send two requests in the same cycle - sendToTarget(payload, tlm::BEGIN_REQ, sendingOffset); - - transactionsSent++; - PRINTDEBUGMESSAGE(name(), "Performing request #" + std::to_string(transactionsSent)); - payloadSent(); -} - -TrafficGenerator::TrafficGenerator(const sc_module_name& name, const Configuration& config, - const DRAMSys::Config::TraceGenerator& conf, TraceSetup& setup) - : TrafficGeneratorIf(name, config, setup, conf.maxPendingReadRequests.value_or(defaultMaxPendingReadRequests), - conf.maxPendingWriteRequests.value_or(defaultMaxPendingWriteRequests), - conf.dataLength.value_or(config.memSpec->defaultBytesPerBurst)), - generatorClk(TrafficInitiator::evaluateGeneratorClk(conf)), conf(conf), - maxTransactions(conf.maxTransactions.value_or(std::numeric_limits::max())), - simMemSizeInBytes(config.memSpec->getSimMemSizeInBytes()), - randomGenerator(std::default_random_engine(conf.seed.value_or(defaultSeed))) -{ - // Perform checks for all states - for (const auto &state : conf.states) - { - if (auto trafficState = std::get_if(&state.second)) - { - uint64_t minAddress = evaluateMinAddress(*trafficState); - uint64_t maxAddress = evaluateMaxAddress(*trafficState, simMemSizeInBytes); - double rwRatio = (*trafficState).rwRatio; - - if (minAddress > config.memSpec->getSimMemSizeInBytes() - 1) - SC_REPORT_FATAL("TrafficGenerator", "minAddress is out of range."); - - if (maxAddress > config.memSpec->getSimMemSizeInBytes() - 1) - SC_REPORT_FATAL("TrafficGenerator", "minAddress is out of range."); - - if (maxAddress < minAddress) - SC_REPORT_FATAL("TrafficGenerator", "maxAddress is smaller than minAddress."); - - if (rwRatio < 0 || rwRatio > 1) - SC_REPORT_FATAL("TraceSetup", "Read/Write ratio is not a number between 0 and 1."); - - if (const auto &eventName = trafficState->notify) - { - stateTranstitionEvents.emplace(std::piecewise_construct, std::forward_as_tuple(*eventName), - std::forward_as_tuple(eventName->c_str(), state.first)); - } - } - } - - if (auto trafficState = - std::get_if(&conf.states.at(currentState))) - { - uint64_t minAddress = evaluateMinAddress(*trafficState); - uint64_t maxAddress = evaluateMaxAddress(*trafficState, simMemSizeInBytes); - randomAddressDistribution = std::uniform_int_distribution(minAddress, maxAddress); - currentClksPerRequest = trafficState->clksPerRequest.value_or(defaultClksPerRequest); - } - - calculateTransitions(); -} - -void TrafficGenerator::calculateTransitions() -{ - unsigned int state = 0; - uint64_t totalTransactions = 0; - stateSequence.push_back(state); - - while (true) - { - auto transitionsIt = conf.transitions.equal_range(state); - float probabilityAccumulated = 0.0f; - std::map> transitionsDistribution; - - for (auto it = transitionsIt.first; it != transitionsIt.second; ++it) - { - float lowerLimit = probabilityAccumulated; - probabilityAccumulated += it->second.probability; - float upperLimit = probabilityAccumulated; - transitionsDistribution[it->second.to] = {lowerLimit, upperLimit}; - } - - if (probabilityAccumulated > 1.001f) - SC_REPORT_WARNING("TrafficGenerator", "Sum of transition probabilities greater than 1."); - - float random = randomDistribution(randomGenerator); - bool transitionFound = false; - - for (const auto &transition : transitionsDistribution) - { - auto to = transition.first; - auto limits = transition.second; - - if (limits.first < random && limits.second > random) - { - state = to; - stateSequence.push_back(state); - transitionFound = true; - break; - } - } - - if (transitionFound) - { - if (auto trafficState = - std::get_if(&conf.states.at(state))) - totalTransactions += trafficState->numRequests; - - if (totalTransactions < maxTransactions) - continue; - } - - break; - } - - stateIt = stateSequence.cbegin(); -} - -bool TrafficGenerator::hasStateTransitionEvent(const std::string &eventName) const -{ - auto it = stateTranstitionEvents.find(eventName); - - if (it == stateTranstitionEvents.end()) - return false; - - return true; -} - -const sc_core::sc_event &TrafficGenerator::getStateTransitionEvent(const std::string &eventName) const -{ - auto it = stateTranstitionEvents.find(eventName); - - if (it == stateTranstitionEvents.end()) - SC_REPORT_FATAL("TraceSetup", "StateTransitionEvent not found."); - - return it->second.event; -} - -uint64_t TrafficGenerator::getTotalTransactions() const -{ - uint64_t totalTransactions = 0; - - for (auto state : stateSequence) - { - if (auto trafficState = std::get_if(&conf.states.at(state))) - totalTransactions += trafficState->numRequests; - } - - if (totalTransactions > maxTransactions) - totalTransactions = maxTransactions; - - return totalTransactions; -} - -void TrafficGenerator::waitUntil(const sc_core::sc_event *ev) -{ - startEvent = ev; -} - -void TrafficGenerator::transitionToNextState() -{ - ++stateIt; - - if (stateIt == stateSequence.cend() || transactionsSent >= maxTransactions) - { - // No transition performed. - finished = true; - return; - } - - currentState = *stateIt; - - // Notify - for (auto &it : stateTranstitionEvents) - { - if (it.second.stateId == currentState) - it.second.event.notify(); - } - - if (auto idleState = std::get_if(&conf.states.at(currentState))) - { - currentClksToIdle += idleState->idleClks; - transitionToNextState(); - return; - } - else if (auto trafficState = - std::get_if(&conf.states.at(currentState))) - { - uint64_t minAddress = evaluateMinAddress(*trafficState); - uint64_t maxAddress = evaluateMaxAddress(*trafficState, simMemSizeInBytes); - randomAddressDistribution = std::uniform_int_distribution(minAddress, maxAddress); - currentClksPerRequest = trafficState->clksPerRequest.value_or(defaultClksPerRequest); - } - - currentAddress = 0x00; - transactionsSentInCurrentState = 0; -} - -void TrafficGenerator::prepareNextPayload() -{ - if (transactionsSent >= maxTransactions) - { - finished = true; - return; - } - - if (startEvent && transactionsSent == 0) - wait(*startEvent); - - if (auto trafficState = - std::get_if(&conf.states.at(currentState))) - { - if (transactionsSentInCurrentState >= trafficState->numRequests) - transitionToNextState(); - } - - // In case we are in an idle state right at the beginning of the simulation, - // set the clksToIdle and transition to the next state. - if (auto idleState = - std::get_if(&conf.states.at(currentState))) - { - currentClksToIdle = idleState->idleClks; - transitionToNextState(); - } -} - -void TrafficGenerator::payloadSent() -{ - // Reset clks to idle. - currentClksToIdle = 0; - - transactionsSentInCurrentState++; -} - -tlm::tlm_command TrafficGenerator::getNextCommand() -{ - // An idle state should never reach this method. - auto &state = std::get(conf.states.at(currentState)); - - tlm_command command; - if (randomDistribution(randomGenerator) < state.rwRatio) - command = tlm::TLM_READ_COMMAND; - else - command = tlm::TLM_WRITE_COMMAND; - - return command; -} - -sc_core::sc_time TrafficGenerator::getGeneratorClk() const -{ - return generatorClk; -} - -uint64_t TrafficGenerator::getNextAddress() -{ - using DRAMSys::Config::AddressDistribution; - - // An idle state should never reach this method. - auto &state = std::get(conf.states.at(currentState)); - - uint64_t minAddress = evaluateMinAddress(state); - uint64_t maxAddress = evaluateMaxAddress(state, simMemSizeInBytes); - - if (state.addressDistribution == AddressDistribution::Sequential) - { - uint64_t addressIncrement = state.addressIncrement.value_or(defaultAddressIncrement); - - uint64_t address = currentAddress; - currentAddress += addressIncrement; - if (currentAddress > maxAddress) - currentAddress = minAddress; - return address; - } - else if (state.addressDistribution == AddressDistribution::Random) - { - return randomAddressDistribution(randomGenerator); - } - else - { - return 0x00; - } -} - -uint64_t TrafficGenerator::evaluateMinAddress(const DRAMSys::Config::TraceGeneratorTrafficState &state) -{ - return state.minAddress.value_or(0x00); -} - -uint64_t TrafficGenerator::evaluateMaxAddress(const DRAMSys::Config::TraceGeneratorTrafficState &state, - uint64_t simMemSizeInBytes) -{ - return state.maxAddress.value_or(simMemSizeInBytes - 1); -} - -TrafficGeneratorHammer::TrafficGeneratorHammer(const sc_core::sc_module_name &name, const Configuration& config, - const DRAMSys::Config::TraceHammer &conf, TraceSetup& setup) - : TrafficGeneratorIf(name, config, setup, 1, 1, config.memSpec->defaultBytesPerBurst), - generatorClk(evaluateGeneratorClk(conf)), rowIncrement(conf.rowIncrement), numRequests(conf.numRequests) -{ -} - -tlm::tlm_command TrafficGeneratorHammer::getNextCommand() -{ - return tlm::TLM_READ_COMMAND; -} - -sc_core::sc_time TrafficGeneratorHammer::getGeneratorClk() const -{ - return generatorClk; -} - -uint64_t TrafficGeneratorHammer::getNextAddress() -{ - if (currentAddress == 0x0) - currentAddress = rowIncrement; - else - currentAddress = 0x0; - - return currentAddress; -} - -void TrafficGeneratorHammer::prepareNextPayload() -{ - if (transactionsSent >= numRequests) - finished = true; -} diff --git a/src/simulator/simulator/TrafficGenerator.h b/src/simulator/simulator/TrafficGenerator.h deleted file mode 100644 index 7732fa9d..00000000 --- a/src/simulator/simulator/TrafficGenerator.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * 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: - * Janik Schlemminger - * Robert Gernhardt - * Matthias Jung - * Derek Christ - */ - -#ifndef TRAFFICGENERATOR_H -#define TRAFFICGENERATOR_H - -#include "simulator/TrafficInitiator.h" -#include "simulator/TraceSetup.h" - -#include -#include -#include - -class TrafficGeneratorIf : public TrafficInitiator -{ -public: - TrafficGeneratorIf(const sc_core::sc_module_name &name, const Configuration& config, TraceSetup& setup, - unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests, - unsigned int dataLength); - -private: - void sendNextPayload() override; - virtual void prepareNextPayload(){}; - virtual uint64_t getNextAddress() = 0; - virtual tlm::tlm_command getNextCommand() = 0; - virtual sc_core::sc_time getGeneratorClk() const = 0; - virtual void payloadSent(){}; - virtual uint64_t clksPerRequest() const { return 1; } - virtual uint64_t clksToIdle() const { return 0; } -}; - -class TrafficGenerator : public TrafficGeneratorIf -{ -public: - TrafficGenerator(const sc_core::sc_module_name &name, const Configuration& config, - const DRAMSys::Config::TraceGenerator &conf, TraceSetup& setup); - - uint64_t getTotalTransactions() const; - void waitUntil(const sc_core::sc_event *ev); - bool hasStateTransitionEvent(const std::string &eventName) const; - const sc_core::sc_event &getStateTransitionEvent(const std::string &eventName) const; - -private: - static uint64_t evaluateMinAddress(const DRAMSys::Config::TraceGeneratorTrafficState& state); - static uint64_t evaluateMaxAddress(const DRAMSys::Config::TraceGeneratorTrafficState& state, - uint64_t simMemSizeInBytes); - - void prepareNextPayload() override; - uint64_t getNextAddress() override; - tlm::tlm_command getNextCommand() override; - sc_core::sc_time getGeneratorClk() const override; - void payloadSent() override; - uint64_t clksPerRequest() const override { return currentClksPerRequest; }; - uint64_t clksToIdle() const override { return currentClksToIdle; } - - void calculateTransitions(); - void transitionToNextState(); - - sc_core::sc_time generatorClk; - - const DRAMSys::Config::TraceGenerator &conf; - unsigned int currentState = 0; - uint64_t currentAddress = 0x00; - uint64_t currentClksPerRequest = 1; - uint64_t transactionsSentInCurrentState = 0; - - const uint64_t maxTransactions; - const uint64_t simMemSizeInBytes; - - uint64_t currentClksToIdle = 0; - - std::vector stateSequence; - std::vector::const_iterator stateIt; - - struct EventPair - { - EventPair(const std::string &name, unsigned int id) : event(name.c_str()), stateId(id) - { - } - sc_core::sc_event event; - unsigned int stateId; - }; - std::map stateTranstitionEvents; - - bool idleAtStart = false; - const sc_core::sc_event *startEvent = nullptr; - - std::default_random_engine randomGenerator; - std::uniform_real_distribution randomDistribution = std::uniform_real_distribution(0.0f, 1.0f); - std::uniform_int_distribution randomAddressDistribution; - - static constexpr uint64_t defaultSeed = 0; - static constexpr uint64_t defaultClksPerRequest = 1; - static constexpr uint64_t defaultAddressIncrement = 0x00; -}; - -class TrafficGeneratorHammer final : public TrafficGeneratorIf -{ -public: - TrafficGeneratorHammer(const sc_core::sc_module_name &name, const Configuration& config, - const DRAMSys::Config::TraceHammer &conf, TraceSetup& setup); - -private: - void prepareNextPayload() override; - uint64_t getNextAddress() override; - tlm::tlm_command getNextCommand() override; - sc_core::sc_time getGeneratorClk() const override; - - sc_core::sc_time generatorClk; - uint64_t rowIncrement; - uint64_t currentAddress = 0x0; - uint64_t numRequests; -}; - -#endif // TRAFFICGENERATOR_H diff --git a/src/simulator/simulator/TrafficInitiator.cpp b/src/simulator/simulator/TrafficInitiator.cpp deleted file mode 100644 index 70c4eeae..00000000 --- a/src/simulator/simulator/TrafficInitiator.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - * 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 - * Derek Christ - */ - -#include "TrafficInitiator.h" - -using namespace sc_core; -using namespace tlm; - -TrafficInitiator::TrafficInitiator(const sc_module_name &name, const Configuration& config, TraceSetup& setup, - unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests, unsigned int defaultDataLength) : - sc_module(name), - payloadEventQueue(this, &TrafficInitiator::peqCallback), - setup(setup), - maxPendingReadRequests(maxPendingReadRequests), - maxPendingWriteRequests(maxPendingWriteRequests), - defaultDataLength(defaultDataLength), - storageEnabled(config.storeMode != Configuration::StoreMode::NoStorage), - simulationProgressBar(config.simulationProgressBar) -{ - SC_THREAD(sendNextPayload); - iSocket.register_nb_transport_bw(this, &TrafficInitiator::nb_transport_bw); -} - -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) - { - if (nextPayloadSendable()) - sendNextPayload(); - else - payloadPostponed = true; - } - else if (phase == BEGIN_RESP) - { - payload.release(); - sendToTarget(payload, END_RESP, SC_ZERO_TIME); - if (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 && nextPayloadSendable()) - { - sendNextPayload(); - payloadPostponed = false; - } - - // If all answers were received: - if (finished && 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() const -{ - // If either the maxPendingReadRequests or maxPendingWriteRequests - // limit is reached, do not send next payload. - if (((pendingReadRequests >= maxPendingReadRequests) && (maxPendingReadRequests != 0)) - || ((pendingWriteRequests >= maxPendingWriteRequests) && (maxPendingWriteRequests != 0))) - return false; - else - return true; -} - -sc_core::sc_time TrafficInitiator::evaluateGeneratorClk(const DRAMSys::Config::TrafficInitiator& conf) -{ - double frequencyMHz = conf.clkMhz; - sc_time playerClk = sc_time(1.0 / frequencyMHz, SC_US); - return playerClk; -} - diff --git a/src/simulator/simulator/generator/RandomProducer.cpp b/src/simulator/simulator/generator/RandomProducer.cpp new file mode 100644 index 00000000..d9e3fbd9 --- /dev/null +++ b/src/simulator/simulator/generator/RandomProducer.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2023, 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: + * Derek Christ + */ + +#include "RandomProducer.h" +#include "definitions.h" + +RandomProducer::RandomProducer(uint64_t numRequests, + std::optional seed, + double rwRatio, + unsigned int clkMhz, + std::optional minAddress, + std::optional maxAddress, + uint64_t memorySize, + unsigned int dataLength) + : numberOfRequests(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), + randomAddressDistribution(minAddress.value_or(DEFAULT_MIN_ADDRESS), + maxAddress.value_or((memorySize / dataLength) - 1)) +{ + if (minAddress > memorySize - 1) + SC_REPORT_FATAL("TrafficGenerator", "minAddress is out of range."); + + if (maxAddress > memorySize - 1) + SC_REPORT_FATAL("TrafficGenerator", "minAddress is out of range."); + + if (maxAddress < minAddress) + SC_REPORT_FATAL("TrafficGenerator", "maxAddress is smaller than minAddress."); + + if (rwRatio < 0 || rwRatio > 1) + SC_REPORT_FATAL("TraceSetup", "Read/Write ratio is not a number between 0 and 1."); +} + +Request RandomProducer::nextRequest() +{ + Request request; + request.address = randomAddressDistribution(randomGenerator) * dataLength; + request.command = readWriteDistribution(randomGenerator) < rwRatio ? Request::Command::Read + : Request::Command::Write; + request.length = dataLength; + request.delay = generatorPeriod; + + return request; +} diff --git a/src/simulator/simulator/generator/RandomProducer.h b/src/simulator/simulator/generator/RandomProducer.h new file mode 100644 index 00000000..c0f55322 --- /dev/null +++ b/src/simulator/simulator/generator/RandomProducer.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2023, 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: + * Derek Christ + */ + +#pragma once + +#include "simulator/request/RequestProducer.h" + +#include +#include + +class RandomProducer : public RequestProducer +{ +public: + RandomProducer(uint64_t numRequests, + std::optional seed, + double rwRatio, + unsigned int clkMhz, + std::optional minAddress, + std::optional maxAddress, + uint64_t memorySize, + unsigned int dataLength); + + 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; + + std::default_random_engine randomGenerator; + std::uniform_real_distribution readWriteDistribution{0.0, 1.0}; + std::uniform_int_distribution randomAddressDistribution; +}; diff --git a/src/simulator/simulator/generator/SequentialProducer.cpp b/src/simulator/simulator/generator/SequentialProducer.cpp new file mode 100644 index 00000000..1ca441fd --- /dev/null +++ b/src/simulator/simulator/generator/SequentialProducer.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2023, 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: + * Derek Christ + */ + +#include "SequentialProducer.h" +#include "definitions.h" + +SequentialProducer::SequentialProducer(uint64_t numRequests, + std::optional seed, + double rwRatio, + unsigned int clkMhz, + std::optional addressIncrement, + std::optional minAddress, + std::optional maxAddress, + uint64_t memorySize, + unsigned int dataLength) + : numberOfRequests(numRequests), + addressIncrement(addressIncrement.value_or(dataLength)), + minAddress(minAddress.value_or(DEFAULT_MIN_ADDRESS)), + maxAddress(maxAddress.value_or(memorySize - 1)), + 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) + SC_REPORT_FATAL("TrafficGenerator", "minAddress is out of range."); + + if (maxAddress > memorySize - 1) + SC_REPORT_FATAL("TrafficGenerator", "minAddress is out of range."); + + if (maxAddress < minAddress) + SC_REPORT_FATAL("TrafficGenerator", "maxAddress is smaller than minAddress."); + + if (rwRatio < 0 || rwRatio > 1) + SC_REPORT_FATAL("TraceSetup", "Read/Write ratio is not a number between 0 and 1."); +} + +Request SequentialProducer::nextRequest() +{ + Request request; + request.address = generatedRequests * addressIncrement % (maxAddress - minAddress) + minAddress; + request.command = readWriteDistribution(randomGenerator) < rwRatio ? Request::Command::Read + : Request::Command::Write; + request.length = dataLength; + request.delay = generatorPeriod; + + generatedRequests++; + return request; +} diff --git a/src/simulator/simulator/generator/SequentialProducer.h b/src/simulator/simulator/generator/SequentialProducer.h new file mode 100644 index 00000000..01f6fd6f --- /dev/null +++ b/src/simulator/simulator/generator/SequentialProducer.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2023, 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: + * Derek Christ + */ + +#pragma once + +#include "simulator/request/RequestProducer.h" + +#include +#include + +class SequentialProducer : public RequestProducer +{ +public: + SequentialProducer(uint64_t numRequests, + std::optional seed, + double rwRatio, + unsigned int clkMhz, + std::optional addressIncrement, + std::optional minAddress, + std::optional maxAddress, + uint64_t memorySize, + unsigned int dataLength); + + 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; + const uint64_t addressIncrement; + const uint64_t minAddress; + 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; + std::uniform_real_distribution readWriteDistribution{0.0, 1.0}; + + uint64_t generatedRequests = 0; +}; diff --git a/src/simulator/simulator/generator/TrafficGenerator.cpp b/src/simulator/simulator/generator/TrafficGenerator.cpp new file mode 100644 index 00000000..59639860 --- /dev/null +++ b/src/simulator/simulator/generator/TrafficGenerator.cpp @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2023, 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: + * Derek Christ + */ + +#include "TrafficGenerator.h" + +TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGeneratorStateMachine const &config, + MemoryManager &memoryManager, + uint64_t memorySize, + unsigned int dataLength, + 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) +{ + for (auto const &state : config.states) + { + std::visit( + [=, &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; + 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, + dataLength); + + producers.emplace(activeState.id, std::move(producer)); + } + else + { + auto producer = + std::make_unique(activeState.numRequests, + config.seed, + activeState.rwRatio, + config.clkMhz, + activeState.addressIncrement, + activeState.minAddress, + activeState.maxAddress, + memorySize, + dataLength); + + producers.emplace(activeState.id, std::move(producer)); + } + } + else if constexpr (std::is_same_v) + { + auto const &idleState = arg; + idleStateClks.emplace(idleState.id, idleState.idleClks); + } + }, + state); + } +} + +TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGenerator const &config, + MemoryManager &memoryManager, + uint64_t memorySize, + unsigned int dataLength, + 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)) +{ + if (config.addressDistribution == DRAMSys::Config::AddressDistribution::Random) + { + auto producer = std::make_unique(config.numRequests, + config.seed, + config.rwRatio, + config.clkMhz, + config.minAddress, + config.maxAddress, + memorySize, + dataLength); + producers.emplace(0, std::move(producer)); + } + else + { + auto producer = std::make_unique(config.numRequests, + config.seed, + config.rwRatio, + config.clkMhz, + config.addressIncrement, + config.minAddress, + config.maxAddress, + memorySize, + dataLength); + producers.emplace(0, std::move(producer)); + } +} + +Request TrafficGenerator::nextRequest() +{ + uint64_t clksToIdle = 0; + if (requestsInState >= producers[currentState]->totalRequests()) + { + // Reset current producer to its initial state + producers[currentState]->reset(); + + auto newState = stateTransition(currentState); + + if (!newState.has_value()) + return Request{.command = Request::Command::Stop}; + + auto idleStateIt = idleStateClks.find(newState.value()); + while (idleStateIt != idleStateClks.cend()) + { + clksToIdle += idleStateIt->second; + newState = stateTransition(currentState); + + if (!newState.has_value()) + return Request{.command = Request::Command::Stop}; + + currentState = newState.value(); + idleStateIt = idleStateClks.find(newState.value()); + } + + currentState = newState.value(); + requestsInState = 0; + } + + requestsInState++; + + Request request = producers[currentState]->nextRequest(); + request.delay += producers[currentState]->clkPeriod() * clksToIdle; + return request; +} + +uint64_t TrafficGenerator::totalRequests() +{ + // Store current state of random generator + std::default_random_engine tempGenerator(randomGenerator); + + // Reset generator to initial state + randomGenerator.seed(); + + uint64_t totalRequests = 0; + unsigned int currentState = 0; + + if (producers.find(currentState) != producers.cend()) + totalRequests += producers.at(currentState)->totalRequests(); + + while (auto nextState = stateTransition(currentState)) + { + currentState = nextState.value(); + + if (producers.find(currentState) != producers.cend()) + totalRequests += producers.at(currentState)->totalRequests(); + } + + // Restore state of random generator + randomGenerator = tempGenerator; + + return totalRequests; +} + +std::optional TrafficGenerator::stateTransition(unsigned int from) +{ + using Transition = DRAMSys::Config::TrafficGeneratorStateTransition; + + std::vector relevantTransitions; + std::copy_if(stateTransistions.cbegin(), + stateTransistions.cend(), + std::back_inserter(relevantTransitions), + [from](Transition transition) { return transition.from == from; }); + + if (relevantTransitions.empty()) + return std::nullopt; + + std::vector propabilities; + std::for_each(relevantTransitions.cbegin(), + relevantTransitions.cend(), + [&propabilities](Transition transition) + { propabilities.push_back(transition.probability); }); + + assert(propabilities.size() == relevantTransitions.size()); + + std::discrete_distribution stateTransitionDistribution(propabilities.cbegin(), + propabilities.cend()); + + std::size_t index = stateTransitionDistribution(randomGenerator); + return relevantTransitions[index].to; +} diff --git a/src/simulator/simulator/generator/TrafficGenerator.h b/src/simulator/simulator/generator/TrafficGenerator.h new file mode 100644 index 00000000..015e31b7 --- /dev/null +++ b/src/simulator/simulator/generator/TrafficGenerator.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2023, 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: + * Derek Christ + */ + +#pragma once + +#include "RandomProducer.h" +#include "SequentialProducer.h" +#include "simulator/Initiator.h" +#include "simulator/MemoryManager.h" +#include "simulator/request/RequestIssuer.h" + +#include + +class TrafficGenerator : public Initiator +{ +public: + TrafficGenerator(DRAMSys::Config::TrafficGenerator const &config, + MemoryManager &memoryManager, + uint64_t memorySize, + unsigned int dataLength, + std::function transactionFinished, + std::function terminateInitiator); + + TrafficGenerator(DRAMSys::Config::TrafficGeneratorStateMachine const &config, + MemoryManager &memoryManager, + uint64_t memorySize, + unsigned int dataLength, + std::function transactionFinished, + std::function terminateInitiator); + + void bind(tlm_utils::multi_target_base<> &target) override { consumer.iSocket.bind(target); } + + uint64_t totalRequests() override; + Request nextRequest(); + + std::optional stateTransition(unsigned int from); + +private: + uint64_t requestsInState = 0; + unsigned int currentState = 0; + const std::vector stateTransistions; + + using IdleClks = uint64_t; + std::unordered_map idleStateClks; + + std::default_random_engine randomGenerator; + + std::unordered_map> producers; + RequestIssuer consumer; +}; diff --git a/src/simulator/simulator/generator/definitions.h b/src/simulator/simulator/generator/definitions.h new file mode 100644 index 00000000..98563553 --- /dev/null +++ b/src/simulator/simulator/generator/definitions.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2023, 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: + * Derek Christ + */ + +#pragma once + +#include + +inline constexpr uint64_t DEFAULT_SEED = 0; +inline constexpr uint64_t DEFAULT_MIN_ADDRESS = 0; diff --git a/src/simulator/simulator/hammer/RowHammer.cpp b/src/simulator/simulator/hammer/RowHammer.cpp new file mode 100644 index 00000000..c1bef363 --- /dev/null +++ b/src/simulator/simulator/hammer/RowHammer.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2023, 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: + * Derek Christ + */ + +#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) +{ +} + +Request RowHammer::nextRequest() +{ + if (generatedRequests >= numberOfRequests) + return Request{.command = Request::Command::Stop}; + + generatedRequests++; + + if (currentAddress == 0x00) + currentAddress = rowIncrement; + else + currentAddress = 0x00; + + Request request; + request.address = currentAddress; + request.command = Request::Command::Read; + request.length = dataLength; + request.delay = generatorPeriod; + return request; +} diff --git a/src/simulator/simulator/hammer/RowHammer.h b/src/simulator/simulator/hammer/RowHammer.h new file mode 100644 index 00000000..78a7c579 --- /dev/null +++ b/src/simulator/simulator/hammer/RowHammer.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2023, 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: + * Derek Christ + */ + +#pragma once + +#include "simulator/request/RequestProducer.h" + +#include + +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; + + uint64_t generatedRequests = 0; + uint64_t currentAddress = 0x00; +}; diff --git a/src/simulator/simulator/main.cpp b/src/simulator/simulator/main.cpp index 8513433f..4c986102 100644 --- a/src/simulator/simulator/main.cpp +++ b/src/simulator/simulator/main.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Technische Universität Kaiserslautern + * Copyright (c) 2023, Technische Universität Kaiserslautern * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,105 +30,158 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: - * Robert Gernhardt - * Matthias Jung - * Luiza Correa - * Lukas Steiner * Derek Christ */ -#include "simulator/TraceSetup.h" -#include "simulator/TrafficInitiator.h" +#include "Initiator.h" +#include "MemoryManager.h" +#include "SimpleInitiator.h" +#include "generator/TrafficGenerator.h" +#include "hammer/RowHammer.h" +#include "player/StlPlayer.h" +#include "util.h" -#include "DRAMSys/simulation/DRAMSys.h" -#include "DRAMSys/simulation/DRAMSysRecordable.h" -#include "DRAMSys/config/DRAMSysConfiguration.h" +#include -#include -#include -#include -#include -#include #include +#include +#include +#include -using namespace sc_core; +#include +#include +#include -std::string pathOfFile(const std::string &file) -{ - return file.substr(0, file.find_last_of('/')); -} - -int main(int argc, char **argv) -{ - return sc_main(argc, argv); -} +static constexpr std::string_view TRACE_DIRECTORY = "traces"; int sc_main(int argc, char **argv) { - sc_set_time_resolution(1, SC_PS); - - std::string resources; - std::string simulationJson; - // Run only with default config (ddr3-example.json): - if (argc == 1) + std::filesystem::path resourceDirectory = "configs"; + if (argc >= 3) { - // Get path of resources: - resources = pathOfFile(argv[0]) - + std::string("/../../configs/"); - simulationJson = resources + "ddr4-example.json"; - } - // Run with specific config but default resource folders: - else if (argc == 2) - { - // Get path of resources: - resources = pathOfFile(argv[0]) - + std::string("/../../configs/"); - simulationJson = argv[1]; - } - // Run with specific config and specific resource folder: - else if (argc == 3) - { - simulationJson = argv[1]; - resources = argv[2]; + resourceDirectory = argv[2]; } - std::vector> players; + std::filesystem::path baseConfig = resourceDirectory / "ddr5-example.json"; + if (argc >= 2) + { + baseConfig = argv[1]; + } - DRAMSys::Config::Configuration configLib = DRAMSys::Config::from_path(simulationJson, resources); + DRAMSys::Config::Configuration configuration = DRAMSys::Config::from_path(baseConfig.c_str()); - // Instantiate DRAMSys: - std::unique_ptr dramSys; + if (!configuration.tracesetup.has_value()) + SC_REPORT_FATAL("Simulator", "No traffic initiators specified"); - if (configLib.simconfig.DatabaseRecording.value_or(false)) - dramSys = std::make_unique("DRAMSys", configLib); - else - dramSys = std::make_unique("DRAMSys", configLib); + DRAMSys::DRAMSysRecordable dramSys("DRAMSys", configuration); - if (!configLib.tracesetup.has_value()) - SC_REPORT_FATAL("sc_main", "No trace setup section provided."); + MemoryManager memoryManager(false); - // Instantiate STL Players: - TraceSetup setup(dramSys->getConfig(), configLib.tracesetup.value(), resources, players); + std::vector> initiators; - // Bind STL Players with DRAMSys: - for (auto& player : players) - player->iSocket.bind(dramSys->tSocket); + unsigned int terminatedInitiators = 0; + auto termianteInitiator = [&initiators, &terminatedInitiators]() + { + terminatedInitiators++; + + if (terminatedInitiators == initiators.size()) + sc_core::sc_stop(); + }; + + uint64_t totalTransactions{}; + uint64_t transactionsFinished = 0; + auto transactionFinished = [&totalTransactions, &transactionsFinished]() + { + transactionsFinished++; + loadBar(transactionsFinished, totalTransactions); + }; + + for (auto const &initiator_config : configuration.tracesetup.value()) + { + uint64_t memorySize = dramSys.getConfig().memSpec->getSimMemSizeInBytes(); + unsigned int dataLength = dramSys.getConfig().memSpec->defaultBytesPerBurst; + + auto initiator = std::visit( + [=, &memoryManager](auto &&config) -> std::unique_ptr + { + using T = std::decay_t; + if constexpr (std::is_same_v || + std::is_same_v) + { + return std::make_unique(config, + memoryManager, + memorySize, + dataLength, + transactionFinished, + termianteInitiator); + } + else if constexpr (std::is_same_v) + { + std::filesystem::path tracePath = + resourceDirectory / TRACE_DIRECTORY / config.name; + + StlPlayer::TraceType traceType; + + auto extension = tracePath.extension(); + if (extension == ".stl") + traceType = StlPlayer::TraceType::Absolute; + else if (extension == ".rtl") + traceType = StlPlayer::TraceType::Relative; + else + { + std::string report = extension.string() + " is not a valid trace format."; + SC_REPORT_FATAL("Simulator", report.c_str()); + } + + StlPlayer player( + tracePath.c_str(), config.clkMhz, dataLength, traceType, false); + + return std::make_unique>(config.name.c_str(), + memoryManager, + std::nullopt, + std::nullopt, + transactionFinished, + termianteInitiator, + std::move(player)); + } + else if constexpr (std::is_same_v) + { + RowHammer hammer( + config.numRequests, config.clkMhz, config.rowIncrement, dataLength); + + return std::make_unique>(config.name.c_str(), + memoryManager, + 1, + 1, + transactionFinished, + termianteInitiator, + std::move(hammer)); + } + }, + initiator_config); + + totalTransactions += initiator->totalRequests(); + + initiator->bind(dramSys.tSocket); + initiators.push_back(std::move(initiator)); + } // Store the starting of the simulation in wall-clock time: auto start = std::chrono::high_resolution_clock::now(); - - // Start SystemC Simulation: - sc_set_stop_mode(SC_STOP_FINISH_DELTA); - sc_start(); - - if (!sc_end_of_simulation_invoked()) + + // Start the SystemC simulation + sc_set_stop_mode(sc_core::SC_STOP_FINISH_DELTA); + sc_core::sc_start(); + + if (!sc_core::sc_end_of_simulation_invoked()) { SC_REPORT_WARNING("sc_main", "Simulation stopped without explicit sc_stop()"); - sc_stop(); + sc_core::sc_stop(); } auto finish = std::chrono::high_resolution_clock::now(); std::chrono::duration elapsed = finish - start; std::cout << "Simulation took " + std::to_string(elapsed.count()) + " seconds." << std::endl; + return 0; } diff --git a/src/simulator/simulator/player/StlPlayer.cpp b/src/simulator/simulator/player/StlPlayer.cpp new file mode 100644 index 00000000..2fbda317 --- /dev/null +++ b/src/simulator/simulator/player/StlPlayer.cpp @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2023, 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: + * Janik Schlemminger + * Robert Gernhardt + * Matthias Jung + * Éder F. Zulian + * Felipe S. Prado + * Derek Christ + */ + +#include "StlPlayer.h" + +#include + +StlPlayer::StlPlayer(std::string_view tracePath, + unsigned int clkMhz, + unsigned int defaultDataLength, + TraceType traceType, + bool storageEnabled) + : traceFile(tracePath.data()), + playerPeriod(sc_core::sc_time(1.0 / static_cast(clkMhz), sc_core::SC_US)), + defaultDataLength(defaultDataLength), + traceType(traceType), + storageEnabled(storageEnabled), + lineBuffers( + {std::make_shared>(), std::make_shared>()}), + readoutBuffer(lineBuffers.at(0)), + parseBuffer(lineBuffers.at(1)) +{ + readoutBuffer->reserve(LINE_BUFFER_SIZE); + parseBuffer->reserve(LINE_BUFFER_SIZE); + + if (!traceFile.is_open()) + SC_REPORT_FATAL("StlPlayer", + (std::string("Could not open trace ") + tracePath.data()).c_str()); + + { + std::string line; + while (std::getline(traceFile, line)) + { + if (line.size() > 1 && line[0] != '#') + numberOfLines++; + } + traceFile.clear(); + traceFile.seekg(0); + } + + parseTraceFile(); + readoutIt = readoutBuffer->cend(); +} + +Request StlPlayer::nextRequest() +{ + if (readoutIt == readoutBuffer->cend()) + { + readoutIt = swapBuffers(); + if (readoutIt == readoutBuffer->cend()) + { + if (parserThread.joinable()) + parserThread.join(); + + // The file is read in completely. Nothing more to do. + return Request{.command = Request::Command::Stop}; + } + } + + sc_core::sc_time delay = readoutIt->delay; + + if (traceType == TraceType::Absolute) + { + delay = std::max(sc_core::sc_time_stamp(), delay); + delay -= sc_core::sc_time_stamp(); + } + + Request request(std::move(*readoutIt)); + request.delay = delay; + + readoutIt++; + return request; +} + +void StlPlayer::parseTraceFile() +{ + unsigned parsedLines = 0; + parseBuffer->clear(); + + while (traceFile && !traceFile.eof() && parsedLines < LINE_BUFFER_SIZE) + { + // Get a new line from the input file. + std::string line; + std::getline(traceFile, line); + currentLine++; + + // If the line is empty (\n or \r\n) or starts with '#' (comment) the transaction is + // ignored. + if (line.size() <= 1 || line.at(0) == '#') + continue; + + parsedLines++; + parseBuffer->emplace_back(); + Request &content = parseBuffer->back(); + + // Trace files MUST provide timestamp, command and address for every + // transaction. The data information depends on the storage mode + // configuration. + std::string element; + std::istringstream iss; + + iss.str(line); + + // Get the timestamp for the transaction. + iss >> element; + if (element.empty()) + SC_REPORT_FATAL( + "StlPlayer", + ("Malformed trace file line " + std::to_string(currentLine) + ".").c_str()); + + content.delay = playerPeriod * static_cast(std::stoull(element)); + + // Get the optional burst length and command + iss >> element; + if (element.empty()) + SC_REPORT_FATAL( + "StlPlayer", + ("Malformed trace file line " + std::to_string(currentLine) + ".").c_str()); + + if (element.at(0) == '(') + { + element.erase(0, 1); + content.length = std::stoul(element); + iss >> element; + if (element.empty()) + SC_REPORT_FATAL( + "StlPlayer", + ("Malformed trace file line " + std::to_string(currentLine) + ".").c_str()); + } + else + content.length = defaultDataLength; + + if (element == "read") + content.command = Request::Command::Read; + else if (element == "write") + content.command = Request::Command::Write; + else + SC_REPORT_FATAL( + "StlPlayer", + ("Malformed trace file line " + std::to_string(currentLine) + ".").c_str()); + + // Get the address. + iss >> element; + if (element.empty()) + SC_REPORT_FATAL( + "StlPlayer", + ("Malformed trace file line " + std::to_string(currentLine) + ".").c_str()); + content.address = std::stoull(element, nullptr, 16); + + // Get the data if necessary. + if (storageEnabled && content.command == Request::Command::Write) + { + // The input trace file must provide the data to be stored into the memory. + iss >> element; + + // Check if data length in the trace file is correct. + // We need two characters to represent 1 byte in hexadecimal. Offset for 0x prefix. + if (element.length() != (content.length * 2 + 2)) + SC_REPORT_FATAL( + "StlPlayer", + ("Malformed trace file line " + std::to_string(currentLine) + ".").c_str()); + + // Set data + for (unsigned i = 0; i < content.length; i++) + content.data.emplace_back(static_cast( + std::stoi(element.substr(i * 2 + 2, 2), nullptr, 16))); + } + } +} + +std::vector::const_iterator StlPlayer::swapBuffers() +{ + // Wait for parser to finish + if (parserThread.joinable()) + parserThread.join(); + + // Swap buffers + std::swap(readoutBuffer, parseBuffer); + + // Start new parser thread + parserThread = std::thread(&StlPlayer::parseTraceFile, this); + + return readoutBuffer->cbegin(); +} diff --git a/src/simulator/simulator/StlPlayer.h b/src/simulator/simulator/player/StlPlayer.h similarity index 57% rename from src/simulator/simulator/StlPlayer.h rename to src/simulator/simulator/player/StlPlayer.h index 35406468..e9d4b8b1 100644 --- a/src/simulator/simulator/StlPlayer.h +++ b/src/simulator/simulator/player/StlPlayer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Technische Universität Kaiserslautern + * Copyright (c) 2023, Technische Universität Kaiserslautern * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,65 +38,59 @@ * Derek Christ */ -#ifndef STLPLAYER_H -#define STLPLAYER_H +#pragma once -#include "simulator/TraceSetup.h" -#include "simulator/TrafficInitiator.h" +#include "simulator/request/Request.h" +#include "simulator/request/RequestProducer.h" -#include -#include -#include -#include -#include #include #include -class StlPlayer : public TrafficInitiator +#include +#include +#include +#include + +class StlPlayer : public RequestProducer { public: - StlPlayer(const sc_core::sc_module_name &name, - const Configuration& config, - const std::string &pathToTrace, - const sc_core::sc_time &playerClk, - unsigned int maxPendingReadRequests, - unsigned int maxPendingWriteRequests, - TraceSetup& setup, - bool relative); - - ~StlPlayer() override; - void sendNextPayload() override; - uint64_t getNumberOfLines() const; - -private: - struct LineContent + enum class TraceType { - sc_core::sc_time sendingTime; - unsigned dataLength; - tlm::tlm_command command; - uint64_t address; - std::vector data; + Absolute, + Relative, }; - void parseTraceFile(); - std::vector::const_iterator swapBuffers(); + StlPlayer(std::string_view tracePath, + unsigned int clkMhz, + unsigned int defaultDataLength, + TraceType traceType, + bool storageEnabled); - std::ifstream file; - uint64_t lineCnt = 0; + Request nextRequest() override; + + sc_core::sc_time clkPeriod() override { return playerPeriod; } + uint64_t totalRequests() override { return numberOfLines; } + +private: + void parseTraceFile(); + std::vector::const_iterator swapBuffers(); + + static constexpr std::size_t LINE_BUFFER_SIZE = 10000; + + const TraceType traceType; + const bool storageEnabled; + const sc_core::sc_time playerPeriod; + const unsigned int defaultDataLength; + + std::ifstream traceFile; + uint64_t currentLine = 0; uint64_t numberOfLines = 0; - const sc_core::sc_time playerClk; // May be different from the memory clock! + std::array>, 2> lineBuffers; + std::shared_ptr> parseBuffer; + std::shared_ptr> readoutBuffer; - static constexpr unsigned lineBufferSize = 10000; - - std::vector* currentBuffer; - std::vector* parseBuffer; - std::array, 2> lineContents; - std::vector::const_iterator lineIterator; + std::vector::const_iterator readoutIt; std::thread parserThread; - - const bool relative; }; - -#endif // STLPLAYER_H diff --git a/src/simulator/simulator/request/Request.h b/src/simulator/simulator/request/Request.h new file mode 100644 index 00000000..7ee69d82 --- /dev/null +++ b/src/simulator/simulator/request/Request.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023, 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: + * Derek Christ + */ + +#pragma once + +#include +#include + +struct Request +{ + enum class Command + { + Read, + Write, + Stop + } command; + uint64_t address; + std::size_t length; + sc_core::sc_time delay; + std::vector data; +}; diff --git a/src/simulator/simulator/request/RequestIssuer.cpp b/src/simulator/simulator/request/RequestIssuer.cpp new file mode 100644 index 00000000..27c76a1b --- /dev/null +++ b/src/simulator/simulator/request/RequestIssuer.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2023, 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: + * Derek Christ + */ + +#include "RequestIssuer.h" + +RequestIssuer::RequestIssuer(sc_core::sc_module_name const &name, + MemoryManager &memoryManager, + std::optional maxPendingReadRequests, + std::optional maxPendingWriteRequests, + std::function nextRequest, + std::function transactionFinished, + std::function terminate) + : sc_module(name), + memoryManager(memoryManager), + maxPendingReadRequests(maxPendingReadRequests), + maxPendingWriteRequests(maxPendingWriteRequests), + nextRequest(std::move(nextRequest)), + transactionFinished(std::move(transactionFinished)), + terminate(std::move(terminate)), + payloadEventQueue(this, &RequestIssuer::peqCallback) +{ + SC_THREAD(sendNextRequest); + iSocket.register_nb_transport_bw(this, &RequestIssuer::nb_transport_bw); +} + +void RequestIssuer::sendNextRequest() +{ + Request request = nextRequest(); + + if (request.command == Request::Command::Stop) + { + finished = true; + return; + } + + tlm::tlm_generic_payload &payload = memoryManager.allocate(request.length); + payload.acquire(); + payload.set_address(request.address); + payload.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); + payload.set_dmi_allowed(false); + payload.set_byte_enable_length(0); + payload.set_data_length(request.length); + payload.set_streaming_width(request.length); + payload.set_command(request.command == Request::Command::Read ? tlm::TLM_READ_COMMAND + : tlm::TLM_WRITE_COMMAND); + + tlm::tlm_phase phase = tlm::BEGIN_REQ; + sc_core::sc_time delay = request.delay; + + if (transactionsSent == 0) + delay = sc_core::SC_ZERO_TIME; + + iSocket->nb_transport_fw(payload, phase, delay); + transactionInProgress = true; + + if (request.command == Request::Command::Read) + pendingReadRequests++; + else if (request.command == Request::Command::Write) + pendingWriteRequests++; + + transactionsSent++; +} + +bool RequestIssuer::nextRequestSendable() const +{ + // If either the maxPendingReadRequests or maxPendingWriteRequests + // limit is reached, do not send next payload. + if (maxPendingReadRequests.has_value() && pendingReadRequests >= maxPendingReadRequests.value()) + return false; + + if (maxPendingWriteRequests.has_value() && + pendingWriteRequests >= maxPendingWriteRequests.value()) + return false; + + return true; +} + +void RequestIssuer::peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase) +{ + if (phase == tlm::END_REQ) + { + if (nextRequestSendable()) + sendNextRequest(); + else + transactionPostponed = true; + } + else if (phase == tlm::BEGIN_RESP) + { + tlm::tlm_phase phase = tlm::END_RESP; + sc_core::sc_time delay = sc_core::SC_ZERO_TIME; + iSocket->nb_transport_fw(payload, phase, delay); + + payload.release(); + transactionInProgress = false; + + 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 (transactionPostponed && nextRequestSendable()) + { + sendNextRequest(); + transactionPostponed = false; + } + + // If all answers were received: + if (finished && transactionsSent == transactionsReceived) + terminate(); + } + else + { + SC_REPORT_FATAL("TrafficInitiator", "PEQ was triggered with unknown phase"); + } +} diff --git a/src/simulator/simulator/TrafficInitiator.h b/src/simulator/simulator/request/RequestIssuer.h similarity index 55% rename from src/simulator/simulator/TrafficInitiator.h rename to src/simulator/simulator/request/RequestIssuer.h index ad3b00ca..1d5b3939 100644 --- a/src/simulator/simulator/TrafficInitiator.h +++ b/src/simulator/simulator/request/RequestIssuer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Technische Universität Kaiserslautern + * Copyright (c) 2023, Technische Universität Kaiserslautern * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,70 +30,68 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: - * Robert Gernhardt - * Matthias Jung - * Éder F. Zulian - * Felipe S. Prado * Derek Christ */ -#ifndef TRAFFICINITIATOR_H -#define TRAFFICINITIATOR_H +#pragma once -#include "simulator/TraceSetup.h" +#include "Request.h" +#include "simulator/MemoryManager.h" -#include "DRAMSys/configuration/Configuration.h" -#include "DRAMSys/common/DebugManager.h" - -#include -#include -#include -#include #include -#include +#include #include +#include -class TrafficInitiator : public sc_core::sc_module +#include + +class RequestIssuer : sc_core::sc_module { public: - tlm_utils::simple_initiator_socket iSocket; - TrafficInitiator(const sc_core::sc_module_name &name, const Configuration& config, TraceSetup& setup, - unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests, unsigned int defaultDataLength); - SC_HAS_PROCESS(TrafficInitiator); - virtual void sendNextPayload() = 0; + tlm_utils::simple_initiator_socket iSocket; -protected: - static sc_core::sc_time evaluateGeneratorClk(const DRAMSys::Config::TrafficInitiator &conf); - - tlm_utils::peq_with_cb_and_phase payloadEventQueue; - void terminate(); - TraceSetup& setup; - void sendToTarget(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase, - const sc_core::sc_time &delay); - - uint64_t transactionsReceived = 0; - uint64_t transactionsSent = 0; - unsigned int pendingReadRequests = 0; - unsigned int pendingWriteRequests = 0; - - const unsigned int maxPendingReadRequests = 0; - const unsigned int maxPendingWriteRequests = 0; - - bool payloadPostponed = false; - bool finished = false; - const unsigned int defaultDataLength; - const bool storageEnabled; - const bool simulationProgressBar; - - // 0 disables the max value. - static constexpr unsigned int defaultMaxPendingWriteRequests = 0; - static constexpr unsigned int defaultMaxPendingReadRequests = 0; + RequestIssuer(sc_core::sc_module_name const &name, + MemoryManager &memoryManager, + std::optional maxPendingReadRequests, + std::optional maxPendingWriteRequests, + std::function nextRequest, + std::function transactionFinished, + std::function terminate); + SC_HAS_PROCESS(RequestIssuer); private: - tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase, - sc_core::sc_time &bwDelay); - void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase); - bool nextPayloadSendable() const; -}; + tlm_utils::peq_with_cb_and_phase payloadEventQueue; + MemoryManager &memoryManager; -#endif // TRAFFICINITIATOR_H + bool transactionInProgress = false; + bool transactionPostponed = false; + bool finished = false; + + uint64_t transactionsSent = 0; + uint64_t transactionsReceived = 0; + + unsigned int pendingReadRequests = 0; + unsigned int pendingWriteRequests = 0; + const std::optional maxPendingReadRequests; + const std::optional maxPendingWriteRequests; + + unsigned int activeProducers = 0; + + std::function transactionFinished; + std::function terminate; + std::function nextRequest; + + void sendNextRequest(); + + bool nextRequestSendable() const; + + tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload, + tlm::tlm_phase &phase, + sc_core::sc_time &bwDelay) + { + payloadEventQueue.notify(payload, phase, bwDelay); + return tlm::TLM_ACCEPTED; + } + + void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase); +}; diff --git a/src/simulator/simulator/request/RequestProducer.h b/src/simulator/simulator/request/RequestProducer.h new file mode 100644 index 00000000..4a6eee73 --- /dev/null +++ b/src/simulator/simulator/request/RequestProducer.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023, 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: + * Derek Christ + */ + +#pragma once + +#include "Request.h" + +class RequestProducer +{ +public: + virtual ~RequestProducer() = default; + + virtual Request nextRequest() = 0; + virtual uint64_t totalRequests() = 0; + virtual sc_core::sc_time clkPeriod() = 0; + virtual void reset(){}; +}; diff --git a/src/simulator/simulator/util.cpp b/src/simulator/simulator/util.cpp new file mode 100644 index 00000000..4c04bb32 --- /dev/null +++ b/src/simulator/simulator/util.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2023, 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: + * Matthias Jung + * Derek Christ + */ + +#include "util.h" + +#include +#include +#include + +void loadBar(uint64_t x, uint64_t n, unsigned int w, unsigned int granularity) +{ + if ((n < 100) || ((x != n) && (x % (n / 100 * granularity) != 0))) + return; + + float ratio = x / (float)n; + unsigned int c = (ratio * w); + float rest = (ratio * w) - c; + std::cout << std::setw(3) << std::round(ratio * 100) << "% |"; + for (unsigned int x = 0; x < c; x++) + std::cout << "█"; + + if (rest >= 0 && rest < 0.125f && c != w) + std::cout << " "; + if (rest >= 0.125f && rest < 2 * 0.125f) + std::cout << "▏"; + if (rest >= 2 * 0.125f && rest < 3 * 0.125f) + std::cout << "▎"; + if (rest >= 3 * 0.125f && rest < 4 * 0.125f) + std::cout << "▍"; + if (rest >= 4 * 0.125f && rest < 5 * 0.125f) + std::cout << "▌"; + if (rest >= 5 * 0.125f && rest < 6 * 0.125f) + std::cout << "▋"; + if (rest >= 6 * 0.125f && rest < 7 * 0.125f) + std::cout << "▊"; + if (rest >= 7 * 0.125f && rest < 8 * 0.125f) + std::cout << "▉"; + + for (unsigned int x = c; x < (w - 1); x++) + std::cout << " "; + std::cout << "|\r" << std::flush; +} diff --git a/src/simulator/simulator/TraceSetup.h b/src/simulator/simulator/util.h similarity index 58% rename from src/simulator/simulator/TraceSetup.h rename to src/simulator/simulator/util.h index 57913573..160d2367 100644 --- a/src/simulator/simulator/TraceSetup.h +++ b/src/simulator/simulator/util.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Technische Universität Kaiserslautern + * Copyright (c) 2023, Technische Universität Kaiserslautern * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,43 +34,8 @@ * Derek Christ */ -#ifndef TRACESETUP_H -#define TRACESETUP_H +#pragma once -#include "simulator/MemoryManager.h" +#include -#include "DRAMSys/config/DRAMSysConfiguration.h" -#include "DRAMSys/configuration/Configuration.h" - -#include -#include -#include -#include - -class TrafficInitiator; - -class TraceSetup -{ -public: - TraceSetup(const Configuration& config, - const DRAMSys::Config::TraceSetup &traceSetup, - const std::string &pathToResources, - std::vector> &devices); - - void trafficInitiatorTerminates(); - void transactionFinished(); - tlm::tlm_generic_payload& allocatePayload(unsigned dataLength); - tlm::tlm_generic_payload& allocatePayload(); - -private: - unsigned int numberOfTrafficInitiators; - uint64_t totalTransactions = 0; - uint64_t remainingTransactions; - unsigned int finishedTrafficInitiators = 0; - MemoryManager memoryManager; - unsigned defaultDataLength = 64; - - static void loadBar(uint64_t x, uint64_t n, unsigned int w = 50, unsigned int granularity = 1); -}; - -#endif // TRACESETUP_H +void loadBar(uint64_t x, uint64_t n, unsigned int w = 50, unsigned int granularity = 1); diff --git a/src/util/DRAMSys/util/json.h b/src/util/DRAMSys/util/json.h index 94a24cdf..8c09489e 100644 --- a/src/util/DRAMSys/util/json.h +++ b/src/util/DRAMSys/util/json.h @@ -35,6 +35,7 @@ * * Authors: * Thomas Psota + * Derek Christ */ diff --git a/tests/tests_configuration/test_configuration.cpp b/tests/tests_configuration/test_configuration.cpp index 89f0740d..3e81d3ef 100644 --- a/tests/tests_configuration/test_configuration.cpp +++ b/tests/tests_configuration/test_configuration.cpp @@ -60,7 +60,7 @@ protected: static DRAMSys::Config::TracePlayer createTracePlayer(); static DRAMSys::Config::TrafficGenerator createTraceGeneratorOneState(); static DRAMSys::Config::TrafficGeneratorStateMachine createTraceGeneratorMultipleStates(); - static DRAMSys::Config::TraceHammer createTraceHammer(); + static DRAMSys::Config::RowHammer createTraceHammer(); DRAMSys::Config::AddressMapping addressMapping{ {{{0, 1}}, @@ -109,7 +109,7 @@ protected: DRAMSys::Config::TracePlayer tracePlayer; DRAMSys::Config::TrafficGenerator traceGeneratorOneState; DRAMSys::Config::TrafficGeneratorStateMachine traceGeneratorMultipleStates; - DRAMSys::Config::TraceHammer traceHammer; + DRAMSys::Config::RowHammer traceHammer; DRAMSys::Config::TraceSetup traceSetup{{tracePlayer, traceGeneratorOneState, traceGeneratorMultipleStates, traceHammer}}; DRAMSys::Config::Configuration configuration{ @@ -183,7 +183,6 @@ DRAMSys::Config::TrafficGenerator ConfigurationTest::createTraceGeneratorOneStat gen.addressIncrement = {}; gen.minAddress = {}; gen.maxAddress = {}; - gen.clksPerRequest = {}; return gen; } @@ -203,7 +202,6 @@ DRAMSys::Config::TrafficGeneratorStateMachine ConfigurationTest::createTraceGene state0.addressIncrement = 256; state0.minAddress = {}; state0.maxAddress = 1024; - state0.clksPerRequest = {}; state0.id = 0; DRAMSys::Config::TrafficGeneratorActiveState state1; @@ -213,7 +211,6 @@ DRAMSys::Config::TrafficGeneratorStateMachine ConfigurationTest::createTraceGene state1.addressIncrement = 512; state1.minAddress = 1024; state1.maxAddress = 2048; - state1.clksPerRequest = {}; state1.id = 1; gen.states.push_back(state0); @@ -226,9 +223,9 @@ DRAMSys::Config::TrafficGeneratorStateMachine ConfigurationTest::createTraceGene return gen; } -DRAMSys::Config::TraceHammer ConfigurationTest::createTraceHammer() +DRAMSys::Config::RowHammer ConfigurationTest::createTraceHammer() { - DRAMSys::Config::TraceHammer hammer; + DRAMSys::Config::RowHammer hammer; hammer.clkMhz = 100; hammer.name = "MyTestHammer";