From f2907093232c6a36e7a9e3401f599c41c2b07f65 Mon Sep 17 00:00:00 2001 From: sprado Date: Sat, 10 Mar 2018 16:04:22 +0100 Subject: [PATCH] Changes Requested --- DRAMSys/library/src/common/dramExtension.cpp | 20 +++ DRAMSys/library/src/common/dramExtension.h | 4 + DRAMSys/library/src/simulation/IArbiter.h | 68 ++++++-- .../library/src/simulation/SimpleArbiter.h | 149 +++++++----------- README.md | 9 ++ 5 files changed, 147 insertions(+), 103 deletions(-) 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/simulation/IArbiter.h b/DRAMSys/library/src/simulation/IArbiter.h index 7cf75bff..1dc3c646 100644 --- a/DRAMSys/library/src/simulation/IArbiter.h +++ b/DRAMSys/library/src/simulation/IArbiter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, University of Kaiserslautern + * Copyright (c) 2018, University of Kaiserslautern * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,8 +30,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: - * Matthias Jung * Felipe S. Prado + * Matthias Jung */ #ifndef IARBITER_H_ @@ -51,20 +51,20 @@ using namespace tlm; struct IArbiter: public sc_module { public: - tlm_utils::multi_passthrough_initiator_socket iSocket; tlm_utils::multi_passthrough_target_socket tSocket; + tlm_utils::multi_passthrough_initiator_socket iSocket; SC_CTOR(IArbiter) { - // 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); - // 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); } @@ -73,15 +73,57 @@ public: virtual void incrementNumberOfOutputBufferTransactions(unsigned int initiatorSocket) = 0; protected: - // 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; - // 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; - virtual unsigned int transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans) = 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 index 4ae4c89d..cbd252f5 100644 --- a/DRAMSys/library/src/simulation/SimpleArbiter.h +++ b/DRAMSys/library/src/simulation/SimpleArbiter.h @@ -1,3 +1,39 @@ +/* + * 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 @@ -9,6 +45,8 @@ 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) { @@ -30,26 +68,6 @@ public: protected: TlmRecorder* tlmRecorder; - - // 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()); - - sendToInitiator(getPayloadThread(payload)-1, payload, phase, 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; - } - // 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) @@ -69,7 +87,7 @@ protected: tlmRecorder->recordPhase(payload, phase, sc_time_stamp()+fwDelay); // Forward Path [1.0] - sendToChannel(getPayloadChannel(payload), payload, phase, fwDelay); + iSocket[getISocketIndex(payload)]->nb_transport_fw(payload, phase, fwDelay); } else if(phase == END_RESP) { @@ -86,86 +104,37 @@ protected: 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); - DecodedAddress decodedAddress = xmlAddressDecoder::getInstance().decodeAddress(trans.get_address()); - size_t index = decodedAddress.channel*Configuration::getInstance().memSpec.NumberOfBanks + DramExtension::getBank(trans).ID(); - return iSocket[index]->transport_dbg(trans); - } - - virtual tlm_sync_enum sendToChannel(unsigned int /*channelId*/, tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay) - { - tlm_phase TPhase = phase; - sc_time TDelay = delay; - return iSocket[getISocketIndex(payload)]->nb_transport_fw(payload, TPhase, TDelay); + return iSocket[getISocketIndex(trans)]->transport_dbg(trans); } virtual unsigned int getISocketIndex(tlm_generic_payload& payload) { return DramExtension::getBank(payload).ID(); } - - virtual tlm_sync_enum sendToInitiator(unsigned int id, tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay) - { - tlm_phase TPhase = phase; - sc_time TDelay = delay; - return tSocket[id]->nb_transport_bw(payload, TPhase, TDelay); - } - - 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; - } - - unsigned int getPayloadChannel(tlm_generic_payload& payload) - { - return DramExtension::getExtension(payload).getChannel().ID(); - } - - unsigned int getPayloadThread(tlm_generic_payload& payload) - { - return DramExtension::getExtension(payload).getThread().ID(); - } }; #endif // SIMPLEARBITER_H diff --git a/README.md b/README.md index 84227900..e16a7dde 100644 --- a/README.md +++ b/README.md @@ -724,6 +724,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.