generic: GUI Python bindings
Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
parent
a05593da62
commit
6fffe24177
@ -444,5 +444,13 @@ void BaseCtx::constrainCellToRegion(IdString cell, IdString region_name)
|
||||
{
|
||||
cells[cell]->region = region[region_name].get();
|
||||
}
|
||||
DecalXY BaseCtx::constructDecalXY(DecalId decal, float x, float y)
|
||||
{
|
||||
DecalXY dxy;
|
||||
dxy.decal = decal;
|
||||
dxy.x = x;
|
||||
dxy.y = y;
|
||||
return dxy;
|
||||
}
|
||||
|
||||
NEXTPNR_NAMESPACE_END
|
||||
|
@ -181,6 +181,9 @@ struct GraphicElement
|
||||
|
||||
float x1 = 0, y1 = 0, x2 = 0, y2 = 0, z = 0;
|
||||
std::string text;
|
||||
GraphicElement() {};
|
||||
GraphicElement(type_t type, style_t style, float x1, float y1, float x2, float y2, float z) : type(type),
|
||||
style(style), x1(x1), y1(y1), x2(x2), y2(y2), z(z) {};
|
||||
};
|
||||
|
||||
struct Loc
|
||||
@ -640,6 +643,9 @@ struct BaseCtx
|
||||
void createRectangularRegion(IdString name, int x0, int y0, int x1, int y1);
|
||||
void addBelToRegion(IdString name, BelId bel);
|
||||
void constrainCellToRegion(IdString cell, IdString region_name);
|
||||
|
||||
// Workaround for lack of wrappable constructors
|
||||
DecalXY constructDecalXY(DecalId decal, float x, float y);
|
||||
};
|
||||
|
||||
NEXTPNR_NAMESPACE_END
|
||||
|
@ -87,7 +87,26 @@ BOOST_PYTHON_MODULE(MODULE_NAME)
|
||||
|
||||
using namespace PythonConversion;
|
||||
|
||||
enum_<GraphicElement::type_t>("GraphicElementType")
|
||||
.value("TYPE_NONE", GraphicElement::TYPE_NONE)
|
||||
.value("TYPE_LINE", GraphicElement::TYPE_LINE)
|
||||
.value("TYPE_ARROW", GraphicElement::TYPE_ARROW)
|
||||
.value("TYPE_BOX", GraphicElement::TYPE_BOX)
|
||||
.value("TYPE_CIRCLE", GraphicElement::TYPE_CIRCLE)
|
||||
.value("TYPE_LABEL", GraphicElement::TYPE_LABEL)
|
||||
.export_values();
|
||||
|
||||
enum_<GraphicElement::style_t>("GraphicElementStyle")
|
||||
.value("STYLE_GRID", GraphicElement::STYLE_GRID)
|
||||
.value("STYLE_FRAME", GraphicElement::STYLE_FRAME)
|
||||
.value("STYLE_HIDDEN", GraphicElement::STYLE_HIDDEN)
|
||||
.value("STYLE_INACTIVE", GraphicElement::STYLE_INACTIVE)
|
||||
.value("STYLE_ACTIVE", GraphicElement::STYLE_ACTIVE)
|
||||
.export_values();
|
||||
|
||||
class_<GraphicElement>("GraphicElement")
|
||||
.def(init<GraphicElement::type_t, GraphicElement::style_t, float, float, float, float, float>(
|
||||
(args("type"), "style", "x1", "y1", "x2", "y2", "z")))
|
||||
.def_readwrite("type", &GraphicElement::type)
|
||||
.def_readwrite("x1", &GraphicElement::x1)
|
||||
.def_readwrite("y1", &GraphicElement::y1)
|
||||
@ -214,8 +233,7 @@ void init_python(const char *executable, bool first)
|
||||
PyImport_AppendInittab(TOSTRING(MODULE_NAME), PYINIT_MODULE_NAME);
|
||||
Py_SetProgramName(program);
|
||||
Py_Initialize();
|
||||
if (first)
|
||||
PyImport_ImportModule(TOSTRING(MODULE_NAME));
|
||||
PyImport_ImportModule(TOSTRING(MODULE_NAME));
|
||||
PyRun_SimpleString("from " TOSTRING(MODULE_NAME) " import *");
|
||||
} catch (boost::python::error_already_set const &) {
|
||||
// Parse and output the exception
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <iostream>
|
||||
#include "nextpnr.h"
|
||||
#include "placer1.h"
|
||||
#include "router1.h"
|
||||
@ -201,7 +202,10 @@ void Arch::setDelayScaling(double scale, double offset)
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
Arch::Arch(ArchArgs args) : chipName("generic"), args(args) {}
|
||||
Arch::Arch(ArchArgs args) : chipName("generic"), args(args) {
|
||||
// Dummy for empty decals
|
||||
decal_graphics[IdString()];
|
||||
}
|
||||
|
||||
void IdString::initialize_arch(const BaseCtx *ctx) {}
|
||||
|
||||
@ -469,7 +473,13 @@ bool Arch::route() { return router1(getCtx(), Router1Cfg(getCtx())); }
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
const std::vector<GraphicElement> &Arch::getDecalGraphics(DecalId decal) const { return decal_graphics.at(decal); }
|
||||
const std::vector<GraphicElement> &Arch::getDecalGraphics(DecalId decal) const {
|
||||
if (!decal_graphics.count(decal)) {
|
||||
std::cerr << "No decal named " << decal.str(this) << std::endl;
|
||||
log_error("No decal named %s!\n", decal.c_str(this));
|
||||
}
|
||||
return decal_graphics.at(decal);
|
||||
}
|
||||
|
||||
DecalXY Arch::getBelDecal(BelId bel) const { return bels.at(bel).decalxy; }
|
||||
|
||||
|
@ -40,6 +40,15 @@ void arch_wrap_python()
|
||||
using namespace PythonConversion;
|
||||
|
||||
auto arch_cls = class_<Arch, Arch *, bases<BaseCtx>, boost::noncopyable>("Arch", init<ArchArgs>());
|
||||
|
||||
auto dxy_cls = class_<ContextualWrapper<DecalXY>>("DecalXY_", no_init);
|
||||
readwrite_wrapper<DecalXY, decltype(&DecalXY::decal), &DecalXY::decal, conv_to_str<DecalId>,
|
||||
conv_from_str<DecalId>>::def_wrap(dxy_cls, "decal");
|
||||
readwrite_wrapper<DecalXY, decltype(&DecalXY::x), &DecalXY::x, pass_through<float>, pass_through<float>>::def_wrap(
|
||||
dxy_cls, "x");
|
||||
readwrite_wrapper<DecalXY, decltype(&DecalXY::y), &DecalXY::y, pass_through<float>, pass_through<float>>::def_wrap(
|
||||
dxy_cls, "y");
|
||||
|
||||
auto ctx_cls = class_<Context, Context *, bases<Arch>, boost::noncopyable>("Context", no_init)
|
||||
.def("checksum", &Context::checksum)
|
||||
.def("pack", &Context::pack)
|
||||
@ -127,6 +136,9 @@ void arch_wrap_python()
|
||||
fn_wrapper_0a<Context, decltype(&Context::archId), &Context::archId, conv_to_str<IdString>>::def_wrap(ctx_cls,
|
||||
"archId");
|
||||
|
||||
fn_wrapper_3a<Context, decltype(&Context::constructDecalXY), &Context::constructDecalXY, wrap_context<DecalXY>,
|
||||
conv_from_str<DecalId>, pass_through<float>, pass_through<float>>::def_wrap(ctx_cls, "DecalXY");
|
||||
|
||||
typedef std::unordered_map<IdString, std::unique_ptr<CellInfo>> CellMap;
|
||||
typedef std::unordered_map<IdString, std::unique_ptr<NetInfo>> NetMap;
|
||||
|
||||
@ -178,13 +190,13 @@ void arch_wrap_python()
|
||||
fn_wrapper_2a_v<Context, decltype(&Context::addDecalGraphic), &Context::addDecalGraphic, conv_from_str<DecalId>,
|
||||
pass_through<GraphicElement>>::def_wrap(ctx_cls, "addDecalGraphic", (arg("decal"), "graphic"));
|
||||
fn_wrapper_2a_v<Context, decltype(&Context::setWireDecal), &Context::setWireDecal, conv_from_str<DecalId>,
|
||||
pass_through<DecalXY>>::def_wrap(ctx_cls, "setWireDecal", (arg("wire"), "decalxy"));
|
||||
unwrap_context<DecalXY>>::def_wrap(ctx_cls, "setWireDecal", (arg("wire"), "decalxy"));
|
||||
fn_wrapper_2a_v<Context, decltype(&Context::setPipDecal), &Context::setPipDecal, conv_from_str<DecalId>,
|
||||
pass_through<DecalXY>>::def_wrap(ctx_cls, "setPipDecal", (arg("pip"), "decalxy"));
|
||||
unwrap_context<DecalXY>>::def_wrap(ctx_cls, "setPipDecal", (arg("pip"), "decalxy"));
|
||||
fn_wrapper_2a_v<Context, decltype(&Context::setBelDecal), &Context::setBelDecal, conv_from_str<DecalId>,
|
||||
pass_through<DecalXY>>::def_wrap(ctx_cls, "setBelDecal", (arg("bel"), "decalxy"));
|
||||
unwrap_context<DecalXY>>::def_wrap(ctx_cls, "setBelDecal", (arg("bel"), "decalxy"));
|
||||
fn_wrapper_2a_v<Context, decltype(&Context::setGroupDecal), &Context::setGroupDecal, conv_from_str<DecalId>,
|
||||
pass_through<DecalXY>>::def_wrap(ctx_cls, "setGroupDecal", (arg("group"), "decalxy"));
|
||||
unwrap_context<DecalXY>>::def_wrap(ctx_cls, "setGroupDecal", (arg("group"), "decalxy"));
|
||||
|
||||
fn_wrapper_3a_v<Context, decltype(&Context::setWireAttr), &Context::setWireAttr, conv_from_str<DecalId>,
|
||||
conv_from_str<IdString>, pass_through<std::string>>::def_wrap(ctx_cls, "setWireAttr",
|
||||
|
@ -14,6 +14,10 @@ Sq = 4
|
||||
# "Sparsity" of local to neighbour local wire pips
|
||||
Sl = 8
|
||||
|
||||
# Create graphic elements
|
||||
# Bels
|
||||
ctx.addDecalGraphic("bel", GraphicElement(type=TYPE_BOX, style=STYLE_INACTIVE, x1=0, y1=0, x2=0.2, y2=(1/(Z+1))-0.02, z=0))
|
||||
|
||||
def is_io(x, y):
|
||||
return x == 0 or x == X-1 or y == 0 or y == Y-1
|
||||
|
||||
@ -37,7 +41,7 @@ for x in range(X):
|
||||
ctx.addBelInput(bel="X%dY%d_IO%d" % (x, y, z), name="I", wire="X%dY%dZ%d_I0" % (x, y, z))
|
||||
ctx.addBelInput(bel="X%dY%d_IO%d" % (x, y, z), name="EN", wire="X%dY%dZ%d_I1" % (x, y, z))
|
||||
ctx.addBelOutput(bel="X%dY%d_IO%d" % (x, y, z), name="O", wire="X%dY%dZ%d_Q" % (x, y, z))
|
||||
|
||||
ctx.setBelDecal(bel="X%dY%d_IO%d" % (x, y, z), decalxy=ctx.DecalXY("bel", 0.6, z * (1/(Z+1))))
|
||||
else:
|
||||
for z in range(Z):
|
||||
ctx.addBel(name="X%dY%d_SLICE%d" % (x, y, z), type="GENERIC_SLICE", loc=Loc(x, y, z), gb=False)
|
||||
@ -45,6 +49,7 @@ for x in range(X):
|
||||
for k in range(K):
|
||||
ctx.addBelInput(bel="X%dY%d_SLICE%d" % (x, y, z), name="I[%d]" % k, wire="X%dY%dZ%d_I%d" % (x, y, z, k))
|
||||
ctx.addBelOutput(bel="X%dY%d_SLICE%d" % (x, y, z), name="Q", wire="X%dY%dZ%d_Q" % (x, y, z))
|
||||
ctx.setBelDecal(bel="X%dY%d_SLICE%d" % (x, y, z), decalxy=ctx.DecalXY("bel", 0.6, z * (1/(Z+1))))
|
||||
|
||||
for x in range(X):
|
||||
for y in range(Y):
|
||||
|
@ -96,9 +96,10 @@ void PythonTab::newContext(Context *ctx)
|
||||
console->clear();
|
||||
|
||||
pyinterpreter_preinit();
|
||||
init_python("nextpnr", !initialized);
|
||||
init_python("nextpnr", true);
|
||||
pyinterpreter_initialize();
|
||||
pyinterpreter_aquire();
|
||||
init_python("nextpnr", false);
|
||||
python_export_global("ctx", ctx);
|
||||
pyinterpreter_release();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user