if issubclass(cls, m5.objects.DRAMCtrl) and opt_mem_ranks:
mem_ctrl.ranks_per_channel = opt_mem_ranks
+ # Enable low-power DRAM states if option is set
+ if issubclass(cls, m5.objects.DRAMCtrl):
+ mem_ctrl.enable_dram_powerdown = \
+ options.enable_dram_powerdown
+
if opt_elastic_trace_en:
mem_ctrl.latency = '1ns'
print("For elastic trace, over-riding Simple Memory "
parser.add_option("--mem-size", action="store", type="string",
default="512MB",
help="Specify the physical memory size (single memory)")
+ parser.add_option("--enable-dram-powerdown", action="store_true",
+ help="Enable low-power states in DRAMCtrl")
parser.add_option("--memchecker", action="store_true")
# to be instantiated for a multi-channel configuration
channels = Param.Unsigned(1, "Number of channels")
+ # Enable DRAM powerdown states if True. This is False by default due to
+ # performance being lower when enabled
+ enable_dram_powerdown = Param.Bool(False, "Enable powerdown states")
+
# For power modelling we need to know if the DRAM has a DLL or not
dll = Param.Bool(True, "DRAM has DLL or not")
backendLatency(p->static_backend_latency),
nextBurstAt(0), prevArrival(0),
nextReqTime(0), activeRank(0), timeStampOffset(0),
- lastStatsResetTick(0)
+ lastStatsResetTick(0), enableDRAMPowerdown(p->enable_dram_powerdown)
{
// sanity check the ranks since we rely on bit slicing for the
// address decoding
// track if this is the last packet before idling
// and that there are no outstanding commands to this rank
if (dram_pkt->rankRef.isQueueEmpty() &&
- dram_pkt->rankRef.outstandingEvents == 0) {
+ dram_pkt->rankRef.outstandingEvents == 0 && enableDRAMPowerdown) {
// verify that there are no events scheduled
assert(!dram_pkt->rankRef.activateEvent.scheduled());
assert(!dram_pkt->rankRef.prechargeEvent.scheduled());
if (numBanksActive == 0) {
// no reads to this rank in the Q and no pending
// RD/WR or refresh commands
- if (isQueueEmpty() && outstandingEvents == 0) {
+ if (isQueueEmpty() && outstandingEvents == 0 &&
+ memory.enableDRAMPowerdown) {
// should still be in ACT state since bank still open
assert(pwrState == PWR_ACT);
// Force PRE power-down if there are no outstanding commands
// in Q after refresh.
- } else if (isQueueEmpty()) {
+ } else if (isQueueEmpty() && memory.enableDRAMPowerdown) {
// still have refresh event outstanding but there should
// be no other events outstanding
assert(outstandingEvents == 1);
// will issue refresh immediately upon entry
if (pwrStatePostRefresh == PWR_PRE_PDN && isQueueEmpty() &&
(memory.drainState() != DrainState::Draining) &&
- (memory.drainState() != DrainState::Drained)) {
+ (memory.drainState() != DrainState::Drained) &&
+ memory.enableDRAMPowerdown) {
DPRINTF(DRAMState, "Rank %d bypassing refresh and transitioning "
"to self refresh at %11u tick\n", rank, curTick());
powerDownSleep(PWR_SREF, curTick());