1/* 2 * Copyright (c) 2010-2014 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 --- 31 unchanged lines hidden (view full) --- 40 * Authors: Andreas Hansson 41 * Ani Udipi 42 * Neha Agarwal 43 */ 44 45#include "base/bitfield.hh" 46#include "base/trace.hh" 47#include "debug/DRAM.hh" |
48#include "debug/DRAMState.hh" |
49#include "debug/Drain.hh" 50#include "mem/dram_ctrl.hh" 51#include "sim/system.hh" 52 53using namespace std; 54 55DRAMCtrl::DRAMCtrl(const DRAMCtrlParams* p) : 56 AbstractMemory(p), 57 port(name() + ".port", *this), 58 retryRdReq(false), retryWrReq(false), 59 rowHitFlag(false), busState(READ), |
60 nextReqEvent(this), respondEvent(this), activateEvent(this), 61 prechargeEvent(this), refreshEvent(this), powerEvent(this), 62 drainManager(NULL), |
63 deviceBusWidth(p->device_bus_width), burstLength(p->burst_length), 64 deviceRowBufferSize(p->device_rowbuffer_size), 65 devicesPerRank(p->devices_per_rank), 66 burstSize((devicesPerRank * burstLength * deviceBusWidth) / 8), 67 rowBufferSize(devicesPerRank * deviceRowBufferSize), 68 columnsPerRowBuffer(rowBufferSize / burstSize), 69 ranksPerChannel(p->ranks_per_channel), 70 banksPerRank(p->banks_per_rank), channels(p->channels), rowsPerBank(0), --- 7 unchanged lines hidden (view full) --- 78 tRCD(p->tRCD), tCL(p->tCL), tRP(p->tRP), tRAS(p->tRAS), 79 tRFC(p->tRFC), tREFI(p->tREFI), tRRD(p->tRRD), 80 tXAW(p->tXAW), activationLimit(p->activation_limit), 81 memSchedPolicy(p->mem_sched_policy), addrMapping(p->addr_mapping), 82 pageMgmt(p->page_policy), 83 maxAccessesPerRow(p->max_accesses_per_row), 84 frontendLatency(p->static_frontend_latency), 85 backendLatency(p->static_backend_latency), |
86 busBusyUntil(0), refreshDueAt(0), refreshState(REF_IDLE), 87 pwrStateTrans(PWR_IDLE), pwrState(PWR_IDLE), prevArrival(0), 88 nextReqTime(0), pwrStateTick(0), numBanksActive(0) |
89{ 90 // create the bank states based on the dimensions of the ranks and 91 // banks 92 banks.resize(ranksPerChannel); 93 actTicks.resize(ranksPerChannel); 94 for (size_t c = 0; c < ranksPerChannel; ++c) { 95 banks[c].resize(banksPerRank); 96 actTicks[c].resize(activationLimit, 0); --- 55 unchanged lines hidden (view full) --- 152 } 153} 154 155void 156DRAMCtrl::startup() 157{ 158 // update the start tick for the precharge accounting to the 159 // current tick |
160 pwrStateTick = curTick(); |
161 162 // shift the bus busy time sufficiently far ahead that we never 163 // have to worry about negative values when computing the time for 164 // the next request, this will add an insignificant bubble at the 165 // start of simulation 166 busBusyUntil = curTick() + tRP + tRCD + tCL; 167 168 // print the configuration of the controller --- 714 unchanged lines hidden (view full) --- 883DRAMCtrl::recordActivate(Tick act_tick, uint8_t rank, uint8_t bank, 884 uint16_t row) 885{ 886 assert(0 <= rank && rank < ranksPerChannel); 887 assert(actTicks[rank].size() == activationLimit); 888 889 DPRINTF(DRAM, "Activate at tick %d\n", act_tick); 890 |
891 // update the open row 892 assert(banks[rank][bank].openRow == Bank::NO_ROW); 893 banks[rank][bank].openRow = row; 894 895 // start counting anew, this covers both the case when we 896 // auto-precharged, and when this access is forced to 897 // precharge 898 banks[rank][bank].bytesAccessed = 0; --- 5 unchanged lines hidden (view full) --- 904 DPRINTF(DRAM, "Activate bank at tick %lld, now got %d active\n", 905 act_tick, numBanksActive); 906 907 // start by enforcing tRRD 908 for(int i = 0; i < banksPerRank; i++) { 909 // next activate must not happen before tRRD 910 banks[rank][i].actAllowedAt = act_tick + tRRD; 911 } |
912 |
913 // tRC should be added to activation tick of the bank currently accessed, 914 // where tRC = tRAS + tRP, this is just for a check as actAllowedAt for same 915 // bank is already captured by bank.freeAt and bank.tRASDoneAt 916 banks[rank][bank].actAllowedAt = act_tick + tRAS + tRP; 917 918 // next, we deal with tXAW, if the activation limit is disabled 919 // then we are done 920 if (actTicks[rank].empty()) --- 19 unchanged lines hidden (view full) --- 940 // oldest in our window of X 941 if (actTicks[rank].back() && (act_tick - actTicks[rank].back()) < tXAW) { 942 DPRINTF(DRAM, "Enforcing tXAW with X = %d, next activate no earlier " 943 "than %d\n", activationLimit, actTicks[rank].back() + tXAW); 944 for(int j = 0; j < banksPerRank; j++) 945 // next activate must not happen before end of window 946 banks[rank][j].actAllowedAt = actTicks[rank].back() + tXAW; 947 } |
948 949 // at the point when this activate takes place, make sure we 950 // transition to the active power state 951 if (!activateEvent.scheduled()) 952 schedule(activateEvent, act_tick); 953 else if (activateEvent.when() > act_tick) 954 // move it sooner in time 955 reschedule(activateEvent, act_tick); |
956} 957 958void |
959DRAMCtrl::processActivateEvent() 960{ 961 // we should transition to the active state as soon as any bank is active 962 if (pwrState != PWR_ACT) 963 // note that at this point numBanksActive could be back at 964 // zero again due to a precharge scheduled in the future 965 schedulePowerEvent(PWR_ACT, curTick()); 966} 967 968void |
969DRAMCtrl::prechargeBank(Bank& bank, Tick free_at) 970{ 971 // make sure the bank has an open row 972 assert(bank.openRow != Bank::NO_ROW); 973 974 // sample the bytes per activate here since we are closing 975 // the page 976 bytesPerActivate.sample(bank.bytesAccessed); 977 978 bank.openRow = Bank::NO_ROW; 979 980 bank.freeAt = free_at; 981 982 assert(numBanksActive != 0); 983 --numBanksActive; 984 985 DPRINTF(DRAM, "Precharged bank, done at tick %lld, now got %d active\n", 986 bank.freeAt, numBanksActive); 987 |
988 // if we look at the current number of active banks we might be 989 // tempted to think the DRAM is now idle, however this can be 990 // undone by an activate that is scheduled to happen before we 991 // would have reached the idle state, so schedule an event and 992 // rather check once we actually make it to the point in time when 993 // the (last) precharge takes place 994 if (!prechargeEvent.scheduled()) 995 schedule(prechargeEvent, free_at); 996 else if (prechargeEvent.when() < free_at) 997 reschedule(prechargeEvent, free_at); 998} 999 1000void 1001DRAMCtrl::processPrechargeEvent() 1002{ |
1003 // if we reached zero, then special conditions apply as we track 1004 // if all banks are precharged for the power models 1005 if (numBanksActive == 0) { |
1006 // we should transition to the idle state when the last bank 1007 // is precharged 1008 schedulePowerEvent(PWR_IDLE, curTick()); |
1009 } 1010} 1011 1012void 1013DRAMCtrl::doDRAMAccess(DRAMPacket* dram_pkt) 1014{ 1015 1016 DPRINTF(DRAM, "Timing access to addr %lld, rank/bank/row %d %d %d\n", --- 417 unchanged lines hidden (view full) --- 1434 return; 1435 } else { 1436 refreshState = REF_PRE; 1437 } 1438 } 1439 1440 // at this point, ensure that all banks are precharged 1441 if (refreshState == REF_PRE) { |
1442 // precharge any active bank if we are not already in the idle 1443 // state 1444 if (pwrState != PWR_IDLE) { 1445 DPRINTF(DRAM, "Precharging all\n"); 1446 for (int i = 0; i < ranksPerChannel; i++) { 1447 for (int j = 0; j < banksPerRank; j++) { 1448 if (banks[i][j].openRow != Bank::NO_ROW) { 1449 // respect both causality and any existing bank 1450 // constraints 1451 Tick free_at = 1452 std::max(std::max(banks[i][j].freeAt, 1453 banks[i][j].tRASDoneAt), 1454 curTick()) + tRP; |
1455 |
1456 prechargeBank(banks[i][j], free_at); 1457 } |
1458 } 1459 } |
1460 } else { 1461 DPRINTF(DRAM, "All banks already precharged, starting refresh\n"); 1462 1463 // go ahead and kick the power state machine into gear if 1464 // we are already idle 1465 schedulePowerEvent(PWR_REF, curTick()); |
1466 } 1467 |
1468 refreshState = REF_RUN; |
1469 assert(numBanksActive == 0); |
1470 |
1471 // wait for all banks to be precharged, at which point the 1472 // power state machine will transition to the idle state, and 1473 // automatically move to a refresh, at that point it will also 1474 // call this method to get the refresh event loop going again |
1475 return; 1476 } 1477 1478 // last but not least we perform the actual refresh 1479 if (refreshState == REF_RUN) { 1480 // should never get here with any banks active 1481 assert(numBanksActive == 0); |
1482 assert(pwrState == PWR_REF); |
1483 1484 Tick banksFree = curTick() + tRFC; 1485 1486 for (int i = 0; i < ranksPerChannel; i++) { 1487 for (int j = 0; j < banksPerRank; j++) { 1488 banks[i][j].freeAt = banksFree; 1489 } 1490 } 1491 1492 // make sure we did not wait so long that we cannot make up 1493 // for it 1494 if (refreshDueAt + tREFI < banksFree) { 1495 fatal("Refresh was delayed so long we cannot catch up\n"); 1496 } 1497 1498 // compensate for the delay in actually performing the refresh 1499 // when scheduling the next one 1500 schedule(refreshEvent, refreshDueAt + tREFI - tRP); 1501 |
1502 assert(!powerEvent.scheduled()); |
1503 |
1504 // move to the idle power state once the refresh is done, this 1505 // will also move the refresh state machine to the refresh 1506 // idle state 1507 schedulePowerEvent(PWR_IDLE, banksFree); |
1508 |
1509 DPRINTF(DRAMState, "Refresh done at %llu and next refresh at %llu\n", 1510 banksFree, refreshDueAt + tREFI); |
1511 } 1512} 1513 1514void |
1515DRAMCtrl::schedulePowerEvent(PowerState pwr_state, Tick tick) 1516{ 1517 // respect causality 1518 assert(tick >= curTick()); 1519 1520 if (!powerEvent.scheduled()) { 1521 DPRINTF(DRAMState, "Scheduling power event at %llu to state %d\n", 1522 tick, pwr_state); 1523 1524 // insert the new transition 1525 pwrStateTrans = pwr_state; 1526 1527 schedule(powerEvent, tick); 1528 } else { 1529 panic("Scheduled power event at %llu to state %d, " 1530 "with scheduled event at %llu to %d\n", tick, pwr_state, 1531 powerEvent.when(), pwrStateTrans); 1532 } 1533} 1534 1535void 1536DRAMCtrl::processPowerEvent() 1537{ 1538 // remember where we were, and for how long 1539 Tick duration = curTick() - pwrStateTick; 1540 PowerState prev_state = pwrState; 1541 1542 // update the accounting 1543 pwrStateTime[prev_state] += duration; 1544 1545 pwrState = pwrStateTrans; 1546 pwrStateTick = curTick(); 1547 1548 if (pwrState == PWR_IDLE) { 1549 DPRINTF(DRAMState, "All banks precharged\n"); 1550 1551 // if we were refreshing, make sure we start scheduling requests again 1552 if (prev_state == PWR_REF) { 1553 DPRINTF(DRAMState, "Was refreshing for %llu ticks\n", duration); 1554 assert(pwrState == PWR_IDLE); 1555 1556 // kick things into action again 1557 refreshState = REF_IDLE; 1558 assert(!nextReqEvent.scheduled()); 1559 schedule(nextReqEvent, curTick()); 1560 } else { 1561 assert(prev_state == PWR_ACT); 1562 1563 // if we have a pending refresh, and are now moving to 1564 // the idle state, direclty transition to a refresh 1565 if (refreshState == REF_RUN) { 1566 // there should be nothing waiting at this point 1567 assert(!powerEvent.scheduled()); 1568 1569 // update the state in zero time and proceed below 1570 pwrState = PWR_REF; 1571 } 1572 } 1573 } 1574 1575 // we transition to the refresh state, let the refresh state 1576 // machine know of this state update and let it deal with the 1577 // scheduling of the next power state transition as well as the 1578 // following refresh 1579 if (pwrState == PWR_REF) { 1580 DPRINTF(DRAMState, "Refreshing\n"); 1581 // kick the refresh event loop into action again, and that 1582 // in turn will schedule a transition to the idle power 1583 // state once the refresh is done 1584 assert(refreshState == REF_RUN); 1585 processRefreshEvent(); 1586 } 1587} 1588 1589void |
1590DRAMCtrl::regStats() 1591{ 1592 using namespace Stats; 1593 1594 AbstractMemory::regStats(); 1595 1596 readReqs 1597 .name(name() + ".readReqs") --- 249 unchanged lines hidden (view full) --- 1847 pageHitRate 1848 .name(name() + ".pageHitRate") 1849 .desc("Row buffer hit rate, read and write combined") 1850 .precision(2); 1851 1852 pageHitRate = (writeRowHits + readRowHits) / 1853 (writeBursts - mergedWrBursts + readBursts - servicedByWrQ) * 100; 1854 |
1855 pwrStateTime 1856 .init(5) 1857 .name(name() + ".memoryStateTime") 1858 .desc("Time in different power states"); 1859 pwrStateTime.subname(0, "IDLE"); 1860 pwrStateTime.subname(1, "REF"); 1861 pwrStateTime.subname(2, "PRE_PDN"); 1862 pwrStateTime.subname(3, "ACT"); 1863 pwrStateTime.subname(4, "ACT_PDN"); |
1864} 1865 1866void 1867DRAMCtrl::recvFunctional(PacketPtr pkt) 1868{ 1869 // rely on the abstract memory 1870 functionalAccess(pkt); 1871} --- 86 unchanged lines hidden --- |