Multi-cycle commands scheduled at last cycle on bus, LPDDR4 adapted.

This commit is contained in:
Lukas Steiner
2020-07-29 09:05:32 +02:00
parent 12a4163afc
commit 4ce4611b9c
10 changed files with 75 additions and 88 deletions

View File

@@ -107,23 +107,23 @@ sc_time MemSpecLPDDR4::getRefreshIntervalPB() const
sc_time MemSpecLPDDR4::getExecutionTime(Command command, const tlm_generic_payload &) const
{
if (command == Command::PRE)
return tRPpb + tCK;
return tRPpb;
else if (command == Command::PREA)
return tRPab + tCK;
return tRPab;
else if (command == Command::ACT)
return tRCD + 3 * tCK;
return tRCD;
else if (command == Command::RD)
return tRL + tDQSCK + burstDuration + 3 * tCK;
return tRL + tDQSCK + burstDuration;
else if (command == Command::RDA)
return burstDuration + tRTP - 5 * tCK + tRPpb;
return burstDuration + tRTP - 8 * tCK + tRPpb;
else if (command == Command::WR)
return tWL + tDQSS + tDQS2DQ + burstDuration + 3 * tCK;
return tWL + tDQSS + tDQS2DQ + burstDuration;
else if (command == Command::WRA)
return tWL + 4 * tCK + burstDuration + tWR + tRPpb;
return tWL + tCK + burstDuration + tWR + tRPpb;
else if (command == Command::REFA)
return tRFCab + tCK;
return tRFCab;
else if (command == Command::REFB)
return tRFCpb + tCK;
return tRFCpb;
else
{
SC_REPORT_FATAL("getExecutionTime",
@@ -135,11 +135,11 @@ sc_time MemSpecLPDDR4::getExecutionTime(Command command, const tlm_generic_paylo
TimeInterval MemSpecLPDDR4::getIntervalOnDataStrobe(Command command) const
{
if (command == Command::RD || command == Command::RDA)
return TimeInterval(sc_time_stamp() + tRL + tDQSCK + 3 * tCK,
sc_time_stamp() + tRL + tDQSCK + burstDuration + 3 * tCK);
return TimeInterval(sc_time_stamp() + tRL + tDQSCK,
sc_time_stamp() + tRL + tDQSCK + burstDuration);
else if (command == Command::WR || command == Command::WRA)
return TimeInterval(sc_time_stamp() + tWL + tDQSS + tDQS2DQ + 3 * tCK,
sc_time_stamp() + tWL + tDQSS + tDQS2DQ + burstDuration + 3 * tCK);
return TimeInterval(sc_time_stamp() + tWL + tDQSS + tDQS2DQ,
sc_time_stamp() + tWL + tDQSS + tDQS2DQ + burstDuration);
else
{
SC_REPORT_FATAL("MemSpecLPDDR4", "Method was called with invalid argument");

View File

@@ -284,7 +284,7 @@ void Controller::controllerMethod()
else
bankMachines[bank.ID()]->updateState(commandPair.first);
refreshManagers[rank.ID()]->updateState(commandPair.first, commandPair.second);
refreshManagers[rank.ID()]->updateState(commandPair.first);
powerDownManagers[rank.ID()]->updateState(commandPair.first);
checker->insert(commandPair.first, rank, bankgroup, bank);

View File

@@ -54,16 +54,16 @@ CheckerLPDDR4::CheckerLPDDR4()
tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL;
tWRRD = memSpec->tWL + memSpec->tCK + tBURST + memSpec->tWTR;
tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL;
tRDPRE = memSpec->tRTP + tBURST - 6 * memSpec->tCK;
tRDPRE = memSpec->tRTP + tBURST - 8 * memSpec->tCK;
tRDAACT = memSpec->tRTP + tBURST - 8 * memSpec->tCK + memSpec->tRPpb;
tWRPRE = memSpec->tWL + tBURST + memSpec->tCK + memSpec->tWR + 2 * memSpec->tCK;
tWRPRE = memSpec->tWL + tBURST + memSpec->tCK + memSpec->tWR;
tWRAACT = memSpec->tWL + tBURST + memSpec->tCK + memSpec->tWR + memSpec->tRPpb;
tACTPDEN = 3 * memSpec->tCK + memSpec->tCMDCKE;
tPRPDEN = memSpec->tCK + memSpec->tCMDCKE;
tRDPDEN = 3 * memSpec->tCK + memSpec->tRL + memSpec->tDQSCK + tBURST + memSpec->tRPST;
tWRPDEN = 3 * memSpec->tCK + memSpec->tWL + (std::ceil(memSpec->tDQSS / memSpec->tCK) + std::ceil(memSpec->tDQS2DQ / memSpec->tCK)) * memSpec->tCK + tBURST + memSpec->tWR;
tWRAPDEN = 3 * memSpec->tCK + memSpec->tWL + (std::ceil(memSpec->tDQSS / memSpec->tCK) + std::ceil(memSpec->tDQS2DQ / memSpec->tCK)) * memSpec->tCK + tBURST + memSpec->tWR + 2 * memSpec->tCK;
tREFPDEN = memSpec->tCK + memSpec->tCMDCKE;
tACTPDEN = memSpec->tCMDCKE;
tPRPDEN = memSpec->tCMDCKE;
tRDPDEN = memSpec->tRL + memSpec->tDQSCK + tBURST + memSpec->tRPST;
tWRPDEN = memSpec->tWL + (std::ceil(memSpec->tDQSS / memSpec->tCK) + std::ceil(memSpec->tDQS2DQ / memSpec->tCK)) * memSpec->tCK + tBURST + memSpec->tWR;
tWRAPDEN = memSpec->tWL + (std::ceil(memSpec->tDQSS / memSpec->tCK) + std::ceil(memSpec->tDQS2DQ / memSpec->tCK)) * memSpec->tCK + tBURST + memSpec->tWR + 2 * memSpec->tCK;
tREFPDEN = memSpec->tCMDCKE;
}
sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, BankGroup, Bank bank) const
@@ -118,7 +118,7 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, Bank
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP + 3 * memSpec->tCK);
}
else if (command == Command::WR || command == Command::WRA)
{
@@ -160,7 +160,7 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, Bank
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP + 3 * memSpec->tCK);
}
else if (command == Command::ACT)
{
@@ -182,44 +182,44 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, Bank
lastCommandStart = lastScheduledByCommandAndBank[Command::PRE][bank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb - 2 * memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb);
lastCommandStart = lastScheduledByCommandAndRank[Command::PREA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab - 2 * memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP + 3 * memSpec->tCK);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP + 3 * memSpec->tCK);
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab - 2 * memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
lastCommandStart = lastScheduledByCommandAndBank[Command::REFB][bank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb - 2 * memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD - 2 * memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD);
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR - 2 * memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
if (last4Activates[rank.ID()].size() >= 4)
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW - 3 * memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
}
else if (command == Command::PRE)
{
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + 2 * memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
@@ -235,13 +235,13 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, Bank
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP + memSpec->tCK);
}
else if (command == Command::PREA)
{
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + 2 * memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
@@ -265,7 +265,7 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, Bank
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP + memSpec->tCK);
lastCommandStart = lastScheduledByCommandAndRank[Command::REFB][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
@@ -275,7 +275,7 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, Bank
{
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb + 2 * memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
@@ -295,7 +295,7 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, Bank
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP + memSpec->tCK);
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
@@ -313,11 +313,11 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, Bank
{
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb + 2 * memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb);
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD + 2 * memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD);
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
@@ -337,11 +337,11 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, Bank
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP + memSpec->tCK);
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP + memSpec->tCK);
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
@@ -356,7 +356,7 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, Bank
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
if (last4Activates[rank.ID()].size() >= 4)
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW - memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, last4Activates[rank.ID()].front() + memSpec->tFAW);
}
else if (command == Command::PDEA)
{
@@ -446,7 +446,7 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, Bank
{
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb + 2 * memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb);
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
@@ -466,7 +466,7 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, Bank
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP + memSpec->tCK);
lastCommandStart = lastScheduledByCommandAndRank[Command::REFA][rank.ID()];
if (lastCommandStart != SC_ZERO_TIME)
@@ -490,7 +490,7 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, Rank rank, Bank
SC_REPORT_FATAL("CheckerLPDDR4", "Unknown command!");
// Check if command bus is free
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->getCommandLength(command));
return earliestTimeToStart;
}
@@ -504,7 +504,7 @@ void CheckerLPDDR4::insert(Command command, Rank rank, BankGroup, Bank bank)
lastScheduledByCommandAndRank[command][rank.ID()] = sc_time_stamp();
lastScheduledByCommand[command] = sc_time_stamp();
lastCommandOnBus = sc_time_stamp() + memSpec->getCommandLength(command) - memSpec->tCK;
lastCommandOnBus = sc_time_stamp();
if (command == Command::ACT || command == Command::REFB)
{

View File

@@ -91,17 +91,14 @@ sc_time RefreshManagerBankwise::start()
bool forcedRefresh = (flexibilityCounter == maxPostponed);
bool allBanksBusy = true;
if (!skipSelection)
for (auto it = remainingBankMachines.begin(); it != remainingBankMachines.end(); it++)
{
for (auto it = remainingBankMachines.begin(); it != remainingBankMachines.end(); it++)
if ((*it)->isIdle())
{
if ((*it)->isIdle())
{
currentIterator = it;
currentBankMachine = *it;
allBanksBusy = false;
break;
}
currentIterator = it;
currentBankMachine = *it;
allBanksBusy = false;
break;
}
}
@@ -116,16 +113,8 @@ sc_time RefreshManagerBankwise::start()
if (currentBankMachine->getState() == BmState::Activated)
nextCommand = Command::PRE;
else
{
nextCommand = Command::REFB;
if (forcedRefresh)
{
currentBankMachine->block();
skipSelection = true;
}
}
timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, rank,
currentBankMachine->getBankGroup(), currentBankMachine->getBank());
return timeToSchedule;
@@ -168,12 +157,11 @@ sc_time RefreshManagerBankwise::start()
return timeForNextTrigger;
}
void RefreshManagerBankwise::updateState(Command command, tlm_generic_payload *payload)
void RefreshManagerBankwise::updateState(Command command)
{
switch (command)
{
case Command::REFB:
skipSelection = false;
remainingBankMachines.erase(currentIterator);
if (remainingBankMachines.empty())
remainingBankMachines = allBankMachines;

View File

@@ -50,7 +50,7 @@ public:
virtual std::pair<Command, tlm::tlm_generic_payload *> getNextCommand() override;
virtual sc_time start() override;
virtual void updateState(Command, tlm::tlm_generic_payload *) override;
virtual void updateState(Command) override;
private:
enum class RmState {Regular, Pulledin} state = RmState::Regular;
@@ -74,7 +74,6 @@ private:
int maxPulledin = 0;
bool sleeping = false;
bool skipSelection = false;
};
#endif // REFRESHMANAGERBANKWISE_H

View File

@@ -46,7 +46,7 @@ class RefreshManagerDummy final : public RefreshManagerIF
public:
virtual std::pair<Command, tlm::tlm_generic_payload *> getNextCommand() override;
virtual sc_time start() override;
virtual void updateState(Command, tlm::tlm_generic_payload *) override {}
virtual void updateState(Command) override {}
};
#endif // REFRESHMANAGERDUMMY_H

View File

@@ -47,7 +47,7 @@ public:
virtual std::pair<Command, tlm::tlm_generic_payload *> getNextCommand() = 0;
virtual sc_time start() = 0;
virtual void updateState(Command, tlm::tlm_generic_payload *) = 0;
virtual void updateState(Command) = 0;
};
#endif // REFRESHMANAGERIF_H

View File

@@ -140,7 +140,7 @@ sc_time RefreshManagerRankwise::start()
return timeForNextTrigger;
}
void RefreshManagerRankwise::updateState(Command command, tlm_generic_payload *)
void RefreshManagerRankwise::updateState(Command command)
{
switch (command)
{

View File

@@ -48,7 +48,7 @@ public:
virtual std::pair<Command, tlm::tlm_generic_payload *> getNextCommand() override;
virtual sc_time start() override;
virtual void updateState(Command, tlm::tlm_generic_payload *) override;
virtual void updateState(Command) override;
private:
enum class RmState {Regular, Pulledin} state = RmState::Regular;

View File

@@ -60,49 +60,49 @@ shared_ptr<Phase> PhaseFactory::CreatePhase(ID id, const QString &dbPhaseName,
{Timespan(span.Begin(), span.Begin() + clk)}, std::shared_ptr<Timespan>()));
else if (dbPhaseName == "PRE")
return shared_ptr<Phase>(new PRE(id, span, trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.PRE)}, std::shared_ptr<Timespan>()));
{Timespan(span.Begin() - clk * (cl.PRE - 1), span.Begin() + clk)}, std::shared_ptr<Timespan>()));
else if (dbPhaseName == "ACTB")
return shared_ptr<Phase>(new ACTB(id, span, trans,
{Timespan(span.Begin(), span.Begin() + clk)}, std::shared_ptr<Timespan>()));
else if (dbPhaseName == "ACT")
return shared_ptr<Phase>(new ACT(id, span, trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.ACT)}, std::shared_ptr<Timespan>()));
{Timespan(span.Begin() - clk * (cl.ACT - 1), span.Begin() + clk)}, std::shared_ptr<Timespan>()));
else if (dbPhaseName == "PREA")
return shared_ptr<Phase>(new PRECHARGE_ALL(id, span, trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.PREA)}, std::shared_ptr<Timespan>()));
{Timespan(span.Begin() - clk * (cl.PREA - 1), span.Begin() + clk)}, std::shared_ptr<Timespan>()));
else if (dbPhaseName == "REFA")
return shared_ptr<Phase>(new REFA(id, span, trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.REFA)}, std::shared_ptr<Timespan>()));
{Timespan(span.Begin() - clk * (cl.REFA - 1), span.Begin() + clk)}, std::shared_ptr<Timespan>()));
else if (dbPhaseName == "REFB")
return shared_ptr<Phase>(new REFB(id, span, trans,
{Timespan(span.Begin(), span.Begin() + clk * cl.REFB)}, std::shared_ptr<Timespan>()));
{Timespan(span.Begin() - clk * (cl.REFB - 1), span.Begin() + clk)}, std::shared_ptr<Timespan>()));
else if (dbPhaseName == "RD")
return shared_ptr<Phase>(new RD(id, span, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.RD)},
return shared_ptr<Phase>(new RD(id, span, trans, {Timespan(span.Begin() - clk * (cl.RD - 1), span.Begin() + clk)},
std::shared_ptr<Timespan>(new Timespan(trans->SpanOnDataStrobe()))));
else if (dbPhaseName == "RDA")
return shared_ptr<Phase>(new RDA(id, span, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.RDA)},
return shared_ptr<Phase>(new RDA(id, span, trans, {Timespan(span.Begin() - clk * (cl.RDA - 1), span.Begin() + clk)},
std::shared_ptr<Timespan>(new Timespan(trans->SpanOnDataStrobe()))));
else if (dbPhaseName == "WR")
return shared_ptr<Phase>(new WR(id, span, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.WR)},
return shared_ptr<Phase>(new WR(id, span, trans, {Timespan(span.Begin() - clk * (cl.WR - 1), span.Begin() + clk)},
std::shared_ptr<Timespan>(new Timespan(trans->SpanOnDataStrobe()))));
else if (dbPhaseName == "WRA")
return shared_ptr<Phase>(new WRA(id, span, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.WRA)},
return shared_ptr<Phase>(new WRA(id, span, trans, {Timespan(span.Begin() - clk * (cl.WRA - 1), span.Begin() + clk)},
std::shared_ptr<Timespan>(new Timespan(trans->SpanOnDataStrobe()))));
else if (dbPhaseName == "PDNA")
return shared_ptr<Phase>(new PDNA(id, span, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.PDEA),
Timespan(span.End() - clk * cl.PDXA, span.End())}, std::shared_ptr<Timespan>()));
return shared_ptr<Phase>(new PDNA(id, span, trans, {Timespan(span.Begin() - clk * (cl.PDEA - 1), span.Begin() + clk),
Timespan(span.End() - clk * (cl.PDXA - 1), span.End() + clk)}, std::shared_ptr<Timespan>()));
else if (dbPhaseName == "PDNAB")
return shared_ptr<Phase>(new PDNAB(id, span, trans, {Timespan(span.Begin(), span.Begin() + clk),
Timespan(span.End() - clk, span.End())}, std::shared_ptr<Timespan>()));
else if (dbPhaseName == "PDNP")
return shared_ptr<Phase>(new PDNP(id, span, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.PDEP),
Timespan(span.End() - clk * cl.PDXP, span.End())}, std::shared_ptr<Timespan>()));
return shared_ptr<Phase>(new PDNP(id, span, trans, {Timespan(span.Begin() - clk * (cl.PDEP - 1), span.Begin() + clk),
Timespan(span.End() - clk * (cl.PDXP - 1), span.End() + clk)}, std::shared_ptr<Timespan>()));
else if (dbPhaseName == "PDNPB")
return shared_ptr<Phase>(new PDNPB(id, span, trans, {Timespan(span.Begin(), span.Begin() + clk),
Timespan(span.End() - clk, span.End())}, std::shared_ptr<Timespan>()));
else if (dbPhaseName == "SREF")
return shared_ptr<Phase>(new SREF(id, span, trans, {Timespan(span.Begin(), span.Begin() + clk * cl.SREFEN),
Timespan(span.End() - clk * cl.SREFEX, span.End())}, std::shared_ptr<Timespan>()));
return shared_ptr<Phase>(new SREF(id, span, trans, {Timespan(span.Begin() - clk * (cl.SREFEN - 1), span.Begin() + clk),
Timespan(span.End() - clk * (cl.SREFEX - 1), span.End() + clk)}, std::shared_ptr<Timespan>()));
else if (dbPhaseName == "SREFB")
return shared_ptr<Phase>(new SREFB(id, span, trans, {Timespan(span.Begin(), span.Begin() + clk),
Timespan(span.End() - clk, span.End())}, std::shared_ptr<Timespan>()));