MemoryPowerModel.cc revision 11555:2efa95cf8504
1/*
2 * Copyright (c) 2012-2014, TU Delft
3 * Copyright (c) 2012-2014, TU Eindhoven
4 * Copyright (c) 2012-2014, TU Kaiserslautern
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * 3. Neither the name of the copyright holder nor the names of its
19 * contributors may be used to endorse or promote products derived from
20 * this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
23 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
28 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 * Authors: Karthik Chandrasekar, Matthias Jung, Omar Naji
35 *
36 */
37
38#include "MemoryPowerModel.h"
39
40#include <stdint.h>
41
42#include <cmath>  // For pow
43#include <iostream>  // fmtflags
44
45
46using namespace std;
47using namespace Data;
48
49// Calculate energy and average power consumption for the given command trace
50
51void MemoryPowerModel::power_calc(const MemorySpecification& memSpec,
52                                  const CommandAnalysis& c,
53                                  int term)
54{
55  const MemTimingSpec& t                 = memSpec.memTimingSpec;
56  const MemArchitectureSpec& memArchSpec = memSpec.memArchSpec;
57  const MemPowerSpec&  mps               = memSpec.memPowerSpec;
58
59  energy.act_energy          = 0.0;
60  energy.pre_energy          = 0.0;
61  energy.read_energy         = 0.0;
62  energy.write_energy        = 0.0;
63  energy.ref_energy          = 0.0;
64  energy.act_stdby_energy    = 0.0;
65  energy.pre_stdby_energy    = 0.0;
66  energy.idle_energy_act     = 0.0;
67  energy.idle_energy_pre     = 0.0;
68  energy.total_energy        = 0.0;
69  energy.f_act_pd_energy     = 0.0;
70  energy.f_pre_pd_energy     = 0.0;
71  energy.s_act_pd_energy     = 0.0;
72  energy.s_pre_pd_energy     = 0.0;
73  energy.sref_energy         = 0.0;
74  energy.sref_ref_energy     = 0.0;
75  energy.sref_ref_act_energy = 0.0;
76  energy.sref_ref_pre_energy = 0.0;
77  energy.spup_energy         = 0.0;
78  energy.spup_ref_energy     = 0.0;
79  energy.spup_ref_act_energy = 0.0;
80  energy.spup_ref_pre_energy = 0.0;
81  energy.pup_act_energy      = 0.0;
82  energy.pup_pre_energy      = 0.0;
83  power.IO_power             = 0.0;
84  power.WR_ODT_power         = 0.0;
85  power.TermRD_power         = 0.0;
86  power.TermWR_power         = 0.0;
87  energy.read_io_energy      = 0.0;
88  energy.write_term_energy   = 0.0;
89  energy.read_oterm_energy   = 0.0;
90  energy.write_oterm_energy  = 0.0;
91  energy.io_term_energy      = 0.0;
92
93  // How long a single burst takes, measured in command-clock cycles.
94  int64_t burstCc = memArchSpec.burstLength / memArchSpec.dataRate;
95
96  // IO and Termination Power measures are included, if required.
97  if (term) {
98    io_term_power(memSpec);
99
100    // memArchSpec.width represents the number of data (dq) pins.
101    // 1 DQS pin is associated with every data byte
102    int64_t dqPlusDqsBits = memArchSpec.width + memArchSpec.width / 8;
103    // 1 DQS and 1 DM pin is associated with every data byte
104    int64_t dqPlusDqsPlusMaskBits = memArchSpec.width + memArchSpec.width / 8 + memArchSpec.width / 8;
105    // Size of one clock period for the data bus.
106    double ddrPeriod = t.clkPeriod / static_cast<double>(memArchSpec.dataRate);
107
108    // Read IO power is consumed by each DQ (data) and DQS (data strobe) pin
109    energy.read_io_energy = calcIoTermEnergy(c.numberofreads * memArchSpec.burstLength,
110                                             ddrPeriod,
111                                             power.IO_power,
112                                             dqPlusDqsBits);
113
114    // Write ODT power is consumed by each DQ (data), DQS (data strobe) and DM
115    energy.write_term_energy = calcIoTermEnergy(c.numberofwrites * memArchSpec.burstLength,
116                                                ddrPeriod,
117                                                power.WR_ODT_power,
118                                                dqPlusDqsPlusMaskBits);
119
120    if (memArchSpec.nbrOfRanks > 1) {
121      // Termination power consumed in the idle rank during reads on the active
122      // rank by each DQ (data) and DQS (data strobe) pin.
123      energy.read_oterm_energy = calcIoTermEnergy(c.numberofreads * memArchSpec.burstLength,
124                                                  ddrPeriod,
125                                                  power.TermRD_power,
126                                                  dqPlusDqsBits);
127
128      // Termination power consumed in the idle rank during writes on the active
129      // rank by each DQ (data), DQS (data strobe) and DM (data mask) pin.
130      energy.write_oterm_energy = calcIoTermEnergy(c.numberofwrites * memArchSpec.burstLength,
131                                                   ddrPeriod,
132                                                   power.TermWR_power,
133                                                   dqPlusDqsPlusMaskBits);
134    }
135
136    // Sum of all IO and termination energy
137    energy.io_term_energy = energy.read_io_energy + energy.write_term_energy
138                            + energy.read_oterm_energy + energy.write_oterm_energy;
139  }
140
141  total_cycles = c.actcycles + c.precycles +
142                 c.f_act_pdcycles + c.f_pre_pdcycles +
143                 c.s_act_pdcycles + c.s_pre_pdcycles + c.sref_cycles
144                 + c.sref_ref_act_cycles + c.sref_ref_pre_cycles +
145                 c.spup_ref_act_cycles + c.spup_ref_pre_cycles;
146
147  EnergyDomain vdd0Domain(mps.vdd, t.clkPeriod);
148
149  energy.act_energy       = vdd0Domain.calcTivEnergy(c.numberofacts   * t.RAS          , mps.idd0 - mps.idd3n);
150  energy.pre_energy       = vdd0Domain.calcTivEnergy(c.numberofpres   * (t.RC - t.RAS) , mps.idd0 - mps.idd2n);
151  energy.read_energy      = vdd0Domain.calcTivEnergy(c.numberofreads  * burstCc        , mps.idd4r - mps.idd3n);
152  energy.write_energy     = vdd0Domain.calcTivEnergy(c.numberofwrites * burstCc        , mps.idd4w - mps.idd3n);
153  energy.ref_energy       = vdd0Domain.calcTivEnergy(c.numberofrefs   * t.RFC          , mps.idd5 - mps.idd3n);
154  energy.pre_stdby_energy = vdd0Domain.calcTivEnergy(c.precycles, mps.idd2n);
155  energy.act_stdby_energy = vdd0Domain.calcTivEnergy(c.actcycles, mps.idd3n);
156  // Idle energy in the active standby clock cycles
157  energy.idle_energy_act  = vdd0Domain.calcTivEnergy(c.idlecycles_act, mps.idd3n);
158  // Idle energy in the precharge standby clock cycles
159  energy.idle_energy_pre  = vdd0Domain.calcTivEnergy(c.idlecycles_pre, mps.idd2n);
160  // fast-exit active power-down cycles energy
161  energy.f_act_pd_energy  = vdd0Domain.calcTivEnergy(c.f_act_pdcycles, mps.idd3p1);
162  // fast-exit precharged power-down cycles energy
163  energy.f_pre_pd_energy  = vdd0Domain.calcTivEnergy(c.f_pre_pdcycles, mps.idd2p1);
164  // slow-exit active power-down cycles energy
165  energy.s_act_pd_energy  = vdd0Domain.calcTivEnergy(c.s_act_pdcycles, mps.idd3p0);
166  // slow-exit precharged power-down cycles energy
167  energy.s_pre_pd_energy  = vdd0Domain.calcTivEnergy(c.s_pre_pdcycles, mps.idd2p0);
168
169  // self-refresh cycles energy including a refresh per self-refresh entry
170  energy.sref_energy = engy_sref(mps.idd6, mps.idd3n,
171                                 mps.idd5, mps.vdd,
172                                 static_cast<double>(c.sref_cycles), static_cast<double>(c.sref_ref_act_cycles),
173                                 static_cast<double>(c.sref_ref_pre_cycles), static_cast<double>(c.spup_ref_act_cycles),
174                                 static_cast<double>(c.spup_ref_pre_cycles), t.clkPeriod);
175
176  // background energy during active auto-refresh cycles in self-refresh
177  energy.sref_ref_act_energy = vdd0Domain.calcTivEnergy(c.sref_ref_act_cycles, mps.idd3p0);
178  // background energy during precharged auto-refresh cycles in self-refresh
179  energy.sref_ref_pre_energy = vdd0Domain.calcTivEnergy(c.sref_ref_pre_cycles, mps.idd2p0);
180  // background energy during active auto-refresh cycles in self-refresh exit
181  energy.spup_ref_act_energy = vdd0Domain.calcTivEnergy(c.spup_ref_act_cycles, mps.idd3n);
182  // background energy during precharged auto-refresh cycles in self-refresh exit
183  energy.spup_ref_pre_energy = vdd0Domain.calcTivEnergy(c.spup_ref_pre_cycles, mps.idd2n);
184  // self-refresh power-up cycles energy -- included
185  energy.spup_energy         = vdd0Domain.calcTivEnergy(c.spup_cycles, mps.idd2n);
186  // active power-up cycles energy - same as active standby -- included
187  energy.pup_act_energy      = vdd0Domain.calcTivEnergy(c.pup_act_cycles, mps.idd3n);
188  // precharged power-up cycles energy - same as precharged standby -- included
189  energy.pup_pre_energy      = vdd0Domain.calcTivEnergy(c.pup_pre_cycles, mps.idd2n);
190
191  // similar equations as before to support multiple voltage domains in LPDDR2
192  // and WIDEIO memories
193  if (memArchSpec.twoVoltageDomains) {
194    EnergyDomain vdd2Domain(mps.vdd2, t.clkPeriod);
195
196    energy.act_energy       += vdd2Domain.calcTivEnergy(c.numberofacts   * t.RAS          , mps.idd02 - mps.idd3n2);
197    energy.pre_energy       += vdd2Domain.calcTivEnergy(c.numberofpres   * (t.RC - t.RAS) , mps.idd02 - mps.idd2n2);
198    energy.read_energy      += vdd2Domain.calcTivEnergy(c.numberofreads  * burstCc        , mps.idd4r2 - mps.idd3n2);
199    energy.write_energy     += vdd2Domain.calcTivEnergy(c.numberofwrites * burstCc        , mps.idd4w2 - mps.idd3n2);
200    energy.ref_energy       += vdd2Domain.calcTivEnergy(c.numberofrefs   * t.RFC          , mps.idd52 - mps.idd3n2);
201    energy.pre_stdby_energy += vdd2Domain.calcTivEnergy(c.precycles, mps.idd2n2);
202    energy.act_stdby_energy += vdd2Domain.calcTivEnergy(c.actcycles, mps.idd3n2);
203    // Idle energy in the active standby clock cycles
204    energy.idle_energy_act  += vdd2Domain.calcTivEnergy(c.idlecycles_act, mps.idd3n2);
205    // Idle energy in the precharge standby clock cycles
206    energy.idle_energy_pre  += vdd2Domain.calcTivEnergy(c.idlecycles_pre, mps.idd2n2);
207    // fast-exit active power-down cycles energy
208    energy.f_act_pd_energy  += vdd2Domain.calcTivEnergy(c.f_act_pdcycles, mps.idd3p12);
209    // fast-exit precharged power-down cycles energy
210    energy.f_pre_pd_energy  += vdd2Domain.calcTivEnergy(c.f_pre_pdcycles, mps.idd2p12);
211    // slow-exit active power-down cycles energy
212    energy.s_act_pd_energy  += vdd2Domain.calcTivEnergy(c.s_act_pdcycles, mps.idd3p02);
213    // slow-exit precharged power-down cycles energy
214    energy.s_pre_pd_energy  += vdd2Domain.calcTivEnergy(c.s_pre_pdcycles, mps.idd2p02);
215
216    energy.sref_energy      += engy_sref(mps.idd62, mps.idd3n2,
217                                         mps.idd52, mps.vdd2,
218                                         static_cast<double>(c.sref_cycles), static_cast<double>(c.sref_ref_act_cycles),
219                                         static_cast<double>(c.sref_ref_pre_cycles), static_cast<double>(c.spup_ref_act_cycles),
220                                         static_cast<double>(c.spup_ref_pre_cycles), t.clkPeriod);
221
222    // background energy during active auto-refresh cycles in self-refresh
223    energy.sref_ref_act_energy += vdd2Domain.calcTivEnergy(c.sref_ref_act_cycles, mps.idd3p02);
224    // background energy during precharged auto-refresh cycles in self-refresh
225    energy.sref_ref_pre_energy += vdd2Domain.calcTivEnergy(c.sref_ref_pre_cycles, mps.idd2p02);
226    // background energy during active auto-refresh cycles in self-refresh exit
227    energy.spup_ref_act_energy += vdd2Domain.calcTivEnergy(c.spup_ref_act_cycles, mps.idd3n2);
228    // background energy during precharged auto-refresh cycles in self-refresh exit
229    energy.spup_ref_pre_energy += vdd2Domain.calcTivEnergy(c.spup_ref_pre_cycles, mps.idd2n2);
230    // self-refresh power-up cycles energy -- included
231    energy.spup_energy         += vdd2Domain.calcTivEnergy(c.spup_cycles, mps.idd2n2);
232    // active power-up cycles energy - same as active standby -- included
233    energy.pup_act_energy      += vdd2Domain.calcTivEnergy(c.pup_act_cycles, mps.idd3n2);
234    // precharged power-up cycles energy - same as precharged standby -- included
235    energy.pup_pre_energy      += vdd2Domain.calcTivEnergy(c.pup_pre_cycles, mps.idd2n2);
236  }
237
238  // auto-refresh energy during self-refresh cycles
239  energy.sref_ref_energy = energy.sref_ref_act_energy + energy.sref_ref_pre_energy;
240
241  // auto-refresh energy during self-refresh exit cycles
242  energy.spup_ref_energy = energy.spup_ref_act_energy + energy.spup_ref_pre_energy;
243
244  // adding all energy components for the active rank and all background and idle
245  // energy components for both ranks (in a dual-rank system)
246  energy.total_energy = energy.act_energy + energy.pre_energy + energy.read_energy +
247                        energy.write_energy + energy.ref_energy + energy.io_term_energy +
248                        static_cast<double>(memArchSpec.nbrOfRanks) * (energy.act_stdby_energy +
249                                                  energy.pre_stdby_energy + energy.sref_energy +
250                                                  energy.f_act_pd_energy + energy.f_pre_pd_energy + energy.s_act_pd_energy
251                                                  + energy.s_pre_pd_energy + energy.sref_ref_energy + energy.spup_ref_energy);
252
253  // Calculate the average power consumption
254  power.average_power = energy.total_energy / (static_cast<double>(total_cycles) * t.clkPeriod);
255} // MemoryPowerModel::power_calc
256
257void MemoryPowerModel::power_print(const MemorySpecification& memSpec, int term, const CommandAnalysis& c) const
258{
259  const MemTimingSpec& memTimingSpec     = memSpec.memTimingSpec;
260  const MemArchitectureSpec& memArchSpec = memSpec.memArchSpec;
261  const uint64_t nRanks = static_cast<uint64_t>(memArchSpec.nbrOfRanks);
262  const char eUnit[] = " pJ";
263
264  ios_base::fmtflags flags = cout.flags();
265  streamsize precision = cout.precision();
266  cout.precision(0);
267  cout << "* Trace Details:" << fixed << endl
268       << endl << "#ACT commands: "                 << c.numberofacts
269       << endl << "#RD + #RDA commands: "           << c.numberofreads
270       << endl << "#WR + #WRA commands: "           << c.numberofwrites
271  /* #PRE commands (precharge all counts a number of #PRE commands equal to the number of active banks) */
272       << endl << "#PRE (+ PREA) commands: "        << c.numberofpres
273       << endl << "#REF commands: "                 << c.numberofrefs
274       << endl << "#Active Cycles: "                << c.actcycles
275       << endl << "  #Active Idle Cycles: "         << c.idlecycles_act
276       << endl << "  #Active Power-Up Cycles: "     << c.pup_act_cycles
277       << endl << "    #Auto-Refresh Active cycles during Self-Refresh Power-Up: " << c.spup_ref_act_cycles
278       << endl << "#Precharged Cycles: "            << c.precycles
279       << endl << "  #Precharged Idle Cycles: "     << c.idlecycles_pre
280       << endl << "  #Precharged Power-Up Cycles: " << c.pup_pre_cycles
281       << endl << "    #Auto-Refresh Precharged cycles during Self-Refresh Power-Up: " << c.spup_ref_pre_cycles
282       << endl << "  #Self-Refresh Power-Up Cycles: "                          << c.spup_cycles
283       << endl << "Total Idle Cycles (Active + Precharged): "                  << c.idlecycles_act + c.idlecycles_pre
284       << endl << "#Power-Downs: "                                             << c.f_act_pdns +  c.s_act_pdns + c.f_pre_pdns + c.s_pre_pdns
285       << endl << "  #Active Fast-exit Power-Downs: "                          << c.f_act_pdns
286       << endl << "  #Active Slow-exit Power-Downs: "                          << c.s_act_pdns
287       << endl << "  #Precharged Fast-exit Power-Downs: "                      << c.f_pre_pdns
288       << endl << "  #Precharged Slow-exit Power-Downs: "                      << c.s_pre_pdns
289       << endl << "#Power-Down Cycles: "                                       << c.f_act_pdcycles + c.s_act_pdcycles + c.f_pre_pdcycles + c.s_pre_pdcycles
290       << endl << "  #Active Fast-exit Power-Down Cycles: "                    << c.f_act_pdcycles
291       << endl << "  #Active Slow-exit Power-Down Cycles: "                    << c.s_act_pdcycles
292       << endl << "    #Auto-Refresh Active cycles during Self-Refresh: "      << c.sref_ref_act_cycles
293       << endl << "  #Precharged Fast-exit Power-Down Cycles: "                << c.f_pre_pdcycles
294       << endl << "  #Precharged Slow-exit Power-Down Cycles: "                << c.s_pre_pdcycles
295       << endl << "    #Auto-Refresh Precharged cycles during Self-Refresh: "  << c.sref_ref_pre_cycles
296       << endl << "#Auto-Refresh Cycles: "                                     << c.numberofrefs * memTimingSpec.RFC
297       << endl << "#Self-Refreshes: "                                          << c.numberofsrefs
298       << endl << "#Self-Refresh Cycles: "                                     << c.sref_cycles
299       << endl << "----------------------------------------"
300       << endl << "Total Trace Length (clock cycles): " << total_cycles
301       << endl << "----------------------------------------" << endl;
302
303  cout.precision(2);
304  cout << endl << "* Trace Power and Energy Estimates:" << endl
305       << endl << "ACT Cmd Energy: " << energy.act_energy   << eUnit
306       << endl << "PRE Cmd Energy: " << energy.pre_energy   << eUnit
307       << endl << "RD Cmd Energy: "  << energy.read_energy  << eUnit
308       << endl << "WR Cmd Energy: "  << energy.write_energy << eUnit;
309
310  if (term) {
311    cout << "RD I/O Energy: " << energy.read_io_energy << eUnit << endl;
312    // No Termination for LPDDR/2/3 and DDR memories
313    if (memSpec.memArchSpec.termination) {
314      cout << "WR Termination Energy: " << energy.write_term_energy << eUnit << endl;
315    }
316
317    if (nRanks > 1 && memSpec.memArchSpec.termination) {
318      cout <<         "RD Termination Energy (Idle rank): " << energy.read_oterm_energy << eUnit
319           << endl << "WR Termination Energy (Idle rank): " << energy.write_oterm_energy << eUnit << endl;
320    }
321  }
322
323  double nRanksDouble = static_cast<double>(nRanks);
324
325  cout <<         "ACT Stdby Energy: "                                                                      << nRanksDouble * energy.act_stdby_energy << eUnit
326       << endl << "  Active Idle Energy: "                                                                  << nRanksDouble * energy.idle_energy_act << eUnit
327       << endl << "  Active Power-Up Energy: "                                                              << nRanksDouble * energy.pup_act_energy << eUnit
328       << endl << "    Active Stdby Energy during Auto-Refresh cycles in Self-Refresh Power-Up: "           << nRanksDouble * energy.spup_ref_act_energy << eUnit
329       << endl << "PRE Stdby Energy: "                                                                      << nRanksDouble * energy.pre_stdby_energy << eUnit
330       << endl << "  Precharge Idle Energy: "                                                               << nRanksDouble * energy.idle_energy_pre << eUnit
331       << endl << "  Precharged Power-Up Energy: "                                                          << nRanksDouble * energy.pup_pre_energy << eUnit
332       << endl << "    Precharge Stdby Energy during Auto-Refresh cycles in Self-Refresh Power-Up: "        << nRanksDouble * energy.spup_ref_pre_energy << eUnit
333       << endl << "  Self-Refresh Power-Up Energy: "                                                        << nRanksDouble * energy.spup_energy << eUnit
334       << endl << "Total Idle Energy (Active + Precharged): "                                               << nRanksDouble * (energy.idle_energy_act + energy.idle_energy_pre) << eUnit
335       << 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
336       << endl << "  Fast-Exit Active Power-Down Energy: "                                                  << nRanksDouble * energy.f_act_pd_energy << eUnit
337       << endl << "  Slow-Exit Active Power-Down Energy: "                                                  << nRanksDouble * energy.s_act_pd_energy << eUnit
338       << endl << "    Slow-Exit Active Power-Down Energy during Auto-Refresh cycles in Self-Refresh: "     << nRanksDouble * energy.sref_ref_act_energy << eUnit
339       << endl << "  Fast-Exit Precharged Power-Down Energy: "                                              << nRanksDouble * energy.f_pre_pd_energy << eUnit
340       << endl << "  Slow-Exit Precharged Power-Down Energy: "                                              << nRanksDouble * energy.s_pre_pd_energy << eUnit
341       << endl << "    Slow-Exit Precharged Power-Down Energy during Auto-Refresh cycles in Self-Refresh: " << nRanksDouble * energy.sref_ref_pre_energy << eUnit
342       << endl << "Auto-Refresh Energy: "                                                                   << energy.ref_energy << eUnit
343       << endl << "Self-Refresh Energy: "                                                                   << nRanksDouble * energy.sref_energy << eUnit
344       << endl << "----------------------------------------"
345       << endl << "Total Trace Energy: "                                                                    << energy.total_energy << eUnit
346       << endl << "Average Power: "                                                                         << power.average_power << " mW"
347       << endl << "----------------------------------------" << endl;
348
349  cout.flags(flags);
350  cout.precision(precision);
351} // MemoryPowerModel::power_print
352
353// Self-refresh active energy estimation (not including background energy)
354double MemoryPowerModel::engy_sref(double idd6, double idd3n, double idd5,
355                                   double vdd, double sref_cycles, double sref_ref_act_cycles,
356                                   double sref_ref_pre_cycles, double spup_ref_act_cycles,
357                                   double spup_ref_pre_cycles, double clk)
358{
359  double sref_energy;
360
361  sref_energy = ((idd6 * sref_cycles) + ((idd5 - idd3n) * (sref_ref_act_cycles
362                                                           + spup_ref_act_cycles + sref_ref_pre_cycles + spup_ref_pre_cycles)))
363                * vdd * clk;
364  return sref_energy;
365}
366
367// IO and Termination power calculation based on Micron Power Calculators
368// Absolute power measures are obtained from Micron Power Calculator (mentioned in mW)
369void MemoryPowerModel::io_term_power(const MemorySpecification& memSpec)
370{
371  const MemTimingSpec& memTimingSpec     = memSpec.memTimingSpec;
372  const MemArchitectureSpec& memArchSpec = memSpec.memArchSpec;
373  const MemPowerSpec&  memPowerSpec      = memSpec.memPowerSpec;
374
375  power.IO_power     = memPowerSpec.ioPower;    // in mW
376  power.WR_ODT_power = memPowerSpec.wrOdtPower; // in mW
377
378  if (memArchSpec.nbrOfRanks > 1) {
379    power.TermRD_power = memPowerSpec.termRdPower; // in mW
380    power.TermWR_power = memPowerSpec.termWrPower; // in mW
381  }
382
383  if (memPowerSpec.capacitance != 0.0) {
384    // If capacity is given, then IO Power depends on DRAM clock frequency.
385    power.IO_power = memPowerSpec.capacitance * 0.5 * pow(memPowerSpec.vdd2, 2.0) * memTimingSpec.clkMhz * 1000000;
386  }
387} // MemoryPowerModel::io_term_power
388
389
390double MemoryPowerModel::calcIoTermEnergy(int64_t cycles, double period, double power, int64_t numBits) const
391{
392  return static_cast<double>(cycles) * period * power * static_cast<double>(numBits);
393}
394
395// time (t) * current (I) * voltage (V) energy calculation
396double EnergyDomain::calcTivEnergy(int64_t cycles, double current) const
397{
398  return static_cast<double>(cycles) * clkPeriod * current * voltage;
399}
400