aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZipCPU <dgisselq@ieee.org>2018-06-07 07:45:22 -0400
committerZipCPU <dgisselq@ieee.org>2018-06-07 07:45:22 -0400
commit1ed5c641c16bffabe96ffd2ef8499dd3ae740050 (patch)
treee7b9417cb4faf44956859289dd6b9dfb579f96d9
parentd7bb30cc66f2ba39c77a979b809a6e6bdfcb5097 (diff)
parented0c44891fb510c8181c2ae9332d7a030f0aaaff (diff)
downloadnextpnr-1ed5c641c16bffabe96ffd2ef8499dd3ae740050.tar.gz
nextpnr-1ed5c641c16bffabe96ffd2ef8499dd3ae740050.tar.bz2
nextpnr-1ed5c641c16bffabe96ffd2ef8499dd3ae740050.zip
Merge branch 'master' into gqtech
-rw-r--r--.clang-format8
-rw-r--r--.gitignore1
-rw-r--r--README.md1
-rw-r--r--common/design.cc1
-rw-r--r--common/design.h119
-rw-r--r--common/pybindings.cc121
-rw-r--r--common/pybindings.h123
-rw-r--r--common/pycontainers.h129
-rw-r--r--common/rulecheck.cc1
-rw-r--r--dummy/chip.cc4
-rw-r--r--dummy/chip.h94
-rw-r--r--dummy/main.cc6
-rw-r--r--dummy/pybindings.cc8
-rw-r--r--gui/mainwindow.cc4
-rw-r--r--ice40/chip.cc752
-rw-r--r--ice40/chip.h879
-rw-r--r--ice40/family.cmake10
-rw-r--r--ice40/main.cc424
-rw-r--r--ice40/pybindings.cc10
-rw-r--r--python/dump_design.py6
-rw-r--r--python/functions.py2
21 files changed, 1501 insertions, 1202 deletions
diff --git a/.clang-format b/.clang-format
index d825df6f..8b3158bb 100644
--- a/.clang-format
+++ b/.clang-format
@@ -47,12 +47,10 @@ DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IncludeCategories:
- - Regex: '^"(llvm|llvm-c|clang|clang-c)/'
- Priority: 2
- - Regex: '^(<|"(gtest|isl|json)/)'
- Priority: 3
- - Regex: '.*'
+ - Regex: '<.*>'
Priority: 1
+ - Regex: '.*'
+ Priority: 2
IndentCaseLabels: false
IndentWidth: 4
IndentWrappedFunctionNames: false
diff --git a/.gitignore b/.gitignore
index a36bdfc5..77f1871d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,3 +18,4 @@ CMakeCache.txt
.*.swp
a.out
*.json
+build/
diff --git a/README.md b/README.md
index 92d055f1..688f3632 100644
--- a/README.md
+++ b/README.md
@@ -21,6 +21,7 @@ Building
- Use CMake to generate the Makefiles (only needs to be done when `CMakeLists.txt` changes)
- For a debug build, run `cmake -DCMAKE_BUILD_TYPE=Debug .`
+ - For a debug build with HX1K support only, run ` cmake -DCMAKE_BUILD_TYPE=Debug -DICE40_HX1K_ONLY=1 .`
- For a release build, run `cmake .`
- Use Make to run the build itself
- For all targets, just run `make`
diff --git a/common/design.cc b/common/design.cc
index 7ba6a9b1..6ab122df 100644
--- a/common/design.cc
+++ b/common/design.cc
@@ -18,4 +18,3 @@
*/
#include "design.h"
-
diff --git a/common/design.h b/common/design.h
index 314c2fd7..f4c24f15 100644
--- a/common/design.h
+++ b/common/design.h
@@ -20,50 +20,52 @@
#ifndef DESIGN_H
#define DESIGN_H
-#include <stdint.h>
#include <assert.h>
-#include <vector>
+#include <stdint.h>
#include <string>
-#include <unordered_set>
#include <unordered_map>
+#include <unordered_set>
+#include <vector>
// replace with proper IdString later
typedef std::string IdString;
// replace with haslib later
-template<typename T> using pool = std::unordered_set<T>;
-template<typename T, typename U> using dict = std::unordered_map<T, U>;
+template <typename T> using pool = std::unordered_set<T>;
+template <typename T, typename U> using dict = std::unordered_map<T, U>;
using std::vector;
struct GraphicElement
{
- // This will control colour, and there should be separate
- // visibility controls in some cases also
- enum {
- // Wires entirely inside tiles, e.g. between switchbox and bels
- G_LOCAL_WIRES,
- // Standard inter-tile routing
- G_GENERAL_WIRES,
- // Special inter-tile wires, e.g. carry chains
- G_DEDICATED_WIRES,
- G_BEL_OUTLINE,
- G_SWITCHBOX_OUTLINE,
- G_TILE_OUTLINE,
- G_BEL_PINS,
- G_SWITCHBOX_PINS,
- G_BEL_MISC,
- G_TILE_MISC,
- } style;
-
- enum {
- G_LINE,
- G_BOX,
- G_CIRCLE,
- G_LABEL
- } type;
-
- float x1, y1, x2, y2, z;
- std::string text;
+ // This will control colour, and there should be separate
+ // visibility controls in some cases also
+ enum
+ {
+ // Wires entirely inside tiles, e.g. between switchbox and bels
+ G_LOCAL_WIRES,
+ // Standard inter-tile routing
+ G_GENERAL_WIRES,
+ // Special inter-tile wires, e.g. carry chains
+ G_DEDICATED_WIRES,
+ G_BEL_OUTLINE,
+ G_SWITCHBOX_OUTLINE,
+ G_TILE_OUTLINE,
+ G_BEL_PINS,
+ G_SWITCHBOX_PINS,
+ G_BEL_MISC,
+ G_TILE_MISC,
+ } style;
+
+ enum
+ {
+ G_LINE,
+ G_BOX,
+ G_CIRCLE,
+ G_LABEL
+ } type;
+
+ float x1, y1, x2, y2, z;
+ std::string text;
};
#include "chip.h"
@@ -72,56 +74,57 @@ struct CellInfo;
struct PortRef
{
- CellInfo *cell;
- IdString port;
+ CellInfo *cell;
+ IdString port;
};
struct NetInfo
{
- IdString name;
- PortRef driver;
- vector<PortRef> users;
- dict<IdString, std::string> attrs;
+ IdString name;
+ PortRef driver;
+ vector<PortRef> users;
+ dict<IdString, std::string> attrs;
- // wire -> (uphill_wire, delay)
- dict<WireId, std::pair<WireId, DelayInfo>> wires;
+ // wire -> (uphill_wire, delay)
+ dict<WireId, std::pair<WireId, DelayInfo>> wires;
};
enum PortType
{
- PORT_IN = 0,
- PORT_OUT = 1,
- PORT_INOUT = 2
+ PORT_IN = 0,
+ PORT_OUT = 1,
+ PORT_INOUT = 2
};
struct PortInfo
{
- IdString name;
- NetInfo *net;
- PortType type;
+ IdString name;
+ NetInfo *net;
+ PortType type;
};
struct CellInfo
{
- IdString name, type;
- dict<IdString, PortInfo> ports;
- dict<IdString, std::string> attrs, params;
+ IdString name, type;
+ dict<IdString, PortInfo> ports;
+ dict<IdString, std::string> attrs, params;
- BelId bel;
- // cell_port -> bel_pin
- dict<IdString, IdString> pins;
+ BelId bel;
+ // cell_port -> bel_pin
+ dict<IdString, IdString> pins;
};
struct Design
{
- struct Chip chip;
+ struct Chip chip;
- Design(ChipArgs args) : chip(args) {
- // ...
- }
+ Design(ChipArgs args) : chip(args)
+ {
+ // ...
+ }
- dict<IdString, NetInfo*> nets;
- dict<IdString, CellInfo*> cells;
+ dict<IdString, NetInfo *> nets;
+ dict<IdString, CellInfo *> cells;
};
#endif
diff --git a/common/pybindings.cc b/common/pybindings.cc
index 556e838e..5c86720e 100644
--- a/common/pybindings.cc
+++ b/common/pybindings.cc
@@ -18,24 +18,89 @@
*
*/
-
-#include "design.h"
#include "chip.h"
+#include "design.h"
+#include "emb.h"
+
+// include after design.h/chip.h
#include "pybindings.h"
-// Required to determine concatenated module name (which differs for different archs)
-#define PASTER(x, y) x ## _ ## y
-#define EVALUATOR(x, y) PASTER(x,y)
+// Required to determine concatenated module name (which differs for different
+// archs)
+#define PASTER(x, y) x##_##y
+#define EVALUATOR(x, y) PASTER(x, y)
#define MODULE_NAME EVALUATOR(nextpnrpy, ARCHNAME)
#define PYINIT_MODULE_NAME EVALUATOR(&PyInit_nextpnrpy, ARCHNAME)
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
-// Architecture-specific bindings should be created in the below function, which must be implemented in all
-// architectures
+// Architecture-specific bindings should be created in the below function, which
+// must be implemented in all architectures
void arch_wrap_python();
-BOOST_PYTHON_MODULE (MODULE_NAME) {
+bool operator==(const PortRef &a, const PortRef &b)
+{
+ return (a.cell == b.cell) && (a.port == b.port);
+}
+
+BOOST_PYTHON_MODULE(MODULE_NAME)
+{
+ class_<GraphicElement>("GraphicElement")
+ .def_readwrite("style", &GraphicElement::style)
+ .def_readwrite("type", &GraphicElement::type)
+ .def_readwrite("x1", &GraphicElement::x1)
+ .def_readwrite("y1", &GraphicElement::y1)
+ .def_readwrite("x2", &GraphicElement::x2)
+ .def_readwrite("y2", &GraphicElement::y2)
+ .def_readwrite("text", &GraphicElement::text);
+
+ class_<PortRef>("PortRef")
+ .def_readwrite("cell", &PortRef::cell)
+ .def_readwrite("port", &PortRef::port);
+
+ class_<NetInfo, NetInfo *>("NetInfo")
+ .def_readwrite("name", &NetInfo::name)
+ .def_readwrite("driver", &NetInfo::driver)
+ .def_readwrite("users", &NetInfo::users)
+ .def_readwrite("attrs", &NetInfo::attrs)
+ .def_readwrite("wires", &NetInfo::wires);
+
+ WRAP_MAP(decltype(NetInfo::attrs), "IdStrMap");
+
+ class_<vector<PortRef>>("PortRefVector")
+ .def(vector_indexing_suite<vector<PortRef>>());
+
+ enum_<PortType>("PortType")
+ .value("PORT_IN", PORT_IN)
+ .value("PORT_OUT", PORT_OUT)
+ .value("PORT_INOUT", PORT_INOUT)
+ .export_values();
+
+ class_<PortInfo>("PortInfo")
+ .def_readwrite("name", &PortInfo::name)
+ .def_readwrite("net", &PortInfo::net)
+ .def_readwrite("type", &PortInfo::type);
+
+ class_<CellInfo, CellInfo *>("CellInfo")
+ .def_readwrite("name", &CellInfo::name)
+ .def_readwrite("type", &CellInfo::type)
+ .def_readwrite("ports", &CellInfo::ports)
+ .def_readwrite("attrs", &CellInfo::attrs)
+ .def_readwrite("params", &CellInfo::params)
+ .def_readwrite("bel", &CellInfo::bel)
+ .def_readwrite("pins", &CellInfo::pins);
+
+ WRAP_MAP(decltype(CellInfo::ports), "IdPortMap");
+ // WRAP_MAP(decltype(CellInfo::pins), "IdIdMap");
+
+ class_<Design, Design *>("Design", no_init)
+ .def_readwrite("chip", &Design::chip)
+ .def_readwrite("nets", &Design::nets)
+ .def_readwrite("cells", &Design::cells);
+
+ WRAP_MAP(decltype(Design::nets), "IdNetMap");
+ WRAP_MAP(decltype(Design::cells), "IdCellMap");
+
arch_wrap_python();
}
@@ -44,35 +109,47 @@ void arch_appendinittab()
PyImport_AppendInittab(TOSTRING(MODULE_NAME), PYINIT_MODULE_NAME);
}
-void execute_python_file(const char *executable, const char* python_file)
+static wchar_t *program;
+
+void init_python(const char *executable)
{
- wchar_t *program = Py_DecodeLocale(executable, NULL);
+ program = Py_DecodeLocale(executable, NULL);
if (program == NULL) {
fprintf(stderr, "Fatal error: cannot decode executable filename\n");
exit(1);
}
- try
- {
+ try {
PyImport_AppendInittab(TOSTRING(MODULE_NAME), PYINIT_MODULE_NAME);
+ emb::append_inittab();
Py_SetProgramName(program);
Py_Initialize();
+ PyImport_ImportModule(TOSTRING(MODULE_NAME));
+ } catch (boost::python::error_already_set const &) {
+ // Parse and output the exception
+ std::string perror_str = parse_python_exception();
+ std::cout << "Error in Python: " << perror_str << std::endl;
+ }
+}
+
+void deinit_python()
+{
+ Py_Finalize();
+ PyMem_RawFree(program);
+}
- FILE* fp = fopen(python_file, "r");
+void execute_python_file(const char *python_file)
+{
+ try {
+ FILE *fp = fopen(python_file, "r");
if (fp == NULL) {
- fprintf(stderr, "Fatal error: file not found %s\n",python_file);
+ fprintf(stderr, "Fatal error: file not found %s\n", python_file);
exit(1);
}
- PyRun_SimpleFile(fp , python_file);
+ PyRun_SimpleFile(fp, python_file);
fclose(fp);
-
- Py_Finalize();
- PyMem_RawFree(program);
- }
- catch(boost::python::error_already_set const &)
- {
+ } catch (boost::python::error_already_set const &) {
// Parse and output the exception
std::string perror_str = parse_python_exception();
std::cout << "Error in Python: " << perror_str << std::endl;
}
}
-
diff --git a/common/pybindings.h b/common/pybindings.h
index f594784c..bb060718 100644
--- a/common/pybindings.h
+++ b/common/pybindings.h
@@ -20,67 +20,98 @@
#ifndef COMMON_PYBINDINGS_H
#define COMMON_PYBINDINGS_H
-#include <utility>
-#include <stdexcept>
+
+#include "pycontainers.h"
+
+#include <Python.h>
#include <boost/python.hpp>
-#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
-#include <boost/python/suite/indexing/map_indexing_suite.hpp>
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
-
+#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
+#include <stdexcept>
+#include <utility>
using namespace boost::python;
+
/*
-A wrapper for a Pythonised nextpnr Iterator. The actual class wrapped is a
-pair<Iterator, Iterator> containing (current, end)
-*/
-
-template<typename T>
-struct iterator_wrapper {
- typedef decltype(*(std::declval<T>())) value_t;
-
- static value_t next(std::pair<T, T> &iter) {
- if (iter.first != iter.second) {
- value_t val = *iter.first;
- ++iter.first;
- return val;
- } else {
- PyErr_SetString(PyExc_StopIteration, "End of range reached");
- boost::python::throw_error_already_set();
- // Should be unreachable, but prevent control may reach end of non-void
- throw std::runtime_error("unreachable");
+A wrapper to enable custom type/ID to/from string conversions
+ */
+template <typename T> struct string_wrapper
+{
+ template <typename F> struct from_pystring_converter
+ {
+ from_pystring_converter()
+ {
+ converter::registry::push_back(&convertible, &construct,
+ boost::python::type_id<T>());
+ };
+
+ static void *convertible(PyObject *object)
+ {
+ return PyUnicode_Check(object) ? object : 0;
}
- }
- static void wrap(const char *python_name) {
- class_<std::pair<T, T>>(python_name, no_init)
- .def("__next__", next);
- }
-};
+ static void construct(PyObject *object,
+ converter::rvalue_from_python_stage1_data *data)
+ {
+ const wchar_t *value = PyUnicode_AsUnicode(object);
+ const std::wstring value_ws(value);
+ if (value == 0)
+ throw_error_already_set();
+ void *storage =
+ ((boost::python::converter::rvalue_from_python_storage<T> *)
+ data)
+ ->storage.bytes;
+ new (storage) T(fn(std::string(value_ws.begin(), value_ws.end())));
+ data->convertible = storage;
+ }
-/*
-A wrapper for a nextpnr Range. Ranges should have two functions, begin()
-and end() which return iterator-like objects supporting ++, * and !=
-Full STL iterator semantics are not required, unlike the standard Boost wrappers
-*/
+ static F fn;
+ };
-template<typename T>
-struct range_wrapper {
- typedef decltype(std::declval<T>().begin()) iterator_t;
+ template <typename F> struct to_str_wrapper
+ {
+ static F fn;
- static std::pair<iterator_t, iterator_t> iter(T &range) {
- return std::make_pair(range.begin(), range.end());
- }
+ std::string str(T &x) { return fn(x); }
+ };
- static void wrap(const char *range_name, const char *iter_name) {
- class_<T>(range_name, no_init)
- .def("__iter__", iter);
- iterator_wrapper<iterator_t>().wrap(iter_name);
+ template <typename F1, typename F2>
+ static void wrap(const char *type_name, F1 to_str_fn, F2 from_str_fn)
+ {
+ from_pystring_converter<F2>::fn = from_str_fn;
+ from_pystring_converter<F2>();
+ to_str_wrapper<F1>::fn = to_str_fn;
+ class_<T>(type_name, no_init).def("__str__", to_str_wrapper<F1>::str);
+ };
+};
+
+std::string parse_python_exception();
+
+template <typename Tn> void python_export_global(const char *name, Tn &x)
+{
+ PyObject *m, *d;
+ m = PyImport_AddModule("__main__");
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+ try {
+ PyObject *p = incref(object(boost::ref(x)).ptr());
+ PyDict_SetItemString(d, name, p);
+ } catch (boost::python::error_already_set const &) {
+ // Parse and output the exception
+ std::string perror_str = parse_python_exception();
+ std::cout << "Error in Python: " << perror_str << std::endl;
+ std::terminate();
}
};
-#define WRAP_RANGE(t) range_wrapper<t##Range>().wrap(#t "Range", #t "Iterator")
+void init_python(const char *executable);
+
+void deinit_python();
+
+void execute_python_file(const char *python_file);
-void execute_python_file(const char *executable, const char* python_file);
std::string parse_python_exception();
+
void arch_appendinittab();
#endif /* end of include guard: COMMON_PYBINDINGS_HH */
diff --git a/common/pycontainers.h b/common/pycontainers.h
new file mode 100644
index 00000000..6e2cdea9
--- /dev/null
+++ b/common/pycontainers.h
@@ -0,0 +1,129 @@
+/*
+ * nextpnr -- Next Generation Place and Route
+ *
+ * Copyright (C) 2018 Clifford Wolf <clifford@clifford.at>
+ * 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 COMMON_PYCONTAINERS_H
+#define COMMON_PYCONTAINERS_H
+
+#include <utility>
+#include <stdexcept>
+#include <type_traits>
+#include <boost/python.hpp>
+#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
+#include <boost/python/suite/indexing/map_indexing_suite.hpp>
+#include <boost/python/suite/indexing/map_indexing_suite.hpp>
+
+using namespace boost::python;
+
+/*
+A wrapper for a Pythonised nextpnr Iterator. The actual class wrapped is a
+pair<Iterator, Iterator> containing (current, end)
+*/
+
+template<typename T, typename P>
+struct iterator_wrapper {
+ typedef decltype(*(std::declval<T>())) value_t;
+
+ static value_t next(std::pair <T, T> &iter) {
+ if (iter.first != iter.second) {
+ value_t val = *iter.first;
+ ++iter.first;
+ return val;
+ } else {
+ PyErr_SetString(PyExc_StopIteration, "End of range reached");
+ boost::python::throw_error_already_set();
+ // Should be unreachable, but prevent control may reach end of non-void
+ throw std::runtime_error("unreachable");
+ }
+ }
+
+ static void wrap(const char *python_name) {
+ class_ < std::pair < T, T >> (python_name, no_init)
+ .def("__next__", next, P());
+ }
+};
+
+/*
+A wrapper for a nextpnr Range. Ranges should have two functions, begin()
+and end() which return iterator-like objects supporting ++, * and !=
+Full STL iterator semantics are not required, unlike the standard Boost wrappers
+*/
+
+template<typename T, typename P = return_value_policy<return_by_value>>
+struct range_wrapper {
+ typedef decltype(std::declval<T>().begin()) iterator_t;
+
+ static std::pair <iterator_t, iterator_t> iter(T &range) {
+ return std::make_pair(range.begin(), range.end());
+ }
+
+ static void wrap(const char *range_name, const char *iter_name) {
+ class_<T>(range_name, no_init)
+ .def("__iter__", iter);
+ iterator_wrapper<iterator_t, P>().wrap(iter_name);
+ }
+ typedef iterator_wrapper<iterator_t, P> iter_wrap;
+};
+
+#define WRAP_RANGE(t) range_wrapper<t##Range>().wrap(#t "Range", #t "Iterator")
+
+/*
+Wrapper for a map, either an unordered_map, regular map or dict
+ */
+inline void KeyError() { PyErr_SetString(PyExc_KeyError, "Key not found"); }
+
+template<typename T>
+struct map_wrapper {
+ typedef typename std::remove_cv<typename std::remove_reference<typename T::key_type>::type>::type K;
+ typedef typename T::mapped_type V;
+ typedef typename T::value_type KV;
+
+ static V &get(T &x, K const &i) {
+ if (x.find(i) != x.end()) return x.at(i);
+ KeyError();
+ std::terminate();
+ }
+
+ static void set(T &x, K const &i, V const &v) {
+ x[i] = v;
+ }
+
+ static void del(T const &x, K const &i) {
+ if (x.find(i) != x.end()) x.erase(i);
+ else KeyError();
+ std::terminate();
+ }
+
+ static void wrap(const char *map_name, const char *kv_name, const char *iter_name) {
+ class_<KV>(kv_name)
+ .def_readonly("first", &KV::first)
+ .def_readwrite("second", &KV::second);
+ typedef range_wrapper<T, return_value_policy<copy_non_const_reference>> rw;
+ typename rw::iter_wrap().wrap(iter_name);
+ class_<T>(map_name, no_init)
+ .def("__iter__", rw::iter)
+ .def("__len__", &T::size)
+ .def("__getitem__", get, return_internal_reference<>())
+ .def("__setitem__", set, with_custodian_and_ward<1,2>());
+ }
+};
+
+#define WRAP_MAP(t, name) map_wrapper<t>().wrap(#name, #name "KeyValue", #name "Iterator")
+
+#endif
diff --git a/common/rulecheck.cc b/common/rulecheck.cc
index b81695b9..28d4b6b7 100644
--- a/common/rulecheck.cc
+++ b/common/rulecheck.cc
@@ -57,5 +57,6 @@ bool check_all_nets_driven(Design *design) {
}
if (debug) log_info(" Verified!\n");
+ return true;
}
diff --git a/dummy/chip.cc b/dummy/chip.cc
index 51a6a840..642984ca 100644
--- a/dummy/chip.cc
+++ b/dummy/chip.cc
@@ -19,6 +19,4 @@
#include "chip.h"
-Chip::Chip(ChipArgs)
-{
-}
+Chip::Chip(ChipArgs) {}
diff --git a/dummy/chip.h b/dummy/chip.h
index 054e822b..8c66fb96 100644
--- a/dummy/chip.h
+++ b/dummy/chip.h
@@ -24,10 +24,10 @@
struct DelayInfo
{
- float delay = 0;
+ float delay = 0;
- float raiseDelay() { return delay; }
- float fallDelay() { return delay; }
+ float raiseDelay() { return delay; }
+ float fallDelay() { return delay; }
};
typedef IdString BelType;
@@ -45,8 +45,8 @@ typedef IdString PipId;
struct BelPin
{
- BelId bel;
- PortPin pin;
+ BelId bel;
+ PortPin pin;
};
struct ChipArgs
@@ -55,48 +55,48 @@ struct ChipArgs
struct Chip
{
- Chip(ChipArgs args);
-
- BelId getBelByName(IdString name) const;
-
- IdString getBelName(BelId bel) const;
- void bindBel(BelId bel, IdString cell);
- void unbindBel(BelId bel);
- bool checkBelAvail(BelId bel) const;
- const vector<BelId> &getBels() const;
- const vector<BelId> &getBelsByType(BelType type) const;
- BelType getBelType(BelId bel) const;
- WireId getWireBelPin(BelId bel, PortPin pin) const;
- BelPin getBelPinUphill(WireId wire) const;
- const vector<BelPin> &getBelPinsDownhill(WireId wire) const;
-
- WireId getWireByName(IdString name) const;
- IdString getWireName(WireId wire) const;
- void bindWire(WireId bel, IdString net);
- void unbindWire(WireId bel);
- bool checkWireAvail(WireId bel) const;
- const vector<WireId> &getWires() const;
-
- PipId getPipByName(IdString name) const;
- IdString getPipName(PipId pip) const;
- void bindPip(PipId bel, IdString net);
- void unbindPip(PipId bel);
- bool checkPipAvail(PipId bel) const;
- const vector<PipId> &getPips() const;
- WireId getPipSrcWire(PipId pip) const;
- WireId getPipDstWire(PipId pip) const;
- DelayInfo getPipDelay(PipId pip) const;
- const vector<PipId> &getPipsDownhill(WireId wire) const;
- const vector<PipId> &getPipsUphill(WireId wire) const;
- const vector<PipId> &getWireAliases(WireId wire) const;
-
- void getBelPosition(BelId bel, float &x, float &y) const;
- void getWirePosition(WireId wire, float &x, float &y) const;
- void getPipPosition(PipId pip, float &x, float &y) const;
- vector<GraphicElement> getBelGraphics(BelId bel) const;
- vector<GraphicElement> getWireGraphics(WireId wire) const;
- vector<GraphicElement> getPipGraphics(PipId pip) const;
- vector<GraphicElement> getFrameGraphics() const;
+ Chip(ChipArgs args);
+
+ BelId getBelByName(IdString name) const;
+
+ IdString getBelName(BelId bel) const;
+ void bindBel(BelId bel, IdString cell);
+ void unbindBel(BelId bel);
+ bool checkBelAvail(BelId bel) const;
+ const vector<BelId> &getBels() const;
+ const vector<BelId> &getBelsByType(BelType type) const;
+ BelType getBelType(BelId bel) const;
+ WireId getWireBelPin(BelId bel, PortPin pin) const;
+ BelPin getBelPinUphill(WireId wire) const;
+ const vector<BelPin> &getBelPinsDownhill(WireId wire) const;
+
+ WireId getWireByName(IdString name) const;
+ IdString getWireName(WireId wire) const;
+ void bindWire(WireId bel, IdString net);
+ void unbindWire(WireId bel);
+ bool checkWireAvail(WireId bel) const;
+ const vector<WireId> &getWires() const;
+
+ PipId getPipByName(IdString name) const;
+ IdString getPipName(PipId pip) const;
+ void bindPip(PipId bel, IdString net);
+ void unbindPip(PipId bel);
+ bool checkPipAvail(PipId bel) const;
+ const vector<PipId> &getPips() const;
+ WireId getPipSrcWire(PipId pip) const;
+ WireId getPipDstWire(PipId pip) const;
+ DelayInfo getPipDelay(PipId pip) const;
+ const vector<PipId> &getPipsDownhill(WireId wire) const;
+ const vector<PipId> &getPipsUphill(WireId wire) const;
+ const vector<PipId> &getWireAliases(WireId wire) const;
+
+ void getBelPosition(BelId bel, float &x, float &y) const;
+ void getWirePosition(WireId wire, float &x, float &y) const;
+ void getPipPosition(PipId pip, float &x, float &y) const;
+ vector<GraphicElement> getBelGraphics(BelId bel) const;
+ vector<GraphicElement> getWireGraphics(WireId wire) const;
+ vector<GraphicElement> getPipGraphics(PipId pip) const;
+ vector<GraphicElement> getFrameGraphics() const;
};
#endif
diff --git a/dummy/main.cc b/dummy/main.cc
index 5c36a961..cc6addb5 100644
--- a/dummy/main.cc
+++ b/dummy/main.cc
@@ -17,15 +17,15 @@
*
*/
+#include <QApplication>
#include "design.h"
#include "mainwindow.h"
-#include <QApplication>
int main(int argc, char *argv[])
{
- Design design(ChipArgs{});
+ Design design(ChipArgs{});
- QApplication a(argc, argv);
+ QApplication a(argc, argv);
MainWindow w;
w.show();
diff --git a/dummy/pybindings.cc b/dummy/pybindings.cc
index a19479a0..12e0ca13 100644
--- a/dummy/pybindings.cc
+++ b/dummy/pybindings.cc
@@ -18,10 +18,10 @@
*
*/
-#include "design.h"
#include "chip.h"
+#include "design.h"
+
+// include after design.h/chip.h
#include "pybindings.h"
-void arch_wrap_python() {
- class_<ChipArgs>("ChipArgs");
-}
+void arch_wrap_python() { class_<ChipArgs>("ChipArgs"); }
diff --git a/gui/mainwindow.cc b/gui/mainwindow.cc
index 4404fc5a..b72a0851 100644
--- a/gui/mainwindow.cc
+++ b/gui/mainwindow.cc
@@ -11,9 +11,6 @@ MainWindow::MainWindow(QWidget *parent) :
ui(new Ui::MainWindow)
{
ui->setupUi(this);
- emb::append_inittab();
- arch_appendinittab();
- Py_Initialize();
PyImport_ImportModule("emb");
write = [this] (std::string s) {
@@ -27,7 +24,6 @@ MainWindow::MainWindow(QWidget *parent) :
MainWindow::~MainWindow()
{
- Py_Finalize();
delete ui;
}
diff --git a/ice40/chip.cc b/ice40/chip.cc
index d1226b3a..4ba7697d 100644
--- a/ice40/chip.cc
+++ b/ice40/chip.cc
@@ -23,460 +23,470 @@
IdString belTypeToId(BelType type)
{
- if (type == TYPE_ICESTORM_LC)
- return "ICESTORM_LC";
- if (type == TYPE_ICESTORM_RAM)
- return "ICESTORM_RAM";
- if (type == TYPE_SB_IO)
- return "SB_IO";
- return IdString();
+ if (type == TYPE_ICESTORM_LC)
+ return "ICESTORM_LC";
+ if (type == TYPE_ICESTORM_RAM)
+ return "ICESTORM_RAM";
+ if (type == TYPE_SB_IO)
+ return "SB_IO";
+ return IdString();
}
BelType belTypeFromId(IdString id)
{
- if (id == "ICESTORM_LC")
- return TYPE_ICESTORM_LC;
- if (id == "ICESTORM_RAM")
- return TYPE_ICESTORM_RAM;
- if (id == "SB_IO")
- return TYPE_SB_IO;
- return TYPE_NIL;
+ if (id == "ICESTORM_LC")
+ return TYPE_ICESTORM_LC;
+ if (id == "ICESTORM_RAM")
+ return TYPE_ICESTORM_RAM;
+ if (id == "SB_IO")
+ return TYPE_SB_IO;
+ return TYPE_NIL;
}
// -----------------------------------------------------------------------
IdString PortPinToId(PortPin type)
{
-#define X(t) if (type == PIN_##t) return #t;
-
- X(IN_0)
- X(IN_1)
- X(IN_2)
- X(IN_3)
- X(O)
- X(LO)
- X(CIN)
- X(COUT)
- X(CEN)
- X(CLK)
- X(SR)
-
- X(MASK_0)
- X(MASK_1)
- X(MASK_2)
- X(MASK_3)
- X(MASK_4)
- X(MASK_5)
- X(MASK_6)
- X(MASK_7)
- X(MASK_8)
- X(MASK_9)
- X(MASK_10)
- X(MASK_11)
- X(MASK_12)
- X(MASK_13)
- X(MASK_14)
- X(MASK_15)
-
- X(RDATA_0)
- X(RDATA_1)
- X(RDATA_2)
- X(RDATA_3)
- X(RDATA_4)
- X(RDATA_5)
- X(RDATA_6)
- X(RDATA_7)
- X(RDATA_8)
- X(RDATA_9)
- X(RDATA_10)
- X(RDATA_11)
- X(RDATA_12)
- X(RDATA_13)
- X(RDATA_14)
- X(RDATA_15)
-
- X(WDATA_0)
- X(WDATA_1)
- X(WDATA_2)
- X(WDATA_3)
- X(WDATA_4)
- X(WDATA_5)
- X(WDATA_6)
- X(WDATA_7)
- X(WDATA_8)
- X(WDATA_9)
- X(WDATA_10)
- X(WDATA_11)
- X(WDATA_12)
- X(WDATA_13)
- X(WDATA_14)
- X(WDATA_15)
-
- X(WADDR_0)
- X(WADDR_1)
- X(WADDR_2)
- X(WADDR_3)
- X(WADDR_4)
- X(WADDR_5)
- X(WADDR_6)
- X(WADDR_7)
- X(WADDR_8)
- X(WADDR_9)
- X(WADDR_10)
-
- X(RADDR_0)
- X(RADDR_1)
- X(RADDR_2)
- X(RADDR_3)
- X(RADDR_4)
- X(RADDR_5)
- X(RADDR_6)
- X(RADDR_7)
- X(RADDR_8)
- X(RADDR_9)
- X(RADDR_10)
-
- X(WCLK)
- X(WCLKE)
- X(WE)
-
- X(RCLK)
- X(RCLKE)
- X(RE)
-
- X(PACKAGE_PIN)
- X(LATCH_INPUT_VALUE)
- X(CLOCK_ENABLE)
- X(INPUT_CLK)
- X(OUTPUT_CLK)
- X(OUTPUT_ENABLE)
- X(D_OUT_0)
- X(D_OUT_1)
- X(D_IN_0)
- X(D_IN_1)
+#define X(t) \
+ if (type == PIN_##t) \
+ return #t;
+
+ X(IN_0)
+ X(IN_1)
+ X(IN_2)
+ X(IN_3)
+ X(O)
+ X(LO)
+ X(CIN)
+ X(COUT)
+ X(CEN)
+ X(CLK)
+ X(SR)
+
+ X(MASK_0)
+ X(MASK_1)
+ X(MASK_2)
+ X(MASK_3)
+ X(MASK_4)
+ X(MASK_5)
+ X(MASK_6)
+ X(MASK_7)
+ X(MASK_8)
+ X(MASK_9)
+ X(MASK_10)
+ X(MASK_11)
+ X(MASK_12)
+ X(MASK_13)
+ X(MASK_14)
+ X(MASK_15)
+
+ X(RDATA_0)
+ X(RDATA_1)
+ X(RDATA_2)
+ X(RDATA_3)
+ X(RDATA_4)
+ X(RDATA_5)
+ X(RDATA_6)
+ X(RDATA_7)
+ X(RDATA_8)
+ X(RDATA_9)
+ X(RDATA_10)
+ X(RDATA_11)
+ X(RDATA_12)
+ X(RDATA_13)
+ X(RDATA_14)
+ X(RDATA_15)
+
+ X(WDATA_0)
+ X(WDATA_1)
+ X(WDATA_2)
+ X(WDATA_3)
+ X(WDATA_4)
+ X(WDATA_5)
+ X(WDATA_6)
+ X(WDATA_7)
+ X(WDATA_8)
+ X(WDATA_9)
+ X(WDATA_10)
+ X(WDATA_11)
+ X(WDATA_12)
+ X(WDATA_13)
+ X(WDATA_14)
+ X(WDATA_15)
+
+ X(WADDR_0)
+ X(WADDR_1)
+ X(WADDR_2)
+ X(WADDR_3)
+ X(WADDR_4)
+ X(WADDR_5)
+ X(WADDR_6)
+ X(WADDR_7)
+ X(WADDR_8)
+ X(WADDR_9)
+ X(WADDR_10)
+
+ X(RADDR_0)
+ X(RADDR_1)
+ X(RADDR_2)
+ X(RADDR_3)
+ X(RADDR_4)
+ X(RADDR_5)
+ X(RADDR_6)
+ X(RADDR_7)
+ X(RADDR_8)
+ X(RADDR_9)
+ X(RADDR_10)
+
+ X(WCLK)
+ X(WCLKE)
+ X(WE)
+
+ X(RCLK)
+ X(RCLKE)
+ X(RE)
+
+ X(PACKAGE_PIN)
+ X(LATCH_INPUT_VALUE)
+ X(CLOCK_ENABLE)
+ X(INPUT_CLK)
+ X(OUTPUT_CLK)
+ X(OUTPUT_ENABLE)
+ X(D_OUT_0)
+ X(D_OUT_1)
+ X(D_IN_0)
+ X(D_IN_1)
#undef X
- return IdString();
+ return IdString();
}
PortPin PortPinFromId(IdString id)
{
-#define X(t) if (id == #t) return PIN_##t;
-
- X(IN_0)
- X(IN_1)
- X(IN_2)
- X(IN_3)
- X(O)
- X(LO)
- X(CIN)
- X(COUT)
- X(CEN)
- X(CLK)
- X(SR)
-
- X(MASK_0)
- X(MASK_1)
- X(MASK_2)
- X(MASK_3)
- X(MASK_4)
- X(MASK_5)
- X(MASK_6)
- X(MASK_7)
- X(MASK_8)
- X(MASK_9)
- X(MASK_10)
- X(MASK_11)
- X(MASK_12)
- X(MASK_13)
- X(MASK_14)
- X(MASK_15)
-
- X(RDATA_0)
- X(RDATA_1)
- X(RDATA_2)
- X(RDATA_3)
- X(RDATA_4)
- X(RDATA_5)
- X(RDATA_6)
- X(RDATA_7)
- X(RDATA_8)
- X(RDATA_9)
- X(RDATA_10)
- X(RDATA_11)
- X(RDATA_12)
- X(RDATA_13)
- X(RDATA_14)
- X(RDATA_15)
-
- X(WDATA_0)
- X(WDATA_1)
- X(WDATA_2)
- X(WDATA_3)
- X(WDATA_4)
- X(WDATA_5)
- X(WDATA_6)
- X(WDATA_7)
- X(WDATA_8)
- X(WDATA_9)
- X(WDATA_10)
- X(WDATA_11)
- X(WDATA_12)
- X(WDATA_13)
- X(WDATA_14)
- X(WDATA_15)
-
- X(WADDR_0)
- X(WADDR_1)
- X(WADDR_2)
- X(WADDR_3)
- X(WADDR_4)
- X(WADDR_5)
- X(WADDR_6)
- X(WADDR_7)
- X(WADDR_8)
- X(WADDR_9)
- X(WADDR_10)
-
- X(RADDR_0)
- X(RADDR_1)
- X(RADDR_2)
- X(RADDR_3)
- X(RADDR_4)
- X(RADDR_5)
- X(RADDR_6)
- X(RADDR_7)
- X(RADDR_8)
- X(RADDR_9)
- X(RADDR_10)
-
- X(WCLK)
- X(WCLKE)
- X(WE)
-
- X(RCLK)
- X(RCLKE)
- X(RE)
-
- X(PACKAGE_PIN)
- X(LATCH_INPUT_VALUE)
- X(CLOCK_ENABLE)
- X(INPUT_CLK)
- X(OUTPUT_CLK)
- X(OUTPUT_ENABLE)
- X(D_OUT_0)
- X(D_OUT_1)
- X(D_IN_0)
- X(D_IN_1)
+#define X(t) \
+ if (id == #t) \
+ return PIN_##t;
+
+ X(IN_0)
+ X(IN_1)
+ X(IN_2)
+ X(IN_3)
+ X(O)
+ X(LO)
+ X(CIN)
+ X(COUT)
+ X(CEN)
+ X(CLK)
+ X(SR)
+
+ X(MASK_0)
+ X(MASK_1)
+ X(MASK_2)
+ X(MASK_3)
+ X(MASK_4)
+ X(MASK_5)
+ X(MASK_6)
+ X(MASK_7)
+ X(MASK_8)
+ X(MASK_9)
+ X(MASK_10)
+ X(MASK_11)
+ X(MASK_12)
+ X(MASK_13)
+ X(MASK_14)
+ X(MASK_15)
+
+ X(RDATA_0)
+ X(RDATA_1)
+ X(RDATA_2)
+ X(RDATA_3)
+ X(RDATA_4)
+ X(RDATA_5)
+ X(RDATA_6)
+ X(RDATA_7)
+ X(RDATA_8)
+ X(RDATA_9)
+ X(RDATA_10)
+ X(RDATA_11)
+ X(RDATA_12)
+ X(RDATA_13)
+ X(RDATA_14)
+ X(RDATA_15)
+
+ X(WDATA_0)
+ X(WDATA_1)
+ X(WDATA_2)
+ X(WDATA_3)
+ X(WDATA_4)
+ X(WDATA_5)
+ X(WDATA_6)
+ X(WDATA_7)
+ X(WDATA_8)
+ X(WDATA_9)
+ X(WDATA_10)
+ X(WDATA_11)
+ X(WDATA_12)
+ X(WDATA_13)
+ X(WDATA_14)
+ X(WDATA_15)
+
+ X(WADDR_0)
+ X(WADDR_1)
+ X(WADDR_2)
+ X(WADDR_3)
+ X(WADDR_4)
+ X(WADDR_5)
+ X(WADDR_6)
+ X(WADDR_7)
+ X(WADDR_8)
+ X(WADDR_9)
+ X(WADDR_10)
+
+ X(RADDR_0)
+ X(RADDR_1)
+ X(RADDR_2)
+ X(RADDR_3)
+ X(RADDR_4)
+ X(RADDR_5)
+ X(RADDR_6)
+ X(RADDR_7)
+ X(RADDR_8)
+ X(RADDR_9)
+ X(RADDR_10)
+
+ X(WCLK)
+ X(WCLKE)
+ X(WE)
+
+ X(RCLK)
+ X(RCLKE)
+ X(RE)
+
+ X(PACKAGE_PIN)
+ X(LATCH_INPUT_VALUE)
+ X(CLOCK_ENABLE)
+ X(INPUT_CLK)
+ X(OUTPUT_CLK)
+ X(OUTPUT_ENABLE)
+ X(D_OUT_0)
+ X(D_OUT_1)
+ X(D_IN_0)
+ X(D_IN_1)
#undef X
- return PIN_NIL;
+ return PIN_NIL;
}
// -----------------------------------------------------------------------
Chip::Chip(ChipArgs args)
{
- if (args.type == ChipArgs::LP384) {
- chip_info = chip_info_384;
- return;
- } else if (args.type == ChipArgs::LP1K || args.type == ChipArgs::HX1K) {
- chip_info = chip_info_1k;
- return;
- } else if (args.type == ChipArgs::UP5K) {
- chip_info = chip_info_5k;
- return;
- } else if (args.type == ChipArgs::LP8K || args.type == ChipArgs::HX8K) {
- chip_info = chip_info_8k;
- return;
- } else {
- fprintf(stderr, "Unsupported chip type\n");
- exit(EXIT_FAILURE);
- }
-
- abort();
+#ifdef ICE40_HX1K_ONLY
+ if (args.type == ChipArgs::HX1K) {
+ chip_info = chip_info_1k;
+ return;
+ }
+#else
+ if (args.type == ChipArgs::LP384) {
+ chip_info = chip_info_384;
+ return;
+ } else if (args.type == ChipArgs::LP1K || args.type == ChipArgs::HX1K) {
+ chip_info = chip_info_1k;
+ return;
+ } else if (args.type == ChipArgs::UP5K) {
+ chip_info = chip_info_5k;
+ return;
+ } else if (args.type == ChipArgs::LP8K || args.type == ChipArgs::HX8K) {
+ chip_info = chip_info_8k;
+ return;
+ } else {
+ fprintf(stderr, "Unsupported chip type\n");
+ exit(EXIT_FAILURE);
+ }
+#endif
+
+ abort();
}
// -----------------------------------------------------------------------
BelId Chip::getBelByName(IdString name) const
{
- BelId ret;
+ BelId ret;
- if (bel_by_name.empty()) {
- for (int i = 0; i < chip_info.num_bels; i++)
- bel_by_name[chip_info.bel_data[i].name] = i;
- }
+ if (bel_by_name.empty()) {
+ for (int i = 0; i < chip_info.num_bels; i++)
+ bel_by_name[chip_info.bel_data[i].name] = i;
+ }
- auto it = bel_by_name.find(name);
- if (it != bel_by_name.end())
- ret.index = it->second;
+ auto it = bel_by_name.find(name);
+ if (it != bel_by_name.end())
+ ret.index = it->second;
- return ret;
+ return ret;
}
WireId Chip::getWireBelPin(BelId bel, PortPin pin) const
{
- // FIXME
- return WireId();
+ // FIXME
+ return WireId();
}
// -----------------------------------------------------------------------
WireId Chip::getWireByName(IdString name) const
{
- WireId ret;
+ WireId ret;
- if (wire_by_name.empty()) {
- for (int i = 0; i < chip_info.num_wires; i++)
- wire_by_name[chip_info.wire_data[i].name] = i;
- }
+ if (wire_by_name.empty()) {
+ for (int i = 0; i < chip_info.num_wires; i++)
+ wire_by_name[chip_info.wire_data[i].name] = i;
+ }
- auto it = wire_by_name.find(name);
- if (it != wire_by_name.end())
- ret.index = it->second;
+ auto it = wire_by_name.find(name);
+ if (it != wire_by_name.end())
+ ret.index = it->second;
- return ret;
+ return ret;
}
// -----------------------------------------------------------------------
PipId Chip::getPipByName(IdString name) const
{
- PipId ret;
+ PipId ret;
- if (pip_by_name.empty()) {
- for (int i = 0; i < chip_info.num_pips; i++) {
- PipId pip;
- pip.index = i;
- pip_by_name[getPipName(pip)] = i;
- }
- }
+ if (pip_by_name.empty()) {
+ for (int i = 0; i < chip_info.num_pips; i++) {
+ PipId pip;
+ pip.index = i;
+ pip_by_name[getPipName(pip)] = i;
+ }
+ }
- auto it = pip_by_name.find(name);
- if (it != pip_by_name.end())
- ret.index = it->second;
+ auto it = pip_by_name.find(name);
+ if (it != pip_by_name.end())
+ ret.index = it->second;
- return ret;
+ return ret;
}
// -----------------------------------------------------------------------
void Chip::getBelPosition(BelId bel, float &x, float &y) const
{
- assert(!bel.nil());
- x = chip_info.bel_data[bel.index].x;
- y = chip_info.bel_data[bel.index].y;
+ assert(!bel.nil());
+ x = chip_info.bel_data[bel.index].x;
+ y = chip_info.bel_data[bel.index].y;
}
void Chip::getWirePosition(WireId wire, float &x, float &y) const
{
- assert(!wire.nil());
- x = chip_info.wire_data[wire.index].x;
- y = chip_info.wire_data[wire.index].y;
+ assert(!wire.nil());
+ x = chip_info.wire_data[wire.index].x;
+ y = chip_info.wire_data[wire.index].y;
}
void Chip::getPipPosition(PipId pip, float &x, float &y) const
{
- assert(!pip.nil());
- x = chip_info.pip_data[pip.index].x;
- y = chip_info.pip_data[pip.index].y;
+ assert(!pip.nil());
+ x = chip_info.pip_data[pip.index].x;
+ y = chip_info.pip_data[pip.index].y;
}
vector<GraphicElement> Chip::getBelGraphics(BelId bel) const
{
- vector<GraphicElement> ret;
-
- auto bel_type = getBelType(bel);
-
- if (bel_type == TYPE_ICESTORM_LC) {
- GraphicElement el;
- el.type = GraphicElement::G_BOX;
- el.x1 = chip_info.bel_data[bel.index].x + 0.1;
- el.x2 = chip_info.bel_data[bel.index].x + 0.9;
- el.y1 = chip_info.bel_data[bel.index].y + 0.10 + (chip_info.bel_data[bel.index].z) * (0.8/8);
- el.y2 = chip_info.bel_data[bel.index].y + 0.18 + (chip_info.bel_data[bel.index].z) * (0.8/8);
- el.z = 0;
- ret.push_back(el);
- }
-
- if (bel_type == TYPE_SB_IO) {
- if (chip_info.bel_data[bel.index].x == 0 || chip_info.bel_data[bel.index].x == chip_info.width-1)
- {
- GraphicElement el;
- el.type = GraphicElement::G_BOX;
- el.x1 = chip_info.bel_data[bel.index].x + 0.1;
- el.x2 = chip_info.bel_data[bel.index].x + 0.9;
- if (chip_info.bel_data[bel.index].z == 0) {
- el.y1 = chip_info.bel_data[bel.index].y + 0.10;
- el.y2 = chip_info.bel_data[bel.index].y + 0.45;
- } else {
- el.y1 = chip_info.bel_data[bel.index].y + 0.55;
- el.y2 = chip_info.bel_data[bel.index].y + 0.90;
- }
- el.z = 0;
- ret.push_back(el);
- }
- else
- {
- GraphicElement el;
- el.type = GraphicElement::G_BOX;
- if (chip_info.bel_data[bel.index].z == 0) {
- el.x1 = chip_info.bel_data[bel.index].x + 0.10;
- el.x2 = chip_info.bel_data[bel.index].x + 0.45;
- } else {
- el.x1 = chip_info.bel_data[bel.index].x + 0.55;
- el.x2 = chip_info.bel_data[bel.index].x + 0.90;
- }
- el.y1 = chip_info.bel_data[bel.index].y + 0.1;
- el.y2 = chip_info.bel_data[bel.index].y + 0.9;
- el.z = 0;
- ret.push_back(el);
- }
- }
-
- if (bel_type == TYPE_ICESTORM_RAM) {
- GraphicElement el;
- el.type = GraphicElement::G_BOX;
- el.x1 = chip_info.bel_data[bel.index].x + 0.1;
- el.x2 = chip_info.bel_data[bel.index].x + 0.9;
- el.y1 = chip_info.bel_data[bel.index].y + 0.1;
- el.y2 = chip_info.bel_data[bel.index].y + 1.9;
- el.z = 0;
- ret.push_back(el);
- }
-
- return ret;
+ vector<GraphicElement> ret;
+
+ auto bel_type = getBelType(bel);
+
+ if (bel_type == TYPE_ICESTORM_LC) {
+ GraphicElement el;
+ el.type = GraphicElement::G_BOX;
+ el.x1 = chip_info.bel_data[bel.index].x + 0.1;
+ el.x2 = chip_info.bel_data[bel.index].x + 0.9;
+ el.y1 = chip_info.bel_data[bel.index].y + 0.10 +
+ (chip_info.bel_data[bel.index].z) * (0.8 / 8);
+ el.y2 = chip_info.bel_data[bel.index].y + 0.18 +
+ (chip_info.bel_data[bel.index].z) * (0.8 / 8);
+ el.z = 0;
+ ret.push_back(el);
+ }
+
+ if (bel_type == TYPE_SB_IO) {
+ if (chip_info.bel_data[bel.index].x == 0 ||
+ chip_info.bel_data[bel.index].x == chip_info.width - 1) {
+ GraphicElement el;
+ el.type = GraphicElement::G_BOX;
+ el.x1 = chip_info.bel_data[bel.index].x + 0.1;
+ el.x2 = chip_info.bel_data[bel.index].x + 0.9;
+ if (chip_info.bel_data[bel.index].z == 0) {
+ el.y1 = chip_info.bel_data[bel.index].y + 0.10;
+ el.y2 = chip_info.bel_data[bel.index].y + 0.45;
+ } else {
+ el.y1 = chip_info.bel_data[bel.index].y + 0.55;
+ el.y2 = chip_info.bel_data[bel.index].y + 0.90;
+ }
+ el.z = 0;
+ ret.push_back(el);
+ } else {
+ GraphicElement el;
+ el.type = GraphicElement::G_BOX;
+ if (chip_info.bel_data[bel.index].z == 0) {
+ el.x1 = chip_info.bel_data[bel.index].x + 0.10;
+ el.x2 = chip_info.bel_data[bel.index].x + 0.45;
+ } else {
+ el.x1 = chip_info.bel_data[bel.index].x + 0.55;
+ el.x2 = chip_info.bel_data[bel.index].x + 0.90;
+ }
+ el.y1 = chip_info.bel_data[bel.index].y + 0.1;
+ el.y2 = chip_info.bel_data[bel.index].y + 0.9;
+ el.z = 0;
+ ret.push_back(el);
+ }
+ }
+
+ if (bel_type == TYPE_ICESTORM_RAM) {
+ GraphicElement el;
+ el.type = GraphicElement::G_BOX;
+ el.x1 = chip_info.bel_data[bel.index].x + 0.1;
+ el.x2 = chip_info.bel_data[bel.index].x + 0.9;
+ el.y1 = chip_info.bel_data[bel.index].y + 0.1;
+ el.y2 = chip_info.bel_data[bel.index].y + 1.9;
+ el.z = 0;
+ ret.push_back(el);
+ }
+
+ return ret;
}
vector<GraphicElement> Chip::getWireGraphics(WireId wire) const
{
- vector<GraphicElement> ret;
- // FIXME
- return ret;
+ vector<GraphicElement> ret;
+ // FIXME
+ return ret;
}
vector<GraphicElement> Chip::getPipGraphics(PipId pip) const
{
- vector<GraphicElement> ret;
- // FIXME
- return ret;
+ vector<GraphicElement> ret;
+ // FIXME
+ return ret;
}
vector<GraphicElement> Chip::getFrameGraphics() const
{
- vector<GraphicElement> ret;
-
- for (int x = 0; x <= chip_info.width; x++)
- for (int y = 0; y <= chip_info.height; y++)
- {
- GraphicElement el;
- el.type = GraphicElement::G_LINE;
- el.x1 = x - 0.05, el.x2 = x + 0.05, el.y1 = y, el.y2 = y, el.z = 0;
- ret.push_back(el);
- el.x1 = x, el.x2 = x, el.y1 = y - 0.05, el.y2 = y + 0.05, el.z = 0;
- ret.push_back(el);
- }
-
- return ret;
+ vector<GraphicElement> ret;
+
+ for (int x = 0; x <= chip_info.width; x++)
+ for (int y = 0; y <= chip_info.height; y++) {
+ GraphicElement el;
+ el.type = GraphicElement::G_LINE;
+ el.x1 = x - 0.05, el.x2 = x + 0.05, el.y1 = y, el.y2 = y, el.z = 0;
+ ret.push_back(el);
+ el.x1 = x, el.x2 = x, el.y1 = y - 0.05, el.y2 = y + 0.05, el.z = 0;
+ ret.push_back(el);
+ }
+
+ return ret;
}
diff --git a/ice40/chip.h b/ice40/chip.h
index 2f0a1284..695eea48 100644
--- a/ice40/chip.h
+++ b/ice40/chip.h
@@ -24,20 +24,20 @@
struct DelayInfo
{
- float delay = 0;
+ float delay = 0;
- float raiseDelay() { return delay; }
- float fallDelay() { return delay; }
+ float raiseDelay() { return delay; }
+ float fallDelay() { return delay; }
};
// -----------------------------------------------------------------------
enum BelType
{
- TYPE_NIL,
- TYPE_ICESTORM_LC,
- TYPE_ICESTORM_RAM,
- TYPE_SB_IO
+ TYPE_NIL,
+ TYPE_ICESTORM_LC,
+ TYPE_ICESTORM_RAM,
+ TYPE_SB_IO
};
IdString belTypeToId(BelType type);
@@ -45,113 +45,113 @@ BelType belTypeFromId(IdString id);
enum PortPin
{
- PIN_NIL,
-
- PIN_IN_0,
- PIN_IN_1,
- PIN_IN_2,
- PIN_IN_3,
- PIN_O,
- PIN_LO,
- PIN_CIN,
- PIN_COUT,
- PIN_CEN,
- PIN_CLK,
- PIN_SR,
-
- PIN_MASK_0,
- PIN_MASK_1,
- PIN_MASK_2,
- PIN_MASK_3,
- PIN_MASK_4,
- PIN_MASK_5,
- PIN_MASK_6,
- PIN_MASK_7,
- PIN_MASK_8,
- PIN_MASK_9,
- PIN_MASK_10,
- PIN_MASK_11,
- PIN_MASK_12,
- PIN_MASK_13,
- PIN_MASK_14,
- PIN_MASK_15,
-
- PIN_RDATA_0,
- PIN_RDATA_1,
- PIN_RDATA_2,
- PIN_RDATA_3,
- PIN_RDATA_4,
- PIN_RDATA_5,
- PIN_RDATA_6,
- PIN_RDATA_7,
- PIN_RDATA_8,
- PIN_RDATA_9,
- PIN_RDATA_10,
- PIN_RDATA_11,
- PIN_RDATA_12,
- PIN_RDATA_13,
- PIN_RDATA_14,
- PIN_RDATA_15,
-
- PIN_WDATA_0,
- PIN_WDATA_1,
- PIN_WDATA_2,
- PIN_WDATA_3,
- PIN_WDATA_4,
- PIN_WDATA_5,
- PIN_WDATA_6,
- PIN_WDATA_7,
- PIN_WDATA_8,
- PIN_WDATA_9,
- PIN_WDATA_10,
- PIN_WDATA_11,
- PIN_WDATA_12,
- PIN_WDATA_13,
- PIN_WDATA_14,
- PIN_WDATA_15,
-
- PIN_WADDR_0,
- PIN_WADDR_1,
- PIN_WADDR_2,
- PIN_WADDR_3,
- PIN_WADDR_4,
- PIN_WADDR_5,
- PIN_WADDR_6,
- PIN_WADDR_7,
- PIN_WADDR_8,
- PIN_WADDR_9,
- PIN_WADDR_10,
-
- PIN_RADDR_0,
- PIN_RADDR_1,
- PIN_RADDR_2,
- PIN_RADDR_3,
- PIN_RADDR_4,
- PIN_RADDR_5,
- PIN_RADDR_6,
- PIN_RADDR_7,
- PIN_RADDR_8,
- PIN_RADDR_9,
- PIN_RADDR_10,
-
- PIN_WCLK,
- PIN_WCLKE,
- PIN_WE,
-
- PIN_RCLK,
- PIN_RCLKE,
- PIN_RE,
-
- PIN_PACKAGE_PIN,
- PIN_LATCH_INPUT_VALUE,
- PIN_CLOCK_ENABLE,
- PIN_INPUT_CLK,
- PIN_OUTPUT_CLK,
- PIN_OUTPUT_ENABLE,
- PIN_D_OUT_0,
- PIN_D_OUT_1,
- PIN_D_IN_0,
- PIN_D_IN_1
+ PIN_NIL,
+
+ PIN_IN_0,
+ PIN_IN_1,
+ PIN_IN_2,
+ PIN_IN_3,
+ PIN_O,
+ PIN_LO,
+ PIN_CIN,
+ PIN_COUT,
+ PIN_CEN,
+ PIN_CLK,
+ PIN_SR,
+
+ PIN_MASK_0,
+ PIN_MASK_1,
+ PIN_MASK_2,
+ PIN_MASK_3,
+ PIN_MASK_4,
+ PIN_MASK_5,
+ PIN_MASK_6,
+ PIN_MASK_7,
+ PIN_MASK_8,
+ PIN_MASK_9,
+ PIN_MASK_10,
+ PIN_MASK_11,
+ PIN_MASK_12,
+ PIN_MASK_13,
+ PIN_MASK_14,
+ PIN_MASK_15,
+
+ PIN_RDATA_0,
+ PIN_RDATA_1,
+ PIN_RDATA_2,
+ PIN_RDATA_3,
+ PIN_RDATA_4,
+ PIN_RDATA_5,
+ PIN_RDATA_6,
+ PIN_RDATA_7,
+ PIN_RDATA_8,
+ PIN_RDATA_9,
+ PIN_RDATA_10,
+ PIN_RDATA_11,
+ PIN_RDATA_12,
+ PIN_RDATA_13,
+ PIN_RDATA_14,
+ PIN_RDATA_15,
+
+ PIN_WDATA_0,
+ PIN_WDATA_1,
+ PIN_WDATA_2,
+ PIN_WDATA_3,
+ PIN_WDATA_4,
+ PIN_WDATA_5,
+ PIN_WDATA_6,
+ PIN_WDATA_7,
+ PIN_WDATA_8,
+ PIN_WDATA_9,
+ PIN_WDATA_10,
+ PIN_WDATA_11,
+ PIN_WDATA_12,
+ PIN_WDATA_13,
+ PIN_WDATA_14,
+ PIN_WDATA_15,
+
+ PIN_WADDR_0,
+ PIN_WADDR_1,
+ PIN_WADDR_2,
+ PIN_WADDR_3,
+ PIN_WADDR_4,
+ PIN_WADDR_5,
+ PIN_WADDR_6,
+ PIN_WADDR_7,
+ PIN_WADDR_8,
+ PIN_WADDR_9,
+ PIN_WADDR_10,
+
+ PIN_RADDR_0,
+ PIN_RADDR_1,
+ PIN_RADDR_2,
+ PIN_RADDR_3,
+ PIN_RADDR_4,
+ PIN_RADDR_5,
+ PIN_RADDR_6,
+ PIN_RADDR_7,
+ PIN_RADDR_8,
+ PIN_RADDR_9,
+ PIN_RADDR_10,
+
+ PIN_WCLK,
+ PIN_WCLKE,
+ PIN_WE,
+
+ PIN_RCLK,
+ PIN_RCLKE,
+ PIN_RE,
+
+ PIN_PACKAGE_PIN,
+ PIN_LATCH_INPUT_VALUE,
+ PIN_CLOCK_ENABLE,
+ PIN_INPUT_CLK,
+ PIN_OUTPUT_CLK,
+ PIN_OUTPUT_ENABLE,
+ PIN_D_OUT_0,
+ PIN_D_OUT_1,
+ PIN_D_IN_0,
+ PIN_D_IN_1
};
IdString PortPinToId(PortPin type);
@@ -159,47 +159,46 @@ PortPin PortPinFromId(IdString id);
// -----------------------------------------------------------------------
-
struct BelInfoPOD
{
- const char *name;
- BelType type;
- int8_t x, y, z;
+ const char *name;
+ BelType type;
+ int8_t x, y, z;
};
struct BelPortPOD
{
- int32_t bel_index;
- PortPin port;
+ int32_t bel_index;
+ PortPin port;
};
struct PipInfoPOD
{
- int32_t src, dst;
- float delay;
- int8_t x, y;
+ int32_t src, dst;
+ float delay;
+ int8_t x, y;
};
struct WireInfoPOD
{
- const char *name;
- int num_uphill, num_downhill;
- int *pips_uphill, *pips_downhill;
+ const char *name;
+ int num_uphill, num_downhill;
+ int *pips_uphill, *pips_downhill;
- int num_bels_downhill;
- BelPortPOD bel_uphill;
- BelPortPOD *bels_downhill;
+ int num_bels_downhill;
+ BelPortPOD bel_uphill;
+ BelPortPOD *bels_downhill;
- float x, y;
+ float x, y;
};
struct ChipInfoPOD
{
- int width, height;
- int num_bels, num_wires, num_pips;
- BelInfoPOD *bel_data;
- WireInfoPOD *wire_data;
- PipInfoPOD *pip_data;
+ int width, height;
+ int num_bels, num_wires, num_pips;
+ BelInfoPOD *bel_data;
+ WireInfoPOD *wire_data;
+ PipInfoPOD *pip_data;
};
extern ChipInfoPOD chip_info_384;
@@ -211,248 +210,256 @@ extern ChipInfoPOD chip_info_8k;
struct BelId
{
- int32_t index = -1;
+ int32_t index = -1;
- bool nil() const {
- return index < 0;
- }
+ bool nil() const { return index < 0; }
- bool operator==(const BelId &other) const { return index == other.index; }
- bool operator!=(const BelId &other) const { return index != other.index; }
+ bool operator==(const BelId &other) const { return index == other.index; }
+ bool operator!=(const BelId &other) const { return index != other.index; }
};
struct WireId
{
- int32_t index = -1;
+ int32_t index = -1;
- bool nil() const {
- return index < 0;
- }
+ bool nil() const { return index < 0; }
- bool operator==(const WireId &other) const { return index == other.index; }
- bool operator!=(const WireId &other) const { return index != other.index; }
+ bool operator==(const WireId &other) const { return index == other.index; }
+ bool operator!=(const WireId &other) const { return index != other.index; }
};
struct PipId
{
- int32_t index = -1;
+ int32_t index = -1;
- bool nil() const {
- return index < 0;
- }
+ bool nil() const { return index < 0; }
- bool operator==(const PipId &other) const { return index == other.index; }
- bool operator!=(const PipId &other) const { return index != other.index; }
+ bool operator==(const PipId &other) const { return index == other.index; }
+ bool operator!=(const PipId &other) const { return index != other.index; }
};
struct BelPin
{
- BelId bel;
- PortPin pin;
+ BelId bel;
+ PortPin pin;
};
-namespace std
+namespace std {
+template <> struct hash<BelId>
{
- template<> struct hash<BelId>
- {
- std::size_t operator()(const BelId &bel) const noexcept
- {
- return bel.index;
- }
- };
+ std::size_t operator()(const BelId &bel) const noexcept
+ {
+ return bel.index;
+ }
+};
- template<> struct hash<WireId>
- {
- std::size_t operator()(const WireId &wire) const noexcept
- {
- return wire.index;
- }
- };
+template <> struct hash<WireId>
+{
+ std::size_t operator()(const WireId &wire) const noexcept
+ {
+ return wire.index;
+ }
+};
- template<> struct hash<PipId>
- {
- std::size_t operator()(const PipId &wire) const noexcept
- {
- return wire.index;
- }
- };
+template <> struct hash<PipId>
+{
+ std::size_t operator()(const PipId &wire) const noexcept
+ {
+ return wire.index;
+ }
+};
}
// -----------------------------------------------------------------------
struct BelIterator
{
- int cursor;
-
- void operator++() { cursor++; }
- bool operator!=(const BelIterator &other) const { return cursor != other.cursor; }
-
- BelId operator*() const {
- BelId ret;
- ret.index = cursor;
- return ret;
- }
+ int cursor;
+
+ void operator++() { cursor++; }
+ bool operator!=(const BelIterator &other) const
+ {
+ return cursor != other.cursor;
+ }
+
+ BelId operator*() const
+ {
+ BelId ret;
+ ret.index = cursor;
+ return ret;
+ }
};
struct BelRange
{
- BelIterator b, e;
- BelIterator begin() const { return b; }
- BelIterator end() const { return e; }
+ BelIterator b, e;
+ BelIterator begin() const { return b; }
+ BelIterator end() const { return e; }
};
// -----------------------------------------------------------------------
struct BelPinIterator
{
- BelPortPOD *ptr = nullptr;
-
- void operator++() { ptr++; }
- bool operator!=(const BelPinIterator &other) const { return ptr != other.ptr; }
-
- BelPin operator*() const {
- BelPin ret;
- ret.bel.index = ptr->bel_index;
- ret.pin = ptr->port;
- return ret;
- }
+ BelPortPOD *ptr = nullptr;
+
+ void operator++() { ptr++; }
+ bool operator!=(const BelPinIterator &other) const
+ {
+ return ptr != other.ptr;
+ }
+
+ BelPin operator*() const
+ {
+ BelPin ret;
+ ret.bel.index = ptr->bel_index;
+ ret.pin = ptr->port;
+ return ret;
+ }
};
struct BelPinRange
{
- BelPinIterator b, e;
- BelPinIterator begin() const { return b; }
- BelPinIterator end() const { return e; }
+ BelPinIterator b, e;
+ BelPinIterator begin() const { return b; }
+ BelPinIterator end() const { return e; }
};
// -----------------------------------------------------------------------
struct WireIterator
{
- int cursor = -1;
-
- void operator++() { cursor++; }
- bool operator!=(const WireIterator &other) const { return cursor != other.cursor; }
-
- WireId operator*() const {
- WireId ret;
- ret.index = cursor;
- return ret;
- }
+ int cursor = -1;
+
+ void operator++() { cursor++; }
+ bool operator!=(const WireIterator &other) const
+ {
+ return cursor != other.cursor;
+ }
+
+ WireId operator*() const
+ {
+ WireId ret;
+ ret.index = cursor;
+ return ret;
+ }
};
struct WireRange
{
- WireIterator b, e;
- WireIterator begin() const { return b; }
- WireIterator end() const { return e; }
+ WireIterator b, e;
+ WireIterator begin() const { return b; }
+ WireIterator end() const { return e; }
};
// -----------------------------------------------------------------------
struct AllPipIterator
{
- int cursor = -1;
-
- void operator++() { cursor++; }
- bool operator!=(const AllPipIterator &other) const { return cursor != other.cursor; }
-
- PipId operator*() const {
- PipId ret;
- ret.index = cursor;
- return ret;
- }
+ int cursor = -1;
+
+ void operator++() { cursor++; }
+ bool operator!=(const AllPipIterator &other) const
+ {
+ return cursor != other.cursor;
+ }
+
+ PipId operator*() const
+ {
+ PipId ret;
+ ret.index = cursor;
+ return ret;
+ }
};
struct AllPipRange
{
- AllPipIterator b, e;
- AllPipIterator begin() const { return b; }
- AllPipIterator end() const { return e; }
+ AllPipIterator b, e;
+ AllPipIterator begin() const { return b; }
+ AllPipIterator end() const { return e; }
};
// -----------------------------------------------------------------------
struct PipIterator
{
- int *cursor = nullptr;
-
- void operator++() { cursor++; }
- bool operator!=(const PipIterator &other) const { return cursor != other.cursor; }
-
- PipId operator*() const {
- PipId ret;
- ret.index = *cursor;
- return ret;
- }
+ int *cursor = nullptr;
+
+ void operator++() { cursor++; }
+ bool operator!=(const PipIterator &other) const
+ {
+ return cursor != other.cursor;
+ }
+
+ PipId operator*() const
+ {
+ PipId ret;
+ ret.index = *cursor;
+ return ret;
+ }
};
struct PipRange
{
- PipIterator b, e;
- PipIterator begin() const { return b; }
- PipIterator end() const { return e; }
+ PipIterator b, e;
+ PipIterator begin() const { return b; }
+ PipIterator end() const { return e; }
};
// -----------------------------------------------------------------------
struct ChipArgs
{
- enum {
- NONE,
- LP384,
- LP1K,
- LP8K,
- HX1K,
- HX8K,
- UP5K
- } type = NONE;
+ enum
+ {
+ NONE,
+ LP384,
+ LP1K,
+ LP8K,
+ HX1K,
+ HX8K,
+ UP5K
+ } type = NONE;
};
struct Chip
{
- ChipInfoPOD chip_info;
+ ChipInfoPOD chip_info;
- mutable dict<IdString, int> bel_by_name;
- mutable dict<IdString, int> wire_by_name;
- mutable dict<IdString, int> pip_by_name;
+ mutable dict<IdString, int> bel_by_name;
+ mutable dict<IdString, int> wire_by_name;
+ mutable dict<IdString, int> pip_by_name;
- Chip(ChipArgs args);
+ Chip(ChipArgs args);
- // -------------------------------------------------
+ // -------------------------------------------------
- BelId getBelByName(IdString name) const;
+ BelId getBelByName(IdString name) const;
- IdString getBelName(BelId bel) const
- {
- assert(!bel.nil());
- return chip_info.bel_data[bel.index].name;
- }
+ IdString getBelName(BelId bel) const
+ {
+ assert(!bel.nil());
+ return chip_info.bel_data[bel.index].name;
+ }
- void bindBel(BelId bel, IdString cell)
- {
- }
+ void bindBel(BelId bel, IdString cell) {}
- void unbindBel(BelId bel)
- {
- }
+ void unbindBel(BelId bel) {}
- bool checkBelAvail(BelId bel) const
- {
- }
+ bool checkBelAvail(BelId bel) const {}
- BelRange getBels() const
- {
- BelRange range;
- range.b.cursor = 0;
- range.e.cursor = chip_info.num_bels;
- return range;
- }
+ BelRange getBels() const
+ {
+ BelRange range;
+ range.b.cursor = 0;
+ range.e.cursor = chip_info.num_bels;
+ return range;
+ }
- BelRange getBelsByType(BelType type) const
- {
- BelRange range;
- // FIXME
+ BelRange getBelsByType(BelType type) const
+ {
+ BelRange range;
+// FIXME
#if 0
if (type == "TYPE_A") {
range.b.cursor = bels_type_a_begin;
@@ -460,161 +467,155 @@ struct Chip
}
...
#endif
- return range;
- }
-
- BelType getBelType(BelId bel) const
- {
- assert(!bel.nil());
- return chip_info.bel_data[bel.index].type;
- }
-
- WireId getWireBelPin(BelId bel, PortPin pin) const;
-
- BelPin getBelPinUphill(WireId wire) const
- {
- BelPin ret;
- assert(!wire.nil());
-
- if (chip_info.wire_data[wire.index].bel_uphill.bel_index >= 0) {
- ret.bel.index = chip_info.wire_data[wire.index].bel_uphill.bel_index;
- ret.pin = chip_info.wire_data[wire.index].bel_uphill.port;
- }
-
- return ret;
- }
-
- BelPinRange getBelPinsDownhill(WireId wire) const
- {
- BelPinRange range;
- assert(!wire.nil());
- range.b.ptr = chip_info.wire_data[wire.index].bels_downhill;
- range.e.ptr = range.b.ptr + chip_info.wire_data[wire.index].num_bels_downhill;
- return range;
- }
-
- // -------------------------------------------------
-
- WireId getWireByName(IdString name) const;
-
- IdString getWireName(WireId wire) const
- {
- assert(!wire.nil());
- return chip_info.wire_data[wire.index].name;
- }
-
- void bindWire(WireId bel, IdString net)
- {
- }
-
- void unbindWire(WireId bel)
- {
- }
-
- bool checkWireAvail(WireId bel) const
- {
- }
-
- WireRange getWires() const
- {
- WireRange range;
- range.b.cursor = 0;
- range.e.cursor = chip_info.num_wires;
- return range;
- }
-
- // -------------------------------------------------
-
- PipId getPipByName(IdString name) const;
-
- IdString getPipName(PipId pip) const
- {
- assert(!pip.nil());
- std::string src_name = chip_info.wire_data[chip_info.pip_data[pip.index].src].name;
- std::string dst_name = chip_info.wire_data[chip_info.pip_data[pip.index].dst].name;
- return src_name + "->" + dst_name;
- }
-
- void bindPip(PipId bel, IdString net)
- {
- }
-
- void unbindPip(PipId bel)
- {
- }
-
- bool checkPipAvail(PipId bel) const
- {
- }
-
- AllPipRange getPips() const
- {
- AllPipRange range;
- range.b.cursor = 0;
- range.e.cursor = chip_info.num_pips;
- return range;
- }
-
- WireId getPipSrcWire(PipId pip) const
- {
- WireId wire;
- assert(!pip.nil());
- wire.index = chip_info.pip_data[pip.index].src;
- return wire;
- }
-
- WireId getPipDstWire(PipId pip) const
- {
- WireId wire;
- assert(!pip.nil());
- wire.index = chip_info.pip_data[pip.index].dst;
- return wire;
- }
-
- DelayInfo getPipDelay(PipId pip) const
- {
- DelayInfo delay;
- assert(!pip.nil());
- delay.delay = chip_info.pip_data[pip.index].delay;
- return delay;
- }
-
- PipRange getPipsDownhill(WireId wire) const
- {
- PipRange range;
- assert(!wire.nil());
- range.b.cursor = chip_info.wire_data[wire.index].pips_downhill;
- range.e.cursor = range.b.cursor + chip_info.wire_data[wire.index].num_downhill;
- return range;
- }
-
- PipRange getPipsUphill(WireId wire) const
- {
- PipRange range;
- assert(!wire.nil());
- range.b.cursor = chip_info.wire_data[wire.index].pips_uphill;
- range.e.cursor = range.b.cursor + chip_info.wire_data[wire.index].num_uphill;
- return range;
- }
-
- PipRange getWireAliases(WireId wire) const
- {
- PipRange range;
- assert(!wire.nil());
- range.b.cursor = nullptr;
- range.e.cursor = nullptr;
- return range;
- }
-
- // -------------------------------------------------
-
- void getBelPosition(BelId bel, float &x, float &y) const;
- void getWirePosition(WireId wire, float &x, float &y) const;
- void getPipPosition(PipId pip, float &x, float &y) const;
- vector<GraphicElement> getBelGraphics(BelId bel) const;
- vector<GraphicElement> getWireGraphics(WireId wire) const;
- vector<GraphicElement> getPipGraphics(PipId pip) const;
- vector<GraphicElement> getFrameGraphics() const;
+ return range;
+ }
+
+ BelType getBelType(BelId bel) const
+ {
+ assert(!bel.nil());
+ return chip_info.bel_data[bel.index].type;
+ }
+
+ WireId getWireBelPin(BelId bel, PortPin pin) const;
+
+ BelPin getBelPinUphill(WireId wire) const
+ {
+ BelPin ret;
+ assert(!wire.nil());
+
+ if (chip_info.wire_data[wire.index].bel_uphill.bel_index >= 0) {
+ ret.bel.index =
+ chip_info.wire_data[wire.index].bel_uphill.bel_index;
+ ret.pin = chip_info.wire_data[wire.index].bel_uphill.port;
+ }
+
+ return ret;
+ }
+
+ BelPinRange getBelPinsDownhill(WireId wire) const
+ {
+ BelPinRange range;
+ assert(!wire.nil());
+ range.b.ptr = chip_info.wire_data[wire.index].bels_downhill;
+ range.e.ptr =
+ range.b.ptr + chip_info.wire_data[wire.index].num_bels_downhill;
+ return range;
+ }
+
+ // -------------------------------------------------
+
+ WireId getWireByName(IdString name) const;
+
+ IdString getWireName(WireId wire) const
+ {
+ assert(!wire.nil());
+ return chip_info.wire_data[wire.index].name;
+ }
+
+ void bindWire(WireId bel, IdString net) {}
+
+ void unbindWire(WireId bel) {}
+
+ bool checkWireAvail(WireId bel) const {}
+
+ WireRange getWires() const
+ {
+ WireRange range;
+ range.b.cursor = 0;
+ range.e.cursor = chip_info.num_wires;
+ return range;
+ }
+
+ // -------------------------------------------------
+
+ PipId getPipByName(IdString name) const;
+
+ IdString getPipName(PipId pip) const
+ {
+ assert(!pip.nil());
+ std::string src_name =
+ chip_info.wire_data[chip_info.pip_data[pip.index].src].name;
+ std::string dst_name =
+ chip_info.wire_data[chip_info.pip_data[pip.index].dst].name;
+ return src_name + "->" + dst_name;
+ }
+
+ void bindPip(PipId bel, IdString net) {}
+
+ void unbindPip(PipId bel) {}
+
+ bool checkPipAvail(PipId bel) const {}
+
+ AllPipRange getPips() const
+ {
+ AllPipRange range;
+ range.b.cursor = 0;
+ range.e.cursor = chip_info.num_pips;
+ return range;
+ }
+
+ WireId getPipSrcWire(PipId pip) const
+ {
+ WireId wire;
+ assert(!pip.nil());
+ wire.index = chip_info.pip_data[pip.index].src;
+ return wire;
+ }
+
+ WireId getPipDstWire(PipId pip) const
+ {
+ WireId wire;
+ assert(!pip.nil());
+ wire.index = chip_info.pip_data[pip.index].dst;
+ return wire;
+ }
+
+ DelayInfo getPipDelay(PipId pip) const
+ {
+ DelayInfo delay;
+ assert(!pip.nil());
+ delay.delay = chip_info.pip_data[pip.index].delay;
+ return delay;
+ }
+
+ PipRange getPipsDownhill(WireId wire) const
+ {
+ PipRange range;
+ assert(!wire.nil());
+ range.b.cursor = chip_info.wire_data[wire.index].pips_downhill;
+ range.e.cursor =
+ range.b.cursor + chip_info.wire_data[wire.index].num_downhill;
+ return range;
+ }
+
+ PipRange getPipsUphill(WireId wire) const
+ {
+ PipRange range;
+ assert(!wire.nil());
+ range.b.cursor = chip_info.wire_data[wire.index].pips_uphill;
+ range.e.cursor =
+ range.b.cursor + chip_info.wire_data[wire.index].num_uphill;
+ return range;
+ }
+
+ PipRange getWireAliases(WireId wire) const
+ {
+ PipRange range;
+ assert(!wire.nil());
+ range.b.cursor = nullptr;
+ range.e.cursor = nullptr;
+ return range;
+ }
+
+ // -------------------------------------------------
+
+ void getBelPosition(BelId bel, float &x, float &y) const;
+ void getWirePosition(WireId wire, float &x, float &y) const;
+ void getPipPosition(PipId pip, float &x, float &y) const;
+ vector<GraphicElement> getBelGraphics(BelId bel) const;
+ vector<GraphicElement> getWireGraphics(WireId wire) const;
+ vector<GraphicElement> getPipGraphics(PipId pip) const;
+ vector<GraphicElement> getFrameGraphics() const;
};
#endif
diff --git a/ice40/family.cmake b/ice40/family.cmake
index 870b69b9..05709388 100644
--- a/ice40/family.cmake
+++ b/ice40/family.cmake
@@ -1,4 +1,12 @@
-set(devices 384 1k 5k 8k)
+if(ICE40_HX1K_ONLY)
+ set(devices 1k)
+ foreach (target ${family_targets})
+ target_compile_definitions(${target} PRIVATE ICE40_HX1K_ONLY=1)
+ endforeach (target)
+else()
+ set(devices 384 1k 5k 8k)
+endif()
+
set(DB_PY ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdb.py)
file(MAKE_DIRECTORY ice40/chipdbs/)
add_library(ice40_chipdb OBJECT ice40/chipdbs/)
diff --git a/ice40/main.cc b/ice40/main.cc
index 9295bde4..d47076fd 100644
--- a/ice40/main.cc
+++ b/ice40/main.cc
@@ -16,208 +16,244 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
-#include "design.h"
-#include "mainwindow.h"
#include <QApplication>
-#include <iostream>
-#include <fstream>
-#include "version.h"
#include <boost/program_options.hpp>
-#include "pybindings.h"
+#include <fstream>
+#include <iostream>
+#include "design.h"
#include "jsonparse.h"
+#include "mainwindow.h"
+#include "pybindings.h"
+#include "version.h"
void svg_dump_el(const GraphicElement &el)
{
- float scale = 10.0, offset = 10.0;
- std::string style = "stroke=\"black\" stroke-width=\"0.1\" fill=\"none\"";
-
- if (el.type == GraphicElement::G_BOX) {
- std::cout << "<rect x=\"" << (offset + scale*el.x1) << "\" y=\"" << (offset + scale*el.y1) <<
- "\" height=\"" << (scale*(el.y2-el.y1)) << "\" width=\"" << (scale*(el.x2-el.x1)) << "\" " << style << "/>\n";
- }
-
- if (el.type == GraphicElement::G_LINE) {
- std::cout << "<line x1=\"" << (offset + scale*el.x1) << "\" y1=\"" << (offset + scale*el.y1) <<
- "\" x2=\"" << (offset + scale*el.x2) << "\" y2=\"" << (offset + scale*el.y2) << "\" " << style << "/>\n";
- }
+ float scale = 10.0, offset = 10.0;
+ std::string style = "stroke=\"black\" stroke-width=\"0.1\" fill=\"none\"";
+
+ if (el.type == GraphicElement::G_BOX) {
+ std::cout << "<rect x=\"" << (offset + scale * el.x1) << "\" y=\""
+ << (offset + scale * el.y1) << "\" height=\""
+ << (scale * (el.y2 - el.y1)) << "\" width=\""
+ << (scale * (el.x2 - el.x1)) << "\" " << style << "/>\n";
+ }
+
+ if (el.type == GraphicElement::G_LINE) {
+ std::cout << "<line x1=\"" << (offset + scale * el.x1) << "\" y1=\""
+ << (offset + scale * el.y1) << "\" x2=\""
+ << (offset + scale * el.x2) << "\" y2=\""
+ << (offset + scale * el.y2) << "\" " << style << "/>\n";
+ }
}
int main(int argc, char *argv[])
{
- namespace po = boost::program_options;
-
- std::string str;
-
- po::options_description options("Allowed options");
- options.add_options()("help,h","show help");
- options.add_options()("test","just a check");
- options.add_options()("gui","start gui");
- options.add_options()("svg","dump SVG file");
- options.add_options()("file", po::value<std::string>(), "python file to execute");
- options.add_options()("json", po::value<std::string>(), "JSON design file to ingest");
- options.add_options()("version,v","show version");
- options.add_options()("lp384","set device type to iCE40LP384");
- options.add_options()("lp1k","set device type to iCE40LP1K");
- options.add_options()("lp8k","set device type to iCE40LP8K");
- options.add_options()("hx1k","set device type to iCE40HX1K");
- options.add_options()("hx8k","set device type to iCE40HX8K");
- options.add_options()("up5k","set device type to iCE40UP5K");
-
- po::positional_options_description pos;
- pos.add("file", -1);
-
- 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 << basename(argv[0]) << " -- Next Generation Place and Route (git sha1 " GIT_COMMIT_HASH_STR ")\n";
- std::cout << "\n";
- std::cout << options << "\n";
- return 1;
- }
-
- if (vm.count("version"))
- {
- std::cout << basename(argv[0])
- << " -- Next Generation Place and Route (git sha1 "
- GIT_COMMIT_HASH_STR ")\n";
- return 1;
- }
-
- ChipArgs chipArgs;
- chipArgs.type = ChipArgs::HX1K;
-
- if (vm.count("lp384"))
- chipArgs.type = ChipArgs::LP384;
-
- if (vm.count("lp1k"))
- chipArgs.type = ChipArgs::LP1K;
-
- if (vm.count("lp8k"))
- chipArgs.type = ChipArgs::LP8K;
-
- if (vm.count("hx1k"))
- chipArgs.type = ChipArgs::HX1K;
-
- if (vm.count("hx8k"))
- chipArgs.type = ChipArgs::HX8K;
-
- if (vm.count("up5k"))
- chipArgs.type = ChipArgs::UP5K;
-
- Design design(chipArgs);
-
- if (vm.count("gui"))
- {
- QApplication a(argc, argv);
- MainWindow w;
- w.show();
-
- return a.exec();
- }
-
- if (vm.count("test"))
- {
- int bel_count = 0, wire_count = 0, pip_count = 0;
-
- std::cout << "Checking bel names.\n";
- for (auto bel : design.chip.getBels()) {
- auto name = design.chip.getBelName(bel);
- assert(bel == design.chip.getBelByName(name));
- bel_count++;
- }
- std::cout << " checked " << bel_count << " bels.\n";
-
- std::cout << "Checking wire names.\n";
- for (auto wire : design.chip.getWires()) {
- auto name = design.chip.getWireName(wire);
- assert(wire == design.chip.getWireByName(name));
- wire_count++;
- }
- std::cout << " checked " << wire_count << " wires.\n";
-
- std::cout << "Checking pip names.\n";
- for (auto pip : design.chip.getPips()) {
- auto name = design.chip.getPipName(pip);
- assert(pip == design.chip.getPipByName(name));
- pip_count++;
- }
- std::cout << " checked " << pip_count << " pips.\n";
-
- std::cout << "Checking uphill -> downhill consistency.\n";
- for (auto dst : design.chip.getWires()) {
- for (auto uphill_pip : design.chip.getPipsUphill(dst)) {
- bool found_downhill = false;
- for (auto downhill_pip : design.chip.getPipsDownhill(design.chip.getPipSrcWire(uphill_pip))) {
- if (uphill_pip == downhill_pip) {
- assert(!found_downhill);
- found_downhill = true;
- }
- }
- assert(found_downhill);
- }
- }
-
- std::cout << "Checking downhill -> uphill consistency.\n";
- for (auto dst : design.chip.getWires()) {
- for (auto downhill_pip : design.chip.getPipsDownhill(dst)) {
- bool found_uphill = false;
- for (auto uphill_pip : design.chip.getPipsUphill(design.chip.getPipDstWire(downhill_pip))) {
- if (uphill_pip == downhill_pip) {
- assert(!found_uphill);
- found_uphill = true;
- }
- }
- assert(found_uphill);
- }
- }
-
- return 0;
- }
-
- if (vm.count("svg"))
- {
- std::cout << "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n";
- for (auto bel : design.chip.getBels()) {
- std::cout << "<!-- " << design.chip.getBelName(bel) << " -->\n";
- for (auto &el : design.chip.getBelGraphics(bel))
- svg_dump_el(el);
- }
- std::cout << "<!-- Frame -->\n";
- for (auto &el : design.chip.getFrameGraphics())
- svg_dump_el(el);
- std::cout << "</svg>\n";
- }
-
- if (vm.count("json"))
- {
- std::string filename = vm["json"].as<std::string>();
- std::istream *f = new std::ifstream(filename);
-
- parse_json_file(f, filename, &design);
- }
-
- if (vm.count("file"))
- {
- std::string filename = vm["file"].as<std::string>();
- execute_python_file(argv[0],filename.c_str());
- }
-
- return 0;
+ namespace po = boost::program_options;
+ int rc = 0;
+ std::string str;
+
+ po::options_description options("Allowed options");
+ options.add_options()("help,h", "show help");
+ options.add_options()("test", "just a check");
+ options.add_options()("gui", "start gui");
+ options.add_options()("svg", "dump SVG file");
+ options.add_options()("run", po::value<std::vector<std::string>>(),
+ "python file to execute");
+ options.add_options()("json", po::value<std::string>(),
+ "JSON design file to ingest");
+ options.add_options()("version,v", "show version");
+ options.add_options()("lp384", "set device type to iCE40LP384");
+ options.add_options()("lp1k", "set device type to iCE40LP1K");
+ options.add_options()("lp8k", "set device type to iCE40LP8K");
+ options.add_options()("hx1k", "set device type to iCE40HX1K");
+ options.add_options()("hx8k", "set device type to iCE40HX8K");
+ options.add_options()("up5k", "set device type to iCE40UP5K");
+
+ po::positional_options_description pos;
+ pos.add("run", -1);
+
+ 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) {
+ help:
+ std::cout << 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 << basename(argv[0])
+ << " -- Next Generation Place and Route (git "
+ "sha1 " GIT_COMMIT_HASH_STR ")\n";
+ return 1;
+ }
+
+ ChipArgs chipArgs;
+
+ if (vm.count("lp384")) {
+ if (chipArgs.type != ChipArgs::NONE)
+ goto help;
+ chipArgs.type = ChipArgs::LP384;
+ }
+
+ if (vm.count("lp1k")) {
+ if (chipArgs.type != ChipArgs::NONE)
+ goto help;
+ chipArgs.type = ChipArgs::LP1K;
+ }
+
+ if (vm.count("lp8k")) {
+ if (chipArgs.type != ChipArgs::NONE)
+ goto help;
+ chipArgs.type = ChipArgs::LP8K;
+ }
+
+ if (vm.count("hx1k")) {
+ if (chipArgs.type != ChipArgs::NONE)
+ goto help;
+ chipArgs.type = ChipArgs::HX1K;
+ }
+
+ if (vm.count("hx8k")) {
+ if (chipArgs.type != ChipArgs::NONE)
+ goto help;
+ chipArgs.type = ChipArgs::HX8K;
+ }
+
+ if (vm.count("up5k")) {
+ if (chipArgs.type != ChipArgs::NONE)
+ goto help;
+ chipArgs.type = ChipArgs::UP5K;
+ }
+
+ if (chipArgs.type == ChipArgs::NONE)
+ chipArgs.type = ChipArgs::HX1K;
+
+#ifdef ICE40_HX1K_ONLY
+ if (chipArgs.type != ChipArgs::HX1K) {
+ std::cout << "This version of nextpnr-ice40 is built with HX1K-support "
+ "only.\n";
+ return 1;
+ }
+#endif
+
+ Design design(chipArgs);
+ init_python(argv[0]);
+ python_export_global("design", design);
+
+ if (vm.count("test")) {
+ int bel_count = 0, wire_count = 0, pip_count = 0;
+
+ std::cout << "Checking bel names.\n";
+ for (auto bel : design.chip.getBels()) {
+ auto name = design.chip.getBelName(bel);
+ assert(bel == design.chip.getBelByName(name));
+ bel_count++;
+ }
+ std::cout << " checked " << bel_count << " bels.\n";
+
+ std::cout << "Checking wire names.\n";
+ for (auto wire : design.chip.getWires()) {
+ auto name = design.chip.getWireName(wire);
+ assert(wire == design.chip.getWireByName(name));
+ wire_count++;
+ }
+ std::cout << " checked " << wire_count << " wires.\n";
+
+ std::cout << "Checking pip names.\n";
+ for (auto pip : design.chip.getPips()) {
+ auto name = design.chip.getPipName(pip);
+ assert(pip == design.chip.getPipByName(name));
+ pip_count++;
+ }
+ std::cout << " checked " << pip_count << " pips.\n";
+
+ std::cout << "Checking uphill -> downhill consistency.\n";
+ for (auto dst : design.chip.getWires()) {
+ for (auto uphill_pip : design.chip.getPipsUphill(dst)) {
+ bool found_downhill = false;
+ for (auto downhill_pip : design.chip.getPipsDownhill(
+ design.chip.getPipSrcWire(uphill_pip))) {
+ if (uphill_pip == downhill_pip) {
+ assert(!found_downhill);
+ found_downhill = true;
+ }
+ }
+ assert(found_downhill);
+ }
+ }
+
+ std::cout << "Checking downhill -> uphill consistency.\n";
+ for (auto dst : design.chip.getWires()) {
+ for (auto downhill_pip : design.chip.getPipsDownhill(dst)) {
+ bool found_uphill = false;
+ for (auto uphill_pip : design.chip.getPipsUphill(
+ design.chip.getPipDstWire(downhill_pip))) {
+ if (uphill_pip == downhill_pip) {
+ assert(!found_uphill);
+ found_uphill = true;
+ }
+ }
+ assert(found_uphill);
+ }
+ }
+
+ return 0;
+ }
+
+ if (vm.count("svg")) {
+ std::cout << "<svg xmlns=\"http://www.w3.org/2000/svg\" "
+ "xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n";
+ for (auto bel : design.chip.getBels()) {
+ std::cout << "<!-- " << design.chip.getBelName(bel) << " -->\n";
+ for (auto &el : design.chip.getBelGraphics(bel))
+ svg_dump_el(el);
+ }
+ std::cout << "<!-- Frame -->\n";
+ for (auto &el : design.chip.getFrameGraphics())
+ svg_dump_el(el);
+ std::cout << "</svg>\n";
+ }
+
+ if (vm.count("json")) {
+ std::string filename = vm["json"].as<std::string>();
+ std::istream *f = new std::ifstream(filename);
+
+ parse_json_file(f, filename, &design);
+ }
+
+ if (vm.count("run")) {
+ std::vector<std::string> files =
+ vm["run"].as<std::vector<std::string>>();
+ for (auto filename : files)
+ execute_python_file(filename.c_str());
+ }
+
+ if (vm.count("gui")) {
+ QApplication a(argc, argv);
+ MainWindow w;
+ w.show();
+
+ rc = a.exec();
+ }
+ deinit_python();
+ return rc;
}
diff --git a/ice40/pybindings.cc b/ice40/pybindings.cc
index dc13f849..daf0be84 100644
--- a/ice40/pybindings.cc
+++ b/ice40/pybindings.cc
@@ -18,13 +18,15 @@
*
*/
-#include "design.h"
#include "chip.h"
+#include "design.h"
+
+// include after design.h/chip.h
#include "pybindings.h"
-void arch_wrap_python() {
- class_<ChipArgs>("ChipArgs")
- .def_readwrite("type", &ChipArgs::type);
+void arch_wrap_python()
+{
+ class_<ChipArgs>("ChipArgs").def_readwrite("type", &ChipArgs::type);
enum_<decltype(std::declval<ChipArgs>().type)>("iCE40Type")
.value("NONE", ChipArgs::NONE)
diff --git a/python/dump_design.py b/python/dump_design.py
new file mode 100644
index 00000000..22d4ab17
--- /dev/null
+++ b/python/dump_design.py
@@ -0,0 +1,6 @@
+# Run ./nextpnr-ice40 --json ice40/blinky.json --run python/dump_design.py
+for cell in sorted(design.cells, key=lambda x: x.first):
+ print("Cell {} : {}".format(cell.first, cell.second.type))
+ for port in sorted(cell.second.ports, key=lambda x: x.first):
+ dir = (" <-- ", " --> ", " <-> ")[int(port.second.type)]
+ print(" {} {} {}".format(port.first, dir, port.second.net.name))
diff --git a/python/functions.py b/python/functions.py
new file mode 100644
index 00000000..4f005456
--- /dev/null
+++ b/python/functions.py
@@ -0,0 +1,2 @@
+def test_function():
+ print("Hello World!")