summaryrefslogtreecommitdiff
path: root/ext/drampower/src/MemoryPowerModel.cc
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2014-10-09 17:52:03 -0400
committerAndreas Hansson <andreas.hansson@arm.com>2014-10-09 17:52:03 -0400
commite0e8b08a42210011205b52c3628749f60658e58c (patch)
treee6daae3c8cd249f52c6504ee2b7fc07805085429 /ext/drampower/src/MemoryPowerModel.cc
parentc81517c293cdd3f612efae94d1143fb0cf002287 (diff)
downloadgem5-e0e8b08a42210011205b52c3628749f60658e58c.tar.xz
ext: Add DRAMPower to enable on-line DRAM power modelling
This patch adds the open-source (BSD 3-clause) tool DRAMPower, commit 8d3cf4bbb10aa202d850ef5e5e3e4f53aa668fa6, to be built as a part of the simulator. We have chosen this specific version of DRAMPower as it provides the necessary functionality, and future updates will be coordinated with the DRAMPower development team. The files added only include the bits needed to build the library, thus excluding all memory specifications, traces, and the stand-alone DRAMPower command-line tool. A future patch includes the DRAMPower functionality in the DRAM controller, to enable on-line DRAM power modelling, and avoid using post-processing of traces.
Diffstat (limited to 'ext/drampower/src/MemoryPowerModel.cc')
-rw-r--r--ext/drampower/src/MemoryPowerModel.cc428
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;
+}