From abe8ef38b85626bd320b9654c49449c0197e8285 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Thu, 14 Jan 2021 16:48:21 +0100 Subject: [PATCH] Implement first version of arbitration delay and think delay. --- .../resources/configs/mcconfigs/fr_fcfs.json | 6 ++++- DRAMSys/library/src/controller/Controller.cpp | 9 ++++---- DRAMSys/library/src/controller/Controller.h | 2 +- .../controller/scheduler/SchedulerFifo.cpp | 22 +++++++++++++------ .../src/controller/scheduler/SchedulerFifo.h | 9 ++++++-- .../controller/scheduler/SchedulerFrFcfs.cpp | 18 ++++++++++++--- .../controller/scheduler/SchedulerFrFcfs.h | 9 ++++++-- .../scheduler/SchedulerFrFcfsGrp.cpp | 18 ++++++++++++--- .../controller/scheduler/SchedulerFrFcfsGrp.h | 9 ++++++-- .../src/controller/scheduler/SchedulerIF.h | 2 +- DRAMSys/library/src/simulation/Arbiter.cpp | 8 +++---- 11 files changed, 82 insertions(+), 30 deletions(-) diff --git a/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs.json b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs.json index 27d580ba..4ed8b65b 100644 --- a/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs.json +++ b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs.json @@ -2,6 +2,7 @@ "mcconfig": { "PagePolicy": "Open", "Scheduler": "FrFcfs", + "SchedulerBuffer": "Bankwise", "RequestBufferSize": 8, "CmdMux": "Oldest", "RespQueue": "Fifo", @@ -9,6 +10,9 @@ "RefreshMaxPostponed": 8, "RefreshMaxPulledin": 8, "PowerDownPolicy": "NoPowerDown", - "PowerDownTimeout": 100 + "PowerDownTimeout": 100, + "ArbitrationDelay": 0, + "ThinkDelay": 0, + "PhyDelay": 0 } } \ No newline at end of file diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index f47008b4..b9788d16 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -67,7 +67,8 @@ Controller::Controller(sc_module_name name) : ControllerIF(name) { SC_METHOD(controllerMethod); - sensitive << beginReqEvent << endRespEvent << controllerEvent << dataResponseEvent; + sensitive << beginReqEvent << endRespEvent + << controllerEvent << dataResponseEvent << thinkDelayEvent; Configuration &config = Configuration::getInstance(); memSpec = config.memSpec; @@ -101,11 +102,11 @@ Controller::Controller(sc_module_name name) : // instantiate scheduler and command mux if (config.scheduler == Configuration::Scheduler::Fifo) - scheduler = new SchedulerFifo(); + scheduler = new SchedulerFifo(thinkDelayEvent); else if (config.scheduler == Configuration::Scheduler::FrFcfs) - scheduler = new SchedulerFrFcfs(); + scheduler = new SchedulerFrFcfs(thinkDelayEvent); else if (config.scheduler == Configuration::Scheduler::FrFcfsGrp) - scheduler = new SchedulerFrFcfsGrp(); + scheduler = new SchedulerFrFcfsGrp(thinkDelayEvent); if (config.cmdMux == Configuration::CmdMux::Oldest) cmdMux = new CmdMuxOldest(); diff --git a/DRAMSys/library/src/controller/Controller.h b/DRAMSys/library/src/controller/Controller.h index ff693776..d6cef920 100644 --- a/DRAMSys/library/src/controller/Controller.h +++ b/DRAMSys/library/src/controller/Controller.h @@ -101,7 +101,7 @@ private: void manageResponses(); void manageRequests(); - sc_event beginReqEvent, endRespEvent, controllerEvent, dataResponseEvent; + sc_event beginReqEvent, endRespEvent, controllerEvent, dataResponseEvent, thinkDelayEvent; }; #endif // CONTROLLER_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp index 90d38301..ba3c05f2 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp @@ -40,7 +40,8 @@ using namespace tlm; -SchedulerFifo::SchedulerFifo() +SchedulerFifo::SchedulerFifo(sc_event &thinkDelayEvent) + : thinkDelayEvent(thinkDelayEvent) { Configuration &config = Configuration::getInstance(); buffer = std::vector>(config.memSpec->numberOfBanks); @@ -65,7 +66,7 @@ bool SchedulerFifo::hasBufferSpace() const void SchedulerFifo::storeRequest(tlm_generic_payload *payload) { - buffer[DramExtension::getBank(payload).ID()].push_back(payload); + thinkDelayBuffer.push({payload, sc_time_stamp() + thinkDelay}); bufferCounter->storeRequest(payload); } @@ -75,8 +76,18 @@ void SchedulerFifo::removeRequest(tlm_generic_payload *payload) bufferCounter->removeRequest(payload); } -tlm_generic_payload *SchedulerFifo::getNextRequest(BankMachine *bankMachine) const +tlm_generic_payload *SchedulerFifo::getNextRequest(BankMachine *bankMachine) { + while ((!thinkDelayBuffer.empty()) && (thinkDelayBuffer.front().second <= sc_time_stamp())) + { + tlm_generic_payload *payload = thinkDelayBuffer.front().first; + buffer[DramExtension::getBank(payload).ID()].push_back(payload); + thinkDelayBuffer.pop(); + } + + if (!thinkDelayBuffer.empty()) + thinkDelayEvent.notify(thinkDelayBuffer.front().second - sc_time_stamp()); + unsigned bankID = bankMachine->getBank().ID(); if (!buffer[bankID].empty()) return buffer[bankID].front(); @@ -97,10 +108,7 @@ bool SchedulerFifo::hasFurtherRowHit(Bank bank, Row row) const bool SchedulerFifo::hasFurtherRequest(Bank bank) const { - if (buffer[bank.ID()].size() >= 2) - return true; - else - return false; + return (buffer[bank.ID()].size() >= 2); } const std::vector &SchedulerFifo::getBufferDepth() const diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h index ae06ac48..167fd074 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include "SchedulerIF.h" #include "../../common/dramExtensions.h" @@ -47,18 +49,21 @@ class SchedulerFifo final : public SchedulerIF { public: - SchedulerFifo(); + SchedulerFifo(sc_event &); 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 tlm::tlm_generic_payload *getNextRequest(BankMachine *) override; virtual bool hasFurtherRowHit(Bank, Row) const override; virtual bool hasFurtherRequest(Bank) const override; virtual const std::vector &getBufferDepth() const override; private: std::vector> buffer; + std::queue> thinkDelayBuffer; + sc_time thinkDelay; + sc_event &thinkDelayEvent; BufferCounterIF *bufferCounter; }; diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp index a15dc6f2..0fa4f433 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp @@ -40,10 +40,12 @@ using namespace tlm; -SchedulerFrFcfs::SchedulerFrFcfs() +SchedulerFrFcfs::SchedulerFrFcfs(sc_event &thinkDelayEvent) + : thinkDelayEvent(thinkDelayEvent) { Configuration &config = Configuration::getInstance(); buffer = std::vector>(config.memSpec->numberOfBanks); + thinkDelay = config.thinkDelay; if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise) bufferCounter = new BufferCounterBankwise(config.requestBufferSize, config.memSpec->numberOfBanks); @@ -65,7 +67,7 @@ bool SchedulerFrFcfs::hasBufferSpace() const void SchedulerFrFcfs::storeRequest(tlm_generic_payload *payload) { - buffer[DramExtension::getBank(payload).ID()].push_back(payload); + thinkDelayBuffer.push({payload, sc_time_stamp() + thinkDelay}); bufferCounter->storeRequest(payload); } @@ -83,8 +85,18 @@ void SchedulerFrFcfs::removeRequest(tlm_generic_payload *payload) } } -tlm_generic_payload *SchedulerFrFcfs::getNextRequest(BankMachine *bankMachine) const +tlm_generic_payload *SchedulerFrFcfs::getNextRequest(BankMachine *bankMachine) { + while ((!thinkDelayBuffer.empty()) && (thinkDelayBuffer.front().second <= sc_time_stamp())) + { + tlm_generic_payload *payload = thinkDelayBuffer.front().first; + buffer[DramExtension::getBank(payload).ID()].push_back(payload); + thinkDelayBuffer.pop(); + } + + if (!thinkDelayBuffer.empty()) + thinkDelayEvent.notify(thinkDelayBuffer.front().second - sc_time_stamp()); + unsigned bankID = bankMachine->getBank().ID(); if (!buffer[bankID].empty()) { diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h index 15633b51..5b15b503 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include "SchedulerIF.h" #include "../../common/dramExtensions.h" @@ -47,18 +49,21 @@ class SchedulerFrFcfs final : public SchedulerIF { public: - SchedulerFrFcfs(); + SchedulerFrFcfs(sc_event &); 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 tlm::tlm_generic_payload *getNextRequest(BankMachine *) override; virtual bool hasFurtherRowHit(Bank, Row) const override; virtual bool hasFurtherRequest(Bank) const override; virtual const std::vector &getBufferDepth() const override; private: std::vector> buffer; + std::queue> thinkDelayBuffer; + sc_time thinkDelay; + sc_event &thinkDelayEvent; BufferCounterIF *bufferCounter; }; diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp index a1510123..98d758c0 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp @@ -40,10 +40,12 @@ using namespace tlm; -SchedulerFrFcfsGrp::SchedulerFrFcfsGrp() +SchedulerFrFcfsGrp::SchedulerFrFcfsGrp(sc_event &thinkDelayEvent) + : thinkDelayEvent(thinkDelayEvent) { Configuration &config = Configuration::getInstance(); buffer = std::vector>(config.memSpec->numberOfBanks); + thinkDelay = config.thinkDelay; if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise) bufferCounter = new BufferCounterBankwise(config.requestBufferSize, config.memSpec->numberOfBanks); @@ -65,7 +67,7 @@ bool SchedulerFrFcfsGrp::hasBufferSpace() const void SchedulerFrFcfsGrp::storeRequest(tlm_generic_payload *payload) { - buffer[DramExtension::getBank(payload).ID()].push_back(payload); + thinkDelayBuffer.push({payload, sc_time_stamp() + thinkDelay}); bufferCounter->storeRequest(payload); } @@ -84,8 +86,18 @@ void SchedulerFrFcfsGrp::removeRequest(tlm_generic_payload *payload) } } -tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine) const +tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine) { + while ((!thinkDelayBuffer.empty()) && (thinkDelayBuffer.front().second <= sc_time_stamp())) + { + tlm_generic_payload *payload = thinkDelayBuffer.front().first; + buffer[DramExtension::getBank(payload).ID()].push_back(payload); + thinkDelayBuffer.pop(); + } + + if (!thinkDelayBuffer.empty()) + thinkDelayEvent.notify(thinkDelayBuffer.front().second - sc_time_stamp()); + unsigned bankID = bankMachine->getBank().ID(); if (!buffer[bankID].empty()) { diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h index b6f67e1c..8096366e 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include "SchedulerIF.h" #include "../../common/dramExtensions.h" @@ -47,18 +49,21 @@ class SchedulerFrFcfsGrp final : public SchedulerIF { public: - SchedulerFrFcfsGrp(); + SchedulerFrFcfsGrp(sc_event &); 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 tlm::tlm_generic_payload *getNextRequest(BankMachine *) override; virtual bool hasFurtherRowHit(Bank, Row) const override; virtual bool hasFurtherRequest(Bank) const override; virtual const std::vector &getBufferDepth() const override; private: std::vector> buffer; + std::queue> thinkDelayBuffer; + sc_time thinkDelay; + sc_event &thinkDelayEvent; tlm::tlm_command lastCommand = tlm::TLM_READ_COMMAND; BufferCounterIF *bufferCounter; }; diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerIF.h b/DRAMSys/library/src/controller/scheduler/SchedulerIF.h index fbde3fdb..7066c791 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerIF.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerIF.h @@ -49,7 +49,7 @@ public: 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 tlm::tlm_generic_payload *getNextRequest(BankMachine *) = 0; virtual bool hasFurtherRowHit(Bank, Row) const = 0; virtual bool hasFurtherRequest(Bank) const = 0; virtual const std::vector &getBufferDepth() const = 0; diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp index e1f7e0af..7aa15a7f 100644 --- a/DRAMSys/library/src/simulation/Arbiter.cpp +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -178,7 +178,7 @@ void ArbiterSimple::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase channelIsBusy[channelId] = true; tlm_phase tPhase = BEGIN_REQ; - sc_time tDelay = SC_ZERO_TIME; + sc_time tDelay = arbitrationDelay; iSocket[static_cast(channelId)]->nb_transport_fw(cbPayload, tPhase, tDelay); } else @@ -198,7 +198,7 @@ void ArbiterSimple::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase pendingRequests[channelId].pop(); tlm_phase tPhase = BEGIN_REQ; // do not send two requests in the same cycle - sc_time tDelay = tCK; + sc_time tDelay = tCK + arbitrationDelay; iSocket[static_cast(channelId)]->nb_transport_fw(tPayload, tPhase, tDelay); } else @@ -209,7 +209,7 @@ void ArbiterSimple::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase if (!threadIsBusy[threadId]) { tlm_phase tPhase = BEGIN_RESP; - sc_time tDelay = SC_ZERO_TIME; + sc_time tDelay = arbitrationDelay; tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(cbPayload, tPhase, tDelay); if (returnValue == TLM_UPDATED) payloadEventQueue.notify(cbPayload, tPhase, tDelay); @@ -233,7 +233,7 @@ void ArbiterSimple::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase pendingResponses[threadId].pop(); tlm_phase tPhase = BEGIN_RESP; // do not send two responses in the same cycle - sc_time tDelay = tCK; + sc_time tDelay = tCK + arbitrationDelay; tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay); if (returnValue == TLM_UPDATED) payloadEventQueue.notify(tPayload, tPhase, tDelay);