diff --git a/DRAMSys/library/CMakeLists.txt b/DRAMSys/library/CMakeLists.txt index 5634ba6d..d88637a8 100644 --- a/DRAMSys/library/CMakeLists.txt +++ b/DRAMSys/library/CMakeLists.txt @@ -135,6 +135,10 @@ add_library(DRAMSysLibrary src/controller/scheduler/SchedulerFifo.cpp src/controller/scheduler/SchedulerFrFcfs.cpp src/controller/scheduler/SchedulerFrFcfsGrp.cpp + + src/controller/scheduler/BufferIF.h + src/controller/scheduler/BufferBankwise.cpp + src/controller/scheduler/BufferReadWrite.cpp src/error/eccbaseclass.cpp src/error/ecchamming.cpp diff --git a/DRAMSys/library/src/configuration/Configuration.cpp b/DRAMSys/library/src/configuration/Configuration.cpp index 4a0b9645..144d2899 100644 --- a/DRAMSys/library/src/configuration/Configuration.cpp +++ b/DRAMSys/library/src/configuration/Configuration.cpp @@ -84,6 +84,8 @@ void Configuration::setParameter(std::string name, nlohmann::json value) pagePolicy = value; else if (name == "Scheduler") scheduler = value; + else if (name == "SchedulerBuffer") + schedulerBuffer = value; else if (name == "RequestBufferSize") requestBufferSize = value; else if (name == "CmdMux") diff --git a/DRAMSys/library/src/configuration/Configuration.h b/DRAMSys/library/src/configuration/Configuration.h index 75176ae5..fa18b382 100644 --- a/DRAMSys/library/src/configuration/Configuration.h +++ b/DRAMSys/library/src/configuration/Configuration.h @@ -71,6 +71,7 @@ public: // MCConfig: std::string pagePolicy = "Open"; std::string scheduler = "Fifo"; + std::string schedulerBuffer = "Bankwise"; std::string cmdMux = "Oldest"; std::string respQueue = "Fifo"; unsigned int requestBufferSize = 8; diff --git a/DRAMSys/library/src/controller/scheduler/BufferBankwise.cpp b/DRAMSys/library/src/controller/scheduler/BufferBankwise.cpp new file mode 100644 index 00000000..d73a3a58 --- /dev/null +++ b/DRAMSys/library/src/controller/scheduler/BufferBankwise.cpp @@ -0,0 +1,58 @@ +/* + * 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 "BufferBankwise.h" +#include "../../common/dramExtensions.h" + +BufferBankwise::BufferBankwise(unsigned requestBufferSize, unsigned numberOfBanks) + : requestBufferSize(requestBufferSize) +{ + requestsOnBank = std::vector(numberOfBanks, 0); +} + +bool BufferBankwise::hasBufferSpace() const +{ + return (requestsOnBank[lastBankID] < requestBufferSize); +} + +void BufferBankwise::storeRequest(tlm::tlm_generic_payload *payload) +{ + lastBankID = DramExtension::getBank(payload).ID(); + requestsOnBank[lastBankID]++; +} + +void BufferBankwise::removeRequest(tlm::tlm_generic_payload *payload) +{ + requestsOnBank[DramExtension::getBank(payload).ID()]--; +} diff --git a/DRAMSys/library/src/controller/scheduler/BufferBankwise.h b/DRAMSys/library/src/controller/scheduler/BufferBankwise.h new file mode 100644 index 00000000..3fd63490 --- /dev/null +++ b/DRAMSys/library/src/controller/scheduler/BufferBankwise.h @@ -0,0 +1,56 @@ +/* + * 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 BUFFERBANKWISE_H +#define BUFFERBANKWISE_H + +#include + +#include "BufferIF.h" + +class BufferBankwise : public BufferIF +{ +public: + BufferBankwise(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; + +private: + const unsigned requestBufferSize; + std::vector requestsOnBank; + unsigned lastBankID; +}; + +#endif // BUFFERBANKWISE_H diff --git a/DRAMSys/library/src/controller/scheduler/BufferIF.h b/DRAMSys/library/src/controller/scheduler/BufferIF.h new file mode 100644 index 00000000..6c8349ae --- /dev/null +++ b/DRAMSys/library/src/controller/scheduler/BufferIF.h @@ -0,0 +1,48 @@ +/* + * 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 BUFFERIF_H +#define BUFFERIF_H + +#include + +class BufferIF +{ +public: + virtual bool hasBufferSpace() const = 0; + virtual void storeRequest(tlm::tlm_generic_payload *payload) = 0; + virtual void removeRequest(tlm::tlm_generic_payload *payload) = 0; +}; + +#endif // BUFFERIF_H diff --git a/DRAMSys/library/src/controller/scheduler/BufferReadWrite.cpp b/DRAMSys/library/src/controller/scheduler/BufferReadWrite.cpp new file mode 100644 index 00000000..62fdf772 --- /dev/null +++ b/DRAMSys/library/src/controller/scheduler/BufferReadWrite.cpp @@ -0,0 +1,59 @@ +/* + * 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 "BufferReadWrite.h" + +BufferReadWrite::BufferReadWrite(unsigned requestBufferSize) + : requestBufferSize(requestBufferSize) {} + +bool BufferReadWrite::hasBufferSpace() const +{ + return (numberOfReads < requestBufferSize && numberOfWrites < requestBufferSize); +} + +void BufferReadWrite::storeRequest(tlm::tlm_generic_payload *payload) +{ + if (payload->is_read()) + numberOfReads++; + else + numberOfWrites++; +} + +void BufferReadWrite::removeRequest(tlm::tlm_generic_payload *payload) +{ + if (payload->is_read()) + numberOfReads--; + else + numberOfWrites--; +} diff --git a/DRAMSys/library/src/controller/scheduler/BufferReadWrite.h b/DRAMSys/library/src/controller/scheduler/BufferReadWrite.h new file mode 100644 index 00000000..32835c74 --- /dev/null +++ b/DRAMSys/library/src/controller/scheduler/BufferReadWrite.h @@ -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 BUFFERREADWRITE_H +#define BUFFERREADWRITE_H + +#include "BufferIF.h" + +class BufferReadWrite : public BufferIF +{ +public: + BufferReadWrite(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; + +private: + const unsigned requestBufferSize; + unsigned numberOfReads = 0; + unsigned numberOfWrites = 0; +}; + +#endif // BUFFERREADWRITE_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp index f90c1c95..7b81977b 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp @@ -34,58 +34,64 @@ #include "SchedulerFifo.h" #include "../../configuration/Configuration.h" +#include "BufferBankwise.h" +#include "BufferReadWrite.h" using namespace tlm; SchedulerFifo::SchedulerFifo() { - buffer = std::vector> - (Configuration::getInstance().memSpec->numberOfBanks); - requestBufferSize = Configuration::getInstance().requestBufferSize; + Configuration &config = Configuration::getInstance(); + localBuffer = std::vector>(config.memSpec->numberOfBanks); + + if (config.schedulerBuffer == "Bankwise") + buffer = new BufferBankwise(config.requestBufferSize, config.memSpec->numberOfBanks); + else if (Configuration::getInstance().schedulerBuffer == "ReadWrite") + buffer = new BufferReadWrite(config.requestBufferSize); + else + SC_REPORT_FATAL("Scheduler", "Unsupported scheduler buffer!"); } -bool SchedulerFifo::hasBufferSpace() +bool SchedulerFifo::hasBufferSpace() const { - if (buffer[lastBankID].size() < requestBufferSize) - return true; - else - return false; + return buffer->hasBufferSpace(); } void SchedulerFifo::storeRequest(tlm_generic_payload *payload) { - lastBankID = DramExtension::getBank(payload).ID(); - buffer[lastBankID].push_back(payload); + localBuffer[DramExtension::getBank(payload).ID()].push_back(payload); + buffer->storeRequest(payload); } void SchedulerFifo::removeRequest(tlm_generic_payload *payload) { - buffer[DramExtension::getBank(payload).ID()].pop_front(); + localBuffer[DramExtension::getBank(payload).ID()].pop_front(); + buffer->removeRequest(payload); } -tlm_generic_payload *SchedulerFifo::getNextRequest(BankMachine *bankMachine) +tlm_generic_payload *SchedulerFifo::getNextRequest(BankMachine *bankMachine) const { unsigned bankID = bankMachine->getBank().ID(); - if (!buffer[bankID].empty()) - return buffer[bankID].front(); + if (!localBuffer[bankID].empty()) + return localBuffer[bankID].front(); else return nullptr; } -bool SchedulerFifo::hasFurtherRowHit(Bank bank, Row row) +bool SchedulerFifo::hasFurtherRowHit(Bank bank, Row row) const { - if (buffer[bank.ID()].size() >= 2) + if (localBuffer[bank.ID()].size() >= 2) { - tlm_generic_payload *nextRequest = buffer[bank.ID()][1]; + tlm_generic_payload *nextRequest = localBuffer[bank.ID()][1]; if (DramExtension::getRow(nextRequest) == row) return true; } return false; } -bool SchedulerFifo::hasFurtherRequest(Bank bank) +bool SchedulerFifo::hasFurtherRequest(Bank bank) const { - if (buffer[bank.ID()].size() >= 2) + if (localBuffer[bank.ID()].size() >= 2) return true; else return false; diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h index aacbb1e8..c34a095a 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h @@ -38,24 +38,26 @@ #include #include #include + #include "SchedulerIF.h" #include "../../common/dramExtensions.h" #include "../BankMachine.h" +#include "BufferIF.h" class SchedulerFifo : public SchedulerIF { public: SchedulerFifo(); - virtual bool hasBufferSpace() 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 *) override; - virtual bool hasFurtherRowHit(Bank, Row) override; - virtual bool hasFurtherRequest(Bank) override; + virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override; + virtual bool hasFurtherRowHit(Bank, Row) const override; + virtual bool hasFurtherRequest(Bank) const override; + private: - std::vector> buffer; - unsigned requestBufferSize; - unsigned lastBankID; + std::vector> localBuffer; + BufferIF *buffer; }; #endif // SCHEDULERFIFO_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp index de91e8b4..e3b11ff0 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp @@ -33,72 +33,75 @@ */ #include "SchedulerFrFcfs.h" - #include "../../configuration/Configuration.h" -#include +#include "BufferBankwise.h" +#include "BufferReadWrite.h" using namespace tlm; SchedulerFrFcfs::SchedulerFrFcfs() { - buffer = std::vector> - (Configuration::getInstance().memSpec->numberOfBanks); - requestBufferSize = Configuration::getInstance().requestBufferSize; + Configuration &config = Configuration::getInstance(); + localBuffer = std::vector>(config.memSpec->numberOfBanks); + + if (config.schedulerBuffer == "Bankwise") + buffer = new BufferBankwise(config.requestBufferSize, config.memSpec->numberOfBanks); + else if (Configuration::getInstance().schedulerBuffer == "ReadWrite") + buffer = new BufferReadWrite(config.requestBufferSize); + else + SC_REPORT_FATAL("Scheduler", "Unsupported scheduler buffer!"); } -bool SchedulerFrFcfs::hasBufferSpace() +bool SchedulerFrFcfs::hasBufferSpace() const { - if (buffer[lastBankID].size() < requestBufferSize) - return true; - else - return false; + return buffer->hasBufferSpace(); } void SchedulerFrFcfs::storeRequest(tlm_generic_payload *payload) { - lastBankID = DramExtension::getBank(payload).ID(); - buffer[lastBankID].push_back(payload); + localBuffer[DramExtension::getBank(payload).ID()].push_back(payload); + buffer->storeRequest(payload); } void SchedulerFrFcfs::removeRequest(tlm_generic_payload *payload) { + buffer->removeRequest(payload); unsigned bankID = DramExtension::getBank(payload).ID(); - for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++) + for (auto it = localBuffer[bankID].begin(); it != localBuffer[bankID].end(); it++) { if (*it == payload) { - buffer[bankID].erase(it); - return; + localBuffer[bankID].erase(it); + break; } } - SC_REPORT_FATAL("SchedulerFrFcfs", "removeRequest failed!"); } -tlm_generic_payload *SchedulerFrFcfs::getNextRequest(BankMachine *bankMachine) +tlm_generic_payload *SchedulerFrFcfs::getNextRequest(BankMachine *bankMachine) const { unsigned bankID = bankMachine->getBank().ID(); - if (!buffer[bankID].empty()) + if (!localBuffer[bankID].empty()) { if (bankMachine->getState() == BmState::Activated) { // Search for row hit Row openRow = bankMachine->getOpenRow(); - for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++) + for (auto it = localBuffer[bankID].begin(); it != localBuffer[bankID].end(); it++) { if (DramExtension::getRow(*it) == openRow) return *it; } } // No row hit found or bank precharged - return buffer[bankID].front(); + return localBuffer[bankID].front(); } return nullptr; } -bool SchedulerFrFcfs::hasFurtherRowHit(Bank bank, Row row) +bool SchedulerFrFcfs::hasFurtherRowHit(Bank bank, Row row) const { unsigned rowHitCounter = 0; - for (auto it = buffer[bank.ID()].begin(); it != buffer[bank.ID()].end(); it++) + for (auto it = localBuffer[bank.ID()].begin(); it != localBuffer[bank.ID()].end(); it++) { if (DramExtension::getRow(*it) == row) { @@ -110,7 +113,7 @@ bool SchedulerFrFcfs::hasFurtherRowHit(Bank bank, Row row) return false; } -bool SchedulerFrFcfs::hasFurtherRequest(Bank bank) +bool SchedulerFrFcfs::hasFurtherRequest(Bank bank) const { - return (buffer[bank.ID()].size() >= 2); + return (localBuffer[bank.ID()].size() >= 2); } diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h index 5d5347a4..d8413b2a 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h @@ -38,24 +38,26 @@ #include #include #include + #include "SchedulerIF.h" #include "../../common/dramExtensions.h" #include "../BankMachine.h" +#include "BufferIF.h" class SchedulerFrFcfs : public SchedulerIF { public: SchedulerFrFcfs(); - virtual bool hasBufferSpace() 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 *) override; - virtual bool hasFurtherRowHit(Bank, Row) override; - virtual bool hasFurtherRequest(Bank) override; + virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override; + virtual bool hasFurtherRowHit(Bank, Row) const override; + virtual bool hasFurtherRequest(Bank) const override; + private: - std::vector> buffer; - unsigned requestBufferSize; - unsigned lastBankID; + std::vector> localBuffer; + BufferIF *buffer; }; #endif // SCHEDULERFRFCFS_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp index 8af96e96..cebaf7fe 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp @@ -34,56 +34,61 @@ #include "SchedulerFrFcfsGrp.h" #include "../../configuration/Configuration.h" +#include "BufferBankwise.h" +#include "BufferReadWrite.h" using namespace tlm; SchedulerFrFcfsGrp::SchedulerFrFcfsGrp() { - buffer = std::vector> - (Configuration::getInstance().memSpec->numberOfBanks); - requestBufferSize = Configuration::getInstance().requestBufferSize; + Configuration &config = Configuration::getInstance(); + localBuffer = std::vector>(config.memSpec->numberOfBanks); + + if (config.schedulerBuffer == "Bankwise") + buffer = new BufferBankwise(config.requestBufferSize, config.memSpec->numberOfBanks); + else if (Configuration::getInstance().schedulerBuffer == "ReadWrite") + buffer = new BufferReadWrite(config.requestBufferSize); + else + SC_REPORT_FATAL("Scheduler", "Unsupported scheduler buffer!"); } -bool SchedulerFrFcfsGrp::hasBufferSpace() +bool SchedulerFrFcfsGrp::hasBufferSpace() const { - if (buffer[lastBankID].size() < requestBufferSize) - return true; - else - return false; + return buffer->hasBufferSpace(); } void SchedulerFrFcfsGrp::storeRequest(tlm_generic_payload *payload) { - lastBankID = DramExtension::getBank(payload).ID(); - buffer[lastBankID].push_back(payload); + localBuffer[DramExtension::getBank(payload).ID()].push_back(payload); + buffer->storeRequest(payload); } void SchedulerFrFcfsGrp::removeRequest(tlm_generic_payload *payload) { + buffer->removeRequest(payload); lastCommand = payload->get_command(); unsigned bankID = DramExtension::getBank(payload).ID(); - for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++) + for (auto it = localBuffer[bankID].begin(); it != localBuffer[bankID].end(); it++) { if (*it == payload) { - buffer[bankID].erase(it); - return; + localBuffer[bankID].erase(it); + break; } } - SC_REPORT_FATAL("SchedulerFrFcfs", "removeRequest failed!"); } -tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine) +tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine) const { unsigned bankID = bankMachine->getBank().ID(); - if (!buffer[bankID].empty()) + if (!localBuffer[bankID].empty()) { if (bankMachine->getState() == BmState::Activated) { // Filter all row hits Row openRow = bankMachine->getOpenRow(); std::list rowHits; - for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++) + for (auto it = localBuffer[bankID].begin(); it != localBuffer[bankID].end(); it++) { if (DramExtension::getRow(*it) == openRow) rowHits.push_back(*it); @@ -113,15 +118,15 @@ tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine } } // No row hit found or bank precharged - return buffer[bankID].front(); + return localBuffer[bankID].front(); } return nullptr; } -bool SchedulerFrFcfsGrp::hasFurtherRowHit(Bank bank, Row row) +bool SchedulerFrFcfsGrp::hasFurtherRowHit(Bank bank, Row row) const { unsigned rowHitCounter = 0; - for (auto it = buffer[bank.ID()].begin(); it != buffer[bank.ID()].end(); it++) + for (auto it = localBuffer[bank.ID()].begin(); it != localBuffer[bank.ID()].end(); it++) { if (DramExtension::getRow(*it) == row) { @@ -133,9 +138,9 @@ bool SchedulerFrFcfsGrp::hasFurtherRowHit(Bank bank, Row row) return false; } -bool SchedulerFrFcfsGrp::hasFurtherRequest(Bank bank) +bool SchedulerFrFcfsGrp::hasFurtherRequest(Bank bank) const { - if (buffer[bank.ID()].size() >= 2) + if (localBuffer[bank.ID()].size() >= 2) return true; else return false; diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h index 34ca4472..af2e6ad4 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h @@ -42,22 +42,23 @@ #include "SchedulerIF.h" #include "../../common/dramExtensions.h" #include "../BankMachine.h" +#include "BufferIF.h" class SchedulerFrFcfsGrp : public SchedulerIF { public: SchedulerFrFcfsGrp(); - virtual bool hasBufferSpace() 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 *) override; - virtual bool hasFurtherRowHit(Bank, Row) override; - virtual bool hasFurtherRequest(Bank) override; + virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override; + virtual bool hasFurtherRowHit(Bank, Row) const override; + virtual bool hasFurtherRequest(Bank) const override; + private: - std::vector> buffer; - unsigned requestBufferSize; + std::vector> localBuffer; tlm::tlm_command lastCommand = tlm::TLM_READ_COMMAND; - unsigned lastBankID; + BufferIF *buffer; }; #endif // SCHEDULERFRFCFSGRP_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerIF.h b/DRAMSys/library/src/controller/scheduler/SchedulerIF.h index c069a5cb..f82ea208 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerIF.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerIF.h @@ -36,6 +36,7 @@ #define SCHEDULERIF_H #include + #include "../../common/dramExtensions.h" #include "../../common/DebugManager.h" @@ -46,12 +47,12 @@ class SchedulerIF { public: virtual ~SchedulerIF() {} - virtual bool hasBufferSpace() = 0; + 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 *) = 0; - virtual bool hasFurtherRowHit(Bank, Row) = 0; - virtual bool hasFurtherRequest(Bank) = 0; + virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const = 0; + virtual bool hasFurtherRowHit(Bank, Row) const = 0; + virtual bool hasFurtherRequest(Bank) const = 0; }; #endif // SCHEDULERIF_H