Refresh Manager

This commit is contained in:
Janik Schlemminger
2014-03-09 05:24:50 -07:00
parent 3567ff3345
commit f951eae4e9
3 changed files with 157 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
/*
* RefreshManager.cpp
*
* Created on: Mar 6, 2014
* Author: jonny
*/
#include <core/RefreshManager.h>
namespace controller {
RefreshManager::RefreshManager(Configuration& configuration, InternalScheduler& internalScheduler) : controllerConfiguration(configuration), internalScheduler(internalScheduler)
{
lastRefresh.time = SC_ZERO_TIME;
lastRefresh.delay = SC_ZERO_TIME;
refreshFinished(SC_ZERO_TIME);
}
/*
* Is called from TLM Wrapper when end_refresh is sent from DRAM.
*/
void RefreshManager::refreshFinished(sc_time currentTime)
{
planNextRefresh(lastRefresh);
assert(currentTime < lastRefresh.time);
scheduleRefresh(lastRefresh);
}
/*
* Checks for a scheduled CommandSequence, if there is a collision with a refresh.
* A refresh may be postponed for a certain time, to fit the scheduled sequence anyways,
* depending on the refresh logic.
*/
bool RefreshManager::hasCollision(CommandSchedule schedule)
{
return true;
}
/*
* If a scheduled CommandSequence collides, the refresh manager provides the earliest
* start time for the new scheduling of this sequence.
*/
sc_time RefreshManager::getEarliestStartTime(CommandSchedule schedule)
{
/*stub*/
return SC_ZERO_TIME;
}
void RefreshManager::scheduleRefresh(const PlannedRefresh& refresh) const
{
internalScheduler.scheduleCommand(ScheduledCommand(Command::Refresh, refresh.time + refresh.delay));
}
void RefreshManager::planNextRefresh(PlannedRefresh& refresh)
{
refresh.time += controllerConfiguration.Timings.tREF;
refresh.delay = SC_ZERO_TIME;
}
} /* namespace controller */

View File

@@ -0,0 +1,48 @@
/*
* RefreshManager.h
*
* Created on: Mar 6, 2014
* Author: jonny
*/
#ifndef REFRESHMANAGER_H_
#define REFRESHMANAGER_H_
#include <systemc.h>
#include "scheduling/InternalScheduler.h"
#include "Configuration.h"
namespace controller {
struct PlannedRefresh{
PlannedRefresh():time(SC_ZERO_TIME), delay(SC_ZERO_TIME){}
sc_time time;
sc_time delay;
};
class RefreshManager
{
public:
RefreshManager(Configuration& configuration, InternalScheduler& internalScheduler);
virtual ~RefreshManager() {}
void refreshFinished(sc_time currentTime);
bool hasCollision(CommandSchedule schedule);
sc_time getEarliestStartTime(CommandSchedule schedule);
private:
Configuration& controllerConfiguration;
InternalScheduler& internalScheduler;
PlannedRefresh lastRefresh;
//void scheduleRefreshTrigger(PlannedRefresh& refresh); idea: schedule refresh only at the regular time. Up to this point refresh can be still shifted to fit a sequence before.
void planNextRefresh(PlannedRefresh& refresh);
void scheduleRefresh(const PlannedRefresh& refresh) const;
};
} /* namespace controller */
#endif /* REFRESHMANAGER_H_ */

View File

@@ -0,0 +1,49 @@
/*
* RefreshManager_test.cpp
*
* Created on: Mar 6, 2014
* Author: jonny
*/
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "core/RefreshManager.h"
using ::testing::_;
using ::testing::AtLeast;
using ::testing::Expectation;
namespace controller {
class MockInternalScheduler: public InternalScheduler
{
public:
MOCK_METHOD1(scheduleCommand, void (ScheduledCommand command));
};
TEST(RefreshManager, RefreshIsScheduledAfterStartup)
{
Configuration config;
MockInternalScheduler internalScheduler;
auto init = ScheduledCommand(Command::Refresh, config.Timings.tREF);
EXPECT_CALL(internalScheduler, scheduleCommand(init));
RefreshManager manager(config, internalScheduler);
}
TEST(RefreshManager, FinishedRefreshTriggersNewRefresh)
{
Configuration config;
MockInternalScheduler internalScheduler;
EXPECT_CALL(internalScheduler, scheduleCommand(_)).Times(2);
//schedule first refresh in constructor
RefreshManager manager(config, internalScheduler);
//schedule second refresh in callback (end_refresh)
manager.refreshFinished(config.Timings.tREF + config.Timings.tREFA);
}
} /* namespace controller */