diff options
Diffstat (limited to 'ext/drampower/src/MemoryPowerModel.cc')
-rw-r--r-- | ext/drampower/src/MemoryPowerModel.cc | 275 |
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; } + |