diff options
author | Ani Udipi <ani.udipi@arm.com> | 2013-01-31 07:49:14 -0500 |
---|---|---|
committer | Ani Udipi <ani.udipi@arm.com> | 2013-01-31 07:49:14 -0500 |
commit | eaa37e611f07a41d97a078bf2588bfe745d83751 (patch) | |
tree | a3f8db3defdc6c3af0e7a0670fb9e7d7139d3f00 /src/mem/simple_dram.cc | |
parent | b7153e2a64bdb88cebe96e59b24d5597a3a42205 (diff) | |
download | gem5-eaa37e611f07a41d97a078bf2588bfe745d83751.tar.xz |
mem: Add tTAW and tFAW to the SimpleDRAM model
This patch adds two additional scheduling constraints to the DRAM
controller model, to constrain the activation rate. The two metrics
are determine the size of the activation window in terms of the number
of activates and the minimum time required for that number of
activates. This maps to current DDRx, LPDDRx and WIOx standards that
have either tFAW (4 activate window) or tTAW (2 activate window)
scheduling constraints.
Diffstat (limited to 'src/mem/simple_dram.cc')
-rw-r--r-- | src/mem/simple_dram.cc | 53 |
1 files changed, 48 insertions, 5 deletions
diff --git a/src/mem/simple_dram.cc b/src/mem/simple_dram.cc index 305a7bcaf..6885e48c0 100644 --- a/src/mem/simple_dram.cc +++ b/src/mem/simple_dram.cc @@ -51,7 +51,7 @@ SimpleDRAM::SimpleDRAM(const SimpleDRAMParams* p) : AbstractMemory(p), port(name() + ".port", *this), retryRdReq(false), retryWrReq(false), - rowHitFlag(false), stopReads(false), + rowHitFlag(false), stopReads(false), actTicks(p->activation_limit, 0), writeEvent(this), respondEvent(this), refreshEvent(this), nextReqEvent(this), drainManager(NULL), bytesPerCacheLine(0), @@ -64,6 +64,7 @@ SimpleDRAM::SimpleDRAM(const SimpleDRAMParams* p) : tWTR(p->tWTR), tBURST(p->tBURST), tRCD(p->tRCD), tCL(p->tCL), tRP(p->tRP), tRFC(p->tRFC), tREFI(p->tREFI), + tXAW(p->tXAW), activationLimit(p->activation_limit), memSchedPolicy(p->mem_sched_policy), addrMapping(p->addr_mapping), pageMgmt(p->page_policy), busBusyUntil(0), prevdramaccess(0), writeStartTime(0), @@ -304,10 +305,13 @@ SimpleDRAM::processWriteEvent() if (!rowHitFlag) { bank.tRASDoneAt = bank.freeAt + tRP; + recordActivate(bank.freeAt - tCL - tRCD); busBusyUntil = bank.freeAt - tCL - tRCD; } } else if (pageMgmt == Enums::close) { bank.freeAt = schedTime + tBURST + accessLat + tRP + tRP; + // Work backwards from bank.freeAt to determine activate time + recordActivate(bank.freeAt - tRP - tRP - tCL - tRCD); busBusyUntil = bank.freeAt - tRP - tRP - tCL - tRCD; DPRINTF(DRAMWR, "processWriteEvent::bank.freeAt for " "banks_id %d is %lld\n", @@ -792,6 +796,41 @@ SimpleDRAM::processNextReqEvent() } void +SimpleDRAM::recordActivate(Tick act_tick) +{ + assert(actTicks.size() == activationLimit); + + DPRINTF(DRAM, "Activate at tick %d\n", act_tick); + + // sanity check + if (actTicks.back() && (act_tick - actTicks.back()) < tXAW) { + panic("Got %d activates in window %d (%d - %d) which is smaller " + "than %d\n", activationLimit, act_tick - actTicks.back(), + act_tick, actTicks.back(), tXAW); + } + + // shift the times used for the book keeping, the last element + // (highest index) is the oldest one and hence the lowest value + actTicks.pop_back(); + + // record an new activation (in the future) + actTicks.push_front(act_tick); + + // cannot activate more than X times in time window tXAW, push the + // next one (the X + 1'st activate) to be tXAW away from the + // oldest in our window of X + if (actTicks.back() && (act_tick - actTicks.back()) < tXAW) { + DPRINTF(DRAM, "Enforcing tXAW with X = %d, next activate no earlier " + "than %d\n", activationLimit, actTicks.back() + tXAW); + for(int i = 0; i < ranksPerChannel; i++) + for(int j = 0; j < banksPerRank; j++) + // next activate must not happen before end of window + banks[i][j].freeAt = std::max(banks[i][j].freeAt, + actTicks.back() + tXAW); + } +} + +void SimpleDRAM::doDRAMAccess(DRAMPacket* dram_pkt) { @@ -821,14 +860,18 @@ SimpleDRAM::doDRAMAccess(DRAMPacket* dram_pkt) bank.openRow = dram_pkt->row; bank.freeAt = curTick() + addDelay + accessLat; // If you activated a new row do to this access, the next access - // will have to respect tRAS for this bank. Assume tRAS ~= 3 * tRP - if (!rowHitFlag) + // will have to respect tRAS for this bank. Assume tRAS ~= 3 * tRP. + // Also need to account for t_XAW + if (!rowHitFlag) { bank.tRASDoneAt = bank.freeAt + tRP; - + recordActivate(bank.freeAt - tCL - tRCD); //since this is open page, + //no tRP by default + } } else if (pageMgmt == Enums::close) { // accounting for tRAS also - // assuming that tRAS ~= 3 * tRP, and tRAS ~= 4 * tRP, as is common + // assuming that tRAS ~= 3 * tRP, and tRC ~= 4 * tRP, as is common // (refer Jacob/Ng/Wang and Micron datasheets) bank.freeAt = curTick() + addDelay + accessLat + tRP + tRP; + recordActivate(bank.freeAt - tRP - tRP - tCL - tRCD); //essentially (freeAt - tRC) DPRINTF(DRAM,"doDRAMAccess::bank.freeAt is %lld\n",bank.freeAt); } else panic("No page management policy chosen\n"); |