MemoryPowerModel.cc revision 11555
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