From 6c5c49179ae8bb672f869e6997708523c50c7092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Tue, 3 Jul 2018 15:03:36 +0200 Subject: [PATCH] Commit of the following: Changed stlPlayer to template class. Integrated the relative stl player. --- DRAMSys/library/library.pro | 1 - DRAMSys/library/src/simulation/StlPlayer.cpp | 168 ------------------ DRAMSys/library/src/simulation/StlPlayer.h | 133 +++++++++++++- DRAMSys/library/src/simulation/TraceSetup.cpp | 32 +++- DRAMSys/library/src/simulation/TraceSetup.h | 2 +- DRAMSys/simulator/main.cpp | 2 +- README.md | 31 +++- 7 files changed, 185 insertions(+), 184 deletions(-) delete mode 100644 DRAMSys/library/src/simulation/StlPlayer.cpp diff --git a/DRAMSys/library/library.pro b/DRAMSys/library/library.pro index c4cef29a..d2e26c1f 100644 --- a/DRAMSys/library/library.pro +++ b/DRAMSys/library/library.pro @@ -112,7 +112,6 @@ SOURCES += \ src/error/errormodel.cpp \ src/controller/Controller.cpp \ src/simulation/TracePlayer.cpp \ - src/simulation/StlPlayer.cpp \ src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.cpp \ src/simulation/TraceSetup.cpp \ src/simulation/DRAMSys.cpp \ diff --git a/DRAMSys/library/src/simulation/StlPlayer.cpp b/DRAMSys/library/src/simulation/StlPlayer.cpp deleted file mode 100644 index e38c3405..00000000 --- a/DRAMSys/library/src/simulation/StlPlayer.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2015, University of 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, - string pathToTrace, - sc_time playerClk, - TracePlayerListener *listener) : - TracePlayer(listener), - file(pathToTrace) -{ - if (!file.is_open()) - SC_REPORT_FATAL(0, (string("Could not open trace ") + pathToTrace).c_str()); - - this->playerClk = playerClk; - this->burstlength = Configuration::getInstance().memSpec.BurstLength; - this->dataLength = Configuration::getInstance().getBytesPerBurst(); - this->lineCnt = 0; -} - -void StlPlayer::nextPayload() -{ - std::string line; - while (line.empty() && file) { - // 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) == '#') - line.clear(); - } - - if (!file) { - // The file is empty. Nothing more to do. - this->finish(); - return; - } else { - numberOfTransactions++; - } - - // Allocate a generic payload for this request. - gp *payload = this->allocatePayload(); - - // Allocate a data buffer and initialize it with zeroes. It may be - // overwritten with data from the trace file depending on the storage - // mode. - unsigned char *data = new unsigned char[dataLength]; - std::fill(data, data + dataLength, 0); - - // Trace files MUST provide timestamp, command and address for every - // transaction. The data information depends on the storage mode - // configuration. - string time; - string command; - string address; - string dataStr; - - std::istringstream iss(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 " + to_string( - lineCnt) + ").").c_str()); - sc_time 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 " + to_string( - lineCnt) + ").").c_str()); - enum tlm_command cmd; - if (command == "read") { - cmd = TLM_READ_COMMAND; - } else if (command == "write") { - cmd = TLM_WRITE_COMMAND; - } else { - SC_REPORT_FATAL("StlPlayer", - (string("Corrupted tracefile, command ") + command + - 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 " + to_string( - lineCnt) + ").").c_str()); - unsigned long long addr = std::stoull(address.c_str(), 0, 16); - - // Get the data if necessary. - if (Configuration::getInstance().StoreMode != StorageMode::NoStorage - && cmd != TLM_READ_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 " + 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. - if (dataStr.length() != (dataLength * 2)) - SC_REPORT_FATAL("StlPlayer", - ("Data in the trace file has an invalid length (line " + to_string( - lineCnt) + ").").c_str()); - - // Set data - for (unsigned i = 0; i < dataLength; i++) - data[i] = (unsigned char)std::stoi(dataStr.substr(i * 2, 2).c_str(), 0, 16); - } - - // Fill up the payload. - payload->set_address(addr); - payload->set_response_status(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_data_ptr(data); - payload->set_command(cmd); - - // Send the transaction directly or schedule it to be sent in the future. - if (sendingTime <= sc_time_stamp()) - this->payloadEventQueue.notify(*payload, BEGIN_REQ, SC_ZERO_TIME); - else - this->payloadEventQueue.notify(*payload, BEGIN_REQ, - sendingTime - sc_time_stamp()); -} - diff --git a/DRAMSys/library/src/simulation/StlPlayer.h b/DRAMSys/library/src/simulation/StlPlayer.h index 4400c58c..8e36b54b 100644 --- a/DRAMSys/library/src/simulation/StlPlayer.h +++ b/DRAMSys/library/src/simulation/StlPlayer.h @@ -46,14 +46,141 @@ using namespace std; using namespace tlm; -struct StlPlayer: public TracePlayer { +template class StlPlayer: public TracePlayer +{ public: StlPlayer(sc_module_name /*name*/, string pathToTrace, sc_time playerClk, - TracePlayerListener *listener); + TracePlayerListener *listener) : + TracePlayer(listener), + file(pathToTrace) + { + if (!file.is_open()) + SC_REPORT_FATAL(0, (string("Could not open trace ") + pathToTrace).c_str()); - void nextPayload(); + this->playerClk = playerClk; + this->burstlength = Configuration::getInstance().memSpec.BurstLength; + this->dataLength = Configuration::getInstance().getBytesPerBurst(); + this->lineCnt = 0; + } + + + + void nextPayload() + { + std::string line; + while (line.empty() && file) { + // 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) == '#') + line.clear(); + } + + if (!file) { + // The file is empty. Nothing more to do. + this->finish(); + return; + } else { + numberOfTransactions++; + } + + // Allocate a generic payload for this request. + gp *payload = this->allocatePayload(); + + // Allocate a data buffer and initialize it with zeroes. It may be + // overwritten with data from the trace file depending on the storage + // mode. + unsigned char *data = new unsigned char[dataLength]; + std::fill(data, data + dataLength, 0); + + // Trace files MUST provide timestamp, command and address for every + // transaction. The data information depends on the storage mode + // configuration. + string time; + string command; + string address; + string dataStr; + + std::istringstream iss(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 " + to_string( + lineCnt) + ").").c_str()); + sc_time 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 " + to_string( + lineCnt) + ").").c_str()); + enum tlm_command cmd; + if (command == "read") { + cmd = TLM_READ_COMMAND; + } else if (command == "write") { + cmd = TLM_WRITE_COMMAND; + } else { + SC_REPORT_FATAL("StlPlayer", + (string("Corrupted tracefile, command ") + command + + 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 " + to_string( + lineCnt) + ").").c_str()); + unsigned long long addr = std::stoull(address.c_str(), 0, 16); + + // Get the data if necessary. + if (Configuration::getInstance().StoreMode != StorageMode::NoStorage + && cmd != TLM_READ_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 " + 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. + if (dataStr.length() != (dataLength * 2)) + SC_REPORT_FATAL("StlPlayer", + ("Data in the trace file has an invalid length (line " + to_string( + lineCnt) + ").").c_str()); + + // Set data + for (unsigned i = 0; i < dataLength; i++) + data[i] = (unsigned char)std::stoi(dataStr.substr(i * 2, 2).c_str(), 0, 16); + } + + // Fill up the payload. + payload->set_address(addr); + payload->set_response_status(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_data_ptr(data); + payload->set_command(cmd); + + if (relative == false) { + // Send the transaction directly or schedule it to be sent in the future. + if (sendingTime <= sc_time_stamp()) + this->payloadEventQueue.notify(*payload, BEGIN_REQ, SC_ZERO_TIME); + else + this->payloadEventQueue.notify(*payload, BEGIN_REQ, + sendingTime - sc_time_stamp()); + } else { + payloadEventQueue.notify(*payload, BEGIN_REQ, sendingTime); + } + } private: ifstream file; diff --git a/DRAMSys/library/src/simulation/TraceSetup.cpp b/DRAMSys/library/src/simulation/TraceSetup.cpp index 21152069..b0fd3390 100644 --- a/DRAMSys/library/src/simulation/TraceSetup.cpp +++ b/DRAMSys/library/src/simulation/TraceSetup.cpp @@ -37,7 +37,7 @@ traceSetup::traceSetup(std::string uri, std::string pathToResources, - std::vector *devices) + std::vector * devices) { // Load Simulation: tinyxml2::XMLDocument simulationdoc; @@ -69,17 +69,37 @@ traceSetup::traceSetup(std::string uri, } std::string name = device->GetText(); + + int 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::string stlFile = pathToResources + string("traces/") + name; std::string moduleName = name; // replace all '.' to '_' std::replace( moduleName.begin(), moduleName.end(), '.', '_'); - StlPlayer *player = new StlPlayer(moduleName.c_str(), - stlFile, - playerClk, - this); - + TracePlayer * player; + if(strcmp(ext.c_str(), "stl") == 0) + { + player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, this); + } + else if(strcmp(ext.c_str(), "rstl") == 0) + { + player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, this); + } + else + { + std::string error = "Unsupported file extension in " + name; + throw std::runtime_error(error); + } devices->push_back(player); if (Configuration::getInstance().SimulationProgressBar) { diff --git a/DRAMSys/library/src/simulation/TraceSetup.h b/DRAMSys/library/src/simulation/TraceSetup.h index 2287d052..2d0596c9 100644 --- a/DRAMSys/library/src/simulation/TraceSetup.h +++ b/DRAMSys/library/src/simulation/TraceSetup.h @@ -49,7 +49,7 @@ class traceSetup : public TracePlayerListener public: traceSetup(std::string uri, std::string pathToResources, - std::vector *devices); + std::vector * devices); virtual void tracePlayerTerminates() override; virtual void transactionFinished() override; diff --git a/DRAMSys/simulator/main.cpp b/DRAMSys/simulator/main.cpp index 39fb82d7..8c71aaeb 100644 --- a/DRAMSys/simulator/main.cpp +++ b/DRAMSys/simulator/main.cpp @@ -72,7 +72,7 @@ int sc_main(int argc, char **argv) SimulationXML = resources + "simulations/ddr3-example.xml"; } - std::vector players; + std::vector players; // Instantiate DRAMSys: DRAMSys *dramSys = new DRAMSys("DRAMSys", SimulationXML, resources); diff --git a/README.md b/README.md index 4421e710..ed4b1a61 100644 --- a/README.md +++ b/README.md @@ -381,11 +381,22 @@ configuration structure. The **device** configuration consists of two parameters - clkMhz (operation frequency for this device) - and a **trace file**. +#### Trace files + A **trace file** is a pre-recorded file containing memory transactions. Each memory transaction has a timestamp that tells the simulator when it shall happen, a transaction type (read or write) and a memory address given in hexadecimal. +There are two different kinds of trace files. They differ in their timing behaviour and are distingushed by their file extension. + +##### STL Trace (.stl) + +The timestamp corresponds to the time the request is to be issued and it is +given in cycles of the bus master device. Example: the device is a FPGA with +frequency 200 MHz (clock period of 5 ns). If the timestamp is 10 it means that +the request is to be issued when time is 50 ns. + Here is an example syntax: ``` @@ -397,10 +408,22 @@ Here is an example syntax: 81: read 0x400180 ``` -The timestamp corresponds to the time the request is to be issued and it is -given in cycles of the bus master device. Example: the device is a FPGA with -frequency 200 MHz (clock period of 5 ns). If the timestamp is 10 it means that -the request is to be issued when time is 50 ns. +##### Relative STL Traces (.rstl) + +The timestamp corresponds to the time the request is to be issued relative to the end of the transaction before or the beginning of the trace. This results in a simulation in which the **trace player** is able to react to possible delays due to DRAM bottlenecks. + +Here is an example syntax: + +``` +# Comment lines begin with # +# [clock-cyle]: [write|read] [hex-address] +31: read 0x400140 +2: read 0x400160 +23: write 0x7fff8000 +25: read 0x400180 +``` + +#### Trace player A **trace player** is **equivalent** to a bus master **device** (processor, FPGA, etc.). It reads an input trace file and translates each line into