MemoryPowerModel.cc revision 10428
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 4010428Sandreas.hansson@arm.com#include <cmath> // For pow 4110428Sandreas.hansson@arm.com 4210428Sandreas.hansson@arm.com#include <stdint.h> 4310428Sandreas.hansson@arm.com 4410428Sandreas.hansson@arm.com 4510428Sandreas.hansson@arm.comusing namespace std; 4610428Sandreas.hansson@arm.comusing namespace Data; 4710428Sandreas.hansson@arm.com 4810428Sandreas.hansson@arm.com// Calculate energy and average power consumption for the given command trace 4910428Sandreas.hansson@arm.com 5010428Sandreas.hansson@arm.comvoid MemoryPowerModel::power_calc(MemorySpecification memSpec, 5110428Sandreas.hansson@arm.com const CommandAnalysis& counters, 5210428Sandreas.hansson@arm.com int term) 5310428Sandreas.hansson@arm.com{ 5410428Sandreas.hansson@arm.com MemTimingSpec& t = memSpec.memTimingSpec; 5510428Sandreas.hansson@arm.com MemArchitectureSpec& memArchSpec = memSpec.memArchSpec; 5610428Sandreas.hansson@arm.com MemPowerSpec& mps = memSpec.memPowerSpec; 5710428Sandreas.hansson@arm.com 5810428Sandreas.hansson@arm.com energy.act_energy = 0.0; 5910428Sandreas.hansson@arm.com energy.pre_energy = 0.0; 6010428Sandreas.hansson@arm.com energy.read_energy = 0.0; 6110428Sandreas.hansson@arm.com energy.write_energy = 0.0; 6210428Sandreas.hansson@arm.com energy.ref_energy = 0.0; 6310428Sandreas.hansson@arm.com energy.act_stdby_energy = 0.0; 6410428Sandreas.hansson@arm.com energy.pre_stdby_energy = 0.0; 6510428Sandreas.hansson@arm.com energy.idle_energy_act = 0.0; 6610428Sandreas.hansson@arm.com energy.idle_energy_pre = 0.0; 6710428Sandreas.hansson@arm.com energy.total_energy = 0.0; 6810428Sandreas.hansson@arm.com energy.f_act_pd_energy = 0.0; 6910428Sandreas.hansson@arm.com energy.f_pre_pd_energy = 0.0; 7010428Sandreas.hansson@arm.com energy.s_act_pd_energy = 0.0; 7110428Sandreas.hansson@arm.com energy.s_pre_pd_energy = 0.0; 7210428Sandreas.hansson@arm.com energy.sref_energy = 0.0; 7310428Sandreas.hansson@arm.com energy.sref_ref_energy = 0.0; 7410428Sandreas.hansson@arm.com energy.sref_ref_act_energy = 0.0; 7510428Sandreas.hansson@arm.com energy.sref_ref_pre_energy = 0.0; 7610428Sandreas.hansson@arm.com energy.spup_energy = 0.0; 7710428Sandreas.hansson@arm.com energy.spup_ref_energy = 0.0; 7810428Sandreas.hansson@arm.com energy.spup_ref_act_energy = 0.0; 7910428Sandreas.hansson@arm.com energy.spup_ref_pre_energy = 0.0; 8010428Sandreas.hansson@arm.com energy.pup_act_energy = 0.0; 8110428Sandreas.hansson@arm.com energy.pup_pre_energy = 0.0; 8210428Sandreas.hansson@arm.com power.IO_power = 0.0; 8310428Sandreas.hansson@arm.com power.WR_ODT_power = 0.0; 8410428Sandreas.hansson@arm.com power.TermRD_power = 0.0; 8510428Sandreas.hansson@arm.com power.TermWR_power = 0.0; 8610428Sandreas.hansson@arm.com energy.read_io_energy = 0.0; 8710428Sandreas.hansson@arm.com energy.write_term_energy = 0.0; 8810428Sandreas.hansson@arm.com energy.read_oterm_energy = 0.0; 8910428Sandreas.hansson@arm.com energy.write_oterm_energy = 0.0; 9010428Sandreas.hansson@arm.com energy.io_term_energy = 0.0; 9110428Sandreas.hansson@arm.com 9210428Sandreas.hansson@arm.com // How long a single burst takes, measured in command-clock cycles. 9310428Sandreas.hansson@arm.com int64_t burstCc = memArchSpec.burstLength / memArchSpec.dataRate; 9410428Sandreas.hansson@arm.com 9510428Sandreas.hansson@arm.com // IO and Termination Power measures are included, if required. 9610428Sandreas.hansson@arm.com if (term) { 9710428Sandreas.hansson@arm.com io_term_power(memSpec); 9810428Sandreas.hansson@arm.com 9910428Sandreas.hansson@arm.com // memArchSpec.width represents the number of data (dq) pins. 10010428Sandreas.hansson@arm.com // 1 DQS pin is associated with every data byte 10110428Sandreas.hansson@arm.com int64_t dqPlusDqsBits = memArchSpec.width + memArchSpec.width / 8; 10210428Sandreas.hansson@arm.com // 1 DQS and 1 DM pin is associated with every data byte 10310428Sandreas.hansson@arm.com int64_t dqPlusDqsPlusMaskBits = memArchSpec.width + memArchSpec.width / 8 + memArchSpec.width / 8; 10410428Sandreas.hansson@arm.com // Size of one clock period for the data bus. 10510428Sandreas.hansson@arm.com double ddrPeriod = t.clkPeriod / memArchSpec.dataRate; 10610428Sandreas.hansson@arm.com 10710428Sandreas.hansson@arm.com // Read IO power is consumed by each DQ (data) and DQS (data strobe) pin 10810428Sandreas.hansson@arm.com energy.read_io_energy = calcIoTermEnergy(counters.numberofreads * memArchSpec.burstLength, 10910428Sandreas.hansson@arm.com ddrPeriod, 11010428Sandreas.hansson@arm.com power.IO_power, 11110428Sandreas.hansson@arm.com dqPlusDqsBits); 11210428Sandreas.hansson@arm.com 11310428Sandreas.hansson@arm.com // Write ODT power is consumed by each DQ (data), DQS (data strobe) and DM 11410428Sandreas.hansson@arm.com energy.write_term_energy = calcIoTermEnergy(counters.numberofwrites * memArchSpec.burstLength, 11510428Sandreas.hansson@arm.com ddrPeriod, 11610428Sandreas.hansson@arm.com power.WR_ODT_power, 11710428Sandreas.hansson@arm.com dqPlusDqsPlusMaskBits); 11810428Sandreas.hansson@arm.com 11910428Sandreas.hansson@arm.com if (memArchSpec.nbrOfRanks > 1) { 12010428Sandreas.hansson@arm.com // Termination power consumed in the idle rank during reads on the active 12110428Sandreas.hansson@arm.com // rank by each DQ (data) and DQS (data strobe) pin. 12210428Sandreas.hansson@arm.com energy.read_oterm_energy = calcIoTermEnergy(counters.numberofreads * memArchSpec.burstLength, 12310428Sandreas.hansson@arm.com ddrPeriod, 12410428Sandreas.hansson@arm.com power.TermRD_power, 12510428Sandreas.hansson@arm.com dqPlusDqsBits); 12610428Sandreas.hansson@arm.com 12710428Sandreas.hansson@arm.com // Termination power consumed in the idle rank during writes on the active 12810428Sandreas.hansson@arm.com // rank by each DQ (data), DQS (data strobe) and DM (data mask) pin. 12910428Sandreas.hansson@arm.com energy.write_oterm_energy = calcIoTermEnergy(counters.numberofwrites * memArchSpec.burstLength, 13010428Sandreas.hansson@arm.com ddrPeriod, 13110428Sandreas.hansson@arm.com power.TermWR_power, 13210428Sandreas.hansson@arm.com dqPlusDqsPlusMaskBits); 13310428Sandreas.hansson@arm.com } 13410428Sandreas.hansson@arm.com 13510428Sandreas.hansson@arm.com // Sum of all IO and termination energy 13610428Sandreas.hansson@arm.com energy.io_term_energy = energy.read_io_energy + energy.write_term_energy 13710428Sandreas.hansson@arm.com + energy.read_oterm_energy + energy.write_oterm_energy; 13810428Sandreas.hansson@arm.com } 13910428Sandreas.hansson@arm.com 14010428Sandreas.hansson@arm.com total_cycles = counters.actcycles + counters.precycles + 14110428Sandreas.hansson@arm.com counters.f_act_pdcycles + counters.f_pre_pdcycles + 14210428Sandreas.hansson@arm.com counters.s_act_pdcycles + counters.s_pre_pdcycles + counters.sref_cycles 14310428Sandreas.hansson@arm.com + counters.sref_ref_act_cycles + counters.sref_ref_pre_cycles + 14410428Sandreas.hansson@arm.com counters.spup_ref_act_cycles + counters.spup_ref_pre_cycles; 14510428Sandreas.hansson@arm.com 14610428Sandreas.hansson@arm.com EnergyDomain vdd0Domain(mps.vdd, t.clkPeriod); 14710428Sandreas.hansson@arm.com 14810428Sandreas.hansson@arm.com energy.act_energy = vdd0Domain.calcTivEnergy(counters.numberofacts * t.RAS , mps.idd0 - mps.idd3n); 14910428Sandreas.hansson@arm.com energy.pre_energy = vdd0Domain.calcTivEnergy(counters.numberofpres * (t.RC - t.RAS) , mps.idd0 - mps.idd2n); 15010428Sandreas.hansson@arm.com energy.read_energy = vdd0Domain.calcTivEnergy(counters.numberofreads * burstCc , mps.idd4r - mps.idd3n); 15110428Sandreas.hansson@arm.com energy.write_energy = vdd0Domain.calcTivEnergy(counters.numberofwrites * burstCc , mps.idd4w - mps.idd3n); 15210428Sandreas.hansson@arm.com energy.ref_energy = vdd0Domain.calcTivEnergy(counters.numberofrefs * t.RFC , mps.idd5 - mps.idd3n); 15310428Sandreas.hansson@arm.com energy.pre_stdby_energy = vdd0Domain.calcTivEnergy(counters.precycles, mps.idd2n); 15410428Sandreas.hansson@arm.com energy.act_stdby_energy = vdd0Domain.calcTivEnergy(counters.actcycles, mps.idd3n); 15510428Sandreas.hansson@arm.com // Idle energy in the active standby clock cycles 15610428Sandreas.hansson@arm.com energy.idle_energy_act = vdd0Domain.calcTivEnergy(counters.idlecycles_act, mps.idd3n); 15710428Sandreas.hansson@arm.com // Idle energy in the precharge standby clock cycles 15810428Sandreas.hansson@arm.com energy.idle_energy_pre = vdd0Domain.calcTivEnergy(counters.idlecycles_pre, mps.idd2n); 15910428Sandreas.hansson@arm.com // fast-exit active power-down cycles energy 16010428Sandreas.hansson@arm.com energy.f_act_pd_energy = vdd0Domain.calcTivEnergy(counters.f_act_pdcycles, mps.idd3p1); 16110428Sandreas.hansson@arm.com // fast-exit precharged power-down cycles energy 16210428Sandreas.hansson@arm.com energy.f_pre_pd_energy = vdd0Domain.calcTivEnergy(counters.f_pre_pdcycles, mps.idd2p1); 16310428Sandreas.hansson@arm.com // slow-exit active power-down cycles energy 16410428Sandreas.hansson@arm.com energy.s_act_pd_energy = vdd0Domain.calcTivEnergy(counters.s_act_pdcycles, mps.idd3p0); 16510428Sandreas.hansson@arm.com // slow-exit precharged power-down cycles energy 16610428Sandreas.hansson@arm.com energy.s_pre_pd_energy = vdd0Domain.calcTivEnergy(counters.s_pre_pdcycles, mps.idd2p0); 16710428Sandreas.hansson@arm.com 16810428Sandreas.hansson@arm.com // self-refresh cycles energy including a refresh per self-refresh entry 16910428Sandreas.hansson@arm.com energy.sref_energy = engy_sref(mps.idd6, mps.idd3n, 17010428Sandreas.hansson@arm.com mps.idd5, mps.vdd, 17110428Sandreas.hansson@arm.com static_cast<double>(counters.sref_cycles), static_cast<double>(counters.sref_ref_act_cycles), 17210428Sandreas.hansson@arm.com static_cast<double>(counters.sref_ref_pre_cycles), static_cast<double>(counters.spup_ref_act_cycles), 17310428Sandreas.hansson@arm.com static_cast<double>(counters.spup_ref_pre_cycles), t.clkPeriod); 17410428Sandreas.hansson@arm.com 17510428Sandreas.hansson@arm.com // background energy during active auto-refresh cycles in self-refresh 17610428Sandreas.hansson@arm.com energy.sref_ref_act_energy = vdd0Domain.calcTivEnergy(counters.sref_ref_act_cycles, mps.idd3p0); 17710428Sandreas.hansson@arm.com // background energy during precharged auto-refresh cycles in self-refresh 17810428Sandreas.hansson@arm.com energy.sref_ref_pre_energy = vdd0Domain.calcTivEnergy(counters.sref_ref_pre_cycles, mps.idd2p0); 17910428Sandreas.hansson@arm.com // background energy during active auto-refresh cycles in self-refresh exit 18010428Sandreas.hansson@arm.com energy.spup_ref_act_energy = vdd0Domain.calcTivEnergy(counters.spup_ref_act_cycles, mps.idd3n); 18110428Sandreas.hansson@arm.com // background energy during precharged auto-refresh cycles in self-refresh exit 18210428Sandreas.hansson@arm.com energy.spup_ref_pre_energy = vdd0Domain.calcTivEnergy(counters.spup_ref_pre_cycles, mps.idd2n); 18310428Sandreas.hansson@arm.com // self-refresh power-up cycles energy -- included 18410428Sandreas.hansson@arm.com energy.spup_energy = vdd0Domain.calcTivEnergy(counters.spup_cycles, mps.idd2n); 18510428Sandreas.hansson@arm.com // active power-up cycles energy - same as active standby -- included 18610428Sandreas.hansson@arm.com energy.pup_act_energy = vdd0Domain.calcTivEnergy(counters.pup_act_cycles, mps.idd3n); 18710428Sandreas.hansson@arm.com // precharged power-up cycles energy - same as precharged standby -- included 18810428Sandreas.hansson@arm.com energy.pup_pre_energy = vdd0Domain.calcTivEnergy(counters.pup_pre_cycles, mps.idd2n); 18910428Sandreas.hansson@arm.com 19010428Sandreas.hansson@arm.com // similar equations as before to support multiple voltage domains in LPDDR2 19110428Sandreas.hansson@arm.com // and WIDEIO memories 19210428Sandreas.hansson@arm.com if (memArchSpec.twoVoltageDomains) { 19310428Sandreas.hansson@arm.com EnergyDomain vdd2Domain(mps.vdd2, t.clkPeriod); 19410428Sandreas.hansson@arm.com 19510428Sandreas.hansson@arm.com energy.act_energy += vdd2Domain.calcTivEnergy(counters.numberofacts * t.RAS , mps.idd02 - mps.idd3n2); 19610428Sandreas.hansson@arm.com energy.pre_energy += vdd2Domain.calcTivEnergy(counters.numberofpres * (t.RC - t.RAS) , mps.idd02 - mps.idd2n2); 19710428Sandreas.hansson@arm.com energy.read_energy += vdd2Domain.calcTivEnergy(counters.numberofreads * burstCc , mps.idd4r2 - mps.idd3n2); 19810428Sandreas.hansson@arm.com energy.write_energy += vdd2Domain.calcTivEnergy(counters.numberofwrites * burstCc , mps.idd4w2 - mps.idd3n2); 19910428Sandreas.hansson@arm.com energy.ref_energy += vdd2Domain.calcTivEnergy(counters.numberofrefs * t.RFC , mps.idd52 - mps.idd3n2); 20010428Sandreas.hansson@arm.com energy.pre_stdby_energy += vdd2Domain.calcTivEnergy(counters.precycles, mps.idd2n2); 20110428Sandreas.hansson@arm.com energy.act_stdby_energy += vdd2Domain.calcTivEnergy(counters.actcycles, mps.idd3n2); 20210428Sandreas.hansson@arm.com // Idle energy in the active standby clock cycles 20310428Sandreas.hansson@arm.com energy.idle_energy_act += vdd2Domain.calcTivEnergy(counters.idlecycles_act, mps.idd3n2); 20410428Sandreas.hansson@arm.com // Idle energy in the precharge standby clock cycles 20510428Sandreas.hansson@arm.com energy.idle_energy_pre += vdd2Domain.calcTivEnergy(counters.idlecycles_pre, mps.idd2n2); 20610428Sandreas.hansson@arm.com // fast-exit active power-down cycles energy 20710428Sandreas.hansson@arm.com energy.f_act_pd_energy += vdd2Domain.calcTivEnergy(counters.f_act_pdcycles, mps.idd3p12); 20810428Sandreas.hansson@arm.com // fast-exit precharged power-down cycles energy 20910428Sandreas.hansson@arm.com energy.f_pre_pd_energy += vdd2Domain.calcTivEnergy(counters.f_pre_pdcycles, mps.idd2p12); 21010428Sandreas.hansson@arm.com // slow-exit active power-down cycles energy 21110428Sandreas.hansson@arm.com energy.s_act_pd_energy += vdd2Domain.calcTivEnergy(counters.s_act_pdcycles, mps.idd3p02); 21210428Sandreas.hansson@arm.com // slow-exit precharged power-down cycles energy 21310428Sandreas.hansson@arm.com energy.s_pre_pd_energy += vdd2Domain.calcTivEnergy(counters.s_pre_pdcycles, mps.idd2p02); 21410428Sandreas.hansson@arm.com 21510428Sandreas.hansson@arm.com energy.sref_energy += engy_sref(mps.idd62, mps.idd3n2, 21610428Sandreas.hansson@arm.com mps.idd52, mps.vdd2, 21710428Sandreas.hansson@arm.com static_cast<double>(counters.sref_cycles), static_cast<double>(counters.sref_ref_act_cycles), 21810428Sandreas.hansson@arm.com static_cast<double>(counters.sref_ref_pre_cycles), static_cast<double>(counters.spup_ref_act_cycles), 21910428Sandreas.hansson@arm.com static_cast<double>(counters.spup_ref_pre_cycles), t.clkPeriod); 22010428Sandreas.hansson@arm.com 22110428Sandreas.hansson@arm.com // background energy during active auto-refresh cycles in self-refresh 22210428Sandreas.hansson@arm.com energy.sref_ref_act_energy += vdd2Domain.calcTivEnergy(counters.sref_ref_act_cycles, mps.idd3p02); 22310428Sandreas.hansson@arm.com // background energy during precharged auto-refresh cycles in self-refresh 22410428Sandreas.hansson@arm.com energy.sref_ref_pre_energy += vdd2Domain.calcTivEnergy(counters.sref_ref_pre_cycles, mps.idd2p02); 22510428Sandreas.hansson@arm.com // background energy during active auto-refresh cycles in self-refresh exit 22610428Sandreas.hansson@arm.com energy.spup_ref_act_energy += vdd2Domain.calcTivEnergy(counters.spup_ref_act_cycles, mps.idd3n2); 22710428Sandreas.hansson@arm.com // background energy during precharged auto-refresh cycles in self-refresh exit 22810428Sandreas.hansson@arm.com energy.spup_ref_pre_energy += vdd2Domain.calcTivEnergy(counters.spup_ref_pre_cycles, mps.idd2n2); 22910428Sandreas.hansson@arm.com // self-refresh power-up cycles energy -- included 23010428Sandreas.hansson@arm.com energy.spup_energy += vdd2Domain.calcTivEnergy(counters.spup_cycles, mps.idd2n2); 23110428Sandreas.hansson@arm.com // active power-up cycles energy - same as active standby -- included 23210428Sandreas.hansson@arm.com energy.pup_act_energy += vdd2Domain.calcTivEnergy(counters.pup_act_cycles, mps.idd3n2); 23310428Sandreas.hansson@arm.com // precharged power-up cycles energy - same as precharged standby -- included 23410428Sandreas.hansson@arm.com energy.pup_pre_energy += vdd2Domain.calcTivEnergy(counters.pup_pre_cycles, mps.idd2n2); 23510428Sandreas.hansson@arm.com } 23610428Sandreas.hansson@arm.com 23710428Sandreas.hansson@arm.com // auto-refresh energy during self-refresh cycles 23810428Sandreas.hansson@arm.com energy.sref_ref_energy = energy.sref_ref_act_energy + energy.sref_ref_pre_energy; 23910428Sandreas.hansson@arm.com 24010428Sandreas.hansson@arm.com // auto-refresh energy during self-refresh exit cycles 24110428Sandreas.hansson@arm.com energy.spup_ref_energy = energy.spup_ref_act_energy + energy.spup_ref_pre_energy; 24210428Sandreas.hansson@arm.com 24310428Sandreas.hansson@arm.com // adding all energy components for the active rank and all background and idle 24410428Sandreas.hansson@arm.com // energy components for both ranks (in a dual-rank system) 24510428Sandreas.hansson@arm.com energy.total_energy = energy.act_energy + energy.pre_energy + energy.read_energy + 24610428Sandreas.hansson@arm.com energy.write_energy + energy.ref_energy + energy.io_term_energy + 24710428Sandreas.hansson@arm.com memArchSpec.nbrOfRanks * (energy.act_stdby_energy + 24810428Sandreas.hansson@arm.com energy.pre_stdby_energy + energy.sref_energy + 24910428Sandreas.hansson@arm.com energy.f_act_pd_energy + energy.f_pre_pd_energy + energy.s_act_pd_energy 25010428Sandreas.hansson@arm.com + energy.s_pre_pd_energy + energy.sref_ref_energy + energy.spup_ref_energy); 25110428Sandreas.hansson@arm.com 25210428Sandreas.hansson@arm.com // Calculate the average power consumption 25310428Sandreas.hansson@arm.com power.average_power = energy.total_energy / (static_cast<double>(total_cycles) * t.clkPeriod); 25410428Sandreas.hansson@arm.com} // MemoryPowerModel::power_calc 25510428Sandreas.hansson@arm.com 25610428Sandreas.hansson@arm.comvoid MemoryPowerModel::power_print(MemorySpecification memSpec, int term, const CommandAnalysis& counters) const 25710428Sandreas.hansson@arm.com{ 25810428Sandreas.hansson@arm.com MemTimingSpec& memTimingSpec = memSpec.memTimingSpec; 25910428Sandreas.hansson@arm.com MemArchitectureSpec& memArchSpec = memSpec.memArchSpec; 26010428Sandreas.hansson@arm.com 26110428Sandreas.hansson@arm.com cout.precision(0); 26210428Sandreas.hansson@arm.com cout << "* Trace Details:" << endl; 26310428Sandreas.hansson@arm.com cout << "Number of Activates: " << fixed << counters.numberofacts << endl; 26410428Sandreas.hansson@arm.com cout << "Number of Reads: " << counters.numberofreads << endl; 26510428Sandreas.hansson@arm.com cout << "Number of Writes: " << counters.numberofwrites << endl; 26610428Sandreas.hansson@arm.com cout << "Number of Precharges: " << counters.numberofpres << endl; 26710428Sandreas.hansson@arm.com cout << "Number of Refreshes: " << counters.numberofrefs << endl; 26810428Sandreas.hansson@arm.com cout << "Number of Active Cycles: " << counters.actcycles << endl; 26910428Sandreas.hansson@arm.com cout << " Number of Active Idle Cycles: " << counters.idlecycles_act << endl; 27010428Sandreas.hansson@arm.com cout << " Number of Active Power-Up Cycles: " << counters.pup_act_cycles << endl; 27110428Sandreas.hansson@arm.com cout << " Number of Auto-Refresh Active cycles during Self-Refresh " << 27210428Sandreas.hansson@arm.com "Power-Up: " << counters.spup_ref_act_cycles << endl; 27310428Sandreas.hansson@arm.com cout << "Number of Precharged Cycles: " << counters.precycles << endl; 27410428Sandreas.hansson@arm.com cout << " Number of Precharged Idle Cycles: " << counters.idlecycles_pre << endl; 27510428Sandreas.hansson@arm.com cout << " Number of Precharged Power-Up Cycles: " << counters.pup_pre_cycles 27610428Sandreas.hansson@arm.com << endl; 27710428Sandreas.hansson@arm.com cout << " Number of Auto-Refresh Precharged cycles during Self-Refresh" 27810428Sandreas.hansson@arm.com << " Power-Up: " << counters.spup_ref_pre_cycles << endl; 27910428Sandreas.hansson@arm.com cout << " Number of Self-Refresh Power-Up Cycles: " << counters.spup_cycles 28010428Sandreas.hansson@arm.com << endl; 28110428Sandreas.hansson@arm.com cout << "Total Idle Cycles (Active + Precharged): " << 28210428Sandreas.hansson@arm.com counters.idlecycles_act + counters.idlecycles_pre << endl; 28310428Sandreas.hansson@arm.com cout << "Number of Power-Downs: " << counters.f_act_pdns + 28410428Sandreas.hansson@arm.com counters.s_act_pdns + counters.f_pre_pdns + counters.s_pre_pdns << endl; 28510428Sandreas.hansson@arm.com cout << " Number of Active Fast-exit Power-Downs: " << counters.f_act_pdns 28610428Sandreas.hansson@arm.com << endl; 28710428Sandreas.hansson@arm.com cout << " Number of Active Slow-exit Power-Downs: " << counters.s_act_pdns 28810428Sandreas.hansson@arm.com << endl; 28910428Sandreas.hansson@arm.com cout << " Number of Precharged Fast-exit Power-Downs: " << 29010428Sandreas.hansson@arm.com counters.f_pre_pdns << endl; 29110428Sandreas.hansson@arm.com cout << " Number of Precharged Slow-exit Power-Downs: " << 29210428Sandreas.hansson@arm.com counters.s_pre_pdns << endl; 29310428Sandreas.hansson@arm.com cout << "Number of Power-Down Cycles: " << counters.f_act_pdcycles + 29410428Sandreas.hansson@arm.com counters.s_act_pdcycles + counters.f_pre_pdcycles + counters.s_pre_pdcycles << endl; 29510428Sandreas.hansson@arm.com cout << " Number of Active Fast-exit Power-Down Cycles: " << 29610428Sandreas.hansson@arm.com counters.f_act_pdcycles << endl; 29710428Sandreas.hansson@arm.com cout << " Number of Active Slow-exit Power-Down Cycles: " << 29810428Sandreas.hansson@arm.com counters.s_act_pdcycles << endl; 29910428Sandreas.hansson@arm.com cout << " Number of Auto-Refresh Active cycles during Self-Refresh: " << 30010428Sandreas.hansson@arm.com counters.sref_ref_act_cycles << endl; 30110428Sandreas.hansson@arm.com cout << " Number of Precharged Fast-exit Power-Down Cycles: " << 30210428Sandreas.hansson@arm.com counters.f_pre_pdcycles << endl; 30310428Sandreas.hansson@arm.com cout << " Number of Precharged Slow-exit Power-Down Cycles: " << 30410428Sandreas.hansson@arm.com counters.s_pre_pdcycles << endl; 30510428Sandreas.hansson@arm.com cout << " Number of Auto-Refresh Precharged cycles during Self-Refresh: " << 30610428Sandreas.hansson@arm.com counters.sref_ref_pre_cycles << endl; 30710428Sandreas.hansson@arm.com cout << "Number of Auto-Refresh Cycles: " << counters.numberofrefs * 30810428Sandreas.hansson@arm.com memTimingSpec.RFC << endl; 30910428Sandreas.hansson@arm.com cout << "Number of Self-Refreshes: " << counters.numberofsrefs << endl; 31010428Sandreas.hansson@arm.com cout << "Number of Self-Refresh Cycles: " << counters.sref_cycles << endl; 31110428Sandreas.hansson@arm.com cout << "----------------------------------------" << endl; 31210428Sandreas.hansson@arm.com cout << "Total Trace Length (clock cycles): " << total_cycles << endl; 31310428Sandreas.hansson@arm.com cout << "----------------------------------------" << endl; 31410428Sandreas.hansson@arm.com cout.precision(2); 31510428Sandreas.hansson@arm.com 31610428Sandreas.hansson@arm.com cout << "\n* Trace Power and Energy Estimates:" << endl; 31710428Sandreas.hansson@arm.com cout << "ACT Cmd Energy: " << energy.act_energy << " pJ" << endl; 31810428Sandreas.hansson@arm.com cout << "PRE Cmd Energy: " << energy.pre_energy << " pJ" << endl; 31910428Sandreas.hansson@arm.com cout << "RD Cmd Energy: " << energy.read_energy << " pJ" << endl; 32010428Sandreas.hansson@arm.com cout << "WR Cmd Energy: " << energy.write_energy << " pJ" << endl; 32110428Sandreas.hansson@arm.com if (term) { 32210428Sandreas.hansson@arm.com cout << "RD I/O Energy: " << energy.read_io_energy << " pJ" << endl; 32310428Sandreas.hansson@arm.com // No Termination for LPDDR/2/3 and DDR memories 32410428Sandreas.hansson@arm.com if (memSpec.memArchSpec.termination) { 32510428Sandreas.hansson@arm.com cout << "WR Termination Energy: " << energy.write_term_energy << " pJ" << endl; 32610428Sandreas.hansson@arm.com } 32710428Sandreas.hansson@arm.com 32810428Sandreas.hansson@arm.com if ((memArchSpec.nbrOfRanks > 1) && memSpec.memArchSpec.termination) { 32910428Sandreas.hansson@arm.com cout << "RD Termination Energy (Idle rank): " << energy.read_oterm_energy 33010428Sandreas.hansson@arm.com << " pJ" << endl; 33110428Sandreas.hansson@arm.com cout << "WR Termination Energy (Idle rank): " << energy.write_oterm_energy 33210428Sandreas.hansson@arm.com << " pJ" << endl; 33310428Sandreas.hansson@arm.com } 33410428Sandreas.hansson@arm.com } 33510428Sandreas.hansson@arm.com cout << "ACT Stdby Energy: " << memArchSpec.nbrOfRanks * energy.act_stdby_energy << 33610428Sandreas.hansson@arm.com " pJ" << endl; 33710428Sandreas.hansson@arm.com cout << " Active Idle Energy: " << memArchSpec.nbrOfRanks * energy.idle_energy_act << 33810428Sandreas.hansson@arm.com " pJ" << endl; 33910428Sandreas.hansson@arm.com cout << " Active Power-Up Energy: " << memArchSpec.nbrOfRanks * energy.pup_act_energy << 34010428Sandreas.hansson@arm.com " pJ" << endl; 34110428Sandreas.hansson@arm.com cout << " Active Stdby Energy during Auto-Refresh cycles in Self-Refresh" 34210428Sandreas.hansson@arm.com << " Power-Up: " << memArchSpec.nbrOfRanks * energy.spup_ref_act_energy << 34310428Sandreas.hansson@arm.com " pJ" << endl; 34410428Sandreas.hansson@arm.com cout << "PRE Stdby Energy: " << memArchSpec.nbrOfRanks * energy.pre_stdby_energy << 34510428Sandreas.hansson@arm.com " pJ" << endl; 34610428Sandreas.hansson@arm.com cout << " Precharge Idle Energy: " << memArchSpec.nbrOfRanks * energy.idle_energy_pre << 34710428Sandreas.hansson@arm.com " pJ" << endl; 34810428Sandreas.hansson@arm.com cout << " Precharged Power-Up Energy: " << memArchSpec.nbrOfRanks * energy.pup_pre_energy << 34910428Sandreas.hansson@arm.com " pJ" << endl; 35010428Sandreas.hansson@arm.com cout << " Precharge Stdby Energy during Auto-Refresh cycles " << 35110428Sandreas.hansson@arm.com "in Self-Refresh Power-Up: " << memArchSpec.nbrOfRanks * energy.spup_ref_pre_energy << 35210428Sandreas.hansson@arm.com " pJ" << endl; 35310428Sandreas.hansson@arm.com cout << " Self-Refresh Power-Up Energy: " << memArchSpec.nbrOfRanks * energy.spup_energy << 35410428Sandreas.hansson@arm.com " pJ" << endl; 35510428Sandreas.hansson@arm.com cout << "Total Idle Energy (Active + Precharged): " << memArchSpec.nbrOfRanks * 35610428Sandreas.hansson@arm.com (energy.idle_energy_act + energy.idle_energy_pre) << " pJ" << endl; 35710428Sandreas.hansson@arm.com cout << "Total Power-Down Energy: " << memArchSpec.nbrOfRanks * (energy.f_act_pd_energy + 35810428Sandreas.hansson@arm.com energy.f_pre_pd_energy + energy.s_act_pd_energy + energy.s_pre_pd_energy) << " pJ" << endl; 35910428Sandreas.hansson@arm.com cout << " Fast-Exit Active Power-Down Energy: " << memArchSpec.nbrOfRanks * 36010428Sandreas.hansson@arm.com energy.f_act_pd_energy << " pJ" << endl; 36110428Sandreas.hansson@arm.com cout << " Slow-Exit Active Power-Down Energy: " << memArchSpec.nbrOfRanks * 36210428Sandreas.hansson@arm.com energy.s_act_pd_energy << " pJ" << endl; 36310428Sandreas.hansson@arm.com cout << " Slow-Exit Active Power-Down Energy during Auto-Refresh cycles " 36410428Sandreas.hansson@arm.com << "in Self-Refresh: " << memArchSpec.nbrOfRanks * energy.sref_ref_act_energy << 36510428Sandreas.hansson@arm.com " pJ" << endl; 36610428Sandreas.hansson@arm.com cout << " Fast-Exit Precharged Power-Down Energy: " << memArchSpec.nbrOfRanks * 36710428Sandreas.hansson@arm.com energy.f_pre_pd_energy << " pJ" << endl; 36810428Sandreas.hansson@arm.com cout << " Slow-Exit Precharged Power-Down Energy: " << memArchSpec.nbrOfRanks * 36910428Sandreas.hansson@arm.com energy.s_pre_pd_energy << " pJ" << endl; 37010428Sandreas.hansson@arm.com cout << " Slow-Exit Precharged Power-Down Energy during Auto-Refresh " << 37110428Sandreas.hansson@arm.com "cycles in Self-Refresh: " << memArchSpec.nbrOfRanks * energy.sref_ref_pre_energy << 37210428Sandreas.hansson@arm.com " pJ" << endl; 37310428Sandreas.hansson@arm.com cout << "Auto-Refresh Energy: " << energy.ref_energy << " pJ" << endl; 37410428Sandreas.hansson@arm.com cout << "Self-Refresh Energy: " << memArchSpec.nbrOfRanks * energy.sref_energy << 37510428Sandreas.hansson@arm.com " pJ" << endl; 37610428Sandreas.hansson@arm.com cout << "----------------------------------------" << endl; 37710428Sandreas.hansson@arm.com cout << "Total Trace Energy: " << energy.total_energy << " pJ" << endl; 37810428Sandreas.hansson@arm.com cout << "Average Power: " << power.average_power << " mW" << endl; 37910428Sandreas.hansson@arm.com cout << "----------------------------------------" << endl; 38010428Sandreas.hansson@arm.com} // MemoryPowerModel::power_print 38110428Sandreas.hansson@arm.com 38210428Sandreas.hansson@arm.com// Self-refresh active energy estimation (not including background energy) 38310428Sandreas.hansson@arm.comdouble MemoryPowerModel::engy_sref(double idd6, double idd3n, double idd5, 38410428Sandreas.hansson@arm.com double vdd, double sref_cycles, double sref_ref_act_cycles, 38510428Sandreas.hansson@arm.com double sref_ref_pre_cycles, double spup_ref_act_cycles, 38610428Sandreas.hansson@arm.com double spup_ref_pre_cycles, double clk) 38710428Sandreas.hansson@arm.com{ 38810428Sandreas.hansson@arm.com double sref_energy; 38910428Sandreas.hansson@arm.com 39010428Sandreas.hansson@arm.com sref_energy = ((idd6 * sref_cycles) + ((idd5 - idd3n) * (sref_ref_act_cycles 39110428Sandreas.hansson@arm.com + spup_ref_act_cycles + sref_ref_pre_cycles + spup_ref_pre_cycles))) 39210428Sandreas.hansson@arm.com * vdd * clk; 39310428Sandreas.hansson@arm.com return sref_energy; 39410428Sandreas.hansson@arm.com} 39510428Sandreas.hansson@arm.com 39610428Sandreas.hansson@arm.com// IO and Termination power calculation based on Micron Power Calculators 39710428Sandreas.hansson@arm.com// Absolute power measures are obtained from Micron Power Calculator (mentioned in mW) 39810428Sandreas.hansson@arm.comvoid MemoryPowerModel::io_term_power(MemorySpecification memSpec) 39910428Sandreas.hansson@arm.com{ 40010428Sandreas.hansson@arm.com MemTimingSpec& memTimingSpec = memSpec.memTimingSpec; 40110428Sandreas.hansson@arm.com MemArchitectureSpec& memArchSpec = memSpec.memArchSpec; 40210428Sandreas.hansson@arm.com MemPowerSpec& memPowerSpec = memSpec.memPowerSpec; 40310428Sandreas.hansson@arm.com 40410428Sandreas.hansson@arm.com power.IO_power = memPowerSpec.ioPower; // in mW 40510428Sandreas.hansson@arm.com power.WR_ODT_power = memPowerSpec.wrOdtPower; // in mW 40610428Sandreas.hansson@arm.com 40710428Sandreas.hansson@arm.com if (memArchSpec.nbrOfRanks > 1) { 40810428Sandreas.hansson@arm.com power.TermRD_power = memPowerSpec.termRdPower; // in mW 40910428Sandreas.hansson@arm.com power.TermWR_power = memPowerSpec.termWrPower; // in mW 41010428Sandreas.hansson@arm.com } 41110428Sandreas.hansson@arm.com 41210428Sandreas.hansson@arm.com if (memPowerSpec.capacitance != 0.0) { 41310428Sandreas.hansson@arm.com // If capacity is given, then IO Power depends on DRAM clock frequency. 41410428Sandreas.hansson@arm.com power.IO_power = memPowerSpec.capacitance * 0.5 * pow(memPowerSpec.vdd2, 2.0) * memTimingSpec.clkMhz * 1000000; 41510428Sandreas.hansson@arm.com } 41610428Sandreas.hansson@arm.com} // MemoryPowerModel::io_term_power 41710428Sandreas.hansson@arm.com 41810428Sandreas.hansson@arm.com 41910428Sandreas.hansson@arm.comdouble MemoryPowerModel::calcIoTermEnergy(int64_t cycles, double period, double power, int64_t numBits) const 42010428Sandreas.hansson@arm.com{ 42110428Sandreas.hansson@arm.com return static_cast<double>(cycles) * period * power * static_cast<double>(numBits); 42210428Sandreas.hansson@arm.com} 42310428Sandreas.hansson@arm.com 42410428Sandreas.hansson@arm.com// time (t) * current (I) * voltage (V) energy calculation 42510428Sandreas.hansson@arm.comdouble EnergyDomain::calcTivEnergy(int64_t cycles, double current) const 42610428Sandreas.hansson@arm.com{ 42710428Sandreas.hansson@arm.com return static_cast<double>(cycles) * clkPeriod * current * voltage; 42810428Sandreas.hansson@arm.com} 429