Files
DRAMSys/dram/src/core/scheduling/checker/ReadChecker.cpp
2014-04-11 23:08:15 +02:00

101 lines
2.6 KiB
C++

/*
* ReadChecker.cpp
*
* Created on: Mar 13, 2014
* Author: jonny
*/
#include "ReadChecker.h"
#include "../../TimingCalculation.h"
#include "../../../common/Utils.h"
namespace core {
void ReadChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
{
assert(command.getCommand() == Command::Read || command.getCommand() == Command::ReadA);
ScheduledCommand lastCommand = state.getLastScheduledCommand(command.getBank());
if (lastCommand.isValidCommand())
{
if (lastCommand.getCommand() == Command::Activate)
{
command.delayToMeetConstraint(lastCommand.getEnd(), SC_ZERO_TIME);
}
else if (lastCommand.getCommand() == Command::Read
|| lastCommand.getCommand() == Command::Write)
{
}
else if (lastCommand.getCommand() == Command::PDNAX)
{
command.delayToMeetConstraint(lastCommand.getStart(), config.Timings.tXP);//TODO DLL also for PDNP and SREF .. not onyl last command
}
else
reportFatal("Read Checker",
"Read can not follow " + commandToString(lastCommand.getCommand()));
}
while (!state.bus.isFree(command.getStart()) || collidesOnDataStrobe(command))
{
command.delayStart(config.Timings.clk);
}
}
bool ReadChecker::collidesOnDataStrobe(ScheduledCommand& read) const
{
for (ScheduledCommand& strobeCommand : state.lastDataStrobeCommands)
{
if (collidesWithStrobeCommand(read, strobeCommand))
return true;
}
return false;
}
bool ReadChecker::collidesWithStrobeCommand(ScheduledCommand& read,
ScheduledCommand& strobeCommand) const
{
//read to read
if (strobeCommand.getCommand() == Command::Read || strobeCommand.getCommand() == Command::ReadA)
{
bool collision = read.collidesOnDataStrobe(strobeCommand);
sc_time tCCD =
(read.getBankGroup() == strobeCommand.getBankGroup()) ?
config.Timings.tCCD_L : config.Timings.tCCD_S;
bool casToCas =
(getDistance(read.getStart(), strobeCommand.getStart()) < tCCD) ? true : false;
return collision || casToCas;
}
else if (strobeCommand.getCommand() == Command::Write
|| strobeCommand.getCommand() == Command::WriteA)
{
//read to write
if (strobeCommand.getStart() >= read.getStart())
{
return strobeCommand.getStart() < read.getIntervalOnDataStrobe().end;
}
//write to read
else
{
sc_time tWTR =
(read.getBankGroup() == strobeCommand.getBankGroup()) ?
config.Timings.tWTR_L : config.Timings.tWTR_S;
return read.getStart()
< clkAlign(strobeCommand.getIntervalOnDataStrobe().end, Alignment::DOWN) + tWTR;
}
}
else
{
reportFatal("Read Checker",
"Invalid strobeCommand in data strobe commands "
+ commandToString(strobeCommand.getCommand()));
return true;
}
}
} /* namespace controller */