From 22c79fa3df8e1a6be502d6bfb031f8f6af9e9790 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Mon, 6 Apr 2020 22:31:32 +0200 Subject: [PATCH 1/9] Extended congen address decoder to channels, ranks and bank groups. --- DRAMSys/library/src/common/AddressDecoder.cpp | 10 +- DRAMSys/library/src/common/AddressDecoder.h | 30 +- .../src/common/CongenAddressDecoder.cpp | 322 ++++++++++-------- .../library/src/common/CongenAddressDecoder.h | 57 ++-- .../library/src/common/XmlAddressDecoder.cpp | 36 +- .../library/src/common/XmlAddressDecoder.h | 14 +- .../library/src/simulation/TracePlayer.cpp | 4 +- DRAMSys/library/src/simulation/TracePlayer.h | 2 +- 8 files changed, 261 insertions(+), 214 deletions(-) diff --git a/DRAMSys/library/src/common/AddressDecoder.cpp b/DRAMSys/library/src/common/AddressDecoder.cpp index 81ea1252..7810c8d0 100644 --- a/DRAMSys/library/src/common/AddressDecoder.cpp +++ b/DRAMSys/library/src/common/AddressDecoder.cpp @@ -48,15 +48,13 @@ AddressDecoder &AddressDecoder::getInstance() void AddressDecoder::createInstance(Type t) { assert(m_pInstance == nullptr); - switch (t) { + switch (t) + { case Type::XML: - m_pInstance = new XmlAddressDecoder; + m_pInstance = new XmlAddressDecoder(); break; case Type::CONGEN: - m_pInstance = new CongenAddressDecoder; - break; - default: - throw std::logic_error("Instance type not supported."); + m_pInstance = new CongenAddressDecoder(); break; } } diff --git a/DRAMSys/library/src/common/AddressDecoder.h b/DRAMSys/library/src/common/AddressDecoder.h index b49f6e81..a750982b 100644 --- a/DRAMSys/library/src/common/AddressDecoder.h +++ b/DRAMSys/library/src/common/AddressDecoder.h @@ -42,24 +42,25 @@ #include #include -struct DecodedAddress { - DecodedAddress() : channel(0), +struct DecodedAddress +{ + DecodedAddress() : + channel(0), rank(0), bankgroup(0), row(0), bank(0), column(0), bytes(0) - { - } + {} - unsigned int channel; - unsigned int rank; - unsigned int bankgroup; - unsigned int row; - unsigned int bank; - unsigned int column; - unsigned int bytes; + unsigned channel; + unsigned rank; + unsigned bankgroup; + unsigned row; + unsigned bank; + unsigned column; + unsigned bytes; }; class AddressDecoder @@ -95,6 +96,13 @@ public: unsigned column = 1; unsigned bytes = 1; } amount; + +protected: + unsigned banksPerGroup; + unsigned banksPerRank; + unsigned bankgroupsPerRank; + + uint64_t maximumAddress; }; #endif // ADDRESSDECODER_H diff --git a/DRAMSys/library/src/common/CongenAddressDecoder.cpp b/DRAMSys/library/src/common/CongenAddressDecoder.cpp index 46613007..b09ea149 100644 --- a/DRAMSys/library/src/common/CongenAddressDecoder.cpp +++ b/DRAMSys/library/src/common/CongenAddressDecoder.cpp @@ -33,21 +33,15 @@ * Johannes Feldmann */ -#include "CongenAddressDecoder.h" -#include "utils.h" - #include #include +#include -using std::ifstream; -using std::cout; -using std::endl; -using std::set; -using std::pair; -using std::map; -using std::deque; +#include "CongenAddressDecoder.h" +#include "utils.h" +#include "../configuration/Configuration.h" -tinyxml2::XMLElement *CongenAddressDecoder::GetXMLNode(tinyxml2::XMLElement +tinyxml2::XMLElement *CongenAddressDecoder::getXMLNode(tinyxml2::XMLElement *pRoot, std::string strName) { tinyxml2::XMLElement *pNode = pRoot->FirstChildElement(strName.c_str()); @@ -58,7 +52,7 @@ tinyxml2::XMLElement *CongenAddressDecoder::GetXMLNode(tinyxml2::XMLElement return pNode; } -unsigned int CongenAddressDecoder::GetUnsignedTextFromXMLNode( +unsigned int CongenAddressDecoder::getUnsignedTextFromXMLNode( tinyxml2::XMLElement *pRoot) { std::string str = pRoot->GetText(); @@ -72,7 +66,7 @@ unsigned int CongenAddressDecoder::GetUnsignedTextFromXMLNode( return atol(str.c_str()); } -unsigned int CongenAddressDecoder::GetUnsignedAttrFromXMLNode( +unsigned int CongenAddressDecoder::getUnsignedAttrFromXMLNode( tinyxml2::XMLElement *pRoot, std::string strName) { std::string str = pRoot->Attribute(strName.c_str()); @@ -86,11 +80,6 @@ unsigned int CongenAddressDecoder::GetUnsignedAttrFromXMLNode( return atol(str.c_str()); } -CongenAddressDecoder::CongenAddressDecoder() -{ - -} - void CongenAddressDecoder::setConfiguration(std::string url) { tinyxml2::XMLDocument doc; @@ -98,64 +87,87 @@ void CongenAddressDecoder::setConfiguration(std::string url) tinyxml2::XMLElement *pRoot = doc.RootElement(); std::string xmlNodeName(pRoot->Name()); - if ( xmlNodeName != "CONGEN") { + if (xmlNodeName != "CONGEN") reportFatal("ConGenAddressDecorder", "Root node name differs from \"CONGEN\". File format not supported."); - } // Load basic configuration - tinyxml2::XMLElement *pNode = GetXMLNode(pRoot, "NAME"); - m_strName = pNode->GetText(); - pNode = GetXMLNode(pRoot, "COSTS"); - m_nCost = GetUnsignedTextFromXMLNode(pNode); - tinyxml2::XMLElement *pConfig = GetXMLNode(pRoot, "CONFIG"); - pNode = GetXMLNode(pConfig, "NUM_BANK_BITS"); - m_nBankBits = GetUnsignedTextFromXMLNode(pNode); - pNode = GetXMLNode(pConfig, "NUM_ROW_BITS"); - m_nRowBits = GetUnsignedTextFromXMLNode(pNode); - pNode = GetXMLNode(pConfig, "NUM_COLUMN_BITS"); - m_nColumnBits = GetUnsignedTextFromXMLNode(pNode); - pNode = GetXMLNode(pConfig, "NUM_BL_BITS"); - m_nBurstLengthBits = GetUnsignedTextFromXMLNode(pNode); - pNode = GetXMLNode(pConfig, "NUM_BYTE_BITS"); - m_nByteBits = GetUnsignedTextFromXMLNode(pNode); + tinyxml2::XMLElement *pNode = getXMLNode(pRoot, "NAME"); + strName = pNode->GetText(); + pNode = getXMLNode(pRoot, "COSTS"); + nCost = getUnsignedTextFromXMLNode(pNode); + tinyxml2::XMLElement *pConfig = getXMLNode(pRoot, "CONFIG"); + pNode = getXMLNode(pConfig, "NUM_CHANNEL_BITS"); + nChannelBits = getUnsignedTextFromXMLNode(pNode); + pNode = getXMLNode(pConfig, "NUM_RANK_BITS"); + nRankBits = getUnsignedTextFromXMLNode(pNode); + pNode = getXMLNode(pConfig, "NUM_BANKGROUP_BITS"); + nBankGroupBits = getUnsignedTextFromXMLNode(pNode); + pNode = getXMLNode(pConfig, "NUM_BANK_BITS"); + nBankBits = getUnsignedTextFromXMLNode(pNode); + pNode = getXMLNode(pConfig, "NUM_ROW_BITS"); + nRowBits = getUnsignedTextFromXMLNode(pNode); + pNode = getXMLNode(pConfig, "NUM_COLUMN_BITS"); + nColumnBits = getUnsignedTextFromXMLNode(pNode); + pNode = getXMLNode(pConfig, "NUM_BYTE_BITS"); + nByteBits = getUnsignedTextFromXMLNode(pNode); // Load address mapping unsigned id = 0; for (pNode = pRoot->FirstChildElement("SOLUTION"); pNode != nullptr; - pNode = pNode->NextSiblingElement("SOLUTION")) { - if (GetUnsignedAttrFromXMLNode(pNode, "ID") == id) { - // Correct mapping was found. - break; - } + pNode = pNode->NextSiblingElement("SOLUTION")) + { + if (getUnsignedAttrFromXMLNode(pNode, "ID") == id) + break; // Correct mapping was found. } - // If no mapping was found report error and return - if (pNode == nullptr) { - reportFatal("ConGenAddressDecoder", - "No mapping with ID " + std::to_string(id) + " was found."); - return; - } + // If no mapping was found report error + if (pNode == nullptr) + SC_REPORT_FATAL("ConGenAddressDecoder", + ("No mapping with ID " + std::to_string(id) + " was found.").c_str()); // get XOR connections // An XOR connection needs two parameters: A bank bit and a Row bit. for (tinyxml2::XMLElement *pXor = pNode->FirstChildElement("XOR"); - pXor != nullptr; pXor = pXor->NextSiblingElement("XOR")) { - m_vXor.push_back(XOR(GetUnsignedAttrFromXMLNode(pXor, "BANK"), - GetUnsignedAttrFromXMLNode(pXor, "ROW"))); + pXor != nullptr; pXor = pXor->NextSiblingElement("XOR")) + { + vXor.push_back(XOR(getUnsignedAttrFromXMLNode(pXor, "BANK"), + getUnsignedAttrFromXMLNode(pXor, "ROW"))); } - set sUsed; + unsigned counter = 0; + for (tinyxml2::XMLElement *pChannel = pNode->FirstChildElement("CHANNEL_BIT"); + pChannel != nullptr; pChannel = pChannel->NextSiblingElement("CHANNEL_BIT")) + { + unsigned nChannel = getUnsignedTextFromXMLNode(pChannel); + vChannelBits.push_back(std::pair(counter++, nChannel)); + } + + counter = 0; + for (tinyxml2::XMLElement *pRank = pNode->FirstChildElement("RANK_BIT"); + pRank != nullptr; pRank = pRank->NextSiblingElement("RANK_BIT")) + { + unsigned nRank = getUnsignedTextFromXMLNode(pRank); + vRankBits.push_back(std::pair(counter++, nRank)); + } + + counter = 0; + for (tinyxml2::XMLElement *pBankGroup = pNode->FirstChildElement("BANKGROUP_BIT"); + pBankGroup != nullptr; pBankGroup = pBankGroup->NextSiblingElement("BANKGROUP_BIT")) + { + unsigned nBankGroup = getUnsignedTextFromXMLNode(pBankGroup); + vBankGroupBits.push_back(std::pair(counter++, nBankGroup)); + } // get all bank bits // Each bank bit of the address will be stored with a counter value which assigns the bit position DecodedAddress struct. - unsigned counter = 0; + counter = 0; for (tinyxml2::XMLElement *pBank = pNode->FirstChildElement("BANK_BIT"); - pBank != nullptr; pBank = pBank->NextSiblingElement("BANK_BIT")) { - unsigned nBank = GetUnsignedTextFromXMLNode(pBank); - m_vBankBits.push_back(pair(counter++, nBank)); - sUsed.insert(nBank); + pBank != nullptr; pBank = pBank->NextSiblingElement("BANK_BIT")) + { + unsigned nBank = getUnsignedTextFromXMLNode(pBank); + vBankBits.push_back(std::pair(counter++, nBank)); } // get all row bits bits @@ -163,138 +175,172 @@ void CongenAddressDecoder::setConfiguration(std::string url) counter = 0; for (tinyxml2::XMLElement *pRow = pNode->FirstChildElement("ROW_BIT"); pRow != nullptr; pRow = pRow->NextSiblingElement("ROW_BIT")) { - unsigned nRow = GetUnsignedTextFromXMLNode(pRow); - m_vRowBits.push_back(pair(counter++, nRow)); - sUsed.insert(nRow); + unsigned nRow = getUnsignedTextFromXMLNode(pRow); + vRowBits.push_back(std::pair(counter++, nRow)); } - // Add byte bits - for (unsigned i = 0; i < m_nByteBits; i++) { - sUsed.insert(i); - } - - // Theset bits are ignored (fixed in Congen) - sUsed.insert(30); - sUsed.insert(31); - - // Create Column mapping - // These bits are not stored in the JSON file, but can be generated. All bits, which are until now not used for any other purpose are column bits. - // Each column bit of the address will be stored with a counter value which assigns the bit position DecodedAddress struct. counter = 0; - for (unsigned i = 0; i < 32; i++) { - if (sUsed.find(i) != sUsed.end()) - continue; // Already mapped + for (tinyxml2::XMLElement *pColumn = pNode->FirstChildElement("COLUMN_BIT"); + pColumn != nullptr; pColumn = pColumn->NextSiblingElement("COLUMN_BIT")) + { + unsigned nColumn = getUnsignedTextFromXMLNode(pColumn); + vColumnBits.push_back(std::pair(counter++, nColumn)); + } - m_vColumnBits.push_back(pair(counter++, i)); + counter = 0; + for (tinyxml2::XMLElement *pByte = pNode->FirstChildElement("BYTE_BIT"); + pByte != nullptr; pByte = pByte->NextSiblingElement("BYTE_BIT")) + { + unsigned nByte = getUnsignedTextFromXMLNode(pByte); + vByteBits.push_back(std::pair(counter++, nByte)); } // Fill the amount map. This is copied from xmlAddressDecoder without further investigation - amount.channel = 1; - amount.bank = pow(2.0, m_vBankBits.size()); - amount.row = pow(2.0, m_vRowBits.size()); - amount.column = pow(2.0, m_vColumnBits.size()); - amount.bytes = pow(2.0, m_nByteBits); + amount.channel = pow(2.0, vChannelBits.size()); + amount.rank = pow(2.0, vRankBits.size()); + amount.bankgroup = pow(2.0, vBankGroupBits.size()); + amount.bank = pow(2.0, vBankBits.size()); + amount.row = pow(2.0, vRowBits.size()); + amount.column = pow(2.0, vColumnBits.size()); + amount.bytes = pow(2.0, vByteBits.size()); + + banksPerGroup = amount.bank; + amount.bank = banksPerGroup * amount.bankgroup * amount.rank; + + bankgroupsPerRank = amount.bankgroup; + amount.bankgroup = bankgroupsPerRank * amount.rank; + + maximumAddress = amount.bytes * amount.column * amount.row * banksPerGroup * bankgroupsPerRank * amount.rank * amount.channel - 1; + + Configuration &config = Configuration::getInstance(); + MemSpec *memSpec = config.memSpec; + + if (config.numberOfMemChannels != amount.channel || memSpec->numberOfRanks != amount.rank + || memSpec->numberOfBankGroups != amount.bankgroup || memSpec->numberOfBanks != amount.bank + || memSpec->numberOfRows != amount.row || memSpec->numberOfColumns != amount.column + || config.numberOfDevicesOnDIMM * memSpec->bitWidth != amount.bytes * 8) + SC_REPORT_FATAL("XmlAddressDecoder", "Memspec and addressmapping do not match"); } -DecodedAddress CongenAddressDecoder::decodeAddress(uint64_t addr) +DecodedAddress CongenAddressDecoder::decodeAddress(uint64_t encAddr) { - DecodedAddress result; + if (encAddr > maximumAddress) + SC_REPORT_WARNING("CongenAddressDecoder", ("Address " + std::to_string(encAddr) + " out of range (maximum address is " + std::to_string(maximumAddress) + ")").c_str()); // Apply XOR // For each used xor: // Get the bank bit and row bit. Apply a bitwise xor operator and save it back to the bank bit. - for (auto it = m_vXor.begin(); it != m_vXor.end(); it++) { + for (auto it = vXor.begin(); it != vXor.end(); it++) + { unsigned new_bank_bit; // Bank Row - new_bank_bit = (((addr >> it->nBank) & 1) ^ ((addr >> it->nRow) & 1)); - addr &= ~(1 << it->nBank); - addr |= new_bank_bit << it->nBank; + new_bank_bit = (((encAddr >> it->nBank) & 1) ^ ((encAddr >> it->nRow) & 1)); + encAddr &= ~(1 << it->nBank); + encAddr |= new_bank_bit << it->nBank; } - // Unsed - result.bankgroup = 0; - result.channel = 0; - result.rank = 0; + DecodedAddress decAddr; - // Pass through of the three byte bits - result.bytes = addr & 0x7; + decAddr.channel = 0; + for (auto it = vChannelBits.begin(); it != vChannelBits.end(); it++) + decAddr.channel |= ((encAddr >> it->second) & 1) << it->first; + + decAddr.rank = 0; + for (auto it = vRankBits.begin(); it != vRankBits.end(); it++) + decAddr.rank |= ((encAddr >> it->second) & 1) << it->first; + + decAddr.bankgroup = 0; + for (auto it = vBankGroupBits.begin(); it != vBankGroupBits.end(); it++) + decAddr.bankgroup |= ((encAddr >> it->second) & 1) << it->first; // Bank // it->second: position of the target bit in the address // it->first: target position of the bit in the variable // For each bank bit: // shift address bit to position 0. Clear all other bits. shift it the right bank bit. Add it to the set of bank bits. - result.bank = 0; - for (auto it = m_vBankBits.begin(); it != m_vBankBits.end(); it++) { - result.bank |= ((addr >> it->second) & 1) << it->first; - } + decAddr.bank = 0; + for (auto it = vBankBits.begin(); it != vBankBits.end(); it++) + decAddr.bank |= ((encAddr >> it->second) & 1) << it->first; // Row // it->second: position of the target bit in the address // it->first: target position of the bit in the variable // For each row bit: // shift address bit to position 0. Clear all other bits. shift it the right row bit. Add it to the set of row bits. - result.row = 0; - for (auto it = m_vRowBits.begin(); it != m_vRowBits.end(); it++) { - result.row |= ((addr >> it->second) & 1) << it->first; - } + decAddr.row = 0; + for (auto it = vRowBits.begin(); it != vRowBits.end(); it++) + decAddr.row |= ((encAddr >> it->second) & 1) << it->first; // Column // it->second: position of the target bit in the address // it->first: target position of the bit in the variable // For each column bit: // shift address bit to position 0. Clear all other bits. shift it the right column bit. Add it to the set of column bits. - result.column = 0; - for (auto it = m_vColumnBits.begin(); it != m_vColumnBits.end(); it++) { - result.column |= ((addr >> it->second) & 1) << it->first; - } + decAddr.column = 0; + for (auto it = vColumnBits.begin(); it != vColumnBits.end(); it++) + decAddr.column |= ((encAddr >> it->second) & 1) << it->first; - return result; + decAddr.bankgroup = decAddr.bankgroup + decAddr.rank * bankgroupsPerRank; + decAddr.bank = decAddr.bank + decAddr.bankgroup * banksPerGroup; + + return decAddr; } -uint64_t CongenAddressDecoder::encodeAddress(DecodedAddress n) +uint64_t CongenAddressDecoder::encodeAddress(DecodedAddress decAddr) { - uint64_t address = 0; + decAddr.bankgroup = decAddr.bankgroup % bankgroupsPerRank; + decAddr.bank = decAddr.bank % banksPerGroup; + + uint64_t encAddr = 0; + + for (auto it = vChannelBits.begin(); it != vChannelBits.end(); it++) + encAddr |= ((decAddr.channel >> it->first) & 1) << it->second; + + for (auto it = vRankBits.begin(); it != vRankBits.end(); it++) + encAddr |= ((decAddr.rank >> it->first) & 1) << it->second; + + for (auto it = vBankGroupBits.begin(); it != vBankGroupBits.end(); it++) + encAddr |= ((decAddr.bankgroup >> it->first) & 1) << it->second; // Bank // it->first: position of the target bit in the DecodedAddress struct field // it->second: target position of the bit in the address // For each bank bit: // shift bank bit to position 0. Clear all other bits. shift it the right address bit. Add it to the set of address bits. - for (auto it = m_vBankBits.begin(); it != m_vBankBits.end(); it++) { - address |= ((n.bank >> it->first) & 1) << it->second; - } + for (auto it = vBankBits.begin(); it != vBankBits.end(); it++) + encAddr |= ((decAddr.bank >> it->first) & 1) << it->second; + // Row // it->first: position of the target bit in the DecodedAddress struct field // it->second: target position of the bit in the address // For each row bit: // shift row bit to position 0. Clear all other bits. shift it the right address bit. Add it to the set of address bits. - for (auto it = m_vRowBits.begin(); it != m_vRowBits.end(); it++) { - address |= ((n.row >> it->first) & 1) << it->second; - } + for (auto it = vRowBits.begin(); it != vRowBits.end(); it++) + encAddr |= ((decAddr.row >> it->first) & 1) << it->second; + // Column // it->first: position of the target bit in the DecodedAddress struct field // it->second: target position of the bit in the address // For each column bit: // shift column bit to position 0. Clear all other bits. shift it the right address bit. Add it to the set of address bits. - for (auto it = m_vColumnBits.begin(); it != m_vColumnBits.end(); it++) { - address |= ((n.column >> it->first) & 1) << it->second; - } + for (auto it = vColumnBits.begin(); it != vColumnBits.end(); it++) + encAddr |= ((decAddr.column >> it->first) & 1) << it->second; - // Add the unchanged byte bits - address |= n.bytes; + for (auto it = vByteBits.begin(); it != vByteBits.end(); it++) + encAddr |= ((decAddr.bytes >> it->first) & 1) << it->second; // Apply XOR // For each used xor: // Get the bank bit and row bit. Apply a bitwise xor operator and save it back to the bank bit. - for (auto it = m_vXor.begin(); it != m_vXor.end(); it++) { + for (auto it = vXor.begin(); it != vXor.end(); it++) + { unsigned new_bank_bit; - new_bank_bit = (((address >> it->nBank) & 1) ^ ((address >> it->nRow) & 1)); - address &= ~(1 << it->nBank); - address |= new_bank_bit << it->nBank; + new_bank_bit = (((encAddr >> it->nBank) & 1) ^ ((encAddr >> it->nRow) & 1)); + encAddr &= ~(1 << it->nBank); + encAddr |= new_bank_bit << it->nBank; } - return address; + return encAddr; } bool CongenAddressDecoder::testConfigFile(std::string url) @@ -311,31 +357,31 @@ bool CongenAddressDecoder::testConfigFile(std::string url) void CongenAddressDecoder::print() { - map> output; + std::map> output; - for (auto it = m_vBankBits.begin(); it != m_vBankBits.end(); it++) { - output[it->second] = pair(it->first, 'B'); + for (auto it = vBankBits.begin(); it != vBankBits.end(); it++) { + output[it->second] = std::pair(it->first, 'B'); } - for (auto it = m_vRowBits.begin(); it != m_vRowBits.end(); it++) { - output[it->second] = pair(it->first, 'R'); + for (auto it = vRowBits.begin(); it != vRowBits.end(); it++) { + output[it->second] = std::pair(it->first, 'R'); } - for (auto it = m_vColumnBits.begin(); it != m_vColumnBits.end(); it++) { - output[it->second] = pair(it->first, 'C'); + for (auto it = vColumnBits.begin(); it != vColumnBits.end(); it++) { + output[it->second] = std::pair(it->first, 'C'); } // add byte bits - output[0] = pair(0, 'b'); - output[1] = pair(1, 'b'); - output[2] = pair(2, 'b'); + output[0] = std::pair(0, 'b'); + output[1] = std::pair(1, 'b'); + output[2] = std::pair(2, 'b'); - cout << "Used addressmapping:" << endl; - cout << headline << endl; + std::cout << "Used addressmapping:" << std::endl; + std::cout << headline << std::endl; for (unsigned i = 0; i < 32; i++) { - cout << " " << i << " "; + std::cout << " " << i << " "; } - cout << endl; + std::cout << std::endl; for (unsigned i = 0; i < 32; i++) { - cout << " " << output[i].second << "(" << output[i].first << ") "; + std::cout << " " << output[i].second << "(" << output[i].first << ") "; } - cout << endl; + std::cout << std::endl; } diff --git a/DRAMSys/library/src/common/CongenAddressDecoder.h b/DRAMSys/library/src/common/CongenAddressDecoder.h index 85829d9d..a4a74cae 100644 --- a/DRAMSys/library/src/common/CongenAddressDecoder.h +++ b/DRAMSys/library/src/common/CongenAddressDecoder.h @@ -50,51 +50,50 @@ class CongenAddressDecoder : private AddressDecoder friend class AddressDecoder; public: - struct XOR { + struct XOR + { unsigned nBank; unsigned nRow; - XOR() {}; - XOR(unsigned bank, unsigned row) : nBank(bank), nRow(row) {}; + XOR() {} + XOR(unsigned bank, unsigned row) : nBank(bank), nRow(row) {} }; // Member variables private: - std::string m_strName; // The Name of this mapping + std::string strName; // The Name of this mapping - unsigned int - m_nCost; // Number of row misses produced by this mapping + unsigned nCost; // Number of row misses produced by this mapping - unsigned int - m_nBankBits; // Number of Bank bits used by this mapping - unsigned int - m_nRowBits; // Number of Row bits used by this mapping - unsigned int - m_nColumnBits; // Number of Column bits used by this mapping - unsigned int - m_nBurstLengthBits; // Number of Burst length bits used by this mapping - unsigned int - m_nByteBits; // Number of Byte bits used by this mapping + unsigned nChannelBits; + unsigned nRankBits; + unsigned nBankGroupBits; + unsigned nBankBits; // Number of Bank bits used by this mapping + unsigned nRowBits; // Number of Row bits used by this mapping + unsigned nColumnBits; // Number of Column bits used by this mapping + unsigned nByteBits; // Number of Byte bits used by this mapping - std::vector - m_vXor; // This container stores for each used xor gate a pair which consists of "First/Number of an address bit which corresponds to a bank" and "Second/Number of an address bit which corresponds to a row" - std::vector> - m_vBankBits; // This container stores for each bank bit a pair which consists of "First/Number of the bank bit" and "Second/Number of the address bit" - std::vector> - m_vRowBits; // This container stores for each row bit a pair which consists of "First/Number of the row bit" and "Second/Number of the address bit" - std::vector> - m_vColumnBits; // This container stores for each column bit a pair which consists of "First/Number of the column bit" and "Second/Number of the address bit" + // This container stores for each used xor gate a pair which consists of "First/Number of an address bit which corresponds to a bank" and "Second/Number of an address bit which corresponds to a row" + std::vector vXor; + std::vector> vChannelBits; + std::vector> vRankBits; + std::vector> vBankGroupBits; + // This container stores for each bank bit a pair which consists of "First/Number of the bank bit" and "Second/Number of the address bit" + std::vector> vBankBits; + // This container stores for each row bit a pair which consists of "First/Number of the row bit" and "Second/Number of the address bit" + std::vector> vRowBits; + // This container stores for each column bit a pair which consists of "First/Number of the column bit" and "Second/Number of the address bit" + std::vector> vColumnBits; + std::vector> vByteBits; //Methods private: - tinyxml2::XMLElement *GetXMLNode(tinyxml2::XMLElement *pRoot, + tinyxml2::XMLElement *getXMLNode(tinyxml2::XMLElement *pRoot, std::string strName); - unsigned int GetUnsignedTextFromXMLNode(tinyxml2::XMLElement *pRoot); - unsigned int GetUnsignedAttrFromXMLNode(tinyxml2::XMLElement *pRoot, + unsigned int getUnsignedTextFromXMLNode(tinyxml2::XMLElement *pRoot); + unsigned int getUnsignedAttrFromXMLNode(tinyxml2::XMLElement *pRoot, std::string strName); public: - CongenAddressDecoder(); - virtual void setConfiguration(std::string url); virtual DecodedAddress decodeAddress(uint64_t addr); diff --git a/DRAMSys/library/src/common/XmlAddressDecoder.cpp b/DRAMSys/library/src/common/XmlAddressDecoder.cpp index 71a54039..168f8899 100644 --- a/DRAMSys/library/src/common/XmlAddressDecoder.cpp +++ b/DRAMSys/library/src/common/XmlAddressDecoder.cpp @@ -132,33 +132,33 @@ void XmlAddressDecoder::setConfiguration(std::string addressConfigURI) } -DecodedAddress XmlAddressDecoder::decodeAddress(uint64_t addr) +DecodedAddress XmlAddressDecoder::decodeAddress(uint64_t encAddr) { - if (addr > maximumAddress) - SC_REPORT_WARNING("XmlAddressDecoder", ("Address " + std::to_string(addr) + " out of range (maximum address is " + std::to_string(maximumAddress) + ")").c_str()); + if (encAddr > maximumAddress) + SC_REPORT_WARNING("XmlAddressDecoder", ("Address " + std::to_string(encAddr) + " out of range (maximum address is " + std::to_string(maximumAddress) + ")").c_str()); DecodedAddress result; - result.channel = (addr & masks.channel) >> shifts.channel; - result.rank = (addr & masks.rank) >> shifts.rank; - result.bankgroup = ((addr & masks.bankgroup) >> shifts.bankgroup) + result.channel = (encAddr & masks.channel) >> shifts.channel; + result.rank = (encAddr & masks.rank) >> shifts.rank; + result.bankgroup = ((encAddr & masks.bankgroup) >> shifts.bankgroup) + result.rank * bankgroupsPerRank; - result.bank = ((addr & masks.bank) >> shifts.bank) + result.bank = ((encAddr & masks.bank) >> shifts.bank) + result.bankgroup * banksPerGroup; - result.row = (addr & masks.row) >> shifts.row; - result.column = (addr & masks.column) >> shifts.column; - result.bytes = (addr & masks.bytes) >> shifts.bytes; + result.row = (encAddr & masks.row) >> shifts.row; + result.column = (encAddr & masks.column) >> shifts.column; + result.bytes = (encAddr & masks.bytes) >> shifts.bytes; return result; } -uint64_t XmlAddressDecoder::encodeAddress(DecodedAddress n) +uint64_t XmlAddressDecoder::encodeAddress(DecodedAddress decAddr) { - return (n.channel << shifts.channel) | - (n.rank << shifts.rank) | - ((n.bankgroup % bankgroupsPerRank) << shifts.bankgroup) | - ((n.bank % banksPerGroup) << shifts.bank) | - (n.row << shifts.row) | - (n.column << shifts.column) | - (n.bytes << shifts.bytes); + return (decAddr.channel << shifts.channel) | + (decAddr.rank << shifts.rank) | + ((decAddr.bankgroup % bankgroupsPerRank) << shifts.bankgroup) | + ((decAddr.bank % banksPerGroup) << shifts.bank) | + (decAddr.row << shifts.row) | + (decAddr.column << shifts.column) | + (decAddr.bytes << shifts.bytes); } bool XmlAddressDecoder::testConfigFile(std::string url) diff --git a/DRAMSys/library/src/common/XmlAddressDecoder.h b/DRAMSys/library/src/common/XmlAddressDecoder.h index 21befb9f..a733ca05 100644 --- a/DRAMSys/library/src/common/XmlAddressDecoder.h +++ b/DRAMSys/library/src/common/XmlAddressDecoder.h @@ -51,6 +51,8 @@ class XmlAddressDecoder : private AddressDecoder friend class AddressDecoder; private: + tinyxml2::XMLElement *addressmapping; + struct Masks { uint64_t channel = 0; @@ -73,24 +75,16 @@ private: unsigned bytes = 0; } shifts; - unsigned banksPerGroup; - unsigned banksPerRank; - unsigned bankgroupsPerRank; - - tinyxml2::XMLElement *addressmapping; - uint64_t maximumAddress; - public: XmlAddressDecoder(); + virtual void setConfiguration(std::string url); + virtual DecodedAddress decodeAddress(uint64_t addr); virtual uint64_t encodeAddress(DecodedAddress n); - void setConfiguration(std::string url); - static bool testConfigFile(std::string url); -public: virtual void print(); }; diff --git a/DRAMSys/library/src/simulation/TracePlayer.cpp b/DRAMSys/library/src/simulation/TracePlayer.cpp index 025221d7..17ddf0b3 100644 --- a/DRAMSys/library/src/simulation/TracePlayer.cpp +++ b/DRAMSys/library/src/simulation/TracePlayer.cpp @@ -47,7 +47,9 @@ TracePlayer::TracePlayer(sc_module_name name, TracePlayerListener *listener) : { iSocket.register_nb_transport_bw(this, &TracePlayer::nb_transport_bw); - if (Configuration::getInstance().storeMode != "NoStorage") + if (Configuration::getInstance().storeMode == "NoStorage") + storageEnabled = false; + else storageEnabled = true; } diff --git a/DRAMSys/library/src/simulation/TracePlayer.h b/DRAMSys/library/src/simulation/TracePlayer.h index 6eabd60c..ffab944b 100644 --- a/DRAMSys/library/src/simulation/TracePlayer.h +++ b/DRAMSys/library/src/simulation/TracePlayer.h @@ -67,7 +67,7 @@ protected: void terminate(); void setNumberOfTransactions(unsigned int n); unsigned int numberOfTransactions = 0; - bool storageEnabled; + bool storageEnabled = false; private: tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase, From 36a8982d79a6632ec37003f5ca601ee69ba765d9 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Tue, 7 Apr 2020 11:09:43 +0200 Subject: [PATCH 2/9] Removed unused member variables in congen address decoder. --- .../src/common/CongenAddressDecoder.cpp | 30 +++---------------- .../library/src/common/CongenAddressDecoder.h | 13 -------- 2 files changed, 4 insertions(+), 39 deletions(-) diff --git a/DRAMSys/library/src/common/CongenAddressDecoder.cpp b/DRAMSys/library/src/common/CongenAddressDecoder.cpp index b09ea149..b7051527 100644 --- a/DRAMSys/library/src/common/CongenAddressDecoder.cpp +++ b/DRAMSys/library/src/common/CongenAddressDecoder.cpp @@ -91,41 +91,19 @@ void CongenAddressDecoder::setConfiguration(std::string url) reportFatal("ConGenAddressDecorder", "Root node name differs from \"CONGEN\". File format not supported."); - // Load basic configuration - tinyxml2::XMLElement *pNode = getXMLNode(pRoot, "NAME"); - strName = pNode->GetText(); - pNode = getXMLNode(pRoot, "COSTS"); - nCost = getUnsignedTextFromXMLNode(pNode); - tinyxml2::XMLElement *pConfig = getXMLNode(pRoot, "CONFIG"); - pNode = getXMLNode(pConfig, "NUM_CHANNEL_BITS"); - nChannelBits = getUnsignedTextFromXMLNode(pNode); - pNode = getXMLNode(pConfig, "NUM_RANK_BITS"); - nRankBits = getUnsignedTextFromXMLNode(pNode); - pNode = getXMLNode(pConfig, "NUM_BANKGROUP_BITS"); - nBankGroupBits = getUnsignedTextFromXMLNode(pNode); - pNode = getXMLNode(pConfig, "NUM_BANK_BITS"); - nBankBits = getUnsignedTextFromXMLNode(pNode); - pNode = getXMLNode(pConfig, "NUM_ROW_BITS"); - nRowBits = getUnsignedTextFromXMLNode(pNode); - pNode = getXMLNode(pConfig, "NUM_COLUMN_BITS"); - nColumnBits = getUnsignedTextFromXMLNode(pNode); - pNode = getXMLNode(pConfig, "NUM_BYTE_BITS"); - nByteBits = getUnsignedTextFromXMLNode(pNode); - // Load address mapping - unsigned id = 0; + tinyxml2::XMLElement *pNode; for (pNode = pRoot->FirstChildElement("SOLUTION"); pNode != nullptr; pNode = pNode->NextSiblingElement("SOLUTION")) { - if (getUnsignedAttrFromXMLNode(pNode, "ID") == id) + if (getUnsignedAttrFromXMLNode(pNode, "ID") == 0) break; // Correct mapping was found. } // If no mapping was found report error if (pNode == nullptr) - SC_REPORT_FATAL("ConGenAddressDecoder", - ("No mapping with ID " + std::to_string(id) + " was found.").c_str()); + SC_REPORT_FATAL("ConGenAddressDecoder", "No mapping with ID 0 was found."); // get XOR connections // An XOR connection needs two parameters: A bank bit and a Row bit. @@ -219,7 +197,7 @@ void CongenAddressDecoder::setConfiguration(std::string url) || memSpec->numberOfBankGroups != amount.bankgroup || memSpec->numberOfBanks != amount.bank || memSpec->numberOfRows != amount.row || memSpec->numberOfColumns != amount.column || config.numberOfDevicesOnDIMM * memSpec->bitWidth != amount.bytes * 8) - SC_REPORT_FATAL("XmlAddressDecoder", "Memspec and addressmapping do not match"); + SC_REPORT_FATAL("CongenAddressDecoder", "Memspec and addressmapping do not match"); } DecodedAddress CongenAddressDecoder::decodeAddress(uint64_t encAddr) diff --git a/DRAMSys/library/src/common/CongenAddressDecoder.h b/DRAMSys/library/src/common/CongenAddressDecoder.h index a4a74cae..100ae350 100644 --- a/DRAMSys/library/src/common/CongenAddressDecoder.h +++ b/DRAMSys/library/src/common/CongenAddressDecoder.h @@ -60,19 +60,6 @@ public: // Member variables private: - std::string strName; // The Name of this mapping - - unsigned nCost; // Number of row misses produced by this mapping - - unsigned nChannelBits; - unsigned nRankBits; - unsigned nBankGroupBits; - unsigned nBankBits; // Number of Bank bits used by this mapping - unsigned nRowBits; // Number of Row bits used by this mapping - unsigned nColumnBits; // Number of Column bits used by this mapping - unsigned nByteBits; // Number of Byte bits used by this mapping - - // This container stores for each used xor gate a pair which consists of "First/Number of an address bit which corresponds to a bank" and "Second/Number of an address bit which corresponds to a row" std::vector vXor; std::vector> vChannelBits; From 37dcd71c49a9dcddae6dc5e50dc89155945dc2a9 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Tue, 7 Apr 2020 17:49:58 +0200 Subject: [PATCH 3/9] Code cleanup. --- DRAMSys/library/CMakeLists.txt | 2 - DRAMSys/library/src/common/TlmRecorder.cpp | 1 - DRAMSys/library/src/common/TlmRecorder.h | 1 - .../src/configuration/Configuration.cpp | 20 +-- DRAMSys/library/src/error/eccbaseclass.h | 1 - DRAMSys/library/src/error/errormodel.h | 2 +- DRAMSys/library/src/simulation/Arbiter.h | 2 +- DRAMSys/library/src/simulation/DRAMSys.cpp | 10 +- DRAMSys/library/src/simulation/DRAMSys.h | 1 - DRAMSys/library/src/simulation/IArbiter.h | 135 ----------------- .../library/src/simulation/MemoryManager.cpp | 15 +- .../library/src/simulation/MemoryManager.h | 7 +- .../library/src/simulation/SimpleArbiter.h | 137 ------------------ DRAMSys/library/src/simulation/StlPlayer.h | 8 +- .../library/src/simulation/TraceGenerator.h | 2 +- .../library/src/simulation/TracePlayer.cpp | 2 +- DRAMSys/library/src/simulation/TracePlayer.h | 3 +- 17 files changed, 28 insertions(+), 321 deletions(-) delete mode 100644 DRAMSys/library/src/simulation/IArbiter.h delete mode 100644 DRAMSys/library/src/simulation/SimpleArbiter.h diff --git a/DRAMSys/library/CMakeLists.txt b/DRAMSys/library/CMakeLists.txt index 31729d23..04947c62 100644 --- a/DRAMSys/library/CMakeLists.txt +++ b/DRAMSys/library/CMakeLists.txt @@ -140,11 +140,9 @@ add_library(DRAMSysLibrary src/simulation/Arbiter.cpp src/simulation/DRAMSys.cpp src/simulation/ExampleInitiator.h - src/simulation/IArbiter.h src/simulation/MemoryManager.cpp src/simulation/ReorderBuffer.h src/simulation/Setup.cpp - src/simulation/SimpleArbiter.h src/simulation/StlPlayer.h src/simulation/TemperatureController.cpp src/simulation/TraceGenerator.h diff --git a/DRAMSys/library/src/common/TlmRecorder.cpp b/DRAMSys/library/src/common/TlmRecorder.cpp index 0571eb98..46a8bedb 100644 --- a/DRAMSys/library/src/common/TlmRecorder.cpp +++ b/DRAMSys/library/src/common/TlmRecorder.cpp @@ -41,7 +41,6 @@ #include "TlmRecorder.h" #include "dramExtensions.h" -#include "XmlAddressDecoder.h" #include "../configuration/Configuration.h" #include "../controller/Command.h" diff --git a/DRAMSys/library/src/common/TlmRecorder.h b/DRAMSys/library/src/common/TlmRecorder.h index 6da4608c..1b32bc39 100644 --- a/DRAMSys/library/src/common/TlmRecorder.h +++ b/DRAMSys/library/src/common/TlmRecorder.h @@ -49,7 +49,6 @@ #include #include #include -#include "XmlAddressDecoder.h" #include "DebugManager.h" #include "utils.h" diff --git a/DRAMSys/library/src/configuration/Configuration.cpp b/DRAMSys/library/src/configuration/Configuration.cpp index 67955ff0..959b128f 100644 --- a/DRAMSys/library/src/configuration/Configuration.cpp +++ b/DRAMSys/library/src/configuration/Configuration.cpp @@ -40,7 +40,6 @@ #include "Configuration.h" #include "ConfigurationLoader.h" -#include "../common/XmlAddressDecoder.h" std::string Configuration::memspecUri = ""; std::string Configuration::mcconfigUri = ""; @@ -230,28 +229,13 @@ std::uint64_t Configuration::getSimMemSizeInBytes() // The bus width is given in bits, e.g., 64-bit data bus, 128-bit data bus, etc. unsigned int Configuration::getDataBusWidth() { - unsigned int dataBusWidth = memSpec->bitWidth * numberOfDevicesOnDIMM; - assert(dataBusWidth > 0); - return dataBusWidth; + return memSpec->bitWidth * numberOfDevicesOnDIMM; } // Returns the number of bytes transfered in a burst unsigned int Configuration::getBytesPerBurst() { - // First multiply to get the number of bits in a burst, then divide by 8 to get the value in bytes. The order is important. Think on a single x4 device. - unsigned int bytesPerBurst = (memSpec->burstLength * getDataBusWidth()) / 8; - assert(bytesPerBurst > 0); - - if (numberOfDevicesOnDIMM > 1) { - // The least significant bits of the physical address are the byte - // offset of the N-byte-wide memory module (DIMM) (a single data word - // or burst element has N bytes. N = 2^(# bits for byte offset)). - unsigned int burstElementSizeInBytes = - AddressDecoder::getInstance().amount.bytes; - assert(bytesPerBurst == (burstElementSizeInBytes * memSpec->burstLength)); - } - - return bytesPerBurst; + return (memSpec->burstLength * getDataBusWidth()) / 8; } // Changes the number of bytes depeding on the ECC Controller. This function is needed for modules which get data directly or indirectly from the ECC Controller diff --git a/DRAMSys/library/src/error/eccbaseclass.h b/DRAMSys/library/src/error/eccbaseclass.h index 57f20aa7..1def9708 100644 --- a/DRAMSys/library/src/error/eccbaseclass.h +++ b/DRAMSys/library/src/error/eccbaseclass.h @@ -8,7 +8,6 @@ #include "ECC/ECC.h" -#include "../common/XmlAddressDecoder.h" #include "../common/DebugManager.h" class ECCBaseClass : sc_module diff --git a/DRAMSys/library/src/error/errormodel.h b/DRAMSys/library/src/error/errormodel.h index d027d9b3..66e80e90 100644 --- a/DRAMSys/library/src/error/errormodel.h +++ b/DRAMSys/library/src/error/errormodel.h @@ -40,7 +40,7 @@ #include #include #include "../configuration/Configuration.h" -#include "../common/XmlAddressDecoder.h" +#include "../common/AddressDecoder.h" #include "../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h" class errorModel : public sc_module diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index 907a8fcf..6da3d63d 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -46,7 +46,7 @@ #include #include #include -#include "../common/XmlAddressDecoder.h" +#include "../common/AddressDecoder.h" #include "../common/dramExtensions.h" #include "../configuration/ConfigurationLoader.h" diff --git a/DRAMSys/library/src/simulation/DRAMSys.cpp b/DRAMSys/library/src/simulation/DRAMSys.cpp index 7eabae3e..e4531944 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -44,6 +44,7 @@ #include "DRAMSys.h" #include "Setup.h" +#include "../common/third_party/tinyxml2/tinyxml2.h" #include "../common/TlmRecorder.h" #include "../common/DebugManager.h" #include "../common/XmlAddressDecoder.h" @@ -81,7 +82,6 @@ DRAMSys::DRAMSys(sc_module_name name, std::string simconfig; std::string thermalconfig; - // TODO: Setup never used? Setup setup(simulationToRun, memspec, mcconfig, @@ -163,8 +163,8 @@ DRAMSys::DRAMSys(sc_module_name name, void DRAMSys::logo() { -#define REDTXT(s) std::string("\033[0;31m"+std::string(s)+"\033[0m") -#define BOLDBLUETXT(s) std::string("\033[1;34m"+std::string(s)+"\033[0m") +#define REDTXT(s) std::string("\033[0;31m" + std::string(s) + "\033[0m") +#define BOLDBLUETXT(s) std::string("\033[1;34m" + std::string(s) + "\033[0m") std::cout << std::endl; std::cout << REDTXT(" |||") << std::endl; std::cout << REDTXT(" +---+ Microelectronic Systems") << std::endl; @@ -172,7 +172,7 @@ void DRAMSys::logo() std::cout << REDTXT("=| |= ") << BOLDBLUETXT("University of Kaiserslautern") << std::endl; std::cout << REDTXT(" +---+ ") << std::endl; - std::cout << REDTXT(" ||| ") << "DRAMSys v4.0" << std::endl; + std::cout << REDTXT(" ||| ") << "DRAMSys4.0" << std::endl; std::cout << std::endl; #undef REDTXT #undef BOLDBLUETXT @@ -180,7 +180,7 @@ void DRAMSys::logo() void DRAMSys::setupDebugManager(const std::string &traceName __attribute__((unused))) { -#ifdef DEBUGGING +#ifndef NDEBUG auto &dbg = DebugManager::getInstance(); dbg.writeToConsole = false; dbg.writeToFile = true; diff --git a/DRAMSys/library/src/simulation/DRAMSys.h b/DRAMSys/library/src/simulation/DRAMSys.h index 15410755..3d78fdc3 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.h +++ b/DRAMSys/library/src/simulation/DRAMSys.h @@ -48,7 +48,6 @@ #include "ReorderBuffer.h" #include #include -#include "../common/third_party/tinyxml2/tinyxml2.h" #include "../common/tlm2_base_protocol_checker.h" #include "../error/eccbaseclass.h" #include "../controller/ControllerIF.h" diff --git a/DRAMSys/library/src/simulation/IArbiter.h b/DRAMSys/library/src/simulation/IArbiter.h deleted file mode 100644 index 3747a1b0..00000000 --- a/DRAMSys/library/src/simulation/IArbiter.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2018, University of Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: - * Felipe S. Prado - * Matthias Jung - */ - -#ifndef IARBITER_H -#define IARBITER_H - -#include -#include -#include -#include -#include -#include -#include -#include "../configuration/ConfigurationLoader.h" - -struct IArbiter : public sc_module -{ -public: - tlm_utils::multi_passthrough_target_socket tSocket; - tlm_utils::multi_passthrough_initiator_socket iSocket; - - SC_CTOR(IArbiter) - { - // One or more devices can accesss all the memory units through the arbiter. - // Devices' initiator sockets are bound to arbiter's target sockets. - // As soon the arbiter receives a request in any of its target sockets it should treat and forward it to the proper memory channel. - tSocket.register_nb_transport_fw(this, &IArbiter::nb_transport_fw); - - // The arbiter communicates with one or more memory unity through one or more sockets (one or more memory channels). - // Each of the arbiter's initiator sockets is bound to a memory controller's target socket. - // Anytime an transaction comes from a memory unity to the arbiter the "bw" callback is called. - iSocket.register_nb_transport_bw(this, &IArbiter::nb_transport_bw); - - tSocket.register_transport_dbg(this, &IArbiter::transport_dbg); - } - - virtual void setTlmRecorder(TlmRecorder *recorder) = 0; - virtual bool isOutputBufferFull(unsigned int initiatorSocket) = 0; - virtual void incrementNumberOfOutputBufferTransactions(unsigned int - initiatorSocket) = 0; - -protected: - // Initiated by initiator side - // This function is called when an arbiter's target socket receives a transaction from a device - virtual tlm::tlm_sync_enum nb_transport_fw(int id, tlm::tlm_generic_payload &payload, - tlm::tlm_phase &phase, sc_time &fwDelay) = 0; - - // Initiated by dram side - // This function is called when an arbiter's initiator socket receives a transaction from a memory controller - virtual tlm::tlm_sync_enum nb_transport_bw(int channelId, - tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase, sc_time &bwDelay) = 0; - - virtual unsigned int transport_dbg(int /*id*/, - tlm::tlm_generic_payload &trans) = 0; - - void appendDramExtension(int socketId, tlm::tlm_generic_payload &payload) - { - // Append Generation Extension - GenerationExtension *genExtension = new GenerationExtension(clkAlign( - sc_time_stamp(), Configuration::getInstance().ControllerClk)); - payload.set_auto_extension(genExtension); - - unsigned int burstlength = payload.get_streaming_width(); - DecodedAddress decodedAddress = XmlAddressDecoder::getInstance().decodeAddress( - payload.get_address()); - // Check the valid range of decodedAddress - if (addressIsValid(decodedAddress)) { - DramExtension *extension = new DramExtension(Thread(socketId + 1), - Channel(decodedAddress.channel), Bank(decodedAddress.bank), - BankGroup(decodedAddress.bankgroup), Row(decodedAddress.row), - Column(decodedAddress.column), burstlength, 0); - payload.set_auto_extension(extension); - } else { - SC_REPORT_FATAL("Arbiter", "Decoded Address are not inside the valid range"); - } - } - - bool addressIsValid(DecodedAddress &decodedAddress) - { - if (decodedAddress.channel >= - XmlAddressDecoder::getInstance().amount.channel) { - return false; - } - if (decodedAddress.bank >= XmlAddressDecoder::getInstance().amount.bank) { - return false; - } -// if (decodedAddress.bankgroup > -// XmlAddressDecoder::getInstance().amount["bankgroup"]) { -// return false; -// } - if (decodedAddress.column >= - XmlAddressDecoder::getInstance().amount.column) { - return false; - } - if (decodedAddress.row >= XmlAddressDecoder::getInstance().amount.row) { - return false; - } - return true; - } -}; - -#endif // IARBITER_H diff --git a/DRAMSys/library/src/simulation/MemoryManager.cpp b/DRAMSys/library/src/simulation/MemoryManager.cpp index e000fc3e..dad4e044 100644 --- a/DRAMSys/library/src/simulation/MemoryManager.cpp +++ b/DRAMSys/library/src/simulation/MemoryManager.cpp @@ -39,11 +39,14 @@ #include "../configuration/Configuration.h" #include -MemoryManager::MemoryManager(): numberOfAllocations(0), numberOfFrees(0) {} +using namespace tlm; + +MemoryManager::MemoryManager() + : numberOfAllocations(0), numberOfFrees(0) {} MemoryManager::~MemoryManager() { - for (gp *payload : freePayloads) { + for (tlm_generic_payload *payload : freePayloads) { delete[] payload->get_data_ptr(); delete payload; numberOfFrees++; @@ -54,11 +57,11 @@ MemoryManager::~MemoryManager() //PRINTDEBUGMESSAGE("MemoryManager","Number of freed payloads: " + to_string(numberOfFrees)); } -gp *MemoryManager::allocate() +tlm_generic_payload *MemoryManager::allocate() { if (freePayloads.empty()) { numberOfAllocations++; - gp *payload = new gp(this); + tlm_generic_payload *payload = new tlm_generic_payload(this); // Allocate a data buffer and initialize it with zeroes: unsigned int dataLength = Configuration::getInstance().getBytesPerBurst(); @@ -68,13 +71,13 @@ gp *MemoryManager::allocate() payload->set_data_ptr(data); return payload; } else { - gp *result = freePayloads.back(); + tlm_generic_payload *result = freePayloads.back(); freePayloads.pop_back(); return result; } } -void MemoryManager::free(gp *payload) +void MemoryManager::free(tlm_generic_payload *payload) { payload->reset(); // clears all extensions freePayloads.push_back(payload); diff --git a/DRAMSys/library/src/simulation/MemoryManager.h b/DRAMSys/library/src/simulation/MemoryManager.h index 83baa275..b38930f6 100644 --- a/DRAMSys/library/src/simulation/MemoryManager.h +++ b/DRAMSys/library/src/simulation/MemoryManager.h @@ -39,20 +39,19 @@ #include #include -typedef tlm::tlm_generic_payload gp; class MemoryManager : public tlm::tlm_mm_interface { public: MemoryManager(); virtual ~MemoryManager(); - virtual gp *allocate(); - virtual void free(gp *payload); + virtual tlm::tlm_generic_payload *allocate(); + virtual void free(tlm::tlm_generic_payload *payload); private: unsigned int numberOfAllocations; unsigned int numberOfFrees; - std::vector freePayloads; + std::vector freePayloads; }; #endif // MEMORYMANAGER_H diff --git a/DRAMSys/library/src/simulation/SimpleArbiter.h b/DRAMSys/library/src/simulation/SimpleArbiter.h deleted file mode 100644 index a61b9a66..00000000 --- a/DRAMSys/library/src/simulation/SimpleArbiter.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2018, University of Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: - * Felipe S. Prado - * Matthias Jung - */ - -#ifndef SIMPLEARBITER_H -#define SIMPLEARBITER_H - -#include "IArbiter.h" -#include "../common/XmlAddressDecoder.h" -#include "../common/dramExtensions.h" - -// Annotated References [X,Y] --> Please refer to TLM AT Cheat Sheet on README - -struct SimpleArbiter: public IArbiter { -public: - SimpleArbiter(sc_module_name name) : IArbiter(name) - { - } - - void setTlmRecorder(TlmRecorder *recorder) - { - tlmRecorder = recorder; - } - - virtual bool isOutputBufferFull(unsigned int /*initiatorSocket*/) - { - return false; - } - - virtual void incrementNumberOfOutputBufferTransactions(unsigned - int /*initiatorSocket*/) - { - } - -protected: - TlmRecorder *tlmRecorder; - // Initiated by initiator side - // This function is called when an arbiter's target socket receives a transaction from a device - virtual tlm::tlm_sync_enum nb_transport_fw(int id, tlm::tlm_generic_payload &payload, - tlm::tlm_phase &phase, sc_time &fwDelay) - { - if (phase == BEGIN_REQ) { - payload.acquire(); - // adjust address offset, e.g. for gem5 simulation - payload.set_address(payload.get_address() - - Configuration::getInstance().AddressOffset); - - // In the begin request phase the socket ID is appended to the payload. - // It will extracted from the payload and used later. - appendDramExtension(id, payload); - - tlmRecorder->recordArbiterPhase(payload, phase, sc_time_stamp() + fwDelay); - tlmRecorder->recordArbiterPhase(payload, END_REQ, sc_time_stamp() + fwDelay); - tlmRecorder->recordPhase(payload, phase, sc_time_stamp() + fwDelay); - - // Forward Path [1.0] - iSocket[getISocketIndex(payload)]->nb_transport_fw(payload, phase, fwDelay); - } else if (phase == END_RESP) { - payload.release(); - tlmRecorder->recordArbiterPhase(payload, phase, sc_time_stamp() + fwDelay); - } else { - SC_REPORT_FATAL("Arbiter", "Illegal phase received by initiator"); - } - - // 4-Phase Handshake [1.1] - // 4-Phase Handshake [1.7] - return tlm::TLM_ACCEPTED; - } - - // Initiated by dram side - // This function is called when an arbiter's initiator socket receives a transaction from a memory controller - virtual tlm::tlm_sync_enum nb_transport_bw(int /*channelId*/, - tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase, sc_time &bwDelay) - { - tlmRecorder->recordPhase(payload, phase, bwDelay + sc_time_stamp()); - - tSocket[DramExtension::getThread(payload).ID()]->nb_transport_bw(payload, - TPhase, bwDelay); - - if (phase == BEGIN_RESP) { - // Early Completion [3.1] - tlmRecorder->recordPhase(payload, END_RESP, bwDelay + sc_time_stamp()); - tlmRecorder->recordArbiterPhase(payload, BEGIN_RESP, sc_time_stamp() + bwDelay); - return tlm::TLM_COMPLETED; - } - // 4-Phase Handshake [1.3] - return tlm::TLM_ACCEPTED; - } - - virtual unsigned int transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans) - { - // adjust address offset: - trans.set_address(trans.get_address() - - Configuration::getInstance().AddressOffset); - - return iSocket[getISocketIndex(trans)]->transport_dbg(trans); - } - - virtual unsigned int getISocketIndex(tlm::tlm_generic_payload &payload) - { - return DramExtension::getBank(payload).ID(); - } -}; - -#endif // SIMPLEARBITER_H diff --git a/DRAMSys/library/src/simulation/StlPlayer.h b/DRAMSys/library/src/simulation/StlPlayer.h index 2ae960b7..e55b568c 100644 --- a/DRAMSys/library/src/simulation/StlPlayer.h +++ b/DRAMSys/library/src/simulation/StlPlayer.h @@ -40,7 +40,7 @@ #ifndef STLPLAYER_H #define STLPLAYER_H -#include "../common/XmlAddressDecoder.h" +#include #include "TracePlayer.h" template @@ -83,7 +83,7 @@ public: numberOfTransactions++; } // Allocate a generic payload for this request. - gp *payload = this->allocatePayload(); + tlm::tlm_generic_payload *payload = this->allocatePayload(); payload->acquire(); unsigned char *data = payload->get_data_ptr(); @@ -126,8 +126,8 @@ public: iss >> address; if (address.empty()) SC_REPORT_FATAL("StlPlayer", - ("Malformed trace file. Address could not be found (line " + std::to_string( - lineCnt) + ").").c_str()); + ("Malformed trace file. Address could not be found (line " + + std::to_string(lineCnt) + ").").c_str()); unsigned long long addr = std::stoull(address.c_str(), 0, 16); // Get the data if necessary. diff --git a/DRAMSys/library/src/simulation/TraceGenerator.h b/DRAMSys/library/src/simulation/TraceGenerator.h index 29eaf26e..d2e50689 100644 --- a/DRAMSys/library/src/simulation/TraceGenerator.h +++ b/DRAMSys/library/src/simulation/TraceGenerator.h @@ -60,7 +60,7 @@ public: this->terminate(); } - gp *payload = this->allocatePayload(); + tlm::tlm_generic_payload *payload = this->allocatePayload(); payload->acquire(); unsigned char *dataElement = new unsigned char[16]; // TODO: column / burst breite diff --git a/DRAMSys/library/src/simulation/TracePlayer.cpp b/DRAMSys/library/src/simulation/TracePlayer.cpp index 17ddf0b3..d1f2787b 100644 --- a/DRAMSys/library/src/simulation/TracePlayer.cpp +++ b/DRAMSys/library/src/simulation/TracePlayer.cpp @@ -53,7 +53,7 @@ TracePlayer::TracePlayer(sc_module_name name, TracePlayerListener *listener) : storageEnabled = true; } -gp *TracePlayer::allocatePayload() +tlm_generic_payload *TracePlayer::allocatePayload() { return memoryManager.allocate(); } diff --git a/DRAMSys/library/src/simulation/TracePlayer.h b/DRAMSys/library/src/simulation/TracePlayer.h index ffab944b..d87e747b 100644 --- a/DRAMSys/library/src/simulation/TracePlayer.h +++ b/DRAMSys/library/src/simulation/TracePlayer.h @@ -49,7 +49,6 @@ #include "MemoryManager.h" #include "../configuration/Configuration.h" #include "../common/DebugManager.h" -#include "../common/XmlAddressDecoder.h" #include "TracePlayerListener.h" struct TracePlayer : public sc_module @@ -61,7 +60,7 @@ public: unsigned int getNumberOfLines(std::string pathToTrace); protected: - gp *allocatePayload(); + tlm::tlm_generic_payload *allocatePayload(); tlm_utils::peq_with_cb_and_phase payloadEventQueue; void finish(); void terminate(); From a3b0c10c8e1b0cda42c2365c48f3b44784fd87da Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 8 Apr 2020 16:52:38 +0200 Subject: [PATCH 4/9] Unified address decoders, moved instantiation into arbiter. --- DRAMSys/library/CMakeLists.txt | 2 - DRAMSys/library/src/common/AddressDecoder.cpp | 332 ++++++++++++++++-- DRAMSys/library/src/common/AddressDecoder.h | 76 ++-- DRAMSys/library/src/error/errormodel.cpp | 24 +- DRAMSys/library/src/error/errormodel.h | 12 +- DRAMSys/library/src/simulation/Arbiter.cpp | 24 +- DRAMSys/library/src/simulation/Arbiter.h | 4 +- DRAMSys/library/src/simulation/DRAMSys.cpp | 29 +- DRAMSys/library/src/simulation/DRAMSys.h | 3 +- .../src/simulation/dram/DramWideIO.cpp | 10 +- 10 files changed, 414 insertions(+), 102 deletions(-) diff --git a/DRAMSys/library/CMakeLists.txt b/DRAMSys/library/CMakeLists.txt index 04947c62..0bfbbd1e 100644 --- a/DRAMSys/library/CMakeLists.txt +++ b/DRAMSys/library/CMakeLists.txt @@ -66,13 +66,11 @@ include_directories( add_library(DRAMSysLibrary src/common/AddressDecoder.cpp - src/common/CongenAddressDecoder.cpp src/common/DebugManager.cpp src/common/dramExtensions.cpp src/common/tlm2_base_protocol_checker.h src/common/TlmRecorder.cpp src/common/utils.cpp - src/common/XmlAddressDecoder.cpp src/common/third_party/tinyxml2/tinyxml2.cpp src/configuration/Configuration.cpp diff --git a/DRAMSys/library/src/common/AddressDecoder.cpp b/DRAMSys/library/src/common/AddressDecoder.cpp index 7810c8d0..d54352a4 100644 --- a/DRAMSys/library/src/common/AddressDecoder.cpp +++ b/DRAMSys/library/src/common/AddressDecoder.cpp @@ -31,30 +31,322 @@ * * Authors: * Johannes Feldmann + * Lukas Steiner */ #include "AddressDecoder.h" -#include "XmlAddressDecoder.h" -#include "CongenAddressDecoder.h" +#include "utils.h" +#include "../configuration/Configuration.h" -AddressDecoder *AddressDecoder::m_pInstance = nullptr; - -AddressDecoder &AddressDecoder::getInstance() +tinyxml2::XMLElement *AddressDecoder::getXMLNode(tinyxml2::XMLElement + *pRoot, std::string strName) { - assert(m_pInstance != nullptr); - return *m_pInstance; -} - -void AddressDecoder::createInstance(Type t) -{ - assert(m_pInstance == nullptr); - switch (t) - { - case Type::XML: - m_pInstance = new XmlAddressDecoder(); - break; - case Type::CONGEN: - m_pInstance = new CongenAddressDecoder(); - break; + tinyxml2::XMLElement *pNode = pRoot->FirstChildElement(strName.c_str()); + if (pNode == nullptr) { + reportFatal("ConGenAddressDecorder", + "XML File corrupted. Missing node " + strName + "."); } + return pNode; } + +unsigned int AddressDecoder::getUnsignedTextFromXMLNode( + tinyxml2::XMLElement *pRoot) +{ + std::string str = pRoot->GetText(); + if (str.empty() || std::find_if(str.begin(), str.end(), [](char c) { + return !std::isdigit(c); + }) != str.end()) { + reportFatal("ConGenAddressDecoder", + "Node " + std::string(pRoot->Name()) + " is empty or not a number."); + return (unsigned)(-1); + } + return atol(str.c_str()); +} + +unsigned int AddressDecoder::getUnsignedAttrFromXMLNode( + tinyxml2::XMLElement *pRoot, std::string strName) +{ + std::string str = pRoot->Attribute(strName.c_str()); + if (str.empty() || std::find_if(str.begin(), str.end(), [](char c) { + return !std::isdigit(c); + }) != str.end()) { + reportFatal("ConGenAddressDecoder", + "Attribute " + strName + " is empty or not a number."); + return (unsigned)(-1); + } + return atol(str.c_str()); +} + +AddressDecoder::AddressDecoder(std::string pathToAddressMapping) +{ + tinyxml2::XMLDocument doc; + loadXML(pathToAddressMapping, doc); + tinyxml2::XMLElement *pRoot = doc.RootElement(); + std::string xmlNodeName(pRoot->Name()); + + if (xmlNodeName != "CONGEN") + reportFatal("ConGenAddressDecorder", + "Root node name differs from \"CONGEN\". File format not supported."); + + // Load address mapping + tinyxml2::XMLElement *pNode; + + for (pNode = pRoot->FirstChildElement("SOLUTION"); pNode != nullptr; + pNode = pNode->NextSiblingElement("SOLUTION")) + { + if (getUnsignedAttrFromXMLNode(pNode, "ID") == 0) + break; // Correct mapping was found. + } + + // If no mapping was found report error + if (pNode == nullptr) + SC_REPORT_FATAL("ConGenAddressDecoder", "No mapping with ID 0 was found."); + + // get XOR connections + // An XOR connection needs two parameters: A bank bit and a Row bit. + for (tinyxml2::XMLElement *pXor = pNode->FirstChildElement("XOR"); + pXor != nullptr; pXor = pXor->NextSiblingElement("XOR")) + { + vXor.push_back(XOR(getUnsignedAttrFromXMLNode(pXor, "BANK"), + getUnsignedAttrFromXMLNode(pXor, "ROW"))); + } + + unsigned counter = 0; + for (tinyxml2::XMLElement *pChannel = pNode->FirstChildElement("CHANNEL_BIT"); + pChannel != nullptr; pChannel = pChannel->NextSiblingElement("CHANNEL_BIT")) + { + unsigned nChannel = getUnsignedTextFromXMLNode(pChannel); + vChannelBits.push_back(std::pair(counter++, nChannel)); + } + + counter = 0; + for (tinyxml2::XMLElement *pRank = pNode->FirstChildElement("RANK_BIT"); + pRank != nullptr; pRank = pRank->NextSiblingElement("RANK_BIT")) + { + unsigned nRank = getUnsignedTextFromXMLNode(pRank); + vRankBits.push_back(std::pair(counter++, nRank)); + } + + counter = 0; + for (tinyxml2::XMLElement *pBankGroup = pNode->FirstChildElement("BANKGROUP_BIT"); + pBankGroup != nullptr; pBankGroup = pBankGroup->NextSiblingElement("BANKGROUP_BIT")) + { + unsigned nBankGroup = getUnsignedTextFromXMLNode(pBankGroup); + vBankGroupBits.push_back(std::pair(counter++, nBankGroup)); + } + + // get all bank bits + // Each bank bit of the address will be stored with a counter value which assigns the bit position DecodedAddress struct. + counter = 0; + for (tinyxml2::XMLElement *pBank = pNode->FirstChildElement("BANK_BIT"); + pBank != nullptr; pBank = pBank->NextSiblingElement("BANK_BIT")) + { + unsigned nBank = getUnsignedTextFromXMLNode(pBank); + vBankBits.push_back(std::pair(counter++, nBank)); + } + + // get all row bits bits + // Each Row bit of the address will be stored with a counter value which assigns the bit position DecodedAddress struct. + counter = 0; + for (tinyxml2::XMLElement *pRow = pNode->FirstChildElement("ROW_BIT"); + pRow != nullptr; pRow = pRow->NextSiblingElement("ROW_BIT")) { + unsigned nRow = getUnsignedTextFromXMLNode(pRow); + vRowBits.push_back(std::pair(counter++, nRow)); + } + + counter = 0; + for (tinyxml2::XMLElement *pColumn = pNode->FirstChildElement("COLUMN_BIT"); + pColumn != nullptr; pColumn = pColumn->NextSiblingElement("COLUMN_BIT")) + { + unsigned nColumn = getUnsignedTextFromXMLNode(pColumn); + vColumnBits.push_back(std::pair(counter++, nColumn)); + } + + counter = 0; + for (tinyxml2::XMLElement *pByte = pNode->FirstChildElement("BYTE_BIT"); + pByte != nullptr; pByte = pByte->NextSiblingElement("BYTE_BIT")) + { + unsigned nByte = getUnsignedTextFromXMLNode(pByte); + vByteBits.push_back(std::pair(counter++, nByte)); + } + + // Fill the amount map. This is copied from xmlAddressDecoder without further investigation + amount.channel = pow(2.0, vChannelBits.size()); + amount.rank = pow(2.0, vRankBits.size()); + amount.bankgroup = pow(2.0, vBankGroupBits.size()); + amount.bank = pow(2.0, vBankBits.size()); + amount.row = pow(2.0, vRowBits.size()); + amount.column = pow(2.0, vColumnBits.size()); + amount.bytes = pow(2.0, vByteBits.size()); + + banksPerGroup = amount.bank; + amount.bank = banksPerGroup * amount.bankgroup * amount.rank; + + bankgroupsPerRank = amount.bankgroup; + amount.bankgroup = bankgroupsPerRank * amount.rank; + + maximumAddress = amount.bytes * amount.column * amount.row * banksPerGroup * bankgroupsPerRank * amount.rank * amount.channel - 1; + + Configuration &config = Configuration::getInstance(); + MemSpec *memSpec = config.memSpec; + + if (config.numberOfMemChannels != amount.channel || memSpec->numberOfRanks != amount.rank + || memSpec->numberOfBankGroups != amount.bankgroup || memSpec->numberOfBanks != amount.bank + || memSpec->numberOfRows != amount.row || memSpec->numberOfColumns != amount.column + || config.numberOfDevicesOnDIMM * memSpec->bitWidth != amount.bytes * 8) + SC_REPORT_FATAL("CongenAddressDecoder", "Memspec and addressmapping do not match"); +} + +DecodedAddress AddressDecoder::decodeAddress(uint64_t encAddr) +{ +// if (encAddr > maximumAddress) +// SC_REPORT_WARNING("CongenAddressDecoder", ("Address " + std::to_string(encAddr) + " out of range (maximum address is " + std::to_string(maximumAddress) + ")").c_str()); + + // Apply XOR + // For each used xor: + // Get the bank bit and row bit. Apply a bitwise xor operator and save it back to the bank bit. + for (auto it = vXor.begin(); it != vXor.end(); it++) + { + unsigned new_bank_bit; + // Bank Row + new_bank_bit = (((encAddr >> it->nBank) & 1) ^ ((encAddr >> it->nRow) & 1)); + encAddr &= ~(1 << it->nBank); + encAddr |= new_bank_bit << it->nBank; + } + + DecodedAddress decAddr; + + decAddr.channel = 0; + for (auto it = vChannelBits.begin(); it != vChannelBits.end(); it++) + decAddr.channel |= ((encAddr >> it->second) & 1) << it->first; + + decAddr.rank = 0; + for (auto it = vRankBits.begin(); it != vRankBits.end(); it++) + decAddr.rank |= ((encAddr >> it->second) & 1) << it->first; + + decAddr.bankgroup = 0; + for (auto it = vBankGroupBits.begin(); it != vBankGroupBits.end(); it++) + decAddr.bankgroup |= ((encAddr >> it->second) & 1) << it->first; + + // Bank + // it->second: position of the target bit in the address + // it->first: target position of the bit in the variable + // For each bank bit: + // shift address bit to position 0. Clear all other bits. shift it the right bank bit. Add it to the set of bank bits. + decAddr.bank = 0; + for (auto it = vBankBits.begin(); it != vBankBits.end(); it++) + decAddr.bank |= ((encAddr >> it->second) & 1) << it->first; + + // Row + // it->second: position of the target bit in the address + // it->first: target position of the bit in the variable + // For each row bit: + // shift address bit to position 0. Clear all other bits. shift it the right row bit. Add it to the set of row bits. + decAddr.row = 0; + for (auto it = vRowBits.begin(); it != vRowBits.end(); it++) + decAddr.row |= ((encAddr >> it->second) & 1) << it->first; + + // Column + // it->second: position of the target bit in the address + // it->first: target position of the bit in the variable + // For each column bit: + // shift address bit to position 0. Clear all other bits. shift it the right column bit. Add it to the set of column bits. + decAddr.column = 0; + for (auto it = vColumnBits.begin(); it != vColumnBits.end(); it++) + decAddr.column |= ((encAddr >> it->second) & 1) << it->first; + + decAddr.bankgroup = decAddr.bankgroup + decAddr.rank * bankgroupsPerRank; + decAddr.bank = decAddr.bank + decAddr.bankgroup * banksPerGroup; + + return decAddr; +} + +uint64_t AddressDecoder::encodeAddress(DecodedAddress decAddr) +{ + decAddr.bankgroup = decAddr.bankgroup % bankgroupsPerRank; + decAddr.bank = decAddr.bank % banksPerGroup; + + uint64_t encAddr = 0; + + for (auto it = vChannelBits.begin(); it != vChannelBits.end(); it++) + encAddr |= ((decAddr.channel >> it->first) & 1) << it->second; + + for (auto it = vRankBits.begin(); it != vRankBits.end(); it++) + encAddr |= ((decAddr.rank >> it->first) & 1) << it->second; + + for (auto it = vBankGroupBits.begin(); it != vBankGroupBits.end(); it++) + encAddr |= ((decAddr.bankgroup >> it->first) & 1) << it->second; + + // Bank + // it->first: position of the target bit in the DecodedAddress struct field + // it->second: target position of the bit in the address + // For each bank bit: + // shift bank bit to position 0. Clear all other bits. shift it the right address bit. Add it to the set of address bits. + for (auto it = vBankBits.begin(); it != vBankBits.end(); it++) + encAddr |= ((decAddr.bank >> it->first) & 1) << it->second; + + // Row + // it->first: position of the target bit in the DecodedAddress struct field + // it->second: target position of the bit in the address + // For each row bit: + // shift row bit to position 0. Clear all other bits. shift it the right address bit. Add it to the set of address bits. + for (auto it = vRowBits.begin(); it != vRowBits.end(); it++) + encAddr |= ((decAddr.row >> it->first) & 1) << it->second; + + // Column + // it->first: position of the target bit in the DecodedAddress struct field + // it->second: target position of the bit in the address + // For each column bit: + // shift column bit to position 0. Clear all other bits. shift it the right address bit. Add it to the set of address bits. + for (auto it = vColumnBits.begin(); it != vColumnBits.end(); it++) + encAddr |= ((decAddr.column >> it->first) & 1) << it->second; + + for (auto it = vByteBits.begin(); it != vByteBits.end(); it++) + encAddr |= ((decAddr.bytes >> it->first) & 1) << it->second; + + // Apply XOR + // For each used xor: + // Get the bank bit and row bit. Apply a bitwise xor operator and save it back to the bank bit. + for (auto it = vXor.begin(); it != vXor.end(); it++) + { + unsigned new_bank_bit; + new_bank_bit = (((encAddr >> it->nBank) & 1) ^ ((encAddr >> it->nRow) & 1)); + encAddr &= ~(1 << it->nBank); + encAddr |= new_bank_bit << it->nBank; + } + + return encAddr; +} + +void AddressDecoder::print() +{ + std::map> output; + + for (auto it = vBankBits.begin(); it != vBankBits.end(); it++) { + output[it->second] = std::pair(it->first, 'B'); + } + for (auto it = vRowBits.begin(); it != vRowBits.end(); it++) { + output[it->second] = std::pair(it->first, 'R'); + } + for (auto it = vColumnBits.begin(); it != vColumnBits.end(); it++) { + output[it->second] = std::pair(it->first, 'C'); + } + + // add byte bits + output[0] = std::pair(0, 'b'); + output[1] = std::pair(1, 'b'); + output[2] = std::pair(2, 'b'); + + std::cout << headline << std::endl; + std::cout << "Used Address Mapping:" << std::endl; + std::cout << std::endl; + for (unsigned i = 0; i < 32; i++) { + std::cout << " " << i << " "; + } + std::cout << std::endl; + for (unsigned i = 0; i < 32; i++) { + std::cout << " " << output[i].second << "(" << output[i].first << ") "; + } + std::cout << std::endl; +} + diff --git a/DRAMSys/library/src/common/AddressDecoder.h b/DRAMSys/library/src/common/AddressDecoder.h index a750982b..e29d8dd6 100644 --- a/DRAMSys/library/src/common/AddressDecoder.h +++ b/DRAMSys/library/src/common/AddressDecoder.h @@ -31,34 +31,37 @@ * * Authors: * Johannes Feldmann + * Lukas Steiner */ #ifndef ADDRESSDECODER_H #define ADDRESSDECODER_H -#include #include #include #include #include +#include + +#include "third_party/tinyxml2/tinyxml2.h" struct DecodedAddress { - DecodedAddress() : - channel(0), - rank(0), - bankgroup(0), - row(0), - bank(0), - column(0), - bytes(0) - {} + DecodedAddress(unsigned channel, unsigned rank, + unsigned bankgroup, unsigned bank, + unsigned row, unsigned column, unsigned bytes) + : channel(channel), rank(rank), bankgroup(bankgroup), + bank(bank), row(row), column(column), bytes(bytes) {} + + DecodedAddress() + : channel(0), rank(0), bankgroup(0), + bank(0), row(0), column(0), bytes(0) {} unsigned channel; unsigned rank; unsigned bankgroup; - unsigned row; unsigned bank; + unsigned row; unsigned column; unsigned bytes; }; @@ -66,25 +69,12 @@ struct DecodedAddress class AddressDecoder { public: - enum class Type { - XML, - CONGEN - }; + AddressDecoder(std::string); -protected: - AddressDecoder() {} + DecodedAddress decodeAddress(uint64_t addr); + uint64_t encodeAddress(DecodedAddress n); - static AddressDecoder *m_pInstance; -public: - static AddressDecoder &getInstance(); - static void createInstance(Type t); - - virtual void setConfiguration(std::string url) = 0; - - virtual DecodedAddress decodeAddress(uint64_t addr) = 0; - virtual uint64_t encodeAddress(DecodedAddress n) = 0; - - virtual void print() = 0; + void print(); struct Amount { @@ -97,12 +87,40 @@ public: unsigned bytes = 1; } amount; -protected: +private: unsigned banksPerGroup; unsigned banksPerRank; unsigned bankgroupsPerRank; uint64_t maximumAddress; + + struct XOR + { + unsigned nBank; + unsigned nRow; + XOR() {} + XOR(unsigned bank, unsigned row) : nBank(bank), nRow(row) {} + }; + + // This container stores for each used xor gate a pair which consists of "First/Number of an address bit which corresponds to a bank" and "Second/Number of an address bit which corresponds to a row" + std::vector vXor; + std::vector> vChannelBits; + std::vector> vRankBits; + std::vector> vBankGroupBits; + // This container stores for each bank bit a pair which consists of "First/Number of the bank bit" and "Second/Number of the address bit" + std::vector> vBankBits; + // This container stores for each row bit a pair which consists of "First/Number of the row bit" and "Second/Number of the address bit" + std::vector> vRowBits; + // This container stores for each column bit a pair which consists of "First/Number of the column bit" and "Second/Number of the address bit" + std::vector> vColumnBits; + std::vector> vByteBits; + +private: + tinyxml2::XMLElement *getXMLNode(tinyxml2::XMLElement *pRoot, + std::string strName); + unsigned int getUnsignedTextFromXMLNode(tinyxml2::XMLElement *pRoot); + unsigned int getUnsignedAttrFromXMLNode(tinyxml2::XMLElement *pRoot, + std::string strName); }; #endif // ADDRESSDECODER_H diff --git a/DRAMSys/library/src/error/errormodel.cpp b/DRAMSys/library/src/error/errormodel.cpp index 9b20c68b..01f8d4ec 100644 --- a/DRAMSys/library/src/error/errormodel.cpp +++ b/DRAMSys/library/src/error/errormodel.cpp @@ -36,10 +36,13 @@ #include "errormodel.h" #include "../common/DebugManager.h" #include "../simulation/TemperatureController.h" +#include "../common/AddressDecoder.h" +#include "../common/dramExtensions.h" #include #include #include +#include void errorModel::init() { @@ -48,7 +51,7 @@ void errorModel::init() // Get Configuration parameters: burstLenght = Configuration::getInstance().memSpec->burstLength; numberOfColumns = Configuration::getInstance().memSpec->numberOfColumns; - bytesPerColumn = AddressDecoder::getInstance().amount.bytes; + bytesPerColumn = std::log2(Configuration::getInstance().getDataBusWidth()); // Adjust number of bytes per column dynamically to the selected ecc controller bytesPerColumn = Configuration::getInstance().adjustNumBytesAfterECC( @@ -60,9 +63,8 @@ void errorModel::init() // Initialize the lastRow Access array: lastRowAccess = new sc_time[numberOfRows]; - for (unsigned int i = 0; i < numberOfRows; i++) { + for (unsigned int i = 0; i < numberOfRows; i++) lastRowAccess[i] = SC_ZERO_TIME; - } // The name is set when the context is clear. contextStr = ""; @@ -155,9 +157,11 @@ void errorModel::store(tlm::tlm_generic_payload &trans) // Check wich bits have flipped during the last access and mark them as flipped: markBitFlips(); - // Get the key for the dataMap from the transaction's address: - DecodedAddress key = AddressDecoder::getInstance().decodeAddress( - trans.get_address()); + // Get the key for the dataMap from the transaction's dram extension: + DramExtension &ext = DramExtension::getExtension(trans); + DecodedAddress key = DecodedAddress(ext.getChannel().ID(), ext.getRank().ID(), + ext.getBankGroup().ID(), ext.getBank().ID(), + ext.getRow().ID(), ext.getColumn().ID(), 0); // Set context: setContext(key); @@ -221,9 +225,11 @@ void errorModel::load(tlm::tlm_generic_payload &trans) // Check wich bits have flipped during the last access and mark them as flipped: markBitFlips(); - // Get the key for the dataMap from the transaction's address: - DecodedAddress key = AddressDecoder::getInstance().decodeAddress( - trans.get_address()); + // Get the key for the dataMap from the transaction's dram extension: + DramExtension &ext = DramExtension::getExtension(trans); + DecodedAddress key = DecodedAddress(ext.getChannel().ID(), ext.getRank().ID(), + ext.getBankGroup().ID(), ext.getBank().ID(), + ext.getRow().ID(), ext.getColumn().ID(), 0); // Set context: setContext(key); diff --git a/DRAMSys/library/src/error/errormodel.h b/DRAMSys/library/src/error/errormodel.h index 66e80e90..30092209 100644 --- a/DRAMSys/library/src/error/errormodel.h +++ b/DRAMSys/library/src/error/errormodel.h @@ -113,13 +113,15 @@ private: weakCell *weakCells; // To use a map for storing the data a comparing function must be defined - struct DecodedAddressComparer { - bool operator()( const DecodedAddress &first , + struct DecodedAddressComparer + { + bool operator() (const DecodedAddress &first , const DecodedAddress &second) const { - uint64_t addrFirst = AddressDecoder::getInstance().encodeAddress(first); - uint64_t addrSecond = AddressDecoder::getInstance().encodeAddress(second); - return addrFirst < addrSecond; + if (first.row == second.row) + return first.column < second.column; + else + return first.row < second.row; } }; diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp index 7f80a9ff..d13737ab 100644 --- a/DRAMSys/library/src/simulation/Arbiter.cpp +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -36,10 +36,11 @@ */ #include "Arbiter.h" +#include "../common/AddressDecoder.h" using namespace tlm; -Arbiter::Arbiter(sc_module_name name) : +Arbiter::Arbiter(sc_module_name name, std::string pathToAddressMapping) : sc_module(name), payloadEventQueue(this, &Arbiter::peqCallback) { // The arbiter communicates with one or more memory unity through one or more sockets (one or more memory channels). @@ -60,6 +61,9 @@ Arbiter::Arbiter(sc_module_name name) : tSocket.register_nb_transport_fw(this, &Arbiter::nb_transport_fw); tSocket.register_transport_dbg(this, &Arbiter::transport_dbg); + + addressDecoder = new AddressDecoder(pathToAddressMapping); + addressDecoder->print(); } // Initiated by initiator side @@ -114,8 +118,7 @@ unsigned int Arbiter::transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans) trans.set_address(trans.get_address() - Configuration::getInstance().addressOffset); - DecodedAddress decodedAddress = AddressDecoder::getInstance().decodeAddress( - trans.get_address()); + DecodedAddress decodedAddress = addressDecoder->decodeAddress(trans.get_address()); return iSocket[decodedAddress.channel]->transport_dbg(trans); } @@ -213,7 +216,7 @@ void Arbiter::appendDramExtension(int socketId, tlm_generic_payload &payload) payload.set_auto_extension(genExtension); unsigned int burstlength = payload.get_streaming_width(); - DecodedAddress decodedAddress = AddressDecoder::getInstance().decodeAddress(payload.get_address()); + DecodedAddress decodedAddress = addressDecoder->decodeAddress(payload.get_address()); // Check the valid range of decodedAddress if (addressIsValid(decodedAddress)) { DramExtension *extension = new DramExtension(Thread(socketId), @@ -227,19 +230,20 @@ void Arbiter::appendDramExtension(int socketId, tlm_generic_payload &payload) } } +//TODO: this part should be checked inside the address decoder! bool Arbiter::addressIsValid(DecodedAddress &decodedAddress) { - if (decodedAddress.channel >= AddressDecoder::getInstance().amount.channel) + if (decodedAddress.channel >= addressDecoder->amount.channel) return false; - if (decodedAddress.rank >= AddressDecoder::getInstance().amount.rank) + if (decodedAddress.rank >= addressDecoder->amount.rank) return false; - if (decodedAddress.bankgroup >= AddressDecoder::getInstance().amount.bankgroup) + if (decodedAddress.bankgroup >= addressDecoder->amount.bankgroup) return false; - if (decodedAddress.bank >= AddressDecoder::getInstance().amount.bank) + if (decodedAddress.bank >= addressDecoder->amount.bank) return false; - if (decodedAddress.row >= AddressDecoder::getInstance().amount.row) + if (decodedAddress.row >= addressDecoder->amount.row) return false; - if (decodedAddress.column >= AddressDecoder::getInstance().amount.column) + if (decodedAddress.column >= addressDecoder->amount.column) return false; return true; } diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index 6da3d63d..4a129b46 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -56,10 +56,12 @@ public: tlm_utils::multi_passthrough_initiator_socket iSocket; tlm_utils::multi_passthrough_target_socket tSocket; - Arbiter(sc_module_name); + Arbiter(sc_module_name, std::string); SC_HAS_PROCESS(Arbiter); private: + AddressDecoder *addressDecoder; + tlm_utils::peq_with_cb_and_phase payloadEventQueue; std::vector channelIsFree; diff --git a/DRAMSys/library/src/simulation/DRAMSys.cpp b/DRAMSys/library/src/simulation/DRAMSys.cpp index e4531944..32f77bcd 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -47,8 +47,6 @@ #include "../common/third_party/tinyxml2/tinyxml2.h" #include "../common/TlmRecorder.h" #include "../common/DebugManager.h" -#include "../common/XmlAddressDecoder.h" -#include "../common/CongenAddressDecoder.h" #include "../configuration/ConfigurationLoader.h" #include "../common/utils.h" #include "../simulation/TemperatureController.h" @@ -112,25 +110,6 @@ DRAMSys::DRAMSys(sc_module_name name, + "configs/thermalsim/" + thermalconfig); - // Load addressmapping - if (XmlAddressDecoder::testConfigFile(pathToResources + "configs/amconfigs/" + - amconfig)) { - AddressDecoder::createInstance(AddressDecoder::Type::XML); - AddressDecoder::getInstance().setConfiguration(pathToResources - + "configs/amconfigs/" - + amconfig); - } else if (CongenAddressDecoder::testConfigFile(pathToResources + - "configs/amconfigs/" + amconfig)) { - AddressDecoder::createInstance(AddressDecoder::Type::CONGEN); - AddressDecoder::getInstance().setConfiguration(pathToResources - + "configs/amconfigs/" - + amconfig); - } else { - throw std::runtime_error("No address mapping loaded. Unsupported file format"); - } - - AddressDecoder::getInstance().print(); - // Setup the debug manager: setupDebugManager(Configuration::getInstance().simulationName); @@ -153,8 +132,9 @@ DRAMSys::DRAMSys(sc_module_name name, } } } + // Instantiate all internal DRAMSys modules: - instantiateModules(simName, pathToResources); + instantiateModules(simName, pathToResources, amconfig); // Connect all internal DRAMSys modules: bindSockets(); @@ -219,7 +199,8 @@ void DRAMSys::setupTlmRecorders(const std::string &traceName, } void DRAMSys::instantiateModules(const std::string &traceName, - const std::string &pathToResources) + const std::string &pathToResources, + const std::string &amconfig) { // The first call to getInstance() creates the Temperature Controller. // The same instance will be accessed by all other modules. @@ -243,7 +224,7 @@ void DRAMSys::instantiateModules(const std::string &traceName, Configuration::getInstance().pECC = ecc; // Create arbiter - arbiter = new Arbiter("arbiter"); + arbiter = new Arbiter("arbiter", pathToResources + "configs/amconfigs/" + amconfig); // Create DRAM std::string memoryType = Configuration::getInstance().memSpec->memoryType; diff --git a/DRAMSys/library/src/simulation/DRAMSys.h b/DRAMSys/library/src/simulation/DRAMSys.h index 3d78fdc3..841dd22b 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.h +++ b/DRAMSys/library/src/simulation/DRAMSys.h @@ -102,7 +102,8 @@ private: void setupTlmRecorders(const std::string &traceName, const std::string &pathToResources); void instantiateModules(const std::string &traceName, - const std::string &pathToResources); + const std::string &pathToResources, + const std::string &amconfig); void bindSockets(); void setupDebugManager(const std::string &traceName); }; diff --git a/DRAMSys/library/src/simulation/dram/DramWideIO.cpp b/DRAMSys/library/src/simulation/dram/DramWideIO.cpp index 71ccca31..f9a25628 100644 --- a/DRAMSys/library/src/simulation/dram/DramWideIO.cpp +++ b/DRAMSys/library/src/simulation/dram/DramWideIO.cpp @@ -157,7 +157,15 @@ DramWideIO::DramWideIO(sc_module_name name) : Dram(name) else { if (storeMode == StorageMode::ErrorModel) - SC_REPORT_FATAL("DramWideIO", "Error modeling without power analysis is not supported"); + { + for (unsigned i = 0; i < memSpec->numberOfBanks; i++) + { + errorModel *em; + std::string errorModelStr = "errorModel_bank" + std::to_string(i); + em = new errorModel(errorModelStr.c_str()); + ememory.push_back(em); + } + } } } From 8447d22fc11eb3faa30455be0e6598c75ac9f559 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 8 Apr 2020 16:52:58 +0200 Subject: [PATCH 5/9] Removed old address decoders. --- .../src/common/CongenAddressDecoder.cpp | 365 ------------------ .../library/src/common/CongenAddressDecoder.h | 94 ----- .../library/src/common/XmlAddressDecoder.cpp | 188 --------- .../library/src/common/XmlAddressDecoder.h | 91 ----- 4 files changed, 738 deletions(-) delete mode 100644 DRAMSys/library/src/common/CongenAddressDecoder.cpp delete mode 100644 DRAMSys/library/src/common/CongenAddressDecoder.h delete mode 100644 DRAMSys/library/src/common/XmlAddressDecoder.cpp delete mode 100644 DRAMSys/library/src/common/XmlAddressDecoder.h diff --git a/DRAMSys/library/src/common/CongenAddressDecoder.cpp b/DRAMSys/library/src/common/CongenAddressDecoder.cpp deleted file mode 100644 index b7051527..00000000 --- a/DRAMSys/library/src/common/CongenAddressDecoder.cpp +++ /dev/null @@ -1,365 +0,0 @@ -/* - * Copyright (c) 2018, University of Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: - * Johannes Feldmann - */ - -#include -#include -#include - -#include "CongenAddressDecoder.h" -#include "utils.h" -#include "../configuration/Configuration.h" - -tinyxml2::XMLElement *CongenAddressDecoder::getXMLNode(tinyxml2::XMLElement - *pRoot, std::string strName) -{ - tinyxml2::XMLElement *pNode = pRoot->FirstChildElement(strName.c_str()); - if (pNode == nullptr) { - reportFatal("ConGenAddressDecorder", - "XML File corrupted. Missing node " + strName + "."); - } - return pNode; -} - -unsigned int CongenAddressDecoder::getUnsignedTextFromXMLNode( - tinyxml2::XMLElement *pRoot) -{ - std::string str = pRoot->GetText(); - if (str.empty() || std::find_if(str.begin(), str.end(), [](char c) { - return !std::isdigit(c); - }) != str.end()) { - reportFatal("ConGenAddressDecoder", - "Node " + std::string(pRoot->Name()) + " is empty or not a number."); - return (unsigned)(-1); - } - return atol(str.c_str()); -} - -unsigned int CongenAddressDecoder::getUnsignedAttrFromXMLNode( - tinyxml2::XMLElement *pRoot, std::string strName) -{ - std::string str = pRoot->Attribute(strName.c_str()); - if (str.empty() || std::find_if(str.begin(), str.end(), [](char c) { - return !std::isdigit(c); - }) != str.end()) { - reportFatal("ConGenAddressDecoder", - "Attribute " + strName + " is empty or not a number."); - return (unsigned)(-1); - } - return atol(str.c_str()); -} - -void CongenAddressDecoder::setConfiguration(std::string url) -{ - tinyxml2::XMLDocument doc; - loadXML(url, doc); - tinyxml2::XMLElement *pRoot = doc.RootElement(); - std::string xmlNodeName(pRoot->Name()); - - if (xmlNodeName != "CONGEN") - reportFatal("ConGenAddressDecorder", - "Root node name differs from \"CONGEN\". File format not supported."); - - // Load address mapping - tinyxml2::XMLElement *pNode; - - for (pNode = pRoot->FirstChildElement("SOLUTION"); pNode != nullptr; - pNode = pNode->NextSiblingElement("SOLUTION")) - { - if (getUnsignedAttrFromXMLNode(pNode, "ID") == 0) - break; // Correct mapping was found. - } - - // If no mapping was found report error - if (pNode == nullptr) - SC_REPORT_FATAL("ConGenAddressDecoder", "No mapping with ID 0 was found."); - - // get XOR connections - // An XOR connection needs two parameters: A bank bit and a Row bit. - for (tinyxml2::XMLElement *pXor = pNode->FirstChildElement("XOR"); - pXor != nullptr; pXor = pXor->NextSiblingElement("XOR")) - { - vXor.push_back(XOR(getUnsignedAttrFromXMLNode(pXor, "BANK"), - getUnsignedAttrFromXMLNode(pXor, "ROW"))); - } - - unsigned counter = 0; - for (tinyxml2::XMLElement *pChannel = pNode->FirstChildElement("CHANNEL_BIT"); - pChannel != nullptr; pChannel = pChannel->NextSiblingElement("CHANNEL_BIT")) - { - unsigned nChannel = getUnsignedTextFromXMLNode(pChannel); - vChannelBits.push_back(std::pair(counter++, nChannel)); - } - - counter = 0; - for (tinyxml2::XMLElement *pRank = pNode->FirstChildElement("RANK_BIT"); - pRank != nullptr; pRank = pRank->NextSiblingElement("RANK_BIT")) - { - unsigned nRank = getUnsignedTextFromXMLNode(pRank); - vRankBits.push_back(std::pair(counter++, nRank)); - } - - counter = 0; - for (tinyxml2::XMLElement *pBankGroup = pNode->FirstChildElement("BANKGROUP_BIT"); - pBankGroup != nullptr; pBankGroup = pBankGroup->NextSiblingElement("BANKGROUP_BIT")) - { - unsigned nBankGroup = getUnsignedTextFromXMLNode(pBankGroup); - vBankGroupBits.push_back(std::pair(counter++, nBankGroup)); - } - - // get all bank bits - // Each bank bit of the address will be stored with a counter value which assigns the bit position DecodedAddress struct. - counter = 0; - for (tinyxml2::XMLElement *pBank = pNode->FirstChildElement("BANK_BIT"); - pBank != nullptr; pBank = pBank->NextSiblingElement("BANK_BIT")) - { - unsigned nBank = getUnsignedTextFromXMLNode(pBank); - vBankBits.push_back(std::pair(counter++, nBank)); - } - - // get all row bits bits - // Each Row bit of the address will be stored with a counter value which assigns the bit position DecodedAddress struct. - counter = 0; - for (tinyxml2::XMLElement *pRow = pNode->FirstChildElement("ROW_BIT"); - pRow != nullptr; pRow = pRow->NextSiblingElement("ROW_BIT")) { - unsigned nRow = getUnsignedTextFromXMLNode(pRow); - vRowBits.push_back(std::pair(counter++, nRow)); - } - - counter = 0; - for (tinyxml2::XMLElement *pColumn = pNode->FirstChildElement("COLUMN_BIT"); - pColumn != nullptr; pColumn = pColumn->NextSiblingElement("COLUMN_BIT")) - { - unsigned nColumn = getUnsignedTextFromXMLNode(pColumn); - vColumnBits.push_back(std::pair(counter++, nColumn)); - } - - counter = 0; - for (tinyxml2::XMLElement *pByte = pNode->FirstChildElement("BYTE_BIT"); - pByte != nullptr; pByte = pByte->NextSiblingElement("BYTE_BIT")) - { - unsigned nByte = getUnsignedTextFromXMLNode(pByte); - vByteBits.push_back(std::pair(counter++, nByte)); - } - - // Fill the amount map. This is copied from xmlAddressDecoder without further investigation - amount.channel = pow(2.0, vChannelBits.size()); - amount.rank = pow(2.0, vRankBits.size()); - amount.bankgroup = pow(2.0, vBankGroupBits.size()); - amount.bank = pow(2.0, vBankBits.size()); - amount.row = pow(2.0, vRowBits.size()); - amount.column = pow(2.0, vColumnBits.size()); - amount.bytes = pow(2.0, vByteBits.size()); - - banksPerGroup = amount.bank; - amount.bank = banksPerGroup * amount.bankgroup * amount.rank; - - bankgroupsPerRank = amount.bankgroup; - amount.bankgroup = bankgroupsPerRank * amount.rank; - - maximumAddress = amount.bytes * amount.column * amount.row * banksPerGroup * bankgroupsPerRank * amount.rank * amount.channel - 1; - - Configuration &config = Configuration::getInstance(); - MemSpec *memSpec = config.memSpec; - - if (config.numberOfMemChannels != amount.channel || memSpec->numberOfRanks != amount.rank - || memSpec->numberOfBankGroups != amount.bankgroup || memSpec->numberOfBanks != amount.bank - || memSpec->numberOfRows != amount.row || memSpec->numberOfColumns != amount.column - || config.numberOfDevicesOnDIMM * memSpec->bitWidth != amount.bytes * 8) - SC_REPORT_FATAL("CongenAddressDecoder", "Memspec and addressmapping do not match"); -} - -DecodedAddress CongenAddressDecoder::decodeAddress(uint64_t encAddr) -{ - if (encAddr > maximumAddress) - SC_REPORT_WARNING("CongenAddressDecoder", ("Address " + std::to_string(encAddr) + " out of range (maximum address is " + std::to_string(maximumAddress) + ")").c_str()); - - // Apply XOR - // For each used xor: - // Get the bank bit and row bit. Apply a bitwise xor operator and save it back to the bank bit. - for (auto it = vXor.begin(); it != vXor.end(); it++) - { - unsigned new_bank_bit; - // Bank Row - new_bank_bit = (((encAddr >> it->nBank) & 1) ^ ((encAddr >> it->nRow) & 1)); - encAddr &= ~(1 << it->nBank); - encAddr |= new_bank_bit << it->nBank; - } - - DecodedAddress decAddr; - - decAddr.channel = 0; - for (auto it = vChannelBits.begin(); it != vChannelBits.end(); it++) - decAddr.channel |= ((encAddr >> it->second) & 1) << it->first; - - decAddr.rank = 0; - for (auto it = vRankBits.begin(); it != vRankBits.end(); it++) - decAddr.rank |= ((encAddr >> it->second) & 1) << it->first; - - decAddr.bankgroup = 0; - for (auto it = vBankGroupBits.begin(); it != vBankGroupBits.end(); it++) - decAddr.bankgroup |= ((encAddr >> it->second) & 1) << it->first; - - // Bank - // it->second: position of the target bit in the address - // it->first: target position of the bit in the variable - // For each bank bit: - // shift address bit to position 0. Clear all other bits. shift it the right bank bit. Add it to the set of bank bits. - decAddr.bank = 0; - for (auto it = vBankBits.begin(); it != vBankBits.end(); it++) - decAddr.bank |= ((encAddr >> it->second) & 1) << it->first; - - // Row - // it->second: position of the target bit in the address - // it->first: target position of the bit in the variable - // For each row bit: - // shift address bit to position 0. Clear all other bits. shift it the right row bit. Add it to the set of row bits. - decAddr.row = 0; - for (auto it = vRowBits.begin(); it != vRowBits.end(); it++) - decAddr.row |= ((encAddr >> it->second) & 1) << it->first; - - // Column - // it->second: position of the target bit in the address - // it->first: target position of the bit in the variable - // For each column bit: - // shift address bit to position 0. Clear all other bits. shift it the right column bit. Add it to the set of column bits. - decAddr.column = 0; - for (auto it = vColumnBits.begin(); it != vColumnBits.end(); it++) - decAddr.column |= ((encAddr >> it->second) & 1) << it->first; - - decAddr.bankgroup = decAddr.bankgroup + decAddr.rank * bankgroupsPerRank; - decAddr.bank = decAddr.bank + decAddr.bankgroup * banksPerGroup; - - return decAddr; -} - -uint64_t CongenAddressDecoder::encodeAddress(DecodedAddress decAddr) -{ - decAddr.bankgroup = decAddr.bankgroup % bankgroupsPerRank; - decAddr.bank = decAddr.bank % banksPerGroup; - - uint64_t encAddr = 0; - - for (auto it = vChannelBits.begin(); it != vChannelBits.end(); it++) - encAddr |= ((decAddr.channel >> it->first) & 1) << it->second; - - for (auto it = vRankBits.begin(); it != vRankBits.end(); it++) - encAddr |= ((decAddr.rank >> it->first) & 1) << it->second; - - for (auto it = vBankGroupBits.begin(); it != vBankGroupBits.end(); it++) - encAddr |= ((decAddr.bankgroup >> it->first) & 1) << it->second; - - // Bank - // it->first: position of the target bit in the DecodedAddress struct field - // it->second: target position of the bit in the address - // For each bank bit: - // shift bank bit to position 0. Clear all other bits. shift it the right address bit. Add it to the set of address bits. - for (auto it = vBankBits.begin(); it != vBankBits.end(); it++) - encAddr |= ((decAddr.bank >> it->first) & 1) << it->second; - - // Row - // it->first: position of the target bit in the DecodedAddress struct field - // it->second: target position of the bit in the address - // For each row bit: - // shift row bit to position 0. Clear all other bits. shift it the right address bit. Add it to the set of address bits. - for (auto it = vRowBits.begin(); it != vRowBits.end(); it++) - encAddr |= ((decAddr.row >> it->first) & 1) << it->second; - - // Column - // it->first: position of the target bit in the DecodedAddress struct field - // it->second: target position of the bit in the address - // For each column bit: - // shift column bit to position 0. Clear all other bits. shift it the right address bit. Add it to the set of address bits. - for (auto it = vColumnBits.begin(); it != vColumnBits.end(); it++) - encAddr |= ((decAddr.column >> it->first) & 1) << it->second; - - for (auto it = vByteBits.begin(); it != vByteBits.end(); it++) - encAddr |= ((decAddr.bytes >> it->first) & 1) << it->second; - - // Apply XOR - // For each used xor: - // Get the bank bit and row bit. Apply a bitwise xor operator and save it back to the bank bit. - for (auto it = vXor.begin(); it != vXor.end(); it++) - { - unsigned new_bank_bit; - new_bank_bit = (((encAddr >> it->nBank) & 1) ^ ((encAddr >> it->nRow) & 1)); - encAddr &= ~(1 << it->nBank); - encAddr |= new_bank_bit << it->nBank; - } - - return encAddr; -} - -bool CongenAddressDecoder::testConfigFile(std::string url) -{ - // Simple test if the root node has the correct name. - // This is suitable for now, but can be extended in future. - - tinyxml2::XMLDocument doc; - loadXML(url, doc); - tinyxml2::XMLElement *pRoot = doc.RootElement(); - - return (strcmp(pRoot->Name(), "CONGEN") == 0); -} - -void CongenAddressDecoder::print() -{ - std::map> output; - - for (auto it = vBankBits.begin(); it != vBankBits.end(); it++) { - output[it->second] = std::pair(it->first, 'B'); - } - for (auto it = vRowBits.begin(); it != vRowBits.end(); it++) { - output[it->second] = std::pair(it->first, 'R'); - } - for (auto it = vColumnBits.begin(); it != vColumnBits.end(); it++) { - output[it->second] = std::pair(it->first, 'C'); - } - - // add byte bits - output[0] = std::pair(0, 'b'); - output[1] = std::pair(1, 'b'); - output[2] = std::pair(2, 'b'); - - std::cout << "Used addressmapping:" << std::endl; - std::cout << headline << std::endl; - for (unsigned i = 0; i < 32; i++) { - std::cout << " " << i << " "; - } - std::cout << std::endl; - for (unsigned i = 0; i < 32; i++) { - std::cout << " " << output[i].second << "(" << output[i].first << ") "; - } - std::cout << std::endl; -} diff --git a/DRAMSys/library/src/common/CongenAddressDecoder.h b/DRAMSys/library/src/common/CongenAddressDecoder.h deleted file mode 100644 index 100ae350..00000000 --- a/DRAMSys/library/src/common/CongenAddressDecoder.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2018, University of Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: - * Johannes Feldmann - */ - -#ifndef CONGENADDRESSDECODER_H -#define CONGENADDRESSDECODER_H - -#include "AddressDecoder.h" - -#include "third_party/tinyxml2/tinyxml2.h" - -#include -#include - -class CongenAddressDecoder : private AddressDecoder -{ - // Friendship needed so that the AddressDecoder can access the - // constructor of this class to create the object in CreateInstance. - friend class AddressDecoder; - -public: - struct XOR - { - unsigned nBank; - unsigned nRow; - XOR() {} - XOR(unsigned bank, unsigned row) : nBank(bank), nRow(row) {} - }; - -// Member variables -private: - // This container stores for each used xor gate a pair which consists of "First/Number of an address bit which corresponds to a bank" and "Second/Number of an address bit which corresponds to a row" - std::vector vXor; - std::vector> vChannelBits; - std::vector> vRankBits; - std::vector> vBankGroupBits; - // This container stores for each bank bit a pair which consists of "First/Number of the bank bit" and "Second/Number of the address bit" - std::vector> vBankBits; - // This container stores for each row bit a pair which consists of "First/Number of the row bit" and "Second/Number of the address bit" - std::vector> vRowBits; - // This container stores for each column bit a pair which consists of "First/Number of the column bit" and "Second/Number of the address bit" - std::vector> vColumnBits; - std::vector> vByteBits; - -//Methods -private: - tinyxml2::XMLElement *getXMLNode(tinyxml2::XMLElement *pRoot, - std::string strName); - unsigned int getUnsignedTextFromXMLNode(tinyxml2::XMLElement *pRoot); - unsigned int getUnsignedAttrFromXMLNode(tinyxml2::XMLElement *pRoot, - std::string strName); -public: - virtual void setConfiguration(std::string url); - - virtual DecodedAddress decodeAddress(uint64_t addr); - virtual uint64_t encodeAddress(DecodedAddress n); - - static bool testConfigFile(std::string url); - - virtual void print(); -}; - -#endif // CONGENADDRESSDECODER_H diff --git a/DRAMSys/library/src/common/XmlAddressDecoder.cpp b/DRAMSys/library/src/common/XmlAddressDecoder.cpp deleted file mode 100644 index 168f8899..00000000 --- a/DRAMSys/library/src/common/XmlAddressDecoder.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2015, University of Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: - * Janik Schlemminger - * Robert Gernhardt - * Matthias Jung - */ - -#include "XmlAddressDecoder.h" -#include -#include "utils.h" -#include "bitset" -#include "../configuration/Configuration.h" - -using namespace tinyxml2; - -XmlAddressDecoder::XmlAddressDecoder() -{ - addressmapping = NULL; -} - -void XmlAddressDecoder::setConfiguration(std::string addressConfigURI) -{ - tinyxml2::XMLDocument doc; - loadXML(addressConfigURI, doc); - tinyxml2::XMLElement *addressMap = doc.RootElement(); - std::string xmlNodeName(addressMap->Name()); - - if (xmlNodeName != "addressmapping") - reportFatal("AddressDecorder", "addressmap node expected"); - - for (XMLElement *child = addressMap->FirstChildElement(); - child != NULL; child = child->NextSiblingElement()) - { - unsigned from; - unsigned to; - - child->QueryAttribute("from", &from); - child->QueryAttribute("to", &to); - - if (std::strcmp(child->Name(), "channel") == 0) - { - shifts.channel = from; - masks.channel = pow(2.0, to + 1.0) - pow(2.0, from + 0.0); - amount.channel = pow(2.0, to - from + 1.0); - } - else if (std::strcmp(child->Name(), "rank") == 0) - { - shifts.rank = from; - masks.rank = pow(2.0, to + 1.0) - pow(2.0, from + 0.0); - amount.rank = pow(2.0, to - from + 1.0); - } - else if (std::strcmp(child->Name(), "bankgroup") == 0) - { - shifts.bankgroup = from; - masks.bankgroup = pow(2.0, to + 1.0) - pow(2.0, from + 0.0); - amount.bankgroup = pow(2.0, to - from + 1.0); - } - else if (std::strcmp(child->Name(), "bank") == 0) - { - shifts.bank = from; - masks.bank = pow(2.0, to + 1.0) - pow(2.0, from + 0.0); - amount.bank = pow(2.0, to - from + 1.0); - } - else if (std::strcmp(child->Name(), "row") == 0) - { - shifts.row = from; - masks.row = pow(2.0, to + 1.0) - pow(2.0, from + 0.0); - amount.row = pow(2.0, to - from + 1.0); - } - else if (std::strcmp(child->Name(), "column") == 0) - { - shifts.column = from; - masks.column = pow(2.0, to + 1.0) - pow(2.0, from + 0.0); - amount.column = pow(2.0, to - from + 1.0); - } - else if (std::strcmp(child->Name(), "bytes") == 0) - { - shifts.bytes = from; - masks.bytes = pow(2.0, to + 1.0) - pow(2.0, from + 0.0); - amount.bytes = pow(2.0, to - from + 1.0); - } - else - SC_REPORT_FATAL("XmlAddressDecoder", ("Unknown field " + std::string(child->Name())).c_str()); - } - - banksPerGroup = amount.bank; - amount.bank = banksPerGroup * amount.bankgroup * amount.rank; - - bankgroupsPerRank = amount.bankgroup; - amount.bankgroup = bankgroupsPerRank * amount.rank; - - maximumAddress = amount.bytes * amount.column * amount.row * banksPerGroup * bankgroupsPerRank * amount.rank * amount.channel - 1; - - Configuration &config = Configuration::getInstance(); - MemSpec *memSpec = config.memSpec; - - if (config.numberOfMemChannels != amount.channel || memSpec->numberOfRanks != amount.rank - || memSpec->numberOfBankGroups != amount.bankgroup || memSpec->numberOfBanks != amount.bank - || memSpec->numberOfRows != amount.row || memSpec->numberOfColumns != amount.column - || config.numberOfDevicesOnDIMM * memSpec->bitWidth != amount.bytes * 8) - SC_REPORT_FATAL("XmlAddressDecoder", "Memspec and addressmapping do not match"); -} - - -DecodedAddress XmlAddressDecoder::decodeAddress(uint64_t encAddr) -{ - if (encAddr > maximumAddress) - SC_REPORT_WARNING("XmlAddressDecoder", ("Address " + std::to_string(encAddr) + " out of range (maximum address is " + std::to_string(maximumAddress) + ")").c_str()); - - DecodedAddress result; - result.channel = (encAddr & masks.channel) >> shifts.channel; - result.rank = (encAddr & masks.rank) >> shifts.rank; - result.bankgroup = ((encAddr & masks.bankgroup) >> shifts.bankgroup) - + result.rank * bankgroupsPerRank; - result.bank = ((encAddr & masks.bank) >> shifts.bank) - + result.bankgroup * banksPerGroup; - result.row = (encAddr & masks.row) >> shifts.row; - result.column = (encAddr & masks.column) >> shifts.column; - result.bytes = (encAddr & masks.bytes) >> shifts.bytes; - return result; -} - -uint64_t XmlAddressDecoder::encodeAddress(DecodedAddress decAddr) -{ - return (decAddr.channel << shifts.channel) | - (decAddr.rank << shifts.rank) | - ((decAddr.bankgroup % bankgroupsPerRank) << shifts.bankgroup) | - ((decAddr.bank % banksPerGroup) << shifts.bank) | - (decAddr.row << shifts.row) | - (decAddr.column << shifts.column) | - (decAddr.bytes << shifts.bytes); -} - -bool XmlAddressDecoder::testConfigFile(std::string url) -{ - // Simple test if the root node has the correct name. - // This is suitable for now, but can be extended in future. - - tinyxml2::XMLDocument doc; - loadXML(url, doc); - tinyxml2::XMLElement *addressMap = doc.RootElement(); - - return (strcmp(addressMap->Name(), "addressmapping") == 0); -} - -void XmlAddressDecoder::print() -{ - std::cout << headline << std::endl; - std::cout << "Address Mapping:" << std::endl << std::endl; - std::cout << " channel: " << std::bitset<64>(masks.channel) << std::endl; - std::cout << " rank: " << std::bitset<64>(masks.rank) << std::endl; - std::cout << " bankgroup: " << std::bitset<64>(masks.bankgroup) << std::endl; - std::cout << " bank: " << std::bitset<64>(masks.bank) << std::endl; - std::cout << " row: " << std::bitset<64>(masks.row) << std::endl; - std::cout << " column: " << std::bitset<64>(masks.column) << std::endl; - std::cout << " bytes: " << std::bitset<64>(masks.bytes) << std::endl; - std::cout << std::endl; -} diff --git a/DRAMSys/library/src/common/XmlAddressDecoder.h b/DRAMSys/library/src/common/XmlAddressDecoder.h deleted file mode 100644 index a733ca05..00000000 --- a/DRAMSys/library/src/common/XmlAddressDecoder.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2015, University of Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: - * Janik Schlemminger - * Robert Gernhardt - * Matthias Jung - */ - -#ifndef XMLADDRESSDECODER_H -#define XMLADDRESSDECODER_H - -#include - -#include "utils.h" -#include "third_party/tinyxml2/tinyxml2.h" -#include "AddressDecoder.h" - -class XmlAddressDecoder : private AddressDecoder -{ - // Friendship needed so that the AddressDecoder can access the - // constructor of this class to create the object in CreateInstance. - friend class AddressDecoder; - -private: - tinyxml2::XMLElement *addressmapping; - - struct Masks - { - uint64_t channel = 0; - uint64_t rank = 0; - uint64_t bankgroup = 0; - uint64_t bank = 0; - uint64_t row = 0; - uint64_t column = 0; - uint64_t bytes = 0; - } masks; - - struct Shifts - { - unsigned channel = 0; - unsigned rank = 0; - unsigned bankgroup = 0; - unsigned bank = 0; - unsigned row = 0; - unsigned column = 0; - unsigned bytes = 0; - } shifts; - -public: - XmlAddressDecoder(); - - virtual void setConfiguration(std::string url); - - virtual DecodedAddress decodeAddress(uint64_t addr); - virtual uint64_t encodeAddress(DecodedAddress n); - - static bool testConfigFile(std::string url); - - virtual void print(); -}; - -#endif // XMLADDRESSDECODER_H From 5445ba36f41b4ca863a498c1656d9abd95bacba6 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 8 Apr 2020 17:17:09 +0200 Subject: [PATCH 6/9] Minor changes (renaming). --- DRAMSys/library/src/common/AddressDecoder.cpp | 54 ++++--------------- DRAMSys/library/src/simulation/Arbiter.cpp | 35 +++--------- DRAMSys/library/src/simulation/Arbiter.h | 2 - 3 files changed, 15 insertions(+), 76 deletions(-) diff --git a/DRAMSys/library/src/common/AddressDecoder.cpp b/DRAMSys/library/src/common/AddressDecoder.cpp index d54352a4..6855b87f 100644 --- a/DRAMSys/library/src/common/AddressDecoder.cpp +++ b/DRAMSys/library/src/common/AddressDecoder.cpp @@ -43,7 +43,7 @@ tinyxml2::XMLElement *AddressDecoder::getXMLNode(tinyxml2::XMLElement { tinyxml2::XMLElement *pNode = pRoot->FirstChildElement(strName.c_str()); if (pNode == nullptr) { - reportFatal("ConGenAddressDecorder", + reportFatal("AddressDecorder", "XML File corrupted. Missing node " + strName + "."); } return pNode; @@ -56,7 +56,7 @@ unsigned int AddressDecoder::getUnsignedTextFromXMLNode( if (str.empty() || std::find_if(str.begin(), str.end(), [](char c) { return !std::isdigit(c); }) != str.end()) { - reportFatal("ConGenAddressDecoder", + reportFatal("AddressDecoder", "Node " + std::string(pRoot->Name()) + " is empty or not a number."); return (unsigned)(-1); } @@ -70,7 +70,7 @@ unsigned int AddressDecoder::getUnsignedAttrFromXMLNode( if (str.empty() || std::find_if(str.begin(), str.end(), [](char c) { return !std::isdigit(c); }) != str.end()) { - reportFatal("ConGenAddressDecoder", + reportFatal("AddressDecoder", "Attribute " + strName + " is empty or not a number."); return (unsigned)(-1); } @@ -85,7 +85,7 @@ AddressDecoder::AddressDecoder(std::string pathToAddressMapping) std::string xmlNodeName(pRoot->Name()); if (xmlNodeName != "CONGEN") - reportFatal("ConGenAddressDecorder", + reportFatal("AddressDecorder", "Root node name differs from \"CONGEN\". File format not supported."); // Load address mapping @@ -95,12 +95,11 @@ AddressDecoder::AddressDecoder(std::string pathToAddressMapping) pNode = pNode->NextSiblingElement("SOLUTION")) { if (getUnsignedAttrFromXMLNode(pNode, "ID") == 0) - break; // Correct mapping was found. + break; } - // If no mapping was found report error if (pNode == nullptr) - SC_REPORT_FATAL("ConGenAddressDecoder", "No mapping with ID 0 was found."); + SC_REPORT_FATAL("AddressDecoder", "No mapping with ID 0 was found."); // get XOR connections // An XOR connection needs two parameters: A bank bit and a Row bit. @@ -135,8 +134,6 @@ AddressDecoder::AddressDecoder(std::string pathToAddressMapping) vBankGroupBits.push_back(std::pair(counter++, nBankGroup)); } - // get all bank bits - // Each bank bit of the address will be stored with a counter value which assigns the bit position DecodedAddress struct. counter = 0; for (tinyxml2::XMLElement *pBank = pNode->FirstChildElement("BANK_BIT"); pBank != nullptr; pBank = pBank->NextSiblingElement("BANK_BIT")) @@ -145,8 +142,6 @@ AddressDecoder::AddressDecoder(std::string pathToAddressMapping) vBankBits.push_back(std::pair(counter++, nBank)); } - // get all row bits bits - // Each Row bit of the address will be stored with a counter value which assigns the bit position DecodedAddress struct. counter = 0; for (tinyxml2::XMLElement *pRow = pNode->FirstChildElement("ROW_BIT"); pRow != nullptr; pRow = pRow->NextSiblingElement("ROW_BIT")) { @@ -170,7 +165,6 @@ AddressDecoder::AddressDecoder(std::string pathToAddressMapping) vByteBits.push_back(std::pair(counter++, nByte)); } - // Fill the amount map. This is copied from xmlAddressDecoder without further investigation amount.channel = pow(2.0, vChannelBits.size()); amount.rank = pow(2.0, vRankBits.size()); amount.bankgroup = pow(2.0, vBankGroupBits.size()); @@ -194,13 +188,13 @@ AddressDecoder::AddressDecoder(std::string pathToAddressMapping) || memSpec->numberOfBankGroups != amount.bankgroup || memSpec->numberOfBanks != amount.bank || memSpec->numberOfRows != amount.row || memSpec->numberOfColumns != amount.column || config.numberOfDevicesOnDIMM * memSpec->bitWidth != amount.bytes * 8) - SC_REPORT_FATAL("CongenAddressDecoder", "Memspec and addressmapping do not match"); + SC_REPORT_FATAL("AddressDecoder", "Memspec and address mapping do not match"); } DecodedAddress AddressDecoder::decodeAddress(uint64_t encAddr) { -// if (encAddr > maximumAddress) -// SC_REPORT_WARNING("CongenAddressDecoder", ("Address " + std::to_string(encAddr) + " out of range (maximum address is " + std::to_string(maximumAddress) + ")").c_str()); + if (encAddr > maximumAddress) + SC_REPORT_WARNING("AddressDecoder", ("Address " + std::to_string(encAddr) + " out of range (maximum address is " + std::to_string(maximumAddress) + ")").c_str()); // Apply XOR // For each used xor: @@ -228,29 +222,14 @@ DecodedAddress AddressDecoder::decodeAddress(uint64_t encAddr) for (auto it = vBankGroupBits.begin(); it != vBankGroupBits.end(); it++) decAddr.bankgroup |= ((encAddr >> it->second) & 1) << it->first; - // Bank - // it->second: position of the target bit in the address - // it->first: target position of the bit in the variable - // For each bank bit: - // shift address bit to position 0. Clear all other bits. shift it the right bank bit. Add it to the set of bank bits. decAddr.bank = 0; for (auto it = vBankBits.begin(); it != vBankBits.end(); it++) decAddr.bank |= ((encAddr >> it->second) & 1) << it->first; - // Row - // it->second: position of the target bit in the address - // it->first: target position of the bit in the variable - // For each row bit: - // shift address bit to position 0. Clear all other bits. shift it the right row bit. Add it to the set of row bits. decAddr.row = 0; for (auto it = vRowBits.begin(); it != vRowBits.end(); it++) decAddr.row |= ((encAddr >> it->second) & 1) << it->first; - // Column - // it->second: position of the target bit in the address - // it->first: target position of the bit in the variable - // For each column bit: - // shift address bit to position 0. Clear all other bits. shift it the right column bit. Add it to the set of column bits. decAddr.column = 0; for (auto it = vColumnBits.begin(); it != vColumnBits.end(); it++) decAddr.column |= ((encAddr >> it->second) & 1) << it->first; @@ -277,27 +256,12 @@ uint64_t AddressDecoder::encodeAddress(DecodedAddress decAddr) for (auto it = vBankGroupBits.begin(); it != vBankGroupBits.end(); it++) encAddr |= ((decAddr.bankgroup >> it->first) & 1) << it->second; - // Bank - // it->first: position of the target bit in the DecodedAddress struct field - // it->second: target position of the bit in the address - // For each bank bit: - // shift bank bit to position 0. Clear all other bits. shift it the right address bit. Add it to the set of address bits. for (auto it = vBankBits.begin(); it != vBankBits.end(); it++) encAddr |= ((decAddr.bank >> it->first) & 1) << it->second; - // Row - // it->first: position of the target bit in the DecodedAddress struct field - // it->second: target position of the bit in the address - // For each row bit: - // shift row bit to position 0. Clear all other bits. shift it the right address bit. Add it to the set of address bits. for (auto it = vRowBits.begin(); it != vRowBits.end(); it++) encAddr |= ((decAddr.row >> it->first) & 1) << it->second; - // Column - // it->first: position of the target bit in the DecodedAddress struct field - // it->second: target position of the bit in the address - // For each column bit: - // shift column bit to position 0. Clear all other bits. shift it the right address bit. Add it to the set of address bits. for (auto it = vColumnBits.begin(); it != vColumnBits.end(); it++) encAddr |= ((decAddr.column >> it->first) & 1) << it->second; diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp index d13737ab..73810df7 100644 --- a/DRAMSys/library/src/simulation/Arbiter.cpp +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -217,33 +217,10 @@ void Arbiter::appendDramExtension(int socketId, tlm_generic_payload &payload) unsigned int burstlength = payload.get_streaming_width(); DecodedAddress decodedAddress = addressDecoder->decodeAddress(payload.get_address()); - // Check the valid range of decodedAddress - if (addressIsValid(decodedAddress)) { - DramExtension *extension = new DramExtension(Thread(socketId), - Channel(decodedAddress.channel), Rank(decodedAddress.rank), - BankGroup(decodedAddress.bankgroup), Bank(decodedAddress.bank), - Row(decodedAddress.row), Column(decodedAddress.column), - burstlength, nextPayloadID[decodedAddress.channel]++); - payload.set_auto_extension(extension); - } else { - SC_REPORT_FATAL("Arbiter", "Decoded Address is not inside the valid range"); - } -} - -//TODO: this part should be checked inside the address decoder! -bool Arbiter::addressIsValid(DecodedAddress &decodedAddress) -{ - if (decodedAddress.channel >= addressDecoder->amount.channel) - return false; - if (decodedAddress.rank >= addressDecoder->amount.rank) - return false; - if (decodedAddress.bankgroup >= addressDecoder->amount.bankgroup) - return false; - if (decodedAddress.bank >= addressDecoder->amount.bank) - return false; - if (decodedAddress.row >= addressDecoder->amount.row) - return false; - if (decodedAddress.column >= addressDecoder->amount.column) - return false; - return true; + DramExtension *extension = new DramExtension(Thread(socketId), + Channel(decodedAddress.channel), Rank(decodedAddress.rank), + BankGroup(decodedAddress.bankgroup), Bank(decodedAddress.bank), + Row(decodedAddress.row), Column(decodedAddress.column), + burstlength, nextPayloadID[decodedAddress.channel]++); + payload.set_auto_extension(extension); } diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index 4a129b46..2e0ab39d 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -95,8 +95,6 @@ private: void appendDramExtension(int socketId, tlm::tlm_generic_payload &payload); std::vector nextPayloadID; - - bool addressIsValid(DecodedAddress &decodedAddress); }; #endif // ARBITER_H From 102b89fa62f8ed898cb204e73049b088fc0cb3a2 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Thu, 9 Apr 2020 15:17:46 +0200 Subject: [PATCH 7/9] Generalized XOR from bank and row to first and second. --- DRAMSys/library/src/common/AddressDecoder.cpp | 27 ++++++++++--------- DRAMSys/library/src/common/AddressDecoder.h | 10 +------ 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/DRAMSys/library/src/common/AddressDecoder.cpp b/DRAMSys/library/src/common/AddressDecoder.cpp index 6855b87f..e97ead26 100644 --- a/DRAMSys/library/src/common/AddressDecoder.cpp +++ b/DRAMSys/library/src/common/AddressDecoder.cpp @@ -106,8 +106,8 @@ AddressDecoder::AddressDecoder(std::string pathToAddressMapping) for (tinyxml2::XMLElement *pXor = pNode->FirstChildElement("XOR"); pXor != nullptr; pXor = pXor->NextSiblingElement("XOR")) { - vXor.push_back(XOR(getUnsignedAttrFromXMLNode(pXor, "BANK"), - getUnsignedAttrFromXMLNode(pXor, "ROW"))); + vXor.push_back(std::pair(getUnsignedAttrFromXMLNode(pXor, "FIRST"), + getUnsignedAttrFromXMLNode(pXor, "SECOND"))); } unsigned counter = 0; @@ -179,7 +179,8 @@ AddressDecoder::AddressDecoder(std::string pathToAddressMapping) bankgroupsPerRank = amount.bankgroup; amount.bankgroup = bankgroupsPerRank * amount.rank; - maximumAddress = amount.bytes * amount.column * amount.row * banksPerGroup * bankgroupsPerRank * amount.rank * amount.channel - 1; + maximumAddress = amount.bytes * amount.column * amount.row * + banksPerGroup * bankgroupsPerRank * amount.rank * amount.channel - 1; Configuration &config = Configuration::getInstance(); MemSpec *memSpec = config.memSpec; @@ -193,19 +194,19 @@ AddressDecoder::AddressDecoder(std::string pathToAddressMapping) DecodedAddress AddressDecoder::decodeAddress(uint64_t encAddr) { - if (encAddr > maximumAddress) - SC_REPORT_WARNING("AddressDecoder", ("Address " + std::to_string(encAddr) + " out of range (maximum address is " + std::to_string(maximumAddress) + ")").c_str()); +// if (encAddr > maximumAddress) +// SC_REPORT_WARNING("AddressDecoder", ("Address " + std::to_string(encAddr) + " out of range (maximum address is " + std::to_string(maximumAddress) + ")").c_str()); // Apply XOR // For each used xor: // Get the bank bit and row bit. Apply a bitwise xor operator and save it back to the bank bit. for (auto it = vXor.begin(); it != vXor.end(); it++) { - unsigned new_bank_bit; + unsigned xoredBit; // Bank Row - new_bank_bit = (((encAddr >> it->nBank) & 1) ^ ((encAddr >> it->nRow) & 1)); - encAddr &= ~(1 << it->nBank); - encAddr |= new_bank_bit << it->nBank; + xoredBit = (((encAddr >> it->first) & 1) ^ ((encAddr >> it->second) & 1)); + encAddr &= ~(1 << it->first); + encAddr |= xoredBit << it->first; } DecodedAddress decAddr; @@ -273,10 +274,10 @@ uint64_t AddressDecoder::encodeAddress(DecodedAddress decAddr) // Get the bank bit and row bit. Apply a bitwise xor operator and save it back to the bank bit. for (auto it = vXor.begin(); it != vXor.end(); it++) { - unsigned new_bank_bit; - new_bank_bit = (((encAddr >> it->nBank) & 1) ^ ((encAddr >> it->nRow) & 1)); - encAddr &= ~(1 << it->nBank); - encAddr |= new_bank_bit << it->nBank; + unsigned xoredBit; + xoredBit = (((encAddr >> it->first) & 1) ^ ((encAddr >> it->second) & 1)); + encAddr &= ~(1 << it->first); + encAddr |= xoredBit << it->first; } return encAddr; diff --git a/DRAMSys/library/src/common/AddressDecoder.h b/DRAMSys/library/src/common/AddressDecoder.h index e29d8dd6..1c0a6cf1 100644 --- a/DRAMSys/library/src/common/AddressDecoder.h +++ b/DRAMSys/library/src/common/AddressDecoder.h @@ -94,16 +94,8 @@ private: uint64_t maximumAddress; - struct XOR - { - unsigned nBank; - unsigned nRow; - XOR() {} - XOR(unsigned bank, unsigned row) : nBank(bank), nRow(row) {} - }; - // This container stores for each used xor gate a pair which consists of "First/Number of an address bit which corresponds to a bank" and "Second/Number of an address bit which corresponds to a row" - std::vector vXor; + std::vector> vXor; std::vector> vChannelBits; std::vector> vRankBits; std::vector> vBankGroupBits; From 506c91c06c61e05926afc1f9c35c680b7d08e809 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Thu, 9 Apr 2020 17:42:32 +0200 Subject: [PATCH 8/9] Some simplifications, adapted print() method. --- DRAMSys/library/src/common/AddressDecoder.cpp | 261 ++++++++---------- DRAMSys/library/src/common/AddressDecoder.h | 55 ++-- DRAMSys/library/src/error/errormodel.cpp | 2 +- 3 files changed, 141 insertions(+), 177 deletions(-) diff --git a/DRAMSys/library/src/common/AddressDecoder.cpp b/DRAMSys/library/src/common/AddressDecoder.cpp index e97ead26..92c6cc4d 100644 --- a/DRAMSys/library/src/common/AddressDecoder.cpp +++ b/DRAMSys/library/src/common/AddressDecoder.cpp @@ -34,6 +34,9 @@ * Lukas Steiner */ +#include +#include + #include "AddressDecoder.h" #include "utils.h" #include "../configuration/Configuration.h" @@ -102,7 +105,7 @@ AddressDecoder::AddressDecoder(std::string pathToAddressMapping) SC_REPORT_FATAL("AddressDecoder", "No mapping with ID 0 was found."); // get XOR connections - // An XOR connection needs two parameters: A bank bit and a Row bit. + // An XOR connection needs two parameters: A first bit and a second bit. for (tinyxml2::XMLElement *pXor = pNode->FirstChildElement("XOR"); pXor != nullptr; pXor = pXor->NextSiblingElement("XOR")) { @@ -110,100 +113,71 @@ AddressDecoder::AddressDecoder(std::string pathToAddressMapping) getUnsignedAttrFromXMLNode(pXor, "SECOND"))); } - unsigned counter = 0; for (tinyxml2::XMLElement *pChannel = pNode->FirstChildElement("CHANNEL_BIT"); pChannel != nullptr; pChannel = pChannel->NextSiblingElement("CHANNEL_BIT")) - { - unsigned nChannel = getUnsignedTextFromXMLNode(pChannel); - vChannelBits.push_back(std::pair(counter++, nChannel)); - } + vChannelBits.push_back(getUnsignedTextFromXMLNode(pChannel)); - counter = 0; for (tinyxml2::XMLElement *pRank = pNode->FirstChildElement("RANK_BIT"); pRank != nullptr; pRank = pRank->NextSiblingElement("RANK_BIT")) - { - unsigned nRank = getUnsignedTextFromXMLNode(pRank); - vRankBits.push_back(std::pair(counter++, nRank)); - } + vRankBits.push_back(getUnsignedTextFromXMLNode(pRank)); - counter = 0; for (tinyxml2::XMLElement *pBankGroup = pNode->FirstChildElement("BANKGROUP_BIT"); pBankGroup != nullptr; pBankGroup = pBankGroup->NextSiblingElement("BANKGROUP_BIT")) - { - unsigned nBankGroup = getUnsignedTextFromXMLNode(pBankGroup); - vBankGroupBits.push_back(std::pair(counter++, nBankGroup)); - } + vBankGroupBits.push_back(getUnsignedTextFromXMLNode(pBankGroup)); - counter = 0; for (tinyxml2::XMLElement *pBank = pNode->FirstChildElement("BANK_BIT"); pBank != nullptr; pBank = pBank->NextSiblingElement("BANK_BIT")) - { - unsigned nBank = getUnsignedTextFromXMLNode(pBank); - vBankBits.push_back(std::pair(counter++, nBank)); - } + vBankBits.push_back(getUnsignedTextFromXMLNode(pBank)); - counter = 0; for (tinyxml2::XMLElement *pRow = pNode->FirstChildElement("ROW_BIT"); - pRow != nullptr; pRow = pRow->NextSiblingElement("ROW_BIT")) { - unsigned nRow = getUnsignedTextFromXMLNode(pRow); - vRowBits.push_back(std::pair(counter++, nRow)); - } + pRow != nullptr; pRow = pRow->NextSiblingElement("ROW_BIT")) + vRowBits.push_back(getUnsignedTextFromXMLNode(pRow)); - counter = 0; for (tinyxml2::XMLElement *pColumn = pNode->FirstChildElement("COLUMN_BIT"); pColumn != nullptr; pColumn = pColumn->NextSiblingElement("COLUMN_BIT")) - { - unsigned nColumn = getUnsignedTextFromXMLNode(pColumn); - vColumnBits.push_back(std::pair(counter++, nColumn)); - } + vColumnBits.push_back(getUnsignedTextFromXMLNode(pColumn)); - counter = 0; for (tinyxml2::XMLElement *pByte = pNode->FirstChildElement("BYTE_BIT"); pByte != nullptr; pByte = pByte->NextSiblingElement("BYTE_BIT")) - { - unsigned nByte = getUnsignedTextFromXMLNode(pByte); - vByteBits.push_back(std::pair(counter++, nByte)); - } + vByteBits.push_back(getUnsignedTextFromXMLNode(pByte)); - amount.channel = pow(2.0, vChannelBits.size()); - amount.rank = pow(2.0, vRankBits.size()); - amount.bankgroup = pow(2.0, vBankGroupBits.size()); - amount.bank = pow(2.0, vBankBits.size()); - amount.row = pow(2.0, vRowBits.size()); - amount.column = pow(2.0, vColumnBits.size()); - amount.bytes = pow(2.0, vByteBits.size()); + unsigned channels = pow(2.0, vChannelBits.size()); + unsigned ranks = pow(2.0, vRankBits.size()); + unsigned bankgroups = pow(2.0, vBankGroupBits.size()); + unsigned banks = pow(2.0, vBankBits.size()); + unsigned rows = pow(2.0, vRowBits.size()); + unsigned columns = pow(2.0, vColumnBits.size()); + unsigned bytes = pow(2.0, vByteBits.size()); - banksPerGroup = amount.bank; - amount.bank = banksPerGroup * amount.bankgroup * amount.rank; + maximumAddress = bytes * columns * rows * banks * bankgroups * ranks * channels - 1; - bankgroupsPerRank = amount.bankgroup; - amount.bankgroup = bankgroupsPerRank * amount.rank; + banksPerGroup = banks; + banks = banksPerGroup * bankgroups * ranks; - maximumAddress = amount.bytes * amount.column * amount.row * - banksPerGroup * bankgroupsPerRank * amount.rank * amount.channel - 1; + bankgroupsPerRank = bankgroups; + bankgroups = bankgroupsPerRank * ranks; Configuration &config = Configuration::getInstance(); MemSpec *memSpec = config.memSpec; - if (config.numberOfMemChannels != amount.channel || memSpec->numberOfRanks != amount.rank - || memSpec->numberOfBankGroups != amount.bankgroup || memSpec->numberOfBanks != amount.bank - || memSpec->numberOfRows != amount.row || memSpec->numberOfColumns != amount.column - || config.numberOfDevicesOnDIMM * memSpec->bitWidth != amount.bytes * 8) + if (config.numberOfMemChannels != channels || memSpec->numberOfRanks != ranks + || memSpec->numberOfBankGroups != bankgroups || memSpec->numberOfBanks != banks + || memSpec->numberOfRows != rows || memSpec->numberOfColumns != columns + || config.numberOfDevicesOnDIMM * memSpec->bitWidth != bytes * 8) SC_REPORT_FATAL("AddressDecoder", "Memspec and address mapping do not match"); } DecodedAddress AddressDecoder::decodeAddress(uint64_t encAddr) { -// if (encAddr > maximumAddress) -// SC_REPORT_WARNING("AddressDecoder", ("Address " + std::to_string(encAddr) + " out of range (maximum address is " + std::to_string(maximumAddress) + ")").c_str()); + if (encAddr > maximumAddress) + SC_REPORT_WARNING("AddressDecoder", ("Address " + std::to_string(encAddr) + " out of range (maximum address is " + std::to_string(maximumAddress) + ")").c_str()); // Apply XOR // For each used xor: - // Get the bank bit and row bit. Apply a bitwise xor operator and save it back to the bank bit. + // Get the first bit and second bit. Apply a bitwise xor operator and save it back to the first bit. for (auto it = vXor.begin(); it != vXor.end(); it++) { unsigned xoredBit; - // Bank Row xoredBit = (((encAddr >> it->first) & 1) ^ ((encAddr >> it->second) & 1)); encAddr &= ~(1 << it->first); encAddr |= xoredBit << it->first; @@ -211,29 +185,26 @@ DecodedAddress AddressDecoder::decodeAddress(uint64_t encAddr) DecodedAddress decAddr; - decAddr.channel = 0; - for (auto it = vChannelBits.begin(); it != vChannelBits.end(); it++) - decAddr.channel |= ((encAddr >> it->second) & 1) << it->first; + for (unsigned it = 0; it < vChannelBits.size(); it++) + decAddr.channel |= ((encAddr >> vChannelBits[it]) & 1) << it; - decAddr.rank = 0; - for (auto it = vRankBits.begin(); it != vRankBits.end(); it++) - decAddr.rank |= ((encAddr >> it->second) & 1) << it->first; + for (unsigned it = 0; it < vRankBits.size(); it++) + decAddr.rank |= ((encAddr >> vRankBits[it]) & 1) << it; - decAddr.bankgroup = 0; - for (auto it = vBankGroupBits.begin(); it != vBankGroupBits.end(); it++) - decAddr.bankgroup |= ((encAddr >> it->second) & 1) << it->first; + for (unsigned it = 0; it < vBankGroupBits.size(); it++) + decAddr.bankgroup |= ((encAddr >> vBankGroupBits[it]) & 1) << it; - decAddr.bank = 0; - for (auto it = vBankBits.begin(); it != vBankBits.end(); it++) - decAddr.bank |= ((encAddr >> it->second) & 1) << it->first; + for (unsigned it = 0; it < vBankBits.size(); it++) + decAddr.bank |= ((encAddr >> vBankBits[it]) & 1) << it; - decAddr.row = 0; - for (auto it = vRowBits.begin(); it != vRowBits.end(); it++) - decAddr.row |= ((encAddr >> it->second) & 1) << it->first; + for (unsigned it = 0; it < vRowBits.size(); it++) + decAddr.row |= ((encAddr >> vRowBits[it]) & 1) << it; - decAddr.column = 0; - for (auto it = vColumnBits.begin(); it != vColumnBits.end(); it++) - decAddr.column |= ((encAddr >> it->second) & 1) << it->first; + for (unsigned it = 0; it < vColumnBits.size(); it++) + decAddr.column |= ((encAddr >> vColumnBits[it]) & 1) << it; + + for (unsigned it = 0; it < vByteBits.size(); it++) + decAddr.byte |= ((encAddr >> vByteBits[it]) & 1) << it; decAddr.bankgroup = decAddr.bankgroup + decAddr.rank * bankgroupsPerRank; decAddr.bank = decAddr.bank + decAddr.bankgroup * banksPerGroup; @@ -241,77 +212,89 @@ DecodedAddress AddressDecoder::decodeAddress(uint64_t encAddr) return decAddr; } -uint64_t AddressDecoder::encodeAddress(DecodedAddress decAddr) -{ - decAddr.bankgroup = decAddr.bankgroup % bankgroupsPerRank; - decAddr.bank = decAddr.bank % banksPerGroup; - - uint64_t encAddr = 0; - - for (auto it = vChannelBits.begin(); it != vChannelBits.end(); it++) - encAddr |= ((decAddr.channel >> it->first) & 1) << it->second; - - for (auto it = vRankBits.begin(); it != vRankBits.end(); it++) - encAddr |= ((decAddr.rank >> it->first) & 1) << it->second; - - for (auto it = vBankGroupBits.begin(); it != vBankGroupBits.end(); it++) - encAddr |= ((decAddr.bankgroup >> it->first) & 1) << it->second; - - for (auto it = vBankBits.begin(); it != vBankBits.end(); it++) - encAddr |= ((decAddr.bank >> it->first) & 1) << it->second; - - for (auto it = vRowBits.begin(); it != vRowBits.end(); it++) - encAddr |= ((decAddr.row >> it->first) & 1) << it->second; - - for (auto it = vColumnBits.begin(); it != vColumnBits.end(); it++) - encAddr |= ((decAddr.column >> it->first) & 1) << it->second; - - for (auto it = vByteBits.begin(); it != vByteBits.end(); it++) - encAddr |= ((decAddr.bytes >> it->first) & 1) << it->second; - - // Apply XOR - // For each used xor: - // Get the bank bit and row bit. Apply a bitwise xor operator and save it back to the bank bit. - for (auto it = vXor.begin(); it != vXor.end(); it++) - { - unsigned xoredBit; - xoredBit = (((encAddr >> it->first) & 1) ^ ((encAddr >> it->second) & 1)); - encAddr &= ~(1 << it->first); - encAddr |= xoredBit << it->first; - } - - return encAddr; -} - void AddressDecoder::print() { - std::map> output; - - for (auto it = vBankBits.begin(); it != vBankBits.end(); it++) { - output[it->second] = std::pair(it->first, 'B'); - } - for (auto it = vRowBits.begin(); it != vRowBits.end(); it++) { - output[it->second] = std::pair(it->first, 'R'); - } - for (auto it = vColumnBits.begin(); it != vColumnBits.end(); it++) { - output[it->second] = std::pair(it->first, 'C'); - } - - // add byte bits - output[0] = std::pair(0, 'b'); - output[1] = std::pair(1, 'b'); - output[2] = std::pair(2, 'b'); - std::cout << headline << std::endl; std::cout << "Used Address Mapping:" << std::endl; std::cout << std::endl; - for (unsigned i = 0; i < 32; i++) { - std::cout << " " << i << " "; + + for (int it = vChannelBits.size() - 1; it >= 0; it--) + { + uint64_t addressBits = (1 << vChannelBits[it]); + for (auto it2 : vXor) + { + if (it2.first == vChannelBits[it]) + addressBits |= (1 << it2.second); + } + std::cout << " Ch " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl; } - std::cout << std::endl; - for (unsigned i = 0; i < 32; i++) { - std::cout << " " << output[i].second << "(" << output[i].first << ") "; + + for (int it = vRankBits.size() - 1; it >= 0; it--) + { + uint64_t addressBits = (1 << vRankBits[it]); + for (auto it2 : vXor) + { + if (it2.first == vRankBits[it]) + addressBits |= (1 << it2.second); + } + std::cout << " Ra " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl; } + + for (int it = vBankGroupBits.size() - 1; it >= 0; it--) + { + uint64_t addressBits = (1 << vBankGroupBits[it]); + for (auto it2 : vXor) + { + if (it2.first == vBankGroupBits[it]) + addressBits |= (1 << it2.second); + } + std::cout << " Bg " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl; + } + + for (int it = vBankBits.size() - 1; it >= 0; it--) + { + uint64_t addressBits = (1 << vBankBits[it]); + for (auto it2 : vXor) + { + if (it2.first == vBankBits[it]) + addressBits |= (1 << it2.second); + } + std::cout << " Ba " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl; + } + + for (int it = vRowBits.size() - 1; it >= 0; it--) + { + uint64_t addressBits = (1 << vRowBits[it]); + for (auto it2 : vXor) + { + if (it2.first == vRowBits[it]) + addressBits |= (1 << it2.second); + } + std::cout << " Ro " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl; + } + + for (int it = vColumnBits.size() - 1; it >= 0; it--) + { + uint64_t addressBits = (1 << vColumnBits[it]); + for (auto it2 : vXor) + { + if (it2.first == vColumnBits[it]) + addressBits |= (1 << it2.second); + } + std::cout << " Co " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl; + } + + for (int it = vByteBits.size() - 1; it >= 0; it--) + { + uint64_t addressBits = (1 << vByteBits[it]); + for (auto it2 : vXor) + { + if (it2.first == vByteBits[it]) + addressBits |= (1 << it2.second); + } + std::cout << " By " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl; + } + std::cout << std::endl; } diff --git a/DRAMSys/library/src/common/AddressDecoder.h b/DRAMSys/library/src/common/AddressDecoder.h index 1c0a6cf1..21b2d243 100644 --- a/DRAMSys/library/src/common/AddressDecoder.h +++ b/DRAMSys/library/src/common/AddressDecoder.h @@ -51,11 +51,11 @@ struct DecodedAddress unsigned bankgroup, unsigned bank, unsigned row, unsigned column, unsigned bytes) : channel(channel), rank(rank), bankgroup(bankgroup), - bank(bank), row(row), column(column), bytes(bytes) {} + bank(bank), row(row), column(column), byte(bytes) {} DecodedAddress() : channel(0), rank(0), bankgroup(0), - bank(0), row(0), column(0), bytes(0) {} + bank(0), row(0), column(0), byte(0) {} unsigned channel; unsigned rank; @@ -63,56 +63,37 @@ struct DecodedAddress unsigned bank; unsigned row; unsigned column; - unsigned bytes; + unsigned byte; }; class AddressDecoder { public: AddressDecoder(std::string); - DecodedAddress decodeAddress(uint64_t addr); - uint64_t encodeAddress(DecodedAddress n); - void print(); - struct Amount - { - unsigned channel = 1; - unsigned rank = 1; - unsigned bankgroup = 1; - unsigned bank = 1; - unsigned row = 1; - unsigned column = 1; - unsigned bytes = 1; - } amount; - -private: - unsigned banksPerGroup; - unsigned banksPerRank; - unsigned bankgroupsPerRank; - - uint64_t maximumAddress; - - // This container stores for each used xor gate a pair which consists of "First/Number of an address bit which corresponds to a bank" and "Second/Number of an address bit which corresponds to a row" - std::vector> vXor; - std::vector> vChannelBits; - std::vector> vRankBits; - std::vector> vBankGroupBits; - // This container stores for each bank bit a pair which consists of "First/Number of the bank bit" and "Second/Number of the address bit" - std::vector> vBankBits; - // This container stores for each row bit a pair which consists of "First/Number of the row bit" and "Second/Number of the address bit" - std::vector> vRowBits; - // This container stores for each column bit a pair which consists of "First/Number of the column bit" and "Second/Number of the address bit" - std::vector> vColumnBits; - std::vector> vByteBits; - private: tinyxml2::XMLElement *getXMLNode(tinyxml2::XMLElement *pRoot, std::string strName); unsigned int getUnsignedTextFromXMLNode(tinyxml2::XMLElement *pRoot); unsigned int getUnsignedAttrFromXMLNode(tinyxml2::XMLElement *pRoot, std::string strName); + + unsigned banksPerGroup; + unsigned bankgroupsPerRank; + + uint64_t maximumAddress; + + // This container stores for each used xor gate a pair of address bits, the first bit is overwritten with the result + std::vector> vXor; + std::vector vChannelBits; + std::vector vRankBits; + std::vector vBankGroupBits; + std::vector vBankBits; + std::vector vRowBits; + std::vector vColumnBits; + std::vector vByteBits; }; #endif // ADDRESSDECODER_H diff --git a/DRAMSys/library/src/error/errormodel.cpp b/DRAMSys/library/src/error/errormodel.cpp index 01f8d4ec..74b0e5c8 100644 --- a/DRAMSys/library/src/error/errormodel.cpp +++ b/DRAMSys/library/src/error/errormodel.cpp @@ -167,7 +167,7 @@ void errorModel::store(tlm::tlm_generic_payload &trans) std::stringstream msg; msg << "bank: " << key.bank << " group: " << key.bankgroup << " bytes: " << - key.bytes << " channel: " << key.channel << " column: " << key.column << + key.byte << " channel: " << key.channel << " column: " << key.column << " rank: " << key.rank << " row: " << key.row; PRINTDEBUGMESSAGE(name(), msg.str()); From ab0004c2202155e3e8fd8df4bc1357128a0499f5 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Thu, 9 Apr 2020 17:49:45 +0200 Subject: [PATCH 9/9] Added example of new congen address mapping. --- .../configs/amconfigs/congen_extended.xml | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 DRAMSys/library/resources/configs/amconfigs/congen_extended.xml diff --git a/DRAMSys/library/resources/configs/amconfigs/congen_extended.xml b/DRAMSys/library/resources/configs/amconfigs/congen_extended.xml new file mode 100644 index 00000000..42617f4a --- /dev/null +++ b/DRAMSys/library/resources/configs/amconfigs/congen_extended.xml @@ -0,0 +1,36 @@ + + + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + + \ No newline at end of file