/* * 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 */ #include "traceanalyzer.h" #include "simulationdialog.h" #include "tracefiletab.h" #include "ui_traceanalyzer.h" #include #include #include #include #include void TraceAnalyzer::setUpStatusBar() { statusLabel = new QLabel(this); statusBar()->addWidget(statusLabel); } void TraceAnalyzer::setUpGui() { ui->setupUi(this); setUpStatusBar(); ui->traceFileTabs->clear(); QObject::connect(ui->actionAbout_Qt, &QAction::triggered, qApp, &QApplication::aboutQt); } TraceAnalyzer::TraceAnalyzer(QWidget* parent) : QMainWindow(parent), evaluationTool(pythonCaller), ui(new Ui::TraceAnalyzer) { setUpGui(); } TraceAnalyzer::TraceAnalyzer(QSet paths, QWidget* parent) : QMainWindow(parent), evaluationTool(pythonCaller), ui(new Ui::TraceAnalyzer) { setUpGui(); for (const QString& path : paths) openTracefileTab(path); } TraceAnalyzer::~TraceAnalyzer() { delete ui; } void TraceAnalyzer::on_actionOpen_triggered() { QStringList paths = QFileDialog::getOpenFileNames( this, tr("Open Tracefile"), "../simulator/", tr("Tracefile (*.tdb)")); if (paths.isEmpty()) return; for (const QString& path : paths) openTracefileTab(path); } TraceFileTab* TraceAnalyzer::createTraceFileTab(const QString& path) { TraceFileTab* traceFileTab = new TraceFileTab(path.toStdString(), pythonCaller, this); connect(traceFileTab, &TraceFileTab::statusChanged, this, &TraceAnalyzer::statusChanged); return traceFileTab; } void TraceAnalyzer::openTracefileTab(const QString& path) { if (openedTraceFiles.contains(path)) return; TraceFileTab* traceFileTab = createTraceFileTab(path); ui->traceFileTabs->addTab(traceFileTab, QFileInfo(path).baseName()); openedTraceFiles.insert(path); statusLabel->clear(); } void TraceAnalyzer::on_menuFile_aboutToShow() { ui->actionOpen->setEnabled(true); ui->actionQuit->setEnabled(true); bool tabsOpen = ui->traceFileTabs->count() > 0; ui->actionSave->setEnabled(tabsOpen); ui->actionSave_all->setEnabled(tabsOpen); ui->actionReload->setEnabled(tabsOpen); ui->actionReload_all->setEnabled(tabsOpen); ui->actionExportAsVCD->setEnabled(tabsOpen); ui->actionTest->setEnabled(tabsOpen); ui->actionMetrics->setEnabled(tabsOpen); ui->actionClose->setEnabled(tabsOpen); ui->actionClose_all->setEnabled(tabsOpen); } void TraceAnalyzer::closeTab(int index) { TraceFileTab* traceFileTab = static_cast(ui->traceFileTabs->widget(index)); if (traceFileTab->close()) { openedTraceFiles.remove(traceFileTab->getPathToTraceFile()); ui->traceFileTabs->removeTab(index); delete traceFileTab; } } void TraceAnalyzer::on_traceFileTabs_tabCloseRequested(int index) { closeTab(index); } void TraceAnalyzer::on_actionClose_triggered() { closeTab(ui->traceFileTabs->currentIndex()); } void TraceAnalyzer::on_actionClose_all_triggered() { for (unsigned int i = ui->traceFileTabs->count(); i--;) closeTab(i); statusLabel->clear(); } void TraceAnalyzer::reloadTab(int index) { auto traceFileTab = static_cast(ui->traceFileTabs->widget(index)); QString traceFile = traceFileTab->getPathToTraceFile(); traceTime time = traceFileTab->getCurrentTraceTime(); traceTime zoomLevel = traceFileTab->getZoomLevel(); auto rootNode = traceFileTab->saveTraceSelectorState(); if (!traceFileTab->close()) return; ui->traceFileTabs->removeTab(index); delete traceFileTab; traceFileTab = createTraceFileTab(traceFile); traceFileTab->setZoomLevel(zoomLevel); traceFileTab->navigateToTime(time); traceFileTab->restoreTraceSelectorState(std::move(rootNode)); ui->traceFileTabs->insertTab(index, traceFileTab, QFileInfo(traceFile).baseName()); ui->traceFileTabs->setCurrentIndex(index); } void TraceAnalyzer::on_actionReload_triggered() { int index = ui->traceFileTabs->currentIndex(); reloadTab(index); this->statusChanged(QString("Reloaded tab ") + QString::number(index) + " "); } void TraceAnalyzer::on_actionReload_all_triggered() { int index = ui->traceFileTabs->currentIndex(); for (unsigned int i = ui->traceFileTabs->count(); i--;) reloadTab(i); ui->traceFileTabs->setCurrentIndex(index); this->statusChanged(QString("All databases reloaded ")); } void TraceAnalyzer::on_actionSave_triggered() { auto traceFileTab = static_cast(ui->traceFileTabs->currentWidget()); traceFileTab->commitChangesToDB(); this->statusChanged(QString("Saved database ") + QFileInfo(traceFileTab->getPathToTraceFile()).baseName() + " "); } void TraceAnalyzer::on_actionSave_all_triggered() { for (int index = 0; index < ui->traceFileTabs->count(); index++) { // Changes in the database files will trigger the file watchers from // the TraceFileTab class. They generate signals connected to // TraceAnalyzer::statusChanged(). TraceFileTab* traceFileTab = static_cast(ui->traceFileTabs->widget(index)); traceFileTab->commitChangesToDB(); } } void TraceAnalyzer::on_actionExportAsVCD_triggered() { TraceFileTab* traceFileTab = static_cast(ui->traceFileTabs->currentWidget()); traceFileTab->exportAsVCD(); } void TraceAnalyzer::statusChanged(const QString& message) { statusLabel->setText(message + QTime::currentTime().toString()); } void TraceAnalyzer::on_actionMetrics_triggered() { evaluationTool.raise(); evaluationTool.activateWindow(); evaluationTool.showAndEvaluateMetrics(openedTraceFiles.values()); } void TraceAnalyzer::on_actionAbout_triggered() { QMessageBox::about( this, QStringLiteral("DRAMSys"), QStringLiteral("DRAMSys4.0 is a flexible DRAM subsystem design space exploration " "framework based on SystemC " "TLM-2.0. It was developed at the Microelectronic Systems " "Design Research Group and Fraunhofer IESE.")); } void TraceAnalyzer::closeEvent(QCloseEvent* event) { for (int i = 0; i < ui->traceFileTabs->count(); i++) { QWidget* tab = ui->traceFileTabs->widget(i); if (!tab->close()) { event->ignore(); return; } } 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(); }