110428Sandreas.hansson@arm.com/*
210428Sandreas.hansson@arm.com * Copyright (c) 2012-2014, TU Delft
310428Sandreas.hansson@arm.com * Copyright (c) 2012-2014, TU Eindhoven
410428Sandreas.hansson@arm.com * Copyright (c) 2012-2014, TU Kaiserslautern
510428Sandreas.hansson@arm.com * All rights reserved.
610428Sandreas.hansson@arm.com *
710428Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
810428Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
910428Sandreas.hansson@arm.com * met:
1010428Sandreas.hansson@arm.com *
1110428Sandreas.hansson@arm.com * 1. Redistributions of source code must retain the above copyright
1210428Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer.
1310428Sandreas.hansson@arm.com *
1410428Sandreas.hansson@arm.com * 2. Redistributions in binary form must reproduce the above copyright
1510428Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
1610428Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution.
1710428Sandreas.hansson@arm.com *
1810428Sandreas.hansson@arm.com * 3. Neither the name of the copyright holder nor the names of its
1910428Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
2010428Sandreas.hansson@arm.com * this software without specific prior written permission.
2110428Sandreas.hansson@arm.com *
2210428Sandreas.hansson@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
2310428Sandreas.hansson@arm.com * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2410428Sandreas.hansson@arm.com * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
2510428Sandreas.hansson@arm.com * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2610428Sandreas.hansson@arm.com * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2710428Sandreas.hansson@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
2810428Sandreas.hansson@arm.com * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2910428Sandreas.hansson@arm.com * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
3010428Sandreas.hansson@arm.com * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3110428Sandreas.hansson@arm.com * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3210428Sandreas.hansson@arm.com * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3310428Sandreas.hansson@arm.com *
3412266Sradhika.jagtap@arm.com * Authors: Karthik Chandrasekar
3512266Sradhika.jagtap@arm.com *          Matthias Jung
3612266Sradhika.jagtap@arm.com *          Omar Naji
3712266Sradhika.jagtap@arm.com *          Subash Kannoth
3812266Sradhika.jagtap@arm.com *          Éder F. Zulian
3912266Sradhika.jagtap@arm.com *          Felipe S. Prado
4010428Sandreas.hansson@arm.com *
4110428Sandreas.hansson@arm.com */
4210428Sandreas.hansson@arm.com
4310428Sandreas.hansson@arm.com#include "MemoryPowerModel.h"
4410428Sandreas.hansson@arm.com
4511555Sjungma@eit.uni-kl.de#include <stdint.h>
4611555Sjungma@eit.uni-kl.de
4710428Sandreas.hansson@arm.com#include <cmath>  // For pow
4811555Sjungma@eit.uni-kl.de#include <iostream>  // fmtflags
4912266Sradhika.jagtap@arm.com#include <algorithm>
5010428Sandreas.hansson@arm.com
5110428Sandreas.hansson@arm.comusing namespace std;
5210428Sandreas.hansson@arm.comusing namespace Data;
5310428Sandreas.hansson@arm.com
5412266Sradhika.jagtap@arm.comMemoryPowerModel::MemoryPowerModel()
5512266Sradhika.jagtap@arm.com{
5612266Sradhika.jagtap@arm.com  total_cycles = 0;
5712266Sradhika.jagtap@arm.com  energy.total_energy = 0;
5812266Sradhika.jagtap@arm.com}
5912266Sradhika.jagtap@arm.com
6010428Sandreas.hansson@arm.com// Calculate energy and average power consumption for the given command trace
6110428Sandreas.hansson@arm.com
6211555Sjungma@eit.uni-kl.devoid MemoryPowerModel::power_calc(const MemorySpecification& memSpec,
6311555Sjungma@eit.uni-kl.de                                  const CommandAnalysis& c,
6412266Sradhika.jagtap@arm.com                                  int term,
6512266Sradhika.jagtap@arm.com                                  const MemBankWiseParams& bwPowerParams)
6610428Sandreas.hansson@arm.com{
6711555Sjungma@eit.uni-kl.de  const MemTimingSpec& t                 = memSpec.memTimingSpec;
6811555Sjungma@eit.uni-kl.de  const MemArchitectureSpec& memArchSpec = memSpec.memArchSpec;
6911555Sjungma@eit.uni-kl.de  const MemPowerSpec&  mps               = memSpec.memPowerSpec;
7012266Sradhika.jagtap@arm.com  const int64_t nbrofBanks               = memSpec.memArchSpec.nbrOfBanks;
7112266Sradhika.jagtap@arm.com
7212266Sradhika.jagtap@arm.com  energy.act_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
7312266Sradhika.jagtap@arm.com  energy.pre_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
7412266Sradhika.jagtap@arm.com  energy.read_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
7512266Sradhika.jagtap@arm.com  energy.write_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
7612266Sradhika.jagtap@arm.com  energy.ref_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
7712266Sradhika.jagtap@arm.com  energy.refb_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
7812266Sradhika.jagtap@arm.com  energy.act_stdby_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
7912266Sradhika.jagtap@arm.com  energy.pre_stdby_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
8012266Sradhika.jagtap@arm.com  energy.idle_energy_act_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
8112266Sradhika.jagtap@arm.com  energy.idle_energy_pre_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
8212266Sradhika.jagtap@arm.com  energy.f_act_pd_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
8312266Sradhika.jagtap@arm.com  energy.f_pre_pd_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
8412266Sradhika.jagtap@arm.com  energy.s_act_pd_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
8512266Sradhika.jagtap@arm.com  energy.s_pre_pd_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
8612266Sradhika.jagtap@arm.com  energy.ref_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
8712266Sradhika.jagtap@arm.com  energy.sref_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
8812266Sradhika.jagtap@arm.com  energy.sref_ref_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
8912266Sradhika.jagtap@arm.com  energy.sref_ref_act_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
9012266Sradhika.jagtap@arm.com  energy.sref_ref_pre_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
9112266Sradhika.jagtap@arm.com  energy.spup_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
9212266Sradhika.jagtap@arm.com  energy.spup_ref_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
9312266Sradhika.jagtap@arm.com  energy.spup_ref_act_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
9412266Sradhika.jagtap@arm.com  energy.spup_ref_pre_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
9512266Sradhika.jagtap@arm.com  energy.pup_act_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
9612266Sradhika.jagtap@arm.com  energy.pup_pre_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
9712266Sradhika.jagtap@arm.com  energy.total_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
9810428Sandreas.hansson@arm.com
9910428Sandreas.hansson@arm.com  energy.act_energy          = 0.0;
10010428Sandreas.hansson@arm.com  energy.pre_energy          = 0.0;
10110428Sandreas.hansson@arm.com  energy.read_energy         = 0.0;
10210428Sandreas.hansson@arm.com  energy.write_energy        = 0.0;
10310428Sandreas.hansson@arm.com  energy.ref_energy          = 0.0;
10410428Sandreas.hansson@arm.com  energy.act_stdby_energy    = 0.0;
10510428Sandreas.hansson@arm.com  energy.pre_stdby_energy    = 0.0;
10610428Sandreas.hansson@arm.com  energy.idle_energy_act     = 0.0;
10710428Sandreas.hansson@arm.com  energy.idle_energy_pre     = 0.0;
10812266Sradhika.jagtap@arm.com  energy.window_energy       = 0.0;
10910428Sandreas.hansson@arm.com  energy.f_act_pd_energy     = 0.0;
11010428Sandreas.hansson@arm.com  energy.f_pre_pd_energy     = 0.0;
11110428Sandreas.hansson@arm.com  energy.s_act_pd_energy     = 0.0;
11210428Sandreas.hansson@arm.com  energy.s_pre_pd_energy     = 0.0;
11310428Sandreas.hansson@arm.com  energy.sref_energy         = 0.0;
11410428Sandreas.hansson@arm.com  energy.sref_ref_energy     = 0.0;
11510428Sandreas.hansson@arm.com  energy.sref_ref_act_energy = 0.0;
11610428Sandreas.hansson@arm.com  energy.sref_ref_pre_energy = 0.0;
11710428Sandreas.hansson@arm.com  energy.spup_energy         = 0.0;
11810428Sandreas.hansson@arm.com  energy.spup_ref_energy     = 0.0;
11910428Sandreas.hansson@arm.com  energy.spup_ref_act_energy = 0.0;
12010428Sandreas.hansson@arm.com  energy.spup_ref_pre_energy = 0.0;
12110428Sandreas.hansson@arm.com  energy.pup_act_energy      = 0.0;
12210428Sandreas.hansson@arm.com  energy.pup_pre_energy      = 0.0;
12310428Sandreas.hansson@arm.com  power.IO_power             = 0.0;
12410428Sandreas.hansson@arm.com  power.WR_ODT_power         = 0.0;
12510428Sandreas.hansson@arm.com  power.TermRD_power         = 0.0;
12610428Sandreas.hansson@arm.com  power.TermWR_power         = 0.0;
12710428Sandreas.hansson@arm.com  energy.read_io_energy      = 0.0;
12810428Sandreas.hansson@arm.com  energy.write_term_energy   = 0.0;
12910428Sandreas.hansson@arm.com  energy.read_oterm_energy   = 0.0;
13010428Sandreas.hansson@arm.com  energy.write_oterm_energy  = 0.0;
13110428Sandreas.hansson@arm.com  energy.io_term_energy      = 0.0;
13210428Sandreas.hansson@arm.com
13310428Sandreas.hansson@arm.com  // How long a single burst takes, measured in command-clock cycles.
13410428Sandreas.hansson@arm.com  int64_t burstCc = memArchSpec.burstLength / memArchSpec.dataRate;
13510428Sandreas.hansson@arm.com
13610428Sandreas.hansson@arm.com  // IO and Termination Power measures are included, if required.
13710428Sandreas.hansson@arm.com  if (term) {
13810428Sandreas.hansson@arm.com    io_term_power(memSpec);
13910428Sandreas.hansson@arm.com
14010428Sandreas.hansson@arm.com    // memArchSpec.width represents the number of data (dq) pins.
14110428Sandreas.hansson@arm.com    // 1 DQS pin is associated with every data byte
14210428Sandreas.hansson@arm.com    int64_t dqPlusDqsBits = memArchSpec.width + memArchSpec.width / 8;
14310428Sandreas.hansson@arm.com    // 1 DQS and 1 DM pin is associated with every data byte
14410428Sandreas.hansson@arm.com    int64_t dqPlusDqsPlusMaskBits = memArchSpec.width + memArchSpec.width / 8 + memArchSpec.width / 8;
14510428Sandreas.hansson@arm.com    // Size of one clock period for the data bus.
14611555Sjungma@eit.uni-kl.de    double ddrPeriod = t.clkPeriod / static_cast<double>(memArchSpec.dataRate);
14710428Sandreas.hansson@arm.com
14810428Sandreas.hansson@arm.com    // Read IO power is consumed by each DQ (data) and DQS (data strobe) pin
14912266Sradhika.jagtap@arm.com    energy.read_io_energy = calcIoTermEnergy(sum(c.numberofreadsBanks) * memArchSpec.burstLength,
15010428Sandreas.hansson@arm.com                                             ddrPeriod,
15110428Sandreas.hansson@arm.com                                             power.IO_power,
15210428Sandreas.hansson@arm.com                                             dqPlusDqsBits);
15310428Sandreas.hansson@arm.com
15410428Sandreas.hansson@arm.com    // Write ODT power is consumed by each DQ (data), DQS (data strobe) and DM
15512266Sradhika.jagtap@arm.com    energy.write_term_energy = calcIoTermEnergy(sum(c.numberofwritesBanks) * memArchSpec.burstLength,
15610428Sandreas.hansson@arm.com                                                ddrPeriod,
15710428Sandreas.hansson@arm.com                                                power.WR_ODT_power,
15810428Sandreas.hansson@arm.com                                                dqPlusDqsPlusMaskBits);
15910428Sandreas.hansson@arm.com
16010428Sandreas.hansson@arm.com    if (memArchSpec.nbrOfRanks > 1) {
16110428Sandreas.hansson@arm.com      // Termination power consumed in the idle rank during reads on the active
16210428Sandreas.hansson@arm.com      // rank by each DQ (data) and DQS (data strobe) pin.
16312266Sradhika.jagtap@arm.com      energy.read_oterm_energy = calcIoTermEnergy(sum(c.numberofreadsBanks) * memArchSpec.burstLength,
16410428Sandreas.hansson@arm.com                                                  ddrPeriod,
16510428Sandreas.hansson@arm.com                                                  power.TermRD_power,
16610428Sandreas.hansson@arm.com                                                  dqPlusDqsBits);
16710428Sandreas.hansson@arm.com
16810428Sandreas.hansson@arm.com      // Termination power consumed in the idle rank during writes on the active
16910428Sandreas.hansson@arm.com      // rank by each DQ (data), DQS (data strobe) and DM (data mask) pin.
17012266Sradhika.jagtap@arm.com      energy.write_oterm_energy = calcIoTermEnergy(sum(c.numberofwritesBanks) * memArchSpec.burstLength,
17110428Sandreas.hansson@arm.com                                                   ddrPeriod,
17210428Sandreas.hansson@arm.com                                                   power.TermWR_power,
17310428Sandreas.hansson@arm.com                                                   dqPlusDqsPlusMaskBits);
17410428Sandreas.hansson@arm.com    }
17510428Sandreas.hansson@arm.com
17610428Sandreas.hansson@arm.com    // Sum of all IO and termination energy
17710428Sandreas.hansson@arm.com    energy.io_term_energy = energy.read_io_energy + energy.write_term_energy
17810428Sandreas.hansson@arm.com                            + energy.read_oterm_energy + energy.write_oterm_energy;
17910428Sandreas.hansson@arm.com  }
18010428Sandreas.hansson@arm.com
18112266Sradhika.jagtap@arm.com  window_cycles = c.actcycles + c.precycles +
18211555Sjungma@eit.uni-kl.de                 c.f_act_pdcycles + c.f_pre_pdcycles +
18311555Sjungma@eit.uni-kl.de                 c.s_act_pdcycles + c.s_pre_pdcycles + c.sref_cycles
18411555Sjungma@eit.uni-kl.de                 + c.sref_ref_act_cycles + c.sref_ref_pre_cycles +
18511555Sjungma@eit.uni-kl.de                 c.spup_ref_act_cycles + c.spup_ref_pre_cycles;
18610428Sandreas.hansson@arm.com
18710428Sandreas.hansson@arm.com  EnergyDomain vdd0Domain(mps.vdd, t.clkPeriod);
18810428Sandreas.hansson@arm.com
18912266Sradhika.jagtap@arm.com  energy.act_energy       = vdd0Domain.calcTivEnergy(sum(c.numberofactsBanks) * t.RAS          , mps.idd0 - mps.idd3n);
19012266Sradhika.jagtap@arm.com  energy.pre_energy       = vdd0Domain.calcTivEnergy(sum(c.numberofpresBanks) * (t.RC - t.RAS) , mps.idd0 - mps.idd2n);
19112266Sradhika.jagtap@arm.com  energy.read_energy      = vdd0Domain.calcTivEnergy(sum(c.numberofreadsBanks) * burstCc        , mps.idd4r - mps.idd3n);
19212266Sradhika.jagtap@arm.com  energy.write_energy     = vdd0Domain.calcTivEnergy(sum(c.numberofwritesBanks) * burstCc        , mps.idd4w - mps.idd3n);
19311555Sjungma@eit.uni-kl.de  energy.ref_energy       = vdd0Domain.calcTivEnergy(c.numberofrefs   * t.RFC          , mps.idd5 - mps.idd3n);
19411555Sjungma@eit.uni-kl.de  energy.pre_stdby_energy = vdd0Domain.calcTivEnergy(c.precycles, mps.idd2n);
19511555Sjungma@eit.uni-kl.de  energy.act_stdby_energy = vdd0Domain.calcTivEnergy(c.actcycles, mps.idd3n);
19612266Sradhika.jagtap@arm.com
19712266Sradhika.jagtap@arm.com  // Using the number of cycles that at least one bank is active here
19812266Sradhika.jagtap@arm.com  // But the current iddrho is less than idd3n
19912266Sradhika.jagtap@arm.com  double iddrho = (static_cast<double>(bwPowerParams.bwPowerFactRho) / 100.0) * (mps.idd3n - mps.idd2n) + mps.idd2n;
20012266Sradhika.jagtap@arm.com  double esharedActStdby = vdd0Domain.calcTivEnergy(c.actcycles, iddrho);
20112266Sradhika.jagtap@arm.com  // Fixed componenent for PASR
20212266Sradhika.jagtap@arm.com  double iddsigma = (static_cast<double>(bwPowerParams.bwPowerFactSigma) / 100.0) * mps.idd6;
20312266Sradhika.jagtap@arm.com  double esharedPASR = vdd0Domain.calcTivEnergy(c.sref_cycles, iddsigma);
20412266Sradhika.jagtap@arm.com  // ione is Active background current for a single bank. When a single bank is Active
20512266Sradhika.jagtap@arm.com  //,all the other remainig (B-1) banks will consume  a current of iddrho (based on factor Rho)
20612266Sradhika.jagtap@arm.com  // So to derrive ione we add (B-1)*iddrho to the idd3n and distribute it to each banks.
20712266Sradhika.jagtap@arm.com  double ione = (mps.idd3n + (iddrho * (static_cast<double>(nbrofBanks - 1)))) / (static_cast<double>(nbrofBanks));
20812266Sradhika.jagtap@arm.com  // If memory specification does not provide  bank wise refresh current,
20912266Sradhika.jagtap@arm.com  // approximate it to single bank background current removed from
21012266Sradhika.jagtap@arm.com  // single bank active current
21112266Sradhika.jagtap@arm.com  double idd5Blocal = (mps.idd5B == 0.0) ? (mps.idd0 - ione) :(mps.idd5B);
21212266Sradhika.jagtap@arm.com  // if memory specification does not provide the REFB timing approximate it
21312266Sradhika.jagtap@arm.com  // to time of ACT + PRE
21412266Sradhika.jagtap@arm.com  int64_t tRefBlocal = (t.REFB == 0) ? (t.RAS + t.RP) : (t.REFB);
21512266Sradhika.jagtap@arm.com
21612266Sradhika.jagtap@arm.com  //Distribution of energy componets to each banks
21712266Sradhika.jagtap@arm.com  for (unsigned i = 0; i < nbrofBanks; i++) {
21812266Sradhika.jagtap@arm.com    energy.act_energy_banks[i] = vdd0Domain.calcTivEnergy(c.numberofactsBanks[i] * t.RAS, mps.idd0 - ione);
21912266Sradhika.jagtap@arm.com    energy.pre_energy_banks[i] = vdd0Domain.calcTivEnergy(c.numberofpresBanks[i] * (t.RP), mps.idd0 - ione);
22012266Sradhika.jagtap@arm.com    energy.read_energy_banks[i] = vdd0Domain.calcTivEnergy(c.numberofreadsBanks[i] * burstCc, mps.idd4r - mps.idd3n);
22112266Sradhika.jagtap@arm.com    energy.write_energy_banks[i] = vdd0Domain.calcTivEnergy(c.numberofwritesBanks[i] * burstCc, mps.idd4w - mps.idd3n);
22212266Sradhika.jagtap@arm.com    energy.ref_energy_banks[i] = vdd0Domain.calcTivEnergy(c.numberofrefs * t.RFC, mps.idd5 - mps.idd3n) / static_cast<double>(nbrofBanks);
22312266Sradhika.jagtap@arm.com    energy.refb_energy_banks[i] = vdd0Domain.calcTivEnergy(c.numberofrefbBanks[i] * tRefBlocal, idd5Blocal);
22412266Sradhika.jagtap@arm.com    energy.pre_stdby_energy_banks[i] = vdd0Domain.calcTivEnergy(c.precycles, mps.idd2n) / static_cast<double>(nbrofBanks);
22512266Sradhika.jagtap@arm.com    energy.act_stdby_energy_banks[i] = vdd0Domain.calcTivEnergy(c.actcyclesBanks[i], (mps.idd3n - iddrho) / static_cast<double>(nbrofBanks))
22612266Sradhika.jagtap@arm.com                                        + esharedActStdby / static_cast<double>(nbrofBanks);
22712266Sradhika.jagtap@arm.com    energy.idle_energy_act_banks[i] = vdd0Domain.calcTivEnergy(c.idlecycles_act, mps.idd3n) / static_cast<double>(nbrofBanks);
22812266Sradhika.jagtap@arm.com    energy.idle_energy_pre_banks[i] = vdd0Domain.calcTivEnergy(c.idlecycles_pre, mps.idd2n) / static_cast<double>(nbrofBanks);
22912266Sradhika.jagtap@arm.com    energy.f_act_pd_energy_banks[i] = vdd0Domain.calcTivEnergy(c.f_act_pdcycles, mps.idd3p1) / static_cast<double>(nbrofBanks);
23012266Sradhika.jagtap@arm.com    energy.f_pre_pd_energy_banks[i] = vdd0Domain.calcTivEnergy(c.f_pre_pdcycles, mps.idd2p1) / static_cast<double>(nbrofBanks);
23112266Sradhika.jagtap@arm.com    energy.s_act_pd_energy_banks[i] = vdd0Domain.calcTivEnergy(c.s_act_pdcycles, mps.idd3p0) / static_cast<double>(nbrofBanks);
23212266Sradhika.jagtap@arm.com    energy.s_pre_pd_energy_banks[i] = vdd0Domain.calcTivEnergy(c.s_pre_pdcycles, mps.idd2p0) / static_cast<double>(nbrofBanks);
23312266Sradhika.jagtap@arm.com
23412266Sradhika.jagtap@arm.com    energy.sref_energy_banks[i] = engy_sref_banks(mps.idd6, mps.idd3n,
23512266Sradhika.jagtap@arm.com                                            mps.idd5, mps.vdd,
23612266Sradhika.jagtap@arm.com                                            static_cast<double>(c.sref_cycles), static_cast<double>(c.sref_ref_act_cycles),
23712266Sradhika.jagtap@arm.com                                            static_cast<double>(c.sref_ref_pre_cycles), static_cast<double>(c.spup_ref_act_cycles),
23812266Sradhika.jagtap@arm.com                                            static_cast<double>(c.spup_ref_pre_cycles), t.clkPeriod,esharedPASR,bwPowerParams,i,nbrofBanks
23912266Sradhika.jagtap@arm.com                                            );
24012266Sradhika.jagtap@arm.com    energy.sref_ref_act_energy_banks[i] = vdd0Domain.calcTivEnergy(c.sref_ref_act_cycles, mps.idd3p0) / static_cast<double>(nbrofBanks);
24112266Sradhika.jagtap@arm.com    energy.sref_ref_pre_energy_banks[i] = vdd0Domain.calcTivEnergy(c.sref_ref_pre_cycles, mps.idd2p0) / static_cast<double>(nbrofBanks);
24212266Sradhika.jagtap@arm.com    energy.sref_ref_energy_banks[i] = energy.sref_ref_act_energy_banks[i] + energy.sref_ref_pre_energy_banks[i] ;//
24312266Sradhika.jagtap@arm.com
24412266Sradhika.jagtap@arm.com    energy.spup_energy_banks[i] = vdd0Domain.calcTivEnergy(c.spup_cycles, mps.idd2n) / static_cast<double>(nbrofBanks);
24512266Sradhika.jagtap@arm.com    energy.spup_ref_act_energy_banks[i] = vdd0Domain.calcTivEnergy(c.spup_ref_act_cycles, mps.idd3n) / static_cast<double>(nbrofBanks);//
24612266Sradhika.jagtap@arm.com    energy.spup_ref_pre_energy_banks[i] = vdd0Domain.calcTivEnergy(c.spup_ref_pre_cycles, mps.idd2n) / static_cast<double>(nbrofBanks);
24712266Sradhika.jagtap@arm.com    energy.spup_ref_energy_banks[i] = ( energy.spup_ref_act_energy + energy.spup_ref_pre_energy ) / static_cast<double>(nbrofBanks);
24812266Sradhika.jagtap@arm.com    energy.pup_act_energy_banks[i] = vdd0Domain.calcTivEnergy(c.pup_act_cycles, mps.idd3n) / static_cast<double>(nbrofBanks);
24912266Sradhika.jagtap@arm.com    energy.pup_pre_energy_banks[i] = vdd0Domain.calcTivEnergy(c.pup_pre_cycles, mps.idd2n) / static_cast<double>(nbrofBanks);
25012266Sradhika.jagtap@arm.com  }
25112266Sradhika.jagtap@arm.com
25210428Sandreas.hansson@arm.com  // Idle energy in the active standby clock cycles
25311555Sjungma@eit.uni-kl.de  energy.idle_energy_act  = vdd0Domain.calcTivEnergy(c.idlecycles_act, mps.idd3n);
25410428Sandreas.hansson@arm.com  // Idle energy in the precharge standby clock cycles
25511555Sjungma@eit.uni-kl.de  energy.idle_energy_pre  = vdd0Domain.calcTivEnergy(c.idlecycles_pre, mps.idd2n);
25610428Sandreas.hansson@arm.com  // fast-exit active power-down cycles energy
25711555Sjungma@eit.uni-kl.de  energy.f_act_pd_energy  = vdd0Domain.calcTivEnergy(c.f_act_pdcycles, mps.idd3p1);
25810428Sandreas.hansson@arm.com  // fast-exit precharged power-down cycles energy
25911555Sjungma@eit.uni-kl.de  energy.f_pre_pd_energy  = vdd0Domain.calcTivEnergy(c.f_pre_pdcycles, mps.idd2p1);
26010428Sandreas.hansson@arm.com  // slow-exit active power-down cycles energy
26111555Sjungma@eit.uni-kl.de  energy.s_act_pd_energy  = vdd0Domain.calcTivEnergy(c.s_act_pdcycles, mps.idd3p0);
26210428Sandreas.hansson@arm.com  // slow-exit precharged power-down cycles energy
26311555Sjungma@eit.uni-kl.de  energy.s_pre_pd_energy  = vdd0Domain.calcTivEnergy(c.s_pre_pdcycles, mps.idd2p0);
26410428Sandreas.hansson@arm.com
26510428Sandreas.hansson@arm.com  // self-refresh cycles energy including a refresh per self-refresh entry
26610428Sandreas.hansson@arm.com  energy.sref_energy = engy_sref(mps.idd6, mps.idd3n,
26710428Sandreas.hansson@arm.com                                 mps.idd5, mps.vdd,
26811555Sjungma@eit.uni-kl.de                                 static_cast<double>(c.sref_cycles), static_cast<double>(c.sref_ref_act_cycles),
26911555Sjungma@eit.uni-kl.de                                 static_cast<double>(c.sref_ref_pre_cycles), static_cast<double>(c.spup_ref_act_cycles),
27011555Sjungma@eit.uni-kl.de                                 static_cast<double>(c.spup_ref_pre_cycles), t.clkPeriod);
27110428Sandreas.hansson@arm.com
27210428Sandreas.hansson@arm.com  // background energy during active auto-refresh cycles in self-refresh
27311555Sjungma@eit.uni-kl.de  energy.sref_ref_act_energy = vdd0Domain.calcTivEnergy(c.sref_ref_act_cycles, mps.idd3p0);
27410428Sandreas.hansson@arm.com  // background energy during precharged auto-refresh cycles in self-refresh
27511555Sjungma@eit.uni-kl.de  energy.sref_ref_pre_energy = vdd0Domain.calcTivEnergy(c.sref_ref_pre_cycles, mps.idd2p0);
27610428Sandreas.hansson@arm.com  // background energy during active auto-refresh cycles in self-refresh exit
27711555Sjungma@eit.uni-kl.de  energy.spup_ref_act_energy = vdd0Domain.calcTivEnergy(c.spup_ref_act_cycles, mps.idd3n);
27810428Sandreas.hansson@arm.com  // background energy during precharged auto-refresh cycles in self-refresh exit
27911555Sjungma@eit.uni-kl.de  energy.spup_ref_pre_energy = vdd0Domain.calcTivEnergy(c.spup_ref_pre_cycles, mps.idd2n);
28010428Sandreas.hansson@arm.com  // self-refresh power-up cycles energy -- included
28111555Sjungma@eit.uni-kl.de  energy.spup_energy         = vdd0Domain.calcTivEnergy(c.spup_cycles, mps.idd2n);
28210428Sandreas.hansson@arm.com  // active power-up cycles energy - same as active standby -- included
28311555Sjungma@eit.uni-kl.de  energy.pup_act_energy      = vdd0Domain.calcTivEnergy(c.pup_act_cycles, mps.idd3n);
28410428Sandreas.hansson@arm.com  // precharged power-up cycles energy - same as precharged standby -- included
28511555Sjungma@eit.uni-kl.de  energy.pup_pre_energy      = vdd0Domain.calcTivEnergy(c.pup_pre_cycles, mps.idd2n);
28610428Sandreas.hansson@arm.com
28710428Sandreas.hansson@arm.com  // similar equations as before to support multiple voltage domains in LPDDR2
28810428Sandreas.hansson@arm.com  // and WIDEIO memories
28910428Sandreas.hansson@arm.com  if (memArchSpec.twoVoltageDomains) {
29010428Sandreas.hansson@arm.com    EnergyDomain vdd2Domain(mps.vdd2, t.clkPeriod);
29110428Sandreas.hansson@arm.com
29212266Sradhika.jagtap@arm.com    energy.act_energy       += vdd2Domain.calcTivEnergy(sum(c.numberofactsBanks) * t.RAS          , mps.idd02 - mps.idd3n2);
29312266Sradhika.jagtap@arm.com    energy.pre_energy       += vdd2Domain.calcTivEnergy(sum(c.numberofpresBanks) * (t.RC - t.RAS) , mps.idd02 - mps.idd2n2);
29412266Sradhika.jagtap@arm.com    energy.read_energy      += vdd2Domain.calcTivEnergy(sum(c.numberofreadsBanks) * burstCc        , mps.idd4r2 - mps.idd3n2);
29512266Sradhika.jagtap@arm.com    energy.write_energy     += vdd2Domain.calcTivEnergy(sum(c.numberofwritesBanks) * burstCc        , mps.idd4w2 - mps.idd3n2);
29611555Sjungma@eit.uni-kl.de    energy.ref_energy       += vdd2Domain.calcTivEnergy(c.numberofrefs   * t.RFC          , mps.idd52 - mps.idd3n2);
29711555Sjungma@eit.uni-kl.de    energy.pre_stdby_energy += vdd2Domain.calcTivEnergy(c.precycles, mps.idd2n2);
29811555Sjungma@eit.uni-kl.de    energy.act_stdby_energy += vdd2Domain.calcTivEnergy(c.actcycles, mps.idd3n2);
29912266Sradhika.jagtap@arm.com
30010428Sandreas.hansson@arm.com    // Idle energy in the active standby clock cycles
30111555Sjungma@eit.uni-kl.de    energy.idle_energy_act  += vdd2Domain.calcTivEnergy(c.idlecycles_act, mps.idd3n2);
30210428Sandreas.hansson@arm.com    // Idle energy in the precharge standby clock cycles
30311555Sjungma@eit.uni-kl.de    energy.idle_energy_pre  += vdd2Domain.calcTivEnergy(c.idlecycles_pre, mps.idd2n2);
30410428Sandreas.hansson@arm.com    // fast-exit active power-down cycles energy
30511555Sjungma@eit.uni-kl.de    energy.f_act_pd_energy  += vdd2Domain.calcTivEnergy(c.f_act_pdcycles, mps.idd3p12);
30610428Sandreas.hansson@arm.com    // fast-exit precharged power-down cycles energy
30711555Sjungma@eit.uni-kl.de    energy.f_pre_pd_energy  += vdd2Domain.calcTivEnergy(c.f_pre_pdcycles, mps.idd2p12);
30810428Sandreas.hansson@arm.com    // slow-exit active power-down cycles energy
30911555Sjungma@eit.uni-kl.de    energy.s_act_pd_energy  += vdd2Domain.calcTivEnergy(c.s_act_pdcycles, mps.idd3p02);
31010428Sandreas.hansson@arm.com    // slow-exit precharged power-down cycles energy
31111555Sjungma@eit.uni-kl.de    energy.s_pre_pd_energy  += vdd2Domain.calcTivEnergy(c.s_pre_pdcycles, mps.idd2p02);
31210428Sandreas.hansson@arm.com
31310428Sandreas.hansson@arm.com    energy.sref_energy      += engy_sref(mps.idd62, mps.idd3n2,
31410428Sandreas.hansson@arm.com                                         mps.idd52, mps.vdd2,
31511555Sjungma@eit.uni-kl.de                                         static_cast<double>(c.sref_cycles), static_cast<double>(c.sref_ref_act_cycles),
31611555Sjungma@eit.uni-kl.de                                         static_cast<double>(c.sref_ref_pre_cycles), static_cast<double>(c.spup_ref_act_cycles),
31711555Sjungma@eit.uni-kl.de                                         static_cast<double>(c.spup_ref_pre_cycles), t.clkPeriod);
31810428Sandreas.hansson@arm.com
31910428Sandreas.hansson@arm.com    // background energy during active auto-refresh cycles in self-refresh
32011555Sjungma@eit.uni-kl.de    energy.sref_ref_act_energy += vdd2Domain.calcTivEnergy(c.sref_ref_act_cycles, mps.idd3p02);
32110428Sandreas.hansson@arm.com    // background energy during precharged auto-refresh cycles in self-refresh
32211555Sjungma@eit.uni-kl.de    energy.sref_ref_pre_energy += vdd2Domain.calcTivEnergy(c.sref_ref_pre_cycles, mps.idd2p02);
32310428Sandreas.hansson@arm.com    // background energy during active auto-refresh cycles in self-refresh exit
32411555Sjungma@eit.uni-kl.de    energy.spup_ref_act_energy += vdd2Domain.calcTivEnergy(c.spup_ref_act_cycles, mps.idd3n2);
32510428Sandreas.hansson@arm.com    // background energy during precharged auto-refresh cycles in self-refresh exit
32611555Sjungma@eit.uni-kl.de    energy.spup_ref_pre_energy += vdd2Domain.calcTivEnergy(c.spup_ref_pre_cycles, mps.idd2n2);
32710428Sandreas.hansson@arm.com    // self-refresh power-up cycles energy -- included
32811555Sjungma@eit.uni-kl.de    energy.spup_energy         += vdd2Domain.calcTivEnergy(c.spup_cycles, mps.idd2n2);
32910428Sandreas.hansson@arm.com    // active power-up cycles energy - same as active standby -- included
33011555Sjungma@eit.uni-kl.de    energy.pup_act_energy      += vdd2Domain.calcTivEnergy(c.pup_act_cycles, mps.idd3n2);
33110428Sandreas.hansson@arm.com    // precharged power-up cycles energy - same as precharged standby -- included
33211555Sjungma@eit.uni-kl.de    energy.pup_pre_energy      += vdd2Domain.calcTivEnergy(c.pup_pre_cycles, mps.idd2n2);
33310428Sandreas.hansson@arm.com  }
33410428Sandreas.hansson@arm.com
33510428Sandreas.hansson@arm.com  // auto-refresh energy during self-refresh cycles
33610428Sandreas.hansson@arm.com  energy.sref_ref_energy = energy.sref_ref_act_energy + energy.sref_ref_pre_energy;
33710428Sandreas.hansson@arm.com
33810428Sandreas.hansson@arm.com  // auto-refresh energy during self-refresh exit cycles
33910428Sandreas.hansson@arm.com  energy.spup_ref_energy = energy.spup_ref_act_energy + energy.spup_ref_pre_energy;
34010428Sandreas.hansson@arm.com
34110428Sandreas.hansson@arm.com  // adding all energy components for the active rank and all background and idle
34210428Sandreas.hansson@arm.com  // energy components for both ranks (in a dual-rank system)
34312266Sradhika.jagtap@arm.com
34412266Sradhika.jagtap@arm.com  if (bwPowerParams.bwMode) {
34512266Sradhika.jagtap@arm.com        // Calculate total energy per bank.
34612266Sradhika.jagtap@arm.com        for (unsigned i = 0; i < nbrofBanks; i++) {
34712266Sradhika.jagtap@arm.com            energy.total_energy_banks[i] = energy.act_energy_banks[i] + energy.pre_energy_banks[i] + energy.read_energy_banks[i]
34812266Sradhika.jagtap@arm.com                                            + energy.ref_energy_banks[i] + energy.write_energy_banks[i] + energy.refb_energy_banks[i]
34912266Sradhika.jagtap@arm.com                                            + static_cast<double>(memArchSpec.nbrOfRanks) * energy.act_stdby_energy_banks[i]
35012266Sradhika.jagtap@arm.com                                            + energy.pre_stdby_energy_banks[i] + energy.f_pre_pd_energy_banks[i] + energy.s_act_pd_energy_banks[i]
35112266Sradhika.jagtap@arm.com                                            + energy.s_pre_pd_energy_banks[i]+ energy.sref_ref_energy_banks[i] + energy.spup_ref_energy_banks[i];
35212266Sradhika.jagtap@arm.com      }
35312266Sradhika.jagtap@arm.com      // Calculate total energy for all banks.
35412266Sradhika.jagtap@arm.com      energy.window_energy = sum(energy.total_energy_banks) + energy.io_term_energy;
35512266Sradhika.jagtap@arm.com
35612266Sradhika.jagtap@arm.com  } else {
35712266Sradhika.jagtap@arm.com    energy.window_energy = energy.act_energy + energy.pre_energy + energy.read_energy + energy.write_energy
35812266Sradhika.jagtap@arm.com                          + energy.ref_energy + energy.io_term_energy + sum(energy.refb_energy_banks)
35912266Sradhika.jagtap@arm.com                          + static_cast<double>(memArchSpec.nbrOfRanks) * (energy.act_stdby_energy
36012266Sradhika.jagtap@arm.com                          + energy.pre_stdby_energy + energy.sref_energy + energy.f_act_pd_energy
36112266Sradhika.jagtap@arm.com                          + energy.f_pre_pd_energy + energy.s_act_pd_energy + energy.s_pre_pd_energy
36212266Sradhika.jagtap@arm.com                          + energy.sref_ref_energy + energy.spup_ref_energy);
36312266Sradhika.jagtap@arm.com  }
36412266Sradhika.jagtap@arm.com
36512266Sradhika.jagtap@arm.com  power.window_average_power = energy.window_energy / (static_cast<double>(window_cycles) * t.clkPeriod);
36612266Sradhika.jagtap@arm.com
36712266Sradhika.jagtap@arm.com  total_cycles += window_cycles;
36812266Sradhika.jagtap@arm.com
36912266Sradhika.jagtap@arm.com  energy.total_energy += energy.window_energy;
37010428Sandreas.hansson@arm.com
37110428Sandreas.hansson@arm.com  // Calculate the average power consumption
37210428Sandreas.hansson@arm.com  power.average_power = energy.total_energy / (static_cast<double>(total_cycles) * t.clkPeriod);
37310428Sandreas.hansson@arm.com} // MemoryPowerModel::power_calc
37410428Sandreas.hansson@arm.com
37512266Sradhika.jagtap@arm.comvoid MemoryPowerModel::power_print(const MemorySpecification& memSpec, int term, const CommandAnalysis& c, bool bankwiseMode) const
37610428Sandreas.hansson@arm.com{
37711555Sjungma@eit.uni-kl.de  const MemTimingSpec& memTimingSpec     = memSpec.memTimingSpec;
37811555Sjungma@eit.uni-kl.de  const MemArchitectureSpec& memArchSpec = memSpec.memArchSpec;
37911555Sjungma@eit.uni-kl.de  const uint64_t nRanks = static_cast<uint64_t>(memArchSpec.nbrOfRanks);
38011555Sjungma@eit.uni-kl.de  const char eUnit[] = " pJ";
38112266Sradhika.jagtap@arm.com  const int64_t nbrofBanks = memSpec.memArchSpec.nbrOfBanks;
38212266Sradhika.jagtap@arm.com  double nRanksDouble = static_cast<double>(nRanks);
38310428Sandreas.hansson@arm.com
38411555Sjungma@eit.uni-kl.de  ios_base::fmtflags flags = cout.flags();
38511555Sjungma@eit.uni-kl.de  streamsize precision = cout.precision();
38610428Sandreas.hansson@arm.com  cout.precision(0);
38712266Sradhika.jagtap@arm.com
38812266Sradhika.jagtap@arm.com  if (bankwiseMode) {
38912266Sradhika.jagtap@arm.com    cout << endl << "* Bankwise Details:";
39012266Sradhika.jagtap@arm.com    for (unsigned i = 0; i < nbrofBanks; i++) {
39112266Sradhika.jagtap@arm.com      cout << endl << "## @ Bank " << i << fixed
39212266Sradhika.jagtap@arm.com        << endl << "  #ACT commands: " << c.numberofactsBanks[i]
39312266Sradhika.jagtap@arm.com        << endl << "  #RD + #RDA commands: " << c.numberofreadsBanks[i]
39412266Sradhika.jagtap@arm.com        << endl << "  #WR + #WRA commands: " << c.numberofwritesBanks[i]
39512266Sradhika.jagtap@arm.com        << endl << "  #PRE (+ PREA) commands: " << c.numberofpresBanks[i];
39612266Sradhika.jagtap@arm.com    }
39712266Sradhika.jagtap@arm.com    cout << endl;
39812266Sradhika.jagtap@arm.com  }
39912266Sradhika.jagtap@arm.com
40012266Sradhika.jagtap@arm.com  cout << endl << "* Trace Details:" << fixed << endl
40112266Sradhika.jagtap@arm.com       << endl << "#ACT commands: "                 << sum(c.numberofactsBanks)
40212266Sradhika.jagtap@arm.com       << endl << "#RD + #RDA commands: "           << sum(c.numberofreadsBanks)
40312266Sradhika.jagtap@arm.com       << endl << "#WR + #WRA commands: "           << sum(c.numberofwritesBanks)
40411555Sjungma@eit.uni-kl.de  /* #PRE commands (precharge all counts a number of #PRE commands equal to the number of active banks) */
40512266Sradhika.jagtap@arm.com       << endl << "#PRE (+ PREA) commands: "        << sum(c.numberofpresBanks)
40611555Sjungma@eit.uni-kl.de       << endl << "#REF commands: "                 << c.numberofrefs
40712266Sradhika.jagtap@arm.com       << endl << "#REFB commands: "                << sum(c.numberofrefbBanks)
40811555Sjungma@eit.uni-kl.de       << endl << "#Active Cycles: "                << c.actcycles
40911555Sjungma@eit.uni-kl.de       << endl << "  #Active Idle Cycles: "         << c.idlecycles_act
41011555Sjungma@eit.uni-kl.de       << endl << "  #Active Power-Up Cycles: "     << c.pup_act_cycles
41111555Sjungma@eit.uni-kl.de       << endl << "    #Auto-Refresh Active cycles during Self-Refresh Power-Up: " << c.spup_ref_act_cycles
41211555Sjungma@eit.uni-kl.de       << endl << "#Precharged Cycles: "            << c.precycles
41311555Sjungma@eit.uni-kl.de       << endl << "  #Precharged Idle Cycles: "     << c.idlecycles_pre
41411555Sjungma@eit.uni-kl.de       << endl << "  #Precharged Power-Up Cycles: " << c.pup_pre_cycles
41511555Sjungma@eit.uni-kl.de       << endl << "    #Auto-Refresh Precharged cycles during Self-Refresh Power-Up: " << c.spup_ref_pre_cycles
41611555Sjungma@eit.uni-kl.de       << endl << "  #Self-Refresh Power-Up Cycles: "                          << c.spup_cycles
41711555Sjungma@eit.uni-kl.de       << endl << "Total Idle Cycles (Active + Precharged): "                  << c.idlecycles_act + c.idlecycles_pre
41811555Sjungma@eit.uni-kl.de       << endl << "#Power-Downs: "                                             << c.f_act_pdns +  c.s_act_pdns + c.f_pre_pdns + c.s_pre_pdns
41911555Sjungma@eit.uni-kl.de       << endl << "  #Active Fast-exit Power-Downs: "                          << c.f_act_pdns
42011555Sjungma@eit.uni-kl.de       << endl << "  #Active Slow-exit Power-Downs: "                          << c.s_act_pdns
42111555Sjungma@eit.uni-kl.de       << endl << "  #Precharged Fast-exit Power-Downs: "                      << c.f_pre_pdns
42211555Sjungma@eit.uni-kl.de       << endl << "  #Precharged Slow-exit Power-Downs: "                      << c.s_pre_pdns
42311555Sjungma@eit.uni-kl.de       << endl << "#Power-Down Cycles: "                                       << c.f_act_pdcycles + c.s_act_pdcycles + c.f_pre_pdcycles + c.s_pre_pdcycles
42411555Sjungma@eit.uni-kl.de       << endl << "  #Active Fast-exit Power-Down Cycles: "                    << c.f_act_pdcycles
42511555Sjungma@eit.uni-kl.de       << endl << "  #Active Slow-exit Power-Down Cycles: "                    << c.s_act_pdcycles
42611555Sjungma@eit.uni-kl.de       << endl << "    #Auto-Refresh Active cycles during Self-Refresh: "      << c.sref_ref_act_cycles
42711555Sjungma@eit.uni-kl.de       << endl << "  #Precharged Fast-exit Power-Down Cycles: "                << c.f_pre_pdcycles
42811555Sjungma@eit.uni-kl.de       << endl << "  #Precharged Slow-exit Power-Down Cycles: "                << c.s_pre_pdcycles
42911555Sjungma@eit.uni-kl.de       << endl << "    #Auto-Refresh Precharged cycles during Self-Refresh: "  << c.sref_ref_pre_cycles
43011555Sjungma@eit.uni-kl.de       << endl << "#Auto-Refresh Cycles: "                                     << c.numberofrefs * memTimingSpec.RFC
43111555Sjungma@eit.uni-kl.de       << endl << "#Self-Refreshes: "                                          << c.numberofsrefs
43211555Sjungma@eit.uni-kl.de       << endl << "#Self-Refresh Cycles: "                                     << c.sref_cycles
43311555Sjungma@eit.uni-kl.de       << endl << "----------------------------------------"
43411555Sjungma@eit.uni-kl.de       << endl << "Total Trace Length (clock cycles): " << total_cycles
43511555Sjungma@eit.uni-kl.de       << endl << "----------------------------------------" << endl;
43611555Sjungma@eit.uni-kl.de
43712266Sradhika.jagtap@arm.com  if (bankwiseMode) {
43812266Sradhika.jagtap@arm.com    cout << endl << "* Bankwise Details:";
43912266Sradhika.jagtap@arm.com    for (unsigned i = 0; i < nbrofBanks; i++) {
44012266Sradhika.jagtap@arm.com      cout << endl << "## @ Bank " << i << fixed
44112266Sradhika.jagtap@arm.com        << endl << "  ACT Cmd Energy: " << energy.act_energy_banks[i] << eUnit
44212266Sradhika.jagtap@arm.com        << endl << "  PRE Cmd Energy: " << energy.pre_energy_banks[i] << eUnit
44312266Sradhika.jagtap@arm.com        << endl << "  RD Cmd Energy: " << energy.read_energy_banks[i] << eUnit
44412266Sradhika.jagtap@arm.com        << endl << "  WR Cmd Energy: " << energy.write_energy_banks[i] << eUnit
44512266Sradhika.jagtap@arm.com        << endl << "  Auto-Refresh Energy: " << energy.ref_energy_banks[i] << eUnit
44612266Sradhika.jagtap@arm.com        << endl << "  Bankwise-Refresh Energy: " << energy.refb_energy_banks[i] << eUnit
44712266Sradhika.jagtap@arm.com        << endl << "  ACT Stdby Energy: " << nRanksDouble * energy.act_stdby_energy_banks[i] << eUnit
44812266Sradhika.jagtap@arm.com        << endl << "  PRE Stdby Energy: " << nRanksDouble * energy.pre_stdby_energy_banks[i] << eUnit
44912266Sradhika.jagtap@arm.com        << endl << "  Active Idle Energy: "<< nRanksDouble * energy.idle_energy_act_banks[i] << eUnit
45012266Sradhika.jagtap@arm.com        << endl << "  Precharge Idle Energy: "<< nRanksDouble * energy.idle_energy_pre_banks[i] << eUnit
45112266Sradhika.jagtap@arm.com        << endl << "  Fast-Exit Active Power-Down Energy: "<< nRanksDouble * energy.f_act_pd_energy_banks[i] << eUnit
45212266Sradhika.jagtap@arm.com        << endl << "  Fast-Exit Precharged Power-Down Energy: "<< nRanksDouble * energy.f_pre_pd_energy_banks[i] << eUnit
45312266Sradhika.jagtap@arm.com        << endl << "  Slow-Exit Active Power-Down Energy: "<< nRanksDouble * energy.s_act_pd_energy_banks[i] << eUnit
45412266Sradhika.jagtap@arm.com        << endl << "  Slow-Exit Precharged Power-Down Energy: "<< nRanksDouble * energy.s_pre_pd_energy_banks[i] << eUnit
45512266Sradhika.jagtap@arm.com        << endl << "  Self-Refresh Energy: "<< nRanksDouble * energy.sref_energy_banks[i] << eUnit
45612266Sradhika.jagtap@arm.com        << endl << "  Slow-Exit Active Power-Down Energy during Auto-Refresh cycles in Self-Refresh: "<< nRanksDouble * energy.sref_ref_act_energy_banks[i] << eUnit
45712266Sradhika.jagtap@arm.com        << endl << "  Slow-Exit Precharged Power-Down Energy during Auto-Refresh cycles in Self-Refresh: " << nRanksDouble * energy.sref_ref_pre_energy_banks[i] << eUnit
45812266Sradhika.jagtap@arm.com        << endl << "  Self-Refresh Power-Up Energy: "<< nRanksDouble * energy.spup_energy_banks[i] << eUnit
45912266Sradhika.jagtap@arm.com        << endl << "  Active Stdby Energy during Auto-Refresh cycles in Self-Refresh Power-Up: "<< nRanksDouble * energy.spup_ref_act_energy_banks[i] << eUnit
46012266Sradhika.jagtap@arm.com        << endl << "  Precharge Stdby Energy during Auto-Refresh cycles in Self-Refresh Power-Up: "<< nRanksDouble * energy.spup_ref_pre_energy_banks[i] << eUnit
46112266Sradhika.jagtap@arm.com        << endl << "  Active Power-Up Energy: "<< nRanksDouble * energy.pup_act_energy_banks[i] << eUnit
46212266Sradhika.jagtap@arm.com        << endl << "  Precharged Power-Up Energy: "<< nRanksDouble * energy.pup_pre_energy_banks[i] << eUnit
46312266Sradhika.jagtap@arm.com        << endl << "  Total Energy: "<< energy.total_energy_banks[i] << eUnit
46412266Sradhika.jagtap@arm.com        << endl;
46512266Sradhika.jagtap@arm.com    }
46612266Sradhika.jagtap@arm.com    cout << endl;
46712266Sradhika.jagtap@arm.com  }
46812266Sradhika.jagtap@arm.com
46910428Sandreas.hansson@arm.com  cout.precision(2);
47011555Sjungma@eit.uni-kl.de  cout << endl << "* Trace Power and Energy Estimates:" << endl
47111555Sjungma@eit.uni-kl.de       << endl << "ACT Cmd Energy: " << energy.act_energy   << eUnit
47211555Sjungma@eit.uni-kl.de       << endl << "PRE Cmd Energy: " << energy.pre_energy   << eUnit
47311555Sjungma@eit.uni-kl.de       << endl << "RD Cmd Energy: "  << energy.read_energy  << eUnit
47411555Sjungma@eit.uni-kl.de       << endl << "WR Cmd Energy: "  << energy.write_energy << eUnit;
47510428Sandreas.hansson@arm.com
47610428Sandreas.hansson@arm.com  if (term) {
47712266Sradhika.jagtap@arm.com    cout << endl << "RD I/O Energy: " << energy.read_io_energy << eUnit << endl;
47810428Sandreas.hansson@arm.com    // No Termination for LPDDR/2/3 and DDR memories
47910428Sandreas.hansson@arm.com    if (memSpec.memArchSpec.termination) {
48011555Sjungma@eit.uni-kl.de      cout << "WR Termination Energy: " << energy.write_term_energy << eUnit << endl;
48110428Sandreas.hansson@arm.com    }
48210428Sandreas.hansson@arm.com
48311555Sjungma@eit.uni-kl.de    if (nRanks > 1 && memSpec.memArchSpec.termination) {
48411555Sjungma@eit.uni-kl.de      cout <<         "RD Termination Energy (Idle rank): " << energy.read_oterm_energy << eUnit
48511555Sjungma@eit.uni-kl.de           << endl << "WR Termination Energy (Idle rank): " << energy.write_oterm_energy << eUnit << endl;
48610428Sandreas.hansson@arm.com    }
48710428Sandreas.hansson@arm.com  }
48811555Sjungma@eit.uni-kl.de
48911555Sjungma@eit.uni-kl.de  cout <<         "ACT Stdby Energy: "                                                                      << nRanksDouble * energy.act_stdby_energy << eUnit
49011555Sjungma@eit.uni-kl.de       << endl << "  Active Idle Energy: "                                                                  << nRanksDouble * energy.idle_energy_act << eUnit
49111555Sjungma@eit.uni-kl.de       << endl << "  Active Power-Up Energy: "                                                              << nRanksDouble * energy.pup_act_energy << eUnit
49211555Sjungma@eit.uni-kl.de       << endl << "    Active Stdby Energy during Auto-Refresh cycles in Self-Refresh Power-Up: "           << nRanksDouble * energy.spup_ref_act_energy << eUnit
49311555Sjungma@eit.uni-kl.de       << endl << "PRE Stdby Energy: "                                                                      << nRanksDouble * energy.pre_stdby_energy << eUnit
49411555Sjungma@eit.uni-kl.de       << endl << "  Precharge Idle Energy: "                                                               << nRanksDouble * energy.idle_energy_pre << eUnit
49511555Sjungma@eit.uni-kl.de       << endl << "  Precharged Power-Up Energy: "                                                          << nRanksDouble * energy.pup_pre_energy << eUnit
49611555Sjungma@eit.uni-kl.de       << endl << "    Precharge Stdby Energy during Auto-Refresh cycles in Self-Refresh Power-Up: "        << nRanksDouble * energy.spup_ref_pre_energy << eUnit
49711555Sjungma@eit.uni-kl.de       << endl << "  Self-Refresh Power-Up Energy: "                                                        << nRanksDouble * energy.spup_energy << eUnit
49811555Sjungma@eit.uni-kl.de       << endl << "Total Idle Energy (Active + Precharged): "                                               << nRanksDouble * (energy.idle_energy_act + energy.idle_energy_pre) << eUnit
49911555Sjungma@eit.uni-kl.de       << endl << "Total Power-Down Energy: "                                                               << nRanksDouble * (energy.f_act_pd_energy + energy.f_pre_pd_energy + energy.s_act_pd_energy + energy.s_pre_pd_energy) << eUnit
50011555Sjungma@eit.uni-kl.de       << endl << "  Fast-Exit Active Power-Down Energy: "                                                  << nRanksDouble * energy.f_act_pd_energy << eUnit
50111555Sjungma@eit.uni-kl.de       << endl << "  Slow-Exit Active Power-Down Energy: "                                                  << nRanksDouble * energy.s_act_pd_energy << eUnit
50211555Sjungma@eit.uni-kl.de       << endl << "    Slow-Exit Active Power-Down Energy during Auto-Refresh cycles in Self-Refresh: "     << nRanksDouble * energy.sref_ref_act_energy << eUnit
50311555Sjungma@eit.uni-kl.de       << endl << "  Fast-Exit Precharged Power-Down Energy: "                                              << nRanksDouble * energy.f_pre_pd_energy << eUnit
50411555Sjungma@eit.uni-kl.de       << endl << "  Slow-Exit Precharged Power-Down Energy: "                                              << nRanksDouble * energy.s_pre_pd_energy << eUnit
50511555Sjungma@eit.uni-kl.de       << endl << "    Slow-Exit Precharged Power-Down Energy during Auto-Refresh cycles in Self-Refresh: " << nRanksDouble * energy.sref_ref_pre_energy << eUnit
50611555Sjungma@eit.uni-kl.de       << endl << "Auto-Refresh Energy: "                                                                   << energy.ref_energy << eUnit
50712266Sradhika.jagtap@arm.com       << endl << "Bankwise-Refresh Energy: "                                                               << sum(energy.refb_energy_banks) << eUnit
50811555Sjungma@eit.uni-kl.de       << endl << "Self-Refresh Energy: "                                                                   << nRanksDouble * energy.sref_energy << eUnit
50911555Sjungma@eit.uni-kl.de       << endl << "----------------------------------------"
51011555Sjungma@eit.uni-kl.de       << endl << "Total Trace Energy: "                                                                    << energy.total_energy << eUnit
51111555Sjungma@eit.uni-kl.de       << endl << "Average Power: "                                                                         << power.average_power << " mW"
51211555Sjungma@eit.uni-kl.de       << endl << "----------------------------------------" << endl;
51311555Sjungma@eit.uni-kl.de
51411555Sjungma@eit.uni-kl.de  cout.flags(flags);
51511555Sjungma@eit.uni-kl.de  cout.precision(precision);
51610428Sandreas.hansson@arm.com} // MemoryPowerModel::power_print
51710428Sandreas.hansson@arm.com
51810428Sandreas.hansson@arm.com// Self-refresh active energy estimation (not including background energy)
51910428Sandreas.hansson@arm.comdouble MemoryPowerModel::engy_sref(double idd6, double idd3n, double idd5,
52010428Sandreas.hansson@arm.com                                   double vdd, double sref_cycles, double sref_ref_act_cycles,
52110428Sandreas.hansson@arm.com                                   double sref_ref_pre_cycles, double spup_ref_act_cycles,
52210428Sandreas.hansson@arm.com                                   double spup_ref_pre_cycles, double clk)
52310428Sandreas.hansson@arm.com{
52410428Sandreas.hansson@arm.com  double sref_energy;
52510428Sandreas.hansson@arm.com
52610428Sandreas.hansson@arm.com  sref_energy = ((idd6 * sref_cycles) + ((idd5 - idd3n) * (sref_ref_act_cycles
52710428Sandreas.hansson@arm.com                                                           + spup_ref_act_cycles + sref_ref_pre_cycles + spup_ref_pre_cycles)))
52810428Sandreas.hansson@arm.com                * vdd * clk;
52910428Sandreas.hansson@arm.com  return sref_energy;
53010428Sandreas.hansson@arm.com}
53110428Sandreas.hansson@arm.com
53212266Sradhika.jagtap@arm.com// Self-refresh active energy estimation per banks
53312266Sradhika.jagtap@arm.comdouble MemoryPowerModel::engy_sref_banks(double idd6, double idd3n, double idd5,
53412266Sradhika.jagtap@arm.com                                   double vdd, double sref_cycles, double sref_ref_act_cycles,
53512266Sradhika.jagtap@arm.com                                   double sref_ref_pre_cycles, double spup_ref_act_cycles,
53612266Sradhika.jagtap@arm.com                                   double spup_ref_pre_cycles, double clk,
53712266Sradhika.jagtap@arm.com                                   double esharedPASR, const MemBankWiseParams& bwPowerParams,
53812266Sradhika.jagtap@arm.com                                   unsigned bnkIdx, int64_t nbrofBanks)
53912266Sradhika.jagtap@arm.com{
54012266Sradhika.jagtap@arm.com    // Bankwise Self-refresh energy
54112266Sradhika.jagtap@arm.com    double sref_energy_banks;
54212266Sradhika.jagtap@arm.com    // Dynamic componenents for PASR energy varying based on PASR mode
54312266Sradhika.jagtap@arm.com    double iddsigmaDynBanks;
54412266Sradhika.jagtap@arm.com    double pasr_energy_dyn;
54512266Sradhika.jagtap@arm.com    // This component is distributed among all banks
54612266Sradhika.jagtap@arm.com    double sref_energy_shared;
54712266Sradhika.jagtap@arm.com    //Is PASR Active
54812266Sradhika.jagtap@arm.com    if (bwPowerParams.flgPASR){
54912266Sradhika.jagtap@arm.com        sref_energy_shared = (((idd5 - idd3n) * (sref_ref_act_cycles
55012266Sradhika.jagtap@arm.com                                                          + spup_ref_act_cycles + sref_ref_pre_cycles + spup_ref_pre_cycles)) * vdd * clk)
55112266Sradhika.jagtap@arm.com                                                / static_cast<double>(nbrofBanks);
55212266Sradhika.jagtap@arm.com        //if the bank is active under current PASR mode
55312266Sradhika.jagtap@arm.com        if (bwPowerParams.isBankActiveInPasr(bnkIdx)){
55412266Sradhika.jagtap@arm.com            // Distribute the sref energy to the active banks
55512266Sradhika.jagtap@arm.com            iddsigmaDynBanks = (static_cast<double>(100 - bwPowerParams.bwPowerFactSigma) / (100.0 * static_cast<double>(nbrofBanks))) * idd6;
55612266Sradhika.jagtap@arm.com            pasr_energy_dyn = vdd * iddsigmaDynBanks * sref_cycles;
55712266Sradhika.jagtap@arm.com            // Add the static components
55812266Sradhika.jagtap@arm.com            sref_energy_banks = sref_energy_shared + pasr_energy_dyn + (esharedPASR /static_cast<double>(nbrofBanks));
55912266Sradhika.jagtap@arm.com
56012266Sradhika.jagtap@arm.com        }else{
56112266Sradhika.jagtap@arm.com            sref_energy_banks = (esharedPASR /static_cast<double>(nbrofBanks));
56212266Sradhika.jagtap@arm.com        }
56312266Sradhika.jagtap@arm.com    }
56412266Sradhika.jagtap@arm.com    //When PASR is not active total all the banks are in Self-Refresh. Thus total Self-Refresh energy is distributed across all banks
56512266Sradhika.jagtap@arm.com    else{
56612266Sradhika.jagtap@arm.com
56712266Sradhika.jagtap@arm.com
56812266Sradhika.jagtap@arm.com            sref_energy_banks = (((idd6 * sref_cycles) + ((idd5 - idd3n) * (sref_ref_act_cycles
56912266Sradhika.jagtap@arm.com                                                + spup_ref_act_cycles + sref_ref_pre_cycles + spup_ref_pre_cycles)))
57012266Sradhika.jagtap@arm.com                                                * vdd * clk)
57112266Sradhika.jagtap@arm.com                                                / static_cast<double>(nbrofBanks);
57212266Sradhika.jagtap@arm.com    }
57312266Sradhika.jagtap@arm.com    return sref_energy_banks;
57412266Sradhika.jagtap@arm.com}
57512266Sradhika.jagtap@arm.com
57612266Sradhika.jagtap@arm.com
57710428Sandreas.hansson@arm.com// IO and Termination power calculation based on Micron Power Calculators
57810428Sandreas.hansson@arm.com// Absolute power measures are obtained from Micron Power Calculator (mentioned in mW)
57911555Sjungma@eit.uni-kl.devoid MemoryPowerModel::io_term_power(const MemorySpecification& memSpec)
58010428Sandreas.hansson@arm.com{
58111555Sjungma@eit.uni-kl.de  const MemTimingSpec& memTimingSpec     = memSpec.memTimingSpec;
58211555Sjungma@eit.uni-kl.de  const MemArchitectureSpec& memArchSpec = memSpec.memArchSpec;
58311555Sjungma@eit.uni-kl.de  const MemPowerSpec&  memPowerSpec      = memSpec.memPowerSpec;
58410428Sandreas.hansson@arm.com
58510428Sandreas.hansson@arm.com  power.IO_power     = memPowerSpec.ioPower;    // in mW
58610428Sandreas.hansson@arm.com  power.WR_ODT_power = memPowerSpec.wrOdtPower; // in mW
58710428Sandreas.hansson@arm.com
58810428Sandreas.hansson@arm.com  if (memArchSpec.nbrOfRanks > 1) {
58910428Sandreas.hansson@arm.com    power.TermRD_power = memPowerSpec.termRdPower; // in mW
59010428Sandreas.hansson@arm.com    power.TermWR_power = memPowerSpec.termWrPower; // in mW
59110428Sandreas.hansson@arm.com  }
59210428Sandreas.hansson@arm.com
59310428Sandreas.hansson@arm.com  if (memPowerSpec.capacitance != 0.0) {
59410428Sandreas.hansson@arm.com    // If capacity is given, then IO Power depends on DRAM clock frequency.
59510428Sandreas.hansson@arm.com    power.IO_power = memPowerSpec.capacitance * 0.5 * pow(memPowerSpec.vdd2, 2.0) * memTimingSpec.clkMhz * 1000000;
59610428Sandreas.hansson@arm.com  }
59710428Sandreas.hansson@arm.com} // MemoryPowerModel::io_term_power
59810428Sandreas.hansson@arm.com
59910428Sandreas.hansson@arm.com
60010428Sandreas.hansson@arm.comdouble MemoryPowerModel::calcIoTermEnergy(int64_t cycles, double period, double power, int64_t numBits) const
60110428Sandreas.hansson@arm.com{
60210428Sandreas.hansson@arm.com  return static_cast<double>(cycles) * period * power * static_cast<double>(numBits);
60310428Sandreas.hansson@arm.com}
60410428Sandreas.hansson@arm.com
60510428Sandreas.hansson@arm.com// time (t) * current (I) * voltage (V) energy calculation
60610428Sandreas.hansson@arm.comdouble EnergyDomain::calcTivEnergy(int64_t cycles, double current) const
60710428Sandreas.hansson@arm.com{
60810428Sandreas.hansson@arm.com  return static_cast<double>(cycles) * clkPeriod * current * voltage;
60910428Sandreas.hansson@arm.com}
61012266Sradhika.jagtap@arm.com
611