Major change to simulation logic in dramSys: Commands in a transaction are now scheduled one at a time, instead of scheduling a whole transaction at once. Since single commands (e.g. Pre or Act) are not that long, refreshes are allowed to be delayed to allow a command to finsh. Consequently, the whole loop in the ControllerCore about trying to scheduleding a transaction and aborting it when it collides with a refresh could be ommitted. Lastly, Fifo_Strict has been added, which is a Fifo Scheduler that forces the read and write transactions, even between different banks to be executed in order. Fifo and FR_FCFS have been modified to fit into the new scheduling logic.
51 lines
1.2 KiB
C++
51 lines
1.2 KiB
C++
#include "Fr_Fcfs.h"
|
|
#include "../../common/dramExtension.h"
|
|
#include "../core/configuration/Configuration.h"
|
|
#include <algorithm>
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
void FR_FCFS::schedule(gp *payload)
|
|
{
|
|
buffer[DramExtension::getExtension(payload).getBank()].emplace_back(payload);
|
|
}
|
|
|
|
std::pair<Command, gp*> FR_FCFS::getNextRequest(Bank bank)
|
|
{
|
|
if(buffer[bank].empty())
|
|
{
|
|
return pair<Command, tlm::tlm_generic_payload*>(Command::NOP, NULL);
|
|
}
|
|
|
|
deque<gp*>::iterator it = FindRowHit(bank);
|
|
if(it != buffer[bank].end())
|
|
{
|
|
gp* payload = *it;
|
|
buffer[bank].erase(it);
|
|
return pair<Command, gp*>(getReadWriteCommand(*payload), payload);
|
|
}
|
|
|
|
return pair<Command, gp*>(getNextCommand(buffer[bank].front()), buffer[bank].front());
|
|
}
|
|
|
|
deque<gp*>::iterator FR_FCFS::FindRowHit(Bank bank)
|
|
{
|
|
deque<gp*> &queue = buffer[bank];
|
|
|
|
if(!controllerCore.getRowBufferStates().rowBufferIsOpen(bank))
|
|
return queue.end();
|
|
|
|
for(auto it = queue.begin(); it!=queue.end(); it++)
|
|
{
|
|
gp* payload = *it;
|
|
//Found row-hit
|
|
if(DramExtension::getRow(payload) == controllerCore.getRowBufferStates().getRowInRowBuffer(bank))
|
|
{
|
|
return it;
|
|
}
|
|
}
|
|
return queue.end();
|
|
}
|