90 lines
2.6 KiB
C++
90 lines
2.6 KiB
C++
/*
|
|
* RefreshManager.cpp
|
|
*
|
|
* Created on: Mar 6, 2014
|
|
* Author: jonny
|
|
*/
|
|
|
|
#include <core/refresh/RefreshManager.h>
|
|
#include "core/utils/Utils.h"
|
|
|
|
|
|
|
|
namespace controller {
|
|
|
|
RefreshManager::RefreshManager(const RefreshTiming& refreshTiming,
|
|
IInternalScheduler& internalScheduler) :
|
|
refreshTiming(refreshTiming), internalScheduler(internalScheduler)
|
|
{
|
|
setupTransaction(refreshTransaction, Bank(0));
|
|
nextPlannedRefresh = new ScheduledCommand(refreshTransaction, Refresh, SC_ZERO_TIME,
|
|
refreshTiming.tRFC);
|
|
planNextRefresh(*nextPlannedRefresh);
|
|
}
|
|
|
|
RefreshManager::RefreshManager(const RefreshTiming& refreshTiming,
|
|
IInternalScheduler& internalScheduler, Bank bank) :
|
|
refreshTiming(refreshTiming), internalScheduler(internalScheduler)
|
|
{
|
|
setupTransaction(refreshTransaction, bank);
|
|
nextPlannedRefresh = new ScheduledCommand(refreshTransaction, Refresh, SC_ZERO_TIME,
|
|
refreshTiming.tRFC);
|
|
planNextRefresh(*nextPlannedRefresh);
|
|
}
|
|
|
|
RefreshManager::~RefreshManager()
|
|
{
|
|
delete nextPlannedRefresh;
|
|
}
|
|
|
|
/*
|
|
* Checks for a scheduled CommandSequence, if there is a collision with the current planned,
|
|
* not yet scheduled, refresh command. In case of a collision the manager schedules the refresh
|
|
* (sends it out) and plans the next refresh. Afterwards the CommandSequence is re-scheduled
|
|
* with the new controller state (earliest start time is the end of the just scheduled refresh).
|
|
*/
|
|
bool RefreshManager::hasCollision(const CommandSchedule& schedule)
|
|
{
|
|
if (schedule.getEnd() < nextPlannedRefresh->getStart())
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
void RefreshManager::scheduleRefresh(sc_time time)
|
|
{
|
|
if (time <= nextPlannedRefresh->getStart())
|
|
scheduleRefresh(*nextPlannedRefresh);
|
|
}
|
|
|
|
void RefreshManager::scheduleRefresh(ScheduledCommand& refresh)
|
|
{
|
|
internalScheduler.scheduleCommand(refresh);
|
|
planNextRefresh(refresh);
|
|
}
|
|
|
|
void RefreshManager::planNextRefresh(ScheduledCommand& refresh) //TODO nicer to return the reference ?
|
|
{
|
|
refresh.delayStart(refreshTiming.tREFI);
|
|
internalScheduler.scheduleTrigger(RefreshTrigger, refresh.getStart());
|
|
}
|
|
|
|
void RefreshManager::setupTransaction(tlm::tlm_generic_payload& transaction, Bank bank)
|
|
{
|
|
transaction.set_address(getStartAddress(bank));
|
|
transaction.set_command(tlm::TLM_READ_COMMAND);
|
|
transaction.set_data_length(0);
|
|
transaction.set_response_status(tlm::TLM_OK_RESPONSE);
|
|
transaction.set_dmi_allowed(false);
|
|
transaction.set_byte_enable_length(0);
|
|
transaction.set_streaming_width(0);
|
|
|
|
transaction.set_extension(new DramExtension(Thread(0), bank, Row(0), Column(0))); //payload takes ownership
|
|
}
|
|
|
|
} /* namespace controller */
|