109 lines
3.1 KiB
C++
109 lines
3.1 KiB
C++
/*
|
|
* RefreshManager.cpp
|
|
*
|
|
* Created on: Mar 29, 2014
|
|
* Author: robert
|
|
*/
|
|
|
|
#include "RefreshManager.h"
|
|
#include "../ControllerCore.h"
|
|
|
|
using namespace tlm;
|
|
namespace core {
|
|
|
|
RefreshManager::RefreshManager(ControllerCore& 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);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//no precharge all
|
|
controller.state.bus.moveCommandToNextFreeSlot(nextRefresh);
|
|
}
|
|
for (tlm::tlm_generic_payload& payload : refreshPayloads)
|
|
{
|
|
Row currentrow = DramExtension::getExtension(payload).getRow();
|
|
DramExtension::getExtension(payload).setRow(Row((currentrow.ID()+1)%Configuration::getInstance().NumberOfBanks));
|
|
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 */
|
|
|