Merge branch 'misc_changes' into 'develop'

Multiple misc changes

See merge request ems/astdm/modeling.dram/dram.sys.5!136
This commit is contained in:
2025-09-24 17:01:53 +02:00
28 changed files with 218 additions and 263 deletions

View File

@@ -52,12 +52,10 @@ static DRAMSys::AddressDecoder addressDecoder()
static void addressdecoder_decode(benchmark::State& state)
{
auto decoder = addressDecoder();
tlm::tlm_generic_payload trans;
trans.set_address(0x0);
for (auto _ : state)
{
// Actual address has no significant impact on performance
auto decodedAddress = decoder.decodeAddress(trans);
auto decodedAddress = decoder.decodeAddress(0x0);
benchmark::DoNotOptimize(decodedAddress);
}
}

View File

@@ -51,6 +51,7 @@ add_library(libdramsys
DRAMSys/common/DramATRecorder.cpp
DRAMSys/common/dramExtensions.cpp
DRAMSys/common/utils.cpp
DRAMSys/common/MemoryManager.cpp
DRAMSys/configuration/memspec/MemSpec.cpp
DRAMSys/configuration/memspec/MemSpecDDR3.cpp
DRAMSys/configuration/memspec/MemSpecDDR4.cpp

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* Copyright (c) 2024, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,46 +33,40 @@
* Authors:
* Robert Gernhardt
* Matthias Jung
* Lukas Steiner
* Derek Christ
*/
#include "MemoryManager.h"
#include "DRAMSys/common/DebugManager.h"
using namespace tlm;
MemoryManager::MemoryManager(bool storageEnabled) : storageEnabled(storageEnabled)
namespace DRAMSys
{
}
MemoryManager::MemoryManager(bool storageEnabled) : storageEnabled(storageEnabled) {};
MemoryManager::~MemoryManager()
{
for (auto& innerBuffer : freePayloads)
for (auto& [size, stack] : freePayloads)
{
while (!innerBuffer.second.empty())
while (!stack.empty())
{
tlm_generic_payload* payload = innerBuffer.second.top();
if (storageEnabled)
tlm::tlm_generic_payload* payload = stack.top();
if (size != 0)
delete[] payload->get_data_ptr();
payload->reset();
delete payload;
innerBuffer.second.pop();
numberOfFrees++;
stack.pop();
}
}
// 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));
}
tlm_generic_payload& MemoryManager::allocate(unsigned dataLength)
tlm::tlm_generic_payload* MemoryManager::allocate(std::size_t dataLength)
{
if (freePayloads[dataLength].empty())
{
numberOfAllocations++;
auto* payload = new tlm_generic_payload(this);
auto* payload = new tlm::tlm_generic_payload(this);
if (storageEnabled)
{
@@ -81,16 +76,18 @@ tlm_generic_payload& MemoryManager::allocate(unsigned dataLength)
payload->set_data_ptr(data);
}
return *payload;
return payload;
}
tlm_generic_payload* result = freePayloads[dataLength].top();
tlm::tlm_generic_payload* result = freePayloads[dataLength].top();
freePayloads[dataLength].pop();
return *result;
return result;
}
void MemoryManager::free(tlm_generic_payload* payload)
void MemoryManager::free(tlm::tlm_generic_payload* trans)
{
unsigned dataLength = payload->get_data_length();
freePayloads[dataLength].push(payload);
unsigned dataLength = trans->get_data_length();
freePayloads[dataLength].push(trans);
}
} // namespace DRAMSys

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
* Copyright (c) 2024, RPTU Kaiserslautern-Landau
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,6 +32,7 @@
* Authors:
* Robert Gernhardt
* Matthias Jung
* Lukas Steiner
* Derek Christ
*/
@@ -42,24 +43,27 @@
#include <tlm>
#include <unordered_map>
namespace DRAMSys
{
class MemoryManager : public tlm::tlm_mm_interface
{
public:
explicit MemoryManager(bool storageEnabled);
MemoryManager(bool storageEnabled);
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);
void free(tlm::tlm_generic_payload* payload) override;
tlm::tlm_generic_payload* allocate(std::size_t dataLength = 0);
void free(tlm::tlm_generic_payload* trans) override;
private:
uint64_t numberOfAllocations = 0;
uint64_t numberOfFrees = 0;
std::unordered_map<unsigned, std::stack<tlm::tlm_generic_payload*>> freePayloads;
bool storageEnabled = false;
std::unordered_map<std::size_t, std::stack<tlm::tlm_generic_payload*>> freePayloads;
bool storageEnabled;
};
} // namespace DRAMSys
#endif // MEMORYMANAGER_H

View File

@@ -102,7 +102,8 @@ Controller::Controller(const sc_module_name& name,
nextWindowEventTime(windowSizeTime),
numberOfBeatsServed(memSpec.ranksPerChannel, 0),
minBytesPerBurst(memSpec.defaultBytesPerBurst),
maxBytesPerBurst(memSpec.maxBytesPerBurst)
maxBytesPerBurst(memSpec.maxBytesPerBurst),
memoryManager(simConfig.storeMode == Config::StoreModeType::Store)
{
if (simConfig.databaseRecording && tlmRecorder != nullptr)
{
@@ -608,7 +609,7 @@ void Controller::manageRequests(const sc_time& delay)
{
// continuous block of data that can be fetched with a single burst
DecodedAddress decodedAddress =
addressDecoder.decodeAddress(*transToAcquire.payload);
addressDecoder.decodeAddress(transToAcquire.payload->get_address());
ControllerExtension::setAutoExtension(
*transToAcquire.payload,
nextChannelPayloadIDToAppend++,
@@ -741,34 +742,6 @@ void Controller::sendToFrontend(tlm_generic_payload& trans, tlm_phase& phase, sc
tSocket->nb_transport_bw(trans, phase, delay);
}
Controller::MemoryManager::~MemoryManager()
{
while (!freePayloads.empty())
{
tlm_generic_payload* trans = freePayloads.top();
freePayloads.pop();
trans->reset();
delete trans;
}
}
tlm::tlm_generic_payload& Controller::MemoryManager::allocate()
{
if (freePayloads.empty())
{
return *new tlm_generic_payload(this);
}
tlm_generic_payload* result = freePayloads.top();
freePayloads.pop();
return *result;
}
void Controller::MemoryManager::free(tlm::tlm_generic_payload* trans)
{
freePayloads.push(trans);
}
void Controller::createChildTranses(tlm::tlm_generic_payload& parentTrans)
{
std::vector<tlm_generic_payload*> childTranses;
@@ -779,14 +752,14 @@ void Controller::createChildTranses(tlm::tlm_generic_payload& parentTrans)
for (unsigned childId = 0; childId < numChildTranses; childId++)
{
tlm_generic_payload& childTrans = memoryManager.allocate();
childTrans.acquire();
childTrans.set_command(parentTrans.get_command());
childTrans.set_address(startAddress + childId * maxBytesPerBurst);
childTrans.set_data_length(maxBytesPerBurst);
childTrans.set_data_ptr(startDataPtr + childId * maxBytesPerBurst);
ChildExtension::setExtension(childTrans, parentTrans);
childTranses.push_back(&childTrans);
tlm_generic_payload* childTrans = memoryManager.allocate();
childTrans->acquire();
childTrans->set_command(parentTrans.get_command());
childTrans->set_address(startAddress + childId * maxBytesPerBurst);
childTrans->set_data_length(maxBytesPerBurst);
childTrans->set_data_ptr(startDataPtr + childId * maxBytesPerBurst);
ChildExtension::setExtension(*childTrans, parentTrans);
childTranses.push_back(childTrans);
}
if (startAddress != parentTrans.get_address())
@@ -795,19 +768,20 @@ void Controller::createChildTranses(tlm::tlm_generic_payload& parentTrans)
firstChildTrans.set_address(firstChildTrans.get_address() + minBytesPerBurst);
firstChildTrans.set_data_ptr(firstChildTrans.get_data_ptr() + minBytesPerBurst);
firstChildTrans.set_data_length(minBytesPerBurst);
tlm_generic_payload& lastChildTrans = memoryManager.allocate();
lastChildTrans.acquire();
lastChildTrans.set_command(parentTrans.get_command());
lastChildTrans.set_address(startAddress + numChildTranses * maxBytesPerBurst);
lastChildTrans.set_data_length(minBytesPerBurst);
lastChildTrans.set_data_ptr(startDataPtr + numChildTranses * maxBytesPerBurst);
ChildExtension::setExtension(lastChildTrans, parentTrans);
childTranses.push_back(&lastChildTrans);
tlm_generic_payload* lastChildTrans = memoryManager.allocate();
lastChildTrans->acquire();
lastChildTrans->set_command(parentTrans.get_command());
lastChildTrans->set_address(startAddress + numChildTranses * maxBytesPerBurst);
lastChildTrans->set_data_length(minBytesPerBurst);
lastChildTrans->set_data_ptr(startDataPtr + numChildTranses * maxBytesPerBurst);
ChildExtension::setExtension(*lastChildTrans, parentTrans);
childTranses.push_back(lastChildTrans);
}
for (auto* childTrans : childTranses)
{
DecodedAddress decodedAddress = addressDecoder.decodeAddress(*childTrans);
DecodedAddress decodedAddress = addressDecoder.decodeAddress(childTrans->get_address());
ControllerExtension::setAutoExtension(*childTrans,
nextChannelPayloadIDToAppend,
Rank(decodedAddress.rank),

View File

@@ -51,6 +51,7 @@
#include "DRAMSys/common/TlmRecorder.h"
#include "DRAMSys/simulation/SimConfig.h"
#include <DRAMSys/common/DebugManager.h>
#include <DRAMSys/common/MemoryManager.h>
#include <DRAMSys/simulation/AddressDecoder.h>
#include <functional>
@@ -148,25 +149,10 @@ private:
const unsigned minBytesPerBurst;
const unsigned maxBytesPerBurst;
MemoryManager memoryManager;
void createChildTranses(tlm::tlm_generic_payload& parentTrans);
class MemoryManager : public tlm::tlm_mm_interface
{
public:
MemoryManager() = default;
MemoryManager(const MemoryManager&) = delete;
MemoryManager(MemoryManager&&) = delete;
MemoryManager& operator=(const MemoryManager&) = delete;
MemoryManager& operator=(MemoryManager&&) = delete;
~MemoryManager() override;
tlm::tlm_generic_payload& allocate();
void free(tlm::tlm_generic_payload* trans) override;
private:
std::stack<tlm::tlm_generic_payload*> freePayloads;
} memoryManager;
class IdleTimeCollector
{
public:

View File

@@ -66,12 +66,12 @@ uint64_t createBitmask(unsigned numBits, unsigned startIndex) {
return ((UINT64_C(1) << numBits) - 1) << startIndex;
}
std::vector<std::bitset<64>> AddressDecoder::transposeMatrix(const std::vector<std::bitset<64>>& matrix) {
std::vector<std::bitset<AddressDecoder::ADDRESS_WIDTH>> AddressDecoder::transposeMatrix(const std::vector<std::bitset<ADDRESS_WIDTH>>& matrix) {
size_t size = matrix.size();
std::vector<std::bitset<64>> transposedMatrix(size);
std::vector<std::bitset<ADDRESS_WIDTH>> transposedMatrix(size);
for (size_t i = 0; i < size; ++i) {
for (size_t j = 0; j < 64; ++j) {
for (size_t j = 0; j < ADDRESS_WIDTH; ++j) {
if (matrix[i].test(j))
transposedMatrix[j].set(i);
}
@@ -79,7 +79,7 @@ std::vector<std::bitset<64>> AddressDecoder::transposeMatrix(const std::vector<s
return transposedMatrix;
}
uint64_t AddressDecoder::gf2Multiplication(const uint64_t& inputVec, const std::vector<std::bitset<64>>& matrix) const
uint64_t AddressDecoder::gf2Multiplication(const uint64_t& inputVec, const std::vector<std::bitset<ADDRESS_WIDTH>>& matrix) const
{
#if defined(__clang__) || defined(__GNUC__)
uint64_t result = 0;
@@ -91,8 +91,8 @@ uint64_t AddressDecoder::gf2Multiplication(const uint64_t& inputVec, const std::
}
return result;
#else
std::bitset<64> resultBits;
std::bitset<64> inputBits(inputVec);
std::bitset<ADDRESS_WIDTH> resultBits;
std::bitset<ADDRESS_WIDTH> inputBits(inputVec);
for (size_t i = 0; i < matrix.size(); ++i) {
resultBits[i] = (inputBits & matrix[i]).count() % 2;
@@ -101,7 +101,7 @@ uint64_t AddressDecoder::gf2Multiplication(const uint64_t& inputVec, const std::
#endif
// Print input, mapping matrix and output in a readable way (useful for debugging)
// std::cout << "Vec " << ":\t" << std::bitset<64>(vector[0]) << std::endl << std::endl;
// std::cout << "Vec " << ":\t" << std::bitset<ADDRESS_WIDTH>(vector[0]) << std::endl << std::endl;
// for (size_t i = 0; i < mappingMatrix.size(); ++i) {
// std::cout << "Row " << i << ":\t" << mappingMatrix[i] << " | " << resultBits[i] << std::endl;
// }
@@ -115,7 +115,7 @@ uint64_t AddressDecoder::gf2Multiplication(const uint64_t& inputVec, const std::
AddressDecoder::AddressDecoder(const DRAMSys::Config::AddressMapping& addressMapping) :
highestBitValue(addressMapping.getHighestBit())
{
mappingMatrix = std::vector<std::bitset<64>>(highestBitValue + 1);
mappingMatrix = std::vector<std::bitset<ADDRESS_WIDTH>>(highestBitValue + 1);
upperBoundAddress = std::pow(2, highestBitValue + 1) - 1;
auto addBitsToMatrix = [&](const std::optional<std::vector<Config::AddressMapping::BitEntry>> bits, int *rowIndex, std::string_view name)
@@ -145,8 +145,8 @@ AddressDecoder::AddressDecoder(const DRAMSys::Config::AddressMapping& addressMap
stackBits = addBitsToMatrix(addressMapping.STACK_BIT, &rowIndex, "St");
transposedMappingMatrix = transposeMatrix(mappingMatrix);
bankgroupsPerRank = std::lround(std::pow(2.0, bankGroupBits.length));
banksPerGroup = std::lround(std::pow(2.0, bankBits.length));
bankgroupsPerRank = std::lround(std::pow(2, bankGroupBits.length));
banksPerGroup = std::lround(std::pow(2, bankBits.length));
}
@@ -157,13 +157,13 @@ void AddressDecoder::plausibilityCheck(const MemSpec& memSpec)
// Check if all address bits are used
// TODO: Check if every bit occurs ~exactly~ once or just at least once?
std::bitset<64> orBitset(0);
std::bitset<ADDRESS_WIDTH> orBitset(0);
for (auto bitset: mappingMatrix) {
orBitset |= bitset;
}
std::bitset<64> mask((1ULL << (highestBitValue + 1)) - 1);
std::bitset<ADDRESS_WIDTH> mask((1ULL << (highestBitValue + 1)) - 1);
if (orBitset != mask) {
SC_REPORT_FATAL("AddressDecoder", "Not all address bits are used");
}
@@ -204,11 +204,11 @@ void AddressDecoder::checkMemorySize(const MemSpec& memSpec) {
}
void AddressDecoder::checkMemSpecCompatibility(const MemSpec& memSpec) {
unsigned channels = std::lround(std::pow(2.0, channelBits.length));
unsigned ranks = std::lround(std::pow(2.0, rankBits.length));
unsigned rows = std::lround(std::pow(2.0, rowBits.length));
unsigned columns = std::lround(std::pow(2.0, columnBits.length));
unsigned pseudochannels = std::lround(std::pow(2.0, pseudochannelBits.length));
unsigned channels = std::lround(std::pow(2, channelBits.length));
unsigned ranks = std::lround(std::pow(2, rankBits.length));
unsigned rows = std::lround(std::pow(2, rowBits.length));
unsigned columns = std::lround(std::pow(2, columnBits.length));
unsigned pseudochannels = std::lround(std::pow(2, pseudochannelBits.length));
unsigned absoluteBankGroups = bankgroupsPerRank * (ranks * pseudochannels);
unsigned absoluteBanks = banksPerGroup * absoluteBankGroups;
@@ -242,7 +242,7 @@ void AddressDecoder::checkAddressableLimits(const MemSpec& memSpec) {
}
unsigned AddressDecoder::calculateAddressableElements(unsigned bitSize) const {
return std::lround(std::pow(2.0, bitSize));
return std::lround(std::pow(2, bitSize));
}
void AddressDecoder::validateAddressableLimit(unsigned memSpecValue, unsigned addressableValue, const std::string& name) {
@@ -289,8 +289,8 @@ void AddressDecoder::checkBurstLengthBits(const MemSpec& memSpec) {
" reserved burst bits.").c_str());
}
std::bitset<64> burstBitset(((1 << numOfMaxBurstLengthBits) - 1) << columnBits.idx);
std::bitset<64> columnBitset;
std::bitset<ADDRESS_WIDTH> burstBitset(((1 << numOfMaxBurstLengthBits) - 1) << columnBits.idx);
std::bitset<ADDRESS_WIDTH> columnBitset;
for (size_t i = 0; i < columnBits.length; i++) {
columnBitset |= mappingMatrix[columnBits.idx + i];
}
@@ -304,12 +304,11 @@ void AddressDecoder::checkBurstLengthBits(const MemSpec& memSpec) {
}
DecodedAddress AddressDecoder::decodeAddress(tlm::tlm_generic_payload& trans) const
DecodedAddress AddressDecoder::decodeAddress(uint64_t address) const
{
uint64_t encAddr = trans.get_address();
uint64_t encAddr = address;
if (encAddr > upperBoundAddress)
{
trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE);
SC_REPORT_WARNING("AddressDecoder",
("Address " + std::to_string(encAddr) +
" out of range (maximum address is " + std::to_string(upperBoundAddress) +
@@ -343,9 +342,11 @@ DecodedAddress AddressDecoder::decodeAddress(tlm::tlm_generic_payload& trans) co
decAddr.column= get_component(columnBits);
decAddr.byte = get_component(byteBits);
if (np2Flag)
if (!isAddressValid(decAddr))
trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE);
if (np2Flag && !isAddressValid(decAddr))
{
SC_REPORT_WARNING("AddressDecoder",
("Address " + std::to_string(encAddr) + " invalid)").c_str());
}
// Important: This offsets must be added after(!) the address validation!
decAddr.bankgroup = decAddr.bankgroup + decAddr.rank * bankgroupsPerRank;

View File

@@ -96,10 +96,10 @@ public:
/**
* @brief Decodes an address from a transaction payload into its address components.
*
* @param trans The transaction payload.
* @param address The encoded address.
* @return The decoded address.
*/
[[nodiscard]] DecodedAddress decodeAddress(tlm::tlm_generic_payload& trans) const;
[[nodiscard]] DecodedAddress decodeAddress(uint64_t address) const;
/**
* @brief Decodes the channel component from an encoded address.
@@ -130,8 +130,10 @@ public:
void print() const;
private:
std::vector<std::bitset<64>> mappingMatrix;
std::vector<std::bitset<64>> transposedMappingMatrix;
static constexpr unsigned ADDRESS_WIDTH = 64;
std::vector<std::bitset<ADDRESS_WIDTH>> mappingMatrix;
std::vector<std::bitset<ADDRESS_WIDTH>> transposedMappingMatrix;
uint64_t highestBitValue;
const MemSpec* memSpec;
uint64_t burstBitMask;
@@ -159,7 +161,7 @@ private:
* @param matrix The matrix to transpose.
* @return The transposed matrix.
*/
[[nodiscard]] std::vector<std::bitset<64>> transposeMatrix(const std::vector<std::bitset<64>>& matrix);
[[nodiscard]] std::vector<std::bitset<ADDRESS_WIDTH>> transposeMatrix(const std::vector<std::bitset<ADDRESS_WIDTH>>& matrix);
/**
* @brief Multiplies a 64-bit vector with a matrix over GF(2).
@@ -168,7 +170,7 @@ private:
* @param matrix The GF(2) matrix.
* @return The result of the multiplication as a 64-bit unsinged integer.
*/
[[nodiscard]] uint64_t gf2Multiplication(const uint64_t& inputVec, const std::vector<std::bitset<64>>& matrix) const;
[[nodiscard]] uint64_t gf2Multiplication(const uint64_t& inputVec, const std::vector<std::bitset<ADDRESS_WIDTH>>& matrix) const;
/**

View File

@@ -195,7 +195,7 @@ void Arbiter::b_transport([[maybe_unused]] int id,
{
trans.set_address(trans.get_address() - addressOffset);
DecodedAddress decodedAddress = addressDecoder.decodeAddress(trans);
DecodedAddress decodedAddress = addressDecoder.decodeAddress(trans.get_address());
iSocket[static_cast<int>(decodedAddress.channel)]->b_transport(trans, delay);
}
@@ -203,7 +203,7 @@ unsigned int Arbiter::transport_dbg([[maybe_unused]] int id, tlm::tlm_generic_pa
{
trans.set_address(trans.get_address() - addressOffset);
DecodedAddress decodedAddress = addressDecoder.decodeAddress(trans);
DecodedAddress decodedAddress = addressDecoder.decodeAddress(trans.get_address());
return iSocket[static_cast<int>(decodedAddress.channel)]->transport_dbg(trans);
}

View File

@@ -152,23 +152,22 @@ void Dram::reportPower()
}
}
tlm_sync_enum Dram::nb_transport_fw(tlm_generic_payload& trans, tlm_phase& phase, sc_time& delay)
tlm_sync_enum
Dram::nb_transport_fw(tlm_generic_payload& trans, tlm_phase& phase, [[maybe_unused]] sc_time& delay)
{
assert(phase >= BEGIN_RD && phase <= END_SREF);
if (DRAMPower)
{
std::size_t channel = static_cast<std::size_t>(ArbiterExtension::getChannel(trans));
std::size_t rank = static_cast<std::size_t>(
auto rank = static_cast<std::size_t>(
ControllerExtension::getRank(trans)); // relaitve to the channel
std::size_t bank_group_abs = static_cast<std::size_t>(
auto bank_group_abs = static_cast<std::size_t>(
ControllerExtension::getBankGroup(trans)); // relative to the channel
std::size_t bank_group =
bank_group_abs - rank * memSpec.groupsPerRank; // relative to the rank
std::size_t bank = static_cast<std::size_t>(ControllerExtension::getBank(trans)) -
bank_group_abs * memSpec.banksPerGroup; // relative to the bank_group
std::size_t row = static_cast<std::size_t>(ControllerExtension::getRow(trans));
std::size_t column = static_cast<std::size_t>(ControllerExtension::getColumn(trans));
auto bank_group = bank_group_abs - (rank * memSpec.groupsPerRank); // relative to the rank
auto bank = static_cast<std::size_t>(ControllerExtension::getBank(trans)) -
(bank_group_abs * memSpec.banksPerGroup); // relative to the bank_group
auto row = static_cast<std::size_t>(ControllerExtension::getRow(trans));
auto column = static_cast<std::size_t>(ControllerExtension::getColumn(trans));
uint64_t cycle = std::lround((sc_time_stamp() + delay) / memSpec.tCK);
// DRAMPower:
@@ -186,6 +185,11 @@ tlm_sync_enum Dram::nb_transport_fw(tlm_generic_payload& trans, tlm_phase& phase
DRAMPower->doCoreInterfaceCommand(command);
}
// Strictly speaking, the DRAM should honor the delay value before executing the read or write
// transaction in the memory. However, as the controller issues only a constant delay, this
// would not make a difference. When coupling with RTL models however, it could make a
// difference.
if (storeMode == Config::StoreModeType::Store)
{
if (phase == BEGIN_RD || phase == BEGIN_RDA)

View File

@@ -43,7 +43,6 @@ find_package(Threads)
add_library(simulator
simulator/Cache.cpp
simulator/EccModule.cpp
simulator/MemoryManager.cpp
simulator/Simulator.cpp
simulator/generator/RandomState.cpp
simulator/generator/SequentialState.cpp

View File

@@ -35,7 +35,6 @@
*/
#include "Cache.h"
#include "MemoryManager.h"
#include <cstring>
@@ -55,7 +54,7 @@ Cache::Cache(const sc_module_name& name,
bool storageEnabled,
sc_core::sc_time cycleTime,
std::size_t hitCycles,
MemoryManager& memoryManager) :
DRAMSys::MemoryManager& memoryManager) :
sc_module(name),
payloadEventQueue(this, &Cache::peqCallback),
storageEnabled(storageEnabled),
@@ -432,17 +431,17 @@ Cache::CacheLine* Cache::evictLine(Cache::index_t index)
if (oldestLine.valid && oldestLine.dirty)
{
auto& wbTrans = memoryManager.allocate(lineSize);
wbTrans.acquire();
wbTrans.set_address(encodeAddress(index, oldestLine.tag));
wbTrans.set_write();
wbTrans.set_data_length(lineSize);
wbTrans.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
auto* wbTrans = memoryManager.allocate(lineSize);
wbTrans->acquire();
wbTrans->set_address(encodeAddress(index, oldestLine.tag));
wbTrans->set_write();
wbTrans->set_data_length(lineSize);
wbTrans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
if (storageEnabled)
std::copy(oldestLine.dataPtr, oldestLine.dataPtr + lineSize, wbTrans.get_data_ptr());
std::copy(oldestLine.dataPtr, oldestLine.dataPtr + lineSize, wbTrans->get_data_ptr());
writeBuffer.emplace_back(index, oldestLine.tag, &wbTrans);
writeBuffer.emplace_back(index, oldestLine.tag, wbTrans);
}
oldestLine.allocated = false;
@@ -500,13 +499,13 @@ void Cache::processMshrQueue()
// Prevents that the cache line will get fetched multiple times from the target
mshrIt->issued = true;
auto& fetchTrans = memoryManager.allocate(lineSize);
fetchTrans.acquire();
fetchTrans.set_read();
fetchTrans.set_data_length(lineSize);
fetchTrans.set_streaming_width(lineSize);
fetchTrans.set_address(alignedAddress);
fetchTrans.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
auto* fetchTrans = memoryManager.allocate(lineSize);
fetchTrans->acquire();
fetchTrans->set_read();
fetchTrans->set_data_length(lineSize);
fetchTrans->set_streaming_width(lineSize);
fetchTrans->set_address(alignedAddress);
fetchTrans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
tlm_phase fwPhase = BEGIN_REQ;
@@ -514,22 +513,22 @@ void Cache::processMshrQueue()
// or we cleared the backpressure from another END_REQ.
sc_time fwDelay = cycleTime;
requestInProgress = &fetchTrans;
tlm_sync_enum returnValue = iSocket->nb_transport_fw(fetchTrans, fwPhase, fwDelay);
requestInProgress = fetchTrans;
tlm_sync_enum returnValue = iSocket->nb_transport_fw(*fetchTrans, fwPhase, fwDelay);
if (returnValue == tlm::TLM_UPDATED)
{
// END_REQ or BEGIN_RESP
payloadEventQueue.notify(fetchTrans, fwPhase, fwDelay);
payloadEventQueue.notify(*fetchTrans, fwPhase, fwDelay);
}
else if (returnValue == tlm::TLM_COMPLETED)
{
clearInitiatorBackpressureAndProcessBuffers();
fillLine(fetchTrans);
fillLine(*fetchTrans);
processMshrResponse();
fetchTrans.release();
fetchTrans->release();
}
if (endRequestPending != nullptr && hasBufferSpace())

View File

@@ -36,11 +36,10 @@
#pragma once
#include "MemoryManager.h"
#include <DRAMSys/common/MemoryManager.h>
#include <cstdint>
#include <list>
#include <queue>
#include <systemc>
#include <tlm>
#include <tlm_utils/peq_with_cb_and_phase.h>
@@ -63,7 +62,7 @@ public:
bool storageEnabled,
sc_core::sc_time cycleTime,
std::size_t hitCycles,
MemoryManager& memoryManager);
DRAMSys::MemoryManager& memoryManager);
SC_HAS_PROCESS(Cache);
private:
@@ -217,5 +216,5 @@ private:
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;
DRAMSys::MemoryManager& memoryManager;
};

View File

@@ -38,12 +38,10 @@
#include "DRAMSys/common/dramExtensions.h"
#include <fstream>
using namespace sc_core;
using namespace tlm;
EccModule::EccModule(sc_module_name name, DRAMSys::AddressDecoder const& addressDecoder) :
EccModule::EccModule(sc_module_name const& name, DRAMSys::AddressDecoder const& addressDecoder) :
sc_core::sc_module(name),
payloadEventQueue(this, &EccModule::peqCallback),
memoryManager(false),
@@ -89,7 +87,7 @@ void EccModule::peqCallback(tlm::tlm_generic_payload& cbPayload, const tlm::tlm_
sc_time tDelay = SC_ZERO_TIME;
DRAMSys::DecodedAddress decodedAddress =
addressDecoder.decodeAddress(cbPayload);
addressDecoder.decodeAddress(cbPayload.get_address());
decodedAddress = calculateOffsetAddress(decodedAddress);
// Update the original address to account for the offsets
@@ -159,7 +157,7 @@ void EccModule::peqCallback(tlm::tlm_generic_payload& cbPayload, const tlm::tlm_
sc_time tDelay = SC_ZERO_TIME;
DRAMSys::DecodedAddress decodedAddress =
addressDecoder.decodeAddress(tPayload);
addressDecoder.decodeAddress(tPayload.get_address());
decodedAddress = calculateOffsetAddress(decodedAddress);
#ifdef ECC_ENABLE
@@ -252,18 +250,18 @@ tlm::tlm_generic_payload* EccModule::generateEccPayload(DRAMSys::DecodedAddress
decodedAddress.column = eccColumn;
uint64_t eccAddress = addressDecoder.encodeAddress(decodedAddress);
tlm_generic_payload& payload = memoryManager.allocate(32);
payload.acquire();
payload.set_address(eccAddress);
payload.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
payload.set_dmi_allowed(false);
payload.set_byte_enable_length(0);
payload.set_data_length(32);
payload.set_streaming_width(32);
payload.set_command(tlm::TLM_READ_COMMAND);
payload.set_extension<DRAMSys::EccExtension>(new DRAMSys::EccExtension);
tlm_generic_payload *payload = memoryManager.allocate(32);
payload->acquire();
payload->set_address(eccAddress);
payload->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
payload->set_dmi_allowed(false);
payload->set_byte_enable_length(0);
payload->set_data_length(32);
payload->set_streaming_width(32);
payload->set_command(tlm::TLM_READ_COMMAND);
payload->set_extension<DRAMSys::EccExtension>(new DRAMSys::EccExtension);
return &payload;
return payload;
}
unsigned int EccModule::alignToBlock(unsigned column)

View File

@@ -37,8 +37,7 @@
#ifndef ECCMODULE_H
#define ECCMODULE_H
#include "simulator/MemoryManager.h"
#include <DRAMSys/common/MemoryManager.h>
#include <DRAMSys/simulation/AddressDecoder.h>
#include <deque>
@@ -55,7 +54,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 const& name, DRAMSys::AddressDecoder const& addressDecoder);
SC_HAS_PROCESS(EccModule);
private:
@@ -91,7 +90,7 @@ private:
bool targetBusy = false;
const sc_core::sc_time tCK;
MemoryManager memoryManager;
DRAMSys::MemoryManager memoryManager;
DRAMSys::AddressDecoder const& addressDecoder;
std::unordered_map<Bank, EccQueue> activeEccBlocks;

View File

@@ -86,14 +86,8 @@ Simulator::instantiateInitiator(const DRAMSys::Config::Initiator& initiator)
uint64_t memorySize = dramSys->getMemSpec().getSimMemSizeInBytes();
sc_core::sc_time interfaceClk = dramSys->getMemSpec().tCK;
// To support non-power-of-two values for the burst length and width, we round the BL
// down to the smaller-or-equal power-of-two.
unsigned int burstBits = std::log2(dramSys->getMemSpec().defaultBurstLength);
unsigned int widthBits = std::log2(dramSys->getMemSpec().dataBusWidth);
unsigned int defaultDataLength = std::pow(2, burstBits) * std::pow(2, widthBits) / 8;
return std::visit(
[=](auto&& config) -> std::unique_ptr<RequestIssuer>
[this, memorySize, interfaceClk](auto&& config) -> std::unique_ptr<RequestIssuer>
{
using T = std::decay_t<decltype(config)>;
if constexpr (std::is_same_v<T, DRAMSys::Config::TrafficGenerator> ||
@@ -131,7 +125,7 @@ Simulator::instantiateInitiator(const DRAMSys::Config::Initiator& initiator)
auto player = std::make_unique<StlPlayer>(
config, tracePath.c_str(), *traceType, storageEnabled);
return std::make_unique<RequestIssuer>(config.name.c_str(),
return std::make_unique<RequestIssuer>(tracePath.stem().c_str(),
std::move(player),
memoryManager,
interfaceClk,

View File

@@ -35,9 +35,9 @@
#pragma once
#include "MemoryManager.h"
#include "simulator/request/RequestIssuer.h"
#include <DRAMSys/common/MemoryManager.h>
#include <DRAMSys/config/DRAMSysConfiguration.h>
#include <DRAMSys/simulation/DRAMSys.h>
@@ -52,7 +52,7 @@ private:
std::unique_ptr<RequestIssuer> instantiateInitiator(const DRAMSys::Config::Initiator& initiator);
bool storageEnabled;
MemoryManager memoryManager;
DRAMSys::MemoryManager memoryManager;
DRAMSys::Config::Configuration configuration;

View File

@@ -49,7 +49,7 @@ TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGeneratorStateMachine
for (auto const& state : config.states)
{
std::visit(
[=, &config](auto&& arg)
[this, memorySize, dataLength, dataAlignment, &config](auto&& arg)
{
using DRAMSys::Config::TrafficGeneratorActiveState;
using DRAMSys::Config::TrafficGeneratorIdleState;
@@ -132,7 +132,7 @@ TrafficGenerator::TrafficGenerator(DRAMSys::Config::TrafficGenerator const& conf
Request TrafficGenerator::nextRequest()
{
if (currentState == STOP_STATE)
return Request{Request::Command::Stop};
return Request{Request::Command::Stop, 0, 0, {}};
Request request = producers[currentState]->nextRequest();
requestsInState++;

View File

@@ -46,7 +46,7 @@ RowHammer::RowHammer(DRAMSys::Config::RowHammer const& config) :
Request RowHammer::nextRequest()
{
if (generatedRequests >= numberOfRequests)
return Request{Request::Command::Stop};
return Request{Request::Command::Stop, 0, 0, {}};
generatedRequests++;

View File

@@ -108,7 +108,7 @@ Request StlPlayer::nextRequest()
if (!currentLineContent.has_value())
{
// The file is read in completely. Nothing more to do.
return Request{Request::Command::Stop};
return Request{Request::Command::Stop, 0, 0, {}};
}
auto command = currentLineContent->command == LineContent::Command::Read

View File

@@ -37,7 +37,7 @@
RequestIssuer::RequestIssuer(sc_core::sc_module_name const& name,
std::unique_ptr<RequestProducer> producer,
MemoryManager& memoryManager,
DRAMSys::MemoryManager& memoryManager,
sc_core::sc_time interfaceClk,
std::optional<unsigned int> maxPendingReadRequests,
std::optional<unsigned int> maxPendingWriteRequests,
@@ -79,23 +79,23 @@ void RequestIssuer::sendNextRequest()
wait(beginResp);
}
tlm::tlm_generic_payload& payload = memoryManager.allocate(request.length);
payload.acquire();
payload.set_address(request.address);
payload.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
payload.set_dmi_allowed(false);
payload.set_byte_enable_length(0);
payload.set_data_length(request.length);
payload.set_streaming_width(request.length);
payload.set_command(request.command == Request::Command::Read ? tlm::TLM_READ_COMMAND
tlm::tlm_generic_payload* payload = memoryManager.allocate(request.length);
payload->acquire();
payload->set_address(request.address);
payload->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
payload->set_dmi_allowed(false);
payload->set_byte_enable_length(0);
payload->set_data_length(request.length);
payload->set_streaming_width(request.length);
payload->set_command(request.command == Request::Command::Read ? tlm::TLM_READ_COMMAND
: tlm::TLM_WRITE_COMMAND);
std::copy(request.data.cbegin(), request.data.cend(), payload.get_data_ptr());
std::copy(request.data.cbegin(), request.data.cend(), payload->get_data_ptr());
tlm::tlm_phase phase = tlm::BEGIN_REQ;
sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
iSocket->nb_transport_fw(payload, phase, delay);
iSocket->nb_transport_fw(*payload, phase, delay);
requestInProgress = true;
if (request.command == Request::Command::Read)

View File

@@ -35,9 +35,9 @@
#pragma once
#include "Request.h"
#include "RequestProducer.h"
#include "simulator/MemoryManager.h"
#include <DRAMSys/common/MemoryManager.h>
#include <memory>
#include <systemc>
@@ -54,7 +54,7 @@ public:
RequestIssuer(sc_core::sc_module_name const& name,
std::unique_ptr<RequestProducer> producer,
MemoryManager& memoryManager,
DRAMSys::MemoryManager& memoryManager,
sc_core::sc_time interfaceClk,
std::optional<unsigned int> maxPendingReadRequests,
std::optional<unsigned int> maxPendingWriteRequests,
@@ -85,7 +85,7 @@ private:
std::unique_ptr<RequestProducer> producer;
tlm_utils::peq_with_cb_and_phase<RequestIssuer> payloadEventQueue;
MemoryManager& memoryManager;
DRAMSys::MemoryManager& memoryManager;
sc_core::sc_time interfaceClk;

View File

@@ -43,6 +43,7 @@
#include <QFileInfo>
#include <QSet>
#include <QString>
#include <csignal>
#include <filesystem>
#include <iostream>
#include <pybind11/embed.h>
@@ -51,6 +52,9 @@ int main(int argc, char* argv[])
{
QApplication a(argc, argv);
// Make CTRL-C work again
std::signal(SIGINT, [](int) { QApplication::quit(); });
QIcon icon(QStringLiteral(":/icon"));
QApplication::setWindowIcon(icon);
QApplication::setApplicationName(QStringLiteral("TraceAnalyzer"));

View File

@@ -46,6 +46,8 @@
#include <iostream>
#include <optional>
// NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers)
using namespace DRAMSys::Config;
class ConfigurationTest : public ::testing::Test
@@ -369,8 +371,8 @@ ConfigurationTest::createTraceGeneratorMultipleStates()
state1.maxAddress = 2048;
state1.id = 1;
gen.states.push_back(state0);
gen.states.push_back(state1);
gen.states.emplace_back(state0);
gen.states.emplace_back(state1);
DRAMSys::Config::TrafficGeneratorStateTransition transistion0{0, 1, 1.0};
@@ -787,3 +789,5 @@ TEST_F(ConfigurationTest, TraceSetup)
EXPECT_EQ(tracesetup_test, tracesetup_reference);
}
// NOLINTEND(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers)

View File

@@ -62,9 +62,7 @@ protected:
TEST_F(AddressDecoderFixture, Decoding)
{
uint64_t address = 0x3A59'1474;
tlm::tlm_generic_payload trans;
trans.set_address(address);
auto decodedAddress = addressDecoder.decodeAddress(trans);
auto decodedAddress = addressDecoder.decodeAddress(address);
unsigned int channel = decodedAddress.channel;
unsigned int rank = decodedAddress.rank;
@@ -95,10 +93,9 @@ TEST_F(AddressDecoderFixture, DecodingNP2Failure)
addressDecoder.plausibilityCheck(*memSpec);
uint64_t address = 0x3A59'1478;
tlm::tlm_generic_payload trans;
trans.set_address(address);
addressDecoder.decodeAddress(trans);
EXPECT_EQ(trans.get_response_status(), tlm::TLM_ADDRESS_ERROR_RESPONSE);
std::ignore = addressDecoder.decodeAddress(address);
// EXPECT_EQ(trans.get_response_status(), tlm::TLM_ADDRESS_ERROR_RESPONSE);
}
TEST_F(AddressDecoderFixture, DecodingNP2Success)
@@ -115,10 +112,7 @@ TEST_F(AddressDecoderFixture, DecodingNP2Success)
addressDecoder.plausibilityCheck(*memSpec);
uint64_t address = 0x3A59'1477;
tlm::tlm_generic_payload trans;
trans.set_address(address);
trans.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
auto decodedAddress = addressDecoder.decodeAddress(trans);
auto decodedAddress = addressDecoder.decodeAddress(address);
unsigned int channel = decodedAddress.channel;
unsigned int rank = decodedAddress.rank;
@@ -133,7 +127,7 @@ TEST_F(AddressDecoderFixture, DecodingNP2Success)
EXPECT_EQ(bank, 4);
EXPECT_EQ(row, 7468);
EXPECT_EQ(column, 558);
EXPECT_EQ(trans.get_response_status(), tlm::TLM_INCOMPLETE_RESPONSE);
// EXPECT_EQ(trans.get_response_status(), tlm::TLM_INCOMPLETE_RESPONSE);
}
TEST_F(AddressDecoderFixture, Encoding)
@@ -160,11 +154,9 @@ TEST_F(AddressDecoderFixture, DeEncoding)
std::uint64_t(0x2FFA'1230),
std::uint64_t(0x0001'FFF0)};
tlm::tlm_generic_payload trans;
for (auto address : testAddresses)
{
trans.set_address(address);
DRAMSys::DecodedAddress decodedAddress = addressDecoder.decodeAddress(trans);
DRAMSys::DecodedAddress decodedAddress = addressDecoder.decodeAddress(address);
uint64_t encodedAddress = addressDecoder.encodeAddress(decodedAddress);
EXPECT_EQ(encodedAddress, address);

View File

@@ -43,7 +43,7 @@
#include <tlm>
#include <utility>
ListInitiator::ListInitiator(const sc_core::sc_module_name& name, MemoryManager& memoryManager) :
ListInitiator::ListInitiator(const sc_core::sc_module_name& name, DRAMSys::MemoryManager& memoryManager) :
sc_core::sc_module(name),
iSocket("iSocket"),
peq(this, &ListInitiator::peqCallback),
@@ -64,30 +64,30 @@ void ListInitiator::process()
? tlm::TLM_WRITE_COMMAND
: tlm::TLM_READ_COMMAND;
auto& trans = memoryManager.allocate(testTransactionData.dataLength);
trans.acquire();
auto* trans = memoryManager.allocate(testTransactionData.dataLength);
trans->acquire();
TestExtension* ext = new TestExtension(testTransactionData);
trans.set_auto_extension(ext);
trans->set_auto_extension(ext);
trans.set_command(command);
trans.set_address(testTransactionData.address);
trans.set_data_length(testTransactionData.dataLength);
trans.set_streaming_width(testTransactionData.dataLength);
trans.set_byte_enable_ptr(nullptr);
trans.set_dmi_allowed(false);
trans.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
trans->set_command(command);
trans->set_address(testTransactionData.address);
trans->set_data_length(testTransactionData.dataLength);
trans->set_streaming_width(testTransactionData.dataLength);
trans->set_byte_enable_ptr(nullptr);
trans->set_dmi_allowed(false);
trans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
if (trans.is_write())
if (trans->is_write())
std::memcpy(
trans.get_data_ptr(), &testTransactionData.data, testTransactionData.dataLength);
trans->get_data_ptr(), &testTransactionData.data, testTransactionData.dataLength);
if (requestInProgress != nullptr)
{
wait(endRequest);
}
requestInProgress = &trans;
requestInProgress = trans;
tlm::tlm_phase phase = tlm::BEGIN_REQ;
sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
@@ -99,17 +99,17 @@ void ListInitiator::process()
<< "0x" << std::setfill('0') << std::setw(8) << std::hex
<< testTransactionData.data << "(nb_transport) \033[0m" << std::endl;
tlm::tlm_sync_enum status = iSocket->nb_transport_fw(trans, phase, delay);
tlm::tlm_sync_enum status = iSocket->nb_transport_fw(*trans, phase, delay);
if (status == tlm::TLM_UPDATED)
{
peq.notify(trans, phase, delay);
peq.notify(*trans, phase, delay);
}
else if (status == tlm::TLM_COMPLETED)
{
requestInProgress = nullptr;
checkTransaction(trans);
trans.release();
checkTransaction(*trans);
trans->release();
}
}
}

View File

@@ -33,7 +33,7 @@
* Derek Christ
*/
#include "simulator/MemoryManager.h"
#include <DRAMSys/common/MemoryManager.h>
#include <tlm_utils/peq_with_cb_and_phase.h>
#include <tlm_utils/simple_initiator_socket.h>
@@ -44,7 +44,7 @@ public:
tlm_utils::simple_initiator_socket<ListInitiator> iSocket;
SC_HAS_PROCESS(ListInitiator);
ListInitiator(const sc_core::sc_module_name& name, MemoryManager& memoryManager);
ListInitiator(const sc_core::sc_module_name& name, DRAMSys::MemoryManager& memoryManager);
struct TestTransactionData
{
@@ -102,5 +102,5 @@ private:
sc_core::sc_event endRequest;
tlm_utils::peq_with_cb_and_phase<ListInitiator> peq;
tlm::tlm_generic_payload* requestInProgress = nullptr;
MemoryManager& memoryManager;
DRAMSys::MemoryManager& memoryManager;
};

View File

@@ -37,7 +37,7 @@
#include "TargetMemory.h"
#include <simulator/Cache.h>
#include <simulator/MemoryManager.h>
#include <DRAMSys/common/MemoryManager.h>
#include <gtest/gtest.h>
@@ -72,7 +72,7 @@ protected:
cache.iSocket.bind(target.tSocket);
}
MemoryManager memoryManager;
DRAMSys::MemoryManager memoryManager;
ListInitiator initiator;
TargetMemory target;
Cache cache;