This commit is contained in:
Janik Schlemminger
2014-03-19 10:09:09 +01:00
parent 39d059ee13
commit 23076bcf7d
32 changed files with 311 additions and 328 deletions

View File

@@ -3,7 +3,6 @@
<name>dram</name> <name>dram</name>
<comment></comment> <comment></comment>
<projects> <projects>
<project>common</project>
</projects> </projects>
<buildSpec> <buildSpec>
<buildCommand> <buildCommand>

View File

@@ -10,150 +10,112 @@
namespace core { namespace core {
void CommandBus::schedule(const CommandSchedule& schedule) void CommandBus::schedule(ScheduledCommand& command)
{ {
const std::vector<ScheduledCommand>& commands = schedule.getScheduledCommands();
for (std::vector<ScheduledCommand>::const_iterator it = commands.begin(); it != commands.end(); scheduleOnBus(command);
++it)
{
scheduleCommand(*it);
}
}
void CommandBus::scheduleCommand(const ScheduledCommand& command)
{
assert(!pendingBusCommands.count(command.getStart()));
//TODO state change in state!!
changeControllerState(command); changeControllerState(command);
pendingBusCommands.insert(command.getStart()); state.pendingBusCommands.insert(command.getStart());
notifyAllCheckersAboutScheduledCommand(command); state.lastCommandsOnBus[command.getCommand()][command.getBank()] = command;
state.lastCommandsOnBus[command.getCommand()][command.getBank()].invalidateTransaction();
wrapper.sendCommand(command.getStart(), command.getTransaction(), command.getCommand()); if(command.getCommand() == Activate)
lastCommandsOnBus[command.getCommand()][command.getBank()] = command;
lastCommandsOnBus[command.getCommand()][command.getBank()].invalidateTransaction();
}
void CommandBus::notifyAllCheckersAboutScheduledCommand(const ScheduledCommand& command)
{
for (std::vector<ICommandChecker*>::iterator it = checker.begin(); it != checker.end(); ++it)
{ {
(*it)->notifyAboutScheduledCommand(command); state.nActivateWindow.put(command.getStart());
} }
} }
void CommandBus::scheduleTrigger(const Trigger command, sc_time time) void CommandBus::scheduleOnBus(ScheduledCommand& command)
{ {
wrapper.sendTrigger(time, command); //TODO write nicer
} sc_time newStart = command.getStart();
assert(isClkAligned(newStart, config.Timings.clk));
std::set<sc_time>::iterator it = state.pendingBusCommands.begin();
ScheduledCommand CommandBus::getLastCommand(Command command, Bank bank) while (it != state.pendingBusCommands.end() && *it <= newStart)
{
return lastCommandsOnBus[command][bank];
}
ScheduledCommand CommandBus::getLastCommand(Command command)
{
ScheduledCommand max;
for (unsigned int i = 0; i < config.numberOfBanks; ++i)
{ {
const ScheduledCommand& current = getLastCommand(command, Bank(i)); if (*it == newStart)
if (current.getStart() > max.getStart()) newStart += config.Timings.clk;
max = current; ++it;
} }
return max; command.setStart(newStart);
} }
ScheduledCommand CommandBus::getLastCommand(Bank bank) void CommandBus::send(const Trigger trigger, sc_time time) const
{ {
ScheduledCommand lastCommand; wrapperConnector.send(trigger, time);
for(std::map<Command, std::map<Bank, ScheduledCommand> >::iterator it = lastCommandsOnBus.begin(); it != lastCommandsOnBus.end(); ++it)
{
ScheduledCommand& current = lastCommandsOnBus[it->first][bank];
if(current.getStart() > lastCommand.getStart())
lastCommand = current;
}
return lastCommand;
} }
bool CommandBus::notYetScheduled(Command command) const void CommandBus::send(const ScheduledCommand& command) const
{ {
return (lastCommandsOnBus.count(command) == 0); wrapperConnector.send(command);
} }
bool CommandBus::notYetScheduled(Command command, Bank bank) const void CommandBus::send(const CommandSchedule& schedule) const
{ {
return (notYetScheduled(command) || lastCommandsOnBus.find(command)->second.count(bank) == 0); for(const ScheduledCommand& cmd : schedule.getScheduledCommands())
} {
send(cmd);
sc_time CommandBus::getEarliestStartTime(const ScheduledCommand& command) const }
{ }
sc_time newStart = command.getStart();
assert(isClkAligned(newStart, config.Timings.clk));
std::set<sc_time>::iterator it = pendingBusCommands.begin();
while (it != pendingBusCommands.end() && *it <= newStart)
{
if (*it == newStart)
newStart += config.Timings.clk;
++it;
}
return newStart;
}
void CommandBus::cleanUpBus(sc_time currentTime) void CommandBus::cleanUpBus(sc_time currentTime)
{ {
pendingBusCommands.erase(pendingBusCommands.begin(), pendingBusCommands.lower_bound(currentTime)); state.pendingBusCommands.erase(state.pendingBusCommands.begin(),
state.pendingBusCommands.lower_bound(currentTime));
} }
void CommandBus::changeControllerState(const ScheduledCommand& command) void CommandBus::changeControllerState(const ScheduledCommand& command)
{ {
switch (command.getCommand()) switch (command.getCommand())
{ {
case Refresh: case Refresh:
refresh(command); refresh(command);
break; break;
case Activate: case Activate:
activate(command); activate(command);
break; break;
case Precharge: case Precharge:
precharge(command); precharge(command);
default: default:
break; break;
} }
} }
void CommandBus::refresh(const ScheduledCommand& command) void CommandBus::refresh(const ScheduledCommand& command)
{ {
if (config.RefreshBankwise) if (config.RefreshBankwise)
{ {
state.bankStates.closeRowBuffer(command.getBank()); state.bankStates.closeRowBuffer(command.getBank());
} }
else else
{ {
state.bankStates.closeAllRowBuffers(); state.bankStates.closeAllRowBuffers();
} }
} }
void CommandBus::precharge(const ScheduledCommand& command) void CommandBus::precharge(const ScheduledCommand& command)
{ {
if (command.getCommand() == Precharge) if (command.getCommand() == Precharge)
{ {
state.bankStates.closeRowBuffer(command.getBank()); state.bankStates.closeRowBuffer(command.getBank());
} }
else if (command.getCommand() == PrechargeAll) else if (command.getCommand() == PrechargeAll)
{ {
state.bankStates.closeAllRowBuffers(); state.bankStates.closeAllRowBuffers();
} }
} }
void CommandBus::activate(const ScheduledCommand& command) void CommandBus::activate(const ScheduledCommand& command)
{ {
if (command.getCommand() == Activate) if (command.getCommand() == Activate)
{ {
state.bankStates.openRowInRowBuffer(command.getBank(), command.getRow()); state.bankStates.openRowInRowBuffer(command.getBank(), command.getRow());
} }
} }
} /* namespace controller */ } /* namespace controller */

View File

@@ -10,9 +10,8 @@
#include <map> #include <map>
#include <set> #include <set>
#include "../tlm/IControllerWrapper.h"
#include "ControllerState.h" #include "ControllerState.h"
#include "IInternalScheduler.h" #include "IWrapperConnector.h"
#include "Configuration.h" #include "Configuration.h"
#include "scheduling/CommandSchedule.h" #include "scheduling/CommandSchedule.h"
#include "scheduling/Trigger.h" #include "scheduling/Trigger.h"
@@ -20,49 +19,36 @@
namespace core { namespace core {
class CommandBus: public IInternalScheduler class CommandBus
{ {
public: public:
CommandBus(const Configuration& config, core::ControllerState& state, CommandBus(IWrapperConnector& wrapperConnector, const Configuration& config, ControllerState& state):
std::vector<ICommandChecker*>& checker, IControllerWrapper& wrapper): wrapperConnector(wrapperConnector), config(config), state(state)
wrapper(wrapper), config(config), state(state), checker(checker)
{ {
} }
virtual void schedule(const CommandSchedule& schedule); //TODO add to interface ~CommandBus(){}
virtual void scheduleCommand(const ScheduledCommand& command);
virtual void scheduleTrigger(const Trigger trigger, sc_time time);
void schedule(ScheduledCommand& command);
void send(const ScheduledCommand& command) const;
void send(const Trigger trigger, sc_time time) const;
void send(const CommandSchedule& schedule) const;
void cleanUpBus(sc_time currentTime); void cleanUpBus(sc_time currentTime);
ScheduledCommand getLastCommand(Command command, Bank bank); //TODO simple way to make it const?
ScheduledCommand getLastCommand(Command command);
ScheduledCommand getLastCommand(Bank bank);
bool notYetScheduled(Command command) const;
bool notYetScheduled(Command command, Bank bank) const;
sc_time getEarliestStartTime(const ScheduledCommand& command) const;
const std::set<sc_time>& getPendingBusCommands() const
{
return pendingBusCommands;
}
private: private:
IControllerWrapper& wrapper; IWrapperConnector& wrapperConnector;
const Configuration& config; const Configuration& config;
core::ControllerState& state; core::ControllerState& state;
std::vector<ICommandChecker*>& checker;
std::map<Command, std::map<Bank, ScheduledCommand> > lastCommandsOnBus;
std::set<sc_time> pendingBusCommands;
void notifyAllCheckersAboutScheduledCommand(const ScheduledCommand& command);
void changeControllerState(const ScheduledCommand& command); void changeControllerState(const ScheduledCommand& command);
void refresh(const ScheduledCommand& command); void refresh(const ScheduledCommand& command);
void precharge(const ScheduledCommand& command); void precharge(const ScheduledCommand& command);
void activate(const ScheduledCommand& command); void activate(const ScheduledCommand& command);
void scheduleOnBus(ScheduledCommand& command);
}; };
} }
#endif /* INTERNALSCHEDULER_H_ */ #endif /* INTERNALSCHEDULER_H_ */

View File

@@ -14,24 +14,34 @@
namespace core { namespace core {
DramController::DramController(IControllerWrapper& wrapper): DramController::DramController(IWrapperConnector& wrapperConnector):
config(),state(config.numberOfBanks), commandSequenceGenerator(state), commandChecker(),allCommandChecker(),commandSequenceScheduler( config(),state(config.numberOfBanks, config.nActivate), savedState(config.numberOfBanks, config.nActivate), commandSequenceGenerator(state), commandChecker(), commandSequenceScheduler(
commandChecker), bus(config, state, allCommandChecker, wrapper), refreshManager(config.Timings.refreshTimings[0], bus) bus, commandChecker), bus(wrapperConnector, config, state), refreshManager(bus, config.Timings.refreshTimings[0])
{ {
addCommandChecker(Activate, new ActivateChecker(config, bus)); commandChecker[Activate] = new ActivateChecker(config, state);
addCommandChecker(Precharge, new PrechargeChecker(config, bus));
addCommandChecker(Read, new ReadChecker(config, bus)); commandChecker[Precharge] = new PrechargeChecker(config, state);
addCommandChecker(Write, new WriteChecker(config, bus)); commandChecker[Read] = new ReadChecker(config, state);
commandChecker[Write] = new WriteChecker(config, state);
} }
DramController::~DramController() DramController::~DramController()
{ {
for (std::vector<ICommandChecker*>::iterator it = allCommandChecker.begin(); it != allCommandChecker.end();++it) delete commandChecker[Activate];
{ delete commandChecker[Precharge];
delete *it; delete commandChecker[Read];
} delete commandChecker[Write];
}
void DramController::saveState()
{
savedState = state;
}
void DramController::resetState()
{
state = savedState;
} }
void DramController::scheduleRefresh(sc_time time) void DramController::scheduleRefresh(sc_time time)
@@ -39,41 +49,43 @@ void DramController::scheduleRefresh(sc_time time)
refreshManager.scheduleRefresh(time); refreshManager.scheduleRefresh(time);
} }
void DramController::addCommandChecker(Command command, ICommandChecker* checker) void DramController::schedule(sc_time start, tlm::tlm_generic_payload& payload)
{ {
commandChecker[command] = checker; bus.cleanUpBus(start);
allCommandChecker.push_back(checker);
}
start = clkAlign(start, config.Timings.clk);
void DramController::schedule(sc_time currentTime, tlm::tlm_generic_payload& payload)
{
bus.cleanUpBus(currentTime);
payload.set_streaming_width(config.burstlength); payload.set_streaming_width(config.burstlength);
saveState();
CommandSequence sequence = commandSequenceGenerator.generateCommandSequence( CommandSequence sequence = commandSequenceGenerator.generateCommandSequence(
payload); payload);
CommandSchedule schedule = commandSequenceScheduler.prepareSchedule(currentTime, CommandSchedule schedule = commandSequenceScheduler.schedule(sequence, start, payload);
payload, sequence);
//commandbuschecker (schedule)
while (refreshManager.hasCollision(schedule)) while (refreshManager.hasCollision(schedule))
{ {
refreshManager.scheduleRefresh(currentTime); resetState();
refreshManager.scheduleRefresh(start);
saveState();
sequence = commandSequenceGenerator.generateCommandSequence(payload); sequence = commandSequenceGenerator.generateCommandSequence(payload);
schedule = commandSequenceScheduler.prepareSchedule(currentTime, payload, schedule = commandSequenceScheduler.schedule(sequence, start, payload);
sequence);
assert(schedule.getExecutionTime() < config.Timings.refreshTimings[0].tREFI); //TODO make nice assert(schedule.getExecutionTime() < config.Timings.refreshTimings[0].tREFI); //TODO make nice
} }
bus.schedule(schedule); bus.send(schedule);
} }
const ICommandChecker& DramController::getChecker(Command command) const
/*const ICommandChecker& DramController::getChecker(Command command) const
{ {
std::map<Command, ICommandChecker*>::const_iterator result = commandChecker.find(command); std::map<Command, ICommandChecker*>::const_iterator result = commandChecker.find(command);
assert(result != commandChecker.end()); assert(result != commandChecker.end());
return *(result->second); return *(result->second);
} }*/
} /* namespace controller */ } /* namespace controller */

View File

@@ -10,7 +10,7 @@
#include <tlm.h> #include <tlm.h>
#include <map> #include <map>
#include "../tlm/IControllerWrapper.h" #include "IWrapperConnector.h"
#include "CommandBus.h" #include "CommandBus.h"
#include "Configuration.h" #include "Configuration.h"
#include "powerdown/PowerDownManager.h" #include "powerdown/PowerDownManager.h"
@@ -24,24 +24,29 @@ namespace core {
class DramController class DramController
{ {
public: public:
DramController(IControllerWrapper& wrapper); DramController(IWrapperConnector& wrapper);
virtual ~DramController() ; virtual ~DramController() ;
void schedule(sc_time currentTime, tlm::tlm_generic_payload& externalTransaction); void schedule(sc_time currentTime, tlm::tlm_generic_payload& payload);
void scheduleRefresh(sc_time time); void scheduleRefresh(sc_time time);
const ICommandChecker& getChecker(Command command) const; const ICommandChecker& getChecker(Command command) const;
Configuration config; Configuration config;
void saveState();
void resetState();
private: private:
ControllerState state; ControllerState state;
ControllerState savedState;
CommandSequenceGenerator commandSequenceGenerator; CommandSequenceGenerator commandSequenceGenerator;
std::map<Command, ICommandChecker*> commandChecker; std::map<Command, ICommandChecker*> commandChecker;
std::vector<ICommandChecker*> allCommandChecker;
CommandSequenceScheduler commandSequenceScheduler; CommandSequenceScheduler commandSequenceScheduler;
//PowerDownManager powerDownManager;
CommandBus bus; CommandBus bus;
RefreshManager refreshManager; RefreshManager refreshManager;
//std::vector<ICommandChecker*> allCommandChecker;
//PowerDownManager powerDownManager;
void addCommandChecker(Command command, ICommandChecker* checker); void addCommandChecker(Command command, ICommandChecker* checker);
}; };

View File

@@ -9,13 +9,35 @@
namespace core { namespace core {
ControllerState::ControllerState(unsigned int numberOfBanks) : bankStates(numberOfBanks) const ScheduledCommand ControllerState::getLastCommand(Command command, Bank bank) //TODO const reference? and make const
{ {
return lastCommandsOnBus[command][bank];
} }
ControllerState::~ControllerState() { const ScheduledCommand ControllerState::getLastCommand(Command command)
// TODO Auto-generated destructor stub {
ScheduledCommand max;
for (unsigned int i = 0; i < bankStates.getNumberOfBanks(); ++i)
{
ScheduledCommand current = getLastCommand(command, Bank(i));
if (current.getStart() > max.getStart())
max = current;
}
return max;
}
const ScheduledCommand ControllerState::getLastCommand(Bank bank)
{
ScheduledCommand lastCommand;
for (std::map<Command, std::map<Bank, ScheduledCommand> >::iterator it =
lastCommandsOnBus.begin(); it != lastCommandsOnBus.end(); ++it)
{
ScheduledCommand& current = lastCommandsOnBus[it->first][bank];
if (current.getStart() > lastCommand.getStart())
lastCommand = current;
}
return lastCommand;
} }
} /* namespace controller */ } /* namespace controller */

View File

@@ -8,16 +8,33 @@
#ifndef CONTROLLER_STATE_H_ #ifndef CONTROLLER_STATE_H_
#define CONTROLLER_STATE_H_ #define CONTROLLER_STATE_H_
#include <systemc.h>
#include "common/BankStates.h" #include "common/BankStates.h"
#include "utils/RingBuffer.h"
#include "scheduling/ScheduledCommand.h"
#include <map>
#include <set>
#include <vector>
namespace core { namespace core {
class ControllerState { class ControllerState {
public: public:
ControllerState(unsigned int numberOfBanks); ControllerState(unsigned int numberOfBanks, unsigned int nActivates) : bankStates(numberOfBanks), nActivateWindow(nActivates){}
virtual ~ControllerState(); virtual ~ControllerState(){}
const ScheduledCommand getLastCommand(Command command, Bank bank);
const ScheduledCommand getLastCommand(Command command);
const ScheduledCommand getLastCommand(Bank bank);
BankStates bankStates; BankStates bankStates;
RingBuffer<sc_time> nActivateWindow;
std::vector<sc_time> nACT;
std::map<Command, std::map<Bank, ScheduledCommand> > lastCommandsOnBus;
std::set<sc_time> pendingBusCommands;
private:
}; };
} /* namespace controller */ } /* namespace controller */

View File

@@ -10,16 +10,19 @@
#include <systemc.h> #include <systemc.h>
#include "scheduling/ScheduledCommand.h" #include "scheduling/ScheduledCommand.h"
#include "scheduling/Trigger.h"
namespace core namespace core
{ {
class IInternalScheduler
class IWrapperConnector
{ {
public: public:
virtual ~IInternalScheduler() {} virtual ~IWrapperConnector() {}
virtual void scheduleCommand(const core::ScheduledCommand& command) = 0; virtual void send(const core::ScheduledCommand& command) = 0;
virtual void scheduleTrigger(const core::Trigger trigger, sc_time time) = 0; virtual void send(core::Trigger trigger, sc_time time) = 0;
}; };
} }
#endif /* IINTERNALSCHEDULER_H_ */ #endif /* IINTERNALSCHEDULER_H_ */

View File

@@ -24,14 +24,17 @@ struct TimingConfiguration
{ {
TimingConfiguration(unsigned int numberOfBanks) TimingConfiguration(unsigned int numberOfBanks)
{ {
clk = sc_time(6.0, SC_NS); // 166MHz
for (unsigned int i = 0; i < numberOfBanks; ++i) for (unsigned int i = 0; i < numberOfBanks; ++i)
{ {
sc_time tRFC = 18*clk; sc_time tRFC = 18*clk;
sc_time tREFI = sc_time(15.6, SC_US); //TODO align sc_time tREFI = sc_time(15.6, SC_US); //TODO align
//tREFI = sc_time(301268, SC_NS);
refreshTimings.push_back(RefreshTiming(tRFC, tREFI)); refreshTimings.push_back(RefreshTiming(tRFC, tREFI));
} }
clk = sc_time(6.0, SC_NS); // 166MHz
tRP = 3*clk; //precharge-time (pre -> act same bank) tRP = 3*clk; //precharge-time (pre -> act same bank)
tRAS = 6*clk; //active-time (act -> pre same bank) tRAS = 6*clk; //active-time (act -> pre same bank)
@@ -42,7 +45,7 @@ struct TimingConfiguration
tRL = 3*clk; //read latency (read command start to data strobe) tRL = 3*clk; //read latency (read command start to data strobe)
tTAW = clkAlign(sc_time(50, SC_NS), clk); //two activate window tTAW = clkAlign(sc_time(50, SC_NS), clk, DOWN); //two activate window
} }
sc_time clk; sc_time clk;

View File

@@ -11,14 +11,13 @@ using namespace std;
namespace core { namespace core {
BankwiseRefreshManager::BankwiseRefreshManager(vector<RefreshTiming> refreshTimings, BankwiseRefreshManager::BankwiseRefreshManager(CommandBus& bus, vector<RefreshTiming> refreshTimings)
IInternalScheduler& internalScheduler)
{ {
assert(!refreshTimings.empty()); assert(!refreshTimings.empty());
for (unsigned int i = 0; i < refreshTimings.size(); ++i) for (unsigned int i = 0; i < refreshTimings.size(); ++i)
{ {
RefreshManager* manager = new RefreshManager(refreshTimings.at(i), internalScheduler, Bank(i)); RefreshManager* manager = new RefreshManager(bus, refreshTimings.at(i), Bank(i));
refreshManagerForBanks.push_back(manager); refreshManagerForBanks.push_back(manager);
} }
} }

View File

@@ -17,8 +17,7 @@ namespace core {
class BankwiseRefreshManager : public IRefreshManager class BankwiseRefreshManager : public IRefreshManager
{ {
public: public:
BankwiseRefreshManager(std::vector<RefreshTiming> refreshTimings, BankwiseRefreshManager(CommandBus& bus, std::vector<RefreshTiming> refreshTimings);
IInternalScheduler& internalScheduler);
virtual ~BankwiseRefreshManager(); virtual ~BankwiseRefreshManager();
virtual bool hasCollision(const CommandSchedule& schedule); virtual bool hasCollision(const CommandSchedule& schedule);

View File

@@ -12,19 +12,20 @@
namespace core { namespace core {
RefreshManager::RefreshManager(const RefreshTiming& refreshTiming, RefreshManager::RefreshManager(CommandBus& bus, const RefreshTiming& refreshTiming) : bus(bus),
IInternalScheduler& internalScheduler) : refreshTiming(refreshTiming)
refreshTiming(refreshTiming), internalScheduler(internalScheduler)
{ {
setupTransaction(refreshTransaction, Bank(0)); setupTransaction(refreshTransaction, Bank(0));
nextPlannedRefresh = new ScheduledCommand(refreshTransaction, Refresh, SC_ZERO_TIME, nextPlannedRefresh = new ScheduledCommand(refreshTransaction, Refresh, SC_ZERO_TIME,
refreshTiming.tRFC); refreshTiming.tRFC);
assert(refreshTiming.tRFC > SC_ZERO_TIME);
assert(nextPlannedRefresh->getExecutionTime()>SC_ZERO_TIME);
planNextRefresh(*nextPlannedRefresh); planNextRefresh(*nextPlannedRefresh);
} }
RefreshManager::RefreshManager(const RefreshTiming& refreshTiming, RefreshManager::RefreshManager(CommandBus& bus, const RefreshTiming& refreshTiming,
IInternalScheduler& internalScheduler, Bank bank) : Bank bank) : bus(bus), refreshTiming(refreshTiming)
refreshTiming(refreshTiming), internalScheduler(internalScheduler)
{ {
setupTransaction(refreshTransaction, bank); setupTransaction(refreshTransaction, bank);
nextPlannedRefresh = new ScheduledCommand(refreshTransaction, Refresh, SC_ZERO_TIME, nextPlannedRefresh = new ScheduledCommand(refreshTransaction, Refresh, SC_ZERO_TIME,
@@ -63,14 +64,15 @@ void RefreshManager::scheduleRefresh(sc_time time)
void RefreshManager::scheduleRefresh(ScheduledCommand& refresh) void RefreshManager::scheduleRefresh(ScheduledCommand& refresh)
{ {
internalScheduler.scheduleCommand(refresh); bus.schedule(refresh);
bus.send(refresh);
planNextRefresh(refresh); planNextRefresh(refresh);
} }
void RefreshManager::planNextRefresh(ScheduledCommand& refresh) //TODO nicer to return the reference ? void RefreshManager::planNextRefresh(ScheduledCommand& refresh) //TODO nicer to return the reference ?
{ {
refresh.delayStart(refreshTiming.tREFI); refresh.delayStart(refreshTiming.tREFI);
internalScheduler.scheduleTrigger(RefreshTrigger, refresh.getStart()); bus.send(RefreshTrigger, refresh.getStart());
} }
void RefreshManager::setupTransaction(tlm::tlm_generic_payload& transaction, Bank bank) void RefreshManager::setupTransaction(tlm::tlm_generic_payload& transaction, Bank bank)

View File

@@ -16,16 +16,16 @@ namespace core {
class RefreshManager : public IRefreshManager class RefreshManager : public IRefreshManager
{ {
public: public:
RefreshManager(const RefreshTiming& refreshTiming, IInternalScheduler& internalScheduler); RefreshManager(CommandBus& bus, const RefreshTiming& refreshTiming);
RefreshManager(const RefreshTiming& refreshTiming, IInternalScheduler& internalScheduler, Bank bank); RefreshManager(CommandBus& bus, const RefreshTiming& refreshTiming, Bank bank);
virtual ~RefreshManager(); virtual ~RefreshManager();
virtual bool hasCollision(const CommandSchedule& schedule); virtual bool hasCollision(const CommandSchedule& schedule);
virtual void scheduleRefresh(sc_time time); virtual void scheduleRefresh(sc_time time);
private: private:
CommandBus& bus;
const RefreshTiming& refreshTiming; const RefreshTiming& refreshTiming;
IInternalScheduler& internalScheduler;
tlm::tlm_generic_payload refreshTransaction; tlm::tlm_generic_payload refreshTransaction;
ScheduledCommand* nextPlannedRefresh; ScheduledCommand* nextPlannedRefresh;

View File

@@ -28,7 +28,7 @@ public:
ScheduledCommand& add(Command command, sc_time time, sc_time executionTime) ScheduledCommand& add(Command command, sc_time time, sc_time executionTime)
{ {
assert(scheduledCommands.empty() || time >= scheduledCommands.back().getEnd()); //assert(scheduledCommands.empty() || time >= scheduledCommands.back().getEnd());
scheduledCommands.push_back(ScheduledCommand(*transaction, command, time, executionTime)); scheduledCommands.push_back(ScheduledCommand(*transaction, command, time, executionTime));
return scheduledCommands.back(); return scheduledCommands.back();
} }

View File

@@ -10,21 +10,21 @@
namespace core { namespace core {
CommandSchedule CommandSequenceScheduler::prepareSchedule(sc_time start, CommandSchedule CommandSequenceScheduler::schedule(CommandSequence commands, sc_time start,
tlm::tlm_generic_payload& transaction, CommandSequence commands) tlm::tlm_generic_payload& transaction)
{ {
CommandSchedule schedule(transaction); CommandSchedule schedule(transaction);
for (unsigned int i = 0; i < commands.size(); ++i)
{
Command command = commands.at(i);
ICommandChecker& checker = *commandChecker[command];
if (i > 0) for (Command cmd : commands)
start = schedule.getEnd(); {
sc_time executionTime(checker.getExecutionTime(transaction, command)); ICommandChecker& checker = *commandChecker.at(cmd);
ScheduledCommand& scheduledCommand = schedule.add(command, start, executionTime);
checker.check(scheduledCommand); sc_time executionTime = checker.getExecutionTime(transaction, cmd);
ScheduledCommand& scheduledCommand = schedule.add(cmd, start, executionTime);
checker.delayToSatisfyConstraints(scheduledCommand);
bus.schedule(scheduledCommand);
} }
return schedule; return schedule;
} }

View File

@@ -11,6 +11,7 @@
#include <map> #include <map>
#include "CommandSchedule.h" #include "CommandSchedule.h"
#include "../Command.h" #include "../Command.h"
#include "../CommandBus.h"
#include "checker/ICommandChecker.h" #include "checker/ICommandChecker.h"
@@ -22,11 +23,13 @@ class DramController;
class CommandSequenceScheduler class CommandSequenceScheduler
{ {
public: public:
CommandSequenceScheduler(std::map<Command, ICommandChecker*>& commandChecker) : commandChecker(commandChecker){} CommandSequenceScheduler(CommandBus& bus, std::map<Command, ICommandChecker*>& commandChecker) : bus(bus), commandChecker(commandChecker){}
virtual ~CommandSequenceScheduler(){} virtual ~CommandSequenceScheduler(){}
CommandSchedule prepareSchedule(sc_time start, tlm::tlm_generic_payload& transaction, CommandSequence commands);
CommandSchedule schedule(CommandSequence commands, sc_time start, tlm::tlm_generic_payload& transaction);
private: private:
CommandBus& bus;
std::map<Command, ICommandChecker*>& commandChecker; std::map<Command, ICommandChecker*>& commandChecker;
}; };

View File

@@ -46,6 +46,11 @@ public:
return start; return start;
} }
void setStart(sc_time newStart)
{
start = newStart;
}
void delayStart(sc_time delay) void delayStart(sc_time delay)
{ {
start += delay; start += delay;

View File

@@ -10,15 +10,20 @@
#include "../../utils/Utils.h" #include "../../utils/Utils.h"
#include "ActivateChecker.h" #include "ActivateChecker.h"
#include <iostream>
namespace core { namespace core {
void ActivateChecker::check(ScheduledCommand& command) const void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
{ {
if (command.getCommand() != Activate) if (command.getCommand() != Activate)
return; return;
check_activateToActivate(command); satisfy_activateToActivate_sameBank(command);
check_nActivateWindow(command); satisfy_activateToActivate_differentBank(command);
check_bus(command); satisfy_nActivateWindow(command);
satisfy_prechargeToActivate(command);
satisfy_refreshToActivate(command);
} }
sc_time ActivateChecker::getExecutionTime(const tlm::tlm_generic_payload& transaction, sc_time ActivateChecker::getExecutionTime(const tlm::tlm_generic_payload& transaction,
@@ -28,53 +33,51 @@ sc_time ActivateChecker::getExecutionTime(const tlm::tlm_generic_payload& transa
return config.Timings.tRCD; return config.Timings.tRCD;
} }
void ActivateChecker::check_activateToActivate(ScheduledCommand& command) const void ActivateChecker::satisfy_activateToActivate_differentBank(ScheduledCommand& command) const
{ {
if (bus.notYetScheduled(Activate)) ScheduledCommand lastActivate = state.getLastCommand(Activate);
return;
ScheduledCommand lastActivate = bus.getLastCommand(Activate);
if (lastActivate.isValidCommand()) if (lastActivate.isValidCommand())
command.delayStart( command.delayStart(
delayByConstraint(lastActivate.getStart(), command.getStart(), delayByConstraint(lastActivate.getStart(), command.getStart(),
config.Timings.tRRD)); config.Timings.tRRD));
}
ScheduledCommand lastActivateOnBank = bus.getLastCommand(Activate, command.getBank()); void ActivateChecker::satisfy_refreshToActivate(ScheduledCommand& command) const
{
ScheduledCommand lastRefresh = state.getLastCommand(Refresh);
if (lastRefresh.isValidCommand())
command.delayStart(
delayByConstraint(lastRefresh.getEnd(), command.getStart(),
SC_ZERO_TIME));
}
void ActivateChecker::satisfy_activateToActivate_sameBank(ScheduledCommand& command) const
{
ScheduledCommand lastActivateOnBank = state.getLastCommand(Activate, command.getBank());
if (lastActivateOnBank.isValidCommand()) if (lastActivateOnBank.isValidCommand())
command.delayStart( command.delayStart(
delayByConstraint(lastActivateOnBank.getStart(), command.getStart(), delayByConstraint(lastActivateOnBank.getStart(), command.getStart(),
config.Timings.tRC)); config.Timings.tRC));
} }
void ActivateChecker::check_prechargeToActivate(ScheduledCommand& command) const void ActivateChecker::satisfy_prechargeToActivate(ScheduledCommand& command) const
{ {
sc_time lastPrechargeOnBank = std::max( sc_time lastPrechargeOnBank = std::max(
bus.getLastCommand(Precharge, command.getBank()).getStart(), state.getLastCommand(Precharge, command.getBank()).getStart(),
bus.getLastCommand(PrechargeAll, command.getBank()).getStart()); state.getLastCommand(PrechargeAll, command.getBank()).getStart());
command.delayStart( command.delayStart(
delayByConstraint(lastPrechargeOnBank, command.getStart(), config.Timings.tRC)); delayByConstraint(lastPrechargeOnBank, command.getStart(), config.Timings.tRC));
} }
void ActivateChecker::check_nActivateWindow(ScheduledCommand& command) const void ActivateChecker::satisfy_nActivateWindow(ScheduledCommand& command) const
{ {
if (!nActivateWindow.isFull()) if (!state.nActivateWindow.isFull())
return; return;
command.delayStart( command.delayStart(
delayByConstraint(nActivateWindow.getOldest(), command.getStart(), delayByConstraint(state.nActivateWindow.getOldest(), command.getStart(),
config.Timings.tTAW)); config.Timings.tTAW));
}
void ActivateChecker::check_bus(ScheduledCommand& command) const
{
command.delayStart(bus.getEarliestStartTime(command) - command.getStart());
}
void ActivateChecker::notifyAboutScheduledCommand(const ScheduledCommand& command)
{
if (command.getCommand() == Activate)
{
nActivateWindow.put(command.getStart());
}
} }
} /* namespace controller */ } /* namespace controller */

View File

@@ -12,29 +12,29 @@
#include "ICommandChecker.h" #include "ICommandChecker.h"
#include "../../Configuration.h" #include "../../Configuration.h"
#include "../../utils/RingBuffer.h" #include "../../utils/RingBuffer.h"
#include "../../CommandBus.h" #include "../../ControllerState.h"
namespace core { namespace core {
class ActivateChecker: public core::ICommandChecker class ActivateChecker: public ICommandChecker
{ {
public: public:
ActivateChecker(Configuration& config, CommandBus& commandBus) : config(config), bus(commandBus), nActivateWindow(config.nActivate){} ActivateChecker(const Configuration& config, ControllerState& state) : config(config), state(state){}
virtual ~ActivateChecker(){} virtual ~ActivateChecker(){}
virtual void check(ScheduledCommand& command) const; virtual void delayToSatisfyConstraints(ScheduledCommand& command) const;
virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& transaction, Command command) const; virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const;
virtual void notifyAboutScheduledCommand(const ScheduledCommand& command);
private: private:
const Configuration& config; const Configuration& config;
CommandBus& bus;//TODO should be const .. but fucking map access operator!!!! ControllerState& state;//TODO make const
void check_activateToActivate(ScheduledCommand& command) const; void satisfy_activateToActivate_sameBank(ScheduledCommand& command) const;
void check_prechargeToActivate(ScheduledCommand& command) const; void satisfy_activateToActivate_differentBank(ScheduledCommand& command) const;
void check_nActivateWindow(ScheduledCommand& command) const; void satisfy_prechargeToActivate(ScheduledCommand& command) const;
void check_bus(ScheduledCommand& command) const; void satisfy_nActivateWindow(ScheduledCommand& command) const;
RingBuffer<sc_time> nActivateWindow; void satisfy_refreshToActivate(ScheduledCommand& command) const;
}; };
} /* namespace controller */ } /* namespace controller */

View File

@@ -8,7 +8,7 @@
#ifndef ICOMMANDSCHEDULER_H_ #ifndef ICOMMANDSCHEDULER_H_
#define ICOMMANDSCHEDULER_H_ #define ICOMMANDSCHEDULER_H_
#include "systemc.h" #include <systemc.h>
#include "../ScheduledCommand.h" #include "../ScheduledCommand.h"
namespace core { namespace core {
@@ -18,9 +18,8 @@ class ICommandChecker
public: public:
virtual ~ICommandChecker() {} virtual ~ICommandChecker() {}
virtual void check(ScheduledCommand& command) const = 0; virtual void delayToSatisfyConstraints(ScheduledCommand& command) const = 0;
virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& transaction, Command command) const = 0; virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const = 0;
virtual void notifyAboutScheduledCommand(const ScheduledCommand& command) = 0;
}; };
} /* namespace controller */ } /* namespace controller */

View File

@@ -9,23 +9,20 @@
namespace core { namespace core {
void PrechargeChecker::check(ScheduledCommand& command) const void PrechargeChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
{ {
ScheduledCommand lastCommand = bus.getLastCommand(command.getBank()); ScheduledCommand lastCommand = state.getLastCommand(command.getBank());
if(lastCommand.isValidCommand() && lastCommand.getEnd() > command.getStart()) if(lastCommand.isValidCommand() && lastCommand.getEnd() > command.getStart())
{ {
command.delayStart(lastCommand.getEnd()-command.getStart()); command.delayStart(lastCommand.getEnd()-command.getStart());
} }
} }
sc_time PrechargeChecker::getExecutionTime(const tlm::tlm_generic_payload& transaction, sc_time PrechargeChecker::getExecutionTime(const tlm::tlm_generic_payload& payload,
Command command) const Command command) const
{ {
assert(command == Precharge || command == PrechargeAll); assert(command == Precharge || command == PrechargeAll);
return config.Timings.tRP; return config.Timings.tRP;
} }
void PrechargeChecker::notifyAboutScheduledCommand(const ScheduledCommand& command)
{
}
} /* namespace controller */ } /* namespace controller */

View File

@@ -10,22 +10,21 @@
#include "ICommandChecker.h" #include "ICommandChecker.h"
#include "../../Configuration.h" #include "../../Configuration.h"
#include "../../CommandBus.h" #include "../../ControllerState.h"
namespace core { namespace core {
class PrechargeChecker: public core::ICommandChecker class PrechargeChecker: public core::ICommandChecker
{ {
public: public:
PrechargeChecker(const Configuration& config, CommandBus& commandBus) : config(config), bus(commandBus) {} PrechargeChecker(const Configuration& config, ControllerState& state) : config(config), state(state) {}
virtual ~PrechargeChecker() {} virtual ~PrechargeChecker() {}
virtual void check(ScheduledCommand& command) const; virtual void delayToSatisfyConstraints(ScheduledCommand& command) const;
virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& transaction, Command command) const; virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const;
virtual void notifyAboutScheduledCommand(const ScheduledCommand& command);
private: private:
const Configuration& config; const Configuration& config;
CommandBus& bus; ControllerState& state;//TODO make const
}; };
} /* namespace controller */ } /* namespace controller */

View File

@@ -10,9 +10,9 @@
namespace core { namespace core {
void ReadChecker::check(ScheduledCommand& command) const void ReadChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
{ {
ScheduledCommand lastCommand = bus.getLastCommand(command.getBank()); ScheduledCommand lastCommand = state.getLastCommand(command.getBank());
if(lastCommand.isValidCommand() && lastCommand.getEnd() > command.getStart()) if(lastCommand.isValidCommand() && lastCommand.getEnd() > command.getStart())
{ {
command.delayStart(lastCommand.getEnd()-command.getStart()); command.delayStart(lastCommand.getEnd()-command.getStart());
@@ -28,8 +28,4 @@ sc_time ReadChecker::getExecutionTime(const tlm::tlm_generic_payload& payload,
return config.Timings.tRL + config.Timings.clk*payload.get_streaming_width(); return config.Timings.tRL + config.Timings.clk*payload.get_streaming_width();
} }
void ReadChecker::notifyAboutScheduledCommand(const ScheduledCommand& command)
{
}
} /* namespace controller */ } /* namespace controller */

View File

@@ -10,22 +10,21 @@
#include "ICommandChecker.h" #include "ICommandChecker.h"
#include "../../Configuration.h" #include "../../Configuration.h"
#include "../../CommandBus.h" #include "../../ControllerState.h"
namespace core { namespace core {
class ReadChecker: public core::ICommandChecker class ReadChecker: public core::ICommandChecker
{ {
public: public:
ReadChecker(const Configuration& config, CommandBus& commandBus) : config(config), bus(commandBus) {} ReadChecker(Configuration& config, ControllerState& state) : config(config), state(state) {}
virtual ~ReadChecker() {} virtual ~ReadChecker() {}
virtual void check(ScheduledCommand& command) const; virtual void delayToSatisfyConstraints(ScheduledCommand& command) const;
virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const; virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const;
virtual void notifyAboutScheduledCommand(const ScheduledCommand& command);
private: private:
const Configuration& config; const Configuration& config;
CommandBus& bus; ControllerState& state;
}; };
} /* namespace controller */ } /* namespace controller */

View File

@@ -9,19 +9,15 @@
namespace core { namespace core {
void WriteChecker::check(ScheduledCommand& command) const void WriteChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
{ {
} }
sc_time WriteChecker::getExecutionTime(const tlm::tlm_generic_payload& transaction, sc_time WriteChecker::getExecutionTime(const tlm::tlm_generic_payload& payload,
Command command) const Command command) const
{ {
assert(command == Write || command == WriteA); assert(command == Write || command == WriteA);
return config.Timings.clk*8; return config.Timings.clk*8;
} }
void WriteChecker::notifyAboutScheduledCommand(const ScheduledCommand& command)
{
}
} /* namespace controller */ } /* namespace controller */

View File

@@ -10,22 +10,21 @@
#include "ICommandChecker.h" #include "ICommandChecker.h"
#include "../../Configuration.h" #include "../../Configuration.h"
#include "../../CommandBus.h" #include "../../ControllerState.h"
namespace core { namespace core {
class WriteChecker: public core::ICommandChecker class WriteChecker: public core::ICommandChecker
{ {
public: public:
WriteChecker(const Configuration& config, const CommandBus& commandBus) : config(config), bus(commandBus) {} WriteChecker(const Configuration& config, ControllerState& state) : config(config), state(state) {}
virtual ~WriteChecker() {} virtual ~WriteChecker() {}
virtual void check(ScheduledCommand& command) const; virtual void delayToSatisfyConstraints(ScheduledCommand& command) const;
virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& transaction, Command command) const; virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const;
virtual void notifyAboutScheduledCommand(const ScheduledCommand& command);
private: private:
const Configuration& config; const Configuration& config;
const CommandBus& bus; ControllerState& state;
}; };
} /* namespace controller */ } /* namespace controller */

View File

@@ -9,6 +9,7 @@
#define RINGBUFFER_H_ #define RINGBUFFER_H_
#include <systemc.h> #include <systemc.h>
#include <vector>
template<typename T> template<typename T>
class RingBuffer class RingBuffer
@@ -20,8 +21,8 @@ public:
void put(T t) void put(T t)
{ {
buffer.push_back(t); buffer.push_back(t);
if(getSize()>maxSize) if(getSize() > maxSize)
buffer.pop_front(); buffer.erase(buffer.begin());
} }
T getOldest() const T getOldest() const
@@ -58,7 +59,7 @@ public:
} }
private: private:
std::deque<T> buffer; std::vector<T> buffer;
unsigned int maxSize; unsigned int maxSize;
}; };

View File

@@ -1,23 +0,0 @@
/*
* IControllerWrapper.h
*
* Created on: Mar 15, 2014
* Author: gernhard
*/
#ifndef ICONTROLLERWRAPPER_H_
#define ICONTROLLERWRAPPER_H_
#include <tlm.h>
#include <systemc.h>
#include "../core/Command.h"
#include "../core/scheduling/Trigger.h"
class IControllerWrapper{
public:
virtual void sendCommand(sc_time startTime, tlm::tlm_generic_payload& payload, core::Command command) = 0;
virtual void sendTrigger(sc_time time, core::Trigger trigger) = 0;
virtual ~IControllerWrapper(){}
};
#endif /* ICONTROLLERWRAPPER_H_ */

View File

@@ -17,7 +17,7 @@
#include "common/protocol.h" #include "common/protocol.h"
#include "common/tlmDBPhaseRecorder.h" #include "common/tlmDBPhaseRecorder.h"
#include "dram/tlm/IControllerWrapper.h" #include "dram/core/IWrapperConnector.h"
#include "dram/core/Controller.h" #include "dram/core/Controller.h"
using namespace std; using namespace std;
@@ -25,7 +25,7 @@ using namespace tlm;
using namespace core; using namespace core;
template<unsigned int BUSWIDTH = 128> template<unsigned int BUSWIDTH = 128>
struct ControllerWrapper: public sc_module, public IControllerWrapper struct ControllerWrapper: public sc_module, public IWrapperConnector
{ {
public: public:
@@ -48,13 +48,12 @@ public:
delete controller; delete controller;
} }
virtual void sendCommand(sc_time startTime, tlm::tlm_generic_payload& payload, virtual void send(const ScheduledCommand& command)
Command command)
{ {
assert(startTime >= sc_time_stamp()); assert(command.getStart() >= sc_time_stamp()||command.getStart()<sc_time(100000, SC_NS));
sc_time delay = startTime - sc_time_stamp(); sc_time delay = command.getStart() - sc_time_stamp();
tlm::tlm_phase phase; tlm::tlm_phase phase;
switch (command) switch (command.getCommand())
{ {
case Read: case Read:
phase = BEGIN_RD; phase = BEGIN_RD;
@@ -76,15 +75,16 @@ public:
break; break;
} }
dramPEQ.notify(payload, phase, delay); dramPEQ.notify(command.getTransaction(), phase, delay);
} }
virtual void sendTrigger(sc_time time, Trigger trigger) virtual void send(Trigger trigger, sc_time time)
{ {
assert(time >= sc_time_stamp()); assert(time >= sc_time_stamp());
sc_time delay = time - sc_time_stamp(); sc_time delay = time - sc_time_stamp();
controllerPEQ.notify(triggerDummy,REFRESH_TRIGGER,delay); controllerPEQ.notify(triggerDummy, REFRESH_TRIGGER, delay);
} }
private: private:
DramController* controller; DramController* controller;
tlm_utils::peq_with_cb_and_phase<ControllerWrapper> frontendPEQ; tlm_utils::peq_with_cb_and_phase<ControllerWrapper> frontendPEQ;
@@ -149,7 +149,7 @@ private:
if (phase == BEGIN_RD || phase == BEGIN_WR || phase == BEGIN_REFA || phase == BEGIN_ACT if (phase == BEGIN_RD || phase == BEGIN_WR || phase == BEGIN_REFA || phase == BEGIN_ACT
|| phase == BEGIN_PRE) || phase == BEGIN_PRE)
{ {
sendToDram(payload, phase, SC_ZERO_TIME); sendToDram(payload, phase, SC_ZERO_TIME);//TODO delay in send mehtod instead of way through PEQ
} }
else if (phase == END_RD || phase == END_WR) else if (phase == END_RD || phase == END_WR)
{ {

View File

@@ -16,7 +16,7 @@ using namespace testing;
namespace core { namespace core {
class MockInternalScheduler: public IInternalScheduler class MockInternalScheduler: public IBus
{ {
public: public:
MOCK_METHOD1(scheduleCommand, void (const ScheduledCommand& command)); MOCK_METHOD1(scheduleCommand, void (const ScheduledCommand& command));

View File

@@ -17,7 +17,7 @@ using namespace testing;
namespace core { namespace core {
class MockInternalScheduler: public IInternalScheduler class MockInternalScheduler: public IBus
{ {
public: public:
MOCK_METHOD1(scheduleCommand, void (const ScheduledCommand& command)); MOCK_METHOD1(scheduleCommand, void (const ScheduledCommand& command));

View File

@@ -74,9 +74,9 @@ TEST(UtilsTest, RingBufferWorks)
TEST(UtilsTest,getBurstLengthInBytesWorks) TEST(UtilsTest,getBurstLengthInBytesWorks)
{ {
tlm::tlm_generic_payload payload; //tlm::tlm_generic_payload payload;
payload.set_data_length(4); // payload.set_data_length(4);
EXPECT_EQ(4,getBurstLengthInBytes(payload,128)); // EXPECT_EQ(4,getBurstLengthInBytes(payload,128));
} }
} /* namespace controller */ } /* namespace controller */