813,820d812
< // open-page policy or close_adaptive policy
< if (pageMgmt == Enums::open || pageMgmt == Enums::open_adaptive ||
< pageMgmt == Enums::close_adaptive) {
< if (bank.openRow == dram_pkt->row) {
< // When we have a row-buffer hit,
< // we don't care about tRAS having expired or not,
< // but do care about bank being free for access
< rowHitFlag = true;
822,835c814,818
< // When a series of requests arrive to the same row,
< // DDR systems are capable of streaming data continuously
< // at maximum bandwidth (subject to tCCD). Here, we approximate
< // this condition, and assume that if whenever a bank is already
< // busy and a new request comes in, it can be completed with no
< // penalty beyond waiting for the existing read to complete.
< if (bank.freeAt > inTime) {
< accLat += bank.freeAt - inTime;
< bankLat += 0;
< } else {
< // CAS latency only
< accLat += tCL;
< bankLat += tCL;
< }
---
> if (bank.openRow == dram_pkt->row) {
> // When we have a row-buffer hit,
> // we don't care about tRAS having expired or not,
> // but do care about bank being free for access
> rowHitFlag = true;
836a820,828
> // When a series of requests arrive to the same row,
> // DDR systems are capable of streaming data continuously
> // at maximum bandwidth (subject to tCCD). Here, we approximate
> // this condition, and assume that if whenever a bank is already
> // busy and a new request comes in, it can be completed with no
> // penalty beyond waiting for the existing read to complete.
> if (bank.freeAt > inTime) {
> accLat += bank.freeAt - inTime;
> bankLat += 0;
838,841c830,838
< // Row-buffer miss, need to close existing row
< // once tRAS has expired, then open the new one,
< // then add cas latency.
< Tick freeTime = std::max(bank.tRASDoneAt, bank.freeAt);
---
> // CAS latency only
> accLat += tCL;
> bankLat += tCL;
> }
> } else {
> // Row-buffer miss, need to close existing row
> // once tRAS has expired, then open the new one,
> // then add cas latency.
> Tick freeTime = std::max(bank.tRASDoneAt, bank.freeAt);
843,844c840,841
< if (freeTime > inTime)
< accLat += freeTime - inTime;
---
> if (freeTime > inTime)
> accLat += freeTime - inTime;
846,848c843,845
< // If the there is no open row (open adaptive), then there
< // is no precharge delay, otherwise go with tRP
< Tick precharge_delay = bank.openRow == Bank::NO_ROW ? 0 : tRP;
---
> // If the there is no open row, then there is no precharge
> // delay, otherwise go with tRP
> Tick precharge_delay = bank.openRow == Bank::NO_ROW ? 0 : tRP;
850,863d846
< //The bank is free, and you may be able to activate
< potentialActTick = inTime + accLat + precharge_delay;
< if (potentialActTick < bank.actAllowedAt)
< accLat += bank.actAllowedAt - potentialActTick;
<
< accLat += precharge_delay + tRCD + tCL;
< bankLat += precharge_delay + tRCD + tCL;
< }
< } else if (pageMgmt == Enums::close) {
< // With a close page policy, no notion of
< // bank.tRASDoneAt
< if (bank.freeAt > inTime)
< accLat += bank.freeAt - inTime;
<
865c848
< potentialActTick = inTime + accLat;
---
> potentialActTick = inTime + accLat + precharge_delay;
869,874c852,854
< // page already closed, simply open the row, and
< // add cas latency
< accLat += tRCD + tCL;
< bankLat += tRCD + tCL;
< } else
< panic("No page management policy chosen\n");
---
> accLat += precharge_delay + tRCD + tCL;
> bankLat += precharge_delay + tRCD + tCL;
> }
1036,1037c1016,1024
< if (pageMgmt == Enums::open || pageMgmt == Enums::open_adaptive ||
< pageMgmt == Enums::close_adaptive) {
---
> if (rowHitFlag) {
> bank.freeAt = curTick() + addDelay + accessLat;
> } else {
> // If there is a page open, precharge it.
> if (bank.openRow != Bank::NO_ROW) {
> prechargeBank(bank, std::max(std::max(bank.freeAt,
> bank.tRASDoneAt),
> curTick()) + tRP);
> }
1039,1047c1026,1028
< if (rowHitFlag) {
< bank.freeAt = curTick() + addDelay + accessLat;
< } else {
< // If there is a page open, precharge it.
< if (bank.openRow != Bank::NO_ROW) {
< prechargeBank(bank, std::max(std::max(bank.freeAt,
< bank.tRASDoneAt),
< curTick()) + tRP);
< }
---
> // Any precharge is already part of the latency
> // estimation, so update the bank free time
> bank.freeAt = curTick() + addDelay + accessLat;
1049,1051c1030,1031
< // Any precharge is already part of the latency
< // estimation, so update the bank free time
< bank.freeAt = curTick() + addDelay + accessLat;
---
> // any waiting for banks account for in freeAt
> actTick = bank.freeAt - tCL - tRCD;
1053,1054c1033,1035
< // any waiting for banks account for in freeAt
< actTick = bank.freeAt - tCL - tRCD;
---
> // If you activated a new row do to this access, the next access
> // will have to respect tRAS for this bank
> bank.tRASDoneAt = actTick + tRAS;
1056,1058c1037,1039
< // If you activated a new row do to this access, the next access
< // will have to respect tRAS for this bank
< bank.tRASDoneAt = actTick + tRAS;
---
> recordActivate(actTick, dram_pkt->rank, dram_pkt->bank,
> dram_pkt->row);
> }
1060,1062c1041,1043
< recordActivate(actTick, dram_pkt->rank, dram_pkt->bank,
< dram_pkt->row);
< }
---
> // increment the bytes accessed and the accesses per row
> bank.bytesAccessed += burstSize;
> ++bank.rowAccesses;
1064,1066c1045,1047
< // increment the bytes accessed and the accesses per row
< bank.bytesAccessed += burstSize;
< ++bank.rowAccesses;
---
> // if we reached the max, then issue with an auto-precharge
> bool auto_precharge = pageMgmt == Enums::close ||
> bank.rowAccesses == maxAccessesPerRow;
1068,1069c1049,1063
< // if we reached the max, then issue with an auto-precharge
< bool auto_precharge = bank.rowAccesses == maxAccessesPerRow;
---
> // if we did not hit the limit, we might still want to
> // auto-precharge
> if (!auto_precharge &&
> (pageMgmt == Enums::open_adaptive ||
> pageMgmt == Enums::close_adaptive)) {
> // a twist on the open and close page policies:
> // 1) open_adaptive page policy does not blindly keep the
> // page open, but close it if there are no row hits, and there
> // are bank conflicts in the queue
> // 2) close_adaptive page policy does not blindly close the
> // page, but closes it only if there are no row hits in the queue.
> // In this case, only force an auto precharge when there
> // are no same page hits in the queue
> bool got_more_hits = false;
> bool got_bank_conflict = false;
1071,1085c1065,1071
< // if we did not hit the limit, we might still want to
< // auto-precharge
< if (!auto_precharge &&
< (pageMgmt == Enums::open_adaptive ||
< pageMgmt == Enums::close_adaptive)) {
< // a twist on the open and close page policies:
< // 1) open_adaptive page policy does not blindly keep the
< // page open, but close it if there are no row hits, and there
< // are bank conflicts in the queue
< // 2) close_adaptive page policy does not blindly close the
< // page, but closes it only if there are no row hits in the queue.
< // In this case, only force an auto precharge when there
< // are no same page hits in the queue
< bool got_more_hits = false;
< bool got_bank_conflict = false;
---
> // either look at the read queue or write queue
> const deque<DRAMPacket*>& queue = dram_pkt->isRead ? readQueue :
> writeQueue;
> auto p = queue.begin();
> // make sure we are not considering the packet that we are
> // currently dealing with (which is the head of the queue)
> ++p;
1087,1092c1073,1082
< // either look at the read queue or write queue
< const deque<DRAMPacket*>& queue = dram_pkt->isRead ? readQueue :
< writeQueue;
< auto p = queue.begin();
< // make sure we are not considering the packet that we are
< // currently dealing with (which is the head of the queue)
---
> // keep on looking until we have found required condition or
> // reached the end
> while (!(got_more_hits &&
> (got_bank_conflict || pageMgmt == Enums::close_adaptive)) &&
> p != queue.end()) {
> bool same_rank_bank = (dram_pkt->rank == (*p)->rank) &&
> (dram_pkt->bank == (*p)->bank);
> bool same_row = dram_pkt->row == (*p)->row;
> got_more_hits |= same_rank_bank && same_row;
> got_bank_conflict |= same_rank_bank && !same_row;
1094,1113d1083
<
< // keep on looking until we have found required condition or
< // reached the end
< while (!(got_more_hits &&
< (got_bank_conflict || pageMgmt == Enums::close_adaptive)) &&
< p != queue.end()) {
< bool same_rank_bank = (dram_pkt->rank == (*p)->rank) &&
< (dram_pkt->bank == (*p)->bank);
< bool same_row = dram_pkt->row == (*p)->row;
< got_more_hits |= same_rank_bank && same_row;
< got_bank_conflict |= same_rank_bank && !same_row;
< ++p;
< }
<
< // auto pre-charge when either
< // 1) open_adaptive policy, we have not got any more hits, and
< // have a bank conflict
< // 2) close_adaptive policy and we have not got any more hits
< auto_precharge = !got_more_hits &&
< (got_bank_conflict || pageMgmt == Enums::close_adaptive);
1116,1119c1086,1092
< // if this access should use auto-precharge, then we are
< // closing the row
< if (auto_precharge) {
< prechargeBank(bank, std::max(bank.freeAt, bank.tRASDoneAt) + tRP);
---
> // auto pre-charge when either
> // 1) open_adaptive policy, we have not got any more hits, and
> // have a bank conflict
> // 2) close_adaptive policy and we have not got any more hits
> auto_precharge = !got_more_hits &&
> (got_bank_conflict || pageMgmt == Enums::close_adaptive);
> }
1121,1122c1094,1097
< DPRINTF(DRAM, "Auto-precharged bank: %d\n", dram_pkt->bankId);
< }
---
> // if this access should use auto-precharge, then we are
> // closing the row
> if (auto_precharge) {
> prechargeBank(bank, std::max(bank.freeAt, bank.tRASDoneAt) + tRP);
1124,1127c1099,1100
< DPRINTF(DRAM, "doDRAMAccess::bank.freeAt is %lld\n", bank.freeAt);
< } else if (pageMgmt == Enums::close) {
< actTick = curTick() + addDelay + accessLat - tRCD - tCL;
< recordActivate(actTick, dram_pkt->rank, dram_pkt->bank, dram_pkt->row);
---
> DPRINTF(DRAM, "Auto-precharged bank: %d\n", dram_pkt->bankId);
> }
1129,1130c1102
< bank.freeAt = actTick + tRCD + tCL;
< bank.tRASDoneAt = actTick + tRAS;
---
> DPRINTF(DRAM, "doDRAMAccess::bank.freeAt is %lld\n", bank.freeAt);
1132,1140d1103
< // sample the relevant values when precharging
< bank.bytesAccessed = burstSize;
< bank.rowAccesses = 1;
<
< prechargeBank(bank, std::max(bank.freeAt, bank.tRASDoneAt) + tRP);
< DPRINTF(DRAM, "doDRAMAccess::bank.freeAt is %lld\n", bank.freeAt);
< } else
< panic("No page management policy chosen\n");
<
1144d1106
<