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 ###
|
### Build options ###
|
||||||
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
|
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_TESTS "Build DRAMSys unit tests" OFF)
|
||||||
option(DRAMSYS_BUILD_BENCHMARKS "Build DRAMSys benchmarks" 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_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_WITH_DRAMPOWER "Build with DRAMPower support enabled." OFF)
|
||||||
option(DRAMSYS_ENABLE_EXTENSIONS "Enable proprietary DRAMSys extensions." OFF)
|
option(DRAMSYS_ENABLE_EXTENSIONS "Enable proprietary DRAMSys extensions." OFF)
|
||||||
option(DRAMSYS_USE_EXTERNAL_SYSTEMC "Use an external SystemC installation." OFF)
|
option(DRAMSYS_USE_EXTERNAL_SYSTEMC "Use an external SystemC installation." OFF)
|
||||||
@@ -184,6 +185,10 @@ if(DRAMSYS_BUILD_CLI)
|
|||||||
add_subdirectory(src/simulator)
|
add_subdirectory(src/simulator)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(DRAMSYS_BUILD_TRACE_ANALYZER)
|
||||||
|
add_subdirectory(src/traceAnalyzer)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(DRAMSYS_ENABLE_EXTENSIONS)
|
if(DRAMSYS_ENABLE_EXTENSIONS)
|
||||||
dramsys_enable_extensions()
|
dramsys_enable_extensions()
|
||||||
endif()
|
endif()
|
||||||
@@ -202,6 +207,6 @@ endif()
|
|||||||
### Benchmark Directory ###
|
### Benchmark Directory ###
|
||||||
###############################################
|
###############################################
|
||||||
|
|
||||||
if(DRAMSYS_BUILD_BENCHMARKS)
|
if(DRAMSYS_BUILD_BENCHMARKS)
|
||||||
add_subdirectory(benches)
|
add_subdirectory(benches)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -6,12 +6,11 @@
|
|||||||
##############################################
|
##############################################
|
||||||
##############################################
|
##############################################
|
||||||
|
|
||||||
|
message(STATUS " Apps:")
|
||||||
|
|
||||||
##############################################
|
##############################################
|
||||||
### TraceAnalyzer ###
|
### TraceAnalyzer ###
|
||||||
##############################################
|
##############################################
|
||||||
|
IF(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/traceAnalyzer")
|
||||||
option(DRAMSYS_EXTENSION_TRACE_ANALYZER_ENABLE "Enable DRAMSys Trace Analyzer" ON)
|
|
||||||
if(DRAMSYS_EXTENSION_TRACE_ANALYZER_ENABLE)
|
|
||||||
message(STATUS " * Trace Analyzer")
|
|
||||||
add_subdirectory(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
|
option(DRAMSYS_EXTENSION_TRACE_ANALYZER_ENABLE "Enable Trace Analyzer extension" ON)
|
||||||
# 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
|
|
||||||
|
|
||||||
########################################
|
if(DRAMSYS_EXTENSION_TRACE_ANALYZER_ENABLE AND TARGET TraceAnalyzer)
|
||||||
### 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)
|
target_sources(TraceAnalyzer PRIVATE ${SOURCE_FILES} ${HEADER_FILES})
|
||||||
file(GLOB_RECURSE HEADER_FILES CONFIGURE_DEPENDS *.h;*.hpp)
|
target_include_directories(TraceAnalyzer PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
target_compile_definitions(TraceAnalyzer PRIVATE EXTENSION_ENABLED)
|
||||||
|
|
||||||
# Add Python3 Dependency:
|
build_source_group()
|
||||||
find_package(Python3 COMPONENTS Development Interpreter)
|
endif()
|
||||||
|
|
||||||
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()
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../data/tracedb.h"
|
#include "data/tracedb.h"
|
||||||
#include "phases/dependencyinfos.h"
|
#include "phases/dependencyinfos.h"
|
||||||
|
|
||||||
#include <QAbstractTableModel>
|
#include <QAbstractTableModel>
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "phasedependency.h"
|
#include "phasedependency.h"
|
||||||
#include "phase.h"
|
#include "businessObjects/phases/phase.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
PhaseDependency::PhaseDependency(DependencyType type,
|
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 "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 "businessObjects/dramTimeDependencies/phasedependenciestracker.h"
|
||||||
#include <QDebug>
|
|
||||||
#include <QFileDialog>
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QItemDelegate>
|
#include <QItemDelegate>
|
||||||
#include <QMessageBox>
|
#include <QStandardItem>
|
||||||
#include <QStandardItemModel>
|
|
||||||
#include <QString>
|
|
||||||
#include <QTextStream>
|
|
||||||
#include <QtConcurrent/QtConcurrent>
|
|
||||||
#include <qwt_legend.h>
|
|
||||||
#include <qwt_plot_canvas.h>
|
|
||||||
#include <qwt_plot_curve.h>
|
#include <qwt_plot_curve.h>
|
||||||
#include <qwt_plot_histogram.h>
|
#include <qwt_plot_histogram.h>
|
||||||
#include <qwt_plot_magnifier.h>
|
#include <qwt_plot_magnifier.h>
|
||||||
#include <qwt_plot_panner.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()
|
void TraceFileTab::setUpPossiblePhases()
|
||||||
{
|
{
|
||||||
@@ -244,94 +63,6 @@ void TraceFileTab::setUpPossiblePhases()
|
|||||||
ConfigurationFactory::deviceSupported(navigator->TraceFile()));
|
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
|
class ItemDelegate : public QItemDelegate
|
||||||
{
|
{
|
||||||
public:
|
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()
|
void TraceFileTab::on_calculateDependencies_clicked()
|
||||||
{
|
{
|
||||||
std::vector<QString> dependencyFilter;
|
std::vector<QString> dependencyFilter;
|
||||||
@@ -490,7 +195,6 @@ void TraceFileTab::on_startLatencyAnalysis_clicked()
|
|||||||
|
|
||||||
void TraceFileTab::on_startPowerAnalysis_clicked()
|
void TraceFileTab::on_startPowerAnalysis_clicked()
|
||||||
{
|
{
|
||||||
qDebug() << "Power Analysis";
|
|
||||||
QSqlDatabase db = navigator->TraceFile().getDatabase();
|
QSqlDatabase db = navigator->TraceFile().getDatabase();
|
||||||
QSqlQuery query(db);
|
QSqlQuery query(db);
|
||||||
|
|
||||||
@@ -502,11 +206,13 @@ void TraceFileTab::on_startPowerAnalysis_clicked()
|
|||||||
QwtPlotCurve* cur = new QwtPlotCurve("Speed");
|
QwtPlotCurve* cur = new QwtPlotCurve("Speed");
|
||||||
QVector<QPointF>* samples = new QVector<QPointF>;
|
QVector<QPointF>* samples = new QVector<QPointF>;
|
||||||
|
|
||||||
|
double maxPower = 0.0;
|
||||||
while (query.next())
|
while (query.next())
|
||||||
{
|
{
|
||||||
double time = query.value(0).toDouble();
|
double time = query.value(0).toDouble();
|
||||||
double power = query.value(1).toDouble();
|
double power = query.value(1).toDouble();
|
||||||
samples->push_back(QPointF(time, power));
|
samples->push_back(QPointF(time, power));
|
||||||
|
maxPower = std::max(maxPower, power);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ui->powerPlot->setAxisTitle(QwtPlot::xBottom,"Time");
|
// ui->powerPlot->setAxisTitle(QwtPlot::xBottom,"Time");
|
||||||
@@ -519,6 +225,12 @@ void TraceFileTab::on_startPowerAnalysis_clicked()
|
|||||||
cur->attach(ui->powerPlot);
|
cur->attach(ui->powerPlot);
|
||||||
cur->setPen(QPen(QColor(255, 0, 0)));
|
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());
|
QwtPlotMagnifier* mag1 = new QwtPlotMagnifier(ui->powerPlot->canvas());
|
||||||
mag1->setAxisEnabled(QwtPlot::xBottom, true);
|
mag1->setAxisEnabled(QwtPlot::xBottom, true);
|
||||||
mag1->setAxisEnabled(QwtPlot::yLeft, false);
|
mag1->setAxisEnabled(QwtPlot::yLeft, false);
|
||||||
|
|||||||
@@ -6,4 +6,4 @@ FOREACH(sub_dir ${sub_dirs})
|
|||||||
IF(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${sub_dir}")
|
IF(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${sub_dir}")
|
||||||
add_subdirectory(${sub_dir})
|
add_subdirectory(${sub_dir})
|
||||||
ENDIF()
|
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
|
#ifndef CONFIGMODELS_H
|
||||||
#define CONFIGMODELS_H
|
#define CONFIGMODELS_H
|
||||||
|
|
||||||
#include "../data/tracedb.h"
|
#include "data/tracedb.h"
|
||||||
#include "phases/dependencyinfos.h"
|
|
||||||
|
#ifdef EXTENSION_ENABLED
|
||||||
|
#include "businessObjects/phases/dependencyinfos.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <QAbstractTableModel>
|
#include <QAbstractTableModel>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@@ -217,6 +217,7 @@ void Phase::drawPhaseDependencies(traceTime begin,
|
|||||||
QPoint depLineTo(static_cast<int>(xMap.transform(begin /* + (end + offset - begin)/4*/)),
|
QPoint depLineTo(static_cast<int>(xMap.transform(begin /* + (end + offset - begin)/4*/)),
|
||||||
static_cast<int>(yVal));
|
static_cast<int>(yVal));
|
||||||
|
|
||||||
|
#ifdef EXTENSION_ENABLED
|
||||||
for (const auto& dep : mDependencies)
|
for (const auto& dep : mDependencies)
|
||||||
{
|
{
|
||||||
if (dep->isVisible())
|
if (dep->isVisible())
|
||||||
@@ -231,6 +232,7 @@ void Phase::drawPhaseDependencies(traceTime begin,
|
|||||||
invisibleDeps += 1;
|
invisibleDeps += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (invisibleDeps > 0)
|
if (invisibleDeps > 0)
|
||||||
{
|
{
|
||||||
@@ -418,7 +420,9 @@ Phase::PhaseSymbol Phase::getPhaseSymbol() const
|
|||||||
return PhaseSymbol::Hexagon;
|
return PhaseSymbol::Hexagon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef EXTENSION_ENABLED
|
||||||
void Phase::addDependency(const std::shared_ptr<PhaseDependency>& dependency)
|
void Phase::addDependency(const std::shared_ptr<PhaseDependency>& dependency)
|
||||||
{
|
{
|
||||||
mDependencies.push_back(dependency);
|
mDependencies.push_back(dependency);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
@@ -39,7 +39,11 @@
|
|||||||
|
|
||||||
#ifndef BANKPHASE_H
|
#ifndef BANKPHASE_H
|
||||||
#define BANKPHASE_H
|
#define BANKPHASE_H
|
||||||
|
|
||||||
|
#ifdef EXTENSION_ENABLED
|
||||||
#include "businessObjects/phases/phasedependency.h"
|
#include "businessObjects/phases/phasedependency.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "businessObjects/timespan.h"
|
#include "businessObjects/timespan.h"
|
||||||
#include "presentation/tracedrawingproperties.h"
|
#include "presentation/tracedrawingproperties.h"
|
||||||
#include "presentation/util/colorgenerator.h"
|
#include "presentation/util/colorgenerator.h"
|
||||||
@@ -141,7 +145,9 @@ public:
|
|||||||
|
|
||||||
virtual QString Name() const = 0;
|
virtual QString Name() const = 0;
|
||||||
|
|
||||||
|
#ifdef EXTENSION_ENABLED
|
||||||
void addDependency(const std::shared_ptr<PhaseDependency>& dependency);
|
void addDependency(const std::shared_ptr<PhaseDependency>& dependency);
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ID id;
|
ID id;
|
||||||
@@ -152,7 +158,9 @@ protected:
|
|||||||
traceTime clk;
|
traceTime clk;
|
||||||
std::weak_ptr<Transaction> transaction;
|
std::weak_ptr<Transaction> transaction;
|
||||||
std::vector<Timespan> spansOnCommandBus;
|
std::vector<Timespan> spansOnCommandBus;
|
||||||
|
#ifdef EXTENSION_ENABLED
|
||||||
std::vector<std::shared_ptr<PhaseDependency>> mDependencies;
|
std::vector<std::shared_ptr<PhaseDependency>> mDependencies;
|
||||||
|
#endif
|
||||||
|
|
||||||
double hexagonHeight;
|
double hexagonHeight;
|
||||||
TextPositioning captionPosition;
|
TextPositioning captionPosition;
|
||||||
@@ -167,6 +167,7 @@ bool TraceDB::checkDependencyTableExists()
|
|||||||
return exists;
|
return exists;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef EXTENSION_ENABLED
|
||||||
void TraceDB::updateDependenciesInTimespan(const Timespan& span)
|
void TraceDB::updateDependenciesInTimespan(const Timespan& span)
|
||||||
{
|
{
|
||||||
if (checkDependencyTableExists())
|
if (checkDependencyTableExists())
|
||||||
@@ -177,6 +178,7 @@ void TraceDB::updateDependenciesInTimespan(const Timespan& span)
|
|||||||
mUpdateDependenciesFromQuery(selectDependenciesByTimespan);
|
mUpdateDependenciesFromQuery(selectDependenciesByTimespan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// TODO Remove exception
|
// TODO Remove exception
|
||||||
std::shared_ptr<Transaction> TraceDB::getTransactionByID(ID id)
|
std::shared_ptr<Transaction> TraceDB::getTransactionByID(ID id)
|
||||||
@@ -498,6 +500,7 @@ std::vector<CommentModel::Comment> TraceDB::getDebugMessagesInTimespan(const Tim
|
|||||||
return parseCommentsFromQuery(selectDebugMessagesByTimespanWithLimit);
|
return parseCommentsFromQuery(selectDebugMessagesByTimespanWithLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef EXTENSION_ENABLED
|
||||||
DependencyInfos TraceDB::getDependencyInfos(DependencyInfos::Type infoType)
|
DependencyInfos TraceDB::getDependencyInfos(DependencyInfos::Type infoType)
|
||||||
{
|
{
|
||||||
DependencyInfos dummy;
|
DependencyInfos dummy;
|
||||||
@@ -551,6 +554,7 @@ DependencyInfos TraceDB::getDependencyInfos(DependencyInfos::Type infoType)
|
|||||||
|
|
||||||
return dummy;
|
return dummy;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
QSqlDatabase TraceDB::getDatabase() const
|
QSqlDatabase TraceDB::getDatabase() const
|
||||||
{
|
{
|
||||||
@@ -643,6 +647,7 @@ TraceDB::parseTransactionsFromQuery(QSqlQuery& query, bool updateVisiblePhases)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef EXTENSION_ENABLED
|
||||||
void TraceDB::mUpdateDependenciesFromQuery(QSqlQuery& query)
|
void TraceDB::mUpdateDependenciesFromQuery(QSqlQuery& query)
|
||||||
{
|
{
|
||||||
DependencyType type;
|
DependencyType type;
|
||||||
@@ -689,6 +694,7 @@ void TraceDB::mUpdateDependenciesFromQuery(QSqlQuery& query)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
std::vector<CommentModel::Comment> TraceDB::parseCommentsFromQuery(QSqlQuery& query)
|
std::vector<CommentModel::Comment> TraceDB::parseCommentsFromQuery(QSqlQuery& query)
|
||||||
{
|
{
|
||||||
@@ -701,6 +707,7 @@ std::vector<CommentModel::Comment> TraceDB::parseCommentsFromQuery(QSqlQuery& qu
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef EXTENSION_ENABLED
|
||||||
DependencyInfos TraceDB::parseDependencyInfos(QSqlQuery& query,
|
DependencyInfos TraceDB::parseDependencyInfos(QSqlQuery& query,
|
||||||
const DependencyInfos::Type infoType)
|
const DependencyInfos::Type infoType)
|
||||||
{
|
{
|
||||||
@@ -715,6 +722,7 @@ DependencyInfos TraceDB::parseDependencyInfos(QSqlQuery& query,
|
|||||||
|
|
||||||
return infos;
|
return infos;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void TraceDB::executeQuery(QSqlQuery query)
|
void TraceDB::executeQuery(QSqlQuery query)
|
||||||
{
|
{
|
||||||
@@ -41,10 +41,14 @@
|
|||||||
#define TRACEDB_H
|
#define TRACEDB_H
|
||||||
|
|
||||||
#include "QueryTexts.h"
|
#include "QueryTexts.h"
|
||||||
|
|
||||||
|
#ifdef EXTENSION_ENABLED
|
||||||
|
#include "businessObjects/phases/dependencyinfos.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "businessObjects/commandlengths.h"
|
#include "businessObjects/commandlengths.h"
|
||||||
#include "businessObjects/commentmodel.h"
|
#include "businessObjects/commentmodel.h"
|
||||||
#include "businessObjects/generalinfo.h"
|
#include "businessObjects/generalinfo.h"
|
||||||
#include "businessObjects/phases/dependencyinfos.h"
|
|
||||||
#include "businessObjects/phases/phasefactory.h"
|
#include "businessObjects/phases/phasefactory.h"
|
||||||
#include "businessObjects/transaction.h"
|
#include "businessObjects/transaction.h"
|
||||||
#include <QSqlDatabase>
|
#include <QSqlDatabase>
|
||||||
@@ -69,11 +73,13 @@ public:
|
|||||||
|
|
||||||
void updateComments(const std::vector<CommentModel::Comment>& comments);
|
void updateComments(const std::vector<CommentModel::Comment>& comments);
|
||||||
void updateFileDescription(const QString& description);
|
void updateFileDescription(const QString& description);
|
||||||
void updateDependenciesInTimespan(const Timespan& span);
|
|
||||||
void refreshData();
|
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; }
|
const CommandLengths& getCommandLengths() const { return commandLengths; }
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Transaction>>
|
std::vector<std::shared_ptr<Transaction>>
|
||||||
@@ -97,8 +103,9 @@ public:
|
|||||||
unsigned int limit);
|
unsigned int limit);
|
||||||
|
|
||||||
bool checkDependencyTableExists();
|
bool checkDependencyTableExists();
|
||||||
|
#ifdef EXTENSION_ENABLED
|
||||||
DependencyInfos getDependencyInfos(DependencyInfos::Type infoType);
|
DependencyInfos getDependencyInfos(DependencyInfos::Type infoType);
|
||||||
|
#endif
|
||||||
QSqlDatabase getDatabase() const;
|
QSqlDatabase getDatabase() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -129,9 +136,11 @@ private:
|
|||||||
parseTransactionsFromQuery(QSqlQuery& query, bool updateVisiblePhases = false);
|
parseTransactionsFromQuery(QSqlQuery& query, bool updateVisiblePhases = false);
|
||||||
static std::vector<CommentModel::Comment> parseCommentsFromQuery(QSqlQuery& query);
|
static std::vector<CommentModel::Comment> parseCommentsFromQuery(QSqlQuery& query);
|
||||||
|
|
||||||
|
#ifdef EXTENSION_ENABLED
|
||||||
void mUpdateDependenciesFromQuery(QSqlQuery& query);
|
void mUpdateDependenciesFromQuery(QSqlQuery& query);
|
||||||
static DependencyInfos parseDependencyInfos(QSqlQuery& query,
|
static DependencyInfos parseDependencyInfos(QSqlQuery& query,
|
||||||
const DependencyInfos::Type infoType);
|
const DependencyInfos::Type infoType);
|
||||||
|
#endif
|
||||||
|
|
||||||
void executeScriptFile(const QString& fileName);
|
void executeScriptFile(const QString& fileName);
|
||||||
void dropAndCreateTables();
|
void dropAndCreateTables();
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, RPTU Kaiserslautern-Landau
|
* Copyright (c) 2024, RPTU Kaiserslautern-Landau
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -33,70 +33,32 @@
|
|||||||
* Derek Christ
|
* Derek Christ
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SIMULATIONDIALOG_H
|
#ifndef EXTENSION_H
|
||||||
#define SIMULATIONDIALOG_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>
|
inline void showExtensionDisclaimerMessageBox()
|
||||||
#include <QPointer>
|
|
||||||
#include <QProcess>
|
|
||||||
#include <QSyntaxHighlighter>
|
|
||||||
#include <QTemporaryFile>
|
|
||||||
#include <QWidget>
|
|
||||||
|
|
||||||
namespace Ui
|
|
||||||
{
|
{
|
||||||
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:
|
#endif // EXTENSION_H
|
||||||
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
|
|
||||||
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
@@ -33,6 +33,7 @@
|
|||||||
* Janik Schlemminger
|
* Janik Schlemminger
|
||||||
* Robert Gernhardt
|
* Robert Gernhardt
|
||||||
* Matthias Jung
|
* Matthias Jung
|
||||||
|
* Derek Christ
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "traceanalyzer.h"
|
#include "traceanalyzer.h"
|
||||||
@@ -48,16 +49,15 @@
|
|||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
std::cout << argv[0] << std::endl;
|
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
|
|
||||||
QIcon icon(QStringLiteral(":/icon"));
|
QIcon icon(QStringLiteral(":/icon"));
|
||||||
a.setWindowIcon(icon);
|
QApplication::setWindowIcon(icon);
|
||||||
a.setApplicationName(QStringLiteral("TraceAnalyzer"));
|
QApplication::setApplicationName(QStringLiteral("TraceAnalyzer"));
|
||||||
a.setApplicationDisplayName(QStringLiteral("Trace Analyzer"));
|
QApplication::setApplicationDisplayName(QStringLiteral("Trace Analyzer"));
|
||||||
|
|
||||||
std::filesystem::path traceAnalyzerDir = DRAMSYS_TRACEANALYZER_DIR;
|
std::filesystem::path extensionDir = DRAMSYS_TRACE_ANALYZER_EXTENSION_DIR;
|
||||||
std::filesystem::path modulesDir = traceAnalyzerDir / "scripts";
|
std::filesystem::path modulesDir = extensionDir / "scripts";
|
||||||
|
|
||||||
pybind11::scoped_interpreter guard;
|
pybind11::scoped_interpreter guard;
|
||||||
|
|
||||||
@@ -92,12 +92,10 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
TraceAnalyzer analyzer(arguments);
|
TraceAnalyzer analyzer(arguments);
|
||||||
analyzer.show();
|
analyzer.show();
|
||||||
return a.exec();
|
return QApplication::exec();
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TraceAnalyzer analyzer;
|
|
||||||
analyzer.show();
|
|
||||||
return a.exec();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TraceAnalyzer analyzer;
|
||||||
|
analyzer.show();
|
||||||
|
return QApplication::exec();
|
||||||
}
|
}
|
||||||
@@ -286,6 +286,11 @@ void TracePlot::setUpActions()
|
|||||||
dependenciesGroup->addAction(disabledDependencies);
|
dependenciesGroup->addAction(disabledDependencies);
|
||||||
dependenciesGroup->addAction(selectedDependencies);
|
dependenciesGroup->addAction(selectedDependencies);
|
||||||
dependenciesGroup->addAction(allDependencies);
|
dependenciesGroup->addAction(allDependencies);
|
||||||
|
dependenciesGroup->addAction(switchDrawDependencyTextsOption);
|
||||||
|
|
||||||
|
#ifndef EXTENSION_ENABLED
|
||||||
|
dependenciesGroup->setEnabled(false);
|
||||||
|
#endif
|
||||||
|
|
||||||
setUpContextMenu();
|
setUpContextMenu();
|
||||||
}
|
}
|
||||||
@@ -628,10 +633,13 @@ void TracePlot::currentTraceTimeChanged()
|
|||||||
|
|
||||||
transactions =
|
transactions =
|
||||||
navigator->TraceFile().getTransactionsInTimespan(GetCurrentTimespan(), drawDependencies);
|
navigator->TraceFile().getTransactionsInTimespan(GetCurrentTimespan(), drawDependencies);
|
||||||
|
|
||||||
|
#ifdef EXTENSION_ENABLED
|
||||||
if (drawDependencies)
|
if (drawDependencies)
|
||||||
{
|
{
|
||||||
navigator->TraceFile().updateDependenciesInTimespan(GetCurrentTimespan());
|
navigator->TraceFile().updateDependenciesInTimespan(GetCurrentTimespan());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
setAxisScale(xBottom, GetCurrentTimespan().Begin(), GetCurrentTimespan().End());
|
setAxisScale(xBottom, GetCurrentTimespan().Begin(), GetCurrentTimespan().End());
|
||||||
|
|
||||||
@@ -220,10 +220,12 @@ void TraceScroller::currentTraceTimeChanged()
|
|||||||
Timespan span = GetCurrentTimespan();
|
Timespan span = GetCurrentTimespan();
|
||||||
transactions = navigator->TraceFile().getTransactionsInTimespan(span, drawDependencies);
|
transactions = navigator->TraceFile().getTransactionsInTimespan(span, drawDependencies);
|
||||||
|
|
||||||
|
#ifdef EXTENSION_ENABLED
|
||||||
if (drawDependencies)
|
if (drawDependencies)
|
||||||
{
|
{
|
||||||
navigator->TraceFile().updateDependenciesInTimespan(span);
|
navigator->TraceFile().updateDependenciesInTimespan(span);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
setAxisScale(xBottom, span.Begin(), span.End());
|
setAxisScale(xBottom, span.Begin(), span.End());
|
||||||
replot();
|
replot();
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "traceanalyzer.h"
|
#include "traceanalyzer.h"
|
||||||
#include "simulationdialog.h"
|
#include "extensionDisclaimer.h"
|
||||||
#include "tracefiletab.h"
|
#include "tracefiletab.h"
|
||||||
#include "ui_traceanalyzer.h"
|
#include "ui_traceanalyzer.h"
|
||||||
|
|
||||||
@@ -53,7 +53,10 @@ void TraceAnalyzer::setUpStatusBar()
|
|||||||
statusBar()->addWidget(statusLabel);
|
statusBar()->addWidget(statusLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TraceAnalyzer::setUpGui()
|
TraceAnalyzer::TraceAnalyzer(QWidget* parent) :
|
||||||
|
QMainWindow(parent),
|
||||||
|
evaluationTool(pythonCaller),
|
||||||
|
ui(new Ui::TraceAnalyzer)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
setUpStatusBar();
|
setUpStatusBar();
|
||||||
@@ -62,21 +65,8 @@ void TraceAnalyzer::setUpGui()
|
|||||||
QObject::connect(ui->actionAbout_Qt, &QAction::triggered, qApp, &QApplication::aboutQt);
|
QObject::connect(ui->actionAbout_Qt, &QAction::triggered, qApp, &QApplication::aboutQt);
|
||||||
}
|
}
|
||||||
|
|
||||||
TraceAnalyzer::TraceAnalyzer(QWidget* parent) :
|
TraceAnalyzer::TraceAnalyzer(QSet<QString> paths, QWidget* parent) : TraceAnalyzer(parent)
|
||||||
QMainWindow(parent),
|
|
||||||
evaluationTool(pythonCaller),
|
|
||||||
ui(new Ui::TraceAnalyzer)
|
|
||||||
{
|
{
|
||||||
setUpGui();
|
|
||||||
}
|
|
||||||
|
|
||||||
TraceAnalyzer::TraceAnalyzer(QSet<QString> paths, QWidget* parent) :
|
|
||||||
QMainWindow(parent),
|
|
||||||
evaluationTool(pythonCaller),
|
|
||||||
ui(new Ui::TraceAnalyzer)
|
|
||||||
{
|
|
||||||
setUpGui();
|
|
||||||
|
|
||||||
for (const QString& path : paths)
|
for (const QString& path : paths)
|
||||||
openTracefileTab(path);
|
openTracefileTab(path);
|
||||||
}
|
}
|
||||||
@@ -99,7 +89,7 @@ void TraceAnalyzer::on_actionOpen_triggered()
|
|||||||
|
|
||||||
TraceFileTab* TraceAnalyzer::createTraceFileTab(const QString& path)
|
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);
|
connect(traceFileTab, &TraceFileTab::statusChanged, this, &TraceAnalyzer::statusChanged);
|
||||||
|
|
||||||
@@ -131,7 +121,6 @@ void TraceAnalyzer::on_menuFile_aboutToShow()
|
|||||||
ui->actionReload->setEnabled(tabsOpen);
|
ui->actionReload->setEnabled(tabsOpen);
|
||||||
ui->actionReload_all->setEnabled(tabsOpen);
|
ui->actionReload_all->setEnabled(tabsOpen);
|
||||||
ui->actionExportAsVCD->setEnabled(tabsOpen);
|
ui->actionExportAsVCD->setEnabled(tabsOpen);
|
||||||
ui->actionTest->setEnabled(tabsOpen);
|
|
||||||
ui->actionMetrics->setEnabled(tabsOpen);
|
ui->actionMetrics->setEnabled(tabsOpen);
|
||||||
ui->actionClose->setEnabled(tabsOpen);
|
ui->actionClose->setEnabled(tabsOpen);
|
||||||
ui->actionClose_all->setEnabled(tabsOpen);
|
ui->actionClose_all->setEnabled(tabsOpen);
|
||||||
@@ -139,7 +128,7 @@ void TraceAnalyzer::on_menuFile_aboutToShow()
|
|||||||
|
|
||||||
void TraceAnalyzer::closeTab(int index)
|
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())
|
if (traceFileTab->close())
|
||||||
{
|
{
|
||||||
@@ -169,7 +158,7 @@ void TraceAnalyzer::on_actionClose_all_triggered()
|
|||||||
|
|
||||||
void TraceAnalyzer::reloadTab(int index)
|
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();
|
QString traceFile = traceFileTab->getPathToTraceFile();
|
||||||
traceTime time = traceFileTab->getCurrentTraceTime();
|
traceTime time = traceFileTab->getCurrentTraceTime();
|
||||||
@@ -212,7 +201,7 @@ void TraceAnalyzer::on_actionReload_all_triggered()
|
|||||||
|
|
||||||
void TraceAnalyzer::on_actionSave_triggered()
|
void TraceAnalyzer::on_actionSave_triggered()
|
||||||
{
|
{
|
||||||
auto traceFileTab = static_cast<TraceFileTab*>(ui->traceFileTabs->currentWidget());
|
auto* traceFileTab = dynamic_cast<TraceFileTab*>(ui->traceFileTabs->currentWidget());
|
||||||
traceFileTab->commitChangesToDB();
|
traceFileTab->commitChangesToDB();
|
||||||
|
|
||||||
this->statusChanged(QString("Saved database ") +
|
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
|
// Changes in the database files will trigger the file watchers from
|
||||||
// the TraceFileTab class. They generate signals connected to
|
// the TraceFileTab class. They generate signals connected to
|
||||||
// TraceAnalyzer::statusChanged().
|
// TraceAnalyzer::statusChanged().
|
||||||
TraceFileTab* traceFileTab = static_cast<TraceFileTab*>(ui->traceFileTabs->widget(index));
|
auto* traceFileTab = dynamic_cast<TraceFileTab*>(ui->traceFileTabs->widget(index));
|
||||||
traceFileTab->commitChangesToDB();
|
traceFileTab->commitChangesToDB();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TraceAnalyzer::on_actionExportAsVCD_triggered()
|
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();
|
traceFileTab->exportAsVCD();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,6 +238,11 @@ void TraceAnalyzer::statusChanged(const QString& message)
|
|||||||
|
|
||||||
void TraceAnalyzer::on_actionMetrics_triggered()
|
void TraceAnalyzer::on_actionMetrics_triggered()
|
||||||
{
|
{
|
||||||
|
#ifndef EXTENSION_ENABLED
|
||||||
|
showExtensionDisclaimerMessageBox();
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
evaluationTool.raise();
|
evaluationTool.raise();
|
||||||
evaluationTool.activateWindow();
|
evaluationTool.activateWindow();
|
||||||
evaluationTool.showAndEvaluateMetrics(openedTraceFiles.values());
|
evaluationTool.showAndEvaluateMetrics(openedTraceFiles.values());
|
||||||
@@ -254,12 +253,15 @@ void TraceAnalyzer::on_actionAbout_triggered()
|
|||||||
QMessageBox::about(
|
QMessageBox::about(
|
||||||
this,
|
this,
|
||||||
QStringLiteral("DRAMSys"),
|
QStringLiteral("DRAMSys"),
|
||||||
QStringLiteral("<b>DRAMSys4.0</b> is a flexible DRAM subsystem design space exploration "
|
QStringLiteral(
|
||||||
"framework based on SystemC "
|
"<b>DRAMSys4.0</b> is a flexible DRAM subsystem design space exploration "
|
||||||
"TLM-2.0. It was developed at the <a "
|
"framework based on SystemC "
|
||||||
"href=\"https://ems.eit.uni-kl.de/en/start/\">Microelectronic Systems "
|
"TLM-2.0. It was developed by the <a "
|
||||||
"Design Research Group</a> and <a "
|
"href=\"https://ems.eit.uni-kl.de/en/start/\">Microelectronic Systems "
|
||||||
"href=\"https://www.iese.fraunhofer.de/en.html\">Fraunhofer IESE</a>."));
|
"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)
|
void TraceAnalyzer::closeEvent(QCloseEvent* event)
|
||||||
@@ -276,16 +278,3 @@ void TraceAnalyzer::closeEvent(QCloseEvent* event)
|
|||||||
|
|
||||||
event->accept();
|
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();
|
~TraceAnalyzer();
|
||||||
|
|
||||||
void setUpStatusBar();
|
void setUpStatusBar();
|
||||||
void setUpGui();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent* event) override;
|
void closeEvent(QCloseEvent* event) override;
|
||||||
@@ -93,7 +92,6 @@ private Q_SLOTS:
|
|||||||
void on_actionClose_triggered();
|
void on_actionClose_triggered();
|
||||||
void on_actionClose_all_triggered();
|
void on_actionClose_all_triggered();
|
||||||
void on_actionAbout_triggered();
|
void on_actionAbout_triggered();
|
||||||
void on_actionSimulate_triggered();
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void statusChanged(const QString& message);
|
void statusChanged(const QString& message);
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>800</width>
|
<width>800</width>
|
||||||
<height>34</height>
|
<height>20</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QMenu" name="menuFile">
|
<widget class="QMenu" name="menuFile">
|
||||||
@@ -78,14 +78,7 @@
|
|||||||
<addaction name="actionAbout"/>
|
<addaction name="actionAbout"/>
|
||||||
<addaction name="actionAbout_Qt"/>
|
<addaction name="actionAbout_Qt"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="menuRun">
|
|
||||||
<property name="title">
|
|
||||||
<string>&Run</string>
|
|
||||||
</property>
|
|
||||||
<addaction name="actionSimulate"/>
|
|
||||||
</widget>
|
|
||||||
<addaction name="menuFile"/>
|
<addaction name="menuFile"/>
|
||||||
<addaction name="menuRun"/>
|
|
||||||
<addaction name="menuHelp"/>
|
<addaction name="menuHelp"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QStatusBar" name="statusbar"/>
|
<widget class="QStatusBar" name="statusbar"/>
|
||||||
@@ -133,32 +126,11 @@
|
|||||||
<string>Ctrl+Shift+W</string>
|
<string>Ctrl+Shift+W</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionInfo">
|
|
||||||
<property name="text">
|
|
||||||
<string>&Info</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionAbout">
|
<action name="actionAbout">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&About DRAMSys</string>
|
<string>&About DRAMSys</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</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">
|
<action name="actionMetrics">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Metrics</string>
|
<string>&Metrics</string>
|
||||||
@@ -232,15 +204,6 @@
|
|||||||
<string>Save &as...</string>
|
<string>Save &as...</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</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">
|
<action name="actionAbout_Qt">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>About &Qt</string>
|
<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
|
#ifndef TRACEFILETAB_H
|
||||||
#define 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 "businessObjects/traceplotlinemodel.h"
|
||||||
#include "presentation/tracenavigator.h"
|
#include "presentation/tracenavigator.h"
|
||||||
#include "presentation/traceplot.h"
|
#include "presentation/traceplot.h"
|
||||||
#include "presentation/tracescroller.h"
|
#include "presentation/tracescroller.h"
|
||||||
|
|
||||||
#include "businessObjects/configmodels.h"
|
|
||||||
#include "businessObjects/dependencymodels.h"
|
|
||||||
#include <QFileSystemWatcher>
|
#include <QFileSystemWatcher>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QTreeWidget>
|
#include <QTreeWidget>
|
||||||
@@ -57,11 +61,6 @@ class McConfigModel;
|
|||||||
class MemSpecModel;
|
class MemSpecModel;
|
||||||
class PythonCaller;
|
class PythonCaller;
|
||||||
|
|
||||||
namespace Ui
|
|
||||||
{
|
|
||||||
class TraceFileTab;
|
|
||||||
}
|
|
||||||
|
|
||||||
class TraceFileTab : public QWidget
|
class TraceFileTab : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -76,11 +75,15 @@ public:
|
|||||||
void setUpTraceplotScrollbar();
|
void setUpTraceplotScrollbar();
|
||||||
void setUpCommentView();
|
void setUpCommentView();
|
||||||
void setUpTraceSelector();
|
void setUpTraceSelector();
|
||||||
|
void addDisclaimer();
|
||||||
|
|
||||||
|
#ifdef EXTENSION_ENABLED
|
||||||
void setUpPossiblePhases();
|
void setUpPossiblePhases();
|
||||||
|
#endif
|
||||||
|
|
||||||
void initNavigatorAndItsDependentWidgets();
|
void initNavigatorAndItsDependentWidgets();
|
||||||
QString getPathToTraceFile() { return traceFilePath.data(); }
|
QString getPathToTraceFile() { return traceFilePath.data(); }
|
||||||
void commitChangesToDB(void);
|
void commitChangesToDB();
|
||||||
void exportAsVCD();
|
void exportAsVCD();
|
||||||
|
|
||||||
traceTime getCurrentTraceTime() const;
|
traceTime getCurrentTraceTime() const;
|
||||||
@@ -116,7 +119,9 @@ private:
|
|||||||
SelectedTracePlotLineModel* selectedRowsModel;
|
SelectedTracePlotLineModel* selectedRowsModel;
|
||||||
TracePlotLineDataSource* tracePlotLineDataSource;
|
TracePlotLineDataSource* tracePlotLineDataSource;
|
||||||
|
|
||||||
|
#ifdef EXTENSION_ENABLED
|
||||||
QAbstractItemModel* depInfosView;
|
QAbstractItemModel* depInfosView;
|
||||||
|
#endif
|
||||||
|
|
||||||
PythonCaller& pythonCaller;
|
PythonCaller& pythonCaller;
|
||||||
|
|
||||||
@@ -131,10 +136,12 @@ Q_SIGNALS:
|
|||||||
void colorGroupingChanged(ColorGrouping colorgrouping);
|
void colorGroupingChanged(ColorGrouping colorgrouping);
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
|
#ifdef EXTENSION_ENABLED
|
||||||
void on_latencyTreeView_doubleClicked(const QModelIndex& index);
|
void on_latencyTreeView_doubleClicked(const QModelIndex& index);
|
||||||
void on_calculateDependencies_clicked();
|
void on_calculateDependencies_clicked();
|
||||||
void on_startLatencyAnalysis_clicked();
|
void on_startLatencyAnalysis_clicked();
|
||||||
void on_startPowerAnalysis_clicked();
|
void on_startPowerAnalysis_clicked();
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TRACEFILETAB_H
|
#endif // TRACEFILETAB_H
|
||||||
@@ -261,33 +261,6 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</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">
|
<widget class="QWidget" name="tabComments">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
<string>Comments</string>
|
<string>Comments</string>
|
||||||
@@ -317,7 +290,6 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
||||||
<widget class="QWidget" name="tabLatencyAnalysis">
|
<widget class="QWidget" name="tabLatencyAnalysis">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Ignored" vsizetype="Ignored">
|
<sizepolicy hsizetype="Ignored" vsizetype="Ignored">
|
||||||
@@ -330,7 +302,7 @@
|
|||||||
</attribute>
|
</attribute>
|
||||||
<layout class="QGridLayout" name="gridLayout_3">
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
<layout class="QVBoxLayout" name="latencyLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="startLatencyAnalysis">
|
<widget class="QPushButton" name="startLatencyAnalysis">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -366,7 +338,6 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
||||||
<widget class="QWidget" name="tabPowerAnalysis">
|
<widget class="QWidget" name="tabPowerAnalysis">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
@@ -390,15 +361,15 @@
|
|||||||
<string>Power and Bandwidth Analysis</string>
|
<string>Power and Bandwidth Analysis</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
<layout class="QGridLayout" name="gridLayout_4">
|
<layout class="QGridLayout" name="gridLayout_4">
|
||||||
<item row="0" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QPushButton" name="startPowerAnalysis">
|
<layout class="QVBoxLayout" name="powerLayout">
|
||||||
<property name="text">
|
<item>
|
||||||
<string>Start Analysis</string>
|
<widget class="QPushButton" name="startPowerAnalysis">
|
||||||
</property>
|
<property name="text">
|
||||||
</widget>
|
<string>Start Analysis</string>
|
||||||
</item>
|
</property>
|
||||||
<item row="1" column="0">
|
</widget>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="powerBox">
|
<widget class="QGroupBox" name="powerBox">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
@@ -439,6 +410,43 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</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>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
Reference in New Issue
Block a user