/*
- * Copyright (c) 2010-2015 ARM Limited
+ * Copyright (c) 2010-2016 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
bank_ref.bank, rank_ref.rank, act_tick,
ranks[rank_ref.rank]->numBanksActive);
- rank_ref.power.powerlib.doCommand(MemCommand::ACT, bank_ref.bank,
- divCeil(act_tick, tCK) -
- timeStampOffset);
+ rank_ref.cmdList.push_back(Command(MemCommand::ACT, bank_ref.bank,
+ act_tick));
DPRINTF(DRAMPower, "%llu,ACT,%d,%d\n", divCeil(act_tick, tCK) -
timeStampOffset, bank_ref.bank, rank_ref.rank);
if (trace) {
- rank_ref.power.powerlib.doCommand(MemCommand::PRE, bank.bank,
- divCeil(pre_at, tCK) -
- timeStampOffset);
+ rank_ref.cmdList.push_back(Command(MemCommand::PRE, bank.bank,
+ pre_at));
DPRINTF(DRAMPower, "%llu,PRE,%d,%d\n", divCeil(pre_at, tCK) -
timeStampOffset, bank.bank, rank_ref.rank);
}
MemCommand::cmds command = (mem_cmd == "RD") ? MemCommand::RD :
MemCommand::WR;
- // if this access should use auto-precharge, then we are
- // closing the row
- if (auto_precharge) {
- // if auto-precharge push a PRE command at the correct tick to the
- // list used by DRAMPower library to calculate power
- prechargeBank(rank, bank, std::max(curTick(), bank.preAllowedAt));
-
- DPRINTF(DRAM, "Auto-precharged bank: %d\n", dram_pkt->bankId);
- }
-
// Update bus state
busBusyUntil = dram_pkt->readyTime;
DPRINTF(DRAM, "Access to %lld, ready at %lld bus busy until %lld.\n",
dram_pkt->addr, dram_pkt->readyTime, busBusyUntil);
- dram_pkt->rankRef.power.powerlib.doCommand(command, dram_pkt->bank,
- divCeil(cmd_at, tCK) -
- timeStampOffset);
+ dram_pkt->rankRef.cmdList.push_back(Command(command, dram_pkt->bank,
+ cmd_at));
DPRINTF(DRAMPower, "%llu,%s,%d,%d\n", divCeil(cmd_at, tCK) -
timeStampOffset, mem_cmd, dram_pkt->bank, dram_pkt->rank);
+ // if this access should use auto-precharge, then we are
+ // closing the row after the read/write burst
+ if (auto_precharge) {
+ // if auto-precharge push a PRE command at the correct tick to the
+ // list used by DRAMPower library to calculate power
+ prechargeBank(rank, bank, std::max(curTick(), bank.preAllowedAt));
+
+ DPRINTF(DRAM, "Auto-precharged bank: %d\n", dram_pkt->bankId);
+ }
+
// Update the minimum timing between the requests, this is a
// conservative estimate of when we have to schedule the next
// request to not introduce any unecessary bubbles. In most cases
}
}
+void
+DRAMCtrl::Rank::flushCmdList()
+{
+ // at the moment sort the list of commands and update the counters
+ // for DRAMPower libray when doing a refresh
+ sort(cmdList.begin(), cmdList.end(), DRAMCtrl::sortTime);
+
+ auto next_iter = cmdList.begin();
+ // push to commands to DRAMPower
+ for ( ; next_iter != cmdList.end() ; ++next_iter) {
+ Command cmd = *next_iter;
+ if (cmd.timeStamp <= curTick()) {
+ // Move all commands at or before curTick to DRAMPower
+ power.powerlib.doCommand(cmd.type, cmd.bank,
+ divCeil(cmd.timeStamp, memory.tCK) -
+ memory.timeStampOffset);
+ } else {
+ // done - found all commands at or before curTick()
+ // next_iter references the 1st command after curTick
+ break;
+ }
+ }
+ // reset cmdList to only contain commands after curTick
+ // if there are no commands after curTick, updated cmdList will be empty
+ // in this case, next_iter is cmdList.end()
+ cmdList.assign(next_iter, cmdList.end());
+}
+
void
DRAMCtrl::Rank::processActivateEvent()
{
}
// precharge all banks in rank
- power.powerlib.doCommand(MemCommand::PREA, 0,
- divCeil(pre_at, memory.tCK) -
- memory.timeStampOffset);
+ cmdList.push_back(Command(MemCommand::PREA, 0, pre_at));
DPRINTF(DRAMPower, "%llu,PREA,0,%d\n",
divCeil(pre_at, memory.tCK) -
}
// at the moment this affects all ranks
- power.powerlib.doCommand(MemCommand::REF, 0,
- divCeil(curTick(), memory.tCK) -
- memory.timeStampOffset);
-
- // at the moment sort the list of commands and update the counters
- // for DRAMPower libray when doing a refresh
- sort(power.powerlib.cmdList.begin(),
- power.powerlib.cmdList.end(), DRAMCtrl::sortTime);
+ cmdList.push_back(Command(MemCommand::REF, 0, curTick()));
+
+ // All commands up to refresh have completed
+ // flush cmdList to DRAMPower
+ flushCmdList();
// update the counters for DRAMPower, passing false to
// indicate that this is not the last command in the
/*
- * Copyright (c) 2012-2015 ARM Limited
+ * Copyright (c) 2012-2016 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
BusState busState;
+ /**
+ * Simple structure to hold the values needed to keep track of
+ * commands for DRAMPower
+ */
+ struct Command {
+ Data::MemCommand::cmds type;
+ uint8_t bank;
+ Tick timeStamp;
+
+ constexpr Command(Data::MemCommand::cmds _type, uint8_t _bank,
+ Tick time_stamp)
+ : type(_type), bank(_bank), timeStamp(time_stamp)
+ { }
+ };
+
/**
* A basic class to track the bank state, i.e. what row is
* currently open (if any), when is the bank free to accept a new
*/
DRAMPower power;
+ /**
+ * List of comamnds issued, to be sent to DRAMPpower at refresh
+ * and stats dump. Keep commands here since commands to different
+ * banks are added out of order. Will only pass commands up to
+ * curTick() to DRAMPower after sorting.
+ */
+ std::vector<Command> cmdList;
+
/**
* Vector of Banks. Each rank is made of several devices which in
* term are made from several banks.
*/
void checkDrainDone();
+ /**
+ * Push command out of cmdList queue that are scheduled at
+ * or before curTick() to DRAMPower library
+ * All commands before curTick are guaranteed to be complete
+ * and can safely be flushed.
+ */
+ void flushCmdList();
+
/*
* Function to register Stats
*/
void updatePowerStats(Rank& rank_ref);
/**
- * Function for sorting commands in the command list of DRAMPower.
+ * Function for sorting Command structures based on timeStamp
*
- * @param a Memory Command in command list of DRAMPower library
- * @param next Memory Command in command list of DRAMPower
- * @return true if timestamp of Command 1 < timestamp of Command 2
+ * @param a Memory Command
+ * @param next Memory Command
+ * @return true if timeStamp of Command 1 < timeStamp of Command 2
*/
- static bool sortTime(const Data::MemCommand& m1,
- const Data::MemCommand& m2) {
- return m1.getTimeInt64() < m2.getTimeInt64();
+ static bool sortTime(const Command& cmd, const Command& cmd_next) {
+ return cmd.timeStamp < cmd_next.timeStamp;
};
-
public:
void regStats() override;