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>
<comment></comment>
<projects>
<project>common</project>
</projects>
<buildSpec>
<buildCommand>

View File

@@ -10,106 +10,68 @@
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();
++it)
{
scheduleCommand(*it);
}
}
void CommandBus::scheduleCommand(const ScheduledCommand& command)
{
assert(!pendingBusCommands.count(command.getStart()));
scheduleOnBus(command);
//TODO state change in state!!
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());
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)
if(command.getCommand() == Activate)
{
(*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)
{
return lastCommandsOnBus[command][bank];
}
ScheduledCommand CommandBus::getLastCommand(Command command)
{
ScheduledCommand max;
for (unsigned int i = 0; i < config.numberOfBanks; ++i)
while (it != state.pendingBusCommands.end() && *it <= newStart)
{
const ScheduledCommand& current = getLastCommand(command, Bank(i));
if (current.getStart() > max.getStart())
max = current;
}
return max;
}
ScheduledCommand CommandBus::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;
}
bool CommandBus::notYetScheduled(Command command) const
{
return (lastCommandsOnBus.count(command) == 0);
}
bool CommandBus::notYetScheduled(Command command, Bank bank) const
{
return (notYetScheduled(command) || lastCommandsOnBus.find(command)->second.count(bank) == 0);
}
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;
}
command.setStart(newStart);
}
return newStart;
void CommandBus::send(const Trigger trigger, sc_time time) const
{
wrapperConnector.send(trigger, time);
}
void CommandBus::send(const ScheduledCommand& command) const
{
wrapperConnector.send(command);
}
void CommandBus::send(const CommandSchedule& schedule) const
{
for(const ScheduledCommand& cmd : schedule.getScheduledCommands())
{
send(cmd);
}
}
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)
{
switch (command.getCommand())
{
switch (command.getCommand())
{
case Refresh:
refresh(command);
break;
@@ -120,40 +82,40 @@ switch (command.getCommand())
precharge(command);
default:
break;
}
}
}
void CommandBus::refresh(const ScheduledCommand& command)
{
if (config.RefreshBankwise)
{
if (config.RefreshBankwise)
{
state.bankStates.closeRowBuffer(command.getBank());
}
else
{
}
else
{
state.bankStates.closeAllRowBuffers();
}
}
}
void CommandBus::precharge(const ScheduledCommand& command)
{
if (command.getCommand() == Precharge)
{
if (command.getCommand() == Precharge)
{
state.bankStates.closeRowBuffer(command.getBank());
}
else if (command.getCommand() == PrechargeAll)
{
}
else if (command.getCommand() == PrechargeAll)
{
state.bankStates.closeAllRowBuffers();
}
}
}
void CommandBus::activate(const ScheduledCommand& command)
{
if (command.getCommand() == Activate)
{
if (command.getCommand() == Activate)
{
state.bankStates.openRowInRowBuffer(command.getBank(), command.getRow());
}
}
}
} /* namespace controller */

View File

@@ -10,9 +10,8 @@
#include <map>
#include <set>
#include "../tlm/IControllerWrapper.h"
#include "ControllerState.h"
#include "IInternalScheduler.h"
#include "IWrapperConnector.h"
#include "Configuration.h"
#include "scheduling/CommandSchedule.h"
#include "scheduling/Trigger.h"
@@ -20,49 +19,36 @@
namespace core {
class CommandBus: public IInternalScheduler
class CommandBus
{
public:
CommandBus(const Configuration& config, core::ControllerState& state,
std::vector<ICommandChecker*>& checker, IControllerWrapper& wrapper):
wrapper(wrapper), config(config), state(state), checker(checker)
CommandBus(IWrapperConnector& wrapperConnector, const Configuration& config, ControllerState& state):
wrapperConnector(wrapperConnector), config(config), state(state)
{
}
virtual void schedule(const CommandSchedule& schedule); //TODO add to interface
virtual void scheduleCommand(const ScheduledCommand& command);
virtual void scheduleTrigger(const Trigger trigger, sc_time time);
~CommandBus(){}
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);
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:
IControllerWrapper& wrapper;
IWrapperConnector& wrapperConnector;
const Configuration& config;
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 refresh(const ScheduledCommand& command);
void precharge(const ScheduledCommand& command);
void activate(const ScheduledCommand& command);
void scheduleOnBus(ScheduledCommand& command);
};
}
#endif /* INTERNALSCHEDULER_H_ */

View File

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

View File

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

View File

@@ -9,13 +9,35 @@
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() {
// TODO Auto-generated destructor stub
const ScheduledCommand ControllerState::getLastCommand(Command command)
{
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 */

View File

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

View File

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

View File

@@ -24,14 +24,17 @@ struct TimingConfiguration
{
TimingConfiguration(unsigned int numberOfBanks)
{
clk = sc_time(6.0, SC_NS); // 166MHz
for (unsigned int i = 0; i < numberOfBanks; ++i)
{
sc_time tRFC = 18*clk;
sc_time tREFI = sc_time(15.6, SC_US); //TODO align
//tREFI = sc_time(301268, SC_NS);
refreshTimings.push_back(RefreshTiming(tRFC, tREFI));
}
clk = sc_time(6.0, SC_NS); // 166MHz
tRP = 3*clk; //precharge-time (pre -> act 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)
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;

View File

@@ -11,14 +11,13 @@ using namespace std;
namespace core {
BankwiseRefreshManager::BankwiseRefreshManager(vector<RefreshTiming> refreshTimings,
IInternalScheduler& internalScheduler)
BankwiseRefreshManager::BankwiseRefreshManager(CommandBus& bus, vector<RefreshTiming> refreshTimings)
{
assert(!refreshTimings.empty());
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);
}
}

View File

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

View File

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

View File

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

View File

@@ -28,7 +28,7 @@ public:
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));
return scheduledCommands.back();
}

View File

@@ -10,21 +10,21 @@
namespace core {
CommandSchedule CommandSequenceScheduler::prepareSchedule(sc_time start,
tlm::tlm_generic_payload& transaction, CommandSequence commands)
CommandSchedule CommandSequenceScheduler::schedule(CommandSequence commands, sc_time start,
tlm::tlm_generic_payload& 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)
start = schedule.getEnd();
sc_time executionTime(checker.getExecutionTime(transaction, command));
ScheduledCommand& scheduledCommand = schedule.add(command, start, executionTime);
checker.check(scheduledCommand);
for (Command cmd : commands)
{
ICommandChecker& checker = *commandChecker.at(cmd);
sc_time executionTime = checker.getExecutionTime(transaction, cmd);
ScheduledCommand& scheduledCommand = schedule.add(cmd, start, executionTime);
checker.delayToSatisfyConstraints(scheduledCommand);
bus.schedule(scheduledCommand);
}
return schedule;
}

View File

@@ -11,6 +11,7 @@
#include <map>
#include "CommandSchedule.h"
#include "../Command.h"
#include "../CommandBus.h"
#include "checker/ICommandChecker.h"
@@ -22,11 +23,13 @@ class DramController;
class CommandSequenceScheduler
{
public:
CommandSequenceScheduler(std::map<Command, ICommandChecker*>& commandChecker) : commandChecker(commandChecker){}
CommandSequenceScheduler(CommandBus& bus, std::map<Command, ICommandChecker*>& commandChecker) : bus(bus), commandChecker(commandChecker){}
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:
CommandBus& bus;
std::map<Command, ICommandChecker*>& commandChecker;
};

View File

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

View File

@@ -10,15 +10,20 @@
#include "../../utils/Utils.h"
#include "ActivateChecker.h"
#include <iostream>
namespace core {
void ActivateChecker::check(ScheduledCommand& command) const
void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
{
if (command.getCommand() != Activate)
return;
check_activateToActivate(command);
check_nActivateWindow(command);
check_bus(command);
satisfy_activateToActivate_sameBank(command);
satisfy_activateToActivate_differentBank(command);
satisfy_nActivateWindow(command);
satisfy_prechargeToActivate(command);
satisfy_refreshToActivate(command);
}
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;
}
void ActivateChecker::check_activateToActivate(ScheduledCommand& command) const
void ActivateChecker::satisfy_activateToActivate_differentBank(ScheduledCommand& command) const
{
if (bus.notYetScheduled(Activate))
return;
ScheduledCommand lastActivate = bus.getLastCommand(Activate);
ScheduledCommand lastActivate = state.getLastCommand(Activate);
if (lastActivate.isValidCommand())
command.delayStart(
delayByConstraint(lastActivate.getStart(), command.getStart(),
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())
command.delayStart(
delayByConstraint(lastActivateOnBank.getStart(), command.getStart(),
config.Timings.tRC));
}
void ActivateChecker::check_prechargeToActivate(ScheduledCommand& command) const
void ActivateChecker::satisfy_prechargeToActivate(ScheduledCommand& command) const
{
sc_time lastPrechargeOnBank = std::max(
bus.getLastCommand(Precharge, command.getBank()).getStart(),
bus.getLastCommand(PrechargeAll, command.getBank()).getStart());
state.getLastCommand(Precharge, command.getBank()).getStart(),
state.getLastCommand(PrechargeAll, command.getBank()).getStart());
command.delayStart(
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;
command.delayStart(
delayByConstraint(nActivateWindow.getOldest(), command.getStart(),
delayByConstraint(state.nActivateWindow.getOldest(), command.getStart(),
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 */

View File

@@ -12,29 +12,29 @@
#include "ICommandChecker.h"
#include "../../Configuration.h"
#include "../../utils/RingBuffer.h"
#include "../../CommandBus.h"
#include "../../ControllerState.h"
namespace core {
class ActivateChecker: public core::ICommandChecker
class ActivateChecker: public ICommandChecker
{
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 void check(ScheduledCommand& command) const;
virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& transaction, Command command) const;
virtual void notifyAboutScheduledCommand(const ScheduledCommand& command);
virtual void delayToSatisfyConstraints(ScheduledCommand& command) const;
virtual sc_time getExecutionTime(const tlm::tlm_generic_payload& payload, Command command) const;
private:
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 check_prechargeToActivate(ScheduledCommand& command) const;
void check_nActivateWindow(ScheduledCommand& command) const;
void check_bus(ScheduledCommand& command) const;
void satisfy_activateToActivate_sameBank(ScheduledCommand& command) const;
void satisfy_activateToActivate_differentBank(ScheduledCommand& command) const;
void satisfy_prechargeToActivate(ScheduledCommand& command) const;
void satisfy_nActivateWindow(ScheduledCommand& command) const;
RingBuffer<sc_time> nActivateWindow;
void satisfy_refreshToActivate(ScheduledCommand& command) const;
};
} /* namespace controller */

View File

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

View File

@@ -9,23 +9,20 @@
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())
{
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
{
assert(command == Precharge || command == PrechargeAll);
return config.Timings.tRP;
}
void PrechargeChecker::notifyAboutScheduledCommand(const ScheduledCommand& command)
{
}
} /* namespace controller */

View File

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

View File

@@ -10,9 +10,9 @@
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())
{
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();
}
void ReadChecker::notifyAboutScheduledCommand(const ScheduledCommand& command)
{
}
} /* namespace controller */

View File

@@ -10,22 +10,21 @@
#include "ICommandChecker.h"
#include "../../Configuration.h"
#include "../../CommandBus.h"
#include "../../ControllerState.h"
namespace core {
class ReadChecker: public core::ICommandChecker
{
public:
ReadChecker(const Configuration& config, CommandBus& commandBus) : config(config), bus(commandBus) {}
ReadChecker(Configuration& config, ControllerState& state) : config(config), state(state) {}
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 void notifyAboutScheduledCommand(const ScheduledCommand& command);
private:
const Configuration& config;
CommandBus& bus;
ControllerState& state;
};
} /* namespace controller */

View File

@@ -9,19 +9,15 @@
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
{
assert(command == Write || command == WriteA);
return config.Timings.clk*8;
}
void WriteChecker::notifyAboutScheduledCommand(const ScheduledCommand& command)
{
}
} /* namespace controller */

View File

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

View File

@@ -9,6 +9,7 @@
#define RINGBUFFER_H_
#include <systemc.h>
#include <vector>
template<typename T>
class RingBuffer
@@ -20,8 +21,8 @@ public:
void put(T t)
{
buffer.push_back(t);
if(getSize()>maxSize)
buffer.pop_front();
if(getSize() > maxSize)
buffer.erase(buffer.begin());
}
T getOldest() const
@@ -58,7 +59,7 @@ public:
}
private:
std::deque<T> buffer;
std::vector<T> buffer;
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/tlmDBPhaseRecorder.h"
#include "dram/tlm/IControllerWrapper.h"
#include "dram/core/IWrapperConnector.h"
#include "dram/core/Controller.h"
using namespace std;
@@ -25,7 +25,7 @@ using namespace tlm;
using namespace core;
template<unsigned int BUSWIDTH = 128>
struct ControllerWrapper: public sc_module, public IControllerWrapper
struct ControllerWrapper: public sc_module, public IWrapperConnector
{
public:
@@ -48,13 +48,12 @@ public:
delete controller;
}
virtual void sendCommand(sc_time startTime, tlm::tlm_generic_payload& payload,
Command command)
virtual void send(const ScheduledCommand& command)
{
assert(startTime >= sc_time_stamp());
sc_time delay = startTime - sc_time_stamp();
assert(command.getStart() >= sc_time_stamp()||command.getStart()<sc_time(100000, SC_NS));
sc_time delay = command.getStart() - sc_time_stamp();
tlm::tlm_phase phase;
switch (command)
switch (command.getCommand())
{
case Read:
phase = BEGIN_RD;
@@ -76,15 +75,16 @@ public:
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());
sc_time delay = time - sc_time_stamp();
controllerPEQ.notify(triggerDummy,REFRESH_TRIGGER,delay);
controllerPEQ.notify(triggerDummy, REFRESH_TRIGGER, delay);
}
private:
DramController* controller;
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
|| 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)
{

View File

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

View File

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

View File

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