Reformat Python bindings and ice40 main

Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
David Shah 2018-06-07 13:10:53 +02:00
parent 6236a10427
commit c3e0252703
6 changed files with 368 additions and 361 deletions

View File

@ -18,134 +18,138 @@
*
*/
#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();
bool operator==(const PortRef &a, const PortRef &b) {
return (a.cell == b.cell) && (a.port == b.port);
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);
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_<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);
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");
WRAP_MAP(decltype(NetInfo::attrs), "IdStrMap");
class_<vector<PortRef>>("PortRefVector")
.def(vector_indexing_suite<vector<PortRef>>());
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();
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_<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);
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");
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);
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");
WRAP_MAP(decltype(Design::nets), "IdNetMap");
WRAP_MAP(decltype(Design::cells), "IdCellMap");
arch_wrap_python();
arch_wrap_python();
}
void arch_appendinittab() {
PyImport_AppendInittab(TOSTRING(MODULE_NAME), PYINIT_MODULE_NAME);
void arch_appendinittab()
{
PyImport_AppendInittab(TOSTRING(MODULE_NAME), PYINIT_MODULE_NAME);
}
static wchar_t *program;
void init_python(const char *executable) {
program = Py_DecodeLocale(executable, NULL);
if (program == NULL) {
fprintf(stderr, "Fatal error: cannot decode executable filename\n");
exit(1);
}
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 init_python(const char *executable)
{
program = Py_DecodeLocale(executable, NULL);
if (program == NULL) {
fprintf(stderr, "Fatal error: cannot decode executable filename\n");
exit(1);
}
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);
void deinit_python()
{
Py_Finalize();
PyMem_RawFree(program);
}
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);
exit(1);
}
PyRun_SimpleFile(fp, python_file);
fclose(fp);
}
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 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);
exit(1);
}
PyRun_SimpleFile(fp, python_file);
fclose(fp);
} 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;
}
}

View File

@ -23,85 +23,85 @@
#include "pycontainers.h"
#include <utility>
#include <stdexcept>
#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 <Python.h>
#include <boost/python.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 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>());
};
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 *convertible(PyObject *object)
{
return PyUnicode_Check(object) ? object : 0;
}
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;
}
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;
}
static F fn;
};
static F fn;
};
template<typename F>
struct to_str_wrapper {
static F fn;
template <typename F> struct to_str_wrapper
{
static F fn;
std::string str(T &x) {
return fn(x);
}
};
std::string str(T &x) { return fn(x); }
};
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);
};
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();
}
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();
}
};
void init_python(const char *executable);

View File

@ -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();

View File

@ -18,12 +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"); }

View File

@ -16,239 +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\"";
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_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";
}
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;
int rc = 0;
std::string str;
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::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::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::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);
}
po::store(parsed, vm);
catch(std::exception& e)
{
std::cout << e.what() << "\n";
return 1;
}
po::notify(vm);
}
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;
}
catch (std::exception &e) {
std::cout << e.what() << "\n";
return 1;
}
ChipArgs chipArgs;
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("lp384")) {
if (chipArgs.type != ChipArgs::NONE)
goto help;
chipArgs.type = ChipArgs::LP384;
}
if (vm.count("version")) {
std::cout << basename(argv[0])
<< " -- Next Generation Place and Route (git "
"sha1 " GIT_COMMIT_HASH_STR ")\n";
return 1;
}
if (vm.count("lp1k")) {
if (chipArgs.type != ChipArgs::NONE)
goto help;
chipArgs.type = ChipArgs::LP1K;
}
ChipArgs chipArgs;
if (vm.count("lp8k")) {
if (chipArgs.type != ChipArgs::NONE)
goto help;
chipArgs.type = ChipArgs::LP8K;
}
if (vm.count("lp384")) {
if (chipArgs.type != ChipArgs::NONE)
goto help;
chipArgs.type = ChipArgs::LP384;
}
if (vm.count("hx1k")) {
if (chipArgs.type != ChipArgs::NONE)
goto help;
chipArgs.type = ChipArgs::HX1K;
}
if (vm.count("lp1k")) {
if (chipArgs.type != ChipArgs::NONE)
goto help;
chipArgs.type = ChipArgs::LP1K;
}
if (vm.count("hx8k")) {
if (chipArgs.type != ChipArgs::NONE)
goto help;
chipArgs.type = ChipArgs::HX8K;
}
if (vm.count("lp8k")) {
if (chipArgs.type != ChipArgs::NONE)
goto help;
chipArgs.type = ChipArgs::LP8K;
}
if (vm.count("up5k")) {
if (chipArgs.type != ChipArgs::NONE)
goto help;
chipArgs.type = ChipArgs::UP5K;
}
if (vm.count("hx1k")) {
if (chipArgs.type != ChipArgs::NONE)
goto help;
chipArgs.type = ChipArgs::HX1K;
}
if (chipArgs.type == ChipArgs::NONE)
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;
}
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);
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;
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 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 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 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 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);
}
}
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;
}
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("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("json")) {
std::string filename = vm["json"].as<std::string>();
std::istream *f = new std::ifstream(filename);
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());
}
parse_json_file(f, filename, &design);
}
if (vm.count("gui"))
{
QApplication a(argc, argv);
MainWindow w;
w.show();
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());
}
rc = a.exec();
}
deinit_python();
return rc;
if (vm.count("gui")) {
QApplication a(argc, argv);
MainWindow w;
w.show();
rc = a.exec();
}
deinit_python();
return rc;
}

View File

@ -18,15 +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)