Bankwise Refresh Manager and some minor refactoring fun

This commit is contained in:
Janik Schlemminger
2014-03-21 16:22:49 +01:00
parent cd556eb572
commit f7fa821e12
22 changed files with 231 additions and 376 deletions

View File

@@ -1,87 +1,49 @@
/*
* RefreshManager.cpp
* BankwiseRefreshManager.cpp
*
* Created on: Mar 6, 2014
* Created on: Mar 9, 2014
* Author: jonny
*/
#include "RefreshManager.h"
#include "../utils/Utils.h"
#include "../Controller.h"
using namespace std;
namespace core {
RefreshManager::RefreshManager(CommandBus& bus, const RefreshTiming& refreshTiming
) : bus(bus), refreshTiming(refreshTiming)
RefreshManager::RefreshManager(DramController& controller) : controller(controller)
{
setupTransaction(refreshTransaction, Bank(0));
nextPlannedRefresh = new ScheduledCommand(refreshTransaction, Refresh, SC_ZERO_TIME,
refreshTiming.tRFC);
planNextRefresh(*nextPlannedRefresh);
}
RefreshManager::RefreshManager(CommandBus& bus, const RefreshTiming& refreshTiming,
Bank bank) : bus(bus), refreshTiming(refreshTiming)
{
setupTransaction(refreshTransaction, bank);
nextPlannedRefresh = new ScheduledCommand(refreshTransaction, Refresh, SC_ZERO_TIME,
refreshTiming.tRFC);
planNextRefresh(*nextPlannedRefresh);
assert(!controller.config.Timings.refreshTimings.empty());
for(Bank bank : controller.state.bankStates.getBanks())
{
refreshManagerForBanks.push_back(new RefreshManagerForBank(controller, bank));
}
}
RefreshManager::~RefreshManager()
{
delete nextPlannedRefresh;
for(RefreshManagerForBank* manager : refreshManagerForBanks)
{
delete manager;
}
}
/*
* 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;
}
RefreshManagerForBank& manager = *refreshManagerForBanks.at(schedule.getBank().ID());
return manager.hasCollision(schedule);
}
void RefreshManager::scheduleRefresh(sc_time time)
{
if (time == nextPlannedRefresh->getStart())
scheduleRefresh(*nextPlannedRefresh);
}
void RefreshManager::scheduleRefresh(ScheduledCommand& refresh)
{
bus.schedule(refresh);
bus.send(refresh);
planNextRefresh(refresh);
}
void RefreshManager::planNextRefresh(ScheduledCommand& refresh) //TODO nicer to return the reference ?
{
refresh.delayStart(refreshTiming.tREFI);
bus.send(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
for (unsigned int i = 0; i < refreshManagerForBanks.size(); ++i)
{
RefreshManagerForBank& manager = *refreshManagerForBanks.at(i);
manager.scheduleRefresh(time);
}
}
} /* namespace controller */