summaryrefslogtreecommitdiff
path: root/ext/drampower/src
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2014-10-09 17:52:03 -0400
committerAndreas Hansson <andreas.hansson@arm.com>2014-10-09 17:52:03 -0400
commite0e8b08a42210011205b52c3628749f60658e58c (patch)
treee6daae3c8cd249f52c6504ee2b7fc07805085429 /ext/drampower/src
parentc81517c293cdd3f612efae94d1143fb0cf002287 (diff)
downloadgem5-e0e8b08a42210011205b52c3628749f60658e58c.tar.xz
ext: Add DRAMPower to enable on-line DRAM power modelling
This patch adds the open-source (BSD 3-clause) tool DRAMPower, commit 8d3cf4bbb10aa202d850ef5e5e3e4f53aa668fa6, to be built as a part of the simulator. We have chosen this specific version of DRAMPower as it provides the necessary functionality, and future updates will be coordinated with the DRAMPower development team. The files added only include the bits needed to build the library, thus excluding all memory specifications, traces, and the stand-alone DRAMPower command-line tool. A future patch includes the DRAMPower functionality in the DRAM controller, to enable on-line DRAM power modelling, and avoid using post-processing of traces.
Diffstat (limited to 'ext/drampower/src')
-rw-r--r--ext/drampower/src/CmdScheduler.cc659
-rw-r--r--ext/drampower/src/CmdScheduler.h168
-rw-r--r--ext/drampower/src/CommandAnalysis.cc666
-rw-r--r--ext/drampower/src/CommandAnalysis.h213
-rw-r--r--ext/drampower/src/MemArchitectureSpec.cc74
-rw-r--r--ext/drampower/src/MemArchitectureSpec.h62
-rw-r--r--ext/drampower/src/MemCommand.cc159
-rw-r--r--ext/drampower/src/MemCommand.h170
-rw-r--r--ext/drampower/src/MemPowerSpec.cc107
-rw-r--r--ext/drampower/src/MemPowerSpec.h77
-rw-r--r--ext/drampower/src/MemTimingSpec.cc110
-rw-r--r--ext/drampower/src/MemTimingSpec.h78
-rw-r--r--ext/drampower/src/MemoryPowerModel.cc428
-rw-r--r--ext/drampower/src/MemoryPowerModel.h176
-rw-r--r--ext/drampower/src/MemorySpecification.cc60
-rw-r--r--ext/drampower/src/MemorySpecification.h239
-rw-r--r--ext/drampower/src/Parameter.cc121
-rw-r--r--ext/drampower/src/Parameter.h102
-rw-r--r--ext/drampower/src/Parametrisable.cc133
-rw-r--r--ext/drampower/src/Parametrisable.h136
-rw-r--r--ext/drampower/src/TraceParser.cc120
-rw-r--r--ext/drampower/src/TraceParser.h70
-rw-r--r--ext/drampower/src/Utils.h64
-rw-r--r--ext/drampower/src/libdrampower/LibDRAMPower.cc83
-rw-r--r--ext/drampower/src/libdrampower/LibDRAMPower.h80
-rw-r--r--ext/drampower/src/uncrustify.cfg280
26 files changed, 4635 insertions, 0 deletions
diff --git a/ext/drampower/src/CmdScheduler.cc b/ext/drampower/src/CmdScheduler.cc
new file mode 100644
index 000000000..bffc5d3bb
--- /dev/null
+++ b/ext/drampower/src/CmdScheduler.cc
@@ -0,0 +1,659 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Karthik Chandrasekar
+ *
+ */
+#include "CmdScheduler.h"
+
+#include <cassert>
+#include <cmath> // For log2
+
+#include <algorithm> // For max
+
+
+using namespace std;
+using namespace Data;
+
+// Read the traces and get the transaction. Each transaction is executed by
+// scheduling a number of commands to the memory. Hence, the transactions are
+// translated into a sequence of commands which will be used for power analysis.
+void cmdScheduler::transTranslation(MemorySpecification memSpec,
+ ifstream& trans_trace, int grouping, int interleaving, int burst, int powerdown)
+{
+ commands.open("commands.trace", ifstream::out);
+ MemArchitectureSpec& memArchSpec = memSpec.memArchSpec;
+ nBanks = memArchSpec.nbrOfBanks;
+ nColumns = memArchSpec.nbrOfColumns;
+ burstLength = memArchSpec.burstLength;
+ nbrOfBankGroups = memArchSpec.nbrOfBankGroups;
+
+ BGI = grouping;
+ BI = interleaving;
+ BC = burst;
+ power_down = powerdown;
+
+ schedulingInitialization(memSpec);
+ getTrans(trans_trace, memSpec);
+
+ trans_trace.close();
+ commands.close();
+ ACT.erase(ACT.begin(), ACT.end());
+ PRE.erase(PRE.begin(), PRE.end());
+ RDWR.erase(RDWR.begin(), RDWR.end());
+ cmdScheduling.erase(cmdScheduling.begin(), cmdScheduling.end());
+ cmdList.erase(cmdList.begin(), cmdList.end());
+ transTrace.erase(transTrace.begin(), transTrace.end());
+} // cmdScheduler::transTranslation
+
+// initialize the variables and vectors for starting command scheduling.
+void cmdScheduler::schedulingInitialization(MemorySpecification memSpec)
+{
+ MemTimingSpec& memTimingSpec = memSpec.memTimingSpec;
+
+ ACT.resize(2 * memSpec.memArchSpec.nbrOfBanks);
+ RDWR.resize(2 * memSpec.memArchSpec.nbrOfBanks);
+ PRE.resize(memSpec.memArchSpec.nbrOfBanks);
+ bankaccess = memSpec.memArchSpec.nbrOfBanks;
+ if (!ACT.empty()) {
+ ACT.erase(ACT.begin(), ACT.end());
+ }
+ if (!PRE.empty()) {
+ PRE.erase(PRE.begin(), PRE.end());
+ }
+ if (!RDWR.empty()) {
+ RDWR.erase(RDWR.begin(), RDWR.end());
+ }
+
+ ///////////////initialization//////////////
+ for (unsigned i = 0; i < memSpec.memArchSpec.nbrOfBanks; i++) {
+ cmd.Type = PRECHARGE;
+ cmd.bank = i;
+ cmd.name = "PRE";
+ if (memSpec.id == "WIDEIO_SDR")
+ cmd.time = 1 - static_cast<double>(memSpec.memTimingSpec.TAW);
+ else
+ cmd.time = 1 - static_cast<double>(memSpec.memTimingSpec.FAW);
+
+ PRE.push_back(cmd);
+
+ cmd.Type = ACTIVATE;
+ cmd.name = "ACT";
+ ACT.push_back(cmd);
+
+ cmd.Type = WRITE;
+ cmd.name = "WRITE";
+ cmd.time = -1;
+ RDWR[i].push_back(cmd);
+ }
+ tREF = memTimingSpec.REFI;
+ transFinish.time = 0;
+ transFinish.bank = 0;
+
+ PreRDWR.bank = -1;
+ PreRDWR.Type = READ;
+ PreRDWR.name = "RD";
+ PreRDWR.time = -1;
+ startTime = 0;
+} // cmdScheduler::schedulingInitialization
+
+// transactions are generated according to the information read from the traces.
+// Then the command scheduling function is triggered to generate commands and
+// schedule them to the memory according to the timing constraints.
+void cmdScheduler::getTrans(std::ifstream& trans_trace, MemorySpecification memSpec)
+{
+ std::string line;
+
+ transTime = 0;
+ unsigned newtranstime;
+ unsigned transAddr;
+ unsigned transType = 1;
+ trans TransItem;
+
+ if (!transTrace.empty()) {
+ transTrace.erase(transTrace.begin(), transTrace.end());
+ }
+
+ while (getline(trans_trace, line)) {
+ istringstream linestream(line);
+ string item;
+ unsigned itemnum = 0;
+ while (getline(linestream, item, ',')) {
+ if (itemnum == 0) {
+ stringstream timestamp(item);
+ timestamp >> newtranstime;
+ transTime = transTime + newtranstime;
+ } else if (itemnum == 1) {
+ if (item == "write" || item == "WRITE") {
+ transType = WRITE;
+ } else {
+ transType = READ;
+ }
+ } else if (itemnum == 2) {
+ stringstream timestamp(item);
+ timestamp >> std::hex >> transAddr;
+ }
+ itemnum++;
+ }
+ // generate a transaction
+ TransItem.timeStamp = transTime;
+ TransItem.logicalAddress = transAddr;
+ TransItem.type = transType;
+
+ transTrace.push_back(TransItem);
+
+ if (transTrace.size() == MILLION) {
+ // The scheduling is implemented for every MILLION transactions.
+ // It is used to reduce the used memory during the running of this tool.
+ analyticalScheduling(memSpec);
+ transTrace.erase(transTrace.begin(), transTrace.end());
+ }
+ }
+
+ if ((transTrace.size() < MILLION) && (!transTrace.empty())) {
+ analyticalScheduling(memSpec);
+ transTrace.erase(transTrace.begin(), transTrace.end());
+ }
+} // cmdScheduler::getTrans
+
+// Transactions are executed individually and the command scheduling is
+// independent between transactions. The commands for a new transaction cannot
+// be scheduled until all the commands for the current one are scheduled.
+// After the scheduling, a sequence of commands are obtained and they are written
+// into commands.txt which will be used for power analysis.
+void cmdScheduler::analyticalScheduling(MemorySpecification memSpec)
+{
+ int Bs = -1;
+ int transType = -1;
+ double timer = 0;
+ int bankGroupPointer = 0;
+ int bankGroupAddr = 0;
+ bool collisionFound;
+ physicalAddr PhysicalAddress;
+ bool bankGroupSwitch = false;
+ std::vector<unsigned> bankPointer(nbrOfBankGroups, 0);
+ std::vector<int> bankAccessNum(nBanks, -1);
+ std::vector<bool> ACTSchedule(nBanks, false);
+ int bankAddr = -1;
+ double endTime = 0;
+ double tComing_REF = 0;
+
+ Inselfrefresh = 0;
+
+ MemTimingSpec& memTimingSpec = memSpec.memTimingSpec;
+
+ for (unsigned t = 0; t < transTrace.size(); t++) {
+ cmdScheduling.erase(cmdScheduling.begin(), cmdScheduling.end());
+
+ for (unsigned i = 0; i < nBanks; i++) {
+ ACTSchedule[i] = false;
+ bankAccessNum[i] = -1;
+ }
+
+ timingsGet = false;
+ timer = transTrace[t].timeStamp;
+
+ PhysicalAddress = memoryMap(transTrace[t], memSpec);
+
+ for (unsigned i = 0; i < nbrOfBankGroups; i++) {
+ bankPointer[i] = PhysicalAddress.bankAddr; // the bank pointer per group.
+ }
+ bankGroupPointer = PhysicalAddress.bankGroupAddr;
+
+ endTime = max(transFinish.time, PRE[transFinish.bank].time +
+ static_cast<int>(memTimingSpec.RP));
+
+ // Before starting the scheduling for the next transaction, it has to
+ // check whether it is necessary for implementing power down.
+ if (power_down == SELF_REFRESH)
+ pdScheduling(endTime, timer, memSpec);
+ else if (power_down == POWER_DOWN)
+ pdScheduling(endTime, min(timer, tREF), memSpec);
+
+ tComing_REF = tREF;
+
+ ///////////////Scheduling Refresh////////////////////////
+ if (((transFinish.time >= tREF) || (timer >= tREF))) {
+ for (double i = 0; i <= ((timer - tComing_REF) > 0 ? (timer - tComing_REF) /
+ memTimingSpec.REFI : 0); i++) {
+ cmd.bank = 0;
+ cmd.name = "REF";
+ cmd.time = max(max(max(transFinish.time, PRE[transFinish.bank].time
+ + static_cast<int>(memTimingSpec.RP)), tREF), startTime);
+ if (((power_down == SELF_REFRESH) && !Inselfrefresh) ||
+ (power_down != SELF_REFRESH)) {
+ cmdScheduling.push_back(cmd);
+ startTime = cmd.time + memTimingSpec.RFC;
+ }
+ tREF = tREF + memTimingSpec.REFI;
+ // during the refreshing, power down should be taken into account.
+ if (!Inselfrefresh)
+ pdScheduling(endTime, min(timer, tREF), memSpec);
+ }
+ }
+ ///////////////Execution Transactions///////////////////
+ Bs = PhysicalAddress.bankAddr;
+ transType = transTrace[t].type;
+
+ tRWTP = getRWTP(transType, memSpec);
+
+ for (int i = 0; i < BI; i++) {
+ for (int k = 0; k < BC; k++) {
+ if (memSpec.memoryType == MemoryType::DDR4) {
+ bankGroupPointer = PhysicalAddress.bankGroupAddr;
+ }
+
+ for (int j = 0; j < BGI; j++) {
+ bankGroupSwitch = false;
+ if (memSpec.memoryType == MemoryType::DDR4) {
+ if (bankGroupPointer != bankGroupAddr) {
+ bankGroupSwitch = true;
+ }
+ // update to the current bank group address.
+ bankGroupAddr = PhysicalAddress.bankGroupAddr + j;
+ bankAddr = bankGroupAddr * nBanks / nbrOfBankGroups +
+ bankPointer[bankGroupAddr];
+ } else {
+ bankAddr = Bs + i;
+ }
+
+ if (!timingsGet) {
+ getTimingConstraints(bankGroupSwitch, memSpec,
+ PreRDWR.Type, transType);
+ }
+
+ ////////////////ACT Scheduling///////////////////
+ if (!ACTSchedule[bankAddr]) {
+ cmd.bank = bankAddr;
+ cmd.PhysicalAddr.bankAddr = cmd.bank;
+ cmd.PhysicalAddr.rowAddr = PhysicalAddress.rowAddr;
+ cmd.Type = ACTIVATE;
+ cmd.name = "ACT";
+ Inselfrefresh = 0;
+ cmd.time = max(max(ACT[bankaccess - 1].time + tRRD_init,
+ PRE[cmd.bank].time + static_cast<int>(memTimingSpec.RP)),
+ ACT[bankaccess - 4].time +
+ static_cast<int>(memTimingSpec.FAW));
+
+ if (memSpec.memoryType == MemoryType::WIDEIO_SDR) {
+ cmd.time = max(max(ACT[bankaccess - 1].time + tRRD_init,
+ PRE[cmd.bank].time + static_cast<int>(memTimingSpec.RP)),
+ ACT[bankaccess - 2].time +
+ static_cast<int>(memTimingSpec.TAW));
+ }
+
+ if ((i == 0) && (j == 0)) {
+ cmd.time = max(cmd.time, PreRDWR.time + 1);
+ cmd.time = max(cmd.time, timer);
+ cmd.time = max(startTime, cmd.time);
+ }
+
+ //////////collision detection////////////////////
+ for (int n = 1; n <= i * BGI + j; n++) {
+ collisionFound = false;
+ for (unsigned m = 0; m < RDWR[bankaccess - n].size(); m++) {
+ if (RDWR[bankaccess - n][m].time == cmd.time) {
+ cmd.time += 1; // ACT is shifted
+ collisionFound = true;
+ break;
+ }
+ }
+ if (collisionFound) {
+ break;
+ }
+ }
+
+ ACT.push_back(cmd);
+ cmdScheduling.push_back(cmd);
+
+ ACTSchedule[bankAddr] = true;
+ bankAccessNum[bankAddr] = bankaccess;
+ bankaccess++;
+ }
+
+ /////RDWR Scheduling//////
+ cmd.bank = bankAddr;
+ cmd.PhysicalAddr.bankAddr = cmd.bank;
+ cmd.PhysicalAddr.rowAddr = PhysicalAddress.rowAddr;
+ cmd.PhysicalAddr.colAddr = PhysicalAddress.colAddr + k * burstLength;
+ cmd.Type = transType;
+ switch (transType) {
+ case READ:
+ cmd.name = "RD";
+ break;
+
+ case WRITE:
+ cmd.name = "WR";
+ break;
+ }
+ for (int ACTBank = static_cast<int>(ACT.size() - 1);
+ ACTBank >= 0; ACTBank--) {
+ if (ACT[ACTBank].bank == bankAddr) {
+ cmd.time = max(PreRDWR.time + tSwitch_init, ACT.back().time
+ + static_cast<int>(memTimingSpec.RCD));
+ break;
+ }
+ }
+
+ if ((i == BI - 1) && (k == BC - 1) && (j == BGI - 1)) {
+ transFinish.time = cmd.time + 1;
+ transFinish.bank = bankAddr;
+ }
+ if (k == BC - 1) {
+ switch (transType) {
+ case READ:
+ cmd.name = "RDA";
+ break;
+
+ case WRITE:
+ cmd.name = "WRA";
+ break;
+ }
+ }
+ PreRDWR = cmd;
+
+ RDWR[bankAccessNum[bankAddr]].push_back(cmd);
+ cmdScheduling.push_back(cmd);
+
+ ////////////////PRE Scheduling////////////////////
+ if (k == BC - 1) {
+ PRE[bankAddr].bank = bankAddr;
+ PRE[bankAddr].Type = PRECHARGE;
+ PRE[bankAddr].name = "PRE";
+ for (int ACTBank = static_cast<int>(ACT.size() - 1);
+ ACTBank >= 0; ACTBank--) {
+ if (ACT[ACTBank].bank == bankAddr) {
+ PRE[bankAddr].time = max(ACT.back().time +
+ static_cast<int>(memTimingSpec.RAS),
+ PreRDWR.time + tRWTP);
+ break;
+ }
+ }
+ bankPointer[bankGroupAddr] = bankPointer[bankGroupAddr] + 1;
+ }
+
+ bankGroupPointer++;
+ }
+ }
+ }
+
+ // make sure the scheduled commands are stored with an ascending scheduling time
+ sort(cmdScheduling.begin(), cmdScheduling.end(),
+ commandItem::commandItemSorter());
+
+ // write the scheduled commands into commands.txt.
+ for (unsigned i = 0; i < cmdScheduling.size(); i++) {
+ cmdList.push_back(cmdScheduling[i]);
+ }
+
+ /////////////Update Vector Length/////////////////
+ // the vector length is reduced so that less memory is used for running
+ // this tool.
+ if (ACT.size() >= memSpec.memArchSpec.nbrOfBanks) {
+ for (int m = 0; m < BI * BGI; m++) {
+ ACT.erase(ACT.begin());
+ RDWR[0].erase(RDWR[0].begin(), RDWR[0].end());
+ for (int h = 0; h < bankaccess - 1 - m; h++) {
+ RDWR[h].insert(RDWR[h].begin(), RDWR[h + 1].begin(), RDWR[h + 1].end());
+ RDWR[h + 1].resize(0);
+ }
+ }
+ bankaccess = bankaccess - (BI * BGI);
+ }
+ }
+
+ for (unsigned j = 0; j < cmdList.size(); j++) {
+ commands.precision(0);
+ commands << fixed << cmdList[j].time << "," << cmdList[j].name << "," <<
+ cmdList[j].bank << endl;
+ }
+ cmdList.erase(cmdList.begin(), cmdList.end());
+} // cmdScheduler::analyticalScheduling
+
+// to add the power down/up during the command scheduling for transactions.
+// It is called when the command scheduling for a transaction is finished, and it
+// is also called if there is a refresh.
+void cmdScheduler::pdScheduling(double endTime, double timer,
+ MemorySpecification memSpec)
+{
+ double ZERO = 0;
+ MemTimingSpec& memTimingSpec = memSpec.memTimingSpec;
+
+ endTime = max(endTime, startTime);
+ double pdTime = max(ZERO, timer - endTime);
+
+ if ((timer > (endTime + memTimingSpec.CKE)) && (power_down == POWER_DOWN)) {
+ cmd.bank = 0;
+ cmd.name = "PDN_S_PRE";
+ cmd.time = endTime;
+ cmdScheduling.push_back(cmd);
+ cmd.name = "PUP_PRE";
+
+ if (pdTime > memTimingSpec.REFI)
+ cmd.time = cmd.time + memTimingSpec.REFI;
+ else
+ cmd.time = cmd.time + pdTime;
+
+ if (memSpec.memoryType.isLPDDRFamily())
+ startTime = cmd.time + memTimingSpec.XP;
+ else
+ startTime = cmd.time + memTimingSpec.XPDLL - memTimingSpec.RCD;
+
+ cmdScheduling.push_back(cmd);
+ } else if ((timer > (endTime + memTimingSpec.CKESR)) && (power_down == SELF_REFRESH)) {
+ cmd.bank = 0;
+ cmd.name = "SREN";
+ cmd.time = endTime;
+ cmdScheduling.push_back(cmd);
+ Inselfrefresh = 1;
+ cmd.name = "SREX";
+ cmd.time = cmd.time + pdTime;
+
+ if (memSpec.memoryType.isLPDDRFamily())
+ startTime = cmd.time + memTimingSpec.XS;
+ else
+ startTime = cmd.time + memTimingSpec.XSDLL - memTimingSpec.RCD;
+
+ cmdScheduling.push_back(cmd);
+ }
+} // cmdScheduler::pdScheduling
+
+// get the time when a precharge occurs after a read/write command is scheduled.
+// In addition, it copes with different kind of memories.
+int cmdScheduler::getRWTP(int transType, MemorySpecification memSpec)
+{
+ int tRWTP_init = 0;
+ MemTimingSpec& memTimingSpec = memSpec.memTimingSpec;
+ MemArchitectureSpec& memArchSpec = memSpec.memArchSpec;
+
+ if (transType == READ) {
+ switch (memSpec.memoryType) {
+ case MemoryType::LPDDR:
+ case MemoryType::WIDEIO_SDR:
+ tRWTP_init = memArchSpec.burstLength / memArchSpec.dataRate;
+ break;
+
+ case MemoryType::LPDDR2:
+ case MemoryType::LPDDR3:
+ tRWTP_init = memArchSpec.burstLength / memArchSpec.dataRate +
+ max(0, static_cast<int>(memTimingSpec.RTP - 2));
+ break;
+
+ case MemoryType::DDR2:
+ tRWTP_init = memTimingSpec.AL + memArchSpec.burstLength /
+ memArchSpec.dataRate +
+ max(static_cast<int>(memTimingSpec.RTP), 2) - 2;
+ break;
+
+ case MemoryType::DDR3:
+ case MemoryType::DDR4:
+ tRWTP_init = memTimingSpec.RTP;
+ break;
+ default:
+ assert("Unknown memory type" && false);
+ } // switch
+ } else if (transType == WRITE) {
+ if (memSpec.memoryType == MemoryType::WIDEIO_SDR) {
+ tRWTP_init = memTimingSpec.WL + memArchSpec.burstLength /
+ memArchSpec.dataRate - 1 + memSpec.memTimingSpec.WR;
+ } else {
+ tRWTP_init = memTimingSpec.WL + memArchSpec.burstLength /
+ memArchSpec.dataRate + memSpec.memTimingSpec.WR;
+ }
+ if ((memSpec.memoryType == MemoryType::LPDDR2) ||
+ (memSpec.memoryType == MemoryType::LPDDR3)) {
+ tRWTP_init = tRWTP_init + 1;
+ }
+ }
+
+ return tRWTP_init;
+} // cmdScheduler::getRWTP
+
+// get the timings for command scheduling according to different memories.
+// In particular, tSwitch_init is generally used to provide the timings for
+// scheduling a read/write command after a read/write command which have been
+// scheduled to any possible banks within any possible bank groups (DDR4).
+void cmdScheduler::getTimingConstraints(bool BGSwitch, MemorySpecification memSpec,
+ int PreType, int CurrentType)
+{
+ MemTimingSpec& memTimingSpec = memSpec.memTimingSpec;
+ MemArchitectureSpec& memArchSpec = memSpec.memArchSpec;
+
+ if (memSpec.memoryType != MemoryType::DDR4) {
+ tRRD_init = memTimingSpec.RRD;
+ if (PreType == CurrentType) {
+ tSwitch_init = memTimingSpec.CCD;
+ timingsGet = true;
+ }
+
+ if ((PreType == WRITE) && (CurrentType == READ)) {
+ if (memSpec.memoryType == MemoryType::WIDEIO_SDR) {
+ tSwitch_init = memTimingSpec.WL + memArchSpec.burstLength /
+ memArchSpec.dataRate - 1 + memTimingSpec.WTR;
+ } else {
+ tSwitch_init = memTimingSpec.WL + memArchSpec.burstLength /
+ memArchSpec.dataRate + memTimingSpec.WTR;
+ }
+
+ if ((memSpec.memoryType == MemoryType::LPDDR2) ||
+ (memSpec.memoryType == MemoryType::LPDDR3)) {
+ tSwitch_init = tSwitch_init + 1;
+ }
+ }
+ }
+
+ if (memSpec.memoryType == MemoryType::DDR4) {
+ if (BGSwitch) {
+ tCCD_init = memTimingSpec.CCD_S;
+ tRRD_init = memTimingSpec.RRD_S;
+ tWTR_init = memTimingSpec.WTR_S;
+ } else {
+ tCCD_init = memTimingSpec.CCD_L;
+ tRRD_init = memTimingSpec.RRD_L;
+ tWTR_init = memTimingSpec.WTR_L;
+ }
+
+ if (PreType == CurrentType) {
+ tSwitch_init = tCCD_init;
+ timingsGet = true;
+ } else if ((PreType == WRITE) && (CurrentType == READ)) {
+ tSwitch_init = memTimingSpec.WL + memArchSpec.burstLength /
+ memArchSpec.dataRate + tWTR_init;
+ }
+ }
+
+ if ((PreType == READ) && (CurrentType == WRITE)) {
+ tSwitch_init = memTimingSpec.RL + memArchSpec.burstLength /
+ memArchSpec.dataRate + 2 - memTimingSpec.WL;
+ }
+} // cmdScheduler::getTimingConstraints
+
+// The logical address of each transaction is translated into a physical address
+// which consists of bank group (for DDR4), bank, row and column addresses.
+cmdScheduler::physicalAddr cmdScheduler::memoryMap(trans Trans,
+ MemorySpecification memSpec)
+{
+ int DecLogic;
+ physicalAddr PhysicalAddr;
+
+ DecLogic = Trans.logicalAddress;
+
+ // row-bank-column-BI-BC-BGI-BL
+ if ((BGI > 1) && (memSpec.memoryType == MemoryType::DDR4)) {
+ unsigned colBits = static_cast<unsigned>(log2(nColumns));
+ unsigned bankShift = static_cast<unsigned>(colBits + ((BI > 1) ? log2(BI) : 0)
+ + ((BGI > 1) ? log2(BGI) : 0));
+ unsigned bankMask = static_cast<unsigned>(nBanks / (BI * nbrOfBankGroups) - 1)
+ << bankShift;
+ unsigned bankAddr = (DecLogic & bankMask) >>
+ static_cast<unsigned>(colBits + ((BGI > 1) ? log2(BGI) : 0));
+ PhysicalAddr.bankAddr = bankAddr;
+
+ unsigned bankGroupShift = static_cast<unsigned>(log2(burstLength));
+ unsigned bankGroupMask = (nbrOfBankGroups / BGI - 1) << bankGroupShift;
+ unsigned bankGroupAddr = (DecLogic & bankGroupMask) >> bankGroupShift;
+ PhysicalAddr.bankGroupAddr = bankGroupAddr;
+
+ unsigned colShift = static_cast<unsigned>(log2(BC * burstLength) +
+ ((BI > 1) ? log2(BI) : 0) + ((BGI > 1) ? log2(BGI) : 0));
+ unsigned colMask = static_cast<unsigned>(nColumns / (BC * burstLength) - 1)
+ << colShift;
+ unsigned colAddr = (DecLogic & colMask) >>
+ static_cast<unsigned>((colShift - log2(static_cast<unsigned>(BC) * burstLength)));
+ PhysicalAddr.colAddr = colAddr;
+ } else {
+ unsigned colBits = static_cast<unsigned>(log2(nColumns));
+ unsigned bankShift = static_cast<unsigned>(colBits + ((BI > 1) ? log2(BI) : 0));
+ unsigned bankMask = static_cast<unsigned>(nBanks / BI - 1) << bankShift;
+ unsigned bankAddr = (DecLogic & bankMask) >> colBits;
+ PhysicalAddr.bankAddr = bankAddr;
+
+ unsigned colShift = static_cast<unsigned>(log2(BC * burstLength) +
+ ((BI > 1) ? log2(BI) : 0));
+ unsigned colMask = static_cast<unsigned>(nColumns / (BC * burstLength) - 1)
+ << colShift;
+ unsigned colAddr = (DecLogic & colMask) >>
+ static_cast<unsigned>((colShift - log2(static_cast<unsigned>(BC) * burstLength)));
+ PhysicalAddr.colAddr = colAddr;
+
+ PhysicalAddr.bankGroupAddr = 0;
+ }
+
+ unsigned rowShift = static_cast<unsigned>(log2(nColumns * nBanks));
+ unsigned rowMask = static_cast<unsigned>(memSpec.memArchSpec.nbrOfRows - 1)
+ << rowShift;
+ unsigned rowAddr = (DecLogic & rowMask) >> rowShift;
+ PhysicalAddr.rowAddr = rowAddr;
+
+ return PhysicalAddr;
+} // cmdScheduler::memoryMap
diff --git a/ext/drampower/src/CmdScheduler.h b/ext/drampower/src/CmdScheduler.h
new file mode 100644
index 000000000..3c60ea886
--- /dev/null
+++ b/ext/drampower/src/CmdScheduler.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Karthik Chandrasekar
+ *
+ */
+
+#ifndef CMDSCHEDULER_H
+#define CMDSCHEDULER_H
+
+#include <string>
+#include <vector>
+#include <functional> // for binary_function<>
+#include <fstream>
+
+#include "MemorySpecification.h"
+#include "Utils.h"
+
+namespace Data {
+class cmdScheduler {
+ public:
+ #define READ 0
+ #define WRITE 1
+ #define ACTIVATE 2
+ #define PRECHARGE 3
+ #define POWER_DOWN 1
+ #define SELF_REFRESH 2
+
+ // the format of a transaction.
+ class trans {
+ public:
+ int type;
+ double timeStamp;
+ unsigned logicalAddress;
+ };
+
+ std::vector<trans> transTrace; // to store the transactions.
+
+ // the format of physical address.
+ class physicalAddr {
+ public:
+ unsigned rowAddr;
+ unsigned bankAddr;
+ unsigned bankGroupAddr;
+ unsigned colAddr;
+ };
+
+ // the format of a command.
+ class commandItem {
+ public:
+ int Type;
+ int bank;
+ double time;
+ std::string name;
+ physicalAddr PhysicalAddr;
+ // sorting the commands according to their scheduling time.
+ struct commandItemSorter : public std::binary_function<commandItem&,
+ commandItem&, bool>{
+ bool operator()(const commandItem& lhs,
+ const commandItem& rhs) const
+ {
+ return lhs.time < rhs.time;
+ }
+ };
+ };
+
+ commandItem cmd;
+ commandItem transFinish; // the last scheduled command for a transaction.
+ commandItem PreRDWR; // the latest scheduled READ or WRITE command.
+ // the scheduled ACTIVATE commands are stored in ACT.
+ std::vector<commandItem> ACT;
+ // PRE is sued to keep recording the time when a precharge occurs.
+ std::vector<commandItem> PRE;
+ // the scheduled READ or WRITE commands are stored in RDWR.
+ std::vector<std::vector<commandItem> > RDWR;
+ // all the scheduled commands for a transaction is stored by cmdScheduling.
+ std::vector<commandItem> cmdScheduling;
+ std::vector<commandItem> cmdList;
+ unsigned elements;
+ int BI, BC, BGI;
+
+ // the function used to translate a transaction into a sequence of
+ // commands which are scheduled to the memory.
+ void transTranslation(Data::MemorySpecification memSpec,
+ std::ifstream& trans_trace,
+ int grouping,
+ int interleaving,
+ int burst,
+ int powerdown);
+ // get the transactions by reading the traces.
+ void getTrans(std::ifstream& pwr_trace,
+ MemorySpecification memSpec);
+ // the initialization function for scheduling.
+ void schedulingInitialization(MemorySpecification memSpec);
+ // the function used to schedule commands according to the timing constraints.
+ void analyticalScheduling(MemorySpecification memSpec);
+ // translate the logical address into physical address.
+ physicalAddr memoryMap(trans Trans,
+ MemorySpecification memSpec);
+ // the power down and power up are scheduled by pdScheduling
+ void pdScheduling(double endTime,
+ double timer,
+ MemorySpecification memSpec);
+ // get the timings for scheduling a precharge since a read or write command
+ // is scheduled.
+ int getRWTP(int transType,
+ MemorySpecification memSpec);
+ // get different kind of timing constraints according to the used memory.
+ void getTimingConstraints(bool BGSwitch,
+ MemorySpecification memSpec,
+ int PreType,
+ int CurrentType);
+
+ double transTime;
+ // the flag for power down.
+ int power_down;
+ int Inselfrefresh;
+ int tRRD_init;
+ int tCCD_init;
+ int tWTR_init;
+ double tREF;
+ double tSwitch_init;
+ double tRWTP;
+ int bankaccess;
+ unsigned nBanks;
+ unsigned nColumns;
+ unsigned burstLength;
+ unsigned nbrOfBankGroups;
+ bool timingsGet;
+ double startTime;
+
+ // the scheduling results for all the transactions are written into
+ // commands which will be used by the power analysis part.
+ std::ofstream commands;
+};
+}
+
+#endif // ifndef CMDSCHEDULER_H
diff --git a/ext/drampower/src/CommandAnalysis.cc b/ext/drampower/src/CommandAnalysis.cc
new file mode 100644
index 000000000..4dea5c101
--- /dev/null
+++ b/ext/drampower/src/CommandAnalysis.cc
@@ -0,0 +1,666 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Karthik Chandrasekar, Matthias Jung, Omar Naji, Sven Goossens
+ *
+ */
+
+#include <fstream>
+#include <algorithm>
+#include <sstream>
+
+#include "CommandAnalysis.h"
+#include "CmdScheduler.h"
+
+using namespace Data;
+using namespace std;
+
+CommandAnalysis::CommandAnalysis()
+{
+}
+
+CommandAnalysis::CommandAnalysis(const int nbrofBanks)
+{
+ // Initializing all counters and variables
+
+ numberofacts = 0;
+ numberofpres = 0;
+ numberofreads = 0;
+ numberofwrites = 0;
+ numberofrefs = 0;
+ f_act_pdns = 0;
+ s_act_pdns = 0;
+ f_pre_pdns = 0;
+ s_pre_pdns = 0;
+ numberofsrefs = 0;
+
+ pop = 0;
+ init = 0;
+ zero = 0;
+
+ actcycles = 0;
+ precycles = 0;
+ f_act_pdcycles = 0;
+ s_act_pdcycles = 0;
+ f_pre_pdcycles = 0;
+ s_pre_pdcycles = 0;
+ pup_act_cycles = 0;
+ pup_pre_cycles = 0;
+ sref_cycles = 0;
+ spup_cycles = 0;
+ sref_ref_act_cycles = 0;
+ sref_ref_pre_cycles = 0;
+ spup_ref_act_cycles = 0;
+ spup_ref_pre_cycles = 0;
+ idlecycles_act = 0;
+ idlecycles_pre = 0;
+
+ latest_act_cycle = -1;
+ latest_pre_cycle = -1;
+ latest_read_cycle = -1;
+ latest_write_cycle = -1;
+ end_read_op = 0;
+ end_write_op = 0;
+ end_act_op = 0;
+
+ first_act_cycle = 0;
+ last_pre_cycle = 0;
+
+ bankstate.resize(nbrofBanks, 0);
+ last_states.resize(nbrofBanks);
+ mem_state = 0;
+
+ sref_cycle = 0;
+ pdn_cycle = 0;
+
+ cmd_list.clear();
+ full_cmd_list.resize(1, MemCommand::PRE);
+ cached_cmd.clear();
+ activation_cycle.resize(nbrofBanks, 0);
+}
+
+// function to clear all arrays
+void CommandAnalysis::clear()
+{
+ cached_cmd.clear();
+ cmd_list.clear();
+ full_cmd_list.clear();
+ last_states.clear();
+ bankstate.clear();
+}
+
+// Reads through the trace file, identifies the timestamp, command and bank
+// If the issued command includes an auto-precharge, adds an explicit
+// precharge to a cached command list and computes the precharge offset from the
+// issued command timestamp, when the auto-precharge would kick in
+
+void CommandAnalysis::getCommands(const Data::MemorySpecification& memSpec,
+ const int nbrofBanks, std::vector<MemCommand>& list, bool lastupdate)
+{
+ for (vector<MemCommand>::const_iterator i = list.begin(); i != list.end(); ++i) {
+ const MemCommand& cmd = *i;
+ cmd_list.push_back(cmd);
+
+ MemCommand::cmds cmdType = cmd.getType();
+ if (cmdType == MemCommand::ACT) {
+ activation_cycle[cmd.getBank()] = cmd.getTimeInt64();
+ } else if (cmdType == MemCommand::RDA || cmdType == MemCommand::WRA) {
+ // Remove auto-precharge flag from command
+ cmd_list.back().setType(cmd.typeWithoutAutoPrechargeFlag());
+
+ // Add the auto precharge to the list of cached_cmds
+ int64_t preTime = max(cmd.getTimeInt64() + cmd.getPrechargeOffset(memSpec, cmdType),
+ activation_cycle[cmd.getBank()] + memSpec.memTimingSpec.RAS);
+ cached_cmd.push_back(MemCommand(MemCommand::PRE, cmd.getBank(), static_cast<double>(preTime)));
+ }
+ }
+ pop = 0;
+ // Note: the extra pre-cmds at the end of the lists, and the cast to double
+ // of the size vector is probably not desirable.
+ cmd_list.push_back(MemCommand::PRE);
+ cached_cmd.push_back(MemCommand::PRE);
+ analyse_commands(nbrofBanks, memSpec, cmd_list.size()-1,
+ cached_cmd.size()-1, lastupdate);
+ cmd_list.clear();
+ cached_cmd.clear();
+} // CommandAnalysis::getCommands
+
+// Checks the auto-precharge cached command list and inserts the explicit
+// precharges with the appropriate timestamp in the original command list
+// (by merging) based on their offset from the issuing command. Calls the
+// evaluate function to analyse this expanded list of commands.
+
+void CommandAnalysis::analyse_commands(const int nbrofBanks,
+ Data::MemorySpecification memSpec, int64_t nCommands, int64_t nCached, bool lastupdate)
+{
+ full_cmd_list.resize(1, MemCommand::PRE);
+ unsigned mCommands = 0;
+ unsigned mCached = 0;
+ for (unsigned i = 0; i < nCommands + nCached + 1; i++) {
+ if (cached_cmd.size() > 1) {
+ if ((cmd_list[mCommands].getTime() > 1) && (init == 0)) {
+ full_cmd_list[i].setType(MemCommand::PREA);
+ init = 1;
+ pop = 1;
+ } else {
+ init = 1;
+ if ((cached_cmd[mCached].getTime() > 0) && (cmd_list.
+ at(mCommands).getTime() < cached_cmd[mCached].
+ getTime()) && ((cmd_list[mCommands].getTime() > 0) ||
+ ((cmd_list[mCommands].getTime() == 0) && (cmd_list[mCommands].
+ getType() != MemCommand::PRE)))) {
+ full_cmd_list[i] = cmd_list[mCommands];
+ mCommands++;
+ } else if ((cached_cmd[mCached].getTime() > 0) && (cmd_list[mCommands].
+ getTime() >= cached_cmd[mCached].getTime())) {
+ full_cmd_list[i] = cached_cmd[mCached];
+ mCached++;
+ } else if (cached_cmd[mCached].getTime() == 0) {
+ if ((cmd_list[mCommands].getTime() > 0) || ((cmd_list[mCommands].
+ getTime() == 0) && (cmd_list[mCommands].
+ getType() != MemCommand::PRE))) {
+ full_cmd_list[i] = cmd_list[mCommands];
+ mCommands++;
+ }
+ } else if (cmd_list[mCommands].getTime() == 0) {
+ full_cmd_list[i] = cached_cmd[mCached];
+ mCached++;
+ }
+ }
+ } else {
+ if ((cmd_list[mCommands].getTime() > 1) && (init == 0)) {
+ full_cmd_list[i].setType(MemCommand::PREA);
+ init = 1;
+ pop = 1;
+ } else {
+ init = 1;
+ if ((cmd_list[mCommands].getTime() > 0) || ((cmd_list.
+ at(mCommands).getTime() == 0) && (cmd_list[mCommands].
+ getType() != MemCommand::PRE))) {
+ full_cmd_list[i] = cmd_list[mCommands];
+ mCommands++;
+ }
+ }
+ }
+ full_cmd_list.resize(full_cmd_list.size() + 1, MemCommand::PRE);
+ }
+
+ full_cmd_list.pop_back();
+ if (pop == 0) {
+ full_cmd_list.pop_back();
+ }
+ if (lastupdate) {
+ full_cmd_list.resize(full_cmd_list.size() + 1, MemCommand::NOP);
+ full_cmd_list[full_cmd_list.size() - 1].setTime(full_cmd_list
+ [full_cmd_list.size() - 2].getTime() + timeToCompletion(memSpec,
+ full_cmd_list[full_cmd_list.size() - 2].getType()) - 1);
+ }
+
+ evaluate(memSpec, full_cmd_list, nbrofBanks);
+} // CommandAnalysis::analyse_commands
+
+// To get the time of completion of the issued command
+// Derived based on JEDEC specifications
+
+int CommandAnalysis::timeToCompletion(const MemorySpecification&
+ memSpec, MemCommand::cmds type)
+{
+ int offset = 0;
+ const MemTimingSpec& memTimingSpec = memSpec.memTimingSpec;
+ const MemArchitectureSpec& memArchSpec = memSpec.memArchSpec;
+
+ if (type == MemCommand::RD) {
+ offset = static_cast<int>(memTimingSpec.RL +
+ memTimingSpec.DQSCK + 1 + (memArchSpec.burstLength /
+ memArchSpec.dataRate));
+ } else if (type == MemCommand::WR) {
+ offset = static_cast<int>(memTimingSpec.WL +
+ (memArchSpec.burstLength / memArchSpec.dataRate) +
+ memTimingSpec.WR);
+ } else if (type == MemCommand::ACT) {
+ offset = static_cast<int>(memTimingSpec.RCD);
+ } else if ((type == MemCommand::PRE) || (type == MemCommand::PREA)) {
+ offset = static_cast<int>(memTimingSpec.RP);
+ }
+ return offset;
+} // CommandAnalysis::timeToCompletion
+
+// Used to analyse a given list of commands and identify command timings
+// and memory state transitions
+void CommandAnalysis::evaluate(const MemorySpecification& memSpec,
+ vector<MemCommand>& cmd_list, int nbrofBanks)
+{
+ // for each command identify timestamp, type and bank
+ for (unsigned cmd_list_counter = 0; cmd_list_counter < cmd_list.size();
+ cmd_list_counter++) {
+ // For command type
+ int type = cmd_list[cmd_list_counter].getType();
+ // For command bank
+ int bank = cmd_list[cmd_list_counter].getBank();
+ // Command Issue timestamp in clock cycles (cc)
+ int64_t timestamp = cmd_list[cmd_list_counter].getTimeInt64();
+
+ if (type == MemCommand::ACT) {
+ // If command is ACT - update number of acts, bank state of the
+ // target bank, first and latest activation cycle and the memory
+ // state. Update the number of precharged/idle-precharged cycles.
+ numberofacts++;
+ if (bankstate[bank] == 1) {
+ printWarning("Bank is already active!", type, timestamp, bank);
+ }
+ bankstate[bank] = 1;
+ if (mem_state == 0) {
+ first_act_cycle = timestamp;
+ precycles += max(zero, timestamp - last_pre_cycle);
+ idle_pre_update(memSpec, timestamp, latest_pre_cycle);
+ }
+ latest_act_cycle = timestamp;
+ mem_state++;
+ } else if (type == MemCommand::RD) {
+ // If command is RD - update number of reads and read cycle. Check
+ // for active idle cycles (if any).
+ if (bankstate[bank] == 0) {
+ printWarning("Bank is not active!", type, timestamp, bank);
+ }
+ numberofreads++;
+ idle_act_update(memSpec, latest_read_cycle, latest_write_cycle,
+ latest_act_cycle, timestamp);
+ latest_read_cycle = timestamp;
+ } else if (type == MemCommand::WR) {
+ // If command is WR - update number of writes and write cycle. Check
+ // for active idle cycles (if any).
+ if (bankstate[bank] == 0) {
+ printWarning("Bank is not active!", type, timestamp, bank);
+ }
+ numberofwrites++;
+ idle_act_update(memSpec, latest_read_cycle, latest_write_cycle,
+ latest_act_cycle, timestamp);
+ latest_write_cycle = timestamp;
+ } else if (type == MemCommand::REF) {
+ // If command is REF - update number of refreshes, set bank state of
+ // all banks to ACT, set the last PRE cycles at RFC-RP cycles from
+ // timestamp, set the number of active cycles to RFC-RP and check
+ // for active and precharged cycles and idle active and idle
+ // precharged cycles before refresh. Change memory state to 0.
+ printWarningIfActive("One or more banks are active! REF requires all banks to be precharged.", type, timestamp, bank);
+ numberofrefs++;
+ idle_pre_update(memSpec, timestamp, latest_pre_cycle);
+ first_act_cycle = timestamp;
+ precycles += max(zero, timestamp - last_pre_cycle);
+ last_pre_cycle = timestamp + memSpec.memTimingSpec.RFC -
+ memSpec.memTimingSpec.RP;
+ latest_pre_cycle = last_pre_cycle;
+ actcycles += memSpec.memTimingSpec.RFC - memSpec.memTimingSpec.RP;
+ mem_state = 0;
+ for (int j = 0; j < nbrofBanks; j++) {
+ bankstate[j] = 0;
+ }
+ } else if (type == MemCommand::PRE) {
+ // If command is explicit PRE - update number of precharges, bank
+ // state of the target bank and last and latest precharge cycle.
+ // Calculate the number of active cycles if the memory was in the
+ // active state before, but there is a state transition to PRE now.
+ // If not, update the number of precharged cycles and idle cycles.
+ // Update memory state if needed.
+ if (bankstate[bank] == 1) {
+ numberofpres++;
+ }
+ bankstate[bank] = 0;
+
+ if (mem_state == 1) {
+ actcycles += max(zero, timestamp - first_act_cycle);
+ last_pre_cycle = timestamp;
+ idle_act_update(memSpec, latest_read_cycle, latest_write_cycle,
+ latest_act_cycle, timestamp);
+ } else if (mem_state == 0) {
+ precycles += max(zero, timestamp - last_pre_cycle);
+ idle_pre_update(memSpec, timestamp, latest_pre_cycle);
+ last_pre_cycle = timestamp;
+ }
+ latest_pre_cycle = timestamp;
+ if (mem_state > 0) {
+ mem_state--;
+ } else {
+ mem_state = 0;
+ }
+ } else if (type == MemCommand::PREA) {
+ // If command is explicit PREA (precharge all banks) - update
+ // number of precharges by the number of banks, update the bank
+ // state of all banks to PRE and set the precharge cycle.
+ // Calculate the number of active cycles if the memory was in the
+ // active state before, but there is a state transition to PRE now.
+ // If not, update the number of precharged cycles and idle cycles.
+ if (timestamp == 0) {
+ numberofpres += 0;
+ } else {
+ numberofpres += mem_state;
+ }
+
+ if (mem_state > 0) {
+ actcycles += max(zero, timestamp - first_act_cycle);
+ idle_act_update(memSpec, latest_read_cycle, latest_write_cycle,
+ latest_act_cycle, timestamp);
+ } else if (mem_state == 0) {
+ precycles += max(zero, timestamp - last_pre_cycle);
+ idle_pre_update(memSpec, timestamp, latest_pre_cycle);
+ }
+
+ latest_pre_cycle = timestamp;
+ last_pre_cycle = timestamp;
+
+ mem_state = 0;
+
+ for (int j = 0; j < nbrofBanks; j++) {
+ bankstate[j] = 0;
+ }
+ } else if (type == MemCommand::PDN_F_ACT) {
+ // If command is fast-exit active power-down - update number of
+ // power-downs, set the power-down cycle and the memory mode to
+ // fast-exit active power-down. Save states of all the banks from
+ // the cycle before entering active power-down, to be returned to
+ // after powering-up. Update active and active idle cycles.
+ printWarningIfNotActive("All banks are precharged! Incorrect use of Active Power-Down.", type, timestamp, bank);
+ f_act_pdns++;
+ for (int j = 0; j < nbrofBanks; j++) {
+ last_states[j] = bankstate[j];
+ }
+ pdn_cycle = timestamp;
+ actcycles += max(zero, timestamp - first_act_cycle);
+ idle_act_update(memSpec, latest_read_cycle, latest_write_cycle,
+ latest_act_cycle, timestamp);
+ mem_state = CommandAnalysis::MS_PDN_F_ACT;
+ } else if (type == MemCommand::PDN_S_ACT) {
+ // If command is slow-exit active power-down - update number of
+ // power-downs, set the power-down cycle and the memory mode to
+ // slow-exit active power-down. Save states of all the banks from
+ // the cycle before entering active power-down, to be returned to
+ // after powering-up. Update active and active idle cycles.
+ printWarningIfNotActive("All banks are precharged! Incorrect use of Active Power-Down.", type, timestamp, bank);
+ s_act_pdns++;
+ for (int j = 0; j < nbrofBanks; j++) {
+ last_states[j] = bankstate[j];
+ }
+ pdn_cycle = timestamp;
+ actcycles += max(zero, timestamp - first_act_cycle);
+ idle_act_update(memSpec, latest_read_cycle, latest_write_cycle,
+ latest_act_cycle, timestamp);
+ mem_state = CommandAnalysis::MS_PDN_S_ACT;
+ } else if (type == MemCommand::PDN_F_PRE) {
+ // If command is fast-exit precharged power-down - update number of
+ // power-downs, set the power-down cycle and the memory mode to
+ // fast-exit precahrged power-down. Update precharged and precharged
+ // idle cycles.
+ printWarningIfActive("One or more banks are active! Incorrect use of Precharged Power-Down.", type, timestamp, bank);
+ f_pre_pdns++;
+ pdn_cycle = timestamp;
+ precycles += max(zero, timestamp - last_pre_cycle);
+ idle_pre_update(memSpec, timestamp, latest_pre_cycle);
+ mem_state = CommandAnalysis::MS_PDN_F_PRE;
+ } else if (type == MemCommand::PDN_S_PRE) {
+ // If command is slow-exit precharged power-down - update number of
+ // power-downs, set the power-down cycle and the memory mode to
+ // slow-exit precahrged power-down. Update precharged and precharged
+ // idle cycles.
+ printWarningIfActive("One or more banks are active! Incorrect use of Precharged Power-Down.", type, timestamp, bank);
+ s_pre_pdns++;
+ pdn_cycle = timestamp;
+ precycles += max(zero, timestamp - last_pre_cycle);
+ idle_pre_update(memSpec, timestamp, latest_pre_cycle);
+ mem_state = CommandAnalysis::MS_PDN_S_PRE;
+ } else if (type == MemCommand::PUP_ACT) {
+ // If command is power-up in the active mode - check the power-down
+ // exit-mode employed (fast or slow), update the number of power-down
+ // and power-up cycles and the latest and first act cycle. Also, reset
+ // all the individual bank states to the respective saved states
+ // before entering power-down.
+ if (mem_state == CommandAnalysis::MS_PDN_F_ACT) {
+ f_act_pdcycles += max(zero, timestamp - pdn_cycle);
+ pup_act_cycles += memSpec.memTimingSpec.XP;
+ latest_act_cycle = max(timestamp, timestamp +
+ memSpec.memTimingSpec.XP - memSpec.memTimingSpec.RCD);
+ } else if (mem_state == CommandAnalysis::MS_PDN_S_ACT) {
+ s_act_pdcycles += max(zero, timestamp - pdn_cycle);
+ if (memSpec.memArchSpec.dll == false) {
+ pup_act_cycles += memSpec.memTimingSpec.XP;
+ latest_act_cycle = max(timestamp, timestamp +
+ memSpec.memTimingSpec.XP - memSpec.memTimingSpec.RCD);
+ } else {
+ pup_act_cycles += memSpec.memTimingSpec.XPDLL -
+ memSpec.memTimingSpec.RCD;
+ latest_act_cycle = max(timestamp, timestamp +
+ memSpec.memTimingSpec.XPDLL -
+ (2 * memSpec.memTimingSpec.RCD));
+ }
+ } else if ((mem_state != CommandAnalysis::MS_PDN_S_ACT) || (mem_state !=
+ CommandAnalysis::MS_PDN_F_ACT)) {
+ cerr << "Incorrect use of Active Power-Up!" << endl;
+ }
+ mem_state = 0;
+ for (int j = 0; j < nbrofBanks; j++) {
+ bankstate[j] = last_states[j];
+ mem_state += last_states[j];
+ }
+ first_act_cycle = timestamp;
+ } else if (type == MemCommand::PUP_PRE) {
+ // If command is power-up in the precharged mode - check the power-down
+ // exit-mode employed (fast or slow), update the number of power-down
+ // and power-up cycles and the latest and last pre cycle.
+ if (mem_state == CommandAnalysis::MS_PDN_F_PRE) {
+ f_pre_pdcycles += max(zero, timestamp - pdn_cycle);
+ pup_pre_cycles += memSpec.memTimingSpec.XP;
+ latest_pre_cycle = max(timestamp, timestamp +
+ memSpec.memTimingSpec.XP - memSpec.memTimingSpec.RP);
+ } else if (mem_state == CommandAnalysis::MS_PDN_S_PRE) {
+ s_pre_pdcycles += max(zero, timestamp - pdn_cycle);
+ if (memSpec.memArchSpec.dll == false) {
+ pup_pre_cycles += memSpec.memTimingSpec.XP;
+ latest_pre_cycle = max(timestamp, timestamp +
+ memSpec.memTimingSpec.XP - memSpec.memTimingSpec.RP);
+ } else {
+ pup_pre_cycles += memSpec.memTimingSpec.XPDLL -
+ memSpec.memTimingSpec.RCD;
+ latest_pre_cycle = max(timestamp, timestamp +
+ memSpec.memTimingSpec.XPDLL - memSpec.memTimingSpec.RCD -
+ memSpec.memTimingSpec.RP);
+ }
+ } else if ((mem_state != CommandAnalysis::MS_PDN_S_PRE) || (mem_state !=
+ CommandAnalysis::MS_PDN_F_PRE)) {
+ cerr << "Incorrect use of Precharged Power-Up!" << endl;
+ }
+ mem_state = 0;
+ last_pre_cycle = timestamp;
+ } else if (type == MemCommand::SREN) {
+ // If command is self-refresh - update number of self-refreshes,
+ // set memory state to SREF, update precharge and idle precharge
+ // cycles and set the self-refresh cycle.
+ printWarningIfActive("One or more banks are active! SREF requires all banks to be precharged.", type, timestamp, bank);
+ numberofsrefs++;
+ sref_cycle = timestamp;
+ precycles += max(zero, timestamp - last_pre_cycle);
+ idle_pre_update(memSpec, timestamp, latest_pre_cycle);
+ mem_state = CommandAnalysis::MS_SREF;
+ } else if (type == MemCommand::SREX) {
+ // If command is self-refresh exit - update the number of self-refresh
+ // clock cycles, number of active and precharged auto-refresh clock
+ // cycles during self-refresh and self-refresh exit based on the number
+ // of cycles in the self-refresh mode and auto-refresh duration (RFC).
+ // Set the last and latest precharge cycle accordingly and set the
+ // memory state to 0.
+ if (mem_state != CommandAnalysis::MS_SREF) {
+ cerr << "Incorrect use of Self-Refresh Power-Up!" << endl;
+ }
+ if (max(zero, timestamp - sref_cycle) >= memSpec.memTimingSpec.RFC) {
+ sref_cycles += max(zero, timestamp - sref_cycle
+ - memSpec.memTimingSpec.RFC);
+ sref_ref_act_cycles += memSpec.memTimingSpec.RFC -
+ memSpec.memTimingSpec.RP;
+ sref_ref_pre_cycles += memSpec.memTimingSpec.RP;
+ last_pre_cycle = timestamp;
+ if (memSpec.memArchSpec.dll == false) {
+ spup_cycles += memSpec.memTimingSpec.XS;
+ latest_pre_cycle = max(timestamp, timestamp +
+ memSpec.memTimingSpec.XS - memSpec.memTimingSpec.RP);
+ } else {
+ spup_cycles += memSpec.memTimingSpec.XSDLL -
+ memSpec.memTimingSpec.RCD;
+ latest_pre_cycle = max(timestamp, timestamp +
+ memSpec.memTimingSpec.XSDLL - memSpec.memTimingSpec.RCD
+ - memSpec.memTimingSpec.RP);
+ }
+ } else {
+ int64_t sref_diff = memSpec.memTimingSpec.RFC - memSpec.memTimingSpec.RP;
+ int64_t sref_pre = max(zero, timestamp - sref_cycle - sref_diff);
+ int64_t spup_pre = memSpec.memTimingSpec.RP - sref_pre;
+ int64_t sref_act = max(zero, timestamp - sref_cycle);
+ int64_t spup_act = memSpec.memTimingSpec.RFC - sref_act;
+
+ if (max(zero, timestamp - sref_cycle) >= sref_diff) {
+ sref_ref_act_cycles += sref_diff;
+ sref_ref_pre_cycles += sref_pre;
+ spup_ref_pre_cycles += spup_pre;
+ last_pre_cycle = timestamp + spup_pre;
+ if (memSpec.memArchSpec.dll == false) {
+ spup_cycles += memSpec.memTimingSpec.XS - spup_pre;
+ latest_pre_cycle = max(timestamp, timestamp +
+ memSpec.memTimingSpec.XS - spup_pre -
+ memSpec.memTimingSpec.RP);
+ } else {
+ spup_cycles += memSpec.memTimingSpec.XSDLL -
+ memSpec.memTimingSpec.RCD - spup_pre;
+ latest_pre_cycle = max(timestamp, timestamp +
+ memSpec.memTimingSpec.XSDLL - memSpec.memTimingSpec.RCD -
+ spup_pre - memSpec.memTimingSpec.RP);
+ }
+ } else {
+ sref_ref_act_cycles += sref_act;
+ spup_ref_act_cycles += spup_act;
+ spup_ref_pre_cycles += memSpec.memTimingSpec.RP;
+ last_pre_cycle = timestamp + spup_act + memSpec.memTimingSpec.RP;
+ if (memSpec.memArchSpec.dll == false) {
+ spup_cycles += memSpec.memTimingSpec.XS - spup_act -
+ memSpec.memTimingSpec.RP;
+ latest_pre_cycle = max(timestamp, timestamp +
+ memSpec.memTimingSpec.XS - spup_act -
+ (2 * memSpec.memTimingSpec.RP));
+ } else {
+ spup_cycles += memSpec.memTimingSpec.XSDLL -
+ memSpec.memTimingSpec.RCD - spup_act -
+ memSpec.memTimingSpec.RP;
+ latest_pre_cycle = max(timestamp, timestamp +
+ memSpec.memTimingSpec.XSDLL - memSpec.memTimingSpec.RCD -
+ spup_act - (2 * memSpec.memTimingSpec.RP));
+ }
+ }
+ }
+ mem_state = 0;
+ } else if ((type == MemCommand::END) || (type == MemCommand::NOP)) {
+ // May be optionally used at the end of memory trace for better accuracy
+ // Update all counters based on completion of operations.
+ if ((mem_state > 0) && (mem_state < 9)) {
+ actcycles += max(zero, timestamp - first_act_cycle);
+ idle_act_update(memSpec, latest_read_cycle, latest_write_cycle,
+ latest_act_cycle, timestamp);
+ } else if (mem_state == 0) {
+ precycles += max(zero, timestamp - last_pre_cycle);
+ idle_pre_update(memSpec, timestamp, latest_pre_cycle);
+ } else if (mem_state == CommandAnalysis::MS_PDN_F_ACT) {
+ f_act_pdcycles += max(zero, timestamp - pdn_cycle);
+ } else if (mem_state == CommandAnalysis::MS_PDN_S_ACT) {
+ s_act_pdcycles += max(zero, timestamp - pdn_cycle);
+ } else if (mem_state == CommandAnalysis::MS_PDN_F_PRE) {
+ f_pre_pdcycles += max(zero, timestamp - pdn_cycle);
+ } else if (mem_state == CommandAnalysis::MS_PDN_S_PRE) {
+ s_pre_pdcycles += max(zero, timestamp - pdn_cycle);
+ } else if (mem_state == CommandAnalysis::MS_SREF) {
+ sref_cycles += max(zero, timestamp - sref_cycle);
+ }
+ }
+ }
+} // CommandAnalysis::evaluate
+
+// To update idle period information whenever active cycles may be idle
+void CommandAnalysis::idle_act_update(const MemorySpecification& memSpec,
+ int64_t latest_read_cycle, int64_t latest_write_cycle,
+ int64_t latest_act_cycle, int64_t timestamp)
+{
+ if (latest_read_cycle >= 0) {
+ end_read_op = latest_read_cycle + timeToCompletion(memSpec,
+ MemCommand::RD) - 1;
+ }
+
+ if (latest_write_cycle >= 0) {
+ end_write_op = latest_write_cycle + timeToCompletion(memSpec,
+ MemCommand::WR) - 1;
+ }
+
+ if (latest_act_cycle >= 0) {
+ end_act_op = latest_act_cycle + timeToCompletion(memSpec,
+ MemCommand::ACT) - 1;
+ }
+
+ idlecycles_act += max(zero, timestamp - max(max(end_read_op, end_write_op),
+ end_act_op));
+} // CommandAnalysis::idle_act_update
+
+// To update idle period information whenever precharged cycles may be idle
+void CommandAnalysis::idle_pre_update(const MemorySpecification& memSpec,
+ int64_t timestamp, int64_t latest_pre_cycle)
+{
+ if (latest_pre_cycle > 0) {
+ idlecycles_pre += max(zero, timestamp - latest_pre_cycle -
+ memSpec.memTimingSpec.RP);
+ } else if (latest_pre_cycle == 0) {
+ idlecycles_pre += max(zero, timestamp - latest_pre_cycle);
+ }
+}
+
+void CommandAnalysis::printWarningIfActive(const string& warning, int type, int64_t timestamp, int bank)
+{
+ if (mem_state != 0) {
+ printWarning(warning, type, timestamp, bank);
+ }
+}
+
+void CommandAnalysis::printWarningIfNotActive(const string& warning, int type, int64_t timestamp, int bank)
+{
+ if (mem_state == 0) {
+ printWarning(warning, type, timestamp, bank);
+ }
+}
+
+void CommandAnalysis::printWarning(const string& warning, int type, int64_t timestamp, int bank)
+{
+ cerr << "WARNING: " << warning << endl;
+ cerr << "Command: " << type << ", Timestamp: " << timestamp <<
+ ", Bank: " << bank << endl;
+}
diff --git a/ext/drampower/src/CommandAnalysis.h b/ext/drampower/src/CommandAnalysis.h
new file mode 100644
index 000000000..b5c7ac778
--- /dev/null
+++ b/ext/drampower/src/CommandAnalysis.h
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Karthik Chandrasekar, Matthias Jung, Omar Naji
+ *
+ */
+
+#ifndef COMMAND_TIMINGS_H
+#define COMMAND_TIMINGS_H
+
+#include <stdint.h>
+
+#include <vector>
+#include <iostream>
+#include <deque>
+#include <string>
+
+#include "MemCommand.h"
+#include "MemorySpecification.h"
+#include "Utils.h"
+
+namespace Data {
+class CommandAnalysis {
+ public:
+ // Power-Down and Self-refresh related memory states
+ enum memstate {
+ MS_PDN_F_ACT = 10, MS_PDN_S_ACT = 11, MS_PDN_F_PRE = 12,
+ MS_PDN_S_PRE = 13, MS_SREF = 14
+ };
+
+ CommandAnalysis();
+
+ // Returns number of reads, writes, acts, pres and refs in the trace
+ CommandAnalysis(const int nbrofBanks);
+
+ // Number of activate commands
+ int64_t numberofacts;
+ // Number of precharge commands
+ int64_t numberofpres;
+ // Number of reads commands
+ int64_t numberofreads;
+ // Number of writes commands
+ int64_t numberofwrites;
+ // Number of refresh commands
+ int64_t numberofrefs;
+ // Number of precharge cycles
+ int64_t precycles;
+ // Number of active cycles
+ int64_t actcycles;
+ // Number of Idle cycles in the active state
+ int64_t idlecycles_act;
+ // Number of Idle cycles in the precharge state
+ int64_t idlecycles_pre;
+ // Number of fast-exit activate power-downs
+ int64_t f_act_pdns;
+ // Number of slow-exit activate power-downs
+ int64_t s_act_pdns;
+ // Number of fast-exit precharged power-downs
+ int64_t f_pre_pdns;
+ // Number of slow-exit activate power-downs
+ int64_t s_pre_pdns;
+ // Number of self-refresh commands
+ int64_t numberofsrefs;
+ // Number of clock cycles in fast-exit activate power-down mode
+ int64_t f_act_pdcycles;
+ // Number of clock cycles in slow-exit activate power-down mode
+ int64_t s_act_pdcycles;
+ // Number of clock cycles in fast-exit precharged power-down mode
+ int64_t f_pre_pdcycles;
+ // Number of clock cycles in slow-exit precharged power-down mode
+ int64_t s_pre_pdcycles;
+ // Number of clock cycles in self-refresh mode
+ int64_t sref_cycles;
+ // Number of clock cycles in activate power-up mode
+ int64_t pup_act_cycles;
+ // Number of clock cycles in precharged power-up mode
+ int64_t pup_pre_cycles;
+ // Number of clock cycles in self-refresh power-up mode
+ int64_t spup_cycles;
+
+ // Number of active auto-refresh cycles in self-refresh mode
+ int64_t sref_ref_act_cycles;
+ // Number of precharged auto-refresh cycles in self-refresh mode
+ int64_t sref_ref_pre_cycles;
+ // Number of active auto-refresh cycles during self-refresh exit
+ int64_t spup_ref_act_cycles;
+ // Number of precharged auto-refresh cycles during self-refresh exit
+ int64_t spup_ref_pre_cycles;
+
+ // function for clearing arrays
+ void clear();
+
+ // To identify auto-precharges
+ void getCommands(const MemorySpecification& memSpec,
+ const int
+ nbrofBanks,
+ std::vector<MemCommand>& list,
+ bool lastupdate);
+
+ private:
+ unsigned init;
+ int64_t zero;
+ unsigned pop;
+ // Cached last read command from the file
+ std::vector<MemCommand> cached_cmd;
+
+ // Stores the memory commands for analysis
+ std::vector<MemCommand> cmd_list;
+
+ // Stores all memory commands for analysis
+ std::vector<MemCommand> full_cmd_list;
+
+ // To save states of the different banks, before entering active
+ // power-down mode (slow/fast-exit).
+ std::vector<int> last_states;
+ // Bank state vector
+ std::vector<int> bankstate;
+
+ std::vector<int64_t> activation_cycle;
+ // To keep track of the last ACT cycle
+ int64_t latest_act_cycle;
+ // To keep track of the last PRE cycle
+ int64_t latest_pre_cycle;
+ // To keep track of the last READ cycle
+ int64_t latest_read_cycle;
+ // To keep track of the last WRITE cycle
+ int64_t latest_write_cycle;
+
+ // To calculate end of READ operation
+ int64_t end_read_op;
+ // To calculate end of WRITE operation
+ int64_t end_write_op;
+ // To calculate end of ACT operation
+ int64_t end_act_op;
+
+ // Clock cycle when self-refresh was issued
+ int64_t sref_cycle;
+
+ // Clock cycle when the latest power-down was issued
+ int64_t pdn_cycle;
+
+ // Memory State
+ unsigned mem_state;
+
+ // Clock cycle of first activate command when memory state changes to ACT
+ int64_t first_act_cycle;
+
+ // Clock cycle of last precharge command when memory state changes to PRE
+ int64_t last_pre_cycle;
+ // To collect and analyse all commands including auto-precharges
+ void analyse_commands(const int nbrofBanks,
+ Data::MemorySpecification
+ memSpec,
+ int64_t nCommands,
+ int64_t nCached,
+ bool lastupdate);
+ // To perform timing analysis of a given set of commands and update command counters
+ void evaluate(const MemorySpecification& memSpec,
+ std::vector<MemCommand>& cmd_list,
+ int nbrofBanks);
+
+ // To calculate time of completion of any issued command
+ int timeToCompletion(const MemorySpecification& memSpec,
+ MemCommand::cmds type);
+
+ // To update idle period information whenever active cycles may be idle
+ void idle_act_update(const MemorySpecification& memSpec,
+ int64_t latest_read_cycle,
+ int64_t latest_write_cycle,
+ int64_t latest_act_cycle,
+ int64_t timestamp);
+
+ // To update idle period information whenever precharged cycles may be idle
+ void idle_pre_update(const MemorySpecification& memSpec,
+ int64_t timestamp,
+ int64_t latest_pre_cycle);
+
+ void printWarningIfActive(const std::string& warning, int type, int64_t timestamp, int bank);
+ void printWarningIfNotActive(const std::string& warning, int type, int64_t timestamp, int bank);
+ void printWarning(const std::string& warning, int type, int64_t timestamp, int bank);
+};
+}
+#endif // ifndef COMMAND_TIMINGS_H
diff --git a/ext/drampower/src/MemArchitectureSpec.cc b/ext/drampower/src/MemArchitectureSpec.cc
new file mode 100644
index 000000000..f3155853d
--- /dev/null
+++ b/ext/drampower/src/MemArchitectureSpec.cc
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Karthik Chandrasekar
+ *
+ */
+
+#include "MemArchitectureSpec.h"
+
+#include <cassert>
+
+using namespace Data;
+
+MemArchitectureSpec::MemArchitectureSpec() :
+ burstLength(0),
+ nbrOfBanks(0),
+ nbrOfRanks(0),
+ dataRate(0),
+ nbrOfColumns(0),
+ nbrOfRows(0),
+ width(0),
+ nbrOfBankGroups(0),
+ dll(false),
+ twoVoltageDomains(false),
+ termination(false)
+{
+}
+
+void MemArchitectureSpec::processParameters()
+{
+ // Load all parameters in our member variables
+ nbrOfBanks = getParamValWithDefault("nbrOfBanks", 1);
+ nbrOfRanks = getParamValWithDefault("nbrOfRanks", 1);
+ nbrOfBankGroups = getParamValWithDefault("nbrOfBankGroups", 1);
+ dataRate = getParamValWithDefault("dataRate", 1);
+ burstLength = getParamValWithDefault("burstLength", 1);
+ nbrOfColumns = getParamValWithDefault("nbrOfColumns", 1);
+ nbrOfRows = getParamValWithDefault("nbrOfRows", 1);
+ width = getParamValWithDefault("width", 1);
+ assert("memory width should be a multiple of 8" && (width % 8) == 0);
+ dll = getParamValWithDefault("dll", false);
+ twoVoltageDomains = getParamValWithDefault("twoVoltageDomains", false);
+ termination = getParamValWithDefault("termination", false);
+}
diff --git a/ext/drampower/src/MemArchitectureSpec.h b/ext/drampower/src/MemArchitectureSpec.h
new file mode 100644
index 000000000..ca79edc91
--- /dev/null
+++ b/ext/drampower/src/MemArchitectureSpec.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Karthik Chandrasekar
+ *
+ */
+
+#ifndef TOOLS_MEM_ARCHITECTURE_SPEC_H
+#define TOOLS_MEM_ARCHITECTURE_SPEC_H
+
+#include "Parametrisable.h"
+
+namespace Data {
+class MemArchitectureSpec : public virtual Parametrisable {
+ public:
+ MemArchitectureSpec();
+ void processParameters();
+
+ unsigned int burstLength;
+ unsigned nbrOfBanks;
+ unsigned nbrOfRanks;
+ unsigned dataRate;
+ unsigned nbrOfColumns;
+ unsigned nbrOfRows;
+ unsigned width;
+ unsigned nbrOfBankGroups;
+ bool dll;
+ bool twoVoltageDomains;
+ bool termination;
+};
+}
+#endif // ifndef TOOLS_MEM_ARCHITECTURE_SPEC_H
diff --git a/ext/drampower/src/MemCommand.cc b/ext/drampower/src/MemCommand.cc
new file mode 100644
index 000000000..156716c2f
--- /dev/null
+++ b/ext/drampower/src/MemCommand.cc
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Karthik Chandrasekar
+ *
+ */
+
+#include "MemCommand.h"
+
+#include <algorithm> // for max
+
+#include "MemorySpecification.h"
+
+using namespace Data;
+using namespace std;
+
+MemCommand::MemCommand() :
+ type(MemCommand::PRE),
+ bank(0),
+ timestamp(0)
+{
+}
+
+MemCommand::MemCommand(MemCommand::cmds type,
+ unsigned bank, double timestamp) :
+ type(type),
+ bank(bank),
+ timestamp(timestamp)
+{
+}
+
+void MemCommand::setType(MemCommand::cmds _type)
+{
+ type = _type;
+}
+
+MemCommand::cmds MemCommand::getType() const
+{
+ return type;
+}
+
+void MemCommand::setBank(unsigned _bank)
+{
+ bank = _bank;
+}
+
+unsigned MemCommand::getBank() const
+{
+ return bank;
+}
+
+// For auto-precharge with read or write - to calculate cycle of precharge
+int MemCommand::getPrechargeOffset(const MemorySpecification& memSpec,
+ MemCommand::cmds type) const
+{
+ int precharge_offset = 0;
+
+ int BL(static_cast<int>(memSpec.memArchSpec.burstLength));
+ int RTP(static_cast<int>(memSpec.memTimingSpec.RTP));
+ int dataRate(static_cast<int>(memSpec.memArchSpec.dataRate));
+ int AL(static_cast<int>(memSpec.memTimingSpec.AL));
+ int WL(static_cast<int>(memSpec.memTimingSpec.WL));
+ int WR(static_cast<int>(memSpec.memTimingSpec.WR));
+ int B = BL/dataRate;
+
+ const MemoryType::MemoryType_t& memType = memSpec.memoryType;
+
+ // Read with auto-precharge
+ if (type == MemCommand::RDA) {
+ if (memType == MemoryType::DDR2) {
+ precharge_offset = B + AL - 2 + max(RTP, 2);
+ } else if (memType == MemoryType::DDR3) {
+ precharge_offset = AL + max(RTP, 4);
+ } else if (memType == MemoryType::DDR4) {
+ precharge_offset = AL + RTP;
+ } else if (memType == MemoryType::LPDDR) {
+ precharge_offset = B;
+ } else if (memType == MemoryType::LPDDR2) {
+ precharge_offset = B + max(0, RTP - 2);
+ } else if (memType == MemoryType::LPDDR3) {
+ precharge_offset = B + max(0, RTP - 4);
+ } else if (memType == MemoryType::WIDEIO_SDR) {
+ precharge_offset = B;
+ }
+ } else if (type == MemCommand::WRA) { // Write with auto-precharge
+ if (memType == MemoryType::DDR2) {
+ precharge_offset = B + WL + WR;
+ } else if (memType == MemoryType::DDR3) {
+ precharge_offset = B + WL + WR;
+ } else if (memType == MemoryType::DDR4) {
+ precharge_offset = B + WL + WR;
+ } else if (memType == MemoryType::LPDDR) {
+ precharge_offset = B + WR; // + DQSS actually, but we don't have that parameter.
+ } else if (memType == MemoryType::LPDDR2) {
+ precharge_offset = B + WL + WR + 1;
+ } else if (memType == MemoryType::LPDDR3) {
+ precharge_offset = B + WL + WR + 1;
+ } else if (memType == MemoryType::WIDEIO_SDR) {
+ precharge_offset = B + WL + WR - 1;
+ }
+ }
+
+ return precharge_offset;
+} // MemCommand::getPrechargeOffset
+
+void MemCommand::setTime(double _timestamp)
+{
+ timestamp = _timestamp;
+}
+
+double MemCommand::getTime() const
+{
+ return timestamp;
+}
+
+int64_t MemCommand::getTimeInt64() const
+{
+ return static_cast<int64_t>(timestamp);
+}
+
+MemCommand::cmds MemCommand::typeWithoutAutoPrechargeFlag() const
+{
+ if (type == MemCommand::RDA) {
+ return MemCommand::RD;
+ } else if (type == MemCommand::WRA) {
+ return MemCommand::WR;
+ }
+ return type;
+}
diff --git a/ext/drampower/src/MemCommand.h b/ext/drampower/src/MemCommand.h
new file mode 100644
index 000000000..4159fe008
--- /dev/null
+++ b/ext/drampower/src/MemCommand.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Karthik Chandrasekar
+ *
+ */
+
+#ifndef MEMCOMMAND_H
+#define MEMCOMMAND_H
+
+#include <stdint.h>
+#include <cassert>
+#include <string>
+
+#include "MemorySpecification.h"
+
+namespace Data {
+class MemCommand {
+ public:
+ /*
+ * 1. ACT - Activate
+ * 2. RD - Read
+ * 3. WR - Write
+ * 4. PRE - Explicit Precharge per bank
+ * 5. REF - Refresh all banks
+ * 6. END - To indicate end of trace
+ * 7. RDA - Read with auto-precharge
+ * 8. WRA - Write with auto-precharge
+ * 9. PREA - Precharge all banks
+ * 10. PDN_F_PRE - Precharge Power-down Entry command (Fast-Exit)
+ * 11. PDN_S_PRE - Precharge Power-down Entry command (Slow-Exit)
+ * 12. PDN_F_ACT - Active Power-down Entry command (Fast-Exit)
+ * 13. PDN_S_ACT - Active Power-down Entry command (Slow-Exit)
+ * 14. PUP_PRE - Precharge Power-down Exit
+ * 15. PUP_ACT - Active Power-down Exit
+ * 16. SREN - Self-Refresh Entry command
+ * 17. SREX - Self-refresh Exit
+ * 18. NOP - To indicate end of trace
+ */
+
+ enum cmds {
+ ACT = 0,
+ RD = 1,
+ WR = 2,
+ PRE = 3,
+ REF = 4,
+ END = 5,
+ RDA = 6,
+ WRA = 7,
+ PREA = 8,
+ PDN_F_PRE = 9,
+ PDN_S_PRE = 10,
+ PDN_F_ACT = 11,
+ PDN_S_ACT = 12,
+ PUP_PRE = 13,
+ PUP_ACT = 14,
+ SREN = 15,
+ SREX = 16,
+ NOP = 17
+ };
+
+ MemCommand();
+ MemCommand(
+ // Command Type
+ MemCommand::cmds type,
+ // Target Bank
+ unsigned bank = 0,
+ // Command Issue Timestamp (in cc)
+ double timestamp = 0);
+
+ // Get command type
+ cmds getType() const;
+
+ // Set command type
+ void setType(MemCommand::cmds type);
+
+ // Set target Bank
+ void setBank(unsigned bank);
+
+ // Get target Bank
+ unsigned getBank() const;
+
+ // Set timestamp
+ void setTime(double _timestamp);
+
+ // Get timestamp
+ double getTime() const;
+ int64_t getTimeInt64() const;
+
+ cmds typeWithoutAutoPrechargeFlag() const;
+
+ // To calculate precharge offset after read or write with auto-precharge
+ int getPrechargeOffset(const MemorySpecification& memSpec,
+ MemCommand::cmds type) const;
+
+ // To check for equivalence
+
+ bool operator==(const MemCommand& other) const
+ {
+ if ((getType() == other.getType()) &&
+ (getBank() == other.getBank())
+ ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ static const unsigned int nCommands = 18;
+
+ static std::string* getCommandTypeStrings()
+ {
+ static std::string type_map[nCommands] = { "ACT", "RD", "WR", "PRE", "REF",
+ "END", "RDA", "WRA", "PREA", "PDN_F_PRE","PDN_S_PRE", "PDN_F_ACT",
+ "PDN_S_ACT", "PUP_PRE", "PUP_ACT", "SREN", "SREX", "NOP" };
+
+ return type_map;
+ }
+
+ // To identify command type from name
+ static cmds getTypeFromName(const std::string name)
+ {
+ std::string* typeStrings = getCommandTypeStrings();
+
+ for (size_t typeId = 0; typeId < nCommands; typeId++) {
+ if (typeStrings[typeId] == name) {
+ cmds commandType = static_cast<cmds>(typeId);
+ return commandType;
+ }
+ }
+ assert(false); // Unknown name.
+ }
+
+ private:
+ MemCommand::cmds type;
+ unsigned bank;
+ double timestamp;
+};
+}
+#endif // ifndef MEMCOMMAND_H
diff --git a/ext/drampower/src/MemPowerSpec.cc b/ext/drampower/src/MemPowerSpec.cc
new file mode 100644
index 000000000..3fbc53992
--- /dev/null
+++ b/ext/drampower/src/MemPowerSpec.cc
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Karthik Chandrasekar
+ *
+ */
+
+#include "MemPowerSpec.h"
+
+using namespace Data;
+
+MemPowerSpec::MemPowerSpec() :
+ idd0(0.0),
+ idd02(0.0),
+ idd2p0(0.0),
+ idd2p02(0.0),
+ idd2p1(0.0),
+ idd2p12(0.0),
+ idd2n(0.0),
+ idd2n2(0.0),
+ idd3p0(0.0),
+ idd3p02(0.0),
+ idd3p1(0.0),
+ idd3p12(0.0),
+ idd3n(0.0),
+ idd3n2(0.0),
+ idd4r(0.0),
+ idd4r2(0.0),
+ idd4w(0.0),
+ idd4w2(0.0),
+ idd5(0.0),
+ idd52(0.0),
+ idd6(0.0),
+ idd62(0.0),
+ vdd(0.0),
+ vdd2(0.0),
+ capacitance(0.0),
+ ioPower(0.0),
+ wrOdtPower(0.0),
+ termRdPower(0.0),
+ termWrPower(0.0)
+{
+}
+
+void MemPowerSpec::processParameters()
+{
+ idd0 = getParamValWithDefault("idd0", 0.0);
+ idd02 = getParamValWithDefault("idd02", 0.0);
+ idd2p0 = getParamValWithDefault("idd2p0", 0.0);
+ idd2p02 = getParamValWithDefault("idd2p02", 0.0);
+ idd2p1 = getParamValWithDefault("idd2p1", 0.0);
+ idd2p12 = getParamValWithDefault("idd2p12", 0.0);
+ idd2n = getParamValWithDefault("idd2n", 0.0);
+ idd2n2 = getParamValWithDefault("idd2n2", 0.0);
+ idd3p0 = getParamValWithDefault("idd3p0", 0.0);
+ idd3p02 = getParamValWithDefault("idd3p02", 0.0);
+ idd3p1 = getParamValWithDefault("idd3p1", 0.0);
+ idd3p12 = getParamValWithDefault("idd3p12", 0.0);
+ idd3n = getParamValWithDefault("idd3n", 0.0);
+ idd3n2 = getParamValWithDefault("idd3n2", 0.0);
+ idd4r = getParamValWithDefault("idd4r", 0.0);
+ idd4r2 = getParamValWithDefault("idd4r2", 0.0);
+ idd4w = getParamValWithDefault("idd4w", 0.0);
+ idd4w2 = getParamValWithDefault("idd4w2", 0.0);
+ idd5 = getParamValWithDefault("idd5", 0.0);
+ idd52 = getParamValWithDefault("idd52", 0.0);
+ idd6 = getParamValWithDefault("idd6", 0.0);
+ idd62 = getParamValWithDefault("idd62", 0.0);
+ vdd = getParamValWithDefault("vdd", 0.0);
+ vdd2 = getParamValWithDefault("vdd2", 0.0);
+
+ capacitance = getParamValWithDefault("capacitance", 0.0);
+ ioPower = getParamValWithDefault("ioPower", 0.0);
+ wrOdtPower = getParamValWithDefault("wrOdtPower", 0.0);
+ termRdPower = getParamValWithDefault("termRdPower", 0.0);
+ termWrPower = getParamValWithDefault("termWrPower", 0.0);
+} // MemPowerSpec::processParameters
diff --git a/ext/drampower/src/MemPowerSpec.h b/ext/drampower/src/MemPowerSpec.h
new file mode 100644
index 000000000..f6958820d
--- /dev/null
+++ b/ext/drampower/src/MemPowerSpec.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Karthik Chandrasekar
+ *
+ */
+
+#include "Parametrisable.h"
+
+namespace Data {
+class MemPowerSpec : public virtual Parametrisable {
+ public:
+ MemPowerSpec();
+ void processParameters();
+
+ double idd0;
+ double idd02;
+ double idd2p0;
+ double idd2p02;
+ double idd2p1;
+ double idd2p12;
+ double idd2n;
+ double idd2n2;
+ double idd3p0;
+ double idd3p02;
+ double idd3p1;
+ double idd3p12;
+ double idd3n;
+ double idd3n2;
+ double idd4r;
+ double idd4r2;
+ double idd4w;
+ double idd4w2;
+ double idd5;
+ double idd52;
+ double idd6;
+ double idd62;
+ double vdd;
+ double vdd2;
+
+ double capacitance;
+ double ioPower;
+ double wrOdtPower;
+ double termRdPower;
+ double termWrPower;
+};
+}
diff --git a/ext/drampower/src/MemTimingSpec.cc b/ext/drampower/src/MemTimingSpec.cc
new file mode 100644
index 000000000..cf18c5f7b
--- /dev/null
+++ b/ext/drampower/src/MemTimingSpec.cc
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Karthik Chandrasekar
+ *
+ */
+
+#include "MemTimingSpec.h"
+
+using namespace Data;
+
+MemTimingSpec::MemTimingSpec() :
+ clkMhz(0.0),
+ RC(0),
+ RCD(0),
+ CCD(0),
+ CCD_S(0),
+ CCD_L(0),
+ RRD(0),
+ RRD_S(0),
+ RRD_L(0),
+ FAW(0),
+ TAW(0),
+ WTR(0),
+ WTR_S(0),
+ WTR_L(0),
+ REFI(0),
+ RL(0),
+ RP(0),
+ RFC(0),
+ RAS(0),
+ WL(0),
+ AL(0),
+ DQSCK(0),
+ RTP(0),
+ WR(0),
+ XP(0),
+ XPDLL(0),
+ XS(0),
+ XSDLL(0),
+ CKE(0),
+ CKESR(0),
+ clkPeriod(0.0)
+{
+}
+
+void MemTimingSpec::processParameters()
+{
+ clkMhz = getParamValWithDefault("clkMhz", 0.0);
+ RC = getParamValWithDefault("RC", 0);
+ RCD = getParamValWithDefault("RCD", 0);
+ CCD = getParamValWithDefault("CCD", 0);
+ RRD = getParamValWithDefault("RRD", 0);
+ WTR = getParamValWithDefault("WTR", 0);
+ CCD_S = getParamValWithDefault("CCD_S", 0);
+ CCD_L = getParamValWithDefault("CCD_L", 0);
+ RRD_S = getParamValWithDefault("RRD_S", 0);
+ RRD_L = getParamValWithDefault("RRD_L", 0);
+ WTR_S = getParamValWithDefault("WTR_S", 0);
+ WTR_L = getParamValWithDefault("WTR_L", 0);
+ TAW = getParamValWithDefault("TAW", 0);
+ FAW = getParamValWithDefault("FAW", 0);
+ REFI = getParamValWithDefault("REFI", 0);
+ RL = getParamValWithDefault("RL", 0);
+ RP = getParamValWithDefault("RP", 0);
+ RFC = getParamValWithDefault("RFC", 0);
+ RAS = getParamValWithDefault("RAS", 0);
+ WL = getParamValWithDefault("WL", 0);
+ AL = getParamValWithDefault("AL", 0);
+ DQSCK = getParamValWithDefault("DQSCK", 0);
+ RTP = getParamValWithDefault("RTP", 0);
+ WR = getParamValWithDefault("WR", 0);
+ XP = getParamValWithDefault("XP", 0);
+ XPDLL = getParamValWithDefault("XPDLL", 0);
+ XS = getParamValWithDefault("XS", 0);
+ XSDLL = getParamValWithDefault("XSDLL", 0);
+ CKE = getParamValWithDefault("CKE", 0);
+ CKESR = getParamValWithDefault("CKESR", 0);
+ clkPeriod = 1000.0 / clkMhz;
+} // MemTimingSpec::processParameters
diff --git a/ext/drampower/src/MemTimingSpec.h b/ext/drampower/src/MemTimingSpec.h
new file mode 100644
index 000000000..1c3a80c6e
--- /dev/null
+++ b/ext/drampower/src/MemTimingSpec.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Karthik Chandrasekar
+ *
+ */
+
+#include "Parametrisable.h"
+
+namespace Data {
+class MemTimingSpec : public virtual Parametrisable {
+ public:
+ MemTimingSpec();
+ void processParameters();
+
+ double clkMhz;
+ unsigned RC;
+ unsigned RCD;
+ unsigned CCD;
+ unsigned CCD_S;
+ unsigned CCD_L;
+ unsigned RRD;
+ unsigned RRD_S;
+ unsigned RRD_L;
+ unsigned FAW;
+ unsigned TAW;
+ unsigned WTR;
+ unsigned WTR_S;
+ unsigned WTR_L;
+ unsigned REFI;
+ unsigned RL;
+ unsigned RP;
+ unsigned RFC;
+ unsigned RAS;
+ unsigned WL;
+ unsigned AL;
+ unsigned DQSCK;
+ unsigned RTP;
+ unsigned WR;
+ unsigned XP;
+ unsigned XPDLL;
+ unsigned XS;
+ unsigned XSDLL;
+ unsigned CKE;
+ unsigned CKESR;
+ double clkPeriod;
+};
+}
diff --git a/ext/drampower/src/MemoryPowerModel.cc b/ext/drampower/src/MemoryPowerModel.cc
new file mode 100644
index 000000000..4817d1bb5
--- /dev/null
+++ b/ext/drampower/src/MemoryPowerModel.cc
@@ -0,0 +1,428 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Karthik Chandrasekar, Matthias Jung, Omar Naji
+ *
+ */
+
+#include "MemoryPowerModel.h"
+
+#include <cmath> // For pow
+
+#include <stdint.h>
+
+
+using namespace std;
+using namespace Data;
+
+// Calculate energy and average power consumption for the given command trace
+
+void MemoryPowerModel::power_calc(MemorySpecification memSpec,
+ const CommandAnalysis& counters,
+ int term)
+{
+ MemTimingSpec& t = memSpec.memTimingSpec;
+ MemArchitectureSpec& memArchSpec = memSpec.memArchSpec;
+ MemPowerSpec& mps = memSpec.memPowerSpec;
+
+ energy.act_energy = 0.0;
+ energy.pre_energy = 0.0;
+ energy.read_energy = 0.0;
+ energy.write_energy = 0.0;
+ energy.ref_energy = 0.0;
+ energy.act_stdby_energy = 0.0;
+ energy.pre_stdby_energy = 0.0;
+ energy.idle_energy_act = 0.0;
+ energy.idle_energy_pre = 0.0;
+ energy.total_energy = 0.0;
+ energy.f_act_pd_energy = 0.0;
+ energy.f_pre_pd_energy = 0.0;
+ energy.s_act_pd_energy = 0.0;
+ energy.s_pre_pd_energy = 0.0;
+ energy.sref_energy = 0.0;
+ energy.sref_ref_energy = 0.0;
+ energy.sref_ref_act_energy = 0.0;
+ energy.sref_ref_pre_energy = 0.0;
+ energy.spup_energy = 0.0;
+ energy.spup_ref_energy = 0.0;
+ energy.spup_ref_act_energy = 0.0;
+ energy.spup_ref_pre_energy = 0.0;
+ energy.pup_act_energy = 0.0;
+ energy.pup_pre_energy = 0.0;
+ power.IO_power = 0.0;
+ power.WR_ODT_power = 0.0;
+ power.TermRD_power = 0.0;
+ power.TermWR_power = 0.0;
+ energy.read_io_energy = 0.0;
+ energy.write_term_energy = 0.0;
+ energy.read_oterm_energy = 0.0;
+ energy.write_oterm_energy = 0.0;
+ energy.io_term_energy = 0.0;
+
+ // How long a single burst takes, measured in command-clock cycles.
+ int64_t burstCc = memArchSpec.burstLength / memArchSpec.dataRate;
+
+ // IO and Termination Power measures are included, if required.
+ if (term) {
+ io_term_power(memSpec);
+
+ // memArchSpec.width represents the number of data (dq) pins.
+ // 1 DQS pin is associated with every data byte
+ int64_t dqPlusDqsBits = memArchSpec.width + memArchSpec.width / 8;
+ // 1 DQS and 1 DM pin is associated with every data byte
+ int64_t dqPlusDqsPlusMaskBits = memArchSpec.width + memArchSpec.width / 8 + memArchSpec.width / 8;
+ // Size of one clock period for the data bus.
+ double ddrPeriod = t.clkPeriod / memArchSpec.dataRate;
+
+ // Read IO power is consumed by each DQ (data) and DQS (data strobe) pin
+ energy.read_io_energy = calcIoTermEnergy(counters.numberofreads * memArchSpec.burstLength,
+ ddrPeriod,
+ power.IO_power,
+ dqPlusDqsBits);
+
+ // Write ODT power is consumed by each DQ (data), DQS (data strobe) and DM
+ energy.write_term_energy = calcIoTermEnergy(counters.numberofwrites * memArchSpec.burstLength,
+ ddrPeriod,
+ power.WR_ODT_power,
+ dqPlusDqsPlusMaskBits);
+
+ if (memArchSpec.nbrOfRanks > 1) {
+ // Termination power consumed in the idle rank during reads on the active
+ // rank by each DQ (data) and DQS (data strobe) pin.
+ energy.read_oterm_energy = calcIoTermEnergy(counters.numberofreads * memArchSpec.burstLength,
+ ddrPeriod,
+ power.TermRD_power,
+ dqPlusDqsBits);
+
+ // Termination power consumed in the idle rank during writes on the active
+ // rank by each DQ (data), DQS (data strobe) and DM (data mask) pin.
+ energy.write_oterm_energy = calcIoTermEnergy(counters.numberofwrites * memArchSpec.burstLength,
+ ddrPeriod,
+ power.TermWR_power,
+ dqPlusDqsPlusMaskBits);
+ }
+
+ // Sum of all IO and termination energy
+ energy.io_term_energy = energy.read_io_energy + energy.write_term_energy
+ + energy.read_oterm_energy + energy.write_oterm_energy;
+ }
+
+ total_cycles = counters.actcycles + counters.precycles +
+ counters.f_act_pdcycles + counters.f_pre_pdcycles +
+ counters.s_act_pdcycles + counters.s_pre_pdcycles + counters.sref_cycles
+ + counters.sref_ref_act_cycles + counters.sref_ref_pre_cycles +
+ counters.spup_ref_act_cycles + counters.spup_ref_pre_cycles;
+
+ EnergyDomain vdd0Domain(mps.vdd, t.clkPeriod);
+
+ energy.act_energy = vdd0Domain.calcTivEnergy(counters.numberofacts * t.RAS , mps.idd0 - mps.idd3n);
+ energy.pre_energy = vdd0Domain.calcTivEnergy(counters.numberofpres * (t.RC - t.RAS) , mps.idd0 - mps.idd2n);
+ energy.read_energy = vdd0Domain.calcTivEnergy(counters.numberofreads * burstCc , mps.idd4r - mps.idd3n);
+ energy.write_energy = vdd0Domain.calcTivEnergy(counters.numberofwrites * burstCc , mps.idd4w - mps.idd3n);
+ energy.ref_energy = vdd0Domain.calcTivEnergy(counters.numberofrefs * t.RFC , mps.idd5 - mps.idd3n);
+ energy.pre_stdby_energy = vdd0Domain.calcTivEnergy(counters.precycles, mps.idd2n);
+ energy.act_stdby_energy = vdd0Domain.calcTivEnergy(counters.actcycles, mps.idd3n);
+ // Idle energy in the active standby clock cycles
+ energy.idle_energy_act = vdd0Domain.calcTivEnergy(counters.idlecycles_act, mps.idd3n);
+ // Idle energy in the precharge standby clock cycles
+ energy.idle_energy_pre = vdd0Domain.calcTivEnergy(counters.idlecycles_pre, mps.idd2n);
+ // fast-exit active power-down cycles energy
+ energy.f_act_pd_energy = vdd0Domain.calcTivEnergy(counters.f_act_pdcycles, mps.idd3p1);
+ // fast-exit precharged power-down cycles energy
+ energy.f_pre_pd_energy = vdd0Domain.calcTivEnergy(counters.f_pre_pdcycles, mps.idd2p1);
+ // slow-exit active power-down cycles energy
+ energy.s_act_pd_energy = vdd0Domain.calcTivEnergy(counters.s_act_pdcycles, mps.idd3p0);
+ // slow-exit precharged power-down cycles energy
+ energy.s_pre_pd_energy = vdd0Domain.calcTivEnergy(counters.s_pre_pdcycles, mps.idd2p0);
+
+ // self-refresh cycles energy including a refresh per self-refresh entry
+ energy.sref_energy = engy_sref(mps.idd6, mps.idd3n,
+ mps.idd5, mps.vdd,
+ static_cast<double>(counters.sref_cycles), static_cast<double>(counters.sref_ref_act_cycles),
+ static_cast<double>(counters.sref_ref_pre_cycles), static_cast<double>(counters.spup_ref_act_cycles),
+ static_cast<double>(counters.spup_ref_pre_cycles), t.clkPeriod);
+
+ // background energy during active auto-refresh cycles in self-refresh
+ energy.sref_ref_act_energy = vdd0Domain.calcTivEnergy(counters.sref_ref_act_cycles, mps.idd3p0);
+ // background energy during precharged auto-refresh cycles in self-refresh
+ energy.sref_ref_pre_energy = vdd0Domain.calcTivEnergy(counters.sref_ref_pre_cycles, mps.idd2p0);
+ // background energy during active auto-refresh cycles in self-refresh exit
+ energy.spup_ref_act_energy = vdd0Domain.calcTivEnergy(counters.spup_ref_act_cycles, mps.idd3n);
+ // background energy during precharged auto-refresh cycles in self-refresh exit
+ energy.spup_ref_pre_energy = vdd0Domain.calcTivEnergy(counters.spup_ref_pre_cycles, mps.idd2n);
+ // self-refresh power-up cycles energy -- included
+ energy.spup_energy = vdd0Domain.calcTivEnergy(counters.spup_cycles, mps.idd2n);
+ // active power-up cycles energy - same as active standby -- included
+ energy.pup_act_energy = vdd0Domain.calcTivEnergy(counters.pup_act_cycles, mps.idd3n);
+ // precharged power-up cycles energy - same as precharged standby -- included
+ energy.pup_pre_energy = vdd0Domain.calcTivEnergy(counters.pup_pre_cycles, mps.idd2n);
+
+ // similar equations as before to support multiple voltage domains in LPDDR2
+ // and WIDEIO memories
+ if (memArchSpec.twoVoltageDomains) {
+ EnergyDomain vdd2Domain(mps.vdd2, t.clkPeriod);
+
+ energy.act_energy += vdd2Domain.calcTivEnergy(counters.numberofacts * t.RAS , mps.idd02 - mps.idd3n2);
+ energy.pre_energy += vdd2Domain.calcTivEnergy(counters.numberofpres * (t.RC - t.RAS) , mps.idd02 - mps.idd2n2);
+ energy.read_energy += vdd2Domain.calcTivEnergy(counters.numberofreads * burstCc , mps.idd4r2 - mps.idd3n2);
+ energy.write_energy += vdd2Domain.calcTivEnergy(counters.numberofwrites * burstCc , mps.idd4w2 - mps.idd3n2);
+ energy.ref_energy += vdd2Domain.calcTivEnergy(counters.numberofrefs * t.RFC , mps.idd52 - mps.idd3n2);
+ energy.pre_stdby_energy += vdd2Domain.calcTivEnergy(counters.precycles, mps.idd2n2);
+ energy.act_stdby_energy += vdd2Domain.calcTivEnergy(counters.actcycles, mps.idd3n2);
+ // Idle energy in the active standby clock cycles
+ energy.idle_energy_act += vdd2Domain.calcTivEnergy(counters.idlecycles_act, mps.idd3n2);
+ // Idle energy in the precharge standby clock cycles
+ energy.idle_energy_pre += vdd2Domain.calcTivEnergy(counters.idlecycles_pre, mps.idd2n2);
+ // fast-exit active power-down cycles energy
+ energy.f_act_pd_energy += vdd2Domain.calcTivEnergy(counters.f_act_pdcycles, mps.idd3p12);
+ // fast-exit precharged power-down cycles energy
+ energy.f_pre_pd_energy += vdd2Domain.calcTivEnergy(counters.f_pre_pdcycles, mps.idd2p12);
+ // slow-exit active power-down cycles energy
+ energy.s_act_pd_energy += vdd2Domain.calcTivEnergy(counters.s_act_pdcycles, mps.idd3p02);
+ // slow-exit precharged power-down cycles energy
+ energy.s_pre_pd_energy += vdd2Domain.calcTivEnergy(counters.s_pre_pdcycles, mps.idd2p02);
+
+ energy.sref_energy += engy_sref(mps.idd62, mps.idd3n2,
+ mps.idd52, mps.vdd2,
+ static_cast<double>(counters.sref_cycles), static_cast<double>(counters.sref_ref_act_cycles),
+ static_cast<double>(counters.sref_ref_pre_cycles), static_cast<double>(counters.spup_ref_act_cycles),
+ static_cast<double>(counters.spup_ref_pre_cycles), t.clkPeriod);
+
+ // background energy during active auto-refresh cycles in self-refresh
+ energy.sref_ref_act_energy += vdd2Domain.calcTivEnergy(counters.sref_ref_act_cycles, mps.idd3p02);
+ // background energy during precharged auto-refresh cycles in self-refresh
+ energy.sref_ref_pre_energy += vdd2Domain.calcTivEnergy(counters.sref_ref_pre_cycles, mps.idd2p02);
+ // background energy during active auto-refresh cycles in self-refresh exit
+ energy.spup_ref_act_energy += vdd2Domain.calcTivEnergy(counters.spup_ref_act_cycles, mps.idd3n2);
+ // background energy during precharged auto-refresh cycles in self-refresh exit
+ energy.spup_ref_pre_energy += vdd2Domain.calcTivEnergy(counters.spup_ref_pre_cycles, mps.idd2n2);
+ // self-refresh power-up cycles energy -- included
+ energy.spup_energy += vdd2Domain.calcTivEnergy(counters.spup_cycles, mps.idd2n2);
+ // active power-up cycles energy - same as active standby -- included
+ energy.pup_act_energy += vdd2Domain.calcTivEnergy(counters.pup_act_cycles, mps.idd3n2);
+ // precharged power-up cycles energy - same as precharged standby -- included
+ energy.pup_pre_energy += vdd2Domain.calcTivEnergy(counters.pup_pre_cycles, mps.idd2n2);
+ }
+
+ // auto-refresh energy during self-refresh cycles
+ energy.sref_ref_energy = energy.sref_ref_act_energy + energy.sref_ref_pre_energy;
+
+ // auto-refresh energy during self-refresh exit cycles
+ energy.spup_ref_energy = energy.spup_ref_act_energy + energy.spup_ref_pre_energy;
+
+ // adding all energy components for the active rank and all background and idle
+ // energy components for both ranks (in a dual-rank system)
+ energy.total_energy = energy.act_energy + energy.pre_energy + energy.read_energy +
+ energy.write_energy + energy.ref_energy + energy.io_term_energy +
+ memArchSpec.nbrOfRanks * (energy.act_stdby_energy +
+ energy.pre_stdby_energy + energy.sref_energy +
+ energy.f_act_pd_energy + energy.f_pre_pd_energy + energy.s_act_pd_energy
+ + energy.s_pre_pd_energy + energy.sref_ref_energy + energy.spup_ref_energy);
+
+ // Calculate the average power consumption
+ power.average_power = energy.total_energy / (static_cast<double>(total_cycles) * t.clkPeriod);
+} // MemoryPowerModel::power_calc
+
+void MemoryPowerModel::power_print(MemorySpecification memSpec, int term, const CommandAnalysis& counters) const
+{
+ MemTimingSpec& memTimingSpec = memSpec.memTimingSpec;
+ MemArchitectureSpec& memArchSpec = memSpec.memArchSpec;
+
+ cout.precision(0);
+ cout << "* Trace Details:" << endl;
+ cout << "Number of Activates: " << fixed << counters.numberofacts << endl;
+ cout << "Number of Reads: " << counters.numberofreads << endl;
+ cout << "Number of Writes: " << counters.numberofwrites << endl;
+ cout << "Number of Precharges: " << counters.numberofpres << endl;
+ cout << "Number of Refreshes: " << counters.numberofrefs << endl;
+ cout << "Number of Active Cycles: " << counters.actcycles << endl;
+ cout << " Number of Active Idle Cycles: " << counters.idlecycles_act << endl;
+ cout << " Number of Active Power-Up Cycles: " << counters.pup_act_cycles << endl;
+ cout << " Number of Auto-Refresh Active cycles during Self-Refresh " <<
+ "Power-Up: " << counters.spup_ref_act_cycles << endl;
+ cout << "Number of Precharged Cycles: " << counters.precycles << endl;
+ cout << " Number of Precharged Idle Cycles: " << counters.idlecycles_pre << endl;
+ cout << " Number of Precharged Power-Up Cycles: " << counters.pup_pre_cycles
+ << endl;
+ cout << " Number of Auto-Refresh Precharged cycles during Self-Refresh"
+ << " Power-Up: " << counters.spup_ref_pre_cycles << endl;
+ cout << " Number of Self-Refresh Power-Up Cycles: " << counters.spup_cycles
+ << endl;
+ cout << "Total Idle Cycles (Active + Precharged): " <<
+ counters.idlecycles_act + counters.idlecycles_pre << endl;
+ cout << "Number of Power-Downs: " << counters.f_act_pdns +
+ counters.s_act_pdns + counters.f_pre_pdns + counters.s_pre_pdns << endl;
+ cout << " Number of Active Fast-exit Power-Downs: " << counters.f_act_pdns
+ << endl;
+ cout << " Number of Active Slow-exit Power-Downs: " << counters.s_act_pdns
+ << endl;
+ cout << " Number of Precharged Fast-exit Power-Downs: " <<
+ counters.f_pre_pdns << endl;
+ cout << " Number of Precharged Slow-exit Power-Downs: " <<
+ counters.s_pre_pdns << endl;
+ cout << "Number of Power-Down Cycles: " << counters.f_act_pdcycles +
+ counters.s_act_pdcycles + counters.f_pre_pdcycles + counters.s_pre_pdcycles << endl;
+ cout << " Number of Active Fast-exit Power-Down Cycles: " <<
+ counters.f_act_pdcycles << endl;
+ cout << " Number of Active Slow-exit Power-Down Cycles: " <<
+ counters.s_act_pdcycles << endl;
+ cout << " Number of Auto-Refresh Active cycles during Self-Refresh: " <<
+ counters.sref_ref_act_cycles << endl;
+ cout << " Number of Precharged Fast-exit Power-Down Cycles: " <<
+ counters.f_pre_pdcycles << endl;
+ cout << " Number of Precharged Slow-exit Power-Down Cycles: " <<
+ counters.s_pre_pdcycles << endl;
+ cout << " Number of Auto-Refresh Precharged cycles during Self-Refresh: " <<
+ counters.sref_ref_pre_cycles << endl;
+ cout << "Number of Auto-Refresh Cycles: " << counters.numberofrefs *
+ memTimingSpec.RFC << endl;
+ cout << "Number of Self-Refreshes: " << counters.numberofsrefs << endl;
+ cout << "Number of Self-Refresh Cycles: " << counters.sref_cycles << endl;
+ cout << "----------------------------------------" << endl;
+ cout << "Total Trace Length (clock cycles): " << total_cycles << endl;
+ cout << "----------------------------------------" << endl;
+ cout.precision(2);
+
+ cout << "\n* Trace Power and Energy Estimates:" << endl;
+ cout << "ACT Cmd Energy: " << energy.act_energy << " pJ" << endl;
+ cout << "PRE Cmd Energy: " << energy.pre_energy << " pJ" << endl;
+ cout << "RD Cmd Energy: " << energy.read_energy << " pJ" << endl;
+ cout << "WR Cmd Energy: " << energy.write_energy << " pJ" << endl;
+ if (term) {
+ cout << "RD I/O Energy: " << energy.read_io_energy << " pJ" << endl;
+ // No Termination for LPDDR/2/3 and DDR memories
+ if (memSpec.memArchSpec.termination) {
+ cout << "WR Termination Energy: " << energy.write_term_energy << " pJ" << endl;
+ }
+
+ if ((memArchSpec.nbrOfRanks > 1) && memSpec.memArchSpec.termination) {
+ cout << "RD Termination Energy (Idle rank): " << energy.read_oterm_energy
+ << " pJ" << endl;
+ cout << "WR Termination Energy (Idle rank): " << energy.write_oterm_energy
+ << " pJ" << endl;
+ }
+ }
+ cout << "ACT Stdby Energy: " << memArchSpec.nbrOfRanks * energy.act_stdby_energy <<
+ " pJ" << endl;
+ cout << " Active Idle Energy: " << memArchSpec.nbrOfRanks * energy.idle_energy_act <<
+ " pJ" << endl;
+ cout << " Active Power-Up Energy: " << memArchSpec.nbrOfRanks * energy.pup_act_energy <<
+ " pJ" << endl;
+ cout << " Active Stdby Energy during Auto-Refresh cycles in Self-Refresh"
+ << " Power-Up: " << memArchSpec.nbrOfRanks * energy.spup_ref_act_energy <<
+ " pJ" << endl;
+ cout << "PRE Stdby Energy: " << memArchSpec.nbrOfRanks * energy.pre_stdby_energy <<
+ " pJ" << endl;
+ cout << " Precharge Idle Energy: " << memArchSpec.nbrOfRanks * energy.idle_energy_pre <<
+ " pJ" << endl;
+ cout << " Precharged Power-Up Energy: " << memArchSpec.nbrOfRanks * energy.pup_pre_energy <<
+ " pJ" << endl;
+ cout << " Precharge Stdby Energy during Auto-Refresh cycles " <<
+ "in Self-Refresh Power-Up: " << memArchSpec.nbrOfRanks * energy.spup_ref_pre_energy <<
+ " pJ" << endl;
+ cout << " Self-Refresh Power-Up Energy: " << memArchSpec.nbrOfRanks * energy.spup_energy <<
+ " pJ" << endl;
+ cout << "Total Idle Energy (Active + Precharged): " << memArchSpec.nbrOfRanks *
+ (energy.idle_energy_act + energy.idle_energy_pre) << " pJ" << endl;
+ cout << "Total Power-Down Energy: " << memArchSpec.nbrOfRanks * (energy.f_act_pd_energy +
+ energy.f_pre_pd_energy + energy.s_act_pd_energy + energy.s_pre_pd_energy) << " pJ" << endl;
+ cout << " Fast-Exit Active Power-Down Energy: " << memArchSpec.nbrOfRanks *
+ energy.f_act_pd_energy << " pJ" << endl;
+ cout << " Slow-Exit Active Power-Down Energy: " << memArchSpec.nbrOfRanks *
+ energy.s_act_pd_energy << " pJ" << endl;
+ cout << " Slow-Exit Active Power-Down Energy during Auto-Refresh cycles "
+ << "in Self-Refresh: " << memArchSpec.nbrOfRanks * energy.sref_ref_act_energy <<
+ " pJ" << endl;
+ cout << " Fast-Exit Precharged Power-Down Energy: " << memArchSpec.nbrOfRanks *
+ energy.f_pre_pd_energy << " pJ" << endl;
+ cout << " Slow-Exit Precharged Power-Down Energy: " << memArchSpec.nbrOfRanks *
+ energy.s_pre_pd_energy << " pJ" << endl;
+ cout << " Slow-Exit Precharged Power-Down Energy during Auto-Refresh " <<
+ "cycles in Self-Refresh: " << memArchSpec.nbrOfRanks * energy.sref_ref_pre_energy <<
+ " pJ" << endl;
+ cout << "Auto-Refresh Energy: " << energy.ref_energy << " pJ" << endl;
+ cout << "Self-Refresh Energy: " << memArchSpec.nbrOfRanks * energy.sref_energy <<
+ " pJ" << endl;
+ cout << "----------------------------------------" << endl;
+ cout << "Total Trace Energy: " << energy.total_energy << " pJ" << endl;
+ cout << "Average Power: " << power.average_power << " mW" << endl;
+ cout << "----------------------------------------" << endl;
+} // MemoryPowerModel::power_print
+
+// Self-refresh active energy estimation (not including background energy)
+double MemoryPowerModel::engy_sref(double idd6, double idd3n, double idd5,
+ double vdd, double sref_cycles, double sref_ref_act_cycles,
+ double sref_ref_pre_cycles, double spup_ref_act_cycles,
+ double spup_ref_pre_cycles, double clk)
+{
+ double sref_energy;
+
+ sref_energy = ((idd6 * sref_cycles) + ((idd5 - idd3n) * (sref_ref_act_cycles
+ + spup_ref_act_cycles + sref_ref_pre_cycles + spup_ref_pre_cycles)))
+ * vdd * clk;
+ return sref_energy;
+}
+
+// IO and Termination power calculation based on Micron Power Calculators
+// Absolute power measures are obtained from Micron Power Calculator (mentioned in mW)
+void MemoryPowerModel::io_term_power(MemorySpecification memSpec)
+{
+ MemTimingSpec& memTimingSpec = memSpec.memTimingSpec;
+ MemArchitectureSpec& memArchSpec = memSpec.memArchSpec;
+ MemPowerSpec& memPowerSpec = memSpec.memPowerSpec;
+
+ power.IO_power = memPowerSpec.ioPower; // in mW
+ power.WR_ODT_power = memPowerSpec.wrOdtPower; // in mW
+
+ if (memArchSpec.nbrOfRanks > 1) {
+ power.TermRD_power = memPowerSpec.termRdPower; // in mW
+ power.TermWR_power = memPowerSpec.termWrPower; // in mW
+ }
+
+ if (memPowerSpec.capacitance != 0.0) {
+ // If capacity is given, then IO Power depends on DRAM clock frequency.
+ power.IO_power = memPowerSpec.capacitance * 0.5 * pow(memPowerSpec.vdd2, 2.0) * memTimingSpec.clkMhz * 1000000;
+ }
+} // MemoryPowerModel::io_term_power
+
+
+double MemoryPowerModel::calcIoTermEnergy(int64_t cycles, double period, double power, int64_t numBits) const
+{
+ return static_cast<double>(cycles) * period * power * static_cast<double>(numBits);
+}
+
+// time (t) * current (I) * voltage (V) energy calculation
+double EnergyDomain::calcTivEnergy(int64_t cycles, double current) const
+{
+ return static_cast<double>(cycles) * clkPeriod * current * voltage;
+}
diff --git a/ext/drampower/src/MemoryPowerModel.h b/ext/drampower/src/MemoryPowerModel.h
new file mode 100644
index 000000000..b894f67dd
--- /dev/null
+++ b/ext/drampower/src/MemoryPowerModel.h
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Karthik Chandrasekar, Matthias Jung, Omar Naji
+ *
+ */
+
+#ifndef MEMORY_POWER_MODEL_H
+#define MEMORY_POWER_MODEL_H
+
+#include "MemorySpecification.h"
+#include "CommandAnalysis.h"
+
+namespace Data {
+class MemoryPowerModel {
+ public:
+ // Calculate energy and average power consumption for the given memory
+ // command trace
+ void power_calc(MemorySpecification memSpec,
+ const CommandAnalysis& counters,
+ int term);
+
+ // Used to calculate self-refresh active energy
+ static double engy_sref(double idd6,
+ double idd3n,
+ double idd5,
+ double vdd,
+ double sref_cycles,
+ double sref_ref_act_cycles,
+ double sref_ref_pre_cycles,
+ double spup_ref_act_cycles,
+ double spup_ref_pre_cycles,
+ double clk);
+
+ int64_t total_cycles;
+
+ struct Energy {
+ // Total energy of all activates
+ double act_energy;
+
+ // Total energy of all precharges
+ double pre_energy;
+
+ // Total energy of all reads
+ double read_energy;
+
+ // Total energy of all writes
+ double write_energy;
+
+ // Total energy of all refreshes
+ double ref_energy;
+
+ // Total background energy of all active standby cycles
+ double act_stdby_energy;
+
+ // Total background energy of all precharge standby cycles
+ double pre_stdby_energy;
+
+ // Total energy of idle cycles in the active mode
+ double idle_energy_act;
+
+ // Total energy of idle cycles in the precharge mode
+ double idle_energy_pre;
+
+ // Total trace/pattern energy
+ double total_energy;
+
+ // Average Power
+ double average_power;
+
+ // Energy consumed in active/precharged fast/slow-exit modes
+ double f_act_pd_energy;
+ double f_pre_pd_energy;
+ double s_act_pd_energy;
+ double s_pre_pd_energy;
+
+ // Energy consumed in self-refresh mode
+ double sref_energy;
+
+ // Energy consumed in auto-refresh during self-refresh mode
+ double sref_ref_energy;
+ double sref_ref_act_energy;
+ double sref_ref_pre_energy;
+
+ // Energy consumed in powering-up from self-refresh mode
+ double spup_energy;
+
+ // Energy consumed in auto-refresh during self-refresh power-up
+ double spup_ref_energy;
+ double spup_ref_act_energy;
+ double spup_ref_pre_energy;
+
+ // Energy consumed in powering-up from active/precharged power-down modes
+ double pup_act_energy;
+ double pup_pre_energy;
+
+ // Energy consumed by IO and Termination
+ double read_io_energy; // Read IO Energy
+ double write_term_energy; // Write Termination Energy
+ double read_oterm_energy; // Read Termination Energy from idle rank
+ double write_oterm_energy; // Write Termination Energy from idle rank
+ // Total IO and Termination Energy
+ double io_term_energy;
+ };
+
+ struct Power {
+ // Power measures corresponding to IO and Termination
+ double IO_power; // Read IO Power
+ double WR_ODT_power; // Write ODT Power
+ double TermRD_power; // Read Termination in idle rank (in dual-rank systems)
+ double TermWR_power; // Write Termination in idle rank (in dual-rank systems)
+
+ // Average Power
+ double average_power;
+ };
+
+ // Print the power and energy
+ void power_print(MemorySpecification memSpec,
+ int term,
+ const CommandAnalysis& counters) const;
+
+ // To derive IO and Termination Power measures using DRAM specification
+ void io_term_power(MemorySpecification memSpec);
+
+ Energy energy;
+ Power power;
+
+ private:
+ double calcIoTermEnergy(int64_t cycles, double period, double power, int64_t numBits) const;
+};
+
+class EnergyDomain {
+ public:
+ EnergyDomain(double voltage, double clkPeriod) :
+ voltage(voltage),
+ clkPeriod(clkPeriod)
+ {}
+
+ double calcTivEnergy(int64_t cycles, double current) const;
+ private:
+ const double voltage;
+ const double clkPeriod;
+};
+
+}
+#endif // ifndef MEMORY_POWER_MODEL_H
diff --git a/ext/drampower/src/MemorySpecification.cc b/ext/drampower/src/MemorySpecification.cc
new file mode 100644
index 000000000..3f9f18811
--- /dev/null
+++ b/ext/drampower/src/MemorySpecification.cc
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Karthik Chandrasekar
+ *
+ */
+
+#include "MemorySpecification.h"
+
+using namespace std;
+using namespace Data;
+
+// Set variable values from XML
+void MemorySpecification::processParameters()
+{
+ setVarFromParam(&id,"memoryId");
+ memoryType = getParamValWithDefault("memoryType", string("DDR3"));
+
+ if (hasParameter("memoryType")) {
+ memArchSpec.twoVoltageDomains = memoryType.hasTwoVoltageDomains();
+ memArchSpec.dll = memoryType.hasDll();
+ memArchSpec.termination = memoryType.hasTermination();
+
+ memPowerSpec.capacitance = memoryType.getCapacitance();
+ memPowerSpec.ioPower = memoryType.getIoPower();
+ memPowerSpec.wrOdtPower = memoryType.getWrOdtPower();
+ memPowerSpec.termRdPower = memoryType.getTermRdPower();
+ memPowerSpec.termWrPower = memoryType.getTermWrPower();
+ }
+}
diff --git a/ext/drampower/src/MemorySpecification.h b/ext/drampower/src/MemorySpecification.h
new file mode 100644
index 000000000..149d41c28
--- /dev/null
+++ b/ext/drampower/src/MemorySpecification.h
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Karthik Chandrasekar
+ *
+ */
+
+#ifndef TOOLS_MEMORY_SPECIFICATION_H
+#define TOOLS_MEMORY_SPECIFICATION_H
+
+#include <cassert>
+#include <string>
+
+#include "MemArchitectureSpec.h"
+#include "MemTimingSpec.h"
+#include "MemPowerSpec.h"
+#include "Parametrisable.h"
+
+
+namespace Data {
+// Supported memory types
+class MemoryType {
+ public:
+ enum MemoryType_t {
+ DDR2 = 0,
+ DDR3,
+ DDR4,
+ LPDDR,
+ LPDDR2,
+ LPDDR3,
+ WIDEIO_SDR,
+ MEMORY_TYPE_INVALID
+ };
+
+ MemoryType(MemoryType_t _val) :
+ val(_val)
+ {
+ }
+
+ MemoryType() :
+ val(MEMORY_TYPE_INVALID)
+ {
+ }
+
+ MemoryType(const std::string& _val) :
+ val(MEMORY_TYPE_INVALID)
+ {
+ if (_val == "DDR2") {
+ val = DDR2;
+ } else if (_val == "DDR3") {
+ val = DDR3;
+ } else if (_val == "DDR4") {
+ val = DDR4;
+ } else if (_val == "LPDDR") {
+ val = LPDDR;
+ } else if (_val == "LPDDR2") {
+ val = LPDDR2;
+ } else if (_val == "LPDDR3") {
+ val = LPDDR3;
+ } else if (_val == "WIDEIO_SDR") {
+ val = WIDEIO_SDR;
+ }
+ assert("Unknown memory type." && val != MEMORY_TYPE_INVALID);
+ }
+
+ bool isLPDDRFamily() const
+ {
+ return val == LPDDR ||
+ val == LPDDR2 ||
+ val == LPDDR3 ||
+ val == WIDEIO_SDR;
+ }
+
+ bool hasTwoVoltageDomains() const
+ {
+ return val == LPDDR ||
+ val == LPDDR2 ||
+ val == LPDDR3 ||
+ val == WIDEIO_SDR;
+ }
+
+ bool isDDRFamily() const
+ {
+ return val == DDR2 ||
+ val == DDR3 ||
+ val == DDR4;
+ }
+
+ bool hasDll() const
+ {
+ return val == DDR2 ||
+ val == DDR3 ||
+ val == DDR4;
+ }
+
+ bool hasTermination() const
+ {
+ return val == DDR2 ||
+ val == DDR3 ||
+ val == DDR4;
+ }
+
+ double getCapacitance() const
+ {
+ // LPDDR/2/3 and DDR memories only have IO Power (no ODT)
+ // Conservative estimates based on Micron Mobile LPDDR2 Power Calculator
+ // LPDDR/2/3 IO Capacitance in mF
+ if (val == LPDDR) {
+ return 0.0000000045;
+ } else if (val == LPDDR2) {
+ return 0.0000000025;
+ } else if (val == LPDDR3) {
+ return 0.0000000018;
+ } else {
+ return 0.0;
+ }
+ }
+
+ double getIoPower() const
+ {
+ if (val == DDR2) {
+ // Conservative estimates based on Micron DDR2 Power Calculator
+ return 1.5; // in mW
+ } else if (val == DDR3) {
+ // Conservative estimates based on Micron DDR3 Power Calculator
+ return 4.6; // in mW
+ } else if (val == DDR4) {
+ // Conservative estimates based on Micron DDR3 Power Calculator
+ // using available termination resistance values from Micron DDR4 Datasheets
+ return 3.7; // in mW
+ } else {
+ return 0.0;
+ }
+ }
+
+ double getWrOdtPower() const
+ {
+ if (val == DDR2) {
+ // Conservative estimates based on Micron DDR2 Power Calculator
+ return 8.2; // in mW
+ } else if (val == DDR3) {
+ // Conservative estimates based on Micron DDR3 Power Calculator
+ return 21.2; // in mW
+ } else if (val == DDR4) {
+ // Conservative estimates based on Micron DDR3 Power Calculator
+ // using available termination resistance values from Micron DDR4 Datasheets
+ return 17.0; // in mW
+ } else {
+ return 0.0;
+ }
+ }
+
+ double getTermRdPower() const
+ {
+ if (val == DDR2) {
+ // Conservative estimates based on Micron DDR2 Power Calculator
+ return 13.1; // in mW
+ } else if (val == DDR3) {
+ // Conservative estimates based on Micron DDR3 Power Calculator
+ return 15.5; // in mW
+ } else if (val == DDR4) {
+ // Conservative estimates based on Micron DDR3 Power Calculator
+ // using available termination resistance values from Micron DDR4 Datasheets
+ return 12.4; // in mW
+ } else {
+ return 0.0;
+ }
+ }
+
+ double getTermWrPower() const
+ {
+ if (val == DDR2) {
+ // Conservative estimates based on Micron DDR2 Power Calculator
+ return 14.6; // in mW
+ } else if (val == DDR3) {
+ // Conservative estimates based on Micron DDR3 Power Calculator
+ return 15.4; // in mW
+ } else if (val == DDR4) {
+ // Conservative estimates based on Micron DDR3 Power Calculator
+ // using available termination resistance values from Micron DDR4 Datasheets
+ return 12.3; // in mW
+ } else {
+ return 0.0;
+ }
+ }
+
+ operator MemoryType_t() const {
+ return val;
+ }
+
+ private:
+ MemoryType_t val;
+};
+
+class MemorySpecification : public virtual Parametrisable {
+ public:
+ std::string id;
+ MemoryType memoryType;
+
+ MemArchitectureSpec memArchSpec;
+ MemTimingSpec memTimingSpec;
+ MemPowerSpec memPowerSpec;
+
+ void processParameters();
+
+ static MemorySpecification getMemSpecFromXML(const std::string& id);
+};
+} // namespace Data
+#endif // ifndef TOOLS_MEMORY_SPECIFICATION_H
diff --git a/ext/drampower/src/Parameter.cc b/ext/drampower/src/Parameter.cc
new file mode 100644
index 000000000..9767e1c94
--- /dev/null
+++ b/ext/drampower/src/Parameter.cc
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Andreas Hansson
+ *
+ */
+
+#include "Parameter.h"
+
+#include <iomanip>
+#include "Utils.h"
+
+using namespace Data;
+using namespace std;
+
+Parameter::Parameter(const string& id, const string& type,
+ const string& value) : id(id), type(type), value(value)
+{
+}
+
+string Parameter::getId() const
+{
+ return id;
+}
+
+string Parameter::getType() const
+{
+ return type;
+}
+
+int Parameter::getIntValue() const
+{
+ return fromString<int>(value);
+}
+
+unsigned int Parameter::getUIntValue() const
+{
+ bool isHex = value.size() > 1 && value[0] == '0' && value[1] == 'x';
+
+ return fromString<unsigned int>(value, isHex ? std::hex : std::dec);
+}
+
+#ifdef _LP64
+
+size_t Parameter::getSizeTValue() const
+{
+ bool isHex = value.size() > 1 && value[0] == '0' && value[1] == 'x';
+
+ return fromString<size_t>(value, isHex ? std::hex : std::dec);
+}
+
+#endif
+
+double Parameter::getDoubleValue() const
+{
+ return fromString<double>(value);
+}
+
+bool Parameter::getBoolValue() const
+{
+ return fromString<bool>(value);
+}
+
+string Parameter::getValue() const
+{
+ return value;
+}
+
+Parameter Data::HexParameter(const string& id, int value)
+{
+ std::ostringstream ss;
+
+ ss << "0x" << hex << setw(8) << setfill('0') << value;
+
+ return Parameter(id, "int", ss.str());
+}
+
+Parameter Data::StringParameter(const string& id, const string& value)
+{
+ return Parameter(id, "string", value);
+}
+
+ostream& Data::operator<<(ostream& os, const Parameter& parameter)
+{
+ os << "<parameter " <<
+ "id=\"" << parameter.getId() << "\" " <<
+ "type=\"" << parameter.getType() << "\" "
+ "value=\"" << parameter.getValue() << "\" />";
+
+ return os;
+}
diff --git a/ext/drampower/src/Parameter.h b/ext/drampower/src/Parameter.h
new file mode 100644
index 000000000..2c9623eeb
--- /dev/null
+++ b/ext/drampower/src/Parameter.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Andreas Hansson
+ *
+ */
+
+#ifndef DATA_PARAMETER_H
+#define DATA_PARAMETER_H
+
+#include <string>
+#include <ostream>
+
+namespace Data {
+class Parameter {
+ public:
+ Parameter(const std::string& id, const std::string& type,
+ const std::string& value);
+
+ std::string getId() const;
+ std::string getType() const;
+ std::string getValue() const;
+
+ int getIntValue() const;
+ unsigned int getUIntValue() const;
+ size_t getSizeTValue() const;
+ double getDoubleValue() const;
+ bool getBoolValue() const;
+
+ operator int() const {
+ return getIntValue();
+ }
+
+ operator unsigned int() const {
+ return getUIntValue();
+ }
+
+#ifdef _LP64
+
+ operator size_t() const {
+ return getSizeTValue();
+ }
+#endif
+
+ operator double() const {
+ return getDoubleValue();
+ }
+
+ operator bool() const {
+ return getBoolValue();
+ }
+
+ operator std::string() const {
+ return getValue();
+ }
+
+ private:
+ std::string id;
+ std::string type;
+ std::string value;
+};
+
+Parameter HexParameter(const std::string& id,
+ int value);
+
+Parameter StringParameter(const std::string& id,
+ const std::string& value);
+
+std::ostream& operator<<(std::ostream& os,
+ const Parameter& parameter);
+}
+#endif // ifndef DATA_PARAMETER_H
diff --git a/ext/drampower/src/Parametrisable.cc b/ext/drampower/src/Parametrisable.cc
new file mode 100644
index 000000000..a348fd86e
--- /dev/null
+++ b/ext/drampower/src/Parametrisable.cc
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Andreas Hansson
+ *
+ */
+
+#include "Parametrisable.h"
+
+#include <iostream>
+#include <cstdlib>
+
+using namespace Data;
+using namespace std;
+
+void Parametrisable::pushParameter(const Parameter& parameter)
+{
+ parameters.push_back(parameter);
+}
+
+void Parametrisable::setParameter(const Parameter& parameter,
+ unsigned int index)
+{
+ unsigned int count = 0;
+
+ vector<Parameter>::iterator p = parameters.begin();
+
+ while (p != parameters.end() && !(p->getId() == parameter.getId() &&
+ index == count)) {
+ if (p->getId() == parameter.getId())
+ ++count;
+ ++p;
+ }
+
+ if (p == parameters.end()) {
+ parameters.push_back(parameter);
+ } else {
+ p = parameters.erase(p);
+ parameters.insert(p, parameter);
+ }
+} // Parametrisable::setParameter
+
+bool Parametrisable::removeParameter(const string& id, unsigned int index)
+{
+ unsigned int count = 0;
+
+ for (vector<Parameter>::iterator p = parameters.begin();
+ p != parameters.end(); ++p) {
+ if ((p->getId() == id) && (index == count++)) {
+ parameters.erase(p);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/**
+ * Get a parameter with a specific id. Should there be a multiplicity,
+ * then the index is used to determine which instance is returned, in
+ * order traversal.
+ */
+Parameter Parametrisable::getParameter(const string& id,
+ unsigned int index) const
+{
+ unsigned int count = 0;
+
+ for (vector<Parameter>::const_iterator p = parameters.begin();
+ p != parameters.end(); ++p) {
+ if ((p->getId() == id) && (index == count++)) {
+ return *p;
+ }
+ }
+
+ cerr << "Could not find parameter '" << id << "' (" << index << ")" << endl;
+ cerr << "Stored parameters are: " << endl;
+ for (vector<Parameter>::const_iterator p = parameters.begin();
+ p != parameters.end(); ++p) {
+ cerr << " " << p->getId() << ": " << p->getValue() << endl;
+ }
+ exit(1);
+
+ return Parameter("", "", "");
+} // Parametrisable::getParameter
+
+vector<Parameter> Parametrisable::getParameters() const
+{
+ return parameters;
+}
+
+bool Parametrisable::hasParameter(const string& id, unsigned int index) const
+{
+ unsigned int count = 0;
+
+ for (vector<Parameter>::const_iterator p = parameters.begin();
+ p != parameters.end(); ++p) {
+ if ((p->getId() == id) && (index == count++)) {
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/ext/drampower/src/Parametrisable.h b/ext/drampower/src/Parametrisable.h
new file mode 100644
index 000000000..31a69190f
--- /dev/null
+++ b/ext/drampower/src/Parametrisable.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Andreas Hansson
+ *
+ */
+
+#ifndef DATA_PARAMETRISABLE_H
+#define DATA_PARAMETRISABLE_H
+
+#include <string>
+#include <vector>
+
+#include "Parameter.h"
+
+namespace Data {
+/**
+ * Convenience class for the architectural components that are
+ * parametrisable. The interface is shared and implemented only in
+ * this class.
+ */
+class Parametrisable {
+ public:
+ Parametrisable()
+ {
+ }
+
+ virtual ~Parametrisable()
+ {
+ }
+
+ /**
+ * Push a new parameter into the in-order vector without checking
+ * for duplicates.
+ */
+ virtual void pushParameter(const Parameter& parameter);
+
+ /**
+ * Set a parameter with a given index (default 0). This could for
+ * example be a queue size for a given channel id.
+ */
+ void setParameter(const Parameter& parameter,
+ unsigned int index = 0);
+
+ /**
+ * Get a parameter of a given name and of a certain index. Calling
+ * this method on an object that has no parameter of that name
+ * will result in application exit.
+ */
+ Parameter getParameter(const std::string& id,
+ unsigned int index = 0) const;
+
+ /**
+ * Remove a parameter with a specific name and index. If a parameter
+ * is removed this method returns true, otherwise false.
+ */
+ bool removeParameter(const std::string& id,
+ unsigned int index = 0);
+
+ /**
+ * Simply get all the parameters.
+ */
+ std::vector<Parameter> getParameters() const;
+
+ /**
+ * Check if a parameter of a certain name exists in the object.
+ */
+ bool hasParameter(const std::string& id,
+ unsigned int index = 0) const;
+
+ /**
+ * Convenience function to set a variable to the value stored in a parameter
+ * with built in error detection/assertion. Returns true if the value was
+ * successfully set.
+ * @param m
+ * @param paramName
+ * @param assertOnFail
+ * @return
+ */
+ template<typename T>
+ bool setVarFromParam(T* m, const char* paramName)
+ {
+ if (hasParameter(paramName)) {
+ *m = static_cast<T>(getParameter(paramName));
+ return true;
+ } else {
+ *m = static_cast<T>(0);
+ return false;
+ }
+ }
+
+ template<typename T>
+ T getParamValWithDefault(const char* paramName, T defaultVal) const
+ {
+ if (hasParameter(paramName)) {
+ return static_cast<T>(getParameter(paramName));
+ } else {
+ return defaultVal;
+ }
+ }
+
+ protected:
+ std::vector<Parameter> parameters;
+};
+}
+#endif // ifndef DATA_PARAMETRISABLE_H
diff --git a/ext/drampower/src/TraceParser.cc b/ext/drampower/src/TraceParser.cc
new file mode 100644
index 000000000..ec87f06da
--- /dev/null
+++ b/ext/drampower/src/TraceParser.cc
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Omar Naji
+ *
+ */
+#include "TraceParser.h"
+
+#include "CommandAnalysis.h"
+#include "CmdScheduler.h"
+
+using namespace Data;
+using namespace std;
+
+Data::MemCommand TraceParser::parseLine(std::string line)
+{
+ MemCommand memcmd;
+ istringstream linestream(line);
+ string item;
+ double item_val;
+ unsigned itemnum = 0;
+ MemCommand::cmds type = MemCommand::NOP; // Initialized to prevent warning
+
+ while (getline(linestream, item, ',')) {
+ if (itemnum == 0) {
+ stringstream timestamp(item);
+ timestamp >> item_val;
+ memcmd.setTime(item_val);
+ } else if (itemnum == 1) {
+ item_val = MemCommand::getTypeFromName(item);
+ memcmd.setType(static_cast<MemCommand::cmds>(item_val));
+ } else if (itemnum == 2) {
+ stringstream bank(item);
+ bank >> item_val;
+ memcmd.setType(type);
+ memcmd.setBank(static_cast<unsigned>(item_val));
+ }
+ type = memcmd.getType();
+ itemnum++;
+ }
+ return memcmd;
+} // TraceParser::parseLine
+
+void TraceParser::parseFile(MemorySpecification memSpec, std::ifstream& trace,
+ int window, int grouping, int interleaving, int burst,
+ int powerdown, int trans)
+{
+ ifstream pwr_trace;
+
+ counters = CommandAnalysis(memSpec.memArchSpec.nbrOfBanks);
+ int nCommands = 0;
+ bool lastupdate = false;
+ if (trans) {
+ cmdScheduler cmdsched;
+ cmdsched.transTranslation(memSpec, trace, grouping, interleaving, burst, powerdown);
+ pwr_trace.open("commands.trace", ifstream::in);
+ std::string line;
+ while (getline(pwr_trace, line)) {
+ MemCommand cmdline = parseLine(line);
+ cmd_list.push_back(cmdline);
+ nCommands++;
+ if (nCommands == window) {
+ counters.getCommands(memSpec, memSpec.memArchSpec.nbrOfBanks, cmd_list, lastupdate);
+ nCommands = 0;
+ cmd_list.clear();
+ }
+ }
+ lastupdate = true;
+ counters.getCommands(memSpec, memSpec.memArchSpec.nbrOfBanks, cmd_list, lastupdate);
+ cmd_list.clear();
+ pwr_trace.close();
+ } else {
+ std::string line;
+ while (getline(trace, line)) {
+ MemCommand cmdline = parseLine(line);
+ cmd_list.push_back(cmdline);
+ nCommands++;
+ if (nCommands == window) {
+ counters.getCommands(memSpec, memSpec.memArchSpec.nbrOfBanks, cmd_list, lastupdate);
+ nCommands = 0;
+ cmd_list.clear();
+ }
+ }
+ lastupdate = true;
+ counters.getCommands(memSpec, memSpec.memArchSpec.nbrOfBanks, cmd_list, lastupdate);
+ cmd_list.clear();
+ }
+ counters.clear();
+ trace.close();
+} // TraceParser::parseFile
diff --git a/ext/drampower/src/TraceParser.h b/ext/drampower/src/TraceParser.h
new file mode 100644
index 000000000..cabfcd395
--- /dev/null
+++ b/ext/drampower/src/TraceParser.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Omar Naji
+ *
+ */
+
+#ifndef TRACE_PARSER_H
+#define TRACE_PARSER_H
+
+#include <vector>
+#include <string>
+
+#include "MemCommand.h"
+#include "MemorySpecification.h"
+#include "CommandAnalysis.h"
+
+
+class TraceParser {
+ public:
+ // list of parsed commands
+ std::vector<Data::MemCommand> cmd_list;
+
+ // function for parsing one line of the trace
+ Data::MemCommand parseLine(std::string line);
+
+ Data::CommandAnalysis counters;
+ // function for parsing the whole file.
+ // use this function for small traces ( no out-of-memory issue )
+ void parseFile(Data::MemorySpecification memSpec,
+ std::ifstream& trace,
+ int window,
+ int grouping,
+ int interleaving,
+ int burst,
+ int powerdown,
+ int trans);
+};
+
+#endif // ifndef TRACE_PARSER_H
diff --git a/ext/drampower/src/Utils.h b/ext/drampower/src/Utils.h
new file mode 100644
index 000000000..3fba0961f
--- /dev/null
+++ b/ext/drampower/src/Utils.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Andreas Hansson
+ *
+ */
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <string>
+#include <sstream>
+#include <stdexcept>
+#include <typeinfo>
+
+#define MILLION 1000000
+
+template<typename T>
+T fromString(const std::string& s,
+ std::ios_base& (*f)(std::ios_base &) = std::dec)
+throw(std::runtime_error)
+{
+ std::istringstream is(s);
+ T t;
+
+ if (!(is >> f >> t)) {
+ throw std::runtime_error("Cannot convert '" + s + "' to " +
+ typeid(t).name() + " using fromString");
+ }
+
+ return t;
+}
+
+#endif /* UTILS_H */
diff --git a/ext/drampower/src/libdrampower/LibDRAMPower.cc b/ext/drampower/src/libdrampower/LibDRAMPower.cc
new file mode 100644
index 000000000..ac16f948b
--- /dev/null
+++ b/ext/drampower/src/libdrampower/LibDRAMPower.cc
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Matthias Jung, Omar Naji
+ *
+ */
+
+#include "LibDRAMPower.h"
+
+using namespace Data;
+
+libDRAMPower::libDRAMPower(const MemorySpecification& memSpec, bool includeIoAndTermination) :
+ memSpec(memSpec),
+ counters(CommandAnalysis(memSpec.memArchSpec.nbrOfBanks)),
+ includeIoAndTermination(includeIoAndTermination)
+{
+}
+
+libDRAMPower::~libDRAMPower()
+{
+}
+
+void libDRAMPower::doCommand(MemCommand::cmds type, int bank, int64_t timestamp)
+{
+ MemCommand cmd(type, static_cast<unsigned>(bank), static_cast<double>(timestamp));
+ cmdList.push_back(cmd);
+}
+
+void libDRAMPower::updateCounters(bool lastUpdate)
+{
+ counters.getCommands(memSpec, memSpec.memArchSpec.nbrOfBanks, cmdList, lastUpdate);
+ cmdList.clear();
+}
+
+void libDRAMPower::calcEnergy()
+{
+ mpm.power_calc(memSpec, counters, includeIoAndTermination);
+}
+
+void libDRAMPower::clearState()
+{
+ counters.clear();
+}
+
+const Data::MemoryPowerModel::Energy& libDRAMPower::getEnergy() const
+{
+ return mpm.energy;
+}
+
+const Data::MemoryPowerModel::Power& libDRAMPower::getPower() const
+{
+ return mpm.power;
+}
diff --git a/ext/drampower/src/libdrampower/LibDRAMPower.h b/ext/drampower/src/libdrampower/LibDRAMPower.h
new file mode 100644
index 000000000..9dea8b0f5
--- /dev/null
+++ b/ext/drampower/src/libdrampower/LibDRAMPower.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2012-2014, TU Delft
+ * Copyright (c) 2012-2014, TU Eindhoven
+ * Copyright (c) 2012-2014, TU Kaiserslautern
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Matthias Jung, Omar Naji
+ *
+ */
+
+#ifndef LIB_DRAM_POWER_H
+#define LIB_DRAM_POWER_H
+
+#include <stdint.h>
+#include <vector>
+
+#include "CommandAnalysis.h"
+#include "MemoryPowerModel.h"
+#include "MemCommand.h"
+
+class libDRAMPower {
+ public:
+ libDRAMPower(const Data::MemorySpecification& memSpec, bool includeIoAndTermination);
+ ~libDRAMPower();
+
+ void doCommand(Data::MemCommand::cmds type,
+ int bank,
+ int64_t timestamp);
+
+ void updateCounters(bool lastUpdate);
+
+ void clearState();
+
+ void calcEnergy();
+
+ const Data::MemoryPowerModel::Energy& getEnergy() const;
+ const Data::MemoryPowerModel::Power& getPower() const;
+
+ // list of all commands
+ std::vector<Data::MemCommand> cmdList;
+ private:
+ Data::MemorySpecification memSpec;
+ public:
+ Data::CommandAnalysis counters;
+ private:
+ bool includeIoAndTermination;
+ // Object of MemoryPowerModel which contains the results
+ // Energies(pJ) stored in energy, Powers(mW) stored in power. Number of
+ // each command stored in timings.
+ Data::MemoryPowerModel mpm;
+};
+
+#endif // ifndef LIB_DRAM_POWER_H
diff --git a/ext/drampower/src/uncrustify.cfg b/ext/drampower/src/uncrustify.cfg
new file mode 100644
index 000000000..ffe0e5f9c
--- /dev/null
+++ b/ext/drampower/src/uncrustify.cfg
@@ -0,0 +1,280 @@
+tok_split_gte=false
+utf8_byte=false
+utf8_force=false
+indent_cmt_with_tabs=false
+indent_align_string=true
+indent_braces=false
+indent_braces_no_func=false
+indent_braces_no_class=false
+indent_braces_no_struct=false
+indent_brace_parent=false
+indent_namespace=false
+indent_extern=false
+indent_class=true
+indent_class_colon=true
+indent_else_if=false
+indent_var_def_cont=false
+indent_func_call_param=false
+indent_func_def_param=false
+indent_func_proto_param=false
+indent_func_class_param=false
+indent_func_ctor_var_param=false
+indent_template_param=false
+indent_func_param_double=false
+indent_relative_single_line_comments=false
+indent_col1_comment=true
+indent_access_spec_body=false
+indent_paren_nl=false
+indent_comma_paren=false
+indent_bool_paren=false
+indent_first_bool_expr=false
+indent_square_nl=false
+indent_preserve_sql=false
+indent_align_assign=true
+sp_balance_nested_parens=false
+align_keep_tabs=false
+align_with_tabs=false
+align_on_tabstop=false
+align_number_left=true
+align_func_params=true
+align_same_func_call_params=true
+align_var_def_colon=true
+align_var_def_attribute=true
+align_var_def_inline=true
+align_right_cmt_mix=false
+align_on_operator=true
+align_mix_var_proto=false
+align_single_line_func=true
+align_single_line_brace=true
+align_nl_cont=true
+align_left_shift=true
+align_oc_decl_colon=false
+nl_collapse_empty_body=false
+nl_assign_leave_one_liners=false
+nl_class_leave_one_liners=false
+nl_enum_leave_one_liners=false
+nl_getset_leave_one_liners=false
+nl_func_leave_one_liners=false
+nl_if_leave_one_liners=false
+nl_multi_line_cond=false
+nl_multi_line_define=false
+nl_before_case=true
+nl_after_case=false
+nl_after_return=true
+nl_after_semicolon=true
+nl_after_brace_open=false
+nl_after_brace_open_cmt=false
+nl_after_vbrace_open=false
+nl_after_vbrace_open_empty=false
+nl_after_brace_close=false
+nl_after_vbrace_close=false
+nl_define_macro=true
+nl_squeeze_ifdef=false
+nl_ds_struct_enum_cmt=true
+nl_ds_struct_enum_close_brace=true
+nl_create_if_one_liner=false
+nl_create_for_one_liner=false
+nl_create_while_one_liner=false
+ls_for_split_full=false
+ls_func_split_full=false
+nl_after_multiline_comment=true
+eat_blanks_after_open_brace=true
+eat_blanks_before_close_brace=true
+mod_full_brace_if_chain=true
+mod_pawn_semicolon=false
+mod_full_paren_if_bool=true
+mod_remove_extra_semicolon=true
+mod_sort_import=false
+mod_sort_using=false
+mod_sort_include=false
+mod_move_case_break=true
+mod_remove_empty_return=true
+cmt_indent_multi=true
+cmt_c_group=false
+cmt_c_nl_start=false
+cmt_c_nl_end=false
+cmt_cpp_group=false
+cmt_cpp_nl_start=false
+cmt_cpp_nl_end=false
+cmt_cpp_to_c=false
+cmt_star_cont=false
+cmt_multi_check_last=true
+cmt_insert_before_preproc=false
+pp_indent_at_level=false
+pp_region_indent_code=false
+pp_if_indent_code=false
+pp_define_at_level=false
+output_tab_size=2
+indent_columns=2
+indent_namespace_level=0
+indent_namespace_limit=0
+indent_access_spec=-1
+align_var_def_span=2
+align_var_def_star_style=0
+align_var_def_amp_style=0
+align_var_def_thresh=2
+align_var_def_gap=1
+align_assign_span=3
+align_assign_thresh=12
+align_enum_equ_span=1
+align_var_struct_span=1
+align_struct_init_span=1
+align_typedef_span=1
+align_typedef_star_style=2
+align_typedef_amp_style=2
+align_right_cmt_span=4
+align_right_cmt_at_col=1
+align_func_proto_span=1
+nl_end_of_file_min=1
+nl_func_var_def_blk=1
+nl_max=2
+nl_after_func_proto=0
+nl_after_func_body=2
+nl_after_func_body_class=2
+nl_after_func_body_one_liner=2
+nl_before_access_spec=2
+nl_after_access_spec=1
+nl_comment_func_def=1
+nl_after_try_catch_finally=1
+mod_full_brace_nl=1
+mod_add_long_function_closebrace_comment=16
+mod_add_long_switch_closebrace_comment=16
+mod_add_long_ifdef_endif_comment=16
+mod_add_long_ifdef_else_comment=16
+newlines=auto
+indent_with_tabs=0
+sp_arith=add
+sp_assign=add
+sp_enum_assign=add
+sp_pp_concat=add
+sp_pp_stringify=add
+sp_bool=add
+sp_compare=add
+sp_inside_paren=remove
+sp_paren_paren=remove
+sp_paren_brace=add
+sp_before_ptr_star=remove
+sp_before_unnamed_ptr_star=remove
+sp_between_ptr_star=remove
+sp_after_ptr_star=force
+sp_after_ptr_star_func=force
+sp_before_ptr_star_func=remove
+sp_before_byref=remove
+sp_before_unnamed_byref=remove
+sp_after_byref=add
+sp_after_byref_func=add
+sp_before_byref_func=remove
+sp_after_type=add
+sp_before_angle=remove
+sp_inside_angle=remove
+sp_after_angle=remove
+sp_angle_paren=remove
+sp_angle_word=force
+sp_before_sparen=force
+sp_inside_sparen=remove
+sp_after_sparen=remove
+sp_sparen_brace=add
+sp_special_semi=remove
+sp_before_semi=remove
+sp_before_semi_for=remove
+sp_before_semi_for_empty=remove
+sp_after_semi_for_empty=remove
+sp_before_square=remove
+sp_before_squares=remove
+sp_inside_square=remove
+sp_after_comma=add
+sp_before_comma=remove
+sp_after_class_colon=add
+sp_before_class_colon=add
+sp_before_case_colon=remove
+sp_after_operator=remove
+sp_after_operator_sym=remove
+sp_after_cast=remove
+sp_inside_paren_cast=remove
+sp_cpp_cast_paren=remove
+sp_sizeof_paren=remove
+sp_inside_braces_enum=add
+sp_inside_braces_struct=add
+sp_inside_braces=add
+sp_inside_braces_empty=remove
+sp_type_func=add
+sp_func_proto_paren=remove
+sp_func_def_paren=remove
+sp_inside_fparens=remove
+sp_inside_fparen=remove
+sp_square_fparen=remove
+sp_fparen_brace=add
+sp_func_call_paren=remove
+sp_func_call_user_paren=remove
+sp_func_class_paren=remove
+sp_return_paren=add
+sp_attribute_paren=remove
+sp_defined_paren=remove
+sp_throw_paren=remove
+sp_macro=add
+sp_macro_func=remove
+sp_else_brace=add
+sp_brace_else=add
+sp_brace_typedef=add
+sp_catch_brace=add
+sp_brace_catch=add
+sp_finally_brace=add
+sp_brace_finally=add
+sp_try_brace=add
+sp_getset_brace=add
+sp_before_dc=remove
+sp_after_dc=remove
+sp_not=remove
+sp_inv=remove
+sp_addr=remove
+sp_member=remove
+sp_deref=remove
+sp_sign=remove
+sp_incdec=remove
+sp_before_nl_cont=remove
+sp_after_oc_scope=remove
+sp_after_oc_colon=remove
+sp_before_oc_colon=remove
+sp_after_send_oc_colon=add
+sp_before_send_oc_colon=remove
+sp_after_oc_type=remove
+sp_cond_colon=add
+sp_cond_question=add
+sp_cmt_cpp_start=add
+nl_start_of_file=remove
+nl_end_of_file=force
+nl_fcall_brace=force
+nl_if_brace=remove
+nl_brace_else=remove
+nl_elseif_brace=remove
+nl_else_brace=remove
+nl_else_if=remove
+nl_for_brace=remove
+nl_while_brace=remove
+nl_do_brace=remove
+nl_switch_brace=remove
+nl_namespace_brace=remove
+nl_class_brace=remove
+nl_class_init_args=add
+nl_func_def_paren=remove
+nl_func_decl_start=remove
+nl_func_decl_args=add
+nl_fdef_brace=force
+nl_before_if=ignore
+nl_after_if=ignore
+nl_before_for=ignore
+nl_after_for=ignore
+nl_before_while=ignore
+nl_after_while=ignore
+nl_before_switch=ignore
+nl_after_switch=ignore
+nl_before_do=ignore
+nl_after_do=ignore
+mod_full_brace_do=force
+mod_full_brace_for=force
+mod_full_brace_function=force
+mod_full_brace_if=force
+mod_full_brace_while=force
+mod_full_brace_using=remove
+mod_paren_on_return=remove
+pp_space=force