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 ---