diff --git a/DRAM/src/core/RefreshManager.cpp b/DRAM/src/core/RefreshManager.cpp new file mode 100644 index 00000000..e618b683 --- /dev/null +++ b/DRAM/src/core/RefreshManager.cpp @@ -0,0 +1,60 @@ +/* + * RefreshManager.cpp + * + * Created on: Mar 6, 2014 + * Author: jonny + */ + +#include + +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 */ diff --git a/DRAM/src/core/RefreshManager.h b/DRAM/src/core/RefreshManager.h new file mode 100644 index 00000000..39a50571 --- /dev/null +++ b/DRAM/src/core/RefreshManager.h @@ -0,0 +1,48 @@ +/* + * RefreshManager.h + * + * Created on: Mar 6, 2014 + * Author: jonny + */ + +#ifndef REFRESHMANAGER_H_ +#define REFRESHMANAGER_H_ + +#include +#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_ */ diff --git a/DRAM/testing/RefreshManager_test.cpp b/DRAM/testing/RefreshManager_test.cpp new file mode 100644 index 00000000..1aad4a26 --- /dev/null +++ b/DRAM/testing/RefreshManager_test.cpp @@ -0,0 +1,49 @@ +/* + * RefreshManager_test.cpp + * + * Created on: Mar 6, 2014 + * Author: jonny + */ + +#include +#include +#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 */