Integrate length converter, add length parameter to stl.
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user