From 4760ec4a5bcdee9f17c2bb3c06c1fd2ee2c8d1a0 Mon Sep 17 00:00:00 2001 From: robert Date: Mon, 16 Jun 2014 17:41:47 +0200 Subject: [PATCH 01/13] adressmappings --- .../resources/configs/amconfigs/am_wideio.xml | 12 +- dram/resources/configs/memconfigs/fifo.xml | 4 +- dram/resources/configs/memconfigs/fr_fcfs.xml | 4 +- dram/resources/configs/memconfigs/par_bs.xml | 13 ++ .../configs/memconfigs/par_bs_unaware.xml | 2 +- dram/resources/scripts/metrics.py | 130 ++++++++---------- dram/resources/simulations/sim-batch.xml | 14 +- dram/src/controller/scheduler/PARBS.cpp | 111 +++++++-------- 8 files changed, 153 insertions(+), 137 deletions(-) create mode 100644 dram/resources/configs/memconfigs/par_bs.xml diff --git a/dram/resources/configs/amconfigs/am_wideio.xml b/dram/resources/configs/amconfigs/am_wideio.xml index 3877cdae..24eb2a9d 100755 --- a/dram/resources/configs/amconfigs/am_wideio.xml +++ b/dram/resources/configs/amconfigs/am_wideio.xml @@ -1,6 +1,6 @@ - + + + + + + + + + + diff --git a/dram/resources/configs/memconfigs/fifo.xml b/dram/resources/configs/memconfigs/fifo.xml index d5e5fba2..37d82f94 100644 --- a/dram/resources/configs/memconfigs/fifo.xml +++ b/dram/resources/configs/memconfigs/fifo.xml @@ -4,10 +4,10 @@ - + - + diff --git a/dram/resources/configs/memconfigs/fr_fcfs.xml b/dram/resources/configs/memconfigs/fr_fcfs.xml index 9f62edef..073db719 100644 --- a/dram/resources/configs/memconfigs/fr_fcfs.xml +++ b/dram/resources/configs/memconfigs/fr_fcfs.xml @@ -4,10 +4,10 @@ - + - + diff --git a/dram/resources/configs/memconfigs/par_bs.xml b/dram/resources/configs/memconfigs/par_bs.xml new file mode 100644 index 00000000..f2b95b02 --- /dev/null +++ b/dram/resources/configs/memconfigs/par_bs.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/dram/resources/configs/memconfigs/par_bs_unaware.xml b/dram/resources/configs/memconfigs/par_bs_unaware.xml index b1f13dd1..c4c2e70e 100644 --- a/dram/resources/configs/memconfigs/par_bs_unaware.xml +++ b/dram/resources/configs/memconfigs/par_bs_unaware.xml @@ -6,7 +6,7 @@ - + diff --git a/dram/resources/scripts/metrics.py b/dram/resources/scripts/metrics.py index c84734af..8f198bfc 100644 --- a/dram/resources/scripts/metrics.py +++ b/dram/resources/scripts/metrics.py @@ -32,6 +32,12 @@ def getTraceLength(connection): result = cursor.fetchone() return result[0] +def getClock(connection): + cursor = connection.cursor() + cursor.execute("SELECT clk FROM GeneralInfo") + result = cursor.fetchone() + return result[0] + @metric def average_response_latency_in_ns(connection): cursor = connection.cursor() @@ -41,8 +47,6 @@ def average_response_latency_in_ns(connection): result = cursor.fetchone() return round(result[0],1) - - def refreshMissDecision(connection,calculatedMetrics): cursor = connection.cursor() cursor.execute("""SELECT phases.ID,PhaseBegin,PhaseEnd,TBank FROM Phases INNER JOIN transactions on transactions.id = phases.transact WHERE PhaseName='AUTO_REFRESH' """) @@ -76,51 +80,18 @@ def refreshMissDecision(connection,calculatedMetrics): totalDecisios = totalDecisios + 1 if(earliestReq[0] != earliestResp[0]): missDecisions = missDecisions + 1 - print("earliest Req: {0}| earliest Res: {1}".format(earliestReq[0], earliestResp[0])) + #print("earliest Req: {0}| earliest Res: {1}".format(earliestReq[0], earliestResp[0])) end if(totalDecisios != 0): - calculatedMetrics.append(("Total Missdecisions", missDecisions)) + #calculatedMetrics.append(("Total Missdecisions", missDecisions)) calculatedMetrics.append(("Relative Missdecisions", 1.0*missDecisions/totalDecisios)) else: calculatedMetrics.append(("Total Missdecisions", 0)) calculatedMetrics.append(("Relative Missdecisions", 0)) -# @metric -# def median_response_latency_in_ns(connection): -# cursor = connection.cursor() -# cursor.execute("""SELECT median(PhaseBegin-timeOfGeneration)/1000 FROM transactions INNER JOIN Phases -# ON phases.transact = transactions.ID WHERE PhaseName='RESP' """) -# result = cursor.fetchone() -# return round(result[0],1) - -# @metric -# def max_response_latency_in_ns(connection): -# cursor = connection.cursor() -# cursor.execute("""SELECT max(PhaseBegin-timeOfGeneration)/1000 FROM transactions INNER JOIN Phases -# ON phases.transact = transactions.ID WHERE PhaseName='RESP' """) -# result = cursor.fetchone() -# return round(result[0],1) - -# @metric -# def min_response_latency_in_ns(connection): -# cursor = connection.cursor() -# cursor.execute("""SELECT min(PhaseBegin-timeOfGeneration)/1000 FROM transactions INNER JOIN Phases -# ON phases.transact = transactions.ID WHERE PhaseName='RESP' """) -# result = cursor.fetchone() -# return round(result[0],1) - -# @metric -# def stdDev_response_latency_in_ns(connection): -# cursor = connection.cursor() -# cursor.execute("""SELECT stdev(PhaseBegin-timeOfGeneration)/1000 FROM transactions INNER JOIN Phases -# ON phases.transact = transactions.ID WHERE PhaseName='RESP' """) -# result = cursor.fetchone() -# return round(result[0],1) - - @threadMetric def average_response_latency_in_ns(connection, thread): cursor = connection.cursor() @@ -131,22 +102,37 @@ def average_response_latency_in_ns(connection, thread): result = cursor.fetchone() return round(result[0],1) -# @threadMetric -# def median_response_latency_in_ns(connection, thread): -# cursor = connection.cursor() -# query = """SELECT median(PhaseBegin-timeOfGeneration)/1000 FROM transactions INNER JOIN Phases -# ON phases.transact = transactions.ID WHERE PhaseName='RESP' AND TThread = :Thread """ +def addStallTime(times,begin,end): + time = begin + while time <= end: + if(time in times): + times[time] = times[time] + 1 + else: + times[time] = 1 + time = time + 1 -# cursor.execute(query, {"Thread": thread}) -# result = cursor.fetchone() -# return round(result[0],1) +#@threadMetric +def paralellism(connection, thread): + cursor = connection.cursor() + stalltimes = {} + query = """SELECT transactions.ID,MIN(phaseBegin)/:clk,MAX(phaseEnd)/:clk + from phases inner join transactions on phases.transact=transactions.id + where phaseName Not in ('REQ','RESP') and tthread=:Thread group by transactions.ID """ -# @metric -# def number_of_activates(connection): -# cursor = connection.cursor() -# cursor.execute("SELECT COUNT(*) FROM Phases WHERE PhaseName = 'ACT'") -# result = cursor.fetchone() -# return result[0] + cursor.execute(query, {"Thread": thread, "clk" : getClock(connection)}) + for currentRow in cursor: + addStallTime(stalltimes,currentRow[1],currentRow[2]) + para = 0 + for time in stalltimes: + para = para + stalltimes[time] + return round(para/len(stalltimes),2) + +@metric +def number_of_activates(connection): + cursor = connection.cursor() + cursor.execute("SELECT COUNT(*) FROM Phases WHERE PhaseName = 'ACT'") + result = cursor.fetchone() + return result[0] # @metric # def number_of_precharges(connection): @@ -155,12 +141,12 @@ def average_response_latency_in_ns(connection, thread): # result = cursor.fetchone() # return result[0] -# @metric -# def accesses_per_activate(connection): -# cursor = connection.cursor() -# cursor.execute("SELECT COUNT(*) FROM Phases WHERE PhaseName IN ('REQ')") -# result = cursor.fetchone() -# return round(result[0]*1.0/number_of_activates(connection),1) +@metric +def accesses_per_activate(connection): + cursor = connection.cursor() + cursor.execute("SELECT COUNT(*) FROM Phases WHERE PhaseName IN ('REQ')") + result = cursor.fetchone() + return round(result[0]*1.0/number_of_activates(connection),1) def timeInPowerStates(connection): totalTimeAllBanks = getTraceLength(connection)*getNumberOfBanks(connection) @@ -247,33 +233,31 @@ def passRatio(connection): def calculateMetrics(pathToTrace): connection = sqlite3.connect(pathToTrace) - #connection.create_aggregate("median", 1, pystaggrelite3.median) - #connection.create_aggregate("stdev", 1, pystaggrelite3.stdev) - calculatedMetrics = [] print("================================") print("Calculating metrics for {0}".format(pathToTrace)) - for metric in metrics: - res = (metric.__name__.replace("_"," "), metric(connection)) - print("{0}: {1}".format(res[0],res[1])) - calculatedMetrics.append(res) - - for thread in getThreads(connection): - for metric in threadMetrics: - res = ("Thread " + str(thread) + " " + metric.__name__.replace("_"," "), metric(connection, thread)) + if(len(getThreads(connection))==1): + for metric in metrics: + res = (metric.__name__.replace("_"," "), metric(connection)) print("{0}: {1}".format(res[0],res[1])) calculatedMetrics.append(res) - calculatedMetrics.append(("test",0)) - #calculatedMetrics.extend(passRatio(connection)) + if(len(getThreads(connection))>1): + # for thread in getThreads(connection): + # for metric in threadMetrics: + # res = ("Thread " + str(thread) + " " + metric.__name__.replace("_"," "), metric(connection, thread)) + # print("{0}: {1}".format(res[0],res[1])) + # calculatedMetrics.append(res) + calculatedMetrics.extend(passRatio(connection)) + #refreshMissDecision(connection, calculatedMetrics) + #calculatedMetrics.extend(timeInPowerStates(connection)) + #print(calculatedMetrics[-1]) + #print(calculatedMetrics[-2]) - refreshMissDecision(connection, calculatedMetrics) - print(calculatedMetrics[-1]) - print(calculatedMetrics[-2]) connection.close() return calculatedMetrics diff --git a/dram/resources/simulations/sim-batch.xml b/dram/resources/simulations/sim-batch.xml index e2ba4924..e2b1f304 100644 --- a/dram/resources/simulations/sim-batch.xml +++ b/dram/resources/simulations/sim-batch.xml @@ -10,14 +10,22 @@ fifo.xml fr_fcfs.xml + par_bs.xml - - test2.stl - + + chstone-aes_32.stl + + + mediabench-h263decode_32.stl + + + chstone-aes_32.stl + mediabench-h263decode_32.stl + diff --git a/dram/src/controller/scheduler/PARBS.cpp b/dram/src/controller/scheduler/PARBS.cpp index c5b187e0..91ddc1c9 100644 --- a/dram/src/controller/scheduler/PARBS.cpp +++ b/dram/src/controller/scheduler/PARBS.cpp @@ -18,18 +18,18 @@ using namespace std; using namespace core; PAR_BS::PAR_BS(const core::BankStates& bankstates, bool useExternalBankstates, unsigned int capsize) : - externalBankstates(bankstates), useExternalBankstates(useExternalBankstates), capsize(capsize) + externalBankstates(bankstates), useExternalBankstates(useExternalBankstates), capsize(capsize) { - if (useExternalBankstates) - { - batch = new FR_FCFS(externalBankstates, true, false); - buffer = new FR_FCFS(externalBankstates, true, false); - } - else - { - batch = new FR_FCFS(internalBankstates, true, false); - buffer = new FR_FCFS(internalBankstates, true, false); - } + if (useExternalBankstates) + { + batch = new FR_FCFS(externalBankstates, true, false); + buffer = new FR_FCFS(externalBankstates, true, false); + } + else + { + batch = new FR_FCFS(internalBankstates, true, false); + buffer = new FR_FCFS(internalBankstates, true, false); + } } PAR_BS::~PAR_BS() @@ -39,74 +39,75 @@ PAR_BS::~PAR_BS() bool PAR_BS::hasTransactionForBank(Bank bank) { - return batch->hasTransactionForBank(bank) || buffer->hasTransactionForBank(bank); + return batch->hasTransactionForBank(bank) || buffer->hasTransactionForBank(bank); } void PAR_BS::schedule(gp* payload) { - buffer->schedule(payload); + buffer->schedule(payload); } gp* PAR_BS::getTransactionForBank(Bank bank) { - sc_assert(hasTransactionForBank(bank)); + sc_assert(hasTransactionForBank(bank)); - if (batch->isEmpty()) - { - formBatch(); - sc_assert(!batch->isEmpty()); - } + if (batch->isEmpty()) + { + formBatch(); + cout << "Formed new batch at: " << sc_time_stamp() << std::endl; + sc_assert(!batch->isEmpty()); + } - //prioritize batch first - if (batch->hasTransactionForBank(bank)) - { - return batch->getTransactionForBank(bank); - } - else - { - return buffer->getTransactionForBank(bank); - } + //prioritize batch first + if (batch->hasTransactionForBank(bank)) + { + return batch->getTransactionForBank(bank); + } + else + { + return buffer->getTransactionForBank(bank); + } } void PAR_BS::popTransactionForBank(Bank bank, gp* payload) { - sc_assert(DramExtension::getExtension(payload).getBank() == bank); - buffer->popTransactionForBank(bank, payload); - batch->popTransactionForBank(bank, payload); + sc_assert(DramExtension::getExtension(payload).getBank() == bank); + buffer->popTransactionForBank(bank, payload); + batch->popTransactionForBank(bank, payload); - if (!useExternalBankstates) - { - internalBankstates.openRowInRowBuffer(bank, DramExtension::getExtension(payload).getRow()); - } + if (!useExternalBankstates) + { + internalBankstates.openRowInRowBuffer(bank, DramExtension::getExtension(payload).getRow()); + } } void PAR_BS::formBatch() { - map loads; + map loads; - for (unsigned int b = 0; b < Configuration::getInstance().NumberOfBanks; ++b) - { - Bank bank(b); - for (unsigned int i = 0; i < capsize && buffer->hasTransactionForBank(bank); i++) - { - gp* payload = buffer->popOldest(bank); - loads[DramExtension::getExtension(payload).getThread()].addTransaction(payload); - } - } + for (unsigned int b = 0; b < Configuration::getInstance().NumberOfBanks; ++b) + { + Bank bank(b); + for (unsigned int i = 0; i < capsize && buffer->hasTransactionForBank(bank); i++) + { + gp* payload = buffer->popOldest(bank); + loads[DramExtension::getExtension(payload).getThread()].addTransaction(payload); + } + } - vector sortedLoads; - for (auto& threadLoadPair : loads) - { - sortedLoads.push_back(&threadLoadPair.second); - } + vector sortedLoads; + for (auto& threadLoadPair : loads) + { + sortedLoads.push_back(&threadLoadPair.second); + } - sort(sortedLoads.begin(), sortedLoads.end(), LoadPointerComparer()); + sort(sortedLoads.begin(), sortedLoads.end(), LoadPointerComparer()); - for (auto& load : sortedLoads) - { - batch->schedule(load->getTransactions()); - } + for (auto& load : sortedLoads) + { + batch->schedule(load->getTransactions()); + } } From 96846ca4b4562df26de49668462530ed51c3c606 Mon Sep 17 00:00:00 2001 From: robert Date: Mon, 16 Jun 2014 17:45:20 +0200 Subject: [PATCH 02/13] modified gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 57b0cd3d..8bf9a499 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ /debug /release +/dram/debug +/dram/release *.tdb *.tdb-journal *.out From 2b062b86ff123011c2cac736c1357e9d63136087 Mon Sep 17 00:00:00 2001 From: robert Date: Fri, 20 Jun 2014 15:49:07 +0200 Subject: [PATCH 03/13] changed scheduler interface. Fixed bug with terminateSimulation --- dram/dramSys/dramSys.pro | 17 +-- dram/resources/configs/memconfigs/fifo.xml | 2 + dram/resources/configs/memconfigs/fr_fcfs.xml | 4 +- .../configs/memconfigs/fr_fcfs_bankwise.xml | 2 + .../configs/memconfigs/fr_fcfs_unaware.xml | 2 + .../configs/memconfigs/memconfig.xml | 2 + dram/resources/configs/memconfigs/par_bs.xml | 2 + .../configs/memconfigs/par_bs_unaware.xml | 2 + dram/resources/simulations/sim-batch.xml | 17 +-- dram/src/common/DebugManager.cpp | 31 ++-- dram/src/common/DebugManager.h | 42 +++--- dram/src/common/TlmRecorder.cpp | 131 ++++++++--------- dram/src/common/TlmRecorder.h | 14 +- dram/src/common/dramExtension.h | 2 +- dram/src/common/libDRAMPower.cpp | 8 +- dram/src/controller/Controller.h | 91 +++++------- dram/src/controller/core/ControllerCore.cpp | 18 ++- dram/src/controller/core/ControllerCore.h | 49 ++++--- dram/src/controller/core/ControllerState.cpp | 12 +- dram/src/controller/core/ControllerState.h | 6 +- .../{BankStates.cpp => RowBufferStates.cpp} | 18 +-- .../core/{BankStates.h => RowBufferStates.h} | 12 +- .../core/configuration/Configuration.h | 66 ++++----- .../core/configuration/MemSpecLoader.cpp | 48 ++++--- .../core/configuration/MemSpecLoader.h | 10 +- .../core/powerdown/PowerDownManager.cpp | 4 +- .../powerdown/PowerDownManagerBankwise.cpp | 4 +- .../powerdown/PowerDownManagerTimeout.cpp | 2 +- .../core/refresh/RefreshManager.cpp | 2 +- .../core/refresh/RefreshManagerBankwise.cpp | 2 +- .../scheduling/CommandSequenceGenerator.cpp | 4 +- dram/src/controller/scheduler/Fifo.cpp | 28 ++-- dram/src/controller/scheduler/Fifo.h | 18 +-- dram/src/controller/scheduler/Fr_Fcfs.cpp | 132 +++++++++--------- dram/src/controller/scheduler/Fr_Fcfs.h | 21 +-- dram/src/controller/scheduler/PARBS.cpp | 65 ++++----- dram/src/controller/scheduler/PARBS.h | 36 ++--- dram/src/controller/scheduler/Scheduler.h | 8 +- dram/src/simulation/Simulation.cpp | 93 +++++++----- dram/src/simulation/Simulation.h | 8 +- dram/src/simulation/SimulationManager.cpp | 2 +- dram/src/simulation/main.cpp | 1 - 42 files changed, 522 insertions(+), 516 deletions(-) rename dram/src/controller/core/{BankStates.cpp => RowBufferStates.cpp} (72%) rename dram/src/controller/core/{BankStates.h => RowBufferStates.h} (75%) diff --git a/dram/dramSys/dramSys.pro b/dram/dramSys/dramSys.pro index 128dd852..b99145ed 100644 --- a/dram/dramSys/dramSys.pro +++ b/dram/dramSys/dramSys.pro @@ -14,18 +14,9 @@ INCLUDEPATH += /opt/boost/include DEFINES += TIXML_USE_STL DEFINES += SC_INCLUDE_DYNAMIC_PROCESSES -CONFIG(release){ -DEFINES += NDEBUG -QMAKE_CXXFLAGS_RELEASE -= -O -QMAKE_CXXFLAGS_RELEASE -= -O1 -QMAKE_CXXFLAGS_RELEASE -= -O2 -QMAKE_CXXFLAGS_RELEASE *= -O3 -} - QMAKE_CXXFLAGS += -std=c++11 QMAKE_CXXFLAGS += -isystem /opt/systemc/include QMAKE_CXXFLAGS += -isystem /opt/boost/include -#QMAKE_CXXFLAGS = -Wno-unused-variable SOURCES += \ ../src/common/third_party/tinyxml2.cpp \ @@ -60,12 +51,12 @@ SOURCES += \ ../src/controller/core/ControllerState.cpp \ ../src/controller/core/ControllerCore.cpp \ ../src/controller/core/Command.cpp \ - ../src/controller/core/BankStates.cpp \ ../src/simulation/SimulationManager.cpp \ ../src/simulation/Simulation.cpp \ ../src/simulation/MemoryManager.cpp \ ../src/simulation/main.cpp \ - ../src/common/libDRAMPower.cpp + ../src/common/libDRAMPower.cpp \ + ../src/controller/core/RowBufferStates.cpp HEADERS += \ ../src/common/third_party/tinyxml2.h \ @@ -112,7 +103,6 @@ HEADERS += \ ../src/controller/core/ControllerState.h \ ../src/controller/core/ControllerCore.h \ ../src/controller/core/Command.h \ - ../src/controller/core/BankStates.h \ ../src/simulation/TracePlayer.h \ ../src/simulation/SimulationManager.h \ ../src/simulation/Simulation.h \ @@ -120,6 +110,7 @@ HEADERS += \ ../src/simulation/ISimulation.h \ ../src/simulation/Dram.h \ ../src/simulation/Arbiter.h \ - ../src/common/libDRAMPower.h + ../src/common/libDRAMPower.h \ + ../src/controller/core/RowBufferStates.h diff --git a/dram/resources/configs/memconfigs/fifo.xml b/dram/resources/configs/memconfigs/fifo.xml index 37d82f94..2e23e330 100644 --- a/dram/resources/configs/memconfigs/fifo.xml +++ b/dram/resources/configs/memconfigs/fifo.xml @@ -9,5 +9,7 @@ + + diff --git a/dram/resources/configs/memconfigs/fr_fcfs.xml b/dram/resources/configs/memconfigs/fr_fcfs.xml index 073db719..b126adb1 100644 --- a/dram/resources/configs/memconfigs/fr_fcfs.xml +++ b/dram/resources/configs/memconfigs/fr_fcfs.xml @@ -1,6 +1,6 @@ - + @@ -9,5 +9,7 @@ + + diff --git a/dram/resources/configs/memconfigs/fr_fcfs_bankwise.xml b/dram/resources/configs/memconfigs/fr_fcfs_bankwise.xml index 19993035..1c2d4e9d 100644 --- a/dram/resources/configs/memconfigs/fr_fcfs_bankwise.xml +++ b/dram/resources/configs/memconfigs/fr_fcfs_bankwise.xml @@ -9,5 +9,7 @@ + + diff --git a/dram/resources/configs/memconfigs/fr_fcfs_unaware.xml b/dram/resources/configs/memconfigs/fr_fcfs_unaware.xml index 30faa1ff..167af96e 100644 --- a/dram/resources/configs/memconfigs/fr_fcfs_unaware.xml +++ b/dram/resources/configs/memconfigs/fr_fcfs_unaware.xml @@ -9,5 +9,7 @@ + + diff --git a/dram/resources/configs/memconfigs/memconfig.xml b/dram/resources/configs/memconfigs/memconfig.xml index 19993035..1c2d4e9d 100644 --- a/dram/resources/configs/memconfigs/memconfig.xml +++ b/dram/resources/configs/memconfigs/memconfig.xml @@ -9,5 +9,7 @@ + + diff --git a/dram/resources/configs/memconfigs/par_bs.xml b/dram/resources/configs/memconfigs/par_bs.xml index f2b95b02..cae1eb9a 100644 --- a/dram/resources/configs/memconfigs/par_bs.xml +++ b/dram/resources/configs/memconfigs/par_bs.xml @@ -9,5 +9,7 @@ + + diff --git a/dram/resources/configs/memconfigs/par_bs_unaware.xml b/dram/resources/configs/memconfigs/par_bs_unaware.xml index c4c2e70e..aed501d7 100644 --- a/dram/resources/configs/memconfigs/par_bs_unaware.xml +++ b/dram/resources/configs/memconfigs/par_bs_unaware.xml @@ -9,5 +9,7 @@ + + diff --git a/dram/resources/simulations/sim-batch.xml b/dram/resources/simulations/sim-batch.xml index e2b1f304..7dff121d 100644 --- a/dram/resources/simulations/sim-batch.xml +++ b/dram/resources/simulations/sim-batch.xml @@ -8,9 +8,10 @@ am_wideio.xml - fifo.xml + par_bs.xml + @@ -18,14 +19,14 @@ chstone-aes_32.stl - - mediabench-h263decode_32.stl + + chstone-motion.stl - - chstone-aes_32.stl - mediabench-h263decode_32.stl - + + mediabench-fractal_32.stl + mediabench-epic_32.stl + diff --git a/dram/src/common/DebugManager.cpp b/dram/src/common/DebugManager.cpp index a79c245d..9d65abc9 100644 --- a/dram/src/common/DebugManager.cpp +++ b/dram/src/common/DebugManager.cpp @@ -11,41 +11,34 @@ using namespace std; void DebugManager::printDebugMessage(string sender, string message) { #ifndef NDEBUG - if (whiteList.count(sender)) - { - if (writeToConsole) - cout << " at " << sc_time_stamp() << "\t in " << sender << "\t: " << message << endl; + if (whiteList.count(sender)) + { + if (writeToConsole) + cout << " at " << sc_time_stamp() << "\t in " << sender << "\t: " << message << endl; - if (writeToFile && debugFile) - debugFile << " at " << sc_time_stamp() << " in " << sender << "\t: " << message << "\n"; - } + if (writeToFile && debugFile) + debugFile << " at " << sc_time_stamp() << " in " << sender << "\t: " << message << "\n"; + } #endif } void DebugManager::addToWhiteList(string sender) { - whiteList.insert(sender); + whiteList.insert(sender); } void DebugManager::addToWhiteList(vector senders) { - for (string sender : senders) - addToWhiteList(sender); + for (string sender : senders) + addToWhiteList(sender); } DebugManager::DebugManager() : - writeToConsole(true), writeToFile(true) + writeToConsole(true), writeToFile(true) { } -void DebugManager::setDebugFile(std::string filename) -{ - if(debugFile) - debugFile.close(); - debugFile.open(filename); -} - DebugManager::~DebugManager() { - debugFile.close(); + debugFile.close(); } diff --git a/dram/src/common/DebugManager.h b/dram/src/common/DebugManager.h index e1d6f9cd..86c10258 100644 --- a/dram/src/common/DebugManager.h +++ b/dram/src/common/DebugManager.h @@ -15,32 +15,32 @@ class DebugManager { public: - ~DebugManager(); - static inline DebugManager& getInstance() - { - static DebugManager manager; - return manager; - } + ~DebugManager(); + static inline DebugManager& getInstance() + { + static DebugManager manager; + return manager; + } - bool writeToConsole; - bool writeToFile; + bool writeToConsole; + bool writeToFile; - void printDebugMessage(std::string message, std::string sender); - - void addToWhiteList(std::string sender); - void addToWhiteList(std::vector senders); - - void setDebugFile(std::string filename); + void printDebugMessage(std::string message, std::string sender); + void openDebugFile(std::string filename) + { + if(debugFile) + debugFile.close(); + debugFile.open(filename); + } + void addToWhiteList(std::string sender); + void addToWhiteList(std::vector senders); private: + DebugManager(); + DebugManager(const DebugManager&){} - ofstream debugFile; - - DebugManager(); - DebugManager(const DebugManager&){}; - - std::set whiteList; - + ofstream debugFile; + std::set whiteList; }; #endif /* DEBUGMANAGER_H_ */ diff --git a/dram/src/common/TlmRecorder.cpp b/dram/src/common/TlmRecorder.cpp index ba7f6614..56c2cee6 100644 --- a/dram/src/common/TlmRecorder.cpp +++ b/dram/src/common/TlmRecorder.cpp @@ -12,27 +12,30 @@ using namespace std; string TlmRecorder::dbName = ""; string TlmRecorder::sqlScriptURI = ""; string TlmRecorder::senderName = "TlmRecorder"; - +bool TlmRecorder::recordingEnabled = true; // ------------- public ----------------------- TlmRecorder::TlmRecorder() : transactionIDCounter(1), recordingEndTime(SC_ZERO_TIME) { - recordedData.reserve(transactionCommitRate); - setUpTransactionTerminatingPhases(); - openDB(TlmRecorder::dbName.c_str()); - char * sErrMsg; - sqlite3_exec(db, "PRAGMA main.page_size = 4096", NULL, NULL, &sErrMsg); - sqlite3_exec(db, "PRAGMA main.cache_size=10000", NULL, NULL, &sErrMsg); - sqlite3_exec(db, "PRAGMA main.locking_mode=EXCLUSIVE", NULL, NULL, &sErrMsg); - sqlite3_exec(db, "PRAGMA main.synchronous=OFF", NULL, NULL, &sErrMsg); - sqlite3_exec(db, "PRAGMA journal_mode = OFF", NULL, NULL, &sErrMsg); + if(recordingEnabled) + { + recordedData.reserve(transactionCommitRate); + setUpTransactionTerminatingPhases(); + openDB(TlmRecorder::dbName.c_str()); + char * sErrMsg; + sqlite3_exec(db, "PRAGMA main.page_size = 4096", NULL, NULL, &sErrMsg); + sqlite3_exec(db, "PRAGMA main.cache_size=10000", NULL, NULL, &sErrMsg); + sqlite3_exec(db, "PRAGMA main.locking_mode=EXCLUSIVE", NULL, NULL, &sErrMsg); + sqlite3_exec(db, "PRAGMA main.synchronous=OFF", NULL, NULL, &sErrMsg); + sqlite3_exec(db, "PRAGMA journal_mode = OFF", NULL, NULL, &sErrMsg); - createTables(TlmRecorder::sqlScriptURI); - prepareSqlStatements(); + createTables(TlmRecorder::sqlScriptURI); + prepareSqlStatements(); - printDebugMessage("Starting new database transaction"); + printDebugMessage("Starting new database transaction"); + } } TlmRecorder::~TlmRecorder() @@ -41,74 +44,61 @@ TlmRecorder::~TlmRecorder() closeConnection(); } -void TlmRecorder::recordDummy(tlm::tlm_generic_payload& trans) -{ - // static unsigned int id = 0; - // RecordingData data(id); - - // insertTransactionInDB(data,trans); - // insertRangeInDB(id,SC_ZERO_TIME,SC_ZERO_TIME); - // for(int i=0;i<5;i++) - // { - // string phaseName("Phase " + to_string(id)); - // sqlite3_bind_text(insertPhaseStatement, 1, phaseName.c_str(), phaseName.length(), 0); - // sqlite3_bind_int64(insertPhaseStatement, 2, 0); - // sqlite3_bind_int64(insertPhaseStatement, 3, 2); - // sqlite3_bind_int(insertPhaseStatement, 4, id); - // executeSqlStatement(insertPhaseStatement); - // } - - // id++; -} - void TlmRecorder::recordPhase(tlm::tlm_generic_payload& trans, tlm::tlm_phase phase, sc_time time) { - if (currentTransactionsInSystem.count(&trans) == 0) - introduceNewTransactionToSystem(trans); - - string phaseName = phaseNameToString(phase); - string phaseBeginPrefix = "BEGIN_"; - string phaseEndPrefix = "END_"; - - if (phaseName.find(phaseBeginPrefix) != string::npos) + if(TlmRecorder::recordingEnabled) { - phaseName.erase(0, phaseBeginPrefix.length()); - assert(currentTransactionsInSystem.count(&trans) != 0); - currentTransactionsInSystem[&trans].insertPhase(phaseName,time); - } - else - { - phaseName.erase(0, phaseEndPrefix.length()); - assert(currentTransactionsInSystem.count(&trans) != 0); - currentTransactionsInSystem[&trans].setPhaseEnd(phaseName,time); - } + if (currentTransactionsInSystem.count(&trans) == 0) + introduceTransactionSystem(trans); - bool phaseTerminatesTransaction = count(transactionTerminatingPhases.begin(), - transactionTerminatingPhases.end(), phase) == 1; - if (phaseTerminatesTransaction) - removeTransactionFromDBAndInsertInDB(trans); + string phaseName = phaseNameToString(phase); + string phaseBeginPrefix = "BEGIN_"; + string phaseEndPrefix = "END_"; - recordingEndTime = time; + if (phaseName.find(phaseBeginPrefix) != string::npos) + { + phaseName.erase(0, phaseBeginPrefix.length()); + assert(currentTransactionsInSystem.count(&trans) != 0); + currentTransactionsInSystem[&trans].insertPhase(phaseName,time); + } + else + { + phaseName.erase(0, phaseEndPrefix.length()); + assert(currentTransactionsInSystem.count(&trans) != 0); + currentTransactionsInSystem[&trans].setPhaseEnd(phaseName,time); + } + + bool phaseTerminatesTransaction = count(transactionTerminatingPhases.begin(), + transactionTerminatingPhases.end(), phase) == 1; + if (phaseTerminatesTransaction) + removeTransactionFromSystem(trans); + + recordingEndTime = time; + } } void TlmRecorder::updateDataStrobe(const sc_time& begin,const sc_time& end, tlm::tlm_generic_payload& trans) { - assert(currentTransactionsInSystem.count(&trans) != 0); - currentTransactionsInSystem[&trans].timeOnDataStrobe.start = begin; - currentTransactionsInSystem[&trans].timeOnDataStrobe.end = end; + if(TlmRecorder::recordingEnabled) + { + assert(currentTransactionsInSystem.count(&trans) != 0); + currentTransactionsInSystem[&trans].timeOnDataStrobe.start = begin; + currentTransactionsInSystem[&trans].timeOnDataStrobe.end = end; + } } void TlmRecorder::recordDebugMessage(std::string message, sc_time time) { - insertDebugMessageInDB(message, time); + if(TlmRecorder::recordingEnabled) + insertDebugMessageInDB(message, time); } // ------------- internal ----------------------- -void TlmRecorder::introduceNewTransactionToSystem(tlm::tlm_generic_payload& trans) +void TlmRecorder::introduceTransactionSystem(tlm::tlm_generic_payload& trans) { unsigned int id = transactionIDCounter++; currentTransactionsInSystem[&trans].id = id; @@ -130,7 +120,7 @@ void TlmRecorder::introduceNewTransactionToSystem(tlm::tlm_generic_payload& tran } } -void TlmRecorder::removeTransactionFromDBAndInsertInDB(tlm::tlm_generic_payload& trans) +void TlmRecorder::removeTransactionFromSystem(tlm::tlm_generic_payload& trans) { assert(currentTransactionsInSystem.count(&trans) != 0); @@ -324,12 +314,15 @@ void TlmRecorder::printDebugMessage(std::string message) void TlmRecorder::closeConnection() { - commitRecordedDataToDB(); - insertGeneralInfo(); - printDebugMessage( - "Number of transactions written to DB: " + std::to_string(transactionIDCounter - 1)); - printDebugMessage("tlmPhaseRecorder:\tEnd Recording"); - sqlite3_close(db); - db = NULL; + if(TlmRecorder::recordingEnabled) + { + commitRecordedDataToDB(); + insertGeneralInfo(); + printDebugMessage( + "Number of transactions written to DB: " + std::to_string(transactionIDCounter - 1)); + printDebugMessage("tlmPhaseRecorder:\tEnd Recording"); + sqlite3_close(db); + db = NULL; + } } diff --git a/dram/src/common/TlmRecorder.h b/dram/src/common/TlmRecorder.h index 70dad21b..3a4e83bf 100755 --- a/dram/src/common/TlmRecorder.h +++ b/dram/src/common/TlmRecorder.h @@ -24,6 +24,7 @@ public: static std::string sqlScriptURI; static std::string dbName; static std::string senderName; + static bool recordingEnabled; static inline TlmRecorder& getInstance() { @@ -31,14 +32,14 @@ public: return decoder; } - void recordDummy(tlm::tlm_generic_payload& trans); + void recordMemconfig(string memconfig){this->memconfig = memconfig;} + void recordMemspec(string memspec){this->memspec = memspec;} + void recordTracenames(string traces){this->traces = traces;} + void recordPhase(tlm::tlm_generic_payload &trans, tlm::tlm_phase phase, sc_time time); 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(); - void recordMemconfig(string memconfig){this->memconfig = memconfig;} - void recordMemspec(string memspec){this->memspec = memspec;} - void recordTracenames(string traces){this->traces = traces;} private: @@ -64,7 +65,6 @@ private: void insertPhase(string name,sc_time begin); void setPhaseEnd(string name,sc_time end); - }; std::string memconfig,memspec,traces; @@ -80,8 +80,8 @@ private: void createTables(std::string pathToURI); void setUpTransactionTerminatingPhases(); - void introduceNewTransactionToSystem(tlm::tlm_generic_payload& trans); - void removeTransactionFromDBAndInsertInDB(tlm::tlm_generic_payload& trans); + void introduceTransactionSystem(tlm::tlm_generic_payload& trans); + void removeTransactionFromSystem(tlm::tlm_generic_payload& trans); void commitRecordedDataToDB(); void insertGeneralInfo(); diff --git a/dram/src/common/dramExtension.h b/dram/src/common/dramExtension.h index ef308e2b..526d659f 100644 --- a/dram/src/common/dramExtension.h +++ b/dram/src/common/dramExtension.h @@ -61,7 +61,7 @@ private: class Bank { public: - explicit Bank(unsigned int id) : + Bank(unsigned int id) : id(id) { } diff --git a/dram/src/common/libDRAMPower.cpp b/dram/src/common/libDRAMPower.cpp index 8a6ae82b..951855d4 100644 --- a/dram/src/common/libDRAMPower.cpp +++ b/dram/src/common/libDRAMPower.cpp @@ -1,5 +1,5 @@ -#include "libdrampower.h" +//#include "libdrampower.h" -libDRAMPower::libDRAMPower() -{ -} +//libDRAMPower::libDRAMPower() +//{ +//} diff --git a/dram/src/controller/Controller.h b/dram/src/controller/Controller.h index 20e347b5..90f7f5fc 100644 --- a/dram/src/controller/Controller.h +++ b/dram/src/controller/Controller.h @@ -8,16 +8,10 @@ #ifndef CONTROLLERWRAPPER_H_ #define CONTROLLERWRAPPER_H_ -//#include -//#include -//#include -//#include -//#include #include #include #include -//#include #include "/opt/systemc-2.3.0/include/systemc" #include "/opt/systemc-2.3.0/include/tlm" #include "/opt/systemc-2.3.0/include/tlm_utils/peq_with_cb_and_phase.h" @@ -59,7 +53,7 @@ public: frontendPEQ(this, &Controller::frontendPEQCallback), dramPEQ(this, &Controller::dramPEQCallback), controllerCorePEQ( this, &Controller::controllerCorePEQCallback), debugManager(DebugManager::getInstance()) { - controller = new ControllerCore(*this, numberOfPayloadsInSystem); + controllerCore = new ControllerCore(*this, numberOfPayloadsInSystem); buildScheduler(); iSocket.register_nb_transport_bw(this, &Controller::nb_transport_bw); tSocket.register_nb_transport_fw(this, &Controller::nb_transport_fw); @@ -72,31 +66,31 @@ public: if (selectedScheduler == "FR_FCFS") { - scheduler = new FR_FCFS(controller->state.bankStates, Configuration::getInstance().RefreshAwareScheduling, + scheduler = new FR_FCFS(*controllerCore, Configuration::getInstance().RefreshAwareScheduling, Configuration::getInstance().AdaptiveOpenPagePolicy); } else if (selectedScheduler == "PAR_BS") { - scheduler = new PAR_BS(controller->state.bankStates, Configuration::getInstance().RefreshAwareScheduling, + scheduler = new PAR_BS(*controllerCore, Configuration::getInstance().RefreshAwareScheduling, Configuration::getInstance().Capsize); } else if (selectedScheduler == "FIFO") - scheduler = new Fifo(); + scheduler = new Fifo(*controllerCore); else reportFatal(name(), "unsupported scheduler: " + selectedScheduler); } ~Controller() { - delete controller; + delete controllerCore; delete scheduler; } void terminateSimulation() { - for (Bank bank : controller->getBanks()) + for (Bank bank : controllerCore->getBanks()) { - controller->powerDownManager->wakeUp(bank, clkAlign(sc_time_stamp())); + controllerCore->powerDownManager->wakeUp(bank, clkAlign(sc_time_stamp())); } } @@ -129,8 +123,6 @@ public: controllerCorePEQ.notify(payload, BEGIN_WRA, command.getStart() - sc_time_stamp()); break; case Command::AutoRefresh: - TlmRecorder::getInstance().recordDummy(payload); - controllerCorePEQ.notify(payload, BEGIN_AUTO_REFRESH, command.getStart() - sc_time_stamp()); break; case Command::Activate: @@ -143,18 +135,12 @@ public: controllerCorePEQ.notify(payload, BEGIN_PRE_ALL, command.getStart() - sc_time_stamp()); break; case Command::PDNA: - TlmRecorder::getInstance().recordDummy(payload); - controllerCorePEQ.notify(payload, BEGIN_PDNA, command.getStart() - sc_time_stamp()); break; case Command::PDNP: - TlmRecorder::getInstance().recordDummy(payload); - controllerCorePEQ.notify(payload, BEGIN_PDNP, command.getStart() - sc_time_stamp()); break; case Command::SREF: - TlmRecorder::getInstance().recordDummy(payload); - controllerCorePEQ.notify(payload, BEGIN_SREF, command.getStart() - sc_time_stamp()); break; case Command::PDNAX: @@ -196,11 +182,11 @@ public: { if (phase == REF_TRIGGER) { - controller->triggerRefresh(payload, sc_time_stamp()); + controllerCore->triggerRefresh(payload, sc_time_stamp()); } else if (phase == PDN_TRIGGER) { - controller->powerDownManager->sleep(DramExtension::getExtension(payload).getBank(),sc_time_stamp()); + controllerCore->powerDownManager->sleep(DramExtension::getExtension(payload).getBank(),sc_time_stamp()); } else { @@ -208,7 +194,7 @@ public: sendToDram(payload, phase, SC_ZERO_TIME); if (phase == BEGIN_RD || phase == BEGIN_WR) - scheduleNextPayload(bank); + scheduleNextPayload(); else if (phase == BEGIN_AUTO_REFRESH) printDebugMessage("Entering auto refresh on bank " + to_string(bank.ID())); else if (isIn(phase, { BEGIN_PDNA, BEGIN_PDNP, BEGIN_SREF })) @@ -224,7 +210,7 @@ public: } private: - ControllerCore* controller; + ControllerCore* controllerCore; Scheduler* scheduler; std::map numberOfPayloadsInSystem; @@ -258,9 +244,10 @@ private: { if (phase == BEGIN_REQ) { + payload.acquire(); payloadEntersSystem(payload); - if (getTotalNumberOfPayloadsInSystem() > controller->config.MaxNrOfTransactions) + if (getTotalNumberOfPayloadsInSystem() > controllerCore->config.MaxNrOfTransactions) { printDebugMessage("##Backpressure: Max number of transactions in system reached"); backpressure = &payload; @@ -269,7 +256,7 @@ private: payload.set_response_status(tlm::TLM_OK_RESPONSE); sendToFrontend(payload, END_REQ, SC_ZERO_TIME); scheduler->schedule(&payload); - scheduleNextPayload(DramExtension::getExtension(payload).getBank()); + scheduleNextPayload(); } else if (phase == END_RESP) { @@ -279,12 +266,11 @@ private: backpressure->set_response_status(tlm::TLM_OK_RESPONSE); sendToFrontend(*backpressure, END_REQ, SC_ZERO_TIME); scheduler->schedule(backpressure); - scheduleNextPayload(DramExtension::getExtension(backpressure).getBank()); + scheduleNextPayload(); backpressure = NULL; } payloadLeavesSystem(payload); - TlmRecorder::getInstance().recordDummy(payload); payload.release(); } else @@ -309,48 +295,33 @@ private: printDebugMessage( "Payload left system on bank " + to_string(bank.ID()) + ". Total number of payloads in Controller: " + to_string(getTotalNumberOfPayloadsInSystem())); - controller->powerDownManager->triggerSleep(bank, sc_time_stamp()); - + controllerCore->powerDownManager->triggerSleep(bank, sc_time_stamp()); } unsigned int getTotalNumberOfPayloadsInSystem() { unsigned int sum = 0; - for (Bank bank : controller->getBanks()) + for (Bank bank : controllerCore->getBanks()) { sum += numberOfPayloadsInSystem[bank]; } return sum; } - void scheduleNextPayload(Bank bank) + void scheduleNextPayload() { - printDebugMessage("Triggering schedule next payload on bank " + to_string(bank.ID())); - if (scheduler->hasTransactionForBank(bank)) + if(scheduler->hasPayloads()) { - controller->powerDownManager->wakeUp(bank, sc_time_stamp()); - - if (controller->isBusy(sc_time_stamp(), bank)) + tlm_generic_payload* payload = scheduler->getNextPayload(); + if(payload != NULL) { - printDebugMessage("\t-> break: controller is busy"); - return; + controllerCore->powerDownManager->wakeUp(DramExtension::getExtension(payload).getBank(), sc_time_stamp()); + if (controllerCore->scheduleRequest(sc_time_stamp(), *payload)) + { + scheduler->removePayload(payload); + printDebugMessage("\t-> Next payload was scheduled by core"); + } } - - tlm_generic_payload* nextTransaction = scheduler->getTransactionForBank(bank); - if (controller->scheduleRequest(sc_time_stamp(), *nextTransaction)) - { - scheduler->popTransactionForBank(bank, nextTransaction); - printDebugMessage("\t-> payload was scheduled by core"); - } - else - { - printDebugMessage("\t-> break: payload was not scheduled by core (collision with refresh)"); - } - } - else - { - printDebugMessage("\t-> break: no transaction for bank"); - controller->powerDownManager->sleep(bank, sc_time_stamp()); } } @@ -376,7 +347,7 @@ private: if (phase == BEGIN_RD || phase == BEGIN_WR) { - scheduleNextPayload(bank); + scheduleNextPayload(); sendToDram(payload, phase, SC_ZERO_TIME); } else if (phase == END_RD || phase == END_WR) @@ -386,12 +357,14 @@ private: else if (phase == END_RDA || phase == END_WRA) { sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME); - scheduleNextPayload(bank); + scheduleNextPayload(); } else if (phase == END_AUTO_REFRESH) { printDebugMessage("Finished auto refresh on bank " + to_string(bank.ID())); - scheduleNextPayload(DramExtension::getExtension(payload).getBank()); + if(numberOfPayloadsInSystem[bank] == 0) + controllerCore->powerDownManager->sleep(bank,sc_time_stamp()); + scheduleNextPayload(); } else if (isIn(phase, { END_PRE, END_PRE_ALL, END_ACT })) { diff --git a/dram/src/controller/core/ControllerCore.cpp b/dram/src/controller/core/ControllerCore.cpp index 851476e9..af2491d2 100644 --- a/dram/src/controller/core/ControllerCore.cpp +++ b/dram/src/controller/core/ControllerCore.cpp @@ -94,12 +94,12 @@ void ControllerCore::resetState() void ControllerCore::triggerRefresh(tlm::tlm_generic_payload& payload, sc_time time) { Bank bank = DramExtension::getExtension(payload).getBank(); - printDebugMessage("Triggering refresh on bank " + to_string(bank.ID())); state.cleanUp(time); if (!refreshManager->isInvalidated(payload, time) && !powerDownManager->isInSelfRefresh(bank)) { + printDebugMessage("Triggering refresh on bank " + to_string(bank.ID())); powerDownManager->wakeUpForRefresh(bank, time); //expects PDNA and PDNP to exit without delay refreshManager->scheduleRefresh(payload, time); } @@ -127,7 +127,7 @@ bool ControllerCore::scheduleRequest(sc_time start, tlm::tlm_generic_payload& pa } } -bool ControllerCore::isBusy(sc_time time, Bank bank) +bool ControllerCore::bankIsBusy(sc_time time, Bank bank) { ScheduledCommand lastScheduledCommand = state.getLastScheduledCommand(bank); @@ -158,9 +158,10 @@ bool ControllerCore::isBusy(sc_time time, Bank bank) } -const std::vector& ControllerCore::getBanks() const +const std::vector& ControllerCore::getBanks() { static std::vector banks; + if (banks.size() == 0) { for (unsigned int i = 0; i < config.NumberOfBanks; i++) @@ -172,6 +173,17 @@ const std::vector& ControllerCore::getBanks() const return banks; } +std::vector ControllerCore::getFreeBanks(sc_time currentTime) +{ + std::vector freeBanks; + for(Bank bank: getBanks()) + { + if(!bankIsBusy(currentTime, bank)) + freeBanks.push_back(bank); + } + return freeBanks; +} + void ControllerCore::send(const CommandSchedule& schedule, tlm::tlm_generic_payload& payload) const { for (const ScheduledCommand& cmd : schedule.getScheduledCommands()) diff --git a/dram/src/controller/core/ControllerCore.h b/dram/src/controller/core/ControllerCore.h index f47a9c29..a0bcd3a6 100644 --- a/dram/src/controller/core/ControllerCore.h +++ b/dram/src/controller/core/ControllerCore.h @@ -24,40 +24,39 @@ namespace core { class ControllerCore { public: - ControllerCore(IWrapperConnector& wrapper, std::map& numberOfPayloads); - virtual ~ControllerCore() ; + ControllerCore(IWrapperConnector& wrapper, std::map& numberOfPayloads); + virtual ~ControllerCore() ; - bool isBusy(sc_time currentTime, Bank bank); - bool scheduleRequest(sc_time currentTime, tlm::tlm_generic_payload& payload); - void triggerRefresh(tlm::tlm_generic_payload& payload, sc_time time); - void triggerWakeUp(tlm::tlm_generic_payload& payload, sc_time time); + bool bankIsBusy(sc_time currentTime, Bank bank); + bool scheduleRequest(sc_time currentTime, tlm::tlm_generic_payload& payload); + void triggerRefresh(tlm::tlm_generic_payload& payload, sc_time time); - const BankStates& getBankStates(){return state.bankStates;} - - void saveState(); - void resetState(); + void saveState(); + void resetState(); - const std::vector& getBanks() const;//TODO put in config? + const std::vector& getBanks(); + std::vector getFreeBanks(sc_time currentTime); + const RowBufferState& getRowBufferStates(){return state.rowBufferStates;} - void send(const CommandSchedule& schedule, tlm::tlm_generic_payload& payload) const; - ICommandChecker& getCommandChecker(Command command); + void send(const CommandSchedule& schedule, tlm::tlm_generic_payload& payload) const; + ICommandChecker& getCommandChecker(Command command); - Configuration config; - ControllerState state; - IWrapperConnector& wrapper; + Configuration config; + ControllerState state; + IWrapperConnector& wrapper; - IPowerDownManager* powerDownManager; - IRefreshManager* refreshManager; - std::map& numberOfPayloads; - static std::string senderName; - static void printDebugMessage(string message); + IPowerDownManager* powerDownManager; + IRefreshManager* refreshManager; + std::map& numberOfPayloads; + static std::string senderName; + static void printDebugMessage(string message); private: - std::map commandChecker; - ControllerState savedState; - CommandSequenceGenerator commandSequenceGenerator; - CommandSequenceScheduler commandSequenceScheduler; + std::map commandChecker; + ControllerState savedState; + CommandSequenceGenerator commandSequenceGenerator; + CommandSequenceScheduler commandSequenceScheduler; }; } /* namespace controller */ diff --git a/dram/src/controller/core/ControllerState.cpp b/dram/src/controller/core/ControllerState.cpp index 702fc954..4c27f6a5 100644 --- a/dram/src/controller/core/ControllerState.cpp +++ b/dram/src/controller/core/ControllerState.cpp @@ -79,30 +79,30 @@ void ControllerState::change(const ScheduledCommand& scheduledCommand) lastDataStrobeCommands.emplace_back(scheduledCommand); break; case Command::ReadA: - bankStates.closeRowBuffer(scheduledCommand.getBank()); + rowBufferStates.closeRowBuffer(scheduledCommand.getBank()); lastDataStrobeCommands.emplace_back(scheduledCommand); break; case Command::Write: lastDataStrobeCommands.emplace_back(scheduledCommand); break; case Command::WriteA: - bankStates.closeRowBuffer(scheduledCommand.getBank()); + rowBufferStates.closeRowBuffer(scheduledCommand.getBank()); lastDataStrobeCommands.emplace_back(scheduledCommand); break; case Command::AutoRefresh: break; case Command::Activate: - bankStates.openRowInRowBuffer(scheduledCommand.getBank(), scheduledCommand.getRow()); + rowBufferStates.openRowInRowBuffer(scheduledCommand.getBank(), scheduledCommand.getRow()); lastActivates.emplace(scheduledCommand.getStart(), scheduledCommand.getBank()); break; case Command::Precharge: - bankStates.closeRowBuffer(scheduledCommand.getBank()); + rowBufferStates.closeRowBuffer(scheduledCommand.getBank()); break; case Command::PrechargeAll: - bankStates.closeAllRowBuffers(); + rowBufferStates.closeAllRowBuffers(); break; case Command::SREF: - bankStates.closeRowBuffer(scheduledCommand.getBank()); + rowBufferStates.closeRowBuffer(scheduledCommand.getBank()); break; default: break; diff --git a/dram/src/controller/core/ControllerState.h b/dram/src/controller/core/ControllerState.h index f6a61f0a..259434af 100644 --- a/dram/src/controller/core/ControllerState.h +++ b/dram/src/controller/core/ControllerState.h @@ -9,7 +9,7 @@ #define CONTROLLER_STATE_H_ #include -#include "BankStates.h" +#include "RowBufferStates.h" #include "scheduling/ScheduledCommand.h" #include "Slots.h" #include "configuration/Configuration.h" @@ -23,7 +23,7 @@ class ControllerState { public: ControllerState(Configuration* config) : - bankStates(), bus(config->Timings.clk), config(config) + rowBufferStates(), bus(config->Timings.clk), config(config) { } virtual ~ControllerState() @@ -38,7 +38,7 @@ public: void change(const ScheduledCommand& scheduledCommand); void cleanUp(sc_time time); - BankStates bankStates; + RowBufferState rowBufferStates; //used by the various checkers std::map > lastScheduledByCommandAndBank; diff --git a/dram/src/controller/core/BankStates.cpp b/dram/src/controller/core/RowBufferStates.cpp similarity index 72% rename from dram/src/controller/core/BankStates.cpp rename to dram/src/controller/core/RowBufferStates.cpp index d6af44ee..7202288c 100644 --- a/dram/src/controller/core/BankStates.cpp +++ b/dram/src/controller/core/RowBufferStates.cpp @@ -5,7 +5,7 @@ * Author: robert */ -#include "BankStates.h" +#include "RowBufferStates.h" #include "ControllerCore.h" #include "../../common/DebugManager.h" #include "../../common/Utils.h" @@ -15,38 +15,38 @@ using namespace std; namespace core { -BankStates::BankStates() +RowBufferState::RowBufferState() { closeAllRowBuffers(); } -BankStates::~BankStates() +RowBufferState::~RowBufferState() { } -bool BankStates::rowBufferIsOpen(Bank bank) const +bool RowBufferState::rowBufferIsOpen(Bank bank) const { return getElementFromMap(rowsInRowBuffers,bank) != Row::NO_ROW; } -Row BankStates::getRowInRowBuffer(Bank bank) const +Row RowBufferState::getRowInRowBuffer(Bank bank) const { return getElementFromMap(rowsInRowBuffers,bank); } -void BankStates::openRowInRowBuffer(Bank bank,Row row) +void RowBufferState::openRowInRowBuffer(Bank bank,Row row) { DebugManager::getInstance().printDebugMessage(ControllerCore::senderName, "Row buffer for bank " + to_string(bank.ID()) + " is now open"); rowsInRowBuffers[bank] = row; } -void BankStates::closeRowBuffer(Bank bank) +void RowBufferState::closeRowBuffer(Bank bank) { DebugManager::getInstance().printDebugMessage(ControllerCore::senderName, "Row buffer for bank " + to_string(bank.ID()) + " is now closed"); rowsInRowBuffers[bank] = Row::NO_ROW; } -bool BankStates::allRowBuffersAreClosed() const +bool RowBufferState::allRowBuffersAreClosed() const { for(unsigned int i=0; i #include "../../common/dramExtension.h" namespace core { -class BankStates { +class RowBufferState { public: - BankStates(); - virtual ~BankStates(); + RowBufferState(); + virtual ~RowBufferState(); bool rowBufferIsOpen(Bank bank) const; bool allRowBuffersAreClosed() const; diff --git a/dram/src/controller/core/configuration/Configuration.h b/dram/src/controller/core/configuration/Configuration.h index ce9567c2..25709dca 100644 --- a/dram/src/controller/core/configuration/Configuration.h +++ b/dram/src/controller/core/configuration/Configuration.h @@ -20,48 +20,48 @@ enum class PowerDownMode{Staggered, TimeoutPDN, TimeoutSREF}; struct Configuration { - static std::string memspecUri; - static std::string memconfigUri; + static std::string memspecUri; + static std::string memconfigUri; - static inline Configuration& getInstance() - { - static Configuration configuration; - return configuration; - } + static inline Configuration& getInstance() + { + static Configuration configuration; + return configuration; + } - std::string MemoryId; - std::string MemoryType; + //MemConfiguration + bool BankwiseLogic; + bool OpenPagePolicy; + bool AdaptiveOpenPagePolicy; + bool RefreshAwareScheduling; + unsigned int MaxNrOfTransactions; + std::string Scheduler; + unsigned int Capsize; - //MemSpecification - unsigned int NumberOfBanks; - unsigned int NumberOfBankGroups; - unsigned int BurstLength; - unsigned int nActivate; - unsigned int DataRate; - unsigned int NumberOfRows; + bool databaseRecordingEnabled; + //MemSpecification + std::string MemoryId; + std::string MemoryType; - // Powerdown Mode - sc_time powerDownTimeout; - PowerDownMode powerDownMode; + unsigned int NumberOfBanks; + unsigned int NumberOfBankGroups; + unsigned int BurstLength; + unsigned int nActivate; + unsigned int DataRate; + unsigned int NumberOfRows; + bool recordingIsEnabled; - //MemTimings - TimingConfiguration Timings; - - //MemConfiguration - bool BankwiseLogic; - bool OpenPagePolicy; - bool AdaptiveOpenPagePolicy; - bool RefreshAwareScheduling; - unsigned int MaxNrOfTransactions; - std::string Scheduler; - unsigned int Capsize; - - const std::vector& getBanks() const; + // Powerdown Mode + sc_time powerDownTimeout; + PowerDownMode powerDownMode; + //MemTimings + TimingConfiguration Timings; + const std::vector& getBanks() const; private: - Configuration(); + Configuration(); }; } /* namespace core */ diff --git a/dram/src/controller/core/configuration/MemSpecLoader.cpp b/dram/src/controller/core/configuration/MemSpecLoader.cpp index 98cfc39d..21536582 100644 --- a/dram/src/controller/core/configuration/MemSpecLoader.cpp +++ b/dram/src/controller/core/configuration/MemSpecLoader.cpp @@ -16,35 +16,20 @@ namespace core { void MemSpecLoader::loadConfiguration(Configuration& config, string memspecUri, string memconfigUri) { tinyxml2::XMLDocument doc; + loadXML(memspecUri, doc); - XMLElement* memspec = doc.FirstChildElement("memspec"); - config.MemoryId = queryStringParameter(memspec, "memoryId"); - config.MemoryType = queryStringParameter(memspec, "memoryType"); - - if (config.MemoryType == "DDR4") - { - loadDDR4(config, memspec); - } - else if (config.MemoryType == "WIDEIO_SDR") - { - loadWideIO(config, memspec); - } - else - { - reportFatal("ConfigurationLoader", "Unsupported Configuration"); - } + loadMemSpec(config, memspec); loadXML(memconfigUri, doc); - memspec = doc.FirstChildElement("memspec"); - loadConfig(config, memspec); - + XMLElement* memconfig = doc.FirstChildElement("memspec"); + loadMemConfig(config, memconfig); } -void MemSpecLoader::loadConfig(Configuration& config, XMLElement* memspec) +void MemSpecLoader::loadMemConfig(Configuration& config, XMLElement* memconfig) { //MemConfiguration - XMLElement* configuration = memspec->FirstChildElement("memconfig"); + XMLElement* configuration = memconfig->FirstChildElement("memconfig"); config.BankwiseLogic = queryBoolParameter(configuration, "bankwiseLogic"); config.OpenPagePolicy = queryBoolParameter(configuration, "openPagePolicy"); @@ -68,6 +53,27 @@ void MemSpecLoader::loadConfig(Configuration& config, XMLElement* memspec) config.powerDownMode = PowerDownMode::TimeoutSREF; } config.powerDownTimeout = queryUIntParameter(configuration, "powerDownTimeout") * config.Timings.clk; + + config.databaseRecordingEnabled = queryBoolParameter(configuration, "databaseRecordingEnabled"); +} + +void MemSpecLoader::loadMemSpec(Configuration& config, XMLElement* memspec) +{ + config.MemoryId = queryStringParameter(memspec, "memoryId"); + config.MemoryType = queryStringParameter(memspec, "memoryType"); + + if (config.MemoryType == "DDR4") + { + loadDDR4(config, memspec); + } + else if (config.MemoryType == "WIDEIO_SDR") + { + loadWideIO(config, memspec); + } + else + { + reportFatal("ConfigurationLoader", "Unsupported DRAM type"); + } } void MemSpecLoader::loadDDR4(Configuration& config, XMLElement* memspec) diff --git a/dram/src/controller/core/configuration/MemSpecLoader.h b/dram/src/controller/core/configuration/MemSpecLoader.h index 415eb04c..7653075e 100644 --- a/dram/src/controller/core/configuration/MemSpecLoader.h +++ b/dram/src/controller/core/configuration/MemSpecLoader.h @@ -18,13 +18,13 @@ namespace core { class MemSpecLoader { public: - void loadConfiguration(Configuration& config, std::string memspec, std::string memconfig); + void loadConfiguration(Configuration& config, std::string memspecUri, std::string memconfigUri); private: - void loadDDR4(Configuration& config, tinyxml2::XMLElement* memspec); - void loadWideIO(Configuration& config, tinyxml2::XMLElement* memspec); - - void loadConfig(Configuration& config, tinyxml2::XMLElement* memspec); + void loadMemConfig(Configuration& config, tinyxml2::XMLElement* memspec); + void loadMemSpec(Configuration& config, tinyxml2::XMLElement* memspec); + void loadDDR4(Configuration& config, tinyxml2::XMLElement* memspec); + void loadWideIO(Configuration& config, tinyxml2::XMLElement* memspec); }; } /* namespace core */ diff --git a/dram/src/controller/core/powerdown/PowerDownManager.cpp b/dram/src/controller/core/powerdown/PowerDownManager.cpp index ab4a8a66..687b22cd 100644 --- a/dram/src/controller/core/powerdown/PowerDownManager.cpp +++ b/dram/src/controller/core/powerdown/PowerDownManager.cpp @@ -43,11 +43,11 @@ void PowerDownManager::sleep(Bank bank, sc_time time) if (state == PowerDownState::Awake) //coming from active { - state = controller.state.bankStates.allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive; + state = controller.state.rowBufferStates.allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive; } else if (state == PowerDownState::AwakeForRefresh) //coming from refresh interrupting power down { - sc_assert(controller.state.bankStates.allRowBuffersAreClosed()); + sc_assert(controller.state.rowBufferStates.allRowBuffersAreClosed()); if (controller.state.getLastCommand(Command::PDNA).getStart() >= controller.state.getLastCommand(Command::PDNP).getStart()) diff --git a/dram/src/controller/core/powerdown/PowerDownManagerBankwise.cpp b/dram/src/controller/core/powerdown/PowerDownManagerBankwise.cpp index 41746b22..db1448e9 100644 --- a/dram/src/controller/core/powerdown/PowerDownManagerBankwise.cpp +++ b/dram/src/controller/core/powerdown/PowerDownManagerBankwise.cpp @@ -36,11 +36,11 @@ void PowerDownManagerBankwise::sleep(Bank bank, sc_time time) PowerDownState state = powerDownStates[bank]; if (state == PowerDownState::Awake) //coming from active { - state = controller.state.bankStates.rowBufferIsOpen(bank) ? PowerDownState::PDNActive : PowerDownState::PDNPrecharge; + state = controller.state.rowBufferStates.rowBufferIsOpen(bank) ? PowerDownState::PDNActive : PowerDownState::PDNPrecharge; } else if (state == PowerDownState::AwakeForRefresh) //coming from refresh interrupting power down { - sc_assert(!controller.state.bankStates.rowBufferIsOpen(bank)); + sc_assert(!controller.state.rowBufferStates.rowBufferIsOpen(bank)); if (controller.state.getLastCommand(Command::PDNA, bank).getStart() >= controller.state.getLastCommand(Command::PDNP, bank).getStart()) diff --git a/dram/src/controller/core/powerdown/PowerDownManagerTimeout.cpp b/dram/src/controller/core/powerdown/PowerDownManagerTimeout.cpp index 9248f6ce..4a3d14f4 100644 --- a/dram/src/controller/core/powerdown/PowerDownManagerTimeout.cpp +++ b/dram/src/controller/core/powerdown/PowerDownManagerTimeout.cpp @@ -34,7 +34,7 @@ void PowerDownManagerTimeout::sleep(Bank bank, sc_time time) PowerDownState newState; if(Configuration::getInstance().powerDownMode == PowerDownMode::TimeoutPDN) { - newState = controller.state.bankStates.allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive; + newState = controller.state.rowBufferStates.allRowBuffersAreClosed() ? PowerDownState::PDNPrecharge : PowerDownState::PDNActive; } else { diff --git a/dram/src/controller/core/refresh/RefreshManager.cpp b/dram/src/controller/core/refresh/RefreshManager.cpp index 8d51e0ab..d46c147b 100644 --- a/dram/src/controller/core/refresh/RefreshManager.cpp +++ b/dram/src/controller/core/refresh/RefreshManager.cpp @@ -40,7 +40,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time { sc_assert(!isInvalidated(payload, time)); - if (!controller.state.bankStates.allRowBuffersAreClosed()) + if (!controller.state.rowBufferStates.allRowBuffersAreClosed()) { ScheduledCommand precharge(Command::PrechargeAll, time, getExecutionTime(Command::PrechargeAll, refreshPayloads[Bank(0)]), DramExtension::getExtension(refreshPayloads[Bank(0)])); diff --git a/dram/src/controller/core/refresh/RefreshManagerBankwise.cpp b/dram/src/controller/core/refresh/RefreshManagerBankwise.cpp index 7147ad9b..9ee29abd 100644 --- a/dram/src/controller/core/refresh/RefreshManagerBankwise.cpp +++ b/dram/src/controller/core/refresh/RefreshManagerBankwise.cpp @@ -49,7 +49,7 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload& payload, DramExtension& extension = DramExtension::getExtension(refreshPayload); - if (controller.state.bankStates.rowBufferIsOpen(extension.getBank())) + if (controller.state.rowBufferStates.rowBufferIsOpen(extension.getBank())) { ScheduledCommand precharge(Command::Precharge, time, getExecutionTime(Command::Precharge, refreshPayload), extension); diff --git a/dram/src/controller/core/scheduling/CommandSequenceGenerator.cpp b/dram/src/controller/core/scheduling/CommandSequenceGenerator.cpp index bab728b3..b4800f7d 100644 --- a/dram/src/controller/core/scheduling/CommandSequenceGenerator.cpp +++ b/dram/src/controller/core/scheduling/CommandSequenceGenerator.cpp @@ -21,11 +21,11 @@ CommandSequence CommandSequenceGenerator::generateCommandSequence(tlm::tlm_gener CommandSequence result; - if (!controllerState.bankStates.rowBufferIsOpen(bank)) + if (!controllerState.rowBufferStates.rowBufferIsOpen(bank)) { return getBankMissCommandSequence(transaction); } - else if (controllerState.bankStates.getRowInRowBuffer(bank) != row) + else if (controllerState.rowBufferStates.getRowInRowBuffer(bank) != row) { return getRowMissCommandSequence(transaction); } diff --git a/dram/src/controller/scheduler/Fifo.cpp b/dram/src/controller/scheduler/Fifo.cpp index b89648f6..7bd32192 100644 --- a/dram/src/controller/scheduler/Fifo.cpp +++ b/dram/src/controller/scheduler/Fifo.cpp @@ -10,28 +10,34 @@ namespace scheduler { -bool Fifo::hasTransactionForBank(Bank bank) +bool Fifo::hasPayloads() { - return !buffer[bank].empty(); + return numberOfQueuedPayloads > 0; } void Fifo::schedule(gp* payload) { - buffer[DramExtension::getExtension(payload).getBank()].push_back(payload); + buffer[DramExtension::getExtension(payload).getBank()].push_back(payload); + numberOfQueuedPayloads++; } -gp* Fifo::getTransactionForBank(Bank bank) +gp* Fifo::getNextPayload() { - sc_assert(hasTransactionForBank(bank)); - gp* result = buffer[bank].front(); - return result; + for(Bank bank: controllerCore.getFreeBanks(sc_time_stamp())) + { + if(!buffer[bank].empty()) + { + return buffer[bank].front(); + } + } + + return NULL; } -void Fifo::popTransactionForBank(Bank bank, gp* payload) +void Fifo::removePayload(gp* payload) { - sc_assert(DramExtension::getExtension(payload).getBank() == bank); - - buffer[bank].pop_front(); + buffer[DramExtension::getExtension(payload).getBank()].pop_front(); + numberOfQueuedPayloads--; } } /* namespace scheduler */ diff --git a/dram/src/controller/scheduler/Fifo.h b/dram/src/controller/scheduler/Fifo.h index c1f17689..16be709b 100644 --- a/dram/src/controller/scheduler/Fifo.h +++ b/dram/src/controller/scheduler/Fifo.h @@ -19,18 +19,20 @@ namespace scheduler { class Fifo : public Scheduler { public: - Fifo() - {} - virtual ~Fifo() - {} + Fifo(core::ControllerCore &controllerCore) : controllerCore(controllerCore), numberOfQueuedPayloads(0) + {} + virtual ~Fifo() + {} - virtual bool hasTransactionForBank(Bank bank) override; + virtual bool hasPayloads() override; virtual void schedule(gp* payload) override; - virtual gp* getTransactionForBank(Bank bank) override; - virtual void popTransactionForBank(Bank bank, gp* payload) override; + virtual gp* getNextPayload() override; + virtual void removePayload(gp* payload) override; private: - std::map> buffer; + std::map> buffer; + core::ControllerCore &controllerCore; + unsigned int numberOfQueuedPayloads; }; } /* namespace scheduler */ diff --git a/dram/src/controller/scheduler/Fr_Fcfs.cpp b/dram/src/controller/scheduler/Fr_Fcfs.cpp index 76e4f355..2f887c6b 100644 --- a/dram/src/controller/scheduler/Fr_Fcfs.cpp +++ b/dram/src/controller/scheduler/Fr_Fcfs.cpp @@ -8,9 +8,9 @@ using namespace core; namespace scheduler { -FR_FCFS::FR_FCFS(const core::BankStates& bankstates, bool useExternalStates, bool adaptiveOpenPage) : - externalBankstates(bankstates), useExternalStates(useExternalStates), adaptiveOpenPage( - adaptiveOpenPage) +FR_FCFS::FR_FCFS(core::ControllerCore& controllerCore, bool useExternalStates, bool adaptiveOpenPage) : + controllerCore(controllerCore), useExternalStates(useExternalStates), adaptiveOpenPage( + adaptiveOpenPage), numberOfQueuedPayloads(0) { } @@ -18,101 +18,99 @@ FR_FCFS::~FR_FCFS() { } -bool FR_FCFS::hasTransactionForBank(Bank bank) +bool FR_FCFS::hasPayloads() { - return !buffer[bank].empty(); + return numberOfQueuedPayloads > 0; } -bool FR_FCFS::isEmpty() -{ - for(unsigned int i = 0; i < Configuration::getInstance().NumberOfBanks;++i) - { - if(!buffer[Bank(i)].empty()) - return false; - } - return true; -} - void FR_FCFS::schedule(gp* payload) { - buffer[DramExtension::getExtension(payload).getBank()].emplace_back(payload); + buffer[DramExtension::getExtension(payload).getBank()].emplace_back(payload); + numberOfQueuedPayloads++; } void FR_FCFS::schedule(std::vector payloads) { - for(gp* payload: payloads) - schedule(payload); + for(gp* payload: payloads) + schedule(payload); } -gp* FR_FCFS::getTransactionForBank(Bank bank) +gp* FR_FCFS::getNextPayload() { - sc_assert(hasTransactionForBank(bank)); + for(Bank bank: controllerCore.getFreeBanks(sc_time_stamp())) + { + if(!buffer[bank].empty()) + { + Row openRowOnBank = (useExternalStates) ? controllerCore.getRowBufferStates().getRowInRowBuffer(bank) : internalBankstates.getRowInRowBuffer(bank); + auto rowHits = findRowHits(bank, openRowOnBank); + gp* result = rowHits.empty() ? buffer[bank].front() : rowHits.front(); - Row openRowOnBank = (useExternalStates) ? externalBankstates.getRowInRowBuffer(bank) : internalBankstates.getRowInRowBuffer(bank); - auto rowHits = findRowHits(bank, openRowOnBank); - gp* result = rowHits.empty() ? buffer[bank].front() : rowHits.front(); + if (!adaptiveOpenPage) + { + return result; + } + else + { + rowHits = findRowHits(bank, DramExtension::getExtension(result).getRow()); + //other row hits are still in buffer, leave page open + if (rowHits.size() > 1) + Configuration::getInstance().OpenPagePolicy = true; + else + Configuration::getInstance().OpenPagePolicy = false; - if (!adaptiveOpenPage) - { - return result; - } - else - { - rowHits = findRowHits(bank, DramExtension::getExtension(result).getRow()); - //other row hits are still in buffer, leave page open - if (rowHits.size() > 1) - Configuration::getInstance().OpenPagePolicy = true; - else - Configuration::getInstance().OpenPagePolicy = false; + //other row hits are still in buffer, leave page open + if(findRowHits(bank,DramExtension::getExtension(result).getRow()).size() > 1) + Configuration::getInstance().OpenPagePolicy = true; + else + Configuration::getInstance().OpenPagePolicy = false; - //other row hits are still in buffer, leave page open -// if(findRowHits(bank,DramExtension::getExtension(result).getRow()).size() > 1) -// Configuration::getInstance().OpenPagePolicy = true; -// else -// Configuration::getInstance().OpenPagePolicy = false; + //no other hit in buffer, but row miss is waiting + if(findRowHits(bank,DramExtension::getExtension(result).getRow()).size() == 1 && buffer[bank].size() > 2 ) + Configuration::getInstance().OpenPagePolicy = false; + else + Configuration::getInstance().OpenPagePolicy = true; + return result; + } -//no other hit in buffer, but row miss is waiting -// if(findRowHits(bank,DramExtension::getExtension(result).getRow()).size() == 1 && buffer[bank].size() > 2 ) -// Configuration::getInstance().OpenPagePolicy = false; -// else -// Configuration::getInstance().OpenPagePolicy = true; - - return result; - } + } + } + return NULL; } gp* FR_FCFS::popOldest(Bank bank) { - sc_assert(hasTransactionForBank(bank)); - - gp* result = buffer[bank].front(); - buffer[bank].pop_front(); - return result; + if(buffer[bank].empty()) + return NULL; + gp* result = buffer[bank].front(); + buffer[bank].pop_front(); + numberOfQueuedPayloads--; + return result; } std::vector FR_FCFS::findRowHits(Bank bank, Row row) { - vector found; - for (gp* payload : buffer[bank]) - { - if (DramExtension::getExtension(payload).getRow() == row) - found.push_back(payload); - } - return found; + vector found; + for (gp* payload : buffer[bank]) + { + if (DramExtension::getExtension(payload).getRow() == row) + found.push_back(payload); + } + return found; } -void FR_FCFS::popTransactionForBank(Bank bank, gp* payload) +void FR_FCFS::removePayload(gp* payload) { - sc_assert(DramExtension::getExtension(payload).getBank() == bank); + Bank bank = DramExtension::getExtension(payload).getBank(); + buffer[bank].remove(payload); - buffer[bank].remove(payload); + if (!useExternalStates) + { + internalBankstates.openRowInRowBuffer(bank, DramExtension::getExtension(payload).getRow()); + } - if (!useExternalStates) - { - internalBankstates.openRowInRowBuffer(bank, DramExtension::getExtension(payload).getRow()); - } + numberOfQueuedPayloads--; } } diff --git a/dram/src/controller/scheduler/Fr_Fcfs.h b/dram/src/controller/scheduler/Fr_Fcfs.h index 8e166b51..3f4c5105 100644 --- a/dram/src/controller/scheduler/Fr_Fcfs.h +++ b/dram/src/controller/scheduler/Fr_Fcfs.h @@ -12,13 +12,13 @@ namespace scheduler { class FR_FCFS : public Scheduler { public: - FR_FCFS(const core::BankStates& bankstates, bool refreshAware, bool adaptiveOpenPage); - virtual ~FR_FCFS(); + FR_FCFS(core::ControllerCore& controllerCore, bool refreshAware, bool adaptiveOpenPage); + virtual ~FR_FCFS(); - virtual bool hasTransactionForBank(Bank bank) override; + virtual bool hasPayloads() override; virtual void schedule(gp* payload) override; - virtual gp* getTransactionForBank(Bank bank) override; - virtual void popTransactionForBank(Bank bank, gp* payload) override; + virtual gp* getNextPayload() override; + virtual void removePayload(gp* payload) override; //used by PAR_BS void schedule (std::vector payloads); @@ -27,11 +27,12 @@ public: private: std::vector findRowHits(Bank bank, Row row); - std::map> buffer; - const core::BankStates& externalBankstates; - core::BankStates internalBankstates; - bool useExternalStates; - bool adaptiveOpenPage; + std::map> buffer; + core::ControllerCore& controllerCore; + core::RowBufferState internalBankstates; + bool useExternalStates; + bool adaptiveOpenPage; + unsigned int numberOfQueuedPayloads; }; } /* namespace scheduler */ diff --git a/dram/src/controller/scheduler/PARBS.cpp b/dram/src/controller/scheduler/PARBS.cpp index 91ddc1c9..70e9e98e 100644 --- a/dram/src/controller/scheduler/PARBS.cpp +++ b/dram/src/controller/scheduler/PARBS.cpp @@ -1,9 +1,9 @@ -/* - * PARBS.cpp - * - * Created on: Apr 9, 2014 - * Author: robert - */ + +// * PARBS.cpp +// * +// * Created on: Apr 9, 2014 +// * Author: robert +// */ #include "PARBS.h" #include "../core/configuration/Configuration.h" @@ -17,18 +17,18 @@ namespace scheduler { using namespace std; using namespace core; -PAR_BS::PAR_BS(const core::BankStates& bankstates, bool useExternalBankstates, unsigned int capsize) : - externalBankstates(bankstates), useExternalBankstates(useExternalBankstates), capsize(capsize) +PAR_BS::PAR_BS(core::ControllerCore& controllerCore, bool useExternalBankstates, unsigned int capsize) : + controllerCore(controllerCore), useExternalBankstates(useExternalBankstates), capsize(capsize) { if (useExternalBankstates) { - batch = new FR_FCFS(externalBankstates, true, false); - buffer = new FR_FCFS(externalBankstates, true, false); + batch = new FR_FCFS(controllerCore, true, false); + buffer = new FR_FCFS(controllerCore, true, false); } else { - batch = new FR_FCFS(internalBankstates, true, false); - buffer = new FR_FCFS(internalBankstates, true, false); + batch = new FR_FCFS(controllerCore, true, false); + buffer = new FR_FCFS(controllerCore, true, false); } } @@ -37,9 +37,9 @@ PAR_BS::~PAR_BS() } -bool PAR_BS::hasTransactionForBank(Bank bank) +bool PAR_BS::hasPayloads() { - return batch->hasTransactionForBank(bank) || buffer->hasTransactionForBank(bank); + return batch->hasPayloads() || buffer->hasPayloads(); } void PAR_BS::schedule(gp* payload) @@ -47,37 +47,31 @@ void PAR_BS::schedule(gp* payload) buffer->schedule(payload); } -gp* PAR_BS::getTransactionForBank(Bank bank) +gp* PAR_BS::getNextPayload() { - sc_assert(hasTransactionForBank(bank)); - - if (batch->isEmpty()) + if (!batch->hasPayloads()) { formBatch(); cout << "Formed new batch at: " << sc_time_stamp() << std::endl; - sc_assert(!batch->isEmpty()); + sc_assert(batch->hasPayloads()); } - //prioritize batch first - if (batch->hasTransactionForBank(bank)) + gp* result = batch->getNextPayload(); + if(result == NULL) { - return batch->getTransactionForBank(bank); - } - else - { - return buffer->getTransactionForBank(bank); + return buffer->getNextPayload(); } } -void PAR_BS::popTransactionForBank(Bank bank, gp* payload) +void PAR_BS::removePayload(gp* payload) { - sc_assert(DramExtension::getExtension(payload).getBank() == bank); - buffer->popTransactionForBank(bank, payload); - batch->popTransactionForBank(bank, payload); + buffer->removePayload(payload); + batch->removePayload(payload); if (!useExternalBankstates) { - internalBankstates.openRowInRowBuffer(bank, DramExtension::getExtension(payload).getRow()); + DramExtension& extension = DramExtension::getExtension(payload); + internalBankstates.openRowInRowBuffer(extension.getBank(), extension.getRow()); } } @@ -86,12 +80,13 @@ void PAR_BS::formBatch() { map loads; - for (unsigned int b = 0; b < Configuration::getInstance().NumberOfBanks; ++b) + for (Bank bank : controllerCore.getBanks()) { - Bank bank(b); - for (unsigned int i = 0; i < capsize && buffer->hasTransactionForBank(bank); i++) + for (unsigned int i = 0; i < capsize; i++) { gp* payload = buffer->popOldest(bank); + if(payload == NULL) + break; loads[DramExtension::getExtension(payload).getThread()].addTransaction(payload); } } @@ -111,4 +106,4 @@ void PAR_BS::formBatch() } -} /* namespace core */ +} diff --git a/dram/src/controller/scheduler/PARBS.h b/dram/src/controller/scheduler/PARBS.h index 19455285..f15ef2c1 100644 --- a/dram/src/controller/scheduler/PARBS.h +++ b/dram/src/controller/scheduler/PARBS.h @@ -1,9 +1,9 @@ -/* - * PARBS.h - * - * Created on: Apr 9, 2014 - * Author: robert - */ + +// * PARBS.h +// * +// * Created on: Apr 9, 2014 +// * Author: robert +// * #ifndef PARBS_H_ #define PARBS_H_ @@ -16,23 +16,23 @@ namespace scheduler { class PAR_BS : public Scheduler { public: - PAR_BS(const core::BankStates& bankstates, bool useExternalBankstates, unsigned int capsize); - virtual ~PAR_BS(); - virtual bool hasTransactionForBank(Bank bank) override; + PAR_BS(core::ControllerCore& controllerCore, bool useExternalBankstates, unsigned int capsize); + virtual ~PAR_BS(); + virtual bool hasPayloads() override; virtual void schedule(gp* payload) override; - virtual gp* getTransactionForBank(Bank bank) override; - virtual void popTransactionForBank(Bank bank, gp* payload) override; + virtual gp* getNextPayload() override; + virtual void removePayload(gp* payload) override; private: void formBatch(); - bool useExternalBankstates; - const core::BankStates& externalBankstates; - core::BankStates internalBankstates; - FR_FCFS *batch; - FR_FCFS *buffer; - unsigned int capsize; + bool useExternalBankstates; + core::ControllerCore& controllerCore; + core::RowBufferState internalBankstates; + FR_FCFS *batch; + FR_FCFS *buffer; + unsigned int capsize; }; } /* scheduler core */ -#endif /* PARBS_H_ */ +#endif diff --git a/dram/src/controller/scheduler/Scheduler.h b/dram/src/controller/scheduler/Scheduler.h index 2337d8bd..abb5b1d4 100644 --- a/dram/src/controller/scheduler/Scheduler.h +++ b/dram/src/controller/scheduler/Scheduler.h @@ -10,14 +10,14 @@ typedef tlm::tlm_generic_payload gp; class Scheduler { public: - virtual ~Scheduler(){}; + virtual ~Scheduler(){} virtual void schedule(gp* payload) = 0; //TODO Rename to payload - virtual bool hasTransactionForBank(Bank bank) = 0; - virtual gp* getTransactionForBank(Bank bank) = 0; - virtual void popTransactionForBank(Bank bank, gp* payload) = 0; + virtual bool hasPayloads() = 0; + virtual gp* getNextPayload() = 0; + virtual void removePayload(gp* payload) = 0; }; } diff --git a/dram/src/simulation/Simulation.cpp b/dram/src/simulation/Simulation.cpp index 978ab3ff..9121b9bf 100644 --- a/dram/src/simulation/Simulation.cpp +++ b/dram/src/simulation/Simulation.cpp @@ -20,45 +20,64 @@ using namespace std; namespace simulation { -void Simulation::setupDebugManager(bool silent, const string& traceName) -{ - - vector whiteList; - if (!silent) - { - whiteList.push_back(controller->name()); - whiteList.push_back(player2->name()); - whiteList.push_back(player1->name()); - whiteList.push_back(this->name()); - whiteList.push_back(TlmRecorder::senderName); - whiteList.push_back(ControllerCore::senderName); - whiteList.push_back(PowerDownManagerBankwise::senderName); - } - auto& dbg = DebugManager::getInstance(); - dbg.addToWhiteList(whiteList); - dbg.setDebugFile(traceName + ".txt"); - if (silent) - { - dbg.writeToConsole = false; - dbg.writeToFile = false; - } -} - Simulation::Simulation(sc_module_name name, string pathToResources, string traceName, DramSetup setup, - std::vector devices, bool silent) : - traceName(traceName), dramSetup(setup) + std::vector devices) : + traceName(traceName), dramSetup(setup) { SC_THREAD(stop); xmlAddressDecoder::addressConfigURI = pathToResources + string("configs/amconfigs/") + setup.addressmapping; - TlmRecorder::dbName = traceName; - TlmRecorder::sqlScriptURI = pathToResources + string("scripts/createTraceDB.sql"); + Configuration::memconfigUri = pathToResources + string("configs/memconfigs/") + setup.memconfig; Configuration::memspecUri = pathToResources + string("configs/memspecs/") + setup.memspec; - TlmRecorder::getInstance().recordMemconfig(setup.memconfig); - TlmRecorder::getInstance().recordMemspec(setup.memspec); + setupTlmRecorder(traceName, pathToResources, setup, devices); + instantiateModules(pathToResources, devices); + bindSockets(); + setupDebugManager(traceName); + calculateNumberOfTransaction(devices, pathToResources); +} + + +void Simulation::setupDebugManager(const string& traceName) +{ + auto& dbg = DebugManager::getInstance(); + + dbg.addToWhiteList(controller->name()); + dbg.addToWhiteList(player2->name()); + dbg.addToWhiteList(player1->name()); + dbg.addToWhiteList(this->name()); + dbg.addToWhiteList(TlmRecorder::senderName); + dbg.addToWhiteList(ControllerCore::senderName); + dbg.addToWhiteList(PowerDownManagerBankwise::senderName); + + dbg.writeToConsole = true; + dbg.writeToFile = true; + if(dbg.writeToFile) + dbg.openDebugFile(traceName + ".txt"); +} + +void Simulation::setupTlmRecorder(const string &traceName, const string &pathToResources, const DramSetup &setup, const std::vector &devices) +{ + if(Configuration::getInstance().databaseRecordingEnabled) + { + TlmRecorder::recordingEnabled = true; + TlmRecorder::dbName = traceName; + TlmRecorder::sqlScriptURI = pathToResources + string("scripts/createTraceDB.sql"); + TlmRecorder::getInstance().recordMemconfig(setup.memconfig); + TlmRecorder::getInstance().recordMemspec(setup.memspec); + TlmRecorder::getInstance().recordTracenames(devices[0].trace + "," + devices[1].trace + "," + devices[2].trace + "," + devices[3].trace); + } + else + { + TlmRecorder::recordingEnabled = false; + } + +} + +void Simulation::instantiateModules(const string &pathToResources, const std::vector& devices) +{ dram = new Dram<>("dram"); arbiter = new Arbiter("arbiter"); controller = new Controller<>("controller"); @@ -67,23 +86,24 @@ Simulation::Simulation(sc_module_name name, string pathToResources, string trace player2 = new TracePlayer<>("player2", pathToResources + string("traces/") + devices[1].trace, devices[1].burstLength, this); player3 = new TracePlayer<>("player3", pathToResources + string("traces/") + devices[2].trace, devices[2].burstLength, this); player4 = new TracePlayer<>("player4", pathToResources + string("traces/") + devices[3].trace, devices[3].burstLength, this); - TlmRecorder::getInstance().recordTracenames(devices[0].trace + "," + devices[1].trace + "," + devices[2].trace + "," + devices[3].trace); +} +void Simulation::bindSockets() +{ player1->iSocket.bind(arbiter->tSockets[0]); player2->iSocket.bind(arbiter->tSockets[1]); player3->iSocket.bind(arbiter->tSockets[2]); player4->iSocket.bind(arbiter->tSockets[3]); - arbiter->iSocket.bind(controller->tSocket); controller->iSocket.bind(dram->tSocket); +} - setupDebugManager(silent, traceName); - +void Simulation::calculateNumberOfTransaction(std::vector devices, string pathToResources) +{ totalTransactions = getNumberOfLines(pathToResources + string("traces/") + devices[0].trace); totalTransactions += getNumberOfLines(pathToResources + string("traces/") + devices[1].trace); totalTransactions += getNumberOfLines(pathToResources + string("traces/") + devices[2].trace); totalTransactions += getNumberOfLines(pathToResources + string("traces/") + devices[3].trace); - remainingTransactions = totalTransactions; } @@ -129,9 +149,8 @@ void Simulation::stop() { wait(terminateSimulation); report("\nTerminating simulation"); - wait(sc_time(50, SC_NS)); controller->terminateSimulation(); - wait(sc_time(50, SC_NS)); + wait(sc_time(200, SC_NS)); TlmRecorder::getInstance().closeConnection(); sc_stop(); diff --git a/dram/src/simulation/Simulation.h b/dram/src/simulation/Simulation.h index 9424763d..6971a93d 100644 --- a/dram/src/simulation/Simulation.h +++ b/dram/src/simulation/Simulation.h @@ -42,7 +42,7 @@ class Simulation: public ISimulation, public sc_module public: SC_HAS_PROCESS(Simulation); Simulation(sc_module_name name, string pathToResources, string traceName, DramSetup setup, - std::vector devices, bool silent = false); + std::vector devices); ~Simulation(); void start(); @@ -51,6 +51,8 @@ public: void inline transactionFinished() override; constexpr static unsigned int NumberOfTracePlayers = 4; + void bindSockets(); + void calculateNumberOfTransaction(std::vector devices, string pathToResources); private: std::string traceName; DramSetup dramSetup; @@ -72,7 +74,9 @@ private: unsigned int getNumberOfLines(string uri); void report(std::string message); - void setupDebugManager(bool silent, const string& traceName); + void setupDebugManager(const string& traceName); + void setupTlmRecorder(const string &traceName, const string &pathToResources, const DramSetup &setup, const std::vector &devices); + void instantiateModules(const string &pathToResources, const std::vector &devices); }; } /* namespace simulation */ diff --git a/dram/src/simulation/SimulationManager.cpp b/dram/src/simulation/SimulationManager.cpp index c345d8d0..7d622ecd 100644 --- a/dram/src/simulation/SimulationManager.cpp +++ b/dram/src/simulation/SimulationManager.cpp @@ -122,7 +122,7 @@ void SimulationManager::runSimulation(string traceName, DramSetup dramSetup, vec int status = 0; if (pid == 0) { - Simulation* simulation = new Simulation("sim", resources, traceName, dramSetup, traceSetup, silent); + Simulation* simulation = new Simulation("sim", resources, traceName, dramSetup, traceSetup); simulation->start(); delete simulation; _Exit(0); diff --git a/dram/src/simulation/main.cpp b/dram/src/simulation/main.cpp index ca1a7664..c064bc67 100644 --- a/dram/src/simulation/main.cpp +++ b/dram/src/simulation/main.cpp @@ -43,7 +43,6 @@ int sc_main(int argc, char **argv) SimulationManager manager(resources); manager.loadSimulationsFromXML(resources + "/simulations/" + simulationToRun); - manager.silent = false; manager.runSimulations(); return 0; From 37c147ba2f2a0fd72158ca14d3773a5ecef43810 Mon Sep 17 00:00:00 2001 From: robert Date: Tue, 1 Jul 2014 11:01:52 +0200 Subject: [PATCH 04/13] added debug message capabilities to scheduler --- dram/dramSys/dramSys.pro | 3 ++- dram/resources/simulations/sim-batch.xml | 16 +++++++--------- dram/src/common/DebugManager.h | 2 +- dram/src/controller/scheduler/PARBS.cpp | 5 ++++- dram/src/controller/scheduler/Scheduler.cpp | 12 ++++++++++++ dram/src/controller/scheduler/Scheduler.h | 4 ++++ dram/src/simulation/Simulation.cpp | 1 + 7 files changed, 31 insertions(+), 12 deletions(-) create mode 100644 dram/src/controller/scheduler/Scheduler.cpp diff --git a/dram/dramSys/dramSys.pro b/dram/dramSys/dramSys.pro index b99145ed..8672da99 100644 --- a/dram/dramSys/dramSys.pro +++ b/dram/dramSys/dramSys.pro @@ -56,7 +56,8 @@ SOURCES += \ ../src/simulation/MemoryManager.cpp \ ../src/simulation/main.cpp \ ../src/common/libDRAMPower.cpp \ - ../src/controller/core/RowBufferStates.cpp + ../src/controller/core/RowBufferStates.cpp \ + ../src/controller/scheduler/Scheduler.cpp HEADERS += \ ../src/common/third_party/tinyxml2.h \ diff --git a/dram/resources/simulations/sim-batch.xml b/dram/resources/simulations/sim-batch.xml index 7dff121d..9d86048f 100644 --- a/dram/resources/simulations/sim-batch.xml +++ b/dram/resources/simulations/sim-batch.xml @@ -8,24 +8,22 @@ am_wideio.xml - par_bs.xml - + + par_bs.xml - + - mediabench-fractal_32.stl - mediabench-epic_32.stl + mediabench-epic_32.stl diff --git a/dram/src/common/DebugManager.h b/dram/src/common/DebugManager.h index 86c10258..38a0d442 100644 --- a/dram/src/common/DebugManager.h +++ b/dram/src/common/DebugManager.h @@ -25,7 +25,7 @@ public: bool writeToConsole; bool writeToFile; - void printDebugMessage(std::string message, std::string sender); + void printDebugMessage(std::string sender, std::string message); void openDebugFile(std::string filename) { if(debugFile) diff --git a/dram/src/controller/scheduler/PARBS.cpp b/dram/src/controller/scheduler/PARBS.cpp index 70e9e98e..b570ff93 100644 --- a/dram/src/controller/scheduler/PARBS.cpp +++ b/dram/src/controller/scheduler/PARBS.cpp @@ -44,15 +44,18 @@ bool PAR_BS::hasPayloads() void PAR_BS::schedule(gp* payload) { + printDebugMessage("hello!"); buffer->schedule(payload); } gp* PAR_BS::getNextPayload() { + printDebugMessage("hello!"); + if (!batch->hasPayloads()) { formBatch(); - cout << "Formed new batch at: " << sc_time_stamp() << std::endl; + printDebugMessage("Formed new batch"); sc_assert(batch->hasPayloads()); } diff --git a/dram/src/controller/scheduler/Scheduler.cpp b/dram/src/controller/scheduler/Scheduler.cpp new file mode 100644 index 00000000..b7bbbbb4 --- /dev/null +++ b/dram/src/controller/scheduler/Scheduler.cpp @@ -0,0 +1,12 @@ +#include "Scheduler.h" +#include "../../common/DebugManager.h" + +using namespace scheduler; + +std::string Scheduler::sendername = "scheduler"; + +void Scheduler::printDebugMessage(std::string message) +{ + DebugManager::getInstance().printDebugMessage(Scheduler::sendername, message); +} + diff --git a/dram/src/controller/scheduler/Scheduler.h b/dram/src/controller/scheduler/Scheduler.h index abb5b1d4..f0d86668 100644 --- a/dram/src/controller/scheduler/Scheduler.h +++ b/dram/src/controller/scheduler/Scheduler.h @@ -18,6 +18,10 @@ public: virtual bool hasPayloads() = 0; virtual gp* getNextPayload() = 0; virtual void removePayload(gp* payload) = 0; + static std::string sendername; + +protected: + void printDebugMessage(std::string message); }; } diff --git a/dram/src/simulation/Simulation.cpp b/dram/src/simulation/Simulation.cpp index 9121b9bf..ee0937ed 100644 --- a/dram/src/simulation/Simulation.cpp +++ b/dram/src/simulation/Simulation.cpp @@ -48,6 +48,7 @@ void Simulation::setupDebugManager(const string& traceName) dbg.addToWhiteList(player2->name()); dbg.addToWhiteList(player1->name()); dbg.addToWhiteList(this->name()); + dbg.addToWhiteList(Scheduler::sendername); dbg.addToWhiteList(TlmRecorder::senderName); dbg.addToWhiteList(ControllerCore::senderName); dbg.addToWhiteList(PowerDownManagerBankwise::senderName); From 4c7c58596882be2844905e0c1dfa2b3cbe553264 Mon Sep 17 00:00:00 2001 From: robert Date: Tue, 1 Jul 2014 13:35:14 +0200 Subject: [PATCH 05/13] fixed error in numberOfQueuedPayloads in fr_fcfs --- dram/src/controller/scheduler/Fr_Fcfs.cpp | 18 ++++++++++++------ dram/src/controller/scheduler/Fr_Fcfs.h | 5 ++--- dram/src/controller/scheduler/PARBS.cpp | 13 +++++++------ dram/src/simulation/Simulation.cpp | 4 ++-- 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/dram/src/controller/scheduler/Fr_Fcfs.cpp b/dram/src/controller/scheduler/Fr_Fcfs.cpp index 2f887c6b..b4cf1db8 100644 --- a/dram/src/controller/scheduler/Fr_Fcfs.cpp +++ b/dram/src/controller/scheduler/Fr_Fcfs.cpp @@ -10,7 +10,7 @@ namespace scheduler { FR_FCFS::FR_FCFS(core::ControllerCore& controllerCore, bool useExternalStates, bool adaptiveOpenPage) : controllerCore(controllerCore), useExternalStates(useExternalStates), adaptiveOpenPage( - adaptiveOpenPage), numberOfQueuedPayloads(0) + adaptiveOpenPage) { } @@ -20,14 +20,13 @@ FR_FCFS::~FR_FCFS() bool FR_FCFS::hasPayloads() { - return numberOfQueuedPayloads > 0; + return getNumberOfQueuedPayloads() > 0; } void FR_FCFS::schedule(gp* payload) { buffer[DramExtension::getExtension(payload).getBank()].emplace_back(payload); - numberOfQueuedPayloads++; } @@ -85,10 +84,19 @@ gp* FR_FCFS::popOldest(Bank bank) return NULL; gp* result = buffer[bank].front(); buffer[bank].pop_front(); - numberOfQueuedPayloads--; return result; } +int FR_FCFS::getNumberOfQueuedPayloads() +{ + int numberOfQueuedPaylods = 0; + for(auto& bufferElement : buffer) + { + numberOfQueuedPaylods += bufferElement.second.size(); + } + return numberOfQueuedPaylods; +} + std::vector FR_FCFS::findRowHits(Bank bank, Row row) { vector found; @@ -109,8 +117,6 @@ void FR_FCFS::removePayload(gp* payload) { internalBankstates.openRowInRowBuffer(bank, DramExtension::getExtension(payload).getRow()); } - - numberOfQueuedPayloads--; } } diff --git a/dram/src/controller/scheduler/Fr_Fcfs.h b/dram/src/controller/scheduler/Fr_Fcfs.h index 3f4c5105..cfd51f5d 100644 --- a/dram/src/controller/scheduler/Fr_Fcfs.h +++ b/dram/src/controller/scheduler/Fr_Fcfs.h @@ -21,9 +21,9 @@ public: virtual void removePayload(gp* payload) override; //used by PAR_BS - void schedule (std::vector payloads); + void schedule(std::vector payloads); gp* popOldest(Bank bank); - bool isEmpty(); + int getNumberOfQueuedPayloads(); private: std::vector findRowHits(Bank bank, Row row); @@ -32,7 +32,6 @@ private: core::RowBufferState internalBankstates; bool useExternalStates; bool adaptiveOpenPage; - unsigned int numberOfQueuedPayloads; }; } /* namespace scheduler */ diff --git a/dram/src/controller/scheduler/PARBS.cpp b/dram/src/controller/scheduler/PARBS.cpp index b570ff93..f871b68c 100644 --- a/dram/src/controller/scheduler/PARBS.cpp +++ b/dram/src/controller/scheduler/PARBS.cpp @@ -50,20 +50,21 @@ void PAR_BS::schedule(gp* payload) gp* PAR_BS::getNextPayload() { - printDebugMessage("hello!"); - if (!batch->hasPayloads()) { + stringstream s; + s << "In batch: " << batch->getNumberOfQueuedPayloads() << "\t" << "in buffer: " << buffer->getNumberOfQueuedPayloads() << endl; formBatch(); - printDebugMessage("Formed new batch"); + s<< "Formed new batch" << endl; + s << "In batch: " << batch->getNumberOfQueuedPayloads() << "\t" << "in buffer: " << buffer->getNumberOfQueuedPayloads() << endl; + printDebugMessage(s.str()); sc_assert(batch->hasPayloads()); } gp* result = batch->getNextPayload(); if(result == NULL) - { - return buffer->getNextPayload(); - } + result = buffer->getNextPayload(); + return result; } void PAR_BS::removePayload(gp* payload) diff --git a/dram/src/simulation/Simulation.cpp b/dram/src/simulation/Simulation.cpp index ee0937ed..afbc039d 100644 --- a/dram/src/simulation/Simulation.cpp +++ b/dram/src/simulation/Simulation.cpp @@ -168,8 +168,8 @@ void Simulation::report(string message) unsigned int Simulation::getNumberOfLines(string uri) { std::ifstream file(uri); - file.unsetf(std::ios_base::skipws); // new lines will be skipped unless we stop it from happening: - // count the newlines with an algorithm specialized for counting: + // count the newlines + file.unsetf(std::ios_base::skipws); unsigned lineCount = std::count(std::istream_iterator(file), std::istream_iterator(), '\n'); return lineCount; } From e128263833057c183dc19152b90e028e32ceda83 Mon Sep 17 00:00:00 2001 From: robert Date: Tue, 1 Jul 2014 13:58:55 +0200 Subject: [PATCH 06/13] minor refactoring --- dram/resources/configs/memconfigs/fifo.xml | 2 +- dram/resources/configs/memconfigs/fr_fcfs.xml | 2 +- dram/resources/configs/memconfigs/par_bs.xml | 2 +- dram/resources/simulations/sim-batch.xml | 4 ++-- dram/src/controller/Controller.h | 14 ++++++++------ dram/src/controller/scheduler/Fifo.cpp | 14 +++++++++++--- dram/src/controller/scheduler/Fifo.h | 4 ++-- dram/src/controller/scheduler/Fr_Fcfs.cpp | 4 ++-- dram/src/controller/scheduler/Fr_Fcfs.h | 2 +- dram/src/controller/scheduler/Scheduler.h | 3 +++ dram/src/simulation/Simulation.cpp | 16 ++++++++-------- 11 files changed, 40 insertions(+), 27 deletions(-) diff --git a/dram/resources/configs/memconfigs/fifo.xml b/dram/resources/configs/memconfigs/fifo.xml index 2e23e330..3bf15c45 100644 --- a/dram/resources/configs/memconfigs/fifo.xml +++ b/dram/resources/configs/memconfigs/fifo.xml @@ -10,6 +10,6 @@ - + diff --git a/dram/resources/configs/memconfigs/fr_fcfs.xml b/dram/resources/configs/memconfigs/fr_fcfs.xml index b126adb1..a57c0e84 100644 --- a/dram/resources/configs/memconfigs/fr_fcfs.xml +++ b/dram/resources/configs/memconfigs/fr_fcfs.xml @@ -10,6 +10,6 @@ - + diff --git a/dram/resources/configs/memconfigs/par_bs.xml b/dram/resources/configs/memconfigs/par_bs.xml index cae1eb9a..d2f77288 100644 --- a/dram/resources/configs/memconfigs/par_bs.xml +++ b/dram/resources/configs/memconfigs/par_bs.xml @@ -10,6 +10,6 @@ - + diff --git a/dram/resources/simulations/sim-batch.xml b/dram/resources/simulations/sim-batch.xml index 9d86048f..f3ad5c97 100644 --- a/dram/resources/simulations/sim-batch.xml +++ b/dram/resources/simulations/sim-batch.xml @@ -8,8 +8,8 @@ am_wideio.xml - + fifo.xml + fr_fcfs.xml par_bs.xml diff --git a/dram/src/controller/Controller.h b/dram/src/controller/Controller.h index 90f7f5fc..ea4a86f0 100644 --- a/dram/src/controller/Controller.h +++ b/dram/src/controller/Controller.h @@ -197,11 +197,11 @@ public: scheduleNextPayload(); else if (phase == BEGIN_AUTO_REFRESH) printDebugMessage("Entering auto refresh on bank " + to_string(bank.ID())); - else if (isIn(phase, { BEGIN_PDNA, BEGIN_PDNP, BEGIN_SREF })) + else if (containsPhase(phase, { BEGIN_PDNA, BEGIN_PDNP, BEGIN_SREF })) printDebugMessage("Entering PowerDown " + phaseNameToString(phase) + " on bank " + to_string(bank.ID())); - else if (isIn(phase, { END_PDNA, END_PDNP, END_SREF })) + else if (containsPhase(phase, { END_PDNA, END_PDNP, END_SREF })) printDebugMessage("Leaving PowerDown " + phaseNameToString(phase) + " on bank " + to_string(bank.ID())); - else if (isIn(phase, { BEGIN_RD, BEGIN_WR, BEGIN_ACT, BEGIN_PRE, BEGIN_PRE_ALL, BEGIN_RDA, BEGIN_WRA })) + else if (containsPhase(phase, { BEGIN_RD, BEGIN_WR, BEGIN_ACT, BEGIN_PRE, BEGIN_PRE_ALL, BEGIN_RDA, BEGIN_WRA })) { } else @@ -308,6 +308,7 @@ private: return sum; } + void scheduleNextPayload() { if(scheduler->hasPayloads()) @@ -316,7 +317,8 @@ private: if(payload != NULL) { controllerCore->powerDownManager->wakeUp(DramExtension::getExtension(payload).getBank(), sc_time_stamp()); - if (controllerCore->scheduleRequest(sc_time_stamp(), *payload)) + bool wasScheduledByCore = controllerCore->scheduleRequest(sc_time_stamp(), *payload); + if (wasScheduledByCore) { scheduler->removePayload(payload); printDebugMessage("\t-> Next payload was scheduled by core"); @@ -366,7 +368,7 @@ private: controllerCore->powerDownManager->sleep(bank,sc_time_stamp()); scheduleNextPayload(); } - else if (isIn(phase, { END_PRE, END_PRE_ALL, END_ACT })) + else if (containsPhase(phase, { END_PRE, END_PRE_ALL, END_ACT })) { } @@ -391,7 +393,7 @@ private: debugManager.printDebugMessage(name(), message); } - bool isIn(tlm_phase phase, std::vector phases) + bool containsPhase(tlm_phase phase, std::vector phases) { for (tlm_phase p : phases) { diff --git a/dram/src/controller/scheduler/Fifo.cpp b/dram/src/controller/scheduler/Fifo.cpp index 7bd32192..cc501769 100644 --- a/dram/src/controller/scheduler/Fifo.cpp +++ b/dram/src/controller/scheduler/Fifo.cpp @@ -12,13 +12,12 @@ namespace scheduler { bool Fifo::hasPayloads() { - return numberOfQueuedPayloads > 0; + return getNumberOfQueuedPayloads() > 0; } void Fifo::schedule(gp* payload) { buffer[DramExtension::getExtension(payload).getBank()].push_back(payload); - numberOfQueuedPayloads++; } gp* Fifo::getNextPayload() @@ -37,7 +36,16 @@ gp* Fifo::getNextPayload() void Fifo::removePayload(gp* payload) { buffer[DramExtension::getExtension(payload).getBank()].pop_front(); - numberOfQueuedPayloads--; +} + +unsigned int Fifo::getNumberOfQueuedPayloads() +{ + unsigned int numberOfQueuedPayloads = 0; + for(auto& bufferElement : buffer) + { + numberOfQueuedPayloads += bufferElement.second.size(); + } + return numberOfQueuedPayloads; } } /* namespace scheduler */ diff --git a/dram/src/controller/scheduler/Fifo.h b/dram/src/controller/scheduler/Fifo.h index 16be709b..d3c34cae 100644 --- a/dram/src/controller/scheduler/Fifo.h +++ b/dram/src/controller/scheduler/Fifo.h @@ -19,7 +19,7 @@ namespace scheduler { class Fifo : public Scheduler { public: - Fifo(core::ControllerCore &controllerCore) : controllerCore(controllerCore), numberOfQueuedPayloads(0) + Fifo(core::ControllerCore &controllerCore) : controllerCore(controllerCore) {} virtual ~Fifo() {} @@ -32,7 +32,7 @@ public: private: std::map> buffer; core::ControllerCore &controllerCore; - unsigned int numberOfQueuedPayloads; + unsigned int getNumberOfQueuedPayloads(); }; } /* namespace scheduler */ diff --git a/dram/src/controller/scheduler/Fr_Fcfs.cpp b/dram/src/controller/scheduler/Fr_Fcfs.cpp index b4cf1db8..b2fefae7 100644 --- a/dram/src/controller/scheduler/Fr_Fcfs.cpp +++ b/dram/src/controller/scheduler/Fr_Fcfs.cpp @@ -87,9 +87,9 @@ gp* FR_FCFS::popOldest(Bank bank) return result; } -int FR_FCFS::getNumberOfQueuedPayloads() +unsigned int FR_FCFS::getNumberOfQueuedPayloads() { - int numberOfQueuedPaylods = 0; + unsigned int numberOfQueuedPaylods = 0; for(auto& bufferElement : buffer) { numberOfQueuedPaylods += bufferElement.second.size(); diff --git a/dram/src/controller/scheduler/Fr_Fcfs.h b/dram/src/controller/scheduler/Fr_Fcfs.h index cfd51f5d..ccfbf718 100644 --- a/dram/src/controller/scheduler/Fr_Fcfs.h +++ b/dram/src/controller/scheduler/Fr_Fcfs.h @@ -23,7 +23,7 @@ public: //used by PAR_BS void schedule(std::vector payloads); gp* popOldest(Bank bank); - int getNumberOfQueuedPayloads(); + unsigned int getNumberOfQueuedPayloads(); private: std::vector findRowHits(Bank bank, Row row); diff --git a/dram/src/controller/scheduler/Scheduler.h b/dram/src/controller/scheduler/Scheduler.h index f0d86668..85fd552b 100644 --- a/dram/src/controller/scheduler/Scheduler.h +++ b/dram/src/controller/scheduler/Scheduler.h @@ -16,6 +16,9 @@ public: //TODO Rename to payload virtual bool hasPayloads() = 0; + /* + *Test + */ virtual gp* getNextPayload() = 0; virtual void removePayload(gp* payload) = 0; static std::string sendername; diff --git a/dram/src/simulation/Simulation.cpp b/dram/src/simulation/Simulation.cpp index afbc039d..4a392d2a 100644 --- a/dram/src/simulation/Simulation.cpp +++ b/dram/src/simulation/Simulation.cpp @@ -44,14 +44,14 @@ void Simulation::setupDebugManager(const string& traceName) { auto& dbg = DebugManager::getInstance(); - dbg.addToWhiteList(controller->name()); - dbg.addToWhiteList(player2->name()); - dbg.addToWhiteList(player1->name()); - dbg.addToWhiteList(this->name()); - dbg.addToWhiteList(Scheduler::sendername); - dbg.addToWhiteList(TlmRecorder::senderName); - dbg.addToWhiteList(ControllerCore::senderName); - dbg.addToWhiteList(PowerDownManagerBankwise::senderName); +// dbg.addToWhiteList(controller->name()); +// dbg.addToWhiteList(player2->name()); +// dbg.addToWhiteList(player1->name()); +// dbg.addToWhiteList(this->name()); +// dbg.addToWhiteList(Scheduler::sendername); +// dbg.addToWhiteList(TlmRecorder::senderName); +// dbg.addToWhiteList(ControllerCore::senderName); +// dbg.addToWhiteList(PowerDownManagerBankwise::senderName); dbg.writeToConsole = true; dbg.writeToFile = true; From 61bacdfb9ff0937062fc72caae85496234cd81de Mon Sep 17 00:00:00 2001 From: robert Date: Tue, 1 Jul 2014 14:39:58 +0200 Subject: [PATCH 07/13] resolved most warnings --- dram/src/common/DebugManager.h | 1 + dram/src/controller/Controller.h | 2 +- dram/src/controller/core/ControllerCore.cpp | 4 +- .../powerdown/PowerDownManagerTimeout.cpp | 4 +- .../core/refresh/RefreshManagerBankwise.cpp | 64 +++++++++---------- .../core/scheduling/ScheduledCommand.cpp | 64 +++++++++---------- .../core/scheduling/ScheduledCommand.h | 8 +-- dram/src/controller/scheduler/PARBS.h | 2 +- dram/src/simulation/Simulation.cpp | 2 +- dram/src/simulation/SimulationManager.cpp | 2 +- dram/src/simulation/TracePlayer.h | 2 +- dram/src/simulation/main.cpp | 2 +- 12 files changed, 78 insertions(+), 79 deletions(-) diff --git a/dram/src/common/DebugManager.h b/dram/src/common/DebugManager.h index 38a0d442..004c5691 100644 --- a/dram/src/common/DebugManager.h +++ b/dram/src/common/DebugManager.h @@ -35,6 +35,7 @@ public: void addToWhiteList(std::string sender); void addToWhiteList(std::vector senders); + private: DebugManager(); DebugManager(const DebugManager&){} diff --git a/dram/src/controller/Controller.h b/dram/src/controller/Controller.h index ea4a86f0..db4b0414 100644 --- a/dram/src/controller/Controller.h +++ b/dram/src/controller/Controller.h @@ -49,7 +49,7 @@ public: tlm_utils::simple_initiator_socket iSocket; tlm_utils::simple_target_socket tSocket; - Controller(sc_module_name name) : + Controller(sc_module_name /*name*/) : frontendPEQ(this, &Controller::frontendPEQCallback), dramPEQ(this, &Controller::dramPEQCallback), controllerCorePEQ( this, &Controller::controllerCorePEQCallback), debugManager(DebugManager::getInstance()) { diff --git a/dram/src/controller/core/ControllerCore.cpp b/dram/src/controller/core/ControllerCore.cpp index af2491d2..168521e0 100644 --- a/dram/src/controller/core/ControllerCore.cpp +++ b/dram/src/controller/core/ControllerCore.cpp @@ -30,8 +30,8 @@ namespace core { std::string ControllerCore::senderName = "Controller Core"; ControllerCore::ControllerCore(IWrapperConnector& wrapperConnector, std::map& numberOfPayloads) : - config(Configuration::getInstance()), state(&config), wrapper(wrapperConnector), commandChecker(), numberOfPayloads( - numberOfPayloads), savedState(&config), commandSequenceGenerator(state), commandSequenceScheduler(*this) + config(Configuration::getInstance()), state(&config), wrapper(wrapperConnector), numberOfPayloads( + numberOfPayloads), commandChecker(), savedState(&config), commandSequenceGenerator(state), commandSequenceScheduler(*this) { commandChecker[Command::Activate] = new ActivateChecker(config, state); diff --git a/dram/src/controller/core/powerdown/PowerDownManagerTimeout.cpp b/dram/src/controller/core/powerdown/PowerDownManagerTimeout.cpp index 4a3d14f4..4f82b3cb 100644 --- a/dram/src/controller/core/powerdown/PowerDownManagerTimeout.cpp +++ b/dram/src/controller/core/powerdown/PowerDownManagerTimeout.cpp @@ -102,7 +102,7 @@ void PowerDownManagerTimeout::wakeUpForRefresh(Bank bank, sc_time time) } } -void PowerDownManagerTimeout::triggerSleep(Bank bank, sc_time time) +void PowerDownManagerTimeout::triggerSleep(Bank /*bank*/, sc_time time) { if(canSleep() && !isInPowerDown()) { @@ -110,7 +110,7 @@ void PowerDownManagerTimeout::triggerSleep(Bank bank, sc_time time) } } -bool PowerDownManagerTimeout::isInSelfRefresh(Bank bank) +bool PowerDownManagerTimeout::isInSelfRefresh(Bank /*bank*/) { return powerDownState == PowerDownState::PDNSelfRefresh; } diff --git a/dram/src/controller/core/refresh/RefreshManagerBankwise.cpp b/dram/src/controller/core/refresh/RefreshManagerBankwise.cpp index 9ee29abd..e50bc250 100644 --- a/dram/src/controller/core/refresh/RefreshManagerBankwise.cpp +++ b/dram/src/controller/core/refresh/RefreshManagerBankwise.cpp @@ -15,13 +15,13 @@ using namespace std; namespace core { RefreshManagerBankwise::RefreshManagerBankwise(ControllerCore& controller) : - controller(controller) + controller(controller) { - for (Bank bank : controller.getBanks()) - { - setUpDummy(refreshPayloads[bank], bank); - planNextRefresh(bank); - } + for (Bank bank : controller.getBanks()) + { + setUpDummy(refreshPayloads[bank], bank); + planNextRefresh(bank); + } } RefreshManagerBankwise::~RefreshManagerBankwise() @@ -30,58 +30,56 @@ RefreshManagerBankwise::~RefreshManagerBankwise() bool RefreshManagerBankwise::hasCollision(const CommandSchedule& schedule) { - return schedule.getStart() < controller.state.getLastCommand(Command::AutoRefresh, schedule.getBank()).getEnd() - || schedule.getEnd() > nextPlannedRefreshs[schedule.getBank()]; + return schedule.getStart() < controller.state.getLastCommand(Command::AutoRefresh, schedule.getBank()).getEnd() + || schedule.getEnd() > nextPlannedRefreshs[schedule.getBank()]; } bool RefreshManagerBankwise::hasCollision(const ScheduledCommand& command) { - const ScheduledCommand& ref= controller.state.getLastCommand(Command::AutoRefresh, command.getBank()); - - return command.getStart() < controller.state.getLastCommand(Command::AutoRefresh, command.getBank()).getEnd() - || command.getEnd() > nextPlannedRefreshs[command.getBank()];} + return command.getStart() < controller.state.getLastCommand(Command::AutoRefresh, command.getBank()).getEnd() + || command.getEnd() > nextPlannedRefreshs[command.getBank()];} void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time) { - sc_assert(!isInvalidated(payload, time)); + sc_assert(!isInvalidated(payload, time)); - tlm::tlm_generic_payload& refreshPayload = refreshPayloads[DramExtension::getExtension(payload).getBank()]; + tlm::tlm_generic_payload& refreshPayload = refreshPayloads[DramExtension::getExtension(payload).getBank()]; - DramExtension& extension = DramExtension::getExtension(refreshPayload); + DramExtension& extension = DramExtension::getExtension(refreshPayload); - if (controller.state.rowBufferStates.rowBufferIsOpen(extension.getBank())) - { - ScheduledCommand precharge(Command::Precharge, time, getExecutionTime(Command::Precharge, refreshPayload), extension); + if (controller.state.rowBufferStates.rowBufferIsOpen(extension.getBank())) + { + ScheduledCommand precharge(Command::Precharge, time, getExecutionTime(Command::Precharge, refreshPayload), extension); - controller.getCommandChecker(Command::Precharge).delayToSatisfyConstraints(precharge); - controller.state.change(precharge); - controller.wrapper.send(precharge, refreshPayload); - } + controller.getCommandChecker(Command::Precharge).delayToSatisfyConstraints(precharge); + controller.state.change(precharge); + controller.wrapper.send(precharge, refreshPayload); + } - ScheduledCommand nextRefresh(Command::AutoRefresh, time, getExecutionTime(Command::AutoRefresh, refreshPayload), extension); - controller.getCommandChecker(Command::AutoRefresh).delayToSatisfyConstraints(nextRefresh); - controller.state.change(nextRefresh); - controller.wrapper.send(nextRefresh, refreshPayload); + ScheduledCommand nextRefresh(Command::AutoRefresh, time, getExecutionTime(Command::AutoRefresh, refreshPayload), extension); + controller.getCommandChecker(Command::AutoRefresh).delayToSatisfyConstraints(nextRefresh); + controller.state.change(nextRefresh); + controller.wrapper.send(nextRefresh, refreshPayload); - extension.increaseRow(); - planNextRefresh(extension.getBank()); + extension.increaseRow(); + planNextRefresh(extension.getBank()); } void RefreshManagerBankwise::planNextRefresh(Bank bank) { - nextPlannedRefreshs[bank] += Configuration::getInstance().Timings.refreshTimings[bank].tREFI; - controller.wrapper.send(REFTrigger, nextPlannedRefreshs[bank], refreshPayloads[bank]); + nextPlannedRefreshs[bank] += Configuration::getInstance().Timings.refreshTimings[bank].tREFI; + controller.wrapper.send(REFTrigger, nextPlannedRefreshs[bank], refreshPayloads[bank]); } void RefreshManagerBankwise::reInitialize(Bank bank, sc_time time) { - nextPlannedRefreshs[bank] = clkAlign(time, Alignment::DOWN); - planNextRefresh(bank); + nextPlannedRefreshs[bank] = clkAlign(time, Alignment::DOWN); + planNextRefresh(bank); } bool RefreshManagerBankwise::isInvalidated(tlm::tlm_generic_payload& payload, sc_time time) { - return nextPlannedRefreshs[DramExtension::getExtension(payload).getBank()] > time; + return nextPlannedRefreshs[DramExtension::getExtension(payload).getBank()] > time; } } /* namespace core */ diff --git a/dram/src/controller/core/scheduling/ScheduledCommand.cpp b/dram/src/controller/core/scheduling/ScheduledCommand.cpp index e41e8184..bcef806b 100644 --- a/dram/src/controller/core/scheduling/ScheduledCommand.cpp +++ b/dram/src/controller/core/scheduling/ScheduledCommand.cpp @@ -13,98 +13,98 @@ namespace core { bool ScheduledCommand::isNoCommand() const { - return (command == Command::NOP && start == SC_ZERO_TIME && executionTime == SC_ZERO_TIME && end == SC_ZERO_TIME); + return (command == Command::NOP && start == SC_ZERO_TIME && executionTime == SC_ZERO_TIME && end == SC_ZERO_TIME); } bool ScheduledCommand::isValidCommand() const { - return !isNoCommand(); + return !isNoCommand(); } const sc_time ScheduledCommand::getStart() const { - return start; + return start; } void ScheduledCommand::setStart(sc_time newStart) { - start = newStart; - end = newStart + executionTime; + start = newStart; + end = newStart + executionTime; } void ScheduledCommand::delayStart(sc_time delay) { - setStart(start+delay); + setStart(start+delay); } void ScheduledCommand::delayToMeetConstraint(sc_time previous, sc_time constraint) { - delayStart(getDelayToMeetConstraint(previous, start, constraint)); + delayStart(getDelayToMeetConstraint(previous, start, constraint)); } -const sc_time ScheduledCommand::getEnd() const +sc_time ScheduledCommand::getEnd() const { - return end; + return end; } -const Command ScheduledCommand::getCommand() const +Command ScheduledCommand::getCommand() const { - return command; + return command; } -const sc_time ScheduledCommand::getExecutionTime() const +sc_time ScheduledCommand::getExecutionTime() const { - return executionTime; + return executionTime; } Bank ScheduledCommand::getBank() const { - return extension.getBank(); + return extension.getBank(); } BankGroup ScheduledCommand::getBankGroup() const { - return extension.getBankGroup(); + return extension.getBankGroup(); } Row ScheduledCommand::getRow() const { - return extension.getRow(); + return extension.getRow(); } unsigned int ScheduledCommand::getBurstLength() const { - return extension.getBurstlength(); + return extension.getBurstlength(); } bool ScheduledCommand::operator ==(const ScheduledCommand& b) const { - return b.command == command && b.start == start && b.executionTime == executionTime && b.end == end; + return b.command == command && b.start == start && b.executionTime == executionTime && b.end == end; } bool ScheduledCommand::commandIsIn(const std::vector& commandSet) const { - return isIn(command, commandSet); + return isIn(command, commandSet); } TimeInterval ScheduledCommand::getIntervalOnDataStrobe() const { - sc_assert( - getCommand() == Command::Read || getCommand() == Command::ReadA - || getCommand() == Command::Write - || getCommand() == Command::WriteA); + sc_assert( + getCommand() == Command::Read || getCommand() == Command::ReadA + || getCommand() == Command::Write + || getCommand() == Command::WriteA); - TimingConfiguration& timings = Configuration::getInstance().Timings; + TimingConfiguration& timings = Configuration::getInstance().Timings; - if (getCommand() == Command::Read || getCommand() == Command::ReadA) - { - return TimeInterval(getStart() + timings.tRL,getStart() + timings.tRL + getReadAccessTime()); - } - else - { - return TimeInterval(getStart() + timings.tWL - timings.clk / 2, getStart() + timings.tWL + getWriteAccessTime() - timings.clk / 2); - } + if (getCommand() == Command::Read || getCommand() == Command::ReadA) + { + return TimeInterval(getStart() + timings.tRL,getStart() + timings.tRL + getReadAccessTime()); + } + else + { + return TimeInterval(getStart() + timings.tWL - timings.clk / 2, getStart() + timings.tWL + getWriteAccessTime() - timings.clk / 2); + } } diff --git a/dram/src/controller/core/scheduling/ScheduledCommand.h b/dram/src/controller/core/scheduling/ScheduledCommand.h index c0ab7536..50b3ad1b 100644 --- a/dram/src/controller/core/scheduling/ScheduledCommand.h +++ b/dram/src/controller/core/scheduling/ScheduledCommand.h @@ -41,9 +41,9 @@ public: void delayStart(sc_time delay); void delayToMeetConstraint(sc_time previous, sc_time constraint); - const sc_time getEnd() const; - const Command getCommand() const; - const sc_time getExecutionTime() const; + sc_time getEnd() const; + Command getCommand() const; + sc_time getExecutionTime() const; Bank getBank() const; BankGroup getBankGroup() const; @@ -57,11 +57,11 @@ public: private: - DramExtension extension; Command command; sc_time start; sc_time executionTime; sc_time end; + DramExtension extension; }; } /* namespace controller */ diff --git a/dram/src/controller/scheduler/PARBS.h b/dram/src/controller/scheduler/PARBS.h index f15ef2c1..2c6f9398 100644 --- a/dram/src/controller/scheduler/PARBS.h +++ b/dram/src/controller/scheduler/PARBS.h @@ -25,8 +25,8 @@ public: private: void formBatch(); - bool useExternalBankstates; core::ControllerCore& controllerCore; + bool useExternalBankstates; core::RowBufferState internalBankstates; FR_FCFS *batch; FR_FCFS *buffer; diff --git a/dram/src/simulation/Simulation.cpp b/dram/src/simulation/Simulation.cpp index 4a392d2a..80af5417 100644 --- a/dram/src/simulation/Simulation.cpp +++ b/dram/src/simulation/Simulation.cpp @@ -20,7 +20,7 @@ using namespace std; namespace simulation { -Simulation::Simulation(sc_module_name name, string pathToResources, string traceName, DramSetup setup, +Simulation::Simulation(sc_module_name /*name*/, string pathToResources, string traceName, DramSetup setup, std::vector devices) : traceName(traceName), dramSetup(setup) diff --git a/dram/src/simulation/SimulationManager.cpp b/dram/src/simulation/SimulationManager.cpp index 7d622ecd..fdc9fc4b 100644 --- a/dram/src/simulation/SimulationManager.cpp +++ b/dram/src/simulation/SimulationManager.cpp @@ -16,7 +16,7 @@ using namespace simulation; namespace simulation { SimulationManager::SimulationManager(string resources) : - resources(resources), silent(false) + silent(false), resources(resources) { } diff --git a/dram/src/simulation/TracePlayer.h b/dram/src/simulation/TracePlayer.h index d5f3cdd2..20aa8c6d 100644 --- a/dram/src/simulation/TracePlayer.h +++ b/dram/src/simulation/TracePlayer.h @@ -31,7 +31,7 @@ struct TracePlayer: public sc_module { public: tlm_utils::simple_initiator_socket iSocket; - TracePlayer(sc_module_name name, string pathToTrace, unsigned int burstLength, + TracePlayer(sc_module_name /*name*/, string pathToTrace, unsigned int burstLength, simulation::ISimulation* simulationManager) : payloadEventQueue(this, &TracePlayer::peqCallback), file(pathToTrace), burstlenght(burstLength), numberOfPendingTransactions( 0), transactionsSent(0), transactionsReceived(0), simulationManager( diff --git a/dram/src/simulation/main.cpp b/dram/src/simulation/main.cpp index c064bc67..19f063f6 100644 --- a/dram/src/simulation/main.cpp +++ b/dram/src/simulation/main.cpp @@ -39,7 +39,7 @@ int sc_main(int argc, char **argv) if(argc > 1) simulationToRun = argv[1]; else - simulationToRun = "sim-batch.xml"; + simulationToRun = "tests.xml"; SimulationManager manager(resources); manager.loadSimulationsFromXML(resources + "/simulations/" + simulationToRun); From c554b4aba12a2d7f77c9789975028b87d2c1a882 Mon Sep 17 00:00:00 2001 From: robert Date: Wed, 2 Jul 2014 18:48:50 +0200 Subject: [PATCH 08/13] minor refactoring --- dram/src/common/DebugManager.cpp | 7 + dram/src/common/DebugManager.h | 7 +- dram/src/common/Utils.h | 1 - dram/src/common/protocol.h | 4 +- dram/src/common/xmlConfig.h | 154 ++-- dram/src/controller/Controller.cpp | 3 + dram/src/controller/Controller.h | 707 +++++++++--------- dram/src/controller/core/ControllerCore.h | 6 +- .../src/controller/core/TimingCalculation.cpp | 6 +- dram/src/controller/core/TimingCalculation.h | 2 +- .../core/powerdown/PowerDownManager.cpp | 2 +- .../core/powerdown/PowerDownManager.h | 31 +- .../powerdown/PowerDownManagerBankwise.cpp | 150 ++-- .../powerdown/PowerDownManagerTimeout.cpp | 2 +- .../controller/core/refresh/RefreshManager.h | 30 +- dram/src/simulation/Simulation.h | 4 +- 16 files changed, 577 insertions(+), 539 deletions(-) create mode 100644 dram/src/controller/Controller.cpp diff --git a/dram/src/common/DebugManager.cpp b/dram/src/common/DebugManager.cpp index 9d65abc9..0ee8dcf2 100644 --- a/dram/src/common/DebugManager.cpp +++ b/dram/src/common/DebugManager.cpp @@ -22,6 +22,13 @@ void DebugManager::printDebugMessage(string sender, string message) #endif } +void DebugManager::openDebugFile(string filename) +{ + if(debugFile) + debugFile.close(); + debugFile.open(filename); +} + void DebugManager::addToWhiteList(string sender) { whiteList.insert(sender); diff --git a/dram/src/common/DebugManager.h b/dram/src/common/DebugManager.h index 004c5691..4bcd5fdf 100644 --- a/dram/src/common/DebugManager.h +++ b/dram/src/common/DebugManager.h @@ -26,12 +26,7 @@ public: bool writeToFile; void printDebugMessage(std::string sender, std::string message); - void openDebugFile(std::string filename) - { - if(debugFile) - debugFile.close(); - debugFile.open(filename); - } + void openDebugFile(std::string filename); void addToWhiteList(std::string sender); void addToWhiteList(std::vector senders); diff --git a/dram/src/common/Utils.h b/dram/src/common/Utils.h index 1ed00124..df203010 100644 --- a/dram/src/common/Utils.h +++ b/dram/src/common/Utils.h @@ -30,7 +30,6 @@ struct TimeInterval bool intersects(TimeInterval other); }; - template inline Val getElementFromMap(const std::map& m, Key key) { diff --git a/dram/src/common/protocol.h b/dram/src/common/protocol.h index f1c8b480..41e5daeb 100755 --- a/dram/src/common/protocol.h +++ b/dram/src/common/protocol.h @@ -1,7 +1,7 @@ #ifndef EXTENDED_PHASE_DRAM #define EXTENDED_PHASE_DRAM -// DRAM Control Phases +// DRAM Control Phases DECLARE_EXTENDED_PHASE(BEGIN_PRE); DECLARE_EXTENDED_PHASE(END_PRE); @@ -16,7 +16,6 @@ DECLARE_EXTENDED_PHASE(END_AUTO_REFRESH); // Phases for Read and Write - DECLARE_EXTENDED_PHASE(BEGIN_WR); DECLARE_EXTENDED_PHASE(END_WR); @@ -30,7 +29,6 @@ DECLARE_EXTENDED_PHASE(BEGIN_RDA); DECLARE_EXTENDED_PHASE(END_RDA); // Phases for Power Down - DECLARE_EXTENDED_PHASE(BEGIN_PDNP); DECLARE_EXTENDED_PHASE(END_PDNP); diff --git a/dram/src/common/xmlConfig.h b/dram/src/common/xmlConfig.h index 78b4645d..110dd2aa 100755 --- a/dram/src/common/xmlConfig.h +++ b/dram/src/common/xmlConfig.h @@ -3,97 +3,95 @@ #include #include -#include "third_party/tinyxml.h" - using namespace std; class xmlConfig { - public: + public: - sc_time clk; - sc_time tRRD; - sc_time tRC; - sc_time tRCD; - sc_time tBL; - sc_time tRL; - sc_time tWL; - sc_time tWTR; - sc_time tRP; - sc_time tRAS; - sc_time tWR; - sc_time tREF; - sc_time tRFC; - sc_time tXP; - sc_time tCKE; - sc_time tXSR; - sc_time tCKESR; - sc_time tREFA; - sc_time tREFB; - sc_time tPDNTO; + sc_time clk; + sc_time tRRD; + sc_time tRC; + sc_time tRCD; + sc_time tBL; + sc_time tRL; + sc_time tWL; + sc_time tWTR; + sc_time tRP; + sc_time tRAS; + sc_time tWR; + sc_time tREF; + sc_time tRFC; + sc_time tXP; + sc_time tCKE; + sc_time tXSR; + sc_time tCKESR; + sc_time tREFA; + sc_time tREFB; + sc_time tPDNTO; - double IDD0; - double IDD2N; - double IDD3N; - double IDD4R; - double IDD4W; - double IDD5; - double IDD6; - double IDD5B1; - double IDD2P; - double IDD3P; - double VDD; + double IDD0; + double IDD2N; + double IDD3N; + double IDD4R; + double IDD4W; + double IDD5; + double IDD6; + double IDD5B1; + double IDD2P; + double IDD3P; + double VDD; - sc_time ccPreprocessingTime; + sc_time ccPreprocessingTime; - public: - xmlConfig() - { - //clk = sc_time(6.0, SC_NS); // 166MHz - clk = sc_time(6, SC_NS); // 166MHz + public: + xmlConfig() + { + //clk = sc_time(6.0, SC_NS); // 166MHz + clk = sc_time(6, SC_NS); // 166MHz - // Timings: - // WC timings for 200MHz - // before thermal: - tRRD = 2 * clk; // 2 * clk; // 4 * clk;//1 * clk; //2 * clk; - tRCD = 3 * clk; // 2 * clk; // 10 * clk;//3 * clk; //4 * clk; - tRL = 3 * clk; // 3 * clk; // 10 * clk;//3 * clk; //3 * clk; - tBL = 1 * clk; // 1 * clk; // 1 * clk;//1 * clk; //1 * clk; - tWL = 1 * clk; // 1 * clk; // 9 * clk;//1 * clk; //1 * clk; - tWTR = 3 * clk; // 3 * clk; // 4 * clk;//3 * clk; //3 * clk; - tRP = 3 * clk; // 3 * clk; // 10 * clk;//3 * clk; //4 * clk; // sadri changed from 2 to 3 = 18ns/6ns - tRAS = 6 * clk; // 5 * clk; // 18 * clk;//8 * clk; //9 * clk; - tWR = 2 * clk; // 2 * clk; // 10 * clk;//2 * clk; //3 * clk; - tRFC = 18 * clk; // 22 * clk; // 15 * clk; // 110* clk;//18 * clk; // sadri changed from 15 to 22 = 130ns/6ns - tXP = 2 * clk; - tCKE = 3 * clk; - tXSR = tRFC + 2 * clk; - tCKESR = 3 * clk; - tPDNTO = 0 * clk; - tRC = tRP + tRAS; - tREF = sc_time(64, SC_MS); - tREFA = tRP + tRFC; - tREFB = tRP + tRC; // refresh for one bank + // Timings: + // WC timings for 200MHz + // before thermal: + tRRD = 2 * clk; // 2 * clk; // 4 * clk;//1 * clk; //2 * clk; + tRCD = 3 * clk; // 2 * clk; // 10 * clk;//3 * clk; //4 * clk; + tRL = 3 * clk; // 3 * clk; // 10 * clk;//3 * clk; //3 * clk; + tBL = 1 * clk; // 1 * clk; // 1 * clk;//1 * clk; //1 * clk; + tWL = 1 * clk; // 1 * clk; // 9 * clk;//1 * clk; //1 * clk; + tWTR = 3 * clk; // 3 * clk; // 4 * clk;//3 * clk; //3 * clk; + tRP = 3 * clk; // 3 * clk; // 10 * clk;//3 * clk; //4 * clk; // sadri changed from 2 to 3 = 18ns/6ns + tRAS = 6 * clk; // 5 * clk; // 18 * clk;//8 * clk; //9 * clk; + tWR = 2 * clk; // 2 * clk; // 10 * clk;//2 * clk; //3 * clk; + tRFC = 18 * clk; // 22 * clk; // 15 * clk; // 110* clk;//18 * clk; // sadri changed from 15 to 22 = 130ns/6ns + tXP = 2 * clk; + tCKE = 3 * clk; + tXSR = tRFC + 2 * clk; + tCKESR = 3 * clk; + tPDNTO = 0 * clk; + tRC = tRP + tRAS; + tREF = sc_time(64, SC_MS); + tREFA = tRP + tRFC; + tREFB = tRP + tRC; // refresh for one bank - // Power realted currents and voltages: - // 166MHz thermal non minimal timings (200MHz) - // 166MHz with minimal timing - IDD0 = 37.85 / 1000.0; // 47.3 / 1000.0; //64 / 1000.0; - IDD2N = 4.36 / 1000.0; // 4.36 / 1000.0; //4.4 / 1000.0; - IDD3N = 5.60 / 1000.0; // 6.07 / 1000.0; //5.9 / 1000.0; - IDD4R = 94.64 / 1000.0; // 94.65 / 1000.0; //94 / 1000.0; - IDD4W = 88.65 / 1000.0; // 88.66 / 1000.0; //88 / 1000.0; - IDD5 = 136.20 / 1000.0; // 162.56 / 1000.0; //163 / 1000.0; - IDD5B1 = 37.32 / 1000.0; // - IDD2P = 2.4 / 1000.0; // - IDD3P = 3.6 / 1000.0; // - IDD6 = 3.4 / 1000.0; // + // Power realted currents and voltages: + // 166MHz thermal non minimal timings (200MHz) + // 166MHz with minimal timing + IDD0 = 37.85 / 1000.0; // 47.3 / 1000.0; //64 / 1000.0; + IDD2N = 4.36 / 1000.0; // 4.36 / 1000.0; //4.4 / 1000.0; + IDD3N = 5.60 / 1000.0; // 6.07 / 1000.0; //5.9 / 1000.0; + IDD4R = 94.64 / 1000.0; // 94.65 / 1000.0; //94 / 1000.0; + IDD4W = 88.65 / 1000.0; // 88.66 / 1000.0; //88 / 1000.0; + IDD5 = 136.20 / 1000.0; // 162.56 / 1000.0; //163 / 1000.0; + IDD5B1 = 37.32 / 1000.0; // + IDD2P = 2.4 / 1000.0; // + IDD3P = 3.6 / 1000.0; // + IDD6 = 3.4 / 1000.0; // - VDD = 1.2; + VDD = 1.2; - ccPreprocessingTime = 1 * clk; - } + ccPreprocessingTime = 1 * clk; + } }; #endif diff --git a/dram/src/controller/Controller.cpp b/dram/src/controller/Controller.cpp new file mode 100644 index 00000000..e7ee32c6 --- /dev/null +++ b/dram/src/controller/Controller.cpp @@ -0,0 +1,3 @@ +#include "Controller.h" + + diff --git a/dram/src/controller/Controller.h b/dram/src/controller/Controller.h index db4b0414..4f8d22d7 100644 --- a/dram/src/controller/Controller.h +++ b/dram/src/controller/Controller.h @@ -45,175 +45,57 @@ template struct Controller: public sc_module, public IWrapperConnector { public: - - tlm_utils::simple_initiator_socket iSocket; - tlm_utils::simple_target_socket tSocket; - Controller(sc_module_name /*name*/) : - frontendPEQ(this, &Controller::frontendPEQCallback), dramPEQ(this, &Controller::dramPEQCallback), controllerCorePEQ( - this, &Controller::controllerCorePEQCallback), debugManager(DebugManager::getInstance()) + frontendPEQ(this, &Controller::frontendPEQCallback), dramPEQ(this, &Controller::dramPEQCallback), controllerCorePEQ( + this, &Controller::controllerCorePEQCallback), debugManager(DebugManager::getInstance()) { controllerCore = new ControllerCore(*this, numberOfPayloadsInSystem); buildScheduler(); - iSocket.register_nb_transport_bw(this, &Controller::nb_transport_bw); - tSocket.register_nb_transport_fw(this, &Controller::nb_transport_fw); + iSocket.register_nb_transport_bw(this, &Controller::nb_transport_bw); + tSocket.register_nb_transport_fw(this, &Controller::nb_transport_fw); } - - void buildScheduler() - { - string selectedScheduler = Configuration::getInstance().Scheduler; - - if (selectedScheduler == "FR_FCFS") - { - - scheduler = new FR_FCFS(*controllerCore, Configuration::getInstance().RefreshAwareScheduling, - Configuration::getInstance().AdaptiveOpenPagePolicy); - } - else if (selectedScheduler == "PAR_BS") - { - scheduler = new PAR_BS(*controllerCore, Configuration::getInstance().RefreshAwareScheduling, - Configuration::getInstance().Capsize); - } - else if (selectedScheduler == "FIFO") - scheduler = new Fifo(*controllerCore); - else - reportFatal(name(), "unsupported scheduler: " + selectedScheduler); - } - ~Controller() { delete controllerCore; delete scheduler; } - void terminateSimulation() - { - for (Bank bank : controllerCore->getBanks()) - { - controllerCore->powerDownManager->wakeUp(bank, clkAlign(sc_time_stamp())); - } - } - // ------- Interaction with controller core --------- - virtual void send(const ScheduledCommand& command, tlm_generic_payload& payload) override - { - sc_assert(command.getStart() >= sc_time_stamp()); - TimeInterval dataStrobe; + void terminateSimulation(); + // ------- CONTROLLER CORE --------- + virtual void send(const ScheduledCommand& command, tlm_generic_payload& payload) override; + virtual void send(Trigger trigger, sc_time time, tlm_generic_payload& payload) override; - switch (command.getCommand()) - { - case Command::Read: - dataStrobe = command.getIntervalOnDataStrobe(); - TlmRecorder::getInstance().updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); - controllerCorePEQ.notify(payload, BEGIN_RD, command.getStart() - sc_time_stamp()); - break; - case Command::ReadA: - dataStrobe = command.getIntervalOnDataStrobe(); - TlmRecorder::getInstance().updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); - controllerCorePEQ.notify(payload, BEGIN_RDA, command.getStart() - sc_time_stamp()); - break; - case Command::Write: - dataStrobe = command.getIntervalOnDataStrobe(); - TlmRecorder::getInstance().updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); - controllerCorePEQ.notify(payload, BEGIN_WR, command.getStart() - sc_time_stamp()); - break; - case Command::WriteA: - dataStrobe = command.getIntervalOnDataStrobe(); - TlmRecorder::getInstance().updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); - controllerCorePEQ.notify(payload, BEGIN_WRA, command.getStart() - sc_time_stamp()); - break; - case Command::AutoRefresh: - controllerCorePEQ.notify(payload, BEGIN_AUTO_REFRESH, command.getStart() - sc_time_stamp()); - break; - case Command::Activate: - controllerCorePEQ.notify(payload, BEGIN_ACT, command.getStart() - sc_time_stamp()); - break; - case Command::Precharge: - controllerCorePEQ.notify(payload, BEGIN_PRE, command.getStart() - sc_time_stamp()); - break; - case Command::PrechargeAll: - controllerCorePEQ.notify(payload, BEGIN_PRE_ALL, command.getStart() - sc_time_stamp()); - break; - case Command::PDNA: - controllerCorePEQ.notify(payload, BEGIN_PDNA, command.getStart() - sc_time_stamp()); - break; - case Command::PDNP: - controllerCorePEQ.notify(payload, BEGIN_PDNP, command.getStart() - sc_time_stamp()); - break; - case Command::SREF: - controllerCorePEQ.notify(payload, BEGIN_SREF, command.getStart() - sc_time_stamp()); - break; - case Command::PDNAX: - controllerCorePEQ.notify(payload, END_PDNA, command.getEnd() - sc_time_stamp()); - break; - case Command::PDNPX: - controllerCorePEQ.notify(payload, END_PDNP, command.getEnd() - sc_time_stamp()); - break; - case Command::SREFX: - controllerCorePEQ.notify(payload, END_SREF, command.getEnd() - sc_time_stamp()); - break; - - default: - SC_REPORT_FATAL(0, "unsupported command was sent by controller"); - break; - } - } - - virtual void send(Trigger trigger, sc_time time, tlm_generic_payload& payload) override - { - sc_assert(time >= sc_time_stamp()); - - sc_time delay = time - sc_time_stamp(); - if (trigger == Trigger::REFTrigger) - { - controllerCorePEQ.notify(payload, REF_TRIGGER, delay); - } - else if (trigger == Trigger::PDNTrigger) - { - controllerCorePEQ.notify(payload, PDN_TRIGGER, delay); - } - else - { - SC_REPORT_FATAL("controller wrapper", "unknown trigger"); - } - } - - void controllerCorePEQCallback(tlm_generic_payload& payload, const tlm_phase& phase) - { - if (phase == REF_TRIGGER) - { - controllerCore->triggerRefresh(payload, sc_time_stamp()); - } - else if (phase == PDN_TRIGGER) - { - controllerCore->powerDownManager->sleep(DramExtension::getExtension(payload).getBank(),sc_time_stamp()); - } - else - { - Bank bank = DramExtension::getExtension(payload).getBank(); - sendToDram(payload, phase, SC_ZERO_TIME); - - if (phase == BEGIN_RD || phase == BEGIN_WR) - scheduleNextPayload(); - else if (phase == BEGIN_AUTO_REFRESH) - printDebugMessage("Entering auto refresh on bank " + to_string(bank.ID())); - else if (containsPhase(phase, { BEGIN_PDNA, BEGIN_PDNP, BEGIN_SREF })) - printDebugMessage("Entering PowerDown " + phaseNameToString(phase) + " on bank " + to_string(bank.ID())); - else if (containsPhase(phase, { END_PDNA, END_PDNP, END_SREF })) - printDebugMessage("Leaving PowerDown " + phaseNameToString(phase) + " on bank " + to_string(bank.ID())); - else if (containsPhase(phase, { BEGIN_RD, BEGIN_WR, BEGIN_ACT, BEGIN_PRE, BEGIN_PRE_ALL, BEGIN_RDA, BEGIN_WRA })) - { - } - else - SC_REPORT_FATAL(0, "refreshTriggerPEQCallback queue in controller wrapper was triggered with unsupported phase"); - } - } + tlm_utils::simple_initiator_socket iSocket; + tlm_utils::simple_target_socket tSocket; private: + void buildScheduler(); + void payloadEntersSystem(tlm_generic_payload& payload); + void payloadLeavesSystem(tlm_generic_payload& payload); + unsigned int getTotalNumberOfPayloadsInSystem(); + void scheduleNextPayload(); + + // --- FRONTEND ------ + tlm_sync_enum nb_transport_fw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& fwDelay); + void frontendPEQCallback(tlm_generic_payload& payload, const tlm_phase& phase); + void sendToFrontend(tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay); + + // --- DRAM ------ + tlm_sync_enum nb_transport_bw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& bwDelay); + void dramPEQCallback(tlm_generic_payload& payload, const tlm_phase& phase); + void sendToDram(tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay); + + // ------- CONTROLLER CORE --------- + void controllerCorePEQCallback(tlm_generic_payload& payload, const tlm_phase& phase); + + //Helpers + void printDebugMessage(string message); + bool containsPhase(tlm_phase phase, std::vector phases); + ControllerCore* controllerCore; Scheduler* scheduler; std::map numberOfPayloadsInSystem; - tlm::tlm_generic_payload* backpressure = NULL; tlm_utils::peq_with_cb_and_phase frontendPEQ; @@ -221,188 +103,347 @@ private: tlm_utils::peq_with_cb_and_phase controllerCorePEQ; DebugManager& debugManager; - - // --- FRONTEND INTERACTION ------ - tlm_sync_enum nb_transport_fw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& fwDelay) - { - if (phase == BEGIN_REQ) - { - TlmRecorder::getInstance().recordPhase(payload, phase, fwDelay + sc_time_stamp()); - frontendPEQ.notify(payload, phase, - clkAlign(sc_time_stamp() + fwDelay) - (sc_time_stamp() + fwDelay) + Configuration::getInstance().Timings.clk); - } - else if (phase == END_RESP) - { - TlmRecorder::getInstance().recordPhase(payload, phase, - fwDelay + sc_time_stamp() + Configuration::getInstance().Timings.clk); - frontendPEQ.notify(payload, phase, clkAlign(sc_time_stamp() + fwDelay) - (sc_time_stamp() + fwDelay)); - } - return TLM_ACCEPTED; - } - - void frontendPEQCallback(tlm_generic_payload& payload, const tlm_phase& phase) - { - if (phase == BEGIN_REQ) - { - - payload.acquire(); - payloadEntersSystem(payload); - if (getTotalNumberOfPayloadsInSystem() > controllerCore->config.MaxNrOfTransactions) - { - printDebugMessage("##Backpressure: Max number of transactions in system reached"); - backpressure = &payload; - return; - } - payload.set_response_status(tlm::TLM_OK_RESPONSE); - sendToFrontend(payload, END_REQ, SC_ZERO_TIME); - scheduler->schedule(&payload); - scheduleNextPayload(); - } - else if (phase == END_RESP) - { - if (backpressure != NULL) - { - printDebugMessage("##Backpressure released"); - backpressure->set_response_status(tlm::TLM_OK_RESPONSE); - sendToFrontend(*backpressure, END_REQ, SC_ZERO_TIME); - scheduler->schedule(backpressure); - scheduleNextPayload(); - backpressure = NULL; - } - - payloadLeavesSystem(payload); - payload.release(); - } - else - { - SC_REPORT_FATAL(0, "Frontend PEQ event queue in controller wrapper was triggered with unknown phase"); - } - } - - void payloadEntersSystem(tlm_generic_payload& payload) - { - Bank bank = DramExtension::getExtension(payload).getBank(); - printDebugMessage( - "Payload enters system on bank " + to_string(bank.ID()) + ". Total number of payloads in Controller: " - + to_string(getTotalNumberOfPayloadsInSystem())); - numberOfPayloadsInSystem[bank]++; - } - - void payloadLeavesSystem(tlm_generic_payload& payload) - { - Bank bank = DramExtension::getExtension(payload).getBank(); - numberOfPayloadsInSystem[bank]--; - printDebugMessage( - "Payload left system on bank " + to_string(bank.ID()) + ". Total number of payloads in Controller: " - + to_string(getTotalNumberOfPayloadsInSystem())); - controllerCore->powerDownManager->triggerSleep(bank, sc_time_stamp()); - } - - unsigned int getTotalNumberOfPayloadsInSystem() - { - unsigned int sum = 0; - for (Bank bank : controllerCore->getBanks()) - { - sum += numberOfPayloadsInSystem[bank]; - } - return sum; - } - - - void scheduleNextPayload() - { - if(scheduler->hasPayloads()) - { - tlm_generic_payload* payload = scheduler->getNextPayload(); - if(payload != NULL) - { - controllerCore->powerDownManager->wakeUp(DramExtension::getExtension(payload).getBank(), sc_time_stamp()); - bool wasScheduledByCore = controllerCore->scheduleRequest(sc_time_stamp(), *payload); - if (wasScheduledByCore) - { - scheduler->removePayload(payload); - printDebugMessage("\t-> Next payload was scheduled by core"); - } - } - } - } - - void sendToFrontend(tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay) - { - tlm_phase TPhase = phase; - sc_time TDelay = delay; - tSocket->nb_transport_bw(payload, TPhase, TDelay); - } - - // --- DRAM INTERACTION ------ - tlm_sync_enum nb_transport_bw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& bwDelay) - { - dramPEQ.notify(payload, phase, bwDelay); - TlmRecorder::getInstance().recordPhase(payload, phase, bwDelay + sc_time_stamp()); - return TLM_ACCEPTED; - } - - void dramPEQCallback(tlm_generic_payload& payload, const tlm_phase& phase) - { - Bank bank = DramExtension::getExtension(payload).getBank(); - printDebugMessage("Received " + phaseNameToString(phase) + " on bank " + to_string(bank.ID()) + " from DRAM"); - - if (phase == BEGIN_RD || phase == BEGIN_WR) - { - scheduleNextPayload(); - sendToDram(payload, phase, SC_ZERO_TIME); - } - else if (phase == END_RD || phase == END_WR) - { - sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME); - } - else if (phase == END_RDA || phase == END_WRA) - { - sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME); - scheduleNextPayload(); - } - else if (phase == END_AUTO_REFRESH) - { - printDebugMessage("Finished auto refresh on bank " + to_string(bank.ID())); - if(numberOfPayloadsInSystem[bank] == 0) - controllerCore->powerDownManager->sleep(bank,sc_time_stamp()); - scheduleNextPayload(); - } - else if (containsPhase(phase, { END_PRE, END_PRE_ALL, END_ACT })) - { - - } - else - { - string str = string("dramPEQCallback queue in controller wrapper was triggered with unsupported phase ") - + phaseNameToString(phase); - SC_REPORT_FATAL(0, str.c_str()); - } - } - - void sendToDram(tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay) - { - tlm_phase TPhase = phase; - sc_time TDelay = delay; - iSocket->nb_transport_fw(payload, TPhase, TDelay); - } - - //Helpers - void printDebugMessage(string message) - { - debugManager.printDebugMessage(name(), message); - } - - bool containsPhase(tlm_phase phase, std::vector phases) - { - for (tlm_phase p : phases) - { - if (p == phase) - return true; - } - return false; - } - }; + + + +// --- IMPLEMENTATION ----- + +template +void Controller::buildScheduler() +{ + string selectedScheduler = Configuration::getInstance().Scheduler; + + if (selectedScheduler == "FR_FCFS") + { + + scheduler = new FR_FCFS(*controllerCore, Configuration::getInstance().RefreshAwareScheduling, + Configuration::getInstance().AdaptiveOpenPagePolicy); + } + else if (selectedScheduler == "PAR_BS") + { + scheduler = new PAR_BS(*controllerCore, Configuration::getInstance().RefreshAwareScheduling, + Configuration::getInstance().Capsize); + } + else if (selectedScheduler == "FIFO") + scheduler = new Fifo(*controllerCore); + else + reportFatal(name(), "unsupported scheduler: " + selectedScheduler); +} + +template +void Controller::send(const ScheduledCommand &command, tlm_generic_payload &payload) +{ + sc_assert(command.getStart() >= sc_time_stamp()); + TimeInterval dataStrobe; + + switch (command.getCommand()) + { + case Command::Read: + dataStrobe = command.getIntervalOnDataStrobe(); + TlmRecorder::getInstance().updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); + controllerCorePEQ.notify(payload, BEGIN_RD, command.getStart() - sc_time_stamp()); + break; + case Command::ReadA: + dataStrobe = command.getIntervalOnDataStrobe(); + TlmRecorder::getInstance().updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); + controllerCorePEQ.notify(payload, BEGIN_RDA, command.getStart() - sc_time_stamp()); + break; + case Command::Write: + dataStrobe = command.getIntervalOnDataStrobe(); + TlmRecorder::getInstance().updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); + controllerCorePEQ.notify(payload, BEGIN_WR, command.getStart() - sc_time_stamp()); + break; + case Command::WriteA: + dataStrobe = command.getIntervalOnDataStrobe(); + TlmRecorder::getInstance().updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); + controllerCorePEQ.notify(payload, BEGIN_WRA, command.getStart() - sc_time_stamp()); + break; + case Command::AutoRefresh: + controllerCorePEQ.notify(payload, BEGIN_AUTO_REFRESH, command.getStart() - sc_time_stamp()); + break; + case Command::Activate: + controllerCorePEQ.notify(payload, BEGIN_ACT, command.getStart() - sc_time_stamp()); + break; + case Command::Precharge: + controllerCorePEQ.notify(payload, BEGIN_PRE, command.getStart() - sc_time_stamp()); + break; + case Command::PrechargeAll: + controllerCorePEQ.notify(payload, BEGIN_PRE_ALL, command.getStart() - sc_time_stamp()); + break; + case Command::PDNA: + controllerCorePEQ.notify(payload, BEGIN_PDNA, command.getStart() - sc_time_stamp()); + break; + case Command::PDNP: + controllerCorePEQ.notify(payload, BEGIN_PDNP, command.getStart() - sc_time_stamp()); + break; + case Command::SREF: + controllerCorePEQ.notify(payload, BEGIN_SREF, command.getStart() - sc_time_stamp()); + break; + case Command::PDNAX: + controllerCorePEQ.notify(payload, END_PDNA, command.getEnd() - sc_time_stamp()); + break; + case Command::PDNPX: + controllerCorePEQ.notify(payload, END_PDNP, command.getEnd() - sc_time_stamp()); + break; + case Command::SREFX: + controllerCorePEQ.notify(payload, END_SREF, command.getEnd() - sc_time_stamp()); + break; + + default: + SC_REPORT_FATAL(0, "unsupported command was sent by controller"); + break; + } +} + +template +void Controller::send(Trigger trigger, sc_time time, tlm_generic_payload &payload) +{ + sc_assert(time >= sc_time_stamp()); + + sc_time delay = time - sc_time_stamp(); + if (trigger == Trigger::REFTrigger) + { + controllerCorePEQ.notify(payload, REF_TRIGGER, delay); + } + else if (trigger == Trigger::PDNTrigger) + { + controllerCorePEQ.notify(payload, PDN_TRIGGER, delay); + } + else + { + SC_REPORT_FATAL("controller wrapper", "unknown trigger"); + } +} + +template +void Controller::controllerCorePEQCallback(tlm_generic_payload &payload, const tlm_phase &phase) +{ + if (phase == REF_TRIGGER) + { + controllerCore->triggerRefresh(payload, sc_time_stamp()); + } + else if (phase == PDN_TRIGGER) + { + controllerCore->powerDownManager->sleep(DramExtension::getExtension(payload).getBank(),sc_time_stamp()); + } + else + { + Bank bank = DramExtension::getExtension(payload).getBank(); + sendToDram(payload, phase, SC_ZERO_TIME); + + if (phase == BEGIN_RD || phase == BEGIN_WR) + scheduleNextPayload(); + else if (phase == BEGIN_AUTO_REFRESH) + printDebugMessage("Entering auto refresh on bank " + to_string(bank.ID())); + else if (containsPhase(phase, { BEGIN_PDNA, BEGIN_PDNP, BEGIN_SREF })) + printDebugMessage("Entering PowerDown " + phaseNameToString(phase) + " on bank " + to_string(bank.ID())); + else if (containsPhase(phase, { END_PDNA, END_PDNP, END_SREF })) + printDebugMessage("Leaving PowerDown " + phaseNameToString(phase) + " on bank " + to_string(bank.ID())); + else if (containsPhase(phase, { BEGIN_RD, BEGIN_WR, BEGIN_ACT, BEGIN_PRE, BEGIN_PRE_ALL, BEGIN_RDA, BEGIN_WRA })) + { + } + else + SC_REPORT_FATAL(0, "refreshTriggerPEQCallback queue in controller wrapper was triggered with unsupported phase"); + } +} + +template +tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload &payload, tlm_phase &phase, sc_time &fwDelay) +{ + if (phase == BEGIN_REQ) + { + TlmRecorder::getInstance().recordPhase(payload, phase, fwDelay + sc_time_stamp()); + frontendPEQ.notify(payload, phase, + clkAlign(sc_time_stamp() + fwDelay) - (sc_time_stamp() + fwDelay) + Configuration::getInstance().Timings.clk); + } + else if (phase == END_RESP) + { + TlmRecorder::getInstance().recordPhase(payload, phase, + fwDelay + sc_time_stamp() + Configuration::getInstance().Timings.clk); + frontendPEQ.notify(payload, phase, clkAlign(sc_time_stamp() + fwDelay) - (sc_time_stamp() + fwDelay)); + } + return TLM_ACCEPTED; +} + +template +void Controller::frontendPEQCallback(tlm_generic_payload &payload, const tlm_phase &phase) +{ + if (phase == BEGIN_REQ) + { + payload.acquire(); + payloadEntersSystem(payload); + if (getTotalNumberOfPayloadsInSystem() > controllerCore->config.MaxNrOfTransactions) + { + printDebugMessage("##Backpressure: Max number of transactions in system reached"); + backpressure = &payload; + return; + } + payload.set_response_status(tlm::TLM_OK_RESPONSE); + sendToFrontend(payload, END_REQ, SC_ZERO_TIME); + scheduler->schedule(&payload); + scheduleNextPayload(); + } + else if (phase == END_RESP) + { + if (backpressure != NULL) + { + printDebugMessage("##Backpressure released"); + backpressure->set_response_status(tlm::TLM_OK_RESPONSE); + sendToFrontend(*backpressure, END_REQ, SC_ZERO_TIME); + scheduler->schedule(backpressure); + scheduleNextPayload(); + backpressure = NULL; + } + + payloadLeavesSystem(payload); + payload.release(); + } + else + { + SC_REPORT_FATAL(0, "Frontend PEQ event queue in controller wrapper was triggered with unknown phase"); + } +} + +template +void Controller::payloadEntersSystem(tlm_generic_payload &payload) +{ + Bank bank = DramExtension::getExtension(payload).getBank(); + printDebugMessage( + "Payload enters system on bank " + to_string(bank.ID()) + ". Total number of payloads in Controller: " + + to_string(getTotalNumberOfPayloadsInSystem())); + numberOfPayloadsInSystem[bank]++; +} + +template +void Controller::payloadLeavesSystem(tlm_generic_payload &payload) +{ + Bank bank = DramExtension::getExtension(payload).getBank(); + numberOfPayloadsInSystem[bank]--; + printDebugMessage( + "Payload left system on bank " + to_string(bank.ID()) + ". Total number of payloads in Controller: " + + to_string(getTotalNumberOfPayloadsInSystem())); + controllerCore->powerDownManager->triggerSleep(bank, sc_time_stamp()); +} + +template +unsigned int Controller::getTotalNumberOfPayloadsInSystem() +{ + unsigned int sum = 0; + for (Bank bank : controllerCore->getBanks()) + { + sum += numberOfPayloadsInSystem[bank]; + } + return sum; +} + +template +void Controller::scheduleNextPayload() +{ + if(scheduler->hasPayloads()) + { + tlm_generic_payload* payload = scheduler->getNextPayload(); + if(payload != NULL) + { + controllerCore->powerDownManager->wakeUp(DramExtension::getExtension(payload).getBank(), sc_time_stamp()); + bool wasScheduledByCore = controllerCore->scheduleRequest(sc_time_stamp(), *payload); + if (wasScheduledByCore) + { + scheduler->removePayload(payload); + printDebugMessage("\t-> Next payload was scheduled by core"); + } + } + } +} + +template +void Controller::sendToFrontend(tlm_generic_payload &payload, const tlm_phase &phase, const sc_time &delay) +{ + tlm_phase TPhase = phase; + sc_time TDelay = delay; + tSocket->nb_transport_bw(payload, TPhase, TDelay); +} + +template +tlm_sync_enum Controller::nb_transport_bw(tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay) +{ + dramPEQ.notify(payload, phase, bwDelay); + TlmRecorder::getInstance().recordPhase(payload, phase, bwDelay + sc_time_stamp()); + return TLM_ACCEPTED; +} + +template +void Controller::dramPEQCallback(tlm_generic_payload &payload, const tlm_phase &phase) +{ + Bank bank = DramExtension::getExtension(payload).getBank(); + printDebugMessage("Received " + phaseNameToString(phase) + " on bank " + to_string(bank.ID()) + " from DRAM"); + + if (phase == BEGIN_RD || phase == BEGIN_WR) + { + scheduleNextPayload(); + sendToDram(payload, phase, SC_ZERO_TIME); + } + else if (phase == END_RD || phase == END_WR) + { + sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME); + } + else if (phase == END_RDA || phase == END_WRA) + { + sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME); + scheduleNextPayload(); + } + else if (phase == END_AUTO_REFRESH) + { + printDebugMessage("Finished auto refresh on bank " + to_string(bank.ID())); + if(numberOfPayloadsInSystem[bank] == 0) + controllerCore->powerDownManager->sleep(bank,sc_time_stamp()); + scheduleNextPayload(); + } + else if (containsPhase(phase, { END_PRE, END_PRE_ALL, END_ACT })) + { + + } + else + { + string str = string("dramPEQCallback queue in controller wrapper was triggered with unsupported phase ") + + phaseNameToString(phase); + SC_REPORT_FATAL(0, str.c_str()); + } +} + +template +void Controller::sendToDram(tlm_generic_payload &payload, const tlm_phase &phase, const sc_time &delay) +{ + tlm_phase TPhase = phase; + sc_time TDelay = delay; + iSocket->nb_transport_fw(payload, TPhase, TDelay); +} + +template +void Controller::printDebugMessage(string message) +{ + debugManager.printDebugMessage(name(), message); +} + +template +bool Controller::containsPhase(tlm_phase phase, std::vector phases) +{ + for (tlm_phase p : phases) + { + if (p == phase) + return true; + } + return false; +} + +template +void Controller::terminateSimulation() +{ + for (Bank bank : controllerCore->getBanks()) + { + controllerCore->powerDownManager->wakeUp(bank, clkAlign(sc_time_stamp())); + } +} + #endif /* CONTROLLERWRAPPER_H_ */ diff --git a/dram/src/controller/core/ControllerCore.h b/dram/src/controller/core/ControllerCore.h index a0bcd3a6..66238e67 100644 --- a/dram/src/controller/core/ControllerCore.h +++ b/dram/src/controller/core/ControllerCore.h @@ -34,13 +34,12 @@ public: void saveState(); void resetState(); - const std::vector& getBanks(); std::vector getFreeBanks(sc_time currentTime); const RowBufferState& getRowBufferStates(){return state.rowBufferStates;} - void send(const CommandSchedule& schedule, tlm::tlm_generic_payload& payload) const; ICommandChecker& getCommandChecker(Command command); + static void printDebugMessage(string message); Configuration config; ControllerState state; @@ -50,9 +49,10 @@ public: IRefreshManager* refreshManager; std::map& numberOfPayloads; static std::string senderName; - static void printDebugMessage(string message); private: + void send(const CommandSchedule& schedule, tlm::tlm_generic_payload& payload) const; + std::map commandChecker; ControllerState savedState; CommandSequenceGenerator commandSequenceGenerator; diff --git a/dram/src/controller/core/TimingCalculation.cpp b/dram/src/controller/core/TimingCalculation.cpp index 8c126058..b9dafb6a 100644 --- a/dram/src/controller/core/TimingCalculation.cpp +++ b/dram/src/controller/core/TimingCalculation.cpp @@ -80,7 +80,7 @@ sc_time getExecutionTime(Command command, tlm::tlm_generic_payload& payload) } } -sc_time getMinimalExecutionTime(Command command, tlm::tlm_generic_payload& payload) +sc_time getMinExecutionTimeForPowerDownCmd(Command command) { TimingConfiguration& config = Configuration::getInstance().Timings; if (command == Command::PDNA || command == Command::PDNP) @@ -107,7 +107,7 @@ bool isClkAligned(sc_time time, sc_time clk) sc_time getReadAccessTime() { Configuration& config = Configuration::getInstance(); - return config.BurstLength/config.DataRate*config.Timings.clk; + return (config.BurstLength / config.DataRate)*config.Timings.clk; } sc_time getWriteAccessTime() @@ -120,7 +120,7 @@ sc_time getWriteAccessTime() } else { - return config.Timings.clk * config.BurstLength / config.DataRate; + return config.Timings.clk * (config.BurstLength / config.DataRate); } } diff --git a/dram/src/controller/core/TimingCalculation.h b/dram/src/controller/core/TimingCalculation.h index 88c40dea..9ba13135 100644 --- a/dram/src/controller/core/TimingCalculation.h +++ b/dram/src/controller/core/TimingCalculation.h @@ -16,7 +16,7 @@ namespace core { -sc_time getMinimalExecutionTime(Command command, tlm::tlm_generic_payload& payload); +sc_time getMinExecutionTimeForPowerDownCmd(Command command); sc_time getExecutionTime(Command command, tlm::tlm_generic_payload& payload); sc_time getReadAccessTime(); diff --git a/dram/src/controller/core/powerdown/PowerDownManager.cpp b/dram/src/controller/core/powerdown/PowerDownManager.cpp index 687b22cd..f49ec845 100644 --- a/dram/src/controller/core/powerdown/PowerDownManager.cpp +++ b/dram/src/controller/core/powerdown/PowerDownManager.cpp @@ -59,7 +59,7 @@ void PowerDownManager::sleep(Bank bank, sc_time time) } Command cmd = IPowerDownManager::getSleepCommand(state); - ScheduledCommand pdn(cmd, time, getMinimalExecutionTime(cmd, powerDownPayloads[bank]), + ScheduledCommand pdn(cmd, time, getMinExecutionTimeForPowerDownCmd(cmd), DramExtension::getExtension(powerDownPayloads[bank])); controller.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); diff --git a/dram/src/controller/core/powerdown/PowerDownManager.h b/dram/src/controller/core/powerdown/PowerDownManager.h index a70e8027..2b1dad8f 100644 --- a/dram/src/controller/core/powerdown/PowerDownManager.h +++ b/dram/src/controller/core/powerdown/PowerDownManager.h @@ -17,26 +17,25 @@ class ControllerCore; class PowerDownManager: public IPowerDownManager { public: - PowerDownManager(ControllerCore& controller); - virtual ~PowerDownManager(); + PowerDownManager(ControllerCore& controller); + virtual ~PowerDownManager(); - virtual void triggerSleep(Bank bank, sc_time time) override; - virtual void sleep(Bank bank, sc_time time) override; - virtual void wakeUp(Bank bank, sc_time time) override; - virtual void wakeUpForRefresh(Bank bank, sc_time time) override; + virtual void triggerSleep(Bank bank, sc_time time) override; + virtual void sleep(Bank bank, sc_time time) override; + virtual void wakeUp(Bank bank, sc_time time) override; + virtual void wakeUpForRefresh(Bank bank, sc_time time) override; + virtual bool isInSelfRefresh(Bank bank) override; - virtual bool isInSelfRefresh(Bank bank) override; private: - PowerDownState powerDownState; - void sendPowerDownPayloads(ScheduledCommand& cmd); + void sendPowerDownPayloads(ScheduledCommand& cmd); + bool isInPowerDown(); + void setPowerDownState(PowerDownState state); + bool canSleep(); + bool isAwakeForRefresh(); - bool isInPowerDown(); - - void setPowerDownState(PowerDownState state); - bool canSleep(); - bool isAwakeForRefresh(); - std::map powerDownPayloads; - ControllerCore& controller; + PowerDownState powerDownState; + std::map powerDownPayloads; + ControllerCore& controller; }; } /* namespace core */ diff --git a/dram/src/controller/core/powerdown/PowerDownManagerBankwise.cpp b/dram/src/controller/core/powerdown/PowerDownManagerBankwise.cpp index db1448e9..92c6aa0c 100644 --- a/dram/src/controller/core/powerdown/PowerDownManagerBankwise.cpp +++ b/dram/src/controller/core/powerdown/PowerDownManagerBankwise.cpp @@ -17,135 +17,135 @@ namespace core { std::string PowerDownManagerBankwise::senderName = "pdn manager"; PowerDownManagerBankwise::PowerDownManagerBankwise(ControllerCore& controller) : - controller(controller) + controller(controller) { - for (Bank bank : controller.getBanks()) - { - setUpDummy(powerDownPayloads[bank], bank); - powerDownStates[bank] = PowerDownState::Awake; - } + for (Bank bank : controller.getBanks()) + { + setUpDummy(powerDownPayloads[bank], bank); + powerDownStates[bank] = PowerDownState::Awake; + } } void PowerDownManagerBankwise::sleep(Bank bank, sc_time time) { - if (!canSleep(bank) || isInPowerDown(bank)) - return; + if (!canSleep(bank) || isInPowerDown(bank)) + return; - tlm_generic_payload& payload = powerDownPayloads[bank]; + tlm_generic_payload& payload = powerDownPayloads[bank]; - PowerDownState state = powerDownStates[bank]; - if (state == PowerDownState::Awake) //coming from active - { - state = controller.state.rowBufferStates.rowBufferIsOpen(bank) ? PowerDownState::PDNActive : PowerDownState::PDNPrecharge; - } - else if (state == PowerDownState::AwakeForRefresh) //coming from refresh interrupting power down - { - sc_assert(!controller.state.rowBufferStates.rowBufferIsOpen(bank)); + PowerDownState state = powerDownStates[bank]; + if (state == PowerDownState::Awake) //coming from active + { + state = controller.state.rowBufferStates.rowBufferIsOpen(bank) ? PowerDownState::PDNActive : PowerDownState::PDNPrecharge; + } + else if (state == PowerDownState::AwakeForRefresh) //coming from refresh interrupting power down + { + sc_assert(!controller.state.rowBufferStates.rowBufferIsOpen(bank)); - if (controller.state.getLastCommand(Command::PDNA, bank).getStart() - >= controller.state.getLastCommand(Command::PDNP, bank).getStart()) - state = PowerDownState::PDNPrecharge; - else - { - state = PowerDownState::PDNSelfRefresh; - } - } + if (controller.state.getLastCommand(Command::PDNA, bank).getStart() + >= controller.state.getLastCommand(Command::PDNP, bank).getStart()) + state = PowerDownState::PDNPrecharge; + else + { + state = PowerDownState::PDNSelfRefresh; + } + } - Command cmd = IPowerDownManager::getSleepCommand(state); - ScheduledCommand pdn(cmd, time, getMinimalExecutionTime(cmd, payload), DramExtension::getExtension(payload)); - controller.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); + Command cmd = IPowerDownManager::getSleepCommand(state); + ScheduledCommand pdn(cmd, time, getMinExecutionTimeForPowerDownCmd(cmd), DramExtension::getExtension(payload)); + controller.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); - if (state != PowerDownState::PDNSelfRefresh && controller.refreshManager->hasCollision(pdn)) - { - return; - } - else - { - setState(state, bank); - sendPowerDownPayload(pdn); - } + if (state != PowerDownState::PDNSelfRefresh && controller.refreshManager->hasCollision(pdn)) + { + return; + } + else + { + setState(state, bank); + sendPowerDownPayload(pdn); + } } void PowerDownManagerBankwise::wakeUp(Bank bank, sc_time time) { - if (isAwakeForRefresh(bank)) - { - setState(PowerDownState::Awake, bank); - } - else if (isInPowerDown(bank)) - { - //Request wakes up power down - Command cmd = IPowerDownManager::getWakeUpCommand(powerDownStates[bank]); - ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]), - DramExtension::getExtension(powerDownPayloads[bank])); - controller.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); + if (isAwakeForRefresh(bank)) + { + setState(PowerDownState::Awake, bank); + } + else if (isInPowerDown(bank)) + { + //Request wakes up power down + Command cmd = IPowerDownManager::getWakeUpCommand(powerDownStates[bank]); + ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]), + DramExtension::getExtension(powerDownPayloads[bank])); + controller.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); - if (cmd == Command::SREFX) - controller.refreshManager->reInitialize(bank, pdn.getEnd()); + if (cmd == Command::SREFX) + controller.refreshManager->reInitialize(bank, pdn.getEnd()); - setState(PowerDownState::Awake, bank); - sendPowerDownPayload(pdn); - } + setState(PowerDownState::Awake, bank); + sendPowerDownPayload(pdn); + } } void PowerDownManagerBankwise::wakeUpForRefresh(Bank bank, sc_time time) { - if (isInPowerDown(bank)) - { - Command cmd = IPowerDownManager::getWakeUpCommand(powerDownStates[bank]); - ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]), - DramExtension::getExtension(powerDownPayloads[bank])); + if (isInPowerDown(bank)) + { + Command cmd = IPowerDownManager::getWakeUpCommand(powerDownStates[bank]); + ScheduledCommand pdn(cmd, time, getExecutionTime(cmd, powerDownPayloads[bank]), + DramExtension::getExtension(powerDownPayloads[bank])); - setState(PowerDownState::AwakeForRefresh, bank); - sendPowerDownPayload(pdn); - } + setState(PowerDownState::AwakeForRefresh, bank); + sendPowerDownPayload(pdn); + } } bool PowerDownManagerBankwise::isInPowerDown(Bank bank) { - return isIn(powerDownStates[bank], - { PowerDownState::PDNActive, PowerDownState::PDNPrecharge, PowerDownState::PDNSelfRefresh }); + return isIn(powerDownStates[bank], + { PowerDownState::PDNActive, PowerDownState::PDNPrecharge, PowerDownState::PDNSelfRefresh }); } bool PowerDownManagerBankwise::isInSelfRefresh(Bank bank) { - return powerDownStates[bank] == PowerDownState::PDNSelfRefresh; + return powerDownStates[bank] == PowerDownState::PDNSelfRefresh; } bool PowerDownManagerBankwise::isAwakeForRefresh(Bank bank) { - return powerDownStates[bank] == PowerDownState::AwakeForRefresh; + return powerDownStates[bank] == PowerDownState::AwakeForRefresh; } bool PowerDownManagerBankwise::isAwake(Bank bank) { - return powerDownStates[bank] == PowerDownState::Awake; + return powerDownStates[bank] == PowerDownState::Awake; } void PowerDownManagerBankwise::setState(PowerDownState state, Bank bank) { - PowerDownState& bankstate = powerDownStates[bank]; - bankstate = state; + PowerDownState& bankstate = powerDownStates[bank]; + bankstate = state; - DebugManager::getInstance().printDebugMessage(PowerDownManagerBankwise::senderName, - "Is now in state " + powerDownStateToString(state) + " on Bank " + to_string(bank.ID())); + DebugManager::getInstance().printDebugMessage(PowerDownManagerBankwise::senderName, + "Is now in state " + powerDownStateToString(state) + " on Bank " + to_string(bank.ID())); } void PowerDownManagerBankwise::sendPowerDownPayload(ScheduledCommand& pdn) { - controller.state.bus.moveCommandToNextFreeSlot(pdn); - controller.state.change(pdn); - controller.wrapper.send(pdn, powerDownPayloads[pdn.getBank()]); + controller.state.bus.moveCommandToNextFreeSlot(pdn); + controller.state.change(pdn); + controller.wrapper.send(pdn, powerDownPayloads[pdn.getBank()]); } bool PowerDownManagerBankwise::canSleep(Bank bank) { - return controller.numberOfPayloads[bank] == 0; + return controller.numberOfPayloads[bank] == 0; } void PowerDownManagerBankwise::triggerSleep(Bank bank, sc_time time) { - sleep(bank, time); + sleep(bank, time); } }/* namespace core */ diff --git a/dram/src/controller/core/powerdown/PowerDownManagerTimeout.cpp b/dram/src/controller/core/powerdown/PowerDownManagerTimeout.cpp index 4f82b3cb..2910ebd3 100644 --- a/dram/src/controller/core/powerdown/PowerDownManagerTimeout.cpp +++ b/dram/src/controller/core/powerdown/PowerDownManagerTimeout.cpp @@ -42,7 +42,7 @@ void PowerDownManagerTimeout::sleep(Bank bank, sc_time time) } Command cmd = IPowerDownManager::getSleepCommand(newState); - ScheduledCommand pdn(cmd, time, getMinimalExecutionTime(cmd, powerDownPayloads[bank]), + ScheduledCommand pdn(cmd, time, getMinExecutionTimeForPowerDownCmd(cmd), DramExtension::getExtension(powerDownPayloads[bank])); controller.getCommandChecker(cmd).delayToSatisfyConstraints(pdn); diff --git a/dram/src/controller/core/refresh/RefreshManager.h b/dram/src/controller/core/refresh/RefreshManager.h index aecb20b3..78280076 100644 --- a/dram/src/controller/core/refresh/RefreshManager.h +++ b/dram/src/controller/core/refresh/RefreshManager.h @@ -18,28 +18,26 @@ class ControllerCore; class RefreshManager : public IRefreshManager { public: - RefreshManager(ControllerCore& controller); - virtual ~RefreshManager(); + RefreshManager(ControllerCore& controller); + virtual ~RefreshManager(); - virtual bool hasCollision(const CommandSchedule& schedule) override; - virtual bool hasCollision(const ScheduledCommand& command) override; + virtual bool hasCollision(const CommandSchedule& schedule) override; + virtual bool hasCollision(const ScheduledCommand& command) override; - - virtual void scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time) override; - void reInitialize(Bank bank, sc_time time) override; - - virtual bool isInvalidated(tlm::tlm_generic_payload& payload, sc_time time) override; + virtual void scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time time) override; + void reInitialize(Bank bank, sc_time time) override; + virtual bool isInvalidated(tlm::tlm_generic_payload& payload, sc_time time) override; private: - ControllerCore& controller; - RefreshTiming& timing; - sc_time nextPlannedRefresh; - std::map refreshPayloads; + ControllerCore& controller; + RefreshTiming& timing; + sc_time nextPlannedRefresh; + std::map refreshPayloads; - void planNextRefresh(); + void planNextRefresh(); - void sendToAllBanks(ScheduledCommand& command); - void setupTransactions(); + void sendToAllBanks(ScheduledCommand& command); + void setupTransactions(); }; } /* namespace core */ diff --git a/dram/src/simulation/Simulation.h b/dram/src/simulation/Simulation.h index 6971a93d..463911e9 100644 --- a/dram/src/simulation/Simulation.h +++ b/dram/src/simulation/Simulation.h @@ -51,8 +51,6 @@ public: void inline transactionFinished() override; constexpr static unsigned int NumberOfTracePlayers = 4; - void bindSockets(); - void calculateNumberOfTransaction(std::vector devices, string pathToResources); private: std::string traceName; DramSetup dramSetup; @@ -77,6 +75,8 @@ private: void setupDebugManager(const string& traceName); void setupTlmRecorder(const string &traceName, const string &pathToResources, const DramSetup &setup, const std::vector &devices); void instantiateModules(const string &pathToResources, const std::vector &devices); + void bindSockets(); + void calculateNumberOfTransaction(std::vector devices, string pathToResources); }; } /* namespace simulation */ From 8467945a3a5ea3cec6145bd2d266ed64890ed072 Mon Sep 17 00:00:00 2001 From: robert Date: Thu, 3 Jul 2014 13:57:39 +0200 Subject: [PATCH 09/13] minor refactoring --- dram/src/common/Utils.h | 9 ++++++--- dram/src/controller/Controller.h | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/dram/src/common/Utils.h b/dram/src/common/Utils.h index df203010..c13aab22 100644 --- a/dram/src/common/Utils.h +++ b/dram/src/common/Utils.h @@ -17,8 +17,8 @@ #include "third_party/tinyxml2.h" #include +//TODO : move to timing specific header sc_time getDistance(sc_time a, sc_time b); - struct TimeInterval { sc_time start,end; @@ -69,11 +69,15 @@ static inline void loadbar(unsigned int x, unsigned int n, unsigned int w = 50, std::cout << "]\r" << std::flush; } +//TODO : Move to debug manager void reportFatal(std::string sender, std::string message); std::string phaseNameToString(tlm::tlm_phase phase); + + +//TODO : Move to other source specific to xml +std::string getFileName(std::string uri); bool parameterExists(tinyxml2::XMLElement* node, std::string name); std::string loadTextFileContents(std::string filename); - void loadXML(std::string uri, tinyxml2::XMLDocument& doc); unsigned int queryUIntParameter(tinyxml2::XMLElement* node, std::string name); std::string queryStringParameter(tinyxml2::XMLElement* node, std::string name); @@ -82,6 +86,5 @@ double queryDoubleParameter(tinyxml2::XMLElement* node, std::string name); void setUpDummy(tlm::tlm_generic_payload& payload, Bank& bank); -std::string getFileName(std::string uri); #endif /* UTILS_COMMON_H_ */ diff --git a/dram/src/controller/Controller.h b/dram/src/controller/Controller.h index 4f8d22d7..5342a992 100644 --- a/dram/src/controller/Controller.h +++ b/dram/src/controller/Controller.h @@ -89,7 +89,7 @@ private: // ------- CONTROLLER CORE --------- void controllerCorePEQCallback(tlm_generic_payload& payload, const tlm_phase& phase); - //Helpers + //Helpers TODO move them void printDebugMessage(string message); bool containsPhase(tlm_phase phase, std::vector phases); From b8febb434ff6af2e747d4d6dd0c23c1bfaa8c9b9 Mon Sep 17 00:00:00 2001 From: robert Date: Sun, 6 Jul 2014 10:34:46 +0200 Subject: [PATCH 10/13] minor refactoring --- dram/dramSys/dramSys.pro | 6 +- dram/resources/configs/memconfigs/fifo.xml | 2 +- dram/resources/configs/memconfigs/fr_fcfs.xml | 2 +- dram/src/common/TlmRecorder.cpp | 28 +- dram/src/common/TlmRecorder.h | 22 +- dram/src/common/Utils.h | 1 + dram/src/common/dramExtension.cpp | 243 ++++++++++-------- dram/src/common/dramExtension.h | 123 ++++----- dram/src/controller/Controller.h | 9 +- dram/src/controller/core/ControllerCore.cpp | 14 +- dram/src/controller/core/ControllerCore.h | 14 +- .../core/refresh/RefreshManager.cpp | 2 +- .../core/refresh/RefreshManagerBankwise.cpp | 2 +- .../core/scheduling/ScheduledCommand.cpp | 6 +- dram/src/controller/scheduler/Fifo.cpp | 2 +- dram/src/controller/scheduler/Fr_Fcfs.cpp | 2 +- dram/src/controller/scheduler/PARBS.h | 2 + dram/src/controller/scheduler/Scheduler.h | 6 - .../controller/scheduler/readwritegrouper.cpp | 121 +++++++++ .../controller/scheduler/readwritegrouper.h | 40 +++ dram/src/simulation/TracePlayer.h | 229 +++++++++-------- 21 files changed, 534 insertions(+), 342 deletions(-) create mode 100644 dram/src/controller/scheduler/readwritegrouper.cpp create mode 100644 dram/src/controller/scheduler/readwritegrouper.h diff --git a/dram/dramSys/dramSys.pro b/dram/dramSys/dramSys.pro index 8672da99..65291f71 100644 --- a/dram/dramSys/dramSys.pro +++ b/dram/dramSys/dramSys.pro @@ -57,7 +57,8 @@ SOURCES += \ ../src/simulation/main.cpp \ ../src/common/libDRAMPower.cpp \ ../src/controller/core/RowBufferStates.cpp \ - ../src/controller/scheduler/Scheduler.cpp + ../src/controller/scheduler/Scheduler.cpp \ + ../src/controller/scheduler/readwritegrouper.cpp HEADERS += \ ../src/common/third_party/tinyxml2.h \ @@ -112,6 +113,7 @@ HEADERS += \ ../src/simulation/Dram.h \ ../src/simulation/Arbiter.h \ ../src/common/libDRAMPower.h \ - ../src/controller/core/RowBufferStates.h + ../src/controller/core/RowBufferStates.h \ + ../src/controller/scheduler/readwritegrouper.h diff --git a/dram/resources/configs/memconfigs/fifo.xml b/dram/resources/configs/memconfigs/fifo.xml index 3bf15c45..2e23e330 100644 --- a/dram/resources/configs/memconfigs/fifo.xml +++ b/dram/resources/configs/memconfigs/fifo.xml @@ -10,6 +10,6 @@ - + diff --git a/dram/resources/configs/memconfigs/fr_fcfs.xml b/dram/resources/configs/memconfigs/fr_fcfs.xml index a57c0e84..b126adb1 100644 --- a/dram/resources/configs/memconfigs/fr_fcfs.xml +++ b/dram/resources/configs/memconfigs/fr_fcfs.xml @@ -10,6 +10,6 @@ - + diff --git a/dram/src/common/TlmRecorder.cpp b/dram/src/common/TlmRecorder.cpp index 56c2cee6..1b69b89a 100644 --- a/dram/src/common/TlmRecorder.cpp +++ b/dram/src/common/TlmRecorder.cpp @@ -17,7 +17,7 @@ bool TlmRecorder::recordingEnabled = true; // ------------- public ----------------------- TlmRecorder::TlmRecorder() : - transactionIDCounter(1), recordingEndTime(SC_ZERO_TIME) + totalNumTransactions(1), simulationTimeCoveredByRecording(SC_ZERO_TIME) { if(recordingEnabled) { @@ -73,7 +73,7 @@ void TlmRecorder::recordPhase(tlm::tlm_generic_payload& trans, tlm::tlm_phase ph if (phaseTerminatesTransaction) removeTransactionFromSystem(trans); - recordingEndTime = time; + simulationTimeCoveredByRecording = time; } } @@ -100,7 +100,7 @@ void TlmRecorder::recordDebugMessage(std::string message, sc_time time) void TlmRecorder::introduceTransactionSystem(tlm::tlm_generic_payload& trans) { - unsigned int id = transactionIDCounter++; + unsigned int id = totalNumTransactions++; currentTransactionsInSystem[&trans].id = id; currentTransactionsInSystem[&trans].address = trans.get_address(); currentTransactionsInSystem[&trans].burstlength = trans.get_streaming_width(); @@ -124,7 +124,7 @@ void TlmRecorder::removeTransactionFromSystem(tlm::tlm_generic_payload& trans) { assert(currentTransactionsInSystem.count(&trans) != 0); - RecordingData& recordingData = currentTransactionsInSystem[&trans]; + Transaction& recordingData = currentTransactionsInSystem[&trans]; recordedData.push_back(recordingData); currentTransactionsInSystem.erase(&trans); } @@ -132,11 +132,11 @@ void TlmRecorder::removeTransactionFromSystem(tlm::tlm_generic_payload& trans) void TlmRecorder::commitRecordedDataToDB() { sqlite3_exec(db, "BEGIN;", 0, 0, 0); - for(RecordingData& recordingData: recordedData) + for(Transaction& recordingData: recordedData) { assert(recordingData.recordedPhases.size() > 0); insertTransactionInDB(recordingData); - for(RecordingData::PhaseData& phaseData: recordingData.recordedPhases) + for(Transaction::Phase& phaseData: recordingData.recordedPhases) { insertPhaseInDB(phaseData.name,phaseData.interval.start,phaseData.interval.end,recordingData.id); } @@ -151,14 +151,14 @@ void TlmRecorder::commitRecordedDataToDB() } -void TlmRecorder::RecordingData::insertPhase(string name, sc_time begin) +void TlmRecorder::Transaction::insertPhase(string name, sc_time begin) { - recordedPhases.push_back(PhaseData(name,begin)); + recordedPhases.push_back(Phase(name,begin)); } -void TlmRecorder::RecordingData::setPhaseEnd(string name, sc_time end) +void TlmRecorder::Transaction::setPhaseEnd(string name, sc_time end) { - for(PhaseData& data: recordedPhases) + for(Phase& data: recordedPhases) { if(data.name == name) { @@ -233,8 +233,8 @@ void TlmRecorder::insertDebugMessageInDB(string message, const sc_time& time) void TlmRecorder::insertGeneralInfo() { - sqlite3_bind_int64(insertGeneralInfoStatement, 1, transactionIDCounter - 1); - sqlite3_bind_int64(insertGeneralInfoStatement, 2, recordingEndTime.value()); + sqlite3_bind_int64(insertGeneralInfoStatement, 1, totalNumTransactions - 1); + sqlite3_bind_int64(insertGeneralInfoStatement, 2, simulationTimeCoveredByRecording.value()); sqlite3_bind_int(insertGeneralInfoStatement, 3, core::Configuration::getInstance().NumberOfBanks); sqlite3_bind_int(insertGeneralInfoStatement, 4, core::Configuration::getInstance().Timings.clk.value()); @@ -245,7 +245,7 @@ void TlmRecorder::insertGeneralInfo() executeSqlStatement(insertGeneralInfoStatement); } -void TlmRecorder::insertTransactionInDB(RecordingData& recordingData) +void TlmRecorder::insertTransactionInDB(Transaction& recordingData) { sqlite3_bind_int(insertTransactionStatement, 1, recordingData.id); sqlite3_bind_int(insertTransactionStatement, 2, recordingData.id); @@ -319,7 +319,7 @@ void TlmRecorder::closeConnection() commitRecordedDataToDB(); insertGeneralInfo(); printDebugMessage( - "Number of transactions written to DB: " + std::to_string(transactionIDCounter - 1)); + "Number of transactions written to DB: " + std::to_string(totalNumTransactions - 1)); printDebugMessage("tlmPhaseRecorder:\tEnd Recording"); sqlite3_close(db); db = NULL; diff --git a/dram/src/common/TlmRecorder.h b/dram/src/common/TlmRecorder.h index 3a4e83bf..e832e744 100755 --- a/dram/src/common/TlmRecorder.h +++ b/dram/src/common/TlmRecorder.h @@ -43,10 +43,10 @@ public: private: - struct RecordingData + struct Transaction { - RecordingData(){} - RecordingData(unsigned int id):id(id){} + Transaction(){} + Transaction(unsigned int id):id(id){} unsigned int id; unsigned int address; @@ -55,13 +55,13 @@ private: sc_time timeOfGeneration; TimeInterval timeOnDataStrobe; - struct PhaseData + struct Phase { - PhaseData(string name,sc_time begin): name(name), interval(begin,SC_ZERO_TIME){} + Phase(string name,sc_time begin): name(name), interval(begin,SC_ZERO_TIME){} string name; TimeInterval interval; }; - std::vector recordedPhases; + std::vector recordedPhases; void insertPhase(string name,sc_time begin); void setPhaseEnd(string name,sc_time end); @@ -85,7 +85,7 @@ private: void commitRecordedDataToDB(); void insertGeneralInfo(); - void insertTransactionInDB(RecordingData& recordingData); + void insertTransactionInDB(Transaction& recordingData); void insertRangeInDB(unsigned int id, const sc_time& begin, const sc_time& end); void insertPhaseInDB(string phaseName, const sc_time& begin, const sc_time& end, unsigned int transactionID); void insertDebugMessageInDB(string message, const sc_time& time); @@ -93,11 +93,11 @@ private: void printDebugMessage(std::string message); static const int transactionCommitRate = 1000; - vector recordedData; - map currentTransactionsInSystem; + vector recordedData; + map currentTransactionsInSystem; - unsigned int transactionIDCounter; - sc_time recordingEndTime; + unsigned int totalNumTransactions; + sc_time simulationTimeCoveredByRecording; std::vector transactionTerminatingPhases; sqlite3 *db; diff --git a/dram/src/common/Utils.h b/dram/src/common/Utils.h index c13aab22..acb5b93b 100644 --- a/dram/src/common/Utils.h +++ b/dram/src/common/Utils.h @@ -19,6 +19,7 @@ //TODO : move to timing specific header sc_time getDistance(sc_time a, sc_time b); + struct TimeInterval { sc_time start,end; diff --git a/dram/src/common/dramExtension.cpp b/dram/src/common/dramExtension.cpp index a3ac2202..8b9d34d3 100644 --- a/dram/src/common/dramExtension.cpp +++ b/dram/src/common/dramExtension.cpp @@ -5,9 +5,22 @@ using namespace tlm; -/* Static methods - * - */ + +DramExtension::DramExtension() : + thread(0), channel(0), bank(0), bankgroup(0), row(0), column(0), burstlength(0) +{ +} + +DramExtension::DramExtension(const Thread &thread, const Bank &bank, const BankGroup &bankgroup, const Row &row, const Column &column, unsigned int burstlength) : + thread(thread), channel(0), bank(bank), bankgroup(bankgroup), row(row), column(column), burstlength(burstlength) +{ +} + +DramExtension::DramExtension(const Thread &thread, const Channel &channel, const Bank &bank, const BankGroup &bankgroup, const Row &row, const Column &column, unsigned int burstlength) : + thread(thread), channel(channel), bank(bank), bankgroup(bankgroup), row(row), column(column), burstlength(burstlength) +{ +} + DramExtension& DramExtension::getExtension(const tlm_generic_payload *payload) { DramExtension *result = NULL; @@ -22,108 +35,12 @@ DramExtension& DramExtension::getExtension(const tlm_generic_payload &payload) return DramExtension::getExtension(&payload); } -bool operator ==(const Thread& lhs, const Thread& rhs) -{ - return lhs.ID() == rhs.ID(); -} - -bool operator !=(const Thread& lhs, const Thread& rhs) -{ - return !(lhs == rhs); -} - -bool operator <(const Thread& lhs, const Thread& rhs) -{ - return lhs.ID() < rhs.ID(); -} - -bool operator ==(const Channel& lhs, const Channel& rhs) -{ - return lhs.ID() == rhs.ID(); -} - -bool operator !=(const Channel& lhs, const Channel& rhs) -{ - return !(lhs == rhs); -} - -BankGroup Bank::getBankGroup() -{ - static std::map bankgroups; - if (bankgroups.size() == 0) - { - core::Configuration& config = core::Configuration::getInstance(); - sc_assert(config.NumberOfBanks % config.NumberOfBankGroups == 0); - - for (unsigned int bank = 0; bank < config.NumberOfBanks; bank++) - { - unsigned int group = bank % config.NumberOfBankGroups; - bankgroups.insert(std::pair(Bank(bank), BankGroup(group))); - } - } - - return getElementFromMap(bankgroups, *this); -} - -bool operator ==(const Bank& lhs, const Bank& rhs) -{ - return lhs.ID() == rhs.ID(); -} - -bool operator !=(const Bank& lhs, const Bank& rhs) -{ - return !(lhs == rhs); -} - -bool operator ==(const BankGroup& lhs, const BankGroup& rhs) -{ - return lhs.ID() == rhs.ID(); -} - -bool operator !=(const BankGroup& lhs, const BankGroup& rhs) -{ - return !(lhs == rhs); -} - -bool operator <(const Bank& lhs, const Bank& rhs) -{ - return lhs.ID() < rhs.ID(); -} - -const Row Row::NO_ROW; - -const Row Row::operator ++() -{ - id = (id + 1) % core::Configuration::getInstance().NumberOfRows; - return *this; -} - -bool operator ==(const Row& lhs, const Row& rhs) -{ - if (lhs.isNoRow != rhs.isNoRow) - return false; - return lhs.ID() == rhs.ID(); -} - -bool operator !=(const Row& lhs, const Row& rhs) -{ - return !(lhs == rhs); -} - -bool operator ==(const Column& lhs, const Column& rhs) -{ - return lhs.ID() == rhs.ID(); -} - -bool operator !=(const Column& lhs, const Column& rhs) -{ - return !(lhs == rhs); -} tlm_extension_base* DramExtension::clone() const { return new DramExtension(thread, bank, bankgroup, row, column, burstlength); } + void DramExtension::copy_from(const tlm_extension_base& ext) { const DramExtension& cpyFrom = static_cast(ext); @@ -135,29 +52,32 @@ void DramExtension::copy_from(const tlm_extension_base& ext) burstlength = cpyFrom.burstlength; } -const Thread& DramExtension::getThread() const +Thread DramExtension::getThread() const { return thread; } -const Channel& DramExtension::getChannel() const + +Channel DramExtension::getChannel() const { return channel; } -const Bank& DramExtension::getBank() const + +Bank DramExtension::getBank() const { return bank; } -const BankGroup& DramExtension::getBankGroup() const + +BankGroup DramExtension::getBankGroup() const { return bankgroup; } -const Row& DramExtension::getRow() const +Row DramExtension::getRow() const { return row; } -const Column& DramExtension::getColumn() const +Column DramExtension::getColumn() const { return column; } @@ -167,7 +87,7 @@ unsigned int DramExtension::getBurstlength() const return burstlength; } -void DramExtension::increaseRow() +void DramExtension::incrementRow() { ++row; } @@ -191,3 +111,112 @@ GenerationExtension& GenerationExtension::getExtension(const tlm::tlm_generic_pa sc_assert(result!=NULL); return *result; } + + +//TODO remove this nonsense, put it in xml +BankGroup Bank::getBankGroup() +{ + static std::map bankgroups; + if (bankgroups.size() == 0) + { + core::Configuration& config = core::Configuration::getInstance(); + sc_assert(config.NumberOfBanks % config.NumberOfBankGroups == 0); + + for (unsigned int bank = 0; bank < config.NumberOfBanks; bank++) + { + unsigned int group = bank % config.NumberOfBankGroups; + bankgroups.insert(std::pair(Bank(bank), BankGroup(group))); + } + } + + return getElementFromMap(bankgroups, *this); +} + + +//THREAD +bool operator ==(const Thread& lhs, const Thread& rhs) +{ + return lhs.ID() == rhs.ID(); +} + +bool operator !=(const Thread& lhs, const Thread& rhs) +{ + return !(lhs == rhs); +} + +bool operator <(const Thread& lhs, const Thread& rhs) +{ + return lhs.ID() < rhs.ID(); +} + +//CHANNEL +bool operator ==(const Channel& lhs, const Channel& rhs) +{ + return lhs.ID() == rhs.ID(); +} + +bool operator !=(const Channel& lhs, const Channel& rhs) +{ + return !(lhs == rhs); +} + + +//BANKGROUP +bool operator ==(const BankGroup& lhs, const BankGroup& rhs) +{ + return lhs.ID() == rhs.ID(); +} + +bool operator !=(const BankGroup& lhs, const BankGroup& rhs) +{ + return !(lhs == rhs); +} + +//BANK +bool operator ==(const Bank& lhs, const Bank& rhs) +{ + return lhs.ID() == rhs.ID(); +} + +bool operator !=(const Bank& lhs, const Bank& rhs) +{ + return !(lhs == rhs); +} + +bool operator <(const Bank& lhs, const Bank& rhs) +{ + return lhs.ID() < rhs.ID(); +} + +//ROW +const Row Row::NO_ROW; + +bool operator ==(const Row& lhs, const Row& rhs) +{ + if (lhs.isNoRow != rhs.isNoRow) + return false; + return lhs.ID() == rhs.ID(); +} + +bool operator !=(const Row& lhs, const Row& rhs) +{ + return !(lhs == rhs); +} + +const Row Row::operator ++() +{ + id = (id + 1) % core::Configuration::getInstance().NumberOfRows; + return *this; +} + + +//COLUMN +bool operator ==(const Column& lhs, const Column& rhs) +{ + return lhs.ID() == rhs.ID(); +} + +bool operator !=(const Column& lhs, const Column& rhs) +{ + return !(lhs == rhs); +} diff --git a/dram/src/common/dramExtension.h b/dram/src/common/dramExtension.h index 526d659f..607daab3 100644 --- a/dram/src/common/dramExtension.h +++ b/dram/src/common/dramExtension.h @@ -12,6 +12,7 @@ #include #include + class Thread { public: @@ -124,6 +125,59 @@ private: unsigned int id; }; + +class DramExtension: public tlm::tlm_extension +{ +public: + DramExtension(); + DramExtension(const Thread& thread, const Bank& bank, const BankGroup& bankgroup, const Row& row, const Column& column, + unsigned int burstlength = 0); + DramExtension(const Thread& thread, const Channel& channel, const Bank& bank, const BankGroup& bankgroup, const Row& row, + const Column& column, unsigned int burstlength = 0); + + virtual tlm_extension_base* clone() const; + virtual void copy_from(const tlm_extension_base& ext); + static DramExtension& getExtension(const tlm::tlm_generic_payload *payload); + static DramExtension& getExtension(const tlm::tlm_generic_payload &payload); + + Thread getThread() const; + Channel getChannel() const; + Bank getBank() const; + BankGroup getBankGroup() const; + Row getRow() const; + Column getColumn() const; + + unsigned int getBurstlength() const; + void incrementRow(); + +private: + Thread thread; + Channel channel; + Bank bank; + BankGroup bankgroup; + Row row; + Column column; + unsigned int burstlength; +}; + + +// Used to indicate the time when a payload is created (in a traceplayer or in a core) +// Note that this time can be different from the time the payload enters the DRAM system +//(at that time the phase BEGIN_REQ is recorded), so timeOfGeneration =< time(BEGIN_REQ) +class GenerationExtension : public tlm::tlm_extension +{ +public: + GenerationExtension(sc_time timeOfGeneration) : timeOfGeneration(timeOfGeneration) {} + virtual tlm_extension_base* clone() const; + virtual void copy_from(const tlm_extension_base& ext); + static GenerationExtension& getExtension(const tlm::tlm_generic_payload *payload); + sc_time TimeOfGeneration() const {return timeOfGeneration;} + +private: + sc_time timeOfGeneration; +}; + + bool operator==(const Thread &lhs, const Thread &rhs); bool operator!=(const Thread &lhs, const Thread &rhs); bool operator<(const Thread &lhs, const Thread &rhs); @@ -144,73 +198,4 @@ bool operator!=(const Row &lhs, const Row &rhs); bool operator==(const Column &lhs, const Column &rhs); bool operator!=(const Column &lhs, const Column &rhs); -class DramExtension: public tlm::tlm_extension -{ -private: - Thread thread; - Channel channel; - Bank bank; - BankGroup bankgroup; - Row row; - Column column; - unsigned int burstlength; -public: - - DramExtension() : - thread(0), channel(0), bank(0), bankgroup(0), row(0), column(0), burstlength(0) - { - } - DramExtension(const Thread& thread, const Bank& bank, const BankGroup& bankgroup, const Row& row, const Column& column, - unsigned int burstlength = 0) : - thread(thread), channel(0), bank(bank), bankgroup(bankgroup), row(row), column(column), burstlength(burstlength) - { - } - DramExtension(const Thread& thread, const Channel& channel, const Bank& bank, const BankGroup& bankgroup, const Row& row, - const Column& column, unsigned int burstlength = 0) : - thread(thread), channel(channel), bank(bank), bankgroup(bankgroup), row(row), column(column), burstlength(burstlength) - { - } - - ~DramExtension() - { - } - - virtual tlm_extension_base* clone() const; - virtual void copy_from(const tlm_extension_base& ext); - - const Thread& getThread() const; - - const Channel& getChannel() const; - - const Bank& getBank() const; - - const BankGroup& getBankGroup() const; - - const Row& getRow() const; - - const Column& getColumn() const; - - unsigned int getBurstlength() const; - - void increaseRow(); - - static DramExtension& getExtension(const tlm::tlm_generic_payload *payload); - static DramExtension& getExtension(const tlm::tlm_generic_payload &payload); -}; - - -class GenerationExtension : public tlm::tlm_extension -{ -public: - GenerationExtension(sc_time timeOfGeneration) : timeOfGeneration(timeOfGeneration) {} - virtual tlm_extension_base* clone() const; - virtual void copy_from(const tlm_extension_base& ext); - static GenerationExtension& getExtension(const tlm::tlm_generic_payload *payload); - - - sc_time TimeOfGeneration() const {return timeOfGeneration;} -private: - sc_time timeOfGeneration; -}; - #endif /* DRAMEXTENSION_H_ */ diff --git a/dram/src/controller/Controller.h b/dram/src/controller/Controller.h index 5342a992..34a1c4e8 100644 --- a/dram/src/controller/Controller.h +++ b/dram/src/controller/Controller.h @@ -35,6 +35,7 @@ #include "scheduler/Fifo.h" #include "scheduler/Fr_Fcfs.h" #include "scheduler/PARBS.h" +#include "scheduler/readwritegrouper.h" using namespace std; using namespace tlm; @@ -54,6 +55,7 @@ public: iSocket.register_nb_transport_bw(this, &Controller::nb_transport_bw); tSocket.register_nb_transport_fw(this, &Controller::nb_transport_fw); } + ~Controller() { delete controllerCore; @@ -118,8 +120,9 @@ void Controller::buildScheduler() if (selectedScheduler == "FR_FCFS") { - scheduler = new FR_FCFS(*controllerCore, Configuration::getInstance().RefreshAwareScheduling, + Scheduler* s = new FR_FCFS(*controllerCore, Configuration::getInstance().RefreshAwareScheduling, Configuration::getInstance().AdaptiveOpenPagePolicy); + scheduler = new ReadWriteGrouper(s); } else if (selectedScheduler == "PAR_BS") { @@ -222,7 +225,7 @@ void Controller::controllerCorePEQCallback(tlm_generic_payload &payloa { if (phase == REF_TRIGGER) { - controllerCore->triggerRefresh(payload, sc_time_stamp()); + controllerCore->triggerRefresh(payload); } else if (phase == PDN_TRIGGER) { @@ -347,7 +350,7 @@ void Controller::scheduleNextPayload() if(payload != NULL) { controllerCore->powerDownManager->wakeUp(DramExtension::getExtension(payload).getBank(), sc_time_stamp()); - bool wasScheduledByCore = controllerCore->scheduleRequest(sc_time_stamp(), *payload); + bool wasScheduledByCore = controllerCore->scheduleRequest(*payload); if (wasScheduledByCore) { scheduler->removePayload(payload); diff --git a/dram/src/controller/core/ControllerCore.cpp b/dram/src/controller/core/ControllerCore.cpp index 168521e0..7d41ed0a 100644 --- a/dram/src/controller/core/ControllerCore.cpp +++ b/dram/src/controller/core/ControllerCore.cpp @@ -91,8 +91,9 @@ void ControllerCore::resetState() state = savedState; } -void ControllerCore::triggerRefresh(tlm::tlm_generic_payload& payload, sc_time time) +void ControllerCore::triggerRefresh(tlm::tlm_generic_payload& payload) { + sc_time time = sc_time_stamp(); Bank bank = DramExtension::getExtension(payload).getBank(); state.cleanUp(time); @@ -105,9 +106,9 @@ void ControllerCore::triggerRefresh(tlm::tlm_generic_payload& payload, sc_time t } } -bool ControllerCore::scheduleRequest(sc_time start, tlm::tlm_generic_payload& payload) +bool ControllerCore::scheduleRequest(tlm::tlm_generic_payload& payload) { - start = clkAlign(start); + sc_time start = clkAlign(sc_time_stamp()); state.cleanUp(start); saveState(); @@ -127,8 +128,9 @@ bool ControllerCore::scheduleRequest(sc_time start, tlm::tlm_generic_payload& pa } } -bool ControllerCore::bankIsBusy(sc_time time, Bank bank) +bool ControllerCore::bankIsBusy(Bank bank) { + sc_time time = sc_time_stamp(); ScheduledCommand lastScheduledCommand = state.getLastScheduledCommand(bank); if (lastScheduledCommand.isNoCommand()) @@ -173,12 +175,12 @@ const std::vector& ControllerCore::getBanks() return banks; } -std::vector ControllerCore::getFreeBanks(sc_time currentTime) +std::vector ControllerCore::getFreeBanks() { std::vector freeBanks; for(Bank bank: getBanks()) { - if(!bankIsBusy(currentTime, bank)) + if(!bankIsBusy(bank)) freeBanks.push_back(bank); } return freeBanks; diff --git a/dram/src/controller/core/ControllerCore.h b/dram/src/controller/core/ControllerCore.h index 66238e67..7f4b7f52 100644 --- a/dram/src/controller/core/ControllerCore.h +++ b/dram/src/controller/core/ControllerCore.h @@ -27,15 +27,11 @@ public: ControllerCore(IWrapperConnector& wrapper, std::map& numberOfPayloads); virtual ~ControllerCore() ; - bool bankIsBusy(sc_time currentTime, Bank bank); - bool scheduleRequest(sc_time currentTime, tlm::tlm_generic_payload& payload); - void triggerRefresh(tlm::tlm_generic_payload& payload, sc_time time); - - void saveState(); - void resetState(); + bool scheduleRequest(tlm::tlm_generic_payload& payload); + void triggerRefresh(tlm::tlm_generic_payload& payload); const std::vector& getBanks(); - std::vector getFreeBanks(sc_time currentTime); + std::vector getFreeBanks(); const RowBufferState& getRowBufferStates(){return state.rowBufferStates;} ICommandChecker& getCommandChecker(Command command); @@ -44,7 +40,6 @@ public: Configuration config; ControllerState state; IWrapperConnector& wrapper; - IPowerDownManager* powerDownManager; IRefreshManager* refreshManager; std::map& numberOfPayloads; @@ -52,6 +47,9 @@ public: private: void send(const CommandSchedule& schedule, tlm::tlm_generic_payload& payload) const; + bool bankIsBusy(Bank bank); + void saveState(); + void resetState(); std::map commandChecker; ControllerState savedState; diff --git a/dram/src/controller/core/refresh/RefreshManager.cpp b/dram/src/controller/core/refresh/RefreshManager.cpp index d46c147b..57f26bdc 100644 --- a/dram/src/controller/core/refresh/RefreshManager.cpp +++ b/dram/src/controller/core/refresh/RefreshManager.cpp @@ -55,7 +55,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload, sc_time for (Bank bank : controller.getBanks()) { - DramExtension::getExtension(refreshPayloads[bank]).increaseRow(); + DramExtension::getExtension(refreshPayloads[bank]).incrementRow(); } planNextRefresh(); diff --git a/dram/src/controller/core/refresh/RefreshManagerBankwise.cpp b/dram/src/controller/core/refresh/RefreshManagerBankwise.cpp index e50bc250..215da8dd 100644 --- a/dram/src/controller/core/refresh/RefreshManagerBankwise.cpp +++ b/dram/src/controller/core/refresh/RefreshManagerBankwise.cpp @@ -61,7 +61,7 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload& payload, controller.state.change(nextRefresh); controller.wrapper.send(nextRefresh, refreshPayload); - extension.increaseRow(); + extension.incrementRow(); planNextRefresh(extension.getBank()); } diff --git a/dram/src/controller/core/scheduling/ScheduledCommand.cpp b/dram/src/controller/core/scheduling/ScheduledCommand.cpp index bcef806b..8e793ed6 100644 --- a/dram/src/controller/core/scheduling/ScheduledCommand.cpp +++ b/dram/src/controller/core/scheduling/ScheduledCommand.cpp @@ -90,8 +90,8 @@ bool ScheduledCommand::commandIsIn(const std::vector& commandSet) const TimeInterval ScheduledCommand::getIntervalOnDataStrobe() const { - sc_assert( - getCommand() == Command::Read || getCommand() == Command::ReadA + //only read and write commands have an assoicated time on the data strobe + sc_assert(getCommand() == Command::Read || getCommand() == Command::ReadA || getCommand() == Command::Write || getCommand() == Command::WriteA); @@ -99,7 +99,7 @@ TimeInterval ScheduledCommand::getIntervalOnDataStrobe() const if (getCommand() == Command::Read || getCommand() == Command::ReadA) { - return TimeInterval(getStart() + timings.tRL,getStart() + timings.tRL + getReadAccessTime()); + return TimeInterval(getStart() + timings.tRL, getStart() + timings.tRL + getReadAccessTime()); } else { diff --git a/dram/src/controller/scheduler/Fifo.cpp b/dram/src/controller/scheduler/Fifo.cpp index cc501769..aef1ecd9 100644 --- a/dram/src/controller/scheduler/Fifo.cpp +++ b/dram/src/controller/scheduler/Fifo.cpp @@ -22,7 +22,7 @@ void Fifo::schedule(gp* payload) gp* Fifo::getNextPayload() { - for(Bank bank: controllerCore.getFreeBanks(sc_time_stamp())) + for(Bank bank: controllerCore.getFreeBanks()) { if(!buffer[bank].empty()) { diff --git a/dram/src/controller/scheduler/Fr_Fcfs.cpp b/dram/src/controller/scheduler/Fr_Fcfs.cpp index b2fefae7..5635cc33 100644 --- a/dram/src/controller/scheduler/Fr_Fcfs.cpp +++ b/dram/src/controller/scheduler/Fr_Fcfs.cpp @@ -38,7 +38,7 @@ void FR_FCFS::schedule(std::vector payloads) gp* FR_FCFS::getNextPayload() { - for(Bank bank: controllerCore.getFreeBanks(sc_time_stamp())) + for(Bank bank: controllerCore.getFreeBanks()) { if(!buffer[bank].empty()) { diff --git a/dram/src/controller/scheduler/PARBS.h b/dram/src/controller/scheduler/PARBS.h index 2c6f9398..3d472011 100644 --- a/dram/src/controller/scheduler/PARBS.h +++ b/dram/src/controller/scheduler/PARBS.h @@ -18,6 +18,7 @@ class PAR_BS : public Scheduler public: PAR_BS(core::ControllerCore& controllerCore, bool useExternalBankstates, unsigned int capsize); virtual ~PAR_BS(); + virtual bool hasPayloads() override; virtual void schedule(gp* payload) override; virtual gp* getNextPayload() override; @@ -25,6 +26,7 @@ public: private: void formBatch(); + core::ControllerCore& controllerCore; bool useExternalBankstates; core::RowBufferState internalBankstates; diff --git a/dram/src/controller/scheduler/Scheduler.h b/dram/src/controller/scheduler/Scheduler.h index 85fd552b..c117f760 100644 --- a/dram/src/controller/scheduler/Scheduler.h +++ b/dram/src/controller/scheduler/Scheduler.h @@ -11,14 +11,8 @@ class Scheduler { public: virtual ~Scheduler(){} - virtual void schedule(gp* payload) = 0; - - //TODO Rename to payload virtual bool hasPayloads() = 0; - /* - *Test - */ virtual gp* getNextPayload() = 0; virtual void removePayload(gp* payload) = 0; static std::string sendername; diff --git a/dram/src/controller/scheduler/readwritegrouper.cpp b/dram/src/controller/scheduler/readwritegrouper.cpp new file mode 100644 index 00000000..5797fddb --- /dev/null +++ b/dram/src/controller/scheduler/readwritegrouper.cpp @@ -0,0 +1,121 @@ +#include "readwritegrouper.h" + +namespace scheduler{ + +using namespace tlm; + +ReadWriteGrouper::ReadWriteGrouper(Scheduler *scheduler): + scheduler(scheduler), mode(Mode::read) +{ + +} + +ReadWriteGrouper::~ReadWriteGrouper() +{ + delete scheduler; +} + + +void ReadWriteGrouper::removePayload(gp *payload) +{ + scheduler->removePayload(payload); + + //if scheduler is empty now + if(!scheduler->hasPayloads()) + { + if(mode == Mode::read && !writeQueue.empty()) + switchToWriteMode(); + else if(mode == Mode::readToWrite) + switchToWriteMode(); + else + switchToReadMode(); + } +} + +void ReadWriteGrouper::schedule(gp *payload) +{ +tlm_command command = payload->get_command(); + +//in read mode hazards could occur by letting a read pass a queued write +if(mode == Mode::read) +{ + if(command == TLM_READ_COMMAND) + { + //if scheduling the read would cause a hazard switch to readToWriteMode and put the read into the readQueue + if(schedulingReadCausesHazard(payload)) + { + switchToReadToWriteMode(); + readQueue.push_back(payload); + } + else + scheduler->schedule(payload); + } + else + { + writeQueue.push_back(payload); + if(!scheduler->hasPayloads()) + //there are no reads in the scheduler, so switch directly to write mode + switchToWriteMode(); + } +} +else if(mode == Mode::readToWrite) +{ + if(command == TLM_READ_COMMAND) + readQueue.push_back(payload); + else + writeQueue.push_back(payload); +} +else if(mode == Mode::write) +{ + if(command == TLM_READ_COMMAND) + readQueue.push_back(payload); + else + scheduler->schedule(payload); +} + +} + +gp *ReadWriteGrouper::getNextPayload() +{ + return scheduler->getNextPayload(); +} + +bool ReadWriteGrouper::hasPayloads() +{ + return scheduler->hasPayloads(); +} + + +bool ReadWriteGrouper::schedulingReadCausesHazard(gp *payload) +{ + sc_assert(payload->is_read()); + for(gp* write: writeQueue) + { + if(payload->get_address()==write->get_address()) + return true; + } + return false; +} + +void ReadWriteGrouper::switchToReadMode() +{ + mode = Mode::read; + for(gp* read: readQueue) + scheduler->schedule(read); + readQueue.clear(); +} + +void ReadWriteGrouper::switchToWriteMode() +{ + mode = Mode::write; + for(gp* write: writeQueue) + scheduler->schedule(write); + writeQueue.clear(); +} + +void ReadWriteGrouper::switchToReadToWriteMode() +{ + mode = Mode::readToWrite; +} + +} diff --git a/dram/src/controller/scheduler/readwritegrouper.h b/dram/src/controller/scheduler/readwritegrouper.h new file mode 100644 index 00000000..4e8b359f --- /dev/null +++ b/dram/src/controller/scheduler/readwritegrouper.h @@ -0,0 +1,40 @@ +#ifndef READWRITEGROUPER_H +#define READWRITEGROUPER_H +#include "Scheduler.h" +#include + +namespace scheduler{ + +/* Scheduler that batches reads and writes to reduce the overhead when switching from + * read to write mode (read-to-write constraints) + * The scheduler prioritizes reads. It switches to write mode, when stalling a write would induce a data-hazard + * or when there are no reads to process. + */ +class ReadWriteGrouper : public Scheduler +{ +public: + ReadWriteGrouper(Scheduler *scheduler); + ~ReadWriteGrouper(); + virtual void schedule(gp* payload) override; + virtual bool hasPayloads() override; + virtual gp* getNextPayload() override; + virtual void removePayload(gp* payload) override; + +private: + Scheduler *scheduler; + std::vector readQueue, writeQueue; + //Mode readToWrite is used to process the remaining reads in the readScheduler before + //switching to write mode (this is used when a potential hazard causes the scheduler to switch modes) + enum class Mode{read,readToWrite, write}; + Mode mode; + + bool schedulingReadCausesHazard(gp* payload); + void switchToReadMode(); + void switchToWriteMode(); + void switchToReadToWriteMode(); +}; + + +} + +#endif // READWRITEGROUPER_H diff --git a/dram/src/simulation/TracePlayer.h b/dram/src/simulation/TracePlayer.h index 20aa8c6d..1c76277a 100644 --- a/dram/src/simulation/TracePlayer.h +++ b/dram/src/simulation/TracePlayer.h @@ -32,29 +32,17 @@ struct TracePlayer: public sc_module public: tlm_utils::simple_initiator_socket iSocket; TracePlayer(sc_module_name /*name*/, string pathToTrace, unsigned int burstLength, - simulation::ISimulation* simulationManager) : - payloadEventQueue(this, &TracePlayer::peqCallback), file(pathToTrace), burstlenght(burstLength), numberOfPendingTransactions( - 0), transactionsSent(0), transactionsReceived(0), simulationManager( - simulationManager) - { - if (!file.is_open()) - SC_REPORT_FATAL(0, (string("Could not open trace ") + pathToTrace).c_str()); + simulation::ISimulation* simulationManager); - this->burstlenght = core::Configuration::getInstance().BurstLength; - iSocket.register_nb_transport_bw(this, &TracePlayer::nb_transport_bw); - } - - void start() - { - bool fileIsEmpty = file.peek() == std::ifstream::traits_type::eof(); - if (!fileIsEmpty) - { - scheduleNextPayload(); - } - } + void start(); private: + void generateNextPayload(); + tlm_sync_enum nb_transport_bw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& bwDelay); + void peqCallback(tlm_generic_payload& payload, const tlm_phase& phase); + void sendToTarget(tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay); tlm_utils::peq_with_cb_and_phase payloadEventQueue; + MemoryManager memoryManager; ifstream file; unsigned int burstlenght; @@ -62,108 +50,135 @@ private: unsigned int transactionsSent; unsigned int transactionsReceived; simulation::ISimulation* simulationManager; +}; - void scheduleNextPayload() + +template +TracePlayer::TracePlayer(sc_module_name, string pathToTrace, unsigned int burstLength, simulation::ISimulation *simulationManager) : + payloadEventQueue(this, &TracePlayer::peqCallback), file(pathToTrace), burstlenght(burstLength), + numberOfPendingTransactions(0), transactionsSent(0), transactionsReceived(0), simulationManager(simulationManager) +{ + if (!file.is_open()) + SC_REPORT_FATAL(0, (string("Could not open trace ") + pathToTrace).c_str()); + + this->burstlenght = core::Configuration::getInstance().BurstLength; + iSocket.register_nb_transport_bw(this, &TracePlayer::nb_transport_bw); +} + +template +void TracePlayer::start() +{ + bool fileIsEmpty = file.peek() == std::ifstream::traits_type::eof(); + if (!fileIsEmpty) { - if (file) - { - string time, command, address; - file >> time >> command >> address; - - //if there is a newline at the end of the .stl - if (time.empty() || command.empty() || address.empty()) - return; - - long parsedAdress = std::stoi(address.c_str(), 0, 16); - - gp* payload = memoryManager.allocate(); - payload->set_address(parsedAdress); - - if (command == "read") - { - payload->set_command(TLM_READ_COMMAND); - } - else if (command == "write") - { - payload->set_command(TLM_WRITE_COMMAND); - } - else - { - SC_REPORT_FATAL(0, - (string("Corrupted tracefile, command ") + command + string(" unknown")).c_str()); - } - - payload->set_data_length(BUSWIDTH / 8); - payload->set_response_status(TLM_INCOMPLETE_RESPONSE); - payload->set_dmi_allowed(false); - payload->set_byte_enable_length(0); - payload->set_streaming_width(burstlenght); - - sc_time sendingTime = sc_time(std::stoi(time.c_str()), SC_NS); - GenerationExtension* genExtension = new GenerationExtension(sendingTime); - payload->set_auto_extension(genExtension); - - if (sendingTime <= sc_time_stamp()) - { - payloadEventQueue.notify(*payload, BEGIN_REQ, SC_ZERO_TIME); - } - else - { - payloadEventQueue.notify(*payload, BEGIN_REQ, sendingTime - sc_time_stamp()); - } - numberOfPendingTransactions++; - } + generateNextPayload(); } +} - tlm_sync_enum nb_transport_bw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& bwDelay) +template +void TracePlayer::generateNextPayload() +{ + if (file) { - payloadEventQueue.notify(payload, phase, bwDelay); - return TLM_ACCEPTED; - } + string time, command, address; + file >> time >> command >> address; - void peqCallback(tlm_generic_payload& payload, const tlm_phase& phase) - { - if (phase == BEGIN_REQ) + //if there is a newline at the end of the .stl + if (time.empty() || command.empty() || address.empty()) + return; + + long parsedAdress = std::stoi(address.c_str(), 0, 16); + + gp* payload = memoryManager.allocate(); + payload->set_address(parsedAdress); + + if (command == "read") { - payload.acquire(); - sendToTarget(payload, phase, SC_ZERO_TIME); - - transactionsSent++; - DebugManager::getInstance().printDebugMessage(name(), - "Sending transaction number: " + std::to_string(transactionsSent)); + payload->set_command(TLM_READ_COMMAND); } - else if (phase == END_REQ) - { - scheduleNextPayload(); - } - else if (phase == BEGIN_RESP) - { - sendToTarget(payload, END_RESP, SC_ZERO_TIME); - payload.release(); - - simulationManager->transactionFinished(); - numberOfPendingTransactions--; - transactionsReceived++; - - DebugManager::getInstance().printDebugMessage(name(), - "Pending transactions in core: " - + std::to_string(transactionsSent - transactionsReceived)); - } - else if (phase == END_RESP) + else if (command == "write") { + payload->set_command(TLM_WRITE_COMMAND); } else { - SC_REPORT_FATAL(0, "TracePlayer PEQ was triggered with unknown phase"); + SC_REPORT_FATAL(0, + (string("Corrupted tracefile, command ") + command + string(" unknown")).c_str()); } - } - void sendToTarget(tlm_generic_payload& payload, const tlm_phase& phase, const sc_time& delay) - { - tlm_phase TPhase = phase; - sc_time TDelay = delay; - iSocket->nb_transport_fw(payload, TPhase, TDelay); + payload->set_data_length(BUSWIDTH / 8); + payload->set_response_status(TLM_INCOMPLETE_RESPONSE); + payload->set_dmi_allowed(false); + payload->set_byte_enable_length(0); + payload->set_streaming_width(burstlenght); + + sc_time sendingTime = sc_time(std::stoi(time.c_str()), SC_NS); + GenerationExtension* genExtension = new GenerationExtension(sendingTime); + payload->set_auto_extension(genExtension); + + if (sendingTime <= sc_time_stamp()) + { + payloadEventQueue.notify(*payload, BEGIN_REQ, SC_ZERO_TIME); + } + else + { + payloadEventQueue.notify(*payload, BEGIN_REQ, sendingTime - sc_time_stamp()); + } + numberOfPendingTransactions++; } -}; +} + +template +tlm_sync_enum TracePlayer::nb_transport_bw(tlm_generic_payload &payload, tlm_phase &phase, sc_time &bwDelay) +{ + payloadEventQueue.notify(payload, phase, bwDelay); + return TLM_ACCEPTED; +} + +template +void TracePlayer::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) +{ + if (phase == BEGIN_REQ) + { + payload.acquire(); + sendToTarget(payload, phase, SC_ZERO_TIME); + + transactionsSent++; + DebugManager::getInstance().printDebugMessage(name(), + "Sending transaction number: " + std::to_string(transactionsSent)); + } + else if (phase == END_REQ) + { + generateNextPayload(); + } + else if (phase == BEGIN_RESP) + { + sendToTarget(payload, END_RESP, SC_ZERO_TIME); + payload.release(); + + simulationManager->transactionFinished(); + numberOfPendingTransactions--; + transactionsReceived++; + + DebugManager::getInstance().printDebugMessage(name(), + "Pending transactions in core: " + + std::to_string(transactionsSent - transactionsReceived)); + } + else if (phase == END_RESP) + { + } + else + { + SC_REPORT_FATAL(0, "TracePlayer PEQ was triggered with unknown phase"); + } +} + +template +void TracePlayer::sendToTarget(tlm_generic_payload &payload, const tlm_phase &phase, const sc_time &delay) +{ + tlm_phase TPhase = phase; + sc_time TDelay = delay; + iSocket->nb_transport_fw(payload, TPhase, TDelay); +} #endif /* TRACEPLAYER_H_ */ From 5746d8f38ddecdd0d1a1af088831764d8ee5be65 Mon Sep 17 00:00:00 2001 From: Robert Gernhardt Date: Thu, 10 Jul 2014 11:16:16 +0200 Subject: [PATCH 11/13] merged with analyzer project --- analyzer/.gitignore | 1 + analyzer/analyzer/.gitignore | 2 + analyzer/analyzer/README.md | 2 + .../businessObjects/calculatedMetric.h | 19 + analyzer/analyzer/businessObjects/comment.h | 16 + .../analyzer/businessObjects/generalinfo.h | 25 + .../analyzer/businessObjects/phases/phase.cpp | 111 ++++ .../analyzer/businessObjects/phases/phase.h | 186 ++++++ .../businessObjects/phases/phasefactory.cpp | 45 ++ .../businessObjects/phases/phasefactory.h | 18 + .../analyzer/businessObjects/pythoncaller.cpp | 108 ++++ .../analyzer/businessObjects/pythoncaller.h | 26 + .../analyzer/businessObjects/testresult.h | 22 + .../analyzer/businessObjects/timespan.cpp | 12 + analyzer/analyzer/businessObjects/timespan.h | 24 + .../businessObjects/tracecalculatedmetrics.h | 46 ++ .../businessObjects/tracetestresults.cpp | 12 + .../businessObjects/tracetestresults.h | 22 + analyzer/analyzer/businessObjects/tracetime.h | 20 + .../analyzer/businessObjects/transaction.cpp | 30 + .../analyzer/businessObjects/transaction.h | 45 ++ analyzer/analyzer/data/QueryTexts.h | 22 + analyzer/analyzer/data/tracedb.cpp | 349 +++++++++++ analyzer/analyzer/data/tracedb.h | 96 +++ analyzer/analyzer/evaluationtool.cpp | 169 ++++++ analyzer/analyzer/evaluationtool.h | 62 ++ analyzer/analyzer/evaluationtool.ui | 188 ++++++ analyzer/analyzer/gototimedialog.cpp | 29 + analyzer/analyzer/gototimedialog.h | 30 + analyzer/analyzer/gototimedialog.ui | 38 ++ analyzer/analyzer/main.cpp | 61 ++ analyzer/analyzer/mainwindow.cpp | 39 ++ analyzer/analyzer/mainwindow.h | 35 ++ analyzer/analyzer/markerplotitem.cpp | 13 + analyzer/analyzer/markerplotitem.h | 20 + analyzer/analyzer/paths.pro | 13 + analyzer/analyzer/preferences.ui | 61 ++ .../presentation/commenttreewidget.cpp | 65 +++ .../analyzer/presentation/commenttreewidget.h | 38 ++ .../presentation/debugmessagetreewidget.cpp | 90 +++ .../presentation/debugmessagetreewidget.h | 37 ++ .../presentation/pornotracescroller.cpp | 238 ++++++++ .../presentation/pornotracescroller.h | 46 ++ .../selectedtransactiontreewidget.cpp | 20 + .../selectedtransactiontreewidget.h | 19 + .../presentation/tracePlotMouseLabel.cpp | 22 + .../presentation/tracePlotMouseLabel.h | 28 + .../analyzer/presentation/tracedrawing.cpp | 135 +++++ analyzer/analyzer/presentation/tracedrawing.h | 17 + .../presentation/tracedrawingproperties.h | 43 ++ .../presentation/tracemetrictreewidget.cpp | 23 + .../presentation/tracemetrictreewidget.h | 16 + .../analyzer/presentation/tracenavigator.cpp | 251 ++++++++ .../analyzer/presentation/tracenavigator.h | 82 +++ analyzer/analyzer/presentation/traceplot.cpp | 546 ++++++++++++++++++ analyzer/analyzer/presentation/traceplot.h | 151 +++++ .../analyzer/presentation/traceplotitem.cpp | 36 ++ .../analyzer/presentation/traceplotitem.h | 32 + .../presentation/tracetesttreewidget.cpp | 46 ++ .../presentation/tracetesttreewidget.h | 31 + .../presentation/transactiontreewidget.cpp | 94 +++ .../presentation/transactiontreewidget.h | 48 ++ .../analyzer/presentation/util/clkgrid.cpp | 29 + analyzer/analyzer/presentation/util/clkgrid.h | 18 + .../presentation/util/colorgenerator.cpp | 31 + .../presentation/util/colorgenerator.h | 21 + .../presentation/util/customlabelscaledraw.h | 20 + .../presentation/util/engineeringScaleDraw.h | 16 + .../analyzer/presentation/util/testlight.cpp | 33 ++ .../analyzer/presentation/util/testlight.h | 23 + analyzer/analyzer/queryeditor.cpp | 40 ++ analyzer/analyzer/queryeditor.h | 30 + analyzer/analyzer/queryeditor.ui | 80 +++ analyzer/analyzer/schedulerwrapper.h | 33 ++ analyzer/analyzer/thirdParty/eng_formant.cpp | 262 +++++++++ analyzer/analyzer/thirdParty/eng_format.h | 115 ++++ analyzer/analyzer/traceAnalyzer.pro | 101 ++++ analyzer/analyzer/traceanalyzer.cpp | 109 ++++ analyzer/analyzer/traceanalyzer.h | 52 ++ analyzer/analyzer/traceanalyzer.ui | 126 ++++ analyzer/analyzer/tracefiletab.cpp | 60 ++ analyzer/analyzer/tracefiletab.h | 43 ++ analyzer/analyzer/tracefiletab.ui | 182 ++++++ dram/dramSys/dramSys.pro | 2 +- 84 files changed, 5596 insertions(+), 1 deletion(-) create mode 100644 analyzer/.gitignore create mode 100644 analyzer/analyzer/.gitignore create mode 100644 analyzer/analyzer/README.md create mode 100644 analyzer/analyzer/businessObjects/calculatedMetric.h create mode 100644 analyzer/analyzer/businessObjects/comment.h create mode 100644 analyzer/analyzer/businessObjects/generalinfo.h create mode 100644 analyzer/analyzer/businessObjects/phases/phase.cpp create mode 100644 analyzer/analyzer/businessObjects/phases/phase.h create mode 100644 analyzer/analyzer/businessObjects/phases/phasefactory.cpp create mode 100644 analyzer/analyzer/businessObjects/phases/phasefactory.h create mode 100644 analyzer/analyzer/businessObjects/pythoncaller.cpp create mode 100644 analyzer/analyzer/businessObjects/pythoncaller.h create mode 100644 analyzer/analyzer/businessObjects/testresult.h create mode 100644 analyzer/analyzer/businessObjects/timespan.cpp create mode 100644 analyzer/analyzer/businessObjects/timespan.h create mode 100644 analyzer/analyzer/businessObjects/tracecalculatedmetrics.h create mode 100644 analyzer/analyzer/businessObjects/tracetestresults.cpp create mode 100644 analyzer/analyzer/businessObjects/tracetestresults.h create mode 100644 analyzer/analyzer/businessObjects/tracetime.h create mode 100644 analyzer/analyzer/businessObjects/transaction.cpp create mode 100644 analyzer/analyzer/businessObjects/transaction.h create mode 100644 analyzer/analyzer/data/QueryTexts.h create mode 100644 analyzer/analyzer/data/tracedb.cpp create mode 100644 analyzer/analyzer/data/tracedb.h create mode 100644 analyzer/analyzer/evaluationtool.cpp create mode 100644 analyzer/analyzer/evaluationtool.h create mode 100644 analyzer/analyzer/evaluationtool.ui create mode 100644 analyzer/analyzer/gototimedialog.cpp create mode 100644 analyzer/analyzer/gototimedialog.h create mode 100644 analyzer/analyzer/gototimedialog.ui create mode 100644 analyzer/analyzer/main.cpp create mode 100644 analyzer/analyzer/mainwindow.cpp create mode 100644 analyzer/analyzer/mainwindow.h create mode 100644 analyzer/analyzer/markerplotitem.cpp create mode 100644 analyzer/analyzer/markerplotitem.h create mode 100644 analyzer/analyzer/paths.pro create mode 100644 analyzer/analyzer/preferences.ui create mode 100644 analyzer/analyzer/presentation/commenttreewidget.cpp create mode 100644 analyzer/analyzer/presentation/commenttreewidget.h create mode 100644 analyzer/analyzer/presentation/debugmessagetreewidget.cpp create mode 100644 analyzer/analyzer/presentation/debugmessagetreewidget.h create mode 100644 analyzer/analyzer/presentation/pornotracescroller.cpp create mode 100644 analyzer/analyzer/presentation/pornotracescroller.h create mode 100644 analyzer/analyzer/presentation/selectedtransactiontreewidget.cpp create mode 100644 analyzer/analyzer/presentation/selectedtransactiontreewidget.h create mode 100644 analyzer/analyzer/presentation/tracePlotMouseLabel.cpp create mode 100644 analyzer/analyzer/presentation/tracePlotMouseLabel.h create mode 100644 analyzer/analyzer/presentation/tracedrawing.cpp create mode 100644 analyzer/analyzer/presentation/tracedrawing.h create mode 100644 analyzer/analyzer/presentation/tracedrawingproperties.h create mode 100644 analyzer/analyzer/presentation/tracemetrictreewidget.cpp create mode 100644 analyzer/analyzer/presentation/tracemetrictreewidget.h create mode 100644 analyzer/analyzer/presentation/tracenavigator.cpp create mode 100644 analyzer/analyzer/presentation/tracenavigator.h create mode 100644 analyzer/analyzer/presentation/traceplot.cpp create mode 100644 analyzer/analyzer/presentation/traceplot.h create mode 100644 analyzer/analyzer/presentation/traceplotitem.cpp create mode 100644 analyzer/analyzer/presentation/traceplotitem.h create mode 100644 analyzer/analyzer/presentation/tracetesttreewidget.cpp create mode 100644 analyzer/analyzer/presentation/tracetesttreewidget.h create mode 100644 analyzer/analyzer/presentation/transactiontreewidget.cpp create mode 100644 analyzer/analyzer/presentation/transactiontreewidget.h create mode 100644 analyzer/analyzer/presentation/util/clkgrid.cpp create mode 100644 analyzer/analyzer/presentation/util/clkgrid.h create mode 100644 analyzer/analyzer/presentation/util/colorgenerator.cpp create mode 100644 analyzer/analyzer/presentation/util/colorgenerator.h create mode 100644 analyzer/analyzer/presentation/util/customlabelscaledraw.h create mode 100644 analyzer/analyzer/presentation/util/engineeringScaleDraw.h create mode 100644 analyzer/analyzer/presentation/util/testlight.cpp create mode 100644 analyzer/analyzer/presentation/util/testlight.h create mode 100644 analyzer/analyzer/queryeditor.cpp create mode 100644 analyzer/analyzer/queryeditor.h create mode 100644 analyzer/analyzer/queryeditor.ui create mode 100644 analyzer/analyzer/schedulerwrapper.h create mode 100644 analyzer/analyzer/thirdParty/eng_formant.cpp create mode 100644 analyzer/analyzer/thirdParty/eng_format.h create mode 100644 analyzer/analyzer/traceAnalyzer.pro create mode 100644 analyzer/analyzer/traceanalyzer.cpp create mode 100644 analyzer/analyzer/traceanalyzer.h create mode 100644 analyzer/analyzer/traceanalyzer.ui create mode 100644 analyzer/analyzer/tracefiletab.cpp create mode 100644 analyzer/analyzer/tracefiletab.h create mode 100644 analyzer/analyzer/tracefiletab.ui diff --git a/analyzer/.gitignore b/analyzer/.gitignore new file mode 100644 index 00000000..30d388a1 --- /dev/null +++ b/analyzer/.gitignore @@ -0,0 +1 @@ +build* \ No newline at end of file diff --git a/analyzer/analyzer/.gitignore b/analyzer/analyzer/.gitignore new file mode 100644 index 00000000..8705455d --- /dev/null +++ b/analyzer/analyzer/.gitignore @@ -0,0 +1,2 @@ +traceAnalyzer.pro.user +traceAnalyzer.pro.user.* diff --git a/analyzer/analyzer/README.md b/analyzer/analyzer/README.md new file mode 100644 index 00000000..b202c4b5 --- /dev/null +++ b/analyzer/analyzer/README.md @@ -0,0 +1,2 @@ +dram.vp.scheduler +================= diff --git a/analyzer/analyzer/businessObjects/calculatedMetric.h b/analyzer/analyzer/businessObjects/calculatedMetric.h new file mode 100644 index 00000000..05a127f3 --- /dev/null +++ b/analyzer/analyzer/businessObjects/calculatedMetric.h @@ -0,0 +1,19 @@ +#ifndef METRIC_H +#define METRIC_H +#include + +class CalculatedMetric +{ +public: + CalculatedMetric(QString name, double value): name(name),value(value){} + QString getName(){return name;} + double getValue(){return value;} + +private: + QString name; + double value; +}; + + + +#endif // METRIC_H diff --git a/analyzer/analyzer/businessObjects/comment.h b/analyzer/analyzer/businessObjects/comment.h new file mode 100644 index 00000000..4f9da45a --- /dev/null +++ b/analyzer/analyzer/businessObjects/comment.h @@ -0,0 +1,16 @@ +#ifndef COMMENT_H +#define COMMENT_H +#include +#include "timespan.h" + +class Comment +{ + traceTime time; + QString text; +public: + Comment(traceTime time,QString text):time(time),text(text){} + traceTime Time() const{return time;} + const QString& Text() const{return text;} +}; + +#endif // COMMENT_H diff --git a/analyzer/analyzer/businessObjects/generalinfo.h b/analyzer/analyzer/businessObjects/generalinfo.h new file mode 100644 index 00000000..2cdb4e8a --- /dev/null +++ b/analyzer/analyzer/businessObjects/generalinfo.h @@ -0,0 +1,25 @@ +#ifndef GENERALINFO_H +#define GENERALINFO_H +#include "timespan.h" +#include + +struct GeneralInfo +{ + unsigned int numberOfTransactions; + unsigned int numberOfPhases; + Timespan span; + unsigned int numberOfBanks; + QString description; + QString unitOfTime; + unsigned int clkPeriod; + +public: + GeneralInfo(unsigned int numberOfTransactions,unsigned int numberOfPhases, Timespan span,unsigned int numberOfBanks,const QString& description, QString unitOfTime,unsigned int clkPeriod) : + numberOfTransactions(numberOfTransactions) , numberOfPhases(numberOfPhases), span(span), numberOfBanks(numberOfBanks), description(description), unitOfTime(unitOfTime),clkPeriod(clkPeriod) + { + } + + GeneralInfo(){} +}; + +#endif // GENERALINFO_H diff --git a/analyzer/analyzer/businessObjects/phases/phase.cpp b/analyzer/analyzer/businessObjects/phases/phase.cpp new file mode 100644 index 00000000..a3e467f4 --- /dev/null +++ b/analyzer/analyzer/businessObjects/phases/phase.cpp @@ -0,0 +1,111 @@ +#include "phase.h" +#include "presentation/tracedrawing.h" +#include "businessObjects/transaction.h" +#include + +using namespace std; + +void Phase::draw(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, bool highlight, const TraceDrawingProperties &drawingProperties) const +{ + Q_UNUSED(canvasRect); + + QColor color = getColor(drawingProperties); + painter->setBrush(QBrush(getColor(drawingProperties),getBrushStyle())); + + if(!drawingProperties.drawBorder) + { + painter->setPen(color); + } + else + { + painter->setPen(Qt::black); + } + + if(highlight) + { + QPen pen(Qt::red); + pen.setWidth(3); + painter->setPen(pen); + } + + drawPhaseSymbol(span.Begin(), span.End(), getYVal(drawingProperties), drawingProperties.drawText,getPhaseSymbol(), painter, xMap, yMap); + + for(Timespan span: spansOnCommandBus) + { + drawPhaseSymbol(span.Begin(), span.End(), drawingProperties.yValCommandBus,false,PhaseSymbol::Hexagon, painter,xMap,yMap); + } + + if(spanOnDataBus) + { + drawPhaseSymbol(spanOnDataBus->Begin(), spanOnDataBus->End(),drawingProperties.yValDataBus, false,PhaseSymbol::Hexagon, painter,xMap,yMap); + } +} + +void Phase::drawPhaseSymbol(traceTime begin, traceTime end, double y,bool drawtext,PhaseSymbol symbol, QPainter* painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap) const +{ + double yVal = yMap.transform(y); + double symbolHeight = yMap.transform(0)-yMap.transform(hexagonHeigth); + + if(symbol == PhaseSymbol::Hexagon) + { + QPoint hexFrom(xMap.transform(begin),yVal); + QPoint hexTo(xMap.transform(end),yVal); + drawHexagon(painter, hexFrom, hexTo, symbolHeight); + } + else + { + QPoint upperLeft(xMap.transform(begin),yVal-symbolHeight/2); + QPoint bottomRight(xMap.transform(end),yVal+symbolHeight/2); + painter->drawRect(QRect(upperLeft,bottomRight)); + } + + if(drawtext) + drawText(painter,Name(), QPoint(xMap.transform(begin), yVal + symbolHeight/2), TextPositioning::bottomRight); +} + +QColor Phase::getColor(const TraceDrawingProperties &drawingProperties) const +{ + switch (drawingProperties.colorGrouping) { + case ColorGrouping::PhaseType: + return getPhaseColor(); + break; + case ColorGrouping::Thread: + return ColorGenerator::getColor(static_cast(transaction->Thread())); + break; + case ColorGrouping::Transaction: + default: + return ColorGenerator::getColor(transaction->Id()); + } +} + +int Phase::getYVal(const TraceDrawingProperties &drawingProperties) const +{ + Q_UNUSED(drawingProperties) + return transaction->Bank(); +} + +Qt::BrushStyle Phase::getBrushStyle() const +{ + return Qt::SolidPattern; +} + +bool Phase::isSelected(traceTime time, double yVal, const TraceDrawingProperties& drawingproperties) const +{ + if (span.contains(time) && fabs(yVal-getYVal(drawingproperties))<=hexagonHeigth) + return true; + if (spanOnDataBus && spanOnDataBus->contains(time) && fabs(yVal-drawingproperties.yValDataBus)<=hexagonHeigth) + return true; + + for(Timespan span: spansOnCommandBus) + { + if (span.contains(time) && fabs(yVal-drawingproperties.yValCommandBus)<=hexagonHeigth) + return true; + } + + return false; +} + +Phase::PhaseSymbol Phase::getPhaseSymbol() const +{ + return PhaseSymbol::Hexagon; +} diff --git a/analyzer/analyzer/businessObjects/phases/phase.h b/analyzer/analyzer/businessObjects/phases/phase.h new file mode 100644 index 00000000..5d827512 --- /dev/null +++ b/analyzer/analyzer/businessObjects/phases/phase.h @@ -0,0 +1,186 @@ +#ifndef BANKPHASE_H +#define BANKPHASE_H +#include "presentation/util/colorgenerator.h" +#include "presentation/tracedrawingproperties.h" +#include "businessObjects/timespan.h" +#include +#include +#include +#include +#include + +typedef unsigned int ID; +enum TextPositioning; +class Transaction; + +class Phase +{ +public: + Phase(ID id,Timespan span,const std::shared_ptr& transaction, std::vector spansOnCommandBus, std::shared_ptr spanOnDataBus): + id(id),span(span),transaction(transaction), spansOnCommandBus(spansOnCommandBus), spanOnDataBus(spanOnDataBus), + hexagonHeigth(0.6), captionPosition(TextPositioning::bottomRight){} + + void draw(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, bool highlight,const TraceDrawingProperties& drawingProperties) const; + bool isSelected(traceTime time, double yVal, const TraceDrawingProperties& drawingproperties) const; + const Timespan& Span() const {return span;} + ID Id() const {return id;} + virtual QString Name() const = 0; + +protected: + ID id; + Timespan span; + std::shared_ptr transaction; + std::vector spansOnCommandBus; + std::shared_ptr spanOnDataBus; + double hexagonHeigth; + TextPositioning captionPosition; + + enum PhaseSymbol {Hexagon,Rect}; + virtual PhaseSymbol getPhaseSymbol() const; + virtual Qt::BrushStyle getBrushStyle() const; + virtual QColor getColor(const TraceDrawingProperties &drawingProperties) const; + virtual int getYVal(const TraceDrawingProperties &drawingProperties) const; + virtual QColor getPhaseColor() const = 0; + virtual void drawPhaseSymbol(traceTime begin, traceTime end, double y,bool drawtext,PhaseSymbol symbol, QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap) const; + +}; + +class REQ : public Phase +{ +public: + using Phase::Phase; +protected: + virtual QColor getPhaseColor() const override {return ColorGenerator::getColor(1);} + virtual QString Name() const final {return "REQ";} + virtual int getYVal(const TraceDrawingProperties &drawingProperties) const override {return drawingProperties.yValRequest;} +}; + + +class RESP : public Phase +{ +public: + using Phase::Phase; +protected: + virtual QColor getPhaseColor() const override {return ColorGenerator::getColor(1);} + virtual QString Name() const override {return "RESP";} + virtual int getYVal(const TraceDrawingProperties &drawingProperties) const override {return drawingProperties.yValResponse;} + +}; + +class PRE : public Phase +{ +public: + using Phase::Phase; +protected: + virtual QColor getPhaseColor() const override {return ColorGenerator::getColor(1);} + virtual QString Name() const override {return "PRE";} +}; + + +class ACT : public Phase +{ +public: + using Phase::Phase; +protected: + virtual QColor getPhaseColor() const override {return ColorGenerator::getColor(3);} + virtual QString Name() const override {return "ACT";} +}; + +class RD : public Phase +{ +public: + using Phase::Phase; +protected: + virtual QColor getPhaseColor() const override {return ColorGenerator::getColor(4);} + virtual QString Name() const override {return "RD";} +}; + +class RDA : public Phase +{ +public: + using Phase::Phase; +protected: + virtual QColor getPhaseColor() const override {return ColorGenerator::getColor(5);} + virtual QString Name() const override {return "RDA";} +}; + +class WR : public Phase +{ +public: + using Phase::Phase; +protected: + virtual QColor getPhaseColor() const override {return ColorGenerator::getColor(6);} + virtual QString Name() const override {return "WR";} +}; + +class WRA : public Phase +{ +public: + using Phase::Phase; +protected: + virtual QColor getPhaseColor() const override {return ColorGenerator::getColor(7);} + virtual QString Name() const override {return "WRA";} +}; + +class AUTO_REFRESH : public Phase +{ +public: + using Phase::Phase; +protected: + virtual QString Name() const override {return "REF";} + virtual std::vector getTimesOnCommandBus() const {return {span.Begin()};} + virtual QColor getColor(const TraceDrawingProperties &drawingProperties) const override {Q_UNUSED(drawingProperties) return getPhaseColor();} + virtual QColor getPhaseColor() const override {QColor phaseColor = QColor(Qt::darkCyan); + phaseColor.setAlpha(130); + return phaseColor; + } +}; + +class PRECHARGE_ALL : public Phase +{ +public: + using Phase::Phase; +protected: + virtual QString Name() const override {return "PREA";} + virtual std::vector getTimesOnCommandBus() const {return {span.Begin()};} + virtual QColor getColor(const TraceDrawingProperties &drawingProperties) const override {Q_UNUSED(drawingProperties) return getPhaseColor();} + virtual QColor getPhaseColor() const override {return ColorGenerator::getColor(10);} +}; + +class PDNA : public Phase +{ +public: + using Phase::Phase; +protected: + virtual QString Name() const override {return "PDNA";} + virtual Qt::BrushStyle getBrushStyle() const override {return Qt::Dense6Pattern;} + virtual QColor getColor(const TraceDrawingProperties &drawingProperties) const override {Q_UNUSED(drawingProperties) return getPhaseColor();} + virtual QColor getPhaseColor() const override {return QColor(Qt::black);} + virtual Phase::PhaseSymbol getPhaseSymbol() const override {return PhaseSymbol::Rect;} +}; + +class PDNP : public Phase +{ +public: + using Phase::Phase; +protected: + virtual QString Name() const override {return "PDNP";} + virtual Qt::BrushStyle getBrushStyle() const override{return Qt::Dense4Pattern;} + virtual QColor getColor(const TraceDrawingProperties &drawingProperties) const override {Q_UNUSED(drawingProperties) return getPhaseColor();} + virtual QColor getPhaseColor() const override {return QColor(Qt::black);} + virtual Phase::PhaseSymbol getPhaseSymbol() const override {return PhaseSymbol::Rect;} +}; + +class SREF : public Phase +{ +public: + using Phase::Phase; +protected: + virtual QString Name() const final {return "SREF";} + virtual Qt::BrushStyle getBrushStyle() const {return Qt::Dense1Pattern;} + virtual QColor getColor(const TraceDrawingProperties &drawingProperties) const override {Q_UNUSED(drawingProperties) return getPhaseColor();} + virtual QColor getPhaseColor() const override {return QColor(Qt::black);} + virtual Phase::PhaseSymbol getPhaseSymbol() const override {return PhaseSymbol::Rect;} +}; + +#endif // BANKPHASE_H diff --git a/analyzer/analyzer/businessObjects/phases/phasefactory.cpp b/analyzer/analyzer/businessObjects/phases/phasefactory.cpp new file mode 100644 index 00000000..37da7a93 --- /dev/null +++ b/analyzer/analyzer/businessObjects/phases/phasefactory.cpp @@ -0,0 +1,45 @@ +#include "phasefactory.h" +#include +#include "phase.h" +#include "businessObjects/transaction.h" +#include "data/tracedb.h" +#include "businessObjects/timespan.h" + +using namespace std; + +shared_ptr PhaseFactory::CreatePhase(ID id, const QString& dbPhaseName,const Timespan& span, const shared_ptr& trans, TraceDB& database) +{ + traceTime clk = database.getGeneralInfo().clkPeriod; + + if(dbPhaseName == "REQ") + return shared_ptr(new REQ(id, span,trans,{},std::shared_ptr())); + else if(dbPhaseName == "RESP") + return shared_ptr(new RESP(id, span,trans,{},std::shared_ptr())); + + else if(dbPhaseName == "PRE") + return shared_ptr(new PRE(id, span,trans,{Timespan(span.Begin(),span.Begin()+clk)},std::shared_ptr())); + else if(dbPhaseName == "ACT") + return shared_ptr(new ACT(id, span,trans,{Timespan(span.Begin(),span.Begin()+clk)},std::shared_ptr())); + else if(dbPhaseName == "PRE_ALL") + return shared_ptr(new PRECHARGE_ALL(id,span,trans,{Timespan(span.Begin(),span.Begin()+clk)},std::shared_ptr())); + else if(dbPhaseName == "AUTO_REFRESH") + return shared_ptr(new AUTO_REFRESH(id, span,trans,{Timespan(span.Begin(),span.Begin()+clk)},std::shared_ptr())); + + else if(dbPhaseName == "RD") + return shared_ptr(new RD(id, span,trans,{Timespan(span.Begin(),span.Begin()+clk)},std::shared_ptr(new Timespan(trans->SpanOnDataStrobe())))); + else if(dbPhaseName == "RDA") + return shared_ptr(new RDA(id, span,trans,{Timespan(span.Begin(),span.Begin()+clk)},std::shared_ptr(new Timespan(trans->SpanOnDataStrobe())))); + else if(dbPhaseName == "WR") + return shared_ptr(new WR(id, span,trans,{Timespan(span.Begin(),span.Begin()+clk)},std::shared_ptr(new Timespan(trans->SpanOnDataStrobe())))); + else if(dbPhaseName == "WRA") + return shared_ptr(new WRA(id, span,trans,{Timespan(span.Begin(),span.Begin()+clk)},std::shared_ptr(new Timespan(trans->SpanOnDataStrobe())))); + + else if(dbPhaseName == "SREF") + return shared_ptr(new SREF(id, span, trans,{Timespan(span.Begin(),span.Begin()+clk),Timespan(span.End()-clk,span.End())},std::shared_ptr())); + else if(dbPhaseName == "PDNA") + return shared_ptr(new PDNA(id, span,trans, {Timespan(span.Begin(),span.Begin()+clk),Timespan(span.End()-clk,span.End())},std::shared_ptr())); + else if(dbPhaseName == "PDNP") + return shared_ptr(new PDNP(id, span,trans, {Timespan(span.Begin(),span.Begin()+clk),Timespan(span.End()-clk,span.End())},std::shared_ptr())); + else + throw std::runtime_error("DB phasename " + dbPhaseName.toStdString() + " unkown to phasefactory"); +} diff --git a/analyzer/analyzer/businessObjects/phases/phasefactory.h b/analyzer/analyzer/businessObjects/phases/phasefactory.h new file mode 100644 index 00000000..7ad09aba --- /dev/null +++ b/analyzer/analyzer/businessObjects/phases/phasefactory.h @@ -0,0 +1,18 @@ +#ifndef PHASEFACTORY_H +#define PHASEFACTORY_H +#include "phase.h" +#include +#include +#include "businessObjects/transaction.h" + +class TraceDB; + +class PhaseFactory +{ +private: + PhaseFactory(); +public: + static std::shared_ptr CreatePhase(ID id, const QString& dbPhaseName,const Timespan& span,const std::shared_ptr& trans, TraceDB& database); +}; + +#endif // PHASEFACTORY_H diff --git a/analyzer/analyzer/businessObjects/pythoncaller.cpp b/analyzer/analyzer/businessObjects/pythoncaller.cpp new file mode 100644 index 00000000..014bd2e9 --- /dev/null +++ b/analyzer/analyzer/businessObjects/pythoncaller.cpp @@ -0,0 +1,108 @@ +#include "pythoncaller.h" +#include +#include +#include +#include +#include + +using namespace std; + +PythonCaller::PythonCaller(const QString& pathToScripts) : + testModuleName("tests"), testFunctionName("runTests"), metricModuleName("metrics"), metricFunctionName("calculateMetrics"), pathToScripts(pathToScripts.toStdString()) +{ + Py_Initialize(); + PyObject *sysPath = PySys_GetObject((char*)"path"); + PyObject *path = PyUnicode_FromString(this->pathToScripts.c_str()); + PyList_Insert(sysPath, 0, path); + Py_DECREF(path); + + qDebug() << testModuleName.c_str() << testFunctionName.c_str(); + + pRunTestsFunction = loadFunctionFromModule(testModuleName, testFunctionName); + pCalculateMetricsFunction = loadFunctionFromModule(metricModuleName, metricFunctionName); +} + + +//returns new reference to the function (see: http://edcjones.tripod.com/refcount.html for the difference between "new reference" and "borrowed reference") +PyObject* PythonCaller::loadFunctionFromModule(string moduleName,string functionName) +{ + PyObject* pModuleName = PyUnicode_FromString(moduleName.c_str()); + PyObject* pModule = PyImport_Import(pModuleName); + + if(!pModule) + { + throw runtime_error(string("Could not load module "+ moduleName)); + } + + PyObject* pFunction = PyObject_GetAttrString(pModule, functionName.c_str()); + + if(!pFunction || !PyCallable_Check(pFunction)) + { + throw runtime_error(string("Could not load test function " + functionName + "in module " + moduleName)); + } + + Py_DECREF(pModuleName); + Py_DECREF(pModule); + return pFunction; +} + +PythonCaller::~PythonCaller() +{ + Py_DECREF(pRunTestsFunction); + Py_DECREF(pCalculateMetricsFunction); + Py_Finalize(); +} + +//returns a new reference to result of function call +PyObject* PythonCaller::callFunctionWithStringArgument(PyObject* function, QString argument) +{ + assert(PyCallable_Check(function)); + + PyObject* pArgs = PyTuple_New(1); + PyObject* pArgument = PyUnicode_FromString(argument.toStdString().c_str()); + PyTuple_SetItem(pArgs, 0, pArgument); + PyObject *pResult = PyObject_CallObject(function, pArgs); + Py_DECREF(pArgument); + + if(!pResult) + { + PyErr_Print(); + throw runtime_error(string("Error in calling " + testFunctionName + "in module " + testModuleName)); + } + + return pResult; +} +TraceTestResults PythonCaller::runTestsOnTrace(QString pathToTrace) +{ + TraceTestResults traceTestResult(QFileInfo(pathToTrace).baseName()); + PyObject *pResult = callFunctionWithStringArgument(pRunTestsFunction, pathToTrace); + + for(Py_ssize_t i= 0; i < PyList_Size(pResult); ++i) + { + PyObject* currentTestResult = PyList_GetItem(pResult,i); + QString testName(PyUnicode_AsUTF8(PyTuple_GetItem(currentTestResult,0))); + bool testPassed = (Py_True == PyTuple_GetItem(currentTestResult,1)); + QString message(PyUnicode_AsUTF8(PyTuple_GetItem(currentTestResult,2))); + + traceTestResult.addTestResult(TestResult(testName,testPassed,message)); + } + Py_DECREF(pResult); + return traceTestResult; +} + +TraceCalculatedMetrics PythonCaller::calculateMetricsOnTrace(QString pathToTrace) +{ + TraceCalculatedMetrics result(QFileInfo(pathToTrace).baseName()); + PyObject *pResult = callFunctionWithStringArgument(pCalculateMetricsFunction, pathToTrace); + + for(Py_ssize_t i= 0; i < PyList_Size(pResult); ++i) + { + PyObject* calculatedMetric = PyList_GetItem(pResult,i); + QString metricName(PyUnicode_AsUTF8(PyTuple_GetItem(calculatedMetric,0))); + double value = PyFloat_AsDouble(PyTuple_GetItem(calculatedMetric,1)); + result.addCalculatedMetric(CalculatedMetric(metricName,value)); + } + + Py_DECREF(pResult); + return result; +} diff --git a/analyzer/analyzer/businessObjects/pythoncaller.h b/analyzer/analyzer/businessObjects/pythoncaller.h new file mode 100644 index 00000000..370f9756 --- /dev/null +++ b/analyzer/analyzer/businessObjects/pythoncaller.h @@ -0,0 +1,26 @@ +#ifndef PYTHONCALLER_H +#define PYTHONCALLER_H +#include +#include +#include +#include "businessObjects/tracetestresults.h" +#include "businessObjects/tracecalculatedmetrics.h" + +class PythonCaller +{ +public: + PythonCaller(const QString& pathToScripts); + ~PythonCaller(); + TraceTestResults runTestsOnTrace(QString pathToTrace); + TraceCalculatedMetrics calculateMetricsOnTrace(QString pathToTrace); + +private: + PyObject *pRunTestsFunction, *pCalculateMetricsFunction; + PyObject* loadFunctionFromModule(std::string moduleName, std::string functionName); + std::string testModuleName, testFunctionName, metricModuleName, metricFunctionName, pathToScripts; + PyObject *callFunctionWithStringArgument(PyObject *function, QString argument); +}; + +#endif // PYTHONCALLER_H + + diff --git a/analyzer/analyzer/businessObjects/testresult.h b/analyzer/analyzer/businessObjects/testresult.h new file mode 100644 index 00000000..aca90583 --- /dev/null +++ b/analyzer/analyzer/businessObjects/testresult.h @@ -0,0 +1,22 @@ +#ifndef TESTRESULT_H +#define TESTRESULT_H +#include + +class TestResult +{ +public: + TestResult(const QString& testName, bool passed, QString& message) : + testName(testName),passed(passed),message(message){} + + QString getTestName() const{return testName;} + QString getMessage() const{return message;} + bool hasPassed() const{return passed;} + +private: + QString testName; + bool passed; + QString message; + +}; + +#endif // TESTRESULT_H diff --git a/analyzer/analyzer/businessObjects/timespan.cpp b/analyzer/analyzer/businessObjects/timespan.cpp new file mode 100644 index 00000000..6249555c --- /dev/null +++ b/analyzer/analyzer/businessObjects/timespan.cpp @@ -0,0 +1,12 @@ +#include "timespan.h" + +bool Timespan::contains(traceTime time) const +{ + return (begin<=time && time<=end); +} + +void Timespan::shift(traceTime offset) +{ + begin += offset; + end += offset; +} diff --git a/analyzer/analyzer/businessObjects/timespan.h b/analyzer/analyzer/businessObjects/timespan.h new file mode 100644 index 00000000..348a7649 --- /dev/null +++ b/analyzer/analyzer/businessObjects/timespan.h @@ -0,0 +1,24 @@ +#ifndef TIMESPAN_H +#define TIMESPAN_H +#include +#include "tracetime.h" +#include "thirdParty/eng_format.h" + +class Timespan +{ + traceTime begin; + traceTime end; +public: + + Timespan(traceTime begin = 0, traceTime end = 0) : begin(begin), end(end){} + traceTime timeCovered() const{return abs(End()-Begin());} + traceTime Begin() const{return begin;} + void setBegin(traceTime time){begin = time;} + traceTime End() const{return end;} + traceTime Middle() const{return (begin + end) / 2;} + void setEnd(traceTime time){end = time;} + bool contains(traceTime time) const; + void shift(traceTime offset); +}; + +#endif // TIMESPAN_H diff --git a/analyzer/analyzer/businessObjects/tracecalculatedmetrics.h b/analyzer/analyzer/businessObjects/tracecalculatedmetrics.h new file mode 100644 index 00000000..d50bed1c --- /dev/null +++ b/analyzer/analyzer/businessObjects/tracecalculatedmetrics.h @@ -0,0 +1,46 @@ +#ifndef TRACEMETRICRESULTS_H +#define TRACEMETRICRESULTS_H +#include +#include +#include "calculatedMetric.h" + +class TraceCalculatedMetrics +{ +public: + TraceCalculatedMetrics(const QString& traceName): traceName(traceName){} + + void addCalculatedMetric(const CalculatedMetric& result) {calculatedMetrics.push_back(result);} + QString getTraceName() const {return traceName;} + const std::vector& getCalculatedMetrics() const{return calculatedMetrics;} + + QString toCSVHeader() + { + QString result = ""; + result.append("Trace"); + for(CalculatedMetric calculatedMetric : calculatedMetrics) + { + result.append(","); + result.append(calculatedMetric.getName()); + } + return result; + } + + QString toCSVLine() + { + QString result = ""; + result.append(traceName); + for(CalculatedMetric calculatedMetric : calculatedMetrics) + { + result.append(","); + result.append(QString::number(calculatedMetric.getValue())); + } + return result; + } + +private: + QString traceName; + std::vector calculatedMetrics; +}; + + +#endif // TRACEMETRICRESULTS_H diff --git a/analyzer/analyzer/businessObjects/tracetestresults.cpp b/analyzer/analyzer/businessObjects/tracetestresults.cpp new file mode 100644 index 00000000..d4b59a36 --- /dev/null +++ b/analyzer/analyzer/businessObjects/tracetestresults.cpp @@ -0,0 +1,12 @@ +#include "tracetestresults.h" + + +bool TraceTestResults::hasPassedAllTests() const +{ + for(const TestResult& testResult: testResults) + { + if(!testResult.hasPassed()) + return false; + } + return true; +} diff --git a/analyzer/analyzer/businessObjects/tracetestresults.h b/analyzer/analyzer/businessObjects/tracetestresults.h new file mode 100644 index 00000000..72bc98a9 --- /dev/null +++ b/analyzer/analyzer/businessObjects/tracetestresults.h @@ -0,0 +1,22 @@ +#ifndef TRACETESTRESULT_H +#define TRACETESTRESULT_H +#include +#include +#include "testresult.h" + +class TraceTestResults +{ +public: + TraceTestResults(const QString& traceName): traceName(traceName){} + + void addTestResult(const TestResult& result) {testResults.push_back(result);} + + QString getTraceName() const {return traceName;} + bool hasPassedAllTests() const; + const std::vector& getTestResults() const{return testResults;} +private: + QString traceName; + std::vector testResults; +}; + +#endif // TRACETESTRESULT_H diff --git a/analyzer/analyzer/businessObjects/tracetime.h b/analyzer/analyzer/businessObjects/tracetime.h new file mode 100644 index 00000000..88bc022c --- /dev/null +++ b/analyzer/analyzer/businessObjects/tracetime.h @@ -0,0 +1,20 @@ +#ifndef TRACETIME_H +#define TRACETIME_H +#include +#include "thirdParty/eng_format.h" + +//time in nanoseconds +typedef long long traceTime; + +inline QString formatTraceTimePretty(traceTime time) +{ + return QString::number(time/1000) + QString(" ns"); +} + +inline traceTime alignToClk(traceTime time, unsigned int clkPeriod) +{ + return round(1.0*time/clkPeriod)*clkPeriod; +} + + +#endif // TRACETIME_H diff --git a/analyzer/analyzer/businessObjects/transaction.cpp b/analyzer/analyzer/businessObjects/transaction.cpp new file mode 100644 index 00000000..2d50a287 --- /dev/null +++ b/analyzer/analyzer/businessObjects/transaction.cpp @@ -0,0 +1,30 @@ +#include "transaction.h" + +using namespace std; +Transaction::Transaction(ID id,unsigned int address,unsigned int burstlength,int thread, unsigned int channel, unsigned int bank,unsigned int bankgroup, unsigned int row, unsigned int column, Timespan span, Timespan spanOnDataStrobe) + :address(address),burstlength(burstlength),channel(channel), bank(bank),bankgroup(bankgroup), row(row), column(column),thread(thread),span(span),spanOnDataStrobe(spanOnDataStrobe),id(id){} + +void Transaction::addPhase(shared_ptr phase) +{ + phases.push_back(phase); +} + +void Transaction::draw(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, bool highlight, const TraceDrawingProperties &drawingProperties) const +{ + for(shared_ptr phase: phases) + phase->draw(painter,xMap,yMap,canvasRect,highlight,drawingProperties); +} + +bool Transaction::isSelected(traceTime time, double yVal, const TraceDrawingProperties& drawingproperties) const +{ + if(span.contains(time)) + { + for(shared_ptr phase: phases) + { + if(phase->isSelected(time,yVal,drawingproperties)) + return true; + } + } + + return false; +} diff --git a/analyzer/analyzer/businessObjects/transaction.h b/analyzer/analyzer/businessObjects/transaction.h new file mode 100644 index 00000000..77e49c91 --- /dev/null +++ b/analyzer/analyzer/businessObjects/transaction.h @@ -0,0 +1,45 @@ +#ifndef TRANSACTION_H +#define TRANSACTION_H +#include +#include +#include "timespan.h" +#include "phases/phase.h" +#include "presentation/tracedrawingproperties.h" + +typedef unsigned int ID; + +class Transaction +{ +private: + unsigned int address,burstlength,channel,bank,bankgroup,row,column; + int thread; + Timespan span; + Timespan spanOnDataStrobe; + ID id; + std::vector> phases; + +public: + Transaction(ID id,unsigned int address,unsigned int burstlength,int thread, unsigned int channel, unsigned int bank,unsigned int bankgroup, unsigned int row, unsigned int column, Timespan span, Timespan spanOnDataStrobe); + + void draw(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, bool highlight,const TraceDrawingProperties& drawingProperties) const; + void addPhase(std::shared_ptr phase); + + bool isSelected(traceTime time,double yVal, const TraceDrawingProperties& drawingproperties) const; + bool isControllerInternal(){return thread==0;} + + unsigned int Address() const{return address;} + unsigned int Burstlength() const{return burstlength;} + int Thread() {return thread;} + unsigned int Channel() const {return channel;} + unsigned int Bank() const{return bank;} + unsigned int BankGroup() const{return bankgroup;} + unsigned int Row() const{return row;} + unsigned int Column() const{return column;} + ID Id() const {return id;} + const Timespan& Span() const{return span;} + const Timespan& SpanOnDataStrobe() {return spanOnDataStrobe;} + const std::vector>& Phases() const{return phases;} + +}; + +#endif // TRANSACTION_H diff --git a/analyzer/analyzer/data/QueryTexts.h b/analyzer/analyzer/data/QueryTexts.h new file mode 100644 index 00000000..a8256518 --- /dev/null +++ b/analyzer/analyzer/data/QueryTexts.h @@ -0,0 +1,22 @@ +#ifndef QUERYTEXTS_H +#define QUERYTEXTS_H +#include + +struct TransactionQueryTexts +{ + QString queryHead; + QString selectTransactionsByTimespan,selectTransactionById; + + TransactionQueryTexts() + { + queryHead = "SELECT Transactions.ID AS TransactionID, Ranges.begin, Ranges.end,DataStrobeBegin,DataStrobeEnd, Address,Burstlength, TThread, TChannel, TBank,TBankgroup, TRow, TColumn,Phases.ID AS PhaseID, PhaseName, PhaseBegin, PhaseEnd " + " FROM Transactions INNER JOIN Phases ON Phases.Transact = Transactions.ID INNER JOIN Ranges ON Transactions.Range = Ranges.ID "; + + selectTransactionsByTimespan = queryHead + " WHERE Ranges.end >= :begin AND Ranges.begin <= :end"; + selectTransactionById = queryHead + " WHERE Transactions.ID = :id"; + + } + +}; + +#endif // QUERYTEXTS_H diff --git a/analyzer/analyzer/data/tracedb.cpp b/analyzer/analyzer/data/tracedb.cpp new file mode 100644 index 00000000..1ca511ce --- /dev/null +++ b/analyzer/analyzer/data/tracedb.cpp @@ -0,0 +1,349 @@ +#include +#include +#include +#include +#include +#include +#include +#include"data/tracedb.h" +#include"businessObjects/comment.h" +#include "businessObjects/phases/phasefactory.h" + + +//define symbol printqueries if all queries should be printed to the console +//#define printqueries + +using namespace std; + +TraceDB::TraceDB(QString path,bool openExisting) +{ + this->pathToDB = path; + database = QSqlDatabase::addDatabase("QSQLITE",path); + database.setDatabaseName(path); + database.open(); + if(!openExisting) + dropAndCreateTables(); + prepareQueries(); + generalInfo = getGeneralInfoFromDB(); +} + +void TraceDB::prepareQueries() +{ + selectTransactionsByTimespan = QSqlQuery(database); + selectTransactionsByTimespan.prepare(queryTexts.selectTransactionsByTimespan); + selectTransactionById = QSqlQuery(database); + + selectTransactionById.prepare(queryTexts.selectTransactionById); + selectDebugMessagesByTimespan = QSqlQuery(database); + selectDebugMessagesByTimespan.prepare("SELECT time, Message FROM DebugMessages WHERE :begin <= time AND time <= :end "); + selectDebugMessagesByTimespanWithLimit = QSqlQuery(database); + selectDebugMessagesByTimespanWithLimit.prepare("SELECT time, Message FROM DebugMessages WHERE :begin <= time AND time <= :end LIMIT :limit"); +} + +void TraceDB::updateComments(vector comments) +{ + + QSqlQuery query(database); + query.prepare("DELETE FROM Comments"); + executeQuery(query); + query.prepare("insert into Comments values(:time,:text)"); + + for(const Comment &comment:comments) + { + query.bindValue(":time",comment.Time()); + query.bindValue(":text",comment.Text()); + executeQuery(query); + } +} + +void TraceDB::updateFileDescription(const QString &description) +{ + QSqlQuery query(database); + query.prepare("UPDATE GeneralInfo SET Description=:description"); + query.bindValue(":description",description); + executeQuery(query); +} + +void TraceDB::refreshData() +{ + generalInfo = getGeneralInfoFromDB(); +} + +//QueryText must select the fields +//TransactionID, Ranges.begin, Ranges.end, Address, TThread, TChannel, TBank, TRow, TColumn, Phases.ID AS PhaseID, PhaseName, PhaseBegin, PhaseEnd +vector> TraceDB::getTransactionsWithCustomQuery(QString queryText) +{ + QSqlQuery query(database); + query.prepare(queryText); + executeQuery(query); + return parseTransactionsFromQuery(query); +} + +vector> TraceDB::getTransactionsInTimespan(const Timespan &span) +{ + selectTransactionsByTimespan.bindValue(":begin",span.Begin()); + selectTransactionsByTimespan.bindValue(":end",span.End()); + executeQuery(selectTransactionsByTimespan); + return parseTransactionsFromQuery(selectTransactionsByTimespan); +} + + +//TODO Remove exception +shared_ptr TraceDB::getTransactionByID(ID id) +{ + selectTransactionById.bindValue(":id", id); + executeQuery(selectTransactionById); + auto result = parseTransactionsFromQuery(selectTransactionById); + if(!result.empty()) + return result[0]; + else +throw sqlException(("Transaction with ID " + QString::number(id) + " not in DB").toStdString(),this->pathToDB.toStdString()); +} + + +shared_ptr TraceDB::getNextActivate(ID currentTransactionId) +{ + QSqlQuery query(database); + QString queryText = queryTexts.queryHead + "WHERE TransactionID > :currentID AND PhaseName = 'ACT' LIMIT 1"; + + query.prepare(queryText); + query.bindValue(":currentID", currentTransactionId); + executeQuery(query); + return parseTransactionFromQuery(query); +} + +shared_ptr TraceDB::getNextPrecharge(ID currentTransactionId) +{ + QSqlQuery query(database); + QString queryText = queryTexts.queryHead + "WHERE TransactionID > :currentID AND PhaseName IN ('PRE','PRE_ALL') LIMIT 1"; + + query.prepare(queryText); + query.bindValue(":currentID", currentTransactionId); + executeQuery(query); + return parseTransactionFromQuery(query); +} + +shared_ptr TraceDB::getNextRefresh(ID currentTransactionId) +{ + QSqlQuery query(database); + QString queryText = queryTexts.queryHead + "WHERE TransactionID > :currentID AND PhaseName = 'AUTO_REFRESH' LIMIT 1"; + + query.prepare(queryText); + query.bindValue(":currentID", currentTransactionId); + executeQuery(query); + return parseTransactionFromQuery(query); +} + +ID TraceDB::getTransactionIDFromPhaseID(ID phaseID) +{ + QSqlQuery query(database); + query.prepare("SELECT Transact FROM Phases WHERE ID=:id"); + query.bindValue(":id",phaseID); + executeQuery(query); + + if(query.next()) + { + return query.value(0).toInt(); + } + else + { + throw sqlException("Phase with ID "+ to_string(phaseID) + " not in db", this->pathToDB.toStdString()); + } +} + +GeneralInfo TraceDB::getGeneralInfoFromDB() +{ + QSqlQuery query(database); + query.prepare("SELECT NumberOfTransactions,TraceEnd,NumberOfBanks,Clk,UnitOfTime,Traces,Memspec,Memconfig FROM GeneralInfo"); + executeQuery(query); + + if(query.next()) + { + unsigned int numberOfTransactions = query.value(0).toInt(); + traceTime traceEnd = query.value(1).toLongLong(); + unsigned int numberOfBanks = query.value(2).toInt(); + unsigned int clkPeriod = query.value(3).toInt(); + QString unitOfTime = query.value(4).toString(); + unsigned int numberOfPhases = getNumberOfPhases(); + + QString traces = "Traces: " + query.value(5).toString(); + QString memspec = "Memspec: " + query.value(6).toString(); + QString memconfig = "Memconfig: " + query.value(7).toString(); + + QString description = (traces + "\n"); + description += memconfig + "\n"; + description += memspec + "\n"; + description += "Number of Transactions: " + QString::number(numberOfTransactions) + "\n"; + description += "Clock period: " + QString::number(clkPeriod) + " " + unitOfTime + "\n"; + description += "Length of trace: " + formatTraceTimePretty(traceEnd); + + return GeneralInfo(numberOfTransactions, numberOfPhases, Timespan(0,traceEnd),numberOfBanks,description,unitOfTime,clkPeriod); + } + else + { + throw sqlException("Tracefile corrupted. No general info table", this->pathToDB.toStdString()); + } +} + +unsigned int TraceDB::getNumberOfPhases() +{ + QSqlQuery query(database); + query.prepare("SELECT COUNT(ID) FROM Phases"); + executeQuery(query); + + query.next(); + return query.value(0).toInt(); +} + +vector TraceDB::getComments() +{ + QSqlQuery query(database); + query.prepare("SELECT Time,Text From Comments"); + executeQuery(query); + return parseCommentsFromQuery(query); +} + + +vector TraceDB::getDebugMessagesInTimespan(const Timespan &span) +{ + selectDebugMessagesByTimespan.bindValue(":begin",span.Begin()); + selectDebugMessagesByTimespan.bindValue(":end",span.End()); + executeQuery(selectDebugMessagesByTimespan); + + return parseCommentsFromQuery(selectDebugMessagesByTimespan); +} + +vector TraceDB::getDebugMessagesInTimespan(const Timespan &span, unsigned int limit = 50) +{ + selectDebugMessagesByTimespanWithLimit.bindValue(":begin",span.Begin()); + selectDebugMessagesByTimespanWithLimit.bindValue(":end",span.End()); + selectDebugMessagesByTimespanWithLimit.bindValue(":limit",limit); + executeQuery(selectDebugMessagesByTimespanWithLimit); + return parseCommentsFromQuery(selectDebugMessagesByTimespanWithLimit); +} + +/* Helpers + * + * + * + */ + + +shared_ptr TraceDB::parseTransactionFromQuery(QSqlQuery &query) +{ + auto result = parseTransactionsFromQuery(query); + if(!result.empty()) + return result[0]; + else + return shared_ptr(); +} + +vector> TraceDB::parseTransactionsFromQuery(QSqlQuery &query) +{ + vector> result; + + bool firstIteration = true; + ID currentID = 0; + int i = -1; + + while(query.next()){ + + ID id = query.value(0).toInt(); + + if(currentID != id || firstIteration) + { + ++i; + firstIteration = false; + currentID = id; + Timespan span(query.value(1).toLongLong(),query.value(2).toLongLong()); + Timespan spanOnStrobe(query.value(3).toLongLong(),query.value(4).toLongLong()); + unsigned int address = query.value(5).toInt(); + unsigned int burstlength = query.value(6).toInt(); + int thread= query.value(7).toInt(); + unsigned int channel = query.value(8).toInt(); + unsigned int bank = query.value(9).toInt(); + unsigned int bankgroup = query.value(10).toInt(); + unsigned int row = query.value(11).toInt(); + unsigned int column = query.value(12).toInt(); + result.push_back(shared_ptr(new Transaction(id,address,burstlength,thread,channel,bank,bankgroup,row,column,span,spanOnStrobe))); + } + + unsigned int phaseID = query.value(13).toInt(); + QString phaseName = query.value(14).toString(); + Timespan span(query.value(15).toLongLong(),query.value(16).toLongLong()); + result.at(result.size()-1)->addPhase(PhaseFactory::CreatePhase(phaseID,phaseName,span,result.at(result.size()-1),*this)); + } + return result; +} + +vector TraceDB::parseCommentsFromQuery(QSqlQuery &query) +{ + vector result; + while(query.next()) + { + result.push_back(Comment(query.value(0).toLongLong(),query.value(1).toString())); + } + return result; +} + +void TraceDB::executeQuery(QSqlQuery query) +{ + + //query.exec returns bool indicating if the query was sucessfull + if(query.exec()) + { +#ifdef printqueries + cout << queryToString(query).toStdString() << endl; +#endif + } + + else + { + throw sqlException( ("Query:\n " + queryToString(query) + "\n failed. Error: \n"+ + query.lastError().text()).toStdString(), this->pathToDB.toStdString()); + } +} + +QString TraceDB::queryToString(QSqlQuery query) +{ + QString str = query.lastQuery(); + QMapIterator it(query.boundValues()); + while (it.hasNext()) + { + it.next(); + str.replace(it.key(),it.value().toString()); + } + return str; +} + + +void TraceDB::dropAndCreateTables() +{ + executeScriptFile("common/static/createTraceDB.sql"); +} + +void TraceDB::executeScriptFile(QString fileName) +{ + QSqlQuery query(database); + QFile scriptFile(fileName); + + if (scriptFile.open(QIODevice::ReadOnly)) + { + // The SQLite driver executes only a single (the first) query in the QSqlQuery + // if the script contains more queries, it needs to be splitted. + QStringList scriptQueries = QTextStream(&scriptFile).readAll().split(';'); + + for (QString &queryTxt : scriptQueries) + { + if (queryTxt.trimmed().isEmpty()) { + continue; + } + if (!query.exec(queryTxt)) + { + throw sqlException("Querry failed:" + query.lastError().text().toStdString(), this->pathToDB.toStdString()); + } + query.finish(); + } + } +} + diff --git a/analyzer/analyzer/data/tracedb.h b/analyzer/analyzer/data/tracedb.h new file mode 100644 index 00000000..0eea8953 --- /dev/null +++ b/analyzer/analyzer/data/tracedb.h @@ -0,0 +1,96 @@ +#ifndef TRACEDB_H +#define TRACEDB_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "businessObjects/transaction.h" +#include "businessObjects/generalinfo.h" +#include "businessObjects/phases/phasefactory.h" +#include "businessObjects/comment.h" +#include "QueryTexts.h" + +/* TraceDB handles the connection to a SQLLite database containing trace data. + * A TraceDB object always holds an open connection to a valid database. + */ + +class TraceDB : public QObject +{ + Q_OBJECT + +public: + TraceDB(QString path, bool openExisting); + const QString& getPathToDB(){return pathToDB;} + + void updateComments(std::vector comments); + void updateFileDescription(const QString &description); + void refreshData(); + + const GeneralInfo& getGeneralInfo() {return generalInfo;} + + std::vector> getTransactionsWithCustomQuery(QString queryText); + std::vector> getTransactionsInTimespan(const Timespan &span); + std::shared_ptr getNextPrecharge(ID currentTransactionId); + std::shared_ptr getNextActivate(ID currentTransactionId); + std::shared_ptr getNextRefresh(ID currentTransactionId); + + + std::shared_ptr getTransactionByID(ID id); + ID getTransactionIDFromPhaseID(ID phaseID); + + std::vector getComments(); + std::vector getDebugMessagesInTimespan(const Timespan &span); + std::vector getDebugMessagesInTimespan(const Timespan &span, unsigned int limit); + +private: + QString pathToDB; + QSqlDatabase database; + GeneralInfo generalInfo; + + QSqlQuery insertPhaseQuery; + QSqlQuery insertTransactionQuery; + QSqlQuery selectTransactionsByTimespan; + QSqlQuery selectTransactionById; + QSqlQuery selectDebugMessagesByTimespan; + QSqlQuery selectDebugMessagesByTimespanWithLimit; + + TransactionQueryTexts queryTexts; + void prepareQueries(); + void executeQuery(QSqlQuery query); + QString queryToString(QSqlQuery query); + std::shared_ptr parseTransactionFromQuery(QSqlQuery &query); + std::vector> parseTransactionsFromQuery(QSqlQuery &query); + std::vector parseCommentsFromQuery(QSqlQuery &query); + + void executeScriptFile(QString fileName); + void dropAndCreateTables(); + + unsigned int getNumberOfPhases(); + GeneralInfo getGeneralInfoFromDB(); +}; + + + +class sqlException : public std::exception +{ +private: + std::string message; +public: + sqlException(std::string message, std::string filename) + { + this->message = std::string("Error in file ") + filename + std::string(" ") + message; + } + const char* what() const noexcept + { + return message.c_str(); + } +}; +#endif // TRACEDB_H + + + diff --git a/analyzer/analyzer/evaluationtool.cpp b/analyzer/analyzer/evaluationtool.cpp new file mode 100644 index 00000000..4ca3d52c --- /dev/null +++ b/analyzer/analyzer/evaluationtool.cpp @@ -0,0 +1,169 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "evaluationtool.h" +#include "ui_evaluationtool.h" + +using namespace std; + + +EvaluationTool::EvaluationTool(QWidget *parent) : + QWidget(parent), + ui(new Ui::EvaluationTool), path("../../dram/resources/scripts""") +{ + ui->setupUi(this); + traceFilesModel = new QStandardItemModel(this); + ui->listView->setModel(traceFilesModel); + QObject::connect(ui->traceTestTreeWidget,SIGNAL(setMessage(QString)),this,SLOT(setTestMessage(QString))); +} + +EvaluationTool::~EvaluationTool() +{ + delete ui; +} + +void EvaluationTool::showForFiles(QList paths) +{ + cleanUpUI(); + fillFileList(paths); + show(); + ui->toolBox->setCurrentIndex(0); +} + +void EvaluationTool::showAndRunTests(QList paths) +{ + cleanUpUI(); + fillFileList(paths); + show(); + ui->toolBox->setCurrentIndex(0); + runTests(); +} + +void EvaluationTool::showAndEvaluateMetrics(QList paths) +{ + cleanUpUI(); + fillFileList(paths); + show(); + ui->toolBox->setCurrentIndex(1); + calculateMetrics(); + std::cout<<"done"<clear(); + calculatedMetrics.clear(); + ui->traceMetricTreeWidget->clear(); + ui->traceTestTreeWidget->clear(); + ui->testMessage->setPlainText(QString("")); + ui->testLight->setGray(); +} + +void EvaluationTool::fillFileList(QList paths) +{ + qSort(paths.begin(), paths.end(), [] (const QString &path1, const QString &path2) {return QFileInfo(path1).baseName() < QFileInfo(path2).baseName();}); + for(const QString& path: paths) + { + traceFilesModel->appendRow(new TraceFileItem(path)); + } +} + +void EvaluationTool::on_btn_test_clicked() +{ + runTests(); +} + +void EvaluationTool::runTests() +{ + PythonCaller pythonCaller(this->path); + ui->traceTestTreeWidget->clear(); + ui->testLight->setGray(); + + if(traceFilesModel->rowCount() == 0) + return; + + bool allTestsPassed = true; + + for(int row = 0; row < traceFilesModel->rowCount(); ++row) + { + TraceFileItem* item = static_cast(traceFilesModel->item(row)); + TraceTestResults traceTestResult = pythonCaller.runTestsOnTrace(item->getPath()); + if(!traceTestResult.hasPassedAllTests()) + allTestsPassed = false; + ui->traceTestTreeWidget->addTraceTestResult(traceTestResult); + } + + ui->traceTestTreeWidget->expandAll(); + + if(allTestsPassed) + ui->testLight->setGreen(); + else + ui->testLight->setRed(); +} + +void EvaluationTool::on_btn_calculateMetrics_clicked() +{ + calculateMetrics(); +} + +void EvaluationTool::calculateMetrics() +{ + qDebug() << this->path; + PythonCaller pythonCaller(this->path); + ui->traceMetricTreeWidget->clear(); + for(int row = 0; row < traceFilesModel->rowCount(); ++row) + { + TraceFileItem* item = static_cast(traceFilesModel->item(row)); + TraceCalculatedMetrics result = pythonCaller.calculateMetricsOnTrace(item->getPath()); + calculatedMetrics.push_back(result); + ui->traceMetricTreeWidget->addTraceMetricResults(result); + } + ui->traceMetricTreeWidget->expandAll(); +} + + + +void EvaluationTool::setTestMessage(QString message) +{ + ui->testMessage->setPlainText(message); +} + +EvaluationTool::TraceFileItem::TraceFileItem(const QString &path) +{ + this->path = path; + setText(QFileInfo(this->path).baseName()); + setCheckable( false ); + setCheckState(Qt::Checked); + setEditable(false); +} + + + +void EvaluationTool::on_btn_exportCSV_clicked() +{ + if(calculatedMetrics.size()>0) + { + QString filename = QFileDialog::getSaveFileName(this, "Export to CSV", "", "Comma separated Values(*.csv)"); + if(filename != "") + { + QFile file(filename); + file.open(QIODevice::WriteOnly | QIODevice::Text); + QTextStream out(&file); + out << calculatedMetrics[0].toCSVHeader() << "\n"; + for(TraceCalculatedMetrics& metrics : calculatedMetrics) + { + out << metrics.toCSVLine() << "\n"; + } + file.close(); + } + } + +} diff --git a/analyzer/analyzer/evaluationtool.h b/analyzer/analyzer/evaluationtool.h new file mode 100644 index 00000000..c9a4bfd5 --- /dev/null +++ b/analyzer/analyzer/evaluationtool.h @@ -0,0 +1,62 @@ +#ifndef EVALUATIONTOOL_H +#define EVALUATIONTOOL_H + +#include +#include +#include +#include +#include +#include +#include +#include "businessObjects/pythoncaller.h" +#include "businessObjects/tracecalculatedmetrics.h" + +namespace Ui { +class EvaluationTool; +} + +class EvaluationTool : public QWidget +{ + Q_OBJECT + +public: + explicit EvaluationTool(QWidget *parent = 0); + ~EvaluationTool(); + + void showForFiles(QList paths); + void showAndRunTests(QList paths); + void showAndEvaluateMetrics(QList paths); + + +private Q_SLOTS: + void on_btn_test_clicked(); + void setTestMessage(QString message); + void on_btn_calculateMetrics_clicked(); + + void on_btn_exportCSV_clicked(); + +private: + void fillFileList(QList paths); + void runTests(); + void calculateMetrics(); + void cleanUpUI(); + + + Ui::EvaluationTool *ui; + QStandardItemModel *traceFilesModel; + std::vector calculatedMetrics; + QString path; + + class TraceFileItem : public QStandardItem + { + public: + TraceFileItem(const QString& path); + QString getPath(){return path;} + + private: + QString path; + }; + +}; + +#endif // EVALUATIONTOOL_H diff --git a/analyzer/analyzer/evaluationtool.ui b/analyzer/analyzer/evaluationtool.ui new file mode 100644 index 00000000..0b773843 --- /dev/null +++ b/analyzer/analyzer/evaluationtool.ui @@ -0,0 +1,188 @@ + + + EvaluationTool + + + + 0 + 0 + 869 + 514 + + + + Evaluate Traces + + + + + + + + + 1 + 0 + + + + + + + + + 5 + 0 + + + + 1 + + + + + 0 + 0 + 702 + 432 + + + + Test + + + + + + + + + 1 + + + + + + + + + + Run tests + + + + + + + + + + 0 + 30 + + + + + + + + Message: + + + + + + + + + + + + + + + + + + 0 + 0 + 702 + 432 + + + + Calculate Metrics + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Calculate metrics + + + + + + + Export to CSV + + + + + + + + + + 1 + + + + + + + + + + + + + + + + + TestLight + QWidget +
presentation/util/testlight.h
+ 1 +
+ + TraceTestTreeWidget + QTreeWidget +
presentation/tracetesttreewidget.h
+
+ + TraceMetricTreeWidget + QTreeWidget +
presentation/tracemetrictreewidget.h
+
+
+ + +
diff --git a/analyzer/analyzer/gototimedialog.cpp b/analyzer/analyzer/gototimedialog.cpp new file mode 100644 index 00000000..33d2df98 --- /dev/null +++ b/analyzer/analyzer/gototimedialog.cpp @@ -0,0 +1,29 @@ +#include "gototimedialog.h" +#include "ui_gototimedialog.h" +#include + +GoToTimeDialog::GoToTimeDialog(double* goToSecond,QWidget *parent) : + QDialog(parent), + goToSecond(goToSecond), + ui(new Ui::GoToTimeDialog) +{ + ui->setupUi(this); +} + +GoToTimeDialog::~GoToTimeDialog() +{ + delete ui; +} + +void GoToTimeDialog::on_pushButton_clicked() +{ + QLocale c(QLocale::C); + bool validNumber; + *goToSecond = c.toDouble(ui->timeEdit->text(),&validNumber); + if(validNumber) + accept(); + else + { + QMessageBox::warning(this,"Invalid number","Please enter a valid floating point number"); + } +} diff --git a/analyzer/analyzer/gototimedialog.h b/analyzer/analyzer/gototimedialog.h new file mode 100644 index 00000000..737e7eb0 --- /dev/null +++ b/analyzer/analyzer/gototimedialog.h @@ -0,0 +1,30 @@ +#ifndef GOTOTIMEDIALOG_H +#define GOTOTIMEDIALOG_H +#include + + + +namespace Ui { + class GoToTimeDialog; +} + +class GoToTimeDialog : public QDialog +{ + Q_OBJECT + +public: + explicit GoToTimeDialog(double* goToSecond, QWidget *parent = 0); + ~GoToTimeDialog(); + + +private: + double* goToSecond; + +private Q_SLOTS: + void on_pushButton_clicked(); + +private: + Ui::GoToTimeDialog *ui; +}; + +#endif // GOTOTIMEDIALOG_H diff --git a/analyzer/analyzer/gototimedialog.ui b/analyzer/analyzer/gototimedialog.ui new file mode 100644 index 00000000..f9243552 --- /dev/null +++ b/analyzer/analyzer/gototimedialog.ui @@ -0,0 +1,38 @@ + + + GoToTimeDialog + + + + 0 + 0 + 395 + 45 + + + + Go to time + + + + + + + + + ns + + + + + + + Ok + + + + + + + + diff --git a/analyzer/analyzer/main.cpp b/analyzer/analyzer/main.cpp new file mode 100644 index 00000000..53fea5ea --- /dev/null +++ b/analyzer/analyzer/main.cpp @@ -0,0 +1,61 @@ +#include "traceanalyzer.h" +#include +#include +#include +#include + +#include +#include +using namespace std; + +int main(int argc, char *argv[]) +{ + cout << argv[0] << std::endl; + QApplication a(argc, argv); + + if(argc > 1) + { + QSet arguments; + for(int i = 1;i paths = arguments; + arguments.clear(); + for(QString path : paths) + { + QDir directory(path); + QStringList files = directory.entryList(nameFilter); + for(QString& file : files) + { + arguments.insert(path.append("/") + file); + } + } + } + + TraceAnalyzer analyzer(arguments, startupOption); + analyzer.show(); + return a.exec(); + } + else + { + TraceAnalyzer analyzer; + analyzer.show(); + return a.exec(); + } + +} + + diff --git a/analyzer/analyzer/mainwindow.cpp b/analyzer/analyzer/mainwindow.cpp new file mode 100644 index 00000000..0e2df84c --- /dev/null +++ b/analyzer/analyzer/mainwindow.cpp @@ -0,0 +1,39 @@ +#include "mainwindow.h" +#include "ui_mainwindow.h" +#include "traceDB.h" +#include "xmldeserializer.h" +#include + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow) +{ + ui->setupUi(this); + // xmlDeserializer des("config.xml"); + // des.xmlToTraceDB("tpr.xml") + + db = new TraceDB("tpr.tdb", true); + traceNavigator = new TraceNavigator(db->getGeneralInfo(), this); + ui->tracePlot->init(traceNavigator, db); + ui->pornoTraceScroller->init(traceNavigator, db, ui->tracePlot); + phases = db->getPhasesInTimespan(traceNavigator->GeneralTraceInfo().TraceSpan()); + transactions = db->getTransactionsInTimespan(traceNavigator->GeneralTraceInfo().TraceSpan()); + + ui->qwtPlot->setAxisScale(QwtPlot::xBottom,traceNavigator->GeneralTraceInfo().TraceSpan().Begin(),traceNavigator->GeneralTraceInfo().TraceSpan().End()); + unsigned int banksize = traceNavigator -> GeneralTraceInfo().NumberOfBanks(); + ui->qwtPlot->setAxisScale(QwtPlot::yLeft,0.0,banksize + 3, 1.0); + + PhaseCollectionDrawingProperties* drawingProperties = new PhaseCollectionDrawingProperties(banksize,this); + drawingProperties->setDrawText(false); + drawingProperties->setDrawBorder(false); + drawingProperties->setDrawPowerDownStates(false); + phaseCollectionPlotItem *phaseCollectionPlot = new phaseCollectionPlotItem(phases,transactions,drawingProperties); + phaseCollectionPlot->attach(ui->qwtPlot); + + traceNavigator->navigateToTime(0); +} + +MainWindow::~MainWindow() +{ + delete ui; +} diff --git a/analyzer/analyzer/mainwindow.h b/analyzer/analyzer/mainwindow.h new file mode 100644 index 00000000..e3a3ef6c --- /dev/null +++ b/analyzer/analyzer/mainwindow.h @@ -0,0 +1,35 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include + +#include "tracenavigator.h" + +class TraceDB; + +namespace Ui { + class MainWindow; +} + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = 0); + ~MainWindow(); + +//private slots: +// void on_horizontalScrollBar_valueChanged(int value); + +private: + Ui::MainWindow *ui; + TraceNavigator *traceNavigator; + TraceDB *db; + QHash phases; + QHash transactions; + +}; + +#endif // MAINWINDOW_H diff --git a/analyzer/analyzer/markerplotitem.cpp b/analyzer/analyzer/markerplotitem.cpp new file mode 100644 index 00000000..026b72cb --- /dev/null +++ b/analyzer/analyzer/markerplotitem.cpp @@ -0,0 +1,13 @@ +#include "markerplotitem.h" +#include "tracedrawing.h" +#include + +int MarkerPlotItem::rtti() const +{ + return QwtPlotItem::Rtti_PlotUserItem; +} + +void MarkerPlotItem::draw(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect) const +{ + drawVerticalLine(painter,xMap.transform(time),canvasRect,color,width); +} diff --git a/analyzer/analyzer/markerplotitem.h b/analyzer/analyzer/markerplotitem.h new file mode 100644 index 00000000..2cadd216 --- /dev/null +++ b/analyzer/analyzer/markerplotitem.h @@ -0,0 +1,20 @@ +#ifndef MARKERPLOTITEM_H +#define MARKERPLOTITEM_H +#include +#include + +class MarkerPlotItem : public QwtPlotItem +{ +private: + traceTime time; + int width; + QColor color; + +public: + MarkerPlotItem(traceTime time, int width = 4, QColor color = QColor(Qt::black)):time(time), width(width), color(color){} + virtual int rtti() const; + virtual void draw(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect) const; + +}; + +#endif // MARKERPLOTITEM_H diff --git a/analyzer/analyzer/paths.pro b/analyzer/analyzer/paths.pro new file mode 100644 index 00000000..4502b6fe --- /dev/null +++ b/analyzer/analyzer/paths.pro @@ -0,0 +1,13 @@ +#This file has to be included after CONFIG has been adjusted and before the path variables are used +#It has to be adjusted to your paths + +CONFIG(qwt){ + LIBS += -L/opt/qwt/lib/ -lqwt -lutil + INCLUDEPATH += /opt/qwt/include +} + + +CONFIG(python){ + LIBS += -lpython3.4m + INCLUDEPATH += /opt/python/include/python3.4m +} diff --git a/analyzer/analyzer/preferences.ui b/analyzer/analyzer/preferences.ui new file mode 100644 index 00000000..7e34a428 --- /dev/null +++ b/analyzer/analyzer/preferences.ui @@ -0,0 +1,61 @@ + + + Preferences + + + + 0 + 0 + 400 + 300 + + + + Preferences + + + + + 10 + 10 + 291 + 101 + + + + Color-Grouping: + + + + 0 + + + QLayout::SetMaximumSize + + + + + Phase-Type + + + + + + + Transaction + + + + + + + Thread + + + + + + + + + diff --git a/analyzer/analyzer/presentation/commenttreewidget.cpp b/analyzer/analyzer/presentation/commenttreewidget.cpp new file mode 100644 index 00000000..3cbcff55 --- /dev/null +++ b/analyzer/analyzer/presentation/commenttreewidget.cpp @@ -0,0 +1,65 @@ +#include "commenttreewidget.h" +#include +#include +#include + +void CommentTreeWidget::init(TraceNavigator *navigator) +{ + Q_ASSERT(isInitialized == false); + isInitialized = true; + this->navigator = navigator; + setColumnCount(2); + setHeaderLabels(QStringList({"Time", "Comment"})); + QObject::connect(navigator,SIGNAL(commentsChanged()),this, SLOT(commentsChanged())); + QObject::connect(this,SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),this,SLOT(itemDoubleClicked(QTreeWidgetItem*,int))); + QObject::connect(this,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(ContextMenuRequested(QPoint))); + setContextMenuPolicy(Qt::CustomContextMenu); + deleteComment = new QAction("Delete comment",this); + printComments(); +} + +void CommentTreeWidget::commentsChanged() +{ + clear(); + printComments(); +} + +void CommentTreeWidget::printComments() +{ + for(const auto &pair: navigator->getComments()) + { + const Comment &comment = pair.second; + QTreeWidgetItem* item = new CommentTreeItem(this,comment); + addTopLevelItem(item); + } + resizeColumnToContents(0); +} + +void CommentTreeWidget::itemDoubleClicked(QTreeWidgetItem *item, int /*column*/) +{ + CommentTreeItem* commentItem = static_cast(item); + navigator->navigateToTime(commentItem->Time()); +} + +void CommentTreeWidget::ContextMenuRequested(QPoint point) +{ + QMenu contextMenu; + contextMenu.addActions({deleteComment}); + QAction* selectedItem = contextMenu.exec(mapToGlobal(point)); + + if(selectedItem) + { + for(QTreeWidgetItem *item: selectedItems()) + { + CommentTreeItem *commentItem = static_cast(item); + navigator->removeCommentAtTime(commentItem->Time()); + } + } +} + + +CommentTreeWidget::CommentTreeItem::CommentTreeItem(QTreeWidget *parent, const Comment &comment):QTreeWidgetItem(parent),comment(comment) +{ + this->setText(0,formatTraceTimePretty(comment.Time())); + this->setText(1,comment.Text()); +} diff --git a/analyzer/analyzer/presentation/commenttreewidget.h b/analyzer/analyzer/presentation/commenttreewidget.h new file mode 100644 index 00000000..89799740 --- /dev/null +++ b/analyzer/analyzer/presentation/commenttreewidget.h @@ -0,0 +1,38 @@ +#ifndef COMMENTTREEWIDGET_H +#define COMMENTTREEWIDGET_H +#include +#include +#include +#include "businessObjects/comment.h" +#include "tracenavigator.h" + +class CommentTreeWidget : public QTreeWidget +{ + Q_OBJECT + +public: + CommentTreeWidget(QWidget *parent = 0) : QTreeWidget(parent),isInitialized(false){} + void init(TraceNavigator* navigator); + +public Q_SLOTS: + void commentsChanged(); + void itemDoubleClicked(QTreeWidgetItem * item, int column); + void ContextMenuRequested(QPoint point); + +private: + bool isInitialized; + TraceNavigator *navigator; + void printComments(); + QAction* deleteComment; + + class CommentTreeItem : public QTreeWidgetItem + { + private: + Comment comment; + public: + CommentTreeItem(QTreeWidget * parent, const Comment &comment); + traceTime Time() {return comment.Time();} + }; +}; + +#endif // COMMENTTREEWIDGET_H diff --git a/analyzer/analyzer/presentation/debugmessagetreewidget.cpp b/analyzer/analyzer/presentation/debugmessagetreewidget.cpp new file mode 100644 index 00000000..01a58ea5 --- /dev/null +++ b/analyzer/analyzer/presentation/debugmessagetreewidget.cpp @@ -0,0 +1,90 @@ +#include "debugmessagetreewidget.h" +#include +#include + +using namespace std; + +void DebugMessageTreeWidget::init(TraceNavigator *navigator, TracePlot *traceplot) +{ + Q_ASSERT(isInitialized == false); + isInitialized = true; + arrangeUiSettings(); + connect(navigator,SIGNAL(currentTraceTimeChanged()),this,SLOT(currentTraceTimeChanged())); + connect(navigator,SIGNAL(selectedTransactionsChanged()),this,SLOT(selectedTransactionChanged())); + this->traceplot = traceplot; + this->navigator = navigator; + currentTraceTimeChanged(); +} + +void DebugMessageTreeWidget::arrangeUiSettings() +{ + QFont font = QGuiApplication::font(); + font.setPointSize(10); + this->setFont(font); + setColumnCount(2); + setHeaderLabels(QStringList({"Time", "Message"})); +} + +void DebugMessageTreeWidget::selectedTransactionChanged() +{ + if(navigator->hasSelectedTransactions()) + { + Timespan span = navigator->getSpanCoveredBySelectedTransaction(); + showDebugMessages(navigator->TraceFile().getDebugMessagesInTimespan(span)); + } + else + { + showDebugMessages(navigator->TraceFile().getDebugMessagesInTimespan(traceplot->GetCurrentTimespan())); + } +} + + +void DebugMessageTreeWidget::currentTraceTimeChanged() +{ + if(!navigator->hasSelectedTransactions()) + showDebugMessages(navigator->TraceFile().getDebugMessagesInTimespan(traceplot->GetCurrentTimespan())); +} + +void DebugMessageTreeWidget::showDebugMessages(const vector& comments) +{ + clear(); + if(comments.empty()) + return; + + traceTime currentTime = -1; + for(Comment comment: comments) + { + if(currentTime != comment.Time()) + { + addTopLevelItem(new QTreeWidgetItem({formatTraceTimePretty(comment.Time()), formatDebugMessage(comment.Text())})); + currentTime = comment.Time(); + } + else + { + addTopLevelItem(new QTreeWidgetItem({"", formatDebugMessage(comment.Text())})); + } + } + + this->resizeColumnToContents(0); + this->scrollToTop(); +} + +QString DebugMessageTreeWidget::formatDebugMessage(const QString &message) +{ + QString formattedMessage = message; + formattedMessage.replace(hexAdressMatcher,""); + formattedMessage.replace(timeAnnotationMatcher,""); + formattedMessage.replace("\t"," "); + return formattedMessage; +} + +void DebugMessageTreeWidget::mousePressEvent(QMouseEvent *event) +{ + QTreeWidgetItem* itemUnderCursor = itemAt(event->pos()); + if(itemUnderCursor != NULL) + { + QToolTip::showText(this->mapToGlobal(event->pos()), itemUnderCursor->text(1)); + } +} + + diff --git a/analyzer/analyzer/presentation/debugmessagetreewidget.h b/analyzer/analyzer/presentation/debugmessagetreewidget.h new file mode 100644 index 00000000..7a0e6cc8 --- /dev/null +++ b/analyzer/analyzer/presentation/debugmessagetreewidget.h @@ -0,0 +1,37 @@ +#ifndef DEBUGMESSAGELISTWIDGET_H +#define DEBUGMESSAGELISTWIDGET_H +#include +#include +#include +#include +#include +#include "businessObjects/comment.h" +#include "tracenavigator.h" +#include "traceplot.h" + +class DebugMessageTreeWidget : public QTreeWidget +{ + Q_OBJECT + +public: + DebugMessageTreeWidget(QWidget *parent = 0) : QTreeWidget(parent),isInitialized(false), timeAnnotationMatcher(QString("@[0-9]+ n?s")), hexAdressMatcher(QString("0x[0-9,a-f]+")) {} + void init(TraceNavigator* navigator, TracePlot* traceplot); + + void showDebugMessages(const std::vector& comments); + void arrangeUiSettings(); + +public Q_SLOTS: + void currentTraceTimeChanged(); + void selectedTransactionChanged(); + +private: + bool isInitialized; + TracePlot* traceplot; + TraceNavigator* navigator; + QRegularExpression timeAnnotationMatcher; + QRegularExpression hexAdressMatcher; + QString formatDebugMessage(const QString& message); + void mousePressEvent(QMouseEvent *event); +}; + +#endif // DEBUGMESSAGELISTWIDGET_H diff --git a/analyzer/analyzer/presentation/pornotracescroller.cpp b/analyzer/analyzer/presentation/pornotracescroller.cpp new file mode 100644 index 00000000..4321da61 --- /dev/null +++ b/analyzer/analyzer/presentation/pornotracescroller.cpp @@ -0,0 +1,238 @@ +#include +#include +#include +#include "pornotracescroller.h" +#include "traceplotitem.h" +#include "util/engineeringScaleDraw.h" + +PornoTraceScroller::PornoTraceScroller(QWidget *parent): + QwtPlot(parent),isInitialized(false),drawingProperties(false, false, ColorGrouping::Transaction) +{ + setAxisScaleDraw(xBottom,new EngineeringScaleDraw); + canvas()->setCursor(Qt::ArrowCursor); + canvasClip = new QwtPlotZoneItem(); + canvasClip->setZ(2); + canvasClip->attach(this); +} + +void PornoTraceScroller::init(TraceNavigator *navigator, TracePlot *tracePlot) +{ + Q_ASSERT(isInitialized == false); + isInitialized = true; + + this -> navigator = navigator; + connectNavigatorQ_SIGNALS(); + + setUpAxis(); + setUpDrawingProperties(); + setUpTracePlotItem(); + getAndDrawComments(); + + this->tracePlot = tracePlot; + QObject::connect(tracePlot,SIGNAL(tracePlotZoomChanged()),this,SLOT(tracePlotZoomChanged())); + tracePlotZoomChanged(); + + QObject::connect(tracePlot,SIGNAL(colorGroupingChanged(ColorGrouping)),this,SLOT(colorGroupingChanged(ColorGrouping))); +} + + +void PornoTraceScroller::setUpTracePlotItem() +{ + TracePlotItem *tracePlotItem = new TracePlotItem(transactions,*navigator, drawingProperties); + tracePlotItem->setZ(1); + tracePlotItem->attach(this); +} + +void PornoTraceScroller::setUpDrawingProperties() +{ + unsigned int numberOfBanks = navigator -> GeneralTraceInfo().numberOfBanks; + drawingProperties.numberOfBanks = numberOfBanks; + drawingProperties.yValResponse = numberOfBanks; + drawingProperties.yValRequest = numberOfBanks + 1; + drawingProperties.yValCommandBus = -3; + drawingProperties.yValDataBus = -4; +} + + +void PornoTraceScroller::setUpAxis() +{ + setAxisScale(yLeft, -1, navigator -> GeneralTraceInfo().numberOfBanks + 2, 1.0); + axisScaleDraw(yLeft)->enableComponent(QwtAbstractScaleDraw::Labels, false ); + axisScaleDraw(yLeft)->enableComponent(QwtAbstractScaleDraw::Ticks, false ); +} + +void PornoTraceScroller::connectNavigatorQ_SIGNALS() +{ + QObject::connect(navigator,SIGNAL(currentTraceTimeChanged()), this, SLOT(currentTraceTimeChanged())); + QObject::connect(navigator,SIGNAL(commentsChanged()),this,SLOT(commentsChanged())); + QObject::connect(navigator,SIGNAL(selectedTransactionsChanged()),this,SLOT(selectedTransactionsChanged())); +} + +Timespan PornoTraceScroller::GetCurrentTimespan() +{ + traceTime deltaOnTracePlot = navigator->GeneralTraceInfo().span.End() - tracePlot->ZoomLevel(); + traceTime deltaOnPornoTraceScroller = navigator->GeneralTraceInfo().span.End() - zoomLevel; + + traceTime newBegin = static_cast (tracePlot->GetCurrentTimespan().Begin() * (1.0*deltaOnPornoTraceScroller)/deltaOnTracePlot); + Timespan span(newBegin, newBegin + zoomLevel); + + if(span.Begin() < 0) + span.shift(-span.Begin()); + else if(span.End() > navigator->GeneralTraceInfo().span.End()) + span.shift(navigator->GeneralTraceInfo().span.End() - span.End()); + return span; +} + + +void PornoTraceScroller::getAndDrawComments() +{ + for(const auto &pair: navigator->getComments()) + { + const Comment &comment = pair.second; + QwtPlotMarker *maker = new QwtPlotMarker(); + maker->setXValue(static_cast(comment.Time())); + maker->setLineStyle(QwtPlotMarker::LineStyle::VLine); + maker->setLinePen(QColor(Qt::blue),2); + maker->attach(this); + } +} + + +/* Q_SLOTS + * + * + */ + +void PornoTraceScroller::selectedTransactionsChanged() +{ + replot(); +} + +void PornoTraceScroller::colorGroupingChanged(ColorGrouping colorGrouping) +{ + drawingProperties.colorGrouping = colorGrouping; + replot(); +} + +void PornoTraceScroller::currentTraceTimeChanged() +{ + Timespan spanOnTracePlot = tracePlot->GetCurrentTimespan(); + canvasClip->setInterval(spanOnTracePlot.Begin(), spanOnTracePlot.End()); + Timespan span = GetCurrentTimespan(); + transactions = navigator->TraceFile().getTransactionsInTimespan(span); + setAxisScale(xBottom,span.Begin(),span.End()); + replot(); +} + +void PornoTraceScroller::commentsChanged() +{ + detachItems(QwtPlotItem::Rtti_PlotMarker); + getAndDrawComments(); + replot(); +} + +void PornoTraceScroller::tracePlotZoomChanged() +{ + zoomLevel = tracePlot->ZoomLevel()*tracePlotEnlargementFactor; + if(zoomLevel > navigator->GeneralTraceInfo().span.timeCovered()) + zoomLevel = navigator->GeneralTraceInfo().span.timeCovered(); +} + +bool PornoTraceScroller::eventFilter( QObject *object, QEvent *event ) +{ + if(object == canvas()) + { + static bool clipDragged = false; + static bool leftMousePressed = false; + static int mouseDownX = 0; + static traceTime mouseDownTracePlotTime = 0; + + switch(event->type()) + { + case QEvent::Wheel : + { + QWheelEvent *wheelEvent = static_cast(event); + traceTime offset; + int speed = 4; + (wheelEvent->delta() > 0) ? offset = -zoomLevel * speed : offset = zoomLevel * speed; + navigator->navigateToTime(navigator->CurrentTraceTime() + offset); + return true; + } + case QEvent::MouseButtonDblClick: + { + QMouseEvent *mouseEvent = static_cast(event); + traceTime time = invTransform(xBottom, mouseEvent->x()); + navigator->navigateToTime(time); + return true; + } + case QEvent::MouseButtonPress: + { + QMouseEvent *mouseEvent = static_cast(event); + + if(mouseEvent->button() == Qt::LeftButton) + { + canvas()->setCursor(Qt::ClosedHandCursor); + leftMousePressed = true; + mouseDownTracePlotTime = tracePlot->GetCurrentTimespan().Middle(); + mouseDownX = mouseEvent->x(); + if(tracePlot->GetCurrentTimespan().contains(invTransform(xBottom, mouseEvent->x()))) + clipDragged = true; + else + clipDragged = false; + return true; + } + else if(mouseEvent->button() == Qt::RightButton) + { + navigator->navigateToTime(static_cast(invTransform(xBottom, mouseEvent->x()))); + return true; + } + } + case QEvent::MouseButtonRelease: + { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == Qt::LeftButton) + { + clipDragged = false; + leftMousePressed = false; + canvas()->setCursor(Qt::ArrowCursor); + return true; + } + } + case QEvent::MouseMove: + { + QMouseEvent *mouseEvent = static_cast(event); + if(leftMousePressed) + { + if(clipDragged) + { + double clipWidth = transform(xBottom, tracePlot->ZoomLevel()) - transform(xBottom, 0); + + if(mouseEvent->x() < clipWidth/2) + { + navigator->navigateToTime(0); + } + else if(mouseEvent->x() > canvas()->width() - clipWidth/2) + { + navigator->navigateToTime(navigator->GeneralTraceInfo().span.End()); + } + else + { + traceTime time = static_cast((mouseEvent->x() - clipWidth/2) / + (canvas()->width() - clipWidth) * (navigator->GeneralTraceInfo().span.End() - tracePlot->ZoomLevel())); + navigator->navigateToTime(time); + } + } + else + { + traceTime deltaTime = invTransform(xBottom, mouseDownX) - invTransform(xBottom, mouseEvent->x()); + navigator->navigateToTime(mouseDownTracePlotTime + deltaTime); + } + return true; + } + } + default: + break; + } + } + return false; +} diff --git a/analyzer/analyzer/presentation/pornotracescroller.h b/analyzer/analyzer/presentation/pornotracescroller.h new file mode 100644 index 00000000..ec552ff3 --- /dev/null +++ b/analyzer/analyzer/presentation/pornotracescroller.h @@ -0,0 +1,46 @@ +#ifndef PORNOTRACESCROLLER_H +#define PORNOTRACESCROLLER_H + +#include +#include +#include +#include "presentation/tracenavigator.h" +#include "traceplot.h" + + +class PornoTraceScroller : public QwtPlot +{ +Q_OBJECT +private: + std::vector> transactions; + bool isInitialized; + TraceNavigator* navigator; + TracePlot* tracePlot; + constexpr static int tracePlotEnlargementFactor = 4; + void setUpTracePlotItem(); + void setUpDrawingProperties(); + void setUpAxis(); + void connectNavigatorQ_SIGNALS(); + + + void getAndDrawComments(); + QwtPlotZoneItem *canvasClip; + traceTime zoomLevel; + bool eventFilter( QObject *object, QEvent *event ); + TraceDrawingProperties drawingProperties; + +public: + PornoTraceScroller(QWidget *parent = NULL); + void init(TraceNavigator* navigator, TracePlot* tracePlot); + Timespan GetCurrentTimespan(); + +public Q_SLOTS: + void currentTraceTimeChanged(); + void commentsChanged(); + void tracePlotZoomChanged(); + void selectedTransactionsChanged(); + void colorGroupingChanged(ColorGrouping colorgrouping); + +}; + +#endif // PORNOTRACESCROLLER_H diff --git a/analyzer/analyzer/presentation/selectedtransactiontreewidget.cpp b/analyzer/analyzer/presentation/selectedtransactiontreewidget.cpp new file mode 100644 index 00000000..95a20a83 --- /dev/null +++ b/analyzer/analyzer/presentation/selectedtransactiontreewidget.cpp @@ -0,0 +1,20 @@ +#include "selectedtransactiontreewidget.h" + + + +void SelectedTransactionTreeWidget::selectedTransactionsChanged() +{ + this->clear(); + for(const auto& transaction : navigator->SelectedTransactions()) + { + AppendTransaction(transaction); + } + expandAll(); + resizeColumnToContents(0); +} + +void SelectedTransactionTreeWidget::init(TraceNavigator *navigator) +{ + TransactionTreeWidget::init(navigator); + QObject::connect(navigator, SIGNAL(selectedTransactionsChanged()), this, SLOT(selectedTransactionsChanged())); +} diff --git a/analyzer/analyzer/presentation/selectedtransactiontreewidget.h b/analyzer/analyzer/presentation/selectedtransactiontreewidget.h new file mode 100644 index 00000000..3621d647 --- /dev/null +++ b/analyzer/analyzer/presentation/selectedtransactiontreewidget.h @@ -0,0 +1,19 @@ +#ifndef SELECTEDTRANSACTIONTREEWIDGET_H +#define SELECTEDTRANSACTIONTREEWIDGET_H +#include "transactiontreewidget.h" + +class SelectedTransactionTreeWidget : public TransactionTreeWidget +{ + Q_OBJECT + + bool isInitialized; +public: + SelectedTransactionTreeWidget(QWidget *parent = 0) : TransactionTreeWidget(parent), isInitialized(false){} + virtual void init(TraceNavigator* navigator); + +public Q_SLOTS: + void selectedTransactionsChanged(); + +}; + +#endif // SELECTEDTRANSACTIONTREEWIDGET_H diff --git a/analyzer/analyzer/presentation/tracePlotMouseLabel.cpp b/analyzer/analyzer/presentation/tracePlotMouseLabel.cpp new file mode 100644 index 00000000..06209dc2 --- /dev/null +++ b/analyzer/analyzer/presentation/tracePlotMouseLabel.cpp @@ -0,0 +1,22 @@ +#include "tracePlotMouseLabel.h" +#include "businessObjects/tracetime.h" + +void TracePlotMouseLabel::setMode(MouseLabelMode mode) +{ + this->mode = mode; +} + +QwtText TracePlotMouseLabel::trackerText(const QPoint &point) const +{ + if(mode == MouseLabelMode::AbsoluteTime) + { + traceTime mouseTime = static_cast(traceplot->invTransform(traceplot->xBottom, point.x())); + return QwtText(formatTraceTimePretty(alignToClk(mouseTime,clkPeriod))); + } + else if(mode == MouseLabelMode::Timedifference) + { + long long numberOfClockCovered = timeDifferenceSpan.timeCovered()/clkPeriod; + QString suffix = (numberOfClockCovered != 1) ? QString(" clks") : QString(" clk"); + return(QwtText(QString::number(numberOfClockCovered) + suffix)); + } +} diff --git a/analyzer/analyzer/presentation/tracePlotMouseLabel.h b/analyzer/analyzer/presentation/tracePlotMouseLabel.h new file mode 100644 index 00000000..9043745e --- /dev/null +++ b/analyzer/analyzer/presentation/tracePlotMouseLabel.h @@ -0,0 +1,28 @@ +#ifndef TRACEPLOTPICKER_H +#define TRACEPLOTPICKER_H + +#include +#include "traceplot.h" + +enum class MouseLabelMode{AbsoluteTime, Timedifference}; + +class TracePlotMouseLabel : public QwtPlotPicker +{ +public: + TracePlotMouseLabel(TracePlot* traceplot, unsigned int clkPeriod, Timespan& timeDifferenceSpan): + QwtPlotPicker(QwtPlot::xBottom, QwtPlot::yLeft,QwtPlotPicker::VLineRubberBand, + QwtPicker::AlwaysOn, traceplot->canvas()), + traceplot(traceplot),clkPeriod(clkPeriod), timeDifferenceSpan(timeDifferenceSpan), mode(MouseLabelMode::AbsoluteTime){} + + void setMode(MouseLabelMode mode); +protected: + virtual QwtText trackerText(const QPoint &point) const; + +private: + MouseLabelMode mode; + TracePlot* traceplot; + Timespan& timeDifferenceSpan; + unsigned int clkPeriod; +}; + +#endif // TRACEPLOTPICKER_H diff --git a/analyzer/analyzer/presentation/tracedrawing.cpp b/analyzer/analyzer/presentation/tracedrawing.cpp new file mode 100644 index 00000000..ab2847f6 --- /dev/null +++ b/analyzer/analyzer/presentation/tracedrawing.cpp @@ -0,0 +1,135 @@ +#include "tracedrawing.h" + +void drawVerticalLine(QPainter *painter, int xPos, const QRectF &canvasRect) +{ + /* P1 (xPos,lowerCanvasYBorder) + * | + * | + * | + * | + * P2 (xPos,upperCanvasYBorder) + */ + + + + QPoint P1(xPos,static_cast(canvasRect.top())); + QPoint P2(xPos,static_cast(canvasRect.bottom())); + painter->drawLine(QLine(P1,P2)); +} + +void drawDoubleArrow(QPainter *painter, int xFrom, int xTo, int y) +{ + + /* P1 P3 + // / \ + // / {text} \ + // from (-------------------------------------------) to + // \ / + // \ / + // P2 P4 + */ + + QPoint from(xFrom,y); + QPoint to(xTo,y); + QPoint P1(xFrom+10,y-5); + QPoint P2(xFrom+10,y+5); + QPoint P3(xTo-10,y-5); + QPoint P4(xTo-10,y+5); + + painter->drawLine(from,to); + painter->drawLine(P1,from); + painter->drawLine(P2,from); + painter->drawLine(P3,to); + painter->drawLine(P4,to); + + + +} + +void drawDoubleArrow(QPainter *painter, int xFrom, int xTo, int y, const QString &text, const QColor &textColor) +{ + drawDoubleArrow(painter, xFrom, xTo, y); + drawText(painter, text, QPoint((xTo + xFrom) / 2, y), TextPositioning::topCenter, textColor); +} + +void drawHexagon(QPainter *painter, const QPoint& from, const QPoint& to, double height) +{ + // {text} + // P1------------------------P2 + // From / \ To + // \ / + // P4-------------------------P3 + + int offset = 10; + if( (to.x() - from.x()) <= 20) + { + offset = 5; + } + if( (to.x() - from.x()) <= 10) + { + offset = 2; + } + if( (to.x() - from.x()) <= 4) + { + offset = 0; + } + + QPointF P1(from.x()+offset , from.y()-height/2); + QPointF P2(to.x() -offset , to.y() -height/2); + QPointF P3(to.x() -offset , to.y() +height/2); + QPointF P4(from.x()+offset , from.y()+height/2); + + QPolygonF polygon; + polygon << from + << P1 + << P2 + << to + << P3 + << P4; + + painter->drawPolygon(polygon); +} + +void drawText(QPainter *painter, const QString &text, const QPoint &position, const TextPositioning &positioning, const QColor &textColor) +{ + //*--------------* + //| | | + //|------x-------| + //| | | + //*--------------* + + QPen saved = painter->pen(); + painter->setPen(QPen(textColor)); + QFontMetrics fm = painter->fontMetrics(); + QPoint offset(fm.width(text), fm.height()); + QRect rect(position - offset, position + offset); + + int flags; + switch(positioning) + { + case TextPositioning::topRight: + flags = Qt::AlignRight | Qt::AlignTop; + break; + case TextPositioning::bottomRight: + flags = Qt::AlignRight | Qt::AlignBottom; + break; + case TextPositioning::bottomLeft: + flags = Qt::AlignLeft | Qt::AlignBottom; + break; + case TextPositioning::topCenter: + flags = Qt::AlignHCenter | Qt::AlignTop; + break; + case TextPositioning::bottomCenter: + flags = Qt::AlignHCenter | Qt::AlignBottom; + break; + case TextPositioning::centerCenter: + flags = Qt::AlignHCenter | Qt::AlignCenter; + break; + case TextPositioning::topLeft:default: + flags = Qt::AlignLeft | Qt::AlignTop; + break; + } + + painter->drawText(rect, flags, text); + painter->setPen(saved); +} diff --git a/analyzer/analyzer/presentation/tracedrawing.h b/analyzer/analyzer/presentation/tracedrawing.h new file mode 100644 index 00000000..2ffe3318 --- /dev/null +++ b/analyzer/analyzer/presentation/tracedrawing.h @@ -0,0 +1,17 @@ +#ifndef TRACEDRAWING_H +#define TRACEDRAWING_H + +#include +#include +#include +#include + +enum class TextPositioning{topRight, topLeft, bottomRight, bottomLeft, topCenter, bottomCenter, centerCenter}; + +void drawVerticalLine(QPainter *painter, int xPos, const QRectF &canvasRect); +void drawDoubleArrow(QPainter *painter, int xFrom, int xTo, int y); +void drawDoubleArrow(QPainter *painter, int xFrom, int xTo, int y, const QString &text, const QColor &textColor = QColor(Qt::black)); +void drawHexagon(QPainter *painter, const QPoint& from, const QPoint& to, double height); +void drawText(QPainter *painter, const QString &text, const QPoint &position, const TextPositioning &positioning, const QColor &textColor = QColor(Qt::black)); + +#endif // TRACEDRAWING_H diff --git a/analyzer/analyzer/presentation/tracedrawingproperties.h b/analyzer/analyzer/presentation/tracedrawingproperties.h new file mode 100644 index 00000000..2d340f91 --- /dev/null +++ b/analyzer/analyzer/presentation/tracedrawingproperties.h @@ -0,0 +1,43 @@ +#ifndef TRACECOLLECTIONDRAWINGPROPERTIES_H +#define TRACECOLLECTIONDRAWINGPROPERTIES_H +#include +#include +#include +#include +#include "tracedrawing.h" + +enum class ColorGrouping {PhaseType, Transaction, Thread}; + +struct TraceDrawingProperties +{ + bool drawText; + bool drawBorder; + ColorGrouping colorGrouping; + int yValResponse; + int yValRequest; + int yValCommandBus; + int yValDataBus; + unsigned int numberOfBanks; + + TraceDrawingProperties() : drawText(true), drawBorder(true), colorGrouping(ColorGrouping::Transaction){} + TraceDrawingProperties(bool drawText, bool drawBorder, ColorGrouping colorGrouping) : drawText(drawText), drawBorder(drawBorder), colorGrouping(colorGrouping){} + TraceDrawingProperties(bool drawText, bool drawBorder, ColorGrouping colorGrouping, int yValResponse,int yValRequest, int yValCommandBus,int yValDataBus, unsigned int numberOfBanks) : + drawText(drawText), drawBorder(drawBorder), colorGrouping(colorGrouping), yValResponse(yValResponse), yValRequest(yValRequest), yValCommandBus(yValCommandBus),yValDataBus(yValDataBus),numberOfBanks(numberOfBanks){} + + QHash getLabels() const + { + QHash result; + for(unsigned int i=0; i +#include "businessObjects/tracecalculatedmetrics.h" + + +class TraceMetricTreeWidget : public QTreeWidget +{ + Q_OBJECT +public: + TraceMetricTreeWidget(QWidget *parent = 0); + void addTraceMetricResults(const TraceCalculatedMetrics& result); + +}; + +#endif // TRACEMETRICTREEWIDGET_H diff --git a/analyzer/analyzer/presentation/tracenavigator.cpp b/analyzer/analyzer/presentation/tracenavigator.cpp new file mode 100644 index 00000000..74d11733 --- /dev/null +++ b/analyzer/analyzer/presentation/tracenavigator.cpp @@ -0,0 +1,251 @@ +#include "tracenavigator.h" +#include "vector" + +using namespace std; + +TraceNavigator::TraceNavigator(QString path, QObject * parent) + : QObject(parent),traceFile(path,true), changesToCommitExist(false) +{ + getCommentsFromDB(); +} + +TraceNavigator::~TraceNavigator() +{ +} + +/* Navigation + * + * + */ + +void TraceNavigator::navigateToTime(traceTime time) +{ + if(time < 0) + time = 0; + else if(time>traceFile.getGeneralInfo().span.End()) + time = traceFile.getGeneralInfo().span.End(); + else + { + currentTraceTime = time; + Q_EMIT currentTraceTimeChanged(); + } +} + +void TraceNavigator::navigateToTransaction(ID id) +{ + navigateToTime(traceFile.getTransactionByID(id)->Span().Begin()); +} + + +/* Comment and debug messages + * + */ +void TraceNavigator::insertComment(const Comment &comment) +{ + comments.emplace(comment.Time(), comment); + changesToCommitExist = true; + Q_EMIT commentsChanged(); +} + +void TraceNavigator::removeCommentAtTime(traceTime time) +{ + auto found = comments.find(time); + if(found != comments.end()) + { + comments.erase(found); + changesToCommitExist = true; + Q_EMIT commentsChanged(); + } +} + + + +/* DB + * + */ + +void TraceNavigator::commitChangesToDB() +{ + vector commentsToInsert; + for(const auto& pair: comments) + { + commentsToInsert.push_back(pair.second); + } + + traceFile.updateComments(commentsToInsert); + //TODO : reinsert file description logic + //traceFile.updateFileDescription(traceFile.getGeneralInfo().Description()); + changesToCommitExist = false; +} + +void TraceNavigator::getCommentsFromDB() +{ + for(const Comment& comment: traceFile.getComments()) + { + comments.emplace(comment.Time(),comment); + } +} + +void TraceNavigator::setFileDescripton(const QString &description) +{ + //TODO : reinsert file description logic + changesToCommitExist = true; +} + +void TraceNavigator::refreshData() +{ + traceFile.refreshData(); + clearSelectedTransactions(); + navigateToTime(currentTraceTime); +} + +/* Transaction Selection + * + * + */ + +void TraceNavigator::addSelectedTransactions(const vector>& transactions) +{ + for(const auto transaction : transactions) + { + selectedTransactions.push_back(transaction); + } + Q_EMIT selectedTransactionsChanged(); +} + +void TraceNavigator::addSelectedTransaction(const shared_ptr &transaction) +{ + selectedTransactions.push_back(transaction); + Q_EMIT selectedTransactionsChanged(); +} + +void TraceNavigator::addSelectedTransaction(ID id) +{ + shared_ptr transaction = TraceFile().getTransactionByID(id); + selectedTransactions.push_back(transaction); + Q_EMIT selectedTransactionsChanged(); +} + +void TraceNavigator::selectTransaction(ID id) +{ + clearSelectedTransactions(); + addSelectedTransaction(id); + navigateToTransaction(id); +} + +void TraceNavigator::selectTransaction(const shared_ptr &transaction) +{ + selectTransaction(transaction->Id()); +} + +void TraceNavigator::selectNextTransaction() +{ + if(selectedTransactions.empty() || selectedTransactions.front()->Id() == traceFile.getGeneralInfo().numberOfTransactions) + selectFirstTransaction(); + else + selectTransaction(selectedTransactions.front()->Id() + 1); +} + +void TraceNavigator::selectPreviousTransaction() +{ + if(selectedTransactions.empty() || selectedTransactions.front()->Id() == 1) + selectLastTransaction(); + else + selectTransaction(selectedTransactions.front()->Id() - 1); +} + +void TraceNavigator::selectFirstTransaction() +{ + selectTransaction(1); +} + +void TraceNavigator::selectLastTransaction() +{ + selectTransaction(traceFile.getGeneralInfo().numberOfTransactions); +} + + +void TraceNavigator::selectNextRefresh() +{ + shared_ptr nextRefresh; + + if(!SelectedTransactions().empty()) + nextRefresh = traceFile.getNextRefresh(SelectedTransactions().front()->Id()); + else + nextRefresh = traceFile.getNextRefresh(0); + + if(nextRefresh) + selectTransaction(nextRefresh); +} + +void TraceNavigator::selectNextActivate() +{ + shared_ptr nextActivate; + + if(!SelectedTransactions().empty()) + nextActivate = traceFile.getNextActivate(SelectedTransactions().front()->Id()); + else + nextActivate = traceFile.getNextActivate(0); + + if(nextActivate) + selectTransaction(nextActivate); +} + +void TraceNavigator::selectNextPrecharge() +{ + shared_ptr nextPrecharge; + + if(!SelectedTransactions().empty()) + nextPrecharge = traceFile.getNextPrecharge(SelectedTransactions().front()->Id()); + else + nextPrecharge = traceFile.getNextPrecharge(0); + + if(nextPrecharge) + selectTransaction(nextPrecharge); +} + + + +bool TraceNavigator::transactionIsSelected(const shared_ptr &transaction) const +{ + return transactionIsSelected(transaction->Id()); +} + +bool TraceNavigator::transactionIsSelected(ID id) const +{ + for (const auto& transaction : selectedTransactions) { + if(transaction->Id() == id) + return true; + } + return false; +} + +void TraceNavigator::clearSelectedTransactions() +{ + if(hasSelectedTransactions()) + { + selectedTransactions.clear(); + Q_EMIT selectedTransactionsChanged(); + } +} + +bool TraceNavigator::hasSelectedTransactions() +{ + return !selectedTransactions.empty(); +} + +Timespan TraceNavigator::getSpanCoveredBySelectedTransaction() +{ + if(!hasSelectedTransactions()) + return Timespan(0,0); + + traceTime begin = SelectedTransactions().at(0)->Span().Begin(); + traceTime end = SelectedTransactions().at(0)->Span().End(); + + for (const auto& transaction : selectedTransactions) { + if(transaction->Span().End() > end) + end = transaction->Span().End(); + } + + return Timespan(begin,end); +} diff --git a/analyzer/analyzer/presentation/tracenavigator.h b/analyzer/analyzer/presentation/tracenavigator.h new file mode 100644 index 00000000..aad497db --- /dev/null +++ b/analyzer/analyzer/presentation/tracenavigator.h @@ -0,0 +1,82 @@ +#ifndef TRACENAVIGATOR_H +#define TRACENAVIGATOR_H +#include +#include +#include "data/tracedb.h" +#include "businessObjects/generalinfo.h" +#include "businessObjects/transaction.h" +#include "businessObjects/comment.h" +#include "memory" + +/* Class to navigate through a tracefile + * + * + */ + +class TraceNavigator : public QObject +{ + Q_OBJECT + using CommentMap = std::map; + +public: + TraceNavigator(QString path, QObject * parent = 0); + ~TraceNavigator(); + + traceTime CurrentTraceTime() const{return currentTraceTime;} + TraceDB& TraceFile(){return traceFile;} + const GeneralInfo& GeneralTraceInfo() {return traceFile.getGeneralInfo();} + + void navigateToTime(traceTime time); + void navigateToTransaction(ID id); + + /* Transaction selection + * (selecting a single transactions also navigates to that transaction) + */ + void selectTransaction(ID id); + void selectTransaction(const std::shared_ptr &transaction); + void selectNextTransaction(); + void selectPreviousTransaction(); + void selectLastTransaction(); + void selectFirstTransaction(); + void selectNextRefresh(); + void selectNextActivate(); + void selectNextPrecharge(); + + void addSelectedTransactions(const std::vector>& transactions); + const std::vector>& SelectedTransactions(){return selectedTransactions;} + void addSelectedTransaction(const std::shared_ptr &Transaction); + void addSelectedTransaction(ID id); + void clearSelectedTransactions(); + bool hasSelectedTransactions(); + Timespan getSpanCoveredBySelectedTransaction(); + + bool transactionIsSelected(ID id) const; + bool transactionIsSelected(const std::shared_ptr &Transaction) const; + + void insertComment(const Comment& comment); + const CommentMap& getComments(){return comments;} + void removeCommentAtTime(traceTime time); + + void setFileDescripton(const QString& text); + void commitChangesToDB(); + void refreshData(); + +Q_SIGNALS: + void currentTraceTimeChanged(); + void selectedTransactionsChanged(); + void commentsChanged(); + +private: + TraceDB traceFile; + + //represents the current position in the tracefile + //components drawing the tracefile center around that time + traceTime currentTraceTime = 0; + std::vector> selectedTransactions; + CommentMap comments; + void getCommentsFromDB(); + bool changesToCommitExist; + +}; + +#endif // TRACENAVIGATOR_H diff --git a/analyzer/analyzer/presentation/traceplot.cpp b/analyzer/analyzer/presentation/traceplot.cpp new file mode 100644 index 00000000..3127aea9 --- /dev/null +++ b/analyzer/analyzer/presentation/traceplot.cpp @@ -0,0 +1,546 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tracePlotMouseLabel.h" +#include "traceplot.h" +#include "gototimedialog.h" +#include "tracedrawing.h" +#include "util/engineeringScaleDraw.h" +#include "util/clkgrid.h" +#include "util/customlabelscaledraw.h" + +using namespace std; + + +TracePlot::TracePlot(QWidget *parent): + QwtPlot(parent),isInitialized(false) +{ + canvas()->setCursor(Qt::ArrowCursor); + setUpActions(); +} + +void TracePlot::setUpActions() +{ + insertComment = new QAction("Insert comment",this); + QObject::connect(insertComment, SIGNAL(triggered()), this, SLOT(on_insertComment())); + + goToTime = new QAction("Go to time",this); + QObject::connect(goToTime, SIGNAL(triggered()), this, SLOT(on_goToTime())); + + goToTransaction = new QAction("Go to transaction", this); + QObject::connect(goToTransaction, SIGNAL(triggered()), this, SLOT(on_goToTransaction())); + + deselectAll = new QAction("Deselect all",this); + QObject::connect(deselectAll, SIGNAL(triggered()), this, SLOT(on_deselectAll())); + + goToPhase = new QAction("Go to phase", this); + QObject::connect(goToPhase, SIGNAL(triggered()), this, SLOT(on_goToPhase())); + + showQueryEditor = new QAction("Execute query",this); + showQueryEditor->setShortcut(QKeySequence("ctrl+e")); + addAction(showQueryEditor); + QObject::connect(showQueryEditor,SIGNAL(triggered()),this,SLOT(on_executeQuery())); + + selectNextRefresh = new QAction("Select next refresh",this); + selectNextRefresh->setShortcut(QKeySequence("alt+r")); + addAction(selectNextRefresh); + QObject::connect(selectNextRefresh, SIGNAL(triggered()), this, SLOT(on_selectNextRefresh())); + + selectNextActivate = new QAction("Select next activate",this); + selectNextActivate->setShortcut(QKeySequence("alt+a")); + addAction(selectNextActivate); + QObject::connect(selectNextActivate, SIGNAL(triggered()), this, SLOT(on_selectNextActivate())); + + selectNextPrecharge = new QAction("Select next precharge",this); + selectNextPrecharge->setShortcut(QKeySequence("alt+p")); + addAction(selectNextPrecharge); + QObject::connect(selectNextPrecharge, SIGNAL(triggered()), this, SLOT(on_selectNextPrecharge())); + + setColorGroupingPhase = new QAction("Group by Phase",this); + addAction(setColorGroupingPhase); + QObject::connect(setColorGroupingPhase, SIGNAL(triggered()), this, SLOT(on_colorGroupingPhase())); + + setColorGroupingTransaction = new QAction("Group by Transaction",this); + addAction(setColorGroupingTransaction); + QObject::connect(setColorGroupingTransaction, SIGNAL(triggered()), this, SLOT(on_colorGroupingTransaction())); + + setColorGroupingThread = new QAction("Group by Thread",this); + addAction(setColorGroupingThread); + QObject::connect(setColorGroupingThread, SIGNAL(triggered()), this, SLOT(on_colorGroupingThread())); + + exportToPdf = new QAction("Export to SVG", this); + addAction(exportToPdf); + QObject::connect(exportToPdf, SIGNAL(triggered()), this, SLOT(on_exportToPDF())); + + setUpContextMenu(); +} + +void TracePlot::setUpContextMenu() +{ + contextMenu = new QMenu(this); + contextMenu->addActions({deselectAll}); + + QMenu* colorGroupingSubMenu = new QMenu("Group by",contextMenu); + colorGroupingSubMenu->addActions({setColorGroupingTransaction, setColorGroupingPhase, setColorGroupingThread}); + contextMenu->addMenu(colorGroupingSubMenu); + + QMenu* goToSubMenu = new QMenu("Go to",contextMenu); + goToSubMenu->addActions({goToPhase,goToTransaction,goToTime}); + contextMenu->addMenu(goToSubMenu); + + QMenu* selectSubMenu = new QMenu("Select",contextMenu); + selectSubMenu->addActions({selectNextRefresh, selectNextActivate,selectNextPrecharge}); + contextMenu->addMenu(selectSubMenu); + + contextMenu->addActions({showQueryEditor, insertComment,exportToPdf}); +} + +void TracePlot::init(TraceNavigator* navigator) +{ + Q_ASSERT(isInitialized == false); + isInitialized = true; + + this->navigator = navigator; + connectNavigatorQ_SIGNALS(); + setUpDrawingProperties(); + setUpAxis(); + setUpGrid(); + setUpTracePlotItem(); + setUpZoom(); + setUpQueryEditor(); + mouseLabel = new TracePlotMouseLabel(this,navigator->GeneralTraceInfo().clkPeriod,this->mouseDownData.zoomSpan); + getAndDrawComments(); + setZoomLevel(1000); + replot(); +} + + +void TracePlot::connectNavigatorQ_SIGNALS() +{ + QObject::connect(navigator,SIGNAL(currentTraceTimeChanged()),this,SLOT(currentTraceTimeChanged())); + QObject::connect(navigator,SIGNAL(selectedTransactionsChanged()),this,SLOT(selectedTransactionsChanged())); + QObject::connect(navigator,SIGNAL(commentsChanged()),this,SLOT(commentsChanged())); +} + +void TracePlot::setUpDrawingProperties() +{ + unsigned int numberOfBanks = navigator -> GeneralTraceInfo().numberOfBanks; + drawingProperties.numberOfBanks = numberOfBanks; + drawingProperties.yValResponse = numberOfBanks; + drawingProperties.yValRequest = numberOfBanks + 1; + drawingProperties.yValCommandBus = -3; + drawingProperties.yValDataBus = -4; +} + + +void TracePlot::setUpQueryEditor() +{ + queryEditor = new QueryEditor(this); + queryEditor->setWindowFlags(Qt::Window); + queryEditor->setWindowTitle("Query " + QFileInfo(navigator->TraceFile().getPathToDB()).baseName()); + queryEditor->init(navigator); +} + +void TracePlot::setUpTracePlotItem() +{ + tracePlotItem = new TracePlotItem(transactions,*navigator,drawingProperties); + tracePlotItem->setZ(1); + tracePlotItem->attach(this); +} + +void TracePlot::setUpGrid() +{ + unsigned int clk = navigator->GeneralTraceInfo().clkPeriod; + QwtPlotGrid *grid = new ClkGrid(clk, GridVisiblityClks*clk); + grid->setZ(0); + grid->attach(this); +} + +void TracePlot::setUpZoom() +{ + minZoomLevel = minZoomClks * navigator->GeneralTraceInfo().clkPeriod; + maxZoomLevel = maxZoomClks * navigator->GeneralTraceInfo().clkPeriod; + textVisibilityZoomLevel = textVisibilityClks * navigator->GeneralTraceInfo().clkPeriod; + zoomZone = new QwtPlotZoneItem(); + zoomZone->setZ(2); + zoomZone->attach(this); + zoomZone->setVisible(false); +} + +void TracePlot::setUpAxis() +{ + int numberOfBanks = navigator -> GeneralTraceInfo().numberOfBanks; + + setAxisScale(yLeft, -5, numberOfBanks + 2, 1.0); + setAxisScaleDraw(yLeft,new CustomLabelScaleDraw(drawingProperties.getLabels())); + + setAxisTitle(xBottom, "Time in ns"); + setAxisScaleDraw(xBottom, new EngineeringScaleDraw); +} + +Timespan TracePlot::GetCurrentTimespan() +{ + Timespan span(navigator->CurrentTraceTime() - zoomLevel / 2, navigator->CurrentTraceTime() + zoomLevel / 2); + if(span.Begin() < 0) + span.shift(-span.Begin()); + else if(span.End() > navigator->GeneralTraceInfo().span.End()) + span.shift(navigator->GeneralTraceInfo().span.End() - span.End()); + return span; +} + +void TracePlot::getAndDrawComments() +{ + for(const auto &pair: navigator->getComments()) + { + const Comment &comment = pair.second; + QwtPlotMarker *maker = new QwtPlotMarker(); + maker->setLabel(comment.Text()); + maker->setLabelOrientation(Qt::Vertical); + maker->setLabelAlignment(Qt::AlignLeft | Qt::AlignBottom); + maker->setXValue(static_cast(comment.Time())); + maker->setLineStyle(QwtPlotMarker::LineStyle::VLine); + maker->setLinePen(QColor(Qt::blue),2); + maker->attach(this); + } +} + +void TracePlot::enterZoomMode() +{ + mouseDownData.mouseIsDownForZooming = true; + mouseLabel->setMode(MouseLabelMode::Timedifference); + zoomZone->setVisible(true); + zoomZone->setInterval(mouseDownData.zoomSpan.Begin(),mouseDownData.zoomSpan.End()); +} + +void TracePlot::exitZoomMode() +{ + mouseDownData.mouseIsDownForZooming = false; + mouseLabel->setMode(MouseLabelMode::AbsoluteTime); + zoomZone->setVisible(false); +} +void TracePlot::zoomIn(traceTime zoomCenter) +{ + setZoomLevel(zoomLevel * zoomFactor); + traceTime time = zoomCenter + (GetCurrentTimespan().Middle() - zoomCenter) * zoomFactor; + Q_EMIT tracePlotZoomChanged(); + navigator->navigateToTime(time); +} + +void TracePlot::zoomOut(traceTime zoomCenter) +{ + setZoomLevel(zoomLevel / zoomFactor); + Q_EMIT tracePlotZoomChanged(); + navigator->navigateToTime(static_cast(zoomCenter + (GetCurrentTimespan().Middle() - zoomCenter) / zoomFactor)); +} + +void TracePlot::setZoomLevel(traceTime newZoomLevel) +{ + zoomLevel = newZoomLevel; + if(zoomLevel < minZoomLevel) + zoomLevel = minZoomLevel; + if(zoomLevel > navigator->GeneralTraceInfo().span.timeCovered()) + zoomLevel = navigator->GeneralTraceInfo().span.timeCovered(); + if(zoomLevel > maxZoomLevel) + zoomLevel = maxZoomLevel; + + if(zoomLevel < textVisibilityZoomLevel) + drawingProperties.drawText = true; + + if(zoomLevel > textVisibilityZoomLevel) + drawingProperties.drawText = false; +} + + +/* Q_SLOTS + * + * + */ + +void TracePlot::currentTraceTimeChanged() +{ + transactions = navigator->TraceFile().getTransactionsInTimespan(GetCurrentTimespan()); + setAxisScale(xBottom,GetCurrentTimespan().Begin(),GetCurrentTimespan().End()); + replot(); +} + +void TracePlot::selectedTransactionsChanged() +{ + replot(); +} + +void TracePlot::commentsChanged() +{ + detachItems(QwtPlotItem::Rtti_PlotMarker); + getAndDrawComments(); + replot(); +} + +void TracePlot::on_executeQuery() +{ + queryEditor->show(); +} + +void TracePlot::on_selectNextRefresh() +{ + navigator->selectNextRefresh(); +} + +void TracePlot::on_selectNextActivate() +{ + navigator->selectNextActivate(); +} + +void TracePlot::on_selectNextPrecharge() +{ + navigator->selectNextPrecharge(); +} + +void TracePlot::on_colorGroupingPhase() +{ + drawingProperties.colorGrouping = ColorGrouping::PhaseType; + Q_EMIT(colorGroupingChanged(ColorGrouping::PhaseType)); + replot(); +} + +void TracePlot::on_colorGroupingTransaction() +{ + drawingProperties.colorGrouping = ColorGrouping::Transaction; + Q_EMIT(colorGroupingChanged(ColorGrouping::Transaction)); + replot(); +} + +void TracePlot::on_colorGroupingThread() +{ + drawingProperties.colorGrouping = ColorGrouping::Thread; + Q_EMIT(colorGroupingChanged(ColorGrouping::Thread)); + replot(); +} + +void TracePlot::on_goToTransaction() +{ + bool ok; + int maxID = navigator->GeneralTraceInfo().numberOfTransactions; + int transactionID = QInputDialog::getInt(this,"Go to transaction","Enter transaction ID (0 - " + QString::number(maxID) + ")",0,0,maxID,1,&ok); + if(ok) + { + navigator->clearSelectedTransactions(); + navigator->selectTransaction(transactionID); + } +} + +void TracePlot::on_goToPhase() +{ + bool ok; + int maxID = navigator->GeneralTraceInfo().numberOfPhases; + int phaseID = QInputDialog::getInt(this,"Go to phase","Enter phase ID (0 - " + QString::number(maxID) + ")",0,0,maxID,1,&ok); + + if(ok) + { + navigator->clearSelectedTransactions(); + navigator->selectTransaction(navigator->TraceFile().getTransactionIDFromPhaseID(phaseID)); + } +} + +void TracePlot::on_deselectAll() +{ + navigator->clearSelectedTransactions(); +} + +void TracePlot::on_insertComment() +{ + traceTime time = invTransform(xBottom, contextMenuMouseDown.x()); + bool ok; + QString text = QInputDialog::getText(this,QString("Insert comment"),QString("Insert comment at ") + formatTraceTimePretty(time),QLineEdit::Normal,QString(),&ok); + if(ok) + { + navigator->insertComment(Comment(time,text)); + } +} + +void TracePlot::on_goToTime() +{ + double goToTime; + GoToTimeDialog dialog(&goToTime,this); + int dialogCode = dialog.exec(); + if(dialogCode == QDialog::Accepted) + { + traceTime time = static_cast(goToTime)*1000; + navigator->navigateToTime(time); + } +} + +void TracePlot::on_exportToPDF() +{ + QwtPlotRenderer renderer; + QString filename = QFileDialog::getSaveFileName(this, "Export to SVG", "", "Portable Document Format(*.svg)"); + if(filename != "") + { + QBrush saved = this->canvasBackground(); + this->setCanvasBackground(QBrush(Qt::white)); + renderer.renderDocument(this, filename,"svg", QSizeF(this->widthMM(),this->heightMM())); + this->setCanvasBackground(QBrush(saved)); + } +} + +/* Keyboard and mouse events + * + * + */ + +void TracePlot::keyPressEvent(QKeyEvent *keyPressedEvent) +{ + int key = keyPressedEvent->key(); + if(Qt::Key_Control == key) + keyPressData.ctrlPressed = true; + else if(Qt::Key_Shift == key) + keyPressData.shiftPressed = true; + else if(Qt::Key_Right == key) + navigator->selectNextTransaction(); + else if(Qt::Key_Left == key) + navigator->selectPreviousTransaction(); +} + +void TracePlot::keyReleaseEvent(QKeyEvent *keyReleasedEvent) +{ + int key = keyReleasedEvent->key(); + + if(Qt::Key_Control == key) + keyPressData.ctrlPressed = false; + else if(Qt::Key_Shift == key) + { + keyPressData.shiftPressed = false; + exitZoomMode(); + replot(); + } +} + + +bool TracePlot::eventFilter(QObject *object, QEvent *event) +{ + if(object == canvas()) + { + switch(event->type()) + { + case QEvent::Wheel : + { + QWheelEvent *wheelEvent = static_cast(event); + traceTime zoomCenter = static_cast(this->invTransform(xBottom, wheelEvent->x())); + + (wheelEvent->delta() > 0) ? zoomIn(zoomCenter) : zoomOut(zoomCenter); + + return true; + } + case QEvent::MouseButtonPress: + { + QMouseEvent *mouseEvent = static_cast(event); + + if(mouseEvent->button() == Qt::LeftButton) + { + if(keyPressData.shiftPressed) + { + mouseDownData.zoomSpan.setBegin(alignToClk(invTransform(xBottom, mouseEvent->x()),navigator->GeneralTraceInfo().clkPeriod)); + mouseDownData.zoomSpan.setEnd(alignToClk(invTransform(xBottom, mouseEvent->x()),navigator->GeneralTraceInfo().clkPeriod)); + enterZoomMode(); + } + else + { + mouseDownData.mouseDownX = mouseEvent->x(); + mouseDownData.mouseDownTime = GetCurrentTimespan().Middle(); + mouseDownData.mouseIsDownForDragging = true; + canvas()->setCursor(Qt::ClosedHandCursor); + SelectTransaction(mouseEvent->x(), mouseEvent->y()); + } + return true; + } + else if(mouseEvent->button() == Qt::RightButton) + { + openContextMenu(this->canvas()->mapToGlobal(mouseEvent->pos()),mouseEvent->pos()); + return true; + } + break; + } + case QEvent::MouseButtonRelease: + { + QMouseEvent *mouseEvent = static_cast(event); + + if(mouseEvent->button() == Qt::LeftButton) + { + if(mouseDownData.mouseIsDownForDragging) + { + mouseDownData.mouseIsDownForDragging = false; + canvas()->setCursor(Qt::ArrowCursor); + return true; + } + else if(mouseDownData.mouseIsDownForZooming) + { + exitZoomMode(); + traceTime newCenter = mouseDownData.zoomSpan.Middle(); + setZoomLevel(mouseDownData.zoomSpan.timeCovered()); + navigator->navigateToTime(newCenter); + replot(); + return true; + } + } + break; + } + case QEvent::MouseMove: + { + QMouseEvent *mouseEvent = static_cast(event); + + if(mouseDownData.mouseIsDownForDragging) + { + traceTime deltaTime = invTransform(xBottom, mouseDownData.mouseDownX) - invTransform(xBottom, mouseEvent->x()); + navigator->navigateToTime(mouseDownData.mouseDownTime + deltaTime); + return true; + } + else if(mouseDownData.mouseIsDownForZooming) + { + mouseDownData.zoomSpan.setEnd(alignToClk(invTransform(xBottom, mouseEvent->x()),navigator->GeneralTraceInfo().clkPeriod)); + if(mouseDownData.zoomSpan.Begin() < mouseDownData.zoomSpan.End()) + zoomZone->setInterval(mouseDownData.zoomSpan.Begin(),mouseDownData.zoomSpan.End()); + else + zoomZone->setInterval(mouseDownData.zoomSpan.End(),mouseDownData.zoomSpan.Begin()); + + replot(); + } + break; + + } + default: + break; + } + } + return false; +} + +void TracePlot::SelectTransaction(int x, int y) +{ + double yVal = invTransform(yLeft, y); + traceTime time = invTransform(xBottom, x); + vector> selectedTransactions = tracePlotItem->getSelectedTransactions(time,yVal); + if(selectedTransactions.size() > 0) + { + if(!keyPressData.ctrlPressed) + navigator->clearSelectedTransactions(); + navigator->addSelectedTransactions(selectedTransactions); + } +} + +void TracePlot::openContextMenu(const QPoint& pos,const QPoint& mouseDown) +{ + contextMenuMouseDown = mouseDown; + contextMenu->exec(pos); +} + + diff --git a/analyzer/analyzer/presentation/traceplot.h b/analyzer/analyzer/presentation/traceplot.h new file mode 100644 index 00000000..4d8f601d --- /dev/null +++ b/analyzer/analyzer/presentation/traceplot.h @@ -0,0 +1,151 @@ +#ifndef TRACEPLOT_H +#define TRACEPLOT_H +#include +#include +#include +#include +#include +#include +#include +#include +#include "traceplotitem.h" +#include "tracenavigator.h" +#include "queryeditor.h" + + +#include "markerplotitem.h" +/* A plot that plots all phases and transactions of a trace file + * Y Axis : Bank0,...,Bank7,Trans,CC + * X Axis : Time + * + */ + +class TracePlotMouseLabel; + +class TracePlot : public QwtPlot +{ + + Q_OBJECT + +public: + TracePlot(QWidget *parent = NULL); + void init(TraceNavigator* navigator); + Timespan GetCurrentTimespan(); + traceTime ZoomLevel() const{return zoomLevel;} + + void setUpActions(); + + void setUpContextMenu(); +public Q_SLOTS: + void currentTraceTimeChanged(); + void selectedTransactionsChanged(); + void commentsChanged(); + + +Q_SIGNALS: + void tracePlotZoomChanged(); + void colorGroupingChanged(ColorGrouping colorgrouping); + +private Q_SLOTS: + void on_executeQuery(); + void on_selectNextRefresh(); + void on_selectNextActivate(); + void on_selectNextPrecharge(); + void on_colorGroupingPhase(); + void on_colorGroupingTransaction(); + void on_colorGroupingThread(); + void on_goToTransaction(); + void on_goToPhase(); + void on_deselectAll(); + void on_insertComment(); + void on_goToTime(); + void on_exportToPDF(); + +private: + bool isInitialized; + TraceNavigator* navigator; + TraceDrawingProperties drawingProperties; + TracePlotItem *tracePlotItem; + QwtPlotZoneItem *zoomZone; + std::vector> transactions; + QueryEditor *queryEditor; + QMenu* contextMenu; + + void setUpTracePlotItem(); + void setUpDrawingProperties(); + void setUpGrid(); + void setUpAxis(); + void setUpZoom(); + void setUpQueryEditor(); + void connectNavigatorQ_SIGNALS(); + + void getAndDrawComments(); + + + /* zooming + * + */ + traceTime zoomLevel; + constexpr static int minZoomClks = 10; + constexpr static int maxZoomClks = 2000; + constexpr static int GridVisiblityClks = 100; + constexpr static int textVisibilityClks = 200; + traceTime minZoomLevel,maxZoomLevel, textVisibilityZoomLevel; + + constexpr static double zoomFactor = 0.8; + void zoomIn(traceTime zoomCenter); + void zoomOut(traceTime zoomCenter); + void setZoomLevel(traceTime newZoomLevel); + void exitZoomMode(); + void enterZoomMode(); + + + /* keyboard an mouse events + * + */ + bool eventFilter( QObject *object, QEvent *event ); + + QAction* goToTime; + QAction* goToTransaction; + QAction* goToPhase; + QAction* showQueryEditor; + QAction* insertComment; + QAction* deselectAll; + QAction* selectNextRefresh; + QAction* selectNextActivate; + QAction* selectNextPrecharge; + QAction* setColorGroupingPhase; + QAction* setColorGroupingTransaction; + QAction* setColorGroupingThread; + QAction* exportToPdf; + + TracePlotMouseLabel* mouseLabel; + + void openContextMenu(const QPoint& pos,const QPoint& mouseDown); + QPoint contextMenuMouseDown; + void SelectTransaction(int x, int y); + void keyPressEvent(QKeyEvent *keyPressedEvent); + void keyReleaseEvent(QKeyEvent *keyReleasedEvent); + + struct KeyPressData + { + bool ctrlPressed, shiftPressed; + KeyPressData():ctrlPressed(false),shiftPressed(false){} + }; + + struct MouseDownData + { + traceTime mouseDownTime; + Timespan zoomSpan; + int mouseDownX; + bool mouseIsDownForDragging; + bool mouseIsDownForZooming; + MouseDownData(): mouseDownTime(0),mouseDownX(0),mouseIsDownForDragging(false),mouseIsDownForZooming(false){} + }; + + MouseDownData mouseDownData; + KeyPressData keyPressData; +}; + + +#endif // TRACEPLOT_H diff --git a/analyzer/analyzer/presentation/traceplotitem.cpp b/analyzer/analyzer/presentation/traceplotitem.cpp new file mode 100644 index 00000000..7c3524f1 --- /dev/null +++ b/analyzer/analyzer/presentation/traceplotitem.cpp @@ -0,0 +1,36 @@ +#include "traceplotitem.h" +#include "tracedrawing.h" +#include "util/colorgenerator.h" +#include +#include +#include +#include +#include + +using namespace std; +int TracePlotItem::rtti() const +{ + return QwtPlotItem::Rtti_PlotUserItem; +} + +void TracePlotItem::draw(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect) const +{ + for(const auto &transaction : transactions) + { + bool highlight = navigator.transactionIsSelected(transaction); + transaction->draw(painter,xMap,yMap,canvasRect,highlight,drawingProperties); + } +} + +vector> TracePlotItem::getSelectedTransactions(traceTime time, double yVal) +{ + vector> result; + + for(const auto &transaction : transactions) + { + if(transaction->isSelected(time,yVal,drawingProperties)) + result.push_back(transaction); + } + + return result; +} diff --git a/analyzer/analyzer/presentation/traceplotitem.h b/analyzer/analyzer/presentation/traceplotitem.h new file mode 100644 index 00000000..d2d06d4d --- /dev/null +++ b/analyzer/analyzer/presentation/traceplotitem.h @@ -0,0 +1,32 @@ +#ifndef TRACEPLOTITEM_H +#define TRACEPLOTITEM_H + +#include +#include +#include +#include +#include "businessObjects/tracetime.h" +#include "businessObjects/transaction.h" +#include "presentation/tracedrawingproperties.h" +#include "util/colorgenerator.h" +#include "presentation/tracenavigator.h" + +class TracePlotItem : public QwtPlotItem +{ +private: + const std::vector> &transactions; + const TraceNavigator& navigator; + const TraceDrawingProperties &drawingProperties; + +public: + TracePlotItem(const std::vector> &transactions,const TraceNavigator& navigator, const TraceDrawingProperties &drawingProperties): + transactions(transactions),navigator(navigator),drawingProperties(drawingProperties){} + + virtual int rtti() const; + virtual void draw(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect) const; + std::vector> getSelectedTransactions(traceTime time,double yVal); + +}; + +#endif // TRACEPLOTITEM_H + diff --git a/analyzer/analyzer/presentation/tracetesttreewidget.cpp b/analyzer/analyzer/presentation/tracetesttreewidget.cpp new file mode 100644 index 00000000..1229103f --- /dev/null +++ b/analyzer/analyzer/presentation/tracetesttreewidget.cpp @@ -0,0 +1,46 @@ +#include "tracetesttreewidget.h" + +TraceTestTreeWidget::TraceTestTreeWidget(QWidget *parent) : QTreeWidget(parent) +{ + QObject::connect(this,SIGNAL(itemSelectionChanged()),this,SLOT(itemSelectionChanged())); + setHeaderHidden(true); +} + +void TraceTestTreeWidget::addTraceTestResult(const TraceTestResults &traceTestResult) +{ + + QTreeWidgetItem* top = new QTreeWidgetItem({traceTestResult.getTraceName()}); + addTopLevelItem(top); + + if(traceTestResult.hasPassedAllTests()) + top->setTextColor(0,Qt::green); + else + top->setTextColor(0,Qt::red); + + for(const TestResult& testResult: traceTestResult.getTestResults()) + { + new TestResultTreeItem(top, testResult); + } +} + +void TraceTestTreeWidget::itemSelectionChanged() +{ + if(!selectedItems().isEmpty() && selectedItems().at(0)->type() == TestResultTreeItem::testResultTreeItemType) + { + TestResultTreeItem* testResultItem = static_cast(selectedItems().at(0)); + Q_EMIT setMessage(testResultItem->getMessage()); + } + else + { + setMessage(QString("")); + } +} + +TraceTestTreeWidget::TestResultTreeItem::TestResultTreeItem(QTreeWidgetItem *parent, const TestResult& testResult) + :QTreeWidgetItem(parent,testResultTreeItemType) +{ + setText(0, testResult.getTestName()); + if(!testResult.hasPassed()) + setTextColor(0,Qt::red); + message = testResult.getMessage(); +} diff --git a/analyzer/analyzer/presentation/tracetesttreewidget.h b/analyzer/analyzer/presentation/tracetesttreewidget.h new file mode 100644 index 00000000..4a5f069a --- /dev/null +++ b/analyzer/analyzer/presentation/tracetesttreewidget.h @@ -0,0 +1,31 @@ +#ifndef TRACETESTTREEWIDGET_H +#define TRACETESTTREEWIDGET_H +#include +#include + +class TraceTestTreeWidget: public QTreeWidget +{ + Q_OBJECT +public: + TraceTestTreeWidget(QWidget *parent = 0); + void addTraceTestResult(const TraceTestResults& traceTestResult); + +Q_SIGNALS: + void setMessage(QString message); + +private: + class TestResultTreeItem : public QTreeWidgetItem + { + public: + TestResultTreeItem(QTreeWidgetItem *parent, const TestResult& testResult); + static constexpr int testResultTreeItemType = 1002; + QString getMessage(){return message;} + private: + QString message; + }; + +private Q_SLOTS: + void itemSelectionChanged(); +}; + +#endif // TRACETESTTREEWIDGET_H diff --git a/analyzer/analyzer/presentation/transactiontreewidget.cpp b/analyzer/analyzer/presentation/transactiontreewidget.cpp new file mode 100644 index 00000000..6c686eb8 --- /dev/null +++ b/analyzer/analyzer/presentation/transactiontreewidget.cpp @@ -0,0 +1,94 @@ +#include "transactiontreewidget.h" +#include "data/tracedb.h" +#include +#include +#include + +using namespace std; + +TransactionTreeWidget::TransactionTreeWidget(QWidget *parent) : QTreeWidget(parent), isInitialized(false) +{ + QObject::connect(this,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(ContextMenuRequested(QPoint))); + setContextMenuPolicy(Qt::CustomContextMenu); + goToTransaction = new QAction("Move to",this); +} + +void TransactionTreeWidget::init(TraceNavigator *navigator) +{ + Q_ASSERT(isInitialized == false); + isInitialized = true; + + this->navigator = navigator; + setColumnCount(3); + setHeaderLabels(QStringList({"Transaction", "Value", "Value"})); +} + +void TransactionTreeWidget::AppendTransaction(const shared_ptr &transaction) +{ + QTreeWidgetItem *node = new TransactionTreeItem(this,transaction); + addTopLevelItem(node); +} + + +void TransactionTreeWidget::ContextMenuRequested(QPoint point) +{ + if(selectedItems().count() > 0 && selectedItems().at(0)->type() == TransactionTreeWidget::TransactionTreeItem::transactionTreeItemType) + { + QMenu contextMenu; + contextMenu.addActions({goToTransaction}); + QAction* selectedContextMenuItems = contextMenu.exec(mapToGlobal(point)); + + if(selectedContextMenuItems) + { + TransactionTreeItem *item = static_cast(selectedItems().at(0)); + navigator->selectTransaction(item->Id()); + } + } +} + +TransactionTreeWidget::TransactionTreeItem::TransactionTreeItem(QTreeWidget *parent, const shared_ptr &transaction) : QTreeWidgetItem(parent,transactionTreeItemType) +{ + this->setText(0, QString::number(transaction->Id())); + this->id = transaction->Id(); + + QTreeWidgetItem *time = new QTreeWidgetItem({"Timespan"}); + AppendTimespan(time, transaction->Span()); + this->addChild(time); + this->addChild(new QTreeWidgetItem( {"Lenght", formatTraceTimePretty(transaction->Span().timeCovered())})); + + this->addChild(new QTreeWidgetItem( {"Channel", QString::number(transaction->Channel())})); + this->addChild(new QTreeWidgetItem( {"Bank", QString::number(transaction->Bank())} )); + this->addChild(new QTreeWidgetItem( {"Bankgroup", QString::number(transaction->BankGroup())} )); + this->addChild(new QTreeWidgetItem( {"Row", QString::number(transaction->Row())} )); + this->addChild(new QTreeWidgetItem( {"Column", QString::number(transaction->Column())} )); + this->addChild(new QTreeWidgetItem( {"Address", QString("0x") + QString::number(transaction->Address(),16)} )); + + if(!transaction->isControllerInternal()) + { + this->addChild(new QTreeWidgetItem( {"Burstlength", QString::number(transaction->Burstlength())})); + this->addChild(new QTreeWidgetItem( {"Thread", QString::number(transaction->Thread())})); + } + + QTreeWidgetItem *phasesNode = new QTreeWidgetItem(this); + phasesNode->setText(0,"Phases"); + phasesNode->addChild(new QTreeWidgetItem( {"", "Begin", "End"} )); + + for(std::shared_ptr phase : transaction->Phases()) + { + AppendPhase(phasesNode, *phase); + } +} + +void TransactionTreeWidget::TransactionTreeItem::AppendPhase(QTreeWidgetItem *parent, const Phase &phase) +{ + QTreeWidgetItem *node = new QTreeWidgetItem(parent); + node->setText(0, phase.Name() + QString(" [") + QString::number(phase.Id()) + QString("]")); + + AppendTimespan(node, phase.Span()); +} + +void TransactionTreeWidget::TransactionTreeItem::AppendTimespan(QTreeWidgetItem *parent, const Timespan ×pan) +{ + parent->setText(1, formatTraceTimePretty(timespan.Begin())); + parent->setText(2, formatTraceTimePretty(timespan.End())); +} diff --git a/analyzer/analyzer/presentation/transactiontreewidget.h b/analyzer/analyzer/presentation/transactiontreewidget.h new file mode 100644 index 00000000..2dbd51fc --- /dev/null +++ b/analyzer/analyzer/presentation/transactiontreewidget.h @@ -0,0 +1,48 @@ +#ifndef TRANSACTIONTREEWIDGET_H +#define TRANSACTIONTREEWIDGET_H + +#include +#include "tracenavigator.h" +#include +#include + +class TransactionTreeWidget : public QTreeWidget +{ + + Q_OBJECT + +public: + TransactionTreeWidget(QWidget *parent); + + void AppendTransaction(const std::shared_ptr &transaction); + virtual void init(TraceNavigator *navigator); + +public Q_SLOTS: + void ContextMenuRequested(QPoint point); + +protected: + TraceNavigator *navigator; + +private: + bool isInitialized; + void AppendTimespan(QTreeWidgetItem *parent, const Timespan ×pan); + void AppendPhase(QTreeWidgetItem *parent, const Phase &phase); + QAction* goToTransaction; + + class TransactionTreeItem : public QTreeWidgetItem + { + public: + static constexpr int transactionTreeItemType = 1001; + TransactionTreeItem(QTreeWidget *parent, const std::shared_ptr &trans); + ID Id(){return id;} + private: + ID id; + void AppendTimespan(QTreeWidgetItem *parent, const Timespan ×pan); + void AppendPhase(QTreeWidgetItem *parent, const Phase &phase); + }; + + + +}; + +#endif // TRANSACTIONTREEWIDGET_H diff --git a/analyzer/analyzer/presentation/util/clkgrid.cpp b/analyzer/analyzer/presentation/util/clkgrid.cpp new file mode 100644 index 00000000..9cd7a80c --- /dev/null +++ b/analyzer/analyzer/presentation/util/clkgrid.cpp @@ -0,0 +1,29 @@ +#include "clkgrid.h" +#include + +using namespace std; + +void ClkGrid::updateScaleDiv(const QwtScaleDiv &xMap, const QwtScaleDiv &yMap) +{ + QwtScaleDiv scaleDiv; + scaleDiv.setInterval( xMap.interval() ); + + double min = xMap.interval().minValue(); + double max = xMap.interval().maxValue(); + + if ( min > max ) + qSwap( min, max ); + + if((max - min) < maxVisibility) + { + min = static_cast( min / clkPeriod ) * clkPeriod; + QList ticks; + for ( double tick = min; tick <= max; tick += clkPeriod ) + ticks += tick; + + scaleDiv.setTicks( QwtScaleDiv::MajorTick, ticks ); + + } + + QwtPlotGrid::updateScaleDiv( scaleDiv, yMap ); + } diff --git a/analyzer/analyzer/presentation/util/clkgrid.h b/analyzer/analyzer/presentation/util/clkgrid.h new file mode 100644 index 00000000..82f25219 --- /dev/null +++ b/analyzer/analyzer/presentation/util/clkgrid.h @@ -0,0 +1,18 @@ +#ifndef CLKGRID_H +#define CLKGRID_H + +#include +#include "businessObjects/tracetime.h" + +class ClkGrid : public QwtPlotGrid +{ +public: + virtual void updateScaleDiv(const QwtScaleDiv &xMap, const QwtScaleDiv &yMap); + ClkGrid(unsigned int clkPeriod, traceTime maxVisibility) : clkPeriod(clkPeriod), maxVisibility(maxVisibility){} + +private: + unsigned int clkPeriod; + double maxVisibility; +}; + +#endif // CLKGRID_H diff --git a/analyzer/analyzer/presentation/util/colorgenerator.cpp b/analyzer/analyzer/presentation/util/colorgenerator.cpp new file mode 100644 index 00000000..63184759 --- /dev/null +++ b/analyzer/analyzer/presentation/util/colorgenerator.cpp @@ -0,0 +1,31 @@ +#include "colorgenerator.h" +#include +ColorGenerator::ColorGenerator() +{ + r[0] = 0xFF; r[1] = 0x00; r[2] = 0x00; r[3] = 0xFF; + g[0] = 0x00; g[1] = 0xFF; g[2] = 0x00; g[3] = 0xFF; + b[0] = 0x00; b[1] = 0x00; b[2] = 0xFF; b[3] = 0x00; + + r[4] = 0xFF; r[5] = 0x00; r[6] = 0xFF; r[7] = 0x6B; + g[4] = 0x00; g[5] = 0xFF; g[6] = 0xA5; g[7] = 0x8E; + b[4] = 0xFF; b[5] = 0xFF; b[6] = 0x00; b[7] = 0x23; + + r[8] = 0x8A; r[9] = 0xFF; r[10] = 0x7C; r[11] = 0x00; + g[8] = 0x2B; g[9] = 0xD7; g[10] = 0xFC; g[11] = 0x00; + b[8] = 0xE2; b[9] = 0x00; b[10] = 0x00; b[11] = 0x80; + + r[12] = 0x80; r[13] = 0x00; r[14] = 0xEE; r[15] = 0xFF; + g[12] = 0x00; g[13] = 0x80; g[14] = 0x82; g[15] = 0x45; + b[12] = 0x00; b[13] = 0x00; b[14] = 0xEE; b[15] = 0x00; + +} + +QColor ColorGenerator::getColor(unsigned int i) +{ + static ColorGenerator gen; + i = i % 16; + QColor result(gen.r[i],gen.g[i],gen.b[i]); + result.setAlpha(130); + return result; +} + diff --git a/analyzer/analyzer/presentation/util/colorgenerator.h b/analyzer/analyzer/presentation/util/colorgenerator.h new file mode 100644 index 00000000..37a4d9a7 --- /dev/null +++ b/analyzer/analyzer/presentation/util/colorgenerator.h @@ -0,0 +1,21 @@ +#ifndef COLORGENERATOR_H +#define COLORGENERATOR_H + +#include +#include + +class ColorGenerator +{ +private: + static constexpr int NumberOfColors = 16; + int r[NumberOfColors]; + int g[NumberOfColors]; + int b[NumberOfColors]; + ColorGenerator(); + +public: + static QColor getColor(unsigned int i); +}; + + +#endif // RANDOMCOLORGENERATOR_H diff --git a/analyzer/analyzer/presentation/util/customlabelscaledraw.h b/analyzer/analyzer/presentation/util/customlabelscaledraw.h new file mode 100644 index 00000000..1da4521d --- /dev/null +++ b/analyzer/analyzer/presentation/util/customlabelscaledraw.h @@ -0,0 +1,20 @@ +#ifndef CUSTOMLABELSCALEDRAW_H +#define CUSTOMLABELSCALEDRAW_H +#include +#include +#include + +class CustomLabelScaleDraw : public QwtScaleDraw +{ +private: + QHash labels; + +public: + CustomLabelScaleDraw(QHash labels): labels(labels){} + virtual QwtText label(double v) const + { + return QwtText(labels[static_cast(v)]); + } +}; + +#endif // CUSTOMLABELSCALEDRAW_H diff --git a/analyzer/analyzer/presentation/util/engineeringScaleDraw.h b/analyzer/analyzer/presentation/util/engineeringScaleDraw.h new file mode 100644 index 00000000..365c698d --- /dev/null +++ b/analyzer/analyzer/presentation/util/engineeringScaleDraw.h @@ -0,0 +1,16 @@ +#ifndef ENGINEERINGSCALEDRAW_H +#define ENGINEERINGSCALEDRAW_H +#include +#include +#include "thirdParty/eng_format.h" +#include "businessObjects/tracetime.h" + +class EngineeringScaleDraw : public QwtScaleDraw +{ + public: + virtual QwtText label(double number) const + { + return QwtText(QString::number(number/1000,'g',9)); + } +}; +#endif // ENGINEERINGSCALEDRAW_H diff --git a/analyzer/analyzer/presentation/util/testlight.cpp b/analyzer/analyzer/presentation/util/testlight.cpp new file mode 100644 index 00000000..361c5691 --- /dev/null +++ b/analyzer/analyzer/presentation/util/testlight.cpp @@ -0,0 +1,33 @@ +#include "testlight.h" +#include + +TestLight::TestLight(QWidget *parent) : QWidget(parent) +{ + setGray(); +} + +void TestLight::setGray() +{ + lightColor = QColor(Qt::gray); + update(); +} + +void TestLight::setGreen() +{ + lightColor = QColor(Qt::green); + update(); +} + +void TestLight::setRed() +{ + lightColor = QColor(Qt::red); + update(); +} + +void TestLight::paintEvent(QPaintEvent* /*paintEvent*/) +{ + QPainter painter(this); + painter.fillRect(this->rect(),lightColor); + painter.drawRect(this->rect()); +} + diff --git a/analyzer/analyzer/presentation/util/testlight.h b/analyzer/analyzer/presentation/util/testlight.h new file mode 100644 index 00000000..325105a8 --- /dev/null +++ b/analyzer/analyzer/presentation/util/testlight.h @@ -0,0 +1,23 @@ +#ifndef TESTLIGHT_H +#define TESTLIGHT_H +#include +#include +#include + +class TestLight : public QWidget +{ + Q_OBJECT + +public: + TestLight(QWidget *parent = 0); + void setGreen(); + void setRed(); + void setGray(); +protected: + void paintEvent(QPaintEvent *paintEvent); + +private: + QColor lightColor; +}; + +#endif // TESTLIGHT_H diff --git a/analyzer/analyzer/queryeditor.cpp b/analyzer/analyzer/queryeditor.cpp new file mode 100644 index 00000000..a743471e --- /dev/null +++ b/analyzer/analyzer/queryeditor.cpp @@ -0,0 +1,40 @@ +#include "queryeditor.h" +#include "ui_queryeditor.h" +#include +#include + +QueryEditor::QueryEditor(QWidget *parent) : + QWidget(parent), + ui(new Ui::QueryEditor) +{ + ui->setupUi(this); + ui->queryHead->setText(queryTexts.queryHead); +} + +QueryEditor::~QueryEditor() +{ + delete ui; +} + +void QueryEditor::init(TraceNavigator *navigator) +{ + this->navigator = navigator; + ui->transactiontreeWidget->init(navigator); +} + +void QueryEditor::on_executeQuery_clicked() +{ + try + { + std::vector> result = navigator->TraceFile().getTransactionsWithCustomQuery(queryTexts.queryHead + " " + ui->queryEdit->toPlainText()); + ui->transactiontreeWidget->clear(); + for(const auto & trans : result) + { + ui->transactiontreeWidget->AppendTransaction(trans); + } + } + catch(sqlException ex) + { + QMessageBox::warning(this,"Query failed",ex.what()); + } +} diff --git a/analyzer/analyzer/queryeditor.h b/analyzer/analyzer/queryeditor.h new file mode 100644 index 00000000..107272e7 --- /dev/null +++ b/analyzer/analyzer/queryeditor.h @@ -0,0 +1,30 @@ +#ifndef QUERYEDITOR_H +#define QUERYEDITOR_H + +#include +#include "data/QueryTexts.h" +#include "presentation/tracenavigator.h" + +namespace Ui { +class QueryEditor; +} + +class QueryEditor : public QWidget +{ + Q_OBJECT + +public: + explicit QueryEditor(QWidget *parent = 0); + ~QueryEditor(); + void init(TraceNavigator *navigator); + +private Q_SLOTS: + void on_executeQuery_clicked(); + +private: + Ui::QueryEditor *ui; + TraceNavigator* navigator; + TransactionQueryTexts queryTexts; +}; + +#endif // QUERYEDITOR_H diff --git a/analyzer/analyzer/queryeditor.ui b/analyzer/analyzer/queryeditor.ui new file mode 100644 index 00000000..60bf1ddf --- /dev/null +++ b/analyzer/analyzer/queryeditor.ui @@ -0,0 +1,80 @@ + + + QueryEditor + + + + 0 + 0 + 667 + 451 + + + + Form + + + + + + + + false + + + + 0 + 1 + + + + true + + + + + + + + 0 + 1 + + + + + + + + Execute query + + + + + + + + 0 + 5 + + + + + 1 + + + + + + + + + + + TransactionTreeWidget + QTreeWidget +
presentation/transactiontreewidget.h
+
+
+ + +
diff --git a/analyzer/analyzer/schedulerwrapper.h b/analyzer/analyzer/schedulerwrapper.h new file mode 100644 index 00000000..939fbe39 --- /dev/null +++ b/analyzer/analyzer/schedulerwrapper.h @@ -0,0 +1,33 @@ +#ifndef SCHEDULERWRAPPER_H +#define SCHEDULERWRAPPER_H + +#include +#include +#include +#include +#include + +struct SchedulerWrapper : public sc_module +{ + tlm_utils::simple_initiator_socket iSocket; + tlm_utils::simple_target_socket tSocket; + + SC_HAS_PROCESS(SchedulerWrapper); + + SchedulerWrapper(sc_module_name name); + +private: + tlm_utils::peq_with_cb_and_phase payloadEventQueue; + + tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload& payload,tlm::tlm_phase& phase,sc_time& bwDelay); + tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& payload,tlm::tlm_phase& phase,sc_time& fwDelay); + + void peqCallback(tlm::tlm_generic_payload& payload,const tlm::tlm_phase& phase); + void sendToTarget(tlm::tlm_generic_payload& payload,const tlm::tlm_phase& phase,const sc_time& delay); + void sendToInitiator(tlm::tlm_generic_payload& payload,const tlm::tlm_phase& phase,const sc_time& delay); + +}; + +#endif // SCHEDULERWRAPPER_H + + diff --git a/analyzer/analyzer/thirdParty/eng_formant.cpp b/analyzer/analyzer/thirdParty/eng_formant.cpp new file mode 100644 index 00000000..eba663b8 --- /dev/null +++ b/analyzer/analyzer/thirdParty/eng_formant.cpp @@ -0,0 +1,262 @@ +// Copyright (C) 2005-2009 by Jukka Korpela +// Copyright (C) 2009-2013 by David Hoerl +// Copyright (C) 2013 by Martin Moene +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include "eng_format.h" + +#include +#include +#include + +#include +#include +#include + +/* + * Note: using fabs() and other math functions in global namespace for + * best compiler coverage. + */ + +/* + * Note: micro, µ, may not work everywhere, so you can define a glyph yourself: + */ +#ifndef ENG_FORMAT_MICRO_GLYPH +# define ENG_FORMAT_MICRO_GLYPH "µ" +#endif + +/* + * Note: if not using signed at the computation of prefix_end below, + * VC2010 -Wall issues a warning about unsigned and addition overflow. + * Hence the cast to signed int here. + */ +#define ENG_FORMAT_DIMENSION_OF(a) ( static_cast( sizeof(a) / sizeof(0[a]) ) ) + +eng_prefixed_t eng_prefixed; +eng_exponential_t eng_exponential; + +namespace +{ + +char const * const prefixes[/*exp*/][2][9] = +{ + { + { "", "m", ENG_FORMAT_MICRO_GLYPH + , "n", "p", "f", "a", "z", "y", }, + { "", "k", "M", "G", "T", "P", "E", "Z", "Y", }, + }, + { + { "e0", "e-3", "e-6", "e-9", "e-12", "e-15", "e-18", "e-21", "e-24", }, + { "e0", "e3", "e6", "e9", "e12", "e15", "e18", "e21", "e24", }, + }, +}; + +const int prefix_count = ENG_FORMAT_DIMENSION_OF( prefixes[false][false] ); + +#if defined( _MSC_VER ) + +template +long lrint( T const x ) +{ + return static_cast( x ); +} + +#endif + +int sign( int const value ) +{ + return value == 0 ? +1 : value / abs( value ); +} + +bool is_zero( double const value ) +{ +#if __cplusplus >= 201103L + return FP_ZERO == fpclassify( value ); +#else + // deliberately compare literally: + return 0.0 == value; +#endif +} + +bool is_nan( double const value ) +{ +#if __cplusplus >= 201103L + return isnan( value ); +#else + // deliberately return false for now: + return false; +#endif +} + +bool is_inf( double const value ) +{ +#if __cplusplus >= 201103L + return isinf( value ); +#else + // deliberately return false for now: + return false; +#endif +} + +long degree_of( double const value ) +{ + return is_zero( value ) ? 0 : lrint( floor( log10( fabs( value ) ) / 3) ); +} + +int precision( double const scaled, int const digits ) +{ + // MSVC6 requires -2 * DBL_EPSILON; + // g++ 4.8.1: ok with -1 * DBL_EPSILON + + return is_zero( scaled ) ? digits - 1 : digits - log10( fabs( scaled ) ) - 2 * DBL_EPSILON; +} + +std::string prefix_or_exponent( bool const exponential, int const degree ) +{ + return std::string( exponential || 0 == degree ? "" : " " ) + prefixes[ exponential ][ sign(degree) > 0 ][ abs( degree ) ]; +} + +std::string exponent( int const degree ) +{ + std::ostringstream os; + os << "e" << 3 * degree; + return os.str(); +} + +/* + * engineering to exponent notation conversion. + */ +std::string engineering_to_exponent( std::string text ); + +} // anonymous namespace + +/** + * convert real number to prefixed or exponential notation, optionally followed by a unit. + */ +std::string +to_engineering_string( double const value, int const digits, bool exponential, std::string const unit /*= ""*/ ) +{ + if ( is_nan( value ) ) return "NaN"; + else if ( is_inf( value ) ) return "INFINITE"; + + const int degree = degree_of( value ); + + std::string factor; + + if ( abs( degree ) < prefix_count ) + { + factor = prefix_or_exponent( exponential, degree ); + } + else + { + exponential = true; + factor = exponent( degree ); + } + + std::ostringstream os; + + const double scaled = value * pow( 1000.0, -degree ); + + const std::string space = ( 0 == degree || exponential ) && unit.length() ? " ":""; + + os << std::fixed << std::setprecision( precision( scaled, digits ) ) << scaled << factor << space << unit; + + return os.str(); +} + +/** + * convert the output of to_engineering_string() into a double. + */ +double from_engineering_string( std::string const text ) +{ + return strtod( engineering_to_exponent( text ).c_str(), NULL ); +} + +/** + * step a value by the smallest possible increment. + */ +std::string step_engineering_string( std::string const text, int digits, bool const exponential, bool const positive ) +{ + const double value = from_engineering_string( text ); + + if ( digits < 3 ) + { + digits = 3; + } + + // correctly round to desired precision + const int expof10 = is_zero(value) ? 0 : lrint( floor( log10( value ) ) ); + const int power = expof10 + 1 - digits; + + const double inc = pow( 10.0, power ) * ( positive ? +1 : -1 ); + const double ret = value + inc; + + return to_engineering_string( ret, digits, exponential ); +} + +namespace +{ + +/* + * "k" => "1e3" + */ +std::string prefix_to_exponent( std::string const pfx ) +{ + for ( int i = 0; i < 2; ++i ) + { + for( int k = 0; k < prefix_count; ++k ) + { + if ( pfx == prefixes[0][i][k] ) + { + return prefixes[1][i][k] ; + } + } + } + return ""; +} + +/* + * Convert engineering presentation to presentation with exponent. + * + * The engineering presentation should not contain a unit, as the first letter + * is interpreted as an SI prefix, e.g. "1 T" is 1e12, not 1 (Tesla). + * + * "1.23 M" => 1.23e+6 + * "1.23 kPa" => 1.23e+3 (ok, but not recommended) + * "1.23 Pa" => 1.23e+12 (not what's intended!) + */ +std::string engineering_to_exponent( std::string const text ) +{ + std::string::size_type pos = text.find( ' ' ); + + if ( std::string::npos == pos ) + { + return text; + } + + const std::string magnitude = text.substr( 0, pos ); + const std::string prefix = text.substr( pos + 1, 1 ); + + return magnitude + prefix_to_exponent( prefix ); +} + +} // anonymous namespace + +// end of file diff --git a/analyzer/analyzer/thirdParty/eng_format.h b/analyzer/analyzer/thirdParty/eng_format.h new file mode 100644 index 00000000..1e528057 --- /dev/null +++ b/analyzer/analyzer/thirdParty/eng_format.h @@ -0,0 +1,115 @@ +// Copyright (C) 2005-2009 by Jukka Korpela +// Copyright (C) 2009-2013 by David Hoerl +// Copyright (C) 2013 by Martin Moene +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef ENG_FORMAT_H_INCLUDED +#define ENG_FORMAT_H_INCLUDED + +#include + +/** + * convert a double to the specified number of digits in SI (prefix) or + * exponential notation, optionally followed by a unit. + */ +std::string +to_engineering_string( double value, int digits, bool exponential, std::string unit = "" ); + +/** + * convert the output of to_engineering_string() into a double. + */ +double +from_engineering_string( std::string text ); + +/** + * step a value by the smallest possible increment. + */ +std::string +step_engineering_string( std::string text, int digits, bool exponential, bool increment ); + +// +// Extended interface: +// + +/** + * \var eng_prefixed + * \brief select SI (prefix) presentation: to_engineering_string(), step_engineering_string(). + */ + +/** + * \var eng_exponential + * \brief select exponential presentation: to_engineering_string(), step_engineering_string(). + */ + +extern struct eng_prefixed_t {} eng_prefixed; +extern struct eng_exponential_t {} eng_exponential; + +/** + * \var eng_increment + * \brief let step_engineering_string() make a postive step. + */ + +/** + * \var eng_decrement + * \brief let step_engineering_string() make a negative step. + */ + +const bool eng_increment = true; +const bool eng_decrement = false; + +/** + * convert a double to the specified number of digits in SI (prefix) notation, + * optionally followed by a unit. + */ +inline std::string +to_engineering_string( double value, int digits, eng_prefixed_t, std::string unit = "" ) +{ + return to_engineering_string( value, digits, false, unit ); +} + +/** + * convert a double to the specified number of digits in exponential notation, + * optionally followed by a unit. + */ +inline std::string +to_engineering_string( double value, int digits, eng_exponential_t, std::string unit = "" ) +{ + return to_engineering_string( value, digits, true, unit ); +} + +/** + * step a value by the smallest possible increment, using SI notation. + */ +inline std::string +step_engineering_string( std::string text, int digits, eng_prefixed_t, bool increment ) +{ + return step_engineering_string( text, digits, false, increment ); +} + +/** + * step a value by the smallest possible increment, using exponential notation. + */ +inline std::string +step_engineering_string( std::string text, int digits, eng_exponential_t, bool increment ) +{ + return step_engineering_string( text, digits, true, increment ); +} + +#endif // ENG_FORMAT_H_INCLUDED diff --git a/analyzer/analyzer/traceAnalyzer.pro b/analyzer/analyzer/traceAnalyzer.pro new file mode 100644 index 00000000..0c58af9a --- /dev/null +++ b/analyzer/analyzer/traceAnalyzer.pro @@ -0,0 +1,101 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2013-11-26T20:21:15 +# +#------------------------------------------------- + +QT += core gui +QT += sql +CONFIG += qwt +CONFIG += python +CONFIG += no_keywords + +include(paths.pro) +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = traceAnalyzer +TEMPLATE = app + +SOURCES += main.cpp\ + businessObjects/transaction.cpp \ + businessObjects/timespan.cpp \ + data/tracedb.cpp \ + presentation/tracenavigator.cpp \ + presentation/util/colorgenerator.cpp \ + presentation/tracedrawing.cpp \ + presentation/traceplotitem.cpp \ + gototimedialog.cpp \ + presentation/traceplot.cpp \ + thirdParty/eng_formant.cpp \ + tracefiletab.cpp \ + presentation/pornotracescroller.cpp \ + traceanalyzer.cpp \ + presentation/transactiontreewidget.cpp \ + presentation/commenttreewidget.cpp \ + presentation/util/clkgrid.cpp \ + queryeditor.cpp \ + presentation/selectedtransactiontreewidget.cpp \ + businessObjects/phases/phasefactory.cpp \ + presentation/debugmessagetreewidget.cpp \ + presentation/tracePlotMouseLabel.cpp \ + evaluationtool.cpp \ + presentation/util/testlight.cpp \ + presentation/tracetesttreewidget.cpp \ + businessObjects/pythoncaller.cpp \ + businessObjects/tracetestresults.cpp \ + presentation/tracemetrictreewidget.cpp \ + businessObjects/phases/phase.cpp + +HEADERS += businessObjects/transaction.h \ + businessObjects/timespan.h \ + businessObjects/generalinfo.h \ + data/tracedb.h \ + presentation/tracenavigator.h \ + presentation/util/colorgenerator.h \ + presentation/util/engineeringScaleDraw.h \ + presentation/tracedrawingproperties.h \ + presentation/tracedrawing.h \ + presentation/traceplotitem.h \ + gototimedialog.h \ + presentation/traceplot.h \ + thirdParty/eng_format.h \ + tracefiletab.h \ + presentation/pornotracescroller.h \ + traceanalyzer.h \ + presentation/transactiontreewidget.h \ + businessObjects/comment.h \ + presentation/commenttreewidget.h \ + businessObjects/tracetime.h \ + presentation/util/clkgrid.h \ + presentation/util/customlabelscaledraw.h \ + data/QueryTexts.h \ + queryeditor.h \ + presentation/selectedtransactiontreewidget.h \ + businessObjects/phases/phasefactory.h \ + presentation/debugmessagetreewidget.h \ + presentation/tracePlotMouseLabel.h \ + evaluationtool.h \ + presentation/util/testlight.h \ + presentation/tracetesttreewidget.h \ + businessObjects/pythoncaller.h \ + businessObjects/testresult.h \ + businessObjects/tracetestresults.h \ + presentation/tracemetrictreewidget.h \ + businessObjects/calculatedMetric.h \ + businessObjects/tracecalculatedmetrics.h \ + businessObjects/phases/phase.h + + +FORMS += \ + gototimedialog.ui \ + tracefiletab.ui \ + traceanalyzer.ui \ + queryeditor.ui \ + preferences.ui \ + evaluationtool.ui + +OTHER_FILES += \ + common/static/createTraceDB.sql + +QMAKE_CXXFLAGS += -std=c++11 +QMAKE_CXXFLAGS += -Xlinker -export-dynamic diff --git a/analyzer/analyzer/traceanalyzer.cpp b/analyzer/analyzer/traceanalyzer.cpp new file mode 100644 index 00000000..771b33eb --- /dev/null +++ b/analyzer/analyzer/traceanalyzer.cpp @@ -0,0 +1,109 @@ +#include "traceanalyzer.h" +#include "ui_traceanalyzer.h" +#include "tracefiletab.h" +#include +#include +#include +#include "QMessageBox" +#include + +void TraceAnalyzer::setUpStatusBar() +{ + statusLabel = new QLabel(this); + statusBar()->addWidget(statusLabel); +} + +void TraceAnalyzer::setUpGui() +{ + ui->setupUi(this); + setUpStatusBar(); + ui->traceFileTabs->clear(); +} + + +TraceAnalyzer::TraceAnalyzer(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::TraceAnalyzer) +{ + setUpGui(); +} + + +TraceAnalyzer::TraceAnalyzer(QSet paths, StartupOption option, QWidget *parent): + QMainWindow(parent), + ui(new Ui::TraceAnalyzer) +{ + setUpGui(); + + for(const QString& path : paths) + openTracefile(path); + + if(option == StartupOption::runTests) + { + ui->actionTest->trigger(); + } +} + +TraceAnalyzer::~TraceAnalyzer() +{ + delete ui; +} + +void TraceAnalyzer::on_actionOpen_triggered() +{ + QStringList paths = QFileDialog::getOpenFileNames(this,tr("Open Tracefile"),"",tr("Tracefile(*.tdb)")); + if(paths.isEmpty()) + return; + + for(const QString &path: paths) + { + openTracefile(path); + } +} + +void TraceAnalyzer::openTracefile(const QString &path) +{ + if(openedTraceFiles.contains(path)) + return; + + TraceFileTab* tab = new TraceFileTab(this, path); + connect(tab, SIGNAL(statusChanged(QString)), this, SLOT(statusChanged(QString))); + ui->traceFileTabs->addTab(tab,QFileInfo(path).baseName()); + openedTraceFiles.insert(path); +} + +void TraceAnalyzer::on_traceFileTabs_tabCloseRequested(int index) +{ + TraceFileTab* traceFileTab = static_cast(ui->traceFileTabs->widget(index)); + openedTraceFiles.remove(traceFileTab->getPathToTraceFile()); + ui->traceFileTabs->removeTab(index); + delete traceFileTab; +} + +void TraceAnalyzer::on_actionClose_all_triggered() +{ + while(ui->traceFileTabs->count()) + on_traceFileTabs_tabCloseRequested(0); +} + + + +void TraceAnalyzer::statusChanged(QString message) +{ + statusLabel->setText(message + " - (" + QTime::currentTime().toString() + ")"); +} + +void TraceAnalyzer::on_actionTest_triggered() +{ + evaluationTool.raise(); + evaluationTool.activateWindow(); + evaluationTool.showAndRunTests(openedTraceFiles.toList()); +} + +void TraceAnalyzer::on_actionMetrics_triggered() +{ + evaluationTool.raise(); + evaluationTool.activateWindow(); + evaluationTool.showAndEvaluateMetrics(openedTraceFiles.toList()); + +} diff --git a/analyzer/analyzer/traceanalyzer.h b/analyzer/analyzer/traceanalyzer.h new file mode 100644 index 00000000..5104da03 --- /dev/null +++ b/analyzer/analyzer/traceanalyzer.h @@ -0,0 +1,52 @@ +#ifndef TRACEANALYZER_H +#define TRACEANALYZER_H + +#include +#include +#include +#include +#include +#include "evaluationtool.h" + +namespace Ui { +class TraceAnalyzer; +} + +enum class StartupOption{showPlots,runTests}; +enum class OpenOptions{files,folders}; + +class TraceAnalyzer : public QMainWindow +{ + Q_OBJECT + +public: + explicit TraceAnalyzer(QWidget *parent = 0); + explicit TraceAnalyzer(QSet paths, StartupOption option, QWidget *parent = 0); + + ~TraceAnalyzer(); + EvaluationTool evaluationTool; + + void setUpStatusBar(); + void setUpGui(); + +private: + void openTracefile(const QString &path); + QLabel *statusLabel; + QSet openedTraceFiles; + +private Q_SLOTS: + void on_actionOpen_triggered(); + void on_traceFileTabs_tabCloseRequested(int index); + void on_actionClose_all_triggered(); + void on_actionTest_triggered(); + + void on_actionMetrics_triggered(); + +public Q_SLOTS: + void statusChanged(QString message); + +private: + Ui::TraceAnalyzer *ui; +}; + +#endif // TRACEANALYZER_H diff --git a/analyzer/analyzer/traceanalyzer.ui b/analyzer/analyzer/traceanalyzer.ui new file mode 100644 index 00000000..d99934c7 --- /dev/null +++ b/analyzer/analyzer/traceanalyzer.ui @@ -0,0 +1,126 @@ + + + TraceAnalyzer + + + + 0 + 0 + 800 + 600 + + + + Trace Analyzer + + + + + + + 0 + + + true + + + true + + + true + + + + Tab 1 + + + + + Tab 2 + + + + + + + + + + 0 + 0 + 800 + 25 + + + + + File + + + + + + + + + + Help + + + + + + + + + + + Open + + + Ctrl+O + + + + + Close all + + + + + Info + + + + + About + + + + + Preferences + + + Ctrl+P + + + + + Test + + + Ctrl+T + + + + + Metrics + + + Ctrl+M + + + + + + diff --git a/analyzer/analyzer/tracefiletab.cpp b/analyzer/analyzer/tracefiletab.cpp new file mode 100644 index 00000000..fde96b89 --- /dev/null +++ b/analyzer/analyzer/tracefiletab.cpp @@ -0,0 +1,60 @@ +#include "tracefiletab.h" +#include "ui_tracefiletab.h" +#include "queryeditor.h" +#include "QFileInfo" +#include "qmessagebox.h" +#include +#include + +TraceFileTab::TraceFileTab(QWidget *parent,const QString& path) : + QWidget(parent), + ui(new Ui::TraceFileTab) +{ + ui->setupUi(this); + this->path = path; + initNavigatorAndItsDependentWidgets(path); + setUpFileWatcher(path); + ui->fileDescriptionEdit->setPlainText(navigator->GeneralTraceInfo().description); + tracefileChanged(); +} + +TraceFileTab::~TraceFileTab() +{ + navigator->setFileDescripton(ui->fileDescriptionEdit->toPlainText()); + navigator->commitChangesToDB(); + delete ui; +} + +void TraceFileTab::initNavigatorAndItsDependentWidgets(QString path) +{ + navigator = new TraceNavigator(path,this); + + ui->traceplot->init(navigator); + + ui->pornoTraceScroller->init(navigator, ui->traceplot); + connect(this,SIGNAL(colorGroupingChanged(ColorGrouping)),ui->pornoTraceScroller,SLOT(colorGroupingChanged(ColorGrouping))); + + ui->selectedTransactionTree->init(navigator); + //ui->debugMessages->init(navigator,ui->traceplot); + ui->commentTree->init(navigator); + +} + +void TraceFileTab::setUpFileWatcher(QString path) +{ + fileWatcher = new QFileSystemWatcher(QStringList(path),this); + QObject::connect(fileWatcher,SIGNAL(fileChanged(QString)),this,SLOT(tracefileChanged())); +} + + + +void TraceFileTab::tracefileChanged() +{ + Q_EMIT statusChanged(QString("Last Database Refresh")); + navigator->refreshData(); +} + + + + + diff --git a/analyzer/analyzer/tracefiletab.h b/analyzer/analyzer/tracefiletab.h new file mode 100644 index 00000000..da66a1ec --- /dev/null +++ b/analyzer/analyzer/tracefiletab.h @@ -0,0 +1,43 @@ +#ifndef TRACEFILETAB_H +#define TRACEFILETAB_H + +#include +#include +#include +#include "presentation/tracenavigator.h" +#include "presentation/traceplot.h" +#include "presentation/pornotracescroller.h" + +namespace Ui { +class TraceFileTab; +} + +class TraceFileTab : public QWidget +{ + Q_OBJECT + +public: + explicit TraceFileTab(QWidget *parent,const QString& path); + ~TraceFileTab(); + + void setUpFileWatcher(QString filename); + void initNavigatorAndItsDependentWidgets(QString path); + QString getPathToTraceFile(){return path;} + +private: + QString path; + Ui::TraceFileTab *ui; + TraceNavigator *navigator; + QFileSystemWatcher *fileWatcher; + void setUpQueryEditor(QString path); + +public Q_SLOTS: + void tracefileChanged(); + +Q_SIGNALS: + void statusChanged(QString); + void colorGroupingChanged(ColorGrouping colorgrouping); + +}; + +#endif // TRACEFILETAB_H diff --git a/analyzer/analyzer/tracefiletab.ui b/analyzer/analyzer/tracefiletab.ui new file mode 100644 index 00000000..e3d18d6f --- /dev/null +++ b/analyzer/analyzer/tracefiletab.ui @@ -0,0 +1,182 @@ + + + TraceFileTab + + + + 0 + 0 + 1235 + 937 + + + + Form + + + + + + + + + + + 3 + 4 + + + + + 0 + 0 + + + + Qt::StrongFocus + + + + + + + + 4 + 1 + + + + + 0 + 150 + + + + + + + + + + + + + 3 + 3 + + + + + 300 + 0 + + + + + 16777215 + 16777215 + + + + true + + + false + + + false + + + 0 + + + true + + + + + + + + 2 + 1 + + + + + 300 + 0 + + + + + 16777215 + 16777215 + + + + + 1 + + + + + + + + true + + + + 2 + 1 + + + + + 300 + 0 + + + + + 16777215 + 16777215 + + + + true + + + + + + + + + + + + TracePlot + QListView +
presentation/traceplot.h
+
+ + PornoTraceScroller + QListView +
presentation/pornotracescroller.h
+
+ + CommentTreeWidget + QTreeWidget +
presentation/commenttreewidget.h
+
+ + SelectedTransactionTreeWidget + QTreeWidget +
presentation/selectedtransactiontreewidget.h
+
+
+ + +
diff --git a/dram/dramSys/dramSys.pro b/dram/dramSys/dramSys.pro index 65291f71..98ac915e 100644 --- a/dram/dramSys/dramSys.pro +++ b/dram/dramSys/dramSys.pro @@ -1,4 +1,4 @@ -TEMPLATE = app + TEMPLATE = app CONFIG += console CONFIG -= app_bundle CONFIG -= qt From 2b427ecb6e04d49704615a4e66805168cb72e2cc Mon Sep 17 00:00:00 2001 From: Robert Gernhardt Date: Fri, 11 Jul 2014 09:22:34 +0200 Subject: [PATCH 12/13] also shows clks now in tooltip in analyzer --- analyzer/analyzer/businessObjects/tracetime.h | 9 ++++++++- analyzer/analyzer/data/tracedb.cpp | 4 ++-- analyzer/analyzer/evaluationtool.cpp | 11 +++++++---- analyzer/analyzer/evaluationtool.h | 2 +- .../analyzer/presentation/commenttreewidget.cpp | 2 +- .../presentation/debugmessagetreewidget.cpp | 2 +- .../analyzer/presentation/tracePlotMouseLabel.cpp | 10 ++++++---- .../analyzer/presentation/tracePlotMouseLabel.h | 4 ++-- analyzer/analyzer/presentation/tracenavigator.cpp | 8 -------- analyzer/analyzer/presentation/tracenavigator.h | 1 - analyzer/analyzer/presentation/traceplot.cpp | 2 +- .../analyzer/presentation/transactiontreewidget.cpp | 6 +++--- analyzer/analyzer/tracefiletab.cpp | 1 - dram/resources/simulations/sim-batch.xml | 13 +++---------- dram/src/simulation/main.cpp | 2 +- 15 files changed, 36 insertions(+), 41 deletions(-) diff --git a/analyzer/analyzer/businessObjects/tracetime.h b/analyzer/analyzer/businessObjects/tracetime.h index 88bc022c..d2da51de 100644 --- a/analyzer/analyzer/businessObjects/tracetime.h +++ b/analyzer/analyzer/businessObjects/tracetime.h @@ -6,11 +6,18 @@ //time in nanoseconds typedef long long traceTime; -inline QString formatTraceTimePretty(traceTime time) +inline QString prettyFormatTime(traceTime time) { return QString::number(time/1000) + QString(" ns"); } +inline QString formatInClks(traceTime time, unsigned int clkPeriod) +{ + long long numberOfClockCovered = time/clkPeriod; + QString suffix = (numberOfClockCovered != 1) ? QString(" clks") : QString(" clk"); + return QString::number(numberOfClockCovered) + suffix; +} + inline traceTime alignToClk(traceTime time, unsigned int clkPeriod) { return round(1.0*time/clkPeriod)*clkPeriod; diff --git a/analyzer/analyzer/data/tracedb.cpp b/analyzer/analyzer/data/tracedb.cpp index 1ca511ce..46317aaa 100644 --- a/analyzer/analyzer/data/tracedb.cpp +++ b/analyzer/analyzer/data/tracedb.cpp @@ -11,7 +11,7 @@ //define symbol printqueries if all queries should be printed to the console -//#define printqueries +#define printqueries using namespace std; @@ -175,7 +175,7 @@ GeneralInfo TraceDB::getGeneralInfoFromDB() description += memspec + "\n"; description += "Number of Transactions: " + QString::number(numberOfTransactions) + "\n"; description += "Clock period: " + QString::number(clkPeriod) + " " + unitOfTime + "\n"; - description += "Length of trace: " + formatTraceTimePretty(traceEnd); + description += "Length of trace: " + prettyFormatTime(traceEnd); return GeneralInfo(numberOfTransactions, numberOfPhases, Timespan(0,traceEnd),numberOfBanks,description,unitOfTime,clkPeriod); } diff --git a/analyzer/analyzer/evaluationtool.cpp b/analyzer/analyzer/evaluationtool.cpp index 4ca3d52c..16f2af3d 100644 --- a/analyzer/analyzer/evaluationtool.cpp +++ b/analyzer/analyzer/evaluationtool.cpp @@ -17,7 +17,7 @@ using namespace std; EvaluationTool::EvaluationTool(QWidget *parent) : QWidget(parent), - ui(new Ui::EvaluationTool), path("../../dram/resources/scripts""") + ui(new Ui::EvaluationTool), resourcesRelPath("/../../dram/resources/scripts""") { ui->setupUi(this); traceFilesModel = new QStandardItemModel(this); @@ -83,7 +83,9 @@ void EvaluationTool::on_btn_test_clicked() void EvaluationTool::runTests() { - PythonCaller pythonCaller(this->path); + QString resourcesAbsPath = QApplication::applicationDirPath() + this->resourcesRelPath; + qDebug() << resourcesAbsPath; + PythonCaller pythonCaller(this->resourcesRelPath); ui->traceTestTreeWidget->clear(); ui->testLight->setGray(); @@ -116,8 +118,9 @@ void EvaluationTool::on_btn_calculateMetrics_clicked() void EvaluationTool::calculateMetrics() { - qDebug() << this->path; - PythonCaller pythonCaller(this->path); + QString resourcesAbsPath = QApplication::applicationDirPath() + this->resourcesRelPath; + qDebug() << resourcesAbsPath; + PythonCaller pythonCaller(this->resourcesRelPath); ui->traceMetricTreeWidget->clear(); for(int row = 0; row < traceFilesModel->rowCount(); ++row) { diff --git a/analyzer/analyzer/evaluationtool.h b/analyzer/analyzer/evaluationtool.h index c9a4bfd5..94359a1d 100644 --- a/analyzer/analyzer/evaluationtool.h +++ b/analyzer/analyzer/evaluationtool.h @@ -45,7 +45,7 @@ private: Ui::EvaluationTool *ui; QStandardItemModel *traceFilesModel; std::vector calculatedMetrics; - QString path; + QString resourcesRelPath; class TraceFileItem : public QStandardItem { diff --git a/analyzer/analyzer/presentation/commenttreewidget.cpp b/analyzer/analyzer/presentation/commenttreewidget.cpp index 3cbcff55..8ff025dd 100644 --- a/analyzer/analyzer/presentation/commenttreewidget.cpp +++ b/analyzer/analyzer/presentation/commenttreewidget.cpp @@ -60,6 +60,6 @@ void CommentTreeWidget::ContextMenuRequested(QPoint point) CommentTreeWidget::CommentTreeItem::CommentTreeItem(QTreeWidget *parent, const Comment &comment):QTreeWidgetItem(parent),comment(comment) { - this->setText(0,formatTraceTimePretty(comment.Time())); + this->setText(0,prettyFormatTime(comment.Time())); this->setText(1,comment.Text()); } diff --git a/analyzer/analyzer/presentation/debugmessagetreewidget.cpp b/analyzer/analyzer/presentation/debugmessagetreewidget.cpp index 01a58ea5..18344844 100644 --- a/analyzer/analyzer/presentation/debugmessagetreewidget.cpp +++ b/analyzer/analyzer/presentation/debugmessagetreewidget.cpp @@ -56,7 +56,7 @@ void DebugMessageTreeWidget::showDebugMessages(const vector& comments) { if(currentTime != comment.Time()) { - addTopLevelItem(new QTreeWidgetItem({formatTraceTimePretty(comment.Time()), formatDebugMessage(comment.Text())})); + addTopLevelItem(new QTreeWidgetItem({prettyFormatTime(comment.Time()), formatDebugMessage(comment.Text())})); currentTime = comment.Time(); } else diff --git a/analyzer/analyzer/presentation/tracePlotMouseLabel.cpp b/analyzer/analyzer/presentation/tracePlotMouseLabel.cpp index 06209dc2..aa05c412 100644 --- a/analyzer/analyzer/presentation/tracePlotMouseLabel.cpp +++ b/analyzer/analyzer/presentation/tracePlotMouseLabel.cpp @@ -11,12 +11,14 @@ QwtText TracePlotMouseLabel::trackerText(const QPoint &point) const if(mode == MouseLabelMode::AbsoluteTime) { traceTime mouseTime = static_cast(traceplot->invTransform(traceplot->xBottom, point.x())); - return QwtText(formatTraceTimePretty(alignToClk(mouseTime,clkPeriod))); + return QwtText(prettyFormatTime(alignToClk(mouseTime,clkPeriod)) + "(" + formatInClks(mouseTime,clkPeriod) + ")"); } else if(mode == MouseLabelMode::Timedifference) { - long long numberOfClockCovered = timeDifferenceSpan.timeCovered()/clkPeriod; - QString suffix = (numberOfClockCovered != 1) ? QString(" clks") : QString(" clk"); - return(QwtText(QString::number(numberOfClockCovered) + suffix)); + return QwtText(formatInClks(timeDifferenceSpan.timeCovered(),clkPeriod)); + } + else + { + Q_ASSERT(false); } } diff --git a/analyzer/analyzer/presentation/tracePlotMouseLabel.h b/analyzer/analyzer/presentation/tracePlotMouseLabel.h index 9043745e..2e5fe3ae 100644 --- a/analyzer/analyzer/presentation/tracePlotMouseLabel.h +++ b/analyzer/analyzer/presentation/tracePlotMouseLabel.h @@ -12,7 +12,7 @@ public: TracePlotMouseLabel(TracePlot* traceplot, unsigned int clkPeriod, Timespan& timeDifferenceSpan): QwtPlotPicker(QwtPlot::xBottom, QwtPlot::yLeft,QwtPlotPicker::VLineRubberBand, QwtPicker::AlwaysOn, traceplot->canvas()), - traceplot(traceplot),clkPeriod(clkPeriod), timeDifferenceSpan(timeDifferenceSpan), mode(MouseLabelMode::AbsoluteTime){} + mode(MouseLabelMode::AbsoluteTime),traceplot(traceplot),clkPeriod(clkPeriod), timeDifferenceSpan(timeDifferenceSpan){} void setMode(MouseLabelMode mode); protected: @@ -21,8 +21,8 @@ protected: private: MouseLabelMode mode; TracePlot* traceplot; - Timespan& timeDifferenceSpan; unsigned int clkPeriod; + Timespan& timeDifferenceSpan; }; #endif // TRACEPLOTPICKER_H diff --git a/analyzer/analyzer/presentation/tracenavigator.cpp b/analyzer/analyzer/presentation/tracenavigator.cpp index 74d11733..c3b06ae2 100644 --- a/analyzer/analyzer/presentation/tracenavigator.cpp +++ b/analyzer/analyzer/presentation/tracenavigator.cpp @@ -73,8 +73,6 @@ void TraceNavigator::commitChangesToDB() } traceFile.updateComments(commentsToInsert); - //TODO : reinsert file description logic - //traceFile.updateFileDescription(traceFile.getGeneralInfo().Description()); changesToCommitExist = false; } @@ -86,12 +84,6 @@ void TraceNavigator::getCommentsFromDB() } } -void TraceNavigator::setFileDescripton(const QString &description) -{ - //TODO : reinsert file description logic - changesToCommitExist = true; -} - void TraceNavigator::refreshData() { traceFile.refreshData(); diff --git a/analyzer/analyzer/presentation/tracenavigator.h b/analyzer/analyzer/presentation/tracenavigator.h index aad497db..b20cfdae 100644 --- a/analyzer/analyzer/presentation/tracenavigator.h +++ b/analyzer/analyzer/presentation/tracenavigator.h @@ -57,7 +57,6 @@ public: const CommentMap& getComments(){return comments;} void removeCommentAtTime(traceTime time); - void setFileDescripton(const QString& text); void commitChangesToDB(); void refreshData(); diff --git a/analyzer/analyzer/presentation/traceplot.cpp b/analyzer/analyzer/presentation/traceplot.cpp index 3127aea9..f17da2f4 100644 --- a/analyzer/analyzer/presentation/traceplot.cpp +++ b/analyzer/analyzer/presentation/traceplot.cpp @@ -361,7 +361,7 @@ void TracePlot::on_insertComment() { traceTime time = invTransform(xBottom, contextMenuMouseDown.x()); bool ok; - QString text = QInputDialog::getText(this,QString("Insert comment"),QString("Insert comment at ") + formatTraceTimePretty(time),QLineEdit::Normal,QString(),&ok); + QString text = QInputDialog::getText(this,QString("Insert comment"),QString("Insert comment at ") + prettyFormatTime(time),QLineEdit::Normal,QString(),&ok); if(ok) { navigator->insertComment(Comment(time,text)); diff --git a/analyzer/analyzer/presentation/transactiontreewidget.cpp b/analyzer/analyzer/presentation/transactiontreewidget.cpp index 6c686eb8..c0d4bc2f 100644 --- a/analyzer/analyzer/presentation/transactiontreewidget.cpp +++ b/analyzer/analyzer/presentation/transactiontreewidget.cpp @@ -54,7 +54,7 @@ TransactionTreeWidget::TransactionTreeItem::TransactionTreeItem(QTreeWidget *par QTreeWidgetItem *time = new QTreeWidgetItem({"Timespan"}); AppendTimespan(time, transaction->Span()); this->addChild(time); - this->addChild(new QTreeWidgetItem( {"Lenght", formatTraceTimePretty(transaction->Span().timeCovered())})); + this->addChild(new QTreeWidgetItem( {"Lenght", prettyFormatTime(transaction->Span().timeCovered())})); this->addChild(new QTreeWidgetItem( {"Channel", QString::number(transaction->Channel())})); this->addChild(new QTreeWidgetItem( {"Bank", QString::number(transaction->Bank())} )); @@ -89,6 +89,6 @@ void TransactionTreeWidget::TransactionTreeItem::AppendPhase(QTreeWidgetItem *pa void TransactionTreeWidget::TransactionTreeItem::AppendTimespan(QTreeWidgetItem *parent, const Timespan ×pan) { - parent->setText(1, formatTraceTimePretty(timespan.Begin())); - parent->setText(2, formatTraceTimePretty(timespan.End())); + parent->setText(1, prettyFormatTime(timespan.Begin())); + parent->setText(2, prettyFormatTime(timespan.End())); } diff --git a/analyzer/analyzer/tracefiletab.cpp b/analyzer/analyzer/tracefiletab.cpp index fde96b89..93801aa4 100644 --- a/analyzer/analyzer/tracefiletab.cpp +++ b/analyzer/analyzer/tracefiletab.cpp @@ -20,7 +20,6 @@ TraceFileTab::TraceFileTab(QWidget *parent,const QString& path) : TraceFileTab::~TraceFileTab() { - navigator->setFileDescripton(ui->fileDescriptionEdit->toPlainText()); navigator->commitChangesToDB(); delete ui; } diff --git a/dram/resources/simulations/sim-batch.xml b/dram/resources/simulations/sim-batch.xml index f3ad5c97..549dcba6 100644 --- a/dram/resources/simulations/sim-batch.xml +++ b/dram/resources/simulations/sim-batch.xml @@ -9,21 +9,14 @@ fifo.xml - fr_fcfs.xml + - - mediabench-epic_32.stl + chstone-jpeg_32.stl diff --git a/dram/src/simulation/main.cpp b/dram/src/simulation/main.cpp index 19f063f6..c064bc67 100644 --- a/dram/src/simulation/main.cpp +++ b/dram/src/simulation/main.cpp @@ -39,7 +39,7 @@ int sc_main(int argc, char **argv) if(argc > 1) simulationToRun = argv[1]; else - simulationToRun = "tests.xml"; + simulationToRun = "sim-batch.xml"; SimulationManager manager(resources); manager.loadSimulationsFromXML(resources + "/simulations/" + simulationToRun); From c77048ac93c92e55424efca3d122e692b52415fa Mon Sep 17 00:00:00 2001 From: Robert Gernhardt Date: Mon, 14 Jul 2014 23:17:18 +0200 Subject: [PATCH 13/13] renamed some stuff --- dram/dramSys/dramSys.pro | 5 +++-- dram/resources/simulations/sim-batch.xml | 2 +- dram/src/controller/core/powerdown/PowerDownManagerTimeout.h | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/dram/dramSys/dramSys.pro b/dram/dramSys/dramSys.pro index 98ac915e..c425e35a 100644 --- a/dram/dramSys/dramSys.pro +++ b/dram/dramSys/dramSys.pro @@ -6,10 +6,12 @@ CONFIG -= qt LIBS += -L/opt/systemc/lib-linux64 -lsystemc LIBS += -L/opt/boost/lib -lboost_filesystem -lboost_system -LIBS += -lsqlite3 +LIBS += -L/opt/sqlite3/lib -lsqlite3 LIBS += -lpthread + INCLUDEPATH += /opt/systemc/include INCLUDEPATH += /opt/boost/include +INCLUDEPATH += /opt/sqlite3/include DEFINES += TIXML_USE_STL DEFINES += SC_INCLUDE_DYNAMIC_PROCESSES @@ -76,7 +78,6 @@ HEADERS += \ ../src/controller/core/powerdown/PowerDownManagerTimeout.h \ ../src/controller/core/powerdown/PowerDownManagerBankwise.h \ ../src/controller/core/powerdown/PowerDownManager.h \ - ../src/controller/core/powerdown/IPowerDownManager.h \ ../src/controller/scheduler/ThreadLoad.h \ ../src/controller/scheduler/Scheduler.h \ ../src/controller/scheduler/PARBS.h \ diff --git a/dram/resources/simulations/sim-batch.xml b/dram/resources/simulations/sim-batch.xml index 549dcba6..6956da22 100644 --- a/dram/resources/simulations/sim-batch.xml +++ b/dram/resources/simulations/sim-batch.xml @@ -16,7 +16,7 @@ - chstone-jpeg_32.stl + mediabench-epic_32.stl
diff --git a/dram/src/controller/core/powerdown/PowerDownManagerTimeout.h b/dram/src/controller/core/powerdown/PowerDownManagerTimeout.h index 05bad85e..fc2539a0 100644 --- a/dram/src/controller/core/powerdown/PowerDownManagerTimeout.h +++ b/dram/src/controller/core/powerdown/PowerDownManagerTimeout.h @@ -8,7 +8,7 @@ #ifndef POWERDOWNMANAGERTIMEOUT_H_ #define POWERDOWNMANAGERTIMEOUT_H_ -#include "IPowerDownManager.h" +#include "PowerDownManager.h" #include #include "../../../common/dramExtension.h" #include "../scheduling/ScheduledCommand.h"