/* * RefreshManager.cpp * * Created on: Mar 29, 2014 * Author: robert */ #include "RefreshManager.h" #include "../Controller.h" using namespace tlm; namespace core { RefreshManager::RefreshManager(Controller& controller) : controller(controller), timing(controller.config.Timings.refreshTimings.at(0)), nextPlannedRefresh(SC_ZERO_TIME), refreshPayloads(controller.config.NumberOfBanks) { setupTransactions(); planNextRefresh(); } RefreshManager::~RefreshManager() { } bool RefreshManager::hasCollision(const CommandSchedule& schedule) { return !(schedule.getEnd() < nextPlannedRefresh); } void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time) { sc_assert(!isInvalidated(payload, time)); ScheduledCommand nextRefresh(Command::AutoRefresh, time, timing.tRFC, DramExtension::getExtension(refreshPayloads.at(0))); if (!controller.state.bankStates.allRowBuffersAreClosed()) { ScheduledCommand precharge(Command::PrechargeAll, time, controller.config.Timings.tRP, DramExtension::getExtension(refreshPayloads.at(0))); controller.getCommandChecker(Command::PrechargeAll).delayToSatisfyConstraints(precharge); nextRefresh.setStart(precharge.getEnd()); for (tlm::tlm_generic_payload& payload : refreshPayloads) { ScheduledCommand prechargeToSend(Command::PrechargeAll, precharge.getStart(), controller.config.Timings.tRP, DramExtension::getExtension(payload)); controller.state.change(prechargeToSend); controller.wrapper.send(prechargeToSend, payload); } } for (tlm::tlm_generic_payload& payload : refreshPayloads) { ScheduledCommand refreshToSend(Command::AutoRefresh, nextRefresh.getStart(), timing.tRFC, DramExtension::getExtension(payload)); controller.state.change(refreshToSend); controller.wrapper.send(refreshToSend, payload); } planNextRefresh(); } void RefreshManager::planNextRefresh() { nextPlannedRefresh += timing.tREFI; controller.wrapper.send(RefreshTrigger, nextPlannedRefresh, refreshPayloads.at(0)); } void RefreshManager::reInitialize(tlm::tlm_generic_payload& payload, sc_time time) { nextPlannedRefresh = clkAlign(time, controller.config.Timings.clk, Alignment::DOWN); planNextRefresh(); } bool core::RefreshManager::isInvalidated(tlm::tlm_generic_payload& payload, sc_time time) { return nextPlannedRefresh > time; } void RefreshManager::setupTransactions() { for (Bank bank : controller.getBanks()) { tlm_generic_payload& payload = refreshPayloads.at(bank.ID()); payload.set_address(getStartAddress(bank)); payload.set_command(tlm::TLM_READ_COMMAND); payload.set_data_length(0); payload.set_response_status(tlm::TLM_OK_RESPONSE); payload.set_dmi_allowed(false); payload.set_byte_enable_length(0); payload.set_streaming_width(0); payload.set_extension(new DramExtension(Thread(0), bank, Row(0), Column(0))); //payload takes ownership } } } /* namespace core */