summaryrefslogtreecommitdiff
path: root/ext/drampower/src/MemoryPowerModel.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ext/drampower/src/MemoryPowerModel.cc')
-rw-r--r--ext/drampower/src/MemoryPowerModel.cc275
1 files changed, 243 insertions, 32 deletions
diff --git a/ext/drampower/src/MemoryPowerModel.cc b/ext/drampower/src/MemoryPowerModel.cc
index e020830e6..5c3549c00 100644
--- a/ext/drampower/src/MemoryPowerModel.cc
+++ b/ext/drampower/src/MemoryPowerModel.cc
@@ -31,7 +31,12 @@
* 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
+ * Authors: Karthik Chandrasekar
+ * Matthias Jung
+ * Omar Naji
+ * Subash Kannoth
+ * Éder F. Zulian
+ * Felipe S. Prado
*
*/
@@ -41,20 +46,55 @@
#include <cmath> // For pow
#include <iostream> // fmtflags
-
+#include <algorithm>
using namespace std;
using namespace Data;
+MemoryPowerModel::MemoryPowerModel()
+{
+ total_cycles = 0;
+ energy.total_energy = 0;
+}
+
// Calculate energy and average power consumption for the given command trace
void MemoryPowerModel::power_calc(const MemorySpecification& memSpec,
const CommandAnalysis& c,
- int term)
+ int term,
+ const MemBankWiseParams& bwPowerParams)
{
const MemTimingSpec& t = memSpec.memTimingSpec;
const MemArchitectureSpec& memArchSpec = memSpec.memArchSpec;
const MemPowerSpec& mps = memSpec.memPowerSpec;
+ const int64_t nbrofBanks = memSpec.memArchSpec.nbrOfBanks;
+
+ energy.act_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.pre_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.read_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.write_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.ref_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.refb_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.act_stdby_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.pre_stdby_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.idle_energy_act_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.idle_energy_pre_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.f_act_pd_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.f_pre_pd_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.s_act_pd_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.s_pre_pd_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.ref_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.sref_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.sref_ref_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.sref_ref_act_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.sref_ref_pre_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.spup_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.spup_ref_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.spup_ref_act_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.spup_ref_pre_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.pup_act_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.pup_pre_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
+ energy.total_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
energy.act_energy = 0.0;
energy.pre_energy = 0.0;
@@ -65,7 +105,7 @@ void MemoryPowerModel::power_calc(const MemorySpecification& memSpec,
energy.pre_stdby_energy = 0.0;
energy.idle_energy_act = 0.0;
energy.idle_energy_pre = 0.0;
- energy.total_energy = 0.0;
+ energy.window_energy = 0.0;
energy.f_act_pd_energy = 0.0;
energy.f_pre_pd_energy = 0.0;
energy.s_act_pd_energy = 0.0;
@@ -106,13 +146,13 @@ void MemoryPowerModel::power_calc(const MemorySpecification& memSpec,
double ddrPeriod = t.clkPeriod / static_cast<double>(memArchSpec.dataRate);
// Read IO power is consumed by each DQ (data) and DQS (data strobe) pin
- energy.read_io_energy = calcIoTermEnergy(c.numberofreads * memArchSpec.burstLength,
+ energy.read_io_energy = calcIoTermEnergy(sum(c.numberofreadsBanks) * 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(c.numberofwrites * memArchSpec.burstLength,
+ energy.write_term_energy = calcIoTermEnergy(sum(c.numberofwritesBanks) * memArchSpec.burstLength,
ddrPeriod,
power.WR_ODT_power,
dqPlusDqsPlusMaskBits);
@@ -120,14 +160,14 @@ void MemoryPowerModel::power_calc(const MemorySpecification& memSpec,
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(c.numberofreads * memArchSpec.burstLength,
+ energy.read_oterm_energy = calcIoTermEnergy(sum(c.numberofreadsBanks) * 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(c.numberofwrites * memArchSpec.burstLength,
+ energy.write_oterm_energy = calcIoTermEnergy(sum(c.numberofwritesBanks) * memArchSpec.burstLength,
ddrPeriod,
power.TermWR_power,
dqPlusDqsPlusMaskBits);
@@ -138,7 +178,7 @@ void MemoryPowerModel::power_calc(const MemorySpecification& memSpec,
+ energy.read_oterm_energy + energy.write_oterm_energy;
}
- total_cycles = c.actcycles + c.precycles +
+ window_cycles = c.actcycles + c.precycles +
c.f_act_pdcycles + c.f_pre_pdcycles +
c.s_act_pdcycles + c.s_pre_pdcycles + c.sref_cycles
+ c.sref_ref_act_cycles + c.sref_ref_pre_cycles +
@@ -146,13 +186,69 @@ void MemoryPowerModel::power_calc(const MemorySpecification& memSpec,
EnergyDomain vdd0Domain(mps.vdd, t.clkPeriod);
- energy.act_energy = vdd0Domain.calcTivEnergy(c.numberofacts * t.RAS , mps.idd0 - mps.idd3n);
- energy.pre_energy = vdd0Domain.calcTivEnergy(c.numberofpres * (t.RC - t.RAS) , mps.idd0 - mps.idd2n);
- energy.read_energy = vdd0Domain.calcTivEnergy(c.numberofreads * burstCc , mps.idd4r - mps.idd3n);
- energy.write_energy = vdd0Domain.calcTivEnergy(c.numberofwrites * burstCc , mps.idd4w - mps.idd3n);
+ energy.act_energy = vdd0Domain.calcTivEnergy(sum(c.numberofactsBanks) * t.RAS , mps.idd0 - mps.idd3n);
+ energy.pre_energy = vdd0Domain.calcTivEnergy(sum(c.numberofpresBanks) * (t.RC - t.RAS) , mps.idd0 - mps.idd2n);
+ energy.read_energy = vdd0Domain.calcTivEnergy(sum(c.numberofreadsBanks) * burstCc , mps.idd4r - mps.idd3n);
+ energy.write_energy = vdd0Domain.calcTivEnergy(sum(c.numberofwritesBanks) * burstCc , mps.idd4w - mps.idd3n);
energy.ref_energy = vdd0Domain.calcTivEnergy(c.numberofrefs * t.RFC , mps.idd5 - mps.idd3n);
energy.pre_stdby_energy = vdd0Domain.calcTivEnergy(c.precycles, mps.idd2n);
energy.act_stdby_energy = vdd0Domain.calcTivEnergy(c.actcycles, mps.idd3n);
+
+ // Using the number of cycles that at least one bank is active here
+ // But the current iddrho is less than idd3n
+ double iddrho = (static_cast<double>(bwPowerParams.bwPowerFactRho) / 100.0) * (mps.idd3n - mps.idd2n) + mps.idd2n;
+ double esharedActStdby = vdd0Domain.calcTivEnergy(c.actcycles, iddrho);
+ // Fixed componenent for PASR
+ double iddsigma = (static_cast<double>(bwPowerParams.bwPowerFactSigma) / 100.0) * mps.idd6;
+ double esharedPASR = vdd0Domain.calcTivEnergy(c.sref_cycles, iddsigma);
+ // ione is Active background current for a single bank. When a single bank is Active
+ //,all the other remainig (B-1) banks will consume a current of iddrho (based on factor Rho)
+ // So to derrive ione we add (B-1)*iddrho to the idd3n and distribute it to each banks.
+ double ione = (mps.idd3n + (iddrho * (static_cast<double>(nbrofBanks - 1)))) / (static_cast<double>(nbrofBanks));
+ // If memory specification does not provide bank wise refresh current,
+ // approximate it to single bank background current removed from
+ // single bank active current
+ double idd5Blocal = (mps.idd5B == 0.0) ? (mps.idd0 - ione) :(mps.idd5B);
+ // if memory specification does not provide the REFB timing approximate it
+ // to time of ACT + PRE
+ int64_t tRefBlocal = (t.REFB == 0) ? (t.RAS + t.RP) : (t.REFB);
+
+ //Distribution of energy componets to each banks
+ for (unsigned i = 0; i < nbrofBanks; i++) {
+ energy.act_energy_banks[i] = vdd0Domain.calcTivEnergy(c.numberofactsBanks[i] * t.RAS, mps.idd0 - ione);
+ energy.pre_energy_banks[i] = vdd0Domain.calcTivEnergy(c.numberofpresBanks[i] * (t.RP), mps.idd0 - ione);
+ energy.read_energy_banks[i] = vdd0Domain.calcTivEnergy(c.numberofreadsBanks[i] * burstCc, mps.idd4r - mps.idd3n);
+ energy.write_energy_banks[i] = vdd0Domain.calcTivEnergy(c.numberofwritesBanks[i] * burstCc, mps.idd4w - mps.idd3n);
+ energy.ref_energy_banks[i] = vdd0Domain.calcTivEnergy(c.numberofrefs * t.RFC, mps.idd5 - mps.idd3n) / static_cast<double>(nbrofBanks);
+ energy.refb_energy_banks[i] = vdd0Domain.calcTivEnergy(c.numberofrefbBanks[i] * tRefBlocal, idd5Blocal);
+ energy.pre_stdby_energy_banks[i] = vdd0Domain.calcTivEnergy(c.precycles, mps.idd2n) / static_cast<double>(nbrofBanks);
+ energy.act_stdby_energy_banks[i] = vdd0Domain.calcTivEnergy(c.actcyclesBanks[i], (mps.idd3n - iddrho) / static_cast<double>(nbrofBanks))
+ + esharedActStdby / static_cast<double>(nbrofBanks);
+ energy.idle_energy_act_banks[i] = vdd0Domain.calcTivEnergy(c.idlecycles_act, mps.idd3n) / static_cast<double>(nbrofBanks);
+ energy.idle_energy_pre_banks[i] = vdd0Domain.calcTivEnergy(c.idlecycles_pre, mps.idd2n) / static_cast<double>(nbrofBanks);
+ energy.f_act_pd_energy_banks[i] = vdd0Domain.calcTivEnergy(c.f_act_pdcycles, mps.idd3p1) / static_cast<double>(nbrofBanks);
+ energy.f_pre_pd_energy_banks[i] = vdd0Domain.calcTivEnergy(c.f_pre_pdcycles, mps.idd2p1) / static_cast<double>(nbrofBanks);
+ energy.s_act_pd_energy_banks[i] = vdd0Domain.calcTivEnergy(c.s_act_pdcycles, mps.idd3p0) / static_cast<double>(nbrofBanks);
+ energy.s_pre_pd_energy_banks[i] = vdd0Domain.calcTivEnergy(c.s_pre_pdcycles, mps.idd2p0) / static_cast<double>(nbrofBanks);
+
+ energy.sref_energy_banks[i] = engy_sref_banks(mps.idd6, mps.idd3n,
+ mps.idd5, mps.vdd,
+ static_cast<double>(c.sref_cycles), static_cast<double>(c.sref_ref_act_cycles),
+ static_cast<double>(c.sref_ref_pre_cycles), static_cast<double>(c.spup_ref_act_cycles),
+ static_cast<double>(c.spup_ref_pre_cycles), t.clkPeriod,esharedPASR,bwPowerParams,i,nbrofBanks
+ );
+ energy.sref_ref_act_energy_banks[i] = vdd0Domain.calcTivEnergy(c.sref_ref_act_cycles, mps.idd3p0) / static_cast<double>(nbrofBanks);
+ energy.sref_ref_pre_energy_banks[i] = vdd0Domain.calcTivEnergy(c.sref_ref_pre_cycles, mps.idd2p0) / static_cast<double>(nbrofBanks);
+ energy.sref_ref_energy_banks[i] = energy.sref_ref_act_energy_banks[i] + energy.sref_ref_pre_energy_banks[i] ;//
+
+ energy.spup_energy_banks[i] = vdd0Domain.calcTivEnergy(c.spup_cycles, mps.idd2n) / static_cast<double>(nbrofBanks);
+ energy.spup_ref_act_energy_banks[i] = vdd0Domain.calcTivEnergy(c.spup_ref_act_cycles, mps.idd3n) / static_cast<double>(nbrofBanks);//
+ energy.spup_ref_pre_energy_banks[i] = vdd0Domain.calcTivEnergy(c.spup_ref_pre_cycles, mps.idd2n) / static_cast<double>(nbrofBanks);
+ energy.spup_ref_energy_banks[i] = ( energy.spup_ref_act_energy + energy.spup_ref_pre_energy ) / static_cast<double>(nbrofBanks);
+ energy.pup_act_energy_banks[i] = vdd0Domain.calcTivEnergy(c.pup_act_cycles, mps.idd3n) / static_cast<double>(nbrofBanks);
+ energy.pup_pre_energy_banks[i] = vdd0Domain.calcTivEnergy(c.pup_pre_cycles, mps.idd2n) / static_cast<double>(nbrofBanks);
+ }
+
// Idle energy in the active standby clock cycles
energy.idle_energy_act = vdd0Domain.calcTivEnergy(c.idlecycles_act, mps.idd3n);
// Idle energy in the precharge standby clock cycles
@@ -193,13 +289,14 @@ void MemoryPowerModel::power_calc(const MemorySpecification& memSpec,
if (memArchSpec.twoVoltageDomains) {
EnergyDomain vdd2Domain(mps.vdd2, t.clkPeriod);
- energy.act_energy += vdd2Domain.calcTivEnergy(c.numberofacts * t.RAS , mps.idd02 - mps.idd3n2);
- energy.pre_energy += vdd2Domain.calcTivEnergy(c.numberofpres * (t.RC - t.RAS) , mps.idd02 - mps.idd2n2);
- energy.read_energy += vdd2Domain.calcTivEnergy(c.numberofreads * burstCc , mps.idd4r2 - mps.idd3n2);
- energy.write_energy += vdd2Domain.calcTivEnergy(c.numberofwrites * burstCc , mps.idd4w2 - mps.idd3n2);
+ energy.act_energy += vdd2Domain.calcTivEnergy(sum(c.numberofactsBanks) * t.RAS , mps.idd02 - mps.idd3n2);
+ energy.pre_energy += vdd2Domain.calcTivEnergy(sum(c.numberofpresBanks) * (t.RC - t.RAS) , mps.idd02 - mps.idd2n2);
+ energy.read_energy += vdd2Domain.calcTivEnergy(sum(c.numberofreadsBanks) * burstCc , mps.idd4r2 - mps.idd3n2);
+ energy.write_energy += vdd2Domain.calcTivEnergy(sum(c.numberofwritesBanks) * burstCc , mps.idd4w2 - mps.idd3n2);
energy.ref_energy += vdd2Domain.calcTivEnergy(c.numberofrefs * t.RFC , mps.idd52 - mps.idd3n2);
energy.pre_stdby_energy += vdd2Domain.calcTivEnergy(c.precycles, mps.idd2n2);
energy.act_stdby_energy += vdd2Domain.calcTivEnergy(c.actcycles, mps.idd3n2);
+
// Idle energy in the active standby clock cycles
energy.idle_energy_act += vdd2Domain.calcTivEnergy(c.idlecycles_act, mps.idd3n2);
// Idle energy in the precharge standby clock cycles
@@ -243,34 +340,71 @@ void MemoryPowerModel::power_calc(const MemorySpecification& memSpec,
// 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 +
- static_cast<double>(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);
+
+ if (bwPowerParams.bwMode) {
+ // Calculate total energy per bank.
+ for (unsigned i = 0; i < nbrofBanks; i++) {
+ energy.total_energy_banks[i] = energy.act_energy_banks[i] + energy.pre_energy_banks[i] + energy.read_energy_banks[i]
+ + energy.ref_energy_banks[i] + energy.write_energy_banks[i] + energy.refb_energy_banks[i]
+ + static_cast<double>(memArchSpec.nbrOfRanks) * energy.act_stdby_energy_banks[i]
+ + energy.pre_stdby_energy_banks[i] + energy.f_pre_pd_energy_banks[i] + energy.s_act_pd_energy_banks[i]
+ + energy.s_pre_pd_energy_banks[i]+ energy.sref_ref_energy_banks[i] + energy.spup_ref_energy_banks[i];
+ }
+ // Calculate total energy for all banks.
+ energy.window_energy = sum(energy.total_energy_banks) + energy.io_term_energy;
+
+ } else {
+ energy.window_energy = energy.act_energy + energy.pre_energy + energy.read_energy + energy.write_energy
+ + energy.ref_energy + energy.io_term_energy + sum(energy.refb_energy_banks)
+ + static_cast<double>(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);
+ }
+
+ power.window_average_power = energy.window_energy / (static_cast<double>(window_cycles) * t.clkPeriod);
+
+ total_cycles += window_cycles;
+
+ energy.total_energy += energy.window_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(const MemorySpecification& memSpec, int term, const CommandAnalysis& c) const
+void MemoryPowerModel::power_print(const MemorySpecification& memSpec, int term, const CommandAnalysis& c, bool bankwiseMode) const
{
const MemTimingSpec& memTimingSpec = memSpec.memTimingSpec;
const MemArchitectureSpec& memArchSpec = memSpec.memArchSpec;
const uint64_t nRanks = static_cast<uint64_t>(memArchSpec.nbrOfRanks);
const char eUnit[] = " pJ";
+ const int64_t nbrofBanks = memSpec.memArchSpec.nbrOfBanks;
+ double nRanksDouble = static_cast<double>(nRanks);
ios_base::fmtflags flags = cout.flags();
streamsize precision = cout.precision();
cout.precision(0);
- cout << "* Trace Details:" << fixed << endl
- << endl << "#ACT commands: " << c.numberofacts
- << endl << "#RD + #RDA commands: " << c.numberofreads
- << endl << "#WR + #WRA commands: " << c.numberofwrites
+
+ if (bankwiseMode) {
+ cout << endl << "* Bankwise Details:";
+ for (unsigned i = 0; i < nbrofBanks; i++) {
+ cout << endl << "## @ Bank " << i << fixed
+ << endl << " #ACT commands: " << c.numberofactsBanks[i]
+ << endl << " #RD + #RDA commands: " << c.numberofreadsBanks[i]
+ << endl << " #WR + #WRA commands: " << c.numberofwritesBanks[i]
+ << endl << " #PRE (+ PREA) commands: " << c.numberofpresBanks[i];
+ }
+ cout << endl;
+ }
+
+ cout << endl << "* Trace Details:" << fixed << endl
+ << endl << "#ACT commands: " << sum(c.numberofactsBanks)
+ << endl << "#RD + #RDA commands: " << sum(c.numberofreadsBanks)
+ << endl << "#WR + #WRA commands: " << sum(c.numberofwritesBanks)
/* #PRE commands (precharge all counts a number of #PRE commands equal to the number of active banks) */
- << endl << "#PRE (+ PREA) commands: " << c.numberofpres
+ << endl << "#PRE (+ PREA) commands: " << sum(c.numberofpresBanks)
<< endl << "#REF commands: " << c.numberofrefs
+ << endl << "#REFB commands: " << sum(c.numberofrefbBanks)
<< endl << "#Active Cycles: " << c.actcycles
<< endl << " #Active Idle Cycles: " << c.idlecycles_act
<< endl << " #Active Power-Up Cycles: " << c.pup_act_cycles
@@ -300,6 +434,38 @@ void MemoryPowerModel::power_print(const MemorySpecification& memSpec, int term,
<< endl << "Total Trace Length (clock cycles): " << total_cycles
<< endl << "----------------------------------------" << endl;
+ if (bankwiseMode) {
+ cout << endl << "* Bankwise Details:";
+ for (unsigned i = 0; i < nbrofBanks; i++) {
+ cout << endl << "## @ Bank " << i << fixed
+ << endl << " ACT Cmd Energy: " << energy.act_energy_banks[i] << eUnit
+ << endl << " PRE Cmd Energy: " << energy.pre_energy_banks[i] << eUnit
+ << endl << " RD Cmd Energy: " << energy.read_energy_banks[i] << eUnit
+ << endl << " WR Cmd Energy: " << energy.write_energy_banks[i] << eUnit
+ << endl << " Auto-Refresh Energy: " << energy.ref_energy_banks[i] << eUnit
+ << endl << " Bankwise-Refresh Energy: " << energy.refb_energy_banks[i] << eUnit
+ << endl << " ACT Stdby Energy: " << nRanksDouble * energy.act_stdby_energy_banks[i] << eUnit
+ << endl << " PRE Stdby Energy: " << nRanksDouble * energy.pre_stdby_energy_banks[i] << eUnit
+ << endl << " Active Idle Energy: "<< nRanksDouble * energy.idle_energy_act_banks[i] << eUnit
+ << endl << " Precharge Idle Energy: "<< nRanksDouble * energy.idle_energy_pre_banks[i] << eUnit
+ << endl << " Fast-Exit Active Power-Down Energy: "<< nRanksDouble * energy.f_act_pd_energy_banks[i] << eUnit
+ << endl << " Fast-Exit Precharged Power-Down Energy: "<< nRanksDouble * energy.f_pre_pd_energy_banks[i] << eUnit
+ << endl << " Slow-Exit Active Power-Down Energy: "<< nRanksDouble * energy.s_act_pd_energy_banks[i] << eUnit
+ << endl << " Slow-Exit Precharged Power-Down Energy: "<< nRanksDouble * energy.s_pre_pd_energy_banks[i] << eUnit
+ << endl << " Self-Refresh Energy: "<< nRanksDouble * energy.sref_energy_banks[i] << eUnit
+ << endl << " Slow-Exit Active Power-Down Energy during Auto-Refresh cycles in Self-Refresh: "<< nRanksDouble * energy.sref_ref_act_energy_banks[i] << eUnit
+ << endl << " Slow-Exit Precharged Power-Down Energy during Auto-Refresh cycles in Self-Refresh: " << nRanksDouble * energy.sref_ref_pre_energy_banks[i] << eUnit
+ << endl << " Self-Refresh Power-Up Energy: "<< nRanksDouble * energy.spup_energy_banks[i] << eUnit
+ << endl << " Active Stdby Energy during Auto-Refresh cycles in Self-Refresh Power-Up: "<< nRanksDouble * energy.spup_ref_act_energy_banks[i] << eUnit
+ << endl << " Precharge Stdby Energy during Auto-Refresh cycles in Self-Refresh Power-Up: "<< nRanksDouble * energy.spup_ref_pre_energy_banks[i] << eUnit
+ << endl << " Active Power-Up Energy: "<< nRanksDouble * energy.pup_act_energy_banks[i] << eUnit
+ << endl << " Precharged Power-Up Energy: "<< nRanksDouble * energy.pup_pre_energy_banks[i] << eUnit
+ << endl << " Total Energy: "<< energy.total_energy_banks[i] << eUnit
+ << endl;
+ }
+ cout << endl;
+ }
+
cout.precision(2);
cout << endl << "* Trace Power and Energy Estimates:" << endl
<< endl << "ACT Cmd Energy: " << energy.act_energy << eUnit
@@ -308,7 +474,7 @@ void MemoryPowerModel::power_print(const MemorySpecification& memSpec, int term,
<< endl << "WR Cmd Energy: " << energy.write_energy << eUnit;
if (term) {
- cout << "RD I/O Energy: " << energy.read_io_energy << eUnit << endl;
+ cout << endl << "RD I/O Energy: " << energy.read_io_energy << eUnit << endl;
// No Termination for LPDDR/2/3 and DDR memories
if (memSpec.memArchSpec.termination) {
cout << "WR Termination Energy: " << energy.write_term_energy << eUnit << endl;
@@ -320,8 +486,6 @@ void MemoryPowerModel::power_print(const MemorySpecification& memSpec, int term,
}
}
- double nRanksDouble = static_cast<double>(nRanks);
-
cout << "ACT Stdby Energy: " << nRanksDouble * energy.act_stdby_energy << eUnit
<< endl << " Active Idle Energy: " << nRanksDouble * energy.idle_energy_act << eUnit
<< endl << " Active Power-Up Energy: " << nRanksDouble * energy.pup_act_energy << eUnit
@@ -340,6 +504,7 @@ void MemoryPowerModel::power_print(const MemorySpecification& memSpec, int term,
<< endl << " Slow-Exit Precharged Power-Down Energy: " << nRanksDouble * energy.s_pre_pd_energy << eUnit
<< endl << " Slow-Exit Precharged Power-Down Energy during Auto-Refresh cycles in Self-Refresh: " << nRanksDouble * energy.sref_ref_pre_energy << eUnit
<< endl << "Auto-Refresh Energy: " << energy.ref_energy << eUnit
+ << endl << "Bankwise-Refresh Energy: " << sum(energy.refb_energy_banks) << eUnit
<< endl << "Self-Refresh Energy: " << nRanksDouble * energy.sref_energy << eUnit
<< endl << "----------------------------------------"
<< endl << "Total Trace Energy: " << energy.total_energy << eUnit
@@ -364,6 +529,51 @@ double MemoryPowerModel::engy_sref(double idd6, double idd3n, double idd5,
return sref_energy;
}
+// Self-refresh active energy estimation per banks
+double MemoryPowerModel::engy_sref_banks(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 esharedPASR, const MemBankWiseParams& bwPowerParams,
+ unsigned bnkIdx, int64_t nbrofBanks)
+{
+ // Bankwise Self-refresh energy
+ double sref_energy_banks;
+ // Dynamic componenents for PASR energy varying based on PASR mode
+ double iddsigmaDynBanks;
+ double pasr_energy_dyn;
+ // This component is distributed among all banks
+ double sref_energy_shared;
+ //Is PASR Active
+ if (bwPowerParams.flgPASR){
+ sref_energy_shared = (((idd5 - idd3n) * (sref_ref_act_cycles
+ + spup_ref_act_cycles + sref_ref_pre_cycles + spup_ref_pre_cycles)) * vdd * clk)
+ / static_cast<double>(nbrofBanks);
+ //if the bank is active under current PASR mode
+ if (bwPowerParams.isBankActiveInPasr(bnkIdx)){
+ // Distribute the sref energy to the active banks
+ iddsigmaDynBanks = (static_cast<double>(100 - bwPowerParams.bwPowerFactSigma) / (100.0 * static_cast<double>(nbrofBanks))) * idd6;
+ pasr_energy_dyn = vdd * iddsigmaDynBanks * sref_cycles;
+ // Add the static components
+ sref_energy_banks = sref_energy_shared + pasr_energy_dyn + (esharedPASR /static_cast<double>(nbrofBanks));
+
+ }else{
+ sref_energy_banks = (esharedPASR /static_cast<double>(nbrofBanks));
+ }
+ }
+ //When PASR is not active total all the banks are in Self-Refresh. Thus total Self-Refresh energy is distributed across all banks
+ else{
+
+
+ sref_energy_banks = (((idd6 * sref_cycles) + ((idd5 - idd3n) * (sref_ref_act_cycles
+ + spup_ref_act_cycles + sref_ref_pre_cycles + spup_ref_pre_cycles)))
+ * vdd * clk)
+ / static_cast<double>(nbrofBanks);
+ }
+ return sref_energy_banks;
+}
+
+
// 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(const MemorySpecification& memSpec)
@@ -397,3 +607,4 @@ double EnergyDomain::calcTivEnergy(int64_t cycles, double current) const
{
return static_cast<double>(cycles) * clkPeriod * current * voltage;
}
+