1/* 2 * Copyright (c) 2010-2016 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 670 unchanged lines hidden (view full) --- 679 680 if (!respQueue.empty()) { 681 assert(respQueue.front()->readyTime >= curTick()); 682 assert(!respondEvent.scheduled()); 683 schedule(respondEvent, respQueue.front()->readyTime); 684 } else { 685 // if there is nothing left in any queue, signal a drain 686 if (drainState() == DrainState::Draining && |
687 writeQueue.empty() && readQueue.empty() && allRanksDrained()) { |
688 689 DPRINTF(Drain, "DRAM controller done draining\n"); 690 signalDrainDone(); 691 } 692 } 693 694 // We have made a location in the queue available at this point, 695 // so if there is a read that was forced to wait, retry now --- 587 unchanged lines hidden (view full) --- 1283 // if we are draining) 1284 if (!writeQueue.empty() && 1285 (drainState() == DrainState::Draining || 1286 writeQueue.size() > writeLowThreshold)) { 1287 1288 switch_to_writes = true; 1289 } else { 1290 // check if we are drained |
1291 // not done draining until in PWR_IDLE state 1292 // ensuring all banks are closed and 1293 // have exited low power states |
1294 if (drainState() == DrainState::Draining && |
1295 respQueue.empty() && allRanksDrained()) { |
1296 1297 DPRINTF(Drain, "DRAM controller done draining\n"); 1298 signalDrainDone(); 1299 } 1300 1301 // nothing to do, not even any point in scheduling an 1302 // event for the next request 1303 return; --- 232 unchanged lines hidden (view full) --- 1536 // precharge 1537 schedule(refreshEvent, ref_tick); 1538} 1539 1540void 1541DRAMCtrl::Rank::suspend() 1542{ 1543 deschedule(refreshEvent); |
1544 1545 // Update the stats 1546 updatePowerStats(); |
1547} 1548 1549void 1550DRAMCtrl::Rank::checkDrainDone() 1551{ 1552 // if this rank was waiting to drain it is now able to proceed to 1553 // precharge 1554 if (refreshState == REF_DRAIN) { --- 154 unchanged lines hidden (view full) --- 1709 1710 for (auto &b : banks) { 1711 b.actAllowedAt = ref_done_at; 1712 } 1713 1714 // at the moment this affects all ranks 1715 cmdList.push_back(Command(MemCommand::REF, 0, curTick())); 1716 |
1717 // Update the stats 1718 updatePowerStats(); 1719 1720 DPRINTF(DRAMPower, "%llu,REF,0,%d\n", divCeil(curTick(), memory.tCK) - 1721 memory.timeStampOffset, rank); 1722 1723 // make sure we did not wait so long that we cannot make up 1724 // for it --- 92 unchanged lines hidden (view full) --- 1817 assert(refreshState == REF_RUN); 1818 processRefreshEvent(); 1819 } 1820} 1821 1822void 1823DRAMCtrl::Rank::updatePowerStats() 1824{ |
1825 // All commands up to refresh have completed 1826 // flush cmdList to DRAMPower 1827 flushCmdList(); 1828 1829 // update the counters for DRAMPower, passing false to 1830 // indicate that this is not the last command in the 1831 // list. DRAMPower requires this information for the 1832 // correct calculation of the background energy at the end 1833 // of the simulation. Ideally we would want to call this 1834 // function with true once at the end of the 1835 // simulation. However, the discarded energy is extremly 1836 // small and does not effect the final results. 1837 power.powerlib.updateCounters(false); 1838 1839 // call the energy function 1840 power.powerlib.calcEnergy(); 1841 |
1842 // Get the energy and power from DRAMPower 1843 Data::MemoryPowerModel::Energy energy = 1844 power.powerlib.getEnergy(); 1845 Data::MemoryPowerModel::Power rank_power = 1846 power.powerlib.getPower(); 1847 1848 actEnergy = energy.act_energy * memory.devicesPerRank; 1849 preEnergy = energy.pre_energy * memory.devicesPerRank; --- 333 unchanged lines hidden (view full) --- 2183 } 2184} 2185 2186DrainState 2187DRAMCtrl::drain() 2188{ 2189 // if there is anything in any of our internal queues, keep track 2190 // of that as well |
2191 if (!(writeQueue.empty() && readQueue.empty() && respQueue.empty() && 2192 allRanksDrained())) { 2193 |
2194 DPRINTF(Drain, "DRAM controller not drained, write: %d, read: %d," 2195 " resp: %d\n", writeQueue.size(), readQueue.size(), 2196 respQueue.size()); 2197 2198 // the only part that is not drained automatically over time 2199 // is the write queue, thus kick things into action if needed 2200 if (!writeQueue.empty() && !nextReqEvent.scheduled()) { 2201 schedule(nextReqEvent, curTick()); 2202 } 2203 return DrainState::Draining; 2204 } else { 2205 return DrainState::Drained; 2206 } 2207} 2208 |
2209bool 2210DRAMCtrl::allRanksDrained() const 2211{ 2212 // true until proven false 2213 bool all_ranks_drained = true; 2214 for (auto r : ranks) { 2215 // then verify that the power state is IDLE 2216 // ensuring all banks are closed and rank is not in a low power state 2217 all_ranks_drained = r->inPwrIdleState() && all_ranks_drained; 2218 } 2219 return all_ranks_drained; 2220} 2221 |
2222void 2223DRAMCtrl::drainResume() 2224{ 2225 if (!isTimingMode && system()->isTimingMode()) { 2226 // if we switched to timing mode, kick things into action, 2227 // and behave as if we restored from a checkpoint 2228 startup(); 2229 } else if (isTimingMode && !system()->isTimingMode()) { --- 57 unchanged lines hidden --- |