aboutsummaryrefslogtreecommitdiffstats
path: root/gui/ice40
diff options
context:
space:
mode:
authorMiodrag Milanovic <mmicko@gmail.com>2018-08-02 18:10:01 +0200
committerMiodrag Milanovic <mmicko@gmail.com>2018-08-02 18:10:01 +0200
commita761b772c8294858590c4abced272d04bd58aad3 (patch)
tree82b08104877e382892f4291e1567ab720b11891e /gui/ice40
parent7f7cb6601e52650714358e84c077bf394d295809 (diff)
downloadnextpnr-a761b772c8294858590c4abced272d04bd58aad3.tar.gz
nextpnr-a761b772c8294858590c4abced272d04bd58aad3.tar.bz2
nextpnr-a761b772c8294858590c4abced272d04bd58aad3.zip
Make worker generic
Diffstat (limited to 'gui/ice40')
-rw-r--r--gui/ice40/mainwindow.cc73
-rw-r--r--gui/ice40/mainwindow.h5
-rw-r--r--gui/ice40/worker.cc221
-rw-r--r--gui/ice40/worker.h110
4 files changed, 27 insertions, 382 deletions
diff --git a/gui/ice40/mainwindow.cc b/gui/ice40/mainwindow.cc
index f06971b6..bc790296 100644
--- a/gui/ice40/mainwindow.cc
+++ b/gui/ice40/mainwindow.cc
@@ -47,9 +47,6 @@ MainWindow::MainWindow(std::unique_ptr<Context> context, ArchArgs args, QWidget
task = new TaskManager();
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(saveasc_finished(bool)), this, SLOT(saveasc_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)));
@@ -238,19 +235,34 @@ void MainWindow::new_proj()
}
}
-void MainWindow::load_json(std::string filename, std::string pcf)
+void MainWindow::load_json(std::string filename)
{
disableActions();
currentJson = filename;
- currentPCF = pcf;
- Q_EMIT task->loadfile(filename);
+ std::ifstream f(filename);
+ if (parse_json_file(f, filename, ctx.get())) {
+ log("Loading design successful.\n");
+ actionLoadPCF->setEnabled(true);
+ actionPack->setEnabled(true);
+ Q_EMIT updateTreeView();
+ } else {
+ actionLoadJSON->setEnabled(true);
+ log("Loading design failed.\n");
+ }
}
void MainWindow::load_pcf(std::string filename)
{
disableActions();
currentPCF = filename;
- Q_EMIT task->loadpcf(filename);
+ std::ifstream f(filename);
+ if (apply_pcf(ctx.get(), f)) {
+ log("Loading PCF successful.\n");
+ actionPack->setEnabled(true);
+ } else {
+ actionLoadPCF->setEnabled(true);
+ log("Loading PCF failed.\n");
+ }
}
void MainWindow::newContext(Context *ctx)
@@ -331,7 +343,9 @@ void MainWindow::open_proj()
}
log_info("Loading json: %s...\n", json.c_str());
- load_json(json, pcf);
+ load_json(json);
+ if (!pcf.empty())
+ load_pcf(json);
} catch (log_execution_error_exception) {
}
}
@@ -341,7 +355,7 @@ void MainWindow::open_json()
{
QString fileName = QFileDialog::getOpenFileName(this, QString("Open JSON"), QString(), QString("*.json"));
if (!fileName.isEmpty()) {
- load_json(fileName.toStdString(), "");
+ load_json(fileName.toStdString());
}
}
@@ -389,7 +403,9 @@ void MainWindow::save_asc()
if (!fileName.isEmpty()) {
std::string fn = fileName.toStdString();
disableActions();
- Q_EMIT task->saveasc(fn);
+ std::ofstream f(fn);
+ write_asc(ctx.get(), f);
+ log("Saving ASC successful.\n");
}
}
@@ -412,43 +428,6 @@ void MainWindow::disableActions()
actionSave->setEnabled(!currentJson.empty());
}
-void MainWindow::loadfile_finished(bool status)
-{
- disableActions();
- if (status) {
- log("Loading design successful.\n");
- actionLoadPCF->setEnabled(true);
- actionPack->setEnabled(true);
- if (!currentPCF.empty())
- load_pcf(currentPCF);
- Q_EMIT updateTreeView();
- } else {
- log("Loading design failed.\n");
- currentPCF = "";
- }
-}
-
-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::saveasc_finished(bool status)
-{
- disableActions();
- if (status) {
- log("Saving ASC successful.\n");
- } else {
- log("Saving ASC failed.\n");
- }
-}
-
void MainWindow::pack_finished(bool status)
{
disableActions();
diff --git a/gui/ice40/mainwindow.h b/gui/ice40/mainwindow.h
index 4600d1da..b71af162 100644
--- a/gui/ice40/mainwindow.h
+++ b/gui/ice40/mainwindow.h
@@ -35,7 +35,7 @@ class MainWindow : public BaseMainWindow
public:
void createMenu();
- void load_json(std::string filename, std::string pcf);
+ void load_json(std::string filename);
void load_pcf(std::string filename);
protected Q_SLOTS:
virtual void new_proj();
@@ -48,9 +48,6 @@ class MainWindow : public BaseMainWindow
void place();
void save_asc();
- void loadfile_finished(bool status);
- void loadpcf_finished(bool status);
- void saveasc_finished(bool status);
void pack_finished(bool status);
void budget_finish(bool status);
void place_finished(bool status);
diff --git a/gui/ice40/worker.cc b/gui/ice40/worker.cc
deleted file mode 100644
index 09093ec8..00000000
--- a/gui/ice40/worker.cc
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * nextpnr -- Next Generation Place and Route
- *
- * Copyright (C) 2018 Miodrag Milanovic <miodrag@symbioticeda.com>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
-#include "worker.h"
-#include <fstream>
-#include "bitstream.h"
-#include "design_utils.h"
-#include "jsonparse.h"
-#include "log.h"
-#include "pcf.h"
-#include "timing.h"
-
-NEXTPNR_NAMESPACE_BEGIN
-
-struct WorkerInterruptionRequested
-{
-};
-
-Worker::Worker(TaskManager *parent) : ctx(nullptr)
-{
- log_write_function = [this, parent](std::string text) {
- Q_EMIT log(text);
- if (parent->shouldTerminate()) {
- parent->clearTerminate();
- throw WorkerInterruptionRequested();
- }
- if (parent->isPaused()) {
- Q_EMIT taskPaused();
- }
- while (parent->isPaused()) {
- if (parent->shouldTerminate()) {
- parent->clearTerminate();
- throw WorkerInterruptionRequested();
- }
- QThread::sleep(1);
- }
- };
-}
-
-void Worker::newContext(Context *ctx_) { ctx = ctx_; }
-
-void Worker::loadfile(const std::string &filename)
-{
- Q_EMIT taskStarted();
- std::string fn = filename;
- std::ifstream f(fn);
- try {
- Q_EMIT loadfile_finished(parse_json_file(f, fn, ctx));
- } catch (WorkerInterruptionRequested) {
- Q_EMIT taskCanceled();
- }
-}
-
-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::saveasc(const std::string &filename)
-{
- Q_EMIT taskStarted();
- std::string fn = filename;
- std::ofstream f(fn);
- try {
- write_asc(ctx, f);
- Q_EMIT saveasc_finished(true);
- } catch (WorkerInterruptionRequested) {
- Q_EMIT taskCanceled();
- }
-}
-
-void Worker::pack()
-{
- Q_EMIT taskStarted();
- try {
- bool res = ctx->pack();
- print_utilisation(ctx);
- Q_EMIT pack_finished(res);
- } catch (WorkerInterruptionRequested) {
- Q_EMIT taskCanceled();
- }
-}
-
-void Worker::budget(double freq)
-{
- Q_EMIT taskStarted();
- try {
- ctx->target_freq = freq;
- assign_budget(ctx);
- Q_EMIT budget_finish(true);
- } catch (WorkerInterruptionRequested) {
- Q_EMIT taskCanceled();
- }
-}
-
-void Worker::place(bool timing_driven)
-{
- Q_EMIT taskStarted();
- try {
- ctx->timing_driven = timing_driven;
- Q_EMIT place_finished(ctx->place());
- } catch (WorkerInterruptionRequested) {
- Q_EMIT taskCanceled();
- }
-}
-
-void Worker::route()
-{
- Q_EMIT taskStarted();
- try {
- Q_EMIT route_finished(ctx->route());
- } catch (WorkerInterruptionRequested) {
- Q_EMIT taskCanceled();
- }
-}
-
-TaskManager::TaskManager() : toTerminate(false), toPause(false)
-{
- Worker *worker = new Worker(this);
- worker->moveToThread(&workerThread);
-
- connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
-
- connect(this, &TaskManager::loadfile, worker, &Worker::loadfile);
- connect(this, &TaskManager::loadpcf, worker, &Worker::loadpcf);
- connect(this, &TaskManager::saveasc, worker, &Worker::saveasc);
- connect(this, &TaskManager::pack, worker, &Worker::pack);
- connect(this, &TaskManager::budget, worker, &Worker::budget);
- connect(this, &TaskManager::place, worker, &Worker::place);
- connect(this, &TaskManager::route, worker, &Worker::route);
-
- connect(this, &TaskManager::contextChanged, worker, &Worker::newContext);
-
- 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::saveasc_finished, this, &TaskManager::saveasc_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);
- connect(worker, &Worker::route_finished, this, &TaskManager::route_finished);
-
- connect(worker, &Worker::taskCanceled, this, &TaskManager::taskCanceled);
- connect(worker, &Worker::taskStarted, this, &TaskManager::taskStarted);
- connect(worker, &Worker::taskPaused, this, &TaskManager::taskPaused);
-
- workerThread.start();
-}
-
-TaskManager::~TaskManager()
-{
- if (workerThread.isRunning())
- terminate_thread();
- workerThread.quit();
- workerThread.wait();
-}
-
-void TaskManager::info(const std::string &result) { Q_EMIT log(result); }
-
-void TaskManager::terminate_thread()
-{
- QMutexLocker locker(&mutex);
- toPause = false;
- toTerminate = true;
-}
-
-bool TaskManager::shouldTerminate()
-{
- QMutexLocker locker(&mutex);
- return toTerminate;
-}
-
-void TaskManager::clearTerminate()
-{
- QMutexLocker locker(&mutex);
- toTerminate = false;
-}
-
-void TaskManager::pause_thread()
-{
- QMutexLocker locker(&mutex);
- toPause = true;
-}
-
-void TaskManager::continue_thread()
-{
- QMutexLocker locker(&mutex);
- toPause = false;
- Q_EMIT taskStarted();
-}
-
-bool TaskManager::isPaused()
-{
- QMutexLocker locker(&mutex);
- return toPause;
-}
-
-NEXTPNR_NAMESPACE_END
diff --git a/gui/ice40/worker.h b/gui/ice40/worker.h
deleted file mode 100644
index f4369535..00000000
--- a/gui/ice40/worker.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * nextpnr -- Next Generation Place and Route
- *
- * Copyright (C) 2018 Miodrag Milanovic <miodrag@symbioticeda.com>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
-#ifndef WORKER_H
-#define WORKER_H
-
-#include <QMutex>
-#include <QThread>
-#include "nextpnr.h"
-
-NEXTPNR_NAMESPACE_BEGIN
-
-class TaskManager;
-
-class Worker : public QObject
-{
- Q_OBJECT
- public:
- explicit Worker(TaskManager *parent);
- public Q_SLOTS:
- void newContext(Context *);
- void loadfile(const std::string &);
- void loadpcf(const std::string &);
- void saveasc(const std::string &);
- void pack();
- void budget(double freq);
- void place(bool timing_driven);
- void route();
- Q_SIGNALS:
- void log(const std::string &text);
- void loadfile_finished(bool status);
- void loadpcf_finished(bool status);
- void saveasc_finished(bool status);
- void pack_finished(bool status);
- void budget_finish(bool status);
- void place_finished(bool status);
- void route_finished(bool status);
- void taskCanceled();
- void taskStarted();
- void taskPaused();
-
- private:
- Context *ctx;
-};
-
-class TaskManager : public QObject
-{
- Q_OBJECT
- QThread workerThread;
-
- public:
- explicit TaskManager();
- ~TaskManager();
- bool shouldTerminate();
- void clearTerminate();
- bool isPaused();
- public Q_SLOTS:
- void info(const std::string &text);
- void terminate_thread();
- void pause_thread();
- void continue_thread();
- Q_SIGNALS:
- void contextChanged(Context *ctx);
- void terminate();
- void loadfile(const std::string &);
- void loadpcf(const std::string &);
- void saveasc(const std::string &);
- void pack();
- void budget(double freq);
- void place(bool timing_driven);
- void route();
-
- // redirected signals
- void log(const std::string &text);
- void loadfile_finished(bool status);
- void loadpcf_finished(bool status);
- void saveasc_finished(bool status);
- void pack_finished(bool status);
- void budget_finish(bool status);
- void place_finished(bool status);
- void route_finished(bool status);
- void taskCanceled();
- void taskStarted();
- void taskPaused();
-
- private:
- QMutex mutex;
- bool toTerminate;
- bool toPause;
-};
-
-NEXTPNR_NAMESPACE_END
-
-#endif // WORKER_H