Merge branch 'rambus_scheduler' into DDR5

# Conflicts:
#	DRAMSys/library/src/common/TlmRecorder.cpp
This commit is contained in:
Lukas Steiner
2020-11-04 15:56:26 +01:00
32 changed files with 442 additions and 54 deletions

View File

@@ -141,6 +141,7 @@ add_library(DRAMSysLibrary
src/controller/scheduler/BufferCounterIF.h
src/controller/scheduler/BufferCounterBankwise.cpp
src/controller/scheduler/BufferCounterReadWrite.cpp
src/controller/scheduler/BufferCounterShared.cpp
src/error/eccbaseclass.cpp
src/error/ecchamming.cpp

View File

@@ -6,6 +6,7 @@ DROP TABLE IF EXISTS ranges;
DROP TABLE IF EXISTS Transactions;
DROP TABLE IF EXISTS DebugMessages;
DROP TABLE IF EXISTS Power;
DROP TABLE IF EXISTS BufferDepth;
CREATE TABLE Phases(
ID INTEGER PRIMARY KEY,
@@ -29,7 +30,8 @@ CREATE TABLE GeneralInfo(
WindowSize INTEGER,
FlexibleRefresh INTEGER,
MaxRefBurst INTEGER,
ControllerThread INTEGER
ControllerThread INTEGER,
MaxBufferDepth INTEGER
);
CREATE TABLE CommandLengths(
@@ -58,6 +60,11 @@ CREATE TABLE Power(
AveragePower DOUBLE
);
CREATE TABLE BufferDepth(
Time DOUBLE,
BufferNumber INTEGER,
AverageBufferDepth DOUBLE
);
CREATE TABLE Comments(
Time INTEGER,
@@ -91,7 +98,7 @@ CREATE TABLE Transactions(
DataStrobeEnd INTEGER,
TimeOfGeneration INTEGER,
Command TEXT
);
);
CREATE INDEX ranges_index ON Transactions(Range);
CREATE INDEX "phasesTransactions" ON "Phases" ("Transact" ASC);

View File

@@ -80,6 +80,7 @@ TlmRecorder::~TlmRecorder()
sqlite3_finalize(insertDebugMessageStatement);
sqlite3_finalize(updateDataStrobeStatement);
sqlite3_finalize(insertPowerStatement);
sqlite3_finalize(insertBufferDepthStatement);
}
void TlmRecorder::recordPower(double timeInSeconds, double averagePower)
@@ -89,6 +90,17 @@ void TlmRecorder::recordPower(double timeInSeconds, double averagePower)
executeSqlStatement(insertPowerStatement);
}
void TlmRecorder::recordBufferDepth(double timeInSeconds, const std::vector<double> &averageBufferDepth)
{
for (size_t index = 0; index < averageBufferDepth.size(); index++)
{
sqlite3_bind_double(insertBufferDepthStatement, 1, timeInSeconds);
sqlite3_bind_int(insertBufferDepthStatement, 2, index);
sqlite3_bind_double(insertBufferDepthStatement, 3, averageBufferDepth[index]);
executeSqlStatement(insertBufferDepthStatement);
}
}
void TlmRecorder::recordPhase(tlm_generic_payload &trans,
tlm_phase phase, sc_time time)
{
@@ -300,7 +312,7 @@ void TlmRecorder::prepareSqlStatements()
insertGeneralInfoString =
"INSERT INTO GeneralInfo VALUES"
"(:numberOfTransactions,:end,:numberOfRanks,:numberOfBankgroups,:numberOfBanks,:clk,:unitOfTime,:mcconfig,:memspec,"
":traces,:windowSize, :flexibleRefresh, :maxRefBurst, :controllerThread)";
":traces,:windowSize, :flexibleRefresh, :maxRefBurst, :controllerThread, :maxBufferDepth)";
insertCommandLengthsString =
"INSERT INTO CommandLengths VALUES"
@@ -310,6 +322,7 @@ void TlmRecorder::prepareSqlStatements()
"INSERT INTO DebugMessages (Time,Message) Values (:time,:message)";
insertPowerString = "INSERT INTO Power VALUES (:time,:averagePower)";
insertBufferDepthString = "INSERT INTO BufferDepth VALUES (:time,:bufferNumber,:averageBufferDepth)";
sqlite3_prepare_v2(db, insertTransactionString.c_str(), -1, &insertTransactionStatement, 0);
sqlite3_prepare_v2(db, insertRangeString.c_str(), -1, &insertRangeStatement, 0);
@@ -321,6 +334,7 @@ void TlmRecorder::prepareSqlStatements()
sqlite3_prepare_v2(db, insertCommandLengthsString.c_str(), -1, &insertCommandLengthsStatement, 0);
sqlite3_prepare_v2(db, insertDebugMessageString.c_str(), -1, &insertDebugMessageStatement, 0);
sqlite3_prepare_v2(db, insertPowerString.c_str(), -1, &insertPowerStatement, 0);
sqlite3_prepare_v2(db, insertBufferDepthString.c_str(), -1, &insertBufferDepthStatement, 0);
}
void TlmRecorder::insertDebugMessageInDB(std::string message, const sc_time &time)
@@ -363,6 +377,7 @@ void TlmRecorder::insertGeneralInfo()
sqlite3_bind_int(insertGeneralInfoStatement, 13, 0);
}
sqlite3_bind_int(insertGeneralInfoStatement, 14, UINT_MAX);
sqlite3_bind_int(insertGeneralInfoStatement, 15, Configuration::getInstance().requestBufferSize);
executeSqlStatement(insertGeneralInfoStatement);
}
@@ -422,7 +437,6 @@ void TlmRecorder::insertTransactionInDB(Transaction &recordingData)
recordingData.cmd.c_str(), recordingData.cmd.length(), NULL);
executeSqlStatement(insertTransactionStatement);
}
void TlmRecorder::insertRangeInDB(unsigned int id, const sc_time &begin,

View File

@@ -77,13 +77,15 @@ public:
void recordPhase(tlm::tlm_generic_payload &trans, tlm::tlm_phase phase,
sc_time time);
void recordPower(double timeInSeconds, double averagePower);
void recordBufferDepth(double timeInSeconds, const std::vector<double> &averageBufferDepth);
void recordDebugMessage(std::string message, sc_time time);
void updateDataStrobe(const sc_time &begin, const sc_time &end,
tlm::tlm_generic_payload &trans);
void closeConnection();
private:
struct Transaction {
struct Transaction
{
Transaction() {}
Transaction(unsigned int id): id(id) {}
@@ -142,10 +144,12 @@ private:
sqlite3_stmt *insertTransactionStatement, *insertRangeStatement,
*updateRangeStatement, *insertPhaseStatement, *updatePhaseStatement,
*insertGeneralInfoStatement, *insertCommandLengthsStatement,
*insertDebugMessageStatement, *updateDataStrobeStatement, *insertPowerStatement;
*insertDebugMessageStatement, *updateDataStrobeStatement,
*insertPowerStatement, *insertBufferDepthStatement;
std::string insertTransactionString, insertRangeString, updateRangeString, insertPhaseString,
updatePhaseString, insertGeneralInfoString, insertCommandLengthsString,
insertDebugMessageString, updateDataStrobeString, insertPowerString;
insertDebugMessageString, updateDataStrobeString, insertPowerString,
insertBufferDepthString;
};
#endif // TLMRECORDER_H

View File

@@ -111,6 +111,8 @@ void Configuration::setParameter(std::string name, nlohmann::json value)
schedulerBuffer = SchedulerBuffer::Bankwise;
else if (value == "ReadWrite")
schedulerBuffer = SchedulerBuffer::ReadWrite;
else if (value == "Shared")
schedulerBuffer = SchedulerBuffer::Shared;
else
SC_REPORT_FATAL("Configuration", "Unsupported scheduler buffer!");
}
@@ -140,7 +142,9 @@ void Configuration::setParameter(std::string name, nlohmann::json value)
}
else if (name == "Arbiter")
{
if (value == "Fifo")
if (value == "Simple")
arbiter = Arbiter::Simple;
else if (value == "Fifo")
arbiter = Arbiter::Fifo;
else if (value == "Reorder")
arbiter = Arbiter::Reorder;

View File

@@ -71,10 +71,10 @@ public:
// MCConfig:
enum class PagePolicy {Open, Closed, OpenAdaptive, ClosedAdaptive} pagePolicy;
enum class Scheduler {Fifo, FrFcfs, FrFcfsGrp} scheduler;
enum class SchedulerBuffer {Bankwise, ReadWrite} schedulerBuffer;
enum class SchedulerBuffer {Bankwise, ReadWrite, Shared} schedulerBuffer;
enum class CmdMux {Oldest, Strict} cmdMux;
enum class RespQueue {Fifo, Reorder} respQueue;
enum class Arbiter {Fifo, Reorder} arbiter;
enum class Arbiter {Simple, Fifo, Reorder} arbiter;
unsigned int requestBufferSize = 8;
enum class RefreshPolicy {NoRefresh, Rankwise, Bankwise, Groupwise} refreshPolicy;
unsigned int refreshMaxPostponed = 0;

View File

@@ -337,16 +337,18 @@ void Controller::controllerMethod()
tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload &trans,
tlm_phase &phase, sc_time &delay)
{
sc_time notificationDelay = delay + Configuration::getInstance().memSpec->tCK;
if (phase == BEGIN_REQ)
{
transToAcquire.payload = &trans;
transToAcquire.time = sc_time_stamp() + delay;
beginReqEvent.notify(delay);
transToAcquire.time = sc_time_stamp() + notificationDelay;
beginReqEvent.notify(notificationDelay);
}
else if (phase == END_RESP)
{
transToRelease.time = sc_time_stamp() + delay;
endRespEvent.notify(delay);
transToRelease.time = sc_time_stamp() + notificationDelay;
endRespEvent.notify(notificationDelay);
}
else
SC_REPORT_FATAL("Controller", "nb_transport_fw in controller was triggered with unknown phase");

View File

@@ -62,7 +62,7 @@ class Controller : public ControllerIF
public:
Controller(sc_module_name);
SC_HAS_PROCESS(Controller);
virtual ~Controller();
virtual ~Controller() override;
protected:
virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &, tlm::tlm_phase &, sc_time &) override;
@@ -72,6 +72,9 @@ protected:
virtual void sendToFrontend(tlm::tlm_generic_payload *, tlm::tlm_phase);
virtual void sendToDram(Command, tlm::tlm_generic_payload *);
virtual void controllerMethod();
SchedulerIF *scheduler;
MemSpec *memSpec;
private:
@@ -82,7 +85,6 @@ private:
std::vector<BankMachine *> bankMachines;
std::vector<std::vector<BankMachine *>> bankMachinesOnRank;
CmdMuxIF *cmdMux;
SchedulerIF *scheduler;
CheckerIF *checker;
RespQueueIF *respQueue;
std::vector<RefreshManagerIF *> refreshManagers;
@@ -99,7 +101,6 @@ private:
void startBeginResp();
void finishEndResp();
void controllerMethod();
sc_event beginReqEvent, endRespEvent, controllerEvent, dataResponseEvent;
};

View File

@@ -37,6 +37,16 @@
using namespace tlm;
ControllerRecordable::ControllerRecordable(sc_module_name name, TlmRecorder *tlmRecorder)
: Controller(name), tlmRecorder(tlmRecorder)
{
sensitive << bufferDepthWindowEvent;
bufferDepthWindowSize = Configuration::getInstance().windowSize * memSpec->tCK;
slidingAverageBufferDepth = std::vector<sc_time>(scheduler->getBufferDepth().size());
averageBufferDepth = std::vector<double>(scheduler->getBufferDepth().size());
bufferDepthWindowEvent.notify(bufferDepthWindowSize);
}
tlm_sync_enum ControllerRecordable::nb_transport_fw(tlm_generic_payload &trans,
tlm_phase &phase, sc_time &delay)
{
@@ -90,3 +100,29 @@ void ControllerRecordable::recordPhase(tlm_generic_payload &trans, tlm_phase pha
tlmRecorder->recordPhase(trans, phase, recTime);
}
void ControllerRecordable::controllerMethod()
{
sc_time timeDiff = sc_time_stamp() - lastTimeCalled;
const std::vector<unsigned> &bufferDepth = scheduler->getBufferDepth();
for (size_t index = 0; index < slidingAverageBufferDepth.size(); index++)
slidingAverageBufferDepth[index] += bufferDepth[index] * timeDiff;
lastTimeCalled = sc_time_stamp();
if (sc_time_stamp() % bufferDepthWindowSize == SC_ZERO_TIME && timeDiff != SC_ZERO_TIME)
{
bufferDepthWindowEvent.notify(bufferDepthWindowSize);
for (size_t index = 0; index < slidingAverageBufferDepth.size(); index++)
{
averageBufferDepth[index] = slidingAverageBufferDepth[index] / bufferDepthWindowSize;
slidingAverageBufferDepth[index] = SC_ZERO_TIME;
}
tlmRecorder->recordBufferDepth(sc_time_stamp().to_seconds(), averageBufferDepth);
}
Controller::controllerMethod();
}

View File

@@ -41,8 +41,8 @@
class ControllerRecordable final : public Controller
{
public:
ControllerRecordable(sc_module_name name, TlmRecorder *tlmRecorder) :
Controller(name), tlmRecorder(tlmRecorder) {}
ControllerRecordable(sc_module_name name, TlmRecorder *tlmRecorder);
virtual ~ControllerRecordable() override {}
protected:
virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &trans,
@@ -53,9 +53,17 @@ protected:
virtual void sendToFrontend(tlm::tlm_generic_payload *, tlm::tlm_phase) override;
virtual void sendToDram(Command, tlm::tlm_generic_payload *) override;
virtual void controllerMethod() override;
private:
void recordPhase(tlm::tlm_generic_payload &trans, tlm::tlm_phase phase, sc_time delay);
TlmRecorder *tlmRecorder;
sc_event bufferDepthWindowEvent;
sc_time bufferDepthWindowSize;
std::vector<sc_time> slidingAverageBufferDepth;
std::vector<double> averageBufferDepth;
sc_time lastTimeCalled = SC_ZERO_TIME;
};
#endif // CONTROLLERRECORDABLE_H

View File

@@ -38,21 +38,26 @@
BufferCounterBankwise::BufferCounterBankwise(unsigned requestBufferSize, unsigned numberOfBanks)
: requestBufferSize(requestBufferSize)
{
requestsOnBank = std::vector<unsigned>(numberOfBanks, 0);
numRequestsOnBank = std::vector<unsigned>(numberOfBanks, 0);
}
bool BufferCounterBankwise::hasBufferSpace() const
{
return (requestsOnBank[lastBankID] < requestBufferSize);
return (numRequestsOnBank[lastBankID] < requestBufferSize);
}
void BufferCounterBankwise::storeRequest(tlm::tlm_generic_payload *payload)
{
lastBankID = DramExtension::getBank(payload).ID();
requestsOnBank[lastBankID]++;
numRequestsOnBank[lastBankID]++;
}
void BufferCounterBankwise::removeRequest(tlm::tlm_generic_payload *payload)
{
requestsOnBank[DramExtension::getBank(payload).ID()]--;
numRequestsOnBank[DramExtension::getBank(payload).ID()]--;
}
const std::vector<unsigned> &BufferCounterBankwise::getBufferDepth() const
{
return numRequestsOnBank;
}

View File

@@ -39,17 +39,18 @@
#include "BufferCounterIF.h"
class BufferCounterBankwise : public BufferCounterIF
class BufferCounterBankwise final : public BufferCounterIF
{
public:
BufferCounterBankwise(unsigned requestBufferSize, unsigned numberOfBanks);
virtual bool hasBufferSpace() const override;
virtual void storeRequest(tlm::tlm_generic_payload *payload) override;
virtual void removeRequest(tlm::tlm_generic_payload *payload) override;
virtual const std::vector<unsigned> &getBufferDepth() const override;
private:
const unsigned requestBufferSize;
std::vector<unsigned> requestsOnBank;
std::vector<unsigned> numRequestsOnBank;
unsigned lastBankID;
};

View File

@@ -40,9 +40,11 @@
class BufferCounterIF
{
public:
virtual ~BufferCounterIF() = default;
virtual bool hasBufferSpace() const = 0;
virtual void storeRequest(tlm::tlm_generic_payload *payload) = 0;
virtual void removeRequest(tlm::tlm_generic_payload *payload) = 0;
virtual const std::vector<unsigned> &getBufferDepth() const = 0;
};
#endif // BUFFERCOUNTERIF_H

View File

@@ -35,25 +35,33 @@
#include "BufferCounterReadWrite.h"
BufferCounterReadWrite::BufferCounterReadWrite(unsigned requestBufferSize)
: requestBufferSize(requestBufferSize) {}
: requestBufferSize(requestBufferSize)
{
numReadWriteRequests = std::vector<unsigned>(2);
}
bool BufferCounterReadWrite::hasBufferSpace() const
{
return (numberOfReads < requestBufferSize && numberOfWrites < requestBufferSize);
return (numReadWriteRequests[0] < requestBufferSize && numReadWriteRequests[1] < requestBufferSize);
}
void BufferCounterReadWrite::storeRequest(tlm::tlm_generic_payload *payload)
{
if (payload->is_read())
numberOfReads++;
numReadWriteRequests[0]++;
else
numberOfWrites++;
numReadWriteRequests[1]++;
}
void BufferCounterReadWrite::removeRequest(tlm::tlm_generic_payload *payload)
{
if (payload->is_read())
numberOfReads--;
numReadWriteRequests[0]--;
else
numberOfWrites--;
numReadWriteRequests[1]--;
}
const std::vector<unsigned> &BufferCounterReadWrite::getBufferDepth() const
{
return numReadWriteRequests;
}

View File

@@ -37,18 +37,18 @@
#include "BufferCounterIF.h"
class BufferCounterReadWrite : public BufferCounterIF
class BufferCounterReadWrite final : public BufferCounterIF
{
public:
BufferCounterReadWrite(unsigned requestBufferSize);
virtual bool hasBufferSpace() const override;
virtual void storeRequest(tlm::tlm_generic_payload *payload) override;
virtual void removeRequest(tlm::tlm_generic_payload *payload) override;
virtual const std::vector<unsigned> &getBufferDepth() const override;
private:
const unsigned requestBufferSize;
unsigned numberOfReads = 0;
unsigned numberOfWrites = 0;
std::vector<unsigned> numReadWriteRequests;
};
#endif // BUFFERCOUNTERREADWRITE_H

View File

@@ -0,0 +1,61 @@
/*
* Copyright (c) 2020, Technische Universität 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.
*
* Author: Lukas Steiner
*/
#include "BufferCounterShared.h"
BufferCounterShared::BufferCounterShared(unsigned requestBufferSize)
: requestBufferSize(requestBufferSize)
{
numRequests = std::vector<unsigned>(1);
}
bool BufferCounterShared::hasBufferSpace() const
{
return (numRequests[0] < requestBufferSize);
}
void BufferCounterShared::storeRequest(tlm::tlm_generic_payload *)
{
numRequests[0]++;
}
void BufferCounterShared::removeRequest(tlm::tlm_generic_payload *)
{
numRequests[0]--;
}
const std::vector<unsigned> &BufferCounterShared::getBufferDepth() const
{
return numRequests;
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 2020, Technische Universität 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.
*
* Author: Lukas Steiner
*/
#ifndef BUFFERCOUNTERSHARED_H
#define BUFFERCOUNTERSHARED_H
#include "BufferCounterIF.h"
class BufferCounterShared final : public BufferCounterIF
{
public:
BufferCounterShared(unsigned requestBufferSize);
virtual bool hasBufferSpace() const override;
virtual void storeRequest(tlm::tlm_generic_payload *payload) override;
virtual void removeRequest(tlm::tlm_generic_payload *payload) override;
virtual const std::vector<unsigned> &getBufferDepth() const override;
private:
const unsigned requestBufferSize;
std::vector<unsigned> numRequests;
};
#endif // BUFFERCOUNTERSHARED_H

View File

@@ -36,6 +36,7 @@
#include "../../configuration/Configuration.h"
#include "BufferCounterBankwise.h"
#include "BufferCounterReadWrite.h"
#include "BufferCounterShared.h"
using namespace tlm;
@@ -48,6 +49,13 @@ SchedulerFifo::SchedulerFifo()
bufferCounter = new BufferCounterBankwise(config.requestBufferSize, config.memSpec->numberOfBanks);
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite)
bufferCounter = new BufferCounterReadWrite(config.requestBufferSize);
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared)
bufferCounter = new BufferCounterShared(config.requestBufferSize);
}
SchedulerFifo::~SchedulerFifo()
{
delete bufferCounter;
}
bool SchedulerFifo::hasBufferSpace() const
@@ -94,3 +102,8 @@ bool SchedulerFifo::hasFurtherRequest(Bank bank) const
else
return false;
}
const std::vector<unsigned> &SchedulerFifo::getBufferDepth() const
{
return bufferCounter->getBufferDepth();
}

View File

@@ -44,16 +44,18 @@
#include "../BankMachine.h"
#include "BufferCounterIF.h"
class SchedulerFifo : public SchedulerIF
class SchedulerFifo final : public SchedulerIF
{
public:
SchedulerFifo();
virtual ~SchedulerFifo() override;
virtual bool hasBufferSpace() const override;
virtual void storeRequest(tlm::tlm_generic_payload *) override;
virtual void removeRequest(tlm::tlm_generic_payload *) override;
virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override;
virtual bool hasFurtherRowHit(Bank, Row) const override;
virtual bool hasFurtherRequest(Bank) const override;
virtual const std::vector<unsigned> &getBufferDepth() const override;
private:
std::vector<std::deque<tlm::tlm_generic_payload *>> buffer;

View File

@@ -36,6 +36,7 @@
#include "../../configuration/Configuration.h"
#include "BufferCounterBankwise.h"
#include "BufferCounterReadWrite.h"
#include "BufferCounterShared.h"
using namespace tlm;
@@ -48,6 +49,13 @@ SchedulerFrFcfs::SchedulerFrFcfs()
bufferCounter = new BufferCounterBankwise(config.requestBufferSize, config.memSpec->numberOfBanks);
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite)
bufferCounter = new BufferCounterReadWrite(config.requestBufferSize);
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared)
bufferCounter = new BufferCounterShared(config.requestBufferSize);
}
SchedulerFrFcfs::~SchedulerFrFcfs()
{
delete bufferCounter;
}
bool SchedulerFrFcfs::hasBufferSpace() const
@@ -115,3 +123,8 @@ bool SchedulerFrFcfs::hasFurtherRequest(Bank bank) const
{
return (buffer[bank.ID()].size() >= 2);
}
const std::vector<unsigned> &SchedulerFrFcfs::getBufferDepth() const
{
return bufferCounter->getBufferDepth();
}

View File

@@ -44,16 +44,18 @@
#include "../BankMachine.h"
#include "BufferCounterIF.h"
class SchedulerFrFcfs : public SchedulerIF
class SchedulerFrFcfs final : public SchedulerIF
{
public:
SchedulerFrFcfs();
virtual ~SchedulerFrFcfs() override;
virtual bool hasBufferSpace() const override;
virtual void storeRequest(tlm::tlm_generic_payload *) override;
virtual void removeRequest(tlm::tlm_generic_payload *) override;
virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override;
virtual bool hasFurtherRowHit(Bank, Row) const override;
virtual bool hasFurtherRequest(Bank) const override;
virtual const std::vector<unsigned> &getBufferDepth() const override;
private:
std::vector<std::list<tlm::tlm_generic_payload *>> buffer;

View File

@@ -36,6 +36,7 @@
#include "../../configuration/Configuration.h"
#include "BufferCounterBankwise.h"
#include "BufferCounterReadWrite.h"
#include "BufferCounterShared.h"
using namespace tlm;
@@ -48,6 +49,13 @@ SchedulerFrFcfsGrp::SchedulerFrFcfsGrp()
bufferCounter = new BufferCounterBankwise(config.requestBufferSize, config.memSpec->numberOfBanks);
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite)
bufferCounter = new BufferCounterReadWrite(config.requestBufferSize);
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared)
bufferCounter = new BufferCounterShared(config.requestBufferSize);
}
SchedulerFrFcfsGrp::~SchedulerFrFcfsGrp()
{
delete bufferCounter;
}
bool SchedulerFrFcfsGrp::hasBufferSpace() const
@@ -143,3 +151,8 @@ bool SchedulerFrFcfsGrp::hasFurtherRequest(Bank bank) const
else
return false;
}
const std::vector<unsigned> &SchedulerFrFcfsGrp::getBufferDepth() const
{
return bufferCounter->getBufferDepth();
}

View File

@@ -44,16 +44,18 @@
#include "../BankMachine.h"
#include "BufferCounterIF.h"
class SchedulerFrFcfsGrp : public SchedulerIF
class SchedulerFrFcfsGrp final : public SchedulerIF
{
public:
SchedulerFrFcfsGrp();
virtual ~SchedulerFrFcfsGrp() override;
virtual bool hasBufferSpace() const override;
virtual void storeRequest(tlm::tlm_generic_payload *) override;
virtual void removeRequest(tlm::tlm_generic_payload *) override;
virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override;
virtual bool hasFurtherRowHit(Bank, Row) const override;
virtual bool hasFurtherRequest(Bank) const override;
virtual const std::vector<unsigned> &getBufferDepth() const override;
private:
std::vector<std::list<tlm::tlm_generic_payload *>> buffer;

View File

@@ -45,13 +45,14 @@ class BankMachine;
class SchedulerIF
{
public:
virtual ~SchedulerIF() {}
virtual ~SchedulerIF() = default;
virtual bool hasBufferSpace() const = 0;
virtual void storeRequest(tlm::tlm_generic_payload *) = 0;
virtual void removeRequest(tlm::tlm_generic_payload *) = 0;
virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const = 0;
virtual bool hasFurtherRowHit(Bank, Row) const = 0;
virtual bool hasFurtherRequest(Bank) const = 0;
virtual const std::vector<unsigned> &getBufferDepth() const = 0;
};
#endif // SCHEDULERIF_H

View File

@@ -55,6 +55,9 @@ Arbiter::Arbiter(sc_module_name name, std::string pathToAddressMapping) :
addressDecoder->print();
}
ArbiterSimple::ArbiterSimple(sc_module_name name, std::string pathToAddressMapping) :
Arbiter(name, pathToAddressMapping) {}
ArbiterFifo::ArbiterFifo(sc_module_name name, std::string pathToAddressMapping) :
Arbiter(name, pathToAddressMapping) {}
@@ -84,6 +87,14 @@ void Arbiter::end_of_elaboration()
}
}
void ArbiterSimple::end_of_elaboration()
{
Arbiter::end_of_elaboration();
for (unsigned i = 0; i < tSocket.size(); i++) // initiator side
pendingResponses.push_back(std::queue<tlm_generic_payload *>());
}
void ArbiterFifo::end_of_elaboration()
{
Arbiter::end_of_elaboration();
@@ -124,6 +135,8 @@ tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload &payload,
payload.get_streaming_width(), 0, 0);
payload.acquire();
}
else if (phase == END_RESP)
notDelay += tCK;
PRINTDEBUGMESSAGE(name(), "[fw] " + getPhaseName(phase) + " notification in " +
notDelay.to_string());
@@ -149,6 +162,87 @@ unsigned int Arbiter::transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans)
return iSocket[static_cast<int>(decodedAddress.channel)]->transport_dbg(trans);
}
void ArbiterSimple::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &cbPhase)
{
unsigned int threadId = DramExtension::getExtension(cbPayload).getThread().ID();
unsigned int channelId = DramExtension::getExtension(cbPayload).getChannel().ID();
if (cbPhase == BEGIN_REQ) // from initiator
{
GenerationExtension::setExtension(cbPayload, sc_time_stamp());
DramExtension::setPayloadIDs(cbPayload,
nextThreadPayloadIDToAppend[threadId]++, nextChannelPayloadIDToAppend[channelId]++);
if (!channelIsBusy[channelId])
{
channelIsBusy[channelId] = true;
tlm_phase tPhase = BEGIN_REQ;
sc_time tDelay = SC_ZERO_TIME;
iSocket[static_cast<int>(channelId)]->nb_transport_fw(cbPayload, tPhase, tDelay);
}
else
pendingRequests[channelId].push(&cbPayload);
}
else if (cbPhase == END_REQ) // from target
{
{
tlm_phase tPhase = END_REQ;
sc_time tDelay = SC_ZERO_TIME;
tSocket[static_cast<int>(threadId)]->nb_transport_bw(cbPayload, tPhase, tDelay);
}
if (!pendingRequests[channelId].empty())
{
tlm_generic_payload &tPayload = *pendingRequests[channelId].front();
pendingRequests[channelId].pop();
tlm_phase tPhase = BEGIN_REQ;
sc_time tDelay = SC_ZERO_TIME;
iSocket[static_cast<int>(channelId)]->nb_transport_fw(tPayload, tPhase, tDelay);
}
else
channelIsBusy[channelId] = false;
}
else if (cbPhase == BEGIN_RESP) // from memory controller
{
if (!threadIsBusy[threadId])
{
tlm_phase tPhase = BEGIN_RESP;
sc_time tDelay = SC_ZERO_TIME;
tlm_sync_enum returnValue = tSocket[static_cast<int>(threadId)]->nb_transport_bw(cbPayload, tPhase, tDelay);
if (returnValue == TLM_UPDATED)
payloadEventQueue.notify(cbPayload, tPhase, tDelay);
threadIsBusy[threadId] = true;
}
else
pendingResponses[threadId].push(&cbPayload);
}
else if (cbPhase == END_RESP) // from initiator
{
{
tlm_phase tPhase = END_RESP;
sc_time tDelay = SC_ZERO_TIME;
iSocket[static_cast<int>(channelId)]->nb_transport_fw(cbPayload, tPhase, tDelay);
}
cbPayload.release();
if (!pendingResponses[threadId].empty())
{
tlm_generic_payload &tPayload = *pendingResponses[threadId].front();
pendingResponses[threadId].pop();
tlm_phase tPhase = BEGIN_RESP;
sc_time tDelay = SC_ZERO_TIME;
tlm_sync_enum returnValue = tSocket[static_cast<int>(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay);
if (returnValue == TLM_UPDATED)
payloadEventQueue.notify(tPayload, tPhase, tDelay);
}
else
threadIsBusy[threadId] = false;
}
else
SC_REPORT_FATAL(0, "Payload event queue in arbiter was triggered with unknown phase");
}
void ArbiterFifo::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &cbPhase)
{
unsigned int threadId = DramExtension::getExtension(cbPayload).getThread().ID();
@@ -266,8 +360,7 @@ void ArbiterFifo::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &c
}
}
else
SC_REPORT_FATAL(0,
"Payload event queue in arbiter was triggered with unknown phase");
SC_REPORT_FATAL(0, "Payload event queue in arbiter was triggered with unknown phase");
}
void ArbiterReorder::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &cbPhase)
@@ -395,6 +488,5 @@ void ArbiterReorder::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase
}
}
else
SC_REPORT_FATAL(0,
"Payload event queue in arbiter was triggered with unknown phase");
SC_REPORT_FATAL(0, "Payload event queue in arbiter was triggered with unknown phase");
}

View File

@@ -92,12 +92,23 @@ protected:
sc_time tCK;
};
class ArbiterSimple final : public Arbiter
{
public:
ArbiterSimple(sc_module_name, std::string);
SC_HAS_PROCESS(ArbiterSimple);
private:
virtual void end_of_elaboration() override;
virtual void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase) override;
std::vector<std::queue<tlm::tlm_generic_payload *>> pendingResponses;
};
class ArbiterFifo final : public Arbiter
{
public:
ArbiterFifo(sc_module_name, std::string);
SC_HAS_PROCESS(ArbiterFifo);
virtual ~ArbiterFifo() override {}
private:
virtual void end_of_elaboration() override;
@@ -110,7 +121,6 @@ class ArbiterReorder final : public Arbiter
public:
ArbiterReorder(sc_module_name, std::string);
SC_HAS_PROCESS(ArbiterReorder);
virtual ~ArbiterReorder() override {}
private:
virtual void end_of_elaboration() override;

View File

@@ -196,7 +196,9 @@ void DRAMSys::instantiateModules(const std::string &pathToResources,
config.pECC = ecc;
// Create arbiter
if (config.arbiter == Configuration::Arbiter::Fifo)
if (config.arbiter == Configuration::Arbiter::Simple)
arbiter = new ArbiterSimple("arbiter", pathToResources + "configs/amconfigs/" + amconfig);
else if (config.arbiter == Configuration::Arbiter::Fifo)
arbiter = new ArbiterFifo("arbiter", pathToResources + "configs/amconfigs/" + amconfig);
else if (config.arbiter == Configuration::Arbiter::Reorder)
arbiter = new ArbiterReorder("arbiter", pathToResources + "configs/amconfigs/" + amconfig);

View File

@@ -137,7 +137,9 @@ void DRAMSysRecordable::instantiateModules(const std::string &traceName,
config.pECC = ecc;
// Create arbiter
if (config.arbiter == Configuration::Arbiter::Fifo)
if (config.arbiter == Configuration::Arbiter::Simple)
arbiter = new ArbiterSimple("arbiter", pathToResources + "configs/amconfigs/" + amconfig);
else if (config.arbiter == Configuration::Arbiter::Fifo)
arbiter = new ArbiterFifo("arbiter", pathToResources + "configs/amconfigs/" + amconfig);
else if (config.arbiter == Configuration::Arbiter::Reorder)
arbiter = new ArbiterReorder("arbiter", pathToResources + "configs/amconfigs/" + amconfig);

View File

@@ -6,6 +6,7 @@ DROP TABLE IF EXISTS ranges;
DROP TABLE IF EXISTS Transactions;
DROP TABLE IF EXISTS DebugMessages;
DROP TABLE IF EXISTS Power;
DROP TABLE IF EXISTS BufferDepth;
CREATE TABLE Phases(
ID INTEGER PRIMARY KEY,
@@ -29,7 +30,8 @@ CREATE TABLE GeneralInfo(
WindowSize INTEGER,
FlexibleRefresh INTEGER,
MaxRefBurst INTEGER,
ControllerThread INTEGER
ControllerThread INTEGER,
MaxBufferDepth INTEGER
);
CREATE TABLE CommandLengths(
@@ -58,6 +60,11 @@ CREATE TABLE Power(
AveragePower DOUBLE
);
CREATE TABLE BufferDepth(
Time DOUBLE,
BufferNumber INTEGER,
AverageBufferDepth DOUBLE
);
CREATE TABLE Comments(
Time INTEGER,
@@ -91,7 +98,7 @@ CREATE TABLE Transactions(
DataStrobeEnd INTEGER,
TimeOfGeneration INTEGER,
Command TEXT
);
);
CREATE INDEX ranges_index ON Transactions(Range);
CREATE INDEX "phasesTransactions" ON "Phases" ("Transact" ASC);

View File

@@ -6,6 +6,7 @@ DROP TABLE IF EXISTS ranges;
DROP TABLE IF EXISTS Transactions;
DROP TABLE IF EXISTS DebugMessages;
DROP TABLE IF EXISTS Power;
DROP TABLE IF EXISTS BufferDepth;
CREATE TABLE Phases(
ID INTEGER PRIMARY KEY,
@@ -29,7 +30,8 @@ CREATE TABLE GeneralInfo(
WindowSize INTEGER,
FlexibleRefresh INTEGER,
MaxRefBurst INTEGER,
ControllerThread INTEGER
ControllerThread INTEGER,
MaxBufferDepth INTEGER
);
CREATE TABLE CommandLengths(
@@ -58,6 +60,11 @@ CREATE TABLE Power(
AveragePower DOUBLE
);
CREATE TABLE BufferDepth(
Time DOUBLE,
BufferNumber INTEGER,
AverageBufferDepth DOUBLE
);
CREATE TABLE Comments(
Time INTEGER,
@@ -91,7 +98,7 @@ CREATE TABLE Transactions(
DataStrobeEnd INTEGER,
TimeOfGeneration INTEGER,
Command TEXT
);
);
CREATE INDEX ranges_index ON Transactions(Range);
CREATE INDEX "phasesTransactions" ON "Phases" ("Transact" ASC);

View File

@@ -6,6 +6,7 @@ DROP TABLE IF EXISTS ranges;
DROP TABLE IF EXISTS Transactions;
DROP TABLE IF EXISTS DebugMessages;
DROP TABLE IF EXISTS Power;
DROP TABLE IF EXISTS BufferDepth;
CREATE TABLE Phases(
ID INTEGER PRIMARY KEY,
@@ -29,7 +30,8 @@ CREATE TABLE GeneralInfo(
WindowSize INTEGER,
FlexibleRefresh INTEGER,
MaxRefBurst INTEGER,
ControllerThread INTEGER
ControllerThread INTEGER,
MaxBufferDepth INTEGER
);
CREATE TABLE CommandLengths(
@@ -58,6 +60,11 @@ CREATE TABLE Power(
AveragePower DOUBLE
);
CREATE TABLE BufferDepth(
Time DOUBLE,
BufferNumber INTEGER,
AverageBufferDepth DOUBLE
);
CREATE TABLE Comments(
Time INTEGER,
@@ -91,7 +98,7 @@ CREATE TABLE Transactions(
DataStrobeEnd INTEGER,
TimeOfGeneration INTEGER,
Command TEXT
);
);
CREATE INDEX ranges_index ON Transactions(Range);
CREATE INDEX "phasesTransactions" ON "Phases" ("Transact" ASC);

View File

@@ -6,6 +6,7 @@ DROP TABLE IF EXISTS ranges;
DROP TABLE IF EXISTS Transactions;
DROP TABLE IF EXISTS DebugMessages;
DROP TABLE IF EXISTS Power;
DROP TABLE IF EXISTS BufferDepth;
CREATE TABLE Phases(
ID INTEGER PRIMARY KEY,
@@ -29,7 +30,8 @@ CREATE TABLE GeneralInfo(
WindowSize INTEGER,
FlexibleRefresh INTEGER,
MaxRefBurst INTEGER,
ControllerThread INTEGER
ControllerThread INTEGER,
MaxBufferDepth INTEGER
);
CREATE TABLE CommandLengths(
@@ -58,6 +60,11 @@ CREATE TABLE Power(
AveragePower DOUBLE
);
CREATE TABLE BufferDepth(
Time DOUBLE,
BufferNumber INTEGER,
AverageBufferDepth DOUBLE
);
CREATE TABLE Comments(
Time INTEGER,
@@ -91,7 +98,7 @@ CREATE TABLE Transactions(
DataStrobeEnd INTEGER,
TimeOfGeneration INTEGER,
Command TEXT
);
);
CREATE INDEX ranges_index ON Transactions(Range);
CREATE INDEX "phasesTransactions" ON "Phases" ("Transact" ASC);