diff --git a/DRAMSys/DRAMSys.astylerc b/DRAMSys/DRAMSys.astylerc new file mode 100644 index 00000000..52adf134 --- /dev/null +++ b/DRAMSys/DRAMSys.astylerc @@ -0,0 +1,10 @@ +--style=kr +--indent=spaces=4 +--align-pointer=name +--align-reference=name +--convert-tabs +--attach-namespaces +--max-code-length=80 +--max-instatement-indent=100 +--pad-header +--pad-oper diff --git a/DRAMSys/gem5/gem5.pro b/DRAMSys/gem5/gem5.pro index 32e43c2f..b848f32b 100644 --- a/DRAMSys/gem5/gem5.pro +++ b/DRAMSys/gem5/gem5.pro @@ -73,3 +73,4 @@ SOURCES += $${gem5_root}/util/tlm/src/sim_control.cc SOURCES += main.cpp +DISTFILES += ../DRAMSys.astylerc diff --git a/DRAMSys/library/library.pro b/DRAMSys/library/library.pro index ad74744a..680d8e3a 100644 --- a/DRAMSys/library/library.pro +++ b/DRAMSys/library/library.pro @@ -190,7 +190,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 thermalsim = $$(THERMALSIM) isEmpty(thermalsim) { @@ -232,3 +234,4 @@ $$eval(thermalsim) { # Additional Files: include(resources/resources.pri) +DISTFILES += ../DRAMSys.astylerc diff --git a/DRAMSys/library/resources/resources.pri b/DRAMSys/library/resources/resources.pri index 0b015adf..32f14d6b 100644 --- a/DRAMSys/library/resources/resources.pri +++ b/DRAMSys/library/resources/resources.pri @@ -1,5 +1,5 @@ # Relative paths to "DRAMSys/library" because this file is included in -# "DRAMSys/library/simulator.pro" +# "DRAMSys/library/library.pro" # Simulation Files OTHER_FILES += resources/simulations/ddr3-example.xml diff --git a/DRAMSys/library/resources/scripts/createTraceDB.sql b/DRAMSys/library/resources/scripts/createTraceDB.sql index 5f1d0d38..1ba6c3aa 100644 --- a/DRAMSys/library/resources/scripts/createTraceDB.sql +++ b/DRAMSys/library/resources/scripts/createTraceDB.sql @@ -23,7 +23,10 @@ CREATE TABLE GeneralInfo( MCconfig TEXT, Memspec TEXT, Traces TEXT, - WindowSize INTEGER + WindowSize INTEGER, + FlexibleRefresh INTEGER, + MaxRefBurst INTEGER, + ControllerThread INTEGER ); CREATE TABLE Power( diff --git a/DRAMSys/library/src/common/DebugManager.h b/DRAMSys/library/src/common/DebugManager.h index 3be8492b..69740367 100644 --- a/DRAMSys/library/src/common/DebugManager.h +++ b/DRAMSys/library/src/common/DebugManager.h @@ -40,7 +40,6 @@ #include #include #include - #include "Utils.h" class DebugManager diff --git a/DRAMSys/library/src/common/TlmRecorder.cpp b/DRAMSys/library/src/common/TlmRecorder.cpp index d7a68f5f..59e546aa 100644 --- a/DRAMSys/library/src/common/TlmRecorder.cpp +++ b/DRAMSys/library/src/common/TlmRecorder.cpp @@ -44,6 +44,7 @@ #include "dramExtension.h" #include "xmlAddressdecoder.h" #include "../controller/core/configuration/Configuration.h" +#include "../controller/Controller.h" using namespace std; @@ -154,7 +155,7 @@ void TlmRecorder::introduceTransactionSystem(tlm::tlm_generic_payload& trans) currentTransactionsInSystem[&trans].burstlength = trans.get_streaming_width(); currentTransactionsInSystem[&trans].dramExtension = DramExtension::getExtension(trans); - if(DramExtension::getExtension(trans).getThread().ID() == 0) + if(DramExtension::getExtension(trans).getThread().ID() == Controller::ControllerThreadId()) currentTransactionsInSystem[&trans].timeOfGeneration = SC_ZERO_TIME; else currentTransactionsInSystem[&trans].timeOfGeneration = GenerationExtension::getExtension(&trans).TimeOfGeneration(); @@ -285,8 +286,8 @@ void TlmRecorder::prepareSqlStatements() updatePhaseString = "UPDATE Phases SET PhaseEnd = :end WHERE Transact = :trans AND PhaseName = :name"; insertGeneralInfoString = - "INSERT INTO GeneralInfo (NumberOfTransactions,TraceEnd,NumberOfBanks,clk,UnitOfTime,MCconfig,Memspec,Traces, WindowSize) VALUES" - "(:numberOfTransactions,:end,:numberOfBanks,:clk,:unitOfTime,:mcconfig,:memspec,:traces,:windowSize)"; + "INSERT INTO GeneralInfo (NumberOfTransactions,TraceEnd,NumberOfBanks,clk,UnitOfTime,MCconfig,Memspec,Traces, WindowSize, FlexibleRefresh, MaxRefBurst, ControllerThread) VALUES" + "(:numberOfTransactions,:end,:numberOfBanks,:clk,:unitOfTime,:mcconfig,:memspec,:traces,:windowSize, :flexibleRefresh, :maxRefBurst, :controllerThread)"; insertDebugMessageString = "INSERT INTO DebugMessages (Time,Message) Values (:time,:message)"; insertPowerString = "INSERT INTO Power VALUES (:time,:averagePower)"; @@ -319,11 +320,21 @@ void TlmRecorder::insertGeneralInfo() sqlite3_bind_text(insertGeneralInfoStatement, 6, mcconfig.c_str(), mcconfig.length(), NULL); sqlite3_bind_text(insertGeneralInfoStatement, 7, memspec.c_str(), memspec.length(), NULL); sqlite3_bind_text(insertGeneralInfoStatement, 8, traces.c_str(), traces.length(), NULL); - if(!Configuration::getInstance().EnableWindowing) + if (!Configuration::getInstance().EnableWindowing) sqlite3_bind_int64(insertGeneralInfoStatement, 9, 0); else sqlite3_bind_int64(insertGeneralInfoStatement, 9, (Configuration::getInstance().memSpec.clk*Configuration::getInstance().WindowSize).value()); - + if (Configuration::getInstance().ControllerCoreEnableRefPostpone || Configuration::getInstance().ControllerCoreEnableRefPullIn) + { + sqlite3_bind_int(insertGeneralInfoStatement, 10, 1); + sqlite3_bind_int(insertGeneralInfoStatement, 11, std::max(Configuration::getInstance().ControllerCoreMaxPulledInARCmd, Configuration::getInstance().ControllerCoreMaxPostponedARCmd)); + } + else + { + sqlite3_bind_int(insertGeneralInfoStatement, 10, 0); + sqlite3_bind_int(insertGeneralInfoStatement, 11, 0); + } + sqlite3_bind_int(insertGeneralInfoStatement, 12, Controller::ControllerThreadId()); ; executeSqlStatement(insertGeneralInfoStatement); } diff --git a/DRAMSys/library/src/common/Utils.cpp b/DRAMSys/library/src/common/Utils.cpp index e5b09fee..18bd282a 100644 --- a/DRAMSys/library/src/common/Utils.cpp +++ b/DRAMSys/library/src/common/Utils.cpp @@ -40,6 +40,7 @@ #include #include #include "dramExtension.h" +#include "../controller/Controller.h" using namespace std; using namespace tinyxml2; @@ -232,7 +233,7 @@ void setUpDummy(tlm::tlm_generic_payload& payload, Bank& bank) payload.set_dmi_allowed(false); payload.set_byte_enable_length(0); payload.set_streaming_width(0); - payload.set_extension(new DramExtension(Thread(0), bank, BankGroup(0), Row(0), Column(0))); //payload takes ownership + payload.set_extension(new DramExtension(Thread(Controller::ControllerThreadId()), bank, BankGroup(0), Row(0), Column(0))); //payload takes ownership //TODO .. Dummies muessen noch banggruppe und rank sauber bekommen .. noch was ueberlegen!!! } diff --git a/DRAMSys/library/src/common/Utils.h b/DRAMSys/library/src/common/Utils.h index 78dc85ed..1e08cace 100644 --- a/DRAMSys/library/src/common/Utils.h +++ b/DRAMSys/library/src/common/Utils.h @@ -47,7 +47,6 @@ #include "dramExtension.h" #include "third_party/tinyxml2/tinyxml2.h" - #define DEF_SINGLETON( NAME ) \ public: \ static NAME& getInstance() \ 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/controller/Controller.h b/DRAMSys/library/src/controller/Controller.h index 4b58d50d..d280b9cf 100644 --- a/DRAMSys/library/src/controller/Controller.h +++ b/DRAMSys/library/src/controller/Controller.h @@ -111,6 +111,8 @@ public: unsigned int getTotalNumberOfPayloadsInSystem(); void scheduleNextFromScheduler(Bank bank) override; + static unsigned int ControllerThreadId() {return controllerThreadId;} + private: void buildScheduler(); void payloadEntersSystem(tlm_generic_payload& payload); @@ -161,6 +163,7 @@ private: // SystemC related: virtual void end_of_simulation() override; + static const unsigned int controllerThreadId = INT_MAX; }; #endif /* CONTROLLERWRAPPER_H_ */ diff --git a/DRAMSys/library/src/controller/scheduler/Fifo.cpp b/DRAMSys/library/src/controller/scheduler/Fifo.cpp index 7d7a90e1..60aecf5b 100644 --- a/DRAMSys/library/src/controller/scheduler/Fifo.cpp +++ b/DRAMSys/library/src/controller/scheduler/Fifo.cpp @@ -60,7 +60,7 @@ pair Fifo::getNextRequest(Bank bank) return pair(Command::NOP, NULL); } -gp* Fifo::getPendingRequest(Bank bank) +gp* Fifo::getPendingRequest(Bank /*bank*/) { return NULL; } diff --git a/DRAMSys/library/src/controller/scheduler/FifoStrict.cpp b/DRAMSys/library/src/controller/scheduler/FifoStrict.cpp index 6e8bd292..6b6b1caa 100644 --- a/DRAMSys/library/src/controller/scheduler/FifoStrict.cpp +++ b/DRAMSys/library/src/controller/scheduler/FifoStrict.cpp @@ -128,7 +128,7 @@ std::pair FifoStrict::getNextRequest(Bank b return pair(Command::NOP, NULL); } -gp* FifoStrict::getPendingRequest(Bank bank) +gp* FifoStrict::getPendingRequest(Bank /*bank*/) { return NULL; } diff --git a/DRAMSys/library/src/controller/scheduler/Fr_Fcfs.cpp b/DRAMSys/library/src/controller/scheduler/Fr_Fcfs.cpp index 5b022ca6..dec43cd2 100644 --- a/DRAMSys/library/src/controller/scheduler/Fr_Fcfs.cpp +++ b/DRAMSys/library/src/controller/scheduler/Fr_Fcfs.cpp @@ -122,7 +122,7 @@ deque::iterator FR_FCFS::FindRowHit(Bank bank) return queue.end(); } -gp* FR_FCFS::getPendingRequest(Bank bank) +gp* FR_FCFS::getPendingRequest(Bank /*bank*/) { return NULL; } diff --git a/DRAMSys/library/src/error/ECC/Word.cpp b/DRAMSys/library/src/error/ECC/Word.cpp index fbf82ef3..2edb4879 100644 --- a/DRAMSys/library/src/error/ECC/Word.cpp +++ b/DRAMSys/library/src/error/ECC/Word.cpp @@ -120,7 +120,7 @@ void CWord::Resize(unsigned nsize) m_nBitLength = nsize; } -bool CWord::PartShiftRight(unsigned nPos, unsigned nShift) +bool CWord::PartShiftRight(unsigned nPos, unsigned /*nShift*/) { if(nPos >= m_nBitLength) return false; diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index 114e3d03..d5dbc1dd 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -157,7 +157,7 @@ private: void peqCallback(tlm_generic_payload& payload, const tlm_phase& phase) { - unsigned int initiatorSocket = DramExtension::getExtension(payload).getThread().ID()-1; + unsigned int initiatorSocket = DramExtension::getExtension(payload).getThread().ID(); unsigned int channelId = DramExtension::getExtension(payload).getChannel().ID(); // Check the valid range of initiatorSocket ID and channel Id @@ -251,7 +251,7 @@ private: 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); + DramExtension* extension = new DramExtension(Thread(socketId), 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"); diff --git a/DRAMSys/library/src/simulation/Dram.h b/DRAMSys/library/src/simulation/Dram.h index 61d5f941..cafd7255 100644 --- a/DRAMSys/library/src/simulation/Dram.h +++ b/DRAMSys/library/src/simulation/Dram.h @@ -566,7 +566,7 @@ struct Dram : sc_module else { tlm::tlm_command cmd = trans.get_command(); - sc_dt::uint64 adr = trans.get_address(); // TODO: - offset; + //sc_dt::uint64 adr = trans.get_address(); // TODO: - offset; unsigned char* ptr = trans.get_data_ptr(); unsigned int len = trans.get_data_length(); //unsigned int bank = DramExtension::getExtension(trans).getBank().ID(); 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..f29cda24 --- /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()]->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/DRAMSys/library/src/simulation/TracePlayer.cpp b/DRAMSys/library/src/simulation/TracePlayer.cpp index d9dfc008..7b59309b 100644 --- a/DRAMSys/library/src/simulation/TracePlayer.cpp +++ b/DRAMSys/library/src/simulation/TracePlayer.cpp @@ -41,9 +41,9 @@ TracePlayer::TracePlayer(TracePlayerListener* listener) : payloadEventQueue(this, &TracePlayer::peqCallback), transactionsSent(0), - transactionsReceived(0), - listener(listener), + transactionsReceived(0), numberOfTransactions(0), + listener(listener), finished(false) { iSocket.register_nb_transport_bw(this, &TracePlayer::nb_transport_bw); diff --git a/DRAMSys/simulator/simulator.pro b/DRAMSys/simulator/simulator.pro index a3c21141..b5b297cf 100644 --- a/DRAMSys/simulator/simulator.pro +++ b/DRAMSys/simulator/simulator.pro @@ -49,3 +49,5 @@ LIBS += -lsqlite3 PRE_TARGETDEPS += ../library/libDRAMSys.a SOURCES += main.cpp + +DISTFILES += ../DRAMSys.astylerc diff --git a/DRAMSys/tests/tests.pri b/DRAMSys/tests/tests.pri index 1d1f41bf..562e6a7a 100644 --- a/DRAMSys/tests/tests.pri +++ b/DRAMSys/tests/tests.pri @@ -1,5 +1,5 @@ # Relative paths to "DRAMSys" because this file is included in -# "DRAMSys/dram.vp.system.pro" +# "DRAMSys/DRAMSys.pro" OTHER_FILES += tests/start.pl diff --git a/DRAMSys/traceAnalyzer/businessObjects/generalinfo.h b/DRAMSys/traceAnalyzer/businessObjects/generalinfo.h index 723d2828..d7100469 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/generalinfo.h +++ b/DRAMSys/traceAnalyzer/businessObjects/generalinfo.h @@ -50,10 +50,11 @@ struct GeneralInfo QString unitOfTime; unsigned int clkPeriod; unsigned int windowSize; + unsigned int controllerThread; public: - GeneralInfo(unsigned int numberOfTransactions,unsigned int numberOfPhases,Timespan span,unsigned int numberOfBanks,const QString& description, QString unitOfTime,unsigned int clkPeriod, unsigned int windowSize) : - numberOfTransactions(numberOfTransactions) , numberOfPhases(numberOfPhases),span(span), numberOfBanks(numberOfBanks), description(description), unitOfTime(unitOfTime), clkPeriod(clkPeriod), windowSize(windowSize) + GeneralInfo(unsigned int numberOfTransactions,unsigned int numberOfPhases,Timespan span,unsigned int numberOfBanks,const QString& description, QString unitOfTime,unsigned int clkPeriod, unsigned int windowSize, unsigned int controllerThread) : + numberOfTransactions(numberOfTransactions) , numberOfPhases(numberOfPhases),span(span), numberOfBanks(numberOfBanks), description(description), unitOfTime(unitOfTime), clkPeriod(clkPeriod), windowSize(windowSize), controllerThread(controllerThread) { } diff --git a/DRAMSys/traceAnalyzer/businessObjects/transaction.cpp b/DRAMSys/traceAnalyzer/businessObjects/transaction.cpp index fa163a82..0578cbb2 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/transaction.cpp +++ b/DRAMSys/traceAnalyzer/businessObjects/transaction.cpp @@ -39,7 +39,7 @@ using namespace std; Transaction::Transaction(ID id,unsigned int address,unsigned int burstlength,int thread, unsigned int channel, unsigned int bank,unsigned int bankgroup, unsigned int row, unsigned int column, Timespan span, Timespan spanOnDataStrobe) - :address(address),burstlength(burstlength),channel(channel), bank(bank),bankgroup(bankgroup), row(row), column(column),thread(thread),span(span),spanOnDataStrobe(spanOnDataStrobe),id(id){} + :address(address), burstlength(burstlength), thread(thread), channel(channel), bank(bank),bankgroup(bankgroup), row(row), column(column),span(span),spanOnDataStrobe(spanOnDataStrobe),id(id){} void Transaction::addPhase(shared_ptr phase) { diff --git a/DRAMSys/traceAnalyzer/businessObjects/transaction.h b/DRAMSys/traceAnalyzer/businessObjects/transaction.h index b2ea8a45..7faa11fc 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/transaction.h +++ b/DRAMSys/traceAnalyzer/businessObjects/transaction.h @@ -48,8 +48,7 @@ typedef unsigned int ID; class Transaction { private: - unsigned int address,burstlength,channel,bank,bankgroup,row,column; - int thread; + unsigned int address,burstlength,thread,channel,bank,bankgroup,row,column; Timespan span; Timespan spanOnDataStrobe; ID id; @@ -62,7 +61,6 @@ public: void addPhase(std::shared_ptr phase); bool isSelected(traceTime time,double yVal, const TraceDrawingProperties& drawingproperties) const; - bool isControllerInternal(){return thread==0;} unsigned int Address() const{return address;} unsigned int Burstlength() const{return burstlength;} @@ -76,7 +74,6 @@ public: const Timespan& Span() const{return span;} const Timespan& SpanOnDataStrobe() {return spanOnDataStrobe;} const std::vector>& Phases() const{return phases;} - }; #endif // TRANSACTION_H diff --git a/DRAMSys/traceAnalyzer/data/tracedb.cpp b/DRAMSys/traceAnalyzer/data/tracedb.cpp index b0e88b4d..00706d5f 100644 --- a/DRAMSys/traceAnalyzer/data/tracedb.cpp +++ b/DRAMSys/traceAnalyzer/data/tracedb.cpp @@ -199,7 +199,7 @@ ID TraceDB::getTransactionIDFromPhaseID(ID phaseID) GeneralInfo TraceDB::getGeneralInfoFromDB() { QSqlQuery query(database); - query.prepare("SELECT NumberOfTransactions,TraceEnd,NumberOfBanks,Clk,UnitOfTime,Traces,Memspec,MCconfig, WindowSize FROM GeneralInfo"); + query.prepare("SELECT NumberOfTransactions,TraceEnd,NumberOfBanks,Clk,UnitOfTime,Traces,Memspec,MCconfig, WindowSize, ControllerThread FROM GeneralInfo"); executeQuery(query); if(query.next()) @@ -215,6 +215,7 @@ GeneralInfo TraceDB::getGeneralInfoFromDB() QString memspec = "Memspec: " + query.value(6).toString(); QString mcconfig = "MCconfig: " + query.value(7).toString(); unsigned int windowSize = query.value(8).toInt(); + unsigned int controllerThread = query.value(9).toUInt(); QString description = (traces + "\n"); description += mcconfig + "\n"; @@ -224,7 +225,7 @@ GeneralInfo TraceDB::getGeneralInfoFromDB() description += "Length of trace: " + prettyFormatTime(traceEnd) + "\n"; description += "Window size:" + QString::number(windowSize) + "\n"; - return GeneralInfo(numberOfTransactions, numberOfPhases, Timespan(0,traceEnd),numberOfBanks,description,unitOfTime,clkPeriod, windowSize); + return GeneralInfo(numberOfTransactions, numberOfPhases, Timespan(0,traceEnd),numberOfBanks,description,unitOfTime,clkPeriod, windowSize, controllerThread); } else { @@ -306,7 +307,7 @@ vector> TraceDB::parseTransactionsFromQuery(QSqlQuery &q Timespan spanOnStrobe(query.value(3).toLongLong(),query.value(4).toLongLong()); unsigned int address = query.value(5).toInt(); unsigned int burstlength = query.value(6).toInt(); - int thread= query.value(7).toInt(); + unsigned int thread= query.value(7).toInt(); unsigned int channel = query.value(8).toInt(); unsigned int bank = query.value(9).toInt(); unsigned int bankgroup = query.value(10).toInt(); diff --git a/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.cpp b/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.cpp index 45bdd2e6..7f552e8f 100644 --- a/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.cpp +++ b/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.cpp @@ -62,11 +62,10 @@ void TransactionTreeWidget::init(TraceNavigator *navigator) void TransactionTreeWidget::AppendTransaction(const shared_ptr &transaction) { - QTreeWidgetItem *node = new TransactionTreeItem(this,transaction); + QTreeWidgetItem *node = new TransactionTreeItem(this,transaction, navigator->GeneralTraceInfo().controllerThread); addTopLevelItem(node); } - void TransactionTreeWidget::ContextMenuRequested(QPoint point) { if(selectedItems().count() > 0 && selectedItems().at(0)->type() == TransactionTreeWidget::TransactionTreeItem::transactionTreeItemType) @@ -83,7 +82,7 @@ void TransactionTreeWidget::ContextMenuRequested(QPoint point) } } -TransactionTreeWidget::TransactionTreeItem::TransactionTreeItem(QTreeWidget *parent, const shared_ptr &transaction) : QTreeWidgetItem(parent,transactionTreeItemType) +TransactionTreeWidget::TransactionTreeItem::TransactionTreeItem(QTreeWidget *parent, const shared_ptr &transaction, unsigned int controllerThread) : QTreeWidgetItem(parent,transactionTreeItemType) { this->setText(0, QString::number(transaction->Id())); this->id = transaction->Id(); @@ -100,7 +99,7 @@ TransactionTreeWidget::TransactionTreeItem::TransactionTreeItem(QTreeWidget *par this->addChild(new QTreeWidgetItem( {"Column", QString::number(transaction->Column())} )); this->addChild(new QTreeWidgetItem( {"Address", QString("0x") + QString::number(transaction->Address(),16)} )); - if(!transaction->isControllerInternal()) + if(!transaction->Thread() != controllerThread) { this->addChild(new QTreeWidgetItem( {"Burstlength", QString::number(transaction->Burstlength())})); this->addChild(new QTreeWidgetItem( {"Thread", QString::number(transaction->Thread())})); diff --git a/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.h b/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.h index b31bd27d..e2c7ed06 100644 --- a/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.h +++ b/DRAMSys/traceAnalyzer/presentation/transactiontreewidget.h @@ -70,16 +70,13 @@ private: { public: static constexpr int transactionTreeItemType = 1001; - TransactionTreeItem(QTreeWidget *parent, const std::shared_ptr &trans); + TransactionTreeItem(QTreeWidget *parent, const std::shared_ptr &trans, unsigned int controllerThread); ID Id(){return id;} private: ID id; void AppendTimespan(QTreeWidgetItem *parent, const Timespan ×pan); void AppendPhase(QTreeWidgetItem *parent, const Phase &phase); }; - - - }; #endif // TRANSACTIONTREEWIDGET_H diff --git a/DRAMSys/traceAnalyzer/scripts/memUtil.py b/DRAMSys/traceAnalyzer/scripts/memUtil.py index eed3fe2b..3779a315 100755 --- a/DRAMSys/traceAnalyzer/scripts/memUtil.py +++ b/DRAMSys/traceAnalyzer/scripts/memUtil.py @@ -76,3 +76,17 @@ def maximum_data_rate(connection): rate = memspec.getValue("dataRate") maxDataRate = float(clk)*float(width)*float(rate) return maxDataRate + + +def getFlexibleRef(connection): + cursor = connection.cursor() + cursor.execute(" SELECT FlexibleRefresh FROM GeneralInfo ") + result = cursor.fetchone() + return result[0] + + +def getMaxRefBurst(connection): + cursor = connection.cursor() + cursor.execute(" SELECT MaxRefBurst FROM GeneralInfo ") + result = cursor.fetchone() + return result[0] diff --git a/DRAMSys/traceAnalyzer/scripts/tests.py b/DRAMSys/traceAnalyzer/scripts/tests.py index 9b2e5703..35d84f8b 100755 --- a/DRAMSys/traceAnalyzer/scripts/tests.py +++ b/DRAMSys/traceAnalyzer/scripts/tests.py @@ -39,6 +39,7 @@ class DramConfig(object): tXSRDLL = 0 # min delay to row access command after srefx for dll commands tAL = 0 # additive delay (delayed execution in dram) tRFC = 0 # min ref->act delay + tREFI = 0 # time between REF commands def readConfigFromFiles(self, connection): print("Parsing dram configuration") @@ -83,6 +84,7 @@ class DramConfig(object): self.tXSRDLL = self.tXSR self.tAL = self.clk * memspec.getIntValue("AL") self.tRFC = self.clk * memspec.getIntValue("RFC") + self.tREFI = self.clk * memspec.getIntValue("REFI") elif (self. memoryType == "DDR4"): self.nActivateWindow = 4 @@ -109,6 +111,7 @@ class DramConfig(object): self.tXSRDLL = self.clk * memspec.getIntValue("XSDLL") self.tAL = self.clk * memspec.getIntValue("AL") self.tRFC = self.clk * memspec.getIntValue("RFC") + self.tREFI = self.clk * memspec.getIntValue("REFI") elif (self. memoryType == "DDR3"): self.nActivateWindow = 4 @@ -135,6 +138,7 @@ class DramConfig(object): self.tXSRDLL = self.clk * memspec.getIntValue("XSDLL"); self.tAL = self.clk * memspec.getIntValue("AL"); self.tRFC = self.clk * memspec.getIntValue("RFC"); + self.tREFI = self.clk * memspec.getIntValue("REFI"); else: raise Exception("MemoryType not supported yet. Insert a coin into the coin machine and try again") @@ -470,6 +474,57 @@ def no_commands_during_refresh(connection): return TestSuceeded() +@test +def max_number_ref_burst(connection): + """Checks that the maximum number of REFA commands in a burst is not exceeded""" + cursor = connection.cursor() + query = """SELECT PhaseBegin, PhaseEnd FROM phases WHERE PhaseName = 'REFA' """ + prevrow = [0] * 2 + cnt = 0 + flexibleRef = getFlexibleRef(connection) + maxRefBurst = getMaxRefBurst(connection) + + cursor.execute(query); + result = cursor.fetchall(); + + if (flexibleRef): + maxRefBurst = maxRefBurst - 1 # Since the intersections will be used for this test, use -1 from the max + + for row in result: + if (prevrow[1] == row[0]): + cnt += 1 + else: + cnt = 0 # Reset the counter every time a burst ends + prevrow = row + if(cnt > maxRefBurst): + return TestFailed("Maximum number of REFA in a burst was exceeded at {0} with {1} REFA in sequence. Maximum allowed is {2}.".format(formatTime(row[0]), cnt, maxRefBurst)) + + return TestSuceeded() + +@test +def max_time_without_ref(connection): + """Checks that the maximum time allowed between REFA commands""" + cursor = connection.cursor() + query = """SELECT PhaseBegin, PhaseEnd FROM phases WHERE PhaseName = 'REFA' """ + prevrow = [0] * 2 + flexibleRef = getFlexibleRef(connection) + maxRefBurst = getMaxRefBurst(connection) + + cursor.execute(query); + result = cursor.fetchall(); + + if (flexibleRef): + maxTimeWithoutRef = ((maxRefBurst + 1) * dramconfig.tREFI) + dramconfig.tRP # Bursts are possible, so max should be the possible burst size + 1 + else: + maxTimeWithoutRef = dramconfig.tREFI + dramconfig.tRP + + for row in result: + timeBetweenRefs = row[0] - prevrow[1] + if (timeBetweenRefs > maxTimeWithoutRef): + return TestFailed("Maximum time between REF commands was exceeded at {0} with {1} between REFs. Maximum allowed is {2}.".format(formatTime(row[0]), formatTime(timeBetweenRefs), formatTime(maxTimeWithoutRef))) + prevrow = row + + return TestSuceeded() # ----------- activate checks --------------------------------------- @test diff --git a/DRAMSys/traceAnalyzer/traceAnalyzer.pro b/DRAMSys/traceAnalyzer/traceAnalyzer.pro index f06bb347..e4365d11 100644 --- a/DRAMSys/traceAnalyzer/traceAnalyzer.pro +++ b/DRAMSys/traceAnalyzer/traceAnalyzer.pro @@ -166,3 +166,4 @@ FORMS += \ # Additional Files: include(scripts/scripts.pri) +DISTFILES += ../DRAMSys.astylerc diff --git a/README.md b/README.md index c5a2a4c4..e16a7dde 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,8 @@ and understand the script then execute it. ```bash $ bash getqwt.sh +$ cd ~/qwt-6.1 +$ sudo make install ``` For further information refer to [this](http://qwt.sourceforge.net/) @@ -722,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. diff --git a/coding-style.md b/coding-style.md new file mode 100644 index 00000000..7b686d65 --- /dev/null +++ b/coding-style.md @@ -0,0 +1,164 @@ + +# Coding style + +The DRAMSys project has long run without a coding style. As a result, there is +a substantial amount of code which does not meet any coding style guidelines. + +This fact leads people to believe that the coding standards do not matter and +are not enforced. Nevertheless, a code base as large as the DRAMSys project +requires some uniformity of code to make it possible for developers to quickly +understand it. So there is no longer room for strangely-formatted code. + +The coding style document should not be read as an absolute law which can +never be transgressed. **If there is a good reason** to go against the style +(a line which becomes far less readable if split to fit within the 80-column +limit, for example), just do it. + +Since DRAMSys is a multi-language project, each with its own peculiarities, we +describe the preferred coding style for them in separate. + +## Tools + +```bash +sudo apt-get -y install astyle +sudo apt-get -y install uncrustify +sudo apt-get -y install clang-format +``` + +**Hint:** +You can use [utils/install.sh](./utils/install.sh) in order to install +dependencies. First read and understand the script then execute it. Type your +password if required. + +## DRAMSys Coding Style for C++ Code + +#### Indentation +4 spaces are used for indentation. + +#### Breaking long lines and strings +Coding style is all about readability and maintainability using commonly +available tools. + +The limit on the length of lines is 80 columns and this is a strongly +preferred limit. + +Statements longer than 80 columns will be broken into sensible chunks, unless +exceeding 80 columns significantly increases readability and does not hide +information. Descendants are always substantially shorter than the parent and +are placed substantially to the right. The same applies to function headers +with a long argument list. However, never break user-visible strings such as +printed messages, because that breaks the ability to grep for them. + +#### Declaring variables +Declare each variable on a separate line. + +Avoid short or meaningless names (e.g., "a", "b", "aux"). + +Wait when declaring a variable until it is needed. + +```c++ +// Wrong +int a, b; +char *c, *d; + +// Correct +int height; +int width; +char *nameOfThis; +short counter; +char itemDelimiter = ' '; +``` + +Classes always start with an upper-case letter (e.g, MemoryManager, +TracePlayer, PythonCaller, etc.). +Acronyms are camel-cased (e.g., TlmRecorder, not TLMRecorder, Dram, not DRAM), +being **DRAMSys** a notable exception to the rule. + +#### Whitespace +Always use a single space after a keyword and before a curly brace: + +```c++ +// Wrong +if(foo){ +} + +// Correct +if (foo) { +} +``` + +For pointers or references, always use a single space between the type and +'\*' or '&', but no space between the '\*' or '&' and the variable name: + +```c++ +char *x; +const QString &myString; +const char * const y = "hello"; +``` + +Surround binary operators with spaces. + +No space after a cast. + +Avoid C-style casts when possible. + +```c++ +// Wrong +char* blockOfMemory = (char* ) malloc(data.size()); + +// Correct +char *blockOfMemory = reinterpret_cast(malloc(data.size())); +``` + +Do not put multiple statements on one line. + +Use a new line for the body of a control flow statement: + +``` +// Wrong +if (foo) bar(); + +// Correct +if (foo) + bar(); +``` + +## DRAMSys Coding Style for Python Code + +We follow the PEP8 style guide. + +**Hint:** +There is a plugin for VIM. More information can be found in +[vim.org](https://www.vim.org/scripts/script.php?script_id=2914). + +## Using Astyle in Qt Creator + ++ Select **Help** > **About Plugins** > **C++** > **Beautifier** to enable the + plugin. + ++ Restart Qt Creator to be able to use the plugin (close Qt Creator and open + it again). + ++ Select **Tools** > **Options** > **Beautifier** to specify settings for + beautifying files. + ++ Select the **Enable auto format on file save** check box to automatically + beautify files when you save them. + + +## References + +[Linux kernel coding style](https://github.com/torvalds/linux/blob/master/Documentation/process/coding-style.rst) + +[C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#S-cpl) + +[PEP 8 -- Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/) + +[Qt Documentation - Beautifying Source Code](http://doc.qt.io/qtcreator/creator-beautifier.html) + +[Artistic Style 3.1 - A Free, Fast, and Small Automatic Formatter for C, C++, C++/CLI, Objective‑C, C#, and Java Source Code](http://astyle.sourceforge.net/astyle.html) + +[Qt Coding Style](https://wiki.qt.io/Qt_Coding_Style) + +[Qt Coding Conventions](https://wiki.qt.io/Coding_Conventions) + diff --git a/utils/getqwt.sh b/utils/getqwt.sh index 31d54adb..daf0f47f 100755 --- a/utils/getqwt.sh +++ b/utils/getqwt.sh @@ -37,7 +37,6 @@ svn checkout svn://svn.code.sf.net/p/qwt/code/branches/qwt-6.1 $dest cd $dest qmake qwt.pro make -sudo make install # Add env. variables to ~/.bashrc echo "LIBQWT_HOME=/usr/local/qwt-6.1.4-svn/lib" >> ~/.bashrc diff --git a/utils/install.sh b/utils/install.sh index fbc9ab47..56370bb1 100755 --- a/utils/install.sh +++ b/utils/install.sh @@ -55,3 +55,6 @@ sudo apt-get -y install libqt5widgets5 sudo apt-get -y install libqt5core5a sudo apt-get -y install qtcreator sudo apt-get -y install qt5-default +sudo apt-get -y install astyle +sudo apt-get -y install uncrustify +sudo apt-get -y install clang-format