Move Trace Analyzer to open source tree
Move the code for the Trace Analyzer to the open source tree and only keep the extensions behind a compiler flag.
This commit is contained in:
@@ -91,10 +91,11 @@ set(DRAMSYS_EXTENSIONS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extensions")
|
||||
### Build options ###
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
|
||||
|
||||
option(DRAMSYS_VERBOSE_CMAKE_OUTPUT "Show detailed CMake output" OFF)
|
||||
option(DRAMSYS_BUILD_TESTS "Build DRAMSys unit tests" OFF)
|
||||
option(DRAMSYS_BUILD_BENCHMARKS "Build DRAMSys benchmarks" OFF)
|
||||
option(DRAMSYS_VERBOSE_CMAKE_OUTPUT "Show detailed CMake output" OFF)
|
||||
option(DRAMSYS_BUILD_CLI "Build DRAMSys Command Line Tool" ON)
|
||||
option(DRAMSYS_BUILD_TRACE_ANALYZER "Build DRAMSys Trace Analyzer" OFF)
|
||||
option(DRAMSYS_WITH_DRAMPOWER "Build with DRAMPower support enabled." OFF)
|
||||
option(DRAMSYS_ENABLE_EXTENSIONS "Enable proprietary DRAMSys extensions." OFF)
|
||||
option(DRAMSYS_USE_EXTERNAL_SYSTEMC "Use an external SystemC installation." OFF)
|
||||
@@ -184,6 +185,10 @@ if(DRAMSYS_BUILD_CLI)
|
||||
add_subdirectory(src/simulator)
|
||||
endif()
|
||||
|
||||
if(DRAMSYS_BUILD_TRACE_ANALYZER)
|
||||
add_subdirectory(src/traceAnalyzer)
|
||||
endif()
|
||||
|
||||
if(DRAMSYS_ENABLE_EXTENSIONS)
|
||||
dramsys_enable_extensions()
|
||||
endif()
|
||||
@@ -202,6 +207,6 @@ endif()
|
||||
### Benchmark Directory ###
|
||||
###############################################
|
||||
|
||||
if(DRAMSYS_BUILD_BENCHMARKS)
|
||||
if(DRAMSYS_BUILD_BENCHMARKS)
|
||||
add_subdirectory(benches)
|
||||
endif()
|
||||
|
||||
@@ -6,12 +6,11 @@
|
||||
##############################################
|
||||
##############################################
|
||||
|
||||
message(STATUS " Apps:")
|
||||
|
||||
##############################################
|
||||
### TraceAnalyzer ###
|
||||
##############################################
|
||||
|
||||
option(DRAMSYS_EXTENSION_TRACE_ANALYZER_ENABLE "Enable DRAMSys Trace Analyzer" ON)
|
||||
if(DRAMSYS_EXTENSION_TRACE_ANALYZER_ENABLE)
|
||||
message(STATUS " * Trace Analyzer")
|
||||
IF(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/traceAnalyzer")
|
||||
add_subdirectory(traceAnalyzer)
|
||||
endif()
|
||||
ENDIF()
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
[Dolphin]
|
||||
Timestamp=2022,2,16,16,1,1.259
|
||||
Version=4
|
||||
ViewMode=1
|
||||
VisibleRoles=Details_text,Details_type,Details_size,Details_modificationtime,CustomizedDetails
|
||||
|
||||
[Settings]
|
||||
HiddenFilesShown=true
|
||||
@@ -1,102 +1,14 @@
|
||||
# Copyright (c) 2020, RPTU Kaiserslautern-Landau
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Authors:
|
||||
# Matthias Jung
|
||||
# Lukas Steiner
|
||||
# Derek Christ
|
||||
# Iron Prando da Silva
|
||||
option(DRAMSYS_EXTENSION_TRACE_ANALYZER_ENABLE "Enable Trace Analyzer extension" ON)
|
||||
|
||||
########################################
|
||||
### TraceAnalyzer ###
|
||||
########################################
|
||||
if(DRAMSYS_EXTENSION_TRACE_ANALYZER_ENABLE AND TARGET TraceAnalyzer)
|
||||
message(STATUS " * Trace Analyzer")
|
||||
|
||||
project(TraceAnalyzer)
|
||||
file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS *.cpp)
|
||||
file(GLOB_RECURSE HEADER_FILES CONFIGURE_DEPENDS *.h;*.hpp)
|
||||
|
||||
file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS *.cpp)
|
||||
file(GLOB_RECURSE HEADER_FILES CONFIGURE_DEPENDS *.h;*.hpp)
|
||||
target_sources(TraceAnalyzer PRIVATE ${SOURCE_FILES} ${HEADER_FILES})
|
||||
target_include_directories(TraceAnalyzer PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_compile_definitions(TraceAnalyzer PRIVATE EXTENSION_ENABLED)
|
||||
|
||||
# Add Python3 Dependency:
|
||||
find_package(Python3 COMPONENTS Development Interpreter)
|
||||
|
||||
FetchContent_Declare(
|
||||
pybind11
|
||||
URL https://github.com/pybind/pybind11/archive/refs/tags/v2.10.4.zip
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(pybind11)
|
||||
|
||||
# Add QWT Dependency:
|
||||
find_library(QWT_LIBRARY NAMES "qwt" "qwt-qt5" PATHS
|
||||
"$ENV{QWT_HOME}/lib"
|
||||
"/opt/homebrew/opt/qwt-qt5/lib"
|
||||
)
|
||||
find_path(QWT_INCLUDE_DIRS NAMES "qwt_plot.h" PATHS
|
||||
"$ENV{QWT_HOME}/include"
|
||||
"/usr/include/qwt-qt5"
|
||||
"/usr/include/qwt"
|
||||
"/opt/homebrew/opt/qwt-qt5/include"
|
||||
"/opt/homebrew/opt/qwt-qt5/lib/qwt.framework/Headers"
|
||||
)
|
||||
|
||||
# Add QT Library:
|
||||
if (APPLE)
|
||||
set(Qt5_DIR "/opt/homebrew/opt/qt@5/lib/cmake/Qt5")
|
||||
endif(APPLE)
|
||||
find_package(Qt5 COMPONENTS Core Gui Widgets Sql REQUIRED)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
add_executable(TraceAnalyzer ${SOURCE_FILES} ${HEADER_FILES})
|
||||
|
||||
target_include_directories(TraceAnalyzer
|
||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
PRIVATE ${QWT_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(TraceAnalyzer
|
||||
PRIVATE pybind11::embed
|
||||
PRIVATE ${QWT_LIBRARY}
|
||||
PRIVATE Qt5::Widgets
|
||||
PRIVATE Qt5::Sql
|
||||
PRIVATE DRAMSys::util
|
||||
PRIVATE DRAMSys::config
|
||||
)
|
||||
|
||||
set(DRAMSYS_TRACEANALYZER_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
DRAMSYS_TRACEANALYZER_DIR="${DRAMSYS_TRACEANALYZER_DIR}"
|
||||
)
|
||||
|
||||
build_source_group()
|
||||
build_source_group()
|
||||
endif()
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../data/tracedb.h"
|
||||
#include "data/tracedb.h"
|
||||
#include "phases/dependencyinfos.h"
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
*/
|
||||
|
||||
#include "phasedependency.h"
|
||||
#include "phase.h"
|
||||
#include "businessObjects/phases/phase.h"
|
||||
#include <iostream>
|
||||
|
||||
PhaseDependency::PhaseDependency(DependencyType type,
|
||||
|
||||
@@ -1,400 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021, RPTU Kaiserslautern-Landau
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#include "simulationdialog.h"
|
||||
#include "DRAMSys/config/TraceSetup.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QRegularExpression>
|
||||
#include <optional>
|
||||
|
||||
SimulationDialog::SimulationDialog(QWidget* parent) : QWidget(parent), ui(new Ui::SimulationDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
showStopButton(false);
|
||||
|
||||
// Try to find path to DRAMSys
|
||||
{
|
||||
QFileInfo fileInfo;
|
||||
|
||||
fileInfo.setFile("../simulator/DRAMSys");
|
||||
if (fileInfo.isFile())
|
||||
ui->dramSysPath->setText(fileInfo.absoluteFilePath());
|
||||
|
||||
fileInfo.setFile("../simulator/DRAMSys.exe");
|
||||
if (fileInfo.isFile())
|
||||
ui->dramSysPath->setText(fileInfo.absoluteFilePath());
|
||||
|
||||
fileInfo.setFile("simulator/DRAMSys");
|
||||
if (fileInfo.isFile())
|
||||
ui->dramSysPath->setText(fileInfo.absoluteFilePath());
|
||||
|
||||
fileInfo.setFile("simulator/DRAMSys.exe");
|
||||
if (fileInfo.isFile())
|
||||
ui->dramSysPath->setText(fileInfo.absoluteFilePath());
|
||||
}
|
||||
|
||||
ui->outputDirLineEdit->setText(QDir::currentPath());
|
||||
}
|
||||
|
||||
void SimulationDialog::on_browseDramSysButton_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(
|
||||
this, ui->browseDramSysButton->text(), {}, "DRAMSys executable (*)");
|
||||
ui->dramSysPath->setText(fileName);
|
||||
}
|
||||
|
||||
void SimulationDialog::on_browseConfigButton_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(
|
||||
this, ui->browseConfigButton->text(), {}, "Configuration file (*.json)");
|
||||
ui->jsonPath->setText(fileName);
|
||||
|
||||
loadConfigurationFromPath();
|
||||
}
|
||||
|
||||
void SimulationDialog::on_browseOutputButton_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getExistingDirectory(this, ui->browseOutputButton->text(), {});
|
||||
ui->outputDirLineEdit->setText(fileName);
|
||||
|
||||
loadConfigurationFromPath();
|
||||
}
|
||||
|
||||
void SimulationDialog::on_browseResourceDirButton_clicked()
|
||||
{
|
||||
QString fileName =
|
||||
QFileDialog::getExistingDirectory(this, ui->browseResourceDirButton->text(), {});
|
||||
ui->resourceDirLineEdit->setText(fileName);
|
||||
|
||||
loadConfigurationFromPath();
|
||||
}
|
||||
|
||||
void SimulationDialog::on_simulateButton_clicked()
|
||||
{
|
||||
saveConfiguration(temporaryConfigurationFile);
|
||||
|
||||
ui->tabWidget->setCurrentWidget(ui->outputTab);
|
||||
ui->progressBar->setEnabled(true);
|
||||
ui->progressBar->setValue(0);
|
||||
|
||||
showStopButton(true);
|
||||
|
||||
// Spawn the DRAMSys process
|
||||
simulatorProcess = new QProcess(this);
|
||||
|
||||
QObject::connect(simulatorProcess,
|
||||
&QIODevice::readyRead,
|
||||
this,
|
||||
[=]
|
||||
{
|
||||
QByteArray msg = simulatorProcess->read(4096);
|
||||
msg = msg.trimmed();
|
||||
processMessage(msg.toStdString());
|
||||
});
|
||||
|
||||
QObject::connect(simulatorProcess,
|
||||
QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
||||
this,
|
||||
[=](int exitCode, QProcess::ExitStatus exitStatus)
|
||||
{
|
||||
Q_UNUSED(exitStatus)
|
||||
|
||||
showStopButton(false);
|
||||
|
||||
// Clear all the contents so that the user is not asked
|
||||
// next time to overwrite the temp file.
|
||||
temporaryConfigurationFile.resize(0);
|
||||
|
||||
if (exitCode == 0)
|
||||
{
|
||||
ui->progressBar->setValue(100);
|
||||
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText("Simulation done.");
|
||||
msgBox.setInformativeText("Do you want to open the results?");
|
||||
msgBox.setStandardButtons(QMessageBox::Open | QMessageBox::Cancel);
|
||||
msgBox.setDefaultButton(QMessageBox::Open);
|
||||
int ret = msgBox.exec();
|
||||
|
||||
if (ret == QMessageBox::Open)
|
||||
{
|
||||
auto results = getSimulationResults();
|
||||
openSimulationResults(results);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
QStringList argumentList;
|
||||
argumentList << temporaryConfigurationFile.fileName();
|
||||
|
||||
if (!ui->resourceDirLineEdit->text().isEmpty())
|
||||
argumentList << ui->resourceDirLineEdit->text();
|
||||
|
||||
simulatorProcess->setWorkingDirectory(ui->outputDirLineEdit->text());
|
||||
simulatorProcess->start(ui->dramSysPath->text(), argumentList);
|
||||
}
|
||||
|
||||
void SimulationDialog::on_reloadButton_clicked()
|
||||
{
|
||||
loadConfigurationFromPath();
|
||||
|
||||
ui->outputPlainTextEdit->clear();
|
||||
}
|
||||
|
||||
void SimulationDialog::on_saveButton_clicked()
|
||||
{
|
||||
QFile file(ui->jsonPath->text());
|
||||
saveConfiguration(file);
|
||||
}
|
||||
|
||||
void SimulationDialog::on_stopButton_clicked()
|
||||
{
|
||||
if (simulatorProcess)
|
||||
simulatorProcess->terminate();
|
||||
}
|
||||
|
||||
void SimulationDialog::showStopButton(bool val)
|
||||
{
|
||||
ui->simulateButton->setVisible(!val);
|
||||
ui->stopButton->setVisible(val);
|
||||
}
|
||||
|
||||
void SimulationDialog::saveConfiguration(QFile& file)
|
||||
{
|
||||
if (!file.open(QIODevice::ReadWrite | QIODevice::Text))
|
||||
return;
|
||||
|
||||
if (file.size() != 0)
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText("The configuration file will be overwritten.");
|
||||
msgBox.setInformativeText("Do you want to save your changes?");
|
||||
msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Cancel);
|
||||
msgBox.setDefaultButton(QMessageBox::Save);
|
||||
int ret = msgBox.exec();
|
||||
|
||||
if (ret != QMessageBox::Save)
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear the file
|
||||
file.resize(0);
|
||||
|
||||
QTextStream out(&file);
|
||||
|
||||
loadConfigurationFromTextFields();
|
||||
|
||||
std::string dump = nlohmann::json(configuration).dump(4);
|
||||
out << dump.c_str();
|
||||
}
|
||||
|
||||
void SimulationDialog::processMessage(const std::string& msg)
|
||||
{
|
||||
// Get percentages
|
||||
QRegularExpression re("(\\d+(\\.\\d+)?|\\.\\d+) ?%");
|
||||
QRegularExpressionMatch match = re.match(msg.c_str());
|
||||
|
||||
if (match.hasMatch())
|
||||
{
|
||||
unsigned int percentage = match.captured(1).toUInt();
|
||||
|
||||
ui->progressBar->setValue(percentage);
|
||||
}
|
||||
|
||||
ui->outputPlainTextEdit->appendPlainText(msg.c_str());
|
||||
}
|
||||
|
||||
void SimulationDialog::loadConfigurationFromTextFields()
|
||||
{
|
||||
using namespace DRAMSys::Config;
|
||||
|
||||
AddressMapping addressMapping;
|
||||
McConfig mcConfig;
|
||||
MemSpec memSpec;
|
||||
SimConfig simConfig;
|
||||
std::string simulationId;
|
||||
std::vector<Initiator> traceSetup;
|
||||
|
||||
simulationId = ui->simulationIdLineEdit->text().toStdString();
|
||||
|
||||
try
|
||||
{
|
||||
nlohmann::json::parse(ui->addressMappingTextEdit->toPlainText().toStdString())
|
||||
.get_to(addressMapping);
|
||||
nlohmann::json::parse(ui->mcConfigTextEdit->toPlainText().toStdString()).get_to(mcConfig);
|
||||
nlohmann::json::parse(ui->memSpecTextEdit->toPlainText().toStdString()).get_to(memSpec);
|
||||
nlohmann::json::parse(ui->simConfigTextEdit->toPlainText().toStdString()).get_to(simConfig);
|
||||
|
||||
if (!ui->traceSetupTextEdit->toPlainText().toStdString().empty())
|
||||
nlohmann::json::parse(ui->traceSetupTextEdit->toPlainText().toStdString())
|
||||
.get_to(traceSetup);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
qWarning() << "Error while parsing json:" << e.what();
|
||||
return;
|
||||
}
|
||||
|
||||
configuration = DRAMSys::Config::Configuration{
|
||||
addressMapping,
|
||||
mcConfig,
|
||||
memSpec,
|
||||
simConfig,
|
||||
simulationId,
|
||||
std::make_optional<std::vector<Initiator>>(std::move(traceSetup))};
|
||||
|
||||
loadConfiguration();
|
||||
}
|
||||
|
||||
void SimulationDialog::loadConfigurationFromPath()
|
||||
{
|
||||
QFileInfo fileInfo(ui->jsonPath->text());
|
||||
|
||||
if (!fileInfo.isFile())
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
configuration = DRAMSys::Config::from_path(ui->jsonPath->text().toStdString());
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
qWarning() << "Error while parsing json:" << e.what();
|
||||
return;
|
||||
}
|
||||
|
||||
loadConfiguration();
|
||||
}
|
||||
|
||||
void SimulationDialog::loadConfiguration()
|
||||
{
|
||||
ui->simulationIdLabel->setEnabled(true);
|
||||
ui->simulationId->setEnabled(true);
|
||||
ui->simulationId->setText(configuration.simulationid.c_str());
|
||||
|
||||
ui->simulationIdLineEdit->setText(configuration.simulationid.c_str());
|
||||
|
||||
loadSimConfig();
|
||||
loadMcConfig();
|
||||
loadMemSpec();
|
||||
loadAddressMapping();
|
||||
loadTraceSetup();
|
||||
loadPreview();
|
||||
}
|
||||
|
||||
void SimulationDialog::loadSimConfig()
|
||||
{
|
||||
ui->simConfigTextEdit->clear();
|
||||
|
||||
std::string dump = nlohmann::json(configuration.simconfig).dump(4);
|
||||
ui->simConfigTextEdit->setText(dump.c_str());
|
||||
}
|
||||
|
||||
void SimulationDialog::loadMcConfig()
|
||||
{
|
||||
ui->mcConfigTextEdit->clear();
|
||||
|
||||
std::string dump = nlohmann::json(configuration.mcconfig).dump(4);
|
||||
ui->mcConfigTextEdit->setText(dump.c_str());
|
||||
}
|
||||
|
||||
void SimulationDialog::loadMemSpec()
|
||||
{
|
||||
ui->memSpecTextEdit->clear();
|
||||
|
||||
std::string dump = nlohmann::json(configuration.memspec).dump(4);
|
||||
ui->memSpecTextEdit->setText(dump.c_str());
|
||||
}
|
||||
|
||||
void SimulationDialog::loadAddressMapping()
|
||||
{
|
||||
ui->addressMappingTextEdit->clear();
|
||||
|
||||
std::string dump = nlohmann::json(configuration.addressmapping).dump(4);
|
||||
ui->addressMappingTextEdit->setText(dump.c_str());
|
||||
}
|
||||
|
||||
void SimulationDialog::loadTraceSetup()
|
||||
{
|
||||
ui->traceSetupTextEdit->clear();
|
||||
|
||||
if (const auto& traceSetup = configuration.tracesetup)
|
||||
{
|
||||
std::string dump = nlohmann::json(*traceSetup).dump(4);
|
||||
ui->traceSetupTextEdit->setText(dump.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void SimulationDialog::loadPreview()
|
||||
{
|
||||
ui->previewTextEdit->clear();
|
||||
|
||||
std::string dump = nlohmann::json(configuration).dump(4);
|
||||
ui->previewTextEdit->setText(dump.c_str());
|
||||
}
|
||||
|
||||
QFileInfoList SimulationDialog::getSimulationResults()
|
||||
{
|
||||
QFileInfoList list;
|
||||
|
||||
// Get the path where the tracefiles are located
|
||||
QDir baseDir(ui->outputDirLineEdit->text());
|
||||
|
||||
for (const auto& fileInfo : baseDir.entryInfoList())
|
||||
{
|
||||
if (fileInfo.baseName().startsWith(configuration.simulationid.c_str()))
|
||||
{
|
||||
// Dont open tracefiles that are older than a few seconds
|
||||
if (fileInfo.metadataChangeTime().secsTo(QDateTime::currentDateTime()) > 30)
|
||||
continue;
|
||||
|
||||
list << fileInfo;
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
void SimulationDialog::openSimulationResults(const QFileInfoList& fileInfos)
|
||||
{
|
||||
for (const auto& fileInfo : fileInfos)
|
||||
openFileRequested(fileInfo.absoluteFilePath());
|
||||
}
|
||||
@@ -1,394 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SimulationDialog</class>
|
||||
<widget class="QWidget" name="SimulationDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>920</width>
|
||||
<height>620</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font/>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Simulation</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Simulation</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="browseLayout">
|
||||
<item row="3" column="2">
|
||||
<widget class="QLineEdit" name="resourceDirLineEdit">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>Path to resource directory... (optional)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QPushButton" name="browseOutputButton">
|
||||
<property name="text">
|
||||
<string>Browse...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="configurationLabel">
|
||||
<property name="text">
|
||||
<string>Base configuration:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QPushButton" name="browseConfigButton">
|
||||
<property name="text">
|
||||
<string>Browse...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="dramSysLabel">
|
||||
<property name="text">
|
||||
<string>DRAMSys:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="outputDirLabel">
|
||||
<property name="text">
|
||||
<string>Output directory:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLineEdit" name="dramSysPath">
|
||||
<property name="placeholderText">
|
||||
<string>Path to DRAMSys...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QPushButton" name="browseResourceDirButton">
|
||||
<property name="text">
|
||||
<string>Browse...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QPushButton" name="browseDramSysButton">
|
||||
<property name="text">
|
||||
<string>Browse...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLineEdit" name="outputDirLineEdit">
|
||||
<property name="placeholderText">
|
||||
<string>Path to output directory...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLineEdit" name="jsonPath">
|
||||
<property name="placeholderText">
|
||||
<string>Path to Json configuration...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="resourceDirectoryLabel">
|
||||
<property name="text">
|
||||
<string>Resource directory:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="simulationIdLabel">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Simulation Id:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="simulationId">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="simulateButton">
|
||||
<property name="text">
|
||||
<string>Start Simulation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="stopButton">
|
||||
<property name="text">
|
||||
<string>Stop Simulation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="simConfigTab">
|
||||
<attribute name="title">
|
||||
<string>SimConfig</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTextEdit" name="simConfigTextEdit">
|
||||
<property name="font">
|
||||
<font/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="mcConfigTab">
|
||||
<attribute name="title">
|
||||
<string>McConfig</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTextEdit" name="mcConfigTextEdit">
|
||||
<property name="font">
|
||||
<font/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="memSpecTab">
|
||||
<attribute name="title">
|
||||
<string>MemSpec</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTextEdit" name="memSpecTextEdit">
|
||||
<property name="font">
|
||||
<font/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="thermalConfigTab">
|
||||
<attribute name="title">
|
||||
<string>ThermalConfig</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTextEdit" name="thermalConfigTextEdit">
|
||||
<property name="font">
|
||||
<font/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="traceSetupTab">
|
||||
<attribute name="title">
|
||||
<string>TraceSetup</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_7">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTextEdit" name="traceSetupTextEdit">
|
||||
<property name="font">
|
||||
<font/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="addressMappingTab">
|
||||
<attribute name="title">
|
||||
<string>AddressMapping</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_9">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTextEdit" name="addressMappingTextEdit">
|
||||
<property name="font">
|
||||
<font/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="previewTab">
|
||||
<attribute name="title">
|
||||
<string>Preview Configuration</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_8">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTextEdit" name="previewTextEdit">
|
||||
<property name="font">
|
||||
<font/>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="outputTab">
|
||||
<attribute name="title">
|
||||
<string>Output</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QPlainTextEdit" name="outputPlainTextEdit">
|
||||
<property name="font">
|
||||
<font/>
|
||||
</property>
|
||||
<property name="lineWrapMode">
|
||||
<enum>QPlainTextEdit::NoWrap</enum>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="reloadButton">
|
||||
<property name="text">
|
||||
<string>Reload</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="simulationIdLineEdit">
|
||||
<property name="placeholderText">
|
||||
<string>Simulation Id</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="saveButton">
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="closeButton">
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>dramSysPath</tabstop>
|
||||
<tabstop>outputDirLineEdit</tabstop>
|
||||
<tabstop>jsonPath</tabstop>
|
||||
<tabstop>resourceDirLineEdit</tabstop>
|
||||
<tabstop>browseDramSysButton</tabstop>
|
||||
<tabstop>browseOutputButton</tabstop>
|
||||
<tabstop>browseConfigButton</tabstop>
|
||||
<tabstop>browseResourceDirButton</tabstop>
|
||||
<tabstop>simulateButton</tabstop>
|
||||
<tabstop>stopButton</tabstop>
|
||||
<tabstop>tabWidget</tabstop>
|
||||
<tabstop>reloadButton</tabstop>
|
||||
<tabstop>simulationIdLineEdit</tabstop>
|
||||
<tabstop>saveButton</tabstop>
|
||||
<tabstop>closeButton</tabstop>
|
||||
<tabstop>simConfigTextEdit</tabstop>
|
||||
<tabstop>outputPlainTextEdit</tabstop>
|
||||
<tabstop>memSpecTextEdit</tabstop>
|
||||
<tabstop>thermalConfigTextEdit</tabstop>
|
||||
<tabstop>traceSetupTextEdit</tabstop>
|
||||
<tabstop>addressMappingTextEdit</tabstop>
|
||||
<tabstop>mcConfigTextEdit</tabstop>
|
||||
<tabstop>previewTextEdit</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>closeButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>SimulationDialog</receiver>
|
||||
<slot>close()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>836</x>
|
||||
<y>507</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>830</x>
|
||||
<y>575</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -38,197 +38,16 @@
|
||||
*/
|
||||
|
||||
#include "tracefiletab.h"
|
||||
#include "businessObjects/commentmodel.h"
|
||||
#include "businessObjects/configmodels.h"
|
||||
#include "businessObjects/dramTimeDependencies/phasedependenciestracker.h"
|
||||
#include "businessObjects/traceplotlinemodel.h"
|
||||
#include "businessObjects/tracetime.h"
|
||||
#include "queryeditor.h"
|
||||
#include "traceanalyzer.h"
|
||||
#include "ui_tracefiletab.h"
|
||||
|
||||
#include <QCloseEvent>
|
||||
#include <QDebug>
|
||||
#include <QFileDialog>
|
||||
#include <QFileInfo>
|
||||
#include "businessObjects/dramTimeDependencies/phasedependenciestracker.h"
|
||||
|
||||
#include <QItemDelegate>
|
||||
#include <QMessageBox>
|
||||
#include <QStandardItemModel>
|
||||
#include <QString>
|
||||
#include <QTextStream>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
#include <qwt_legend.h>
|
||||
#include <qwt_plot_canvas.h>
|
||||
#include <QStandardItem>
|
||||
|
||||
#include <qwt_plot_curve.h>
|
||||
#include <qwt_plot_histogram.h>
|
||||
#include <qwt_plot_magnifier.h>
|
||||
#include <qwt_plot_panner.h>
|
||||
#include <qwt_scale_draw.h>
|
||||
#include <qwt_scale_widget.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <pybind11/pybind11.h>
|
||||
|
||||
TraceFileTab::TraceFileTab(std::string_view traceFilePath,
|
||||
PythonCaller& pythonCaller,
|
||||
QWidget* parent) :
|
||||
QWidget(parent),
|
||||
traceFilePath(traceFilePath),
|
||||
ui(new Ui::TraceFileTab),
|
||||
commentModel(new CommentModel(this)),
|
||||
navigator(new TraceNavigator(traceFilePath.data(), commentModel, this)),
|
||||
mcConfigModel(new McConfigModel(navigator->TraceFile(), this)),
|
||||
memSpecModel(new MemSpecModel(navigator->TraceFile(), this)),
|
||||
availableRowsModel(new AvailableTracePlotLineModel(navigator->GeneralTraceInfo(), this)),
|
||||
selectedRowsModel(new SelectedTracePlotLineModel(navigator->GeneralTraceInfo(), this)),
|
||||
tracePlotLineDataSource(new TracePlotLineDataSource(selectedRowsModel, this)),
|
||||
depInfosView(new DependencyInfosModel(navigator->TraceFile(), this)),
|
||||
pythonCaller(pythonCaller),
|
||||
savingChangesToDB(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
std::cout << "Opening new tab for \"" << traceFilePath << "\"" << std::endl;
|
||||
|
||||
ui->mcConfigView->setModel(mcConfigModel);
|
||||
ui->mcConfigView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||
|
||||
ui->memSpecView->setModel(memSpecModel);
|
||||
ui->memSpecView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||
|
||||
ui->depInfosView->setModel(depInfosView);
|
||||
ui->depInfosView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||
|
||||
setUpTraceSelector();
|
||||
initNavigatorAndItsDependentWidgets();
|
||||
setUpFileWatcher(traceFilePath.data());
|
||||
setUpTraceplotScrollbar();
|
||||
setUpCommentView();
|
||||
|
||||
setUpPossiblePhases();
|
||||
|
||||
tracefileChanged();
|
||||
}
|
||||
|
||||
TraceFileTab::~TraceFileTab()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void TraceFileTab::commitChangesToDB()
|
||||
{
|
||||
savingChangesToDB = true;
|
||||
navigator->commitChangesToDB();
|
||||
}
|
||||
|
||||
void TraceFileTab::exportAsVCD()
|
||||
{
|
||||
std::string filename =
|
||||
QFileDialog::getSaveFileName(this, "Export to VCD", "", "VCD files (*.vcd)").toStdString();
|
||||
|
||||
auto dump = PythonCaller::dumpVcd(traceFilePath);
|
||||
|
||||
std::ofstream file(filename);
|
||||
file << dump;
|
||||
|
||||
Q_EMIT statusChanged(QString("VCD export finished."));
|
||||
}
|
||||
|
||||
void TraceFileTab::setUpTraceSelector()
|
||||
{
|
||||
ui->availableTreeView->setModel(availableRowsModel);
|
||||
ui->availableTreeView->setSelectionModel(availableRowsModel->selectionModel());
|
||||
ui->availableTreeView->installEventFilter(availableRowsModel);
|
||||
|
||||
ui->selectedTreeView->setModel(selectedRowsModel);
|
||||
ui->selectedTreeView->setSelectionModel(selectedRowsModel->selectionModel());
|
||||
ui->selectedTreeView->installEventFilter(selectedRowsModel);
|
||||
|
||||
connect(availableRowsModel,
|
||||
&AvailableTracePlotLineModel::returnPressed,
|
||||
selectedRowsModel,
|
||||
&SelectedTracePlotLineModel::addIndexesFromAvailableModel);
|
||||
|
||||
connect(ui->availableTreeView,
|
||||
&QAbstractItemView::doubleClicked,
|
||||
availableRowsModel,
|
||||
&AvailableTracePlotLineModel::itemsDoubleClicked);
|
||||
connect(ui->selectedTreeView,
|
||||
&QAbstractItemView::doubleClicked,
|
||||
selectedRowsModel,
|
||||
&SelectedTracePlotLineModel::itemsDoubleClicked);
|
||||
|
||||
connect(selectedRowsModel,
|
||||
&QAbstractItemModel::dataChanged,
|
||||
tracePlotLineDataSource,
|
||||
&TracePlotLineDataSource::updateModel);
|
||||
connect(selectedRowsModel,
|
||||
&QAbstractItemModel::rowsInserted,
|
||||
tracePlotLineDataSource,
|
||||
&TracePlotLineDataSource::updateModel);
|
||||
connect(selectedRowsModel,
|
||||
&QAbstractItemModel::rowsRemoved,
|
||||
tracePlotLineDataSource,
|
||||
&TracePlotLineDataSource::updateModel);
|
||||
}
|
||||
|
||||
void TraceFileTab::setUpTraceplotScrollbar()
|
||||
{
|
||||
QObject::connect(ui->traceplotScrollbar,
|
||||
SIGNAL(valueChanged(int)),
|
||||
ui->traceplot,
|
||||
SLOT(verticalScrollbarChanged(int)));
|
||||
}
|
||||
|
||||
void TraceFileTab::initNavigatorAndItsDependentWidgets()
|
||||
{
|
||||
ui->traceplot->init(navigator, ui->traceplotScrollbar, tracePlotLineDataSource, commentModel);
|
||||
|
||||
ui->traceScroller->init(navigator, ui->traceplot, tracePlotLineDataSource);
|
||||
connect(this,
|
||||
SIGNAL(colorGroupingChanged(ColorGrouping)),
|
||||
ui->traceScroller,
|
||||
SLOT(colorGroupingChanged(ColorGrouping)));
|
||||
|
||||
ui->selectedTransactionTree->init(navigator);
|
||||
// ui->debugMessages->init(navigator,ui->traceplot);
|
||||
|
||||
ui->bandwidthPlot->canvas()->installEventFilter(this);
|
||||
ui->powerPlot->canvas()->installEventFilter(this);
|
||||
ui->bufferPlot->canvas()->installEventFilter(this);
|
||||
}
|
||||
|
||||
void TraceFileTab::setUpFileWatcher(QString path)
|
||||
{
|
||||
fileWatcher = new QFileSystemWatcher(QStringList(path), this);
|
||||
QObject::connect(fileWatcher, SIGNAL(fileChanged(QString)), this, SLOT(tracefileChanged()));
|
||||
}
|
||||
|
||||
void TraceFileTab::setUpCommentView()
|
||||
{
|
||||
ui->commentView->setModel(commentModel);
|
||||
ui->commentView->setSelectionModel(commentModel->selectionModel());
|
||||
ui->commentView->installEventFilter(commentModel);
|
||||
ui->commentView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
|
||||
QObject::connect(ui->commentView,
|
||||
&QTableView::customContextMenuRequested,
|
||||
commentModel,
|
||||
&CommentModel::openContextMenu);
|
||||
|
||||
QObject::connect(commentModel,
|
||||
&CommentModel::editTriggered,
|
||||
ui->commentView,
|
||||
[=](const QModelIndex& index)
|
||||
{
|
||||
ui->tabWidget->setCurrentWidget(ui->tabComments);
|
||||
ui->commentView->edit(index);
|
||||
ui->commentView->scrollTo(index);
|
||||
});
|
||||
|
||||
QObject::connect(
|
||||
ui->commentView, &QTableView::doubleClicked, commentModel, &CommentModel::rowDoubleClicked);
|
||||
}
|
||||
|
||||
void TraceFileTab::setUpPossiblePhases()
|
||||
{
|
||||
@@ -244,94 +63,6 @@ void TraceFileTab::setUpPossiblePhases()
|
||||
ConfigurationFactory::deviceSupported(navigator->TraceFile()));
|
||||
}
|
||||
|
||||
void TraceFileTab::tracefileChanged()
|
||||
{
|
||||
if (savingChangesToDB == true)
|
||||
{
|
||||
// Database has changed due to user action (e.g., saving comments).
|
||||
// No need to disable the "Save changes to DB" menu.
|
||||
savingChangesToDB = false;
|
||||
Q_EMIT statusChanged(QString("Changes saved "));
|
||||
}
|
||||
else
|
||||
{
|
||||
// External event changed the database file (e.g., the database file
|
||||
// was overwritten when running a new test).
|
||||
// The "Save changes to DB" menu must be disabled to avoid saving
|
||||
// changes to a corrupted or inconsistent file.
|
||||
Q_EMIT statusChanged(QString("At least one database has changed on disk "));
|
||||
}
|
||||
navigator->refreshData();
|
||||
}
|
||||
|
||||
void TraceFileTab::closeEvent(QCloseEvent* event)
|
||||
{
|
||||
if (navigator->existChangesToCommit())
|
||||
{
|
||||
QMessageBox saveDialog;
|
||||
saveDialog.setWindowTitle(QFileInfo(traceFilePath.data()).baseName());
|
||||
saveDialog.setText("The trace file has been modified.");
|
||||
saveDialog.setInformativeText(
|
||||
"Do you want to save your changes?<br><b>Unsaved changes will be lost.</b>");
|
||||
saveDialog.setStandardButtons(QMessageBox::Save | QMessageBox::Discard |
|
||||
QMessageBox::Cancel);
|
||||
saveDialog.setDefaultButton(QMessageBox::Save);
|
||||
saveDialog.setIcon(QMessageBox::Warning);
|
||||
int returnCode = saveDialog.exec();
|
||||
|
||||
switch (returnCode)
|
||||
{
|
||||
case QMessageBox::Cancel:
|
||||
event->ignore();
|
||||
break;
|
||||
case QMessageBox::Discard:
|
||||
event->accept();
|
||||
break;
|
||||
case QMessageBox::Save:
|
||||
commitChangesToDB();
|
||||
event->accept();
|
||||
break;
|
||||
};
|
||||
}
|
||||
else
|
||||
event->accept();
|
||||
}
|
||||
|
||||
traceTime TraceFileTab::getCurrentTraceTime() const
|
||||
{
|
||||
return navigator->CurrentTraceTime();
|
||||
}
|
||||
|
||||
void TraceFileTab::navigateToTime(traceTime time)
|
||||
{
|
||||
navigator->navigateToTime(time);
|
||||
}
|
||||
|
||||
traceTime TraceFileTab::getZoomLevel() const
|
||||
{
|
||||
TracePlot* traceplot = static_cast<TracePlot*>(ui->traceplot);
|
||||
return traceplot->ZoomLevel();
|
||||
}
|
||||
|
||||
void TraceFileTab::setZoomLevel(traceTime zoomLevel)
|
||||
{
|
||||
TracePlot* traceplot = static_cast<TracePlot*>(ui->traceplot);
|
||||
TraceScroller* tracescroller = static_cast<TraceScroller*>(ui->traceScroller);
|
||||
traceplot->setZoomLevel(zoomLevel);
|
||||
tracescroller->tracePlotZoomChanged();
|
||||
}
|
||||
|
||||
std::shared_ptr<AbstractTracePlotLineModel::Node> TraceFileTab::saveTraceSelectorState() const
|
||||
{
|
||||
return selectedRowsModel->getClonedRootNode();
|
||||
}
|
||||
|
||||
void TraceFileTab::restoreTraceSelectorState(
|
||||
std::shared_ptr<AbstractTracePlotLineModel::Node> rootNode)
|
||||
{
|
||||
selectedRowsModel->setRootNode(std::move(rootNode));
|
||||
}
|
||||
|
||||
class ItemDelegate : public QItemDelegate
|
||||
{
|
||||
public:
|
||||
@@ -372,32 +103,6 @@ void TraceFileTab::on_latencyTreeView_doubleClicked(const QModelIndex& index)
|
||||
}
|
||||
}
|
||||
|
||||
bool TraceFileTab::eventFilter(QObject* object, QEvent* event)
|
||||
{
|
||||
if (auto canvas = qobject_cast<QwtPlotCanvas*>(object))
|
||||
{
|
||||
if (event->type() == QEvent::MouseButtonDblClick)
|
||||
{
|
||||
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
|
||||
if (mouseEvent->button() != Qt::LeftButton)
|
||||
return false;
|
||||
|
||||
QwtPlot* plot = canvas->plot();
|
||||
|
||||
double realTime = plot->invTransform(QwtPlot::xBottom, mouseEvent->x());
|
||||
|
||||
// Convert from seconds to picoseconds
|
||||
traceTime time = realTime * 1000 * 1000 * 1000 * 1000;
|
||||
|
||||
navigator->navigateToTime(time);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return QWidget::eventFilter(object, event);
|
||||
}
|
||||
|
||||
void TraceFileTab::on_calculateDependencies_clicked()
|
||||
{
|
||||
std::vector<QString> dependencyFilter;
|
||||
@@ -490,7 +195,6 @@ void TraceFileTab::on_startLatencyAnalysis_clicked()
|
||||
|
||||
void TraceFileTab::on_startPowerAnalysis_clicked()
|
||||
{
|
||||
qDebug() << "Power Analysis";
|
||||
QSqlDatabase db = navigator->TraceFile().getDatabase();
|
||||
QSqlQuery query(db);
|
||||
|
||||
@@ -502,11 +206,13 @@ void TraceFileTab::on_startPowerAnalysis_clicked()
|
||||
QwtPlotCurve* cur = new QwtPlotCurve("Speed");
|
||||
QVector<QPointF>* samples = new QVector<QPointF>;
|
||||
|
||||
double maxPower = 0.0;
|
||||
while (query.next())
|
||||
{
|
||||
double time = query.value(0).toDouble();
|
||||
double power = query.value(1).toDouble();
|
||||
samples->push_back(QPointF(time, power));
|
||||
maxPower = std::max(maxPower, power);
|
||||
}
|
||||
|
||||
// ui->powerPlot->setAxisTitle(QwtPlot::xBottom,"Time");
|
||||
@@ -519,6 +225,12 @@ void TraceFileTab::on_startPowerAnalysis_clicked()
|
||||
cur->attach(ui->powerPlot);
|
||||
cur->setPen(QPen(QColor(255, 0, 0)));
|
||||
|
||||
ui->powerPlot->setAxisTitle(0, "Power [mW]");
|
||||
ui->powerPlot->setAxisScale(0, 0.0, maxPower);
|
||||
QwtText axisTitle0("Time [s]");
|
||||
axisTitle0.setFont(ui->powerPlot->axisTitle(QwtPlot::xBottom).font());
|
||||
ui->powerPlot->setAxisTitle(QwtPlot::xBottom, axisTitle0);
|
||||
|
||||
QwtPlotMagnifier* mag1 = new QwtPlotMagnifier(ui->powerPlot->canvas());
|
||||
mag1->setAxisEnabled(QwtPlot::xBottom, true);
|
||||
mag1->setAxisEnabled(QwtPlot::yLeft, false);
|
||||
|
||||
@@ -6,4 +6,4 @@ FOREACH(sub_dir ${sub_dirs})
|
||||
IF(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${sub_dir}")
|
||||
add_subdirectory(${sub_dir})
|
||||
ENDIF()
|
||||
ENDFOREACH()
|
||||
ENDFOREACH()
|
||||
|
||||
104
src/traceAnalyzer/CMakeLists.txt
Normal file
104
src/traceAnalyzer/CMakeLists.txt
Normal file
@@ -0,0 +1,104 @@
|
||||
# Copyright (c) 2020, RPTU Kaiserslautern-Landau
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Authors:
|
||||
# Matthias Jung
|
||||
# Lukas Steiner
|
||||
# Derek Christ
|
||||
# Iron Prando da Silva
|
||||
|
||||
########################################
|
||||
### TraceAnalyzer ###
|
||||
########################################
|
||||
|
||||
project(TraceAnalyzer)
|
||||
|
||||
file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS *.cpp)
|
||||
file(GLOB_RECURSE HEADER_FILES CONFIGURE_DEPENDS *.h;*.hpp)
|
||||
|
||||
# Add Python3 Dependency:
|
||||
find_package(Python3 COMPONENTS Development Interpreter)
|
||||
|
||||
FetchContent_Declare(
|
||||
pybind11
|
||||
URL https://github.com/pybind/pybind11/archive/refs/tags/v2.13.1.zip
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(pybind11)
|
||||
|
||||
# Add QWT Dependency:
|
||||
find_library(QWT_LIBRARY NAMES "qwt" "qwt-qt5" PATHS
|
||||
"$ENV{QWT_HOME}/lib"
|
||||
"/opt/homebrew/opt/qwt-qt5/lib"
|
||||
)
|
||||
find_path(QWT_INCLUDE_DIRS NAMES "qwt_plot.h" PATHS
|
||||
"$ENV{QWT_HOME}/include"
|
||||
"/usr/include/qwt-qt5"
|
||||
"/usr/include/qwt"
|
||||
"/opt/homebrew/opt/qwt-qt5/include"
|
||||
"/opt/homebrew/opt/qwt-qt5/lib/qwt.framework/Headers"
|
||||
)
|
||||
|
||||
# Add QT Library:
|
||||
if (APPLE)
|
||||
set(Qt5_DIR "/opt/homebrew/opt/qt@5/lib/cmake/Qt5")
|
||||
endif(APPLE)
|
||||
find_package(Qt5 COMPONENTS Core Gui Widgets Sql REQUIRED)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
add_executable(TraceAnalyzer ${SOURCE_FILES} ${HEADER_FILES})
|
||||
|
||||
target_include_directories(TraceAnalyzer
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${QWT_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(TraceAnalyzer
|
||||
PRIVATE
|
||||
pybind11::embed
|
||||
${QWT_LIBRARY}
|
||||
Qt5::Widgets
|
||||
Qt5::Sql
|
||||
DRAMSys::util
|
||||
DRAMSys::config
|
||||
)
|
||||
|
||||
set(DRAMSYS_TRACE_ANALYZER_EXTENSION_DIR "${CMAKE_SOURCE_DIR}/extensions/apps/traceAnalyzer")
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
DRAMSYS_TRACE_ANALYZER_EXTENSION_DIR="${DRAMSYS_TRACE_ANALYZER_EXTENSION_DIR}"
|
||||
)
|
||||
|
||||
build_source_group()
|
||||
@@ -36,8 +36,11 @@
|
||||
#ifndef CONFIGMODELS_H
|
||||
#define CONFIGMODELS_H
|
||||
|
||||
#include "../data/tracedb.h"
|
||||
#include "phases/dependencyinfos.h"
|
||||
#include "data/tracedb.h"
|
||||
|
||||
#ifdef EXTENSION_ENABLED
|
||||
#include "businessObjects/phases/dependencyinfos.h"
|
||||
#endif
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <utility>
|
||||
@@ -217,6 +217,7 @@ void Phase::drawPhaseDependencies(traceTime begin,
|
||||
QPoint depLineTo(static_cast<int>(xMap.transform(begin /* + (end + offset - begin)/4*/)),
|
||||
static_cast<int>(yVal));
|
||||
|
||||
#ifdef EXTENSION_ENABLED
|
||||
for (const auto& dep : mDependencies)
|
||||
{
|
||||
if (dep->isVisible())
|
||||
@@ -231,6 +232,7 @@ void Phase::drawPhaseDependencies(traceTime begin,
|
||||
invisibleDeps += 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (invisibleDeps > 0)
|
||||
{
|
||||
@@ -418,7 +420,9 @@ Phase::PhaseSymbol Phase::getPhaseSymbol() const
|
||||
return PhaseSymbol::Hexagon;
|
||||
}
|
||||
|
||||
#ifdef EXTENSION_ENABLED
|
||||
void Phase::addDependency(const std::shared_ptr<PhaseDependency>& dependency)
|
||||
{
|
||||
mDependencies.push_back(dependency);
|
||||
}
|
||||
#endif
|
||||
@@ -39,7 +39,11 @@
|
||||
|
||||
#ifndef BANKPHASE_H
|
||||
#define BANKPHASE_H
|
||||
|
||||
#ifdef EXTENSION_ENABLED
|
||||
#include "businessObjects/phases/phasedependency.h"
|
||||
#endif
|
||||
|
||||
#include "businessObjects/timespan.h"
|
||||
#include "presentation/tracedrawingproperties.h"
|
||||
#include "presentation/util/colorgenerator.h"
|
||||
@@ -141,7 +145,9 @@ public:
|
||||
|
||||
virtual QString Name() const = 0;
|
||||
|
||||
#ifdef EXTENSION_ENABLED
|
||||
void addDependency(const std::shared_ptr<PhaseDependency>& dependency);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
ID id;
|
||||
@@ -152,7 +158,9 @@ protected:
|
||||
traceTime clk;
|
||||
std::weak_ptr<Transaction> transaction;
|
||||
std::vector<Timespan> spansOnCommandBus;
|
||||
#ifdef EXTENSION_ENABLED
|
||||
std::vector<std::shared_ptr<PhaseDependency>> mDependencies;
|
||||
#endif
|
||||
|
||||
double hexagonHeight;
|
||||
TextPositioning captionPosition;
|
||||
@@ -167,6 +167,7 @@ bool TraceDB::checkDependencyTableExists()
|
||||
return exists;
|
||||
}
|
||||
|
||||
#ifdef EXTENSION_ENABLED
|
||||
void TraceDB::updateDependenciesInTimespan(const Timespan& span)
|
||||
{
|
||||
if (checkDependencyTableExists())
|
||||
@@ -177,6 +178,7 @@ void TraceDB::updateDependenciesInTimespan(const Timespan& span)
|
||||
mUpdateDependenciesFromQuery(selectDependenciesByTimespan);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO Remove exception
|
||||
std::shared_ptr<Transaction> TraceDB::getTransactionByID(ID id)
|
||||
@@ -498,6 +500,7 @@ std::vector<CommentModel::Comment> TraceDB::getDebugMessagesInTimespan(const Tim
|
||||
return parseCommentsFromQuery(selectDebugMessagesByTimespanWithLimit);
|
||||
}
|
||||
|
||||
#ifdef EXTENSION_ENABLED
|
||||
DependencyInfos TraceDB::getDependencyInfos(DependencyInfos::Type infoType)
|
||||
{
|
||||
DependencyInfos dummy;
|
||||
@@ -551,6 +554,7 @@ DependencyInfos TraceDB::getDependencyInfos(DependencyInfos::Type infoType)
|
||||
|
||||
return dummy;
|
||||
}
|
||||
#endif
|
||||
|
||||
QSqlDatabase TraceDB::getDatabase() const
|
||||
{
|
||||
@@ -643,6 +647,7 @@ TraceDB::parseTransactionsFromQuery(QSqlQuery& query, bool updateVisiblePhases)
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef EXTENSION_ENABLED
|
||||
void TraceDB::mUpdateDependenciesFromQuery(QSqlQuery& query)
|
||||
{
|
||||
DependencyType type;
|
||||
@@ -689,6 +694,7 @@ void TraceDB::mUpdateDependenciesFromQuery(QSqlQuery& query)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
std::vector<CommentModel::Comment> TraceDB::parseCommentsFromQuery(QSqlQuery& query)
|
||||
{
|
||||
@@ -701,6 +707,7 @@ std::vector<CommentModel::Comment> TraceDB::parseCommentsFromQuery(QSqlQuery& qu
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef EXTENSION_ENABLED
|
||||
DependencyInfos TraceDB::parseDependencyInfos(QSqlQuery& query,
|
||||
const DependencyInfos::Type infoType)
|
||||
{
|
||||
@@ -715,6 +722,7 @@ DependencyInfos TraceDB::parseDependencyInfos(QSqlQuery& query,
|
||||
|
||||
return infos;
|
||||
}
|
||||
#endif
|
||||
|
||||
void TraceDB::executeQuery(QSqlQuery query)
|
||||
{
|
||||
@@ -41,10 +41,14 @@
|
||||
#define TRACEDB_H
|
||||
|
||||
#include "QueryTexts.h"
|
||||
|
||||
#ifdef EXTENSION_ENABLED
|
||||
#include "businessObjects/phases/dependencyinfos.h"
|
||||
#endif
|
||||
|
||||
#include "businessObjects/commandlengths.h"
|
||||
#include "businessObjects/commentmodel.h"
|
||||
#include "businessObjects/generalinfo.h"
|
||||
#include "businessObjects/phases/dependencyinfos.h"
|
||||
#include "businessObjects/phases/phasefactory.h"
|
||||
#include "businessObjects/transaction.h"
|
||||
#include <QSqlDatabase>
|
||||
@@ -69,11 +73,13 @@ public:
|
||||
|
||||
void updateComments(const std::vector<CommentModel::Comment>& comments);
|
||||
void updateFileDescription(const QString& description);
|
||||
void updateDependenciesInTimespan(const Timespan& span);
|
||||
void refreshData();
|
||||
|
||||
const GeneralInfo& getGeneralInfo() const { return generalInfo; }
|
||||
#ifdef EXTENSION_ENABLED
|
||||
void updateDependenciesInTimespan(const Timespan& span);
|
||||
#endif
|
||||
|
||||
const GeneralInfo& getGeneralInfo() const { return generalInfo; }
|
||||
const CommandLengths& getCommandLengths() const { return commandLengths; }
|
||||
|
||||
std::vector<std::shared_ptr<Transaction>>
|
||||
@@ -97,8 +103,9 @@ public:
|
||||
unsigned int limit);
|
||||
|
||||
bool checkDependencyTableExists();
|
||||
#ifdef EXTENSION_ENABLED
|
||||
DependencyInfos getDependencyInfos(DependencyInfos::Type infoType);
|
||||
|
||||
#endif
|
||||
QSqlDatabase getDatabase() const;
|
||||
|
||||
private:
|
||||
@@ -129,9 +136,11 @@ private:
|
||||
parseTransactionsFromQuery(QSqlQuery& query, bool updateVisiblePhases = false);
|
||||
static std::vector<CommentModel::Comment> parseCommentsFromQuery(QSqlQuery& query);
|
||||
|
||||
#ifdef EXTENSION_ENABLED
|
||||
void mUpdateDependenciesFromQuery(QSqlQuery& query);
|
||||
static DependencyInfos parseDependencyInfos(QSqlQuery& query,
|
||||
const DependencyInfos::Type infoType);
|
||||
#endif
|
||||
|
||||
void executeScriptFile(const QString& fileName);
|
||||
void dropAndCreateTables();
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, RPTU Kaiserslautern-Landau
|
||||
* Copyright (c) 2024, RPTU Kaiserslautern-Landau
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -33,70 +33,32 @@
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#ifndef SIMULATIONDIALOG_H
|
||||
#define SIMULATIONDIALOG_H
|
||||
#ifndef EXTENSION_H
|
||||
#define EXTENSION_H
|
||||
|
||||
#include "ui_simulationdialog.h"
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "DRAMSys/config/DRAMSysConfiguration.h"
|
||||
inline constexpr std::string_view EXTENSION_DISCLAIMER =
|
||||
"This feature is part of the full version of Trace Analyzer. For more information, please "
|
||||
"contact <a href=\"mailto:DRAMSys@iese.fraunhofer.de\">DRAMSys@iese.fraunhofer.de</a>.";
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QPointer>
|
||||
#include <QProcess>
|
||||
#include <QSyntaxHighlighter>
|
||||
#include <QTemporaryFile>
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui
|
||||
inline void showExtensionDisclaimerMessageBox()
|
||||
{
|
||||
class SimulationDialog;
|
||||
QMessageBox box;
|
||||
box.setText("Feature unavailable");
|
||||
box.setInformativeText(EXTENSION_DISCLAIMER.data());
|
||||
box.setIcon(QMessageBox::Information);
|
||||
box.exec();
|
||||
}
|
||||
|
||||
class SimulationDialog : public QWidget
|
||||
inline QLabel* disclaimerLabel()
|
||||
{
|
||||
Q_OBJECT
|
||||
auto* label = new QLabel;
|
||||
label->setText(EXTENSION_DISCLAIMER.data());
|
||||
label->setAlignment(Qt::AlignHCenter);
|
||||
label->setWordWrap(true);
|
||||
return label;
|
||||
}
|
||||
|
||||
public:
|
||||
explicit SimulationDialog(QWidget* parent = nullptr);
|
||||
|
||||
signals:
|
||||
void openFileRequested(const QString& path);
|
||||
|
||||
private Q_SLOTS:
|
||||
void on_browseDramSysButton_clicked();
|
||||
void on_browseConfigButton_clicked();
|
||||
void on_browseOutputButton_clicked();
|
||||
void on_browseResourceDirButton_clicked();
|
||||
void on_simulateButton_clicked();
|
||||
void on_reloadButton_clicked();
|
||||
void on_saveButton_clicked();
|
||||
void on_stopButton_clicked();
|
||||
|
||||
private:
|
||||
void loadConfigurationFromPath();
|
||||
void loadConfigurationFromTextFields();
|
||||
|
||||
void loadConfiguration();
|
||||
void loadSimConfig();
|
||||
void loadMcConfig();
|
||||
void loadMemSpec();
|
||||
void loadAddressMapping();
|
||||
void loadTraceSetup();
|
||||
void loadPreview();
|
||||
|
||||
void showStopButton(bool val);
|
||||
void saveConfiguration(QFile& file);
|
||||
void processMessage(const std::string& msg);
|
||||
|
||||
QFileInfoList getSimulationResults();
|
||||
void openSimulationResults(const QFileInfoList& fileInfos);
|
||||
|
||||
QTemporaryFile temporaryConfigurationFile;
|
||||
DRAMSys::Config::Configuration configuration;
|
||||
|
||||
QPointer<QProcess> simulatorProcess;
|
||||
|
||||
Ui::SimulationDialog* ui;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // EXTENSION_H
|
||||
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
@@ -33,6 +33,7 @@
|
||||
* Janik Schlemminger
|
||||
* Robert Gernhardt
|
||||
* Matthias Jung
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#include "traceanalyzer.h"
|
||||
@@ -48,16 +49,15 @@
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
std::cout << argv[0] << std::endl;
|
||||
QApplication a(argc, argv);
|
||||
|
||||
QIcon icon(QStringLiteral(":/icon"));
|
||||
a.setWindowIcon(icon);
|
||||
a.setApplicationName(QStringLiteral("TraceAnalyzer"));
|
||||
a.setApplicationDisplayName(QStringLiteral("Trace Analyzer"));
|
||||
QApplication::setWindowIcon(icon);
|
||||
QApplication::setApplicationName(QStringLiteral("TraceAnalyzer"));
|
||||
QApplication::setApplicationDisplayName(QStringLiteral("Trace Analyzer"));
|
||||
|
||||
std::filesystem::path traceAnalyzerDir = DRAMSYS_TRACEANALYZER_DIR;
|
||||
std::filesystem::path modulesDir = traceAnalyzerDir / "scripts";
|
||||
std::filesystem::path extensionDir = DRAMSYS_TRACE_ANALYZER_EXTENSION_DIR;
|
||||
std::filesystem::path modulesDir = extensionDir / "scripts";
|
||||
|
||||
pybind11::scoped_interpreter guard;
|
||||
|
||||
@@ -92,12 +92,10 @@ int main(int argc, char* argv[])
|
||||
|
||||
TraceAnalyzer analyzer(arguments);
|
||||
analyzer.show();
|
||||
return a.exec();
|
||||
}
|
||||
else
|
||||
{
|
||||
TraceAnalyzer analyzer;
|
||||
analyzer.show();
|
||||
return a.exec();
|
||||
return QApplication::exec();
|
||||
}
|
||||
|
||||
TraceAnalyzer analyzer;
|
||||
analyzer.show();
|
||||
return QApplication::exec();
|
||||
}
|
||||
@@ -286,6 +286,11 @@ void TracePlot::setUpActions()
|
||||
dependenciesGroup->addAction(disabledDependencies);
|
||||
dependenciesGroup->addAction(selectedDependencies);
|
||||
dependenciesGroup->addAction(allDependencies);
|
||||
dependenciesGroup->addAction(switchDrawDependencyTextsOption);
|
||||
|
||||
#ifndef EXTENSION_ENABLED
|
||||
dependenciesGroup->setEnabled(false);
|
||||
#endif
|
||||
|
||||
setUpContextMenu();
|
||||
}
|
||||
@@ -628,10 +633,13 @@ void TracePlot::currentTraceTimeChanged()
|
||||
|
||||
transactions =
|
||||
navigator->TraceFile().getTransactionsInTimespan(GetCurrentTimespan(), drawDependencies);
|
||||
|
||||
#ifdef EXTENSION_ENABLED
|
||||
if (drawDependencies)
|
||||
{
|
||||
navigator->TraceFile().updateDependenciesInTimespan(GetCurrentTimespan());
|
||||
}
|
||||
#endif
|
||||
|
||||
setAxisScale(xBottom, GetCurrentTimespan().Begin(), GetCurrentTimespan().End());
|
||||
|
||||
@@ -220,10 +220,12 @@ void TraceScroller::currentTraceTimeChanged()
|
||||
Timespan span = GetCurrentTimespan();
|
||||
transactions = navigator->TraceFile().getTransactionsInTimespan(span, drawDependencies);
|
||||
|
||||
#ifdef EXTENSION_ENABLED
|
||||
if (drawDependencies)
|
||||
{
|
||||
navigator->TraceFile().updateDependenciesInTimespan(span);
|
||||
}
|
||||
#endif
|
||||
|
||||
setAxisScale(xBottom, span.Begin(), span.End());
|
||||
replot();
|
||||
@@ -37,7 +37,7 @@
|
||||
*/
|
||||
|
||||
#include "traceanalyzer.h"
|
||||
#include "simulationdialog.h"
|
||||
#include "extensionDisclaimer.h"
|
||||
#include "tracefiletab.h"
|
||||
#include "ui_traceanalyzer.h"
|
||||
|
||||
@@ -53,7 +53,10 @@ void TraceAnalyzer::setUpStatusBar()
|
||||
statusBar()->addWidget(statusLabel);
|
||||
}
|
||||
|
||||
void TraceAnalyzer::setUpGui()
|
||||
TraceAnalyzer::TraceAnalyzer(QWidget* parent) :
|
||||
QMainWindow(parent),
|
||||
evaluationTool(pythonCaller),
|
||||
ui(new Ui::TraceAnalyzer)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setUpStatusBar();
|
||||
@@ -62,21 +65,8 @@ void TraceAnalyzer::setUpGui()
|
||||
QObject::connect(ui->actionAbout_Qt, &QAction::triggered, qApp, &QApplication::aboutQt);
|
||||
}
|
||||
|
||||
TraceAnalyzer::TraceAnalyzer(QWidget* parent) :
|
||||
QMainWindow(parent),
|
||||
evaluationTool(pythonCaller),
|
||||
ui(new Ui::TraceAnalyzer)
|
||||
TraceAnalyzer::TraceAnalyzer(QSet<QString> paths, QWidget* parent) : TraceAnalyzer(parent)
|
||||
{
|
||||
setUpGui();
|
||||
}
|
||||
|
||||
TraceAnalyzer::TraceAnalyzer(QSet<QString> paths, QWidget* parent) :
|
||||
QMainWindow(parent),
|
||||
evaluationTool(pythonCaller),
|
||||
ui(new Ui::TraceAnalyzer)
|
||||
{
|
||||
setUpGui();
|
||||
|
||||
for (const QString& path : paths)
|
||||
openTracefileTab(path);
|
||||
}
|
||||
@@ -99,7 +89,7 @@ void TraceAnalyzer::on_actionOpen_triggered()
|
||||
|
||||
TraceFileTab* TraceAnalyzer::createTraceFileTab(const QString& path)
|
||||
{
|
||||
TraceFileTab* traceFileTab = new TraceFileTab(path.toStdString(), pythonCaller, this);
|
||||
auto* traceFileTab = new TraceFileTab(path.toStdString(), pythonCaller, this);
|
||||
|
||||
connect(traceFileTab, &TraceFileTab::statusChanged, this, &TraceAnalyzer::statusChanged);
|
||||
|
||||
@@ -131,7 +121,6 @@ void TraceAnalyzer::on_menuFile_aboutToShow()
|
||||
ui->actionReload->setEnabled(tabsOpen);
|
||||
ui->actionReload_all->setEnabled(tabsOpen);
|
||||
ui->actionExportAsVCD->setEnabled(tabsOpen);
|
||||
ui->actionTest->setEnabled(tabsOpen);
|
||||
ui->actionMetrics->setEnabled(tabsOpen);
|
||||
ui->actionClose->setEnabled(tabsOpen);
|
||||
ui->actionClose_all->setEnabled(tabsOpen);
|
||||
@@ -139,7 +128,7 @@ void TraceAnalyzer::on_menuFile_aboutToShow()
|
||||
|
||||
void TraceAnalyzer::closeTab(int index)
|
||||
{
|
||||
TraceFileTab* traceFileTab = static_cast<TraceFileTab*>(ui->traceFileTabs->widget(index));
|
||||
auto* traceFileTab = dynamic_cast<TraceFileTab*>(ui->traceFileTabs->widget(index));
|
||||
|
||||
if (traceFileTab->close())
|
||||
{
|
||||
@@ -169,7 +158,7 @@ void TraceAnalyzer::on_actionClose_all_triggered()
|
||||
|
||||
void TraceAnalyzer::reloadTab(int index)
|
||||
{
|
||||
auto traceFileTab = static_cast<TraceFileTab*>(ui->traceFileTabs->widget(index));
|
||||
auto* traceFileTab = dynamic_cast<TraceFileTab*>(ui->traceFileTabs->widget(index));
|
||||
|
||||
QString traceFile = traceFileTab->getPathToTraceFile();
|
||||
traceTime time = traceFileTab->getCurrentTraceTime();
|
||||
@@ -212,7 +201,7 @@ void TraceAnalyzer::on_actionReload_all_triggered()
|
||||
|
||||
void TraceAnalyzer::on_actionSave_triggered()
|
||||
{
|
||||
auto traceFileTab = static_cast<TraceFileTab*>(ui->traceFileTabs->currentWidget());
|
||||
auto* traceFileTab = dynamic_cast<TraceFileTab*>(ui->traceFileTabs->currentWidget());
|
||||
traceFileTab->commitChangesToDB();
|
||||
|
||||
this->statusChanged(QString("Saved database ") +
|
||||
@@ -226,14 +215,19 @@ void TraceAnalyzer::on_actionSave_all_triggered()
|
||||
// Changes in the database files will trigger the file watchers from
|
||||
// the TraceFileTab class. They generate signals connected to
|
||||
// TraceAnalyzer::statusChanged().
|
||||
TraceFileTab* traceFileTab = static_cast<TraceFileTab*>(ui->traceFileTabs->widget(index));
|
||||
auto* traceFileTab = dynamic_cast<TraceFileTab*>(ui->traceFileTabs->widget(index));
|
||||
traceFileTab->commitChangesToDB();
|
||||
}
|
||||
}
|
||||
|
||||
void TraceAnalyzer::on_actionExportAsVCD_triggered()
|
||||
{
|
||||
TraceFileTab* traceFileTab = static_cast<TraceFileTab*>(ui->traceFileTabs->currentWidget());
|
||||
#ifndef EXTENSION_ENABLED
|
||||
showExtensionDisclaimerMessageBox();
|
||||
return;
|
||||
#endif
|
||||
|
||||
auto* traceFileTab = dynamic_cast<TraceFileTab*>(ui->traceFileTabs->currentWidget());
|
||||
traceFileTab->exportAsVCD();
|
||||
}
|
||||
|
||||
@@ -244,6 +238,11 @@ void TraceAnalyzer::statusChanged(const QString& message)
|
||||
|
||||
void TraceAnalyzer::on_actionMetrics_triggered()
|
||||
{
|
||||
#ifndef EXTENSION_ENABLED
|
||||
showExtensionDisclaimerMessageBox();
|
||||
return;
|
||||
#endif
|
||||
|
||||
evaluationTool.raise();
|
||||
evaluationTool.activateWindow();
|
||||
evaluationTool.showAndEvaluateMetrics(openedTraceFiles.values());
|
||||
@@ -254,12 +253,15 @@ void TraceAnalyzer::on_actionAbout_triggered()
|
||||
QMessageBox::about(
|
||||
this,
|
||||
QStringLiteral("DRAMSys"),
|
||||
QStringLiteral("<b>DRAMSys4.0</b> is a flexible DRAM subsystem design space exploration "
|
||||
"framework based on SystemC "
|
||||
"TLM-2.0. It was developed at the <a "
|
||||
"href=\"https://ems.eit.uni-kl.de/en/start/\">Microelectronic Systems "
|
||||
"Design Research Group</a> and <a "
|
||||
"href=\"https://www.iese.fraunhofer.de/en.html\">Fraunhofer IESE</a>."));
|
||||
QStringLiteral(
|
||||
"<b>DRAMSys4.0</b> is a flexible DRAM subsystem design space exploration "
|
||||
"framework based on SystemC "
|
||||
"TLM-2.0. It was developed by the <a "
|
||||
"href=\"https://ems.eit.uni-kl.de/en/start/\">Microelectronic Systems "
|
||||
"Design Research Group</a>, by <a "
|
||||
"href=\"https://www.iese.fraunhofer.de/en.html\">Fraunhofer IESE</a> and by the <a "
|
||||
"href=\"https://www.informatik.uni-wuerzburg.de/ce\">Computer Engineering Group</a> at "
|
||||
"<a href=\"https://www.uni-wuerzburg.de/en/home\">JMU Würzburg</a>."));
|
||||
}
|
||||
|
||||
void TraceAnalyzer::closeEvent(QCloseEvent* event)
|
||||
@@ -276,16 +278,3 @@ void TraceAnalyzer::closeEvent(QCloseEvent* event)
|
||||
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void TraceAnalyzer::on_actionSimulate_triggered()
|
||||
{
|
||||
SimulationDialog* simulationDialog = new SimulationDialog(this);
|
||||
simulationDialog->setWindowFlag(Qt::Window);
|
||||
|
||||
QObject::connect(simulationDialog,
|
||||
&SimulationDialog::openFileRequested,
|
||||
this,
|
||||
&TraceAnalyzer::openTracefileTab);
|
||||
|
||||
simulationDialog->show();
|
||||
}
|
||||
@@ -63,7 +63,6 @@ public:
|
||||
~TraceAnalyzer();
|
||||
|
||||
void setUpStatusBar();
|
||||
void setUpGui();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent* event) override;
|
||||
@@ -93,7 +92,6 @@ private Q_SLOTS:
|
||||
void on_actionClose_triggered();
|
||||
void on_actionClose_all_triggered();
|
||||
void on_actionAbout_triggered();
|
||||
void on_actionSimulate_triggered();
|
||||
|
||||
public Q_SLOTS:
|
||||
void statusChanged(const QString& message);
|
||||
@@ -49,7 +49,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>34</height>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
@@ -78,14 +78,7 @@
|
||||
<addaction name="actionAbout"/>
|
||||
<addaction name="actionAbout_Qt"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuRun">
|
||||
<property name="title">
|
||||
<string>&Run</string>
|
||||
</property>
|
||||
<addaction name="actionSimulate"/>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
<addaction name="menuRun"/>
|
||||
<addaction name="menuHelp"/>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
@@ -133,32 +126,11 @@
|
||||
<string>Ctrl+Shift+W</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionInfo">
|
||||
<property name="text">
|
||||
<string>&Info</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAbout">
|
||||
<property name="text">
|
||||
<string>&About DRAMSys</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPreferences">
|
||||
<property name="text">
|
||||
<string>Preferences</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+P</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionTest">
|
||||
<property name="text">
|
||||
<string>&Test</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+T</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionMetrics">
|
||||
<property name="text">
|
||||
<string>&Metrics</string>
|
||||
@@ -232,15 +204,6 @@
|
||||
<string>Save &as...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSimulate">
|
||||
<property name="icon">
|
||||
<iconset theme="system-run">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Simulate...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAbout_Qt">
|
||||
<property name="text">
|
||||
<string>About &Qt</string>
|
||||
364
src/traceAnalyzer/tracefiletab.cpp
Normal file
364
src/traceAnalyzer/tracefiletab.cpp
Normal file
@@ -0,0 +1,364 @@
|
||||
/*
|
||||
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Janik Schlemminger
|
||||
* Robert Gernhardt
|
||||
* Matthias Jung
|
||||
* Derek Christ
|
||||
* Iron Prando da Silva
|
||||
*/
|
||||
|
||||
#include "tracefiletab.h"
|
||||
#include "businessObjects/pythoncaller.h"
|
||||
#include "extensionDisclaimer.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QFileInfo>
|
||||
#include <QMessageBox>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include <qwt_plot_canvas.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
TraceFileTab::TraceFileTab(std::string_view traceFilePath,
|
||||
PythonCaller& pythonCaller,
|
||||
QWidget* parent) :
|
||||
QWidget(parent),
|
||||
traceFilePath(traceFilePath),
|
||||
ui(new Ui::TraceFileTab),
|
||||
commentModel(new CommentModel(this)),
|
||||
navigator(new TraceNavigator(traceFilePath.data(), commentModel, this)),
|
||||
mcConfigModel(new McConfigModel(navigator->TraceFile(), this)),
|
||||
memSpecModel(new MemSpecModel(navigator->TraceFile(), this)),
|
||||
availableRowsModel(new AvailableTracePlotLineModel(navigator->GeneralTraceInfo(), this)),
|
||||
selectedRowsModel(new SelectedTracePlotLineModel(navigator->GeneralTraceInfo(), this)),
|
||||
tracePlotLineDataSource(new TracePlotLineDataSource(selectedRowsModel, this)),
|
||||
#ifdef EXTENSION_ENABLED
|
||||
depInfosView(new DependencyInfosModel(navigator->TraceFile(), this)),
|
||||
#endif
|
||||
pythonCaller(pythonCaller),
|
||||
savingChangesToDB(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
std::cout << "Opening new tab for \"" << traceFilePath << "\"" << std::endl;
|
||||
|
||||
ui->mcConfigView->setModel(mcConfigModel);
|
||||
ui->mcConfigView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||
|
||||
ui->memSpecView->setModel(memSpecModel);
|
||||
ui->memSpecView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||
|
||||
#ifdef EXTENSION_ENABLED
|
||||
ui->depInfosView->setModel(depInfosView);
|
||||
ui->depInfosView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||
#endif
|
||||
|
||||
setUpTraceSelector();
|
||||
initNavigatorAndItsDependentWidgets();
|
||||
setUpFileWatcher(traceFilePath.data());
|
||||
setUpTraceplotScrollbar();
|
||||
setUpCommentView();
|
||||
|
||||
#ifdef EXTENSION_ENABLED
|
||||
setUpPossiblePhases();
|
||||
#else
|
||||
addDisclaimer();
|
||||
#endif
|
||||
|
||||
tracefileChanged();
|
||||
}
|
||||
|
||||
TraceFileTab::~TraceFileTab()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void TraceFileTab::commitChangesToDB()
|
||||
{
|
||||
savingChangesToDB = true;
|
||||
navigator->commitChangesToDB();
|
||||
}
|
||||
|
||||
void TraceFileTab::exportAsVCD()
|
||||
{
|
||||
std::string filename =
|
||||
QFileDialog::getSaveFileName(this, "Export to VCD", "", "VCD files (*.vcd)").toStdString();
|
||||
|
||||
auto dump = PythonCaller::dumpVcd(traceFilePath);
|
||||
|
||||
std::ofstream file(filename);
|
||||
file << dump;
|
||||
|
||||
Q_EMIT statusChanged(QString("VCD export finished."));
|
||||
}
|
||||
|
||||
void TraceFileTab::setUpTraceSelector()
|
||||
{
|
||||
ui->availableTreeView->setModel(availableRowsModel);
|
||||
ui->availableTreeView->setSelectionModel(availableRowsModel->selectionModel());
|
||||
ui->availableTreeView->installEventFilter(availableRowsModel);
|
||||
|
||||
ui->selectedTreeView->setModel(selectedRowsModel);
|
||||
ui->selectedTreeView->setSelectionModel(selectedRowsModel->selectionModel());
|
||||
ui->selectedTreeView->installEventFilter(selectedRowsModel);
|
||||
|
||||
connect(availableRowsModel,
|
||||
&AvailableTracePlotLineModel::returnPressed,
|
||||
selectedRowsModel,
|
||||
&SelectedTracePlotLineModel::addIndexesFromAvailableModel);
|
||||
|
||||
connect(ui->availableTreeView,
|
||||
&QAbstractItemView::doubleClicked,
|
||||
availableRowsModel,
|
||||
&AvailableTracePlotLineModel::itemsDoubleClicked);
|
||||
connect(ui->selectedTreeView,
|
||||
&QAbstractItemView::doubleClicked,
|
||||
selectedRowsModel,
|
||||
&SelectedTracePlotLineModel::itemsDoubleClicked);
|
||||
|
||||
connect(selectedRowsModel,
|
||||
&QAbstractItemModel::dataChanged,
|
||||
tracePlotLineDataSource,
|
||||
&TracePlotLineDataSource::updateModel);
|
||||
connect(selectedRowsModel,
|
||||
&QAbstractItemModel::rowsInserted,
|
||||
tracePlotLineDataSource,
|
||||
&TracePlotLineDataSource::updateModel);
|
||||
connect(selectedRowsModel,
|
||||
&QAbstractItemModel::rowsRemoved,
|
||||
tracePlotLineDataSource,
|
||||
&TracePlotLineDataSource::updateModel);
|
||||
}
|
||||
|
||||
void TraceFileTab::setUpTraceplotScrollbar()
|
||||
{
|
||||
QObject::connect(ui->traceplotScrollbar,
|
||||
SIGNAL(valueChanged(int)),
|
||||
ui->traceplot,
|
||||
SLOT(verticalScrollbarChanged(int)));
|
||||
}
|
||||
|
||||
void TraceFileTab::initNavigatorAndItsDependentWidgets()
|
||||
{
|
||||
ui->traceplot->init(navigator, ui->traceplotScrollbar, tracePlotLineDataSource, commentModel);
|
||||
|
||||
ui->traceScroller->init(navigator, ui->traceplot, tracePlotLineDataSource);
|
||||
connect(this,
|
||||
SIGNAL(colorGroupingChanged(ColorGrouping)),
|
||||
ui->traceScroller,
|
||||
SLOT(colorGroupingChanged(ColorGrouping)));
|
||||
|
||||
ui->selectedTransactionTree->init(navigator);
|
||||
// ui->debugMessages->init(navigator,ui->traceplot);
|
||||
|
||||
ui->bandwidthPlot->canvas()->installEventFilter(this);
|
||||
ui->powerPlot->canvas()->installEventFilter(this);
|
||||
ui->bufferPlot->canvas()->installEventFilter(this);
|
||||
}
|
||||
|
||||
void TraceFileTab::setUpFileWatcher(QString path)
|
||||
{
|
||||
fileWatcher = new QFileSystemWatcher(QStringList(path), this);
|
||||
QObject::connect(fileWatcher, SIGNAL(fileChanged(QString)), this, SLOT(tracefileChanged()));
|
||||
}
|
||||
|
||||
void TraceFileTab::setUpCommentView()
|
||||
{
|
||||
ui->commentView->setModel(commentModel);
|
||||
ui->commentView->setSelectionModel(commentModel->selectionModel());
|
||||
ui->commentView->installEventFilter(commentModel);
|
||||
ui->commentView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
|
||||
QObject::connect(ui->commentView,
|
||||
&QTableView::customContextMenuRequested,
|
||||
commentModel,
|
||||
&CommentModel::openContextMenu);
|
||||
|
||||
QObject::connect(commentModel,
|
||||
&CommentModel::editTriggered,
|
||||
ui->commentView,
|
||||
[=](const QModelIndex& index)
|
||||
{
|
||||
ui->tabWidget->setCurrentWidget(ui->tabComments);
|
||||
ui->commentView->edit(index);
|
||||
ui->commentView->scrollTo(index);
|
||||
});
|
||||
|
||||
QObject::connect(
|
||||
ui->commentView, &QTableView::doubleClicked, commentModel, &CommentModel::rowDoubleClicked);
|
||||
}
|
||||
|
||||
void TraceFileTab::addDisclaimer()
|
||||
{
|
||||
// Latency analysis
|
||||
auto* latencyDisclaimerLabel = disclaimerLabel();
|
||||
ui->latencyLayout->insertWidget(0, latencyDisclaimerLabel);
|
||||
|
||||
ui->latencyAnalysisProgressBar->setEnabled(false);
|
||||
ui->startLatencyAnalysis->setEnabled(false);
|
||||
ui->latencyPlot->setEnabled(false);
|
||||
ui->latencyTreeView->setEnabled(false);
|
||||
|
||||
// Power analysis
|
||||
auto* powerDisclaimerLabel = disclaimerLabel();
|
||||
ui->powerLayout->insertWidget(0, powerDisclaimerLabel);
|
||||
|
||||
ui->startPowerAnalysis->setEnabled(false);
|
||||
ui->powerBox->setEnabled(false);
|
||||
ui->bandwidthBox->setEnabled(false);
|
||||
ui->bufferBox->setEnabled(false);
|
||||
|
||||
// Dependencies
|
||||
auto* dependenciesDisclaimerLabel = disclaimerLabel();
|
||||
ui->verticalLayout_depInfos->insertWidget(0, dependenciesDisclaimerLabel);
|
||||
|
||||
ui->depInfoLabel->setEnabled(false);
|
||||
ui->depInfosView->setEnabled(false);
|
||||
ui->depTabPossiblePhases->setEnabled(false);
|
||||
ui->calculateDependencies->setEnabled(false);
|
||||
}
|
||||
|
||||
void TraceFileTab::tracefileChanged()
|
||||
{
|
||||
if (savingChangesToDB == true)
|
||||
{
|
||||
// Database has changed due to user action (e.g., saving comments).
|
||||
// No need to disable the "Save changes to DB" menu.
|
||||
savingChangesToDB = false;
|
||||
Q_EMIT statusChanged(QString("Changes saved "));
|
||||
}
|
||||
else
|
||||
{
|
||||
// External event changed the database file (e.g., the database file
|
||||
// was overwritten when running a new test).
|
||||
// The "Save changes to DB" menu must be disabled to avoid saving
|
||||
// changes to a corrupted or inconsistent file.
|
||||
Q_EMIT statusChanged(QString("At least one database has changed on disk "));
|
||||
}
|
||||
navigator->refreshData();
|
||||
}
|
||||
|
||||
void TraceFileTab::closeEvent(QCloseEvent* event)
|
||||
{
|
||||
if (navigator->existChangesToCommit())
|
||||
{
|
||||
QMessageBox saveDialog;
|
||||
saveDialog.setWindowTitle(QFileInfo(traceFilePath.data()).baseName());
|
||||
saveDialog.setText("The trace file has been modified.");
|
||||
saveDialog.setInformativeText(
|
||||
"Do you want to save your changes?<br><b>Unsaved changes will be lost.</b>");
|
||||
saveDialog.setStandardButtons(QMessageBox::Save | QMessageBox::Discard |
|
||||
QMessageBox::Cancel);
|
||||
saveDialog.setDefaultButton(QMessageBox::Save);
|
||||
saveDialog.setIcon(QMessageBox::Warning);
|
||||
int returnCode = saveDialog.exec();
|
||||
|
||||
switch (returnCode)
|
||||
{
|
||||
case QMessageBox::Cancel:
|
||||
event->ignore();
|
||||
break;
|
||||
case QMessageBox::Discard:
|
||||
event->accept();
|
||||
break;
|
||||
case QMessageBox::Save:
|
||||
commitChangesToDB();
|
||||
event->accept();
|
||||
break;
|
||||
};
|
||||
}
|
||||
else
|
||||
event->accept();
|
||||
}
|
||||
|
||||
traceTime TraceFileTab::getCurrentTraceTime() const
|
||||
{
|
||||
return navigator->CurrentTraceTime();
|
||||
}
|
||||
|
||||
void TraceFileTab::navigateToTime(traceTime time)
|
||||
{
|
||||
navigator->navigateToTime(time);
|
||||
}
|
||||
|
||||
traceTime TraceFileTab::getZoomLevel() const
|
||||
{
|
||||
TracePlot* traceplot = static_cast<TracePlot*>(ui->traceplot);
|
||||
return traceplot->ZoomLevel();
|
||||
}
|
||||
|
||||
void TraceFileTab::setZoomLevel(traceTime zoomLevel)
|
||||
{
|
||||
TracePlot* traceplot = static_cast<TracePlot*>(ui->traceplot);
|
||||
TraceScroller* tracescroller = static_cast<TraceScroller*>(ui->traceScroller);
|
||||
traceplot->setZoomLevel(zoomLevel);
|
||||
tracescroller->tracePlotZoomChanged();
|
||||
}
|
||||
|
||||
std::shared_ptr<AbstractTracePlotLineModel::Node> TraceFileTab::saveTraceSelectorState() const
|
||||
{
|
||||
return selectedRowsModel->getClonedRootNode();
|
||||
}
|
||||
|
||||
void TraceFileTab::restoreTraceSelectorState(
|
||||
std::shared_ptr<AbstractTracePlotLineModel::Node> rootNode)
|
||||
{
|
||||
selectedRowsModel->setRootNode(std::move(rootNode));
|
||||
}
|
||||
|
||||
bool TraceFileTab::eventFilter(QObject* object, QEvent* event)
|
||||
{
|
||||
if (auto canvas = qobject_cast<QwtPlotCanvas*>(object))
|
||||
{
|
||||
if (event->type() == QEvent::MouseButtonDblClick)
|
||||
{
|
||||
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
|
||||
if (mouseEvent->button() != Qt::LeftButton)
|
||||
return false;
|
||||
|
||||
QwtPlot* plot = canvas->plot();
|
||||
|
||||
double realTime = plot->invTransform(QwtPlot::xBottom, mouseEvent->x());
|
||||
|
||||
// Convert from seconds to picoseconds
|
||||
traceTime time = realTime * 1000 * 1000 * 1000 * 1000;
|
||||
|
||||
navigator->navigateToTime(time);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return QWidget::eventFilter(object, event);
|
||||
}
|
||||
@@ -40,13 +40,17 @@
|
||||
#ifndef TRACEFILETAB_H
|
||||
#define TRACEFILETAB_H
|
||||
|
||||
#include "ui_tracefiletab.h"
|
||||
|
||||
#include "businessObjects/configmodels.h"
|
||||
#ifdef EXTENSION_ENABLED
|
||||
#include "businessObjects/dependencymodels.h"
|
||||
#endif
|
||||
#include "businessObjects/traceplotlinemodel.h"
|
||||
#include "presentation/tracenavigator.h"
|
||||
#include "presentation/traceplot.h"
|
||||
#include "presentation/tracescroller.h"
|
||||
|
||||
#include "businessObjects/configmodels.h"
|
||||
#include "businessObjects/dependencymodels.h"
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QString>
|
||||
#include <QTreeWidget>
|
||||
@@ -57,11 +61,6 @@ class McConfigModel;
|
||||
class MemSpecModel;
|
||||
class PythonCaller;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class TraceFileTab;
|
||||
}
|
||||
|
||||
class TraceFileTab : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -76,11 +75,15 @@ public:
|
||||
void setUpTraceplotScrollbar();
|
||||
void setUpCommentView();
|
||||
void setUpTraceSelector();
|
||||
void addDisclaimer();
|
||||
|
||||
#ifdef EXTENSION_ENABLED
|
||||
void setUpPossiblePhases();
|
||||
#endif
|
||||
|
||||
void initNavigatorAndItsDependentWidgets();
|
||||
QString getPathToTraceFile() { return traceFilePath.data(); }
|
||||
void commitChangesToDB(void);
|
||||
void commitChangesToDB();
|
||||
void exportAsVCD();
|
||||
|
||||
traceTime getCurrentTraceTime() const;
|
||||
@@ -116,7 +119,9 @@ private:
|
||||
SelectedTracePlotLineModel* selectedRowsModel;
|
||||
TracePlotLineDataSource* tracePlotLineDataSource;
|
||||
|
||||
#ifdef EXTENSION_ENABLED
|
||||
QAbstractItemModel* depInfosView;
|
||||
#endif
|
||||
|
||||
PythonCaller& pythonCaller;
|
||||
|
||||
@@ -131,10 +136,12 @@ Q_SIGNALS:
|
||||
void colorGroupingChanged(ColorGrouping colorgrouping);
|
||||
|
||||
private Q_SLOTS:
|
||||
#ifdef EXTENSION_ENABLED
|
||||
void on_latencyTreeView_doubleClicked(const QModelIndex& index);
|
||||
void on_calculateDependencies_clicked();
|
||||
void on_startLatencyAnalysis_clicked();
|
||||
void on_startPowerAnalysis_clicked();
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // TRACEFILETAB_H
|
||||
@@ -261,33 +261,6 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
||||
<widget class="QWidget" name="tabDepInfos">
|
||||
<attribute name="title">
|
||||
<string>Dependency Information</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_depInfos">
|
||||
<item>
|
||||
<widget class="QTreeView" name="depInfosView">
|
||||
<property name="uniformRowHeights">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="depTabPossiblePhases">
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="calculateDependencies">
|
||||
<property name="text">
|
||||
<string>Calculate Dependencies</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
||||
<widget class="QWidget" name="tabComments">
|
||||
<attribute name="title">
|
||||
<string>Comments</string>
|
||||
@@ -317,7 +290,6 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
||||
<widget class="QWidget" name="tabLatencyAnalysis">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Ignored">
|
||||
@@ -330,7 +302,7 @@
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<layout class="QVBoxLayout" name="latencyLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="startLatencyAnalysis">
|
||||
<property name="text">
|
||||
@@ -366,7 +338,6 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
||||
<widget class="QWidget" name="tabPowerAnalysis">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
@@ -390,15 +361,15 @@
|
||||
<string>Power and Bandwidth Analysis</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="startPowerAnalysis">
|
||||
<property name="text">
|
||||
<string>Start Analysis</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item row="2" column="0">
|
||||
<layout class="QVBoxLayout" name="powerLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="startPowerAnalysis">
|
||||
<property name="text">
|
||||
<string>Start Analysis</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="powerBox">
|
||||
<property name="title">
|
||||
@@ -439,6 +410,43 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabDepInfos">
|
||||
<attribute name="title">
|
||||
<string>Dependency Information</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_depInfos">
|
||||
<item>
|
||||
<widget class="QLabel" name="depInfoLabel">
|
||||
<property name="text">
|
||||
<string>To display timing dependencies between transaction phases, select the respective phases and press "Calculate Dependencies". The dependencies can now be displayed in the trace view using the context menu.</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeView" name="depInfosView">
|
||||
<property name="uniformRowHeights">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="depTabPossiblePhases"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="calculateDependencies">
|
||||
<property name="text">
|
||||
<string>Calculate Dependencies</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
Reference in New Issue
Block a user