diff options
| -rw-r--r-- | ecp5/arch.h | 2 | ||||
| -rw-r--r-- | ecp5/main.cc | 2 | ||||
| -rw-r--r-- | generic/arch.cc | 2 | ||||
| -rw-r--r-- | generic/main.cc | 5 | ||||
| -rw-r--r-- | gui/basewindow.cc | 4 | ||||
| -rw-r--r-- | gui/basewindow.h | 3 | ||||
| -rw-r--r-- | gui/ecp5/mainwindow.cc | 124 | ||||
| -rw-r--r-- | gui/ecp5/mainwindow.h | 18 | ||||
| -rw-r--r-- | gui/ecp5/nextpnr.qrc | 4 | ||||
| -rw-r--r-- | gui/ecp5/resources/open_base.png | bin | 0 -> 2022 bytes | |||
| -rw-r--r-- | gui/ecp5/resources/save_config.png | bin | 0 -> 1428 bytes | |||
| -rw-r--r-- | gui/generic/mainwindow.cc | 10 | ||||
| -rw-r--r-- | gui/generic/mainwindow.h | 3 | ||||
| -rw-r--r-- | gui/ice40/mainwindow.cc | 11 | ||||
| -rw-r--r-- | gui/ice40/mainwindow.h | 2 | 
15 files changed, 165 insertions, 25 deletions
| diff --git a/ecp5/arch.h b/ecp5/arch.h index cd103b12..6daf543d 100644 --- a/ecp5/arch.h +++ b/ecp5/arch.h @@ -384,7 +384,7 @@ struct PipRange  struct ArchArgs  { -    enum +    enum ArchArgsTypes      {          NONE,          LFE5U_25F, diff --git a/ecp5/main.cc b/ecp5/main.cc index dac7a635..dde3ffed 100644 --- a/ecp5/main.cc +++ b/ecp5/main.cc @@ -148,7 +148,7 @@ int main(int argc, char *argv[])  #ifndef NO_GUI          if (vm.count("gui")) {              Application a(argc, argv); -            MainWindow w(std::move(ctx)); +            MainWindow w(std::move(ctx),args);              w.show();              return a.exec(); diff --git a/generic/arch.cc b/generic/arch.cc index f9133f9e..7c0828e0 100644 --- a/generic/arch.cc +++ b/generic/arch.cc @@ -175,7 +175,7 @@ void Arch::setGroupDecal(GroupId group, DecalXY decalxy)  // --------------------------------------------------------------- -Arch::Arch(ArchArgs) {} +Arch::Arch(ArchArgs) : chipName("generic") {}  void IdString::initialize_arch(const BaseCtx *ctx) {} diff --git a/generic/main.cc b/generic/main.cc index 3b8b3fe6..8653da01 100644 --- a/generic/main.cc +++ b/generic/main.cc @@ -90,7 +90,8 @@ int main(int argc, char *argv[])              return 1;          } -        std::unique_ptr<Context> ctx = std::unique_ptr<Context>(new Context(ArchArgs{})); +        ArchArgs chipArgs{}; +        std::unique_ptr<Context> ctx = std::unique_ptr<Context>(new Context(chipArgs));          if (vm.count("verbose")) {              ctx->verbose = true; @@ -107,7 +108,7 @@ int main(int argc, char *argv[])  #ifndef NO_GUI          if (vm.count("gui")) {              Application a(argc, argv); -            MainWindow w(std::move(ctx)); +            MainWindow w(std::move(ctx), chipArgs);              w.show();              return a.exec(); diff --git a/gui/basewindow.cc b/gui/basewindow.cc index 37141fd6..53720156 100644 --- a/gui/basewindow.cc +++ b/gui/basewindow.cc @@ -37,8 +37,8 @@ static void initBasenameResource() { Q_INIT_RESOURCE(base); }  NEXTPNR_NAMESPACE_BEGIN
 -BaseMainWindow::BaseMainWindow(std::unique_ptr<Context> context, QWidget *parent)
 -        : QMainWindow(parent), ctx(std::move(context)), timing_driven(false)
 +BaseMainWindow::BaseMainWindow(std::unique_ptr<Context> context, ArchArgs args, QWidget *parent)
 +        : QMainWindow(parent), chipArgs(args), ctx(std::move(context)), timing_driven(false)
  {
      initBasenameResource();
      qRegisterMetaType<std::string>();
 diff --git a/gui/basewindow.h b/gui/basewindow.h index 5cec24c5..341cc8e2 100644 --- a/gui/basewindow.h +++ b/gui/basewindow.h @@ -45,7 +45,7 @@ class BaseMainWindow : public QMainWindow      Q_OBJECT
    public:
 -    explicit BaseMainWindow(std::unique_ptr<Context> context, QWidget *parent = 0);
 +    explicit BaseMainWindow(std::unique_ptr<Context> context, ArchArgs args, QWidget *parent = 0);
      virtual ~BaseMainWindow();
      Context *getContext() { return ctx.get(); }
 @@ -88,6 +88,7 @@ class BaseMainWindow : public QMainWindow    protected:
      // state variables
 +    ArchArgs chipArgs;
      std::unique_ptr<Context> ctx;
      TaskManager *task;
      bool timing_driven;
 diff --git a/gui/ecp5/mainwindow.cc b/gui/ecp5/mainwindow.cc index 935daefd..efaad364 100644 --- a/gui/ecp5/mainwindow.cc +++ b/gui/ecp5/mainwindow.cc @@ -18,30 +18,148 @@   */
  #include "mainwindow.h"
 +#include "bitstream.h"
 +#include "log.h"
 +
 +#include <QFileDialog>
 +#include <QInputDialog>
 +#include <QLineEdit>
  static void initMainResource() { Q_INIT_RESOURCE(nextpnr); }
  NEXTPNR_NAMESPACE_BEGIN
 -MainWindow::MainWindow(std::unique_ptr<Context> context, QWidget *parent) : BaseMainWindow(std::move(context), parent)
 +MainWindow::MainWindow(std::unique_ptr<Context> context, ArchArgs args, QWidget *parent) : BaseMainWindow(std::move(context), args, parent)
  {
      initMainResource();
      std::string title = "nextpnr-ecp5 - [EMPTY]";
      setWindowTitle(title.c_str());
 +    connect(this, &BaseMainWindow::contextChanged, this, &MainWindow::newContext);
 +
      createMenu();
      Q_EMIT contextChanged(ctx.get());
  }
  MainWindow::~MainWindow() {}
 -void MainWindow::createMenu() {}
 +void MainWindow::newContext(Context *ctx)
 +{
 +    std::string title = "nextpnr-generic - " + ctx->getChipName() + " ( " + chipArgs.package + " )";
 +    setWindowTitle(title.c_str());
 +}
 +
 +void MainWindow::createMenu() {
 +    // Add arch specific actions
 +    actionLoadBase = new QAction("Open Base Config", this);
 +    actionLoadBase->setIcon(QIcon(":/icons/resources/open_base.png"));
 +    actionLoadBase->setStatusTip("Open Base Config file");
 +    actionLoadBase->setEnabled(false);
 +    connect(actionLoadBase, &QAction::triggered, this, &MainWindow::open_base);
 +
 +    actionSaveConfig = new QAction("Save Bitstream", this);
 +    actionSaveConfig->setIcon(QIcon(":/icons/resources/save_config.png"));
 +    actionSaveConfig->setStatusTip("Save Bitstream config file");
 +    actionSaveConfig->setEnabled(false);
 +    connect(actionSaveConfig, &QAction::triggered, this, &MainWindow::save_config);
 +
 +    // Add actions in menus
 +    mainActionBar->addSeparator();
 +    mainActionBar->addAction(actionLoadBase);
 +    mainActionBar->addAction(actionSaveConfig);
 +
 +    menuDesign->addSeparator();
 +    menuDesign->addAction(actionLoadBase);
 +    menuDesign->addAction(actionSaveConfig);    
 +}
 +
 +static const ChipInfoPOD *get_chip_info(const RelPtr<ChipInfoPOD> *ptr) { return ptr->get(); }
 +
 +static QStringList getSupportedPackages(ArchArgs::ArchArgsTypes chip)
 +{
 +    QStringList packages;
 +    const ChipInfoPOD *chip_info;
 +    if (chip == ArchArgs::LFE5U_25F) {
 +        chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_25k));
 +    } else if (chip == ArchArgs::LFE5U_45F) {
 +        chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_45k));
 +    } else if (chip == ArchArgs::LFE5U_85F) {
 +        chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_85k));
 +    } else {
 +        log_error("Unsupported ECP5 chip type.\n");
 +    }
 +
 +    for (int i = 0; i < chip_info->num_packages; i++) {
 +        packages << chip_info->package_info[i].name.get();
 +    }
 +    return packages;
 +}
 +
 +
 +void MainWindow::new_proj() {
 +    QMap<QString, int> arch;
 +    arch.insert("Lattice ECP5 25K", ArchArgs::LFE5U_25F);
 +    arch.insert("Lattice ECP5 45K", ArchArgs::LFE5U_45F);
 +    arch.insert("Lattice ECP5 85K", ArchArgs::LFE5U_85F);
 +    bool ok;
 +    QString item = QInputDialog::getItem(this, "Select new context", "Chip:", arch.keys(), 0, false, &ok);
 +    if (ok && !item.isEmpty()) {
 -void MainWindow::new_proj() {}
 +        chipArgs.type = (ArchArgs::ArchArgsTypes)arch.value(item);
 +
 +        QString package = QInputDialog::getItem(this, "Select package", "Package:", getSupportedPackages(chipArgs.type),
 +                                                0, false, &ok);
 +
 +        if (ok && !item.isEmpty()) {
 +            currentProj = "";
 +            currentJson = "";
 +            disableActions();
 +            chipArgs.package = package.toStdString().c_str();
 +            ctx = std::unique_ptr<Context>(new Context(chipArgs));
 +            actionLoadJSON->setEnabled(true);
 +
 +            Q_EMIT contextChanged(ctx.get());
 +        }
 +    }
 +}
  void MainWindow::open_proj() {}
  bool MainWindow::save_proj() { return false; }
 +void MainWindow::load_base_config(std::string filename)
 +{
 +    disableActions();
 +    currentBaseConfig = filename;
 +    actionSaveConfig->setEnabled(true);
 +}
 +
 +void MainWindow::open_base()
 +{
 +    QString fileName = QFileDialog::getOpenFileName(this, QString("Open Base Config"), QString(), QString("*.config"));
 +    if (!fileName.isEmpty()) {
 +        load_base_config(fileName.toStdString());
 +    }
 +}
 +
 +void MainWindow::save_config()
 +{
 +    QString fileName = QFileDialog::getSaveFileName(this, QString("Save Bitstream"), QString(), QString("*.config"));
 +    if (!fileName.isEmpty()) {
 +        std::string fn = fileName.toStdString();
 +        disableActions();
 +        write_bitstream(ctx.get(), currentBaseConfig, fileName.toStdString());
 +        log("Saving Bitstream successful.\n");
 +    }
 +}
 +
 +void MainWindow::onDisableActions()
 +{
 +    actionLoadBase->setEnabled(false);
 +    actionSaveConfig->setEnabled(false);
 +}
 +
 +void MainWindow::onRouteFinished() { actionLoadBase->setEnabled(true); }
 +
  NEXTPNR_NAMESPACE_END
 diff --git a/gui/ecp5/mainwindow.h b/gui/ecp5/mainwindow.h index e97bb4e7..d1d5a5a2 100644 --- a/gui/ecp5/mainwindow.h +++ b/gui/ecp5/mainwindow.h @@ -29,16 +29,32 @@ class MainWindow : public BaseMainWindow      Q_OBJECT
    public:
 -    explicit MainWindow(std::unique_ptr<Context> context, QWidget *parent = 0);
 +    explicit MainWindow(std::unique_ptr<Context> context, ArchArgs args, QWidget *parent = 0);
      virtual ~MainWindow();
    public:
      void createMenu();
 +    void load_base_config(std::string filename);
 +
 +  protected:
 +    void onDisableActions() override;
 +    void onRouteFinished() override;
    protected Q_SLOTS:
      virtual void new_proj();
      virtual void open_proj();
      virtual bool save_proj();
 +    void newContext(Context *ctx);
 +    void open_base();
 +    void save_config();
 +  private:
 +    QAction *actionLoadBase;
 +    QAction *actionSaveConfig;
 +
 +    ArchArgs chipArgs;
 +
 +    std::string currentProj;
 +    std::string currentBaseConfig;
  };
  NEXTPNR_NAMESPACE_END
 diff --git a/gui/ecp5/nextpnr.qrc b/gui/ecp5/nextpnr.qrc index 03585ec0..09f96d74 100644 --- a/gui/ecp5/nextpnr.qrc +++ b/gui/ecp5/nextpnr.qrc @@ -1,2 +1,6 @@  <RCC> +    <qresource prefix="/icons"> +        <file>resources/open_base.png</file> +        <file>resources/save_config.png</file> +    </qresource>  </RCC> diff --git a/gui/ecp5/resources/open_base.png b/gui/ecp5/resources/open_base.pngBinary files differ new file mode 100644 index 00000000..d58d226c --- /dev/null +++ b/gui/ecp5/resources/open_base.png diff --git a/gui/ecp5/resources/save_config.png b/gui/ecp5/resources/save_config.pngBinary files differ new file mode 100644 index 00000000..2ade7128 --- /dev/null +++ b/gui/ecp5/resources/save_config.png diff --git a/gui/generic/mainwindow.cc b/gui/generic/mainwindow.cc index 70ee600d..050c0fb8 100644 --- a/gui/generic/mainwindow.cc +++ b/gui/generic/mainwindow.cc @@ -23,19 +23,27 @@ static void initMainResource() { Q_INIT_RESOURCE(nextpnr); }  NEXTPNR_NAMESPACE_BEGIN
 -MainWindow::MainWindow(std::unique_ptr<Context> context, QWidget *parent) : BaseMainWindow(std::move(context), parent)
 +MainWindow::MainWindow(std::unique_ptr<Context> context, ArchArgs args, QWidget *parent) : BaseMainWindow(std::move(context), args, parent)
  {
      initMainResource();
      std::string title = "nextpnr-generic - [EMPTY]";
      setWindowTitle(title.c_str());
 +    connect(this, &BaseMainWindow::contextChanged, this, &MainWindow::newContext);
 +
      createMenu();
      Q_EMIT contextChanged(ctx.get());
  }
  MainWindow::~MainWindow() {}
 +void MainWindow::newContext(Context *ctx)
 +{
 +    std::string title = "nextpnr-generic - " + ctx->getChipName();
 +    setWindowTitle(title.c_str());
 +}
 +
  void MainWindow::createMenu() {}
  void MainWindow::new_proj() {}
 diff --git a/gui/generic/mainwindow.h b/gui/generic/mainwindow.h index e97bb4e7..375436b6 100644 --- a/gui/generic/mainwindow.h +++ b/gui/generic/mainwindow.h @@ -29,7 +29,7 @@ class MainWindow : public BaseMainWindow      Q_OBJECT
    public:
 -    explicit MainWindow(std::unique_ptr<Context> context, QWidget *parent = 0);
 +    explicit MainWindow(std::unique_ptr<Context> context, ArchArgs args, QWidget *parent = 0);
      virtual ~MainWindow();
    public:
 @@ -39,6 +39,7 @@ class MainWindow : public BaseMainWindow      virtual void new_proj();
      virtual void open_proj();
      virtual bool save_proj();
 +    void newContext(Context *ctx);
  };
  NEXTPNR_NAMESPACE_END
 diff --git a/gui/ice40/mainwindow.cc b/gui/ice40/mainwindow.cc index 2fa2e561..40b863e9 100644 --- a/gui/ice40/mainwindow.cc +++ b/gui/ice40/mainwindow.cc @@ -37,7 +37,7 @@ static void initMainResource() { Q_INIT_RESOURCE(nextpnr); }  NEXTPNR_NAMESPACE_BEGIN
  MainWindow::MainWindow(std::unique_ptr<Context> context, ArchArgs args, QWidget *parent)
 -        : BaseMainWindow(std::move(context), parent), chipArgs(args)
 +        : BaseMainWindow(std::move(context), args, parent)
  {
      initMainResource();
 @@ -78,18 +78,11 @@ void MainWindow::createMenu()      menuDesign->addAction(actionSaveAsc);
  }
 -#if defined(_MSC_VER)
 -void load_chipdb();
 -#endif
 -
  static const ChipInfoPOD *get_chip_info(const RelPtr<ChipInfoPOD> *ptr) { return ptr->get(); }
 -QStringList getSupportedPackages(ArchArgs::ArchArgsTypes chip)
 +static QStringList getSupportedPackages(ArchArgs::ArchArgsTypes chip)
  {
      QStringList packages;
 -#if defined(_MSC_VER)
 -    load_chipdb();
 -#endif
      const ChipInfoPOD *chip_info;
  #ifdef ICE40_HX1K_ONLY
      if (chip == ArchArgs::HX1K) {
 diff --git a/gui/ice40/mainwindow.h b/gui/ice40/mainwindow.h index 230ccc4e..829375e2 100644 --- a/gui/ice40/mainwindow.h +++ b/gui/ice40/mainwindow.h @@ -55,8 +55,6 @@ class MainWindow : public BaseMainWindow      QAction *actionLoadPCF;
      QAction *actionSaveAsc;
 -    ArchArgs chipArgs;
 -
      std::string currentProj;
      std::string currentPCF;
  };
 | 
