/* * ActivateScheduler.cpp * * Created on: Mar 12, 2014 * Author: jonny */ #include #include #include "ActivateChecker.h" #include "../../TimingCalculation.h" #include "../../../common/DebugManager.h" #include "../../Command.h" #include "../../../common/Utils.h" #include 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 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 */