Integrate length converter, add length parameter to stl.

This commit is contained in:
Lukas Steiner
2022-02-11 11:12:04 +01:00
parent 45bbb4aaaa
commit 8737e6d297
10 changed files with 120 additions and 84 deletions

View File

@@ -52,6 +52,7 @@ add_executable(DRAMSys
TrafficGenerator.cpp
TrafficInitiator.cpp
TraceSetup.cpp
LengthConverter.cpp
)
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/../library/src/simulation/DRAMSysRecordable.cpp)

View File

@@ -59,7 +59,7 @@ public:
tlm_utils::simple_initiator_socket<LengthConverter> iSocket;
tlm_utils::simple_target_socket<LengthConverter> tSocket;
explicit LengthConverter(const sc_core::sc_module_name& name, unsigned maxOutputLength, bool storageEnabled);
LengthConverter(const sc_core::sc_module_name& name, unsigned maxOutputLength, bool storageEnabled);
SC_HAS_PROCESS(LengthConverter);
private:
@@ -69,8 +69,8 @@ private:
//std::vector<bool> tSocketIsBusy;
//std::vector<bool> iSocketIsBusy;
unsigned maxOutputLength;
bool storageEnabled;
const unsigned maxOutputLength;
const bool storageEnabled;
void createChildTranses(tlm::tlm_generic_payload* parentTrans);
@@ -183,17 +183,13 @@ private:
static bool isParentTrans(const tlm::tlm_generic_payload* trans)
{
if (trans->get_extension<ParentExtension>() != nullptr)
return true;
auto* extension = trans->get_extension<ParentExtension>();
if (extension != nullptr)
return !extension->childTranses.empty();
else
return false;
}
// tlm::tlm_generic_payload* getParentTrans()
// {
// return parentTrans;
// }
static void setExtension(tlm::tlm_generic_payload* parentTrans, std::vector<tlm::tlm_generic_payload*> childTranses)
{
auto* extension = parentTrans->get_extension<ParentExtension>();

View File

@@ -48,9 +48,10 @@ StlPlayer::StlPlayer(const sc_module_name &name,
const sc_time &playerClk,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
bool needsLengthConverter,
TraceSetup *setup,
bool relative) :
TrafficInitiator(name, setup, maxPendingReadRequests, maxPendingWriteRequests),
TrafficInitiator(name, setup, maxPendingReadRequests, maxPendingWriteRequests, needsLengthConverter),
file(pathToTrace), relative(relative), playerClk(playerClk)
{
currentBuffer = &lineContents[0];
@@ -73,8 +74,7 @@ StlPlayer::StlPlayer(const sc_module_name &name,
SC_REPORT_FATAL("StlPlayer", "Trace file is empty");
}
burstLength = Configuration::getInstance().memSpec->burstLength;
dataLength = Configuration::getInstance().memSpec->bytesPerBurst;
defaultDataLength = Configuration::getInstance().memSpec->bytesPerBurst;
currentBuffer->reserve(lineBufferSize);
parseBuffer->reserve(lineBufferSize);
@@ -107,13 +107,12 @@ void StlPlayer::sendNextPayload()
payload->acquire();
// Fill up the payload.
payload->set_address(lineIterator->addr);
payload->set_address(lineIterator->address);
payload->set_response_status(TLM_INCOMPLETE_RESPONSE);
payload->set_dmi_allowed(false);
payload->set_byte_enable_length(0);
payload->set_streaming_width(burstLength);
payload->set_data_length(dataLength);
payload->set_command(lineIterator->cmd);
payload->set_data_length(lineIterator->dataLength);
payload->set_command(lineIterator->command);
std::copy(lineIterator->data.begin(), lineIterator->data.end(), payload->get_data_ptr());
sc_time sendingTime;
@@ -164,64 +163,61 @@ void StlPlayer::parseTraceFile()
// Trace files MUST provide timestamp, command and address for every
// transaction. The data information depends on the storage mode
// configuration.
std::string time, command, address, dataStr;
std::string element;
std::istringstream iss;
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 = playerClk * static_cast<double>(std::stoull(time));
iss >> element;
if (element.empty())
SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ").").c_str());
content.sendingTime = playerClk * static_cast<double>(std::stoull(element));
// 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_READ_COMMAND;
else if (command == "write")
content.cmd = TLM_WRITE_COMMAND;
// Get the optional burst length and command
iss >> element;
if (element.empty())
SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ").").c_str());
if (element.at(0) == '(')
{
element.erase(0, 1);
content.dataLength = std::stoul(element);
iss >> element;
if (element.empty())
SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ").").c_str());
}
else
SC_REPORT_FATAL("StlPlayer",
(std::string("Corrupted tracefile, command ") + command +
std::string(" unknown")).c_str());
content.dataLength = defaultDataLength;
std::cout << "Data length: " << content.dataLength << std::endl;
if (element == "read")
content.command = TLM_READ_COMMAND;
else if (element == "write")
content.command = TLM_WRITE_COMMAND;
else
SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ").").c_str());
// Get the address.
iss >> 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, nullptr, 16);
iss >> element;
if (element.empty())
SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ").").c_str());
content.address = std::stoull(element, nullptr, 16);
// Get the data if necessary.
if (storageEnabled && content.cmd == TLM_WRITE_COMMAND)
if (storageEnabled && content.command == 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());
iss >> element;
// Check if data length in the trace file is correct.
// We need two characters to represent 1 byte in hexadecimal. Offset for 0x prefix.
if (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());
if (element.length() != (content.dataLength * 2 + 2))
SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ").").c_str());
// Set data
for (unsigned i = 0; i < dataLength; i++)
for (unsigned i = 0; i < content.dataLength; i++)
content.data.emplace_back(static_cast<unsigned char>
(std::stoi(dataStr.substr(i * 2 + 2, 2), nullptr, 16)));
(std::stoi(element.substr(i * 2 + 2, 2), nullptr, 16)));
}
}
}

View File

@@ -55,8 +55,9 @@
struct LineContent
{
sc_core::sc_time sendingTime;
tlm::tlm_command cmd;
uint64_t addr;
unsigned dataLength;
tlm::tlm_command command;
uint64_t address;
std::vector<unsigned char> data;
};
@@ -68,6 +69,7 @@ public:
const sc_core::sc_time &playerClk,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
bool needsLengthConverter,
TraceSetup *setup,
bool relative);

View File

@@ -83,6 +83,11 @@ TraceSetup::TraceSetup(const std::string &uri,
if (value["maxPendingWriteRequests"].is_number_unsigned())
maxPendingWriteRequests = value["maxPendingWriteRequests"];
bool needsLengthConverter = false;
if (value["needsLengthConverter"].is_boolean())
needsLengthConverter = value["needsLengthConverter"];
std::string type;
// Defaulting to type "player" when not specified
@@ -112,10 +117,12 @@ TraceSetup::TraceSetup(const std::string &uri,
StlPlayer *player;
if (ext == "stl")
player = new StlPlayer(moduleName.c_str(), stlFile, playerClk,
maxPendingReadRequests, maxPendingWriteRequests, this, false);
maxPendingReadRequests, maxPendingWriteRequests, needsLengthConverter,
this, false);
else if (ext == "rstl")
player = new StlPlayer(moduleName.c_str(), stlFile, playerClk,
maxPendingReadRequests, maxPendingWriteRequests, this, true);
maxPendingReadRequests, maxPendingWriteRequests, needsLengthConverter,
this, true);
else
throw std::runtime_error("Unsupported file extension in " + name);
@@ -192,14 +199,15 @@ TraceSetup::TraceSetup(const std::string &uri,
generator = new TrafficGeneratorSequential(name.c_str(), playerClk, numRequests,
maxPendingReadRequests, maxPendingWriteRequests,
minAddress, maxAddress, rwRatio, addressIncrement, seed,
this);
needsLengthConverter, minAddress, maxAddress, rwRatio,
addressIncrement, seed, this);
}
else
{
generator = new TrafficGeneratorRandom(name.c_str(), playerClk, numRequests,
maxPendingReadRequests, maxPendingWriteRequests,
minAddress, maxAddress, rwRatio, seed, this);
needsLengthConverter, minAddress, maxAddress, rwRatio,
seed, this);
}
players.push_back(generator);

View File

@@ -46,14 +46,14 @@ TrafficGenerator::TrafficGenerator(const sc_module_name &name,
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
bool needsLengthConverter,
float rwRatio,
unsigned int seed,
TraceSetup *setup) :
TrafficInitiator(name, setup, maxPendingReadRequests, maxPendingWriteRequests),
TrafficInitiator(name, setup, maxPendingReadRequests, maxPendingWriteRequests, needsLengthConverter),
generatorClk(generatorClk), numRequests(numRequests), rwRatio(rwRatio)
{
burstLength = Configuration::getInstance().memSpec->burstLength;
dataLength = Configuration::getInstance().memSpec->bytesPerBurst;
defaultDataLength = Configuration::getInstance().memSpec->bytesPerBurst;
randomGenerator = std::default_random_engine(seed);
}
@@ -89,8 +89,7 @@ void TrafficGenerator::sendNextPayload()
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_data_length(defaultDataLength);
payload->set_command(command);
sc_time sendingOffset;
@@ -111,13 +110,14 @@ TrafficGeneratorRandom::TrafficGeneratorRandom(const sc_core::sc_module_name &na
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
bool needsLengthConverter,
uint64_t minAddress,
uint64_t maxAddress,
float rwRatio,
unsigned int seed,
TraceSetup *setup) :
TrafficGenerator(name, generatorClk, numRequests, maxPendingReadRequests, maxPendingWriteRequests, rwRatio, seed,
setup)
TrafficGenerator(name, generatorClk, numRequests, maxPendingReadRequests, maxPendingWriteRequests,
needsLengthConverter, rwRatio, seed, setup)
{
randomAddressDistribution = std::uniform_int_distribution<uint64_t> (minAddress, maxAddress);
}
@@ -132,14 +132,16 @@ TrafficGeneratorSequential::TrafficGeneratorSequential(const sc_core::sc_module_
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
bool needsLengthConverter,
uint64_t minAddress,
uint64_t maxAddress,
float rwRatio,
uint64_t addressIncrement,
unsigned int seed,
TraceSetup *setup) :
TrafficGenerator(name, generatorClk, numRequests, maxPendingReadRequests, maxPendingWriteRequests, rwRatio, seed,
setup), minAddress(minAddress), maxAddress(maxAddress), addressIncrement(addressIncrement),
TrafficGenerator(name, generatorClk, numRequests, maxPendingReadRequests, maxPendingWriteRequests,
needsLengthConverter, rwRatio, seed, setup),
minAddress(minAddress), maxAddress(maxAddress), addressIncrement(addressIncrement),
currentAddress(minAddress)
{
}
@@ -159,7 +161,7 @@ TrafficGeneratorHammer::TrafficGeneratorHammer(const sc_core::sc_module_name &na
uint64_t numRequests,
uint64_t rowIncrement,
TraceSetup *setup) :
TrafficGenerator(name, generatorClk, numRequests, 1, 1, 1.0f, 1, setup), rowIncrement(rowIncrement)
TrafficGenerator(name, generatorClk, numRequests, 1, 1, false, 1.0f, 1, setup), rowIncrement(rowIncrement)
{
}

View File

@@ -52,6 +52,7 @@ protected:
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
bool needsLengthConverter,
float rwRatio,
unsigned int seed,
TraceSetup *setup);
@@ -78,6 +79,7 @@ public:
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
bool needsLengthConverter,
uint64_t minAddress,
uint64_t maxAddress,
float rwRatio,
@@ -98,6 +100,7 @@ public:
uint64_t numRequests,
unsigned int maxPendingReadRequests,
unsigned int maxPendingWriteRequests,
bool needsLengthConverter,
uint64_t minAddress,
uint64_t maxAddress,
float rwRatio,

View File

@@ -44,10 +44,11 @@ using namespace sc_core;
using namespace tlm;
TrafficInitiator::TrafficInitiator(const sc_module_name &name, TraceSetup *setup,
unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests) :
unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests, bool needsLengthConverter) :
sc_module(name), payloadEventQueue(this, &TrafficInitiator::peqCallback),
setup(setup),
maxPendingReadRequests(maxPendingReadRequests), maxPendingWriteRequests(maxPendingWriteRequests)
maxPendingReadRequests(maxPendingReadRequests), maxPendingWriteRequests(maxPendingWriteRequests),
mNeedsLengthConverter(needsLengthConverter)
{
SC_METHOD(sendNextPayload);
iSocket.register_nb_transport_bw(this, &TrafficInitiator::nb_transport_bw);
@@ -129,3 +130,8 @@ bool TrafficInitiator::nextPayloadSendable() const
else
return true;
}
bool TrafficInitiator::needsLengthConverter() const
{
return mNeedsLengthConverter;
}

View File

@@ -57,9 +57,10 @@ class TrafficInitiator : public sc_core::sc_module
public:
tlm_utils::simple_initiator_socket<TrafficInitiator> iSocket;
TrafficInitiator(const sc_core::sc_module_name &name, TraceSetup *setup,
unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests);
unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests, bool needsLengthConverter);
SC_HAS_PROCESS(TrafficInitiator);
virtual void sendNextPayload() = 0;
bool needsLengthConverter() const;
protected:
tlm_utils::peq_with_cb_and_phase<TrafficInitiator> payloadEventQueue;
@@ -73,13 +74,13 @@ protected:
uint64_t transactionsSent = 0;
unsigned int pendingReadRequests = 0;
unsigned int pendingWriteRequests = 0;
unsigned int maxPendingReadRequests = 0;
unsigned int maxPendingWriteRequests = 0;
const unsigned int maxPendingReadRequests = 0;
const unsigned int maxPendingWriteRequests = 0;
const bool mNeedsLengthConverter = false;
bool payloadPostponed = false;
bool finished = false;
unsigned int burstLength;
unsigned int dataLength;
unsigned int defaultDataLength;
private:
tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase,

View File

@@ -40,12 +40,14 @@
#include <string>
#include <utility>
#include <vector>
#include <list>
#include <chrono>
#include <systemc>
#include "simulation/DRAMSys.h"
#include "TraceSetup.h"
#include "TrafficInitiator.h"
#include "LengthConverter.h"
#ifdef RECORDING
#include "simulation/DRAMSysRecordable.h"
@@ -96,6 +98,7 @@ int sc_main(int argc, char **argv)
}
std::vector<TrafficInitiator *> players;
std::list<LengthConverter> lengthConverters;
// Instantiate DRAMSys:
DRAMSys *dramSys;
@@ -120,14 +123,32 @@ int sc_main(int argc, char **argv)
{
std::string str = "TLMCheckerPlayer" + std::to_string(i);
tlm_utils::tlm2_base_protocol_checker<> *playerTlmChecker =
new tlm_utils::tlm2_base_protocol_checker<>(str.c_str());
new tlm_utils::tlm2_base_protocol_checker<>(("TLMCheckerPlayer" + std::to_string(i)).c_str());
dramSys->playersTlmCheckers.push_back(playerTlmChecker);
players[i]->iSocket.bind(dramSys->playersTlmCheckers[i]->target_socket);
dramSys->playersTlmCheckers[i]->initiator_socket.bind(dramSys->tSocket);
if (players[i]->needsLengthConverter())
{
lengthConverters.emplace_back(("LengthConverter" + std::to_string(i)).c_str(), 64, false);
players[i]->iSocket.bind(lengthConverters.back().tSocket);
lengthConverters.back().iSocket.bind(dramSys->playersTlmCheckers.back()->target_socket);
}
else
{
players[i]->iSocket.bind(dramSys->playersTlmCheckers[i]->target_socket);
}
dramSys->playersTlmCheckers.back()->initiator_socket.bind(dramSys->tSocket);
}
else
{
players[i]->iSocket.bind(dramSys->tSocket);
if (players[i]->needsLengthConverter())
{
lengthConverters.emplace_back(("LengthConverter" + std::to_string(i)).c_str(), 64, false);
players[i]->iSocket.bind(lengthConverters.back().tSocket);
lengthConverters.back().iSocket.bind(dramSys->tSocket);
}
else
{
players[i]->iSocket.bind(dramSys->tSocket);
}
}
}