Files
DRAMSys/DRAM/dram/core/scheduling/CommandBus.cpp
2014-03-15 18:31:16 +01:00

139 lines
3.1 KiB
C++

/*
* InternalScheduler.cpp
*
* Created on: Mar 9, 2014
* Author: jonny
*/
#include "CommandBus.h"
#include <algorithm>
namespace controller {
void CommandBus::schedule(const CommandSchedule& schedule)
{
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()));
changeControllerState(command);
pendingBusCommands.insert(command.getStart());
lastCommandsOnBus[command.getCommand()][command.getBank()] = command;
//notify tlm wrapper
lastCommandsOnBus[command.getCommand()][command.getBank()].invalidateTransaction();
}
void CommandBus::scheduleTrigger(const Trigger command, sc_time time)
{
//notify tlm wrapper
}
ScheduledCommand& CommandBus::getLastCommand(Command command, Bank bank)
{
return lastCommandsOnBus[command][bank];
}
ScheduledCommand& CommandBus::getLastCommand(Command command)
{
ScheduledCommand* max = &getLastCommand(command, Bank(0));
for (unsigned int i = 0; i < config.numberOfBanks; ++i)
{
ScheduledCommand* current = &getLastCommand(command, Bank(i));
if (current->getStart() > max->getStart())
max = current;
}
return *max;
}
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;
}
return newStart;
}
void CommandBus::cleanUpBus(sc_time currentTime)
{
pendingBusCommands.erase(pendingBusCommands.begin(),
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;
}
}
void CommandBus::refresh(const ScheduledCommand& command)
{
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();
}
}
void CommandBus::activate(const ScheduledCommand& command)
{
if(command.getCommand() == Activate)
{
state.bankStates.openRowInRowBuffer(command.getBank(), command.getRow());
}
}
} /* namespace controller */