Deleted Added
sdiff udiff text old ( 12637:bfc3cb9c7e6c ) new ( 12705:9668a82ead4b )
full compact
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 ---