44a45
> * Radhika Jagtap
97c98,99
< nextReqTime(0), activeRank(0), timeStampOffset(0)
---
> nextReqTime(0), activeRank(0), timeStampOffset(0),
> lastStatsResetTick(0)
745c747
< if (ranks[dram_pkt->rank]->isAvailable()) {
---
> if (ranks[dram_pkt->rank]->inRefIdleState()) {
758c760
< if (ranks[dram_pkt->rank]->isAvailable()) {
---
> if (ranks[dram_pkt->rank]->inRefIdleState()) {
804,805c806,808
< // check if rank is available, if not, jump to the next packet
< if (dram_pkt->rankRef.isAvailable()) {
---
> // check if rank is not doing a refresh and thus is available, if not,
> // jump to the next packet
> if (dram_pkt->rankRef.inRefIdleState()) {
1271c1274
< if (!r->isAvailable()) {
---
> if (!r->inRefIdleState()) {
1388c1391
< assert(dram_pkt->rankRef.isAvailable());
---
> assert(dram_pkt->rankRef.inRefIdleState());
1445,1448c1448,1452
< // if no writes to an available rank are found then return.
< // There could be reads to the available ranks. However, to avoid
< // adding more complexity to the code, return at this point and wait
< // for a refresh event to kick things into action again.
---
> // if there are no writes to a rank that is available to service
> // requests (i.e. rank is in refresh idle state) are found then
> // return. There could be reads to the available ranks. However, to
> // avoid adding more complexity to the code, return at this point and
> // wait for a refresh event to kick things into action again.
1453c1457
< assert(dram_pkt->rankRef.isAvailable());
---
> assert(dram_pkt->rankRef.inRefIdleState());
1545c1549
< if (p->rankRef.isAvailable())
---
> if (p->rankRef.inRefIdleState())
1559c1563
< assert(ranks[i]->isAvailable());
---
> assert(ranks[i]->inRefIdleState());
2181c2185
< // set refresh state to REF_SREF_EXIT, ensuring isAvailable
---
> // set refresh state to REF_SREF_EXIT, ensuring inRefIdleState
2238,2246c2242,2247
< // update the counters for DRAMPower, passing false to
< // indicate that this is not the last command in the
< // list. DRAMPower requires this information for the
< // correct calculation of the background energy at the end
< // of the simulation. Ideally we would want to call this
< // function with true once at the end of the
< // simulation. However, the discarded energy is extremly
< // small and does not effect the final results.
< power.powerlib.updateCounters(false);
---
> // Call the function that calculates window energy at intermediate update
> // events like at refresh, stats dump as well as at simulation exit.
> // Window starts at the last time the calcWindowEnergy function was called
> // and is upto current time.
> power.powerlib.calcWindowEnergy(divCeil(curTick(), memory.tCK) -
> memory.timeStampOffset);
2248,2249c2249,2250
< // call the energy function
< power.powerlib.calcEnergy();
---
> // Get the energy from DRAMPower
> Data::MemoryPowerModel::Energy energy = power.powerlib.getEnergy();
2251,2255c2252,2263
< // Get the energy and power from DRAMPower
< Data::MemoryPowerModel::Energy energy =
< power.powerlib.getEnergy();
< Data::MemoryPowerModel::Power rank_power =
< power.powerlib.getPower();
---
> // The energy components inside the power lib are calculated over
> // the window so accumulate into the corresponding gem5 stat
> actEnergy += energy.act_energy * memory.devicesPerRank;
> preEnergy += energy.pre_energy * memory.devicesPerRank;
> readEnergy += energy.read_energy * memory.devicesPerRank;
> writeEnergy += energy.write_energy * memory.devicesPerRank;
> refreshEnergy += energy.ref_energy * memory.devicesPerRank;
> actBackEnergy += energy.act_stdby_energy * memory.devicesPerRank;
> preBackEnergy += energy.pre_stdby_energy * memory.devicesPerRank;
> actPowerDownEnergy += energy.f_act_pd_energy * memory.devicesPerRank;
> prePowerDownEnergy += energy.f_pre_pd_energy * memory.devicesPerRank;
> selfRefreshEnergy += energy.sref_energy * memory.devicesPerRank;
2257,2268c2265,2275
< actEnergy = energy.act_energy * memory.devicesPerRank;
< preEnergy = energy.pre_energy * memory.devicesPerRank;
< readEnergy = energy.read_energy * memory.devicesPerRank;
< writeEnergy = energy.write_energy * memory.devicesPerRank;
< refreshEnergy = energy.ref_energy * memory.devicesPerRank;
< actBackEnergy = energy.act_stdby_energy * memory.devicesPerRank;
< preBackEnergy = energy.pre_stdby_energy * memory.devicesPerRank;
< actPowerDownEnergy = energy.f_act_pd_energy * memory.devicesPerRank;
< prePowerDownEnergy = energy.f_pre_pd_energy * memory.devicesPerRank;
< selfRefreshEnergy = energy.sref_energy * memory.devicesPerRank;
< totalEnergy = energy.total_energy * memory.devicesPerRank;
< averagePower = rank_power.average_power * memory.devicesPerRank;
---
> // Accumulate window energy into the total energy.
> totalEnergy += energy.window_energy * memory.devicesPerRank;
> // Average power must not be accumulated but calculated over the time
> // since last stats reset. SimClock::Frequency is tick period not tick
> // frequency.
> // energy (pJ) 1e-9
> // power (mW) = ----------- * ----------
> // time (tick) tick_frequency
> averagePower = (totalEnergy.value() /
> (curTick() - memory.lastStatsResetTick)) *
> (SimClock::Frequency / 1000000000.0);
2274c2281
< DPRINTF(DRAM,"Computing final stats\n");
---
> DPRINTF(DRAM,"Computing stats due to a dump callback\n");
2276,2279d2282
< // Force DRAM power to update counters based on time spent in
< // current state up to curTick()
< cmdList.push_back(Command(MemCommand::NOP, 0, curTick()));
<
2289a2293,2302
> DRAMCtrl::Rank::resetStats() {
> // The only way to clear the counters in DRAMPower is to call
> // calcWindowEnergy function as that then calls clearCounters. The
> // clearCounters method itself is private.
> power.powerlib.calcWindowEnergy(divCeil(curTick(), memory.tCK) -
> memory.timeStampOffset);
>
> }
>
> void
2357a2371
> registerResetCallback(new RankResetCallback(this));
2369a2384,2385
> registerResetCallback(new MemResetCallback(this));
>
2675,2677c2691,2695
< // then verify that the power state is IDLE
< // ensuring all banks are closed and rank is not in a low power state
< all_ranks_drained = r->inPwrIdleState() && all_ranks_drained;
---
> // then verify that the power state is IDLE ensuring all banks are
> // closed and rank is not in a low power state. Also verify that rank
> // is idle from a refresh point of view.
> all_ranks_drained = r->inPwrIdleState() && r->inRefIdleState() &&
> all_ranks_drained;