From ac950afda9a88fae4428d2e9863d816520962ede Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Mon, 26 Mar 2018 16:04:17 +0200 Subject: [PATCH 01/11] Created base class for XMLAddressDecoder and created an alternative JSONAddressDecoder class. This class has still no functionality. --- DRAMSys/library/library.pro | 8 +- DRAMSys/library/src/common/AddressDecoder.cpp | 28 ++++++ DRAMSys/library/src/common/AddressDecoder.h | 93 +++++++++++++++++++ .../library/src/common/jsonAddressDecoder.cpp | 44 +++++++++ .../library/src/common/jsonAddressDecoder.h | 58 ++++++++++++ .../library/src/common/xmlAddressdecoder.cpp | 17 +--- .../library/src/common/xmlAddressdecoder.h | 37 ++------ .../core/configuration/Configuration.cpp | 4 +- DRAMSys/library/src/error/errormodel.cpp | 6 +- DRAMSys/library/src/error/errormodel.h | 4 +- DRAMSys/library/src/simulation/Arbiter.h | 14 +-- DRAMSys/library/src/simulation/DRAMSys.cpp | 23 ++++- 12 files changed, 269 insertions(+), 67 deletions(-) create mode 100644 DRAMSys/library/src/common/AddressDecoder.cpp create mode 100644 DRAMSys/library/src/common/AddressDecoder.h create mode 100644 DRAMSys/library/src/common/jsonAddressDecoder.cpp create mode 100644 DRAMSys/library/src/common/jsonAddressDecoder.h diff --git a/DRAMSys/library/library.pro b/DRAMSys/library/library.pro index ad74744a..20a1eb2d 100644 --- a/DRAMSys/library/library.pro +++ b/DRAMSys/library/library.pro @@ -119,7 +119,9 @@ 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 \ @@ -190,7 +192,9 @@ HEADERS += \ src/error/eccbaseclass.h \ src/error/ecchamming.h \ src/controller/scheduler/Fr_Fcfs_read_priority.h \ - src/controller/scheduler/Fr_Fcfs_grouper.h + src/controller/scheduler/Fr_Fcfs_grouper.h \ + src/common/AddressDecoder.h \ + src/common/jsonAddressDecoder.h thermalsim = $$(THERMALSIM) isEmpty(thermalsim) { diff --git a/DRAMSys/library/src/common/AddressDecoder.cpp b/DRAMSys/library/src/common/AddressDecoder.cpp new file mode 100644 index 00000000..a473b442 --- /dev/null +++ b/DRAMSys/library/src/common/AddressDecoder.cpp @@ -0,0 +1,28 @@ +#include "AddressDecoder.h" +#include "xmlAddressdecoder.h" +#include "jsonAddressDecoder.h" + +CAddressDecoder* CAddressDecoder::m_pInstance = nullptr; + +CAddressDecoder& CAddressDecoder::getInstance() +{ + assert(m_pInstance != nullptr); + return *m_pInstance; +} + +void CAddressDecoder::createInstance(Type t) +{ + assert(m_pInstance == nullptr); + switch(t) + { + case Type::XML: + m_pInstance = new xmlAddressDecoder; + case Type::JSON: + m_pInstance = new JSONAddressDecoder; + } +} + +CAddressDecoder::CAddressDecoder() +{ + +} diff --git a/DRAMSys/library/src/common/AddressDecoder.h b/DRAMSys/library/src/common/AddressDecoder.h new file mode 100644 index 00000000..c5c23a70 --- /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 CAddressDecoder +{ +public: + enum class Type + { + XML, + JSON + }; + +protected: + CAddressDecoder(); + + static CAddressDecoder* m_pInstance; +public: + static CAddressDecoder& 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..d82f41bf --- /dev/null +++ b/DRAMSys/library/src/common/jsonAddressDecoder.cpp @@ -0,0 +1,44 @@ +#include "jsonAddressDecoder.h" + +#include + +using std::ifstream; +using std::cout; +using std::endl; + +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; + } + + file.close(); +} + +DecodedAddress JSONAddressDecoder::decodeAddress(sc_dt::uint64 addr) +{ + DecodedAddress result; + + return result; +} + +sc_dt::uint64 JSONAddressDecoder::encodeAddress(DecodedAddress n) +{ + return 0; +} + +void JSONAddressDecoder::print() +{ + +} diff --git a/DRAMSys/library/src/common/jsonAddressDecoder.h b/DRAMSys/library/src/common/jsonAddressDecoder.h new file mode 100644 index 00000000..bc5eb8df --- /dev/null +++ b/DRAMSys/library/src/common/jsonAddressDecoder.h @@ -0,0 +1,58 @@ +/* + * 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" + +class JSONAddressDecoder + : public CAddressDecoder +{ + friend class CAddressDecoder; + +private: + JSONAddressDecoder(); + +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..ed300670 100644 --- a/DRAMSys/library/src/common/xmlAddressdecoder.h +++ b/DRAMSys/library/src/common/xmlAddressdecoder.h @@ -38,45 +38,20 @@ #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 CAddressDecoder { + friend class CAddressDecoder; - private: +private: xmlAddressDecoder(); - xmlAddressDecoder(std::string URI); - xmlAddressDecoder(tinyxml2::XMLElement* addressMap); std::map masks; std::map shifts; @@ -84,13 +59,13 @@ class xmlAddressDecoder tinyxml2::XMLElement* addressmapping; public: - DEF_SINGLETON(xmlAddressDecoder); - DecodedAddress decodeAddress(sc_dt::uint64 addr); sc_dt::uint64 encodeAddress(DecodedAddress n); void setConfiguration(std::string url); +private: void setConfiguration(tinyxml2::XMLElement* addressMap); +public: void print(); std::map amount; diff --git a/DRAMSys/library/src/controller/core/configuration/Configuration.cpp b/DRAMSys/library/src/controller/core/configuration/Configuration.cpp index 93a1d523..29cc6f94 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 = CAddressDecoder::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 = CAddressDecoder::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..18966452 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 = CAddressDecoder::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 = CAddressDecoder::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 = CAddressDecoder::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..d3914c6c 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 = CAddressDecoder::getInstance().encodeAddress(first); + sc_dt::uint64 addrSecond = CAddressDecoder::getInstance().encodeAddress(second); return addrFirst < addrSecond; } }; diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index 114e3d03..5b60b410 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 = CAddressDecoder::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 = CAddressDecoder::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); @@ -260,19 +260,19 @@ private: bool addressIsValid(DecodedAddress& decodedAddress) { - if (decodedAddress.channel >= xmlAddressDecoder::getInstance().amount["channel"]) { + if (decodedAddress.channel >= CAddressDecoder::getInstance().amount["channel"]) { return false; } - if (decodedAddress.bank >= xmlAddressDecoder::getInstance().amount["bank"]) { + if (decodedAddress.bank >= CAddressDecoder::getInstance().amount["bank"]) { return false; } - if (decodedAddress.bankgroup > xmlAddressDecoder::getInstance().amount["bankgroup"]) { + if (decodedAddress.bankgroup > CAddressDecoder::getInstance().amount["bankgroup"]) { return false; } - if (decodedAddress.column >= xmlAddressDecoder::getInstance().amount["column"]) { + if (decodedAddress.column >= CAddressDecoder::getInstance().amount["column"]) { return false; } - if (decodedAddress.row >= xmlAddressDecoder::getInstance().amount["row"]) { + if (decodedAddress.row >= CAddressDecoder::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..403435d4 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -83,10 +83,25 @@ 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) + { + CAddressDecoder::createInstance(CAddressDecoder::Type::XML); + CAddressDecoder::getInstance().setConfiguration(pathToResources + + "configs/amconfigs/" + + amconfig); + } + else if(amconfig.find(".json") != string::npos) + { + CAddressDecoder::createInstance(CAddressDecoder::Type::JSON); + CAddressDecoder::getInstance().setConfiguration(pathToResources + amconfig); + } + else + { + cout << "No address mapping loaded. Unknown file extension" << endl; + } + + CAddressDecoder::getInstance().print(); ConfigurationLoader::loadMemSpec(Configuration::getInstance(), pathToResources From 13baae168ba58e7c84441bf2aecdb45736783353 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Tue, 27 Mar 2018 10:10:50 +0200 Subject: [PATCH 02/11] Third party module for json added. --- .gitmodules | 3 +++ 1 file changed, 3 insertions(+) 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 From 3be950e70467228435a54033f7b5ef6b3794f0b1 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Tue, 27 Mar 2018 10:17:29 +0200 Subject: [PATCH 03/11] Added missing breaks in switch cases. --- DRAMSys/library/src/common/AddressDecoder.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DRAMSys/library/src/common/AddressDecoder.cpp b/DRAMSys/library/src/common/AddressDecoder.cpp index a473b442..938129c8 100644 --- a/DRAMSys/library/src/common/AddressDecoder.cpp +++ b/DRAMSys/library/src/common/AddressDecoder.cpp @@ -17,8 +17,10 @@ void CAddressDecoder::createInstance(Type t) { case Type::XML: m_pInstance = new xmlAddressDecoder; + break; case Type::JSON: m_pInstance = new JSONAddressDecoder; + break; } } From fd80bcabb3ba7e6380d80ec96a72cccbbd13960c Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Tue, 27 Mar 2018 10:36:09 +0200 Subject: [PATCH 04/11] Output file of ConGen added for test purposes. --- .../amconfigs/am_test_congen_output.json | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 DRAMSys/library/resources/configs/amconfigs/am_test_congen_output.json 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..74d8c492 --- /dev/null +++ b/DRAMSys/library/resources/configs/amconfigs/am_test_congen_output.json @@ -0,0 +1,44 @@ +{ + "Config": { + "numberOfBankBits": 3, + "numberOfRowBits": 14, + "numberOfColumnBits": 10, + "numberOfByteBits": 3, + "numberOfBLBits": 3 + }, + "Name": "merged_sorted", + "Solutions": [ + { + "XOR": [], + "Banks Rows": [ + { + "bank_bits": [ + 18, + 12, + 11 + ], + "rows": { + "row_bits": [ + 24, + 13, + 17, + 14, + 15, + 16, + 25, + 19, + 21, + 20, + 26, + 23, + 29, + 28 + ], + "costs": 477468 + }, + "costs": 477468 + } + ] + } + ] +} \ No newline at end of file From ef9d09662e91fc3eaf9b05ae60d02ea771fbfd52 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Tue, 27 Mar 2018 14:56:26 +0200 Subject: [PATCH 05/11] Functionality for JSONAddressDecoder added. Fixed several smaller bugs. --- DRAMSys/library/library.pro | 4 +- .../amconfigs/am_test_congen_output.json | 25 +-- DRAMSys/library/resources/resources.pri | 3 +- .../library/src/common/jsonAddressDecoder.cpp | 162 +++++++++++++++++- .../library/src/common/jsonAddressDecoder.h | 12 ++ .../library/src/common/xmlAddressdecoder.h | 12 +- DRAMSys/library/src/simulation/DRAMSys.cpp | 4 +- 7 files changed, 198 insertions(+), 24 deletions(-) diff --git a/DRAMSys/library/library.pro b/DRAMSys/library/library.pro index 20a1eb2d..df48ed98 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 @@ -194,7 +195,8 @@ HEADERS += \ src/controller/scheduler/Fr_Fcfs_read_priority.h \ src/controller/scheduler/Fr_Fcfs_grouper.h \ src/common/AddressDecoder.h \ - src/common/jsonAddressDecoder.h + src/common/jsonAddressDecoder.h \ + src/common/third_party/json/include/nlohmann/json.hpp 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 index 74d8c492..3aca28c7 100644 --- a/DRAMSys/library/resources/configs/amconfigs/am_test_congen_output.json +++ b/DRAMSys/library/resources/configs/amconfigs/am_test_congen_output.json @@ -9,30 +9,31 @@ "Name": "merged_sorted", "Solutions": [ { - "XOR": [], + "XOR": [ + ], "Banks Rows": [ { "bank_bits": [ - 18, - 12, - 11 + 27, + 28, + 29 ], "rows": { "row_bits": [ - 24, 13, - 17, 14, 15, 16, - 25, + 17, + 18, 19, - 21, 20, - 26, + 21, + 22, 23, - 29, - 28 + 24, + 25, + 26 ], "costs": 477468 }, @@ -41,4 +42,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/DRAMSys/library/resources/resources.pri b/DRAMSys/library/resources/resources.pri index cd77f0c8..cb6615b2 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/jsonAddressDecoder.cpp b/DRAMSys/library/src/common/jsonAddressDecoder.cpp index d82f41bf..dd9c8b62 100644 --- a/DRAMSys/library/src/common/jsonAddressDecoder.cpp +++ b/DRAMSys/library/src/common/jsonAddressDecoder.cpp @@ -1,4 +1,5 @@ #include "jsonAddressDecoder.h" +#include "Utils.h" #include @@ -6,6 +7,14 @@ using std::ifstream; using std::cout; using std::endl; +#include + +using json = nlohmann::json; + +#include + +using std::set; + JSONAddressDecoder::JSONAddressDecoder() { @@ -23,22 +32,173 @@ void JSONAddressDecoder::setConfiguration(std::string url) return; } + // parse json file + json data; + file >> data; + file.close(); + + // extract data + // For simplicity takethe first solution of one or more available ones. + auto sol = data["Solutions"].begin(); + assert(sol != data["Solutions"].end()); + + // Set for connected bits + set sUsed; + + // get XOR connections + 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 + 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 + 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 + 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)); + } + + 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(auto it = m_vXor.begin(); it != m_vXor.end(); it++) + { + addr &= ~(1 << it->first); + addr |= (((addr >> it->first) & 1) ^ ((addr >> it->second) & 1)) << it->first; + } + + // Unsed + result.bankgroup = 0; + result.channel = 0; + result.rank = 0; + + // Pass through of the three byte bits + result.bytes = addr & 0x7; + + // Bank + result.bank = 0; + for(auto it = m_vBankBits.begin(); it != m_vBankBits.end(); it++) + { + result.bank |= ((addr >> it->second) & 1) << it->first; + } + + // Row + result.row = 0; + for(auto it = m_vRowBits.begin(); it != m_vRowBits.end(); it++) + { + result.row |= ((addr >> it->second) & 1) << it->first; + } + + // Column + 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) { - return 0; + sc_dt::uint64 address = 0; + for(auto it = m_vBankBits.begin(); it != m_vBankBits.end(); it++) + { + address |= ((n.bank >> it->first) & 1) << it->second; + } + for(auto it = m_vRowBits.begin(); it != m_vRowBits.end(); it++) + { + address |= ((n.row >> it->first) & 1) << it->second; + } + for(auto it = m_vColumnBits.begin(); it != m_vColumnBits.end(); it++) + { + address |= ((n.column >> it->first) & 1) << it->second; + } + + address |= n.bytes; + + // Apply XOR + for(auto it = m_vXor.begin(); it != m_vXor.end(); it++) + { + address &= ~(1 << it->first); + address |= (((address >> it->first) & 1) ^ ((address >> it->second) & 1)) << 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 index bc5eb8df..354b7513 100644 --- a/DRAMSys/library/src/common/jsonAddressDecoder.h +++ b/DRAMSys/library/src/common/jsonAddressDecoder.h @@ -38,6 +38,13 @@ #include "AddressDecoder.h" +#include +#include + +using std::vector; +using std::pair; +using std::map; + class JSONAddressDecoder : public CAddressDecoder { @@ -46,6 +53,11 @@ class JSONAddressDecoder private: JSONAddressDecoder(); + vector> m_vXor; + vector> m_vBankBits; + vector> m_vRowBits; + vector> m_vColumnBits; + public: virtual void setConfiguration(std::string url); diff --git a/DRAMSys/library/src/common/xmlAddressdecoder.h b/DRAMSys/library/src/common/xmlAddressdecoder.h index ed300670..03ade6c5 100644 --- a/DRAMSys/library/src/common/xmlAddressdecoder.h +++ b/DRAMSys/library/src/common/xmlAddressdecoder.h @@ -50,7 +50,6 @@ class xmlAddressDecoder friend class CAddressDecoder; private: - xmlAddressDecoder(); std::map masks; @@ -59,16 +58,13 @@ private: tinyxml2::XMLElement* addressmapping; public: - 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); -private: - void setConfiguration(tinyxml2::XMLElement* addressMap); -public: - void print(); - std::map amount; +public: + virtual void print(); }; #endif diff --git a/DRAMSys/library/src/simulation/DRAMSys.cpp b/DRAMSys/library/src/simulation/DRAMSys.cpp index 403435d4..245b4aca 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -94,7 +94,9 @@ DRAMSys::DRAMSys(sc_module_name __attribute__((unused)) name, else if(amconfig.find(".json") != string::npos) { CAddressDecoder::createInstance(CAddressDecoder::Type::JSON); - CAddressDecoder::getInstance().setConfiguration(pathToResources + amconfig); + CAddressDecoder::getInstance().setConfiguration(pathToResources + + "configs/amconfigs/" + + amconfig); } else { From 22b766a04da932a1d025827af6993a8f9a5ef32b Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Tue, 27 Mar 2018 16:15:33 +0200 Subject: [PATCH 06/11] Added more comments. Simulator will throw an exception if no proper address mapping could be loaded. --- .../library/src/common/jsonAddressDecoder.cpp | 49 +++++++++++++++++-- .../library/src/common/jsonAddressDecoder.h | 9 ++-- DRAMSys/library/src/simulation/DRAMSys.cpp | 3 +- 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/DRAMSys/library/src/common/jsonAddressDecoder.cpp b/DRAMSys/library/src/common/jsonAddressDecoder.cpp index dd9c8b62..ad828f02 100644 --- a/DRAMSys/library/src/common/jsonAddressDecoder.cpp +++ b/DRAMSys/library/src/common/jsonAddressDecoder.cpp @@ -39,22 +39,24 @@ void JSONAddressDecoder::setConfiguration(std::string url) file.close(); // extract data - // For simplicity takethe first solution of one or more available ones. + // 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 + // 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++) { @@ -63,6 +65,7 @@ void JSONAddressDecoder::setConfiguration(std::string url) } // 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++) { @@ -80,6 +83,8 @@ void JSONAddressDecoder::setConfiguration(std::string url) 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++) { @@ -89,6 +94,7 @@ void JSONAddressDecoder::setConfiguration(std::string url) 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()); @@ -101,6 +107,8 @@ 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++) { addr &= ~(1 << it->first); @@ -116,6 +124,10 @@ DecodedAddress JSONAddressDecoder::decodeAddress(sc_dt::uint64 addr) 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++) { @@ -123,6 +135,10 @@ DecodedAddress JSONAddressDecoder::decodeAddress(sc_dt::uint64 addr) } // 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++) { @@ -130,6 +146,10 @@ DecodedAddress JSONAddressDecoder::decodeAddress(sc_dt::uint64 addr) } // 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++) { @@ -142,23 +162,42 @@ DecodedAddress JSONAddressDecoder::decodeAddress(sc_dt::uint64 addr) sc_dt::uint64 JSONAddressDecoder::encodeAddress(DecodedAddress n) { sc_dt::uint64 address = 0; - for(auto it = m_vBankBits.begin(); it != m_vBankBits.end(); it++) + + // 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(auto it = m_vXor.begin(); it != m_vXor.end(); it++) + // 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++) { address &= ~(1 << it->first); address |= (((address >> it->first) & 1) ^ ((address >> it->second) & 1)) << it->first; diff --git a/DRAMSys/library/src/common/jsonAddressDecoder.h b/DRAMSys/library/src/common/jsonAddressDecoder.h index 354b7513..843db6fc 100644 --- a/DRAMSys/library/src/common/jsonAddressDecoder.h +++ b/DRAMSys/library/src/common/jsonAddressDecoder.h @@ -53,10 +53,11 @@ class JSONAddressDecoder private: JSONAddressDecoder(); - vector> m_vXor; - vector> m_vBankBits; - vector> m_vRowBits; - vector> m_vColumnBits; + 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); diff --git a/DRAMSys/library/src/simulation/DRAMSys.cpp b/DRAMSys/library/src/simulation/DRAMSys.cpp index 245b4aca..0b2db6fc 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" @@ -100,7 +101,7 @@ DRAMSys::DRAMSys(sc_module_name __attribute__((unused)) name, } else { - cout << "No address mapping loaded. Unknown file extension" << endl; + throw std::runtime_error("No address mapping loaded. Unknown file extension"); } CAddressDecoder::getInstance().print(); From 9ed217c01d12edc75f141b96c69a93a497a8d110 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Fri, 30 Mar 2018 16:47:43 +0200 Subject: [PATCH 07/11] Created a section for address decoding with json files. --- README.md | 123 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 96 insertions(+), 27 deletions(-) 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 From ff91c37df335f3806b40efff556e5087cefe328f Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Fri, 30 Mar 2018 17:51:12 +0200 Subject: [PATCH 08/11] Changes suggest by review colleagues. --- DRAMSys/library/src/common/AddressDecoder.cpp | 43 +++++++++++++++++-- DRAMSys/library/src/common/AddressDecoder.h | 8 ++-- .../library/src/common/jsonAddressDecoder.cpp | 35 +++++++++++++++ .../library/src/common/jsonAddressDecoder.h | 6 ++- .../library/src/common/xmlAddressdecoder.h | 6 ++- .../core/configuration/Configuration.cpp | 4 +- DRAMSys/library/src/error/errormodel.cpp | 6 +-- DRAMSys/library/src/error/errormodel.h | 4 +- DRAMSys/library/src/simulation/Arbiter.h | 14 +++--- DRAMSys/library/src/simulation/DRAMSys.cpp | 10 ++--- 10 files changed, 105 insertions(+), 31 deletions(-) diff --git a/DRAMSys/library/src/common/AddressDecoder.cpp b/DRAMSys/library/src/common/AddressDecoder.cpp index 938129c8..63e2e921 100644 --- a/DRAMSys/library/src/common/AddressDecoder.cpp +++ b/DRAMSys/library/src/common/AddressDecoder.cpp @@ -1,16 +1,51 @@ +/* + * 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" -CAddressDecoder* CAddressDecoder::m_pInstance = nullptr; +AddressDecoder* AddressDecoder::m_pInstance = nullptr; -CAddressDecoder& CAddressDecoder::getInstance() +AddressDecoder& AddressDecoder::getInstance() { assert(m_pInstance != nullptr); return *m_pInstance; } -void CAddressDecoder::createInstance(Type t) +void AddressDecoder::createInstance(Type t) { assert(m_pInstance == nullptr); switch(t) @@ -24,7 +59,7 @@ void CAddressDecoder::createInstance(Type t) } } -CAddressDecoder::CAddressDecoder() +AddressDecoder::AddressDecoder() { } diff --git a/DRAMSys/library/src/common/AddressDecoder.h b/DRAMSys/library/src/common/AddressDecoder.h index c5c23a70..be74980f 100644 --- a/DRAMSys/library/src/common/AddressDecoder.h +++ b/DRAMSys/library/src/common/AddressDecoder.h @@ -63,7 +63,7 @@ struct DecodedAddress unsigned int bytes; }; -class CAddressDecoder +class AddressDecoder { public: enum class Type @@ -73,11 +73,11 @@ public: }; protected: - CAddressDecoder(); + AddressDecoder(); - static CAddressDecoder* m_pInstance; + static AddressDecoder* m_pInstance; public: - static CAddressDecoder& getInstance(); + static AddressDecoder& getInstance(); static void createInstance(Type t); virtual void setConfiguration(std::string url) = 0; diff --git a/DRAMSys/library/src/common/jsonAddressDecoder.cpp b/DRAMSys/library/src/common/jsonAddressDecoder.cpp index dd9c8b62..9fdf09bd 100644 --- a/DRAMSys/library/src/common/jsonAddressDecoder.cpp +++ b/DRAMSys/library/src/common/jsonAddressDecoder.cpp @@ -1,3 +1,38 @@ +/* + * 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" diff --git a/DRAMSys/library/src/common/jsonAddressDecoder.h b/DRAMSys/library/src/common/jsonAddressDecoder.h index 354b7513..475d084d 100644 --- a/DRAMSys/library/src/common/jsonAddressDecoder.h +++ b/DRAMSys/library/src/common/jsonAddressDecoder.h @@ -46,9 +46,11 @@ using std::pair; using std::map; class JSONAddressDecoder - : public CAddressDecoder + : public AddressDecoder { - friend class CAddressDecoder; + // Friendship needed so that the AddressDecoder can access the + // constructor of this class to create the object in CreateInstance. + friend class AddressDecoder; private: JSONAddressDecoder(); diff --git a/DRAMSys/library/src/common/xmlAddressdecoder.h b/DRAMSys/library/src/common/xmlAddressdecoder.h index 03ade6c5..7266b8df 100644 --- a/DRAMSys/library/src/common/xmlAddressdecoder.h +++ b/DRAMSys/library/src/common/xmlAddressdecoder.h @@ -45,9 +45,11 @@ #include "AddressDecoder.h" class xmlAddressDecoder - : public CAddressDecoder + : public AddressDecoder { - friend class CAddressDecoder; + // Friendship needed so that the AddressDecoder can access the + // constructor of this class to create the object in CreateInstance. + friend class AddressDecoder; private: xmlAddressDecoder(); diff --git a/DRAMSys/library/src/controller/core/configuration/Configuration.cpp b/DRAMSys/library/src/controller/core/configuration/Configuration.cpp index 29cc6f94..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 = CAddressDecoder::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 = CAddressDecoder::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 18966452..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 = CAddressDecoder::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 = CAddressDecoder::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 = CAddressDecoder::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 d3914c6c..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 = CAddressDecoder::getInstance().encodeAddress(first); - sc_dt::uint64 addrSecond = CAddressDecoder::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 5b60b410..72e8e1c8 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 = CAddressDecoder::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 = CAddressDecoder::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+1), 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 >= CAddressDecoder::getInstance().amount["channel"]) { + if (decodedAddress.channel >= AddressDecoder::getInstance().amount["channel"]) { return false; } - if (decodedAddress.bank >= CAddressDecoder::getInstance().amount["bank"]) { + if (decodedAddress.bank >= AddressDecoder::getInstance().amount["bank"]) { return false; } - if (decodedAddress.bankgroup > CAddressDecoder::getInstance().amount["bankgroup"]) { + if (decodedAddress.bankgroup > AddressDecoder::getInstance().amount["bankgroup"]) { return false; } - if (decodedAddress.column >= CAddressDecoder::getInstance().amount["column"]) { + if (decodedAddress.column >= AddressDecoder::getInstance().amount["column"]) { return false; } - if (decodedAddress.row >= CAddressDecoder::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 245b4aca..e37ae09f 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -86,15 +86,15 @@ DRAMSys::DRAMSys(sc_module_name __attribute__((unused)) name, if(amconfig.find(".xml") != string::npos) { - CAddressDecoder::createInstance(CAddressDecoder::Type::XML); - CAddressDecoder::getInstance().setConfiguration(pathToResources + AddressDecoder::createInstance(AddressDecoder::Type::XML); + AddressDecoder::getInstance().setConfiguration(pathToResources + "configs/amconfigs/" + amconfig); } else if(amconfig.find(".json") != string::npos) { - CAddressDecoder::createInstance(CAddressDecoder::Type::JSON); - CAddressDecoder::getInstance().setConfiguration(pathToResources + AddressDecoder::createInstance(AddressDecoder::Type::JSON); + AddressDecoder::getInstance().setConfiguration(pathToResources + "configs/amconfigs/" + amconfig); } @@ -103,7 +103,7 @@ DRAMSys::DRAMSys(sc_module_name __attribute__((unused)) name, cout << "No address mapping loaded. Unknown file extension" << endl; } - CAddressDecoder::getInstance().print(); + AddressDecoder::getInstance().print(); ConfigurationLoader::loadMemSpec(Configuration::getInstance(), pathToResources From 42b5ad004e686328f181ed9b3b33a5a260b3f240 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Tue, 3 Apr 2018 10:41:35 +0200 Subject: [PATCH 09/11] Add missing '\' in library.pro --- DRAMSys/library/library.pro | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DRAMSys/library/library.pro b/DRAMSys/library/library.pro index 4dbfd863..56353e00 100644 --- a/DRAMSys/library/library.pro +++ b/DRAMSys/library/library.pro @@ -126,6 +126,7 @@ SOURCES += \ 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 \ @@ -193,12 +194,11 @@ HEADERS += \ src/error/eccbaseclass.h \ src/error/ecchamming.h \ src/controller/scheduler/Fr_Fcfs_read_priority.h \ - src/controller/scheduler/Fr_Fcfs_grouper.h + src/controller/scheduler/Fr_Fcfs_grouper.h \ src/simulation/IArbiter.h \ src/simulation/SimpleArbiter.h \ src/common/AddressDecoder.h \ - src/common/jsonAddressDecoder.h \ - src/common/third_party/json/include/nlohmann/json.hpp + src/common/jsonAddressDecoder.h thermalsim = $$(THERMALSIM) isEmpty(thermalsim) { From 23648c6f6060379d4a3cd7df0664df9e7bf73690 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Tue, 3 Apr 2018 11:43:40 +0200 Subject: [PATCH 10/11] Added default case to AddressDecoder::CreateInstance. --- DRAMSys/library/src/common/AddressDecoder.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/DRAMSys/library/src/common/AddressDecoder.cpp b/DRAMSys/library/src/common/AddressDecoder.cpp index 63e2e921..266e9bca 100644 --- a/DRAMSys/library/src/common/AddressDecoder.cpp +++ b/DRAMSys/library/src/common/AddressDecoder.cpp @@ -56,6 +56,9 @@ void AddressDecoder::createInstance(Type t) case Type::JSON: m_pInstance = new JSONAddressDecoder; break; + default: + throw std::logic_error("Instance type not supported."); + break; } } From 7a715d171fb722bbb538c9de8bd3d9c2f41c2aa7 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Tue, 10 Apr 2018 16:36:57 +0200 Subject: [PATCH 11/11] Fixed a bug in the XOR mapping --- DRAMSys/library/src/common/jsonAddressDecoder.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/DRAMSys/library/src/common/jsonAddressDecoder.cpp b/DRAMSys/library/src/common/jsonAddressDecoder.cpp index 3f32cb79..333c200d 100644 --- a/DRAMSys/library/src/common/jsonAddressDecoder.cpp +++ b/DRAMSys/library/src/common/jsonAddressDecoder.cpp @@ -146,8 +146,11 @@ DecodedAddress JSONAddressDecoder::decodeAddress(sc_dt::uint64 addr) // 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 |= (((addr >> it->first) & 1) ^ ((addr >> it->second) & 1)) << it->first; + addr |= new_bank_bit << it->first; } // Unsed @@ -234,8 +237,10 @@ sc_dt::uint64 JSONAddressDecoder::encodeAddress(DecodedAddress n) // 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++) { - address &= ~(1 << it->first); - address |= (((address >> it->first) & 1) ^ ((address >> it->second) & 1)) << it->first; + 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;