summaryrefslogtreecommitdiff
path: root/src/mem
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem')
-rw-r--r--src/mem/SimpleDRAM.py6
-rw-r--r--src/mem/simple_dram.cc41
2 files changed, 32 insertions, 15 deletions
diff --git a/src/mem/SimpleDRAM.py b/src/mem/SimpleDRAM.py
index a72bd518c..514ff3664 100644
--- a/src/mem/SimpleDRAM.py
+++ b/src/mem/SimpleDRAM.py
@@ -54,8 +54,10 @@ class MemSched(Enum): vals = ['fcfs', 'frfcfs']
# maximises parallelism.
class AddrMap(Enum): vals = ['RoRaBaChCo', 'RoRaBaCoCh', 'RoCoRaBaCh']
-# Enum for the page policy, either open, open_adaptive or close.
-class PageManage(Enum): vals = ['open', 'open_adaptive', 'close']
+# Enum for the page policy, either open, open_adaptive, close, or
+# close_adaptive.
+class PageManage(Enum): vals = ['open', 'open_adaptive', 'close',
+ 'close_adaptive']
# SimpleDRAM is a single-channel single-ported DRAM controller model
# that aims to model the most important system-level performance
diff --git a/src/mem/simple_dram.cc b/src/mem/simple_dram.cc
index a8c3e0552..cb640dcb2 100644
--- a/src/mem/simple_dram.cc
+++ b/src/mem/simple_dram.cc
@@ -589,7 +589,8 @@ SimpleDRAM::printParams() const
string address_mapping = addrMapping == Enums::RoRaBaChCo ? "RoRaBaChCo" :
(addrMapping == Enums::RoRaBaCoCh ? "RoRaBaCoCh" : "RoCoRaBaCh");
string page_policy = pageMgmt == Enums::open ? "OPEN" :
- (pageMgmt == Enums::open_adaptive ? "OPEN (adaptive)" : "CLOSE");
+ (pageMgmt == Enums::open_adaptive ? "OPEN (adaptive)" :
+ (pageMgmt == Enums::close_adaptive ? "CLOSE (adaptive)" : "CLOSE"));
DPRINTF(DRAM,
"Memory controller %s characteristics\n" \
@@ -892,8 +893,9 @@ SimpleDRAM::estimateLatency(DRAMPacket* dram_pkt, Tick inTime)
Tick potentialActTick;
const Bank& bank = dram_pkt->bankRef;
- // open-page policy
- if (pageMgmt == Enums::open || pageMgmt == Enums::open_adaptive) {
+ // 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,
@@ -986,7 +988,8 @@ SimpleDRAM::recordActivate(Tick act_tick, uint8_t rank, uint8_t bank)
// No need to update number of active banks for closed-page policy as only 1
// bank will be activated at any given point, which will be instatntly
// precharged
- if (pageMgmt == Enums::open || pageMgmt == Enums::open_adaptive)
+ if (pageMgmt == Enums::open || pageMgmt == Enums::open_adaptive ||
+ pageMgmt == Enums::close_adaptive)
++numBanksActive;
// start by enforcing tRRD
@@ -1055,7 +1058,8 @@ SimpleDRAM::doDRAMAccess(DRAMPacket* dram_pkt)
Bank& bank = dram_pkt->bankRef;
// Update bank state
- if (pageMgmt == Enums::open || pageMgmt == Enums::open_adaptive) {
+ if (pageMgmt == Enums::open || pageMgmt == Enums::open_adaptive ||
+ pageMgmt == Enums::close_adaptive) {
bank.freeAt = curTick() + addDelay + accessLat;
// If you activated a new row do to this access, the next access
@@ -1091,10 +1095,17 @@ SimpleDRAM::doDRAMAccess(DRAMPacket* dram_pkt)
// if we did not hit the limit, we might still want to
// auto-precharge
- if (!auto_precharge && pageMgmt == Enums::open_adaptive) {
- // a twist on the open page policy is to not blindly keep the
+ 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;
@@ -1106,9 +1117,10 @@ SimpleDRAM::doDRAMAccess(DRAMPacket* dram_pkt)
// currently dealing with (which is the head of the queue)
++p;
- // keep on looking until we have found both or reached
- // the end
- while (!(got_more_hits && got_bank_conflict) &&
+ // 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);
@@ -1118,9 +1130,12 @@ SimpleDRAM::doDRAMAccess(DRAMPacket* dram_pkt)
++p;
}
- // auto pre-charge if we have not got any more hits, and
- // have a bank conflict
- auto_precharge = !got_more_hits && got_bank_conflict;
+ // 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);
}
// if this access should use auto-precharge, then we are