diff --git a/gui/ice40/mainwindow.cc b/gui/ice40/mainwindow.cc index c8df0677..34769abe 100644 --- a/gui/ice40/mainwindow.cc +++ b/gui/ice40/mainwindow.cc @@ -47,6 +47,7 @@ MainWindow::MainWindow(Context *_ctx, QWidget *parent) : BaseMainWindow(_ctx, pa connect(task, SIGNAL(log(std::string)), this, SLOT(writeInfo(std::string))); connect(task, SIGNAL(loadfile_finished(bool)), this, SLOT(loadfile_finished(bool))); + connect(task, SIGNAL(loadpcf_finished(bool)), this, SLOT(loadpcf_finished(bool))); connect(task, SIGNAL(pack_finished(bool)), this, SLOT(pack_finished(bool))); connect(task, SIGNAL(budget_finish(bool)), this, SLOT(budget_finish(bool))); connect(task, SIGNAL(place_finished(bool)), this, SLOT(place_finished(bool))); @@ -56,9 +57,6 @@ MainWindow::MainWindow(Context *_ctx, QWidget *parent) : BaseMainWindow(_ctx, pa connect(task, SIGNAL(taskStarted()), this, SLOT(taskStarted())); connect(task, SIGNAL(taskPaused()), this, SLOT(taskPaused())); - connect(this, SIGNAL(budget(double)), task, SIGNAL(budget(double))); - connect(this, SIGNAL(place(bool)), task, SIGNAL(place(bool))); - createMenu(); } @@ -69,6 +67,14 @@ void MainWindow::createMenu() QMenu *menu_Design = new QMenu("&Design", menuBar); menuBar->addAction(menu_Design->menuAction()); + actionLoadPCF = new QAction("Open PCF", this); + QIcon iconLoadPCF; + iconLoadPCF.addFile(QStringLiteral(":/icons/resources/open_pcf.png")); + actionLoadPCF->setIcon(iconLoadPCF); + actionLoadPCF->setStatusTip("Open PCF file"); + connect(actionLoadPCF, SIGNAL(triggered()), this, SLOT(open_pcf())); + actionLoadPCF->setEnabled(false); + actionPack = new QAction("Pack", this); QIcon iconPack; iconPack.addFile(QStringLiteral(":/icons/resources/pack.png")); @@ -104,11 +110,13 @@ void MainWindow::createMenu() QToolBar *taskFPGABar = new QToolBar(); addToolBar(Qt::TopToolBarArea, taskFPGABar); + taskFPGABar->addAction(actionLoadPCF); taskFPGABar->addAction(actionPack); taskFPGABar->addAction(actionAssignBudget); taskFPGABar->addAction(actionPlace); taskFPGABar->addAction(actionRoute); + menu_Design->addAction(actionLoadPCF); menu_Design->addAction(actionPack); menu_Design->addAction(actionAssignBudget); menu_Design->addAction(actionPlace); @@ -159,10 +167,23 @@ void MainWindow::open() } } +void MainWindow::open_pcf() +{ + QString fileName = QFileDialog::getOpenFileName(this, QString(), QString(), QString("*.pcf")); + if (!fileName.isEmpty()) { + tabWidget->setCurrentWidget(info); + + std::string fn = fileName.toStdString(); + disableActions(); + Q_EMIT task->loadpcf(fn); + } +} + bool MainWindow::save() { return false; } void MainWindow::disableActions() { + actionLoadPCF->setEnabled(false); actionPack->setEnabled(false); actionAssignBudget->setEnabled(false); actionPlace->setEnabled(false); @@ -178,11 +199,24 @@ void MainWindow::loadfile_finished(bool status) disableActions(); if (status) { log("Loading design successful.\n"); + actionLoadPCF->setEnabled(true); actionPack->setEnabled(true); } else { log("Loading design failed.\n"); } } + +void MainWindow::loadpcf_finished(bool status) +{ + disableActions(); + if (status) { + log("Loading PCF successful.\n"); + actionPack->setEnabled(true); + } else { + log("Loading PCF failed.\n"); + } +} + void MainWindow::pack_finished(bool status) { disableActions(); @@ -252,10 +286,10 @@ void MainWindow::budget() if (ok) { freq *= 1e6; timing_driven = true; - Q_EMIT budget(freq); + Q_EMIT task->budget(freq); } } -void MainWindow::place() { Q_EMIT place(timing_driven); } +void MainWindow::place() { Q_EMIT task->place(timing_driven); } NEXTPNR_NAMESPACE_END \ No newline at end of file diff --git a/gui/ice40/mainwindow.h b/gui/ice40/mainwindow.h index 9857adf8..66814d32 100644 --- a/gui/ice40/mainwindow.h +++ b/gui/ice40/mainwindow.h @@ -36,18 +36,16 @@ class MainWindow : public BaseMainWindow public: void createMenu(); - Q_SIGNALS: - void budget(double freq); - void place(bool timing_driven); - protected Q_SLOTS: virtual void open(); virtual bool save(); + void open_pcf(); void budget(); void place(); void loadfile_finished(bool status); + void loadpcf_finished(bool status); void pack_finished(bool status); void budget_finish(bool status); void place_finished(bool status); @@ -61,6 +59,7 @@ class MainWindow : public BaseMainWindow void disableActions(); TaskManager *task; + QAction *actionLoadPCF; QAction *actionPack; QAction *actionAssignBudget; QAction *actionPlace; diff --git a/gui/ice40/nextpnr.qrc b/gui/ice40/nextpnr.qrc index 33f72ad8..4a73d791 100644 --- a/gui/ice40/nextpnr.qrc +++ b/gui/ice40/nextpnr.qrc @@ -7,5 +7,6 @@ resources/place.png resources/route.png resources/time_add.png + resources/open_pcf.png diff --git a/gui/ice40/resources/open_pcf.png b/gui/ice40/resources/open_pcf.png new file mode 100644 index 00000000..093dec39 Binary files /dev/null and b/gui/ice40/resources/open_pcf.png differ diff --git a/gui/ice40/worker.cc b/gui/ice40/worker.cc index 1558bc0c..9986ff3b 100644 --- a/gui/ice40/worker.cc +++ b/gui/ice40/worker.cc @@ -68,6 +68,18 @@ void Worker::loadfile(const std::string &filename) } } +void Worker::loadpcf(const std::string &filename) +{ + Q_EMIT taskStarted(); + std::string fn = filename; + std::ifstream f(fn); + try { + Q_EMIT loadpcf_finished(apply_pcf(ctx, f)); + } catch (WorkerInterruptionRequested) { + Q_EMIT taskCanceled(); + } +} + void Worker::pack() { Q_EMIT taskStarted(); @@ -119,6 +131,7 @@ TaskManager::TaskManager(Context *ctx) : toTerminate(false), toPause(false) connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater); connect(this, &TaskManager::loadfile, worker, &Worker::loadfile); + connect(this, &TaskManager::loadpcf, worker, &Worker::loadpcf); connect(this, &TaskManager::pack, worker, &Worker::pack); connect(this, &TaskManager::budget, worker, &Worker::budget); connect(this, &TaskManager::place, worker, &Worker::place); @@ -126,6 +139,7 @@ TaskManager::TaskManager(Context *ctx) : toTerminate(false), toPause(false) connect(worker, &Worker::log, this, &TaskManager::info); connect(worker, &Worker::loadfile_finished, this, &TaskManager::loadfile_finished); + connect(worker, &Worker::loadpcf_finished, this, &TaskManager::loadpcf_finished); connect(worker, &Worker::pack_finished, this, &TaskManager::pack_finished); connect(worker, &Worker::budget_finish, this, &TaskManager::budget_finish); connect(worker, &Worker::place_finished, this, &TaskManager::place_finished); diff --git a/gui/ice40/worker.h b/gui/ice40/worker.h index d599e993..2995a851 100644 --- a/gui/ice40/worker.h +++ b/gui/ice40/worker.h @@ -35,6 +35,7 @@ class Worker : public QObject Worker(Context *ctx, TaskManager *parent); public Q_SLOTS: void loadfile(const std::string &); + void loadpcf(const std::string &); void pack(); void budget(double freq); void place(bool timing_driven); @@ -42,6 +43,7 @@ class Worker : public QObject Q_SIGNALS: void log(const std::string &text); void loadfile_finished(bool status); + void loadpcf_finished(bool status); void pack_finished(bool status); void budget_finish(bool status); void place_finished(bool status); @@ -73,6 +75,7 @@ class TaskManager : public QObject Q_SIGNALS: void terminate(); void loadfile(const std::string &); + void loadpcf(const std::string &); void pack(); void budget(double freq); void place(bool timing_driven); @@ -81,6 +84,7 @@ class TaskManager : public QObject // redirected signals void log(const std::string &text); void loadfile_finished(bool status); + void loadpcf_finished(bool status); void pack_finished(bool status); void budget_finish(bool status); void place_finished(bool status);