..
This commit is contained in:
@@ -3,7 +3,6 @@
|
||||
<name>dram</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
<project>common</project>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
|
||||
@@ -10,150 +10,112 @@
|
||||
|
||||
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;
|
||||
if (*it == newStart)
|
||||
newStart += config.Timings.clk;
|
||||
++it;
|
||||
}
|
||||
return max;
|
||||
command.setStart(newStart);
|
||||
}
|
||||
|
||||
ScheduledCommand CommandBus::getLastCommand(Bank bank)
|
||||
void CommandBus::send(const Trigger trigger, sc_time time) const
|
||||
{
|
||||
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;
|
||||
wrapperConnector.send(trigger, time);
|
||||
}
|
||||
|
||||
bool CommandBus::notYetScheduled(Command command) const
|
||||
{
|
||||
return (lastCommandsOnBus.count(command) == 0);
|
||||
}
|
||||
void CommandBus::send(const ScheduledCommand& command) const
|
||||
{
|
||||
wrapperConnector.send(command);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
return newStart;
|
||||
}
|
||||
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())
|
||||
{
|
||||
case Refresh:
|
||||
refresh(command);
|
||||
break;
|
||||
case Activate:
|
||||
activate(command);
|
||||
break;
|
||||
case Precharge:
|
||||
precharge(command);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (command.getCommand())
|
||||
{
|
||||
case Refresh:
|
||||
refresh(command);
|
||||
break;
|
||||
case Activate:
|
||||
activate(command);
|
||||
break;
|
||||
case Precharge:
|
||||
precharge(command);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CommandBus::refresh(const ScheduledCommand& command)
|
||||
{
|
||||
if (config.RefreshBankwise)
|
||||
{
|
||||
state.bankStates.closeRowBuffer(command.getBank());
|
||||
}
|
||||
else
|
||||
{
|
||||
state.bankStates.closeAllRowBuffers();
|
||||
}
|
||||
if (config.RefreshBankwise)
|
||||
{
|
||||
state.bankStates.closeRowBuffer(command.getBank());
|
||||
}
|
||||
else
|
||||
{
|
||||
state.bankStates.closeAllRowBuffers();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CommandBus::precharge(const ScheduledCommand& command)
|
||||
{
|
||||
if (command.getCommand() == Precharge)
|
||||
{
|
||||
state.bankStates.closeRowBuffer(command.getBank());
|
||||
}
|
||||
else if (command.getCommand() == PrechargeAll)
|
||||
{
|
||||
state.bankStates.closeAllRowBuffers();
|
||||
}
|
||||
if (command.getCommand() == Precharge)
|
||||
{
|
||||
state.bankStates.closeRowBuffer(command.getBank());
|
||||
}
|
||||
else if (command.getCommand() == PrechargeAll)
|
||||
{
|
||||
state.bankStates.closeAllRowBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
void CommandBus::activate(const ScheduledCommand& command)
|
||||
{
|
||||
if (command.getCommand() == Activate)
|
||||
{
|
||||
state.bankStates.openRowInRowBuffer(command.getBank(), command.getRow());
|
||||
}
|
||||
if (command.getCommand() == Activate)
|
||||
{
|
||||
state.bankStates.openRowInRowBuffer(command.getBank(), command.getRow());
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace controller */
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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_ */
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -46,6 +46,11 @@ public:
|
||||
return start;
|
||||
}
|
||||
|
||||
void setStart(sc_time newStart)
|
||||
{
|
||||
start = newStart;
|
||||
}
|
||||
|
||||
void delayStart(sc_time delay)
|
||||
{
|
||||
start += delay;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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_ */
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user