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/DRAMPower.hh" |
49#include "debug/DRAMState.hh" 50#include "debug/Drain.hh" 51#include "mem/dram_ctrl.hh" 52#include "sim/system.hh" 53 54using namespace std; 55 56DRAMCtrl::DRAMCtrl(const DRAMCtrlParams* p) : --- 721 unchanged lines hidden (view full) --- 778 // auto-precharged, and when this access is forced to 779 // precharge 780 bank.bytesAccessed = 0; 781 bank.rowAccesses = 0; 782 783 ++numBanksActive; 784 assert(numBanksActive <= banksPerRank * ranksPerChannel); 785 |
786 DPRINTF(DRAM, "Activate bank %d, rank %d at tick %lld, now got %d active\n", 787 bank.bank, bank.rank, act_tick, numBanksActive); |
788 |
789 DPRINTF(DRAMPower, "%llu,ACT,%d,%d\n", divCeil(act_tick, tCK), bank.bank, 790 bank.rank); 791 |
792 // The next access has to respect tRAS for this bank 793 bank.preAllowedAt = act_tick + tRAS; 794 795 // Respect the row-to-column command delay 796 bank.colAllowedAt = act_tick + tRCD; 797 798 // start by enforcing tRRD 799 for(int i = 0; i < banksPerRank; i++) { --- 50 unchanged lines hidden (view full) --- 850 // we should transition to the active state as soon as any bank is active 851 if (pwrState != PWR_ACT) 852 // note that at this point numBanksActive could be back at 853 // zero again due to a precharge scheduled in the future 854 schedulePowerEvent(PWR_ACT, curTick()); 855} 856 857void |
858DRAMCtrl::prechargeBank(Bank& bank, Tick pre_at, bool trace) |
859{ 860 // make sure the bank has an open row 861 assert(bank.openRow != Bank::NO_ROW); 862 863 // sample the bytes per activate here since we are closing 864 // the page 865 bytesPerActivate.sample(bank.bytesAccessed); 866 --- 4 unchanged lines hidden (view full) --- 871 872 Tick pre_done_at = pre_at + tRP; 873 874 bank.actAllowedAt = std::max(bank.actAllowedAt, pre_done_at); 875 876 assert(numBanksActive != 0); 877 --numBanksActive; 878 |
879 DPRINTF(DRAM, "Precharging bank %d, rank %d at tick %lld, now got " 880 "%d active\n", bank.bank, bank.rank, pre_at, numBanksActive); |
881 |
882 if (trace) 883 DPRINTF(DRAMPower, "%llu,PRE,%d,%d\n", divCeil(pre_at, tCK), 884 bank.bank, bank.rank); 885 |
886 // if we look at the current number of active banks we might be 887 // tempted to think the DRAM is now idle, however this can be 888 // undone by an activate that is scheduled to happen before we 889 // would have reached the idle state, so schedule an event and 890 // rather check once we actually make it to the point in time when 891 // the (last) precharge takes place 892 if (!prechargeEvent.scheduled()) 893 schedule(prechargeEvent, pre_done_at); --- 120 unchanged lines hidden (view full) --- 1014 // auto pre-charge when either 1015 // 1) open_adaptive policy, we have not got any more hits, and 1016 // have a bank conflict 1017 // 2) close_adaptive policy and we have not got any more hits 1018 auto_precharge = !got_more_hits && 1019 (got_bank_conflict || pageMgmt == Enums::close_adaptive); 1020 } 1021 |
1022 // DRAMPower trace command to be written 1023 std::string mem_cmd = dram_pkt->isRead ? "RD" : "WR"; 1024 |
1025 // if this access should use auto-precharge, then we are 1026 // closing the row 1027 if (auto_precharge) { |
1028 prechargeBank(bank, std::max(curTick(), bank.preAllowedAt), false); |
1029 |
1030 mem_cmd.append("A"); 1031 |
1032 DPRINTF(DRAM, "Auto-precharged bank: %d\n", dram_pkt->bankId); 1033 } 1034 1035 // Update bus state 1036 busBusyUntil = dram_pkt->readyTime; 1037 1038 DPRINTF(DRAM, "Access to %lld, ready at %lld bus busy until %lld.\n", 1039 dram_pkt->addr, dram_pkt->readyTime, busBusyUntil); 1040 |
1041 DPRINTF(DRAMPower, "%llu,%s,%d,%d\n", divCeil(cmd_at, tCK), mem_cmd, 1042 dram_pkt->bank, dram_pkt->rank); 1043 |
1044 // Update the minimum timing between the requests, this is a 1045 // conservative estimate of when we have to schedule the next 1046 // request to not introduce any unecessary bubbles. In most cases 1047 // we will wake up sooner than we have to. 1048 nextReqTime = busBusyUntil - (tRP + tRCD + tCL); 1049 1050 // Update the stats and schedule the next request 1051 if (dram_pkt->isRead) { --- 274 unchanged lines hidden (view full) --- 1326 1327 // make sure all banks are precharged, and for those that 1328 // already are, update their availability 1329 Tick act_allowed_at = pre_at + tRP; 1330 1331 for (int i = 0; i < ranksPerChannel; i++) { 1332 for (int j = 0; j < banksPerRank; j++) { 1333 if (banks[i][j].openRow != Bank::NO_ROW) { |
1334 prechargeBank(banks[i][j], pre_at, false); |
1335 } else { 1336 banks[i][j].actAllowedAt = 1337 std::max(banks[i][j].actAllowedAt, act_allowed_at); 1338 banks[i][j].preAllowedAt = 1339 std::max(banks[i][j].preAllowedAt, pre_at); 1340 } 1341 } |
1342 1343 // at the moment this affects all ranks 1344 DPRINTF(DRAMPower, "%llu,PREA,0,%d\n", divCeil(pre_at, tCK), 1345 i); |
1346 } 1347 } else { 1348 DPRINTF(DRAM, "All banks already precharged, starting refresh\n"); 1349 1350 // go ahead and kick the power state machine into gear if 1351 // we are already idle 1352 schedulePowerEvent(PWR_REF, curTick()); 1353 } --- 15 unchanged lines hidden (view full) --- 1369 assert(pwrState == PWR_REF); 1370 1371 Tick ref_done_at = curTick() + tRFC; 1372 1373 for (int i = 0; i < ranksPerChannel; i++) { 1374 for (int j = 0; j < banksPerRank; j++) { 1375 banks[i][j].actAllowedAt = ref_done_at; 1376 } |
1377 1378 // at the moment this affects all ranks 1379 DPRINTF(DRAMPower, "%llu,REF,0,%d\n", divCeil(curTick(), tCK), i); |
1380 } 1381 1382 // make sure we did not wait so long that we cannot make up 1383 // for it 1384 if (refreshDueAt + tREFI < ref_done_at) { 1385 fatal("Refresh was delayed so long we cannot catch up\n"); 1386 } 1387 --- 449 unchanged lines hidden --- |