Merge branch 'master' of git.rhrk.uni-kl.de:EIT-Wehn/dram.vp.system
This commit is contained in:
10
DRAMSys/DRAMSys.astylerc
Normal file
10
DRAMSys/DRAMSys.astylerc
Normal file
@@ -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
|
||||
@@ -73,3 +73,4 @@ SOURCES += $${gem5_root}/util/tlm/src/sim_control.cc
|
||||
|
||||
SOURCES += main.cpp
|
||||
|
||||
DISTFILES += ../DRAMSys.astylerc
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include <systemc.h>
|
||||
#include <string>
|
||||
#include <set>
|
||||
|
||||
#include "Utils.h"
|
||||
|
||||
class DebugManager
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <tlm.h>
|
||||
#include <fstream>
|
||||
#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!!!
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,6 @@
|
||||
#include "dramExtension.h"
|
||||
#include "third_party/tinyxml2/tinyxml2.h"
|
||||
|
||||
|
||||
#define DEF_SINGLETON( NAME ) \
|
||||
public: \
|
||||
static NAME& getInstance() \
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -60,7 +60,7 @@ pair<Command, tlm::tlm_generic_payload*> Fifo::getNextRequest(Bank bank)
|
||||
return pair<Command, tlm::tlm_generic_payload*>(Command::NOP, NULL);
|
||||
}
|
||||
|
||||
gp* Fifo::getPendingRequest(Bank bank)
|
||||
gp* Fifo::getPendingRequest(Bank /*bank*/)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ std::pair<Command, tlm::tlm_generic_payload *> FifoStrict::getNextRequest(Bank b
|
||||
return pair<Command, tlm::tlm_generic_payload*>(Command::NOP, NULL);
|
||||
}
|
||||
|
||||
gp* FifoStrict::getPendingRequest(Bank bank)
|
||||
gp* FifoStrict::getPendingRequest(Bank /*bank*/)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ deque<gp*>::iterator FR_FCFS::FindRowHit(Bank bank)
|
||||
return queue.end();
|
||||
}
|
||||
|
||||
gp* FR_FCFS::getPendingRequest(Bank bank)
|
||||
gp* FR_FCFS::getPendingRequest(Bank /*bank*/)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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();
|
||||
|
||||
129
DRAMSys/library/src/simulation/IArbiter.h
Normal file
129
DRAMSys/library/src/simulation/IArbiter.h
Normal file
@@ -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 <tlm.h>
|
||||
#include <systemc.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <tlm_utils/multi_passthrough_target_socket.h>
|
||||
#include <tlm_utils/multi_passthrough_initiator_socket.h>
|
||||
#include "../controller/core/configuration/ConfigurationLoader.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace tlm;
|
||||
|
||||
struct IArbiter: public sc_module {
|
||||
public:
|
||||
tlm_utils::multi_passthrough_target_socket<IArbiter> tSocket;
|
||||
tlm_utils::multi_passthrough_initiator_socket<IArbiter> 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_ */
|
||||
140
DRAMSys/library/src/simulation/SimpleArbiter.h
Normal file
140
DRAMSys/library/src/simulation/SimpleArbiter.h
Normal file
@@ -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
|
||||
@@ -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);
|
||||
|
||||
@@ -49,3 +49,5 @@ LIBS += -lsqlite3
|
||||
PRE_TARGETDEPS += ../library/libDRAMSys.a
|
||||
|
||||
SOURCES += main.cpp
|
||||
|
||||
DISTFILES += ../DRAMSys.astylerc
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -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> phase)
|
||||
{
|
||||
|
||||
@@ -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> 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<std::shared_ptr<Phase>>& Phases() const{return phases;}
|
||||
|
||||
};
|
||||
|
||||
#endif // TRANSACTION_H
|
||||
|
||||
@@ -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<shared_ptr<Transaction>> 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();
|
||||
|
||||
@@ -62,11 +62,10 @@ void TransactionTreeWidget::init(TraceNavigator *navigator)
|
||||
|
||||
void TransactionTreeWidget::AppendTransaction(const shared_ptr<Transaction> &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> &transaction) : QTreeWidgetItem(parent,transactionTreeItemType)
|
||||
TransactionTreeWidget::TransactionTreeItem::TransactionTreeItem(QTreeWidget *parent, const shared_ptr<Transaction> &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())}));
|
||||
|
||||
@@ -70,16 +70,13 @@ private:
|
||||
{
|
||||
public:
|
||||
static constexpr int transactionTreeItemType = 1001;
|
||||
TransactionTreeItem(QTreeWidget *parent, const std::shared_ptr<Transaction> &trans);
|
||||
TransactionTreeItem(QTreeWidget *parent, const std::shared_ptr<Transaction> &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
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -166,3 +166,4 @@ FORMS += \
|
||||
# Additional Files:
|
||||
include(scripts/scripts.pri)
|
||||
|
||||
DISTFILES += ../DRAMSys.astylerc
|
||||
|
||||
11
README.md
11
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.
|
||||
|
||||

|
||||
|
||||
|
||||
- **Payload Extension information**
|
||||
|
||||
GenerationExtension is added in TracePlayer and DramExtension is added in Arbiter.
|
||||
|
||||
164
coding-style.md
Normal file
164
coding-style.md
Normal file
@@ -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<char *>(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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user