diff options
author | Andreas Hansson <andreas.hansson@arm.com> | 2014-05-09 18:58:48 -0400 |
---|---|---|
committer | Andreas Hansson <andreas.hansson@arm.com> | 2014-05-09 18:58:48 -0400 |
commit | 8e3869411d85ddfec1d30a5da4dbfb30adf3e6ea (patch) | |
tree | bf5fdedf6b4b8c34d63d4138dd81b4d3c32ff669 | |
parent | 0ba1e72e9b9c369e93b282100b0064e76191f0eb (diff) | |
download | gem5-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.cc | 31 |
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); } } } |