/* * Copyright (c) 2015, University of Kaiserslautern * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: * Janik Schlemminger * Matthias Jung */ #include "ControllerState.h" #include #include "core/TimingCalculation.h" const ScheduledCommand ControllerState::getLastCommand(Command command, Bank bank) //TODO const reference? and make const { return lastScheduledByCommandAndBank[command][bank]; } const ScheduledCommand ControllerState::getLastCommand(Command command) { ScheduledCommand max; for (unsigned int i = 0; i < config->memSpec.NumberOfBanks; ++i) { ScheduledCommand current = getLastCommand(command, Bank(i)); if (current.getStart() > max.getStart()) max = current; } return max; } const ScheduledCommand ControllerState::getLastScheduledCommand() { ScheduledCommand lastCommand; for(Command cmd : getAllCommands()) { for(Bank bank : Configuration::getInstance().memSpec.getBanks()) { ScheduledCommand& current = lastScheduledByCommandAndBank[cmd][bank]; if (current.getStart() > lastCommand.getStart()) lastCommand = current; } } return lastCommand; } const ScheduledCommand ControllerState::getLastScheduledCommand(Bank bank) { ScheduledCommand lastCommand; for(Command cmd : getAllCommands()) { ScheduledCommand& current = lastScheduledByCommandAndBank[cmd][bank]; if (current.getStart() > lastCommand.getStart()) lastCommand = current; } return lastCommand; } void ControllerState::change(const ScheduledCommand& scheduledCommand) { bus.blockSlot(scheduledCommand.getStart()); lastScheduledByCommandAndBank[scheduledCommand.getCommand()][scheduledCommand.getBank()] = scheduledCommand; switch (scheduledCommand.getCommand()) { case Command::Read: lastDataStrobeCommands.emplace_back(scheduledCommand); break; case Command::ReadA: rowBufferStates.closeRowBuffer(scheduledCommand.getBank()); lastDataStrobeCommands.emplace_back(scheduledCommand); break; case Command::Write: lastDataStrobeCommands.emplace_back(scheduledCommand); break; case Command::WriteA: rowBufferStates.closeRowBuffer(scheduledCommand.getBank()); lastDataStrobeCommands.emplace_back(scheduledCommand); break; case Command::AutoRefresh: break; case Command::Activate: rowBufferStates.openRowInRowBuffer(scheduledCommand.getBank(), scheduledCommand.getRow()); lastActivates.emplace(scheduledCommand.getStart(), scheduledCommand); break; case Command::Precharge: rowBufferStates.closeRowBuffer(scheduledCommand.getBank()); break; case Command::PrechargeAll: rowBufferStates.closeAllRowBuffers(); break; case Command::SREF: rowBufferStates.closeRowBuffer(scheduledCommand.getBank()); break; default: break; } } void ControllerState::cleanUp(sc_time time) { bus.cleanUpSlots(time); vector tmp; for(ScheduledCommand& command: lastDataStrobeCommands) { if(command.getEnd() >= time || getDistance(command.getEnd(), time) <= config->memSpec.tDataStrobeHistory()) tmp.push_back(command); } lastDataStrobeCommands = tmp; if(time >= config->memSpec.tActHistory()) lastActivates.erase(lastActivates.begin(), lastActivates.lower_bound(time - config->memSpec.tActHistory())); }