diff --git a/DRAMSys/library/library.pro b/DRAMSys/library/library.pro index df48ed98..4dbfd863 100644 --- a/DRAMSys/library/library.pro +++ b/DRAMSys/library/library.pro @@ -193,7 +193,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/simulation/IArbiter.h \ + src/simulation/SimpleArbiter.h \ src/common/AddressDecoder.h \ src/common/jsonAddressDecoder.h \ src/common/third_party/json/include/nlohmann/json.hpp diff --git a/DRAMSys/library/src/common/dramExtension.cpp b/DRAMSys/library/src/common/dramExtension.cpp index a0a44015..6a19eb08 100644 --- a/DRAMSys/library/src/common/dramExtension.cpp +++ b/DRAMSys/library/src/common/dramExtension.cpp @@ -82,6 +82,26 @@ Bank DramExtension::getBank(const tlm_generic_payload &payload) return DramExtension::getBank(&payload); } +Channel DramExtension::getChannel(const tlm_generic_payload *payload) +{ + return DramExtension::getExtension(payload).getChannel(); +} + +Channel DramExtension::getChannel(const tlm_generic_payload &payload) +{ + return DramExtension::getChannel(&payload); +} + +Thread DramExtension::getThread(const tlm_generic_payload *payload) +{ + return DramExtension::getExtension(payload).getThread(); +} + +Thread DramExtension::getThread(const tlm_generic_payload &payload) +{ + return DramExtension::getThread(&payload); +} + Row DramExtension::getRow(const tlm_generic_payload *payload) { return DramExtension::getExtension(payload).getRow(); diff --git a/DRAMSys/library/src/common/dramExtension.h b/DRAMSys/library/src/common/dramExtension.h index ab30decf..b61ac90d 100644 --- a/DRAMSys/library/src/common/dramExtension.h +++ b/DRAMSys/library/src/common/dramExtension.h @@ -177,6 +177,10 @@ public: // Used for convience, caller could also use getExtension(..) to access these field static Bank getBank(const tlm::tlm_generic_payload *payload); static Bank getBank(const tlm::tlm_generic_payload &payload); + static Channel getChannel(const tlm::tlm_generic_payload *payload); + static Channel getChannel(const tlm::tlm_generic_payload &payload); + static Thread getThread(const tlm::tlm_generic_payload *payload); + static Thread getThread(const tlm::tlm_generic_payload &payload); static Row getRow(const tlm::tlm_generic_payload *payload); static Row getRow(const tlm::tlm_generic_payload &payload); diff --git a/DRAMSys/library/src/common/jsonAddressDecoder.cpp b/DRAMSys/library/src/common/jsonAddressDecoder.cpp index 9fdf09bd..3f32cb79 100644 --- a/DRAMSys/library/src/common/jsonAddressDecoder.cpp +++ b/DRAMSys/library/src/common/jsonAddressDecoder.cpp @@ -74,22 +74,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++) { @@ -98,6 +100,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++) { @@ -115,6 +118,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++) { @@ -124,6 +129,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()); @@ -136,6 +142,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); @@ -151,6 +159,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++) { @@ -158,6 +170,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++) { @@ -165,6 +181,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++) { @@ -177,23 +197,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 475d084d..ee25d77e 100644 --- a/DRAMSys/library/src/common/jsonAddressDecoder.h +++ b/DRAMSys/library/src/common/jsonAddressDecoder.h @@ -55,10 +55,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 e37ae09f..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" @@ -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"); } AddressDecoder::getInstance().print(); diff --git a/DRAMSys/library/src/simulation/IArbiter.h b/DRAMSys/library/src/simulation/IArbiter.h new file mode 100644 index 00000000..1dc3c646 --- /dev/null +++ b/DRAMSys/library/src/simulation/IArbiter.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2018, University of Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Felipe S. Prado + * Matthias Jung + */ + +#ifndef IARBITER_H_ +#define IARBITER_H_ + +#include +#include +#include +#include +#include +#include +#include +#include "../controller/core/configuration/ConfigurationLoader.h" + +using namespace std; +using namespace tlm; + +struct IArbiter: public sc_module { +public: + tlm_utils::multi_passthrough_target_socket tSocket; + tlm_utils::multi_passthrough_initiator_socket iSocket; + + SC_CTOR(IArbiter) { + // One or more devices can accesss all the memory units through the arbiter. + // Devices' initiator sockets are bound to arbiter's target sockets. + // As soon the arbiter receives a request in any of its target sockets it should treat and forward it to the proper memory channel. + tSocket.register_nb_transport_fw(this, &IArbiter::nb_transport_fw); + + // The arbiter communicates with one or more memory unity through one or more sockets (one or more memory channels). + // Each of the arbiter's initiator sockets is bound to a memory controller's target socket. + // Anytime an transaction comes from a memory unity to the arbiter the "bw" callback is called. + iSocket.register_nb_transport_bw(this, &IArbiter::nb_transport_bw); + + tSocket.register_transport_dbg(this, &IArbiter::transport_dbg); + } + + virtual void setTlmRecorder(TlmRecorder* recorder) = 0; + virtual bool isOutputBufferFull(unsigned int initiatorSocket) = 0; + virtual void incrementNumberOfOutputBufferTransactions(unsigned int initiatorSocket) = 0; + +protected: + // Initiated by initiator side + // This function is called when an arbiter's target socket receives a transaction from a device + virtual tlm_sync_enum nb_transport_fw(int id, tlm_generic_payload& payload, tlm_phase& phase, sc_time& fwDelay) = 0; + + // Initiated by dram side + // This function is called when an arbiter's initiator socket receives a transaction from a memory controller + virtual tlm_sync_enum nb_transport_bw(int channelId, tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay) = 0; + + virtual unsigned int transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans) = 0; + + void printDebugMessage(std::string message) + { + DebugManager::getInstance().printDebugMessage(this->name(), message); + } + + void appendDramExtension(int socketId, tlm_generic_payload& payload) + { + // Append Generation Extension + GenerationExtension* genExtension = new GenerationExtension(clkAlign(sc_time_stamp(),Configuration::getInstance().ControllerClk)); + payload.set_auto_extension(genExtension); + + unsigned int burstlength = payload.get_streaming_width(); + DecodedAddress decodedAddress = xmlAddressDecoder::getInstance().decodeAddress(payload.get_address()); + // Check the valid range of decodedAddress + if (addressIsValid(decodedAddress)) { + DramExtension* extension = new DramExtension(Thread(socketId+1), Channel(decodedAddress.channel), Bank(decodedAddress.bank), BankGroup(decodedAddress.bankgroup), Row(decodedAddress.row), Column(decodedAddress.column),burstlength); + payload.set_auto_extension(extension); + } else { + SC_REPORT_FATAL("Arbiter", "Decoded Address are not inside the valid range"); + } + } + + bool addressIsValid(DecodedAddress& decodedAddress) + { + if (decodedAddress.channel >= xmlAddressDecoder::getInstance().amount["channel"]) { + return false; + } + if (decodedAddress.bank >= xmlAddressDecoder::getInstance().amount["bank"]) { + return false; + } + if (decodedAddress.bankgroup > xmlAddressDecoder::getInstance().amount["bankgroup"]) { + return false; + } + if (decodedAddress.column >= xmlAddressDecoder::getInstance().amount["column"]) { + return false; + } + if (decodedAddress.row >= xmlAddressDecoder::getInstance().amount["row"]) { + return false; + } + return true; + } +}; + +#endif /* IARBITER_H_ */ diff --git a/DRAMSys/library/src/simulation/SimpleArbiter.h b/DRAMSys/library/src/simulation/SimpleArbiter.h new file mode 100644 index 00000000..cbd252f5 --- /dev/null +++ b/DRAMSys/library/src/simulation/SimpleArbiter.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2018, University of Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Felipe S. Prado + * Matthias Jung + */ + +#ifndef SIMPLEARBITER_H +#define SIMPLEARBITER_H + +#include "IArbiter.h" +#include "../common/xmlAddressdecoder.h" +#include "../common/dramExtension.h" +#include "../controller/core/TimingCalculation.h" + +using namespace std; +using namespace tlm; + +// Annotated References [X,Y] --> Please refer to TLM AT Cheat Sheet on README + +struct SimpleArbiter: public IArbiter{ +public: + SimpleArbiter(sc_module_name name) : IArbiter(name) { + } + + void setTlmRecorder(TlmRecorder* recorder) + { + tlmRecorder = recorder; + } + + virtual bool isOutputBufferFull(unsigned int /*initiatorSocket*/) + { + return false; + } + + virtual void incrementNumberOfOutputBufferTransactions(unsigned int /*initiatorSocket*/) + { + } + +protected: + TlmRecorder* tlmRecorder; + // Initiated by initiator side + // This function is called when an arbiter's target socket receives a transaction from a device + virtual tlm_sync_enum nb_transport_fw(int id, tlm_generic_payload& payload, tlm_phase& phase, sc_time& fwDelay) + { + if (phase == BEGIN_REQ) + { + payload.acquire(); + // adjust address offset, e.g. for gem5 simulation + payload.set_address(payload.get_address() - Configuration::getInstance().AddressOffset); + + // In the begin request phase the socket ID is appended to the payload. + // It will extracted from the payload and used later. + appendDramExtension(id, payload); + + tlmRecorder->recordArbiterPhase(payload, phase, sc_time_stamp()+fwDelay); + tlmRecorder->recordArbiterPhase(payload, END_REQ,sc_time_stamp()+fwDelay); + tlmRecorder->recordPhase(payload, phase, sc_time_stamp()+fwDelay); + + // Forward Path [1.0] + iSocket[getISocketIndex(payload)]->nb_transport_fw(payload, phase, fwDelay); + } + else if(phase == END_RESP) + { + payload.release(); + tlmRecorder->recordArbiterPhase(payload, phase, sc_time_stamp()+fwDelay); + } + else + { + SC_REPORT_FATAL("Arbiter", "Illegal phase received by initiator"); + } + + // 4-Phase Handshake [1.1] + // 4-Phase Handshake [1.7] + return TLM_ACCEPTED; + } + + // Initiated by dram side + // This function is called when an arbiter's initiator socket receives a transaction from a memory controller + virtual tlm_sync_enum nb_transport_bw(int /*channelId*/, tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay) + { + tlmRecorder->recordPhase(payload, phase, bwDelay + sc_time_stamp()); + + tSocket[DramExtension::getThread(payload).ID()-1]->nb_transport_bw(payload, TPhase, bwDelay); + + if(phase == BEGIN_RESP) + { + // Early Completion [3.1] + tlmRecorder->recordPhase(payload, END_RESP, bwDelay + sc_time_stamp()); + tlmRecorder->recordArbiterPhase(payload, BEGIN_RESP, sc_time_stamp()+bwDelay); + return TLM_COMPLETED; + } + // 4-Phase Handshake [1.3] + return TLM_ACCEPTED; + } + + virtual unsigned int transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans) + { + // adjust address offset: + trans.set_address(trans.get_address() - Configuration::getInstance().AddressOffset); + + return iSocket[getISocketIndex(trans)]->transport_dbg(trans); + } + + virtual unsigned int getISocketIndex(tlm_generic_payload& payload) + { + return DramExtension::getBank(payload).ID(); + } +}; + +#endif // SIMPLEARBITER_H diff --git a/README.md b/README.md index 84227900..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 @@ -724,6 +793,15 @@ For more information check the documentation in [DRAMSylva folder](DRAMSys/libra #### DRAMsys Diagrams +- **TLM Approximately Timed (AT)** + + The figure below shows a cheat sheet with the possibilities that the TLM AT protocol + offers. The annotated references [X,Y] are placed into the source code for a better + orientation. + + ![TLM AT Cheat Sheet](DRAMSys/docs/images/tlmATCheatSheet.png) + + - **Payload Extension information** GenerationExtension is added in TracePlayer and DramExtension is added in Arbiter. @@ -732,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