dram_ctrl.cc (10246:e0e3efe3b1d5) | dram_ctrl.cc (10247:0ad233f0a77d) |
---|---|
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" | 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" |
|
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) : --- 721 unchanged lines hidden (view full) --- 777 // auto-precharged, and when this access is forced to 778 // precharge 779 bank.bytesAccessed = 0; 780 bank.rowAccesses = 0; 781 782 ++numBanksActive; 783 assert(numBanksActive <= banksPerRank * ranksPerChannel); 784 | 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 |
785 DPRINTF(DRAM, "Activate bank at tick %lld, now got %d active\n", 786 act_tick, numBanksActive); | 786 DPRINTF(DRAM, "Activate bank %d, rank %d at tick %lld, now got %d active\n", 787 bank.bank, bank.rank, act_tick, numBanksActive); |
787 | 788 |
789 DPRINTF(DRAMPower, "%llu,ACT,%d,%d\n", divCeil(act_tick, tCK), bank.bank, 790 bank.rank); 791 |
|
788 // The next access has to respect tRAS for this bank 789 bank.preAllowedAt = act_tick + tRAS; 790 791 // Respect the row-to-column command delay 792 bank.colAllowedAt = act_tick + tRCD; 793 794 // start by enforcing tRRD 795 for(int i = 0; i < banksPerRank; i++) { --- 50 unchanged lines hidden (view full) --- 846 // we should transition to the active state as soon as any bank is active 847 if (pwrState != PWR_ACT) 848 // note that at this point numBanksActive could be back at 849 // zero again due to a precharge scheduled in the future 850 schedulePowerEvent(PWR_ACT, curTick()); 851} 852 853void | 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 |
854DRAMCtrl::prechargeBank(Bank& bank, Tick pre_at) | 858DRAMCtrl::prechargeBank(Bank& bank, Tick pre_at, bool trace) |
855{ 856 // make sure the bank has an open row 857 assert(bank.openRow != Bank::NO_ROW); 858 859 // sample the bytes per activate here since we are closing 860 // the page 861 bytesPerActivate.sample(bank.bytesAccessed); 862 --- 4 unchanged lines hidden (view full) --- 867 868 Tick pre_done_at = pre_at + tRP; 869 870 bank.actAllowedAt = std::max(bank.actAllowedAt, pre_done_at); 871 872 assert(numBanksActive != 0); 873 --numBanksActive; 874 | 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 |
875 DPRINTF(DRAM, "Precharging bank at tick %lld, now got %d active\n", 876 pre_at, numBanksActive); | 879 DPRINTF(DRAM, "Precharging bank %d, rank %d at tick %lld, now got " 880 "%d active\n", bank.bank, bank.rank, pre_at, numBanksActive); |
877 | 881 |
882 if (trace) 883 DPRINTF(DRAMPower, "%llu,PRE,%d,%d\n", divCeil(pre_at, tCK), 884 bank.bank, bank.rank); 885 |
|
878 // if we look at the current number of active banks we might be 879 // tempted to think the DRAM is now idle, however this can be 880 // undone by an activate that is scheduled to happen before we 881 // would have reached the idle state, so schedule an event and 882 // rather check once we actually make it to the point in time when 883 // the (last) precharge takes place 884 if (!prechargeEvent.scheduled()) 885 schedule(prechargeEvent, pre_done_at); --- 120 unchanged lines hidden (view full) --- 1006 // auto pre-charge when either 1007 // 1) open_adaptive policy, we have not got any more hits, and 1008 // have a bank conflict 1009 // 2) close_adaptive policy and we have not got any more hits 1010 auto_precharge = !got_more_hits && 1011 (got_bank_conflict || pageMgmt == Enums::close_adaptive); 1012 } 1013 | 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 |
|
1014 // if this access should use auto-precharge, then we are 1015 // closing the row 1016 if (auto_precharge) { | 1025 // if this access should use auto-precharge, then we are 1026 // closing the row 1027 if (auto_precharge) { |
1017 prechargeBank(bank, std::max(curTick(), bank.preAllowedAt)); | 1028 prechargeBank(bank, std::max(curTick(), bank.preAllowedAt), false); |
1018 | 1029 |
1030 mem_cmd.append("A"); 1031 |
|
1019 DPRINTF(DRAM, "Auto-precharged bank: %d\n", dram_pkt->bankId); 1020 } 1021 1022 // Update bus state 1023 busBusyUntil = dram_pkt->readyTime; 1024 1025 DPRINTF(DRAM, "Access to %lld, ready at %lld bus busy until %lld.\n", 1026 dram_pkt->addr, dram_pkt->readyTime, busBusyUntil); 1027 | 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 |
|
1028 // Update the minimum timing between the requests, this is a 1029 // conservative estimate of when we have to schedule the next 1030 // request to not introduce any unecessary bubbles. In most cases 1031 // we will wake up sooner than we have to. 1032 nextReqTime = busBusyUntil - (tRP + tRCD + tCL); 1033 1034 // Update the stats and schedule the next request 1035 if (dram_pkt->isRead) { --- 274 unchanged lines hidden (view full) --- 1310 1311 // make sure all banks are precharged, and for those that 1312 // already are, update their availability 1313 Tick act_allowed_at = pre_at + tRP; 1314 1315 for (int i = 0; i < ranksPerChannel; i++) { 1316 for (int j = 0; j < banksPerRank; j++) { 1317 if (banks[i][j].openRow != Bank::NO_ROW) { | 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) { |
1318 prechargeBank(banks[i][j], pre_at); | 1334 prechargeBank(banks[i][j], pre_at, false); |
1319 } else { 1320 banks[i][j].actAllowedAt = 1321 std::max(banks[i][j].actAllowedAt, act_allowed_at); 1322 banks[i][j].preAllowedAt = 1323 std::max(banks[i][j].preAllowedAt, pre_at); 1324 } 1325 } | 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); |
|
1326 } 1327 } else { 1328 DPRINTF(DRAM, "All banks already precharged, starting refresh\n"); 1329 1330 // go ahead and kick the power state machine into gear if 1331 // we are already idle 1332 schedulePowerEvent(PWR_REF, curTick()); 1333 } --- 15 unchanged lines hidden (view full) --- 1349 assert(pwrState == PWR_REF); 1350 1351 Tick ref_done_at = curTick() + tRFC; 1352 1353 for (int i = 0; i < ranksPerChannel; i++) { 1354 for (int j = 0; j < banksPerRank; j++) { 1355 banks[i][j].actAllowedAt = ref_done_at; 1356 } | 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); |
|
1357 } 1358 1359 // make sure we did not wait so long that we cannot make up 1360 // for it 1361 if (refreshDueAt + tREFI < ref_done_at) { 1362 fatal("Refresh was delayed so long we cannot catch up\n"); 1363 } 1364 --- 449 unchanged lines hidden --- | 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 --- |