Deleted Added
sdiff udiff text old ( 10208:c249f7660eb7 ) new ( 10209:ac71c857e1e1 )
full compact
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

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

805 // to complete, NOT any additional time thereafter for tRAS or
806 // tRP.
807 Tick accLat = 0;
808 Tick bankLat = 0;
809 rowHitFlag = false;
810 Tick potentialActTick;
811
812 const Bank& bank = dram_pkt->bankRef;
813
814 if (bank.openRow == dram_pkt->row) {
815 // When we have a row-buffer hit,
816 // we don't care about tRAS having expired or not,
817 // but do care about bank being free for access
818 rowHitFlag = true;
819
820 // When a series of requests arrive to the same row,
821 // DDR systems are capable of streaming data continuously
822 // at maximum bandwidth (subject to tCCD). Here, we approximate
823 // this condition, and assume that if whenever a bank is already
824 // busy and a new request comes in, it can be completed with no
825 // penalty beyond waiting for the existing read to complete.
826 if (bank.freeAt > inTime) {
827 accLat += bank.freeAt - inTime;
828 bankLat += 0;
829 } else {
830 // CAS latency only
831 accLat += tCL;
832 bankLat += tCL;
833 }
834 } else {
835 // Row-buffer miss, need to close existing row
836 // once tRAS has expired, then open the new one,
837 // then add cas latency.
838 Tick freeTime = std::max(bank.tRASDoneAt, bank.freeAt);
839
840 if (freeTime > inTime)
841 accLat += freeTime - inTime;
842
843 // If the there is no open row, then there is no precharge
844 // delay, otherwise go with tRP
845 Tick precharge_delay = bank.openRow == Bank::NO_ROW ? 0 : tRP;
846
847 //The bank is free, and you may be able to activate
848 potentialActTick = inTime + accLat + precharge_delay;
849 if (potentialActTick < bank.actAllowedAt)
850 accLat += bank.actAllowedAt - potentialActTick;
851
852 accLat += precharge_delay + tRCD + tCL;
853 bankLat += precharge_delay + tRCD + tCL;
854 }
855
856 DPRINTF(DRAM, "Returning < %lld, %lld > from estimateLatency()\n",
857 bankLat, accLat);
858
859 return make_pair(bankLat, accLat);
860}
861
862void

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

1008 // to correct for that.
1009
1010 Tick addDelay = (curTick() + accessLat < busBusyUntil) ?
1011 busBusyUntil - (curTick() + accessLat) : 0;
1012
1013 Bank& bank = dram_pkt->bankRef;
1014
1015 // Update bank state
1016 if (rowHitFlag) {
1017 bank.freeAt = curTick() + addDelay + accessLat;
1018 } else {
1019 // If there is a page open, precharge it.
1020 if (bank.openRow != Bank::NO_ROW) {
1021 prechargeBank(bank, std::max(std::max(bank.freeAt,
1022 bank.tRASDoneAt),
1023 curTick()) + tRP);
1024 }
1025
1026 // Any precharge is already part of the latency
1027 // estimation, so update the bank free time
1028 bank.freeAt = curTick() + addDelay + accessLat;
1029
1030 // any waiting for banks account for in freeAt
1031 actTick = bank.freeAt - tCL - tRCD;
1032
1033 // If you activated a new row do to this access, the next access
1034 // will have to respect tRAS for this bank
1035 bank.tRASDoneAt = actTick + tRAS;
1036
1037 recordActivate(actTick, dram_pkt->rank, dram_pkt->bank,
1038 dram_pkt->row);
1039 }
1040
1041 // increment the bytes accessed and the accesses per row
1042 bank.bytesAccessed += burstSize;
1043 ++bank.rowAccesses;
1044
1045 // if we reached the max, then issue with an auto-precharge
1046 bool auto_precharge = pageMgmt == Enums::close ||
1047 bank.rowAccesses == maxAccessesPerRow;
1048
1049 // if we did not hit the limit, we might still want to
1050 // auto-precharge
1051 if (!auto_precharge &&
1052 (pageMgmt == Enums::open_adaptive ||
1053 pageMgmt == Enums::close_adaptive)) {
1054 // a twist on the open and close page policies:
1055 // 1) open_adaptive page policy does not blindly keep the
1056 // page open, but close it if there are no row hits, and there
1057 // are bank conflicts in the queue
1058 // 2) close_adaptive page policy does not blindly close the
1059 // page, but closes it only if there are no row hits in the queue.
1060 // In this case, only force an auto precharge when there
1061 // are no same page hits in the queue
1062 bool got_more_hits = false;
1063 bool got_bank_conflict = false;
1064
1065 // either look at the read queue or write queue
1066 const deque<DRAMPacket*>& queue = dram_pkt->isRead ? readQueue :
1067 writeQueue;
1068 auto p = queue.begin();
1069 // make sure we are not considering the packet that we are
1070 // currently dealing with (which is the head of the queue)
1071 ++p;
1072
1073 // keep on looking until we have found required condition or
1074 // reached the end
1075 while (!(got_more_hits &&
1076 (got_bank_conflict || pageMgmt == Enums::close_adaptive)) &&
1077 p != queue.end()) {
1078 bool same_rank_bank = (dram_pkt->rank == (*p)->rank) &&
1079 (dram_pkt->bank == (*p)->bank);
1080 bool same_row = dram_pkt->row == (*p)->row;
1081 got_more_hits |= same_rank_bank && same_row;
1082 got_bank_conflict |= same_rank_bank && !same_row;
1083 ++p;
1084 }
1085
1086 // auto pre-charge when either
1087 // 1) open_adaptive policy, we have not got any more hits, and
1088 // have a bank conflict
1089 // 2) close_adaptive policy and we have not got any more hits
1090 auto_precharge = !got_more_hits &&
1091 (got_bank_conflict || pageMgmt == Enums::close_adaptive);
1092 }
1093
1094 // if this access should use auto-precharge, then we are
1095 // closing the row
1096 if (auto_precharge) {
1097 prechargeBank(bank, std::max(bank.freeAt, bank.tRASDoneAt) + tRP);
1098
1099 DPRINTF(DRAM, "Auto-precharged bank: %d\n", dram_pkt->bankId);
1100 }
1101
1102 DPRINTF(DRAM, "doDRAMAccess::bank.freeAt is %lld\n", bank.freeAt);
1103
1104 // Update request parameters
1105 dram_pkt->readyTime = curTick() + addDelay + accessLat + tBURST;
1106
1107 DPRINTF(DRAM, "Req %lld: curtick is %lld accessLat is %d " \
1108 "readytime is %lld busbusyuntil is %lld. " \
1109 "Scheduling at readyTime\n", dram_pkt->addr,
1110 curTick(), accessLat, dram_pkt->readyTime, busBusyUntil);
1111
1112 // Make sure requests are not overlapping on the databus
1113 assert(dram_pkt->readyTime - busBusyUntil >= tBURST);
1114

--- 805 unchanged lines hidden ---