/* * 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 */