aboutsummaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
Diffstat (limited to 'generic')
-rw-r--r--generic/arch.cc196
-rw-r--r--generic/arch.h115
-rw-r--r--generic/archdefs.h53
-rw-r--r--generic/family.cmake0
-rw-r--r--generic/main.cc139
-rw-r--r--generic/place_legaliser.cc26
-rw-r--r--generic/place_legaliser.h31
-rw-r--r--generic/pybindings.cc32
8 files changed, 592 insertions, 0 deletions
diff --git a/generic/arch.cc b/generic/arch.cc
new file mode 100644
index 00000000..9bdda5ba
--- /dev/null
+++ b/generic/arch.cc
@@ -0,0 +1,196 @@
+/*
+ * nextpnr -- Next Generation Place and Route
+ *
+ * Copyright (C) 2018 Clifford Wolf <clifford@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 <math.h>
+#include "nextpnr.h"
+
+NEXTPNR_NAMESPACE_BEGIN
+
+Arch::Arch(ArchArgs) {}
+
+std::string Arch::getChipName() { return "Generic"; }
+
+void IdString::initialize_arch(const BaseCtx *ctx) {}
+
+// ---------------------------------------------------------------
+
+BelId Arch::getBelByName(IdString name) const { return BelId(); }
+
+IdString Arch::getBelName(BelId bel) const { return IdString(); }
+
+uint32_t Arch::getBelChecksum(BelId bel) const { return 0; }
+
+void Arch::bindBel(BelId bel, IdString cell, PlaceStrength strength) {}
+
+void Arch::unbindBel(BelId bel) {}
+
+bool Arch::checkBelAvail(BelId bel) const { return false; }
+
+IdString Arch::getBoundBelCell(BelId bel) const { return IdString(); }
+
+IdString Arch::getConflictingBelCell(BelId bel) const { return IdString(); }
+
+const std::vector<BelId> &Arch::getBels() const
+{
+ static std::vector<BelId> ret;
+ return ret;
+}
+
+const std::vector<BelId> &Arch::getBelsByType(BelType type) const
+{
+ static std::vector<BelId> ret;
+ return ret;
+}
+
+BelType Arch::getBelType(BelId bel) const { return BelType(); }
+
+WireId Arch::getWireBelPin(BelId bel, PortPin pin) const { return WireId(); }
+
+BelPin Arch::getBelPinUphill(WireId wire) const { return BelPin(); }
+
+const std::vector<BelPin> &Arch::getBelPinsDownhill(WireId wire) const
+{
+ static std::vector<BelPin> ret;
+ return ret;
+}
+
+// ---------------------------------------------------------------
+
+WireId Arch::getWireByName(IdString name) const { return WireId(); }
+
+IdString Arch::getWireName(WireId wire) const { return IdString(); }
+
+uint32_t Arch::getWireChecksum(WireId wire) const { return 0; }
+
+void Arch::bindWire(WireId wire, IdString net, PlaceStrength strength) {}
+
+void Arch::unbindWire(WireId wire) {}
+
+bool Arch::checkWireAvail(WireId wire) const { return false; }
+
+IdString Arch::getBoundWireNet(WireId wire) const { return IdString(); }
+
+IdString Arch::getConflictingWireNet(WireId wire) const { return IdString(); }
+
+const std::vector<WireId> &Arch::getWires() const
+{
+ static std::vector<WireId> ret;
+ return ret;
+}
+
+// ---------------------------------------------------------------
+
+PipId Arch::getPipByName(IdString name) const { return PipId(); }
+
+IdString Arch::getPipName(PipId pip) const { return IdString(); }
+
+uint32_t Arch::getPipChecksum(PipId wire) const { return 0; }
+
+void Arch::bindPip(PipId pip, IdString net, PlaceStrength strength) {}
+
+void Arch::unbindPip(PipId pip) {}
+
+bool Arch::checkPipAvail(PipId pip) const { return false; }
+
+IdString Arch::getBoundPipNet(PipId pip) const { return IdString(); }
+
+IdString Arch::getConflictingPipNet(PipId pip) const { return IdString(); }
+
+const std::vector<PipId> &Arch::getPips() const
+{
+ static std::vector<PipId> ret;
+ return ret;
+}
+
+WireId Arch::getPipSrcWire(PipId pip) const { return WireId(); }
+
+WireId Arch::getPipDstWire(PipId pip) const { return WireId(); }
+
+DelayInfo Arch::getPipDelay(PipId pip) const { return DelayInfo(); }
+
+const std::vector<PipId> &Arch::getPipsDownhill(WireId wire) const
+{
+ static std::vector<PipId> ret;
+ return ret;
+}
+
+const std::vector<PipId> &Arch::getPipsUphill(WireId wire) const
+{
+ static std::vector<PipId> ret;
+ return ret;
+}
+
+const std::vector<PipId> &Arch::getWireAliases(WireId wire) const
+{
+ static std::vector<PipId> ret;
+ return ret;
+}
+
+// ---------------------------------------------------------------
+
+void Arch::estimatePosition(BelId bel, int &x, int &y, bool &gb) const
+{
+ x = 0;
+ y = 0;
+ gb = false;
+}
+
+delay_t Arch::estimateDelay(WireId src, WireId dst) const { return 0.0; }
+
+// ---------------------------------------------------------------
+
+std::vector<GraphicElement> Arch::getFrameGraphics() const
+{
+ static std::vector<GraphicElement> ret;
+ return ret;
+}
+
+std::vector<GraphicElement> Arch::getBelGraphics(BelId bel) const
+{
+ static std::vector<GraphicElement> ret;
+ return ret;
+}
+
+std::vector<GraphicElement> Arch::getWireGraphics(WireId wire) const
+{
+ static std::vector<GraphicElement> ret;
+ return ret;
+}
+
+std::vector<GraphicElement> Arch::getPipGraphics(PipId pip) const
+{
+ static std::vector<GraphicElement> ret;
+ return ret;
+}
+
+// ---------------------------------------------------------------
+
+bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, delay_t &delay) const
+{
+ return false;
+}
+
+IdString Arch::getPortClock(const CellInfo *cell, IdString port) const { return IdString(); }
+
+bool Arch::isClockPort(const CellInfo *cell, IdString port) const { return false; }
+
+bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const { return true; }
+bool Arch::isBelLocationValid(BelId bel) const { return true; }
+
+NEXTPNR_NAMESPACE_END
diff --git a/generic/arch.h b/generic/arch.h
new file mode 100644
index 00000000..ae68b974
--- /dev/null
+++ b/generic/arch.h
@@ -0,0 +1,115 @@
+/*
+ * nextpnr -- Next Generation Place and Route
+ *
+ * Copyright (C) 2018 Clifford Wolf <clifford@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 NEXTPNR_H
+#error Include "arch.h" via "nextpnr.h" only.
+#endif
+
+NEXTPNR_NAMESPACE_BEGIN
+
+struct ArchArgs
+{
+};
+
+struct Arch : BaseCtx
+{
+ Arch(ArchArgs args);
+
+ std::string getChipName();
+
+ virtual IdString id(const std::string &s) const { abort(); }
+ virtual IdString id(const char *s) const { abort(); }
+
+ IdString archId() const { return id("generic"); }
+ IdString archArgsToId(ArchArgs args) const { return id("none"); }
+
+ IdString belTypeToId(BelType type) const { return type; }
+ IdString portPinToId(PortPin type) const { return type; }
+
+ BelType belTypeFromId(IdString id) const { return id; }
+ PortPin portPinFromId(IdString id) const { return id; }
+
+ BelId getBelByName(IdString name) const;
+ IdString getBelName(BelId bel) const;
+ uint32_t getBelChecksum(BelId bel) const;
+ void bindBel(BelId bel, IdString cell, PlaceStrength strength);
+ void unbindBel(BelId bel);
+ bool checkBelAvail(BelId bel) const;
+ IdString getBoundBelCell(BelId bel) const;
+ IdString getConflictingBelCell(BelId bel) const;
+ const std::vector<BelId> &getBels() const;
+ const std::vector<BelId> &getBelsByType(BelType type) const;
+ BelType getBelType(BelId bel) const;
+ WireId getWireBelPin(BelId bel, PortPin pin) const;
+ BelPin getBelPinUphill(WireId wire) const;
+ const std::vector<BelPin> &getBelPinsDownhill(WireId wire) const;
+
+ WireId getWireByName(IdString name) const;
+ IdString getWireName(WireId wire) const;
+ uint32_t getWireChecksum(WireId wire) const;
+ void bindWire(WireId wire, IdString net, PlaceStrength strength);
+ void unbindWire(WireId wire);
+ bool checkWireAvail(WireId wire) const;
+ IdString getBoundWireNet(WireId wire) const;
+ IdString getConflictingWireNet(WireId wire) const;
+ const std::vector<WireId> &getWires() const;
+
+ PipId getPipByName(IdString name) const;
+ IdString getPipName(PipId pip) const;
+ uint32_t getPipChecksum(PipId pip) const;
+ void bindPip(PipId pip, IdString net, PlaceStrength strength);
+ void unbindPip(PipId pip);
+ bool checkPipAvail(PipId pip) const;
+ IdString getBoundPipNet(PipId pip) const;
+ IdString getConflictingPipNet(PipId pip) const;
+ const std::vector<PipId> &getPips() const;
+ WireId getPipSrcWire(PipId pip) const;
+ WireId getPipDstWire(PipId pip) const;
+ DelayInfo getPipDelay(PipId pip) const;
+ const std::vector<PipId> &getPipsDownhill(WireId wire) const;
+ const std::vector<PipId> &getPipsUphill(WireId wire) const;
+ const std::vector<PipId> &getWireAliases(WireId wire) const;
+
+ void estimatePosition(BelId bel, int &x, int &y, bool &gb) const;
+ delay_t estimateDelay(WireId src, WireId dst) const;
+ delay_t getDelayEpsilon() const { return 0.01; }
+ delay_t getRipupDelayPenalty() const { return 1.0; }
+ float getDelayNS(delay_t v) const { return v; }
+ uint32_t getDelayChecksum(delay_t v) const { return 0; }
+
+ std::vector<GraphicElement> getFrameGraphics() const;
+ std::vector<GraphicElement> getBelGraphics(BelId bel) const;
+ std::vector<GraphicElement> getWireGraphics(WireId wire) const;
+ std::vector<GraphicElement> getPipGraphics(PipId pip) const;
+
+ bool allGraphicsReload = false;
+ bool frameGraphicsReload = false;
+ std::unordered_set<BelId> belGraphicsReload;
+ std::unordered_set<WireId> wireGraphicsReload;
+ std::unordered_set<PipId> pipGraphicsReload;
+
+ bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, delay_t &delay) const;
+ IdString getPortClock(const CellInfo *cell, IdString port) const;
+ bool isClockPort(const CellInfo *cell, IdString port) const;
+
+ bool isValidBelForCell(CellInfo *cell, BelId bel) const;
+ bool isBelLocationValid(BelId bel) const;
+};
+
+NEXTPNR_NAMESPACE_END
diff --git a/generic/archdefs.h b/generic/archdefs.h
new file mode 100644
index 00000000..9e8462e0
--- /dev/null
+++ b/generic/archdefs.h
@@ -0,0 +1,53 @@
+/*
+ * nextpnr -- Next Generation Place and Route
+ *
+ * Copyright (C) 2018 Clifford Wolf <clifford@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 NEXTPNR_H
+#error Include "archdefs.h" via "nextpnr.h" only.
+#endif
+
+NEXTPNR_NAMESPACE_BEGIN
+
+typedef float delay_t;
+
+struct DelayInfo
+{
+ delay_t delay = 0;
+
+ delay_t raiseDelay() const { return delay; }
+
+ delay_t fallDelay() const { return delay; }
+
+ delay_t avgDelay() const { return delay; }
+
+ DelayInfo operator+(const DelayInfo &other) const
+ {
+ DelayInfo ret;
+ ret.delay = this->delay + other.delay;
+ return ret;
+ }
+};
+
+typedef IdString BelType;
+typedef IdString PortPin;
+
+typedef IdString BelId;
+typedef IdString WireId;
+typedef IdString PipId;
+
+NEXTPNR_NAMESPACE_END
diff --git a/generic/family.cmake b/generic/family.cmake
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/generic/family.cmake
diff --git a/generic/main.cc b/generic/main.cc
new file mode 100644
index 00000000..d025d8d4
--- /dev/null
+++ b/generic/main.cc
@@ -0,0 +1,139 @@
+/*
+ * nextpnr -- Next Generation Place and Route
+ *
+ * Copyright (C) 2018 Clifford Wolf <clifford@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.
+ *
+ */
+
+#ifdef MAIN_EXECUTABLE
+
+#ifndef NO_GUI
+#include <QApplication>
+#include "application.h"
+#include "mainwindow.h"
+#endif
+#ifndef NO_PYTHON
+#include "pybindings.h"
+#endif
+#include <boost/filesystem/convenience.hpp>
+#include <boost/program_options.hpp>
+#include <iostream>
+#include "log.h"
+#include "nextpnr.h"
+#include "version.h"
+
+USING_NEXTPNR_NAMESPACE
+
+int main(int argc, char *argv[])
+{
+ try {
+
+ namespace po = boost::program_options;
+ int rc = 0;
+
+ log_files.push_back(stdout);
+
+ po::options_description options("Allowed options");
+ options.add_options()("help,h", "show help");
+ options.add_options()("verbose,v", "verbose output");
+ options.add_options()("force,f", "keep running after errors");
+#ifndef NO_GUI
+ options.add_options()("gui", "start gui");
+#endif
+
+ po::positional_options_description pos;
+#ifndef NO_PYTHON
+ options.add_options()("run", po::value<std::vector<std::string>>(), "python file to execute");
+ pos.add("run", -1);
+#endif
+ options.add_options()("version,V", "show version");
+
+ po::variables_map vm;
+ try {
+ po::parsed_options parsed = po::command_line_parser(argc, argv).options(options).positional(pos).run();
+
+ po::store(parsed, vm);
+
+ po::notify(vm);
+ }
+
+ catch (std::exception &e) {
+ std::cout << e.what() << "\n";
+ return 1;
+ }
+
+ if (vm.count("help") || argc == 1) {
+ std::cout << boost::filesystem::basename(argv[0])
+ << " -- Next Generation Place and Route (git "
+ "sha1 " GIT_COMMIT_HASH_STR ")\n";
+ std::cout << "\n";
+ std::cout << options << "\n";
+ return argc != 1;
+ }
+
+ if (vm.count("version")) {
+ std::cout << boost::filesystem::basename(argv[0])
+ << " -- Next Generation Place and Route (git "
+ "sha1 " GIT_COMMIT_HASH_STR ")\n";
+ return 1;
+ }
+
+ Context ctx(ArchArgs{});
+
+ if (vm.count("verbose")) {
+ ctx.verbose = true;
+ }
+
+ if (vm.count("force")) {
+ ctx.force = true;
+ }
+
+ if (vm.count("seed")) {
+ ctx.rngseed(vm["seed"].as<int>());
+ }
+
+#ifndef NO_PYTHON
+ if (vm.count("run")) {
+ init_python(argv[0], true);
+ python_export_global("ctx", ctx);
+
+ std::vector<std::string> files = vm["run"].as<std::vector<std::string>>();
+ for (auto filename : files)
+ execute_python_file(filename.c_str());
+
+ deinit_python();
+ }
+#endif
+
+#ifndef NO_GUI
+ if (vm.count("gui")) {
+ Application a(argc, argv);
+ MainWindow w;
+ w.show();
+
+ rc = a.exec();
+ }
+#endif
+ return rc;
+ } catch (log_execution_error_exception) {
+#if defined(_MSC_VER)
+ _exit(EXIT_FAILURE);
+#else
+ _Exit(EXIT_FAILURE);
+#endif
+ }
+}
+
+#endif
diff --git a/generic/place_legaliser.cc b/generic/place_legaliser.cc
new file mode 100644
index 00000000..0d23f15b
--- /dev/null
+++ b/generic/place_legaliser.cc
@@ -0,0 +1,26 @@
+/*
+ * nextpnr -- Next Generation Place and Route
+ *
+ * Copyright (C) 2018 David Shah <david@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 "place_legaliser.h"
+
+NEXTPNR_NAMESPACE_BEGIN
+
+bool legalise_design(Context *ctx) { return true; }
+
+NEXTPNR_NAMESPACE_END
diff --git a/generic/place_legaliser.h b/generic/place_legaliser.h
new file mode 100644
index 00000000..5f4df6aa
--- /dev/null
+++ b/generic/place_legaliser.h
@@ -0,0 +1,31 @@
+/*
+ * nextpnr -- Next Generation Place and Route
+ *
+ * Copyright (C) 2018 David Shah <david@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 PLACE_LEGALISER_H
+#define PLACE_LEGALISER_H
+
+#include "nextpnr.h"
+
+NEXTPNR_NAMESPACE_BEGIN
+
+bool legalise_design(Context *ctx);
+
+NEXTPNR_NAMESPACE_END
+
+#endif
diff --git a/generic/pybindings.cc b/generic/pybindings.cc
new file mode 100644
index 00000000..a2997456
--- /dev/null
+++ b/generic/pybindings.cc
@@ -0,0 +1,32 @@
+/*
+ * nextpnr -- Next Generation Place and Route
+ *
+ * Copyright (C) 2018 Clifford Wolf <clifford@symbioticeda.com>
+ * Copyright (C) 2018 David Shah <dave@ds0.me>
+ *
+ * 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 NO_PYTHON
+
+#include "pybindings.h"
+#include "nextpnr.h"
+
+NEXTPNR_NAMESPACE_BEGIN
+
+void arch_wrap_python() { class_<ArchArgs>("ArchArgs"); }
+
+NEXTPNR_NAMESPACE_END
+
+#endif \ No newline at end of file