Deleted Added
sdiff udiff text old ( 12084:5a3769ff3d55 ) new ( 12266:63b8da9eeca4 )
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

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

37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Andreas Hansson
41 * Ani Udipi
42 * Neha Agarwal
43 * Omar Naji
44 * Wendy Elsasser
45 * Radhika Jagtap
46 */
47
48#include "mem/dram_ctrl.hh"
49
50#include "base/bitfield.hh"
51#include "base/trace.hh"
52#include "debug/DRAM.hh"
53#include "debug/DRAMPower.hh"

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

90 tRRD_L(p->tRRD_L), tXAW(p->tXAW), tXP(p->tXP), tXS(p->tXS),
91 activationLimit(p->activation_limit),
92 memSchedPolicy(p->mem_sched_policy), addrMapping(p->addr_mapping),
93 pageMgmt(p->page_policy),
94 maxAccessesPerRow(p->max_accesses_per_row),
95 frontendLatency(p->static_frontend_latency),
96 backendLatency(p->static_backend_latency),
97 busBusyUntil(0), prevArrival(0),
98 nextReqTime(0), activeRank(0), timeStampOffset(0),
99 lastStatsResetTick(0)
100{
101 // sanity check the ranks since we rely on bit slicing for the
102 // address decoding
103 fatal_if(!isPowerOf2(ranksPerChannel), "DRAM rank count of %d is not "
104 "allowed, must be a power of two\n", ranksPerChannel);
105
106 fatal_if(!isPowerOf2(burstSize), "DRAM burst size %d is not allowed, "
107 "must be a power of two\n", burstSize);

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

739 // FCFS, this method does nothing
740 assert(!queue.empty());
741
742 // bool to indicate if a packet to an available rank is found
743 bool found_packet = false;
744 if (queue.size() == 1) {
745 DRAMPacket* dram_pkt = queue.front();
746 // available rank corresponds to state refresh idle
747 if (ranks[dram_pkt->rank]->inRefIdleState()) {
748 found_packet = true;
749 DPRINTF(DRAM, "Single request, going to a free rank\n");
750 } else {
751 DPRINTF(DRAM, "Single request, going to a busy rank\n");
752 }
753 return found_packet;
754 }
755
756 if (memSchedPolicy == Enums::fcfs) {
757 // check if there is a packet going to a free rank
758 for (auto i = queue.begin(); i != queue.end() ; ++i) {
759 DRAMPacket* dram_pkt = *i;
760 if (ranks[dram_pkt->rank]->inRefIdleState()) {
761 queue.erase(i);
762 queue.push_front(dram_pkt);
763 found_packet = true;
764 break;
765 }
766 }
767 } else if (memSchedPolicy == Enums::frfcfs) {
768 found_packet = reorderQueue(queue, extra_col_delay);

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

798 // time we need to issue a column command to be seamless
799 const Tick min_col_at = std::max(busBusyUntil - tCL + extra_col_delay,
800 curTick());
801
802 for (auto i = queue.begin(); i != queue.end() ; ++i) {
803 DRAMPacket* dram_pkt = *i;
804 const Bank& bank = dram_pkt->bankRef;
805
806 // check if rank is not doing a refresh and thus is available, if not,
807 // jump to the next packet
808 if (dram_pkt->rankRef.inRefIdleState()) {
809 // check if it is a row hit
810 if (bank.openRow == dram_pkt->row) {
811 // no additional rank-to-rank or same bank-group
812 // delays, or we switched read/write and might as well
813 // go for the row hit
814 if (bank.colAllowedAt <= min_col_at) {
815 // FCFS within the hits, giving priority to
816 // commands that can issue seamlessly, without

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

1266 }
1267}
1268
1269void
1270DRAMCtrl::processNextReqEvent()
1271{
1272 int busyRanks = 0;
1273 for (auto r : ranks) {
1274 if (!r->inRefIdleState()) {
1275 if (r->pwrState != PWR_SREF) {
1276 // rank is busy refreshing
1277 DPRINTF(DRAMState, "Rank %d is not available\n", r->rank);
1278 busyRanks++;
1279
1280 // let the rank know that if it was waiting to drain, it
1281 // is now done and ready to proceed
1282 r->checkDrainDone();

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

1383 // at this point. There could be writes to the available ranks
1384 // which are above the required threshold. However, to
1385 // avoid adding more complexity to the code, return and wait
1386 // for a refresh event to kick things into action again.
1387 if (!found_read)
1388 return;
1389
1390 DRAMPacket* dram_pkt = readQueue.front();
1391 assert(dram_pkt->rankRef.inRefIdleState());
1392
1393 // here we get a bit creative and shift the bus busy time not
1394 // just the tWTR, but also a CAS latency to capture the fact
1395 // that we are allowed to prepare a new bank, but not issue a
1396 // read command until after tWTR, in essence we capture a
1397 // bubble on the data bus that is tWTR + tCL
1398 if (switched_cmd_type && dram_pkt->rank == activeRank) {
1399 busBusyUntil += tWTR + tCL;

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

1440 // bool to check if write to free rank is found
1441 bool found_write = false;
1442
1443 // If we are changing command type, incorporate the minimum
1444 // bus turnaround delay
1445 found_write = chooseNext(writeQueue,
1446 switched_cmd_type ? std::min(tRTW, tCS) : 0);
1447
1448 // if there are no writes to a rank that is available to service
1449 // requests (i.e. rank is in refresh idle state) are found then
1450 // return. There could be reads to the available ranks. However, to
1451 // avoid adding more complexity to the code, return at this point and
1452 // wait for a refresh event to kick things into action again.
1453 if (!found_write)
1454 return;
1455
1456 DRAMPacket* dram_pkt = writeQueue.front();
1457 assert(dram_pkt->rankRef.inRefIdleState());
1458 // sanity check
1459 assert(dram_pkt->size <= burstSize);
1460
1461 // add a bubble to the data bus, as defined by the
1462 // tRTW when access is to the same rank as previous burst
1463 // Different rank timing is handled with tCS, which is
1464 // applied to colAllowedAt
1465 if (switched_cmd_type && dram_pkt->rank == activeRank) {

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

1541 // Flag condition when bank can be opened without incurring additional
1542 // delay on the data bus
1543 bool hidden_bank_prep = false;
1544
1545 // determine if we have queued transactions targetting the
1546 // bank in question
1547 vector<bool> got_waiting(ranksPerChannel * banksPerRank, false);
1548 for (const auto& p : queue) {
1549 if (p->rankRef.inRefIdleState())
1550 got_waiting[p->bankId] = true;
1551 }
1552
1553 // Find command with optimal bank timing
1554 // Will prioritize commands that can issue seamlessly.
1555 for (int i = 0; i < ranksPerChannel; i++) {
1556 for (int j = 0; j < banksPerRank; j++) {
1557 uint16_t bank_id = i * banksPerRank + j;
1558
1559 // if we have waiting requests for the bank, and it is
1560 // amongst the first available, update the mask
1561 if (got_waiting[bank_id]) {
1562 // make sure this rank is not currently refreshing.
1563 assert(ranks[i]->inRefIdleState());
1564 // simplistic approximation of when the bank can issue
1565 // an activate, ignoring any rank-to-rank switching
1566 // cost in this calculation
1567 Tick act_at = ranks[i]->banks[j].openRow == Bank::NO_ROW ?
1568 std::max(ranks[i]->banks[j].actAllowedAt, curTick()) :
1569 std::max(ranks[i]->banks[j].preAllowedAt, curTick()) + tRP;
1570
1571 // When is the earliest the R/W burst can issue?

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

2177
2178 // go back to REF event and close banks
2179 refreshState = REF_PRE;
2180 schedule(refreshEvent, curTick());
2181 }
2182 } else if (pwrState == PWR_IDLE) {
2183 DPRINTF(DRAMState, "All banks precharged\n");
2184 if (prev_state == PWR_SREF) {
2185 // set refresh state to REF_SREF_EXIT, ensuring inRefIdleState
2186 // continues to return false during tXS after SREF exit
2187 // Schedule a refresh which kicks things back into action
2188 // when it finishes
2189 refreshState = REF_SREF_EXIT;
2190 schedule(refreshEvent, curTick() + memory.tXS);
2191 } else {
2192 // if we have a pending refresh, and are now moving to
2193 // the idle state, directly transition to a refresh

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

2234
2235void
2236DRAMCtrl::Rank::updatePowerStats()
2237{
2238 // All commands up to refresh have completed
2239 // flush cmdList to DRAMPower
2240 flushCmdList();
2241
2242 // Call the function that calculates window energy at intermediate update
2243 // events like at refresh, stats dump as well as at simulation exit.
2244 // Window starts at the last time the calcWindowEnergy function was called
2245 // and is upto current time.
2246 power.powerlib.calcWindowEnergy(divCeil(curTick(), memory.tCK) -
2247 memory.timeStampOffset);
2248
2249 // Get the energy from DRAMPower
2250 Data::MemoryPowerModel::Energy energy = power.powerlib.getEnergy();
2251
2252 // The energy components inside the power lib are calculated over
2253 // the window so accumulate into the corresponding gem5 stat
2254 actEnergy += energy.act_energy * memory.devicesPerRank;
2255 preEnergy += energy.pre_energy * memory.devicesPerRank;
2256 readEnergy += energy.read_energy * memory.devicesPerRank;
2257 writeEnergy += energy.write_energy * memory.devicesPerRank;
2258 refreshEnergy += energy.ref_energy * memory.devicesPerRank;
2259 actBackEnergy += energy.act_stdby_energy * memory.devicesPerRank;
2260 preBackEnergy += energy.pre_stdby_energy * memory.devicesPerRank;
2261 actPowerDownEnergy += energy.f_act_pd_energy * memory.devicesPerRank;
2262 prePowerDownEnergy += energy.f_pre_pd_energy * memory.devicesPerRank;
2263 selfRefreshEnergy += energy.sref_energy * memory.devicesPerRank;
2264
2265 // Accumulate window energy into the total energy.
2266 totalEnergy += energy.window_energy * memory.devicesPerRank;
2267 // Average power must not be accumulated but calculated over the time
2268 // since last stats reset. SimClock::Frequency is tick period not tick
2269 // frequency.
2270 // energy (pJ) 1e-9
2271 // power (mW) = ----------- * ----------
2272 // time (tick) tick_frequency
2273 averagePower = (totalEnergy.value() /
2274 (curTick() - memory.lastStatsResetTick)) *
2275 (SimClock::Frequency / 1000000000.0);
2276}
2277
2278void
2279DRAMCtrl::Rank::computeStats()
2280{
2281 DPRINTF(DRAM,"Computing stats due to a dump callback\n");
2282
2283 // Update the stats
2284 updatePowerStats();
2285
2286 // final update of power state times
2287 pwrStateTime[pwrState] += (curTick() - pwrStateTick);
2288 pwrStateTick = curTick();
2289
2290}
2291
2292void
2293DRAMCtrl::Rank::resetStats() {
2294 // The only way to clear the counters in DRAMPower is to call
2295 // calcWindowEnergy function as that then calls clearCounters. The
2296 // clearCounters method itself is private.
2297 power.powerlib.calcWindowEnergy(divCeil(curTick(), memory.tCK) -
2298 memory.timeStampOffset);
2299
2300}
2301
2302void
2303DRAMCtrl::Rank::regStats()
2304{
2305 using namespace Stats;
2306
2307 pwrStateTime
2308 .init(6)
2309 .name(name() + ".memoryStateTime")
2310 .desc("Time in different power states");

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

2363 .name(name() + ".averagePower")
2364 .desc("Core power per rank (mW)");
2365
2366 totalIdleTime
2367 .name(name() + ".totalIdleTime")
2368 .desc("Total Idle time Per DRAM Rank");
2369
2370 registerDumpCallback(new RankDumpCallback(this));
2371 registerResetCallback(new RankResetCallback(this));
2372}
2373void
2374DRAMCtrl::regStats()
2375{
2376 using namespace Stats;
2377
2378 AbstractMemory::regStats();
2379
2380 for (auto r : ranks) {
2381 r->regStats();
2382 }
2383
2384 registerResetCallback(new MemResetCallback(this));
2385
2386 readReqs
2387 .name(name() + ".readReqs")
2388 .desc("Number of read requests accepted");
2389
2390 writeReqs
2391 .name(name() + ".writeReqs")
2392 .desc("Number of write requests accepted");
2393

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

2683}
2684
2685bool
2686DRAMCtrl::allRanksDrained() const
2687{
2688 // true until proven false
2689 bool all_ranks_drained = true;
2690 for (auto r : ranks) {
2691 // then verify that the power state is IDLE ensuring all banks are
2692 // closed and rank is not in a low power state. Also verify that rank
2693 // is idle from a refresh point of view.
2694 all_ranks_drained = r->inPwrIdleState() && r->inRefIdleState() &&
2695 all_ranks_drained;
2696 }
2697 return all_ranks_drained;
2698}
2699
2700void
2701DRAMCtrl::drainResume()
2702{
2703 if (!isTimingMode && system()->isTimingMode()) {

--- 61 unchanged lines hidden ---