2 * Copyright (c) 2012-2014, TU Delft
3 * Copyright (c) 2012-2014, TU Eindhoven
4 * Copyright (c) 2012-2014, TU Kaiserslautern
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
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.
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.
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.
34 * Authors: Karthik Chandrasekar, Matthias Jung, Omar Naji
38 #include "MemoryPowerModel.h"
40 #include <cmath> // For pow
48 // Calculate energy and average power consumption for the given command trace
50 void MemoryPowerModel::power_calc(MemorySpecification memSpec
,
51 const CommandAnalysis
& counters
,
54 MemTimingSpec
& t
= memSpec
.memTimingSpec
;
55 MemArchitectureSpec
& memArchSpec
= memSpec
.memArchSpec
;
56 MemPowerSpec
& mps
= memSpec
.memPowerSpec
;
58 energy
.act_energy
= 0.0;
59 energy
.pre_energy
= 0.0;
60 energy
.read_energy
= 0.0;
61 energy
.write_energy
= 0.0;
62 energy
.ref_energy
= 0.0;
63 energy
.act_stdby_energy
= 0.0;
64 energy
.pre_stdby_energy
= 0.0;
65 energy
.idle_energy_act
= 0.0;
66 energy
.idle_energy_pre
= 0.0;
67 energy
.total_energy
= 0.0;
68 energy
.f_act_pd_energy
= 0.0;
69 energy
.f_pre_pd_energy
= 0.0;
70 energy
.s_act_pd_energy
= 0.0;
71 energy
.s_pre_pd_energy
= 0.0;
72 energy
.sref_energy
= 0.0;
73 energy
.sref_ref_energy
= 0.0;
74 energy
.sref_ref_act_energy
= 0.0;
75 energy
.sref_ref_pre_energy
= 0.0;
76 energy
.spup_energy
= 0.0;
77 energy
.spup_ref_energy
= 0.0;
78 energy
.spup_ref_act_energy
= 0.0;
79 energy
.spup_ref_pre_energy
= 0.0;
80 energy
.pup_act_energy
= 0.0;
81 energy
.pup_pre_energy
= 0.0;
83 power
.WR_ODT_power
= 0.0;
84 power
.TermRD_power
= 0.0;
85 power
.TermWR_power
= 0.0;
86 energy
.read_io_energy
= 0.0;
87 energy
.write_term_energy
= 0.0;
88 energy
.read_oterm_energy
= 0.0;
89 energy
.write_oterm_energy
= 0.0;
90 energy
.io_term_energy
= 0.0;
92 // How long a single burst takes, measured in command-clock cycles.
93 int64_t burstCc
= memArchSpec
.burstLength
/ memArchSpec
.dataRate
;
95 // IO and Termination Power measures are included, if required.
97 io_term_power(memSpec
);
99 // memArchSpec.width represents the number of data (dq) pins.
100 // 1 DQS pin is associated with every data byte
101 int64_t dqPlusDqsBits
= memArchSpec
.width
+ memArchSpec
.width
/ 8;
102 // 1 DQS and 1 DM pin is associated with every data byte
103 int64_t dqPlusDqsPlusMaskBits
= memArchSpec
.width
+ memArchSpec
.width
/ 8 + memArchSpec
.width
/ 8;
104 // Size of one clock period for the data bus.
105 double ddrPeriod
= t
.clkPeriod
/ memArchSpec
.dataRate
;
107 // Read IO power is consumed by each DQ (data) and DQS (data strobe) pin
108 energy
.read_io_energy
= calcIoTermEnergy(counters
.numberofreads
* memArchSpec
.burstLength
,
113 // Write ODT power is consumed by each DQ (data), DQS (data strobe) and DM
114 energy
.write_term_energy
= calcIoTermEnergy(counters
.numberofwrites
* memArchSpec
.burstLength
,
117 dqPlusDqsPlusMaskBits
);
119 if (memArchSpec
.nbrOfRanks
> 1) {
120 // Termination power consumed in the idle rank during reads on the active
121 // rank by each DQ (data) and DQS (data strobe) pin.
122 energy
.read_oterm_energy
= calcIoTermEnergy(counters
.numberofreads
* memArchSpec
.burstLength
,
127 // Termination power consumed in the idle rank during writes on the active
128 // rank by each DQ (data), DQS (data strobe) and DM (data mask) pin.
129 energy
.write_oterm_energy
= calcIoTermEnergy(counters
.numberofwrites
* memArchSpec
.burstLength
,
132 dqPlusDqsPlusMaskBits
);
135 // Sum of all IO and termination energy
136 energy
.io_term_energy
= energy
.read_io_energy
+ energy
.write_term_energy
137 + energy
.read_oterm_energy
+ energy
.write_oterm_energy
;
140 total_cycles
= counters
.actcycles
+ counters
.precycles
+
141 counters
.f_act_pdcycles
+ counters
.f_pre_pdcycles
+
142 counters
.s_act_pdcycles
+ counters
.s_pre_pdcycles
+ counters
.sref_cycles
143 + counters
.sref_ref_act_cycles
+ counters
.sref_ref_pre_cycles
+
144 counters
.spup_ref_act_cycles
+ counters
.spup_ref_pre_cycles
;
146 EnergyDomain
vdd0Domain(mps
.vdd
, t
.clkPeriod
);
148 energy
.act_energy
= vdd0Domain
.calcTivEnergy(counters
.numberofacts
* t
.RAS
, mps
.idd0
- mps
.idd3n
);
149 energy
.pre_energy
= vdd0Domain
.calcTivEnergy(counters
.numberofpres
* (t
.RC
- t
.RAS
) , mps
.idd0
- mps
.idd2n
);
150 energy
.read_energy
= vdd0Domain
.calcTivEnergy(counters
.numberofreads
* burstCc
, mps
.idd4r
- mps
.idd3n
);
151 energy
.write_energy
= vdd0Domain
.calcTivEnergy(counters
.numberofwrites
* burstCc
, mps
.idd4w
- mps
.idd3n
);
152 energy
.ref_energy
= vdd0Domain
.calcTivEnergy(counters
.numberofrefs
* t
.RFC
, mps
.idd5
- mps
.idd3n
);
153 energy
.pre_stdby_energy
= vdd0Domain
.calcTivEnergy(counters
.precycles
, mps
.idd2n
);
154 energy
.act_stdby_energy
= vdd0Domain
.calcTivEnergy(counters
.actcycles
, mps
.idd3n
);
155 // Idle energy in the active standby clock cycles
156 energy
.idle_energy_act
= vdd0Domain
.calcTivEnergy(counters
.idlecycles_act
, mps
.idd3n
);
157 // Idle energy in the precharge standby clock cycles
158 energy
.idle_energy_pre
= vdd0Domain
.calcTivEnergy(counters
.idlecycles_pre
, mps
.idd2n
);
159 // fast-exit active power-down cycles energy
160 energy
.f_act_pd_energy
= vdd0Domain
.calcTivEnergy(counters
.f_act_pdcycles
, mps
.idd3p1
);
161 // fast-exit precharged power-down cycles energy
162 energy
.f_pre_pd_energy
= vdd0Domain
.calcTivEnergy(counters
.f_pre_pdcycles
, mps
.idd2p1
);
163 // slow-exit active power-down cycles energy
164 energy
.s_act_pd_energy
= vdd0Domain
.calcTivEnergy(counters
.s_act_pdcycles
, mps
.idd3p0
);
165 // slow-exit precharged power-down cycles energy
166 energy
.s_pre_pd_energy
= vdd0Domain
.calcTivEnergy(counters
.s_pre_pdcycles
, mps
.idd2p0
);
168 // self-refresh cycles energy including a refresh per self-refresh entry
169 energy
.sref_energy
= engy_sref(mps
.idd6
, mps
.idd3n
,
171 static_cast<double>(counters
.sref_cycles
), static_cast<double>(counters
.sref_ref_act_cycles
),
172 static_cast<double>(counters
.sref_ref_pre_cycles
), static_cast<double>(counters
.spup_ref_act_cycles
),
173 static_cast<double>(counters
.spup_ref_pre_cycles
), t
.clkPeriod
);
175 // background energy during active auto-refresh cycles in self-refresh
176 energy
.sref_ref_act_energy
= vdd0Domain
.calcTivEnergy(counters
.sref_ref_act_cycles
, mps
.idd3p0
);
177 // background energy during precharged auto-refresh cycles in self-refresh
178 energy
.sref_ref_pre_energy
= vdd0Domain
.calcTivEnergy(counters
.sref_ref_pre_cycles
, mps
.idd2p0
);
179 // background energy during active auto-refresh cycles in self-refresh exit
180 energy
.spup_ref_act_energy
= vdd0Domain
.calcTivEnergy(counters
.spup_ref_act_cycles
, mps
.idd3n
);
181 // background energy during precharged auto-refresh cycles in self-refresh exit
182 energy
.spup_ref_pre_energy
= vdd0Domain
.calcTivEnergy(counters
.spup_ref_pre_cycles
, mps
.idd2n
);
183 // self-refresh power-up cycles energy -- included
184 energy
.spup_energy
= vdd0Domain
.calcTivEnergy(counters
.spup_cycles
, mps
.idd2n
);
185 // active power-up cycles energy - same as active standby -- included
186 energy
.pup_act_energy
= vdd0Domain
.calcTivEnergy(counters
.pup_act_cycles
, mps
.idd3n
);
187 // precharged power-up cycles energy - same as precharged standby -- included
188 energy
.pup_pre_energy
= vdd0Domain
.calcTivEnergy(counters
.pup_pre_cycles
, mps
.idd2n
);
190 // similar equations as before to support multiple voltage domains in LPDDR2
191 // and WIDEIO memories
192 if (memArchSpec
.twoVoltageDomains
) {
193 EnergyDomain
vdd2Domain(mps
.vdd2
, t
.clkPeriod
);
195 energy
.act_energy
+= vdd2Domain
.calcTivEnergy(counters
.numberofacts
* t
.RAS
, mps
.idd02
- mps
.idd3n2
);
196 energy
.pre_energy
+= vdd2Domain
.calcTivEnergy(counters
.numberofpres
* (t
.RC
- t
.RAS
) , mps
.idd02
- mps
.idd2n2
);
197 energy
.read_energy
+= vdd2Domain
.calcTivEnergy(counters
.numberofreads
* burstCc
, mps
.idd4r2
- mps
.idd3n2
);
198 energy
.write_energy
+= vdd2Domain
.calcTivEnergy(counters
.numberofwrites
* burstCc
, mps
.idd4w2
- mps
.idd3n2
);
199 energy
.ref_energy
+= vdd2Domain
.calcTivEnergy(counters
.numberofrefs
* t
.RFC
, mps
.idd52
- mps
.idd3n2
);
200 energy
.pre_stdby_energy
+= vdd2Domain
.calcTivEnergy(counters
.precycles
, mps
.idd2n2
);
201 energy
.act_stdby_energy
+= vdd2Domain
.calcTivEnergy(counters
.actcycles
, mps
.idd3n2
);
202 // Idle energy in the active standby clock cycles
203 energy
.idle_energy_act
+= vdd2Domain
.calcTivEnergy(counters
.idlecycles_act
, mps
.idd3n2
);
204 // Idle energy in the precharge standby clock cycles
205 energy
.idle_energy_pre
+= vdd2Domain
.calcTivEnergy(counters
.idlecycles_pre
, mps
.idd2n2
);
206 // fast-exit active power-down cycles energy
207 energy
.f_act_pd_energy
+= vdd2Domain
.calcTivEnergy(counters
.f_act_pdcycles
, mps
.idd3p12
);
208 // fast-exit precharged power-down cycles energy
209 energy
.f_pre_pd_energy
+= vdd2Domain
.calcTivEnergy(counters
.f_pre_pdcycles
, mps
.idd2p12
);
210 // slow-exit active power-down cycles energy
211 energy
.s_act_pd_energy
+= vdd2Domain
.calcTivEnergy(counters
.s_act_pdcycles
, mps
.idd3p02
);
212 // slow-exit precharged power-down cycles energy
213 energy
.s_pre_pd_energy
+= vdd2Domain
.calcTivEnergy(counters
.s_pre_pdcycles
, mps
.idd2p02
);
215 energy
.sref_energy
+= engy_sref(mps
.idd62
, mps
.idd3n2
,
217 static_cast<double>(counters
.sref_cycles
), static_cast<double>(counters
.sref_ref_act_cycles
),
218 static_cast<double>(counters
.sref_ref_pre_cycles
), static_cast<double>(counters
.spup_ref_act_cycles
),
219 static_cast<double>(counters
.spup_ref_pre_cycles
), t
.clkPeriod
);
221 // background energy during active auto-refresh cycles in self-refresh
222 energy
.sref_ref_act_energy
+= vdd2Domain
.calcTivEnergy(counters
.sref_ref_act_cycles
, mps
.idd3p02
);
223 // background energy during precharged auto-refresh cycles in self-refresh
224 energy
.sref_ref_pre_energy
+= vdd2Domain
.calcTivEnergy(counters
.sref_ref_pre_cycles
, mps
.idd2p02
);
225 // background energy during active auto-refresh cycles in self-refresh exit
226 energy
.spup_ref_act_energy
+= vdd2Domain
.calcTivEnergy(counters
.spup_ref_act_cycles
, mps
.idd3n2
);
227 // background energy during precharged auto-refresh cycles in self-refresh exit
228 energy
.spup_ref_pre_energy
+= vdd2Domain
.calcTivEnergy(counters
.spup_ref_pre_cycles
, mps
.idd2n2
);
229 // self-refresh power-up cycles energy -- included
230 energy
.spup_energy
+= vdd2Domain
.calcTivEnergy(counters
.spup_cycles
, mps
.idd2n2
);
231 // active power-up cycles energy - same as active standby -- included
232 energy
.pup_act_energy
+= vdd2Domain
.calcTivEnergy(counters
.pup_act_cycles
, mps
.idd3n2
);
233 // precharged power-up cycles energy - same as precharged standby -- included
234 energy
.pup_pre_energy
+= vdd2Domain
.calcTivEnergy(counters
.pup_pre_cycles
, mps
.idd2n2
);
237 // auto-refresh energy during self-refresh cycles
238 energy
.sref_ref_energy
= energy
.sref_ref_act_energy
+ energy
.sref_ref_pre_energy
;
240 // auto-refresh energy during self-refresh exit cycles
241 energy
.spup_ref_energy
= energy
.spup_ref_act_energy
+ energy
.spup_ref_pre_energy
;
243 // adding all energy components for the active rank and all background and idle
244 // energy components for both ranks (in a dual-rank system)
245 energy
.total_energy
= energy
.act_energy
+ energy
.pre_energy
+ energy
.read_energy
+
246 energy
.write_energy
+ energy
.ref_energy
+ energy
.io_term_energy
+
247 memArchSpec
.nbrOfRanks
* (energy
.act_stdby_energy
+
248 energy
.pre_stdby_energy
+ energy
.sref_energy
+
249 energy
.f_act_pd_energy
+ energy
.f_pre_pd_energy
+ energy
.s_act_pd_energy
250 + energy
.s_pre_pd_energy
+ energy
.sref_ref_energy
+ energy
.spup_ref_energy
);
252 // Calculate the average power consumption
253 power
.average_power
= energy
.total_energy
/ (static_cast<double>(total_cycles
) * t
.clkPeriod
);
254 } // MemoryPowerModel::power_calc
256 void MemoryPowerModel::power_print(MemorySpecification memSpec
, int term
, const CommandAnalysis
& counters
) const
258 MemTimingSpec
& memTimingSpec
= memSpec
.memTimingSpec
;
259 MemArchitectureSpec
& memArchSpec
= memSpec
.memArchSpec
;
262 cout
<< "* Trace Details:" << endl
;
263 cout
<< "Number of Activates: " << fixed
<< counters
.numberofacts
<< endl
;
264 cout
<< "Number of Reads: " << counters
.numberofreads
<< endl
;
265 cout
<< "Number of Writes: " << counters
.numberofwrites
<< endl
;
266 cout
<< "Number of Precharges: " << counters
.numberofpres
<< endl
;
267 cout
<< "Number of Refreshes: " << counters
.numberofrefs
<< endl
;
268 cout
<< "Number of Active Cycles: " << counters
.actcycles
<< endl
;
269 cout
<< " Number of Active Idle Cycles: " << counters
.idlecycles_act
<< endl
;
270 cout
<< " Number of Active Power-Up Cycles: " << counters
.pup_act_cycles
<< endl
;
271 cout
<< " Number of Auto-Refresh Active cycles during Self-Refresh " <<
272 "Power-Up: " << counters
.spup_ref_act_cycles
<< endl
;
273 cout
<< "Number of Precharged Cycles: " << counters
.precycles
<< endl
;
274 cout
<< " Number of Precharged Idle Cycles: " << counters
.idlecycles_pre
<< endl
;
275 cout
<< " Number of Precharged Power-Up Cycles: " << counters
.pup_pre_cycles
277 cout
<< " Number of Auto-Refresh Precharged cycles during Self-Refresh"
278 << " Power-Up: " << counters
.spup_ref_pre_cycles
<< endl
;
279 cout
<< " Number of Self-Refresh Power-Up Cycles: " << counters
.spup_cycles
281 cout
<< "Total Idle Cycles (Active + Precharged): " <<
282 counters
.idlecycles_act
+ counters
.idlecycles_pre
<< endl
;
283 cout
<< "Number of Power-Downs: " << counters
.f_act_pdns
+
284 counters
.s_act_pdns
+ counters
.f_pre_pdns
+ counters
.s_pre_pdns
<< endl
;
285 cout
<< " Number of Active Fast-exit Power-Downs: " << counters
.f_act_pdns
287 cout
<< " Number of Active Slow-exit Power-Downs: " << counters
.s_act_pdns
289 cout
<< " Number of Precharged Fast-exit Power-Downs: " <<
290 counters
.f_pre_pdns
<< endl
;
291 cout
<< " Number of Precharged Slow-exit Power-Downs: " <<
292 counters
.s_pre_pdns
<< endl
;
293 cout
<< "Number of Power-Down Cycles: " << counters
.f_act_pdcycles
+
294 counters
.s_act_pdcycles
+ counters
.f_pre_pdcycles
+ counters
.s_pre_pdcycles
<< endl
;
295 cout
<< " Number of Active Fast-exit Power-Down Cycles: " <<
296 counters
.f_act_pdcycles
<< endl
;
297 cout
<< " Number of Active Slow-exit Power-Down Cycles: " <<
298 counters
.s_act_pdcycles
<< endl
;
299 cout
<< " Number of Auto-Refresh Active cycles during Self-Refresh: " <<
300 counters
.sref_ref_act_cycles
<< endl
;
301 cout
<< " Number of Precharged Fast-exit Power-Down Cycles: " <<
302 counters
.f_pre_pdcycles
<< endl
;
303 cout
<< " Number of Precharged Slow-exit Power-Down Cycles: " <<
304 counters
.s_pre_pdcycles
<< endl
;
305 cout
<< " Number of Auto-Refresh Precharged cycles during Self-Refresh: " <<
306 counters
.sref_ref_pre_cycles
<< endl
;
307 cout
<< "Number of Auto-Refresh Cycles: " << counters
.numberofrefs
*
308 memTimingSpec
.RFC
<< endl
;
309 cout
<< "Number of Self-Refreshes: " << counters
.numberofsrefs
<< endl
;
310 cout
<< "Number of Self-Refresh Cycles: " << counters
.sref_cycles
<< endl
;
311 cout
<< "----------------------------------------" << endl
;
312 cout
<< "Total Trace Length (clock cycles): " << total_cycles
<< endl
;
313 cout
<< "----------------------------------------" << endl
;
316 cout
<< "\n* Trace Power and Energy Estimates:" << endl
;
317 cout
<< "ACT Cmd Energy: " << energy
.act_energy
<< " pJ" << endl
;
318 cout
<< "PRE Cmd Energy: " << energy
.pre_energy
<< " pJ" << endl
;
319 cout
<< "RD Cmd Energy: " << energy
.read_energy
<< " pJ" << endl
;
320 cout
<< "WR Cmd Energy: " << energy
.write_energy
<< " pJ" << endl
;
322 cout
<< "RD I/O Energy: " << energy
.read_io_energy
<< " pJ" << endl
;
323 // No Termination for LPDDR/2/3 and DDR memories
324 if (memSpec
.memArchSpec
.termination
) {
325 cout
<< "WR Termination Energy: " << energy
.write_term_energy
<< " pJ" << endl
;
328 if ((memArchSpec
.nbrOfRanks
> 1) && memSpec
.memArchSpec
.termination
) {
329 cout
<< "RD Termination Energy (Idle rank): " << energy
.read_oterm_energy
331 cout
<< "WR Termination Energy (Idle rank): " << energy
.write_oterm_energy
335 cout
<< "ACT Stdby Energy: " << memArchSpec
.nbrOfRanks
* energy
.act_stdby_energy
<<
337 cout
<< " Active Idle Energy: " << memArchSpec
.nbrOfRanks
* energy
.idle_energy_act
<<
339 cout
<< " Active Power-Up Energy: " << memArchSpec
.nbrOfRanks
* energy
.pup_act_energy
<<
341 cout
<< " Active Stdby Energy during Auto-Refresh cycles in Self-Refresh"
342 << " Power-Up: " << memArchSpec
.nbrOfRanks
* energy
.spup_ref_act_energy
<<
344 cout
<< "PRE Stdby Energy: " << memArchSpec
.nbrOfRanks
* energy
.pre_stdby_energy
<<
346 cout
<< " Precharge Idle Energy: " << memArchSpec
.nbrOfRanks
* energy
.idle_energy_pre
<<
348 cout
<< " Precharged Power-Up Energy: " << memArchSpec
.nbrOfRanks
* energy
.pup_pre_energy
<<
350 cout
<< " Precharge Stdby Energy during Auto-Refresh cycles " <<
351 "in Self-Refresh Power-Up: " << memArchSpec
.nbrOfRanks
* energy
.spup_ref_pre_energy
<<
353 cout
<< " Self-Refresh Power-Up Energy: " << memArchSpec
.nbrOfRanks
* energy
.spup_energy
<<
355 cout
<< "Total Idle Energy (Active + Precharged): " << memArchSpec
.nbrOfRanks
*
356 (energy
.idle_energy_act
+ energy
.idle_energy_pre
) << " pJ" << endl
;
357 cout
<< "Total Power-Down Energy: " << memArchSpec
.nbrOfRanks
* (energy
.f_act_pd_energy
+
358 energy
.f_pre_pd_energy
+ energy
.s_act_pd_energy
+ energy
.s_pre_pd_energy
) << " pJ" << endl
;
359 cout
<< " Fast-Exit Active Power-Down Energy: " << memArchSpec
.nbrOfRanks
*
360 energy
.f_act_pd_energy
<< " pJ" << endl
;
361 cout
<< " Slow-Exit Active Power-Down Energy: " << memArchSpec
.nbrOfRanks
*
362 energy
.s_act_pd_energy
<< " pJ" << endl
;
363 cout
<< " Slow-Exit Active Power-Down Energy during Auto-Refresh cycles "
364 << "in Self-Refresh: " << memArchSpec
.nbrOfRanks
* energy
.sref_ref_act_energy
<<
366 cout
<< " Fast-Exit Precharged Power-Down Energy: " << memArchSpec
.nbrOfRanks
*
367 energy
.f_pre_pd_energy
<< " pJ" << endl
;
368 cout
<< " Slow-Exit Precharged Power-Down Energy: " << memArchSpec
.nbrOfRanks
*
369 energy
.s_pre_pd_energy
<< " pJ" << endl
;
370 cout
<< " Slow-Exit Precharged Power-Down Energy during Auto-Refresh " <<
371 "cycles in Self-Refresh: " << memArchSpec
.nbrOfRanks
* energy
.sref_ref_pre_energy
<<
373 cout
<< "Auto-Refresh Energy: " << energy
.ref_energy
<< " pJ" << endl
;
374 cout
<< "Self-Refresh Energy: " << memArchSpec
.nbrOfRanks
* energy
.sref_energy
<<
376 cout
<< "----------------------------------------" << endl
;
377 cout
<< "Total Trace Energy: " << energy
.total_energy
<< " pJ" << endl
;
378 cout
<< "Average Power: " << power
.average_power
<< " mW" << endl
;
379 cout
<< "----------------------------------------" << endl
;
380 } // MemoryPowerModel::power_print
382 // Self-refresh active energy estimation (not including background energy)
383 double MemoryPowerModel::engy_sref(double idd6
, double idd3n
, double idd5
,
384 double vdd
, double sref_cycles
, double sref_ref_act_cycles
,
385 double sref_ref_pre_cycles
, double spup_ref_act_cycles
,
386 double spup_ref_pre_cycles
, double clk
)
390 sref_energy
= ((idd6
* sref_cycles
) + ((idd5
- idd3n
) * (sref_ref_act_cycles
391 + spup_ref_act_cycles
+ sref_ref_pre_cycles
+ spup_ref_pre_cycles
)))
396 // IO and Termination power calculation based on Micron Power Calculators
397 // Absolute power measures are obtained from Micron Power Calculator (mentioned in mW)
398 void MemoryPowerModel::io_term_power(MemorySpecification memSpec
)
400 MemTimingSpec
& memTimingSpec
= memSpec
.memTimingSpec
;
401 MemArchitectureSpec
& memArchSpec
= memSpec
.memArchSpec
;
402 MemPowerSpec
& memPowerSpec
= memSpec
.memPowerSpec
;
404 power
.IO_power
= memPowerSpec
.ioPower
; // in mW
405 power
.WR_ODT_power
= memPowerSpec
.wrOdtPower
; // in mW
407 if (memArchSpec
.nbrOfRanks
> 1) {
408 power
.TermRD_power
= memPowerSpec
.termRdPower
; // in mW
409 power
.TermWR_power
= memPowerSpec
.termWrPower
; // in mW
412 if (memPowerSpec
.capacitance
!= 0.0) {
413 // If capacity is given, then IO Power depends on DRAM clock frequency.
414 power
.IO_power
= memPowerSpec
.capacitance
* 0.5 * pow(memPowerSpec
.vdd2
, 2.0) * memTimingSpec
.clkMhz
* 1000000;
416 } // MemoryPowerModel::io_term_power
419 double MemoryPowerModel::calcIoTermEnergy(int64_t cycles
, double period
, double power
, int64_t numBits
) const
421 return static_cast<double>(cycles
) * period
* power
* static_cast<double>(numBits
);
424 // time (t) * current (I) * voltage (V) energy calculation
425 double EnergyDomain::calcTivEnergy(int64_t cycles
, double current
) const
427 return static_cast<double>(cycles
) * clkPeriod
* current
* voltage
;