Bank machines now consider lately-arriving requests.
This commit is contained in:
@@ -122,12 +122,9 @@ sc_time BankMachineOpen::start()
|
||||
if (sleeping)
|
||||
return timeToSchedule;
|
||||
|
||||
currentPayload = scheduler->getNextRequest(this);
|
||||
if (currentPayload == nullptr)
|
||||
{
|
||||
currentPayload = scheduler->getNextRequest(this);
|
||||
if (currentPayload == nullptr)
|
||||
return timeToSchedule;
|
||||
}
|
||||
return timeToSchedule;
|
||||
|
||||
if (currentState == BmState::Precharged && !blocked) // row miss
|
||||
{
|
||||
@@ -170,12 +167,9 @@ sc_time BankMachineClosed::start()
|
||||
if (sleeping)
|
||||
return timeToSchedule;
|
||||
|
||||
currentPayload = scheduler->getNextRequest(this);
|
||||
if (currentPayload == nullptr)
|
||||
{
|
||||
currentPayload = scheduler->getNextRequest(this);
|
||||
if (currentPayload == nullptr)
|
||||
return timeToSchedule;
|
||||
}
|
||||
return timeToSchedule;
|
||||
|
||||
if (currentState == BmState::Precharged && !blocked) // row miss
|
||||
{
|
||||
@@ -210,12 +204,9 @@ sc_time BankMachineOpenAdaptive::start()
|
||||
if (sleeping)
|
||||
return timeToSchedule;
|
||||
|
||||
currentPayload = scheduler->getNextRequest(this);
|
||||
if (currentPayload == nullptr)
|
||||
{
|
||||
currentPayload = scheduler->getNextRequest(this);
|
||||
if (currentPayload == nullptr)
|
||||
return timeToSchedule;
|
||||
}
|
||||
return timeToSchedule;
|
||||
|
||||
if (currentState == BmState::Precharged && !blocked) // row miss
|
||||
{
|
||||
@@ -276,12 +267,9 @@ sc_time BankMachineClosedAdaptive::start()
|
||||
if (sleeping)
|
||||
return timeToSchedule;
|
||||
|
||||
currentPayload = scheduler->getNextRequest(this);
|
||||
if (currentPayload == nullptr)
|
||||
{
|
||||
currentPayload = scheduler->getNextRequest(this);
|
||||
if (currentPayload == nullptr)
|
||||
return timeToSchedule;
|
||||
}
|
||||
return timeToSchedule;
|
||||
|
||||
if (currentState == BmState::Precharged && !blocked) // row miss
|
||||
{
|
||||
|
||||
@@ -66,7 +66,7 @@ Controller::Controller(sc_module_name name) :
|
||||
dont_initialize();
|
||||
|
||||
Configuration &config = Configuration::getInstance();
|
||||
MemSpec *memSpec = config.memSpec;
|
||||
memSpec = config.memSpec;
|
||||
ranksNumberOfPayloads = std::vector<unsigned>(memSpec->NumberOfRanks);
|
||||
|
||||
// instantiate timing checker
|
||||
@@ -257,7 +257,7 @@ void Controller::controllerMethod()
|
||||
std::pair<Command, tlm_generic_payload *> commandPair;
|
||||
std::vector<std::pair<Command, tlm_generic_payload *>> readyCommands;
|
||||
// (5.1) Check for power-down commands (PDEA/PDEP/SREFEN or PDXA/PDXP/SREFEX)
|
||||
for (unsigned rankID = 0; rankID < Configuration::getInstance().memSpec->NumberOfRanks; rankID++)
|
||||
for (unsigned rankID = 0; rankID < memSpec->NumberOfRanks; rankID++)
|
||||
{
|
||||
commandPair = powerDownManagers[rankID]->getNextCommand();
|
||||
if (commandPair.second != nullptr)
|
||||
@@ -303,6 +303,23 @@ void Controller::controllerMethod()
|
||||
powerDownManagers[rank.ID()]->updateState(commandPair.first);
|
||||
checker->insert(commandPair.first, rank, bankgroup, bank);
|
||||
|
||||
if (isCasCommand(commandPair.first))
|
||||
{
|
||||
scheduler->removeRequest(commandPair.second);
|
||||
respQueue->insertPayload(commandPair.second, memSpec->getIntervalOnDataStrobe(commandPair.first).end);
|
||||
|
||||
sc_time triggerTime = respQueue->getTriggerTime();
|
||||
if (triggerTime != sc_max_time())
|
||||
dataResponseEvent.notify(triggerTime - sc_time_stamp());
|
||||
|
||||
ranksNumberOfPayloads[rank.ID()]--;
|
||||
if (ranksNumberOfPayloads[rank.ID()] == 0)
|
||||
{
|
||||
refreshManagers[rank.ID()]->notifyIdle();
|
||||
powerDownManagers[rank.ID()]->triggerEntry(TriggerSource::Controller);
|
||||
}
|
||||
}
|
||||
|
||||
sendToDram(commandPair.first, commandPair.second);
|
||||
}
|
||||
else
|
||||
@@ -356,29 +373,12 @@ tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload &trans,
|
||||
return TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
tlm_sync_enum Controller::nb_transport_bw(tlm_generic_payload &trans,
|
||||
tlm_sync_enum Controller::nb_transport_bw(tlm_generic_payload &,
|
||||
tlm_phase &phase, sc_time &delay)
|
||||
{
|
||||
PRINTDEBUGMESSAGE(name(), "[bw] " + phaseNameToString(phase) + " notification in " +
|
||||
delay.to_string());
|
||||
|
||||
if (phase == END_RD || phase == END_RDA || phase == END_WR || phase == END_WRA)
|
||||
{
|
||||
// TODO: check this part (order of responses)
|
||||
respQueue->insertPayload(&trans, delay);
|
||||
|
||||
sc_time triggerTime = respQueue->getTriggerTime();
|
||||
if (triggerTime != sc_max_time())
|
||||
dataResponseEvent.notify(triggerTime - sc_time_stamp());
|
||||
|
||||
Rank rank = DramExtension::getRank(trans);
|
||||
ranksNumberOfPayloads[rank.ID()]--;
|
||||
if (ranksNumberOfPayloads[rank.ID()] == 0)
|
||||
{
|
||||
refreshManagers[rank.ID()]->notifyIdle();
|
||||
powerDownManagers[rank.ID()]->triggerEntry(TriggerSource::Controller);
|
||||
}
|
||||
}
|
||||
return TLM_ACCEPTED;
|
||||
}
|
||||
|
||||
|
||||
@@ -82,13 +82,15 @@ private:
|
||||
tlm_generic_payload *payloadToRelease = nullptr;
|
||||
sc_time timeToRelease = sc_max_time();
|
||||
std::queue<std::pair<sc_time, tlm_generic_payload *>> responseQueue;
|
||||
RespQueueIF *respQueue;
|
||||
|
||||
MemSpec *memSpec;
|
||||
|
||||
std::vector<BankMachine *> bankMachines;
|
||||
std::vector<std::vector<BankMachine *>> bankMachinesOnRank;
|
||||
CmdMuxIF *commandMux;
|
||||
SchedulerIF *scheduler;
|
||||
CheckerIF *checker;
|
||||
RespQueueIF *respQueue;
|
||||
std::vector<RefreshManagerIF *> refreshManagers;
|
||||
std::vector<PowerDownManagerIF *> powerDownManagers;
|
||||
|
||||
|
||||
@@ -34,9 +34,9 @@
|
||||
|
||||
#include "RespQueueFifo.h"
|
||||
|
||||
void RespQueueFifo::insertPayload(tlm_generic_payload *payload, sc_time delay)
|
||||
void RespQueueFifo::insertPayload(tlm_generic_payload *payload, sc_time strobeEnd)
|
||||
{
|
||||
buffer.push({payload, sc_time_stamp() + delay});
|
||||
buffer.push({payload, strobeEnd});
|
||||
}
|
||||
|
||||
tlm_generic_payload *RespQueueFifo::nextPayload()
|
||||
|
||||
@@ -35,9 +35,9 @@
|
||||
#include "RespQueueReorder.h"
|
||||
#include "../../common/dramExtensions.h"
|
||||
|
||||
void RespQueueReorder::insertPayload(tlm_generic_payload *payload, sc_time delay)
|
||||
void RespQueueReorder::insertPayload(tlm_generic_payload *payload, sc_time strobeEnd)
|
||||
{
|
||||
buffer[DramExtension::getPayloadID(payload)] = {payload, sc_time_stamp() + delay};
|
||||
buffer[DramExtension::getPayloadID(payload)] = {payload, strobeEnd};
|
||||
}
|
||||
|
||||
tlm_generic_payload *RespQueueReorder::nextPayload()
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
SchedulerFifo::SchedulerFifo()
|
||||
{
|
||||
buffer = std::vector<std::queue<tlm_generic_payload *>>
|
||||
buffer = std::vector<std::deque<tlm_generic_payload *>>
|
||||
(Configuration::getInstance().memSpec->NumberOfBanks);
|
||||
maxNumberOfRequests = Configuration::getInstance().MaxNrOfTransactions;
|
||||
}
|
||||
@@ -51,28 +51,29 @@ bool SchedulerFifo::hasBufferSpace(tlm_generic_payload *payload)
|
||||
|
||||
void SchedulerFifo::storeRequest(tlm_generic_payload *payload)
|
||||
{
|
||||
buffer[DramExtension::getBank(payload).ID()].push(payload);
|
||||
buffer[DramExtension::getBank(payload).ID()].push_back(payload);
|
||||
}
|
||||
|
||||
void SchedulerFifo::removeRequest(tlm_generic_payload *payload)
|
||||
{
|
||||
buffer[DramExtension::getBank(payload).ID()].pop_front();
|
||||
}
|
||||
|
||||
tlm_generic_payload *SchedulerFifo::getNextRequest(BankMachine *bankMachine)
|
||||
{
|
||||
unsigned bankID = bankMachine->getBank().ID();
|
||||
if (!buffer[bankID].empty())
|
||||
{
|
||||
tlm_generic_payload *front = buffer[bankID].front();
|
||||
buffer[bankID].pop();
|
||||
return front;
|
||||
}
|
||||
return buffer[bankID].front();
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool SchedulerFifo::hasRowHit(Bank bank, Row row)
|
||||
{
|
||||
if (!buffer[bank.ID()].empty())
|
||||
if (buffer[bank.ID()].size() >= 2)
|
||||
{
|
||||
tlm_generic_payload *front = buffer[bank.ID()].front();
|
||||
if (DramExtension::getRow(front) == row)
|
||||
tlm_generic_payload *nextRequest = buffer[bank.ID()][1];
|
||||
if (DramExtension::getRow(nextRequest) == row)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -80,8 +81,8 @@ bool SchedulerFifo::hasRowHit(Bank bank, Row row)
|
||||
|
||||
bool SchedulerFifo::hasRequest(Bank bank)
|
||||
{
|
||||
if (buffer[bank.ID()].empty())
|
||||
return false;
|
||||
else
|
||||
if (buffer[bank.ID()].size() >= 2)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
#include <tlm.h>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <deque>
|
||||
#include "SchedulerIF.h"
|
||||
#include "../../common/dramExtensions.h"
|
||||
#include "../BankMachine.h"
|
||||
@@ -50,11 +50,12 @@ public:
|
||||
SchedulerFifo();
|
||||
virtual bool hasBufferSpace(tlm_generic_payload *) override;
|
||||
virtual void storeRequest(tlm_generic_payload *) override;
|
||||
virtual void removeRequest(tlm_generic_payload *) override;
|
||||
virtual tlm_generic_payload *getNextRequest(BankMachine *) override;
|
||||
virtual bool hasRowHit(Bank, Row) override;
|
||||
virtual bool hasRequest(Bank) override;
|
||||
private:
|
||||
std::vector<std::queue<tlm_generic_payload *>> buffer;
|
||||
std::vector<std::deque<tlm_generic_payload *>> buffer;
|
||||
unsigned maxNumberOfRequests;
|
||||
};
|
||||
|
||||
|
||||
@@ -56,56 +56,61 @@ void SchedulerFrFcfs::storeRequest(tlm_generic_payload *payload)
|
||||
buffer[DramExtension::getBank(payload).ID()].push_back(payload);
|
||||
}
|
||||
|
||||
void SchedulerFrFcfs::removeRequest(tlm_generic_payload *payload)
|
||||
{
|
||||
unsigned bankID = DramExtension::getBank(payload).ID();
|
||||
for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++)
|
||||
{
|
||||
if (*it == payload)
|
||||
{
|
||||
buffer[bankID].erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
SC_REPORT_FATAL("SchedulerFrFcfs", "removeRequest failed!");
|
||||
}
|
||||
|
||||
tlm_generic_payload *SchedulerFrFcfs::getNextRequest(BankMachine *bankMachine)
|
||||
{
|
||||
unsigned bankID = bankMachine->getBank().ID();
|
||||
if (!buffer[bankID].empty())
|
||||
{
|
||||
BmState currentState = bankMachine->getState();
|
||||
if (currentState == BmState::Precharged)
|
||||
{
|
||||
tlm_generic_payload *result = buffer[bankID].front();
|
||||
buffer[bankID].pop_front();
|
||||
return result;
|
||||
}
|
||||
else if (currentState == BmState::Activated)
|
||||
if (currentState == BmState::Activated)
|
||||
{
|
||||
// Search for row hit
|
||||
Row openRow = bankMachine->getOpenRow();
|
||||
for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++)
|
||||
{
|
||||
if (DramExtension::getRow(*it) == openRow)
|
||||
{
|
||||
tlm_generic_payload *result = *it;
|
||||
buffer[bankID].erase(it);
|
||||
return result;
|
||||
}
|
||||
return *it;
|
||||
}
|
||||
// No row hit found
|
||||
tlm_generic_payload *result = buffer[bankID].front();
|
||||
buffer[bankID].pop_front();
|
||||
return result;
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("SchedulerFrFcfs", "Wrong BM state!");
|
||||
// No row hit found or bank precharged
|
||||
return buffer[bankID].front();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool SchedulerFrFcfs::hasRowHit(Bank bank, Row row)
|
||||
{
|
||||
unsigned rowHitCounter = 0;
|
||||
for (auto it = buffer[bank.ID()].begin(); it != buffer[bank.ID()].end(); it++)
|
||||
{
|
||||
if (DramExtension::getRow(*it) == row)
|
||||
return true;
|
||||
{
|
||||
rowHitCounter++;
|
||||
if (rowHitCounter == 2)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SchedulerFrFcfs::hasRequest(Bank bank)
|
||||
{
|
||||
if (buffer[bank.ID()].empty())
|
||||
return false;
|
||||
else
|
||||
if (buffer[bank.ID()].size() >= 2)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ public:
|
||||
SchedulerFrFcfs();
|
||||
virtual bool hasBufferSpace(tlm_generic_payload *) override;
|
||||
virtual void storeRequest(tlm_generic_payload *) override;
|
||||
virtual void removeRequest(tlm_generic_payload *) override;
|
||||
virtual tlm_generic_payload *getNextRequest(BankMachine *) override;
|
||||
virtual bool hasRowHit(Bank, Row) override;
|
||||
virtual bool hasRequest(Bank) override;
|
||||
|
||||
@@ -51,6 +51,7 @@ public:
|
||||
virtual ~SchedulerIF() {}
|
||||
virtual bool hasBufferSpace(tlm_generic_payload *) = 0;
|
||||
virtual void storeRequest(tlm_generic_payload *) = 0;
|
||||
virtual void removeRequest(tlm_generic_payload *) = 0;
|
||||
virtual tlm_generic_payload *getNextRequest(BankMachine *) = 0;
|
||||
virtual bool hasRowHit(Bank, Row) = 0;
|
||||
virtual bool hasRequest(Bank) = 0;
|
||||
|
||||
Reference in New Issue
Block a user