New RefreshManager logic. A refresh trigger is introduced, which is
scheduled in the future to trigger a schedule of a refresh command. This allows for more sophisticated refresh logics in the futurer (postponing).
This commit is contained in:
@@ -19,12 +19,6 @@ struct Configuration
|
||||
TimingConfiguration Timings;
|
||||
|
||||
bool RefreshBankwise = false;
|
||||
|
||||
unsigned int getStartAddress(int bank)//TODO utils??
|
||||
{
|
||||
//return ColumnSize * BytesSize;???
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace controller */
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#define CONTROLLER_H_
|
||||
|
||||
#include <tlm.h>
|
||||
#include "scheduling/CommandGenerator.h"
|
||||
#include "scheduling/CommandSequenceGenerator.h"
|
||||
#include "scheduling/InternalScheduler.h"
|
||||
#include "Configuration.h"
|
||||
#include "scheduling/CommandSequenceScheduler.h"
|
||||
@@ -30,7 +30,7 @@ private:
|
||||
Configuration config;
|
||||
ControllerState state;
|
||||
|
||||
CommandGenerator commandGenerator;
|
||||
CommandSequenceGenerator commandGenerator;
|
||||
CommandSequenceScheduler commandSequenceScheduler;
|
||||
RefreshManager refreshManager;
|
||||
PowerDownManager powerDownManager;
|
||||
|
||||
@@ -12,8 +12,26 @@
|
||||
|
||||
namespace controller{
|
||||
|
||||
struct RefreshTiming
|
||||
{
|
||||
RefreshTiming(sc_time tRFC, sc_time tREFI) : tRFC(tRFC), tREFI(tREFI) {}
|
||||
sc_time tRFC;
|
||||
sc_time tREFI;
|
||||
};
|
||||
|
||||
struct TimingConfiguration
|
||||
{
|
||||
TimingConfiguration()
|
||||
{
|
||||
unsigned int numberOfBanks = 8;
|
||||
for (unsigned int i = 0; i < numberOfBanks; ++i)
|
||||
{
|
||||
sc_time tRFC = 18*clk;
|
||||
sc_time tREFI = sc_time(15.6, SC_US); //TODO align
|
||||
refreshTimings.push_back(RefreshTiming(tRFC, tREFI));
|
||||
}
|
||||
}
|
||||
|
||||
sc_time clk = sc_time(6.0, SC_NS); // 166MHz
|
||||
|
||||
|
||||
@@ -22,12 +40,14 @@ struct TimingConfiguration
|
||||
sc_time tRC = tRP + tRAS;
|
||||
|
||||
//Refresh
|
||||
sc_time tRFC = 18*clk;
|
||||
sc_time tREF = sc_time(64, SC_MS);
|
||||
sc_time tREFA = tRP + tRFC;
|
||||
sc_time tREFB = tRP + tRC;
|
||||
//sc_time tRFC = 18*clk;
|
||||
//sc_time tREF = sc_time(64, SC_MS);
|
||||
//sc_time tREFA = tRP + tRFC;
|
||||
//sc_time tREFB = tRP + tRC;
|
||||
|
||||
sc_time tREFI = tREFA;
|
||||
//sc_time tREFI = tREFA;
|
||||
|
||||
std::vector<RefreshTiming> refreshTimings;
|
||||
|
||||
};
|
||||
|
||||
|
||||
15
DRAM/src/core/Utils.cpp
Normal file
15
DRAM/src/core/Utils.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Utils.cpp
|
||||
*
|
||||
* Created on: Mar 12, 2014
|
||||
* Author: jonny
|
||||
*/
|
||||
|
||||
#include "Utils.h"
|
||||
|
||||
using namespace common;
|
||||
|
||||
unsigned int getStartAddress(Bank bank)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
16
DRAM/src/core/Utils.h
Normal file
16
DRAM/src/core/Utils.h
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Utils.h
|
||||
*
|
||||
* Created on: Mar 10, 2014
|
||||
* Author: jonny
|
||||
*/
|
||||
|
||||
#ifndef UTILS_H_
|
||||
#define UTILS_H_
|
||||
|
||||
#include "common/dramextension.h"
|
||||
|
||||
unsigned int getStartAddress(common::Bank bank);
|
||||
|
||||
|
||||
#endif /* UTILS_H_ */
|
||||
@@ -7,56 +7,36 @@
|
||||
|
||||
#include <core/refresh/BankwiseRefreshManager.h>
|
||||
|
||||
using namespace common;
|
||||
using namespace std;
|
||||
|
||||
namespace controller {
|
||||
|
||||
BankwiseRefreshManager::BankwiseRefreshManager(Configuration& configuration, IInternalScheduler& internalScheduler) : controllerConfiguration(configuration), internalScheduler(internalScheduler), refreshTransactions(configuration.numberOfBanks), lastRefreshs()
|
||||
/*
|
||||
BankwiseRefreshManager::BankwiseRefreshManager(vector<RefreshTiming> refreshTimings,
|
||||
IInternalScheduler& internalScheduler)
|
||||
{
|
||||
lastRefreshs.reserve(configuration.numberOfBanks);
|
||||
for (unsigned int i = 0; i < configuration.numberOfBanks; ++i)
|
||||
assert(!refreshTimings.empty());
|
||||
|
||||
for (unsigned int i = 0; i < refreshTimings.size(); ++i)
|
||||
{
|
||||
tlm::tlm_generic_payload& transaction = refreshTransactions[i];
|
||||
//setup
|
||||
lastRefreshs.push_back(ScheduledCommand(transaction, Command::Refresh, SC_ZERO_TIME));
|
||||
RefreshManager manager(refreshTimings.at(i), internalScheduler, Bank(i));
|
||||
refreshManagerForBanks.push_back(&manager);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
BankwiseRefreshManager::~BankwiseRefreshManager()
|
||||
{
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
||||
bool BankwiseRefreshManager::hasCollision(const CommandSchedule& schedule)
|
||||
{
|
||||
RefreshManager& manager = refreshManagerForBanks.at(schedule.getBank().ID());
|
||||
return manager.hasCollision(schedule);
|
||||
}
|
||||
|
||||
sc_time BankwiseRefreshManager::getEarliestStartTime(const CommandSchedule& schedule)
|
||||
void BankwiseRefreshManager::scheduleRefresh(sc_time time)
|
||||
{
|
||||
}
|
||||
|
||||
void BankwiseRefreshManager::cb_refreshFinished(tlm::tlm_generic_payload& transaction,
|
||||
sc_time currentTime)
|
||||
{
|
||||
}
|
||||
|
||||
void BankwiseRefreshManager::planNextRefresh(ScheduledCommand& refresh)
|
||||
{
|
||||
}
|
||||
|
||||
void BankwiseRefreshManager::scheduleRefresh(const ScheduledCommand& refresh) const
|
||||
{
|
||||
}
|
||||
|
||||
void BankwiseRefreshManager::setupTransaction(unsigned int i)
|
||||
{
|
||||
refreshTransactions[i].set_address(controllerConfiguration.getStartAddress(i));
|
||||
refreshTransactions[i].set_command(tlm::TLM_READ_COMMAND);
|
||||
refreshTransactions[i].set_data_length(0);
|
||||
refreshTransactions[i].set_response_status(tlm::TLM_OK_RESPONSE);
|
||||
refreshTransactions[i].set_dmi_allowed(false);
|
||||
refreshTransactions[i].set_byte_enable_length(0);
|
||||
refreshTransactions[i].set_streaming_width(0);
|
||||
}
|
||||
for (unsigned int i = 0; i < refreshManagerForBanks.size(); ++i)
|
||||
{
|
||||
RefreshManager& manager = refreshManagerForBanks.at(i);
|
||||
manager.scheduleRefresh(time);
|
||||
}
|
||||
}*/
|
||||
|
||||
} /* namespace controller */
|
||||
|
||||
@@ -9,35 +9,25 @@
|
||||
#define BANKWISEREFRESHMANAGER_H_
|
||||
|
||||
#include "IRefreshManager.h"
|
||||
#include "common/dramextension.h"
|
||||
#include "RefreshManager.h"
|
||||
|
||||
namespace controller {
|
||||
|
||||
/*
|
||||
class BankwiseRefreshManager : public IRefreshManager
|
||||
{
|
||||
public:
|
||||
BankwiseRefreshManager(Configuration& configuration, IInternalScheduler& internalScheduler);
|
||||
virtual ~BankwiseRefreshManager();
|
||||
BankwiseRefreshManager(std::vector<RefreshTiming> refreshTimings,
|
||||
IInternalScheduler& internalScheduler);
|
||||
virtual ~BankwiseRefreshManager(){}
|
||||
|
||||
//internal:
|
||||
virtual bool hasCollision(const CommandSchedule& schedule);
|
||||
virtual sc_time getEarliestStartTime(const CommandSchedule& schedule);
|
||||
|
||||
//external:
|
||||
virtual void cb_refreshFinished(tlm::tlm_generic_payload& transaction, sc_time currentTime);
|
||||
virtual void scheduleRefresh(sc_time time);
|
||||
|
||||
private:
|
||||
Configuration& controllerConfiguration;
|
||||
IInternalScheduler& internalScheduler;
|
||||
|
||||
std::vector<tlm::tlm_generic_payload> refreshTransactions;
|
||||
std::vector<ScheduledCommand> lastRefreshs;
|
||||
|
||||
void planNextRefresh(ScheduledCommand& refresh);
|
||||
void scheduleRefresh(const ScheduledCommand& refresh) const;
|
||||
|
||||
void setupTransaction(unsigned int i);
|
||||
std::vector<RefreshManager> refreshManagerForBanks;
|
||||
};
|
||||
|
||||
*/
|
||||
} /* namespace controller */
|
||||
|
||||
#endif /* BANKWISEREFRESHMANAGER_H_ */
|
||||
|
||||
@@ -21,15 +21,8 @@ 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(tlm::tlm_generic_payload& transaction, sc_time currentTime) = 0;
|
||||
|
||||
private:
|
||||
virtual void scheduleRefresh(const ScheduledCommand& refresh) const = 0;
|
||||
virtual void scheduleRefresh(sc_time time) = 0;
|
||||
};
|
||||
|
||||
} /* namespace controller */
|
||||
|
||||
@@ -6,63 +6,79 @@
|
||||
*/
|
||||
|
||||
#include <core/refresh/RefreshManager.h>
|
||||
#include "core/Utils.h"
|
||||
|
||||
using namespace common;
|
||||
|
||||
namespace controller {
|
||||
|
||||
RefreshManager::RefreshManager(const Configuration& configuration, IInternalScheduler& internalScheduler) : controllerConfiguration(configuration), internalScheduler(internalScheduler), lastRefresh(refreshTransaction, Command::Refresh, SC_ZERO_TIME)
|
||||
RefreshManager::RefreshManager(const RefreshTiming& refreshTiming,
|
||||
IInternalScheduler& internalScheduler) :
|
||||
refreshTiming(refreshTiming), internalScheduler(internalScheduler), nextPlannedRefresh(
|
||||
refreshTransaction, Command::Refresh, SC_ZERO_TIME, refreshTiming.tRFC)
|
||||
{
|
||||
setupTransaction();
|
||||
cb_refreshFinished(refreshTransaction, SC_ZERO_TIME);
|
||||
//RefreshManager(refreshTiming, internalScheduler, Bank(0)); --> something is overwritten?
|
||||
setupTransaction(refreshTransaction, Bank(0));
|
||||
planNextRefresh(nextPlannedRefresh);
|
||||
}
|
||||
|
||||
RefreshManager::RefreshManager(const RefreshTiming& refreshTiming,
|
||||
IInternalScheduler& internalScheduler, Bank bank) :
|
||||
refreshTiming(refreshTiming), internalScheduler(internalScheduler), nextPlannedRefresh(
|
||||
refreshTransaction, Command::Refresh, sc_time(65, SC_MS), refreshTiming.tRFC)
|
||||
{
|
||||
setupTransaction(refreshTransaction, bank);
|
||||
planNextRefresh(nextPlannedRefresh);
|
||||
}
|
||||
|
||||
/*
|
||||
* Is called from TLM Wrapper when end_refresh is sent from DRAM.
|
||||
*/
|
||||
void RefreshManager::cb_refreshFinished(tlm::tlm_generic_payload& transaction, 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.
|
||||
* 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)
|
||||
{
|
||||
return true;
|
||||
if (schedule.getEnd() < nextPlannedRefresh.getStart())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
scheduleRefresh(nextPlannedRefresh);
|
||||
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(const CommandSchedule& schedule)
|
||||
void RefreshManager::scheduleRefresh(sc_time time)
|
||||
{
|
||||
return SC_ZERO_TIME;
|
||||
if (time == nextPlannedRefresh.getStart())
|
||||
scheduleRefresh(nextPlannedRefresh);
|
||||
}
|
||||
|
||||
void RefreshManager::scheduleRefresh(const ScheduledCommand& refresh) const
|
||||
void RefreshManager::scheduleRefresh(ScheduledCommand& refresh)
|
||||
{
|
||||
internalScheduler.scheduleCommand(refresh);
|
||||
planNextRefresh(refresh);
|
||||
}
|
||||
|
||||
void RefreshManager::planNextRefresh(ScheduledCommand& refresh)
|
||||
void RefreshManager::planNextRefresh(ScheduledCommand& refresh) //TODO nicer to return the reference ?
|
||||
{
|
||||
refresh.time += controllerConfiguration.Timings.tREF;
|
||||
refresh.delayStart(refreshTiming.tREFI);
|
||||
internalScheduler.scheduleTrigger(Trigger::RefreshTrigger, refresh.getStart());
|
||||
}
|
||||
|
||||
void RefreshManager::setupTransaction()
|
||||
void RefreshManager::setupTransaction(tlm::tlm_generic_payload& transaction, Bank bank)
|
||||
{
|
||||
refreshTransaction.set_address(0);
|
||||
refreshTransaction.set_command(tlm::TLM_READ_COMMAND);
|
||||
refreshTransaction.set_data_length(0);
|
||||
refreshTransaction.set_response_status(tlm::TLM_OK_RESPONSE);
|
||||
refreshTransaction.set_dmi_allowed(false);
|
||||
refreshTransaction.set_byte_enable_length(0);
|
||||
refreshTransaction.set_streaming_width(0);
|
||||
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
|
||||
}
|
||||
|
||||
} /* namespace controller */
|
||||
|
||||
@@ -9,33 +9,31 @@
|
||||
#define REFRESHMANAGER_H_
|
||||
|
||||
#include "IRefreshManager.h"
|
||||
#include "common/dramextension.h"
|
||||
|
||||
namespace controller {
|
||||
|
||||
class RefreshManager : public IRefreshManager
|
||||
{
|
||||
public:
|
||||
RefreshManager(const Configuration& configuration, IInternalScheduler& internalScheduler);
|
||||
virtual ~RefreshManager() {}
|
||||
RefreshManager(const RefreshTiming& refreshTiming, IInternalScheduler& internalScheduler);
|
||||
RefreshManager(const RefreshTiming& refreshTiming, IInternalScheduler& internalScheduler, common::Bank bank);
|
||||
virtual ~RefreshManager(){}
|
||||
|
||||
//internal:
|
||||
virtual bool hasCollision(const CommandSchedule& schedule);
|
||||
virtual sc_time getEarliestStartTime(const CommandSchedule& schedule);
|
||||
|
||||
//external:
|
||||
virtual void cb_refreshFinished(tlm::tlm_generic_payload& transaction, sc_time currentTime);
|
||||
virtual void scheduleRefresh(sc_time time);
|
||||
|
||||
private:
|
||||
const Configuration& controllerConfiguration;
|
||||
const RefreshTiming& refreshTiming;
|
||||
IInternalScheduler& internalScheduler;
|
||||
|
||||
tlm::tlm_generic_payload refreshTransaction;
|
||||
ScheduledCommand lastRefresh;
|
||||
ScheduledCommand nextPlannedRefresh;
|
||||
|
||||
void scheduleRefresh(ScheduledCommand& refresh);
|
||||
void planNextRefresh(ScheduledCommand& refresh);
|
||||
void scheduleRefresh(const ScheduledCommand& refresh) const;
|
||||
|
||||
void setupTransaction();
|
||||
void setupTransaction(tlm::tlm_generic_payload& transaction, common::Bank bank);
|
||||
};
|
||||
|
||||
} /* namespace controller */
|
||||
|
||||
@@ -12,23 +12,49 @@
|
||||
#include "common/dramextension.h"
|
||||
#include "ScheduledCommand.h"
|
||||
|
||||
using namespace common;
|
||||
|
||||
namespace controller {
|
||||
|
||||
class CommandSchedule {
|
||||
public:
|
||||
CommandSchedule();
|
||||
CommandSchedule(tlm::tlm_generic_payload& transaction) : transaction(transaction) {};
|
||||
virtual ~CommandSchedule();
|
||||
|
||||
void push_back(ScheduledCommand scheduledCommand)
|
||||
void add(Command command, sc_time time, sc_time executionTime)
|
||||
{
|
||||
scheduledCommands.push_back(scheduledCommand);
|
||||
assert(scheduledCommands.empty() || time >= scheduledCommands.back().getEnd());
|
||||
scheduledCommands.push_back(ScheduledCommand(transaction, command, time, executionTime));
|
||||
}
|
||||
|
||||
const std::vector<ScheduledCommand>& getScheduledCommands() const
|
||||
{
|
||||
return this->scheduledCommands;
|
||||
return scheduledCommands;
|
||||
}
|
||||
|
||||
sc_time getStart() const
|
||||
{
|
||||
return scheduledCommands.front().getStart();
|
||||
}
|
||||
|
||||
sc_time getEnd() const
|
||||
{
|
||||
return scheduledCommands.back().getEnd();
|
||||
}
|
||||
|
||||
sc_time getExecutionTime() const
|
||||
{
|
||||
return scheduledCommands.back().getEnd() - scheduledCommands.front().getStart();
|
||||
}
|
||||
|
||||
Bank getBank() const
|
||||
{
|
||||
return DramExtension::getExtension(&transaction).getBank();
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<ScheduledCommand> scheduledCommands;
|
||||
const tlm::tlm_generic_payload& transaction;
|
||||
};
|
||||
|
||||
} /* namespace controller */
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* CommandGenerator.cpp
|
||||
* CommandSequenceGenerator.cpp
|
||||
*
|
||||
* Created on: Mar 5, 2014
|
||||
* Author: jonny
|
||||
*/
|
||||
|
||||
#include "CommandGenerator.h"
|
||||
#include "CommandSequenceGenerator.h"
|
||||
#include "common/dramextension.h"
|
||||
|
||||
using namespace common;
|
||||
@@ -13,7 +13,7 @@ using namespace std;
|
||||
|
||||
namespace controller {
|
||||
|
||||
CommandSequence CommandGenerator::generateCommandSequence(tlm::tlm_generic_payload& transaction)
|
||||
CommandSequence CommandSequenceGenerator::generateCommandSequence(tlm::tlm_generic_payload& transaction)
|
||||
{
|
||||
const DramExtension& extension = DramExtension::getExtension(&transaction);
|
||||
Bank bank = extension.getBank();
|
||||
@@ -35,13 +35,13 @@ CommandSequence CommandGenerator::generateCommandSequence(tlm::tlm_generic_paylo
|
||||
}
|
||||
}
|
||||
|
||||
CommandSequence CommandGenerator::generateCommandSequence(
|
||||
CommandSequence CommandSequenceGenerator::generateCommandSequence(
|
||||
tlm::tlm_generic_payload* transaction)
|
||||
{
|
||||
return generateCommandSequence(*transaction);
|
||||
}
|
||||
|
||||
CommandSequence CommandGenerator::getBankMissCommandSequence(tlm::tlm_generic_payload& transaction)
|
||||
CommandSequence CommandSequenceGenerator::getBankMissCommandSequence(tlm::tlm_generic_payload& transaction)
|
||||
{
|
||||
vector<Command> result;
|
||||
result.push_back(Command::Activate);
|
||||
@@ -49,7 +49,7 @@ CommandSequence CommandGenerator::getBankMissCommandSequence(tlm::tlm_generic_pa
|
||||
return result;
|
||||
}
|
||||
|
||||
CommandSequence CommandGenerator::getRowMissCommandSequence(tlm::tlm_generic_payload& transaction)
|
||||
CommandSequence CommandSequenceGenerator::getRowMissCommandSequence(tlm::tlm_generic_payload& transaction)
|
||||
{
|
||||
vector<Command> result;
|
||||
result.push_back(Command::Precharge);
|
||||
@@ -58,14 +58,14 @@ CommandSequence CommandGenerator::getRowMissCommandSequence(tlm::tlm_generic_pay
|
||||
return result;
|
||||
}
|
||||
|
||||
CommandSequence CommandGenerator::getRowHitCommandSequence(tlm::tlm_generic_payload& transaction)
|
||||
CommandSequence CommandSequenceGenerator::getRowHitCommandSequence(tlm::tlm_generic_payload& transaction)
|
||||
{
|
||||
vector<Command> result;
|
||||
result.push_back(getReadWriteCommand(transaction));
|
||||
return result;
|
||||
}
|
||||
|
||||
Command CommandGenerator::getReadWriteCommand(tlm::tlm_generic_payload& transaction)
|
||||
Command CommandSequenceGenerator::getReadWriteCommand(tlm::tlm_generic_payload& transaction)
|
||||
{
|
||||
if (transaction.get_command() == tlm::tlm_command::TLM_READ_COMMAND)
|
||||
{
|
||||
@@ -17,10 +17,10 @@ namespace controller {
|
||||
|
||||
typedef std::vector<Command> CommandSequence;
|
||||
|
||||
class CommandGenerator {
|
||||
class CommandSequenceGenerator {
|
||||
public:
|
||||
CommandGenerator(const ControllerState& controllerState) : controllerState(controllerState) {};
|
||||
virtual ~CommandGenerator() {};
|
||||
CommandSequenceGenerator(const ControllerState& controllerState) : controllerState(controllerState) {};
|
||||
virtual ~CommandSequenceGenerator() {};
|
||||
|
||||
CommandSequence generateCommandSequence(tlm::tlm_generic_payload& transaction);
|
||||
CommandSequence generateCommandSequence(tlm::tlm_generic_payload* transaction);
|
||||
@@ -11,12 +11,17 @@ namespace controller {
|
||||
|
||||
void InternalScheduler::scheduleCommand(const ScheduledCommand& command)
|
||||
{
|
||||
if(command.command == Command::Refresh)
|
||||
if(command.getCommand() == Command::Refresh)
|
||||
{
|
||||
scheduleRefresh(command);
|
||||
}
|
||||
}
|
||||
|
||||
void InternalScheduler::scheduleTrigger(const Trigger command, sc_time time)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void InternalScheduler::scheduleRefresh(const ScheduledCommand& command)
|
||||
{
|
||||
state.bankStates.closeAllRowBuffers();
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "CommandSchedule.h"
|
||||
#include "core/ControllerState.h"
|
||||
#include "core/scheduling/Trigger.h"
|
||||
|
||||
namespace controller{
|
||||
|
||||
@@ -18,6 +19,7 @@ class IInternalScheduler
|
||||
public:
|
||||
virtual ~IInternalScheduler() {}
|
||||
virtual void scheduleCommand(const controller::ScheduledCommand& command) = 0;
|
||||
virtual void scheduleTrigger(const controller::Trigger trigger, sc_time time) = 0;
|
||||
};
|
||||
|
||||
class InternalScheduler : public IInternalScheduler
|
||||
@@ -25,6 +27,7 @@ class InternalScheduler : public IInternalScheduler
|
||||
public:
|
||||
InternalScheduler(controller::ControllerState& state) : state(state) {}
|
||||
virtual void scheduleCommand(const controller::ScheduledCommand& command);
|
||||
virtual void scheduleTrigger(const controller::Trigger trigger, sc_time time);
|
||||
|
||||
private:
|
||||
controller::ControllerState& state;
|
||||
|
||||
@@ -11,20 +11,59 @@
|
||||
#include "Command.h"
|
||||
#include <systemc.h>
|
||||
|
||||
namespace controller{
|
||||
namespace controller {
|
||||
|
||||
struct ScheduledCommand{
|
||||
ScheduledCommand(const tlm::tlm_generic_payload& transaction, Command command, sc_time time) : transaction(transaction), command(command), time(time){};
|
||||
class ScheduledCommand
|
||||
{
|
||||
public:
|
||||
ScheduledCommand(const tlm::tlm_generic_payload& transaction, Command command, sc_time time,
|
||||
sc_time executionTime) :
|
||||
transaction(transaction), command(command), start(time), executionTime(executionTime)
|
||||
{
|
||||
}
|
||||
|
||||
const tlm::tlm_generic_payload& transaction;
|
||||
Command command;
|
||||
sc_time time;
|
||||
const sc_time getStart() const
|
||||
{
|
||||
return start;
|
||||
}
|
||||
|
||||
void delayStart(sc_time delay)
|
||||
{
|
||||
start += delay;
|
||||
}
|
||||
|
||||
const sc_time getEnd() const
|
||||
{
|
||||
return start + executionTime;
|
||||
}
|
||||
|
||||
const Command getCommand() const
|
||||
{
|
||||
return command;
|
||||
}
|
||||
|
||||
const sc_time getExecutionTime() const
|
||||
{
|
||||
return executionTime;
|
||||
}
|
||||
|
||||
const tlm::tlm_generic_payload& getTransaction() const
|
||||
{
|
||||
return transaction;
|
||||
}
|
||||
|
||||
inline bool operator==(const ScheduledCommand& b) const
|
||||
{
|
||||
return b.command == command && b.time == time;
|
||||
return b.command == command && b.start == start && b.executionTime == executionTime
|
||||
&& &b.transaction == &transaction;
|
||||
}
|
||||
|
||||
private:
|
||||
const tlm::tlm_generic_payload& transaction;
|
||||
const Command command;
|
||||
sc_time start;
|
||||
const sc_time executionTime;
|
||||
|
||||
};
|
||||
|
||||
} /* namespace controller */
|
||||
|
||||
17
DRAM/src/core/scheduling/Trigger.h
Normal file
17
DRAM/src/core/scheduling/Trigger.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Trigger.h
|
||||
*
|
||||
* Created on: Mar 11, 2014
|
||||
* Author: jonny
|
||||
*/
|
||||
|
||||
#ifndef TRIGGER_H_
|
||||
#define TRIGGER_H_
|
||||
|
||||
namespace controller {
|
||||
|
||||
enum class Trigger {RefreshTrigger};
|
||||
|
||||
} /* namespace controller */
|
||||
|
||||
#endif /* TRIGGER_H_ */
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "core/scheduling/CommandGenerator.h"
|
||||
#include "core/scheduling/CommandSequenceGenerator.h"
|
||||
#include "testUtils.h"
|
||||
#include <vector>
|
||||
|
||||
@@ -12,10 +12,10 @@ constexpr unsigned int numberOfBanks = 8;
|
||||
constexpr tlm::tlm_command READ = tlm::tlm_command::TLM_READ_COMMAND;
|
||||
constexpr tlm::tlm_command WRITE = tlm::tlm_command::TLM_WRITE_COMMAND;
|
||||
|
||||
TEST(CommandGenerator, ReadAndWriteWithRowHit)
|
||||
TEST(CommandSequenceGenerator, ReadAndWriteWithRowHit)
|
||||
{
|
||||
ControllerState state(numberOfBanks);
|
||||
CommandGenerator generator(state);
|
||||
CommandSequenceGenerator generator(state);
|
||||
|
||||
state.bankStates.openRowInRowBuffer(Bank(0), Row(3));
|
||||
|
||||
@@ -30,10 +30,10 @@ TEST(CommandGenerator, ReadAndWriteWithRowHit)
|
||||
EXPECT_EQ(expected_write, generator.generateCommandSequence(hit_write.get()));
|
||||
}
|
||||
|
||||
TEST(CommandGenerator, ReadAndWriteWithRowMiss)
|
||||
TEST(CommandSequenceGenerator, ReadAndWriteWithRowMiss)
|
||||
{
|
||||
ControllerState state(numberOfBanks);
|
||||
CommandGenerator generator(state);
|
||||
CommandSequenceGenerator generator(state);
|
||||
|
||||
state.bankStates.openRowInRowBuffer(Bank(0), Row(3));
|
||||
|
||||
@@ -48,10 +48,10 @@ TEST(CommandGenerator, ReadAndWriteWithRowMiss)
|
||||
EXPECT_EQ(expected_write, generator.generateCommandSequence(miss_write.get()));
|
||||
}
|
||||
|
||||
TEST(CommandGenerator, ReadAndWriteWithBankMiss)
|
||||
TEST(CommandSequenceGenerator, ReadAndWriteWithBankMiss)
|
||||
{
|
||||
ControllerState state(numberOfBanks);
|
||||
CommandGenerator generator(state);
|
||||
CommandSequenceGenerator generator(state);
|
||||
|
||||
state.bankStates.openRowInRowBuffer(Bank(0), Row(3));
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ class MockInternalScheduler: public IInternalScheduler
|
||||
{
|
||||
public:
|
||||
MOCK_METHOD1(scheduleCommand, void (const ScheduledCommand& command));
|
||||
MOCK_METHOD2(scheduleTrigger, void (const Trigger command, sc_time time));
|
||||
};
|
||||
|
||||
TEST(RefreshManager, RefreshIsScheduledAfterStartup)
|
||||
@@ -28,12 +29,14 @@ TEST(RefreshManager, RefreshIsScheduledAfterStartup)
|
||||
Configuration config;
|
||||
MockInternalScheduler internalScheduler;
|
||||
|
||||
tlm::tlm_generic_payload trans;
|
||||
auto init = ScheduledCommand(trans, Command::Refresh, config.Timings.tREF);
|
||||
EXPECT_CALL(internalScheduler, scheduleTrigger(Trigger::RefreshTrigger, _)).Times(2);
|
||||
EXPECT_CALL(internalScheduler, scheduleCommand(_));
|
||||
|
||||
EXPECT_CALL(internalScheduler, scheduleCommand(init));
|
||||
//first trigger is scheduled
|
||||
RefreshManager manager(config.Timings.refreshTimings.at(0), internalScheduler);
|
||||
|
||||
RefreshManager manager(config, internalScheduler);
|
||||
//first refresh is scheduled, second trigger is scheduled
|
||||
manager.scheduleRefresh(config.Timings.refreshTimings.at(0).tREFI);//call back from wrapper
|
||||
}
|
||||
|
||||
TEST(RefreshManager, FinishedRefreshTriggersNewRefresh)
|
||||
@@ -43,11 +46,14 @@ TEST(RefreshManager, FinishedRefreshTriggersNewRefresh)
|
||||
|
||||
EXPECT_CALL(internalScheduler, scheduleCommand(_)).Times(2);
|
||||
|
||||
//schedule first refresh in constructor
|
||||
RefreshManager manager(config, internalScheduler);
|
||||
//schedule second refresh in callback (end_refresh)
|
||||
tlm::tlm_generic_payload trans;
|
||||
manager.cb_refreshFinished(trans, config.Timings.tREF + config.Timings.tREFA);
|
||||
//first trigger is scheduled
|
||||
RefreshManager manager(config.Timings.refreshTimings.at(0), internalScheduler);
|
||||
|
||||
//first refresh is scheduled at tREFI (wrapper triggers), second trigger is scheduled
|
||||
manager.scheduleRefresh(config.Timings.refreshTimings.at(0).tREFI);//call back from wrapper
|
||||
|
||||
//second trigger should schedule second refresh (wrapper triggers)
|
||||
manager.scheduleRefresh(config.Timings.refreshTimings.at(0).tREFI * 2);
|
||||
}
|
||||
|
||||
} /* namespace controller */
|
||||
|
||||
Reference in New Issue
Block a user