Implement first version of arbitration delay and think delay.

This commit is contained in:
Lukas Steiner
2021-01-14 16:48:21 +01:00
parent a6684d95a4
commit abe8ef38b8
11 changed files with 82 additions and 30 deletions

View File

@@ -2,6 +2,7 @@
"mcconfig": {
"PagePolicy": "Open",
"Scheduler": "FrFcfs",
"SchedulerBuffer": "Bankwise",
"RequestBufferSize": 8,
"CmdMux": "Oldest",
"RespQueue": "Fifo",
@@ -9,6 +10,9 @@
"RefreshMaxPostponed": 8,
"RefreshMaxPulledin": 8,
"PowerDownPolicy": "NoPowerDown",
"PowerDownTimeout": 100
"PowerDownTimeout": 100,
"ArbitrationDelay": 0,
"ThinkDelay": 0,
"PhyDelay": 0
}
}

View File

@@ -67,7 +67,8 @@ Controller::Controller(sc_module_name name) :
ControllerIF(name)
{
SC_METHOD(controllerMethod);
sensitive << beginReqEvent << endRespEvent << controllerEvent << dataResponseEvent;
sensitive << beginReqEvent << endRespEvent
<< controllerEvent << dataResponseEvent << thinkDelayEvent;
Configuration &config = Configuration::getInstance();
memSpec = config.memSpec;
@@ -101,11 +102,11 @@ Controller::Controller(sc_module_name name) :
// instantiate scheduler and command mux
if (config.scheduler == Configuration::Scheduler::Fifo)
scheduler = new SchedulerFifo();
scheduler = new SchedulerFifo(thinkDelayEvent);
else if (config.scheduler == Configuration::Scheduler::FrFcfs)
scheduler = new SchedulerFrFcfs();
scheduler = new SchedulerFrFcfs(thinkDelayEvent);
else if (config.scheduler == Configuration::Scheduler::FrFcfsGrp)
scheduler = new SchedulerFrFcfsGrp();
scheduler = new SchedulerFrFcfsGrp(thinkDelayEvent);
if (config.cmdMux == Configuration::CmdMux::Oldest)
cmdMux = new CmdMuxOldest();

View File

@@ -101,7 +101,7 @@ private:
void manageResponses();
void manageRequests();
sc_event beginReqEvent, endRespEvent, controllerEvent, dataResponseEvent;
sc_event beginReqEvent, endRespEvent, controllerEvent, dataResponseEvent, thinkDelayEvent;
};
#endif // CONTROLLER_H

View File

@@ -40,7 +40,8 @@
using namespace tlm;
SchedulerFifo::SchedulerFifo()
SchedulerFifo::SchedulerFifo(sc_event &thinkDelayEvent)
: thinkDelayEvent(thinkDelayEvent)
{
Configuration &config = Configuration::getInstance();
buffer = std::vector<std::deque<tlm_generic_payload *>>(config.memSpec->numberOfBanks);
@@ -65,7 +66,7 @@ bool SchedulerFifo::hasBufferSpace() const
void SchedulerFifo::storeRequest(tlm_generic_payload *payload)
{
buffer[DramExtension::getBank(payload).ID()].push_back(payload);
thinkDelayBuffer.push({payload, sc_time_stamp() + thinkDelay});
bufferCounter->storeRequest(payload);
}
@@ -75,8 +76,18 @@ void SchedulerFifo::removeRequest(tlm_generic_payload *payload)
bufferCounter->removeRequest(payload);
}
tlm_generic_payload *SchedulerFifo::getNextRequest(BankMachine *bankMachine) const
tlm_generic_payload *SchedulerFifo::getNextRequest(BankMachine *bankMachine)
{
while ((!thinkDelayBuffer.empty()) && (thinkDelayBuffer.front().second <= sc_time_stamp()))
{
tlm_generic_payload *payload = thinkDelayBuffer.front().first;
buffer[DramExtension::getBank(payload).ID()].push_back(payload);
thinkDelayBuffer.pop();
}
if (!thinkDelayBuffer.empty())
thinkDelayEvent.notify(thinkDelayBuffer.front().second - sc_time_stamp());
unsigned bankID = bankMachine->getBank().ID();
if (!buffer[bankID].empty())
return buffer[bankID].front();
@@ -97,10 +108,7 @@ bool SchedulerFifo::hasFurtherRowHit(Bank bank, Row row) const
bool SchedulerFifo::hasFurtherRequest(Bank bank) const
{
if (buffer[bank.ID()].size() >= 2)
return true;
else
return false;
return (buffer[bank.ID()].size() >= 2);
}
const std::vector<unsigned> &SchedulerFifo::getBufferDepth() const

View File

@@ -38,6 +38,8 @@
#include <tlm.h>
#include <vector>
#include <deque>
#include <queue>
#include <utility>
#include "SchedulerIF.h"
#include "../../common/dramExtensions.h"
@@ -47,18 +49,21 @@
class SchedulerFifo final : public SchedulerIF
{
public:
SchedulerFifo();
SchedulerFifo(sc_event &);
virtual ~SchedulerFifo() override;
virtual bool hasBufferSpace() const override;
virtual void storeRequest(tlm::tlm_generic_payload *) override;
virtual void removeRequest(tlm::tlm_generic_payload *) override;
virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override;
virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) override;
virtual bool hasFurtherRowHit(Bank, Row) const override;
virtual bool hasFurtherRequest(Bank) const override;
virtual const std::vector<unsigned> &getBufferDepth() const override;
private:
std::vector<std::deque<tlm::tlm_generic_payload *>> buffer;
std::queue<std::pair<tlm::tlm_generic_payload *, sc_time>> thinkDelayBuffer;
sc_time thinkDelay;
sc_event &thinkDelayEvent;
BufferCounterIF *bufferCounter;
};

View File

@@ -40,10 +40,12 @@
using namespace tlm;
SchedulerFrFcfs::SchedulerFrFcfs()
SchedulerFrFcfs::SchedulerFrFcfs(sc_event &thinkDelayEvent)
: thinkDelayEvent(thinkDelayEvent)
{
Configuration &config = Configuration::getInstance();
buffer = std::vector<std::list<tlm_generic_payload *>>(config.memSpec->numberOfBanks);
thinkDelay = config.thinkDelay;
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
bufferCounter = new BufferCounterBankwise(config.requestBufferSize, config.memSpec->numberOfBanks);
@@ -65,7 +67,7 @@ bool SchedulerFrFcfs::hasBufferSpace() const
void SchedulerFrFcfs::storeRequest(tlm_generic_payload *payload)
{
buffer[DramExtension::getBank(payload).ID()].push_back(payload);
thinkDelayBuffer.push({payload, sc_time_stamp() + thinkDelay});
bufferCounter->storeRequest(payload);
}
@@ -83,8 +85,18 @@ void SchedulerFrFcfs::removeRequest(tlm_generic_payload *payload)
}
}
tlm_generic_payload *SchedulerFrFcfs::getNextRequest(BankMachine *bankMachine) const
tlm_generic_payload *SchedulerFrFcfs::getNextRequest(BankMachine *bankMachine)
{
while ((!thinkDelayBuffer.empty()) && (thinkDelayBuffer.front().second <= sc_time_stamp()))
{
tlm_generic_payload *payload = thinkDelayBuffer.front().first;
buffer[DramExtension::getBank(payload).ID()].push_back(payload);
thinkDelayBuffer.pop();
}
if (!thinkDelayBuffer.empty())
thinkDelayEvent.notify(thinkDelayBuffer.front().second - sc_time_stamp());
unsigned bankID = bankMachine->getBank().ID();
if (!buffer[bankID].empty())
{

View File

@@ -38,6 +38,8 @@
#include <tlm.h>
#include <vector>
#include <list>
#include <queue>
#include <utility>
#include "SchedulerIF.h"
#include "../../common/dramExtensions.h"
@@ -47,18 +49,21 @@
class SchedulerFrFcfs final : public SchedulerIF
{
public:
SchedulerFrFcfs();
SchedulerFrFcfs(sc_event &);
virtual ~SchedulerFrFcfs() override;
virtual bool hasBufferSpace() const override;
virtual void storeRequest(tlm::tlm_generic_payload *) override;
virtual void removeRequest(tlm::tlm_generic_payload *) override;
virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override;
virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) override;
virtual bool hasFurtherRowHit(Bank, Row) const override;
virtual bool hasFurtherRequest(Bank) const override;
virtual const std::vector<unsigned> &getBufferDepth() const override;
private:
std::vector<std::list<tlm::tlm_generic_payload *>> buffer;
std::queue<std::pair<tlm::tlm_generic_payload *, sc_time>> thinkDelayBuffer;
sc_time thinkDelay;
sc_event &thinkDelayEvent;
BufferCounterIF *bufferCounter;
};

View File

@@ -40,10 +40,12 @@
using namespace tlm;
SchedulerFrFcfsGrp::SchedulerFrFcfsGrp()
SchedulerFrFcfsGrp::SchedulerFrFcfsGrp(sc_event &thinkDelayEvent)
: thinkDelayEvent(thinkDelayEvent)
{
Configuration &config = Configuration::getInstance();
buffer = std::vector<std::list<tlm_generic_payload *>>(config.memSpec->numberOfBanks);
thinkDelay = config.thinkDelay;
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
bufferCounter = new BufferCounterBankwise(config.requestBufferSize, config.memSpec->numberOfBanks);
@@ -65,7 +67,7 @@ bool SchedulerFrFcfsGrp::hasBufferSpace() const
void SchedulerFrFcfsGrp::storeRequest(tlm_generic_payload *payload)
{
buffer[DramExtension::getBank(payload).ID()].push_back(payload);
thinkDelayBuffer.push({payload, sc_time_stamp() + thinkDelay});
bufferCounter->storeRequest(payload);
}
@@ -84,8 +86,18 @@ void SchedulerFrFcfsGrp::removeRequest(tlm_generic_payload *payload)
}
}
tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine) const
tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine)
{
while ((!thinkDelayBuffer.empty()) && (thinkDelayBuffer.front().second <= sc_time_stamp()))
{
tlm_generic_payload *payload = thinkDelayBuffer.front().first;
buffer[DramExtension::getBank(payload).ID()].push_back(payload);
thinkDelayBuffer.pop();
}
if (!thinkDelayBuffer.empty())
thinkDelayEvent.notify(thinkDelayBuffer.front().second - sc_time_stamp());
unsigned bankID = bankMachine->getBank().ID();
if (!buffer[bankID].empty())
{

View File

@@ -38,6 +38,8 @@
#include <tlm.h>
#include <vector>
#include <list>
#include <queue>
#include <utility>
#include "SchedulerIF.h"
#include "../../common/dramExtensions.h"
@@ -47,18 +49,21 @@
class SchedulerFrFcfsGrp final : public SchedulerIF
{
public:
SchedulerFrFcfsGrp();
SchedulerFrFcfsGrp(sc_event &);
virtual ~SchedulerFrFcfsGrp() override;
virtual bool hasBufferSpace() const override;
virtual void storeRequest(tlm::tlm_generic_payload *) override;
virtual void removeRequest(tlm::tlm_generic_payload *) override;
virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override;
virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) override;
virtual bool hasFurtherRowHit(Bank, Row) const override;
virtual bool hasFurtherRequest(Bank) const override;
virtual const std::vector<unsigned> &getBufferDepth() const override;
private:
std::vector<std::list<tlm::tlm_generic_payload *>> buffer;
std::queue<std::pair<tlm::tlm_generic_payload *, sc_time>> thinkDelayBuffer;
sc_time thinkDelay;
sc_event &thinkDelayEvent;
tlm::tlm_command lastCommand = tlm::TLM_READ_COMMAND;
BufferCounterIF *bufferCounter;
};

View File

@@ -49,7 +49,7 @@ public:
virtual bool hasBufferSpace() const = 0;
virtual void storeRequest(tlm::tlm_generic_payload *) = 0;
virtual void removeRequest(tlm::tlm_generic_payload *) = 0;
virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const = 0;
virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) = 0;
virtual bool hasFurtherRowHit(Bank, Row) const = 0;
virtual bool hasFurtherRequest(Bank) const = 0;
virtual const std::vector<unsigned> &getBufferDepth() const = 0;

View File

@@ -178,7 +178,7 @@ void ArbiterSimple::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase
channelIsBusy[channelId] = true;
tlm_phase tPhase = BEGIN_REQ;
sc_time tDelay = SC_ZERO_TIME;
sc_time tDelay = arbitrationDelay;
iSocket[static_cast<int>(channelId)]->nb_transport_fw(cbPayload, tPhase, tDelay);
}
else
@@ -198,7 +198,7 @@ void ArbiterSimple::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase
pendingRequests[channelId].pop();
tlm_phase tPhase = BEGIN_REQ;
// do not send two requests in the same cycle
sc_time tDelay = tCK;
sc_time tDelay = tCK + arbitrationDelay;
iSocket[static_cast<int>(channelId)]->nb_transport_fw(tPayload, tPhase, tDelay);
}
else
@@ -209,7 +209,7 @@ void ArbiterSimple::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase
if (!threadIsBusy[threadId])
{
tlm_phase tPhase = BEGIN_RESP;
sc_time tDelay = SC_ZERO_TIME;
sc_time tDelay = arbitrationDelay;
tlm_sync_enum returnValue = tSocket[static_cast<int>(threadId)]->nb_transport_bw(cbPayload, tPhase, tDelay);
if (returnValue == TLM_UPDATED)
payloadEventQueue.notify(cbPayload, tPhase, tDelay);
@@ -233,7 +233,7 @@ void ArbiterSimple::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase
pendingResponses[threadId].pop();
tlm_phase tPhase = BEGIN_RESP;
// do not send two responses in the same cycle
sc_time tDelay = tCK;
sc_time tDelay = tCK + arbitrationDelay;
tlm_sync_enum returnValue = tSocket[static_cast<int>(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay);
if (returnValue == TLM_UPDATED)
payloadEventQueue.notify(tPayload, tPhase, tDelay);