/* * InternalScheduler.cpp * * Created on: Mar 9, 2014 * Author: jonny */ #include "CommandBus.h" #include namespace controller { void CommandBus::schedule(const CommandSchedule& schedule) { const std::vector& commands = schedule.getScheduledCommands(); for(std::vector::const_iterator it = commands.begin();it != commands.end();++it) { scheduleCommand(*it); } } void CommandBus::scheduleCommand(const ScheduledCommand& command) { assert(!pendingBusCommands.count(command.getStart())); changeControllerState(command); pendingBusCommands.insert(command.getStart()); lastCommandsOnBus[command.getCommand()][command.getBank()] = command; //notify tlm wrapper lastCommandsOnBus[command.getCommand()][command.getBank()].invalidateTransaction(); } void CommandBus::scheduleTrigger(const Trigger command, sc_time time) { //notify tlm wrapper } ScheduledCommand& CommandBus::getLastCommand(Command command, Bank bank) { return lastCommandsOnBus[command][bank]; } ScheduledCommand& CommandBus::getLastCommand(Command command) { ScheduledCommand* max = &getLastCommand(command, Bank(0)); for (unsigned int i = 0; i < config.numberOfBanks; ++i) { ScheduledCommand* current = &getLastCommand(command, Bank(i)); if (current->getStart() > max->getStart()) max = current; } return *max; } bool CommandBus::notYetScheduled(Command command) const { return (lastCommandsOnBus.count(command) == 0); } bool CommandBus::notYetScheduled(Command command, Bank bank) const { return (notYetScheduled(command) || lastCommandsOnBus.find(command)->second.count(bank) == 0); } sc_time CommandBus::getEarliestStartTime(const ScheduledCommand& command) const { sc_time newStart = command.getStart(); assert(isClkAligned(newStart, config.Timings.clk)); std::set::iterator it = pendingBusCommands.begin(); while (it != pendingBusCommands.end() && *it <= newStart) { if (*it == newStart) newStart += config.Timings.clk; ++it; } return newStart; } void CommandBus::cleanUpBus(sc_time currentTime) { pendingBusCommands.erase(pendingBusCommands.begin(), pendingBusCommands.lower_bound(currentTime)); } void CommandBus::changeControllerState(const ScheduledCommand& command) { switch (command.getCommand()) { case Refresh: refresh(command); break; case Activate: activate(command); break; case Precharge: precharge(command); default: break; } } void CommandBus::refresh(const ScheduledCommand& command) { if(config.RefreshBankwise) { state.bankStates.closeRowBuffer(command.getBank()); } else { state.bankStates.closeAllRowBuffers(); } } void CommandBus::precharge(const ScheduledCommand& command) { if(command.getCommand() == Precharge) { state.bankStates.closeRowBuffer(command.getBank()); } else if(command.getCommand() == PrechargeAll) { state.bankStates.closeAllRowBuffers(); } } void CommandBus::activate(const ScheduledCommand& command) { if(command.getCommand() == Activate) { state.bankStates.openRowInRowBuffer(command.getBank(), command.getRow()); } } } /* namespace controller */