MemoryPowerModel.cc revision 11555
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 *
3410428Sandreas.hansson@arm.com * Authors: Karthik Chandrasekar, Matthias Jung, Omar Naji
3510428Sandreas.hansson@arm.com *
3610428Sandreas.hansson@arm.com */
3710428Sandreas.hansson@arm.com
3810428Sandreas.hansson@arm.com#include "MemoryPowerModel.h"
3910428Sandreas.hansson@arm.com
4011555Sjungma@eit.uni-kl.de#include <stdint.h>
4111555Sjungma@eit.uni-kl.de
4210428Sandreas.hansson@arm.com#include <cmath>  // For pow
4311555Sjungma@eit.uni-kl.de#include <iostream>  // fmtflags
4410428Sandreas.hansson@arm.com
4510428Sandreas.hansson@arm.com
4610428Sandreas.hansson@arm.comusing namespace std;
4710428Sandreas.hansson@arm.comusing namespace Data;
4810428Sandreas.hansson@arm.com
4910428Sandreas.hansson@arm.com// Calculate energy and average power consumption for the given command trace
5010428Sandreas.hansson@arm.com
5111555Sjungma@eit.uni-kl.devoid MemoryPowerModel::power_calc(const MemorySpecification& memSpec,
5211555Sjungma@eit.uni-kl.de                                  const CommandAnalysis& c,
5310428Sandreas.hansson@arm.com                                  int term)
5410428Sandreas.hansson@arm.com{
5511555Sjungma@eit.uni-kl.de  const MemTimingSpec& t                 = memSpec.memTimingSpec;
5611555Sjungma@eit.uni-kl.de  const MemArchitectureSpec& memArchSpec = memSpec.memArchSpec;
5711555Sjungma@eit.uni-kl.de  const MemPowerSpec&  mps               = memSpec.memPowerSpec;
5810428Sandreas.hansson@arm.com
5910428Sandreas.hansson@arm.com  energy.act_energy          = 0.0;
6010428Sandreas.hansson@arm.com  energy.pre_energy          = 0.0;
6110428Sandreas.hansson@arm.com  energy.read_energy         = 0.0;
6210428Sandreas.hansson@arm.com  energy.write_energy        = 0.0;
6310428Sandreas.hansson@arm.com  energy.ref_energy          = 0.0;
6410428Sandreas.hansson@arm.com  energy.act_stdby_energy    = 0.0;
6510428Sandreas.hansson@arm.com  energy.pre_stdby_energy    = 0.0;
6610428Sandreas.hansson@arm.com  energy.idle_energy_act     = 0.0;
6710428Sandreas.hansson@arm.com  energy.idle_energy_pre     = 0.0;
6810428Sandreas.hansson@arm.com  energy.total_energy        = 0.0;
6910428Sandreas.hansson@arm.com  energy.f_act_pd_energy     = 0.0;
7010428Sandreas.hansson@arm.com  energy.f_pre_pd_energy     = 0.0;
7110428Sandreas.hansson@arm.com  energy.s_act_pd_energy     = 0.0;
7210428Sandreas.hansson@arm.com  energy.s_pre_pd_energy     = 0.0;
7310428Sandreas.hansson@arm.com  energy.sref_energy         = 0.0;
7410428Sandreas.hansson@arm.com  energy.sref_ref_energy     = 0.0;
7510428Sandreas.hansson@arm.com  energy.sref_ref_act_energy = 0.0;
7610428Sandreas.hansson@arm.com  energy.sref_ref_pre_energy = 0.0;
7710428Sandreas.hansson@arm.com  energy.spup_energy         = 0.0;
7810428Sandreas.hansson@arm.com  energy.spup_ref_energy     = 0.0;
7910428Sandreas.hansson@arm.com  energy.spup_ref_act_energy = 0.0;
8010428Sandreas.hansson@arm.com  energy.spup_ref_pre_energy = 0.0;
8110428Sandreas.hansson@arm.com  energy.pup_act_energy      = 0.0;
8210428Sandreas.hansson@arm.com  energy.pup_pre_energy      = 0.0;
8310428Sandreas.hansson@arm.com  power.IO_power             = 0.0;
8410428Sandreas.hansson@arm.com  power.WR_ODT_power         = 0.0;
8510428Sandreas.hansson@arm.com  power.TermRD_power         = 0.0;
8610428Sandreas.hansson@arm.com  power.TermWR_power         = 0.0;
8710428Sandreas.hansson@arm.com  energy.read_io_energy      = 0.0;
8810428Sandreas.hansson@arm.com  energy.write_term_energy   = 0.0;
8910428Sandreas.hansson@arm.com  energy.read_oterm_energy   = 0.0;
9010428Sandreas.hansson@arm.com  energy.write_oterm_energy  = 0.0;
9110428Sandreas.hansson@arm.com  energy.io_term_energy      = 0.0;
9210428Sandreas.hansson@arm.com
9310428Sandreas.hansson@arm.com  // How long a single burst takes, measured in command-clock cycles.
9410428Sandreas.hansson@arm.com  int64_t burstCc = memArchSpec.burstLength / memArchSpec.dataRate;
9510428Sandreas.hansson@arm.com
9610428Sandreas.hansson@arm.com  // IO and Termination Power measures are included, if required.
9710428Sandreas.hansson@arm.com  if (term) {
9810428Sandreas.hansson@arm.com    io_term_power(memSpec);
9910428Sandreas.hansson@arm.com
10010428Sandreas.hansson@arm.com    // memArchSpec.width represents the number of data (dq) pins.
10110428Sandreas.hansson@arm.com    // 1 DQS pin is associated with every data byte
10210428Sandreas.hansson@arm.com    int64_t dqPlusDqsBits = memArchSpec.width + memArchSpec.width / 8;
10310428Sandreas.hansson@arm.com    // 1 DQS and 1 DM pin is associated with every data byte
10410428Sandreas.hansson@arm.com    int64_t dqPlusDqsPlusMaskBits = memArchSpec.width + memArchSpec.width / 8 + memArchSpec.width / 8;
10510428Sandreas.hansson@arm.com    // Size of one clock period for the data bus.
10611555Sjungma@eit.uni-kl.de    double ddrPeriod = t.clkPeriod / static_cast<double>(memArchSpec.dataRate);
10710428Sandreas.hansson@arm.com
10810428Sandreas.hansson@arm.com    // Read IO power is consumed by each DQ (data) and DQS (data strobe) pin
10911555Sjungma@eit.uni-kl.de    energy.read_io_energy = calcIoTermEnergy(c.numberofreads * memArchSpec.burstLength,
11010428Sandreas.hansson@arm.com                                             ddrPeriod,
11110428Sandreas.hansson@arm.com                                             power.IO_power,
11210428Sandreas.hansson@arm.com                                             dqPlusDqsBits);
11310428Sandreas.hansson@arm.com
11410428Sandreas.hansson@arm.com    // Write ODT power is consumed by each DQ (data), DQS (data strobe) and DM
11511555Sjungma@eit.uni-kl.de    energy.write_term_energy = calcIoTermEnergy(c.numberofwrites * memArchSpec.burstLength,
11610428Sandreas.hansson@arm.com                                                ddrPeriod,
11710428Sandreas.hansson@arm.com                                                power.WR_ODT_power,
11810428Sandreas.hansson@arm.com                                                dqPlusDqsPlusMaskBits);
11910428Sandreas.hansson@arm.com
12010428Sandreas.hansson@arm.com    if (memArchSpec.nbrOfRanks > 1) {
12110428Sandreas.hansson@arm.com      // Termination power consumed in the idle rank during reads on the active
12210428Sandreas.hansson@arm.com      // rank by each DQ (data) and DQS (data strobe) pin.
12311555Sjungma@eit.uni-kl.de      energy.read_oterm_energy = calcIoTermEnergy(c.numberofreads * memArchSpec.burstLength,
12410428Sandreas.hansson@arm.com                                                  ddrPeriod,
12510428Sandreas.hansson@arm.com                                                  power.TermRD_power,
12610428Sandreas.hansson@arm.com                                                  dqPlusDqsBits);
12710428Sandreas.hansson@arm.com
12810428Sandreas.hansson@arm.com      // Termination power consumed in the idle rank during writes on the active
12910428Sandreas.hansson@arm.com      // rank by each DQ (data), DQS (data strobe) and DM (data mask) pin.
13011555Sjungma@eit.uni-kl.de      energy.write_oterm_energy = calcIoTermEnergy(c.numberofwrites * memArchSpec.burstLength,
13110428Sandreas.hansson@arm.com                                                   ddrPeriod,
13210428Sandreas.hansson@arm.com                                                   power.TermWR_power,
13310428Sandreas.hansson@arm.com                                                   dqPlusDqsPlusMaskBits);
13410428Sandreas.hansson@arm.com    }
13510428Sandreas.hansson@arm.com
13610428Sandreas.hansson@arm.com    // Sum of all IO and termination energy
13710428Sandreas.hansson@arm.com    energy.io_term_energy = energy.read_io_energy + energy.write_term_energy
13810428Sandreas.hansson@arm.com                            + energy.read_oterm_energy + energy.write_oterm_energy;
13910428Sandreas.hansson@arm.com  }
14010428Sandreas.hansson@arm.com
14111555Sjungma@eit.uni-kl.de  total_cycles = c.actcycles + c.precycles +
14211555Sjungma@eit.uni-kl.de                 c.f_act_pdcycles + c.f_pre_pdcycles +
14311555Sjungma@eit.uni-kl.de                 c.s_act_pdcycles + c.s_pre_pdcycles + c.sref_cycles
14411555Sjungma@eit.uni-kl.de                 + c.sref_ref_act_cycles + c.sref_ref_pre_cycles +
14511555Sjungma@eit.uni-kl.de                 c.spup_ref_act_cycles + c.spup_ref_pre_cycles;
14610428Sandreas.hansson@arm.com
14710428Sandreas.hansson@arm.com  EnergyDomain vdd0Domain(mps.vdd, t.clkPeriod);
14810428Sandreas.hansson@arm.com
14911555Sjungma@eit.uni-kl.de  energy.act_energy       = vdd0Domain.calcTivEnergy(c.numberofacts   * t.RAS          , mps.idd0 - mps.idd3n);
15011555Sjungma@eit.uni-kl.de  energy.pre_energy       = vdd0Domain.calcTivEnergy(c.numberofpres   * (t.RC - t.RAS) , mps.idd0 - mps.idd2n);
15111555Sjungma@eit.uni-kl.de  energy.read_energy      = vdd0Domain.calcTivEnergy(c.numberofreads  * burstCc        , mps.idd4r - mps.idd3n);
15211555Sjungma@eit.uni-kl.de  energy.write_energy     = vdd0Domain.calcTivEnergy(c.numberofwrites * burstCc        , mps.idd4w - mps.idd3n);
15311555Sjungma@eit.uni-kl.de  energy.ref_energy       = vdd0Domain.calcTivEnergy(c.numberofrefs   * t.RFC          , mps.idd5 - mps.idd3n);
15411555Sjungma@eit.uni-kl.de  energy.pre_stdby_energy = vdd0Domain.calcTivEnergy(c.precycles, mps.idd2n);
15511555Sjungma@eit.uni-kl.de  energy.act_stdby_energy = vdd0Domain.calcTivEnergy(c.actcycles, mps.idd3n);
15610428Sandreas.hansson@arm.com  // Idle energy in the active standby clock cycles
15711555Sjungma@eit.uni-kl.de  energy.idle_energy_act  = vdd0Domain.calcTivEnergy(c.idlecycles_act, mps.idd3n);
15810428Sandreas.hansson@arm.com  // Idle energy in the precharge standby clock cycles
15911555Sjungma@eit.uni-kl.de  energy.idle_energy_pre  = vdd0Domain.calcTivEnergy(c.idlecycles_pre, mps.idd2n);
16010428Sandreas.hansson@arm.com  // fast-exit active power-down cycles energy
16111555Sjungma@eit.uni-kl.de  energy.f_act_pd_energy  = vdd0Domain.calcTivEnergy(c.f_act_pdcycles, mps.idd3p1);
16210428Sandreas.hansson@arm.com  // fast-exit precharged power-down cycles energy
16311555Sjungma@eit.uni-kl.de  energy.f_pre_pd_energy  = vdd0Domain.calcTivEnergy(c.f_pre_pdcycles, mps.idd2p1);
16410428Sandreas.hansson@arm.com  // slow-exit active power-down cycles energy
16511555Sjungma@eit.uni-kl.de  energy.s_act_pd_energy  = vdd0Domain.calcTivEnergy(c.s_act_pdcycles, mps.idd3p0);
16610428Sandreas.hansson@arm.com  // slow-exit precharged power-down cycles energy
16711555Sjungma@eit.uni-kl.de  energy.s_pre_pd_energy  = vdd0Domain.calcTivEnergy(c.s_pre_pdcycles, mps.idd2p0);
16810428Sandreas.hansson@arm.com
16910428Sandreas.hansson@arm.com  // self-refresh cycles energy including a refresh per self-refresh entry
17010428Sandreas.hansson@arm.com  energy.sref_energy = engy_sref(mps.idd6, mps.idd3n,
17110428Sandreas.hansson@arm.com                                 mps.idd5, mps.vdd,
17211555Sjungma@eit.uni-kl.de                                 static_cast<double>(c.sref_cycles), static_cast<double>(c.sref_ref_act_cycles),
17311555Sjungma@eit.uni-kl.de                                 static_cast<double>(c.sref_ref_pre_cycles), static_cast<double>(c.spup_ref_act_cycles),
17411555Sjungma@eit.uni-kl.de                                 static_cast<double>(c.spup_ref_pre_cycles), t.clkPeriod);
17510428Sandreas.hansson@arm.com
17610428Sandreas.hansson@arm.com  // background energy during active auto-refresh cycles in self-refresh
17711555Sjungma@eit.uni-kl.de  energy.sref_ref_act_energy = vdd0Domain.calcTivEnergy(c.sref_ref_act_cycles, mps.idd3p0);
17810428Sandreas.hansson@arm.com  // background energy during precharged auto-refresh cycles in self-refresh
17911555Sjungma@eit.uni-kl.de  energy.sref_ref_pre_energy = vdd0Domain.calcTivEnergy(c.sref_ref_pre_cycles, mps.idd2p0);
18010428Sandreas.hansson@arm.com  // background energy during active auto-refresh cycles in self-refresh exit
18111555Sjungma@eit.uni-kl.de  energy.spup_ref_act_energy = vdd0Domain.calcTivEnergy(c.spup_ref_act_cycles, mps.idd3n);
18210428Sandreas.hansson@arm.com  // background energy during precharged auto-refresh cycles in self-refresh exit
18311555Sjungma@eit.uni-kl.de  energy.spup_ref_pre_energy = vdd0Domain.calcTivEnergy(c.spup_ref_pre_cycles, mps.idd2n);
18410428Sandreas.hansson@arm.com  // self-refresh power-up cycles energy -- included
18511555Sjungma@eit.uni-kl.de  energy.spup_energy         = vdd0Domain.calcTivEnergy(c.spup_cycles, mps.idd2n);
18610428Sandreas.hansson@arm.com  // active power-up cycles energy - same as active standby -- included
18711555Sjungma@eit.uni-kl.de  energy.pup_act_energy      = vdd0Domain.calcTivEnergy(c.pup_act_cycles, mps.idd3n);
18810428Sandreas.hansson@arm.com  // precharged power-up cycles energy - same as precharged standby -- included
18911555Sjungma@eit.uni-kl.de  energy.pup_pre_energy      = vdd0Domain.calcTivEnergy(c.pup_pre_cycles, mps.idd2n);
19010428Sandreas.hansson@arm.com
19110428Sandreas.hansson@arm.com  // similar equations as before to support multiple voltage domains in LPDDR2
19210428Sandreas.hansson@arm.com  // and WIDEIO memories
19310428Sandreas.hansson@arm.com  if (memArchSpec.twoVoltageDomains) {
19410428Sandreas.hansson@arm.com    EnergyDomain vdd2Domain(mps.vdd2, t.clkPeriod);
19510428Sandreas.hansson@arm.com
19611555Sjungma@eit.uni-kl.de    energy.act_energy       += vdd2Domain.calcTivEnergy(c.numberofacts   * t.RAS          , mps.idd02 - mps.idd3n2);
19711555Sjungma@eit.uni-kl.de    energy.pre_energy       += vdd2Domain.calcTivEnergy(c.numberofpres   * (t.RC - t.RAS) , mps.idd02 - mps.idd2n2);
19811555Sjungma@eit.uni-kl.de    energy.read_energy      += vdd2Domain.calcTivEnergy(c.numberofreads  * burstCc        , mps.idd4r2 - mps.idd3n2);
19911555Sjungma@eit.uni-kl.de    energy.write_energy     += vdd2Domain.calcTivEnergy(c.numberofwrites * burstCc        , mps.idd4w2 - mps.idd3n2);
20011555Sjungma@eit.uni-kl.de    energy.ref_energy       += vdd2Domain.calcTivEnergy(c.numberofrefs   * t.RFC          , mps.idd52 - mps.idd3n2);
20111555Sjungma@eit.uni-kl.de    energy.pre_stdby_energy += vdd2Domain.calcTivEnergy(c.precycles, mps.idd2n2);
20211555Sjungma@eit.uni-kl.de    energy.act_stdby_energy += vdd2Domain.calcTivEnergy(c.actcycles, mps.idd3n2);
20310428Sandreas.hansson@arm.com    // Idle energy in the active standby clock cycles
20411555Sjungma@eit.uni-kl.de    energy.idle_energy_act  += vdd2Domain.calcTivEnergy(c.idlecycles_act, mps.idd3n2);
20510428Sandreas.hansson@arm.com    // Idle energy in the precharge standby clock cycles
20611555Sjungma@eit.uni-kl.de    energy.idle_energy_pre  += vdd2Domain.calcTivEnergy(c.idlecycles_pre, mps.idd2n2);
20710428Sandreas.hansson@arm.com    // fast-exit active power-down cycles energy
20811555Sjungma@eit.uni-kl.de    energy.f_act_pd_energy  += vdd2Domain.calcTivEnergy(c.f_act_pdcycles, mps.idd3p12);
20910428Sandreas.hansson@arm.com    // fast-exit precharged power-down cycles energy
21011555Sjungma@eit.uni-kl.de    energy.f_pre_pd_energy  += vdd2Domain.calcTivEnergy(c.f_pre_pdcycles, mps.idd2p12);
21110428Sandreas.hansson@arm.com    // slow-exit active power-down cycles energy
21211555Sjungma@eit.uni-kl.de    energy.s_act_pd_energy  += vdd2Domain.calcTivEnergy(c.s_act_pdcycles, mps.idd3p02);
21310428Sandreas.hansson@arm.com    // slow-exit precharged power-down cycles energy
21411555Sjungma@eit.uni-kl.de    energy.s_pre_pd_energy  += vdd2Domain.calcTivEnergy(c.s_pre_pdcycles, mps.idd2p02);
21510428Sandreas.hansson@arm.com
21610428Sandreas.hansson@arm.com    energy.sref_energy      += engy_sref(mps.idd62, mps.idd3n2,
21710428Sandreas.hansson@arm.com                                         mps.idd52, mps.vdd2,
21811555Sjungma@eit.uni-kl.de                                         static_cast<double>(c.sref_cycles), static_cast<double>(c.sref_ref_act_cycles),
21911555Sjungma@eit.uni-kl.de                                         static_cast<double>(c.sref_ref_pre_cycles), static_cast<double>(c.spup_ref_act_cycles),
22011555Sjungma@eit.uni-kl.de                                         static_cast<double>(c.spup_ref_pre_cycles), t.clkPeriod);
22110428Sandreas.hansson@arm.com
22210428Sandreas.hansson@arm.com    // background energy during active auto-refresh cycles in self-refresh
22311555Sjungma@eit.uni-kl.de    energy.sref_ref_act_energy += vdd2Domain.calcTivEnergy(c.sref_ref_act_cycles, mps.idd3p02);
22410428Sandreas.hansson@arm.com    // background energy during precharged auto-refresh cycles in self-refresh
22511555Sjungma@eit.uni-kl.de    energy.sref_ref_pre_energy += vdd2Domain.calcTivEnergy(c.sref_ref_pre_cycles, mps.idd2p02);
22610428Sandreas.hansson@arm.com    // background energy during active auto-refresh cycles in self-refresh exit
22711555Sjungma@eit.uni-kl.de    energy.spup_ref_act_energy += vdd2Domain.calcTivEnergy(c.spup_ref_act_cycles, mps.idd3n2);
22810428Sandreas.hansson@arm.com    // background energy during precharged auto-refresh cycles in self-refresh exit
22911555Sjungma@eit.uni-kl.de    energy.spup_ref_pre_energy += vdd2Domain.calcTivEnergy(c.spup_ref_pre_cycles, mps.idd2n2);
23010428Sandreas.hansson@arm.com    // self-refresh power-up cycles energy -- included
23111555Sjungma@eit.uni-kl.de    energy.spup_energy         += vdd2Domain.calcTivEnergy(c.spup_cycles, mps.idd2n2);
23210428Sandreas.hansson@arm.com    // active power-up cycles energy - same as active standby -- included
23311555Sjungma@eit.uni-kl.de    energy.pup_act_energy      += vdd2Domain.calcTivEnergy(c.pup_act_cycles, mps.idd3n2);
23410428Sandreas.hansson@arm.com    // precharged power-up cycles energy - same as precharged standby -- included
23511555Sjungma@eit.uni-kl.de    energy.pup_pre_energy      += vdd2Domain.calcTivEnergy(c.pup_pre_cycles, mps.idd2n2);
23610428Sandreas.hansson@arm.com  }
23710428Sandreas.hansson@arm.com
23810428Sandreas.hansson@arm.com  // auto-refresh energy during self-refresh cycles
23910428Sandreas.hansson@arm.com  energy.sref_ref_energy = energy.sref_ref_act_energy + energy.sref_ref_pre_energy;
24010428Sandreas.hansson@arm.com
24110428Sandreas.hansson@arm.com  // auto-refresh energy during self-refresh exit cycles
24210428Sandreas.hansson@arm.com  energy.spup_ref_energy = energy.spup_ref_act_energy + energy.spup_ref_pre_energy;
24310428Sandreas.hansson@arm.com
24410428Sandreas.hansson@arm.com  // adding all energy components for the active rank and all background and idle
24510428Sandreas.hansson@arm.com  // energy components for both ranks (in a dual-rank system)
24610428Sandreas.hansson@arm.com  energy.total_energy = energy.act_energy + energy.pre_energy + energy.read_energy +
24710428Sandreas.hansson@arm.com                        energy.write_energy + energy.ref_energy + energy.io_term_energy +
24811555Sjungma@eit.uni-kl.de                        static_cast<double>(memArchSpec.nbrOfRanks) * (energy.act_stdby_energy +
24910428Sandreas.hansson@arm.com                                                  energy.pre_stdby_energy + energy.sref_energy +
25010428Sandreas.hansson@arm.com                                                  energy.f_act_pd_energy + energy.f_pre_pd_energy + energy.s_act_pd_energy
25110428Sandreas.hansson@arm.com                                                  + energy.s_pre_pd_energy + energy.sref_ref_energy + energy.spup_ref_energy);
25210428Sandreas.hansson@arm.com
25310428Sandreas.hansson@arm.com  // Calculate the average power consumption
25410428Sandreas.hansson@arm.com  power.average_power = energy.total_energy / (static_cast<double>(total_cycles) * t.clkPeriod);
25510428Sandreas.hansson@arm.com} // MemoryPowerModel::power_calc
25610428Sandreas.hansson@arm.com
25711555Sjungma@eit.uni-kl.devoid MemoryPowerModel::power_print(const MemorySpecification& memSpec, int term, const CommandAnalysis& c) const
25810428Sandreas.hansson@arm.com{
25911555Sjungma@eit.uni-kl.de  const MemTimingSpec& memTimingSpec     = memSpec.memTimingSpec;
26011555Sjungma@eit.uni-kl.de  const MemArchitectureSpec& memArchSpec = memSpec.memArchSpec;
26111555Sjungma@eit.uni-kl.de  const uint64_t nRanks = static_cast<uint64_t>(memArchSpec.nbrOfRanks);
26211555Sjungma@eit.uni-kl.de  const char eUnit[] = " pJ";
26310428Sandreas.hansson@arm.com
26411555Sjungma@eit.uni-kl.de  ios_base::fmtflags flags = cout.flags();
26511555Sjungma@eit.uni-kl.de  streamsize precision = cout.precision();
26610428Sandreas.hansson@arm.com  cout.precision(0);
26711555Sjungma@eit.uni-kl.de  cout << "* Trace Details:" << fixed << endl
26811555Sjungma@eit.uni-kl.de       << endl << "#ACT commands: "                 << c.numberofacts
26911555Sjungma@eit.uni-kl.de       << endl << "#RD + #RDA commands: "           << c.numberofreads
27011555Sjungma@eit.uni-kl.de       << endl << "#WR + #WRA commands: "           << c.numberofwrites
27111555Sjungma@eit.uni-kl.de  /* #PRE commands (precharge all counts a number of #PRE commands equal to the number of active banks) */
27211555Sjungma@eit.uni-kl.de       << endl << "#PRE (+ PREA) commands: "        << c.numberofpres
27311555Sjungma@eit.uni-kl.de       << endl << "#REF commands: "                 << c.numberofrefs
27411555Sjungma@eit.uni-kl.de       << endl << "#Active Cycles: "                << c.actcycles
27511555Sjungma@eit.uni-kl.de       << endl << "  #Active Idle Cycles: "         << c.idlecycles_act
27611555Sjungma@eit.uni-kl.de       << endl << "  #Active Power-Up Cycles: "     << c.pup_act_cycles
27711555Sjungma@eit.uni-kl.de       << endl << "    #Auto-Refresh Active cycles during Self-Refresh Power-Up: " << c.spup_ref_act_cycles
27811555Sjungma@eit.uni-kl.de       << endl << "#Precharged Cycles: "            << c.precycles
27911555Sjungma@eit.uni-kl.de       << endl << "  #Precharged Idle Cycles: "     << c.idlecycles_pre
28011555Sjungma@eit.uni-kl.de       << endl << "  #Precharged Power-Up Cycles: " << c.pup_pre_cycles
28111555Sjungma@eit.uni-kl.de       << endl << "    #Auto-Refresh Precharged cycles during Self-Refresh Power-Up: " << c.spup_ref_pre_cycles
28211555Sjungma@eit.uni-kl.de       << endl << "  #Self-Refresh Power-Up Cycles: "                          << c.spup_cycles
28311555Sjungma@eit.uni-kl.de       << endl << "Total Idle Cycles (Active + Precharged): "                  << c.idlecycles_act + c.idlecycles_pre
28411555Sjungma@eit.uni-kl.de       << endl << "#Power-Downs: "                                             << c.f_act_pdns +  c.s_act_pdns + c.f_pre_pdns + c.s_pre_pdns
28511555Sjungma@eit.uni-kl.de       << endl << "  #Active Fast-exit Power-Downs: "                          << c.f_act_pdns
28611555Sjungma@eit.uni-kl.de       << endl << "  #Active Slow-exit Power-Downs: "                          << c.s_act_pdns
28711555Sjungma@eit.uni-kl.de       << endl << "  #Precharged Fast-exit Power-Downs: "                      << c.f_pre_pdns
28811555Sjungma@eit.uni-kl.de       << endl << "  #Precharged Slow-exit Power-Downs: "                      << c.s_pre_pdns
28911555Sjungma@eit.uni-kl.de       << endl << "#Power-Down Cycles: "                                       << c.f_act_pdcycles + c.s_act_pdcycles + c.f_pre_pdcycles + c.s_pre_pdcycles
29011555Sjungma@eit.uni-kl.de       << endl << "  #Active Fast-exit Power-Down Cycles: "                    << c.f_act_pdcycles
29111555Sjungma@eit.uni-kl.de       << endl << "  #Active Slow-exit Power-Down Cycles: "                    << c.s_act_pdcycles
29211555Sjungma@eit.uni-kl.de       << endl << "    #Auto-Refresh Active cycles during Self-Refresh: "      << c.sref_ref_act_cycles
29311555Sjungma@eit.uni-kl.de       << endl << "  #Precharged Fast-exit Power-Down Cycles: "                << c.f_pre_pdcycles
29411555Sjungma@eit.uni-kl.de       << endl << "  #Precharged Slow-exit Power-Down Cycles: "                << c.s_pre_pdcycles
29511555Sjungma@eit.uni-kl.de       << endl << "    #Auto-Refresh Precharged cycles during Self-Refresh: "  << c.sref_ref_pre_cycles
29611555Sjungma@eit.uni-kl.de       << endl << "#Auto-Refresh Cycles: "                                     << c.numberofrefs * memTimingSpec.RFC
29711555Sjungma@eit.uni-kl.de       << endl << "#Self-Refreshes: "                                          << c.numberofsrefs
29811555Sjungma@eit.uni-kl.de       << endl << "#Self-Refresh Cycles: "                                     << c.sref_cycles
29911555Sjungma@eit.uni-kl.de       << endl << "----------------------------------------"
30011555Sjungma@eit.uni-kl.de       << endl << "Total Trace Length (clock cycles): " << total_cycles
30111555Sjungma@eit.uni-kl.de       << endl << "----------------------------------------" << endl;
30211555Sjungma@eit.uni-kl.de
30310428Sandreas.hansson@arm.com  cout.precision(2);
30411555Sjungma@eit.uni-kl.de  cout << endl << "* Trace Power and Energy Estimates:" << endl
30511555Sjungma@eit.uni-kl.de       << endl << "ACT Cmd Energy: " << energy.act_energy   << eUnit
30611555Sjungma@eit.uni-kl.de       << endl << "PRE Cmd Energy: " << energy.pre_energy   << eUnit
30711555Sjungma@eit.uni-kl.de       << endl << "RD Cmd Energy: "  << energy.read_energy  << eUnit
30811555Sjungma@eit.uni-kl.de       << endl << "WR Cmd Energy: "  << energy.write_energy << eUnit;
30910428Sandreas.hansson@arm.com
31010428Sandreas.hansson@arm.com  if (term) {
31111555Sjungma@eit.uni-kl.de    cout << "RD I/O Energy: " << energy.read_io_energy << eUnit << endl;
31210428Sandreas.hansson@arm.com    // No Termination for LPDDR/2/3 and DDR memories
31310428Sandreas.hansson@arm.com    if (memSpec.memArchSpec.termination) {
31411555Sjungma@eit.uni-kl.de      cout << "WR Termination Energy: " << energy.write_term_energy << eUnit << endl;
31510428Sandreas.hansson@arm.com    }
31610428Sandreas.hansson@arm.com
31711555Sjungma@eit.uni-kl.de    if (nRanks > 1 && memSpec.memArchSpec.termination) {
31811555Sjungma@eit.uni-kl.de      cout <<         "RD Termination Energy (Idle rank): " << energy.read_oterm_energy << eUnit
31911555Sjungma@eit.uni-kl.de           << endl << "WR Termination Energy (Idle rank): " << energy.write_oterm_energy << eUnit << endl;
32010428Sandreas.hansson@arm.com    }
32110428Sandreas.hansson@arm.com  }
32211555Sjungma@eit.uni-kl.de
32311555Sjungma@eit.uni-kl.de  double nRanksDouble = static_cast<double>(nRanks);
32411555Sjungma@eit.uni-kl.de
32511555Sjungma@eit.uni-kl.de  cout <<         "ACT Stdby Energy: "                                                                      << nRanksDouble * energy.act_stdby_energy << eUnit
32611555Sjungma@eit.uni-kl.de       << endl << "  Active Idle Energy: "                                                                  << nRanksDouble * energy.idle_energy_act << eUnit
32711555Sjungma@eit.uni-kl.de       << endl << "  Active Power-Up Energy: "                                                              << nRanksDouble * energy.pup_act_energy << eUnit
32811555Sjungma@eit.uni-kl.de       << endl << "    Active Stdby Energy during Auto-Refresh cycles in Self-Refresh Power-Up: "           << nRanksDouble * energy.spup_ref_act_energy << eUnit
32911555Sjungma@eit.uni-kl.de       << endl << "PRE Stdby Energy: "                                                                      << nRanksDouble * energy.pre_stdby_energy << eUnit
33011555Sjungma@eit.uni-kl.de       << endl << "  Precharge Idle Energy: "                                                               << nRanksDouble * energy.idle_energy_pre << eUnit
33111555Sjungma@eit.uni-kl.de       << endl << "  Precharged Power-Up Energy: "                                                          << nRanksDouble * energy.pup_pre_energy << eUnit
33211555Sjungma@eit.uni-kl.de       << endl << "    Precharge Stdby Energy during Auto-Refresh cycles in Self-Refresh Power-Up: "        << nRanksDouble * energy.spup_ref_pre_energy << eUnit
33311555Sjungma@eit.uni-kl.de       << endl << "  Self-Refresh Power-Up Energy: "                                                        << nRanksDouble * energy.spup_energy << eUnit
33411555Sjungma@eit.uni-kl.de       << endl << "Total Idle Energy (Active + Precharged): "                                               << nRanksDouble * (energy.idle_energy_act + energy.idle_energy_pre) << eUnit
33511555Sjungma@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
33611555Sjungma@eit.uni-kl.de       << endl << "  Fast-Exit Active Power-Down Energy: "                                                  << nRanksDouble * energy.f_act_pd_energy << eUnit
33711555Sjungma@eit.uni-kl.de       << endl << "  Slow-Exit Active Power-Down Energy: "                                                  << nRanksDouble * energy.s_act_pd_energy << eUnit
33811555Sjungma@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
33911555Sjungma@eit.uni-kl.de       << endl << "  Fast-Exit Precharged Power-Down Energy: "                                              << nRanksDouble * energy.f_pre_pd_energy << eUnit
34011555Sjungma@eit.uni-kl.de       << endl << "  Slow-Exit Precharged Power-Down Energy: "                                              << nRanksDouble * energy.s_pre_pd_energy << eUnit
34111555Sjungma@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
34211555Sjungma@eit.uni-kl.de       << endl << "Auto-Refresh Energy: "                                                                   << energy.ref_energy << eUnit
34311555Sjungma@eit.uni-kl.de       << endl << "Self-Refresh Energy: "                                                                   << nRanksDouble * energy.sref_energy << eUnit
34411555Sjungma@eit.uni-kl.de       << endl << "----------------------------------------"
34511555Sjungma@eit.uni-kl.de       << endl << "Total Trace Energy: "                                                                    << energy.total_energy << eUnit
34611555Sjungma@eit.uni-kl.de       << endl << "Average Power: "                                                                         << power.average_power << " mW"
34711555Sjungma@eit.uni-kl.de       << endl << "----------------------------------------" << endl;
34811555Sjungma@eit.uni-kl.de
34911555Sjungma@eit.uni-kl.de  cout.flags(flags);
35011555Sjungma@eit.uni-kl.de  cout.precision(precision);
35110428Sandreas.hansson@arm.com} // MemoryPowerModel::power_print
35210428Sandreas.hansson@arm.com
35310428Sandreas.hansson@arm.com// Self-refresh active energy estimation (not including background energy)
35410428Sandreas.hansson@arm.comdouble MemoryPowerModel::engy_sref(double idd6, double idd3n, double idd5,
35510428Sandreas.hansson@arm.com                                   double vdd, double sref_cycles, double sref_ref_act_cycles,
35610428Sandreas.hansson@arm.com                                   double sref_ref_pre_cycles, double spup_ref_act_cycles,
35710428Sandreas.hansson@arm.com                                   double spup_ref_pre_cycles, double clk)
35810428Sandreas.hansson@arm.com{
35910428Sandreas.hansson@arm.com  double sref_energy;
36010428Sandreas.hansson@arm.com
36110428Sandreas.hansson@arm.com  sref_energy = ((idd6 * sref_cycles) + ((idd5 - idd3n) * (sref_ref_act_cycles
36210428Sandreas.hansson@arm.com                                                           + spup_ref_act_cycles + sref_ref_pre_cycles + spup_ref_pre_cycles)))
36310428Sandreas.hansson@arm.com                * vdd * clk;
36410428Sandreas.hansson@arm.com  return sref_energy;
36510428Sandreas.hansson@arm.com}
36610428Sandreas.hansson@arm.com
36710428Sandreas.hansson@arm.com// IO and Termination power calculation based on Micron Power Calculators
36810428Sandreas.hansson@arm.com// Absolute power measures are obtained from Micron Power Calculator (mentioned in mW)
36911555Sjungma@eit.uni-kl.devoid MemoryPowerModel::io_term_power(const MemorySpecification& memSpec)
37010428Sandreas.hansson@arm.com{
37111555Sjungma@eit.uni-kl.de  const MemTimingSpec& memTimingSpec     = memSpec.memTimingSpec;
37211555Sjungma@eit.uni-kl.de  const MemArchitectureSpec& memArchSpec = memSpec.memArchSpec;
37311555Sjungma@eit.uni-kl.de  const MemPowerSpec&  memPowerSpec      = memSpec.memPowerSpec;
37410428Sandreas.hansson@arm.com
37510428Sandreas.hansson@arm.com  power.IO_power     = memPowerSpec.ioPower;    // in mW
37610428Sandreas.hansson@arm.com  power.WR_ODT_power = memPowerSpec.wrOdtPower; // in mW
37710428Sandreas.hansson@arm.com
37810428Sandreas.hansson@arm.com  if (memArchSpec.nbrOfRanks > 1) {
37910428Sandreas.hansson@arm.com    power.TermRD_power = memPowerSpec.termRdPower; // in mW
38010428Sandreas.hansson@arm.com    power.TermWR_power = memPowerSpec.termWrPower; // in mW
38110428Sandreas.hansson@arm.com  }
38210428Sandreas.hansson@arm.com
38310428Sandreas.hansson@arm.com  if (memPowerSpec.capacitance != 0.0) {
38410428Sandreas.hansson@arm.com    // If capacity is given, then IO Power depends on DRAM clock frequency.
38510428Sandreas.hansson@arm.com    power.IO_power = memPowerSpec.capacitance * 0.5 * pow(memPowerSpec.vdd2, 2.0) * memTimingSpec.clkMhz * 1000000;
38610428Sandreas.hansson@arm.com  }
38710428Sandreas.hansson@arm.com} // MemoryPowerModel::io_term_power
38810428Sandreas.hansson@arm.com
38910428Sandreas.hansson@arm.com
39010428Sandreas.hansson@arm.comdouble MemoryPowerModel::calcIoTermEnergy(int64_t cycles, double period, double power, int64_t numBits) const
39110428Sandreas.hansson@arm.com{
39210428Sandreas.hansson@arm.com  return static_cast<double>(cycles) * period * power * static_cast<double>(numBits);
39310428Sandreas.hansson@arm.com}
39410428Sandreas.hansson@arm.com
39510428Sandreas.hansson@arm.com// time (t) * current (I) * voltage (V) energy calculation
39610428Sandreas.hansson@arm.comdouble EnergyDomain::calcTivEnergy(int64_t cycles, double current) const
39710428Sandreas.hansson@arm.com{
39810428Sandreas.hansson@arm.com  return static_cast<double>(cycles) * clkPeriod * current * voltage;
39910428Sandreas.hansson@arm.com}
400