From d40462dcf792003cfb5895f427ac12a174230299 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Tue, 6 Oct 2020 13:33:50 +0200 Subject: [PATCH 1/6] Split up StlPlayer into source and header file. --- DRAMSys/library/src/simulation/Arbiter.cpp | 18 +- DRAMSys/simulator/CMakeLists.txt | 2 +- DRAMSys/simulator/StlPlayer.cpp | 215 +++++++++++++++++++++ DRAMSys/simulator/StlPlayer.h | 177 +---------------- DRAMSys/simulator/TracePlayer.cpp | 22 ++- DRAMSys/simulator/TraceSetup.cpp | 4 +- 6 files changed, 250 insertions(+), 188 deletions(-) create mode 100644 DRAMSys/simulator/StlPlayer.cpp diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp index b25f3c2f..85b26716 100644 --- a/DRAMSys/library/src/simulation/Arbiter.cpp +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -105,7 +105,7 @@ tlm_sync_enum Arbiter::nb_transport_bw(int channelId, tlm_generic_payload &paylo tlm_phase &phase, sc_time &bwDelay) { // Check channel ID - assert((unsigned int)channelId == DramExtension::getExtension(payload).getChannel().ID()); + assert(static_cast(channelId) == DramExtension::getExtension(payload).getChannel().ID()); PRINTDEBUGMESSAGE(name(), "[bw] " + getPhaseName(phase) + " notification in " + bwDelay.to_string()); @@ -120,7 +120,7 @@ unsigned int Arbiter::transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans) Configuration::getInstance().addressOffset); DecodedAddress decodedAddress = addressDecoder->decodeAddress(trans.get_address()); - return iSocket[decodedAddress.channel]->transport_dbg(trans); + return iSocket[static_cast(decodedAddress.channel)]->transport_dbg(trans); } void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) @@ -141,7 +141,7 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) channelIsFree[channelId] = false; tlm_phase tPhase = BEGIN_REQ; sc_time tDelay = SC_ZERO_TIME; - iSocket[channelId]->nb_transport_fw(payload, tPhase, tDelay); + iSocket[static_cast(channelId)]->nb_transport_fw(payload, tPhase, tDelay); // TODO: early completion of channel controller!!! } else @@ -158,7 +158,7 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) // The arbiter receives a transaction which phase is END_REQ from memory controller and forwards it to the requester device. tlm_phase tPhase = END_REQ; sc_time tDelay = SC_ZERO_TIME; - tSocket[threadId]->nb_transport_bw(payload, tPhase, tDelay); + tlm_sync_enum response = tSocket[static_cast(threadId)]->nb_transport_bw(payload, tPhase, tDelay); // This channel is now free! Dispatch a new transaction (phase is BEGIN_REQ) from the queue, if any. Send it to the memory controller. if (!pendingRequests[channelId].empty()) @@ -168,7 +168,7 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) pendingRequests[channelId].pop(); tlm_phase tPhase = BEGIN_REQ; sc_time tDelay = SC_ZERO_TIME; - iSocket[channelId]->nb_transport_fw(payloadToSend, tPhase, tDelay); + iSocket[static_cast(channelId)]->nb_transport_fw(payloadToSend, tPhase, tDelay); // TODO: early completion of channel controller // Mark the channel as busy again. channelIsFree[channelId] = false; @@ -183,7 +183,7 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) { tlm_phase tPhase = BEGIN_RESP; sc_time tDelay = SC_ZERO_TIME; - tlm_sync_enum returnValue = tSocket[threadId]->nb_transport_bw(payload, tPhase, tDelay); + tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(payload, tPhase, tDelay); if (returnValue != TLM_ACCEPTED) { tPhase = END_RESP; @@ -201,7 +201,7 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) { tlm_phase tPhase = END_RESP; sc_time tDelay = SC_ZERO_TIME; - iSocket[channelId]->nb_transport_fw(payload, tPhase, tDelay); + iSocket[static_cast(channelId)]->nb_transport_fw(payload, tPhase, tDelay); } // Drop one element of the queue of BEGIN_RESP from memory to this device pendingResponses[threadId].pop(); @@ -215,7 +215,7 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) // Send ONE extra BEGIN_RESP to the device tlm_phase tPhase = BEGIN_RESP; sc_time tDelay = SC_ZERO_TIME; - tlm_sync_enum returnValue = tSocket[threadId]->nb_transport_bw(payloadToSend, tPhase, tDelay); + tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(payloadToSend, tPhase, tDelay); if (returnValue != TLM_ACCEPTED) { tPhase = END_RESP; @@ -235,7 +235,7 @@ void Arbiter::appendDramExtension(int socketId, tlm_generic_payload &payload) unsigned int burstlength = payload.get_streaming_width(); DecodedAddress decodedAddress = addressDecoder->decodeAddress(payload.get_address()); - DramExtension::setExtension(payload, Thread(socketId), + DramExtension::setExtension(payload, Thread(static_cast(socketId)), Channel(decodedAddress.channel), Rank(decodedAddress.rank), BankGroup(decodedAddress.bankgroup), Bank(decodedAddress.bank), Row(decodedAddress.row), Column(decodedAddress.column), diff --git a/DRAMSys/simulator/CMakeLists.txt b/DRAMSys/simulator/CMakeLists.txt index 6dc49e0b..f43029b8 100644 --- a/DRAMSys/simulator/CMakeLists.txt +++ b/DRAMSys/simulator/CMakeLists.txt @@ -45,7 +45,7 @@ add_executable(DRAMSys main.cpp ExampleInitiator.h MemoryManager.cpp - StlPlayer.h + StlPlayer.cpp TraceGenerator.h TracePlayer.cpp TracePlayerListener.h diff --git a/DRAMSys/simulator/StlPlayer.cpp b/DRAMSys/simulator/StlPlayer.cpp new file mode 100644 index 00000000..a336a330 --- /dev/null +++ b/DRAMSys/simulator/StlPlayer.cpp @@ -0,0 +1,215 @@ +/* + * 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 + */ + +#include "StlPlayer.h" + +StlPlayer::StlPlayer(sc_module_name name, + std::string pathToTrace, + sc_time playerClk, + TracePlayerListener *listener, + bool relative) + : TracePlayer(name, listener), file(pathToTrace), + currentBuffer(&lineContents[0]), + parseBuffer(&lineContents[1]), + relative(relative) +{ + if (!file.is_open()) + SC_REPORT_FATAL(0, (std::string("Could not open trace ") + pathToTrace).c_str()); + + this->playerClk = playerClk; + burstlength = Configuration::getInstance().memSpec->burstLength; + dataLength = Configuration::getInstance().getBytesPerBurst(); + lineCnt = 0; + + currentBuffer->reserve(lineBufferSize); + parseBuffer->reserve(lineBufferSize); + + parseTraceFile(); + lineIterator = currentBuffer->cend(); +} + +StlPlayer::~StlPlayer() +{ + if (parserThread.joinable()) + parserThread.join(); +} + +void StlPlayer::nextPayload() +{ + if (lineIterator == currentBuffer->cend()) + { + lineIterator = swapBuffers(); + if (lineIterator == currentBuffer->cend()) + { + // The file is empty. Nothing more to do. + this->finish(); + return; + } + } + + numberOfTransactions++; + + // Allocate a generic payload for this request. + tlm::tlm_generic_payload *payload = this->allocatePayload(); + payload->acquire(); + + // Fill up the payload. + payload->set_address(lineIterator->addr); + payload->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); + payload->set_dmi_allowed(false); + payload->set_byte_enable_length(0); + payload->set_streaming_width(burstlength); + payload->set_data_length(dataLength); + payload->set_command(lineIterator->cmd); + std::copy(lineIterator->data.begin(), lineIterator->data.end(), payload->get_data_ptr()); + + if (!relative) + { + // Send the transaction directly or schedule it to be sent in the future. + if (lineIterator->sendingTime <= sc_time_stamp()) + this->payloadEventQueue.notify(*payload, tlm::BEGIN_REQ, SC_ZERO_TIME); + else + this->payloadEventQueue.notify(*payload, tlm::BEGIN_REQ, + lineIterator->sendingTime - sc_time_stamp()); + } + else + payloadEventQueue.notify(*payload, tlm::BEGIN_REQ, lineIterator->sendingTime); + + lineIterator++; +} + +void StlPlayer::parseTraceFile() +{ + unsigned parsedLines = 0; + parseBuffer->clear(); + while (file && !file.eof() && parsedLines < lineBufferSize) + { + // Get a new line from the input file. + std::getline(file, line); + lineCnt++; + // If the line starts with '#' (commented lines) the transaction is ignored. + if (line.empty() || 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. + time.clear(); + command.clear(); + address.clear(); + dataStr.clear(); + + iss.clear(); + iss.str(line); + + // Get the timestamp for the transaction. + iss >> time; + if (time.empty()) + SC_REPORT_FATAL("StlPlayer", + ("Malformed trace file. Timestamp could not be found (line " + std::to_string( + lineCnt) + ").").c_str()); + content.sendingTime = std::stoull(time.c_str()) * playerClk; + + // Get the command. + iss >> command; + if (command.empty()) + SC_REPORT_FATAL("StlPlayer", + ("Malformed trace file. Command could not be found (line " + std::to_string( + lineCnt) + ").").c_str()); + + if (command == "read") + content.cmd = tlm::TLM_READ_COMMAND; + else if (command == "write") + content.cmd = tlm::TLM_WRITE_COMMAND; + else + SC_REPORT_FATAL("StlPlayer", + (std::string("Corrupted tracefile, command ") + command + + std::string(" unknown")).c_str()); + + // Get the address. + iss >> address; + if (address.empty()) + SC_REPORT_FATAL("StlPlayer", + ("Malformed trace file. Address could not be found (line " + + std::to_string(lineCnt) + ").").c_str()); + content.addr = std::stoull(address.c_str(), nullptr, 16); + + // Get the data if necessary. + if (storageEnabled && content.cmd == tlm::TLM_WRITE_COMMAND) + { + // The input trace file must provide the data to be stored into the memory. + iss >> dataStr; + if (dataStr.empty()) + SC_REPORT_FATAL("StlPlayer", + ("Malformed trace file. Data information could not be found (line " + std::to_string( + lineCnt) + ").").c_str()); + + // 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 (dataStr.length() != (dataLength * 2 + 2)) + SC_REPORT_FATAL("StlPlayer", + ("Data in the trace file has an invalid length (line " + std::to_string( + lineCnt) + ").").c_str()); + + // Set data + for (unsigned i = 0; i < dataLength; i++) + content.data.emplace_back(static_cast + (std::stoi(dataStr.substr(i * 2 + 2, 2).c_str(), nullptr, 16))); + } + } +} + +std::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(); +} diff --git a/DRAMSys/simulator/StlPlayer.h b/DRAMSys/simulator/StlPlayer.h index 787f00d5..0a8cea6b 100644 --- a/DRAMSys/simulator/StlPlayer.h +++ b/DRAMSys/simulator/StlPlayer.h @@ -54,186 +54,23 @@ struct LineContent std::vector data; }; -template class StlPlayer : public TracePlayer { public: StlPlayer(sc_module_name name, std::string pathToTrace, sc_time playerClk, - TracePlayerListener *listener) : - TracePlayer(name, listener), - file(pathToTrace), - currentBuffer(&lineContents[0]), - parseBuffer(&lineContents[1]) - { - if (!file.is_open()) - SC_REPORT_FATAL(0, (std::string("Could not open trace ") + pathToTrace).c_str()); + TracePlayerListener *listener, + bool relative); - this->playerClk = playerClk; - burstlength = Configuration::getInstance().memSpec->burstLength; - dataLength = Configuration::getInstance().getBytesPerBurst(); - lineCnt = 0; + virtual ~StlPlayer() override; - currentBuffer->reserve(lineBufferSize); - parseBuffer->reserve(lineBufferSize); - - parseTraceFile(); - lineIterator = currentBuffer->cend(); - } - - ~StlPlayer() - { - if (parserThread.joinable()) - parserThread.join(); - } + virtual void nextPayload() override; private: - void parseTraceFile() - { - unsigned parsedLines = 0; - parseBuffer->clear(); - while (file && !file.eof() && parsedLines < lineBufferSize) - { - // Get a new line from the input file. - std::getline(file, line); - lineCnt++; - // If the line starts with '#' (commented lines) the transaction is ignored. - if (line.empty() || line.at(0) == '#') - continue; + void parseTraceFile(); + std::vector::const_iterator swapBuffers(); - 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. - time.clear(); - command.clear(); - address.clear(); - dataStr.clear(); - - iss.clear(); - iss.str(line); - - // Get the timestamp for the transaction. - iss >> time; - if (time.empty()) - SC_REPORT_FATAL("StlPlayer", - ("Malformed trace file. Timestamp could not be found (line " + std::to_string( - lineCnt) + ").").c_str()); - content.sendingTime = std::stoull(time.c_str()) * playerClk; - - // Get the command. - iss >> command; - if (command.empty()) - SC_REPORT_FATAL("StlPlayer", - ("Malformed trace file. Command could not be found (line " + std::to_string( - lineCnt) + ").").c_str()); - - if (command == "read") - content.cmd = tlm::TLM_READ_COMMAND; - else if (command == "write") - content.cmd = tlm::TLM_WRITE_COMMAND; - else - SC_REPORT_FATAL("StlPlayer", - (std::string("Corrupted tracefile, command ") + command + - std::string(" unknown")).c_str()); - - // Get the address. - iss >> address; - if (address.empty()) - SC_REPORT_FATAL("StlPlayer", - ("Malformed trace file. Address could not be found (line " - + std::to_string(lineCnt) + ").").c_str()); - content.addr = std::stoull(address.c_str(), nullptr, 16); - - // Get the data if necessary. - if (storageEnabled && content.cmd == tlm::TLM_WRITE_COMMAND) - { - // The input trace file must provide the data to be stored into the memory. - iss >> dataStr; - if (dataStr.empty()) - SC_REPORT_FATAL("StlPlayer", - ("Malformed trace file. Data information could not be found (line " + std::to_string( - lineCnt) + ").").c_str()); - - // 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 (dataStr.length() != (dataLength * 2 + 2)) - SC_REPORT_FATAL("StlPlayer", - ("Data in the trace file has an invalid length (line " + std::to_string( - lineCnt) + ").").c_str()); - - // Set data - for (unsigned i = 0; i < dataLength; i++) - content.data.emplace_back((unsigned char)std::stoi(dataStr.substr(i * 2 + 2, 2).c_str(), nullptr, 16)); - } - } - } - - std::vector::const_iterator 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(); - } - -public: - void nextPayload() - { - if (lineIterator == currentBuffer->cend()) - { - lineIterator = swapBuffers(); - if (lineIterator == currentBuffer->cend()) - { - // The file is empty. Nothing more to do. - this->finish(); - return; - } - } - - numberOfTransactions++; - - // Allocate a generic payload for this request. - tlm::tlm_generic_payload *payload = this->allocatePayload(); - payload->acquire(); - - // Fill up the payload. - payload->set_address(lineIterator->addr); - payload->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); - payload->set_dmi_allowed(false); - payload->set_byte_enable_length(0); - payload->set_streaming_width(burstlength); - payload->set_data_length(dataLength); - payload->set_command(lineIterator->cmd); - std::copy(lineIterator->data.begin(), lineIterator->data.end(), payload->get_data_ptr()); - - if (relative == false) - { - // Send the transaction directly or schedule it to be sent in the future. - if (lineIterator->sendingTime <= sc_time_stamp()) - this->payloadEventQueue.notify(*payload, tlm::BEGIN_REQ, SC_ZERO_TIME); - else - this->payloadEventQueue.notify(*payload, tlm::BEGIN_REQ, - lineIterator->sendingTime - sc_time_stamp()); - } - else - payloadEventQueue.notify(*payload, tlm::BEGIN_REQ, lineIterator->sendingTime); - - lineIterator++; - } - -private: std::ifstream file; unsigned int lineCnt; @@ -257,6 +94,8 @@ private: std::string line; std::istringstream iss; + + const bool relative; }; #endif // STLPLAYER_H diff --git a/DRAMSys/simulator/TracePlayer.cpp b/DRAMSys/simulator/TracePlayer.cpp index 1162963e..06305557 100644 --- a/DRAMSys/simulator/TracePlayer.cpp +++ b/DRAMSys/simulator/TracePlayer.cpp @@ -79,13 +79,18 @@ tlm_sync_enum TracePlayer::nb_transport_bw(tlm_generic_payload &payload, void TracePlayer::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) { - if (phase == BEGIN_REQ) { + if (phase == BEGIN_REQ) + { sendToTarget(payload, phase, SC_ZERO_TIME); transactionsSent++; PRINTDEBUGMESSAGE(name(), "Performing request #" + std::to_string(transactionsSent)); - } else if (phase == END_REQ) { + } + else if (phase == END_REQ) + { nextPayload(); - } else if (phase == BEGIN_RESP) { + } + else if (phase == BEGIN_RESP) + { payload.release(); sendToTarget(payload, END_RESP, SC_ZERO_TIME); if (Configuration::getInstance().simulationProgressBar) @@ -95,11 +100,14 @@ void TracePlayer::peqCallback(tlm_generic_payload &payload, // If all answers were received: if (finished == true && numberOfTransactions == transactionsReceived) - { this->terminate(); - } - } else if (phase == END_RESP) { - } else { + + } + else if (phase == END_RESP) + { + } + else + { SC_REPORT_FATAL(0, "TracePlayer PEQ was triggered with unknown phase"); } } diff --git a/DRAMSys/simulator/TraceSetup.cpp b/DRAMSys/simulator/TraceSetup.cpp index 73bdb3f1..b2e7e512 100644 --- a/DRAMSys/simulator/TraceSetup.cpp +++ b/DRAMSys/simulator/TraceSetup.cpp @@ -79,9 +79,9 @@ TraceSetup::TraceSetup(std::string uri, TracePlayer *player; if (ext == "stl") - player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, this); + player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, this, false); else if (ext == "rstl") - player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, this); + player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, this, true); else throw std::runtime_error("Unsupported file extension in " + name); From 432d37a9d7575ae0234359550ab93fa5e2d14906 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Tue, 6 Oct 2020 15:51:24 +0200 Subject: [PATCH 2/6] File cleanup. --- DRAMSys/simulator/CMakeLists.txt | 3 +- DRAMSys/simulator/MemoryManager.cpp | 29 ++++++++++----- DRAMSys/simulator/MemoryManager.h | 1 + DRAMSys/simulator/StlPlayer.cpp | 14 ++++--- DRAMSys/simulator/StlPlayer.h | 3 +- DRAMSys/simulator/TraceGenerator.h | 38 ++----------------- DRAMSys/simulator/TracePlayer.cpp | 14 +++---- DRAMSys/simulator/TracePlayer.h | 11 ++---- DRAMSys/simulator/TracePlayerListener.h | 49 ------------------------- DRAMSys/simulator/TraceSetup.cpp | 14 +++++-- DRAMSys/simulator/TraceSetup.h | 16 ++++---- DRAMSys/simulator/main.cpp | 14 ++++--- 12 files changed, 73 insertions(+), 133 deletions(-) delete mode 100644 DRAMSys/simulator/TracePlayerListener.h diff --git a/DRAMSys/simulator/CMakeLists.txt b/DRAMSys/simulator/CMakeLists.txt index f43029b8..1b3a9851 100644 --- a/DRAMSys/simulator/CMakeLists.txt +++ b/DRAMSys/simulator/CMakeLists.txt @@ -46,9 +46,8 @@ add_executable(DRAMSys ExampleInitiator.h MemoryManager.cpp StlPlayer.cpp - TraceGenerator.h + TraceGenerator.cpp TracePlayer.cpp - TracePlayerListener.h TraceSetup.cpp ) diff --git a/DRAMSys/simulator/MemoryManager.cpp b/DRAMSys/simulator/MemoryManager.cpp index 24ef8d12..361b3f68 100644 --- a/DRAMSys/simulator/MemoryManager.cpp +++ b/DRAMSys/simulator/MemoryManager.cpp @@ -42,14 +42,23 @@ using namespace tlm; MemoryManager::MemoryManager() - : numberOfAllocations(0), numberOfFrees(0) {} + : numberOfAllocations(0), numberOfFrees(0) +{ + if (Configuration::getInstance().storeMode == "NoStorage") + storageEnabled = false; + else + storageEnabled = true; +} MemoryManager::~MemoryManager() { for (tlm_generic_payload *payload : freePayloads) { - // Delete data buffer - delete[] payload->get_data_ptr(); + if (storageEnabled) + { + // Delete data buffer + delete[] payload->get_data_ptr(); + } // Delete all extensions payload->reset(); delete payload; @@ -68,12 +77,15 @@ tlm_generic_payload *MemoryManager::allocate() numberOfAllocations++; tlm_generic_payload *payload = new tlm_generic_payload(this); - // Allocate a data buffer and initialize it with zeroes: - unsigned int dataLength = Configuration::getInstance().getBytesPerBurst(); - unsigned char *data = new unsigned char[dataLength]; - std::fill(data, data + dataLength, 0); + if (storageEnabled) + { + // Allocate a data buffer and initialize it with zeroes: + unsigned int dataLength = Configuration::getInstance().getBytesPerBurst(); + unsigned char *data = new unsigned char[dataLength]; + std::fill(data, data + dataLength, 0); + payload->set_data_ptr(data); + } - payload->set_data_ptr(data); return payload; } else @@ -88,4 +100,3 @@ void MemoryManager::free(tlm_generic_payload *payload) { freePayloads.push_back(payload); } - diff --git a/DRAMSys/simulator/MemoryManager.h b/DRAMSys/simulator/MemoryManager.h index 397ed40d..9893496d 100644 --- a/DRAMSys/simulator/MemoryManager.h +++ b/DRAMSys/simulator/MemoryManager.h @@ -52,6 +52,7 @@ private: uint64_t numberOfAllocations; uint64_t numberOfFrees; std::vector freePayloads; + bool storageEnabled = false; }; #endif // MEMORYMANAGER_H diff --git a/DRAMSys/simulator/StlPlayer.cpp b/DRAMSys/simulator/StlPlayer.cpp index a336a330..4a471931 100644 --- a/DRAMSys/simulator/StlPlayer.cpp +++ b/DRAMSys/simulator/StlPlayer.cpp @@ -39,12 +39,14 @@ #include "StlPlayer.h" +using namespace tlm; + StlPlayer::StlPlayer(sc_module_name name, std::string pathToTrace, sc_time playerClk, - TracePlayerListener *listener, + TraceSetup *setup, bool relative) - : TracePlayer(name, listener), file(pathToTrace), + : TracePlayer(name, setup), file(pathToTrace), currentBuffer(&lineContents[0]), parseBuffer(&lineContents[1]), relative(relative) @@ -86,12 +88,12 @@ void StlPlayer::nextPayload() numberOfTransactions++; // Allocate a generic payload for this request. - tlm::tlm_generic_payload *payload = this->allocatePayload(); + tlm_generic_payload *payload = setup->allocatePayload(); payload->acquire(); // Fill up the payload. payload->set_address(lineIterator->addr); - payload->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); + payload->set_response_status(TLM_INCOMPLETE_RESPONSE); payload->set_dmi_allowed(false); payload->set_byte_enable_length(0); payload->set_streaming_width(burstlength); @@ -103,9 +105,9 @@ void StlPlayer::nextPayload() { // Send the transaction directly or schedule it to be sent in the future. if (lineIterator->sendingTime <= sc_time_stamp()) - this->payloadEventQueue.notify(*payload, tlm::BEGIN_REQ, SC_ZERO_TIME); + payloadEventQueue.notify(*payload, tlm::BEGIN_REQ, SC_ZERO_TIME); else - this->payloadEventQueue.notify(*payload, tlm::BEGIN_REQ, + payloadEventQueue.notify(*payload, tlm::BEGIN_REQ, lineIterator->sendingTime - sc_time_stamp()); } else diff --git a/DRAMSys/simulator/StlPlayer.h b/DRAMSys/simulator/StlPlayer.h index 0a8cea6b..74e4f713 100644 --- a/DRAMSys/simulator/StlPlayer.h +++ b/DRAMSys/simulator/StlPlayer.h @@ -44,6 +44,7 @@ #include #include #include +#include "TraceSetup.h" #include "TracePlayer.h" struct LineContent @@ -60,7 +61,7 @@ public: StlPlayer(sc_module_name name, std::string pathToTrace, sc_time playerClk, - TracePlayerListener *listener, + TraceSetup *setup, bool relative); virtual ~StlPlayer() override; diff --git a/DRAMSys/simulator/TraceGenerator.h b/DRAMSys/simulator/TraceGenerator.h index d39edfc6..8993e8d3 100644 --- a/DRAMSys/simulator/TraceGenerator.h +++ b/DRAMSys/simulator/TraceGenerator.h @@ -39,43 +39,13 @@ #define TRACEGENERATOR_H #include "TracePlayer.h" +#include "TraceSetup.h" -struct TraceGenerator : public TracePlayer +class TraceGenerator : public TracePlayer { public: - TraceGenerator(sc_module_name name, unsigned int fCKMhz, TracePlayerListener *listener) - : TracePlayer(name, listener), transCounter(0) - { - if (fCKMhz == 0) - tCK = Configuration::getInstance().memSpec->tCK; - else - tCK = sc_time(1.0 / fCKMhz, SC_US); - - this->burstlenght = Configuration::getInstance().memSpec->burstLength; - } - - virtual void nextPayload() override - { - if (transCounter >= 1000) { // TODO set limit! - this->terminate(); - } - - tlm::tlm_generic_payload *payload = this->allocatePayload(); - payload->acquire(); - unsigned char *dataElement = new unsigned - char[16]; // TODO: column / burst breite - - payload->set_address(0x0); - payload->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); - payload->set_dmi_allowed(false); - payload->set_byte_enable_length(0); - payload->set_streaming_width(this->burstlenght); - payload->set_data_ptr(dataElement); - payload->set_data_length(16); - payload->set_command(tlm::TLM_READ_COMMAND); - transCounter++; - this->payloadEventQueue.notify(*payload, tlm::BEGIN_REQ, SC_ZERO_TIME); - } + TraceGenerator(sc_module_name name, unsigned int fCKMhz, TraceSetup *setup); + virtual void nextPayload() override; private: unsigned int burstlenght; diff --git a/DRAMSys/simulator/TracePlayer.cpp b/DRAMSys/simulator/TracePlayer.cpp index 06305557..a87a5947 100644 --- a/DRAMSys/simulator/TracePlayer.cpp +++ b/DRAMSys/simulator/TracePlayer.cpp @@ -37,13 +37,14 @@ */ #include "TracePlayer.h" +#include "TraceSetup.h" using namespace tlm; -TracePlayer::TracePlayer(sc_module_name name, TracePlayerListener *listener) : +TracePlayer::TracePlayer(sc_module_name name, TraceSetup *setup) : sc_module(name), payloadEventQueue(this, &TracePlayer::peqCallback), - listener(listener) + setup(setup) { iSocket.register_nb_transport_bw(this, &TracePlayer::nb_transport_bw); @@ -53,11 +54,6 @@ TracePlayer::TracePlayer(sc_module_name name, TracePlayerListener *listener) : storageEnabled = true; } -tlm_generic_payload *TracePlayer::allocatePayload() -{ - return memoryManager.allocate(); -} - void TracePlayer::finish() { finished = true; @@ -66,7 +62,7 @@ void TracePlayer::finish() void TracePlayer::terminate() { cout << sc_time_stamp() << " " << this->name() << " terminated " << std::endl; - listener->tracePlayerTerminates(); + setup->tracePlayerTerminates(); } tlm_sync_enum TracePlayer::nb_transport_bw(tlm_generic_payload &payload, @@ -94,7 +90,7 @@ void TracePlayer::peqCallback(tlm_generic_payload &payload, payload.release(); sendToTarget(payload, END_RESP, SC_ZERO_TIME); if (Configuration::getInstance().simulationProgressBar) - listener->transactionFinished(); + setup->transactionFinished(); transactionsReceived++; diff --git a/DRAMSys/simulator/TracePlayer.h b/DRAMSys/simulator/TracePlayer.h index e1a35b56..d00bbadc 100644 --- a/DRAMSys/simulator/TracePlayer.h +++ b/DRAMSys/simulator/TracePlayer.h @@ -46,26 +46,25 @@ #include #include #include -#include "MemoryManager.h" #include "configuration/Configuration.h" #include "common/DebugManager.h" -#include "TracePlayerListener.h" +#include "TraceSetup.h" -struct TracePlayer : public sc_module +class TracePlayer : public sc_module { public: tlm_utils::simple_initiator_socket iSocket; - TracePlayer(sc_module_name name, TracePlayerListener *listener); + TracePlayer(sc_module_name name, TraceSetup *setup); virtual void nextPayload() = 0; unsigned int getNumberOfLines(std::string pathToTrace); protected: - tlm::tlm_generic_payload *allocatePayload(); tlm_utils::peq_with_cb_and_phase payloadEventQueue; void finish(); void terminate(); unsigned int numberOfTransactions = 0; bool storageEnabled = false; + TraceSetup *setup; private: tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase, @@ -73,10 +72,8 @@ private: void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase); void sendToTarget(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase, const sc_time &delay); - MemoryManager memoryManager; unsigned int transactionsSent = 0; unsigned int transactionsReceived = 0; - TracePlayerListener *listener; bool finished = false; }; diff --git a/DRAMSys/simulator/TracePlayerListener.h b/DRAMSys/simulator/TracePlayerListener.h deleted file mode 100644 index c4bd7460..00000000 --- a/DRAMSys/simulator/TracePlayerListener.h +++ /dev/null @@ -1,49 +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 - */ - -#ifndef TRACEPLAYERLISTENER_H -#define TRACEPLAYERLISTENER_H - -class TracePlayerListener -{ -public: - virtual void tracePlayerTerminates() = 0; - virtual void transactionFinished() = 0; - virtual ~TracePlayerListener() {} -}; - -#endif // TRACEPLAYERLISTENER_H diff --git a/DRAMSys/simulator/TraceSetup.cpp b/DRAMSys/simulator/TraceSetup.cpp index b2e7e512..decd5423 100644 --- a/DRAMSys/simulator/TraceSetup.cpp +++ b/DRAMSys/simulator/TraceSetup.cpp @@ -35,10 +35,13 @@ */ #include "TraceSetup.h" +#include "StlPlayer.h" + +using namespace tlm; TraceSetup::TraceSetup(std::string uri, std::string pathToResources, - std::vector *devices) + std::vector *players) { // Load Simulation: nlohmann::json simulationdoc = parseJSON(uri); @@ -85,7 +88,7 @@ TraceSetup::TraceSetup(std::string uri, else throw std::runtime_error("Unsupported file extension in " + name); - devices->push_back(player); + players->push_back(player); if (Configuration::getInstance().simulationProgressBar) totalTransactions += player->getNumberOfLines(stlFile); @@ -93,7 +96,7 @@ TraceSetup::TraceSetup(std::string uri, } remainingTransactions = totalTransactions; - numberOfTracePlayers = devices->size(); + numberOfTracePlayers = players->size(); } void TraceSetup::tracePlayerTerminates() @@ -113,3 +116,8 @@ void TraceSetup::transactionFinished() if (remainingTransactions == 0) std::cout << std::endl; } + +tlm_generic_payload *TraceSetup::allocatePayload() +{ + return memoryManager.allocate(); +} diff --git a/DRAMSys/simulator/TraceSetup.h b/DRAMSys/simulator/TraceSetup.h index 6d3f1f48..165c8747 100644 --- a/DRAMSys/simulator/TraceSetup.h +++ b/DRAMSys/simulator/TraceSetup.h @@ -38,28 +38,28 @@ #include #include +#include +#include "MemoryManager.h" -#include "common/utils.h" -#include "TracePlayer.h" -#include "StlPlayer.h" +class TracePlayer; - -class TraceSetup : public TracePlayerListener +class TraceSetup { public: TraceSetup(std::string uri, std::string pathToResources, std::vector *devices); - virtual void tracePlayerTerminates() override; - virtual void transactionFinished() override; - virtual ~TraceSetup() {} + void tracePlayerTerminates(); + void transactionFinished(); + tlm::tlm_generic_payload *allocatePayload(); private: unsigned int numberOfTracePlayers; unsigned int totalTransactions = 0; unsigned int remainingTransactions; unsigned int finishedTracePlayers = 0; + MemoryManager memoryManager; }; #endif // TRACESETUP_H diff --git a/DRAMSys/simulator/main.cpp b/DRAMSys/simulator/main.cpp index 7d29c614..1a0d5a0c 100644 --- a/DRAMSys/simulator/main.cpp +++ b/DRAMSys/simulator/main.cpp @@ -45,6 +45,7 @@ #include "simulation/DRAMSys.h" #include "TraceSetup.h" +#include "TracePlayer.h" #ifdef RECORDING #include "simulation/DRAMSysRecordable.h" @@ -70,21 +71,24 @@ int sc_main(int argc, char **argv) std::string resources; std::string simulationJson; // Run only with default config (ddr3-example.json): - if (argc == 1) { + if (argc == 1) + { // Get path of resources: resources = pathOfFile(argv[0]) + std::string("/../../DRAMSys/library/resources/"); simulationJson = resources + "simulations/ddr3-example.json"; } // Run with specific config but default resource folders: - else if (argc == 2) { + else if (argc == 2) + { // Get path of resources: resources = pathOfFile(argv[0]) + std::string("/../../DRAMSys/library/resources/"); simulationJson = argv[1]; } // Run with spefific config and specific resource folder: - else if (argc == 3) { + else if (argc == 3) + { simulationJson = argv[1]; resources = argv[2]; } @@ -105,7 +109,7 @@ int sc_main(int argc, char **argv) dramSys = new DRAMSys("DRAMSys", simulationJson, resources); // Instantiate STL Players: - TraceSetup *ts = new TraceSetup(simulationJson, resources, &players); + TraceSetup *setup = new TraceSetup(simulationJson, resources, &players); // Bind STL Players with DRAMSys: for (size_t i = 0; i < players.size(); i++) @@ -143,7 +147,7 @@ int sc_main(int argc, char **argv) delete dramSys; for (auto player : players) delete player; - delete ts; + delete setup; return 0; } From e90df2174c550b6e6690c60b3ebe323222298a23 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Thu, 8 Oct 2020 14:42:00 +0200 Subject: [PATCH 3/6] Directly call arbiter PEQ from trace player. --- DRAMSys/simulator/StlPlayer.cpp | 10 +++++----- DRAMSys/simulator/TracePlayer.cpp | 13 ++----------- DRAMSys/simulator/TracePlayer.h | 9 +++++---- DRAMSys/simulator/main.cpp | 4 ---- 4 files changed, 12 insertions(+), 24 deletions(-) diff --git a/DRAMSys/simulator/StlPlayer.cpp b/DRAMSys/simulator/StlPlayer.cpp index 4a471931..4aa918ec 100644 --- a/DRAMSys/simulator/StlPlayer.cpp +++ b/DRAMSys/simulator/StlPlayer.cpp @@ -103,16 +103,16 @@ void StlPlayer::nextPayload() if (!relative) { - // Send the transaction directly or schedule it to be sent in the future. if (lineIterator->sendingTime <= sc_time_stamp()) - payloadEventQueue.notify(*payload, tlm::BEGIN_REQ, SC_ZERO_TIME); + sendToTarget(*payload, BEGIN_REQ, SC_ZERO_TIME); else - payloadEventQueue.notify(*payload, tlm::BEGIN_REQ, - lineIterator->sendingTime - sc_time_stamp()); + sendToTarget(*payload, BEGIN_REQ, lineIterator->sendingTime - sc_time_stamp()); } else - payloadEventQueue.notify(*payload, tlm::BEGIN_REQ, lineIterator->sendingTime); + sendToTarget(*payload, BEGIN_REQ, lineIterator->sendingTime); + transactionsSent++; + PRINTDEBUGMESSAGE(name(), "Performing request #" + std::to_string(transactionsSent)); lineIterator++; } diff --git a/DRAMSys/simulator/TracePlayer.cpp b/DRAMSys/simulator/TracePlayer.cpp index a87a5947..69e8b16a 100644 --- a/DRAMSys/simulator/TracePlayer.cpp +++ b/DRAMSys/simulator/TracePlayer.cpp @@ -46,6 +46,7 @@ TracePlayer::TracePlayer(sc_module_name name, TraceSetup *setup) : payloadEventQueue(this, &TracePlayer::peqCallback), setup(setup) { + SC_METHOD(nextPayload); iSocket.register_nb_transport_bw(this, &TracePlayer::nb_transport_bw); if (Configuration::getInstance().storeMode == "NoStorage") @@ -75,13 +76,7 @@ tlm_sync_enum TracePlayer::nb_transport_bw(tlm_generic_payload &payload, void TracePlayer::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) { - if (phase == BEGIN_REQ) - { - sendToTarget(payload, phase, SC_ZERO_TIME); - transactionsSent++; - PRINTDEBUGMESSAGE(name(), "Performing request #" + std::to_string(transactionsSent)); - } - else if (phase == END_REQ) + if (phase == END_REQ) { nextPayload(); } @@ -97,10 +92,6 @@ void TracePlayer::peqCallback(tlm_generic_payload &payload, // If all answers were received: if (finished == true && numberOfTransactions == transactionsReceived) this->terminate(); - - } - else if (phase == END_RESP) - { } else { diff --git a/DRAMSys/simulator/TracePlayer.h b/DRAMSys/simulator/TracePlayer.h index d00bbadc..998929c9 100644 --- a/DRAMSys/simulator/TracePlayer.h +++ b/DRAMSys/simulator/TracePlayer.h @@ -55,6 +55,7 @@ class TracePlayer : public sc_module public: tlm_utils::simple_initiator_socket iSocket; TracePlayer(sc_module_name name, TraceSetup *setup); + SC_HAS_PROCESS(TracePlayer); virtual void nextPayload() = 0; unsigned int getNumberOfLines(std::string pathToTrace); @@ -62,17 +63,17 @@ protected: tlm_utils::peq_with_cb_and_phase payloadEventQueue; void finish(); void terminate(); - unsigned int numberOfTransactions = 0; bool storageEnabled = false; TraceSetup *setup; + void sendToTarget(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase, + const sc_time &delay); + unsigned int numberOfTransactions = 0; + unsigned int transactionsSent = 0; private: tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase, sc_time &bwDelay); void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase); - void sendToTarget(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase, - const sc_time &delay); - unsigned int transactionsSent = 0; unsigned int transactionsReceived = 0; bool finished = false; }; diff --git a/DRAMSys/simulator/main.cpp b/DRAMSys/simulator/main.cpp index 1a0d5a0c..8d26d245 100644 --- a/DRAMSys/simulator/main.cpp +++ b/DRAMSys/simulator/main.cpp @@ -132,10 +132,6 @@ int sc_main(int argc, char **argv) // Store the starting of the simulation in wallclock time: auto start = std::chrono::high_resolution_clock::now(); - // Kickstart the players: - for (auto &p : players) - p->nextPayload(); - // Start SystemC Simulation: sc_set_stop_mode(SC_STOP_FINISH_DELTA); sc_start(); From 0501bbd2c8f4e9c9243f58f3444146d2f5c6048b Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Thu, 8 Oct 2020 16:00:52 +0200 Subject: [PATCH 4/6] Add trace generator cpp file. --- DRAMSys/simulator/TraceGenerator.cpp | 75 ++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 DRAMSys/simulator/TraceGenerator.cpp diff --git a/DRAMSys/simulator/TraceGenerator.cpp b/DRAMSys/simulator/TraceGenerator.cpp new file mode 100644 index 00000000..3a3069ff --- /dev/null +++ b/DRAMSys/simulator/TraceGenerator.cpp @@ -0,0 +1,75 @@ +/* + * 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 + */ + +#include "TraceGenerator.h" + +TraceGenerator::TraceGenerator(sc_module_name name, + unsigned int fCKMhz, TraceSetup *setup) + : TracePlayer(name, setup), transCounter(0) +{ + if (fCKMhz == 0) + tCK = Configuration::getInstance().memSpec->tCK; + else + tCK = sc_time(1.0 / fCKMhz, SC_US); + + burstlenght = Configuration::getInstance().memSpec->burstLength; +} + +void TraceGenerator::nextPayload() +{ + if (transCounter >= 1000) // TODO set limit! + terminate(); + + tlm::tlm_generic_payload *payload = setup->allocatePayload(); + payload->acquire(); + unsigned char *dataElement = new unsigned char[16]; + // TODO: column / burst breite + + payload->set_address(0x0); + payload->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); + payload->set_dmi_allowed(false); + payload->set_byte_enable_length(0); + payload->set_streaming_width(burstlenght); + payload->set_data_ptr(dataElement); + payload->set_data_length(16); + payload->set_command(tlm::TLM_READ_COMMAND); + transCounter++; + + sendToTarget(*payload, tlm::BEGIN_REQ, SC_ZERO_TIME); + transactionsSent++; + PRINTDEBUGMESSAGE(name(), "Performing request #" + std::to_string(transactionsSent)); +} From 328a37184347feee6899b39de46809f4d96dbf0d Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Tue, 20 Oct 2020 09:32:28 +0200 Subject: [PATCH 5/6] Make controller easier to understand. --- DRAMSys/library/src/controller/Controller.cpp | 122 ++++++++++-------- DRAMSys/library/src/controller/Controller.h | 9 +- DRAMSys/library/src/simulation/Arbiter.h | 3 +- 3 files changed, 72 insertions(+), 62 deletions(-) diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index 8ff1d7f6..4176929e 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -219,24 +219,14 @@ Controller::~Controller() void Controller::controllerMethod() { - // clear command buffer - readyCommands.clear(); - // (1) Release payload if arbiter has accepted the result (finish END_RESP) - if (payloadToRelease != nullptr && timeToRelease <= sc_time_stamp()) - finishEndResp(); + finishEndResp(); // (2) Send next result to arbiter (start BEGIN_RESP) - if (payloadToRelease == nullptr) - startBeginResp(); + startBeginResp(); // (3) Insert new request from arbiter into scheduler and restart appropriate BM (finish BEGIN_REQ) - if (payloadToAcquire != nullptr && timeToAcquire <= sc_time_stamp()) - { - unsigned bankID = DramExtension::getBank(payloadToAcquire).ID(); - finishBeginReq(); - bankMachines[bankID]->start(); - } + finishBeginReq(); // (4) Start refresh and power-down managers to issue requests for the current time for (auto it : refreshManagers) @@ -244,8 +234,10 @@ void Controller::controllerMethod() for (auto it : powerDownManagers) it->start(); - // (5) Choose one request and send it to DRAM + // (5) Collect all ready commands from BMs, RMs and PDMs CommandTuple::Type commandTuple; + // clear command buffer + readyCommands.clear(); for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++) { @@ -270,6 +262,7 @@ void Controller::controllerMethod() } } + // (6) Select one of the ready commands and issue it to the DRAM bool readyCmdBlocked = false; if (!readyCommands.empty()) { @@ -314,12 +307,10 @@ void Controller::controllerMethod() readyCmdBlocked = true; } - // (6) Accept request from arbiter if scheduler is not full, otherwise backpressure (start END_REQ) - if (payloadToAcquire != nullptr && timeToAcquire == sc_max_time()) - startEndReq(); + // (7) Accept request from arbiter if scheduler is not full, otherwise backpressure (start END_REQ) + startEndReq(); - // (7) Restart bank machines, refresh managers and power-down managers to issue new requests for the future - // TODO: check if all calls are necessary + // (8) Restart bank machines, refresh managers and power-down managers to issue new requests for the future sc_time timeForNextTrigger = sc_max_time(); for (auto it : bankMachines) { @@ -343,13 +334,13 @@ tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload &trans, if (phase == BEGIN_REQ) { - payloadToAcquire = &trans; - timeToAcquire = sc_time_stamp() + notificationDelay; + transToAcquire.payload = &trans; + transToAcquire.time = sc_time_stamp() + notificationDelay; beginReqEvent.notify(notificationDelay); } else if (phase == END_RESP) { - timeToRelease = sc_time_stamp() + notificationDelay; + transToRelease.time = sc_time_stamp() + notificationDelay; endRespEvent.notify(notificationDelay); } else @@ -375,63 +366,80 @@ unsigned int Controller::transport_dbg(tlm_generic_payload &trans) void Controller::finishBeginReq() { - NDEBUG_UNUSED(uint64_t id) = DramExtension::getPayloadID(payloadToAcquire); - PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " entered system."); + if (transToAcquire.payload != nullptr && transToAcquire.time <= sc_time_stamp()) + { + NDEBUG_UNUSED(uint64_t id) = DramExtension::getPayloadID(transToAcquire.payload); + PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " entered system."); - if (totalNumberOfPayloads == 0) - idleTimeCollector.end(); - totalNumberOfPayloads++; + if (totalNumberOfPayloads == 0) + idleTimeCollector.end(); + totalNumberOfPayloads++; - Rank rank = DramExtension::getRank(payloadToAcquire); - if (ranksNumberOfPayloads[rank.ID()] == 0) - powerDownManagers[rank.ID()]->triggerExit(); + Rank rank = DramExtension::getRank(transToAcquire.payload); + if (ranksNumberOfPayloads[rank.ID()] == 0) + powerDownManagers[rank.ID()]->triggerExit(); - ranksNumberOfPayloads[rank.ID()]++; + ranksNumberOfPayloads[rank.ID()]++; - scheduler->storeRequest(payloadToAcquire); - payloadToAcquire->acquire(); - timeToAcquire = sc_max_time(); + scheduler->storeRequest(transToAcquire.payload); + transToAcquire.payload->acquire(); + transToAcquire.time = sc_max_time(); + + Bank bank = DramExtension::getBank(transToAcquire.payload); + bankMachines[bank.ID()]->start(); + } } void Controller::startEndReq() { - if (scheduler->hasBufferSpace()) + if (transToAcquire.payload != nullptr && transToAcquire.time == sc_max_time()) { - payloadToAcquire->set_response_status(TLM_OK_RESPONSE); - sendToFrontend(payloadToAcquire, END_REQ); - payloadToAcquire = nullptr; + if (scheduler->hasBufferSpace()) + { + transToAcquire.payload->set_response_status(TLM_OK_RESPONSE); + sendToFrontend(transToAcquire.payload, END_REQ); + transToAcquire.payload = nullptr; + } + else + PRINTDEBUGMESSAGE(name(), "Total number of payloads exceeded, backpressure!"); } - else - PRINTDEBUGMESSAGE(name(), "Total number of payloads exceeded, backpressure!"); } void Controller::startBeginResp() { - payloadToRelease = respQueue->nextPayload(); - - if (payloadToRelease != nullptr) - sendToFrontend(payloadToRelease, BEGIN_RESP); - else + if (transToRelease.payload == nullptr) { - sc_time triggerTime = respQueue->getTriggerTime(); - if (triggerTime != sc_max_time()) - dataResponseEvent.notify(triggerTime - sc_time_stamp()); + transToRelease.payload = respQueue->nextPayload(); + + if (transToRelease.payload != nullptr) + { + transToRelease.time = sc_max_time(); + sendToFrontend(transToRelease.payload, BEGIN_RESP); + } + else + { + sc_time triggerTime = respQueue->getTriggerTime(); + if (triggerTime != sc_max_time()) + dataResponseEvent.notify(triggerTime - sc_time_stamp()); + } } } void Controller::finishEndResp() { - NDEBUG_UNUSED(uint64_t id) = DramExtension::getPayloadID(payloadToRelease); - PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " left system."); + if (transToRelease.payload != nullptr && transToRelease.time <= sc_time_stamp()) + { + NDEBUG_UNUSED(uint64_t id) = DramExtension::getPayloadID(transToRelease.payload); + PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " left system."); - payloadToRelease->release(); - payloadToRelease = nullptr; - timeToRelease = sc_max_time(); - numberOfTransactionsServed++; + transToRelease.payload->release(); + transToRelease.payload = nullptr; + numberOfTransactionsServed++; - totalNumberOfPayloads--; - if (totalNumberOfPayloads == 0) - idleTimeCollector.start(); + totalNumberOfPayloads--; + if (totalNumberOfPayloads == 0) + idleTimeCollector.start(); + } } void Controller::sendToFrontend(tlm_generic_payload *payload, tlm_phase phase) diff --git a/DRAMSys/library/src/controller/Controller.h b/DRAMSys/library/src/controller/Controller.h index 9002c007..4fef0c65 100644 --- a/DRAMSys/library/src/controller/Controller.h +++ b/DRAMSys/library/src/controller/Controller.h @@ -88,10 +88,11 @@ private: std::vector refreshManagers; std::vector powerDownManagers; - tlm::tlm_generic_payload *payloadToAcquire = nullptr; - sc_time timeToAcquire = sc_max_time(); - tlm::tlm_generic_payload *payloadToRelease = nullptr; - sc_time timeToRelease = sc_max_time(); + struct Transaction + { + tlm::tlm_generic_payload *payload = nullptr; + sc_time time = sc_max_time(); + } transToAcquire, transToRelease; void finishBeginReq(); void startEndReq(); diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index a6373b33..c845e2b9 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -70,7 +71,7 @@ private: std::vector> pendingRequests; // used to account for the response_accept_delay in the initiators (traceplayer, core etc.) // This is a queue of responses comming from the memory side. The phase of these transactions is BEGIN_RESP. - std::map> pendingResponses; + std::unordered_map> pendingResponses; // Initiated by initiator side // This function is called when an arbiter's target socket receives a transaction from a device From 32c7148dd9938e5dd40403f209d48cc479e9e65e Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Thu, 22 Oct 2020 13:43:00 +0200 Subject: [PATCH 6/6] Set correct time of generation in arbiter. --- DRAMSys/library/src/simulation/Arbiter.cpp | 6 +++--- DRAMSys/library/src/simulation/Arbiter.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp index 85b26716..8ed91d8e 100644 --- a/DRAMSys/library/src/simulation/Arbiter.cpp +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -84,7 +84,7 @@ tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload &payload, // In the begin request phase the socket ID is appended to the payload. // It will extracted from the payload and used later. - appendDramExtension(id, payload); + appendDramExtension(id, payload, fwDelay); payload.acquire(); } else if (phase == END_RESP) @@ -228,10 +228,10 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) "Payload event queue in arbiter was triggered with unknown phase"); } -void Arbiter::appendDramExtension(int socketId, tlm_generic_payload &payload) +void Arbiter::appendDramExtension(int socketId, tlm_generic_payload &payload, sc_time delay) { // Set Generation Extension and DRAM Extension - GenerationExtension::setExtension(&payload, sc_time_stamp()); + GenerationExtension::setExtension(&payload, sc_time_stamp() + delay); unsigned int burstlength = payload.get_streaming_width(); DecodedAddress decodedAddress = addressDecoder->decodeAddress(payload.get_address()); diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index c845e2b9..c2c83222 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -87,7 +87,7 @@ private: void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase); - void appendDramExtension(int socketId, tlm::tlm_generic_payload &payload); + void appendDramExtension(int socketId, tlm::tlm_generic_payload &payload, sc_time delay); std::vector nextPayloadID; };