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 // open-page policy or close_adaptive policy
814 if (pageMgmt == Enums::open || pageMgmt == Enums::open_adaptive ||
815 pageMgmt == Enums::close_adaptive) {
816 if (bank.openRow == dram_pkt->row) {
817 // When we have a row-buffer hit,
818 // we don't care about tRAS having expired or not,
819 // but do care about bank being free for access
820 rowHitFlag = true;
821
822 // When a series of requests arrive to the same row,
823 // DDR systems are capable of streaming data continuously
824 // at maximum bandwidth (subject to tCCD). Here, we approximate
825 // this condition, and assume that if whenever a bank is already
826 // busy and a new request comes in, it can be completed with no
827 // penalty beyond waiting for the existing read to complete.
828 if (bank.freeAt > inTime) {
829 accLat += bank.freeAt - inTime;
830 bankLat += 0;
831 } else {
832 // CAS latency only
833 accLat += tCL;
834 bankLat += tCL;
835 }
836
837 } else {
838 // Row-buffer miss, need to close existing row
839 // once tRAS has expired, then open the new one,
840 // then add cas latency.
841 Tick freeTime = std::max(bank.tRASDoneAt, bank.freeAt);
842
843 if (freeTime > inTime)
844 accLat += freeTime - inTime;
845
846 // If the there is no open row (open adaptive), then there
847 // is no precharge delay, otherwise go with tRP
848 Tick precharge_delay = bank.openRow == Bank::NO_ROW ? 0 : tRP;
849
850 //The bank is free, and you may be able to activate
851 potentialActTick = inTime + accLat + precharge_delay;
852 if (potentialActTick < bank.actAllowedAt)
853 accLat += bank.actAllowedAt - potentialActTick;
854
855 accLat += precharge_delay + tRCD + tCL;
856 bankLat += precharge_delay + tRCD + tCL;
857 }
858 } else if (pageMgmt == Enums::close) {
859 // With a close page policy, no notion of
860 // bank.tRASDoneAt
861 if (bank.freeAt > inTime)
862 accLat += bank.freeAt - inTime;
863
864 //The bank is free, and you may be able to activate
865 potentialActTick = inTime + accLat;
866 if (potentialActTick < bank.actAllowedAt)
867 accLat += bank.actAllowedAt - potentialActTick;
868
869 // page already closed, simply open the row, and
870 // add cas latency
871 accLat += tRCD + tCL;
872 bankLat += tRCD + tCL;
873 } else
874 panic("No page management policy chosen\n");
875
876 DPRINTF(DRAM, "Returning < %lld, %lld > from estimateLatency()\n",
877 bankLat, accLat);
878
879 return make_pair(bankLat, accLat);
880}
881
882void

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

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

--- 805 unchanged lines hidden ---