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:
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user