Commented the FR_FCFS scheduler

since the original implementation the comments are missed. I just added
the comments such that anybody can understand it.
This commit is contained in:
Matthias Jung
2017-06-20 17:07:25 +02:00
parent 2b332515bc
commit 9ed9ba480b

View File

@@ -42,20 +42,43 @@
using namespace std;
// The FR_FCFS is descibed in a 2000 paper from Rixner et al.:
// Memory Access Scheduling
//
// The FR_FCFS scheduler features for each bank in the DRAM a specific
// scheduling buffer for example:
//
// Bank0: OOOOOOOO
// Bank1: OOXXXXXX
// ... ^ ^
// ... | |
// ... back |
// ... front
// ...
// Bank6: OOOOO0XX
// Bank7: XXXXXXXX
void FR_FCFS::schedule(gp *payload)
{
buffer[DramExtension::getExtension(payload).getBank()].emplace_back(payload);
// FIXME: Question: what if the buffer is full? IMHO the schedule function
// should provide a true or false when the placement into the buffer worked
// out or not (?).
buffer[DramExtension::getExtension(payload).getBank()]
.emplace_back(payload);
}
std::pair<Command, gp*> FR_FCFS::getNextRequest(Bank bank)
{
// If the bank is empty like Bank0 in the example we do nothing
if(buffer[bank].empty())
{
return pair<Command, tlm::tlm_generic_payload*>(Command::NOP, NULL);
}
// In FR_FCFS row hits have always the highest priority, therefore we search
// for row hits. If we find a row hit, we remove the transaction from the
// queue and send it to the DRAM.
deque<gp*>::iterator it = FindRowHit(bank);
if(it != buffer[bank].end())
{
@@ -64,9 +87,19 @@ std::pair<Command, gp*> FR_FCFS::getNextRequest(Bank bank)
return pair<Command, gp*>(getReadWriteCommand(*payload), payload);
}
return pair<Command, gp*>(getNextCommand(buffer[bank].front()), buffer[bank].front());
// If there is no row hit, the FR_FCFS takes always the oldest transaction
// in the buffer, i.e. the transaction in the front.
return pair<Command, gp*>(getNextCommand(buffer[bank].front()),
buffer[bank].front());
}
// This function searches for a row hit in the scheduling queue of the specific
// bank. If no row hit is found the end of the queue is returned.
//
// Note: end() Returns an iterator referring to the past-the-end element in the
// deque container. The past-the-end element is the theoretical element that
// would follow the last element in the deque container. It does not point to
// any element, and thus shall not be dereferenced.
deque<gp*>::iterator FR_FCFS::FindRowHit(Bank bank)
{
deque<gp*> &queue = buffer[bank];
@@ -74,14 +107,17 @@ deque<gp*>::iterator FR_FCFS::FindRowHit(Bank bank)
if(!controllerCore.getRowBufferStates().rowBufferIsOpen(bank))
return queue.end();
// Traverse the scheduling queue of the specific bank:
for(auto it = queue.begin(); it!=queue.end(); it++)
{
gp* payload = *it;
//Found row-hit
if(DramExtension::getRow(payload) == controllerCore.getRowBufferStates().getRowInRowBuffer(bank))
//Found row-hit and return the according iterator
if(DramExtension::getRow(payload)
== controllerCore.getRowBufferStates().getRowInRowBuffer(bank))
{
return it;
}
}
return queue.end();
}