Format all files
This commit is contained in:
@@ -45,7 +45,7 @@ using namespace sc_core;
|
||||
DECLARE_EXTENDED_PHASE(HIT_HANDLING);
|
||||
DECLARE_EXTENDED_PHASE(MISS_HANDLING);
|
||||
|
||||
Cache::Cache(const sc_module_name &name,
|
||||
Cache::Cache(const sc_module_name& name,
|
||||
std::size_t size,
|
||||
std::size_t associativity,
|
||||
std::size_t lineSize,
|
||||
@@ -55,7 +55,7 @@ Cache::Cache(const sc_module_name &name,
|
||||
bool storageEnabled,
|
||||
sc_core::sc_time cycleTime,
|
||||
std::size_t hitCycles,
|
||||
MemoryManager &memoryManager) :
|
||||
MemoryManager& memoryManager) :
|
||||
sc_module(name),
|
||||
payloadEventQueue(this, &Cache::peqCallback),
|
||||
storageEnabled(storageEnabled),
|
||||
@@ -76,7 +76,8 @@ Cache::Cache(const sc_module_name &name,
|
||||
iSocket.register_nb_transport_bw(this, &Cache::nb_transport_bw);
|
||||
tSocket.register_nb_transport_fw(this, &Cache::nb_transport_fw);
|
||||
|
||||
lineTable = std::vector<std::vector<CacheLine>>(numberOfSets, std::vector<CacheLine>(associativity));
|
||||
lineTable =
|
||||
std::vector<std::vector<CacheLine>>(numberOfSets, std::vector<CacheLine>(associativity));
|
||||
|
||||
if (storageEnabled)
|
||||
{
|
||||
@@ -85,18 +86,22 @@ Cache::Cache(const sc_module_name &name,
|
||||
for (std::size_t set = 0; set < lineTable.size(); set++)
|
||||
{
|
||||
for (std::size_t way = 0; way < lineTable[set].size(); way++)
|
||||
lineTable[set][way].dataPtr = dataMemory.data() + set * associativity * lineSize + way * lineSize;
|
||||
lineTable[set][way].dataPtr =
|
||||
dataMemory.data() + set * associativity * lineSize + way * lineSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tlm_sync_enum Cache::nb_transport_fw(tlm_generic_payload &trans, tlm_phase &phase, sc_time &delay) // core side --->
|
||||
tlm_sync_enum Cache::nb_transport_fw(tlm_generic_payload& trans,
|
||||
tlm_phase& phase,
|
||||
sc_time& delay) // core side --->
|
||||
{
|
||||
if (phase == BEGIN_REQ)
|
||||
{
|
||||
if (trans.get_data_length() > lineSize)
|
||||
{
|
||||
SC_REPORT_FATAL(name(), "Accesses larger than line size in non-blocking mode not supported!");
|
||||
SC_REPORT_FATAL(name(),
|
||||
"Accesses larger than line size in non-blocking mode not supported!");
|
||||
}
|
||||
|
||||
trans.acquire();
|
||||
@@ -108,7 +113,9 @@ tlm_sync_enum Cache::nb_transport_fw(tlm_generic_payload &trans, tlm_phase &phas
|
||||
return TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
tlm_sync_enum Cache::nb_transport_bw(tlm_generic_payload &trans, tlm_phase &phase, sc_time &bwDelay) // DRAM side <---
|
||||
tlm_sync_enum Cache::nb_transport_bw(tlm_generic_payload& trans,
|
||||
tlm_phase& phase,
|
||||
sc_time& bwDelay) // DRAM side <---
|
||||
{
|
||||
// TODO: early completion would be possible
|
||||
payloadEventQueue.notify(trans, phase, ceilDelay(bwDelay));
|
||||
@@ -116,7 +123,7 @@ tlm_sync_enum Cache::nb_transport_bw(tlm_generic_payload &trans, tlm_phase &phas
|
||||
return TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
void Cache::peqCallback(tlm_generic_payload &trans, const tlm_phase &phase)
|
||||
void Cache::peqCallback(tlm_generic_payload& trans, const tlm_phase& phase)
|
||||
{
|
||||
if (phase == BEGIN_REQ) // core side --->
|
||||
{
|
||||
@@ -151,7 +158,7 @@ void Cache::peqCallback(tlm_generic_payload &trans, const tlm_phase &phase)
|
||||
clearTargetBackpressureAndProcessLines(trans);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (phase == HIT_HANDLING) // direct hit, account for the hit delay
|
||||
{
|
||||
index_t index = 0;
|
||||
@@ -169,8 +176,10 @@ void Cache::peqCallback(tlm_generic_payload &trans, const tlm_phase &phase)
|
||||
tag_t tag = 0;
|
||||
std::tie(index, tag, std::ignore) = decodeAddress(trans.get_address());
|
||||
|
||||
auto mshrIt = std::find_if(mshrQueue.begin(), mshrQueue.end(),
|
||||
[index, tag](const Mshr &mshr) { return mshr.index == index && mshr.tag == tag; });
|
||||
auto mshrIt = std::find_if(mshrQueue.begin(),
|
||||
mshrQueue.end(),
|
||||
[index, tag](const Mshr& mshr)
|
||||
{ return mshr.index == index && mshr.tag == tag; });
|
||||
|
||||
assert(mshrIt != mshrQueue.end());
|
||||
mshrIt->hitDelayAccounted = true;
|
||||
@@ -193,7 +202,7 @@ void Cache::peqCallback(tlm_generic_payload &trans, const tlm_phase &phase)
|
||||
}
|
||||
|
||||
/// Handler for begin request from core side.
|
||||
void Cache::fetchLineAndSendEndRequest(tlm_generic_payload &trans)
|
||||
void Cache::fetchLineAndSendEndRequest(tlm_generic_payload& trans)
|
||||
{
|
||||
if (hasBufferSpace())
|
||||
{
|
||||
@@ -201,9 +210,10 @@ void Cache::fetchLineAndSendEndRequest(tlm_generic_payload &trans)
|
||||
tag_t tag = 0;
|
||||
std::tie(index, tag, std::ignore) = decodeAddress(trans.get_address());
|
||||
|
||||
auto mshrEntry =
|
||||
std::find_if(mshrQueue.begin(), mshrQueue.end(),
|
||||
[index, tag](const Mshr &entry) { return (index == entry.index) && (tag == entry.tag); });
|
||||
auto mshrEntry = std::find_if(mshrQueue.begin(),
|
||||
mshrQueue.end(),
|
||||
[index, tag](const Mshr& entry)
|
||||
{ return (index == entry.index) && (tag == entry.tag); });
|
||||
|
||||
if (isHit(index, tag))
|
||||
{
|
||||
@@ -237,7 +247,7 @@ void Cache::fetchLineAndSendEndRequest(tlm_generic_payload &trans)
|
||||
|
||||
// Cache miss and no fetch in progress.
|
||||
// So evict line and allocate empty line.
|
||||
auto *evictedLine = evictLine(index);
|
||||
auto* evictedLine = evictLine(index);
|
||||
if (evictedLine == nullptr)
|
||||
{
|
||||
// Line eviction not possible.
|
||||
@@ -272,7 +282,7 @@ void Cache::clearInitiatorBackpressureAndProcessBuffers()
|
||||
}
|
||||
|
||||
/// Handler for begin response from DRAM side.
|
||||
void Cache::sendEndResponseAndFillLine(tlm_generic_payload &trans)
|
||||
void Cache::sendEndResponseAndFillLine(tlm_generic_payload& trans)
|
||||
{
|
||||
tlm_phase fwPhase = END_RESP;
|
||||
sc_time fwDelay = SC_ZERO_TIME;
|
||||
@@ -288,7 +298,7 @@ void Cache::sendEndResponseAndFillLine(tlm_generic_payload &trans)
|
||||
}
|
||||
|
||||
/// Handler for end response from core side.
|
||||
void Cache::clearTargetBackpressureAndProcessLines(tlm_generic_payload &trans)
|
||||
void Cache::clearTargetBackpressureAndProcessLines(tlm_generic_payload& trans)
|
||||
{
|
||||
trans.release();
|
||||
tSocketBackpressure = false;
|
||||
@@ -307,16 +317,18 @@ void Cache::clearTargetBackpressureAndProcessLines(tlm_generic_payload &trans)
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int Cache::transport_dbg(tlm_generic_payload &trans)
|
||||
unsigned int Cache::transport_dbg(tlm_generic_payload& trans)
|
||||
{
|
||||
return iSocket->transport_dbg(trans);
|
||||
}
|
||||
|
||||
bool Cache::isHit(index_t index, tag_t tag) const
|
||||
{
|
||||
return std::find_if(lineTable[index].begin(), lineTable[index].end(),
|
||||
[tag](const CacheLine &cacheLine)
|
||||
{ return (cacheLine.tag == tag) && cacheLine.valid; }) != lineTable[index].end();
|
||||
return std::find_if(lineTable[index].begin(),
|
||||
lineTable[index].end(),
|
||||
[tag](const CacheLine& cacheLine) {
|
||||
return (cacheLine.tag == tag) && cacheLine.valid;
|
||||
}) != lineTable[index].end();
|
||||
}
|
||||
|
||||
bool Cache::isHit(uint64_t address) const
|
||||
@@ -328,24 +340,31 @@ bool Cache::isHit(uint64_t address) const
|
||||
return isHit(index, tag);
|
||||
}
|
||||
|
||||
std::tuple<Cache::index_t, Cache::tag_t, Cache::lineOffset_t> Cache::decodeAddress(uint64_t address) const
|
||||
std::tuple<Cache::index_t, Cache::tag_t, Cache::lineOffset_t>
|
||||
Cache::decodeAddress(uint64_t address) const
|
||||
{
|
||||
return {(address >> indexShifts) & indexMask, address >> tagShifts, address % lineSize};
|
||||
}
|
||||
|
||||
uint64_t Cache::encodeAddress(Cache::index_t index, Cache::tag_t tag, Cache::lineOffset_t lineOffset) const
|
||||
uint64_t
|
||||
Cache::encodeAddress(Cache::index_t index, Cache::tag_t tag, Cache::lineOffset_t lineOffset) const
|
||||
{
|
||||
return static_cast<uint64_t>(tag << tagShifts) | index << indexShifts | lineOffset;
|
||||
}
|
||||
|
||||
/// Write data to an available cache line, update flags
|
||||
void Cache::writeLine(
|
||||
index_t index, tag_t tag, lineOffset_t lineOffset, unsigned int dataLength, const unsigned char *dataPtr)
|
||||
void Cache::writeLine(index_t index,
|
||||
tag_t tag,
|
||||
lineOffset_t lineOffset,
|
||||
unsigned int dataLength,
|
||||
const unsigned char* dataPtr)
|
||||
{
|
||||
// SC_REPORT_ERROR("cache", "Write to Cache not allowed!");
|
||||
|
||||
CacheLine ¤tLine = *std::find_if(lineTable[index].begin(), lineTable[index].end(),
|
||||
[tag](const CacheLine &cacheLine) { return cacheLine.tag == tag; });
|
||||
CacheLine& currentLine =
|
||||
*std::find_if(lineTable[index].begin(),
|
||||
lineTable[index].end(),
|
||||
[tag](const CacheLine& cacheLine) { return cacheLine.tag == tag; });
|
||||
|
||||
assert(currentLine.valid);
|
||||
currentLine.lastAccessTime = sc_time_stamp();
|
||||
@@ -356,24 +375,33 @@ void Cache::writeLine(
|
||||
}
|
||||
|
||||
/// Read data from an available cache line, update flags
|
||||
void Cache::readLine(index_t index, tag_t tag, lineOffset_t lineOffset, unsigned int dataLength, unsigned char *dataPtr)
|
||||
void Cache::readLine(index_t index,
|
||||
tag_t tag,
|
||||
lineOffset_t lineOffset,
|
||||
unsigned int dataLength,
|
||||
unsigned char* dataPtr)
|
||||
{
|
||||
CacheLine ¤tLine = *std::find_if(lineTable[index].begin(), lineTable[index].end(),
|
||||
[tag](const CacheLine &cacheLine) { return cacheLine.tag == tag; });
|
||||
CacheLine& currentLine =
|
||||
*std::find_if(lineTable[index].begin(),
|
||||
lineTable[index].end(),
|
||||
[tag](const CacheLine& cacheLine) { return cacheLine.tag == tag; });
|
||||
|
||||
assert(currentLine.valid);
|
||||
currentLine.lastAccessTime = sc_time_stamp();
|
||||
|
||||
if (storageEnabled)
|
||||
std::copy(currentLine.dataPtr + lineOffset, currentLine.dataPtr + lineOffset + dataLength, dataPtr);
|
||||
std::copy(currentLine.dataPtr + lineOffset,
|
||||
currentLine.dataPtr + lineOffset + dataLength,
|
||||
dataPtr);
|
||||
}
|
||||
|
||||
/// Tries to evict oldest line (insert into write memory)
|
||||
/// Returns the line or a nullptr if not possible
|
||||
Cache::CacheLine *Cache::evictLine(Cache::index_t index)
|
||||
Cache::CacheLine* Cache::evictLine(Cache::index_t index)
|
||||
{
|
||||
CacheLine &oldestLine = *std::min_element(lineTable[index].begin(), lineTable[index].end(),
|
||||
[](const CacheLine &lhs, const CacheLine &rhs)
|
||||
CacheLine& oldestLine = *std::min_element(lineTable[index].begin(),
|
||||
lineTable[index].end(),
|
||||
[](const CacheLine& lhs, const CacheLine& rhs)
|
||||
{ return lhs.lastAccessTime < rhs.lastAccessTime; });
|
||||
|
||||
if (oldestLine.allocated && !oldestLine.valid)
|
||||
@@ -383,7 +411,7 @@ Cache::CacheLine *Cache::evictLine(Cache::index_t index)
|
||||
}
|
||||
if (std::find_if(mshrQueue.begin(),
|
||||
mshrQueue.end(),
|
||||
[index, oldestLine](const Mshr &entry) {
|
||||
[index, oldestLine](const Mshr& entry) {
|
||||
return (index == entry.index) && (oldestLine.tag == entry.tag);
|
||||
}) != mshrQueue.end())
|
||||
{
|
||||
@@ -391,9 +419,11 @@ Cache::CacheLine *Cache::evictLine(Cache::index_t index)
|
||||
// There are still entries in mshrQueue to the oldest line -> do not evict it
|
||||
return nullptr;
|
||||
}
|
||||
if (std::find_if(hitQueue.begin(), hitQueue.end(),
|
||||
[index, oldestLine](const BufferEntry &entry)
|
||||
{ return (index == entry.index) && (oldestLine.tag == entry.tag); }) != hitQueue.end())
|
||||
if (std::find_if(hitQueue.begin(),
|
||||
hitQueue.end(),
|
||||
[index, oldestLine](const BufferEntry& entry) {
|
||||
return (index == entry.index) && (oldestLine.tag == entry.tag);
|
||||
}) != hitQueue.end())
|
||||
{
|
||||
// TODO: solve this in a more clever way
|
||||
// There are still hits in hitQueue to the oldest line -> do not evict it
|
||||
@@ -402,7 +432,7 @@ Cache::CacheLine *Cache::evictLine(Cache::index_t index)
|
||||
|
||||
if (oldestLine.valid && oldestLine.dirty)
|
||||
{
|
||||
auto &wbTrans = memoryManager.allocate(lineSize);
|
||||
auto& wbTrans = memoryManager.allocate(lineSize);
|
||||
wbTrans.acquire();
|
||||
wbTrans.set_address(encodeAddress(index, oldestLine.tag));
|
||||
wbTrans.set_write();
|
||||
@@ -434,7 +464,8 @@ void Cache::processMshrQueue()
|
||||
if ((requestInProgress == nullptr) && !mshrQueue.empty())
|
||||
{
|
||||
// Get the first entry that wasn't already issued to the target
|
||||
auto mshrIt = std::find_if(mshrQueue.begin(), mshrQueue.end(), [](const Mshr &entry) { return !entry.issued; });
|
||||
auto mshrIt = std::find_if(
|
||||
mshrQueue.begin(), mshrQueue.end(), [](const Mshr& entry) { return !entry.issued; });
|
||||
|
||||
if (mshrIt == mshrQueue.end())
|
||||
return;
|
||||
@@ -447,9 +478,11 @@ void Cache::processMshrQueue()
|
||||
std::tie(index, tag, std::ignore) = decodeAddress(alignedAddress);
|
||||
|
||||
// Search through the writeBuffer in reverse order to get the most recent entry.
|
||||
auto writeBufferEntry = std::find_if(writeBuffer.rbegin(), writeBuffer.rbegin(),
|
||||
[index, tag](const BufferEntry &entry)
|
||||
{ return (index == entry.index) && (tag == entry.tag); });
|
||||
auto writeBufferEntry =
|
||||
std::find_if(writeBuffer.rbegin(),
|
||||
writeBuffer.rbegin(),
|
||||
[index, tag](const BufferEntry& entry)
|
||||
{ return (index == entry.index) && (tag == entry.tag); });
|
||||
|
||||
if (writeBufferEntry != writeBuffer.rbegin())
|
||||
{
|
||||
@@ -467,7 +500,7 @@ void Cache::processMshrQueue()
|
||||
// Prevents that the cache line will get fetched multiple times from the target
|
||||
mshrIt->issued = true;
|
||||
|
||||
auto &fetchTrans = memoryManager.allocate(lineSize);
|
||||
auto& fetchTrans = memoryManager.allocate(lineSize);
|
||||
fetchTrans.acquire();
|
||||
fetchTrans.set_read();
|
||||
fetchTrans.set_data_length(lineSize);
|
||||
@@ -512,7 +545,7 @@ void Cache::processWriteBuffer()
|
||||
{
|
||||
if ((requestInProgress == nullptr) && !writeBuffer.empty())
|
||||
{
|
||||
tlm_generic_payload &wbTrans = *writeBuffer.front().trans;
|
||||
tlm_generic_payload& wbTrans = *writeBuffer.front().trans;
|
||||
|
||||
tlm_phase fwPhase = BEGIN_REQ;
|
||||
sc_time fwDelay = (lastEndReq == sc_time_stamp()) ? cycleTime : SC_ZERO_TIME;
|
||||
@@ -542,15 +575,16 @@ void Cache::processWriteBuffer()
|
||||
}
|
||||
|
||||
/// Fill allocated cache line with data from memory
|
||||
void Cache::fillLine(tlm_generic_payload &trans)
|
||||
void Cache::fillLine(tlm_generic_payload& trans)
|
||||
{
|
||||
index_t index = 0;
|
||||
tag_t tag = 0;
|
||||
std::tie(index, tag, std::ignore) = decodeAddress(trans.get_address());
|
||||
|
||||
CacheLine &allocatedLine =
|
||||
*std::find_if(lineTable[index].begin(), lineTable[index].end(),
|
||||
[tag](const CacheLine &cacheLine) { return cacheLine.allocated && cacheLine.tag == tag; });
|
||||
CacheLine& allocatedLine = *std::find_if(
|
||||
lineTable[index].begin(),
|
||||
lineTable[index].end(),
|
||||
[tag](const CacheLine& cacheLine) { return cacheLine.allocated && cacheLine.tag == tag; });
|
||||
|
||||
allocatedLine.valid = true;
|
||||
allocatedLine.dirty = false;
|
||||
@@ -572,7 +606,7 @@ void Cache::processHitQueue()
|
||||
}
|
||||
|
||||
/// Access the available cache line and send the response
|
||||
void Cache::accessCacheAndSendResponse(tlm_generic_payload &trans)
|
||||
void Cache::accessCacheAndSendResponse(tlm_generic_payload& trans)
|
||||
{
|
||||
assert(!tSocketBackpressure);
|
||||
assert(isHit(trans.get_address()));
|
||||
@@ -597,28 +631,34 @@ void Cache::accessCacheAndSendResponse(tlm_generic_payload &trans)
|
||||
}
|
||||
|
||||
/// Allocates an empty line for later filling (lastAccessTime = sc_max_time())
|
||||
void Cache::allocateLine(CacheLine *line, tag_t tag)
|
||||
void Cache::allocateLine(CacheLine* line, tag_t tag)
|
||||
{
|
||||
line->allocated = true;
|
||||
line->tag = tag;
|
||||
line->lastAccessTime = sc_max_time();
|
||||
}
|
||||
|
||||
/// Checks whether a line with the corresponding tag is already allocated (fetch in progress or already valid)
|
||||
/// Checks whether a line with the corresponding tag is already allocated (fetch in progress or
|
||||
/// already valid)
|
||||
bool Cache::isAllocated(Cache::index_t index, Cache::tag_t tag) const
|
||||
{
|
||||
return std::find_if(lineTable[index].begin(), lineTable[index].end(),
|
||||
[tag](const CacheLine &cacheLine)
|
||||
{ return (cacheLine.tag == tag) && cacheLine.allocated; }) != lineTable[index].end();
|
||||
return std::find_if(lineTable[index].begin(),
|
||||
lineTable[index].end(),
|
||||
[tag](const CacheLine& cacheLine) {
|
||||
return (cacheLine.tag == tag) && cacheLine.allocated;
|
||||
}) != lineTable[index].end();
|
||||
}
|
||||
|
||||
/// Process oldest hit in mshrQueue, accept pending request from initiator
|
||||
void Cache::processMshrResponse()
|
||||
{
|
||||
if (!tSocketBackpressure) // TODO: Bedingung eigentlich zu streng, wenn man Hit delay berücksichtigt.
|
||||
if (!tSocketBackpressure) // TODO: Bedingung eigentlich zu streng, wenn man Hit delay
|
||||
// berücksichtigt.
|
||||
{
|
||||
const auto hitIt = std::find_if(mshrQueue.begin(), mshrQueue.end(),
|
||||
[this](const Mshr &entry) { return isHit(entry.index, entry.tag); });
|
||||
const auto hitIt =
|
||||
std::find_if(mshrQueue.begin(),
|
||||
mshrQueue.end(),
|
||||
[this](const Mshr& entry) { return isHit(entry.index, entry.tag); });
|
||||
|
||||
// In case there are hits in mshrActive, handle them. Otherwise try again later.
|
||||
if (hitIt == mshrQueue.end())
|
||||
@@ -630,7 +670,7 @@ void Cache::processMshrResponse()
|
||||
return;
|
||||
|
||||
// Get the first request in the list and respond to it
|
||||
tlm_generic_payload &returnTrans = *hitIt->requestList.front();
|
||||
tlm_generic_payload& returnTrans = *hitIt->requestList.front();
|
||||
hitIt->requestList.pop_front();
|
||||
|
||||
if (hitIt->hitDelayAccounted)
|
||||
@@ -661,12 +701,12 @@ bool Cache::hasBufferSpace() const
|
||||
return mshrQueue.size() < mshrDepth && writeBuffer.size() < writeBufferDepth;
|
||||
}
|
||||
|
||||
sc_time Cache::ceilTime(const sc_time &inTime) const
|
||||
sc_time Cache::ceilTime(const sc_time& inTime) const
|
||||
{
|
||||
return std::ceil(inTime / cycleTime) * cycleTime;
|
||||
}
|
||||
|
||||
sc_time Cache::ceilDelay(const sc_time &inDelay) const
|
||||
sc_time Cache::ceilDelay(const sc_time& inDelay) const
|
||||
{
|
||||
sc_time inTime = sc_time_stamp() + inDelay;
|
||||
sc_time outTime = ceilTime(inTime);
|
||||
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
tlm_utils::simple_initiator_socket<Cache> iSocket;
|
||||
tlm_utils::simple_target_socket<Cache> tSocket;
|
||||
|
||||
Cache(const sc_core::sc_module_name &name,
|
||||
Cache(const sc_core::sc_module_name& name,
|
||||
std::size_t size,
|
||||
std::size_t associativity,
|
||||
std::size_t lineSize,
|
||||
@@ -63,24 +63,24 @@ public:
|
||||
bool storageEnabled,
|
||||
sc_core::sc_time cycleTime,
|
||||
std::size_t hitCycles,
|
||||
MemoryManager &memoryManager);
|
||||
MemoryManager& memoryManager);
|
||||
SC_HAS_PROCESS(Cache);
|
||||
|
||||
private:
|
||||
void peqCallback(tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase);
|
||||
void peqCallback(tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase);
|
||||
|
||||
tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &trans,
|
||||
tlm::tlm_phase &phase,
|
||||
sc_core::sc_time &fwDelay);
|
||||
tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &trans,
|
||||
tlm::tlm_phase &phase,
|
||||
sc_core::sc_time &bwDelay);
|
||||
unsigned int transport_dbg(tlm::tlm_generic_payload &trans);
|
||||
tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& trans,
|
||||
tlm::tlm_phase& phase,
|
||||
sc_core::sc_time& fwDelay);
|
||||
tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload& trans,
|
||||
tlm::tlm_phase& phase,
|
||||
sc_core::sc_time& bwDelay);
|
||||
unsigned int transport_dbg(tlm::tlm_generic_payload& trans);
|
||||
|
||||
void fetchLineAndSendEndRequest(tlm::tlm_generic_payload &trans);
|
||||
void fetchLineAndSendEndRequest(tlm::tlm_generic_payload& trans);
|
||||
void clearInitiatorBackpressureAndProcessBuffers();
|
||||
void sendEndResponseAndFillLine(tlm::tlm_generic_payload &trans);
|
||||
void clearTargetBackpressureAndProcessLines(tlm::tlm_generic_payload &trans);
|
||||
void sendEndResponseAndFillLine(tlm::tlm_generic_payload& trans);
|
||||
void clearTargetBackpressureAndProcessLines(tlm::tlm_generic_payload& trans);
|
||||
|
||||
tlm_utils::peq_with_cb_and_phase<Cache> payloadEventQueue;
|
||||
|
||||
@@ -109,7 +109,7 @@ private:
|
||||
struct CacheLine
|
||||
{
|
||||
tag_t tag = 0;
|
||||
unsigned char *dataPtr = nullptr;
|
||||
unsigned char* dataPtr = nullptr;
|
||||
bool allocated = false;
|
||||
bool valid = false;
|
||||
bool dirty = false;
|
||||
@@ -126,15 +126,15 @@ private:
|
||||
tag_t tag,
|
||||
lineOffset_t lineOffset,
|
||||
unsigned int dataLength,
|
||||
const unsigned char *dataPtr);
|
||||
|
||||
const unsigned char* dataPtr);
|
||||
|
||||
void readLine(index_t index,
|
||||
tag_t tag,
|
||||
lineOffset_t lineOffset,
|
||||
unsigned int dataLength,
|
||||
unsigned char *dataPtr);
|
||||
unsigned char* dataPtr);
|
||||
|
||||
CacheLine *evictLine(index_t index);
|
||||
CacheLine* evictLine(index_t index);
|
||||
|
||||
std::tuple<index_t, tag_t, lineOffset_t> decodeAddress(std::uint64_t address) const;
|
||||
std::uint64_t encodeAddress(index_t index, tag_t tag, lineOffset_t lineOffset = 0) const;
|
||||
@@ -143,10 +143,12 @@ private:
|
||||
{
|
||||
index_t index;
|
||||
tag_t tag;
|
||||
tlm::tlm_generic_payload *trans;
|
||||
tlm::tlm_generic_payload* trans;
|
||||
|
||||
BufferEntry(index_t index, tag_t tag, tlm::tlm_generic_payload *trans)
|
||||
: index(index), tag(tag), trans(trans)
|
||||
BufferEntry(index_t index, tag_t tag, tlm::tlm_generic_payload* trans) :
|
||||
index(index),
|
||||
tag(tag),
|
||||
trans(trans)
|
||||
{
|
||||
}
|
||||
};
|
||||
@@ -155,7 +157,7 @@ private:
|
||||
{
|
||||
index_t index;
|
||||
tag_t tag;
|
||||
std::list<tlm::tlm_generic_payload *> requestList;
|
||||
std::list<tlm::tlm_generic_payload*> requestList;
|
||||
|
||||
/// Whether the Mshr entry was already issued to the target.
|
||||
bool issued = false;
|
||||
@@ -170,8 +172,10 @@ private:
|
||||
/// delay when it is already being waited on.
|
||||
bool hitDelayStarted = false;
|
||||
|
||||
Mshr(index_t index, tag_t tag, tlm::tlm_generic_payload *request)
|
||||
: index(index), tag(tag), requestList{request}
|
||||
Mshr(index_t index, tag_t tag, tlm::tlm_generic_payload* request) :
|
||||
index(index),
|
||||
tag(tag),
|
||||
requestList{request}
|
||||
{
|
||||
}
|
||||
};
|
||||
@@ -196,22 +200,22 @@ private:
|
||||
bool tSocketBackpressure = false;
|
||||
|
||||
// Request to the target
|
||||
tlm::tlm_generic_payload *requestInProgress = nullptr;
|
||||
tlm::tlm_generic_payload* requestInProgress = nullptr;
|
||||
|
||||
// Backpressure on initiator
|
||||
tlm::tlm_generic_payload *endRequestPending = nullptr;
|
||||
tlm::tlm_generic_payload* endRequestPending = nullptr;
|
||||
|
||||
sc_core::sc_time lastEndReq = sc_core::sc_max_time();
|
||||
|
||||
void fillLine(tlm::tlm_generic_payload &trans);
|
||||
void accessCacheAndSendResponse(tlm::tlm_generic_payload &trans);
|
||||
static void allocateLine(CacheLine *line, tag_t tag);
|
||||
void fillLine(tlm::tlm_generic_payload& trans);
|
||||
void accessCacheAndSendResponse(tlm::tlm_generic_payload& trans);
|
||||
static void allocateLine(CacheLine* line, tag_t tag);
|
||||
|
||||
bool isAllocated(index_t index, tag_t tag) const;
|
||||
bool hasBufferSpace() const;
|
||||
|
||||
sc_core::sc_time ceilTime(const sc_core::sc_time &inTime) const;
|
||||
sc_core::sc_time ceilDelay(const sc_core::sc_time &inDelay) const;
|
||||
sc_core::sc_time ceilTime(const sc_core::sc_time& inTime) const;
|
||||
sc_core::sc_time ceilDelay(const sc_core::sc_time& inDelay) const;
|
||||
|
||||
MemoryManager &memoryManager;
|
||||
MemoryManager& memoryManager;
|
||||
};
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
EccModule::EccModule(sc_module_name name, DRAMSys::AddressDecoder const &addressDecoder) :
|
||||
EccModule::EccModule(sc_module_name name, DRAMSys::AddressDecoder const& addressDecoder) :
|
||||
sc_core::sc_module(name),
|
||||
payloadEventQueue(this, &EccModule::peqCallback),
|
||||
memoryManager(false),
|
||||
@@ -53,9 +53,9 @@ EccModule::EccModule(sc_module_name name, DRAMSys::AddressDecoder const &address
|
||||
tSocket.register_nb_transport_fw(this, &EccModule::nb_transport_fw);
|
||||
}
|
||||
|
||||
tlm::tlm_sync_enum EccModule::nb_transport_fw(tlm::tlm_generic_payload &payload,
|
||||
tlm::tlm_phase &phase,
|
||||
sc_core::sc_time &fwDelay)
|
||||
tlm::tlm_sync_enum EccModule::nb_transport_fw(tlm::tlm_generic_payload& payload,
|
||||
tlm::tlm_phase& phase,
|
||||
sc_core::sc_time& fwDelay)
|
||||
{
|
||||
if (phase == BEGIN_REQ)
|
||||
{
|
||||
@@ -66,15 +66,15 @@ tlm::tlm_sync_enum EccModule::nb_transport_fw(tlm::tlm_generic_payload &payload,
|
||||
return TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
tlm::tlm_sync_enum EccModule::nb_transport_bw(tlm::tlm_generic_payload &payload,
|
||||
tlm::tlm_phase &phase,
|
||||
sc_core::sc_time &bwDelay)
|
||||
tlm::tlm_sync_enum EccModule::nb_transport_bw(tlm::tlm_generic_payload& payload,
|
||||
tlm::tlm_phase& phase,
|
||||
sc_core::sc_time& bwDelay)
|
||||
{
|
||||
payloadEventQueue.notify(payload, phase, bwDelay);
|
||||
return TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
void EccModule::peqCallback(tlm::tlm_generic_payload &cbPayload, const tlm::tlm_phase &cbPhase)
|
||||
void EccModule::peqCallback(tlm::tlm_generic_payload& cbPayload, const tlm::tlm_phase& cbPhase)
|
||||
{
|
||||
if (cbPhase == BEGIN_REQ) // from initiator
|
||||
{
|
||||
@@ -88,7 +88,8 @@ void EccModule::peqCallback(tlm::tlm_generic_payload &cbPayload, const tlm::tlm_
|
||||
tlm_phase tPhase = BEGIN_REQ;
|
||||
sc_time tDelay = SC_ZERO_TIME;
|
||||
|
||||
DRAMSys::DecodedAddress decodedAddress = addressDecoder.decodeAddress(cbPayload.get_address());
|
||||
DRAMSys::DecodedAddress decodedAddress =
|
||||
addressDecoder.decodeAddress(cbPayload.get_address());
|
||||
decodedAddress = calculateOffsetAddress(decodedAddress);
|
||||
|
||||
// Update the original address to account for the offsets
|
||||
@@ -103,14 +104,14 @@ void EccModule::peqCallback(tlm::tlm_generic_payload &cbPayload, const tlm::tlm_
|
||||
{
|
||||
blockedRequest = &cbPayload;
|
||||
|
||||
auto &eccFifo = activeEccBlocks[decodedAddress.bank];
|
||||
auto& eccFifo = activeEccBlocks[decodedAddress.bank];
|
||||
eccFifo.push_back({currentBlock, decodedAddress.row});
|
||||
|
||||
// Only hold 4 elements at max.
|
||||
if (eccFifo.size() >= 4)
|
||||
eccFifo.pop_front();
|
||||
|
||||
tlm::tlm_generic_payload *eccPayload = generateEccPayload(decodedAddress);
|
||||
tlm::tlm_generic_payload* eccPayload = generateEccPayload(decodedAddress);
|
||||
|
||||
iSocket->nb_transport_fw(*eccPayload, tPhase, tDelay);
|
||||
}
|
||||
@@ -138,7 +139,7 @@ void EccModule::peqCallback(tlm::tlm_generic_payload &cbPayload, const tlm::tlm_
|
||||
|
||||
if (blockedRequest != nullptr)
|
||||
{
|
||||
tlm_generic_payload &tPayload = *blockedRequest;
|
||||
tlm_generic_payload& tPayload = *blockedRequest;
|
||||
blockedRequest = nullptr;
|
||||
|
||||
tlm_phase tPhase = BEGIN_REQ;
|
||||
@@ -152,12 +153,13 @@ void EccModule::peqCallback(tlm::tlm_generic_payload &cbPayload, const tlm::tlm_
|
||||
|
||||
if (pendingRequest != nullptr)
|
||||
{
|
||||
tlm_generic_payload &tPayload = *pendingRequest;
|
||||
tlm_generic_payload& tPayload = *pendingRequest;
|
||||
|
||||
tlm_phase tPhase = BEGIN_REQ;
|
||||
sc_time tDelay = SC_ZERO_TIME;
|
||||
|
||||
DRAMSys::DecodedAddress decodedAddress = addressDecoder.decodeAddress(tPayload.get_address());
|
||||
DRAMSys::DecodedAddress decodedAddress =
|
||||
addressDecoder.decodeAddress(tPayload.get_address());
|
||||
decodedAddress = calculateOffsetAddress(decodedAddress);
|
||||
|
||||
#ifdef ECC_ENABLE
|
||||
@@ -168,14 +170,14 @@ void EccModule::peqCallback(tlm::tlm_generic_payload &cbPayload, const tlm::tlm_
|
||||
blockedRequest = pendingRequest;
|
||||
pendingRequest = nullptr;
|
||||
|
||||
auto &eccFifo = activeEccBlocks[decodedAddress.bank];
|
||||
auto& eccFifo = activeEccBlocks[decodedAddress.bank];
|
||||
eccFifo.push_back({currentBlock, decodedAddress.row});
|
||||
|
||||
// Only hold 4 elements at max.
|
||||
if (eccFifo.size() >= 4)
|
||||
eccFifo.pop_front();
|
||||
|
||||
tlm::tlm_generic_payload *eccPayload = generateEccPayload(decodedAddress);
|
||||
tlm::tlm_generic_payload* eccPayload = generateEccPayload(decodedAddress);
|
||||
|
||||
iSocket->nb_transport_fw(*eccPayload, tPhase, tDelay);
|
||||
}
|
||||
@@ -242,7 +244,7 @@ void EccModule::peqCallback(tlm::tlm_generic_payload &cbPayload, const tlm::tlm_
|
||||
}
|
||||
}
|
||||
|
||||
tlm::tlm_generic_payload *EccModule::generateEccPayload(DRAMSys::DecodedAddress decodedAddress)
|
||||
tlm::tlm_generic_payload* EccModule::generateEccPayload(DRAMSys::DecodedAddress decodedAddress)
|
||||
{
|
||||
unsigned int eccAtom = decodedAddress.column / 512;
|
||||
uint64_t eccColumn = 1792 + eccAtom * 32;
|
||||
@@ -250,7 +252,7 @@ tlm::tlm_generic_payload *EccModule::generateEccPayload(DRAMSys::DecodedAddress
|
||||
decodedAddress.column = eccColumn;
|
||||
uint64_t eccAddress = addressDecoder.encodeAddress(decodedAddress);
|
||||
|
||||
tlm_generic_payload &payload = memoryManager.allocate(32);
|
||||
tlm_generic_payload& payload = memoryManager.allocate(32);
|
||||
payload.acquire();
|
||||
payload.set_address(eccAddress);
|
||||
payload.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
|
||||
@@ -286,13 +288,14 @@ void EccModule::end_of_simulation()
|
||||
uint64_t latencies = 0;
|
||||
uint64_t numberOfLatencies = 0;
|
||||
|
||||
for (auto const &[latency, occurences] : latencyMap)
|
||||
for (auto const& [latency, occurences] : latencyMap)
|
||||
{
|
||||
latencies += (latency.to_double() / 1000.0) * occurences;
|
||||
numberOfLatencies += occurences;
|
||||
}
|
||||
|
||||
std::cout << "Average latency: " << static_cast<double>(latencies) / numberOfLatencies << std::endl;
|
||||
std::cout << "Average latency: " << static_cast<double>(latencies) / numberOfLatencies
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
sc_time EccModule::roundLatency(sc_time latency)
|
||||
@@ -305,7 +308,8 @@ sc_time EccModule::roundLatency(sc_time latency)
|
||||
|
||||
bool EccModule::activeEccBlock(Bank bank, Row row, Block block) const
|
||||
{
|
||||
auto eccIt = std::find_if(activeEccBlocks.at(bank).cbegin(), activeEccBlocks.at(bank).cend(),
|
||||
auto eccIt = std::find_if(activeEccBlocks.at(bank).cbegin(),
|
||||
activeEccBlocks.at(bank).cend(),
|
||||
[block, row](EccIdentifier identifier) {
|
||||
return (identifier.first == block) && (identifier.second == row);
|
||||
});
|
||||
|
||||
@@ -41,13 +41,13 @@
|
||||
|
||||
#include <DRAMSys/simulation/AddressDecoder.h>
|
||||
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <systemc>
|
||||
#include <tlm_utils/peq_with_cb_and_phase.h>
|
||||
#include <tlm_utils/simple_initiator_socket.h>
|
||||
#include <tlm_utils/simple_target_socket.h>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
#include <deque>
|
||||
|
||||
class EccModule : public sc_core::sc_module
|
||||
{
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
tlm_utils::simple_initiator_socket<EccModule> iSocket;
|
||||
tlm_utils::simple_target_socket<EccModule> tSocket;
|
||||
|
||||
EccModule(sc_core::sc_module_name name, DRAMSys::AddressDecoder const &addressDecoder);
|
||||
EccModule(sc_core::sc_module_name name, DRAMSys::AddressDecoder const& addressDecoder);
|
||||
SC_HAS_PROCESS(EccModule);
|
||||
|
||||
private:
|
||||
@@ -71,32 +71,32 @@ private:
|
||||
|
||||
void end_of_simulation() override;
|
||||
|
||||
void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase);
|
||||
void peqCallback(tlm::tlm_generic_payload& payload, const tlm::tlm_phase& phase);
|
||||
|
||||
tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &payload,
|
||||
tlm::tlm_phase &phase,
|
||||
sc_core::sc_time &fwDelay);
|
||||
tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload,
|
||||
tlm::tlm_phase &phase,
|
||||
sc_core::sc_time &bwDelay);
|
||||
tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& payload,
|
||||
tlm::tlm_phase& phase,
|
||||
sc_core::sc_time& fwDelay);
|
||||
tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload& payload,
|
||||
tlm::tlm_phase& phase,
|
||||
sc_core::sc_time& bwDelay);
|
||||
|
||||
tlm::tlm_generic_payload *generateEccPayload(DRAMSys::DecodedAddress decodedAddress);
|
||||
tlm::tlm_generic_payload* generateEccPayload(DRAMSys::DecodedAddress decodedAddress);
|
||||
|
||||
static unsigned int alignToBlock(unsigned int column);
|
||||
|
||||
|
||||
tlm_utils::peq_with_cb_and_phase<EccModule> payloadEventQueue;
|
||||
|
||||
tlm::tlm_generic_payload *pendingRequest = nullptr;
|
||||
tlm::tlm_generic_payload *blockedRequest = nullptr;
|
||||
tlm::tlm_generic_payload* pendingRequest = nullptr;
|
||||
tlm::tlm_generic_payload* blockedRequest = nullptr;
|
||||
bool targetBusy = false;
|
||||
|
||||
const sc_core::sc_time tCK;
|
||||
MemoryManager memoryManager;
|
||||
DRAMSys::AddressDecoder const &addressDecoder;
|
||||
DRAMSys::AddressDecoder const& addressDecoder;
|
||||
|
||||
std::unordered_map<Bank, EccQueue> activeEccBlocks;
|
||||
|
||||
using EccPayload = tlm::tlm_generic_payload *;
|
||||
using EccPayload = tlm::tlm_generic_payload*;
|
||||
using StartTime = sc_core::sc_time;
|
||||
std::unordered_map<tlm::tlm_generic_payload*, StartTime> payloadMap;
|
||||
|
||||
|
||||
@@ -40,15 +40,15 @@
|
||||
class Initiator
|
||||
{
|
||||
protected:
|
||||
Initiator(const Initiator &) = default;
|
||||
Initiator(Initiator &&) = default;
|
||||
Initiator &operator=(const Initiator &) = default;
|
||||
Initiator &operator=(Initiator &&) = default;
|
||||
Initiator(const Initiator&) = default;
|
||||
Initiator(Initiator&&) = default;
|
||||
Initiator& operator=(const Initiator&) = default;
|
||||
Initiator& operator=(Initiator&&) = default;
|
||||
|
||||
public:
|
||||
Initiator() = default;
|
||||
virtual ~Initiator() = default;
|
||||
|
||||
virtual void bind(tlm_utils::multi_target_base<> &target) = 0;
|
||||
virtual void bind(tlm_utils::multi_target_base<>& target) = 0;
|
||||
virtual uint64_t totalRequests() = 0;
|
||||
};
|
||||
|
||||
@@ -40,9 +40,9 @@
|
||||
|
||||
using namespace tlm;
|
||||
|
||||
MemoryManager::MemoryManager(bool storageEnabled)
|
||||
: storageEnabled(storageEnabled)
|
||||
{}
|
||||
MemoryManager::MemoryManager(bool storageEnabled) : storageEnabled(storageEnabled)
|
||||
{
|
||||
}
|
||||
|
||||
MemoryManager::~MemoryManager()
|
||||
{
|
||||
@@ -61,8 +61,9 @@ MemoryManager::~MemoryManager()
|
||||
}
|
||||
|
||||
// Comment in if you are suspecting a memory leak in the manager
|
||||
//PRINTDEBUGMESSAGE("MemoryManager","Number of allocated payloads: " + to_string(numberOfAllocations));
|
||||
//PRINTDEBUGMESSAGE("MemoryManager","Number of freed payloads: " + to_string(numberOfFrees));
|
||||
// PRINTDEBUGMESSAGE("MemoryManager","Number of allocated payloads: " +
|
||||
// to_string(numberOfAllocations)); PRINTDEBUGMESSAGE("MemoryManager","Number of freed payloads:
|
||||
// " + to_string(numberOfFrees));
|
||||
}
|
||||
|
||||
tlm_generic_payload& MemoryManager::allocate(unsigned dataLength)
|
||||
@@ -83,7 +84,7 @@ tlm_generic_payload& MemoryManager::allocate(unsigned dataLength)
|
||||
return *payload;
|
||||
}
|
||||
|
||||
tlm_generic_payload *result = freePayloads[dataLength].top();
|
||||
tlm_generic_payload* result = freePayloads[dataLength].top();
|
||||
freePayloads[dataLength].pop();
|
||||
return *result;
|
||||
}
|
||||
|
||||
@@ -38,18 +38,18 @@
|
||||
#ifndef MEMORYMANAGER_H
|
||||
#define MEMORYMANAGER_H
|
||||
|
||||
#include <unordered_map>
|
||||
#include <stack>
|
||||
#include <tlm>
|
||||
#include <unordered_map>
|
||||
|
||||
class MemoryManager : public tlm::tlm_mm_interface
|
||||
{
|
||||
public:
|
||||
explicit MemoryManager(bool storageEnabled);
|
||||
MemoryManager(const MemoryManager &) = delete;
|
||||
MemoryManager(MemoryManager &&) = delete;
|
||||
MemoryManager &operator=(const MemoryManager &) = delete;
|
||||
MemoryManager &operator=(MemoryManager &&) = delete;
|
||||
MemoryManager(const MemoryManager&) = delete;
|
||||
MemoryManager(MemoryManager&&) = delete;
|
||||
MemoryManager& operator=(const MemoryManager&) = delete;
|
||||
MemoryManager& operator=(MemoryManager&&) = delete;
|
||||
~MemoryManager() override;
|
||||
|
||||
tlm::tlm_generic_payload& allocate(unsigned dataLength);
|
||||
|
||||
@@ -38,32 +38,31 @@
|
||||
#include "Initiator.h"
|
||||
#include "request/RequestIssuer.h"
|
||||
|
||||
template <typename Producer>
|
||||
class SimpleInitiator : public Initiator
|
||||
template <typename Producer> class SimpleInitiator : public Initiator
|
||||
{
|
||||
public:
|
||||
SimpleInitiator(sc_core::sc_module_name const &name,
|
||||
MemoryManager &memoryManager,
|
||||
SimpleInitiator(sc_core::sc_module_name const& name,
|
||||
MemoryManager& memoryManager,
|
||||
unsigned int clkMhz,
|
||||
std::optional<unsigned int> maxPendingReadRequests,
|
||||
std::optional<unsigned int> maxPendingWriteRequests,
|
||||
std::function<void()> transactionFinished,
|
||||
std::function<void()> terminate,
|
||||
Producer &&producer)
|
||||
: producer(std::forward<Producer>(producer)),
|
||||
issuer(
|
||||
name,
|
||||
memoryManager,
|
||||
clkMhz,
|
||||
maxPendingReadRequests,
|
||||
maxPendingWriteRequests,
|
||||
[this] { return this->producer.nextRequest(); },
|
||||
std::move(transactionFinished),
|
||||
std::move(terminate))
|
||||
Producer&& producer) :
|
||||
producer(std::forward<Producer>(producer)),
|
||||
issuer(
|
||||
name,
|
||||
memoryManager,
|
||||
clkMhz,
|
||||
maxPendingReadRequests,
|
||||
maxPendingWriteRequests,
|
||||
[this] { return this->producer.nextRequest(); },
|
||||
std::move(transactionFinished),
|
||||
std::move(terminate))
|
||||
{
|
||||
}
|
||||
|
||||
void bind(tlm_utils::multi_target_base<> &target) override { issuer.iSocket.bind(target); }
|
||||
void bind(tlm_utils::multi_target_base<>& target) override { issuer.iSocket.bind(target); }
|
||||
uint64_t totalRequests() override { return producer.totalRequests(); };
|
||||
|
||||
private:
|
||||
|
||||
@@ -43,15 +43,15 @@ RandomProducer::RandomProducer(uint64_t numRequests,
|
||||
std::optional<uint64_t> maxAddress,
|
||||
uint64_t memorySize,
|
||||
unsigned int dataLength,
|
||||
unsigned int dataAlignment)
|
||||
: numberOfRequests(numRequests),
|
||||
seed(seed.value_or(DEFAULT_SEED)),
|
||||
rwRatio(rwRatio),
|
||||
dataLength(dataLength),
|
||||
dataAlignment(dataAlignment),
|
||||
randomGenerator(this->seed),
|
||||
randomAddressDistribution(minAddress.value_or(DEFAULT_MIN_ADDRESS),
|
||||
maxAddress.value_or((memorySize) - dataLength))
|
||||
unsigned int dataAlignment) :
|
||||
numberOfRequests(numRequests),
|
||||
seed(seed.value_or(DEFAULT_SEED)),
|
||||
rwRatio(rwRatio),
|
||||
dataLength(dataLength),
|
||||
dataAlignment(dataAlignment),
|
||||
randomGenerator(this->seed),
|
||||
randomAddressDistribution(minAddress.value_or(DEFAULT_MIN_ADDRESS),
|
||||
maxAddress.value_or((memorySize)-dataLength))
|
||||
{
|
||||
if (minAddress > memorySize - 1)
|
||||
SC_REPORT_FATAL("TrafficGenerator", "minAddress is out of range.");
|
||||
|
||||
@@ -43,15 +43,15 @@ SequentialProducer::SequentialProducer(uint64_t numRequests,
|
||||
std::optional<uint64_t> minAddress,
|
||||
std::optional<uint64_t> maxAddress,
|
||||
uint64_t memorySize,
|
||||
unsigned int dataLength)
|
||||
: numberOfRequests(numRequests),
|
||||
addressIncrement(addressIncrement.value_or(dataLength)),
|
||||
minAddress(minAddress.value_or(DEFAULT_MIN_ADDRESS)),
|
||||
maxAddress(maxAddress.value_or(memorySize - 1)),
|
||||
seed(seed.value_or(DEFAULT_SEED)),
|
||||
rwRatio(rwRatio),
|
||||
dataLength(dataLength),
|
||||
randomGenerator(this->seed)
|
||||
unsigned int dataLength) :
|
||||
numberOfRequests(numRequests),
|
||||
addressIncrement(addressIncrement.value_or(dataLength)),
|
||||
minAddress(minAddress.value_or(DEFAULT_MIN_ADDRESS)),
|
||||
maxAddress(maxAddress.value_or(memorySize - 1)),
|
||||
seed(seed.value_or(DEFAULT_SEED)),
|
||||
rwRatio(rwRatio),
|
||||
dataLength(dataLength),
|
||||
randomGenerator(this->seed)
|
||||
{
|
||||
if (minAddress > memorySize - 1)
|
||||
SC_REPORT_FATAL("TrafficGenerator", "minAddress is out of range.");
|
||||
|
||||
@@ -46,21 +46,21 @@
|
||||
class TrafficGenerator : public Initiator
|
||||
{
|
||||
public:
|
||||
TrafficGenerator(DRAMSys::Config::TrafficGenerator const &config,
|
||||
MemoryManager &memoryManager,
|
||||
TrafficGenerator(DRAMSys::Config::TrafficGenerator const& config,
|
||||
MemoryManager& memoryManager,
|
||||
uint64_t memorySize,
|
||||
unsigned int defaultDataLength,
|
||||
std::function<void()> transactionFinished,
|
||||
std::function<void()> terminateInitiator);
|
||||
|
||||
TrafficGenerator(DRAMSys::Config::TrafficGeneratorStateMachine const &config,
|
||||
MemoryManager &memoryManager,
|
||||
TrafficGenerator(DRAMSys::Config::TrafficGeneratorStateMachine const& config,
|
||||
MemoryManager& memoryManager,
|
||||
uint64_t memorySize,
|
||||
unsigned int defaultDataLength,
|
||||
std::function<void()> transactionFinished,
|
||||
std::function<void()> terminateInitiator);
|
||||
|
||||
void bind(tlm_utils::multi_target_base<> &target) override { issuer.iSocket.bind(target); }
|
||||
void bind(tlm_utils::multi_target_base<>& target) override { issuer.iSocket.bind(target); }
|
||||
|
||||
uint64_t totalRequests() override;
|
||||
Request nextRequest();
|
||||
|
||||
@@ -35,12 +35,10 @@
|
||||
|
||||
#include "RowHammer.h"
|
||||
|
||||
RowHammer::RowHammer(uint64_t numRequests,
|
||||
uint64_t rowIncrement,
|
||||
unsigned int dataLength)
|
||||
: numberOfRequests(numRequests),
|
||||
dataLength(dataLength),
|
||||
rowIncrement(rowIncrement)
|
||||
RowHammer::RowHammer(uint64_t numRequests, uint64_t rowIncrement, unsigned int dataLength) :
|
||||
numberOfRequests(numRequests),
|
||||
dataLength(dataLength),
|
||||
rowIncrement(rowIncrement)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -48,7 +46,7 @@ Request RowHammer::nextRequest()
|
||||
{
|
||||
if (generatedRequests >= numberOfRequests)
|
||||
return Request{Request::Command::Stop};
|
||||
|
||||
|
||||
generatedRequests++;
|
||||
|
||||
if (currentAddress == 0x00)
|
||||
|
||||
@@ -42,9 +42,7 @@
|
||||
class RowHammer : public RequestProducer
|
||||
{
|
||||
public:
|
||||
RowHammer(uint64_t numRequests,
|
||||
uint64_t rowIncrement,
|
||||
unsigned int dataLength);
|
||||
RowHammer(uint64_t numRequests, uint64_t rowIncrement, unsigned int dataLength);
|
||||
|
||||
Request nextRequest() override;
|
||||
uint64_t totalRequests() override { return numberOfRequests; }
|
||||
|
||||
@@ -46,16 +46,16 @@ StlPlayer::StlPlayer(std::string_view tracePath,
|
||||
unsigned int clkMhz,
|
||||
unsigned int defaultDataLength,
|
||||
TraceType traceType,
|
||||
bool storageEnabled)
|
||||
: traceType(traceType),
|
||||
storageEnabled(storageEnabled),
|
||||
playerPeriod(sc_core::sc_time(1.0 / static_cast<double>(clkMhz), sc_core::SC_US)),
|
||||
defaultDataLength(defaultDataLength),
|
||||
traceFile(tracePath.data()),
|
||||
lineBuffers(
|
||||
{std::make_shared<std::vector<Request>>(), std::make_shared<std::vector<Request>>()}),
|
||||
parseBuffer(lineBuffers.at(1)),
|
||||
readoutBuffer(lineBuffers.at(0))
|
||||
bool storageEnabled) :
|
||||
traceType(traceType),
|
||||
storageEnabled(storageEnabled),
|
||||
playerPeriod(sc_core::sc_time(1.0 / static_cast<double>(clkMhz), sc_core::SC_US)),
|
||||
defaultDataLength(defaultDataLength),
|
||||
traceFile(tracePath.data()),
|
||||
lineBuffers(
|
||||
{std::make_shared<std::vector<Request>>(), std::make_shared<std::vector<Request>>()}),
|
||||
parseBuffer(lineBuffers.at(1)),
|
||||
readoutBuffer(lineBuffers.at(0))
|
||||
{
|
||||
readoutBuffer->reserve(LINE_BUFFER_SIZE);
|
||||
parseBuffer->reserve(LINE_BUFFER_SIZE);
|
||||
@@ -72,8 +72,7 @@ StlPlayer::StlPlayer(std::string_view tracePath,
|
||||
numberOfLines++;
|
||||
}
|
||||
if (numberOfLines == 0)
|
||||
SC_REPORT_FATAL("StlPlayer",
|
||||
(std::string("Empty trace ") + tracePath.data()).c_str());
|
||||
SC_REPORT_FATAL("StlPlayer", (std::string("Empty trace ") + tracePath.data()).c_str());
|
||||
traceFile.clear();
|
||||
traceFile.seekg(0);
|
||||
}
|
||||
@@ -101,7 +100,8 @@ Request StlPlayer::nextRequest()
|
||||
if (traceType == TraceType::Absolute)
|
||||
{
|
||||
bool behindSchedule = sc_core::sc_time_stamp() > readoutIt->delay;
|
||||
delay = behindSchedule ? sc_core::SC_ZERO_TIME : readoutIt->delay - sc_core::sc_time_stamp();
|
||||
delay =
|
||||
behindSchedule ? sc_core::SC_ZERO_TIME : readoutIt->delay - sc_core::sc_time_stamp();
|
||||
}
|
||||
else // if (traceType == TraceType::Relative)
|
||||
{
|
||||
@@ -134,7 +134,7 @@ void StlPlayer::parseTraceFile()
|
||||
|
||||
parsedLines++;
|
||||
parseBuffer->emplace_back();
|
||||
Request &content = parseBuffer->back();
|
||||
Request& content = parseBuffer->back();
|
||||
|
||||
// Trace files MUST provide timestamp, command and address for every
|
||||
// transaction. The data information depends on the storage mode
|
||||
@@ -150,8 +150,8 @@ void StlPlayer::parseTraceFile()
|
||||
iss >> element;
|
||||
if (element.empty())
|
||||
SC_REPORT_FATAL(
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
|
||||
content.delay = playerPeriod * static_cast<double>(std::stoull(element));
|
||||
|
||||
@@ -159,8 +159,8 @@ void StlPlayer::parseTraceFile()
|
||||
iss >> element;
|
||||
if (element.empty())
|
||||
SC_REPORT_FATAL(
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
|
||||
if (element.at(0) == '(')
|
||||
{
|
||||
@@ -169,8 +169,8 @@ void StlPlayer::parseTraceFile()
|
||||
iss >> element;
|
||||
if (element.empty())
|
||||
SC_REPORT_FATAL(
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
}
|
||||
else
|
||||
content.length = defaultDataLength;
|
||||
@@ -181,15 +181,15 @@ void StlPlayer::parseTraceFile()
|
||||
content.command = Request::Command::Write;
|
||||
else
|
||||
SC_REPORT_FATAL(
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
|
||||
// Get the address.
|
||||
iss >> element;
|
||||
if (element.empty())
|
||||
SC_REPORT_FATAL(
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
content.address = std::stoull(element, nullptr, 16);
|
||||
|
||||
// Get the data if necessary.
|
||||
@@ -202,20 +202,20 @@ void StlPlayer::parseTraceFile()
|
||||
// We need two characters to represent 1 byte in hexadecimal. Offset for 0x prefix.
|
||||
if (element.length() != (content.length * 2 + 2))
|
||||
SC_REPORT_FATAL(
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
|
||||
// Set data
|
||||
for (unsigned i = 0; i < content.length; i++)
|
||||
content.data.emplace_back(static_cast<unsigned char>(
|
||||
std::stoi(element.substr(i * 2 + 2, 2), nullptr, 16)));
|
||||
std::stoi(element.substr(i * 2 + 2, 2), nullptr, 16)));
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
SC_REPORT_FATAL(
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
"StlPlayer",
|
||||
("Malformed trace file line " + std::to_string(currentLine) + ".").c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,23 +35,23 @@
|
||||
|
||||
#include "RequestIssuer.h"
|
||||
|
||||
RequestIssuer::RequestIssuer(sc_core::sc_module_name const &name,
|
||||
MemoryManager &memoryManager,
|
||||
RequestIssuer::RequestIssuer(sc_core::sc_module_name const& name,
|
||||
MemoryManager& memoryManager,
|
||||
unsigned int clkMhz,
|
||||
std::optional<unsigned int> maxPendingReadRequests,
|
||||
std::optional<unsigned int> maxPendingWriteRequests,
|
||||
std::function<Request()> nextRequest,
|
||||
std::function<void()> transactionFinished,
|
||||
std::function<void()> terminate)
|
||||
: sc_module(name),
|
||||
payloadEventQueue(this, &RequestIssuer::peqCallback),
|
||||
memoryManager(memoryManager),
|
||||
clkPeriod(sc_core::sc_time(1.0 / static_cast<double>(clkMhz), sc_core::SC_US)),
|
||||
maxPendingReadRequests(maxPendingReadRequests),
|
||||
maxPendingWriteRequests(maxPendingWriteRequests),
|
||||
transactionFinished(std::move(transactionFinished)),
|
||||
terminate(std::move(terminate)),
|
||||
nextRequest(std::move(nextRequest))
|
||||
std::function<void()> terminate) :
|
||||
sc_module(name),
|
||||
payloadEventQueue(this, &RequestIssuer::peqCallback),
|
||||
memoryManager(memoryManager),
|
||||
clkPeriod(sc_core::sc_time(1.0 / static_cast<double>(clkMhz), sc_core::SC_US)),
|
||||
maxPendingReadRequests(maxPendingReadRequests),
|
||||
maxPendingWriteRequests(maxPendingWriteRequests),
|
||||
transactionFinished(std::move(transactionFinished)),
|
||||
terminate(std::move(terminate)),
|
||||
nextRequest(std::move(nextRequest))
|
||||
{
|
||||
SC_THREAD(sendNextRequest);
|
||||
iSocket.register_nb_transport_bw(this, &RequestIssuer::nb_transport_bw);
|
||||
@@ -67,7 +67,7 @@ void RequestIssuer::sendNextRequest()
|
||||
return;
|
||||
}
|
||||
|
||||
tlm::tlm_generic_payload &payload = memoryManager.allocate(request.length);
|
||||
tlm::tlm_generic_payload& payload = memoryManager.allocate(request.length);
|
||||
payload.acquire();
|
||||
payload.set_address(request.address);
|
||||
payload.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
|
||||
@@ -120,7 +120,7 @@ bool RequestIssuer::nextRequestSendable() const
|
||||
return true;
|
||||
}
|
||||
|
||||
void RequestIssuer::peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase)
|
||||
void RequestIssuer::peqCallback(tlm::tlm_generic_payload& payload, const tlm::tlm_phase& phase)
|
||||
{
|
||||
if (phase == tlm::END_REQ)
|
||||
{
|
||||
|
||||
@@ -50,8 +50,8 @@ class RequestIssuer : sc_core::sc_module
|
||||
public:
|
||||
tlm_utils::simple_initiator_socket<RequestIssuer> iSocket;
|
||||
|
||||
RequestIssuer(sc_core::sc_module_name const &name,
|
||||
MemoryManager &memoryManager,
|
||||
RequestIssuer(sc_core::sc_module_name const& name,
|
||||
MemoryManager& memoryManager,
|
||||
unsigned int clkMhz,
|
||||
std::optional<unsigned int> maxPendingReadRequests,
|
||||
std::optional<unsigned int> maxPendingWriteRequests,
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
|
||||
private:
|
||||
tlm_utils::peq_with_cb_and_phase<RequestIssuer> payloadEventQueue;
|
||||
MemoryManager &memoryManager;
|
||||
MemoryManager& memoryManager;
|
||||
|
||||
const sc_core::sc_time clkPeriod;
|
||||
|
||||
@@ -85,13 +85,13 @@ private:
|
||||
void sendNextRequest();
|
||||
bool nextRequestSendable() const;
|
||||
|
||||
tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload,
|
||||
tlm::tlm_phase &phase,
|
||||
sc_core::sc_time &bwDelay)
|
||||
tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload& payload,
|
||||
tlm::tlm_phase& phase,
|
||||
sc_core::sc_time& bwDelay)
|
||||
{
|
||||
payloadEventQueue.notify(payload, phase, bwDelay);
|
||||
return tlm::TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase);
|
||||
void peqCallback(tlm::tlm_generic_payload& payload, const tlm::tlm_phase& phase);
|
||||
};
|
||||
|
||||
@@ -40,10 +40,10 @@
|
||||
class RequestProducer
|
||||
{
|
||||
protected:
|
||||
RequestProducer(const RequestProducer &) = default;
|
||||
RequestProducer(RequestProducer &&) = default;
|
||||
RequestProducer &operator=(const RequestProducer &) = default;
|
||||
RequestProducer &operator=(RequestProducer &&) = default;
|
||||
RequestProducer(const RequestProducer&) = default;
|
||||
RequestProducer(RequestProducer&&) = default;
|
||||
RequestProducer& operator=(const RequestProducer&) = default;
|
||||
RequestProducer& operator=(RequestProducer&&) = default;
|
||||
|
||||
public:
|
||||
RequestProducer() = default;
|
||||
|
||||
Reference in New Issue
Block a user