Commit of the following:
Changed stlPlayer to template class. Integrated the relative stl player.
This commit is contained in:
@@ -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 \
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -46,14 +46,141 @@
|
||||
using namespace std;
|
||||
using namespace tlm;
|
||||
|
||||
struct StlPlayer: public TracePlayer {
|
||||
template <bool relative> 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;
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
traceSetup::traceSetup(std::string uri,
|
||||
std::string pathToResources,
|
||||
std::vector<StlPlayer *> *devices)
|
||||
std::vector<TracePlayer *> * 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<false>(moduleName.c_str(), stlFile, playerClk, this);
|
||||
}
|
||||
else if(strcmp(ext.c_str(), "rstl") == 0)
|
||||
{
|
||||
player = new StlPlayer<true>(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) {
|
||||
|
||||
@@ -49,7 +49,7 @@ class traceSetup : public TracePlayerListener
|
||||
public:
|
||||
traceSetup(std::string uri,
|
||||
std::string pathToResources,
|
||||
std::vector<StlPlayer *> *devices);
|
||||
std::vector<TracePlayer*> * devices);
|
||||
|
||||
virtual void tracePlayerTerminates() override;
|
||||
virtual void transactionFinished() override;
|
||||
|
||||
@@ -72,7 +72,7 @@ int sc_main(int argc, char **argv)
|
||||
SimulationXML = resources + "simulations/ddr3-example.xml";
|
||||
}
|
||||
|
||||
std::vector<StlPlayer *> players;
|
||||
std::vector<TracePlayer*> players;
|
||||
|
||||
// Instantiate DRAMSys:
|
||||
DRAMSys *dramSys = new DRAMSys("DRAMSys", SimulationXML, resources);
|
||||
|
||||
31
README.md
31
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
|
||||
|
||||
Reference in New Issue
Block a user