Files
DRAMSys/dram/src/core/scheduling/checker/ActivateChecker.cpp
2014-04-12 11:44:27 +02:00

110 lines
3.1 KiB
C++

/*
* ActivateScheduler.cpp
*
* Created on: Mar 12, 2014
* Author: jonny
*/
#include <algorithm>
#include <set>
#include "ActivateChecker.h"
#include "../../TimingCalculation.h"
#include "../../../common/DebugManager.h"
#include "../../Command.h"
#include "../../../common/Utils.h"
#include <iostream>
namespace core {
void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
{
sc_assert(command.getCommand() == Command::Activate);
ScheduledCommand lastCommandOnBank = state.getLastScheduledCommand(command.getBank());
if (lastCommandOnBank.isValidCommand())
{
if (isIn(lastCommandOnBank.getCommand(), { Command::Precharge, Command::AutoRefresh,
Command::ReadA, Command::WriteA }))
{
command.delayToMeetConstraint(lastCommandOnBank.getEnd(), SC_ZERO_TIME);
}
else if (lastCommandOnBank.getCommand() == Command::PDNPX
|| lastCommandOnBank.getCommand() == Command::PDNAX)
{
command.delayToMeetConstraint(lastCommandOnBank.getStart(), config.Timings.tXP);
}
else if (lastCommandOnBank.getCommand() == Command::SREFX)
{
command.delayToMeetConstraint(lastCommandOnBank.getStart(), config.Timings.tXSR);
}
else
reportFatal("Activate Checker",
"Activate can not follow " + commandToString(lastCommandOnBank.getCommand()));
}
delay_to_satisfy_activateToActivate_sameBank(command);
while (!(state.bus.isFree(command.getStart())
&& satsfies_activateToActivate_differentBank(command)
&& satisfies_nActivateWindow(command)))
{
command.delayStart(config.Timings.clk);
}
}
void ActivateChecker::delay_to_satisfy_activateToActivate_sameBank(ScheduledCommand& command) const
{
ScheduledCommand lastActivateOnBank = state.getLastCommand(Command::Activate,
command.getBank());
if (lastActivateOnBank.isValidCommand())
{
command.delayToMeetConstraint(lastActivateOnBank.getStart(), config.Timings.tRC);
}
}
bool ActivateChecker::satsfies_activateToActivate_differentBank(ScheduledCommand& command) const
{
for (auto act : state.lastActivates)
{
sc_time time = act.first;
sc_time tRRD =
(command.getBankGroup() == act.second.getBankGroup()) ?
config.Timings.tRRD_L : config.Timings.tRRD_S;
if ((time < command.getStart() && command.getStart() - time < tRRD)
|| (command.getStart() <= time && time - command.getStart() < tRRD))
return false;
}
return true;
}
bool ActivateChecker::satisfies_nActivateWindow(ScheduledCommand& command) const
{
/*
* there may be activates scheduled in the future, so emplace
* command in a copied set (not necessarily the last in time),
* and check if the n-act constraint holds for the whole set.
*/
if (state.lastActivates.size() >= config.nActivate)
{
map<sc_time, Bank> lastActivates = state.lastActivates;
lastActivates.emplace(command.getStart(), command.getBank());
auto upper = lastActivates.begin();
advance(upper, config.nActivate);
auto lower = lastActivates.begin();
while (upper != lastActivates.end())
{
if (upper->first - lower->first < config.Timings.tNAW)
return false;
++upper;
++lower;
}
}
return true;
}
} /* namespace controller */