115 lines
3.0 KiB
C++
115 lines
3.0 KiB
C++
/*
|
|
* ReadChecker.cpp
|
|
*
|
|
* Created on: Mar 13, 2014
|
|
* Author: jonny
|
|
*/
|
|
|
|
#include "ReadChecker.h"
|
|
#include "../../utils/Utils.h"
|
|
|
|
namespace core {
|
|
|
|
void ReadChecker::delayToSatisfyConstraints(ScheduledCommand& command) const
|
|
{
|
|
assert(command.getCommand() == Command::Read || command.getCommand() == Command::ReadA);
|
|
|
|
ScheduledCommand lastCommandOnBank = state.getLastScheduledCommand(command.getBank());
|
|
|
|
if (lastCommandOnBank.isValidCommand())
|
|
{
|
|
if (lastCommandOnBank.getCommand() == Command::Activate)
|
|
{
|
|
command.delayStart(getDelayToMeetConstraint(lastCommandOnBank.getEnd(),command.getStart(), SC_ZERO_TIME));
|
|
}
|
|
else if (lastCommandOnBank.getCommand() == Command::Read
|
|
|| lastCommandOnBank.getCommand() == Command::Write)
|
|
{
|
|
}
|
|
else
|
|
reportFatal("Read Checker",
|
|
"Read can not follow " + commandToString(lastCommandOnBank.getCommand()));
|
|
}
|
|
|
|
while (!state.bus.isFree(command.getStart()) || collidesOnDataStrobe(command))
|
|
{
|
|
command.delayStart(config.Timings.clk);
|
|
}
|
|
}
|
|
|
|
sc_time ReadChecker::getExecutionTime(const tlm::tlm_generic_payload& payload,
|
|
Command command) const
|
|
{
|
|
assert(command == Command::Read || command == Command::ReadA);
|
|
|
|
if (command == Command::Read)
|
|
{
|
|
return config.Timings.tRL + config.Timings.clk * payload.get_streaming_width();
|
|
}
|
|
else
|
|
{
|
|
return config.Timings.tRL + config.Timings.clk * payload.get_streaming_width()
|
|
+ config.Timings.tRP;
|
|
}
|
|
}
|
|
|
|
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
|
|
{
|
|
if (strobeCommand.getCommand() == Command::Read || strobeCommand.getCommand() == Command::ReadA)
|
|
{
|
|
//read to read
|
|
TimeInterval readOnStrobe = getIntervalOnDataStrobe(read, config.Timings);
|
|
TimeInterval otherReadOnStrobe = getIntervalOnDataStrobe(strobeCommand, config.Timings);
|
|
|
|
if (readOnStrobe.timeIsInInterval(otherReadOnStrobe.start))
|
|
{
|
|
return !isClkAligned(otherReadOnStrobe.start - readOnStrobe.start,
|
|
2 * config.Timings.clk);
|
|
}
|
|
else if (otherReadOnStrobe.timeIsInInterval(readOnStrobe.start))
|
|
{
|
|
return !isClkAligned(readOnStrobe.start - otherReadOnStrobe.start,
|
|
2 * config.Timings.clk);
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else if (strobeCommand.getCommand() == Command::Write
|
|
|| strobeCommand.getCommand() == Command::WriteA)
|
|
{
|
|
//read to write
|
|
if (strobeCommand.getStart() >= read.getStart())
|
|
{
|
|
return !(strobeCommand.getStart() >= getIntervalOnDataStrobe(read, config.Timings).end);
|
|
}
|
|
//write to read
|
|
else
|
|
{
|
|
return !(read.getStart()>= getIntervalOnDataStrobe(strobeCommand, config.Timings).end + config.Timings.tWTR);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
reportFatal("Read Checker",
|
|
"Invalid strobeCommand in data strobe commands "
|
|
+ commandToString(strobeCommand.getCommand()));
|
|
return true;
|
|
}
|
|
}
|
|
|
|
} /* namespace controller */
|