Bankwise Refresh Manager and some minor refactoring fun
This commit is contained in:
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user