Refactoring of RefreshManager (introduced interface IRefreshManager).

This commit is contained in:
Janik Schlemminger
2014-03-09 16:56:17 -07:00
parent 43c5d6a4b3
commit 3cda347e37
19 changed files with 287 additions and 86 deletions

View File

@@ -15,6 +15,8 @@ namespace controller{
struct Configuration
{
unsigned int numberOfBanks;
bool RefreshBankwise = false;
TimingConfiguration Timings;
};

View File

@@ -10,20 +10,31 @@
#include <tlm.h>
#include "scheduling/CommandGenerator.h"
#include "scheduling/InternalScheduler.h"
#include "Configuration.h"
#include "scheduling/CommandSequenceScheduler.h"
#include "refresh/RefreshManager.h"
#include "powerdown/PowerDownManager.h"
namespace controller {
class Controller {
class Controller
{
public:
Controller();
virtual ~Controller();
bool schedule(tlm::tlm_generic_payload* externalTransaction);//return TLM status??
bool schedule(tlm::tlm_generic_payload* externalTransaction); //return TLM status??
private:
Configuration config;
ControllerState state;
CommandGenerator commandGenerator;
CommandGenerator commandGenerator;
CommandSequenceScheduler commandSequenceScheduler;
RefreshManager refreshManager;
PowerDownManager powerDownManager;
InternalScheduler internalScheduler;
};
} /* namespace controller */

View File

@@ -1,48 +0,0 @@
/*
* 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,23 @@
/*
* PowerDownManager.cpp
*
* Created on: Mar 9, 2014
* Author: jonny
*/
#include <core/PowerDownManager.h>
namespace controller {
PowerDownManager::PowerDownManager()
{
// TODO Auto-generated constructor stub
}
PowerDownManager::~PowerDownManager()
{
// TODO Auto-generated destructor stub
}
} /* namespace controller */

View File

@@ -0,0 +1,22 @@
/*
* PowerDownManager.h
*
* Created on: Mar 9, 2014
* Author: jonny
*/
#ifndef POWERDOWNMANAGER_H_
#define POWERDOWNMANAGER_H_
namespace controller {
class PowerDownManager
{
public:
PowerDownManager();
virtual ~PowerDownManager();
};
} /* namespace controller */
#endif /* POWERDOWNMANAGER_H_ */

View File

@@ -0,0 +1,33 @@
/*
* IRefreshManager.h
*
* Created on: Mar 9, 2014
* Author: jonny
*/
#ifndef IREFRESHMANAGER_H_
#define IREFRESHMANAGER_H_
#include <systemc.h>
namespace controller {
class IRefreshManager
{
public:
virtual ~IRefreshManager() {}
//internal:
virtual bool hasCollision(const CommandSchedule& schedule) = 0;
virtual sc_time getEarliestStartTime(const CommandSchedule& schedule) = 0;
//external:
virtual void cb_refreshFinished(sc_time currentTime) = 0;
private:
virtual void scheduleRefresh(const ScheduledCommand& refresh) const = 0;
};
} /* namespace controller */
#endif /* IREFRESHMANAGER_H_ */

View File

@@ -5,21 +5,19 @@
* Author: jonny
*/
#include <core/RefreshManager.h>
#include <core/refresh/RefreshManager.h>
namespace controller {
RefreshManager::RefreshManager(Configuration& configuration, InternalScheduler& internalScheduler) : controllerConfiguration(configuration), internalScheduler(internalScheduler)
RefreshManager::RefreshManager(Configuration& configuration, IInternalScheduler& internalScheduler) : controllerConfiguration(configuration), internalScheduler(internalScheduler), lastRefresh(refreshTransaction, Command::Refresh, SC_ZERO_TIME)
{
lastRefresh.time = SC_ZERO_TIME;
lastRefresh.delay = SC_ZERO_TIME;
refreshFinished(SC_ZERO_TIME);
cb_refreshFinished(SC_ZERO_TIME);
}
/*
* Is called from TLM Wrapper when end_refresh is sent from DRAM.
*/
void RefreshManager::refreshFinished(sc_time currentTime)
void RefreshManager::cb_refreshFinished(sc_time currentTime)
{
planNextRefresh(lastRefresh);
assert(currentTime < lastRefresh.time);
@@ -31,7 +29,7 @@ void RefreshManager::refreshFinished(sc_time currentTime)
* 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)
bool RefreshManager::hasCollision(const CommandSchedule& schedule)
{
return true;
}
@@ -40,21 +38,19 @@ bool RefreshManager::hasCollision(CommandSchedule schedule)
* 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)
sc_time RefreshManager::getEarliestStartTime(const CommandSchedule& schedule)
{
/*stub*/
return SC_ZERO_TIME;
}
void RefreshManager::scheduleRefresh(const PlannedRefresh& refresh) const
void RefreshManager::scheduleRefresh(const ScheduledCommand& refresh) const
{
internalScheduler.scheduleCommand(ScheduledCommand(Command::Refresh, refresh.time + refresh.delay));
internalScheduler.scheduleCommand(refresh);
}
void RefreshManager::planNextRefresh(PlannedRefresh& refresh)
void RefreshManager::planNextRefresh(ScheduledCommand& refresh)
{
refresh.time += controllerConfiguration.Timings.tREF;
refresh.delay = SC_ZERO_TIME;
}
} /* namespace controller */

View File

@@ -0,0 +1,44 @@
/*
* RefreshManager.h
*
* Created on: Mar 6, 2014
* Author: jonny
*/
#ifndef REFRESHMANAGER_H_
#define REFRESHMANAGER_H_
#include <vector>
#include "core/scheduling/InternalScheduler.h"
#include "core/Configuration.h"
#include "IRefreshManager.h"
namespace controller {
class RefreshManager : public IRefreshManager
{
public:
RefreshManager(Configuration& configuration, IInternalScheduler& internalScheduler);
virtual ~RefreshManager() {}
//internal:
virtual bool hasCollision(const CommandSchedule& schedule);
virtual sc_time getEarliestStartTime(const CommandSchedule& schedule);
//external:
virtual void cb_refreshFinished(sc_time currentTime);
private:
IInternalScheduler& internalScheduler;
Configuration& controllerConfiguration;
tlm::tlm_generic_payload refreshTransaction;
ScheduledCommand lastRefresh;
void planNextRefresh(ScheduledCommand& refresh);
void scheduleRefresh(const ScheduledCommand& refresh) const;
};
} /* namespace controller */
#endif /* REFRESHMANAGER_H_ */

View File

@@ -10,7 +10,7 @@
namespace controller {
enum class Command {Precharge, PrechargeAll, Activate, Read, Write, ReadA, WriteA, Refresh, RefreshTrigger};//TODO handle RefreshTrigger Event differently
enum class Command {Precharge, PrechargeAll, Activate, Read, Write, ReadA, WriteA, Refresh};
} /* namespace controller */

View File

@@ -7,20 +7,19 @@
#include "CommandGenerator.h"
#include "common/schedulerextension.h"
#include "vector"
using namespace common;
using namespace std;
namespace controller {
vector<Command> CommandGenerator::generateCommandSequence(tlm::tlm_generic_payload& transaction)
CommandSequence CommandGenerator::generateCommandSequence(tlm::tlm_generic_payload& transaction)
{
const SchedulerExtension& extension = SchedulerExtension::getExtension(&transaction);
Bank bank = extension.getBank();
Row row = extension.getRow();
vector<Command> result;
CommandSequence result;
if (!controllerState.bankStates.rowBufferIsOpen(bank))
{
@@ -36,13 +35,13 @@ vector<Command> CommandGenerator::generateCommandSequence(tlm::tlm_generic_paylo
}
}
vector<Command> CommandGenerator::generateCommandSequence(
CommandSequence CommandGenerator::generateCommandSequence(
tlm::tlm_generic_payload* transaction)
{
return generateCommandSequence(*transaction);
}
vector<Command> CommandGenerator::getBankMissCommandSequence(tlm::tlm_generic_payload& transaction)
CommandSequence CommandGenerator::getBankMissCommandSequence(tlm::tlm_generic_payload& transaction)
{
vector<Command> result;
result.push_back(Command::Activate);
@@ -50,7 +49,7 @@ vector<Command> CommandGenerator::getBankMissCommandSequence(tlm::tlm_generic_pa
return result;
}
vector<Command> CommandGenerator::getRowMissCommandSequence(tlm::tlm_generic_payload& transaction)
CommandSequence CommandGenerator::getRowMissCommandSequence(tlm::tlm_generic_payload& transaction)
{
vector<Command> result;
result.push_back(Command::Precharge);
@@ -59,7 +58,7 @@ vector<Command> CommandGenerator::getRowMissCommandSequence(tlm::tlm_generic_pay
return result;
}
vector<Command> CommandGenerator::getRowHitCommandSequence(tlm::tlm_generic_payload& transaction)
CommandSequence CommandGenerator::getRowHitCommandSequence(tlm::tlm_generic_payload& transaction)
{
vector<Command> result;
result.push_back(getReadWriteCommand(transaction));

View File

@@ -9,26 +9,29 @@
#define COMMANDGENERATOR_H_
#include <tlm.h>
#include <vector>
#include "core/ControllerState.h"
#include "Command.h"
namespace controller {
typedef std::vector<Command> CommandSequence;
class CommandGenerator {
public:
CommandGenerator(const ControllerState& controllerState) : controllerState(controllerState) {};
virtual ~CommandGenerator() {};
std::vector<Command> generateCommandSequence(tlm::tlm_generic_payload& transaction);
std::vector<Command> generateCommandSequence(tlm::tlm_generic_payload* transaction);
CommandSequence generateCommandSequence(tlm::tlm_generic_payload& transaction);
CommandSequence generateCommandSequence(tlm::tlm_generic_payload* transaction);
private:
const ControllerState& controllerState;
Command getReadWriteCommand(tlm::tlm_generic_payload& transaction);
std::vector<Command> getBankMissCommandSequence(tlm::tlm_generic_payload& transaction);
std::vector<Command> getRowMissCommandSequence(tlm::tlm_generic_payload& transaction);
std::vector<Command> getRowHitCommandSequence(tlm::tlm_generic_payload& transaction);
CommandSequence getBankMissCommandSequence(tlm::tlm_generic_payload& transaction);
CommandSequence getRowMissCommandSequence(tlm::tlm_generic_payload& transaction);
CommandSequence getRowHitCommandSequence(tlm::tlm_generic_payload& transaction);
};
} /* namespace controller */

View File

@@ -11,12 +11,15 @@
#include <vector>
#include <systemc.h>
#include "Command.h"
#include "common/schedulerextension.h"
namespace controller {
struct ScheduledCommand{
ScheduledCommand(Command command, sc_time time) : command(command), time(time){};
ScheduledCommand(const tlm::tlm_generic_payload& transaction, Command command, sc_time time) : transaction(transaction), command(command), time(time){};
const tlm::tlm_generic_payload& transaction;
Command command;
sc_time time;

View File

@@ -0,0 +1,23 @@
/*
* CommandSequenceScheduler.cpp
*
* Created on: Mar 9, 2014
* Author: jonny
*/
#include <core/scheduling/CommandSequenceScheduler.h>
namespace controller {
CommandSequenceScheduler::CommandSequenceScheduler()
{
// TODO Auto-generated constructor stub
}
CommandSequenceScheduler::~CommandSequenceScheduler()
{
// TODO Auto-generated destructor stub
}
} /* namespace controller */

View File

@@ -0,0 +1,22 @@
/*
* CommandSequenceScheduler.h
*
* Created on: Mar 9, 2014
* Author: jonny
*/
#ifndef COMMANDSEQUENCESCHEDULER_H_
#define COMMANDSEQUENCESCHEDULER_H_
namespace controller {
class CommandSequenceScheduler
{
public:
CommandSequenceScheduler();
virtual ~CommandSequenceScheduler();
};
} /* namespace controller */
#endif /* COMMANDSEQUENCESCHEDULER_H_ */

View File

@@ -0,0 +1,27 @@
/*
* InternalScheduler.cpp
*
* Created on: Mar 9, 2014
* Author: jonny
*/
#include "InternalScheduler.h"
namespace controller {
void InternalScheduler::scheduleCommand(const ScheduledCommand& command)
{
if(command.command == Command::Refresh)
{
scheduleRefresh(command);
}
}
void InternalScheduler::scheduleRefresh(const ScheduledCommand& command)
{
state.bankStates.closeAllRowBuffers();
}
} /* namespace controller */

View File

@@ -9,14 +9,28 @@
#define INTERNALSCHEDULER_H_
#include "CommandSchedule.h"
#include "core/ControllerState.h"
class InternalScheduler
namespace controller{
class IInternalScheduler
{
public:
virtual ~InternalScheduler() {}
virtual void scheduleCommand(controller::ScheduledCommand command) = 0;
virtual ~IInternalScheduler() {}
virtual void scheduleCommand(const controller::ScheduledCommand& command) = 0;
};
class InternalScheduler : public IInternalScheduler
{
public:
InternalScheduler(controller::ControllerState& state) : state(state) {}
virtual void scheduleCommand(const controller::ScheduledCommand& command);
private:
controller::ControllerState& state;
void scheduleRefresh(const controller::ScheduledCommand& command);
};
}
#endif /* INTERNALSCHEDULER_H_ */

View File

@@ -0,0 +1,12 @@
/*
* CommandSequenceScheduler_test.cpp
*
* Created on: Mar 9, 2014
* Author: jonny
*/
#include <core/scheduling/CommandSequenceScheduler.h>
namespace controller {
} /* namespace controller */

View File

@@ -0,0 +1,12 @@
/*
* PowerDownManager_test.cpp
*
* Created on: Mar 9, 2014
* Author: jonny
*/
#include <core/PowerDownManager.h>
namespace controller {
} /* namespace controller */

View File

@@ -7,18 +7,20 @@
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "core/RefreshManager.h"
#include "core/refresh/RefreshManager.h"
using ::testing::_;
using ::testing::AtLeast;
using ::testing::Expectation;
constexpr unsigned int numberOfBanks = 8;
namespace controller {
class MockInternalScheduler: public InternalScheduler
class MockInternalScheduler: public IInternalScheduler
{
public:
MOCK_METHOD1(scheduleCommand, void (ScheduledCommand command));
MOCK_METHOD1(scheduleCommand, void (const ScheduledCommand& command));
};
TEST(RefreshManager, RefreshIsScheduledAfterStartup)
@@ -26,7 +28,8 @@ TEST(RefreshManager, RefreshIsScheduledAfterStartup)
Configuration config;
MockInternalScheduler internalScheduler;
auto init = ScheduledCommand(Command::Refresh, config.Timings.tREF);
tlm::tlm_generic_payload trans;
auto init = ScheduledCommand(trans, Command::Refresh, config.Timings.tREF);
EXPECT_CALL(internalScheduler, scheduleCommand(init));
@@ -43,7 +46,7 @@ TEST(RefreshManager, FinishedRefreshTriggersNewRefresh)
//schedule first refresh in constructor
RefreshManager manager(config, internalScheduler);
//schedule second refresh in callback (end_refresh)
manager.refreshFinished(config.Timings.tREF + config.Timings.tREFA);
manager.cb_refreshFinished(config.Timings.tREF + config.Timings.tREFA);
}
} /* namespace controller */