diff --git a/CMakeLists.txt b/CMakeLists.txt index 83fca6ab..24de0758 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -238,14 +238,7 @@ else() endif() if (BUILD_GUI) - # Find the Qt6/5 libraries find_package(Qt6 COMPONENTS Core Widgets OpenGL OpenGLWidgets QUIET) - if (Qt6_FOUND) - message(STATUS "Using Qt6") - else() - message(STATUS "Using Qt5") - find_package(Qt5 COMPONENTS Core Widgets OpenGL REQUIRED) - endif() # For higher quality backtraces set(CMAKE_ENABLE_EXPORTS ON) diff --git a/README.md b/README.md index 9a6c5cd9..72474724 100644 --- a/README.md +++ b/README.md @@ -195,7 +195,7 @@ sudo make install ### GUI -The nextpnr GUI is not built by default, to reduce the number of dependencies for a standard headless build. To enable it, add `-DBUILD_GUI=ON` to the CMake command line and ensure that Qt5/Qt6 and OpenGL are available: +The nextpnr GUI is not built by default, to reduce the number of dependencies for a standard headless build. To enable it, add `-DBUILD_GUI=ON` to the CMake command line and ensure that Qt6 and OpenGL are available: For Qt6: - On Ubuntu 22.04 LTS or later, install `qt6-base-dev` @@ -203,13 +203,6 @@ For Qt6: - For Homebrew, install `qt6` and add qt6 in path: `echo 'export PATH="/usr/local/opt/qt/bin:$PATH"' >> ~/.bash_profile` ` - this change is effective in next terminal session, so please re-open terminal window before building -For Qt5: - - On Ubuntu 22.04 LTS, install `qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools` - - On other Ubuntu versions, install `qt5-default` - - For MSVC vcpkg, install `qt5-base` (32-bit) or `qt5-base:x64-windows` (64-bit) - - For Homebrew, install `qt5` and add qt5 in path: `echo 'export PATH="/usr/local/opt/qt/bin:$PATH"' >> ~/.bash_profile` -` - this change is effective in next terminal session, so please re-open terminal window before building - ### Multiple architectures To build nextpnr for multiple architectures at once, a semicolon-separated list can be used with `-DARCH`. diff --git a/common/place/placer_heap.cc b/common/place/placer_heap.cc index 96f94266..191c273c 100644 --- a/common/place/placer_heap.cc +++ b/common/place/placer_heap.cc @@ -164,7 +164,6 @@ class HeAPPlacer HeAPPlacer(Context *ctx, PlacerHeapCfg cfg) : ctx(ctx), cfg(cfg), fast_bels(ctx, /*check_bel_available=*/true, -1), tmg(ctx) { - Eigen::initParallel(); tmg.setup_only = true; tmg.setup(); diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt index eb628e7d..60c547b7 100644 --- a/gui/CMakeLists.txt +++ b/gui/CMakeLists.txt @@ -27,17 +27,10 @@ set(GUI_SOURCES ${family}/mainwindow.h ) -if (Qt6_FOUND) - qt6_add_resources(GUI_QT_RESOURCES - base.qrc - ${family}/nextpnr.qrc - ) -else() - qt5_add_resources(GUI_QT_RESOURCES - base.qrc - ${family}/nextpnr.qrc - ) -endif() +qt6_add_resources(GUI_QT_RESOURCES + base.qrc + ${family}/nextpnr.qrc +) add_library(nextpnr-${target}-gui OBJECT ${GUI_SOURCES} diff --git a/gui/designwidget.cc b/gui/designwidget.cc index dfe110e3..1f2c8955 100644 --- a/gui/designwidget.cc +++ b/gui/designwidget.cc @@ -32,6 +32,8 @@ NEXTPNR_NAMESPACE_BEGIN +using QtType = QMetaType::Type; + TreeView::TreeView(QWidget *parent) : QTreeView(parent) {} TreeView::~TreeView() {} @@ -630,27 +632,27 @@ void DesignWidget::onSelectionChanged(int num, const QItemSelection &, const QIt BelId bel = ctx->getBelByName(c); QtProperty *topItem = addTopLevelProperty("Bel"); - addProperty(topItem, QVariant::String, "Name", ctx->nameOfBel(bel)); - addProperty(topItem, QVariant::String, "Type", ctx->getBelType(bel).c_str(ctx)); - addProperty(topItem, QVariant::Bool, "Available", ctx->checkBelAvail(bel)); - addProperty(topItem, QVariant::String, "Bound Cell", ctx->nameOf(ctx->getBoundBelCell(bel)), ElementType::CELL); - addProperty(topItem, QVariant::String, "Bound Cell Type", + addProperty(topItem, QtType::QString, "Name", ctx->nameOfBel(bel)); + addProperty(topItem, QtType::QString, "Type", ctx->getBelType(bel).c_str(ctx)); + addProperty(topItem, QtType::Bool, "Available", ctx->checkBelAvail(bel)); + addProperty(topItem, QtType::QString, "Bound Cell", ctx->nameOf(ctx->getBoundBelCell(bel)), ElementType::CELL); + addProperty(topItem, QtType::QString, "Bound Cell Type", ctx->getBoundBelCell(bel) ? ctx->getBoundBelCell(bel)->type.c_str(ctx) : ""); - addProperty(topItem, QVariant::String, "Conflicting Cell", ctx->nameOf(ctx->getConflictingBelCell(bel)), + addProperty(topItem, QtType::QString, "Conflicting Cell", ctx->nameOf(ctx->getConflictingBelCell(bel)), ElementType::CELL); QtProperty *attrsItem = addSubGroup(topItem, "Attributes"); for (auto &item : ctx->getBelAttrs(bel)) { - addProperty(attrsItem, QVariant::String, item.first.c_str(ctx), item.second.c_str()); + addProperty(attrsItem, QtType::QString, item.first.c_str(ctx), item.second.c_str()); } QtProperty *belpinsItem = addSubGroup(topItem, "Ports"); for (const auto &item : ctx->getBelPins(bel)) { QtProperty *portInfoItem = addSubGroup(belpinsItem, item.c_str(ctx)); - addProperty(portInfoItem, QVariant::String, "Name", item.c_str(ctx)); - addProperty(portInfoItem, QVariant::Int, "Type", int(ctx->getBelPinType(bel, item))); + addProperty(portInfoItem, QtType::QString, "Name", item.c_str(ctx)); + addProperty(portInfoItem, QtType::Int, "Type", int(ctx->getBelPinType(bel, item))); WireId wire = ctx->getBelPinWire(bel, item); - addProperty(portInfoItem, QVariant::String, "Wire", ctx->nameOfWire(wire), ElementType::WIRE); + addProperty(portInfoItem, QtType::QString, "Wire", ctx->nameOfWire(wire), ElementType::WIRE); } } else if (type == ElementType::WIRE) { std::lock_guard lock_ui(ctx->ui_mutex); @@ -659,27 +661,27 @@ void DesignWidget::onSelectionChanged(int num, const QItemSelection &, const QIt WireId wire = ctx->getWireByName(c); QtProperty *topItem = addTopLevelProperty("Wire"); - addProperty(topItem, QVariant::String, "Name", ctx->nameOfWire(wire)); - addProperty(topItem, QVariant::String, "Type", ctx->getWireType(wire).c_str(ctx)); - addProperty(topItem, QVariant::Bool, "Available", ctx->checkWireAvail(wire)); - addProperty(topItem, QVariant::String, "Bound Net", ctx->nameOf(ctx->getBoundWireNet(wire)), ElementType::NET); - addProperty(topItem, QVariant::String, "Conflicting Wire", ctx->nameOfWire(ctx->getConflictingWireWire(wire)), + addProperty(topItem, QtType::QString, "Name", ctx->nameOfWire(wire)); + addProperty(topItem, QtType::QString, "Type", ctx->getWireType(wire).c_str(ctx)); + addProperty(topItem, QtType::Bool, "Available", ctx->checkWireAvail(wire)); + addProperty(topItem, QtType::QString, "Bound Net", ctx->nameOf(ctx->getBoundWireNet(wire)), ElementType::NET); + addProperty(topItem, QtType::QString, "Conflicting Wire", ctx->nameOfWire(ctx->getConflictingWireWire(wire)), ElementType::WIRE); - addProperty(topItem, QVariant::String, "Conflicting Net", ctx->nameOf(ctx->getConflictingWireNet(wire)), + addProperty(topItem, QtType::QString, "Conflicting Net", ctx->nameOf(ctx->getConflictingWireNet(wire)), ElementType::NET); QtProperty *attrsItem = addSubGroup(topItem, "Attributes"); for (auto &item : ctx->getWireAttrs(wire)) { - addProperty(attrsItem, QVariant::String, item.first.c_str(ctx), item.second.c_str()); + addProperty(attrsItem, QtType::QString, item.first.c_str(ctx), item.second.c_str()); } DelayQuad delay = ctx->getWireDelay(wire); QtProperty *delayItem = addSubGroup(topItem, "Delay"); - addProperty(delayItem, QVariant::Double, "Min Rise", delay.minRiseDelay()); - addProperty(delayItem, QVariant::Double, "Max Rise", delay.maxRiseDelay()); - addProperty(delayItem, QVariant::Double, "Min Fall", delay.minFallDelay()); - addProperty(delayItem, QVariant::Double, "Max Fall", delay.maxFallDelay()); + addProperty(delayItem, QtType::Double, "Min Rise", delay.minRiseDelay()); + addProperty(delayItem, QtType::Double, "Max Rise", delay.maxRiseDelay()); + addProperty(delayItem, QtType::Double, "Min Fall", delay.minFallDelay()); + addProperty(delayItem, QtType::Double, "Max Fall", delay.maxFallDelay()); QtProperty *belpinsItem = addSubGroup(topItem, "BelPins"); for (const auto &item : ctx->getWireBelPins(wire)) { @@ -689,17 +691,17 @@ void DesignWidget::onSelectionChanged(int num, const QItemSelection &, const QIt QString pinname = item.pin.c_str(ctx); QtProperty *dhItem = addSubGroup(belpinsItem, belname + "-" + pinname); - addProperty(dhItem, QVariant::String, "Bel", belname, ElementType::BEL); - addProperty(dhItem, QVariant::String, "PortPin", pinname); + addProperty(dhItem, QtType::QString, "Bel", belname, ElementType::BEL); + addProperty(dhItem, QtType::QString, "PortPin", pinname); } int counter = 0; QtProperty *pipsDownItem = addSubGroup(topItem, "Pips Downhill"); for (const auto &item : ctx->getPipsDownhill(wire)) { - addProperty(pipsDownItem, QVariant::String, "", ctx->nameOfPip(item), ElementType::PIP); + addProperty(pipsDownItem, QtType::QString, "", ctx->nameOfPip(item), ElementType::PIP); counter++; if (counter == 50) { - addProperty(pipsDownItem, QVariant::String, "Warning", "Too many items...", ElementType::NONE); + addProperty(pipsDownItem, QtType::QString, "Warning", "Too many items...", ElementType::NONE); break; } } @@ -707,10 +709,10 @@ void DesignWidget::onSelectionChanged(int num, const QItemSelection &, const QIt counter = 0; QtProperty *pipsUpItem = addSubGroup(topItem, "Pips Uphill"); for (const auto &item : ctx->getPipsUphill(wire)) { - addProperty(pipsUpItem, QVariant::String, "", ctx->nameOfPip(item), ElementType::PIP); + addProperty(pipsUpItem, QtType::QString, "", ctx->nameOfPip(item), ElementType::PIP); counter++; if (counter == 50) { - addProperty(pipsUpItem, QVariant::String, "Warning", "Too many items...", ElementType::NONE); + addProperty(pipsUpItem, QtType::QString, "Warning", "Too many items...", ElementType::NONE); break; } } @@ -721,34 +723,34 @@ void DesignWidget::onSelectionChanged(int num, const QItemSelection &, const QIt PipId pip = ctx->getPipByName(c); QtProperty *topItem = addTopLevelProperty("Pip"); - addProperty(topItem, QVariant::String, "Name", ctx->nameOfPip(pip)); - addProperty(topItem, QVariant::String, "Type", ctx->getPipType(pip).c_str(ctx)); - addProperty(topItem, QVariant::Bool, "Available", ctx->checkPipAvail(pip)); - addProperty(topItem, QVariant::String, "Bound Net", ctx->nameOf(ctx->getBoundPipNet(pip)), ElementType::NET); + addProperty(topItem, QtType::QString, "Name", ctx->nameOfPip(pip)); + addProperty(topItem, QtType::QString, "Type", ctx->getPipType(pip).c_str(ctx)); + addProperty(topItem, QtType::Bool, "Available", ctx->checkPipAvail(pip)); + addProperty(topItem, QtType::QString, "Bound Net", ctx->nameOf(ctx->getBoundPipNet(pip)), ElementType::NET); if (ctx->getConflictingPipWire(pip) != WireId()) { - addProperty(topItem, QVariant::String, "Conflicting Wire", ctx->nameOfWire(ctx->getConflictingPipWire(pip)), + addProperty(topItem, QtType::QString, "Conflicting Wire", ctx->nameOfWire(ctx->getConflictingPipWire(pip)), ElementType::WIRE); } else { - addProperty(topItem, QVariant::String, "Conflicting Wire", "", ElementType::NONE); + addProperty(topItem, QtType::QString, "Conflicting Wire", "", ElementType::NONE); } - addProperty(topItem, QVariant::String, "Conflicting Net", ctx->nameOf(ctx->getConflictingPipNet(pip)), + addProperty(topItem, QtType::QString, "Conflicting Net", ctx->nameOf(ctx->getConflictingPipNet(pip)), ElementType::NET); - addProperty(topItem, QVariant::String, "Src Wire", ctx->nameOfWire(ctx->getPipSrcWire(pip)), ElementType::WIRE); - addProperty(topItem, QVariant::String, "Dest Wire", ctx->nameOfWire(ctx->getPipDstWire(pip)), + addProperty(topItem, QtType::QString, "Src Wire", ctx->nameOfWire(ctx->getPipSrcWire(pip)), ElementType::WIRE); + addProperty(topItem, QtType::QString, "Dest Wire", ctx->nameOfWire(ctx->getPipDstWire(pip)), ElementType::WIRE); QtProperty *attrsItem = addSubGroup(topItem, "Attributes"); for (auto &item : ctx->getPipAttrs(pip)) { - addProperty(attrsItem, QVariant::String, item.first.c_str(ctx), item.second.c_str()); + addProperty(attrsItem, QtType::QString, item.first.c_str(ctx), item.second.c_str()); } DelayQuad delay = ctx->getPipDelay(pip); QtProperty *delayItem = addSubGroup(topItem, "Delay"); - addProperty(delayItem, QVariant::Double, "Min Rise", delay.minRiseDelay()); - addProperty(delayItem, QVariant::Double, "Max Rise", delay.maxRiseDelay()); - addProperty(delayItem, QVariant::Double, "Min Fall", delay.minFallDelay()); - addProperty(delayItem, QVariant::Double, "Max Fall", delay.maxFallDelay()); + addProperty(delayItem, QtType::Double, "Min Rise", delay.minRiseDelay()); + addProperty(delayItem, QtType::Double, "Max Rise", delay.maxRiseDelay()); + addProperty(delayItem, QtType::Double, "Min Fall", delay.minFallDelay()); + addProperty(delayItem, QtType::Double, "Max Fall", delay.maxFallDelay()); } else if (type == ElementType::NET) { std::lock_guard lock_ui(ctx->ui_mutex); std::lock_guard lock(ctx->mutex); @@ -757,29 +759,29 @@ void DesignWidget::onSelectionChanged(int num, const QItemSelection &, const QIt QtProperty *topItem = addTopLevelProperty("Net"); - addProperty(topItem, QVariant::String, "Name", net->name.c_str(ctx)); + addProperty(topItem, QtType::QString, "Name", net->name.c_str(ctx)); QtProperty *driverItem = addSubGroup(topItem, "Driver"); - addProperty(driverItem, QVariant::String, "Port", net->driver.port.c_str(ctx)); + addProperty(driverItem, QtType::QString, "Port", net->driver.port.c_str(ctx)); if (net->driver.cell) - addProperty(driverItem, QVariant::String, "Cell", net->driver.cell->name.c_str(ctx), ElementType::CELL); + addProperty(driverItem, QtType::QString, "Cell", net->driver.cell->name.c_str(ctx), ElementType::CELL); else - addProperty(driverItem, QVariant::String, "Cell", "", ElementType::CELL); + addProperty(driverItem, QtType::QString, "Cell", "", ElementType::CELL); QtProperty *usersItem = addSubGroup(topItem, "Users"); for (auto &item : net->users) { QtProperty *portItem = addSubGroup(usersItem, item.port.c_str(ctx)); - addProperty(portItem, QVariant::String, "Port", item.port.c_str(ctx)); + addProperty(portItem, QtType::QString, "Port", item.port.c_str(ctx)); if (item.cell) - addProperty(portItem, QVariant::String, "Cell", item.cell->name.c_str(ctx), ElementType::CELL); + addProperty(portItem, QtType::QString, "Cell", item.cell->name.c_str(ctx), ElementType::CELL); else - addProperty(portItem, QVariant::String, "Cell", "", ElementType::CELL); + addProperty(portItem, QtType::QString, "Cell", "", ElementType::CELL); } QtProperty *attrsItem = addSubGroup(topItem, "Attributes"); for (auto &item : net->attrs) { - addProperty(attrsItem, QVariant::String, item.first.c_str(ctx), + addProperty(attrsItem, QtType::QString, item.first.c_str(ctx), item.second.is_string ? item.second.as_string().c_str() : item.second.to_string().c_str()); } @@ -788,14 +790,14 @@ void DesignWidget::onSelectionChanged(int num, const QItemSelection &, const QIt auto name = ctx->nameOfWire(item.first); QtProperty *wireItem = addSubGroup(wiresItem, name); - addProperty(wireItem, QVariant::String, "Wire", name, ElementType::WIRE); + addProperty(wireItem, QtType::QString, "Wire", name, ElementType::WIRE); if (item.second.pip != PipId()) - addProperty(wireItem, QVariant::String, "Pip", ctx->nameOfPip(item.second.pip), ElementType::PIP); + addProperty(wireItem, QtType::QString, "Pip", ctx->nameOfPip(item.second.pip), ElementType::PIP); else - addProperty(wireItem, QVariant::String, "Pip", "", ElementType::PIP); + addProperty(wireItem, QtType::QString, "Pip", "", ElementType::PIP); - addProperty(wireItem, QVariant::Int, "Strength", (int)item.second.strength); + addProperty(wireItem, QtType::Int, "Strength", (int)item.second.strength); } } else if (type == ElementType::CELL) { @@ -806,36 +808,36 @@ void DesignWidget::onSelectionChanged(int num, const QItemSelection &, const QIt QtProperty *topItem = addTopLevelProperty("Cell"); - addProperty(topItem, QVariant::String, "Name", cell->name.c_str(ctx)); - addProperty(topItem, QVariant::String, "Type", cell->type.c_str(ctx)); + addProperty(topItem, QtType::QString, "Name", cell->name.c_str(ctx)); + addProperty(topItem, QtType::QString, "Type", cell->type.c_str(ctx)); if (cell->bel != BelId()) - addProperty(topItem, QVariant::String, "Bel", ctx->nameOfBel(cell->bel), ElementType::BEL); + addProperty(topItem, QtType::QString, "Bel", ctx->nameOfBel(cell->bel), ElementType::BEL); else - addProperty(topItem, QVariant::String, "Bel", "", ElementType::BEL); - addProperty(topItem, QVariant::Int, "Bel strength", int(cell->belStrength)); + addProperty(topItem, QtType::QString, "Bel", "", ElementType::BEL); + addProperty(topItem, QtType::Int, "Bel strength", int(cell->belStrength)); QtProperty *cellPortsItem = addSubGroup(topItem, "Ports"); for (auto &item : cell->ports) { PortInfo p = item.second; QtProperty *portInfoItem = addSubGroup(cellPortsItem, p.name.c_str(ctx)); - addProperty(portInfoItem, QVariant::String, "Name", p.name.c_str(ctx)); - addProperty(portInfoItem, QVariant::Int, "Type", int(p.type)); + addProperty(portInfoItem, QtType::QString, "Name", p.name.c_str(ctx)); + addProperty(portInfoItem, QtType::Int, "Type", int(p.type)); if (p.net) - addProperty(portInfoItem, QVariant::String, "Net", p.net->name.c_str(ctx), ElementType::NET); + addProperty(portInfoItem, QtType::QString, "Net", p.net->name.c_str(ctx), ElementType::NET); else - addProperty(portInfoItem, QVariant::String, "Net", "", ElementType::NET); + addProperty(portInfoItem, QtType::QString, "Net", "", ElementType::NET); } QtProperty *cellAttrItem = addSubGroup(topItem, "Attributes"); for (auto &item : cell->attrs) { - addProperty(cellAttrItem, QVariant::String, item.first.c_str(ctx), + addProperty(cellAttrItem, QtType::QString, item.first.c_str(ctx), item.second.is_string ? item.second.as_string().c_str() : item.second.to_string().c_str()); } QtProperty *cellParamsItem = addSubGroup(topItem, "Parameters"); for (auto &item : cell->params) { - addProperty(cellParamsItem, QVariant::String, item.first.c_str(ctx), + addProperty(cellParamsItem, QtType::QString, item.first.c_str(ctx), item.second.is_string ? item.second.as_string().c_str() : item.second.to_string().c_str()); } } diff --git a/gui/pythontab.cc b/gui/pythontab.cc index 36eab471..f47bf7d2 100644 --- a/gui/pythontab.cc +++ b/gui/pythontab.cc @@ -29,9 +29,7 @@ const QString PythonTab::MULTILINE_PROMPT = "... "; PythonTab::PythonTab(QWidget *parent) : QWidget(parent), initialized(false) { - QFont f("unexistent"); - f.setStyleHint(QFont::Monospace); - + const QFont f = QFontDatabase::systemFont(QFontDatabase::FixedFont); // Add text area for Python output and input line console = new PythonConsole(); console->setMinimumHeight(100);