mem: Add precharge all (PREA) to the DRAM controller
This patch adds the basic ingredients for a precharge all operation, to be used in conjunction with DRAM power modelling. Currently we do not try and apply any cleverness when precharging all banks, thus even if only a single bank is open we use PREA as opposed to PRE. At the moment we only have a single tRP (tRPpb), and do not model the slightly longer all-bank precharge constraint (tRPab).
This commit is contained in:
parent
0ba1e72e9b
commit
8e3869411d
1 changed files with 26 additions and 5 deletions
|
@ -850,6 +850,9 @@ DRAMCtrl::prechargeBank(Bank& bank, Tick pre_at)
|
||||||
|
|
||||||
bank.openRow = Bank::NO_ROW;
|
bank.openRow = Bank::NO_ROW;
|
||||||
|
|
||||||
|
// no precharge allowed before this one
|
||||||
|
bank.preAllowedAt = pre_at;
|
||||||
|
|
||||||
Tick pre_done_at = pre_at + tRP;
|
Tick pre_done_at = pre_at + tRP;
|
||||||
|
|
||||||
bank.actAllowedAt = std::max(bank.actAllowedAt, pre_done_at);
|
bank.actAllowedAt = std::max(bank.actAllowedAt, pre_done_at);
|
||||||
|
@ -1305,16 +1308,34 @@ DRAMCtrl::processRefreshEvent()
|
||||||
// precharge any active bank if we are not already in the idle
|
// precharge any active bank if we are not already in the idle
|
||||||
// state
|
// state
|
||||||
if (pwrState != PWR_IDLE) {
|
if (pwrState != PWR_IDLE) {
|
||||||
|
// at the moment, we use a precharge all even if there is
|
||||||
|
// only a single bank open
|
||||||
DPRINTF(DRAM, "Precharging all\n");
|
DPRINTF(DRAM, "Precharging all\n");
|
||||||
|
|
||||||
|
// first determine when we can precharge
|
||||||
|
Tick pre_at = curTick();
|
||||||
|
for (int i = 0; i < ranksPerChannel; i++) {
|
||||||
|
for (int j = 0; j < banksPerRank; j++) {
|
||||||
|
// respect both causality and any existing bank
|
||||||
|
// constraints, some banks could already have a
|
||||||
|
// (auto) precharge scheduled
|
||||||
|
pre_at = std::max(banks[i][j].preAllowedAt, pre_at);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure all banks are precharged, and for those that
|
||||||
|
// already are, update their availability
|
||||||
|
Tick act_allowed_at = pre_at + tRP;
|
||||||
|
|
||||||
for (int i = 0; i < ranksPerChannel; i++) {
|
for (int i = 0; i < ranksPerChannel; i++) {
|
||||||
for (int j = 0; j < banksPerRank; j++) {
|
for (int j = 0; j < banksPerRank; j++) {
|
||||||
if (banks[i][j].openRow != Bank::NO_ROW) {
|
if (banks[i][j].openRow != Bank::NO_ROW) {
|
||||||
// respect both causality and any existing bank
|
|
||||||
// constraints
|
|
||||||
Tick pre_at = std::max(banks[i][j].preAllowedAt,
|
|
||||||
curTick());
|
|
||||||
|
|
||||||
prechargeBank(banks[i][j], pre_at);
|
prechargeBank(banks[i][j], pre_at);
|
||||||
|
} else {
|
||||||
|
banks[i][j].actAllowedAt =
|
||||||
|
std::max(banks[i][j].actAllowedAt, act_allowed_at);
|
||||||
|
banks[i][j].preAllowedAt =
|
||||||
|
std::max(banks[i][j].preAllowedAt, pre_at);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue