Add separate scheduler buffers (bankwise, separate read/write).

This commit is contained in:
Lukas Steiner
2020-10-22 16:41:49 +02:00
parent 27819b4a7b
commit 472c810f89
15 changed files with 392 additions and 90 deletions

View File

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

View File

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

View File

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

View File

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

View File

@@ -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 <vector>
#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<unsigned> requestsOnBank;
unsigned lastBankID;
};
#endif // BUFFERBANKWISE_H

View File

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

View File

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

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

View File

@@ -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<std::deque<tlm_generic_payload *>>
(Configuration::getInstance().memSpec->numberOfBanks);
requestBufferSize = Configuration::getInstance().requestBufferSize;
Configuration &config = Configuration::getInstance();
localBuffer = std::vector<std::deque<tlm_generic_payload *>>(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;

View File

@@ -38,24 +38,26 @@
#include <tlm.h>
#include <vector>
#include <deque>
#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<std::deque<tlm::tlm_generic_payload *>> buffer;
unsigned requestBufferSize;
unsigned lastBankID;
std::vector<std::deque<tlm::tlm_generic_payload *>> localBuffer;
BufferIF *buffer;
};
#endif // SCHEDULERFIFO_H

View File

@@ -33,72 +33,75 @@
*/
#include "SchedulerFrFcfs.h"
#include "../../configuration/Configuration.h"
#include <systemc.h>
#include "BufferBankwise.h"
#include "BufferReadWrite.h"
using namespace tlm;
SchedulerFrFcfs::SchedulerFrFcfs()
{
buffer = std::vector<std::list<tlm_generic_payload *>>
(Configuration::getInstance().memSpec->numberOfBanks);
requestBufferSize = Configuration::getInstance().requestBufferSize;
Configuration &config = Configuration::getInstance();
localBuffer = std::vector<std::list<tlm_generic_payload *>>(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);
}

View File

@@ -38,24 +38,26 @@
#include <tlm.h>
#include <vector>
#include <list>
#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<std::list<tlm::tlm_generic_payload *>> buffer;
unsigned requestBufferSize;
unsigned lastBankID;
std::vector<std::list<tlm::tlm_generic_payload *>> localBuffer;
BufferIF *buffer;
};
#endif // SCHEDULERFRFCFS_H

View File

@@ -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<std::list<tlm_generic_payload *>>
(Configuration::getInstance().memSpec->numberOfBanks);
requestBufferSize = Configuration::getInstance().requestBufferSize;
Configuration &config = Configuration::getInstance();
localBuffer = std::vector<std::list<tlm_generic_payload *>>(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<tlm_generic_payload *> 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;

View File

@@ -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<std::list<tlm::tlm_generic_payload *>> buffer;
unsigned requestBufferSize;
std::vector<std::list<tlm::tlm_generic_payload *>> localBuffer;
tlm::tlm_command lastCommand = tlm::TLM_READ_COMMAND;
unsigned lastBankID;
BufferIF *buffer;
};
#endif // SCHEDULERFRFCFSGRP_H

View File

@@ -36,6 +36,7 @@
#define SCHEDULERIF_H
#include <tlm.h>
#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