/*
 * Copyright (c) 2022, Technische Universität Kaiserslautern
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors:
 *    Iron Prando da Silva
 */

#include "TimeDependenciesInfoLPDDR5.h"

using namespace std;

TimeDependenciesInfoLPDDR5::TimeDependenciesInfoLPDDR5(const QJsonObject& memspec, const uint tCK) : DRAMTimeDependenciesBase(memspec, tCK) {
  mInitializeValues();
}

void TimeDependenciesInfoLPDDR5::mInitializeValues() {
  burstLength = mMemspecJson["memarchitecturespec"].toObject()["burstLength"].toInt();
  dataRate = mMemspecJson["memarchitecturespec"].toObject()["dataRate"].toInt();
  per2BankOffset = mMemspecJson["memarchitecturespec"].toObject()["per2BankOffset"].toInt();

  tRCD = tCK * mMemspecJson["memtimingspec"].toObject()["RCD"].toInt();
  tRPpb = tCK * mMemspecJson["memtimingspec"].toObject()["RPpb"].toInt();
  tRPab = tCK * mMemspecJson["memtimingspec"].toObject()["RPab"].toInt();
  tRAS = tCK * mMemspecJson["memtimingspec"].toObject()["RAS"].toInt();
  tRCpb = tCK * mMemspecJson["memtimingspec"].toObject()["RCpb"].toInt();
  tRCab = tCK * mMemspecJson["memtimingspec"].toObject()["RCab"].toInt();
  tCL = tCK * mMemspecJson["memtimingspec"].toObject()["CL"].toInt();
  tCWL = tCK * mMemspecJson["memtimingspec"].toObject()["CWL"].toInt();
  tAL = tCK * mMemspecJson["memtimingspec"].toObject()["AL"].toInt();
  tRL = tCK * mMemspecJson["memtimingspec"].toObject()["RL"].toInt();
  tRPRE = tCK * mMemspecJson["memtimingspec"].toObject()["RPRE"].toInt();
  tWPRE = tCK * mMemspecJson["memtimingspec"].toObject()["WPRE"].toInt();
  tWL = tCK * mMemspecJson["memtimingspec"].toObject()["WL"].toInt();
  tCCD_S = tCK * mMemspecJson["memtimingspec"].toObject()["CCD_S"].toInt();
  tCCD_L = tCK * mMemspecJson["memtimingspec"].toObject()["CCD_L"].toInt();
  tRRD = tCK * mMemspecJson["memtimingspec"].toObject()["RRD"].toInt();
  tFAW = tCK * mMemspecJson["memtimingspec"].toObject()["FAW"].toInt();
  tWTR_S = tCK * mMemspecJson["memtimingspec"].toObject()["WTR_S"].toInt();
  tWTR_L = tCK * mMemspecJson["memtimingspec"].toObject()["WTR_L"].toInt();
  tRTP = tCK * mMemspecJson["memtimingspec"].toObject()["RTP"].toInt();
  tWR = tCK * mMemspecJson["memtimingspec"].toObject()["WR"].toInt();
  tRFCab = tCK * mMemspecJson["memtimingspec"].toObject()["RFCab"].toInt();
  tRFCpb = tCK * mMemspecJson["memtimingspec"].toObject()["RFCpb"].toInt();
  tXS = tCK * mMemspecJson["memtimingspec"].toObject()["XS"].toInt();
  tXSDLL = tCK * mMemspecJson["memtimingspec"].toObject()["XSDLL"].toInt();
  tXP = tCK * mMemspecJson["memtimingspec"].toObject()["XP"].toInt();
  tCKE = tCK * mMemspecJson["memtimingspec"].toObject()["CKE"].toInt();
  tCKESR = tCK * mMemspecJson["memtimingspec"].toObject()["CKESR"].toInt();
  tPD = tCK * mMemspecJson["memtimingspec"].toObject()["PD"].toInt();
  tPRPDEN = tCK * mMemspecJson["memtimingspec"].toObject()["PRPDEN"].toInt();
  tREFPDEN = tCK * mMemspecJson["memtimingspec"].toObject()["REFPDEN"].toInt();
  tRTRS = tCK * mMemspecJson["memtimingspec"].toObject()["RTRS"].toInt();
  tRBTP = tCK * mMemspecJson["memtimingspec"].toObject()["RBTP"].toInt();
  BL_n_min_16 = tCK * mMemspecJson["memtimingspec"].toObject()["BL_n_min_16"].toInt();
  BL_n_min_32 = tCK * mMemspecJson["memtimingspec"].toObject()["BL_n_min_32"].toInt();
  BL_n_max_16 = tCK * mMemspecJson["memtimingspec"].toObject()["BL_n_max_16"].toInt();
  BL_n_max_32 = tCK * mMemspecJson["memtimingspec"].toObject()["BL_n_max_32"].toInt();
  BL_n_S_16 = tCK * mMemspecJson["memtimingspec"].toObject()["BL_n_S_16"].toInt();
  BL_n_S_32 = tCK * mMemspecJson["memtimingspec"].toObject()["BL_n_S_32"].toInt();
  BL_n_L_16 = tCK * mMemspecJson["memtimingspec"].toObject()["BL_n_L_16"].toInt();
  BL_n_L_32 = tCK * mMemspecJson["memtimingspec"].toObject()["BL_n_L_32"].toInt();
  tWCK2DQO = tCK * mMemspecJson["memtimingspec"].toObject()["WCK2DQO"].toInt();
  tPPD = tCK * mMemspecJson["memtimingspec"].toObject()["PPD"].toInt();
  tpbR2act = tCK * mMemspecJson["memtimingspec"].toObject()["pbR2act"].toInt();
  tpbR2pbR = tCK * mMemspecJson["memtimingspec"].toObject()["pbR2pbR"].toInt();

  tBURST16 = (uint) (16 / (float) dataRate) * tCK;
  tBURST32 = (uint) (32 / (float) dataRate) * tCK;

  mPools.insert({
    "CMD_BUS", {
      1, {
        {"ACT", 2 * tCK},
        {"RD", tCK},
        {"WR", tCK},
        {"RDA", tCK},
        {"WRA", tCK},
        {"PREPB", tCK},
        {"PREAB", tCK},
        {"REFAB", tCK},
        {"REFPB", tCK},
        {"REFP2B", tCK},
      }
    }
  });

  mPools.insert({
    "NAW", {
      4, {
        {"ACT", tFAW},
        {"REFPB", tFAW},
        {"REFP2B", tFAW},
      }
    }
  });

}

const std::vector<QString> TimeDependenciesInfoLPDDR5::getPossiblePhases() {
  return {
    "ACT",
    "RD",
    "WR",
    "PREPB",
    "RDA",
    "WRA",
    "REFPB",
    "REFP2B",
    "REFAB",
    "PREAB",
  };
}

DependencyMap TimeDependenciesInfoLPDDR5::mSpecializedGetDependencies() const {
  DependencyMap dmap;

  auto passBurstLength16 = std::make_shared<PassFunction>(
    [] PASSFUNCTIONDECL {
      auto other = std::dynamic_pointer_cast<LPDDR5DBPhaseEntry>(otherPhase);
      if (!other) return false;
      return other->tBurstLength == 16;
    }
  );
  auto passBurstLength32 = std::make_shared<PassFunction>(
    [] PASSFUNCTIONDECL {
      auto other = std::dynamic_pointer_cast<LPDDR5DBPhaseEntry>(otherPhase);
      if (!other) return false;
      return other->tBurstLength == 32;
    }
  );

  dmap.emplace(
    piecewise_construct,
    forward_as_tuple("ACT"),
    forward_as_tuple(
      initializer_list<TimeDependency>{
        {tRCpb, "ACT", DependencyType::IntraBank, "tRCpb"},
        {tRRD, "ACT", DependencyType::IntraRank, "tRRD"},
        {BL_n_min_16 + tRBTP + tRPpb - tCK, "RDA", DependencyType::IntraBank, "BL_n_min_16 + tRBTP + tRPpb - tCK", passBurstLength16},
        {BL_n_min_32 + tRBTP + tRPpb - tCK, "RDA", DependencyType::IntraBank, "BL_n_min_32 + tRBTP + tRPpb - tCK", passBurstLength32},
        {tWL + BL_n_min_16 + tCK + tWR + tRPpb - tCK, "WRA", DependencyType::IntraBank, "tWL + BL_n_min_16 + tCK + tWR + tRPpb - tCK", passBurstLength16},
        {tWL + BL_n_min_32 + tCK + tWR + tRPpb - tCK, "WRA", DependencyType::IntraBank, "tWL + BL_n_min_32 + tCK + tWR + tRPpb - tCK", passBurstLength32},
        {tRPpb - tCK, "PREPB", DependencyType::IntraBank, "tRPpb - tCK"},
        {tRPab - tCK, "PREAB", DependencyType::IntraRank, "tRPab - tCK"},
        {tRFCab - tCK, "REFAB", DependencyType::IntraRank, "tRFCab - tCK"},
        {tpbR2act - tCK, "REFPB", DependencyType::IntraRank, "tpbR2act - tCK"},
        {tpbR2act - tCK, "REFP2B", DependencyType::IntraRank, "tpbR2act - tCK"},
        {tRFCpb - tCK, "REFPB", DependencyType::IntraBank, "tRFCpb - tCK"},
        {tRFCpb - tCK, "REFP2B", DependencyType::IntraBank, "tRFCpb - tCK"},
        {0, "CMD_BUS", DependencyType::InterRank, "CMDBus"},
        {0, "NAW", DependencyType::IntraRank, "tFAW"},
      }
    )
  );

  dmap.emplace(
    piecewise_construct,
    forward_as_tuple("RD"),
    forward_as_tuple(
      initializer_list<TimeDependency>{
        {tRCD + tCK, "ACT", DependencyType::IntraBank, "tRCD + tCK"},
        {BL_n_L_16, "RD", DependencyType::IntraBankGroup, "BL_n_L_16", passBurstLength16},
        {BL_n_L_32, "RD", DependencyType::IntraBankGroup, "BL_n_L_32", passBurstLength32},
        {BL_n_S_16, "RD", DependencyType::IntraRank, "BL_n_S_16", passBurstLength16},
        {BL_n_S_32, "RD", DependencyType::IntraRank, "BL_n_S_32", passBurstLength32},
        {tBURST16 + tRTRS, "RD", DependencyType::InterRank, "tBURST16 + tRTRS", passBurstLength16},
        {tBURST32 + tRTRS, "RD", DependencyType::InterRank, "tBURST32 + tRTRS", passBurstLength32},
        {BL_n_L_16, "RDA", DependencyType::IntraBankGroup, "BL_n_L_16", passBurstLength16},
        {BL_n_L_32, "RDA", DependencyType::IntraBankGroup, "BL_n_L_32", passBurstLength32},
        {BL_n_S_16, "RDA", DependencyType::IntraRank, "BL_n_S_16", passBurstLength16},
        {BL_n_S_32, "RDA", DependencyType::IntraRank, "BL_n_S_32", passBurstLength32},
        {tBURST16 + tRTRS, "RDA", DependencyType::InterRank, "tBURST16 + tRTRS", passBurstLength16},
        {tBURST32 + tRTRS, "RDA", DependencyType::InterRank, "tBURST32 + tRTRS", passBurstLength32},
        {tWL + BL_n_max_16 + tWTR_L, "WR", DependencyType::IntraBankGroup, "tWL + BL_n_max_16 + tWTR_L", passBurstLength16},
        {tWL + BL_n_max_32 + tWTR_L, "WR", DependencyType::IntraBankGroup, "tWL + BL_n_max_32 + tWTR_L", passBurstLength32},
        {tWL + BL_n_min_16 + tWTR_S, "WR", DependencyType::IntraRank, "tWL + BL_n_min_16 + tWTR_S", passBurstLength16},
        {tWL + BL_n_min_32 + tWTR_S, "WR", DependencyType::IntraRank, "tWL + BL_n_min_32 + tWTR_S", passBurstLength32},
        {tWL + BL_n_max_16 + tWTR_L, "WRA", DependencyType::IntraBankGroup, "tWL + BL_n_max_16 + tWTR_L", passBurstLength16},
        {tWL + BL_n_max_32 + tWTR_L, "WRA", DependencyType::IntraBankGroup, "tWL + BL_n_max_32 + tWTR_L", passBurstLength32},
        {tWL + BL_n_min_16 + tWTR_S, "WRA", DependencyType::IntraRank, "tWL + BL_n_min_16 + tWTR_S", passBurstLength16},
        {tWL + BL_n_min_32 + tWTR_S, "WRA", DependencyType::IntraRank, "tWL + BL_n_min_32 + tWTR_S", passBurstLength32},
        {0, "CMD_BUS", DependencyType::InterRank, "CMDBus"},
      }
    )
  );

  dmap.emplace(
    piecewise_construct,
    forward_as_tuple("WR"),
    forward_as_tuple(
      initializer_list<TimeDependency>{
        {tRCD + tCK, "ACT", DependencyType::IntraBank, "tRCD + tCK"},
        {tRL + BL_n_max_16 + tWCK2DQO - tWL, "RD", DependencyType::IntraBankGroup, "tRL + BL_n_max_16 + tWCK2DQO - tWL", passBurstLength16},
        {tRL + BL_n_max_32 + tWCK2DQO - tWL, "RD", DependencyType::IntraBankGroup, "tRL + BL_n_max_32 + tWCK2DQO - tWL", passBurstLength32},
        {tRL + BL_n_min_16 + tWCK2DQO - tWL, "RD", DependencyType::IntraRank, "tRL + BL_n_min_16 + tWCK2DQO - tWL", passBurstLength16},
        {tRL + BL_n_min_32 + tWCK2DQO - tWL, "RD", DependencyType::IntraRank, "tRL + BL_n_min_32 + tWCK2DQO - tWL", passBurstLength32},
        {tRL + BL_n_max_16 + tWCK2DQO - tWL, "RDA", DependencyType::IntraBankGroup, "tRL + BL_n_max_16 + tWCK2DQO - tWL", passBurstLength16},
        {tRL + BL_n_max_32 + tWCK2DQO - tWL, "RDA", DependencyType::IntraBankGroup, "tRL + BL_n_max_32 + tWCK2DQO - tWL", passBurstLength32},
        {tRL + BL_n_min_16 + tWCK2DQO - tWL, "RDA", DependencyType::IntraRank, "tRL + BL_n_min_16 + tWCK2DQO - tWL", passBurstLength16},
        {tRL + BL_n_min_32 + tWCK2DQO - tWL, "RDA", DependencyType::IntraRank, "tRL + BL_n_min_32 + tWCK2DQO - tWL", passBurstLength32},
        {BL_n_L_16, "WR", DependencyType::IntraBankGroup, "BL_n_L_16", passBurstLength16},
        {BL_n_L_32, "WR", DependencyType::IntraBankGroup, "BL_n_L_32", passBurstLength32},
        {BL_n_S_16, "WR", DependencyType::IntraRank, "BL_n_S_16", passBurstLength16},
        {BL_n_S_32, "WR", DependencyType::IntraRank, "BL_n_S_32", passBurstLength32},
        {tBURST16 + tRTRS, "WR", DependencyType::InterRank, "tBURST16 + tRTRS", passBurstLength16},
        {tBURST32 + tRTRS, "WR", DependencyType::InterRank, "tBURST32 + tRTRS", passBurstLength32},
        {BL_n_L_16, "WRA", DependencyType::IntraBankGroup, "BL_n_L_16", passBurstLength16},
        {BL_n_L_32, "WRA", DependencyType::IntraBankGroup, "BL_n_L_32", passBurstLength32},
        {BL_n_S_16, "WRA", DependencyType::IntraRank, "BL_n_S_16", passBurstLength16},
        {BL_n_S_32, "WRA", DependencyType::IntraRank, "BL_n_S_32", passBurstLength32},
        {tBURST16 + tRTRS, "WRA", DependencyType::InterRank, "tBURST16 + tRTRS", passBurstLength16},
        {tBURST32 + tRTRS, "WRA", DependencyType::InterRank, "tBURST32 + tRTRS", passBurstLength32},
        {0, "CMD_BUS", DependencyType::InterRank, "CMDBus"},
      }
    )
  );

  dmap.emplace(
    piecewise_construct,
    forward_as_tuple("PREPB"),
    forward_as_tuple(
      initializer_list<TimeDependency>{
        {tRAS + tCK, "ACT", DependencyType::IntraBank, "tRAS + tCK"},
        {BL_n_min_16 + tRBTP, "RD", DependencyType::IntraBank, "BL_n_min_16 + tRBTP", passBurstLength16},
        {BL_n_min_32 + tRBTP, "RD", DependencyType::IntraBank, "BL_n_min_32 + tRBTP", passBurstLength32},
        {tWL + BL_n_min_16 + tCK + tWR, "WR", DependencyType::IntraBank, "tWL + BL_n_min_16 + tCK + tWR", passBurstLength16},
        {tWL + BL_n_min_32 + tCK + tWR, "WR", DependencyType::IntraBank, "tWL + BL_n_min_32 + tCK + tWR", passBurstLength32},
        {tPPD, "PREPB", DependencyType::IntraRank, "tPPD"},
        {0, "CMD_BUS", DependencyType::InterRank, "CMDBus"},
      }
    )
  );

  dmap.emplace(
    piecewise_construct,
    forward_as_tuple("RDA"),
    forward_as_tuple(
      initializer_list<TimeDependency>{
        {tRCD + tCK, "ACT", DependencyType::IntraBank, "tRCD + tCK"},
        {BL_n_L_16, "RD", DependencyType::IntraBankGroup, "BL_n_L_16", passBurstLength16},
        {BL_n_L_32, "RD", DependencyType::IntraBankGroup, "BL_n_L_32", passBurstLength32},
        {BL_n_S_16, "RD", DependencyType::IntraRank, "BL_n_S_16", passBurstLength16},
        {BL_n_S_32, "RD", DependencyType::IntraRank, "BL_n_S_32", passBurstLength32},
        {tBURST16 + tRTRS, "RD", DependencyType::InterRank, "tBURST16 + tRTRS", passBurstLength16},
        {tBURST32 + tRTRS, "RD", DependencyType::InterRank, "tBURST32 + tRTRS", passBurstLength32},
        {BL_n_L_16, "RDA", DependencyType::IntraBankGroup, "BL_n_L_16", passBurstLength16},
        {BL_n_L_32, "RDA", DependencyType::IntraBankGroup, "BL_n_L_32", passBurstLength32},
        {BL_n_S_16, "RDA", DependencyType::IntraRank, "BL_n_S_16", passBurstLength16},
        {BL_n_S_32, "RDA", DependencyType::IntraRank, "BL_n_S_32", passBurstLength32},
        {tBURST16 + tRTRS, "RDA", DependencyType::InterRank, "tBURST16 + tRTRS", passBurstLength16},
        {tBURST32 + tRTRS, "RDA", DependencyType::InterRank, "tBURST32 + tRTRS", passBurstLength32},
        {tWL + BL_n_max_16 + tWTR_L, "WR", DependencyType::IntraBankGroup, "tWL + BL_n_max_16 + tWTR_L", passBurstLength16},
        {tWL + BL_n_max_32 + tWTR_L, "WR", DependencyType::IntraBankGroup, "tWL + BL_n_max_32 + tWTR_L", passBurstLength32},
        {tWL + BL_n_min_16 + tWTR_S, "WR", DependencyType::IntraRank, "tWL + BL_n_min_16 + tWTR_S", passBurstLength16},
        {tWL + BL_n_min_32 + tWTR_S, "WR", DependencyType::IntraRank, "tWL + BL_n_min_32 + tWTR_S", passBurstLength32},
        {tWL + BL_n_max_16 + tWTR_L, "WRA", DependencyType::IntraBankGroup, "tWL + BL_n_max_16 + tWTR_L", passBurstLength16},
        {tWL + BL_n_max_32 + tWTR_L, "WRA", DependencyType::IntraBankGroup, "tWL + BL_n_max_32 + tWTR_L", passBurstLength32},
        {tWL + BL_n_min_16 + tWTR_S, "WRA", DependencyType::IntraRank, "tWL + BL_n_min_16 + tWTR_S", passBurstLength16},
        {tWL + BL_n_min_32 + tWTR_S, "WRA", DependencyType::IntraRank, "tWL + BL_n_min_32 + tWTR_S", passBurstLength32},
        {0, "CMD_BUS", DependencyType::InterRank, "CMDBus"},
      }
    )
  );

  dmap.emplace(
    piecewise_construct,
    forward_as_tuple("WRA"),
    forward_as_tuple(
      initializer_list<TimeDependency>{
        {tRCD + tCK, "ACT", DependencyType::IntraBank, "tRCD + tCK"},
        {tRL + BL_n_max_16 + tWCK2DQO - tWL, "RD", DependencyType::IntraBankGroup, "tRL + BL_n_max_16 + tWCK2DQO - tWL", passBurstLength16},
        {tRL + BL_n_max_32 + tWCK2DQO - tWL, "RD", DependencyType::IntraBankGroup, "tRL + BL_n_max_32 + tWCK2DQO - tWL", passBurstLength32},
        {tRL + BL_n_min_16 + tWCK2DQO - tWL, "RD", DependencyType::IntraRank, "tRL + BL_n_min_16 + tWCK2DQO - tWL", passBurstLength16},
        {tRL + BL_n_min_32 + tWCK2DQO - tWL, "RD", DependencyType::IntraRank, "tRL + BL_n_min_32 + tWCK2DQO - tWL", passBurstLength32},
        {tRL + BL_n_max_16 + tWCK2DQO - tWL, "RDA", DependencyType::IntraBankGroup, "tRL + BL_n_max_16 + tWCK2DQO - tWL", passBurstLength16},
        {tRL + BL_n_max_32 + tWCK2DQO - tWL, "RDA", DependencyType::IntraBankGroup, "tRL + BL_n_max_32 + tWCK2DQO - tWL", passBurstLength32},
        {tRL + BL_n_min_16 + tWCK2DQO - tWL, "RDA", DependencyType::IntraRank, "tRL + BL_n_min_16 + tWCK2DQO - tWL", passBurstLength16},
        {tRL + BL_n_min_32 + tWCK2DQO - tWL, "RDA", DependencyType::IntraRank, "tRL + BL_n_min_32 + tWCK2DQO - tWL", passBurstLength32},
        {BL_n_L_16, "WR", DependencyType::IntraBankGroup, "BL_n_L_16", passBurstLength16},
        {BL_n_L_32, "WR", DependencyType::IntraBankGroup, "BL_n_L_32", passBurstLength32},
        {BL_n_S_16, "WR", DependencyType::IntraRank, "BL_n_S_16", passBurstLength16},
        {BL_n_S_32, "WR", DependencyType::IntraRank, "BL_n_S_32", passBurstLength32},
        {tBURST16 + tRTRS, "WR", DependencyType::InterRank, "tBURST16 + tRTRS", passBurstLength16},
        {tBURST32 + tRTRS, "WR", DependencyType::InterRank, "tBURST32 + tRTRS", passBurstLength32},
        {BL_n_L_16, "WRA", DependencyType::IntraBankGroup, "BL_n_L_16", passBurstLength16},
        {BL_n_L_32, "WRA", DependencyType::IntraBankGroup, "BL_n_L_32", passBurstLength32},
        {BL_n_S_16, "WRA", DependencyType::IntraRank, "BL_n_S_16", passBurstLength16},
        {BL_n_S_32, "WRA", DependencyType::IntraRank, "BL_n_S_32", passBurstLength32},
        {tBURST16 + tRTRS, "WRA", DependencyType::InterRank, "tBURST16 + tRTRS", passBurstLength16},
        {tBURST32 + tRTRS, "WRA", DependencyType::InterRank, "tBURST32 + tRTRS", passBurstLength32},
        {0, "CMD_BUS", DependencyType::InterRank, "CMDBus"},
      }
    )
  );

  dmap.emplace(
    piecewise_construct,
    forward_as_tuple("REFAB"),
    forward_as_tuple(
      initializer_list<TimeDependency>{
        {tRCpb + tCK, "ACT", DependencyType::IntraRank, "tRCpb + tCK"},
        {BL_n_min_16 + tRBTP + tRPpb, "RDA", DependencyType::IntraRank, "BL_n_min_16 + tRBTP + tRPpb", passBurstLength16},
        {BL_n_min_32 + tRBTP + tRPpb, "RDA", DependencyType::IntraRank, "BL_n_min_32 + tRBTP + tRPpb", passBurstLength32},
        {tWL + BL_n_min_16 + tCK + tWR + tRPpb, "WRA", DependencyType::IntraRank, "tWL + BL_n_min_16 + tCK + tWR + tRPpb", passBurstLength16},
        {tWL + BL_n_min_32 + tCK + tWR + tRPpb, "WRA", DependencyType::IntraRank, "tWL + BL_n_min_32 + tCK + tWR + tRPpb", passBurstLength32},
        {tRPpb, "PREPB", DependencyType::IntraRank, "tRPpb"},
        {tRPab, "PREAB", DependencyType::IntraRank, "tRPab"},
        {tRFCab, "REFAB", DependencyType::IntraRank, "tRFCab"},
        {0, "CMD_BUS", DependencyType::InterRank, "CMDBus"},
      }
    )
  );

  dmap.emplace(
    piecewise_construct,
    forward_as_tuple("PREAB"),
    forward_as_tuple(
      initializer_list<TimeDependency>{
        {tRAS + tCK, "ACT", DependencyType::IntraRank, "tRAS + tCK"},
        {BL_n_min_16 + tRBTP, "RD", DependencyType::IntraRank, "BL_n_min_16 + tRBTP", passBurstLength16},
        {BL_n_min_32 + tRBTP, "RD", DependencyType::IntraRank, "BL_n_min_32 + tRBTP", passBurstLength32},
        {BL_n_min_16 + tRBTP, "RDA", DependencyType::IntraRank, "BL_n_min_16 + tRBTP", passBurstLength16},
        {BL_n_min_32 + tRBTP, "RDA", DependencyType::IntraRank, "BL_n_min_32 + tRBTP", passBurstLength32},
        {tWL + BL_n_min_16 + tCK + tWR, "WR", DependencyType::IntraRank, "tWL + BL_n_min_16 + tCK + tWR", passBurstLength16},
        {tWL + BL_n_min_32 + tCK + tWR, "WR", DependencyType::IntraRank, "tWL + BL_n_min_32 + tCK + tWR", passBurstLength32},
        {tWL + BL_n_min_16 + tCK + tWR, "WRA", DependencyType::IntraRank, "tWL + BL_n_min_16 + tCK + tWR", passBurstLength16},
        {tWL + BL_n_min_32 + tCK + tWR, "WRA", DependencyType::IntraRank, "tWL + BL_n_min_32 + tCK + tWR", passBurstLength32},
        {tPPD, "PREPB", DependencyType::IntraRank, "tPPD"},
        {0, "CMD_BUS", DependencyType::InterRank, "CMDBus"},
      }
    )
  );

  dmap.emplace(
    piecewise_construct,
    forward_as_tuple("REFPB"),
    forward_as_tuple(
      initializer_list<TimeDependency>{
        {tRCpb + tCK, "ACT", DependencyType::IntraBank, "tRCpb + tCK"},
        {tRRD + tCK, "ACT", DependencyType::IntraRank, "tRRD + tCK"},
        {BL_n_min_16 + tRBTP + tRPpb, "RDA", DependencyType::IntraBank, "BL_n_min_16 + tRBTP + tRPpb", passBurstLength16},
        {BL_n_min_32 + tRBTP + tRPpb, "RDA", DependencyType::IntraBank, "BL_n_min_32 + tRBTP + tRPpb", passBurstLength32},
        {tWL + BL_n_min_16 + tCK + tWR + tRPpb, "WRA", DependencyType::IntraBank, "tWL + BL_n_min_16 + tCK + tWR + tRPpb", passBurstLength16},
        {tWL + BL_n_min_32 + tCK + tWR + tRPpb, "WRA", DependencyType::IntraBank, "tWL + BL_n_min_32 + tCK + tWR + tRPpb", passBurstLength32},
        {tRPpb, "PREPB", DependencyType::IntraBank, "tRPpb"},
        {tRPab, "PREAB", DependencyType::IntraRank, "tRPab"},
        {tRFCpb, "REFPB", DependencyType::IntraBank, "tRFCpb"},
        {tpbR2pbR, "REFPB", DependencyType::IntraRank, "tpbR2pbR"},
        {0, "CMD_BUS", DependencyType::InterRank, "CMDBus"},
        {0, "NAW", DependencyType::IntraRank, "tFAW"},
      }
    )
  );

  dmap.emplace(
    piecewise_construct,
    forward_as_tuple("REFP2B"),
    forward_as_tuple(
      initializer_list<TimeDependency>{
        {tRCpb + tCK, "ACT", DependencyType::IntraBank, "tRCpb + tCK"},
        {tRRD + tCK, "ACT", DependencyType::IntraRank, "tRRD + tCK"},
        {BL_n_min_16 + tRBTP + tRPpb, "RDA", DependencyType::IntraBank, "BL_n_min_16 + tRBTP + tRPpb", passBurstLength16},
        {BL_n_min_32 + tRBTP + tRPpb, "RDA", DependencyType::IntraBank, "BL_n_min_32 + tRBTP + tRPpb", passBurstLength32},
        {tWL + BL_n_min_16 + tCK + tWR + tRPpb, "WRA", DependencyType::IntraBank, "tWL + BL_n_min_16 + tCK + tWR + tRPpb", passBurstLength16},
        {tWL + BL_n_min_32 + tCK + tWR + tRPpb, "WRA", DependencyType::IntraBank, "tWL + BL_n_min_32 + tCK + tWR + tRPpb", passBurstLength32},
        {tRPpb, "PREPB", DependencyType::IntraBank, "tRPpb"},
        {tRPab, "PREAB", DependencyType::IntraRank, "tRPab"},
        {tRFCpb, "REFP2B", DependencyType::IntraBank, "tRFCpb"},
        {tpbR2pbR, "REFP2B", DependencyType::IntraRank, "tpbR2pbR"},
        {0, "CMD_BUS", DependencyType::InterRank, "CMDBus"},
        {0, "NAW", DependencyType::IntraRank, "tFAW"},
      }
    )
  );

  return dmap;
}
