diff --git a/DRAMSys/library/CMakeLists.txt b/DRAMSys/library/CMakeLists.txt index 6c69454c..44a42618 100644 --- a/DRAMSys/library/CMakeLists.txt +++ b/DRAMSys/library/CMakeLists.txt @@ -142,6 +142,8 @@ add_library(DRAMSysLibrary src/controller/scheduler/SchedulerFifo.cpp src/controller/scheduler/SchedulerFrFcfs.cpp src/controller/scheduler/SchedulerFrFcfsGrp.cpp + src/controller/scheduler/SchedulerGrpFrFcfs.cpp + src/controller/scheduler/SchedulerGrpFrFcfsWm.cpp src/controller/scheduler/BufferCounterIF.h src/controller/scheduler/BufferCounterBankwise.cpp diff --git a/DRAMSys/library/src/common/configuration/McConfig.h b/DRAMSys/library/src/common/configuration/McConfig.h index eecae645..aa473750 100644 --- a/DRAMSys/library/src/common/configuration/McConfig.h +++ b/DRAMSys/library/src/common/configuration/McConfig.h @@ -70,13 +70,17 @@ enum class Scheduler Fifo, FrFcfs, FrFcfsGrp, + GrpFrFcfs, + GrpFrFcfsWm, Invalid = -1 }; NLOHMANN_JSON_SERIALIZE_ENUM(Scheduler, {{Scheduler::Invalid, nullptr}, {Scheduler::Fifo, "Fifo"}, {Scheduler::FrFcfs, "FrFcfs"}, - {Scheduler::FrFcfsGrp, "FrFcfsGrp"}}) + {Scheduler::FrFcfsGrp, "FrFcfsGrp"}, + {Scheduler::GrpFrFcfs, "GrpFrFcfs"}, + {Scheduler::GrpFrFcfsWm, "GrpFrFcfsWm"}}) enum class SchedulerBuffer { diff --git a/DRAMSys/library/src/configuration/Configuration.cpp b/DRAMSys/library/src/configuration/Configuration.cpp index 76636cd4..3d895413 100644 --- a/DRAMSys/library/src/configuration/Configuration.cpp +++ b/DRAMSys/library/src/configuration/Configuration.cpp @@ -196,8 +196,12 @@ void Configuration::loadMCConfig(Configuration &config, const DRAMSysConfigurati return Scheduler::Fifo; else if (scheduler == DRAMSysConfiguration::Scheduler::FrFcfs) return Scheduler::FrFcfs; - else + else if (scheduler == DRAMSysConfiguration::Scheduler::FrFcfsGrp) return Scheduler::FrFcfsGrp; + else if (scheduler == DRAMSysConfiguration::Scheduler::GrpFrFcfs) + return Scheduler::GrpFrFcfs; + else + return Scheduler::GrpFrFcfsWm; }(); if (const auto &schedulerBuffer = mcConfig.schedulerBuffer) diff --git a/DRAMSys/library/src/configuration/Configuration.h b/DRAMSys/library/src/configuration/Configuration.h index 946b48c7..40df4488 100644 --- a/DRAMSys/library/src/configuration/Configuration.h +++ b/DRAMSys/library/src/configuration/Configuration.h @@ -64,8 +64,10 @@ private: public: // MCConfig: enum class PagePolicy {Open, Closed, OpenAdaptive, ClosedAdaptive} pagePolicy = PagePolicy::Open; - enum class Scheduler {Fifo, FrFcfs, FrFcfsGrp} scheduler = Scheduler::FrFcfs; + enum class Scheduler {Fifo, FrFcfs, FrFcfsGrp, GrpFrFcfs, GrpFrFcfsWm} scheduler = Scheduler::FrFcfs; enum class SchedulerBuffer {Bankwise, ReadWrite, Shared} schedulerBuffer = SchedulerBuffer::Bankwise; + unsigned int lowWatermark = 8; + unsigned int highWatermark = 16; enum class CmdMux {Oldest, Strict} cmdMux = CmdMux::Oldest; enum class RespQueue {Fifo, Reorder} respQueue = RespQueue::Fifo; enum class Arbiter {Simple, Fifo, Reorder} arbiter = Arbiter::Simple; diff --git a/DRAMSys/library/src/controller/BankMachine.cpp b/DRAMSys/library/src/controller/BankMachine.cpp index ae9c2cc6..97b3aed2 100644 --- a/DRAMSys/library/src/controller/BankMachine.cpp +++ b/DRAMSys/library/src/controller/BankMachine.cpp @@ -165,7 +165,7 @@ sc_time BankMachineOpen::start() if (!(sleeping || blocked)) { - currentPayload = scheduler.getNextRequest(this); + currentPayload = scheduler.getNextRequest(*this); if (currentPayload != nullptr) { if (state == State::Precharged) // bank precharged @@ -200,7 +200,7 @@ sc_time BankMachineClosed::start() if (!(sleeping || blocked)) { - currentPayload = scheduler.getNextRequest(this); + currentPayload = scheduler.getNextRequest(*this); if (currentPayload != nullptr) { if (state == State::Precharged) // bank precharged @@ -230,7 +230,7 @@ sc_time BankMachineOpenAdaptive::start() if (!(sleeping || blocked)) { - currentPayload = scheduler.getNextRequest(this); + currentPayload = scheduler.getNextRequest(*this); if (currentPayload != nullptr) { if (state == State::Precharged) // bank precharged @@ -239,7 +239,8 @@ sc_time BankMachineOpenAdaptive::start() { if (DramExtension::getRow(currentPayload) == openRow) // row hit { - if (scheduler.hasFurtherRequest(bank) && !scheduler.hasFurtherRowHit(bank, openRow)) + if (scheduler.hasFurtherRequest(bank, currentPayload->get_command()) + &&!scheduler.hasFurtherRowHit(bank, openRow, currentPayload->get_command())) { if (currentPayload->is_read()) nextCommand = Command::RDA; @@ -277,7 +278,7 @@ sc_time BankMachineClosedAdaptive::start() if (!(sleeping || blocked)) { - currentPayload = scheduler.getNextRequest(this); + currentPayload = scheduler.getNextRequest(*this); if (currentPayload != nullptr) { if (state == State::Precharged && !blocked) // bank precharged @@ -286,7 +287,7 @@ sc_time BankMachineClosedAdaptive::start() { if (DramExtension::getRow(currentPayload) == openRow) // row hit { - if (scheduler.hasFurtherRowHit(bank, openRow)) + if (scheduler.hasFurtherRowHit(bank, openRow, currentPayload->get_command())) { if (currentPayload->is_read()) nextCommand = Command::RD; diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index ff917f4d..02c51948 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -52,6 +52,8 @@ #include "scheduler/SchedulerFifo.h" #include "scheduler/SchedulerFrFcfs.h" #include "scheduler/SchedulerFrFcfsGrp.h" +#include "scheduler/SchedulerGrpFrFcfs.h" +#include "scheduler/SchedulerGrpFrFcfsWm.h" #include "cmdmux/CmdMuxStrict.h" #include "cmdmux/CmdMuxOldest.h" #include "respqueue/RespQueueFifo.h" @@ -118,6 +120,10 @@ Controller::Controller(const sc_module_name &name) : scheduler = std::make_unique(); else if (config.scheduler == Configuration::Scheduler::FrFcfsGrp) scheduler = std::make_unique(); + else if (config.scheduler == Configuration::Scheduler::GrpFrFcfs) + scheduler = std::make_unique(); + else if (config.scheduler == Configuration::Scheduler::GrpFrFcfsWm) + scheduler = std::make_unique(); if (config.cmdMux == Configuration::CmdMux::Oldest) { @@ -314,7 +320,7 @@ void Controller::controllerMethod() if (command.isCasCommand()) { - scheduler->removeRequest(payload); + scheduler->removeRequest(*payload); manageRequests(thinkDelayFw); respQueue->insertPayload(payload, sc_time_stamp() + thinkDelayFw + phyDelayFw @@ -417,7 +423,7 @@ void Controller::manageRequests(const sc_time &delay) ranksNumberOfPayloads[rank.ID()]++; - scheduler->storeRequest(transToAcquire.payload); + scheduler->storeRequest(*transToAcquire.payload); transToAcquire.payload->acquire(); Bank bank = DramExtension::getBank(transToAcquire.payload); diff --git a/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.cpp b/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.cpp index 7acc2482..a45baede 100644 --- a/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.cpp +++ b/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.cpp @@ -48,18 +48,36 @@ bool BufferCounterBankwise::hasBufferSpace() const return (numRequestsOnBank[lastBankID] < requestBufferSize); } -void BufferCounterBankwise::storeRequest(tlm_generic_payload *payload) +void BufferCounterBankwise::storeRequest(const tlm_generic_payload& trans) { - lastBankID = DramExtension::getBank(payload).ID(); + lastBankID = DramExtension::getBank(trans).ID(); numRequestsOnBank[lastBankID]++; + if (trans.is_read()) + numReadRequests++; + else + numWriteRequests++; } -void BufferCounterBankwise::removeRequest(tlm_generic_payload *payload) +void BufferCounterBankwise::removeRequest(const tlm_generic_payload& trans) { - numRequestsOnBank[DramExtension::getBank(payload).ID()]--; + numRequestsOnBank[DramExtension::getBank(trans).ID()]--; + if (trans.is_read()) + numReadRequests--; + else + numWriteRequests--; } const std::vector &BufferCounterBankwise::getBufferDepth() const { return numRequestsOnBank; } + +unsigned BufferCounterBankwise::getNumReadRequests() const +{ + return numReadRequests; +} + +unsigned BufferCounterBankwise::getNumWriteRequests() const +{ + return numWriteRequests; +} \ No newline at end of file diff --git a/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.h b/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.h index 02725b81..f970a697 100644 --- a/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.h +++ b/DRAMSys/library/src/controller/scheduler/BufferCounterBankwise.h @@ -45,14 +45,18 @@ class BufferCounterBankwise final : public BufferCounterIF public: BufferCounterBankwise(unsigned requestBufferSize, unsigned numberOfBanks); bool hasBufferSpace() const override; - void storeRequest(tlm::tlm_generic_payload *payload) override; - void removeRequest(tlm::tlm_generic_payload *payload) override; + void storeRequest(const tlm::tlm_generic_payload& trans) override; + void removeRequest(const tlm::tlm_generic_payload& trans) override; const std::vector &getBufferDepth() const override; + unsigned getNumReadRequests() const override; + unsigned getNumWriteRequests() const override; private: const unsigned requestBufferSize; std::vector numRequestsOnBank; unsigned lastBankID = 0; + unsigned numReadRequests = 0; + unsigned numWriteRequests = 0; }; #endif // BUFFERCOUNTERBANKWISE_H diff --git a/DRAMSys/library/src/controller/scheduler/BufferCounterIF.h b/DRAMSys/library/src/controller/scheduler/BufferCounterIF.h index 38ca4340..87936fbf 100644 --- a/DRAMSys/library/src/controller/scheduler/BufferCounterIF.h +++ b/DRAMSys/library/src/controller/scheduler/BufferCounterIF.h @@ -44,9 +44,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 void storeRequest(const tlm::tlm_generic_payload& trans) = 0; + virtual void removeRequest(const tlm::tlm_generic_payload& trans) = 0; virtual const std::vector &getBufferDepth() const = 0; + virtual unsigned getNumReadRequests() const = 0; + virtual unsigned getNumWriteRequests() const = 0; }; #endif // BUFFERCOUNTERIF_H diff --git a/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.cpp b/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.cpp index 3a036e0a..fae82ad5 100644 --- a/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.cpp +++ b/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.cpp @@ -47,17 +47,17 @@ bool BufferCounterReadWrite::hasBufferSpace() const return (numReadWriteRequests[0] < requestBufferSize && numReadWriteRequests[1] < requestBufferSize); } -void BufferCounterReadWrite::storeRequest(tlm_generic_payload *payload) +void BufferCounterReadWrite::storeRequest(const tlm_generic_payload& trans) { - if (payload->is_read()) + if (trans.is_read()) numReadWriteRequests[0]++; else numReadWriteRequests[1]++; } -void BufferCounterReadWrite::removeRequest(tlm_generic_payload *payload) +void BufferCounterReadWrite::removeRequest(const tlm_generic_payload& trans) { - if (payload->is_read()) + if (trans.is_read()) numReadWriteRequests[0]--; else numReadWriteRequests[1]--; @@ -67,3 +67,13 @@ const std::vector &BufferCounterReadWrite::getBufferDepth() const { return numReadWriteRequests; } + +unsigned BufferCounterReadWrite::getNumReadRequests() const +{ + return numReadWriteRequests[0]; +} + +unsigned BufferCounterReadWrite::getNumWriteRequests() const +{ + return numReadWriteRequests[1]; +} \ No newline at end of file diff --git a/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.h b/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.h index f0d28a90..fb330499 100644 --- a/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.h +++ b/DRAMSys/library/src/controller/scheduler/BufferCounterReadWrite.h @@ -45,9 +45,11 @@ class BufferCounterReadWrite final : public BufferCounterIF public: explicit BufferCounterReadWrite(unsigned requestBufferSize); bool hasBufferSpace() const override; - void storeRequest(tlm::tlm_generic_payload *payload) override; - void removeRequest(tlm::tlm_generic_payload *payload) override; + void storeRequest(const tlm::tlm_generic_payload& trans) override; + void removeRequest(const tlm::tlm_generic_payload& trans) override; const std::vector &getBufferDepth() const override; + unsigned getNumReadRequests() const override; + unsigned getNumWriteRequests() const override; private: const unsigned requestBufferSize; diff --git a/DRAMSys/library/src/controller/scheduler/BufferCounterShared.cpp b/DRAMSys/library/src/controller/scheduler/BufferCounterShared.cpp index a4b80ef1..7008d899 100644 --- a/DRAMSys/library/src/controller/scheduler/BufferCounterShared.cpp +++ b/DRAMSys/library/src/controller/scheduler/BufferCounterShared.cpp @@ -47,17 +47,35 @@ bool BufferCounterShared::hasBufferSpace() const return (numRequests[0] < requestBufferSize); } -void BufferCounterShared::storeRequest(tlm_generic_payload *) +void BufferCounterShared::storeRequest(const tlm_generic_payload& trans) { numRequests[0]++; + if (trans.is_read()) + numReadRequests++; + else + numWriteRequests++; } -void BufferCounterShared::removeRequest(tlm_generic_payload *) +void BufferCounterShared::removeRequest(const tlm_generic_payload& trans) { numRequests[0]--; + if (trans.is_read()) + numReadRequests--; + else + numWriteRequests--; } const std::vector &BufferCounterShared::getBufferDepth() const { return numRequests; } + +unsigned BufferCounterShared::getNumReadRequests() const +{ + return numReadRequests; +} + +unsigned BufferCounterShared::getNumWriteRequests() const +{ + return numWriteRequests; +} diff --git a/DRAMSys/library/src/controller/scheduler/BufferCounterShared.h b/DRAMSys/library/src/controller/scheduler/BufferCounterShared.h index 7e530579..31277f6a 100644 --- a/DRAMSys/library/src/controller/scheduler/BufferCounterShared.h +++ b/DRAMSys/library/src/controller/scheduler/BufferCounterShared.h @@ -45,13 +45,17 @@ class BufferCounterShared final : public BufferCounterIF public: explicit BufferCounterShared(unsigned requestBufferSize); bool hasBufferSpace() const override; - void storeRequest(tlm::tlm_generic_payload *payload) override; - void removeRequest(tlm::tlm_generic_payload *payload) override; + void storeRequest(const tlm::tlm_generic_payload& trans) override; + void removeRequest(const tlm::tlm_generic_payload& trans) override; const std::vector &getBufferDepth() const override; + unsigned getNumReadRequests() const override; + unsigned getNumWriteRequests() const override; private: const unsigned requestBufferSize; std::vector numRequests; + unsigned numReadRequests = 0; + unsigned numWriteRequests = 0; }; #endif // BUFFERCOUNTERSHARED_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp index 61038d65..d0c30a89 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp @@ -46,16 +46,11 @@ SchedulerFifo::SchedulerFifo() buffer = std::vector>(config.memSpec->banksPerChannel); if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise) - bufferCounter = new BufferCounterBankwise(config.requestBufferSize, config.memSpec->banksPerChannel); + bufferCounter = std::make_unique(config.requestBufferSize, config.memSpec->banksPerChannel); else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite) - bufferCounter = new BufferCounterReadWrite(config.requestBufferSize); + bufferCounter = std::make_unique(config.requestBufferSize); else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared) - bufferCounter = new BufferCounterShared(config.requestBufferSize); -} - -SchedulerFifo::~SchedulerFifo() -{ - delete bufferCounter; + bufferCounter = std::make_unique(config.requestBufferSize); } bool SchedulerFifo::hasBufferSpace() const @@ -63,28 +58,28 @@ bool SchedulerFifo::hasBufferSpace() const return bufferCounter->hasBufferSpace(); } -void SchedulerFifo::storeRequest(tlm_generic_payload *payload) +void SchedulerFifo::storeRequest(tlm_generic_payload& payload) { - buffer[DramExtension::getBank(payload).ID()].push_back(payload); + buffer[DramExtension::getBank(payload).ID()].push_back(&payload); bufferCounter->storeRequest(payload); } -void SchedulerFifo::removeRequest(tlm_generic_payload *payload) +void SchedulerFifo::removeRequest(tlm_generic_payload& payload) { buffer[DramExtension::getBank(payload).ID()].pop_front(); bufferCounter->removeRequest(payload); } -tlm_generic_payload *SchedulerFifo::getNextRequest(BankMachine *bankMachine) const +tlm_generic_payload *SchedulerFifo::getNextRequest(const BankMachine& bankMachine) const { - unsigned bankID = bankMachine->getBank().ID(); + unsigned bankID = bankMachine.getBank().ID(); if (!buffer[bankID].empty()) return buffer[bankID].front(); else return nullptr; } -bool SchedulerFifo::hasFurtherRowHit(Bank bank, Row row) const +bool SchedulerFifo::hasFurtherRowHit(Bank bank, Row row, tlm_command command) const { if (buffer[bank.ID()].size() >= 2) { @@ -95,7 +90,7 @@ bool SchedulerFifo::hasFurtherRowHit(Bank bank, Row row) const return false; } -bool SchedulerFifo::hasFurtherRequest(Bank bank) const +bool SchedulerFifo::hasFurtherRequest(Bank bank, tlm_command command) const { if (buffer[bank.ID()].size() >= 2) return true; diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h index b6c6f645..f2cf12a4 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h @@ -37,6 +37,7 @@ #include #include +#include #include #include "SchedulerIF.h" @@ -48,18 +49,17 @@ class SchedulerFifo final : public SchedulerIF { public: SchedulerFifo(); - ~SchedulerFifo() override; bool hasBufferSpace() const override; - void storeRequest(tlm::tlm_generic_payload *) override; - void removeRequest(tlm::tlm_generic_payload *) override; - tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override; - bool hasFurtherRowHit(Bank, Row) const override; - bool hasFurtherRequest(Bank) const override; + void storeRequest(tlm::tlm_generic_payload&) override; + void removeRequest(tlm::tlm_generic_payload&) override; + tlm::tlm_generic_payload *getNextRequest(const BankMachine&) const override; + bool hasFurtherRowHit(Bank, Row, tlm::tlm_command) const override; + bool hasFurtherRequest(Bank, tlm::tlm_command) const override; const std::vector &getBufferDepth() const override; private: std::vector> buffer; - BufferCounterIF *bufferCounter; + std::unique_ptr bufferCounter; }; #endif // SCHEDULERFIFO_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp index 8efe1a73..1a69537f 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp @@ -46,16 +46,11 @@ SchedulerFrFcfs::SchedulerFrFcfs() buffer = std::vector>(config.memSpec->banksPerChannel); if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise) - bufferCounter = new BufferCounterBankwise(config.requestBufferSize, config.memSpec->banksPerChannel); + bufferCounter = std::make_unique(config.requestBufferSize, config.memSpec->banksPerChannel); else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite) - bufferCounter = new BufferCounterReadWrite(config.requestBufferSize); + bufferCounter = std::make_unique(config.requestBufferSize); else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared) - bufferCounter = new BufferCounterShared(config.requestBufferSize); -} - -SchedulerFrFcfs::~SchedulerFrFcfs() -{ - delete bufferCounter; + bufferCounter = std::make_unique(config.requestBufferSize); } bool SchedulerFrFcfs::hasBufferSpace() const @@ -63,19 +58,19 @@ bool SchedulerFrFcfs::hasBufferSpace() const return bufferCounter->hasBufferSpace(); } -void SchedulerFrFcfs::storeRequest(tlm_generic_payload *payload) +void SchedulerFrFcfs::storeRequest(tlm_generic_payload& trans) { - buffer[DramExtension::getBank(payload).ID()].push_back(payload); - bufferCounter->storeRequest(payload); + buffer[DramExtension::getBank(trans).ID()].push_back(&trans); + bufferCounter->storeRequest(trans); } -void SchedulerFrFcfs::removeRequest(tlm_generic_payload *payload) +void SchedulerFrFcfs::removeRequest(tlm_generic_payload& trans) { - bufferCounter->removeRequest(payload); - unsigned bankID = DramExtension::getBank(payload).ID(); + bufferCounter->removeRequest(trans); + unsigned bankID = DramExtension::getBank(trans).ID(); for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++) { - if (*it == payload) + if (*it == &trans) { buffer[bankID].erase(it); break; @@ -83,15 +78,15 @@ void SchedulerFrFcfs::removeRequest(tlm_generic_payload *payload) } } -tlm_generic_payload *SchedulerFrFcfs::getNextRequest(BankMachine *bankMachine) const +tlm_generic_payload *SchedulerFrFcfs::getNextRequest(const BankMachine& bankMachine) const { - unsigned bankID = bankMachine->getBank().ID(); + unsigned bankID = bankMachine.getBank().ID(); if (!buffer[bankID].empty()) { - if (bankMachine->isActivated()) + if (bankMachine.isActivated()) { // Search for row hit - Row openRow = bankMachine->getOpenRow(); + Row openRow = bankMachine.getOpenRow(); for (auto it : buffer[bankID]) { if (DramExtension::getRow(it) == openRow) @@ -104,7 +99,7 @@ tlm_generic_payload *SchedulerFrFcfs::getNextRequest(BankMachine *bankMachine) c return nullptr; } -bool SchedulerFrFcfs::hasFurtherRowHit(Bank bank, Row row) const +bool SchedulerFrFcfs::hasFurtherRowHit(Bank bank, Row row, tlm_command command) const { unsigned rowHitCounter = 0; for (auto it : buffer[bank.ID()]) @@ -119,7 +114,7 @@ bool SchedulerFrFcfs::hasFurtherRowHit(Bank bank, Row row) const return false; } -bool SchedulerFrFcfs::hasFurtherRequest(Bank bank) const +bool SchedulerFrFcfs::hasFurtherRequest(Bank bank, tlm_command command) const { return (buffer[bank.ID()].size() >= 2); } diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h index 0f5bd219..0f907f04 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h @@ -37,6 +37,7 @@ #include #include +#include #include #include "SchedulerIF.h" @@ -48,18 +49,17 @@ class SchedulerFrFcfs final : public SchedulerIF { public: SchedulerFrFcfs(); - ~SchedulerFrFcfs() override; bool hasBufferSpace() const override; - void storeRequest(tlm::tlm_generic_payload *) override; - void removeRequest(tlm::tlm_generic_payload *) override; - tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override; - bool hasFurtherRowHit(Bank, Row) const override; - bool hasFurtherRequest(Bank) const override; + void storeRequest(tlm::tlm_generic_payload&) override; + void removeRequest(tlm::tlm_generic_payload&) override; + tlm::tlm_generic_payload *getNextRequest(const BankMachine&) const override; + bool hasFurtherRowHit(Bank, Row, tlm::tlm_command) const override; + bool hasFurtherRequest(Bank, tlm::tlm_command) const override; const std::vector &getBufferDepth() const override; private: std::vector> buffer; - BufferCounterIF *bufferCounter; + std::unique_ptr bufferCounter; }; #endif // SCHEDULERFRFCFS_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp index ebe46e45..d004aacf 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp @@ -46,16 +46,11 @@ SchedulerFrFcfsGrp::SchedulerFrFcfsGrp() buffer = std::vector>(config.memSpec->banksPerChannel); if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise) - bufferCounter = new BufferCounterBankwise(config.requestBufferSize, config.memSpec->banksPerChannel); + bufferCounter = std::make_unique(config.requestBufferSize, config.memSpec->banksPerChannel); else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite) - bufferCounter = new BufferCounterReadWrite(config.requestBufferSize); + bufferCounter = std::make_unique(config.requestBufferSize); else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared) - bufferCounter = new BufferCounterShared(config.requestBufferSize); -} - -SchedulerFrFcfsGrp::~SchedulerFrFcfsGrp() -{ - delete bufferCounter; + bufferCounter = std::make_unique(config.requestBufferSize); } bool SchedulerFrFcfsGrp::hasBufferSpace() const @@ -63,20 +58,20 @@ bool SchedulerFrFcfsGrp::hasBufferSpace() const return bufferCounter->hasBufferSpace(); } -void SchedulerFrFcfsGrp::storeRequest(tlm_generic_payload *payload) +void SchedulerFrFcfsGrp::storeRequest(tlm_generic_payload& trans) { - buffer[DramExtension::getBank(payload).ID()].push_back(payload); - bufferCounter->storeRequest(payload); + buffer[DramExtension::getBank(trans).ID()].push_back(&trans); + bufferCounter->storeRequest(trans); } -void SchedulerFrFcfsGrp::removeRequest(tlm_generic_payload *payload) +void SchedulerFrFcfsGrp::removeRequest(tlm_generic_payload& trans) { - bufferCounter->removeRequest(payload); - lastCommand = payload->get_command(); - unsigned bankID = DramExtension::getBank(payload).ID(); + bufferCounter->removeRequest(trans); + lastCommand = trans.get_command(); + unsigned bankID = DramExtension::getBank(trans).ID(); for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++) { - if (*it == payload) + if (*it == &trans) { buffer[bankID].erase(it); break; @@ -84,15 +79,15 @@ void SchedulerFrFcfsGrp::removeRequest(tlm_generic_payload *payload) } } -tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine) const +tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(const BankMachine& bankMachine) const { - unsigned bankID = bankMachine->getBank().ID(); + unsigned bankID = bankMachine.getBank().ID(); if (!buffer[bankID].empty()) { - if (bankMachine->isActivated()) + if (bankMachine.isActivated()) { // Filter all row hits - Row openRow = bankMachine->getOpenRow(); + Row openRow = bankMachine.getOpenRow(); std::list rowHits; for (auto it : buffer[bankID]) { @@ -129,7 +124,7 @@ tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine return nullptr; } -bool SchedulerFrFcfsGrp::hasFurtherRowHit(Bank bank, Row row) const +bool SchedulerFrFcfsGrp::hasFurtherRowHit(Bank bank, Row row, tlm_command command) const { unsigned rowHitCounter = 0; for (auto it : buffer[bank.ID()]) @@ -144,7 +139,7 @@ bool SchedulerFrFcfsGrp::hasFurtherRowHit(Bank bank, Row row) const return false; } -bool SchedulerFrFcfsGrp::hasFurtherRequest(Bank bank) const +bool SchedulerFrFcfsGrp::hasFurtherRequest(Bank bank, tlm_command command) const { if (buffer[bank.ID()].size() >= 2) return true; diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h index 7090b9cb..64d8c6ba 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h @@ -37,6 +37,7 @@ #include #include +#include #include #include "SchedulerIF.h" @@ -48,19 +49,18 @@ class SchedulerFrFcfsGrp final : public SchedulerIF { public: SchedulerFrFcfsGrp(); - ~SchedulerFrFcfsGrp() override; bool hasBufferSpace() const override; - void storeRequest(tlm::tlm_generic_payload *) override; - void removeRequest(tlm::tlm_generic_payload *) override; - tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override; - bool hasFurtherRowHit(Bank, Row) const override; - bool hasFurtherRequest(Bank) const override; + void storeRequest(tlm::tlm_generic_payload&) override; + void removeRequest(tlm::tlm_generic_payload&) override; + tlm::tlm_generic_payload *getNextRequest(const BankMachine&) const override; + bool hasFurtherRowHit(Bank, Row, tlm::tlm_command) const override; + bool hasFurtherRequest(Bank, tlm::tlm_command) const override; const std::vector &getBufferDepth() const override; private: std::vector> buffer; tlm::tlm_command lastCommand = tlm::TLM_READ_COMMAND; - BufferCounterIF *bufferCounter; + std::unique_ptr bufferCounter; }; #endif // SCHEDULERFRFCFSGRP_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerGrpFrFcfs.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerGrpFrFcfs.cpp new file mode 100644 index 00000000..d52eb57d --- /dev/null +++ b/DRAMSys/library/src/controller/scheduler/SchedulerGrpFrFcfs.cpp @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2022, 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 "SchedulerGrpFrFcfs.h" +#include "../../configuration/Configuration.h" +#include "BufferCounterBankwise.h" +#include "BufferCounterReadWrite.h" +#include "BufferCounterShared.h" + +using namespace tlm; + +SchedulerGrpFrFcfs::SchedulerGrpFrFcfs() +{ + Configuration &config = Configuration::getInstance(); + readBuffer = std::vector>(config.memSpec->banksPerChannel); + writeBuffer = std::vector>(config.memSpec->banksPerChannel); + + if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise) + bufferCounter = std::make_unique(config.requestBufferSize, config.memSpec->banksPerChannel); + else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite) + bufferCounter = std::make_unique(config.requestBufferSize); + else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared) + bufferCounter = std::make_unique(config.requestBufferSize); +} + +bool SchedulerGrpFrFcfs::hasBufferSpace() const +{ + return bufferCounter->hasBufferSpace(); +} + +void SchedulerGrpFrFcfs::storeRequest(tlm_generic_payload& trans) +{ + if (trans.is_read()) + readBuffer[DramExtension::getBank(trans).ID()].push_back(&trans); + else + writeBuffer[DramExtension::getBank(trans).ID()].push_back(&trans); + bufferCounter->storeRequest(trans); +} + +void SchedulerGrpFrFcfs::removeRequest(tlm_generic_payload& trans) +{ + bufferCounter->removeRequest(trans); + lastCommand = trans.get_command(); + unsigned bankID = DramExtension::getBank(trans).ID(); + + if (trans.is_read()) + readBuffer[bankID].remove(&trans); + else + writeBuffer[bankID].remove(&trans); +} + +tlm_generic_payload *SchedulerGrpFrFcfs::getNextRequest(const BankMachine& bankMachine) const +{ + // search row hits, search wrd/wr hits + // search rd/wr hits, search row hits + unsigned bankID = bankMachine.getBank().ID(); + + if (lastCommand == tlm::TLM_READ_COMMAND) + { + if (!readBuffer[bankID].empty()) + { + if (bankMachine.isActivated()) + { + // Search for read row hit + Row openRow = bankMachine.getOpenRow(); + for (auto it : readBuffer[bankID]) + { + if (DramExtension::getRow(it) == openRow) + return it; + } + } + // No read row hit found or bank precharged + return readBuffer[bankID].front(); + } + else if (!writeBuffer[bankID].empty()) + { + if (bankMachine.isActivated()) + { + // Search for write row hit + Row openRow = bankMachine.getOpenRow(); + for (auto it : writeBuffer[bankID]) + { + if (DramExtension::getRow(it) == openRow) + return it; + } + } + // No write row hit found or bank precharged + return writeBuffer[bankID].front(); + } + else + return nullptr; + } + else + { + if (!writeBuffer[bankID].empty()) + { + if (bankMachine.isActivated()) + { + // Search for write row hit + Row openRow = bankMachine.getOpenRow(); + for (auto it : writeBuffer[bankID]) + { + if (DramExtension::getRow(it) == openRow) + return it; + } + } + // No write row hit found or bank precharged + return writeBuffer[bankID].front(); + } + else if (!readBuffer[bankID].empty()) + { + if (bankMachine.isActivated()) + { + // Search for read row hit + Row openRow = bankMachine.getOpenRow(); + for (auto it : readBuffer[bankID]) + { + if (DramExtension::getRow(it) == openRow) + return it; + } + } + // No read row hit found or bank precharged + return readBuffer[bankID].front(); + } + else + return nullptr; + } +} + +bool SchedulerGrpFrFcfs::hasFurtherRowHit(Bank bank, Row row, tlm_command command) const +{ + // TODO: do this based on current RD/WR mode + unsigned rowHitCounter = 0; + if (command == tlm::TLM_READ_COMMAND) + { + for (auto it : readBuffer[bank.ID()]) + { + if (DramExtension::getRow(it) == row) + { + rowHitCounter++; + if (rowHitCounter == 2) + return true; + } + } + return false; + } + else + { + for (auto it : writeBuffer[bank.ID()]) + { + if (DramExtension::getRow(it) == row) + { + rowHitCounter++; + if (rowHitCounter == 2) + return true; + } + } + return false; + } +} + +bool SchedulerGrpFrFcfs::hasFurtherRequest(Bank bank, tlm_command command) const +{ + if (command == tlm::TLM_READ_COMMAND) + { + if (readBuffer[bank.ID()].size() >= 2) + return true; + else + return false; + } + else + { + if (writeBuffer[bank.ID()].size() >= 2) + return true; + else + return false; + } +} + +const std::vector &SchedulerGrpFrFcfs::getBufferDepth() const +{ + return bufferCounter->getBufferDepth(); +} diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerGrpFrFcfs.h b/DRAMSys/library/src/controller/scheduler/SchedulerGrpFrFcfs.h new file mode 100644 index 00000000..b037f92a --- /dev/null +++ b/DRAMSys/library/src/controller/scheduler/SchedulerGrpFrFcfs.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2022, 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 SCHEDULERGRPFRFCFS_H +#define SCHEDULERGRPFRFCFS_H + +#include +#include +#include + +#include +#include "SchedulerIF.h" +#include "../../common/dramExtensions.h" +#include "../BankMachine.h" +#include "BufferCounterIF.h" + +class SchedulerGrpFrFcfs final : public SchedulerIF +{ +public: + SchedulerGrpFrFcfs(); + bool hasBufferSpace() const override; + void storeRequest(tlm::tlm_generic_payload&) override; + void removeRequest(tlm::tlm_generic_payload&) override; + tlm::tlm_generic_payload *getNextRequest(const BankMachine&) const override; + bool hasFurtherRowHit(Bank, Row, tlm::tlm_command) const override; + bool hasFurtherRequest(Bank, tlm::tlm_command) const override; + const std::vector &getBufferDepth() const override; + +private: + std::vector> readBuffer; + std::vector> writeBuffer; + tlm::tlm_command lastCommand = tlm::TLM_READ_COMMAND; + std::unique_ptr bufferCounter; +}; + +#endif // SCHEDULERGRPFRFCFS_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerGrpFrFcfsWm.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerGrpFrFcfsWm.cpp new file mode 100644 index 00000000..4b3e1eac --- /dev/null +++ b/DRAMSys/library/src/controller/scheduler/SchedulerGrpFrFcfsWm.cpp @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2022, 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 "SchedulerGrpFrFcfsWm.h" +#include "../../configuration/Configuration.h" +#include "BufferCounterBankwise.h" +#include "BufferCounterReadWrite.h" +#include "BufferCounterShared.h" + +using namespace tlm; + +SchedulerGrpFrFcfsWm::SchedulerGrpFrFcfsWm() : lowWatermark(0), highWatermark(0) +{ + Configuration &config = Configuration::getInstance(); + readBuffer = std::vector>(config.memSpec->banksPerChannel); + writeBuffer = std::vector>(config.memSpec->banksPerChannel); + + if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise) + bufferCounter = std::make_unique(config.requestBufferSize, config.memSpec->banksPerChannel); + else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite) + bufferCounter = std::make_unique(config.requestBufferSize); + else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared) + bufferCounter = std::make_unique(config.requestBufferSize); + + lowWatermark = config.lowWatermark; + highWatermark = config.highWatermark; +} + +bool SchedulerGrpFrFcfsWm::hasBufferSpace() const +{ + return bufferCounter->hasBufferSpace(); +} + +void SchedulerGrpFrFcfsWm::storeRequest(tlm_generic_payload& trans) +{ + if (trans.is_read()) + readBuffer[DramExtension::getBank(trans).ID()].push_back(&trans); + else + writeBuffer[DramExtension::getBank(trans).ID()].push_back(&trans); + bufferCounter->storeRequest(trans); + evaluateWriteMode(); +} + +void SchedulerGrpFrFcfsWm::removeRequest(tlm_generic_payload& trans) +{ + bufferCounter->removeRequest(trans); + unsigned bankID = DramExtension::getBank(trans).ID(); + + if (trans.is_read()) + readBuffer[bankID].remove(&trans); + else + writeBuffer[bankID].remove(&trans); + + evaluateWriteMode(); +} + +tlm_generic_payload *SchedulerGrpFrFcfsWm::getNextRequest(const BankMachine& bankMachine) const +{ + unsigned bankID = bankMachine.getBank().ID(); + + if (!writeMode) + { + if (!readBuffer[bankID].empty()) + { + if (bankMachine.isActivated()) + { + // Search for read row hit + Row openRow = bankMachine.getOpenRow(); + for (auto it : readBuffer[bankID]) + { + if (DramExtension::getRow(it) == openRow) + return it; + } + } + // No read row hit found or bank precharged + return readBuffer[bankID].front(); + } + else + return nullptr; + } + else + { + if (!writeBuffer[bankID].empty()) + { + if (bankMachine.isActivated()) + { + // Search for write row hit + Row openRow = bankMachine.getOpenRow(); + for (auto it : writeBuffer[bankID]) + { + if (DramExtension::getRow(it) == openRow) + return it; + } + } + // No row hit found or bank precharged + return writeBuffer[bankID].front(); + } + else + return nullptr; + } +} + +bool SchedulerGrpFrFcfsWm::hasFurtherRowHit(Bank bank, Row row, tlm::tlm_command command) const +{ + unsigned rowHitCounter = 0; + if (!writeMode) + { + for (auto it : readBuffer[bank.ID()]) + { + if (DramExtension::getRow(it) == row) + { + rowHitCounter++; + if (rowHitCounter == 2) + return true; + } + } + return false; + } + else + { + for (auto it : writeBuffer[bank.ID()]) + { + if (DramExtension::getRow(it) == row) + { + rowHitCounter++; + if (rowHitCounter == 2) + return true; + } + } + return false; + } +} + +bool SchedulerGrpFrFcfsWm::hasFurtherRequest(Bank bank, tlm::tlm_command command) const +{ + if (!writeMode) + return (readBuffer[bank.ID()].size() >= 2); + else + return (writeBuffer[bank.ID()].size() >= 2); +} + +const std::vector &SchedulerGrpFrFcfsWm::getBufferDepth() const +{ + return bufferCounter->getBufferDepth(); +} + +void SchedulerGrpFrFcfsWm::evaluateWriteMode() +{ + if (writeMode) + { + if (bufferCounter->getNumWriteRequests() <= lowWatermark && bufferCounter->getNumReadRequests() != 0) + writeMode = false; + } + else + { + if (bufferCounter->getNumWriteRequests() > highWatermark || bufferCounter->getNumReadRequests() == 0) + writeMode = true; + } +} \ No newline at end of file diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerGrpFrFcfsWm.h b/DRAMSys/library/src/controller/scheduler/SchedulerGrpFrFcfsWm.h new file mode 100644 index 00000000..0824066f --- /dev/null +++ b/DRAMSys/library/src/controller/scheduler/SchedulerGrpFrFcfsWm.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2022, 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 SCHEDULERGRPFRFCFSWM_H +#define SCHEDULERGRPFRFCFSWM_H + +#include +#include +#include + +#include +#include "SchedulerIF.h" +#include "../../common/dramExtensions.h" +#include "../BankMachine.h" +#include "BufferCounterIF.h" + +class SchedulerGrpFrFcfsWm final : public SchedulerIF +{ +public: + SchedulerGrpFrFcfsWm(); + bool hasBufferSpace() const override; + void storeRequest(tlm::tlm_generic_payload&) override; + void removeRequest(tlm::tlm_generic_payload&) override; + tlm::tlm_generic_payload *getNextRequest(const BankMachine&) const override; + bool hasFurtherRowHit(Bank, Row, tlm::tlm_command) const override; + bool hasFurtherRequest(Bank, tlm::tlm_command) const override; + const std::vector &getBufferDepth() const override; + +private: + void evaluateWriteMode(); + + std::vector> readBuffer; + std::vector> writeBuffer; + std::unique_ptr bufferCounter; + unsigned lowWatermark; + unsigned highWatermark; + bool writeMode = false; +}; + +#endif // SCHEDULERGRPFRFCFSWM_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerIF.h b/DRAMSys/library/src/controller/scheduler/SchedulerIF.h index a440f8bb..3b45a0db 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerIF.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerIF.h @@ -47,11 +47,11 @@ class SchedulerIF public: 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 void storeRequest(tlm::tlm_generic_payload&) = 0; + virtual void removeRequest(tlm::tlm_generic_payload&) = 0; + virtual tlm::tlm_generic_payload *getNextRequest(const BankMachine&) const = 0; + virtual bool hasFurtherRowHit(Bank, Row, tlm::tlm_command) const = 0; + virtual bool hasFurtherRequest(Bank, tlm::tlm_command) const = 0; virtual const std::vector &getBufferDepth() const = 0; };