From d95f460237374dfef118ef4f520d97c07cc14cac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Thu, 7 Apr 2016 00:24:21 +0200 Subject: [PATCH 1/4] Power plots generation fixed. This is the DRAMSys patch related to the following DRAMPower issue: https://github.com/ravenrd/DRAMPower/issues/31 --- DRAMSys/analyzer/scripts/plots.py | 10 ++- .../resources/scripts/createTraceDB.sql | 2 +- DRAMSys/simulator/src/common/TlmRecorder.cpp | 4 +- DRAMSys/simulator/src/common/TlmRecorder.h | 2 +- DRAMSys/simulator/src/simulation/Dram.h | 64 +++++++++---------- 5 files changed, 40 insertions(+), 42 deletions(-) mode change 100644 => 100755 DRAMSys/analyzer/scripts/plots.py diff --git a/DRAMSys/analyzer/scripts/plots.py b/DRAMSys/analyzer/scripts/plots.py old mode 100644 new mode 100755 index 745ad8c2..6d9ddc21 --- a/DRAMSys/analyzer/scripts/plots.py +++ b/DRAMSys/analyzer/scripts/plots.py @@ -28,7 +28,7 @@ def memory_utilisation_window(connection, tracePath): total = cursor.fetchone() windowSize = ceil(float(total[0])/float(steps)) if (windowSize == 0): - windowSize = 1 + windowSize = 1 # print(steps) # All possible cases of data transfers inside a time window queryFull = """ SELECT sum(DataStrobeEnd - DataStrobeBegin) FROM transactions Where DataStrobeBegin > ? and DataStrobeEnd < ?""" # The data transfer begins and ends inside the time window @@ -72,8 +72,6 @@ def memory_utilisation_window(connection, tracePath): name = ntpath.basename(tracePath) basename, extension = os.path.splitext(name) - - OUTPUT_FILE = 'memory_utilization_' + basename + '.pdf' print("Output file is {0}".format(OUTPUT_FILE)) @@ -120,8 +118,8 @@ def power_window(connection, tracePath): power = [0] * steps for i in range(steps): result = cursor.fetchone() - time[i] = int(result[0])/1000 - power[i] = float(result[1]) + time[i] = float(result[0]) * 1000000000 # convertion of seconds to nanoseconds + power[i] = float(result[1]) / 1000000000 # conversion of pW to mW name = ntpath.basename(tracePath) basename, extension = os.path.splitext(name) @@ -156,7 +154,7 @@ def power_window(connection, tracePath): # return "Saved as hist.png" -def generatePlots(pathToTrace): +def generatePlots(pathToTrace): connection = sqlite3.connect(pathToTrace) print("================================") diff --git a/DRAMSys/simulator/resources/scripts/createTraceDB.sql b/DRAMSys/simulator/resources/scripts/createTraceDB.sql index aa236f83..a8bad1fe 100644 --- a/DRAMSys/simulator/resources/scripts/createTraceDB.sql +++ b/DRAMSys/simulator/resources/scripts/createTraceDB.sql @@ -26,7 +26,7 @@ CREATE TABLE GeneralInfo( ); CREATE TABLE Power( - time INTEGER, + time DOUBLE, AveragePower DOUBLE ); diff --git a/DRAMSys/simulator/src/common/TlmRecorder.cpp b/DRAMSys/simulator/src/common/TlmRecorder.cpp index c55b2c19..270f04ea 100644 --- a/DRAMSys/simulator/src/common/TlmRecorder.cpp +++ b/DRAMSys/simulator/src/common/TlmRecorder.cpp @@ -74,10 +74,10 @@ TlmRecorder::~TlmRecorder() closeConnection(); } -void TlmRecorder::recordPower(sc_time time, double averagePower) +void TlmRecorder::recordPower(double timeInSeconds, double averagePower) { if (TlmRecorder::recordingEnabled) { - sqlite3_bind_int64(insertPowerStatement, 1, time.value()); + sqlite3_bind_double(insertPowerStatement, 1, timeInSeconds); sqlite3_bind_double(insertPowerStatement, 2, averagePower); executeSqlStatement(insertPowerStatement); } diff --git a/DRAMSys/simulator/src/common/TlmRecorder.h b/DRAMSys/simulator/src/common/TlmRecorder.h index 1f5e499a..d0c0ad49 100644 --- a/DRAMSys/simulator/src/common/TlmRecorder.h +++ b/DRAMSys/simulator/src/common/TlmRecorder.h @@ -69,7 +69,7 @@ public: void recordTracenames(string traces){this->traces = traces;} void recordPhase(tlm::tlm_generic_payload &trans, tlm::tlm_phase phase, sc_time time); - void recordPower(sc_time time, double averagePower); + void recordPower(double timeInSeconds, double averagePower); void recordDebugMessage(std::string message, sc_time time); void updateDataStrobe(const sc_time& begin, const sc_time& end, tlm::tlm_generic_payload& trans); void closeConnection(); diff --git a/DRAMSys/simulator/src/simulation/Dram.h b/DRAMSys/simulator/src/simulation/Dram.h index ed5152b0..62986456 100644 --- a/DRAMSys/simulator/src/simulation/Dram.h +++ b/DRAMSys/simulator/src/simulation/Dram.h @@ -91,7 +91,7 @@ struct Dram : sc_module if(powerAnalysis == true) { sc_time clk = Configuration::getInstance().memSpec.clk; - + MemArchitectureSpec memArchSpec; memArchSpec.burstLength = Configuration::getInstance().memSpec.BurstLength; memArchSpec.dataRate = Configuration::getInstance().memSpec.DataRate; @@ -164,7 +164,7 @@ struct Dram : sc_module memPowerSpec.vdd2 = Configuration::getInstance().memSpec.vDD2; MemorySpecification memSpec; - memSpec.memTimingSpec = memTimingSpec; + memSpec.memTimingSpec = memTimingSpec; memSpec.memPowerSpec = memPowerSpec; memSpec.memArchSpec = memArchSpec; @@ -194,35 +194,27 @@ struct Dram : sc_module ~Dram() { - if(powerAnalysis == true) - { + if (powerAnalysis == true) { + // Obtain the residual energy which was not covered by previous windows DRAMPower->updateCounters(true); DRAMPower->calcEnergy(); - // Calculate the residual power and energy which was not covered by previous windows... - printDebugMessage(string("\tCurrent Energy: \t") + to_string(DRAMPower->getEnergy().total_energy - totalEnergy)); - printDebugMessage(string("\tAverage Power: \t") + to_string((DRAMPower->getEnergy().total_energy - totalEnergy)/powerWindowSize.value())); + double energy = sumOfEnergyWindows + DRAMPower->getEnergy().total_energy; + double averagePower = energy / sc_time_stamp().to_seconds(); - double currentTotalEnergy = DRAMPower->getEnergy().total_energy - totalEnergy; - double currentAveragePower = currentTotalEnergy/powerWindowSize.value(); - sumOfEnergyWindows += currentTotalEnergy; - tlmRecorder->recordPower(sc_time_stamp(),currentAveragePower); - totalEnergy = DRAMPower->getEnergy().total_energy; + tlmRecorder->recordPower(sc_time_stamp().to_seconds(), averagePower); - // Make sure that the summed energy of the windows is the same as the final value provided by DRAMPower: - assert(sumOfEnergyWindows == totalEnergy); - - // Print Final Total Power Values: - cout << name() << string("\tTotal Energy: \t") + to_string(totalEnergy) << endl; - cout << name() << string("\tAverage Power: \t") + to_string(DRAMPower->getPower().average_power) << endl; + // Print Final Total Power Values + cout << name() << string("\tTotal Energy: \t") + to_string(energy) + string("\t[pJ]") << endl; + cout << name() << string("\tAverage Power: \t") + to_string(averagePower) + string("\t[pW]") << endl; } + // Clean up: for (auto e : ememory) { delete e; } - //std::cout << "Simulated Memory Size: " << memory.size() << endl; // TODO Aufrauemen } - + // This Thread is only triggered when Power Simulation is enabled. // It estimates the current average power which will be stored in the trace database for visualization purposes. void powerWindow() @@ -230,22 +222,30 @@ struct Dram : sc_module double currentAveragePower = 0; double currentTotalEnergy = 0; - do - { + do { + unsigned long long c = sc_time_stamp().value() / Configuration::getInstance().memSpec.clk.value(); + + DRAMPower->doCommand(MemCommand::NOP, 0, c); DRAMPower->updateCounters(false); DRAMPower->calcEnergy(); - currentTotalEnergy = DRAMPower->getEnergy().total_energy - totalEnergy; - currentAveragePower = currentTotalEnergy/powerWindowSize.value(); - tlmRecorder->recordPower(sc_time_stamp(),currentAveragePower); - totalEnergy = DRAMPower->getEnergy().total_energy; + + currentTotalEnergy = DRAMPower->getEnergy().total_energy; + + assert(currentTotalEnergy != 0); + + DRAMPower->clearCounters(c); + sumOfEnergyWindows += currentTotalEnergy; + // [pW] = [pJ] / [s] (here considering that DRAMPower provides the value always in pJ) + currentAveragePower = currentTotalEnergy / powerWindowSize.to_seconds(); + + tlmRecorder->recordPower(sc_time_stamp().to_seconds(), currentAveragePower); + + printDebugMessage(string("\tCurrent Energy: \t") + to_string(currentTotalEnergy) + string("\t[pJ]")); + printDebugMessage(string("\tAverage Power: \t") + to_string(currentAveragePower) + string("\t[pW]")); - printDebugMessage(string("\tCurrent Energy: \t") + to_string(currentTotalEnergy)); - printDebugMessage(string("\tAverage Power: \t") + to_string(currentAveragePower)); wait(powerWindowSize); - } - while(true); - + } while(true); } virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& payload, tlm::tlm_phase& phase, sc_time& delay) @@ -510,7 +510,7 @@ struct Dram : sc_module void setTlmRecorder(TlmRecorder *rec) { - tlmRecorder = rec; + tlmRecorder = rec; } }; From e07445a58ec5356751e062049b2f6b4916df479b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Fri, 22 Apr 2016 11:50:39 +0200 Subject: [PATCH 2/4] Using average power values directly from DRAMPower. Now we store the average power values directly obtained from the DRAMPower library into the database. Thus we do not have to divide energy by time to calculate them anymore (avoiding any possible lost of accuracy due to rounding). Other changes: - At the very beginning (zero clock cycles) the energy is 0, so the powerWindow thread wait first. - When working with floats, we have to decide ourselves what is an acceptable definition for "equal". Now we compare the energy value with a suitable error margin (0.00001). Now the assertion that ensures the energy is not zero is working properly. Notes: - The assert() function does nothing if NDEBUG is defined. - The total energy is provided by DRAMPower as a double. We accumulate the total energy for every window since we are clearing the library counters. Explanation about double precision: The double type ensures 15 decimal digits to represent a number. It does not matter if the digits are before or after the comma. Thus we only have rounding for numbers represented with more than 15 decimal digits. In more technical terms: An IEEE double has 53 significant bits (see also DBL_MANT_DIG in ). That is approximately 15.95 decimal digits (log10(2^53)). The implementation sets the number of digits (DBL_DIG) to 15, not 16, because it has to round down. --- DRAMSys/analyzer/scripts/plots.py | 2 +- DRAMSys/simulator/simulator.pro | 7 --- DRAMSys/simulator/src/simulation/Dram.h | 60 +++++++++++++++++-------- 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/DRAMSys/analyzer/scripts/plots.py b/DRAMSys/analyzer/scripts/plots.py index 6d9ddc21..c161140d 100755 --- a/DRAMSys/analyzer/scripts/plots.py +++ b/DRAMSys/analyzer/scripts/plots.py @@ -119,7 +119,7 @@ def power_window(connection, tracePath): for i in range(steps): result = cursor.fetchone() time[i] = float(result[0]) * 1000000000 # convertion of seconds to nanoseconds - power[i] = float(result[1]) / 1000000000 # conversion of pW to mW + power[i] = float(result[1]) # values are stored in mW name = ntpath.basename(tracePath) basename, extension = os.path.splitext(name) diff --git a/DRAMSys/simulator/simulator.pro b/DRAMSys/simulator/simulator.pro index 307a3ffc..2629ff42 100644 --- a/DRAMSys/simulator/simulator.pro +++ b/DRAMSys/simulator/simulator.pro @@ -49,13 +49,6 @@ INCLUDEPATH += src/common/third_party/DRAMPower/src/libdrampower DEFINES += TIXML_USE_STL DEFINES += SC_INCLUDE_DYNAMIC_PROCESSES -release { - DEFINES += NDEBUG -} - -#CONFIG += c++11 -#QMAKE_CXXFLAGS += -O0 -g -#QMAKE_CXXFLAGS += -std=c++0x -O0 -g unix:!macx { QMAKE_CXXFLAGS += -std=c++11 -O0 -g diff --git a/DRAMSys/simulator/src/simulation/Dram.h b/DRAMSys/simulator/src/simulation/Dram.h index 62986456..8e025324 100644 --- a/DRAMSys/simulator/src/simulation/Dram.h +++ b/DRAMSys/simulator/src/simulation/Dram.h @@ -45,6 +45,7 @@ #include #include #include +#include #include "../common/DebugManager.h" #include "../common/dramExtension.h" #include "../controller/core/TimingCalculation.h" @@ -71,8 +72,7 @@ struct Dram : sc_module enum sc_time_unit pWindowUnit = Configuration::getInstance().PowerWindowUnit; sc_time powerWindowSize = sc_time(pWindowSize, pWindowUnit); libDRAMPower *DRAMPower; - double totalEnergy = 0; - double sumOfEnergyWindows = 0; + double sumOfEnergyWindows = 0.0; // Error Model related: ErrorStorageMode ErrorStoreMode = Configuration::getInstance().ErrorStoreMode; @@ -199,14 +199,13 @@ struct Dram : sc_module DRAMPower->updateCounters(true); DRAMPower->calcEnergy(); - double energy = sumOfEnergyWindows + DRAMPower->getEnergy().total_energy; - double averagePower = energy / sc_time_stamp().to_seconds(); + double totalEnergy = sumOfEnergyWindows + DRAMPower->getEnergy().total_energy; + // The energy is given in [pJ] and divided by [s] resulting in [pW] then converted to [mW] + double averagePower = (totalEnergy / sc_time_stamp().to_seconds()) / 1e9; - tlmRecorder->recordPower(sc_time_stamp().to_seconds(), averagePower); - - // Print Final Total Power Values - cout << name() << string("\tTotal Energy: \t") + to_string(energy) + string("\t[pJ]") << endl; - cout << name() << string("\tAverage Power: \t") + to_string(averagePower) + string("\t[pW]") << endl; + // Print the final total energy and the average power for the simulation + cout << name() << string("\tTotal Energy: \t") + to_string(totalEnergy) + string("\t[pJ]") << endl; + cout << name() << string("\tAverage Power: \t") + to_string(averagePower) + string("\t[mW]") << endl; } // Clean up: @@ -215,6 +214,14 @@ struct Dram : sc_module } } + // When working with floats, we have to decide ourselves what is an + // acceptable definition for "equal". Here the number is compared with a + // suitable error margin (0.00001). + bool is_equal(double a, double b, const double epsilon = 1e-05) + { + return std::fabs(a - b) < epsilon; + } + // This Thread is only triggered when Power Simulation is enabled. // It estimates the current average power which will be stored in the trace database for visualization purposes. void powerWindow() @@ -223,28 +230,45 @@ struct Dram : sc_module double currentTotalEnergy = 0; do { - unsigned long long c = sc_time_stamp().value() / Configuration::getInstance().memSpec.clk.value(); + // At the very beginning (zero clock cycles) the energy is 0, so we wait first + wait(powerWindowSize); - DRAMPower->doCommand(MemCommand::NOP, 0, c); + unsigned long long clk_cycles = sc_time_stamp().value() / Configuration::getInstance().memSpec.clk.value(); + + DRAMPower->doCommand(MemCommand::NOP, 0, clk_cycles); DRAMPower->updateCounters(false); DRAMPower->calcEnergy(); currentTotalEnergy = DRAMPower->getEnergy().total_energy; + currentAveragePower = DRAMPower->getPower().average_power; - assert(currentTotalEnergy != 0); + DRAMPower->clearCounters(clk_cycles); - DRAMPower->clearCounters(c); + // During operation the energy should never be zero since the device is always consuming + assert(!is_equal(currentTotalEnergy, 0.0)); + // Accumulate the energy since we are clearing the library + // counters. + // + // Here we use double values. The double type ensures 15 decimal + // digits to represent a number. It does not matter if the digits + // are before or after the comma. Thus we only have rounding for + // numbers represented with more than 15 decimal digits. + // + // In more technical terms: + // An IEEE double has 53 significant bits (see also DBL_MANT_DIG + // in ). That is approximately 15.95 decimal digits + // (log10(2^53)). The implementation sets the number of digits + // (DBL_DIG) to 15, not 16, because it has to round down. + // sumOfEnergyWindows += currentTotalEnergy; - // [pW] = [pJ] / [s] (here considering that DRAMPower provides the value always in pJ) - currentAveragePower = currentTotalEnergy / powerWindowSize.to_seconds(); + // Store the time (in seconds) and the current average power (in mW) into the database tlmRecorder->recordPower(sc_time_stamp().to_seconds(), currentAveragePower); + // Here considering that DRAMPower provides the energy in pJ and the power in mW printDebugMessage(string("\tCurrent Energy: \t") + to_string(currentTotalEnergy) + string("\t[pJ]")); - printDebugMessage(string("\tAverage Power: \t") + to_string(currentAveragePower) + string("\t[pW]")); - - wait(powerWindowSize); + printDebugMessage(string("\tAverage Power 1: \t") + to_string(currentAveragePower) + string("\t[mW]")); } while(true); } From 8e4e9f4f65e15c2f46fd4bf317209747bc00bdb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Tue, 3 May 2016 17:24:12 +0200 Subject: [PATCH 3/4] Typo fixed --- DRAMSys/simulator/src/simulation/Dram.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DRAMSys/simulator/src/simulation/Dram.h b/DRAMSys/simulator/src/simulation/Dram.h index 8e025324..d11154c7 100644 --- a/DRAMSys/simulator/src/simulation/Dram.h +++ b/DRAMSys/simulator/src/simulation/Dram.h @@ -268,7 +268,7 @@ struct Dram : sc_module // Here considering that DRAMPower provides the energy in pJ and the power in mW printDebugMessage(string("\tCurrent Energy: \t") + to_string(currentTotalEnergy) + string("\t[pJ]")); - printDebugMessage(string("\tAverage Power 1: \t") + to_string(currentAveragePower) + string("\t[mW]")); + printDebugMessage(string("\tAverage Power: \t") + to_string(currentAveragePower) + string("\t[mW]")); } while(true); } From 5371930f1a3ab1e1d78a2b69a97eaec4bc4d23e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Tue, 10 May 2016 15:29:15 +0200 Subject: [PATCH 4/4] This commit reverts some changes because the plots generation was broken. We may reimplement such changes in the near feature considering also the new status of DRAMSys (more specifically Dram.h) and DRAMPower. Changes introduced in the following commits were reverted: 98249947f4a1cd56f5bcab44b002771a4846664a c0f83bb1dcd22eae2d80f714722bedaa54a89598 Other changes: Upper and lower limits for some plots adjusted. --- DRAMSys/analyzer/scripts/plots.py | 56 +++++++++++++++++-------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/DRAMSys/analyzer/scripts/plots.py b/DRAMSys/analyzer/scripts/plots.py index d09bc31f..e14b32c3 100755 --- a/DRAMSys/analyzer/scripts/plots.py +++ b/DRAMSys/analyzer/scripts/plots.py @@ -22,48 +22,52 @@ def memory_utilisation_window(connection, tracePath): # Besides, extracting the data from the memory specs, it is feasible to calculate the maximum data rate of the memory and then determine the bandwidth in Gbit/s. # The bandwidth data are then plotted in two graphics. + steps = 1000 cursor = connection.cursor() - cursor.execute(""" SELECT max(time) FROM Power """) - maxTime = cursor.fetchone() - cursor.execute(""" SELECT min(time) FROM Power where time > 0 """) - windowSize = cursor.fetchone()[0] - steps = ceil(float(maxTime[0])/float(windowSize)) + cursor.execute(""" SELECT max(DataStrobeEnd) FROM Transactions """) + total = cursor.fetchone() + windowSize = ceil(float(total[0])/float(steps)) + if (windowSize == 0): + windowSize = 1 + # print(steps) # All possible cases of data transfers inside a time window queryFull = """ SELECT sum(DataStrobeEnd - DataStrobeBegin) FROM transactions Where DataStrobeBegin > ? and DataStrobeEnd < ?""" # The data transfer begins and ends inside the time window queryEnd = """ SELECT sum(DataStrobeEnd - ?) FROM transactions Where DataStrobeBegin < ? and DataStrobeEnd > ? and DataStrobeEnd <=?""" # Only the end of the data transfer is inside the time window queryBegin = """ SELECT sum(? - DataStrobeBegin) FROM transactions Where DataStrobeBegin >= ? and DataStrobeBegin < ? and DataStrobeEnd > ?""" # Only the beginning of the data transfer is inside the time window queryPart = """ SELECT DataStrobeBegin FROM transactions Where DataStrobeBegin <= ? and DataStrobeEnd >= ?""" # The data transfer occupies all the time window maxDataRate = maximum_data_rate(connection) - bandwidthPercentage = [0] * (steps+1) - bandwidth = [0] * (steps+1) - bandwidthPercentage[0] = 0 - bandwidth[0] = 0 + # print(width) + # print(clk) + # print(rate) + bandwidthPercentage = [0] * steps + bandwidth = [0] * steps for i in range(steps): - bandwidthPercentage[i+1] = 0 + # print(i) + bandwidthPercentage[i] = 0 cursor.execute(queryPart, (i*windowSize, (i+1)*windowSize)) result = cursor.fetchone() if(result is None): cursor.execute(queryFull, (i*windowSize, (i+1)*windowSize)) result = cursor.fetchone() if(result[0] is not None): - bandwidthPercentage[i+1] += int(result[0]) + bandwidthPercentage[i] += int(result[0]) # print(bandwidthPercentage[i]) cursor.execute(queryEnd, (i*windowSize, i*windowSize, i*windowSize, (i+1)*windowSize)) result = cursor.fetchone() if(result[0] is not None): - bandwidthPercentage[i+1] += int(result[0]) + bandwidthPercentage[i] += int(result[0]) # print(bandwidthPercentage[i]) cursor.execute(queryBegin, ((i+1)*windowSize, i*windowSize, (i+1)*windowSize, (i+1)*windowSize)) result = cursor.fetchone() if(result[0] is not None): - bandwidthPercentage[i+1] += int(result[0]) + bandwidthPercentage[i] += int(result[0]) # print(bandwidthPercentage[i]) else: - bandwidthPercentage[i+1] = windowSize + bandwidthPercentage[i] = windowSize # print(bandwidthPercentage[i]) - bandwidthPercentage[i+1] = float(bandwidthPercentage[i+1]/windowSize) - bandwidth[i+1] = float(bandwidthPercentage[i+1])*float(maxDataRate)/1024 - bandwidthPercentage[i+1] *= 100 + bandwidthPercentage[i] = float(bandwidthPercentage[i]/windowSize) + bandwidth[i] = float(bandwidthPercentage[i])*float(maxDataRate)/1024 + bandwidthPercentage[i] *= 100 name = ntpath.basename(tracePath) basename, extension = os.path.splitext(name) @@ -75,7 +79,8 @@ def memory_utilisation_window(connection, tracePath): import numpy as np from matplotlib.backends.backend_pdf import PdfPages - time = np.arange(0, (steps+1)*windowSize, windowSize) + time = np.arange(0, steps*windowSize, windowSize) + plt.figure() subplotIndex = 211 @@ -83,7 +88,7 @@ def memory_utilisation_window(connection, tracePath): plt.plot(time/1000, bandwidthPercentage) plt.xlabel('Time (ns)') plt.ylabel('Bandwidth (%)') - plt.ylim(0, 120) + plt.ylim(0, 100) plt.grid(True) subplotIndex += 1 @@ -105,13 +110,13 @@ def power_window(connection, tracePath): cursor = connection.cursor() cursor.execute(""" SELECT max(time) FROM Power """) maxTime = cursor.fetchone() - cursor.execute(""" SELECT min(time) FROM Power where time > 0 """) - windowSize = cursor.fetchone()[0] - steps = ceil(float(maxTime[0])/float(windowSize)) + cursor.execute(""" SELECT min(time) FROM Power WHERE time > 0""") + windowSize = cursor.fetchone() + steps = ceil(float(maxTime[0])/float(windowSize[0])) cursor.execute(""" SELECT * FROM Power """) - time = [0] * (steps+1) - power = [0] * (steps+1) - for i in range((steps+1)): + time = [0] * steps + power = [0] * steps + for i in range(steps): result = cursor.fetchone() time[i] = float(result[0]) * 1000000000 # convertion of seconds to nanoseconds power[i] = float(result[1]) # values are stored in mW @@ -128,6 +133,7 @@ def power_window(connection, tracePath): plt.plot(time, power) plt.xlabel('Time (ns)') plt.ylabel('Power (mW)') + plt.gca().set_ylim(bottom=0) plt.grid(True) pdf = PdfPages(OUTPUT_FILE) pdf.savefig()