mem: Add tWR to DRAM activate and precharge constraints
This patch adds the write recovery time to the DRAM timing constraints, and changes the current tRASDoneAt to a more generic preAllowedAt, capturing when a precharge is allowed to take place. The part of the DRAM access code that accounts for the precharge and activate constraints is updated accordingly.
This commit is contained in:
parent
c735ef6cb0
commit
b8631d9ae8
|
@ -132,6 +132,9 @@ class DRAMCtrl(AbstractMemory):
|
||||||
# minimum time between an activate and a precharge to the same row
|
# minimum time between an activate and a precharge to the same row
|
||||||
tRAS = Param.Latency("ACT to PRE delay")
|
tRAS = Param.Latency("ACT to PRE delay")
|
||||||
|
|
||||||
|
# minimum time between a write data transfer and a precharge
|
||||||
|
tWR = Param.Latency("Write recovery time")
|
||||||
|
|
||||||
# time to complete a burst transfer, typically the burst length
|
# time to complete a burst transfer, typically the burst length
|
||||||
# divided by two due to the DDR bus, but by making it a parameter
|
# divided by two due to the DDR bus, but by making it a parameter
|
||||||
# it is easier to also evaluate SDR memories like WideIO.
|
# it is easier to also evaluate SDR memories like WideIO.
|
||||||
|
@ -194,6 +197,7 @@ class DDR3_1600_x64(DRAMCtrl):
|
||||||
tCL = '13.75ns'
|
tCL = '13.75ns'
|
||||||
tRP = '13.75ns'
|
tRP = '13.75ns'
|
||||||
tRAS = '35ns'
|
tRAS = '35ns'
|
||||||
|
tWR = '15ns'
|
||||||
|
|
||||||
# 8 beats across an x64 interface translates to 4 clocks @ 800 MHz.
|
# 8 beats across an x64 interface translates to 4 clocks @ 800 MHz.
|
||||||
# Note this is a BL8 DDR device.
|
# Note this is a BL8 DDR device.
|
||||||
|
@ -252,6 +256,7 @@ class DDR3_1333_x64_DRAMSim2(DRAMCtrl):
|
||||||
tCL = '15ns'
|
tCL = '15ns'
|
||||||
tRP = '15ns'
|
tRP = '15ns'
|
||||||
tRAS = '36ns'
|
tRAS = '36ns'
|
||||||
|
tWR = '15ns'
|
||||||
|
|
||||||
# 8 beats across an x64 interface translates to 4 clocks @ 666.66 MHz.
|
# 8 beats across an x64 interface translates to 4 clocks @ 666.66 MHz.
|
||||||
# Note this is a BL8 DDR device.
|
# Note this is a BL8 DDR device.
|
||||||
|
@ -307,6 +312,7 @@ class LPDDR2_S4_1066_x32(DRAMCtrl):
|
||||||
tRP = '15ns'
|
tRP = '15ns'
|
||||||
|
|
||||||
tRAS = '42ns'
|
tRAS = '42ns'
|
||||||
|
tWR = '15ns'
|
||||||
|
|
||||||
# 8 beats across an x32 DDR interface translates to 4 clocks @ 533 MHz.
|
# 8 beats across an x32 DDR interface translates to 4 clocks @ 533 MHz.
|
||||||
# Note this is a BL8 DDR device.
|
# Note this is a BL8 DDR device.
|
||||||
|
@ -358,6 +364,7 @@ class WideIO_200_x128(DRAMCtrl):
|
||||||
tCL = '18ns'
|
tCL = '18ns'
|
||||||
tRP = '18ns'
|
tRP = '18ns'
|
||||||
tRAS = '42ns'
|
tRAS = '42ns'
|
||||||
|
tWR = '15ns'
|
||||||
|
|
||||||
# 4 beats across an x128 SDR interface translates to 4 clocks @ 200 MHz.
|
# 4 beats across an x128 SDR interface translates to 4 clocks @ 200 MHz.
|
||||||
# Note this is a BL4 SDR device.
|
# Note this is a BL4 SDR device.
|
||||||
|
@ -411,6 +418,7 @@ class LPDDR3_1600_x32(DRAMCtrl):
|
||||||
tCL = '15ns'
|
tCL = '15ns'
|
||||||
|
|
||||||
tRAS = '42ns'
|
tRAS = '42ns'
|
||||||
|
tWR = '15ns'
|
||||||
|
|
||||||
# Pre-charge one bank 15 ns (all banks 18 ns)
|
# Pre-charge one bank 15 ns (all banks 18 ns)
|
||||||
tRP = '15ns'
|
tRP = '15ns'
|
||||||
|
|
|
@ -75,7 +75,7 @@ DRAMCtrl::DRAMCtrl(const DRAMCtrlParams* p) :
|
||||||
minWritesPerSwitch(p->min_writes_per_switch),
|
minWritesPerSwitch(p->min_writes_per_switch),
|
||||||
writesThisTime(0), readsThisTime(0),
|
writesThisTime(0), readsThisTime(0),
|
||||||
tWTR(p->tWTR), tRTW(p->tRTW), tBURST(p->tBURST),
|
tWTR(p->tWTR), tRTW(p->tRTW), tBURST(p->tBURST),
|
||||||
tRCD(p->tRCD), tCL(p->tCL), tRP(p->tRP), tRAS(p->tRAS),
|
tRCD(p->tRCD), tCL(p->tCL), tRP(p->tRP), tRAS(p->tRAS), tWR(p->tWR),
|
||||||
tRFC(p->tRFC), tREFI(p->tREFI), tRRD(p->tRRD),
|
tRFC(p->tRFC), tREFI(p->tREFI), tRRD(p->tRRD),
|
||||||
tXAW(p->tXAW), activationLimit(p->activation_limit),
|
tXAW(p->tXAW), activationLimit(p->activation_limit),
|
||||||
memSchedPolicy(p->mem_sched_policy), addrMapping(p->addr_mapping),
|
memSchedPolicy(p->mem_sched_policy), addrMapping(p->addr_mapping),
|
||||||
|
@ -559,9 +559,10 @@ DRAMCtrl::printParams() const
|
||||||
"tREFI %d ticks\n" \
|
"tREFI %d ticks\n" \
|
||||||
"tWTR %d ticks\n" \
|
"tWTR %d ticks\n" \
|
||||||
"tRTW %d ticks\n" \
|
"tRTW %d ticks\n" \
|
||||||
|
"tWR %d ticks\n" \
|
||||||
"tXAW (%d) %d ticks\n",
|
"tXAW (%d) %d ticks\n",
|
||||||
name(), tRCD, tCL, tRP, tBURST, tRFC, tREFI, tWTR,
|
name(), tRCD, tCL, tRP, tBURST, tRFC, tREFI, tWTR,
|
||||||
tRTW, activationLimit, tXAW);
|
tRTW, tWR, activationLimit, tXAW);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -807,7 +808,6 @@ DRAMCtrl::estimateLatency(DRAMPacket* dram_pkt, Tick inTime)
|
||||||
Tick accLat = 0;
|
Tick accLat = 0;
|
||||||
Tick bankLat = 0;
|
Tick bankLat = 0;
|
||||||
rowHitFlag = false;
|
rowHitFlag = false;
|
||||||
Tick potentialActTick;
|
|
||||||
|
|
||||||
const Bank& bank = dram_pkt->bankRef;
|
const Bank& bank = dram_pkt->bankRef;
|
||||||
|
|
||||||
|
@ -832,22 +832,27 @@ DRAMCtrl::estimateLatency(DRAMPacket* dram_pkt, Tick inTime)
|
||||||
bankLat += tCL;
|
bankLat += tCL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Row-buffer miss, need to close existing row
|
// Row-buffer miss, need to potentially close an existing row,
|
||||||
// once tRAS has expired, then open the new one,
|
// then open the new one, then add CAS latency
|
||||||
// then add cas latency.
|
Tick free_at = bank.freeAt;
|
||||||
Tick freeTime = std::max(bank.tRASDoneAt, bank.freeAt);
|
Tick precharge_delay = 0;
|
||||||
|
|
||||||
if (freeTime > inTime)
|
// Check if we first need to precharge
|
||||||
accLat += freeTime - inTime;
|
if (bank.openRow != Bank::NO_ROW) {
|
||||||
|
free_at = std::max(bank.preAllowedAt, free_at);
|
||||||
|
precharge_delay = tRP;
|
||||||
|
}
|
||||||
|
|
||||||
// If the there is no open row, then there is no precharge
|
// If the earliest time to issue the command is in the future,
|
||||||
// delay, otherwise go with tRP
|
// add it to the access latency
|
||||||
Tick precharge_delay = bank.openRow == Bank::NO_ROW ? 0 : tRP;
|
if (free_at > inTime)
|
||||||
|
accLat += free_at - inTime;
|
||||||
|
|
||||||
//The bank is free, and you may be able to activate
|
// We also need to account for the earliest activation time,
|
||||||
potentialActTick = inTime + accLat + precharge_delay;
|
// and potentially add that as well to the access latency
|
||||||
if (potentialActTick < bank.actAllowedAt)
|
Tick act_at = inTime + accLat + precharge_delay;
|
||||||
accLat += bank.actAllowedAt - potentialActTick;
|
if (act_at < bank.actAllowedAt)
|
||||||
|
accLat += bank.actAllowedAt - act_at;
|
||||||
|
|
||||||
accLat += precharge_delay + tRCD + tCL;
|
accLat += precharge_delay + tRCD + tCL;
|
||||||
bankLat += precharge_delay + tRCD + tCL;
|
bankLat += precharge_delay + tRCD + tCL;
|
||||||
|
@ -860,8 +865,8 @@ DRAMCtrl::estimateLatency(DRAMPacket* dram_pkt, Tick inTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DRAMCtrl::recordActivate(Tick act_tick, uint8_t rank, uint8_t bank,
|
DRAMCtrl::activateBank(Tick act_tick, uint8_t rank, uint8_t bank,
|
||||||
uint16_t row)
|
uint16_t row, Bank& bank_ref)
|
||||||
{
|
{
|
||||||
assert(0 <= rank && rank < ranksPerChannel);
|
assert(0 <= rank && rank < ranksPerChannel);
|
||||||
assert(actTicks[rank].size() == activationLimit);
|
assert(actTicks[rank].size() == activationLimit);
|
||||||
|
@ -869,14 +874,14 @@ DRAMCtrl::recordActivate(Tick act_tick, uint8_t rank, uint8_t bank,
|
||||||
DPRINTF(DRAM, "Activate at tick %d\n", act_tick);
|
DPRINTF(DRAM, "Activate at tick %d\n", act_tick);
|
||||||
|
|
||||||
// update the open row
|
// update the open row
|
||||||
assert(banks[rank][bank].openRow == Bank::NO_ROW);
|
assert(bank_ref.openRow == Bank::NO_ROW);
|
||||||
banks[rank][bank].openRow = row;
|
bank_ref.openRow = row;
|
||||||
|
|
||||||
// start counting anew, this covers both the case when we
|
// start counting anew, this covers both the case when we
|
||||||
// auto-precharged, and when this access is forced to
|
// auto-precharged, and when this access is forced to
|
||||||
// precharge
|
// precharge
|
||||||
banks[rank][bank].bytesAccessed = 0;
|
bank_ref.bytesAccessed = 0;
|
||||||
banks[rank][bank].rowAccesses = 0;
|
bank_ref.rowAccesses = 0;
|
||||||
|
|
||||||
++numBanksActive;
|
++numBanksActive;
|
||||||
assert(numBanksActive <= banksPerRank * ranksPerChannel);
|
assert(numBanksActive <= banksPerRank * ranksPerChannel);
|
||||||
|
@ -886,15 +891,12 @@ DRAMCtrl::recordActivate(Tick act_tick, uint8_t rank, uint8_t bank,
|
||||||
|
|
||||||
// start by enforcing tRRD
|
// start by enforcing tRRD
|
||||||
for(int i = 0; i < banksPerRank; i++) {
|
for(int i = 0; i < banksPerRank; i++) {
|
||||||
// next activate must not happen before tRRD
|
// next activate to any bank in this rank must not happen
|
||||||
banks[rank][i].actAllowedAt = act_tick + tRRD;
|
// before tRRD
|
||||||
|
banks[rank][i].actAllowedAt = std::max(act_tick + tRRD,
|
||||||
|
banks[rank][i].actAllowedAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
// next, we deal with tXAW, if the activation limit is disabled
|
||||||
// then we are done
|
// then we are done
|
||||||
if (actTicks[rank].empty())
|
if (actTicks[rank].empty())
|
||||||
|
@ -902,10 +904,9 @@ DRAMCtrl::recordActivate(Tick act_tick, uint8_t rank, uint8_t bank,
|
||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
if (actTicks[rank].back() && (act_tick - actTicks[rank].back()) < tXAW) {
|
if (actTicks[rank].back() && (act_tick - actTicks[rank].back()) < tXAW) {
|
||||||
// @todo For now, stick with a warning
|
panic("Got %d activates in window %d (%llu - %llu) which is smaller "
|
||||||
warn("Got %d activates in window %d (%d - %d) which is smaller "
|
"than %llu\n", activationLimit, act_tick - actTicks[rank].back(),
|
||||||
"than %d\n", activationLimit, act_tick - actTicks[rank].back(),
|
act_tick, actTicks[rank].back(), tXAW);
|
||||||
act_tick, actTicks[rank].back(), tXAW);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// shift the times used for the book keeping, the last element
|
// shift the times used for the book keeping, the last element
|
||||||
|
@ -920,10 +921,12 @@ DRAMCtrl::recordActivate(Tick act_tick, uint8_t rank, uint8_t bank,
|
||||||
// oldest in our window of X
|
// oldest in our window of X
|
||||||
if (actTicks[rank].back() && (act_tick - actTicks[rank].back()) < tXAW) {
|
if (actTicks[rank].back() && (act_tick - actTicks[rank].back()) < tXAW) {
|
||||||
DPRINTF(DRAM, "Enforcing tXAW with X = %d, next activate no earlier "
|
DPRINTF(DRAM, "Enforcing tXAW with X = %d, next activate no earlier "
|
||||||
"than %d\n", activationLimit, actTicks[rank].back() + tXAW);
|
"than %llu\n", activationLimit, actTicks[rank].back() + tXAW);
|
||||||
for(int j = 0; j < banksPerRank; j++)
|
for(int j = 0; j < banksPerRank; j++)
|
||||||
// next activate must not happen before end of window
|
// next activate must not happen before end of window
|
||||||
banks[rank][j].actAllowedAt = actTicks[rank].back() + tXAW;
|
banks[rank][j].actAllowedAt =
|
||||||
|
std::max(actTicks[rank].back() + tXAW,
|
||||||
|
banks[rank][j].actAllowedAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// at the point when this activate takes place, make sure we
|
// at the point when this activate takes place, make sure we
|
||||||
|
@ -1006,10 +1009,20 @@ DRAMCtrl::doDRAMAccess(DRAMPacket* dram_pkt)
|
||||||
// to estimateLatency(). However, between then and now, both the
|
// to estimateLatency(). However, between then and now, both the
|
||||||
// accessLatency and/or busBusyUntil may have changed. We need
|
// accessLatency and/or busBusyUntil may have changed. We need
|
||||||
// to correct for that.
|
// to correct for that.
|
||||||
|
|
||||||
Tick addDelay = (curTick() + accessLat < busBusyUntil) ?
|
Tick addDelay = (curTick() + accessLat < busBusyUntil) ?
|
||||||
busBusyUntil - (curTick() + accessLat) : 0;
|
busBusyUntil - (curTick() + accessLat) : 0;
|
||||||
|
|
||||||
|
// Update request parameters
|
||||||
|
dram_pkt->readyTime = curTick() + addDelay + accessLat + tBURST;
|
||||||
|
|
||||||
|
DPRINTF(DRAM, "Req %lld: curtick is %lld accessLat is %d " \
|
||||||
|
"readytime is %lld busbusyuntil is %lld. " \
|
||||||
|
"Scheduling at readyTime\n", dram_pkt->addr,
|
||||||
|
curTick(), accessLat, dram_pkt->readyTime, busBusyUntil);
|
||||||
|
|
||||||
|
// Make sure requests are not overlapping on the databus
|
||||||
|
assert(dram_pkt->readyTime - busBusyUntil >= tBURST);
|
||||||
|
|
||||||
Bank& bank = dram_pkt->bankRef;
|
Bank& bank = dram_pkt->bankRef;
|
||||||
|
|
||||||
// Update bank state
|
// Update bank state
|
||||||
|
@ -1019,7 +1032,7 @@ DRAMCtrl::doDRAMAccess(DRAMPacket* dram_pkt)
|
||||||
// If there is a page open, precharge it.
|
// If there is a page open, precharge it.
|
||||||
if (bank.openRow != Bank::NO_ROW) {
|
if (bank.openRow != Bank::NO_ROW) {
|
||||||
prechargeBank(bank, std::max(std::max(bank.freeAt,
|
prechargeBank(bank, std::max(std::max(bank.freeAt,
|
||||||
bank.tRASDoneAt),
|
bank.preAllowedAt),
|
||||||
curTick()) + tRP);
|
curTick()) + tRP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1030,14 +1043,30 @@ DRAMCtrl::doDRAMAccess(DRAMPacket* dram_pkt)
|
||||||
// any waiting for banks account for in freeAt
|
// any waiting for banks account for in freeAt
|
||||||
actTick = bank.freeAt - tCL - tRCD;
|
actTick = bank.freeAt - tCL - tRCD;
|
||||||
|
|
||||||
// If you activated a new row do to this access, the next access
|
// The next access has to respect tRAS for this bank
|
||||||
// will have to respect tRAS for this bank
|
bank.preAllowedAt = actTick + tRAS;
|
||||||
bank.tRASDoneAt = actTick + tRAS;
|
|
||||||
|
// Record the activation and deal with all the global timing
|
||||||
|
// constraints caused be a new activation (tRRD and tXAW)
|
||||||
|
activateBank(actTick, dram_pkt->rank, dram_pkt->bank,
|
||||||
|
dram_pkt->row, bank);
|
||||||
|
|
||||||
recordActivate(actTick, dram_pkt->rank, dram_pkt->bank,
|
|
||||||
dram_pkt->row);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this is a write, we also need to respect the write
|
||||||
|
// recovery time before a precharge
|
||||||
|
if (!dram_pkt->isRead) {
|
||||||
|
bank.preAllowedAt = std::max(bank.preAllowedAt,
|
||||||
|
dram_pkt->readyTime + tWR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We also have to respect tRP, and any constraints on when we may
|
||||||
|
// precharge the bank, in the case of reads this is really only
|
||||||
|
// going to cause any change if we did not have a row hit and are
|
||||||
|
// now forced to respect tRAS
|
||||||
|
bank.actAllowedAt = std::max(bank.actAllowedAt,
|
||||||
|
bank.preAllowedAt + tRP);
|
||||||
|
|
||||||
// increment the bytes accessed and the accesses per row
|
// increment the bytes accessed and the accesses per row
|
||||||
bank.bytesAccessed += burstSize;
|
bank.bytesAccessed += burstSize;
|
||||||
++bank.rowAccesses;
|
++bank.rowAccesses;
|
||||||
|
@ -1094,24 +1123,13 @@ DRAMCtrl::doDRAMAccess(DRAMPacket* dram_pkt)
|
||||||
// if this access should use auto-precharge, then we are
|
// if this access should use auto-precharge, then we are
|
||||||
// closing the row
|
// closing the row
|
||||||
if (auto_precharge) {
|
if (auto_precharge) {
|
||||||
prechargeBank(bank, std::max(bank.freeAt, bank.tRASDoneAt) + tRP);
|
prechargeBank(bank, std::max(bank.freeAt, bank.preAllowedAt) + tRP);
|
||||||
|
|
||||||
DPRINTF(DRAM, "Auto-precharged bank: %d\n", dram_pkt->bankId);
|
DPRINTF(DRAM, "Auto-precharged bank: %d\n", dram_pkt->bankId);
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTF(DRAM, "doDRAMAccess::bank.freeAt is %lld\n", bank.freeAt);
|
DPRINTF(DRAM, "doDRAMAccess::bank.freeAt is %lld\n", bank.freeAt);
|
||||||
|
|
||||||
// Update request parameters
|
|
||||||
dram_pkt->readyTime = curTick() + addDelay + accessLat + tBURST;
|
|
||||||
|
|
||||||
DPRINTF(DRAM, "Req %lld: curtick is %lld accessLat is %d " \
|
|
||||||
"readytime is %lld busbusyuntil is %lld. " \
|
|
||||||
"Scheduling at readyTime\n", dram_pkt->addr,
|
|
||||||
curTick(), accessLat, dram_pkt->readyTime, busBusyUntil);
|
|
||||||
|
|
||||||
// Make sure requests are not overlapping on the databus
|
|
||||||
assert(dram_pkt->readyTime - busBusyUntil >= tBURST);
|
|
||||||
|
|
||||||
// Update bus state
|
// Update bus state
|
||||||
busBusyUntil = dram_pkt->readyTime;
|
busBusyUntil = dram_pkt->readyTime;
|
||||||
|
|
||||||
|
@ -1412,7 +1430,7 @@ DRAMCtrl::processRefreshEvent()
|
||||||
// constraints
|
// constraints
|
||||||
Tick free_at =
|
Tick free_at =
|
||||||
std::max(std::max(banks[i][j].freeAt,
|
std::max(std::max(banks[i][j].freeAt,
|
||||||
banks[i][j].tRASDoneAt),
|
banks[i][j].preAllowedAt),
|
||||||
curTick()) + tRP;
|
curTick()) + tRP;
|
||||||
|
|
||||||
prechargeBank(banks[i][j], free_at);
|
prechargeBank(banks[i][j], free_at);
|
||||||
|
|
|
@ -143,10 +143,13 @@ class DRAMCtrl : public AbstractMemory
|
||||||
std::vector<std::deque<Tick>> actTicks;
|
std::vector<std::deque<Tick>> actTicks;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A basic class to track the bank state indirectly via times
|
* A basic class to track the bank state, i.e. what row is
|
||||||
* "freeAt" and "tRASDoneAt" and what page is currently open. The
|
* currently open (if any), when is the bank free to accept a new
|
||||||
* bank also keeps track of how many bytes have been accessed in
|
* command, when can it be precharged, and when can it be
|
||||||
* the open row since it was opened.
|
* activated.
|
||||||
|
*
|
||||||
|
* The bank also keeps track of how many bytes have been accessed
|
||||||
|
* in the open row since it was opened.
|
||||||
*/
|
*/
|
||||||
class Bank
|
class Bank
|
||||||
{
|
{
|
||||||
|
@ -158,14 +161,14 @@ class DRAMCtrl : public AbstractMemory
|
||||||
uint32_t openRow;
|
uint32_t openRow;
|
||||||
|
|
||||||
Tick freeAt;
|
Tick freeAt;
|
||||||
Tick tRASDoneAt;
|
Tick preAllowedAt;
|
||||||
Tick actAllowedAt;
|
Tick actAllowedAt;
|
||||||
|
|
||||||
uint32_t rowAccesses;
|
uint32_t rowAccesses;
|
||||||
uint32_t bytesAccessed;
|
uint32_t bytesAccessed;
|
||||||
|
|
||||||
Bank() :
|
Bank() :
|
||||||
openRow(NO_ROW), freeAt(0), tRASDoneAt(0), actAllowedAt(0),
|
openRow(NO_ROW), freeAt(0), preAllowedAt(0), actAllowedAt(0),
|
||||||
rowAccesses(0), bytesAccessed(0)
|
rowAccesses(0), bytesAccessed(0)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
@ -410,9 +413,15 @@ class DRAMCtrl : public AbstractMemory
|
||||||
* the maximum number of activations in the activation window. The
|
* the maximum number of activations in the activation window. The
|
||||||
* method updates the time that the banks become available based
|
* method updates the time that the banks become available based
|
||||||
* on the current limits.
|
* on the current limits.
|
||||||
|
*
|
||||||
|
* @param act_tick Time when the activation takes place
|
||||||
|
* @param rank Index of the rank
|
||||||
|
* @param bank Index of the bank
|
||||||
|
* @param row Index of the row
|
||||||
|
* @param bank_ref Reference to the bank
|
||||||
*/
|
*/
|
||||||
void recordActivate(Tick act_tick, uint8_t rank, uint8_t bank,
|
void activateBank(Tick act_tick, uint8_t rank, uint8_t bank,
|
||||||
uint16_t row);
|
uint16_t row, Bank& bank_ref);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Precharge a given bank and also update when the precharge is
|
* Precharge a given bank and also update when the precharge is
|
||||||
|
@ -420,9 +429,9 @@ class DRAMCtrl : public AbstractMemory
|
||||||
* accesses to the open page.
|
* accesses to the open page.
|
||||||
*
|
*
|
||||||
* @param bank The bank to precharge
|
* @param bank The bank to precharge
|
||||||
* @param free_at Time when the precharge is done
|
* @param pre_done_at Time when the precharge is done
|
||||||
*/
|
*/
|
||||||
void prechargeBank(Bank& bank, Tick free_at);
|
void prechargeBank(Bank& bank, Tick pre_done_at);
|
||||||
|
|
||||||
void printParams() const;
|
void printParams() const;
|
||||||
|
|
||||||
|
@ -495,6 +504,7 @@ class DRAMCtrl : public AbstractMemory
|
||||||
const Tick tCL;
|
const Tick tCL;
|
||||||
const Tick tRP;
|
const Tick tRP;
|
||||||
const Tick tRAS;
|
const Tick tRAS;
|
||||||
|
const Tick tWR;
|
||||||
const Tick tRFC;
|
const Tick tRFC;
|
||||||
const Tick tREFI;
|
const Tick tREFI;
|
||||||
const Tick tRRD;
|
const Tick tRRD;
|
||||||
|
|
Loading…
Reference in a new issue