diff options
| -rw-r--r-- | gui/basewindow.cc | 35 | ||||
| -rw-r--r-- | gui/basewindow.h | 10 | ||||
| -rw-r--r-- | gui/dummy/mainwindow.cc | 9 | ||||
| -rw-r--r-- | gui/dummy/mainwindow.h | 6 | ||||
| -rw-r--r-- | gui/ice40/mainwindow.cc | 21 | ||||
| -rw-r--r-- | gui/ice40/mainwindow.h | 10 | ||||
| -rw-r--r-- | gui/ice40/worker.cc | 58 | ||||
| -rw-r--r-- | gui/ice40/worker.h | 37 | 
8 files changed, 153 insertions, 33 deletions
diff --git a/gui/basewindow.cc b/gui/basewindow.cc index fa9528fc..1e6b171f 100644 --- a/gui/basewindow.cc +++ b/gui/basewindow.cc @@ -3,28 +3,22 @@  #include <QGridLayout>
  #include <QIcon>
  #include <QSplitter>
 -#include <fstream>
  #include "designwidget.h"
  #include "fpgaviewwidget.h"
  #include "jsonparse.h"
  #include "log.h"
  #include "mainwindow.h"
  #include "pythontab.h"
 -//#include "pack.h"
 -//#include "pcf.h"
 -#include "place_sa.h"
 -#include "route.h"
 -//#include "bitstream.h"
 -#include "design_utils.h"
 +
  BaseMainWindow::BaseMainWindow(Context *_ctx, QWidget *parent)
          : QMainWindow(parent), ctx(_ctx)
  {
      Q_INIT_RESOURCE(nextpnr);
 +    qRegisterMetaType<std::string>();
      log_files.clear();
      log_streams.clear();
 -    log_write_function = [this](std::string text) { info->info(text); };
      setObjectName(QStringLiteral("BaseMainWindow"));
      resize(1024, 768);
 @@ -57,7 +51,11 @@ BaseMainWindow::BaseMainWindow(Context *_ctx, QWidget *parent)      tabWidget->addTab(new PythonTab(), "Python");
      info = new InfoTab();
      tabWidget->addTab(info, "Info");
 -    splitter_v->addWidget(new FPGAViewWidget());
 +
 +    centralTabWidget = new QTabWidget();
 +    centralTabWidget->addTab(new FPGAViewWidget(), "Graphics");
 +
 +    splitter_v->addWidget(centralTabWidget);
      splitter_v->addWidget(tabWidget);
  }
 @@ -117,22 +115,3 @@ void BaseMainWindow::createMenusAndBars()      mainToolBar->addAction(actionOpen);
      mainToolBar->addAction(actionSave);
  }
 -
 -void BaseMainWindow::open()
 -{
 -    QString fileName = QFileDialog::getOpenFileName(this, QString(), QString(),
 -                                                    QString("*.json"));
 -    if (!fileName.isEmpty()) {
 -        tabWidget->setCurrentWidget(info);
 -
 -        std::string fn = fileName.toStdString();
 -        std::istream *f = new std::ifstream(fn);
 -
 -        parse_json_file(f, fn, ctx);
 -
 -        // pack_design(ctx);
 -        print_utilisation(ctx);
 -    }
 -}
 -
 -bool BaseMainWindow::save() { return false; }
 diff --git a/gui/basewindow.h b/gui/basewindow.h index 630e0f84..d6915ae9 100644 --- a/gui/basewindow.h +++ b/gui/basewindow.h @@ -14,13 +14,15 @@  // FIXME
  USING_NEXTPNR_NAMESPACE
 +Q_DECLARE_METATYPE(std::string)
 +
  class BaseMainWindow : public QMainWindow
  {
      Q_OBJECT
    public:
      explicit BaseMainWindow(Context *ctx, QWidget *parent = 0);
 -    ~BaseMainWindow();
 +    virtual ~BaseMainWindow();
      Context *getContext() { return ctx; }
    protected:
 @@ -28,12 +30,14 @@ class BaseMainWindow : public QMainWindow    protected Q_SLOTS:
      void writeInfo(std::string text);
 -    void open();
 -    bool save();
 +    
 +    virtual void open() = 0;
 +    virtual bool save() = 0;
    protected:
      Context *ctx;
      QTabWidget *tabWidget;
 +    QTabWidget *centralTabWidget;
      InfoTab *info;
      QMenuBar *menuBar;
 diff --git a/gui/dummy/mainwindow.cc b/gui/dummy/mainwindow.cc index a9420524..f714e30e 100644 --- a/gui/dummy/mainwindow.cc +++ b/gui/dummy/mainwindow.cc @@ -16,3 +16,12 @@ void MainWindow::createMenu()      QMenu *menu_Custom = new QMenu("&Dummy", menuBar);
      menuBar->addAction(menu_Custom->menuAction());
  }
 +
 +void MainWindow::open()
 +{
 +}
 +
 +bool MainWindow::save()
 +{
 +    return false;
 +}
\ No newline at end of file diff --git a/gui/dummy/mainwindow.h b/gui/dummy/mainwindow.h index e9c8ff77..ea4480fb 100644 --- a/gui/dummy/mainwindow.h +++ b/gui/dummy/mainwindow.h @@ -12,10 +12,14 @@ class MainWindow : public BaseMainWindow    public:
      explicit MainWindow(Context *ctx, QWidget *parent = 0);
 -    ~MainWindow();
 +    virtual ~MainWindow();
    public:
      void createMenu();
 +
 +  protected Q_SLOTS:
 +    virtual void open();
 +    virtual bool save();    
  };
  #endif // MAINWINDOW_H
 diff --git a/gui/ice40/mainwindow.cc b/gui/ice40/mainwindow.cc index 3744cdc7..dafd92e9 100644 --- a/gui/ice40/mainwindow.cc +++ b/gui/ice40/mainwindow.cc @@ -1,5 +1,6 @@  #include "mainwindow.h"
  #include <QAction>
 +#include <QFileDialog>
  #include <QIcon>
  #include "bitstream.h"
  #include "design_utils.h"
 @@ -17,6 +18,10 @@ MainWindow::MainWindow(Context *_ctx, QWidget *parent)      setWindowTitle(title.c_str());
      createMenu();
 +
 +    task = new TaskManager(_ctx);
 +    connect(task, SIGNAL(log(std::string)), this,
 +            SLOT(writeInfo(std::string)));
  }
  MainWindow::~MainWindow() {}
 @@ -26,3 +31,19 @@ void MainWindow::createMenu()      QMenu *menu_Custom = new QMenu("&ICE 40", menuBar);
      menuBar->addAction(menu_Custom->menuAction());
  }
 +
 +void MainWindow::open()
 +{
 +    QString fileName = QFileDialog::getOpenFileName(this, QString(), QString(),
 +                                                    QString("*.json"));
 +    if (!fileName.isEmpty()) {
 +        tabWidget->setCurrentWidget(info);
 +
 +        std::string fn = fileName.toStdString();
 +        task->parsejson(fn);
 +    }
 +}
 +bool MainWindow::save()
 +{
 +    return false;
 +}
\ No newline at end of file diff --git a/gui/ice40/mainwindow.h b/gui/ice40/mainwindow.h index e9c8ff77..fd65f9ae 100644 --- a/gui/ice40/mainwindow.h +++ b/gui/ice40/mainwindow.h @@ -2,6 +2,7 @@  #define MAINWINDOW_H
  #include "../basewindow.h"
 +#include "worker.h"
  // FIXME
  USING_NEXTPNR_NAMESPACE
 @@ -12,10 +13,17 @@ class MainWindow : public BaseMainWindow    public:
      explicit MainWindow(Context *ctx, QWidget *parent = 0);
 -    ~MainWindow();
 +    virtual ~MainWindow();
    public:
      void createMenu();
 +
 +  protected Q_SLOTS:
 +    virtual void open();
 +    virtual bool save();
 +
 +  private:
 +    TaskManager *task;
  };
  #endif // MAINWINDOW_H
 diff --git a/gui/ice40/worker.cc b/gui/ice40/worker.cc new file mode 100644 index 00000000..5a8ff0e9 --- /dev/null +++ b/gui/ice40/worker.cc @@ -0,0 +1,58 @@ +#include "worker.h" +#include <fstream> +#include "jsonparse.h" +#include "log.h" +#include "pack.h" +#include "pcf.h" +#include "place_sa.h" +#include "route.h" +#include "bitstream.h" +#include "design_utils.h" +#include "timing.h" + +Worker::Worker(Context *_ctx) : ctx(_ctx) +{ +    log_write_function = [this](std::string text) { Q_EMIT log(text); }; +} + +void Worker::parsejson(const std::string &filename)  +{ +    std::string fn = filename; +    std::istream *f = new std::ifstream(fn); + +    parse_json_file(f, fn, ctx); +    if (!pack_design(ctx)) +        log_error("Packing design failed.\n"); +    double freq = 50e6; +    assign_budget(ctx, freq); +    print_utilisation(ctx); + +    if (!place_design_sa(ctx)) +        log_error("Placing design failed.\n"); +    if (!route_design(ctx)) +        log_error("Routing design failed.\n"); +    print_utilisation(ctx); +    Q_EMIT log("done"); +} + + +TaskManager::TaskManager(Context *ctx)  +{ +    Worker *worker = new Worker(ctx); +    worker->moveToThread(&workerThread); +    connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater); +    connect(this, &TaskManager::parsejson, worker, &Worker::parsejson); +    connect(worker, &Worker::log, this, &TaskManager::info); +    workerThread.start(); +} + +TaskManager::~TaskManager()  +{ +    workerThread.quit(); +    workerThread.wait(); +} + +void TaskManager::info(const std::string &result) +{ +    Q_EMIT log(result); +}
\ No newline at end of file diff --git a/gui/ice40/worker.h b/gui/ice40/worker.h new file mode 100644 index 00000000..5dc25d89 --- /dev/null +++ b/gui/ice40/worker.h @@ -0,0 +1,37 @@ +#ifndef WORKER_H +#define WORKER_H + +#include "nextpnr.h" +#include <QThread> + +// FIXME +USING_NEXTPNR_NAMESPACE + +class Worker : public QObject +{ +    Q_OBJECT +public: +    Worker(Context *ctx); +public Q_SLOTS: +    void parsejson(const std::string &filename); +Q_SIGNALS: +    void log(const std::string &text); +private: +    Context *ctx; +}; + +class TaskManager : public QObject +{ +    Q_OBJECT +    QThread workerThread; +public: +    TaskManager(Context *ctx); +    ~TaskManager(); +public Q_SLOTS: +    void info(const std::string &text); +Q_SIGNALS: +    void parsejson(const std::string &); +    void log(const std::string &text); +}; + +#endif // WORKER_H  | 
