summaryrefslogtreecommitdiff
path: root/ext/drampower/src
diff options
context:
space:
mode:
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