diff --git a/DRAMSys/library/CMakeLists.txt b/DRAMSys/library/CMakeLists.txt
index 31729d23..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
@@ -140,11 +138,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/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
diff --git a/DRAMSys/library/src/common/AddressDecoder.cpp b/DRAMSys/library/src/common/AddressDecoder.cpp
index 81ea1252..92c6cc4d 100644
--- a/DRAMSys/library/src/common/AddressDecoder.cpp
+++ b/DRAMSys/library/src/common/AddressDecoder.cpp
@@ -31,32 +31,270 @@
*
* Authors:
* Johannes Feldmann
+ * Lukas Steiner
*/
+#include
+#include
+
#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;
- default:
- throw std::logic_error("Instance type not supported.");
- break;
+ tinyxml2::XMLElement *pNode = pRoot->FirstChildElement(strName.c_str());
+ if (pNode == nullptr) {
+ reportFatal("AddressDecorder",
+ "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("AddressDecoder",
+ "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("AddressDecoder",
+ "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("AddressDecorder",
+ "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;
+ }
+
+ if (pNode == nullptr)
+ SC_REPORT_FATAL("AddressDecoder", "No mapping with ID 0 was found.");
+
+ // get XOR connections
+ // 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"))
+ {
+ vXor.push_back(std::pair(getUnsignedAttrFromXMLNode(pXor, "FIRST"),
+ getUnsignedAttrFromXMLNode(pXor, "SECOND")));
+ }
+
+ for (tinyxml2::XMLElement *pChannel = pNode->FirstChildElement("CHANNEL_BIT");
+ pChannel != nullptr; pChannel = pChannel->NextSiblingElement("CHANNEL_BIT"))
+ vChannelBits.push_back(getUnsignedTextFromXMLNode(pChannel));
+
+ for (tinyxml2::XMLElement *pRank = pNode->FirstChildElement("RANK_BIT");
+ pRank != nullptr; pRank = pRank->NextSiblingElement("RANK_BIT"))
+ vRankBits.push_back(getUnsignedTextFromXMLNode(pRank));
+
+ for (tinyxml2::XMLElement *pBankGroup = pNode->FirstChildElement("BANKGROUP_BIT");
+ pBankGroup != nullptr; pBankGroup = pBankGroup->NextSiblingElement("BANKGROUP_BIT"))
+ vBankGroupBits.push_back(getUnsignedTextFromXMLNode(pBankGroup));
+
+ for (tinyxml2::XMLElement *pBank = pNode->FirstChildElement("BANK_BIT");
+ pBank != nullptr; pBank = pBank->NextSiblingElement("BANK_BIT"))
+ vBankBits.push_back(getUnsignedTextFromXMLNode(pBank));
+
+ for (tinyxml2::XMLElement *pRow = pNode->FirstChildElement("ROW_BIT");
+ pRow != nullptr; pRow = pRow->NextSiblingElement("ROW_BIT"))
+ vRowBits.push_back(getUnsignedTextFromXMLNode(pRow));
+
+ for (tinyxml2::XMLElement *pColumn = pNode->FirstChildElement("COLUMN_BIT");
+ pColumn != nullptr; pColumn = pColumn->NextSiblingElement("COLUMN_BIT"))
+ vColumnBits.push_back(getUnsignedTextFromXMLNode(pColumn));
+
+ for (tinyxml2::XMLElement *pByte = pNode->FirstChildElement("BYTE_BIT");
+ pByte != nullptr; pByte = pByte->NextSiblingElement("BYTE_BIT"))
+ vByteBits.push_back(getUnsignedTextFromXMLNode(pByte));
+
+ 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());
+
+ maximumAddress = bytes * columns * rows * banks * bankgroups * ranks * channels - 1;
+
+ banksPerGroup = banks;
+ banks = banksPerGroup * bankgroups * ranks;
+
+ bankgroupsPerRank = bankgroups;
+ bankgroups = bankgroupsPerRank * ranks;
+
+ Configuration &config = Configuration::getInstance();
+ MemSpec *memSpec = config.memSpec;
+
+ 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());
+
+ // Apply XOR
+ // For each used xor:
+ // 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;
+ xoredBit = (((encAddr >> it->first) & 1) ^ ((encAddr >> it->second) & 1));
+ encAddr &= ~(1 << it->first);
+ encAddr |= xoredBit << it->first;
+ }
+
+ DecodedAddress decAddr;
+
+ for (unsigned it = 0; it < vChannelBits.size(); it++)
+ decAddr.channel |= ((encAddr >> vChannelBits[it]) & 1) << it;
+
+ for (unsigned it = 0; it < vRankBits.size(); it++)
+ decAddr.rank |= ((encAddr >> vRankBits[it]) & 1) << it;
+
+ for (unsigned it = 0; it < vBankGroupBits.size(); it++)
+ decAddr.bankgroup |= ((encAddr >> vBankGroupBits[it]) & 1) << it;
+
+ for (unsigned it = 0; it < vBankBits.size(); it++)
+ decAddr.bank |= ((encAddr >> vBankBits[it]) & 1) << it;
+
+ for (unsigned it = 0; it < vRowBits.size(); it++)
+ decAddr.row |= ((encAddr >> vRowBits[it]) & 1) << it;
+
+ 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;
+
+ return decAddr;
+}
+
+void AddressDecoder::print()
+{
+ std::cout << headline << std::endl;
+ std::cout << "Used Address Mapping:" << std::endl;
+ std::cout << std::endl;
+
+ 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;
+ }
+
+ 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 b49f6e81..21b2d243 100644
--- a/DRAMSys/library/src/common/AddressDecoder.h
+++ b/DRAMSys/library/src/common/AddressDecoder.h
@@ -31,70 +31,69 @@
*
* Authors:
* Johannes Feldmann
+ * Lukas Steiner
*/
#ifndef ADDRESSDECODER_H
#define ADDRESSDECODER_H
-#include
#include
#include
#include
#include