diff --git a/.gitmodules b/.gitmodules index 82647b71..60369680 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,3 +5,6 @@ path = DRAMSys/library/src/common/third_party/DRAMPower url = https://github.com/tukl-msd/DRAMPower.git branch = master +[submodule "DRAMSys/library/src/common/third_party/json"] + path = DRAMSys/library/src/common/third_party/json + url = https://github.com/nlohmann/json.git diff --git a/DRAMSys/library/library.pro b/DRAMSys/library/library.pro index 680d8e3a..23f56ddc 100644 --- a/DRAMSys/library/library.pro +++ b/DRAMSys/library/library.pro @@ -51,6 +51,7 @@ INCLUDEPATH += $${systemc_home}/include INCLUDEPATH += src/common/third_party/DRAMPower/src INCLUDEPATH += src/common/third_party/DRAMPower/src/libdrampower +INCLUDEPATH += src/common/third_party/json/include DEFINES += TIXML_USE_STL DEFINES += SC_INCLUDE_DYNAMIC_PROCESSES @@ -119,10 +120,13 @@ SOURCES += \ src/error/eccbaseclass.cpp \ src/error/ecchamming.cpp \ src/controller/scheduler/Fr_Fcfs_read_priority.cpp \ - src/controller/scheduler/Fr_Fcfs_grouper.cpp + src/controller/scheduler/Fr_Fcfs_grouper.cpp \ + src/common/AddressDecoder.cpp \ + src/common/jsonAddressDecoder.cpp HEADERS += \ src/common/third_party/tinyxml2/tinyxml2.h \ + src/common/third_party/json/include/nlohmann/json.hpp \ src/common/xmlAddressdecoder.h \ src/common/Utils.h \ src/common/TlmRecorder.h \ @@ -192,7 +196,9 @@ HEADERS += \ src/controller/scheduler/Fr_Fcfs_read_priority.h \ src/controller/scheduler/Fr_Fcfs_grouper.h \ src/simulation/IArbiter.h \ - src/simulation/SimpleArbiter.h + src/simulation/SimpleArbiter.h \ + src/common/AddressDecoder.h \ + src/common/jsonAddressDecoder.h thermalsim = $$(THERMALSIM) isEmpty(thermalsim) { diff --git a/DRAMSys/library/resources/configs/amconfigs/am_test_congen_output.json b/DRAMSys/library/resources/configs/amconfigs/am_test_congen_output.json new file mode 100644 index 00000000..3aca28c7 --- /dev/null +++ b/DRAMSys/library/resources/configs/amconfigs/am_test_congen_output.json @@ -0,0 +1,45 @@ +{ + "Config": { + "numberOfBankBits": 3, + "numberOfRowBits": 14, + "numberOfColumnBits": 10, + "numberOfByteBits": 3, + "numberOfBLBits": 3 + }, + "Name": "merged_sorted", + "Solutions": [ + { + "XOR": [ + ], + "Banks Rows": [ + { + "bank_bits": [ + 27, + 28, + 29 + ], + "rows": { + "row_bits": [ + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26 + ], + "costs": 477468 + }, + "costs": 477468 + } + ] + } + ] +} diff --git a/DRAMSys/library/resources/resources.pri b/DRAMSys/library/resources/resources.pri index 9f28a12f..115c4ba7 100644 --- a/DRAMSys/library/resources/resources.pri +++ b/DRAMSys/library/resources/resources.pri @@ -172,4 +172,5 @@ DISTFILES += \ $$PWD/configs/simulator/lpddr4.xml \ $$PWD/simulations/lpddr4-single-device.xml \ $$PWD/configs/amconfigs/am_lpddr4.xml \ - $$PWD/configs/memspecs/MICRON_6Gb_LPDDR4-3200_NDA_NDA_NDA.xml + $$PWD/configs/memspecs/MICRON_6Gb_LPDDR4-3200_NDA_NDA_NDA.xml \ + $$PWD/configs/amconfigs/am_test_congen_output.json diff --git a/DRAMSys/library/src/common/AddressDecoder.cpp b/DRAMSys/library/src/common/AddressDecoder.cpp new file mode 100644 index 00000000..266e9bca --- /dev/null +++ b/DRAMSys/library/src/common/AddressDecoder.cpp @@ -0,0 +1,68 @@ +/* + * 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 "AddressDecoder.h" +#include "xmlAddressdecoder.h" +#include "jsonAddressDecoder.h" + +AddressDecoder* AddressDecoder::m_pInstance = nullptr; + +AddressDecoder& AddressDecoder::getInstance() +{ + 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::JSON: + m_pInstance = new JSONAddressDecoder; + break; + default: + throw std::logic_error("Instance type not supported."); + break; + } +} + +AddressDecoder::AddressDecoder() +{ + +} diff --git a/DRAMSys/library/src/common/AddressDecoder.h b/DRAMSys/library/src/common/AddressDecoder.h new file mode 100644 index 00000000..be74980f --- /dev/null +++ b/DRAMSys/library/src/common/AddressDecoder.h @@ -0,0 +1,93 @@ +/* + * 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 ADDRESSDECODER_H +#define ADDRESSDECODER_H + +#include +#include +#include +#include +#include + +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; +}; + +class AddressDecoder +{ +public: + enum class Type + { + XML, + JSON + }; + +protected: + AddressDecoder(); + + static AddressDecoder* m_pInstance; +public: + static AddressDecoder& getInstance(); + static void createInstance(Type t); + + virtual void setConfiguration(std::string url) = 0; + + virtual DecodedAddress decodeAddress(sc_dt::uint64 addr) = 0; + virtual sc_dt::uint64 encodeAddress(DecodedAddress n) = 0; + + virtual void print() = 0; + + std::map amount; +}; + +#endif // ADDRESSDECODER_H diff --git a/DRAMSys/library/src/common/jsonAddressDecoder.cpp b/DRAMSys/library/src/common/jsonAddressDecoder.cpp new file mode 100644 index 00000000..333c200d --- /dev/null +++ b/DRAMSys/library/src/common/jsonAddressDecoder.cpp @@ -0,0 +1,283 @@ +/* + * 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 "jsonAddressDecoder.h" +#include "Utils.h" + +#include + +using std::ifstream; +using std::cout; +using std::endl; + +#include + +using json = nlohmann::json; + +#include + +using std::set; + +JSONAddressDecoder::JSONAddressDecoder() +{ + +} + +void JSONAddressDecoder::setConfiguration(std::string url) +{ + ifstream file; + + file.open(url); + + if(!file.is_open()) + { + cout << "Unable to open file " << url << endl; + return; + } + + // parse json file + json data; + file >> data; + + file.close(); + + // extract data + // For simplicity take the first solution of one or more available ones. + auto sol = data["Solutions"].begin(); + assert(sol != data["Solutions"].end()); + + // Set for connected bits. Used to find the remaining bits, which are not part of the json file = column bits. + set sUsed; + + // get XOR connections + // An XOR connection needs two parameters: A bank bit and a Row bit. + // These parameters are all stored in one array with the following pattern: bank0, bank1, ..., row0, row1, ... + unsigned num = (*sol)["XOR"].size()>>1; + for(unsigned i = 0; i < num; i++) + { + m_vXor.push_back(pair ((*sol)["XOR"].at(i), (*sol)["XOR"].at(i+num))); + } + + // 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(auto it = (*sol)["Banks Rows"][0]["bank_bits"].begin(); it != (*sol)["Banks Rows"][0]["bank_bits"].end(); it++) + { + m_vBankBits.push_back(pair(counter++, (*it))); + sUsed.insert((unsigned)(*it)); + } + + // 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(auto it = (*sol)["Banks Rows"][0]["rows"]["row_bits"].begin(); it != (*sol)["Banks Rows"][0]["rows"]["row_bits"].end(); it++) + { + m_vRowBits.push_back(pair(counter++, (*it))); + sUsed.insert((unsigned)(*it)); + } + + // Add byte bits (fixed) + sUsed.insert(0); + sUsed.insert(1); + sUsed.insert(2); + + // Theset bits are ignored + 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, 3); +} + +DecodedAddress JSONAddressDecoder::decodeAddress(sc_dt::uint64 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->first) & 1) ^ ((addr >> it->second) & 1)); + addr &= ~(1 << it->first); + addr |= new_bank_bit << it->first; + } + + // 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; +} + +sc_dt::uint64 JSONAddressDecoder::encodeAddress(DecodedAddress n) +{ + sc_dt::uint64 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->first) & 1) ^ ((address >> it->second) & 1)); + address &= ~(1 << it->first); + address |= new_bank_bit << it->first; + } + + return address; +} + +void JSONAddressDecoder::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/jsonAddressDecoder.h b/DRAMSys/library/src/common/jsonAddressDecoder.h new file mode 100644 index 00000000..ee25d77e --- /dev/null +++ b/DRAMSys/library/src/common/jsonAddressDecoder.h @@ -0,0 +1,73 @@ +/* + * 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 JSONADDRESSDECODER_H +#define JSONADDRESSDECODER_H + +#include "AddressDecoder.h" + +#include +#include + +using std::vector; +using std::pair; +using std::map; + +class JSONAddressDecoder + : public AddressDecoder +{ + // Friendship needed so that the AddressDecoder can access the + // constructor of this class to create the object in CreateInstance. + friend class AddressDecoder; + +private: + JSONAddressDecoder(); + + 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" + 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" + 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" + 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" + +public: + virtual void setConfiguration(std::string url); + + virtual DecodedAddress decodeAddress(sc_dt::uint64 addr); + virtual sc_dt::uint64 encodeAddress(DecodedAddress n); + + virtual void print(); +}; + +#endif // JSONADDRESSDECODER_H diff --git a/DRAMSys/library/src/common/xmlAddressdecoder.cpp b/DRAMSys/library/src/common/xmlAddressdecoder.cpp index 31304f1d..639631fa 100644 --- a/DRAMSys/library/src/common/xmlAddressdecoder.cpp +++ b/DRAMSys/library/src/common/xmlAddressdecoder.cpp @@ -49,26 +49,11 @@ xmlAddressDecoder::xmlAddressDecoder() addressmapping = NULL; } -xmlAddressDecoder::xmlAddressDecoder(string addressConfigURI) -{ - setConfiguration(addressConfigURI); -} - -xmlAddressDecoder::xmlAddressDecoder(XMLElement* addressmap) -{ - setConfiguration(addressmap); -} - void xmlAddressDecoder::setConfiguration(std::string addressConfigURI) { tinyxml2::XMLDocument doc; loadXML(addressConfigURI, doc); - setConfiguration(doc.RootElement()); -} - -void xmlAddressDecoder::setConfiguration(tinyxml2::XMLElement* addressMap) -{ - tinyxml2::XMLDocument doc; + tinyxml2::XMLElement* addressMap = doc.RootElement(); string xmlNodeName(addressMap->Name()); if( xmlNodeName != "addressmapping") diff --git a/DRAMSys/library/src/common/xmlAddressdecoder.h b/DRAMSys/library/src/common/xmlAddressdecoder.h index 0e9094fb..7266b8df 100644 --- a/DRAMSys/library/src/common/xmlAddressdecoder.h +++ b/DRAMSys/library/src/common/xmlAddressdecoder.h @@ -38,45 +38,21 @@ #ifndef _XMLADDRESSDECODER_H #define _XMLADDRESSDECODER_H -#include -#include -#include -#include #include -#include #include "Utils.h" #include "third_party/tinyxml2/tinyxml2.h" - -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; -}; +#include "AddressDecoder.h" class xmlAddressDecoder + : public AddressDecoder { + // Friendship needed so that the AddressDecoder can access the + // constructor of this class to create the object in CreateInstance. + friend class AddressDecoder; - private: - +private: xmlAddressDecoder(); - xmlAddressDecoder(std::string URI); - xmlAddressDecoder(tinyxml2::XMLElement* addressMap); std::map masks; std::map shifts; @@ -84,16 +60,13 @@ class xmlAddressDecoder tinyxml2::XMLElement* addressmapping; public: - DEF_SINGLETON(xmlAddressDecoder); - - DecodedAddress decodeAddress(sc_dt::uint64 addr); - sc_dt::uint64 encodeAddress(DecodedAddress n); + virtual DecodedAddress decodeAddress(sc_dt::uint64 addr); + virtual sc_dt::uint64 encodeAddress(DecodedAddress n); void setConfiguration(std::string url); - void setConfiguration(tinyxml2::XMLElement* addressMap); - void print(); - std::map amount; +public: + virtual void print(); }; #endif diff --git a/DRAMSys/library/src/controller/core/configuration/Configuration.cpp b/DRAMSys/library/src/controller/core/configuration/Configuration.cpp index 93a1d523..d7070107 100644 --- a/DRAMSys/library/src/controller/core/configuration/Configuration.cpp +++ b/DRAMSys/library/src/controller/core/configuration/Configuration.cpp @@ -191,7 +191,7 @@ void Configuration::setParameter(std::string name, std::string value) Debug = string2bool(value); else if (name == "NumberOfMemChannels") { NumberOfMemChannels = string2int(value); - unsigned int maxNumberofMemChannels = xmlAddressDecoder::getInstance().amount["channel"]; + unsigned int maxNumberofMemChannels = AddressDecoder::getInstance().amount["channel"]; if (NumberOfMemChannels > maxNumberofMemChannels) { SC_REPORT_FATAL("Configuration", ("Invalid value for parameter " + name @@ -349,7 +349,7 @@ unsigned int Configuration::getBytesPerBurst() // 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 = xmlAddressDecoder::getInstance().amount["bytes"]; + unsigned int burstElementSizeInBytes = AddressDecoder::getInstance().amount["bytes"]; assert(bytesPerBurst == (burstElementSizeInBytes * memSpec.BurstLength)); } diff --git a/DRAMSys/library/src/error/errormodel.cpp b/DRAMSys/library/src/error/errormodel.cpp index e1010f6a..9a40a869 100644 --- a/DRAMSys/library/src/error/errormodel.cpp +++ b/DRAMSys/library/src/error/errormodel.cpp @@ -48,7 +48,7 @@ void errorModel::init() // Get Configuration parameters: burstLenght = Configuration::getInstance().memSpec.BurstLength; numberOfColumns = Configuration::getInstance().memSpec.NumberOfColumns; - bytesPerColumn = xmlAddressDecoder::getInstance().amount["bytes"]; + bytesPerColumn = AddressDecoder::getInstance().amount["bytes"]; // Adjust number of bytes per column dynamically to the selected ecc controller bytesPerColumn = Configuration::getInstance().adjustNumBytesAfterECC(bytesPerColumn); @@ -157,7 +157,7 @@ void errorModel::store(tlm::tlm_generic_payload &trans) markBitFlips(); // Get the key for the dataMap from the transaction's address: - DecodedAddress key = xmlAddressDecoder::getInstance().decodeAddress(trans.get_address()); + DecodedAddress key = AddressDecoder::getInstance().decodeAddress(trans.get_address()); // Set context: setContext(key); @@ -225,7 +225,7 @@ void errorModel::load(tlm::tlm_generic_payload &trans) markBitFlips(); // Get the key for the dataMap from the transaction's address: - DecodedAddress key = xmlAddressDecoder::getInstance().decodeAddress(trans.get_address()); + DecodedAddress key = AddressDecoder::getInstance().decodeAddress(trans.get_address()); // Set context: setContext(key); diff --git a/DRAMSys/library/src/error/errormodel.h b/DRAMSys/library/src/error/errormodel.h index d85027c5..f7efed69 100644 --- a/DRAMSys/library/src/error/errormodel.h +++ b/DRAMSys/library/src/error/errormodel.h @@ -120,8 +120,8 @@ class errorModel : public sc_module { bool operator()( const DecodedAddress& first , const DecodedAddress& second) const { - sc_dt::uint64 addrFirst = xmlAddressDecoder::getInstance().encodeAddress(first); - sc_dt::uint64 addrSecond = xmlAddressDecoder::getInstance().encodeAddress(second); + sc_dt::uint64 addrFirst = AddressDecoder::getInstance().encodeAddress(first); + sc_dt::uint64 addrSecond = AddressDecoder::getInstance().encodeAddress(second); return addrFirst < addrSecond; } }; diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index d5dbc1dd..fe9ce71e 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -151,7 +151,7 @@ private: // adjust address offset: trans.set_address(trans.get_address() - Configuration::getInstance().AddressOffset); - DecodedAddress decodedAddress = xmlAddressDecoder::getInstance().decodeAddress(trans.get_address()); + DecodedAddress decodedAddress = AddressDecoder::getInstance().decodeAddress(trans.get_address()); return iSocket[decodedAddress.channel]->transport_dbg(trans); } @@ -248,7 +248,7 @@ private: payload.set_auto_extension(genExtension); unsigned int burstlength = payload.get_streaming_width(); - DecodedAddress decodedAddress = xmlAddressDecoder::getInstance().decodeAddress(payload.get_address()); + 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), Bank(decodedAddress.bank), BankGroup(decodedAddress.bankgroup), Row(decodedAddress.row), Column(decodedAddress.column),burstlength); @@ -260,19 +260,19 @@ private: bool addressIsValid(DecodedAddress& decodedAddress) { - if (decodedAddress.channel >= xmlAddressDecoder::getInstance().amount["channel"]) { + if (decodedAddress.channel >= AddressDecoder::getInstance().amount["channel"]) { return false; } - if (decodedAddress.bank >= xmlAddressDecoder::getInstance().amount["bank"]) { + if (decodedAddress.bank >= AddressDecoder::getInstance().amount["bank"]) { return false; } - if (decodedAddress.bankgroup > xmlAddressDecoder::getInstance().amount["bankgroup"]) { + if (decodedAddress.bankgroup > AddressDecoder::getInstance().amount["bankgroup"]) { return false; } - if (decodedAddress.column >= xmlAddressDecoder::getInstance().amount["column"]) { + if (decodedAddress.column >= AddressDecoder::getInstance().amount["column"]) { return false; } - if (decodedAddress.row >= xmlAddressDecoder::getInstance().amount["row"]) { + if (decodedAddress.row >= AddressDecoder::getInstance().amount["row"]) { return false; } return true; diff --git a/DRAMSys/library/src/simulation/DRAMSys.cpp b/DRAMSys/library/src/simulation/DRAMSys.cpp index ea544ee4..3e9211cc 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include "DRAMSys.h" #include "Setup.h" @@ -83,10 +84,27 @@ DRAMSys::DRAMSys(sc_module_name __attribute__((unused)) name, // The xmlAddressDecoder MUST be initialized before calling the // ConfigurationLoader because some information from the xmlAddressDecoder // is needed to assure the coherence of the configuration. - xmlAddressDecoder::getInstance().setConfiguration(pathToResources - + "configs/amconfigs/" - + amconfig); - xmlAddressDecoder::getInstance().print(); + + if(amconfig.find(".xml") != string::npos) + { + AddressDecoder::createInstance(AddressDecoder::Type::XML); + AddressDecoder::getInstance().setConfiguration(pathToResources + + "configs/amconfigs/" + + amconfig); + } + else if(amconfig.find(".json") != string::npos) + { + AddressDecoder::createInstance(AddressDecoder::Type::JSON); + AddressDecoder::getInstance().setConfiguration(pathToResources + + "configs/amconfigs/" + + amconfig); + } + else + { + throw std::runtime_error("No address mapping loaded. Unknown file extension"); + } + + AddressDecoder::getInstance().print(); ConfigurationLoader::loadMemSpec(Configuration::getInstance(), pathToResources diff --git a/README.md b/README.md index e16a7dde..7cbda275 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Configure git on your machine. Some basic configurations follow. Replace $ git config --global user.name "FirstName OtherNames LastName" $ git config --global user.email rhrkuser@rhrk.uni-kl.de $ git config --global credential.helper ’cache --timeout=3600’ -$ git config --global color.ui auto +$ git config --global color.ui auto ``` Login using your **git.rhrk** account. Fork the repository by clicking in @@ -239,17 +239,17 @@ ln -s lib/ lib-macosx64 $ brew install python3 ``` -Python3 (via homebrew) will be installed in +Python3 (via homebrew) will be installed in ``` /usr/local/Cellar/python3/3.5.2_2/Frameworks/Python.framework ``` or you can install manually using official package provided in [link](https://www.python.org/downloads/) -**Note:** Official Python Package will be installed in +**Note:** Official Python Package will be installed in ``` /Library/Frameworks/Python.framework -``` +``` - Install the QtCreator using offical setup file from [link](https://www.qt.io/download-open-source/#section-2) @@ -292,7 +292,7 @@ export LIBQWT_HEADERS=/opt/qwt-6.1.4/lib/qwt.framework/Headers - For the trace analyzer the file: ``` -/opt/local/Library/Frameworks/Python.framework/Versions/3.5/include/python3.4m/pyport.h +/opt/local/Library/Frameworks/Python.framework/Versions/3.5/include/python3.4m/pyport.h ``` has to be changed like [this](https://trac.macports.org/attachment/ticket/44288/issue10910-workaround.txt) @@ -431,13 +431,13 @@ Below, the sub-configurations are listed and explained. - "1": enables thermal simulation - "0": static temperature during simulation - *SimulationProgressBar* (boolean) - - "1": enables the simulation progress bar + - "1": enables the simulation progress bar - "0": disables the simulation progress bar - *NumberOfDevicesOnDIMM* (unsigned int) - Number of devices on dual inline memory module - *CheckTLM2Protocol* (boolean) - - "1": enables the TLM 2.0 Protocol Checking - - "0": disables the TLM 2.0 Protocol Checking + - "1": enables the TLM 2.0 Protocol Checking + - "0": disables the TLM 2.0 Protocol Checking - *ECCControllerMode* (string) - "Disabled": No ECC Controller is used - "Hamming": Enables an ECC Controller with classic SECDED implementation using Hamming Code @@ -503,6 +503,10 @@ Below, the sub-configurations are listed and explained. - **Address Mapping** + There are currently two different file formats to describe the address mapping. This software automatically chooses the correct interpreter using the file extension as selection criterion. So please make sure that all files have the correct extension. + +- **XML file format** + XML files describe the address mapping to be used in the simulation. Example for 1GB x64 DIMM with: 8 x 1 Gbit x8 Devices (Micron MT41J128M8) with Page Size: 1KB @@ -510,23 +514,23 @@ Below, the sub-configurations are listed and explained. [am_ddr3_8x1Gbx8_dimm_p1KB_brc.xml](DRAMSys/library/resources/configs/amconfigs/am_ddr3_8x1Gbx8_dimm_p1KB_brc.xml) ``` xml - - + @@ -537,18 +541,18 @@ Below, the sub-configurations are listed and explained. ``` Some more examples with graphical representation follow: - + [am_wideio.xml](DRAMSys/library/resources/configs/amconfigs/am_wideio.xml) ``` xml - + - + ``` @@ -568,6 +572,71 @@ Below, the sub-configurations are listed and explained. ![Address Mapping Sample 2](DRAMSys/docs/images/am_wideio_brc.png) +- **JSON file format** + + This file format is generated by ConGen. It does not have an unambiguous assignment of the address lines. + + The format delivers more information than needed for an address mapping. + Unused data: + - Block "Config": Gives you information about the ConGen configuration + - Key "Name": Name of the trace file which was used by ConGen + - All items of the array "Solutions" but the first one: Alternative solution with same result. + - Key "costs": Number of row misses which this configuration produces while playing the trace. + + Used data: + - First item of array "Solution": + - "XOR": Array of row and bank bits which are connected with an xor. Order of the bit: bank1, bank2, ..., row1, row2, ... + - "bank_bits": Number of the addres bits which are connected to a bank bit + - "row_bits": Number of the addres bits which are connected to a row bit + + ```json + { + "Config": { + "numberOfBankBits": 3, + "numberOfRowBits": 14, + "numberOfColumnBits": 10, + "numberOfByteBits": 3, + "numberOfBLBits": 3 + }, + "Name": "trace_name", + "Solutions": [ + { + "XOR": [ + ], + "Banks Rows": [ + { + "bank_bits": [ + 27, + 28, + 29 + ], + "rows": { + "row_bits": [ + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26 + ], + "costs": 477468 + }, + "costs": 477468 + } + ] + } + ] + } +``` + - **Memory Configuration** The content of [fifo.xml](DRAMSys/library/resources/configs/memconfigs/fifo.xml) is @@ -676,7 +745,7 @@ A description of the content each directory follows. - **scripts**: useful tools. - **simulations**: main configuration files. - **traces**: pre-recorded trace files that may be used as stimuli in simulations. - + #### Log Collector Script Users can profit of running multiple simulations automatically with @@ -741,28 +810,28 @@ For more information check the documentation in [DRAMSylva folder](DRAMSys/libra the socket id (thread) of a payload. It is added in the Arbiter and is sent to the Controller. ![Payload Extension information](DRAMSys/docs/images/PayloadExtension.png) - + - **Transaction object with Memory Manager** - + The TracePlayer allocates the memory for the transaction object by calling allocatePayload method. - + The acquire method is called before passing the transaction object in TracePlayer, Arbiter and Controller. The release method is called after each component is done with the transaction object. After the final call of release method, the free method of the memory manager is called to free the transaction object. - + ![Payload Memory Manager](DRAMSys/docs/images/PayloadMemoryManager.png) - **Architecture of the backend TLM model** The below figure shows our custom TLM protocol between the Controller and the Dram. A new transaction enters the Controller with the BEGIN_REQ phase is stored in frontendPEQ. The callback function of the frontendPEQ is called and send the payload to the Scheduler. - + The Scheduler checks the address of payload and the current state to determine proper command (Active, Precharge, Read or Write). Then the ControllerCore sends the payload with the corresponding phase (BEGIN_ACT, BEGIN_PRE, BEGIN_RD or BEGIN_WR) to the Dram by calling nb_transport_fw method. - - The Dram receives the transaction then send back to the Controller by calling nb_transport_bw with appropriate END phase (END_ACT, END_PRE, END_RD or END_WR). + + The Dram receives the transaction then send back to the Controller by calling nb_transport_bw with appropriate END phase (END_ACT, END_PRE, END_RD or END_WR). ![Architecture backend TLM](DRAMSys/docs/images/TransactionPhase.png) -### DRAMSys Thermal Simulation +### DRAMSys Thermal Simulation The thermal simulation is performed by a **3D-ICE** [8] server accessed through the network. Therefore users interested in thermal simulation during