diff options
Diffstat (limited to 'ext/drampower/src/MemoryPowerModel.cc')
-rw-r--r-- | ext/drampower/src/MemoryPowerModel.cc | 428 |
1 files changed, 428 insertions, 0 deletions
diff --git a/ext/drampower/src/MemoryPowerModel.cc b/ext/drampower/src/MemoryPowerModel.cc new file mode 100644 index 000000000..4817d1bb5 --- /dev/null +++ b/ext/drampower/src/MemoryPowerModel.cc @@ -0,0 +1,428 @@ +/* + * Copyright (c) 2012-2014, TU Delft + * Copyright (c) 2012-2014, TU Eindhoven + * Copyright (c) 2012-2014, TU Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Karthik Chandrasekar, Matthias Jung, Omar Naji + * + */ + +#include "MemoryPowerModel.h" + +#include <cmath> // For pow + +#include <stdint.h> + + +using namespace std; +using namespace Data; + +// Calculate energy and average power consumption for the given command trace + +void MemoryPowerModel::power_calc(MemorySpecification memSpec, + const CommandAnalysis& counters, + int term) +{ + MemTimingSpec& t = memSpec.memTimingSpec; + MemArchitectureSpec& memArchSpec = memSpec.memArchSpec; + MemPowerSpec& mps = memSpec.memPowerSpec; + + energy.act_energy = 0.0; + energy.pre_energy = 0.0; + energy.read_energy = 0.0; + energy.write_energy = 0.0; + energy.ref_energy = 0.0; + energy.act_stdby_energy = 0.0; + energy.pre_stdby_energy = 0.0; + energy.idle_energy_act = 0.0; + energy.idle_energy_pre = 0.0; + energy.total_energy = 0.0; + energy.f_act_pd_energy = 0.0; + energy.f_pre_pd_energy = 0.0; + energy.s_act_pd_energy = 0.0; + energy.s_pre_pd_energy = 0.0; + energy.sref_energy = 0.0; + energy.sref_ref_energy = 0.0; + energy.sref_ref_act_energy = 0.0; + energy.sref_ref_pre_energy = 0.0; + energy.spup_energy = 0.0; + energy.spup_ref_energy = 0.0; + energy.spup_ref_act_energy = 0.0; + energy.spup_ref_pre_energy = 0.0; + energy.pup_act_energy = 0.0; + energy.pup_pre_energy = 0.0; + power.IO_power = 0.0; + power.WR_ODT_power = 0.0; + power.TermRD_power = 0.0; + power.TermWR_power = 0.0; + energy.read_io_energy = 0.0; + energy.write_term_energy = 0.0; + energy.read_oterm_energy = 0.0; + energy.write_oterm_energy = 0.0; + energy.io_term_energy = 0.0; + + // How long a single burst takes, measured in command-clock cycles. + int64_t burstCc = memArchSpec.burstLength / memArchSpec.dataRate; + + // IO and Termination Power measures are included, if required. + if (term) { + io_term_power(memSpec); + + // memArchSpec.width represents the number of data (dq) pins. + // 1 DQS pin is associated with every data byte + int64_t dqPlusDqsBits = memArchSpec.width + memArchSpec.width / 8; + // 1 DQS and 1 DM pin is associated with every data byte + int64_t dqPlusDqsPlusMaskBits = memArchSpec.width + memArchSpec.width / 8 + memArchSpec.width / 8; + // Size of one clock period for the data bus. + double ddrPeriod = t.clkPeriod / memArchSpec.dataRate; + + // Read IO power is consumed by each DQ (data) and DQS (data strobe) pin + energy.read_io_energy = calcIoTermEnergy(counters.numberofreads * memArchSpec.burstLength, + ddrPeriod, + power.IO_power, + dqPlusDqsBits); + + // Write ODT power is consumed by each DQ (data), DQS (data strobe) and DM + energy.write_term_energy = calcIoTermEnergy(counters.numberofwrites * memArchSpec.burstLength, + ddrPeriod, + power.WR_ODT_power, + dqPlusDqsPlusMaskBits); + + if (memArchSpec.nbrOfRanks > 1) { + // Termination power consumed in the idle rank during reads on the active + // rank by each DQ (data) and DQS (data strobe) pin. + energy.read_oterm_energy = calcIoTermEnergy(counters.numberofreads * memArchSpec.burstLength, + ddrPeriod, + power.TermRD_power, + dqPlusDqsBits); + + // Termination power consumed in the idle rank during writes on the active + // rank by each DQ (data), DQS (data strobe) and DM (data mask) pin. + energy.write_oterm_energy = calcIoTermEnergy(counters.numberofwrites * memArchSpec.burstLength, + ddrPeriod, + power.TermWR_power, + dqPlusDqsPlusMaskBits); + } + + // Sum of all IO and termination energy + energy.io_term_energy = energy.read_io_energy + energy.write_term_energy + + energy.read_oterm_energy + energy.write_oterm_energy; + } + + total_cycles = counters.actcycles + counters.precycles + + counters.f_act_pdcycles + counters.f_pre_pdcycles + + counters.s_act_pdcycles + counters.s_pre_pdcycles + counters.sref_cycles + + counters.sref_ref_act_cycles + counters.sref_ref_pre_cycles + + counters.spup_ref_act_cycles + counters.spup_ref_pre_cycles; + + EnergyDomain vdd0Domain(mps.vdd, t.clkPeriod); + + energy.act_energy = vdd0Domain.calcTivEnergy(counters.numberofacts * t.RAS , mps.idd0 - mps.idd3n); + energy.pre_energy = vdd0Domain.calcTivEnergy(counters.numberofpres * (t.RC - t.RAS) , mps.idd0 - mps.idd2n); + energy.read_energy = vdd0Domain.calcTivEnergy(counters.numberofreads * burstCc , mps.idd4r - mps.idd3n); + energy.write_energy = vdd0Domain.calcTivEnergy(counters.numberofwrites * burstCc , mps.idd4w - mps.idd3n); + energy.ref_energy = vdd0Domain.calcTivEnergy(counters.numberofrefs * t.RFC , mps.idd5 - mps.idd3n); + energy.pre_stdby_energy = vdd0Domain.calcTivEnergy(counters.precycles, mps.idd2n); + energy.act_stdby_energy = vdd0Domain.calcTivEnergy(counters.actcycles, mps.idd3n); + // Idle energy in the active standby clock cycles + energy.idle_energy_act = vdd0Domain.calcTivEnergy(counters.idlecycles_act, mps.idd3n); + // Idle energy in the precharge standby clock cycles + energy.idle_energy_pre = vdd0Domain.calcTivEnergy(counters.idlecycles_pre, mps.idd2n); + // fast-exit active power-down cycles energy + energy.f_act_pd_energy = vdd0Domain.calcTivEnergy(counters.f_act_pdcycles, mps.idd3p1); + // fast-exit precharged power-down cycles energy + energy.f_pre_pd_energy = vdd0Domain.calcTivEnergy(counters.f_pre_pdcycles, mps.idd2p1); + // slow-exit active power-down cycles energy + energy.s_act_pd_energy = vdd0Domain.calcTivEnergy(counters.s_act_pdcycles, mps.idd3p0); + // slow-exit precharged power-down cycles energy + energy.s_pre_pd_energy = vdd0Domain.calcTivEnergy(counters.s_pre_pdcycles, mps.idd2p0); + + // self-refresh cycles energy including a refresh per self-refresh entry + energy.sref_energy = engy_sref(mps.idd6, mps.idd3n, + mps.idd5, mps.vdd, + static_cast<double>(counters.sref_cycles), static_cast<double>(counters.sref_ref_act_cycles), + static_cast<double>(counters.sref_ref_pre_cycles), static_cast<double>(counters.spup_ref_act_cycles), + static_cast<double>(counters.spup_ref_pre_cycles), t.clkPeriod); + + // background energy during active auto-refresh cycles in self-refresh + energy.sref_ref_act_energy = vdd0Domain.calcTivEnergy(counters.sref_ref_act_cycles, mps.idd3p0); + // background energy during precharged auto-refresh cycles in self-refresh + energy.sref_ref_pre_energy = vdd0Domain.calcTivEnergy(counters.sref_ref_pre_cycles, mps.idd2p0); + // background energy during active auto-refresh cycles in self-refresh exit + energy.spup_ref_act_energy = vdd0Domain.calcTivEnergy(counters.spup_ref_act_cycles, mps.idd3n); + // background energy during precharged auto-refresh cycles in self-refresh exit + energy.spup_ref_pre_energy = vdd0Domain.calcTivEnergy(counters.spup_ref_pre_cycles, mps.idd2n); + // self-refresh power-up cycles energy -- included + energy.spup_energy = vdd0Domain.calcTivEnergy(counters.spup_cycles, mps.idd2n); + // active power-up cycles energy - same as active standby -- included + energy.pup_act_energy = vdd0Domain.calcTivEnergy(counters.pup_act_cycles, mps.idd3n); + // precharged power-up cycles energy - same as precharged standby -- included + energy.pup_pre_energy = vdd0Domain.calcTivEnergy(counters.pup_pre_cycles, mps.idd2n); + + // similar equations as before to support multiple voltage domains in LPDDR2 + // and WIDEIO memories + if (memArchSpec.twoVoltageDomains) { + EnergyDomain vdd2Domain(mps.vdd2, t.clkPeriod); + + energy.act_energy += vdd2Domain.calcTivEnergy(counters.numberofacts * t.RAS , mps.idd02 - mps.idd3n2); + energy.pre_energy += vdd2Domain.calcTivEnergy(counters.numberofpres * (t.RC - t.RAS) , mps.idd02 - mps.idd2n2); + energy.read_energy += vdd2Domain.calcTivEnergy(counters.numberofreads * burstCc , mps.idd4r2 - mps.idd3n2); + energy.write_energy += vdd2Domain.calcTivEnergy(counters.numberofwrites * burstCc , mps.idd4w2 - mps.idd3n2); + energy.ref_energy += vdd2Domain.calcTivEnergy(counters.numberofrefs * t.RFC , mps.idd52 - mps.idd3n2); + energy.pre_stdby_energy += vdd2Domain.calcTivEnergy(counters.precycles, mps.idd2n2); + energy.act_stdby_energy += vdd2Domain.calcTivEnergy(counters.actcycles, mps.idd3n2); + // Idle energy in the active standby clock cycles + energy.idle_energy_act += vdd2Domain.calcTivEnergy(counters.idlecycles_act, mps.idd3n2); + // Idle energy in the precharge standby clock cycles + energy.idle_energy_pre += vdd2Domain.calcTivEnergy(counters.idlecycles_pre, mps.idd2n2); + // fast-exit active power-down cycles energy + energy.f_act_pd_energy += vdd2Domain.calcTivEnergy(counters.f_act_pdcycles, mps.idd3p12); + // fast-exit precharged power-down cycles energy + energy.f_pre_pd_energy += vdd2Domain.calcTivEnergy(counters.f_pre_pdcycles, mps.idd2p12); + // slow-exit active power-down cycles energy + energy.s_act_pd_energy += vdd2Domain.calcTivEnergy(counters.s_act_pdcycles, mps.idd3p02); + // slow-exit precharged power-down cycles energy + energy.s_pre_pd_energy += vdd2Domain.calcTivEnergy(counters.s_pre_pdcycles, mps.idd2p02); + + energy.sref_energy += engy_sref(mps.idd62, mps.idd3n2, + mps.idd52, mps.vdd2, + static_cast<double>(counters.sref_cycles), static_cast<double>(counters.sref_ref_act_cycles), + static_cast<double>(counters.sref_ref_pre_cycles), static_cast<double>(counters.spup_ref_act_cycles), + static_cast<double>(counters.spup_ref_pre_cycles), t.clkPeriod); + + // background energy during active auto-refresh cycles in self-refresh + energy.sref_ref_act_energy += vdd2Domain.calcTivEnergy(counters.sref_ref_act_cycles, mps.idd3p02); + // background energy during precharged auto-refresh cycles in self-refresh + energy.sref_ref_pre_energy += vdd2Domain.calcTivEnergy(counters.sref_ref_pre_cycles, mps.idd2p02); + // background energy during active auto-refresh cycles in self-refresh exit + energy.spup_ref_act_energy += vdd2Domain.calcTivEnergy(counters.spup_ref_act_cycles, mps.idd3n2); + // background energy during precharged auto-refresh cycles in self-refresh exit + energy.spup_ref_pre_energy += vdd2Domain.calcTivEnergy(counters.spup_ref_pre_cycles, mps.idd2n2); + // self-refresh power-up cycles energy -- included + energy.spup_energy += vdd2Domain.calcTivEnergy(counters.spup_cycles, mps.idd2n2); + // active power-up cycles energy - same as active standby -- included + energy.pup_act_energy += vdd2Domain.calcTivEnergy(counters.pup_act_cycles, mps.idd3n2); + // precharged power-up cycles energy - same as precharged standby -- included + energy.pup_pre_energy += vdd2Domain.calcTivEnergy(counters.pup_pre_cycles, mps.idd2n2); + } + + // auto-refresh energy during self-refresh cycles + energy.sref_ref_energy = energy.sref_ref_act_energy + energy.sref_ref_pre_energy; + + // auto-refresh energy during self-refresh exit cycles + energy.spup_ref_energy = energy.spup_ref_act_energy + energy.spup_ref_pre_energy; + + // adding all energy components for the active rank and all background and idle + // energy components for both ranks (in a dual-rank system) + energy.total_energy = energy.act_energy + energy.pre_energy + energy.read_energy + + energy.write_energy + energy.ref_energy + energy.io_term_energy + + memArchSpec.nbrOfRanks * (energy.act_stdby_energy + + energy.pre_stdby_energy + energy.sref_energy + + energy.f_act_pd_energy + energy.f_pre_pd_energy + energy.s_act_pd_energy + + energy.s_pre_pd_energy + energy.sref_ref_energy + energy.spup_ref_energy); + + // Calculate the average power consumption + power.average_power = energy.total_energy / (static_cast<double>(total_cycles) * t.clkPeriod); +} // MemoryPowerModel::power_calc + +void MemoryPowerModel::power_print(MemorySpecification memSpec, int term, const CommandAnalysis& counters) const +{ + MemTimingSpec& memTimingSpec = memSpec.memTimingSpec; + MemArchitectureSpec& memArchSpec = memSpec.memArchSpec; + + cout.precision(0); + cout << "* Trace Details:" << endl; + cout << "Number of Activates: " << fixed << counters.numberofacts << endl; + cout << "Number of Reads: " << counters.numberofreads << endl; + cout << "Number of Writes: " << counters.numberofwrites << endl; + cout << "Number of Precharges: " << counters.numberofpres << endl; + cout << "Number of Refreshes: " << counters.numberofrefs << endl; + cout << "Number of Active Cycles: " << counters.actcycles << endl; + cout << " Number of Active Idle Cycles: " << counters.idlecycles_act << endl; + cout << " Number of Active Power-Up Cycles: " << counters.pup_act_cycles << endl; + cout << " Number of Auto-Refresh Active cycles during Self-Refresh " << + "Power-Up: " << counters.spup_ref_act_cycles << endl; + cout << "Number of Precharged Cycles: " << counters.precycles << endl; + cout << " Number of Precharged Idle Cycles: " << counters.idlecycles_pre << endl; + cout << " Number of Precharged Power-Up Cycles: " << counters.pup_pre_cycles + << endl; + cout << " Number of Auto-Refresh Precharged cycles during Self-Refresh" + << " Power-Up: " << counters.spup_ref_pre_cycles << endl; + cout << " Number of Self-Refresh Power-Up Cycles: " << counters.spup_cycles + << endl; + cout << "Total Idle Cycles (Active + Precharged): " << + counters.idlecycles_act + counters.idlecycles_pre << endl; + cout << "Number of Power-Downs: " << counters.f_act_pdns + + counters.s_act_pdns + counters.f_pre_pdns + counters.s_pre_pdns << endl; + cout << " Number of Active Fast-exit Power-Downs: " << counters.f_act_pdns + << endl; + cout << " Number of Active Slow-exit Power-Downs: " << counters.s_act_pdns + << endl; + cout << " Number of Precharged Fast-exit Power-Downs: " << + counters.f_pre_pdns << endl; + cout << " Number of Precharged Slow-exit Power-Downs: " << + counters.s_pre_pdns << endl; + cout << "Number of Power-Down Cycles: " << counters.f_act_pdcycles + + counters.s_act_pdcycles + counters.f_pre_pdcycles + counters.s_pre_pdcycles << endl; + cout << " Number of Active Fast-exit Power-Down Cycles: " << + counters.f_act_pdcycles << endl; + cout << " Number of Active Slow-exit Power-Down Cycles: " << + counters.s_act_pdcycles << endl; + cout << " Number of Auto-Refresh Active cycles during Self-Refresh: " << + counters.sref_ref_act_cycles << endl; + cout << " Number of Precharged Fast-exit Power-Down Cycles: " << + counters.f_pre_pdcycles << endl; + cout << " Number of Precharged Slow-exit Power-Down Cycles: " << + counters.s_pre_pdcycles << endl; + cout << " Number of Auto-Refresh Precharged cycles during Self-Refresh: " << + counters.sref_ref_pre_cycles << endl; + cout << "Number of Auto-Refresh Cycles: " << counters.numberofrefs * + memTimingSpec.RFC << endl; + cout << "Number of Self-Refreshes: " << counters.numberofsrefs << endl; + cout << "Number of Self-Refresh Cycles: " << counters.sref_cycles << endl; + cout << "----------------------------------------" << endl; + cout << "Total Trace Length (clock cycles): " << total_cycles << endl; + cout << "----------------------------------------" << endl; + cout.precision(2); + + cout << "\n* Trace Power and Energy Estimates:" << endl; + cout << "ACT Cmd Energy: " << energy.act_energy << " pJ" << endl; + cout << "PRE Cmd Energy: " << energy.pre_energy << " pJ" << endl; + cout << "RD Cmd Energy: " << energy.read_energy << " pJ" << endl; + cout << "WR Cmd Energy: " << energy.write_energy << " pJ" << endl; + if (term) { + cout << "RD I/O Energy: " << energy.read_io_energy << " pJ" << endl; + // No Termination for LPDDR/2/3 and DDR memories + if (memSpec.memArchSpec.termination) { + cout << "WR Termination Energy: " << energy.write_term_energy << " pJ" << endl; + } + + if ((memArchSpec.nbrOfRanks > 1) && memSpec.memArchSpec.termination) { + cout << "RD Termination Energy (Idle rank): " << energy.read_oterm_energy + << " pJ" << endl; + cout << "WR Termination Energy (Idle rank): " << energy.write_oterm_energy + << " pJ" << endl; + } + } + cout << "ACT Stdby Energy: " << memArchSpec.nbrOfRanks * energy.act_stdby_energy << + " pJ" << endl; + cout << " Active Idle Energy: " << memArchSpec.nbrOfRanks * energy.idle_energy_act << + " pJ" << endl; + cout << " Active Power-Up Energy: " << memArchSpec.nbrOfRanks * energy.pup_act_energy << + " pJ" << endl; + cout << " Active Stdby Energy during Auto-Refresh cycles in Self-Refresh" + << " Power-Up: " << memArchSpec.nbrOfRanks * energy.spup_ref_act_energy << + " pJ" << endl; + cout << "PRE Stdby Energy: " << memArchSpec.nbrOfRanks * energy.pre_stdby_energy << + " pJ" << endl; + cout << " Precharge Idle Energy: " << memArchSpec.nbrOfRanks * energy.idle_energy_pre << + " pJ" << endl; + cout << " Precharged Power-Up Energy: " << memArchSpec.nbrOfRanks * energy.pup_pre_energy << + " pJ" << endl; + cout << " Precharge Stdby Energy during Auto-Refresh cycles " << + "in Self-Refresh Power-Up: " << memArchSpec.nbrOfRanks * energy.spup_ref_pre_energy << + " pJ" << endl; + cout << " Self-Refresh Power-Up Energy: " << memArchSpec.nbrOfRanks * energy.spup_energy << + " pJ" << endl; + cout << "Total Idle Energy (Active + Precharged): " << memArchSpec.nbrOfRanks * + (energy.idle_energy_act + energy.idle_energy_pre) << " pJ" << endl; + cout << "Total Power-Down Energy: " << memArchSpec.nbrOfRanks * (energy.f_act_pd_energy + + energy.f_pre_pd_energy + energy.s_act_pd_energy + energy.s_pre_pd_energy) << " pJ" << endl; + cout << " Fast-Exit Active Power-Down Energy: " << memArchSpec.nbrOfRanks * + energy.f_act_pd_energy << " pJ" << endl; + cout << " Slow-Exit Active Power-Down Energy: " << memArchSpec.nbrOfRanks * + energy.s_act_pd_energy << " pJ" << endl; + cout << " Slow-Exit Active Power-Down Energy during Auto-Refresh cycles " + << "in Self-Refresh: " << memArchSpec.nbrOfRanks * energy.sref_ref_act_energy << + " pJ" << endl; + cout << " Fast-Exit Precharged Power-Down Energy: " << memArchSpec.nbrOfRanks * + energy.f_pre_pd_energy << " pJ" << endl; + cout << " Slow-Exit Precharged Power-Down Energy: " << memArchSpec.nbrOfRanks * + energy.s_pre_pd_energy << " pJ" << endl; + cout << " Slow-Exit Precharged Power-Down Energy during Auto-Refresh " << + "cycles in Self-Refresh: " << memArchSpec.nbrOfRanks * energy.sref_ref_pre_energy << + " pJ" << endl; + cout << "Auto-Refresh Energy: " << energy.ref_energy << " pJ" << endl; + cout << "Self-Refresh Energy: " << memArchSpec.nbrOfRanks * energy.sref_energy << + " pJ" << endl; + cout << "----------------------------------------" << endl; + cout << "Total Trace Energy: " << energy.total_energy << " pJ" << endl; + cout << "Average Power: " << power.average_power << " mW" << endl; + cout << "----------------------------------------" << endl; +} // MemoryPowerModel::power_print + +// Self-refresh active energy estimation (not including background energy) +double MemoryPowerModel::engy_sref(double idd6, double idd3n, double idd5, + double vdd, double sref_cycles, double sref_ref_act_cycles, + double sref_ref_pre_cycles, double spup_ref_act_cycles, + double spup_ref_pre_cycles, double clk) +{ + double sref_energy; + + sref_energy = ((idd6 * sref_cycles) + ((idd5 - idd3n) * (sref_ref_act_cycles + + spup_ref_act_cycles + sref_ref_pre_cycles + spup_ref_pre_cycles))) + * vdd * clk; + return sref_energy; +} + +// IO and Termination power calculation based on Micron Power Calculators +// Absolute power measures are obtained from Micron Power Calculator (mentioned in mW) +void MemoryPowerModel::io_term_power(MemorySpecification memSpec) +{ + MemTimingSpec& memTimingSpec = memSpec.memTimingSpec; + MemArchitectureSpec& memArchSpec = memSpec.memArchSpec; + MemPowerSpec& memPowerSpec = memSpec.memPowerSpec; + + power.IO_power = memPowerSpec.ioPower; // in mW + power.WR_ODT_power = memPowerSpec.wrOdtPower; // in mW + + if (memArchSpec.nbrOfRanks > 1) { + power.TermRD_power = memPowerSpec.termRdPower; // in mW + power.TermWR_power = memPowerSpec.termWrPower; // in mW + } + + if (memPowerSpec.capacitance != 0.0) { + // If capacity is given, then IO Power depends on DRAM clock frequency. + power.IO_power = memPowerSpec.capacitance * 0.5 * pow(memPowerSpec.vdd2, 2.0) * memTimingSpec.clkMhz * 1000000; + } +} // MemoryPowerModel::io_term_power + + +double MemoryPowerModel::calcIoTermEnergy(int64_t cycles, double period, double power, int64_t numBits) const +{ + return static_cast<double>(cycles) * period * power * static_cast<double>(numBits); +} + +// time (t) * current (I) * voltage (V) energy calculation +double EnergyDomain::calcTivEnergy(int64_t cycles, double current) const +{ + return static_cast<double>(cycles) * clkPeriod * current * voltage; +} |