1/* 2 * Copyright (c) 2010-2017 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 --- 650 unchanged lines hidden (view full) --- 659 660 // at this moment should not have transitioned to a low-power state 661 assert((dram_pkt->rankRef.pwrState != PWR_SREF) && 662 (dram_pkt->rankRef.pwrState != PWR_PRE_PDN) && 663 (dram_pkt->rankRef.pwrState != PWR_ACT_PDN)); 664 665 // track if this is the last packet before idling 666 // and that there are no outstanding commands to this rank |
667 if (dram_pkt->rankRef.isQueueEmpty() && 668 dram_pkt->rankRef.outstandingEvents == 0) { |
669 // verify that there are no events scheduled 670 assert(!dram_pkt->rankRef.activateEvent.scheduled()); 671 assert(!dram_pkt->rankRef.prechargeEvent.scheduled()); 672 673 // if coming from active state, schedule power event to 674 // active power-down else go to precharge power-down 675 DPRINTF(DRAMState, "Rank %d sleep at tick %d; current power state is " 676 "%d\n", dram_pkt->rank, curTick(), dram_pkt->rankRef.pwrState); --- 984 unchanged lines hidden (view full) --- 1661 // Update the stats 1662 updatePowerStats(); 1663 1664 // don't automatically transition back to LP state after next REF 1665 pwrStatePostRefresh = PWR_IDLE; 1666} 1667 1668bool |
1669DRAMCtrl::Rank::isQueueEmpty() const |
1670{ |
1671 // check commmands in Q based on current bus direction |
1672 bool no_queued_cmds = ((memory.busStateNext == READ) && (readEntries == 0)) 1673 || ((memory.busStateNext == WRITE) && 1674 (writeEntries == 0)); |
1675 return no_queued_cmds; |
1676} 1677 1678void 1679DRAMCtrl::Rank::checkDrainDone() 1680{ 1681 // if this rank was waiting to drain it is now able to proceed to 1682 // precharge 1683 if (refreshState == REF_DRAIN) { --- 53 unchanged lines hidden (view full) --- 1737 // precharge complete, decrement count 1738 --outstandingEvents; 1739 1740 // if we reached zero, then special conditions apply as we track 1741 // if all banks are precharged for the power models 1742 if (numBanksActive == 0) { 1743 // no reads to this rank in the Q and no pending 1744 // RD/WR or refresh commands |
1745 if (isQueueEmpty() && outstandingEvents == 0) { |
1746 // should still be in ACT state since bank still open 1747 assert(pwrState == PWR_ACT); 1748 1749 // All banks closed - switch to precharge power down state. 1750 DPRINTF(DRAMState, "Rank %d sleep at tick %d\n", 1751 rank, curTick()); 1752 powerDownSleep(PWR_PRE_PDN, curTick()); 1753 } else { --- 184 unchanged lines hidden (view full) --- 1938 assert(pwrState == PWR_REF); 1939 DPRINTF(DRAMState, "Rank %d sleeping after refresh and was in " 1940 "power state %d before refreshing\n", rank, 1941 pwrStatePostRefresh); 1942 powerDownSleep(pwrState, curTick()); 1943 1944 // Force PRE power-down if there are no outstanding commands 1945 // in Q after refresh. |
1946 } else if (isQueueEmpty()) { 1947 // still have refresh event outstanding but there should 1948 // be no other events outstanding 1949 assert(outstandingEvents == 1); |
1950 DPRINTF(DRAMState, "Rank %d sleeping after refresh but was NOT" 1951 " in a low power state before refreshing\n", rank); 1952 powerDownSleep(PWR_PRE_PDN, curTick()); 1953 1954 } else { 1955 // move to the idle power state once the refresh is done, this 1956 // will also move the refresh state machine to the refresh 1957 // idle state 1958 schedulePowerEvent(PWR_IDLE, curTick()); 1959 } 1960 } 1961 |
1962 // At this point, we have completed the current refresh. 1963 // In the SREF bypass case, we do not get to this state in the 1964 // refresh STM and therefore can always schedule next event. 1965 // Compensate for the delay in actually performing the refresh 1966 // when scheduling the next one 1967 schedule(refreshEvent, refreshDueAt - memory.tRP); |
1968 |
1969 DPRINTF(DRAMState, "Refresh done at %llu and next refresh" 1970 " at %llu\n", curTick(), refreshDueAt); |
1971 } 1972} 1973 1974void 1975DRAMCtrl::Rank::schedulePowerEvent(PowerState pwr_state, Tick tick) 1976{ 1977 // respect causality 1978 assert(tick >= curTick()); --- 30 unchanged lines hidden (view full) --- 2009 // power state. In reality tCKE is needed to enter active low power. 2010 // This is neglected here. 2011 schedulePowerEvent(pwr_state, tick); 2012 //push Command to DRAMPower 2013 cmdList.push_back(Command(MemCommand::PDN_F_PRE, 0, tick)); 2014 DPRINTF(DRAMPower, "%llu,PDN_F_PRE,0,%d\n", divCeil(tick, 2015 memory.tCK) - memory.timeStampOffset, rank); 2016 } else if (pwr_state == PWR_REF) { |
2017 // if a refresh just occurred |
2018 // transition to PRE_PDN now that all banks are closed |
2019 // precharge power down requires tCKE to enter. For simplicity 2020 // this is not considered. 2021 schedulePowerEvent(PWR_PRE_PDN, tick); 2022 //push Command to DRAMPower 2023 cmdList.push_back(Command(MemCommand::PDN_F_PRE, 0, tick)); 2024 DPRINTF(DRAMPower, "%llu,PDN_F_PRE,0,%d\n", divCeil(tick, 2025 memory.tCK) - memory.timeStampOffset, rank); 2026 } else if (pwr_state == PWR_SREF) { 2027 // should only enter SREF after PRE-PD wakeup to do a refresh 2028 assert(pwrStatePostRefresh == PWR_PRE_PDN); 2029 // self refresh requires time tCKESR to enter. For simplicity, 2030 // this is not considered. 2031 schedulePowerEvent(PWR_SREF, tick); 2032 // push Command to DRAMPower 2033 cmdList.push_back(Command(MemCommand::SREN, 0, tick)); 2034 DPRINTF(DRAMPower, "%llu,SREN,0,%d\n", divCeil(tick, 2035 memory.tCK) - memory.timeStampOffset, rank); |
2036 } 2037 // Ensure that we don't power-down and back up in same tick 2038 // Once we commit to PD entry, do it and wait for at least 1tCK 2039 // This could be replaced with tCKE if/when that is added to the model 2040 wakeUpAllowedAt = tick + memory.tCK; 2041 2042 // Transitioning to a low power state, set flag 2043 inLowPowerState = true; --- 88 unchanged lines hidden (view full) --- 2132 pwrState = pwrStateTrans; 2133 pwrStateTick = curTick(); 2134 2135 // if rank was refreshing, make sure to start scheduling requests again 2136 if (prev_state == PWR_REF) { 2137 // bus IDLED prior to REF 2138 // counter should be one for refresh command only 2139 assert(outstandingEvents == 1); |
2140 // REF complete, decrement count and go back to IDLE |
2141 --outstandingEvents; |
2142 refreshState = REF_IDLE; |
2143 2144 DPRINTF(DRAMState, "Was refreshing for %llu ticks\n", duration); |
2145 // if moving back to power-down after refresh |
2146 if (pwrState != PWR_IDLE) { |
2147 assert(pwrState == PWR_PRE_PDN); |
2148 DPRINTF(DRAMState, "Switching to power down state after refreshing" 2149 " rank %d at %llu tick\n", rank, curTick()); 2150 } |
2151 2152 // completed refresh event, ensure next request is scheduled |
2153 if (!memory.nextReqEvent.scheduled()) { |
2154 DPRINTF(DRAM, "Scheduling next request after refreshing" 2155 " rank %d\n", rank); |
2156 schedule(memory.nextReqEvent, curTick()); 2157 } |
2158 } |
2159 |
2160 if ((pwrState == PWR_ACT) && (refreshState == REF_PD_EXIT)) { 2161 // have exited ACT PD 2162 assert(prev_state == PWR_ACT_PDN); 2163 2164 // go back to REF event and close banks 2165 refreshState = REF_PRE; 2166 schedule(refreshEvent, curTick()); |
2167 } else if (pwrState == PWR_IDLE) { 2168 DPRINTF(DRAMState, "All banks precharged\n"); 2169 if (prev_state == PWR_SREF) { 2170 // set refresh state to REF_SREF_EXIT, ensuring inRefIdleState 2171 // continues to return false during tXS after SREF exit 2172 // Schedule a refresh which kicks things back into action 2173 // when it finishes 2174 refreshState = REF_SREF_EXIT; 2175 schedule(refreshEvent, curTick() + memory.tXS); 2176 } else { 2177 // if we have a pending refresh, and are now moving to |
2178 // the idle state, directly transition to, or schedule refresh |
2179 if ((refreshState == REF_PRE) || (refreshState == REF_PD_EXIT)) { 2180 // ensure refresh is restarted only after final PRE command. 2181 // do not restart refresh if controller is in an intermediate 2182 // state, after PRE_PDN exit, when banks are IDLE but an 2183 // ACT is scheduled. 2184 if (!activateEvent.scheduled()) { 2185 // there should be nothing waiting at this point 2186 assert(!powerEvent.scheduled()); |
2187 if (refreshState == REF_PD_EXIT) { 2188 // exiting PRE PD, will be in IDLE until tXP expires 2189 // and then should transition to PWR_REF state 2190 assert(prev_state == PWR_PRE_PDN); 2191 schedulePowerEvent(PWR_REF, curTick() + memory.tXP); 2192 } else if (refreshState == REF_PRE) { 2193 // can directly move to PWR_REF state and proceed below 2194 pwrState = PWR_REF; 2195 } |
2196 } else { 2197 // must have PRE scheduled to transition back to IDLE 2198 // and re-kick off refresh 2199 assert(prechargeEvent.scheduled()); 2200 } 2201 } |
2202 } |
2203 } 2204 |
2205 // transition to the refresh state and re-start refresh process 2206 // refresh state machine will schedule the next power state transition |
2207 if (pwrState == PWR_REF) { |
2208 // completed final PRE for refresh or exiting power-down |
2209 assert(refreshState == REF_PRE || refreshState == REF_PD_EXIT); |
2210 |
2211 // exited PRE PD for refresh, with no pending commands 2212 // bypass auto-refresh and go straight to SREF, where memory 2213 // will issue refresh immediately upon entry 2214 if (pwrStatePostRefresh == PWR_PRE_PDN && isQueueEmpty() && 2215 (memory.drainState() != DrainState::Draining) && 2216 (memory.drainState() != DrainState::Drained)) { 2217 DPRINTF(DRAMState, "Rank %d bypassing refresh and transitioning " 2218 "to self refresh at %11u tick\n", rank, curTick()); 2219 powerDownSleep(PWR_SREF, curTick()); 2220 2221 // Since refresh was bypassed, remove event by decrementing count 2222 assert(outstandingEvents == 1); 2223 --outstandingEvents; 2224 2225 // reset state back to IDLE temporarily until SREF is entered 2226 pwrState = PWR_IDLE; 2227 2228 // Not bypassing refresh for SREF entry |
2229 } else { |
2230 DPRINTF(DRAMState, "Refreshing\n"); 2231 2232 // there should be nothing waiting at this point 2233 assert(!powerEvent.scheduled()); 2234 2235 // kick the refresh event loop into action again, and that 2236 // in turn will schedule a transition to the idle power 2237 // state once the refresh is done |
2238 schedule(refreshEvent, curTick()); |
2239 2240 // Banks transitioned to IDLE, start REF 2241 refreshState = REF_START; |
2242 } |
2243 } |
2244 |
2245} 2246 2247void 2248DRAMCtrl::Rank::updatePowerStats() 2249{ 2250 // All commands up to refresh have completed 2251 // flush cmdList to DRAMPower 2252 flushCmdList(); --- 522 unchanged lines hidden --- |