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 +#include -struct DecodedAddress { - DecodedAddress() : channel(0), - rank(0), - bankgroup(0), - row(0), - bank(0), - column(0), - bytes(0) - { - } +#include "third_party/tinyxml2/tinyxml2.h" - unsigned int channel; - unsigned int rank; - unsigned int bankgroup; - unsigned int row; - unsigned int bank; - unsigned int column; - unsigned int bytes; +struct DecodedAddress +{ + 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), byte(bytes) {} + + DecodedAddress() + : channel(0), rank(0), bankgroup(0), + bank(0), row(0), column(0), byte(0) {} + + unsigned channel; + unsigned rank; + unsigned bankgroup; + unsigned bank; + unsigned row; + unsigned column; + unsigned byte; }; class AddressDecoder { public: - enum class Type { - XML, - CONGEN - }; + AddressDecoder(std::string); + DecodedAddress decodeAddress(uint64_t addr); + void print(); -protected: - AddressDecoder() {} +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); - static AddressDecoder *m_pInstance; -public: - static AddressDecoder &getInstance(); - static void createInstance(Type t); + unsigned banksPerGroup; + unsigned bankgroupsPerRank; - virtual void setConfiguration(std::string url) = 0; + uint64_t maximumAddress; - virtual DecodedAddress decodeAddress(uint64_t addr) = 0; - virtual uint64_t encodeAddress(DecodedAddress n) = 0; - - virtual void print() = 0; - - struct Amount - { - unsigned channel = 1; - unsigned rank = 1; - unsigned bankgroup = 1; - unsigned bank = 1; - unsigned row = 1; - unsigned column = 1; - unsigned bytes = 1; - } amount; + // 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/common/CongenAddressDecoder.cpp b/DRAMSys/library/src/common/CongenAddressDecoder.cpp deleted file mode 100644 index 46613007..00000000 --- a/DRAMSys/library/src/common/CongenAddressDecoder.cpp +++ /dev/null @@ -1,341 +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 "CongenAddressDecoder.h" -#include "utils.h" - -#include -#include - -using std::ifstream; -using std::cout; -using std::endl; -using std::set; -using std::pair; -using std::map; -using std::deque; - -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()); -} - -CongenAddressDecoder::CongenAddressDecoder() -{ - -} - -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 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); - - // 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; - } - } - - // 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; - } - - // 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"))); - } - - set sUsed; - - // 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; - 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); - } - - // 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); - m_vRowBits.push_back(pair(counter++, nRow)); - sUsed.insert(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 - - m_vColumnBits.push_back(pair(counter++, i)); - } - - // 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); -} - -DecodedAddress CongenAddressDecoder::decodeAddress(uint64_t addr) -{ - DecodedAddress result; - - // 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++) { - 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; - } - - // Unsed - result.bankgroup = 0; - result.channel = 0; - result.rank = 0; - - // Pass through of the three byte bits - result.bytes = addr & 0x7; - - // 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; - } - - // 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; - } - - // 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; - } - - return result; -} - -uint64_t CongenAddressDecoder::encodeAddress(DecodedAddress n) -{ - uint64_t address = 0; - - // 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; - } - // 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; - } - // 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; - } - - // Add the unchanged byte bits - address |= n.bytes; - - // 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++) { - 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; - } - - return address; -} - -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() -{ - map> output; - - for (auto it = m_vBankBits.begin(); it != m_vBankBits.end(); it++) { - output[it->second] = 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 = m_vColumnBits.begin(); it != m_vColumnBits.end(); it++) { - output[it->second] = pair(it->first, 'C'); - } - - // add byte bits - output[0] = pair(0, 'b'); - output[1] = pair(1, 'b'); - output[2] = pair(2, 'b'); - - cout << "Used addressmapping:" << endl; - cout << headline << endl; - for (unsigned i = 0; i < 32; i++) { - cout << " " << i << " "; - } - cout << endl; - for (unsigned i = 0; i < 32; i++) { - cout << " " << output[i].second << "(" << output[i].first << ") "; - } - cout << endl; -} diff --git a/DRAMSys/library/src/common/CongenAddressDecoder.h b/DRAMSys/library/src/common/CongenAddressDecoder.h deleted file mode 100644 index 85829d9d..00000000 --- a/DRAMSys/library/src/common/CongenAddressDecoder.h +++ /dev/null @@ -1,108 +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: - std::string m_strName; // The Name of this mapping - - unsigned int - m_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 - - - 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" - -//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: - CongenAddressDecoder(); - - 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/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/common/XmlAddressDecoder.cpp b/DRAMSys/library/src/common/XmlAddressDecoder.cpp deleted file mode 100644 index 71a54039..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 addr) -{ - if (addr > maximumAddress) - SC_REPORT_WARNING("XmlAddressDecoder", ("Address " + std::to_string(addr) + " 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.rank * bankgroupsPerRank; - result.bank = ((addr & 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; - return result; -} - -uint64_t XmlAddressDecoder::encodeAddress(DecodedAddress n) -{ - 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); -} - -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 21befb9f..00000000 --- a/DRAMSys/library/src/common/XmlAddressDecoder.h +++ /dev/null @@ -1,97 +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: - 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; - - unsigned banksPerGroup; - unsigned banksPerRank; - unsigned bankgroupsPerRank; - - tinyxml2::XMLElement *addressmapping; - uint64_t maximumAddress; - -public: - XmlAddressDecoder(); - - 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(); -}; - -#endif // XMLADDRESSDECODER_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.cpp b/DRAMSys/library/src/error/errormodel.cpp index 9b20c68b..74b0e5c8 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,15 +157,17 @@ 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); 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()); @@ -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 d027d9b3..30092209 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 @@ -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..73810df7 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,33 +216,11 @@ 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()); - // 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"); - } -} - -bool Arbiter::addressIsValid(DecodedAddress &decodedAddress) -{ - if (decodedAddress.channel >= AddressDecoder::getInstance().amount.channel) - return false; - if (decodedAddress.rank >= AddressDecoder::getInstance().amount.rank) - return false; - if (decodedAddress.bankgroup >= AddressDecoder::getInstance().amount.bankgroup) - return false; - if (decodedAddress.bank >= AddressDecoder::getInstance().amount.bank) - return false; - if (decodedAddress.row >= AddressDecoder::getInstance().amount.row) - return false; - if (decodedAddress.column >= AddressDecoder::getInstance().amount.column) - return false; - return true; + DecodedAddress decodedAddress = addressDecoder->decodeAddress(payload.get_address()); + 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 907a8fcf..2e0ab39d 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" @@ -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; @@ -93,8 +95,6 @@ private: void appendDramExtension(int socketId, tlm::tlm_generic_payload &payload); std::vector nextPayloadID; - - bool addressIsValid(DecodedAddress &decodedAddress); }; #endif // ARBITER_H diff --git a/DRAMSys/library/src/simulation/DRAMSys.cpp b/DRAMSys/library/src/simulation/DRAMSys.cpp index 7eabae3e..32f77bcd 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -44,10 +44,9 @@ #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" -#include "../common/CongenAddressDecoder.h" #include "../configuration/ConfigurationLoader.h" #include "../common/utils.h" #include "../simulation/TemperatureController.h" @@ -81,7 +80,6 @@ DRAMSys::DRAMSys(sc_module_name name, std::string simconfig; std::string thermalconfig; - // TODO: Setup never used? Setup setup(simulationToRun, memspec, mcconfig, @@ -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(); @@ -163,8 +143,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 +152,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 +160,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; @@ -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 15410755..841dd22b 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" @@ -103,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/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 025221d7..d1f2787b 100644 --- a/DRAMSys/library/src/simulation/TracePlayer.cpp +++ b/DRAMSys/library/src/simulation/TracePlayer.cpp @@ -47,11 +47,13 @@ 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; } -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 6eabd60c..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,13 +60,13 @@ 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(); 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, 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); + } + } } }