From 3d7c3ca4733a6accc1d9a68658c6bf9db2bed6fb Mon Sep 17 00:00:00 2001 From: Zimmerma Date: Fri, 26 Sep 2025 09:41:26 +0200 Subject: [PATCH] refactor(am): improve checking and reporting --- .../DRAMSys/simulation/AddressDecoder.cpp | 65 ++++++++++++------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/src/libdramsys/DRAMSys/simulation/AddressDecoder.cpp b/src/libdramsys/DRAMSys/simulation/AddressDecoder.cpp index d0506ddf..5f111be7 100644 --- a/src/libdramsys/DRAMSys/simulation/AddressDecoder.cpp +++ b/src/libdramsys/DRAMSys/simulation/AddressDecoder.cpp @@ -198,34 +198,55 @@ void AddressDecoder::checkMemorySize(const MemSpec& memSpec) { (memSpec.getSimMemSizeInBytes() < upperBoundAddress + 1 && !np2Flag); if (isMemorySizeMismatch) { - SC_REPORT_FATAL("AddressDecoder", "The mapped bits do not match the memory size"); + std::ostringstream o; + o << "The mapped bits do not match the memory size field (MemSpec size: " + << memSpec.getSimMemSizeInBytes() << ", mapping=" << upperBoundAddress + 1 << ")"; + SC_REPORT_FATAL("AddressDecoder", o.str().c_str()); } } void AddressDecoder::checkMemSpecCompatibility(const MemSpec& memSpec) { - 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)); + const unsigned channels = std::lround(std::pow(2, channelBits.length)); + const unsigned ranks = std::lround(std::pow(2, rankBits.length)); + const unsigned rows = std::lround(std::pow(2, rowBits.length)); + const unsigned columns = std::lround(std::pow(2, columnBits.length)); + const unsigned pseudochannels = std::lround(std::pow(2, pseudochannelBits.length)); - unsigned absoluteBankGroups = bankgroupsPerRank * (ranks * pseudochannels); - unsigned absoluteBanks = banksPerGroup * absoluteBankGroups; + const unsigned absoluteBankGroups = bankgroupsPerRank * (ranks * pseudochannels); + const unsigned absoluteBanks = banksPerGroup * absoluteBankGroups; + const unsigned effectiveRanksPerChannel = static_cast(ranks) * static_cast(pseudochannels); - // Depending on the NP2 flag we must adapt the strictness of this check - if (np2Flag) { - if (memSpec.numberOfChannels > channels || memSpec.ranksPerChannel > (ranks * pseudochannels) || - memSpec.bankGroupsPerChannel > absoluteBankGroups || - memSpec.banksPerChannel > absoluteBanks || memSpec.rowsPerBank > rows || - memSpec.columnsPerRow > columns) - SC_REPORT_FATAL("AddressDecoder", "Memspec and address mapping do not match"); - } - else { - if (memSpec.numberOfChannels != channels || memSpec.ranksPerChannel != (ranks * pseudochannels) || - memSpec.bankGroupsPerChannel != absoluteBankGroups || - memSpec.banksPerChannel != absoluteBanks || memSpec.rowsPerBank != rows || - memSpec.columnsPerRow != columns) - SC_REPORT_FATAL("AddressDecoder", "Memspec and address mapping do not match"); + // Depending on the NP2 flag we might need to adapt the strictness of the checks + auto cmp = np2Flag + ? std::function([](uint64_t a, uint64_t b){ return a <= b; }) + : std::function([](uint64_t a, uint64_t b){ return a == b; }); + + // Check all and collect the errors + std::vector errors; + const char* rel = np2Flag ? "<=" : "=="; + auto check = [&](const char* field, uint64_t mem, uint64_t map) { + if (!cmp(mem, map)) { + std::ostringstream o; + o << field << ": memSpec=" << mem << ", mapping=" << map + << " (required: memSpec " << rel << " mapping)"; + errors.push_back(o.str()); + } + }; + + check("numberOfChannels", memSpec.numberOfChannels, channels); + check("ranksPerChannel", memSpec.ranksPerChannel, effectiveRanksPerChannel); + check("bankGroupsPerChannel", memSpec.bankGroupsPerChannel, absoluteBankGroups); + check("banksPerChannel", memSpec.banksPerChannel, absoluteBanks); + check("rowsPerBank", memSpec.rowsPerBank, rows); + check("columnsPerRow", memSpec.columnsPerRow, columns); + + // Handle collected errors + if (!errors.empty()) { + std::ostringstream all; + all << "Unexpected deviations between MemSpec and Address Mapping:\n"; + for (auto& e : errors) all << " - " << e << '\n'; + std::string msg = all.str(); + SC_REPORT_FATAL("AddressDecoder", msg.c_str()); } }