Included FAW check.
This commit is contained in:
@@ -96,38 +96,26 @@ const ScheduledCommand ControllerState::getLastScheduledCommand(Bank bank)
|
||||
|
||||
void ControllerState::change(const ScheduledCommand &scheduledCommand)
|
||||
{
|
||||
bus.blockSlot(scheduledCommand.getStart());
|
||||
|
||||
printDebugMessage("Changing state on bank " + to_string(
|
||||
scheduledCommand.getBank().ID()) + " command is " + commandToString(
|
||||
scheduledCommand.getCommand()));
|
||||
|
||||
bus.blockSlot(scheduledCommand.getStart());
|
||||
lastScheduledByCommandAndBank[scheduledCommand.getCommand()][scheduledCommand.getBank()]
|
||||
= scheduledCommand;
|
||||
|
||||
switch (scheduledCommand.getCommand())
|
||||
// TODO: implement FAW for ACTB
|
||||
if (scheduledCommand.getCommand() == Command::ACT)
|
||||
{
|
||||
case Command::ACTB:
|
||||
lastActivatesB.emplace(scheduledCommand.getStart(), scheduledCommand);
|
||||
break;
|
||||
case Command::ACT:
|
||||
lastActivates.emplace(scheduledCommand.getStart(), scheduledCommand);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (lastActivates.size() == 4)
|
||||
lastActivates.pop();
|
||||
lastActivates.push(scheduledCommand.getStart());
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerState::cleanUp(sc_time time)
|
||||
{
|
||||
bus.cleanUpSlots(time);
|
||||
|
||||
if (time >= config->memSpec->tActHistory())
|
||||
lastActivates.erase(lastActivates.begin(),
|
||||
lastActivates.lower_bound(time - config->memSpec->tActHistory()));
|
||||
|
||||
if (time >= config->memSpec->tActBHistory())
|
||||
lastActivatesB.erase(lastActivatesB.begin(),
|
||||
lastActivatesB.lower_bound(time - config->memSpec->tActBHistory()));
|
||||
}
|
||||
|
||||
void ControllerState::printDebugMessage(std::string message)
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "core/Slots.h"
|
||||
#include "core/configuration/Configuration.h"
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <list>
|
||||
|
||||
@@ -67,7 +68,7 @@ public:
|
||||
//ScheduledCommand lastScheduled;
|
||||
|
||||
Slots bus;
|
||||
std::map<sc_time, ScheduledCommand> lastActivates;
|
||||
std::queue<sc_time> lastActivates;
|
||||
std::map<sc_time, ScheduledCommand> lastActivatesB;
|
||||
|
||||
private:
|
||||
|
||||
@@ -113,14 +113,14 @@ bool ActBChecker::satsfies_activateToActivate_differentBank(
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (auto act : state.lastActivates) {
|
||||
sc_time t = act.first, tRRD = (cmd.getBankGroup() == act.second.getBankGroup() ?
|
||||
config.memSpec->tRRD_L_old : config.memSpec->tRRD_S_old);
|
||||
if ((t < cmd.getStart() && cmd.getStart() - t < tRRD) || (cmd.getStart() <= t
|
||||
&& t - cmd.getStart() < tRRD)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// for (auto act : state.lastActivates) {
|
||||
// sc_time t = act.first, tRRD = (cmd.getBankGroup() == act.second.getBankGroup() ?
|
||||
// config.memSpec->tRRD_L_old : config.memSpec->tRRD_S_old);
|
||||
// if ((t < cmd.getStart() && cmd.getStart() - t < tRRD) || (cmd.getStart() <= t
|
||||
// && t - cmd.getStart() < tRRD)) {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -110,15 +110,15 @@ void ActivateChecker::delay_to_satisfy_activateToActivate_sameBank(
|
||||
bool ActivateChecker::satsfies_activateToActivate_differentBank(
|
||||
ScheduledCommand &command) const
|
||||
{
|
||||
for (auto act : state.lastActivates) {
|
||||
sc_time time = act.first;
|
||||
sc_time tRRD = (command.getBankGroup() == act.second.getBankGroup()) ?
|
||||
config.memSpec->tRRD_L_old : config.memSpec->tRRD_S_old;
|
||||
// for (auto act : state.lastActivates) {
|
||||
// sc_time time = act.first;
|
||||
// sc_time tRRD = (command.getBankGroup() == act.second.getBankGroup()) ?
|
||||
// config.memSpec->tRRD_L_old : config.memSpec->tRRD_S_old;
|
||||
|
||||
if ((time < command.getStart() && command.getStart() - time < tRRD)
|
||||
|| (command.getStart() <= time && time - command.getStart() < tRRD))
|
||||
return false;
|
||||
}
|
||||
// if ((time < command.getStart() && command.getStart() - time < tRRD)
|
||||
// || (command.getStart() <= time && time - command.getStart() < tRRD))
|
||||
// return false;
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -129,20 +129,20 @@ bool ActivateChecker::satisfies_nActivateWindow(ScheduledCommand &command) const
|
||||
* command in a copied set (not necessarily the last in time),
|
||||
* and check if the n-act constraint holds for the whole set.
|
||||
*/
|
||||
if (state.lastActivates.size() >= config.memSpec->nActivate) {
|
||||
map<sc_time, ScheduledCommand> lastActivates = state.lastActivates;
|
||||
lastActivates.emplace(command.getStart(), command);
|
||||
auto upper = lastActivates.begin();
|
||||
advance(upper, config.memSpec->nActivate);
|
||||
auto lower = lastActivates.begin();
|
||||
// if (state.lastActivates.size() >= config.memSpec->nActivate) {
|
||||
// map<sc_time, ScheduledCommand> lastActivates = state.lastActivates;
|
||||
// lastActivates.emplace(command.getStart(), command);
|
||||
// auto upper = lastActivates.begin();
|
||||
// advance(upper, config.memSpec->nActivate);
|
||||
// auto lower = lastActivates.begin();
|
||||
|
||||
while (upper != lastActivates.end()) {
|
||||
if (upper->first - lower->first < config.memSpec->tNAW_old)
|
||||
return false;
|
||||
++upper;
|
||||
++lower;
|
||||
}
|
||||
}
|
||||
// while (upper != lastActivates.end()) {
|
||||
// if (upper->first - lower->first < config.memSpec->tNAW_old)
|
||||
// return false;
|
||||
// ++upper;
|
||||
// ++lower;
|
||||
// }
|
||||
// }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -397,13 +397,13 @@ void CheckerDDR3::delay_to_satisfy_activateToActivate_sameBank(ScheduledCommand
|
||||
|
||||
bool CheckerDDR3::satsfies_activateToActivate_differentBank(ScheduledCommand &command) const
|
||||
{
|
||||
for (auto act : state.lastActivates)
|
||||
{
|
||||
sc_time time = act.first;
|
||||
if ((time < command.getStart() && command.getStart() - time < memSpec->tRRD)
|
||||
|| (command.getStart() <= time && time - command.getStart() < memSpec->tRRD))
|
||||
return false;
|
||||
}
|
||||
// for (auto act : state.lastActivates)
|
||||
// {
|
||||
// sc_time time = act.first;
|
||||
// if ((time < command.getStart() && command.getStart() - time < memSpec->tRRD)
|
||||
// || (command.getStart() <= time && time - command.getStart() < memSpec->tRRD))
|
||||
// return false;
|
||||
// }
|
||||
return true;
|
||||
|
||||
}
|
||||
@@ -415,22 +415,22 @@ bool CheckerDDR3::satisfies_nActivateWindow(ScheduledCommand &command) const
|
||||
* command in a copied set (not necessarily the last in time),
|
||||
* and check if the n-act constraint holds for the whole set.
|
||||
*/
|
||||
if (state.lastActivates.size() >= memSpec->nActivate)
|
||||
{
|
||||
std::map<sc_time, ScheduledCommand> lastActivates = state.lastActivates;
|
||||
lastActivates.emplace(command.getStart(), command);
|
||||
auto upper = lastActivates.begin();
|
||||
std::advance(upper, memSpec->nActivate);
|
||||
auto lower = lastActivates.begin();
|
||||
// if (state.lastActivates.size() >= memSpec->nActivate)
|
||||
// {
|
||||
// std::map<sc_time, ScheduledCommand> lastActivates = state.lastActivates;
|
||||
// lastActivates.emplace(command.getStart(), command);
|
||||
// auto upper = lastActivates.begin();
|
||||
// std::advance(upper, memSpec->nActivate);
|
||||
// auto lower = lastActivates.begin();
|
||||
|
||||
while (upper != lastActivates.end())
|
||||
{
|
||||
if (upper->first - lower->first < memSpec->tNAW_old)
|
||||
return false;
|
||||
upper++;
|
||||
lower++;
|
||||
}
|
||||
}
|
||||
// while (upper != lastActivates.end())
|
||||
// {
|
||||
// if (upper->first - lower->first < memSpec->tNAW_old)
|
||||
// return false;
|
||||
// upper++;
|
||||
// lower++;
|
||||
// }
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,8 @@ sc_time CheckerDDR3New::delayToSatisfyConstraints(Command command, Bank bank)
|
||||
|
||||
if (!state.bus.isFree(sc_time_stamp()))
|
||||
minTimeToWait = max(minTimeToWait, sc_time_stamp() + memSpec->clk);
|
||||
|
||||
minTimeToWait = max(minTimeToWait, timeToSatisfyFAW());
|
||||
}
|
||||
else if (command == Command::RD || command == Command::RDA)
|
||||
{
|
||||
@@ -165,28 +167,16 @@ sc_time CheckerDDR3New::delayToSatisfyConstraints(Command command, Bank bank)
|
||||
return (minTimeToWait - sc_time_stamp());
|
||||
}
|
||||
|
||||
bool CheckerDDR3New::satisfiesNActivateWindow(ScheduledCommand &command) const
|
||||
sc_time CheckerDDR3New::timeToSatisfyFAW()
|
||||
{
|
||||
/*
|
||||
* there may be activates scheduled in the future, so emplace
|
||||
* command in a copied set (not necessarily the last in time),
|
||||
* and check if the n-act constraint holds for the whole set.
|
||||
*/
|
||||
if (state.lastActivates.size() >= memSpec->nActivate)
|
||||
if (state.lastActivates.size() < 4)
|
||||
return sc_time_stamp();
|
||||
else
|
||||
{
|
||||
std::map<sc_time, ScheduledCommand> lastActivates = state.lastActivates;
|
||||
lastActivates.emplace(command.getStart(), command);
|
||||
auto upper = lastActivates.begin();
|
||||
std::advance(upper, memSpec->nActivate);
|
||||
auto lower = lastActivates.begin();
|
||||
|
||||
while (upper != lastActivates.end())
|
||||
{
|
||||
if (upper->first - lower->first < memSpec->tNAW_old)
|
||||
return false;
|
||||
upper++;
|
||||
lower++;
|
||||
}
|
||||
sc_time earliestTime = state.lastActivates.front() + memSpec->tFAW;
|
||||
if (earliestTime > sc_time_stamp())
|
||||
return earliestTime;
|
||||
else
|
||||
return sc_time_stamp();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ private:
|
||||
MemSpecDDR3 *memSpec;
|
||||
|
||||
//Activate
|
||||
bool satisfiesNActivateWindow(ScheduledCommand &command) const;
|
||||
sc_time timeToSatisfyFAW();
|
||||
|
||||
//PowerDown TODO: Implement this method?
|
||||
//sc_time getTimeConstraintToEnterPowerDown(Command lastCmd, Command pdnCmd) const;
|
||||
|
||||
Reference in New Issue
Block a user