dram_ctrl.cc (11675:60d18201148d) dram_ctrl.cc (11676:8a882e297eb2)
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 &&
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()) {
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
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
1291 if (drainState() == DrainState::Draining &&
1294 if (drainState() == DrainState::Draining &&
1292 respQueue.empty()) {
1295 respQueue.empty() && allRanksDrained()) {
1293
1294 DPRINTF(Drain, "DRAM controller done draining\n");
1295 signalDrainDone();
1296 }
1297
1298 // nothing to do, not even any point in scheduling an
1299 // event for the next request
1300 return;

--- 232 unchanged lines hidden (view full) ---

1533 // precharge
1534 schedule(refreshEvent, ref_tick);
1535}
1536
1537void
1538DRAMCtrl::Rank::suspend()
1539{
1540 deschedule(refreshEvent);
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();
1541}
1542
1543void
1544DRAMCtrl::Rank::checkDrainDone()
1545{
1546 // if this rank was waiting to drain it is now able to proceed to
1547 // precharge
1548 if (refreshState == REF_DRAIN) {

--- 154 unchanged lines hidden (view full) ---

1703
1704 for (auto &b : banks) {
1705 b.actAllowedAt = ref_done_at;
1706 }
1707
1708 // at the moment this affects all ranks
1709 cmdList.push_back(Command(MemCommand::REF, 0, curTick()));
1710
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
1711 // All commands up to refresh have completed
1712 // flush cmdList to DRAMPower
1713 flushCmdList();
1714
1715 // update the counters for DRAMPower, passing false to
1716 // indicate that this is not the last command in the
1717 // list. DRAMPower requires this information for the
1718 // correct calculation of the background energy at the end
1719 // of the simulation. Ideally we would want to call this
1720 // function with true once at the end of the
1721 // simulation. However, the discarded energy is extremly
1722 // small and does not effect the final results.
1723 power.powerlib.updateCounters(false);
1724
1725 // call the energy function
1726 power.powerlib.calcEnergy();
1727
1728 // Update the stats
1729 updatePowerStats();
1730
1731 DPRINTF(DRAMPower, "%llu,REF,0,%d\n", divCeil(curTick(), memory.tCK) -
1732 memory.timeStampOffset, rank);
1733
1734 // make sure we did not wait so long that we cannot make up
1735 // for it

--- 92 unchanged lines hidden (view full) ---

1828 assert(refreshState == REF_RUN);
1829 processRefreshEvent();
1830 }
1831}
1832
1833void
1834DRAMCtrl::Rank::updatePowerStats()
1835{
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
1836 // Get the energy and power from DRAMPower
1837 Data::MemoryPowerModel::Energy energy =
1838 power.powerlib.getEnergy();
1839 Data::MemoryPowerModel::Power rank_power =
1840 power.powerlib.getPower();
1841
1842 actEnergy = energy.act_energy * memory.devicesPerRank;
1843 preEnergy = energy.pre_energy * memory.devicesPerRank;

--- 333 unchanged lines hidden (view full) ---

2177 }
2178}
2179
2180DrainState
2181DRAMCtrl::drain()
2182{
2183 // if there is anything in any of our internal queues, keep track
2184 // of that as well
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
2185 if (!(writeQueue.empty() && readQueue.empty() && respQueue.empty())) {
2191 if (!(writeQueue.empty() && readQueue.empty() && respQueue.empty() &&
2192 allRanksDrained())) {
2193
2186 DPRINTF(Drain, "DRAM controller not drained, write: %d, read: %d,"
2187 " resp: %d\n", writeQueue.size(), readQueue.size(),
2188 respQueue.size());
2189
2190 // the only part that is not drained automatically over time
2191 // is the write queue, thus kick things into action if needed
2192 if (!writeQueue.empty() && !nextReqEvent.scheduled()) {
2193 schedule(nextReqEvent, curTick());
2194 }
2195 return DrainState::Draining;
2196 } else {
2197 return DrainState::Drained;
2198 }
2199}
2200
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
2201void
2202DRAMCtrl::drainResume()
2203{
2204 if (!isTimingMode && system()->isTimingMode()) {
2205 // if we switched to timing mode, kick things into action,
2206 // and behave as if we restored from a checkpoint
2207 startup();
2208 } else if (isTimingMode && !system()->isTimingMode()) {

--- 57 unchanged lines hidden ---
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 ---