summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2014-05-09 18:58:48 -0400
committerAndreas Hansson <andreas.hansson@arm.com>2014-05-09 18:58:48 -0400
commit8e3869411d85ddfec1d30a5da4dbfb30adf3e6ea (patch)
treebf5fdedf6b4b8c34d63d4138dd81b4d3c32ff669
parent0ba1e72e9b9c369e93b282100b0064e76191f0eb (diff)
downloadgem5-8e3869411d85ddfec1d30a5da4dbfb30adf3e6ea.tar.xz
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).
-rw-r--r--src/mem/dram_ctrl.cc31
1 files changed, 26 insertions, 5 deletions
diff --git a/src/mem/dram_ctrl.cc b/src/mem/dram_ctrl.cc
index 2da4b7609..b5566c88d 100644
--- a/src/mem/dram_ctrl.cc
+++ b/src/mem/dram_ctrl.cc
@@ -850,6 +850,9 @@ DRAMCtrl::prechargeBank(Bank& bank, Tick pre_at)
bank.openRow = Bank::NO_ROW;
+ // no precharge allowed before this one
+ bank.preAllowedAt = pre_at;
+
Tick pre_done_at = pre_at + tRP;
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
// state
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");
+
+ // first determine when we can precharge
+ Tick pre_at = curTick();
for (int i = 0; i < ranksPerChannel; i++) {
for (int j = 0; j < banksPerRank; j++) {
- 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());
+ // 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 j = 0; j < banksPerRank; j++) {
+ if (banks[i][j].openRow != Bank::NO_ROW) {
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);
}
}
}