Merge branch 'master' of git.rhrk.uni-kl.de:EIT-Wehn/dram.vp.system

This commit is contained in:
Matthias Jung
2018-04-12 13:48:12 +02:00
36 changed files with 607 additions and 40 deletions

10
DRAMSys/DRAMSys.astylerc Normal file
View 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

View File

@@ -73,3 +73,4 @@ SOURCES += $${gem5_root}/util/tlm/src/sim_control.cc
SOURCES += main.cpp
DISTFILES += ../DRAMSys.astylerc

View File

@@ -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

View File

@@ -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

View File

@@ -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(

View File

@@ -40,7 +40,6 @@
#include <systemc.h>
#include <string>
#include <set>
#include "Utils.h"
class DebugManager

View File

@@ -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);
}

View File

@@ -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!!!
}

View File

@@ -47,7 +47,6 @@
#include "dramExtension.h"
#include "third_party/tinyxml2/tinyxml2.h"
#define DEF_SINGLETON( NAME ) \
public: \
static NAME& getInstance() \

View File

@@ -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();

View File

@@ -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);

View File

@@ -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_ */

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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");

View File

@@ -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();

View 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_ */

View 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

View File

@@ -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);

View File

@@ -49,3 +49,5 @@ LIBS += -lsqlite3
PRE_TARGETDEPS += ../library/libDRAMSys.a
SOURCES += main.cpp
DISTFILES += ../DRAMSys.astylerc

View File

@@ -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

View File

@@ -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)
{
}

View File

@@ -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)
{

View File

@@ -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

View File

@@ -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();

View File

@@ -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())}));

View File

@@ -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 &timespan);
void AppendPhase(QTreeWidgetItem *parent, const Phase &phase);
};
};
#endif // TRANSACTIONTREEWIDGET_H

View File

@@ -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]

View File

@@ -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

View File

@@ -166,3 +166,4 @@ FORMS += \
# Additional Files:
include(scripts/scripts.pri)
DISTFILES += ../DRAMSys.astylerc

View File

@@ -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.

164
coding-style.md Normal file
View 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, ObjectiveC, 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)

View File

@@ -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

View File

@@ -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