# write-to-read turn around penalty, assumed same as read-to-write
tWTR = Param.Latency("Write to read switching time")
+ # minimum row activate to row activate delay time
+ tRRD = Param.Latency("ACT to ACT delay")
+
# time window in which a maximum number of activates are allowed
# to take place, set to 0 to disable
tXAW = Param.Latency("X activation window")
# Greater of 4 CK or 7.5 ns, 4 CK @ 800 MHz = 5 ns
tWTR = '7.5ns'
+ # Assume 5 CK for activate to activate for different banks
+ tRRD = '6.25ns'
+
# With a 2kbyte page size, DDR3-1600 lands around 40 ns
tXAW = '40ns'
activation_limit = 4
# Irrespective of speed grade, tWTR is 7.5 ns
tWTR = '7.5ns'
+ # Activate to activate irrespective of density and speed grade
+ tRRD = '10.0ns'
+
# Irrespective of density, tFAW is 50 ns
tXAW = '50ns'
activation_limit = 4
# Greater of 2 CK or 15 ns, 2 CK @ 200 MHz = 10 ns
tWTR = '15ns'
+ # Activate to activate irrespective of density and speed grade
+ tRRD = '10.0ns'
+
# Two instead of four activation window
tXAW = '50ns'
activation_limit = 2
# Irrespective of speed grade, tWTR is 7.5 ns
tWTR = '7.5ns'
+ # Activate to activate irrespective of density and speed grade
+ tRRD = '10.0ns'
+
# Irrespective of size, tFAW is 50 ns
tXAW = '50ns'
activation_limit = 4
writeThresholdPerc(p->write_thresh_perc),
tWTR(p->tWTR), tBURST(p->tBURST),
tRCD(p->tRCD), tCL(p->tCL), tRP(p->tRP), tRAS(p->tRAS),
- tRFC(p->tRFC), tREFI(p->tREFI),
+ tRFC(p->tRFC), tREFI(p->tREFI), tRRD(p->tRRD),
tXAW(p->tXAW), activationLimit(p->activation_limit),
memSchedPolicy(p->mem_sched_policy), addrMapping(p->addr_mapping),
pageMgmt(p->page_policy),
}
void
-SimpleDRAM::recordActivate(Tick act_tick, uint8_t rank)
+SimpleDRAM::recordActivate(Tick act_tick, uint8_t rank, uint8_t bank)
{
assert(0 <= rank && rank < ranksPerChannel);
assert(actTicks[rank].size() == activationLimit);
DPRINTF(DRAM, "Activate at tick %d\n", act_tick);
- // if the activation limit is disabled then we are done
+ // start by enforcing tRRD
+ for(int i = 0; i < banksPerRank; i++) {
+ // next activate must not happen before tRRD
+ banks[rank][i].actAllowedAt = act_tick + tRRD;
+ }
+ // tRC should be added to activation tick of the bank currently accessed,
+ // where tRC = tRAS + tRP, this is just for a check as actAllowedAt for same
+ // bank is already captured by bank.freeAt and bank.tRASDoneAt
+ banks[rank][bank].actAllowedAt = act_tick + tRAS + tRP;
+
+ // next, we deal with tXAW, if the activation limit is disabled
+ // then we are done
if (actTicks[rank].empty())
return;
// any waiting for banks account for in freeAt
actTick = bank.freeAt - tCL - tRCD;
bank.tRASDoneAt = actTick + tRAS;
- recordActivate(actTick, dram_pkt->rank);
+ recordActivate(actTick, dram_pkt->rank, dram_pkt->bank);
// sample the number of bytes accessed and reset it as
// we are now closing this row
bytesPerActivate.sample(bank.bytesAccessed);
bank.bytesAccessed = 0;
}
+ 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);
+ recordActivate(actTick, dram_pkt->rank, dram_pkt->bank);
// 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);
+ DPRINTF(DRAM, "doDRAMAccess::bank.freeAt is %lld\n", bank.freeAt);
bytesPerActivate.sample(burstSize);
} else
panic("No page management policy chosen\n");