mem: Add tRAS parameter to the DRAM controller model

This patch adds an explicit tRAS parameter to the DRAM controller
model. Previously tRAS was, rather conservatively, assumed to be tRCD
+ tCL + tRP. The default values for tRAS are chosen to match the
previous behaviour and will be updated later.
This commit is contained in:
Ani Udipi 2013-11-01 11:56:16 -04:00
parent 0e6ced5c4f
commit d4cf009b95
3 changed files with 47 additions and 23 deletions

View file

@ -114,6 +114,9 @@ class SimpleDRAM(AbstractMemory):
# minimum time between a precharge and subsequent activate
tRP = Param.Latency("Row precharge time")
# minimum time between an activate and a precharge to the same row
tRAS = Param.Latency("ACT to PRE delay")
# time to complete a burst transfer, typically the burst length
# divided by two due to the DDR bus, but by making it a parameter
# it is easier to also evaluate SDR memories like WideIO.
@ -140,11 +143,7 @@ class SimpleDRAM(AbstractMemory):
# Currently rolled into other params
######################################################################
# the minimum amount of time between a row being activated, and
# precharged (de-activated)
# tRAS - assumed to be 3 * tRP
# tRC - assumed to be 4 * tRP
# tRC - assumed to be tRAS + tRP
# A single DDR3 x64 interface (one command and address bus), with
# default timings based on DDR3-1600 4 Gbit parts in an 8x8
@ -173,6 +172,7 @@ class DDR3_1600_x64(SimpleDRAM):
tRCD = '13.75ns'
tCL = '13.75ns'
tRP = '13.75ns'
tRAS = '41.25ns'
# 8 beats across an x64 interface translates to 4 clocks @ 800 MHz.
# Note this is a BL8 DDR device.
@ -224,6 +224,8 @@ class LPDDR2_S4_1066_x32(SimpleDRAM):
# Pre-charge one bank 15 ns (all banks 18 ns)
tRP = '15ns'
tRAS = '45ns'
# 8 beats across an x32 DDR interface translates to 4 clocks @ 533 MHz.
# Note this is a BL8 DDR device.
# Requests larger than 32 bytes are broken down into multiple requests
@ -267,6 +269,7 @@ class WideIO_200_x128(SimpleDRAM):
tRCD = '18ns'
tCL = '18ns'
tRP = '18ns'
tRAS = '54ns'
# 4 beats across an x128 SDR interface translates to 4 clocks @ 200 MHz.
# Note this is a BL4 SDR device.
@ -314,6 +317,8 @@ class LPDDR3_1600_x32(SimpleDRAM):
# 12 CK read latency, 6 CK write latency @ 800 MHz, 1.25 ns cycle time
tCL = '15ns'
tRAS = '45ns'
# Pre-charge one bank 15 ns (all banks 18 ns)
tRP = '15ns'

View file

@ -68,7 +68,7 @@ SimpleDRAM::SimpleDRAM(const SimpleDRAMParams* p) :
writeBufferSize(p->write_buffer_size),
writeThresholdPerc(p->write_thresh_perc),
tWTR(p->tWTR), tBURST(p->tBURST),
tRCD(p->tRCD), tCL(p->tCL), tRP(p->tRP),
tRCD(p->tRCD), tCL(p->tCL), tRP(p->tRP), tRAS(p->tRAS),
tRFC(p->tRFC), tREFI(p->tREFI),
tXAW(p->tXAW), activationLimit(p->activation_limit),
memSchedPolicy(p->mem_sched_policy), addrMapping(p->addr_mapping),
@ -382,6 +382,7 @@ SimpleDRAM::processWriteEvent()
{
assert(!writeQueue.empty());
uint32_t numWritesThisTime = 0;
Tick actTick;
DPRINTF(DRAMWR, "Beginning DRAM Writes\n");
Tick temp1 M5_VAR_USED = std::max(curTick(), busBusyUntil);
@ -422,9 +423,10 @@ SimpleDRAM::processWriteEvent()
bank.bytesAccessed += burstSize;
if (!rowHitFlag) {
bank.tRASDoneAt = bank.freeAt + tRP;
recordActivate(bank.freeAt - tCL - tRCD);
busBusyUntil = bank.freeAt - tCL - tRCD;
actTick = bank.freeAt - tCL - tRCD;//new row opened
bank.tRASDoneAt = actTick + tRAS;
recordActivate(actTick);
busBusyUntil = actTick;
// sample the number of bytes accessed and reset it as
// we are now closing this row
@ -432,10 +434,19 @@ SimpleDRAM::processWriteEvent()
bank.bytesAccessed = 0;
}
} 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;
// All ticks waiting for a bank (if required) are included
// in accessLat
actTick = schedTime + tBURST + accessLat - tCL - tRCD;
recordActivate(actTick);
// If the DRAM has a very quick tRAS, bank can be made free
// after consecutive tCL,tRCD,tRP times. In general, however,
// an additional wait is required to respect tRAS.
bank.freeAt = std::max(actTick + tRAS + tRP,
actTick + tCL + tRCD + tRP);
//assuming that DRAM first gets write data, then activates
busBusyUntil = actTick;
DPRINTF(DRAMWR, "processWriteEvent::bank.freeAt for "
"banks_id %d is %lld\n",
dram_pkt->rank * banksPerRank + dram_pkt->bank,
@ -1043,6 +1054,7 @@ SimpleDRAM::doDRAMAccess(DRAMPacket* dram_pkt)
pair<Tick, Tick> lat = estimateLatency(dram_pkt, curTick());
Tick bankLat = lat.first;
Tick accessLat = lat.second;
Tick actTick;
// This request was woken up at this time based on a prior call
// to estimateLatency(). However, between then and now, both the
@ -1061,22 +1073,28 @@ SimpleDRAM::doDRAMAccess(DRAMPacket* dram_pkt)
bank.bytesAccessed += burstSize;
// 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.
// Also need to account for t_XAW
// will have to respect tRAS for this bank.
if (!rowHitFlag) {
bank.tRASDoneAt = bank.freeAt + tRP;
recordActivate(bank.freeAt - tCL - tRCD); //since this is open page,
//no tRP by default
// any waiting for banks account for in freeAt
actTick = bank.freeAt - tCL - tRCD;
bank.tRASDoneAt = actTick + tRAS;
recordActivate(actTick);
// sample the number of bytes accessed and reset it as
// we are now closing this row
bytesPerActivate.sample(bank.bytesAccessed);
bank.bytesAccessed = 0;
}
} else if (pageMgmt == Enums::close) { // accounting for tRAS also
// 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)
} else if (pageMgmt == Enums::close) {
actTick = curTick() + addDelay + accessLat - tRCD - tCL;
recordActivate(actTick);
// If the DRAM has a very quick tRAS, bank can be made free
// after consecutive tCL,tRCD,tRP times. In general, however,
// an additional wait is required to respect tRAS.
bank.freeAt = std::max(actTick + tRAS + tRP,
actTick + tRCD + tCL + tRP);
DPRINTF(DRAM,"doDRAMAccess::bank.freeAt is %lld\n",bank.freeAt);
bytesPerActivate.sample(burstSize);
} else

View file

@ -462,6 +462,7 @@ class SimpleDRAM : public AbstractMemory
const Tick tRCD;
const Tick tCL;
const Tick tRP;
const Tick tRAS;
const Tick tRFC;
const Tick tREFI;
const Tick tXAW;