/* * 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 "simulator/Initiator.h" #include "simulator/MemoryManager.h" #include "simulator/SimpleInitiator.h" #include "simulator/generator/TrafficGenerator.h" #include "simulator/hammer/RowHammer.h" #include "simulator/player/StlPlayer.h" #include "simulator/util.h" #include #include #include #include #include #include #include #include static constexpr std::string_view TRACE_DIRECTORY = "traces"; int sc_main(int argc, char **argv) { std::filesystem::path resourceDirectory = DRAMSYS_RESOURCE_DIR; if (argc >= 3) { resourceDirectory = argv[2]; } std::filesystem::path baseConfig = resourceDirectory / "ddr4-example.json"; if (argc >= 2) { baseConfig = argv[1]; } DRAMSys::Config::Configuration configuration = DRAMSys::Config::from_path(baseConfig.c_str(), resourceDirectory.c_str()); if (!configuration.tracesetup.has_value()) SC_REPORT_FATAL("Simulator", "No traffic initiators specified"); std::unique_ptr dramSys; if (configuration.simconfig.DatabaseRecording.value_or(false)) { dramSys = std::make_unique("DRAMSys", configuration); } else { dramSys = std::make_unique("DRAMSys", configuration); } bool storageEnabled = dramSys->getConfig().storeMode == DRAMSys::Configuration::StoreMode::Store; MemoryManager memoryManager(storageEnabled); std::vector> initiators; 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, &configuration]() { transactionsFinished++; if (configuration.simconfig.SimulationProgressBar.value_or(false)) loadBar(transactionsFinished, totalTransactions); }; for (auto const &initiator_config : configuration.tracesetup.value()) { uint64_t memorySize = dramSys->getConfig().memSpec->getSimMemSizeInBytes(); unsigned int defaultDataLength = 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, defaultDataLength, 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, defaultDataLength, 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, defaultDataLength); 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 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_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; }