python: More design-related bindings, dump_design.py working again
Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
parent
79e91368f9
commit
46db500123
@ -82,43 +82,71 @@ BOOST_PYTHON_MODULE(MODULE_NAME)
|
|||||||
.def_readwrite("y2", &GraphicElement::y2)
|
.def_readwrite("y2", &GraphicElement::y2)
|
||||||
.def_readwrite("text", &GraphicElement::text);
|
.def_readwrite("text", &GraphicElement::text);
|
||||||
|
|
||||||
class_<PortRef>("PortRef").def_readwrite("cell", &PortRef::cell).def_readwrite("port", &PortRef::port);
|
|
||||||
|
|
||||||
class_<NetInfo, NetInfo *, boost::noncopyable>("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_<std::vector<PortRef>>("PortRefVector").def(vector_indexing_suite<std::vector<PortRef>>());
|
|
||||||
|
|
||||||
enum_<PortType>("PortType")
|
enum_<PortType>("PortType")
|
||||||
.value("PORT_IN", PORT_IN)
|
.value("PORT_IN", PORT_IN)
|
||||||
.value("PORT_OUT", PORT_OUT)
|
.value("PORT_OUT", PORT_OUT)
|
||||||
.value("PORT_INOUT", PORT_INOUT)
|
.value("PORT_INOUT", PORT_INOUT)
|
||||||
.export_values();
|
.export_values();
|
||||||
|
|
||||||
class_<PortInfo>("PortInfo")
|
typedef std::unordered_map<IdString, std::string> AttrMap;
|
||||||
.def_readwrite("name", &PortInfo::name)
|
typedef std::unordered_map<IdString, PortInfo> PortMap;
|
||||||
.def_readwrite("net", &PortInfo::net)
|
typedef std::unordered_map<IdString, IdString> PinMap;
|
||||||
.def_readwrite("type", &PortInfo::type);
|
|
||||||
|
|
||||||
class_<BaseCtx, BaseCtx *, boost::noncopyable>("BaseCtx", no_init);
|
class_<BaseCtx, BaseCtx *, boost::noncopyable>("BaseCtx", no_init);
|
||||||
|
|
||||||
typedef std::unordered_map<IdString, std::string> AttrMap;
|
|
||||||
|
|
||||||
auto ci_cls = class_<ContextualWrapper<CellInfo &>>("CellInfo", no_init);
|
auto ci_cls = class_<ContextualWrapper<CellInfo &>>("CellInfo", no_init);
|
||||||
readonly_wrapper<CellInfo &, typeof(&CellInfo::type), &CellInfo::type, conv_to_str<IdString>>::def_wrap(ci_cls,
|
readwrite_wrapper<CellInfo &, typeof(&CellInfo::name), &CellInfo::name, conv_to_str<IdString>,
|
||||||
"type");
|
conv_from_str<IdString>>::def_wrap(ci_cls, "name");
|
||||||
|
readwrite_wrapper<CellInfo &, typeof(&CellInfo::type), &CellInfo::type, conv_to_str<IdString>,
|
||||||
|
conv_from_str<IdString>>::def_wrap(ci_cls, "type");
|
||||||
readonly_wrapper<CellInfo &, typeof(&CellInfo::attrs), &CellInfo::attrs, wrap_context<AttrMap &>>::def_wrap(
|
readonly_wrapper<CellInfo &, typeof(&CellInfo::attrs), &CellInfo::attrs, wrap_context<AttrMap &>>::def_wrap(
|
||||||
ci_cls, "attrs");
|
ci_cls, "attrs");
|
||||||
|
readonly_wrapper<CellInfo &, typeof(&CellInfo::params), &CellInfo::params, wrap_context<AttrMap &>>::def_wrap(
|
||||||
|
ci_cls, "params");
|
||||||
|
readonly_wrapper<CellInfo &, typeof(&CellInfo::ports), &CellInfo::ports, wrap_context<PortMap &>>::def_wrap(
|
||||||
|
ci_cls, "ports");
|
||||||
|
readwrite_wrapper<CellInfo &, typeof(&CellInfo::bel), &CellInfo::bel, conv_to_str<BelId>,
|
||||||
|
conv_from_str<BelId>>::def_wrap(ci_cls, "bel");
|
||||||
|
readwrite_wrapper<CellInfo &, typeof(&CellInfo::belStrength), &CellInfo::belStrength, pass_through<PlaceStrength>,
|
||||||
|
pass_through<PlaceStrength>>::def_wrap(ci_cls, "belStrength");
|
||||||
|
readonly_wrapper<CellInfo &, typeof(&CellInfo::pins), &CellInfo::pins, wrap_context<PinMap &>>::def_wrap(ci_cls,
|
||||||
|
"pins");
|
||||||
|
|
||||||
|
auto pi_cls = class_<ContextualWrapper<PortInfo &>>("PortInfo", no_init);
|
||||||
|
readwrite_wrapper<PortInfo &, typeof(&PortInfo::name), &PortInfo::name, conv_to_str<IdString>,
|
||||||
|
conv_from_str<IdString>>::def_wrap(pi_cls, "name");
|
||||||
|
readonly_wrapper<PortInfo &, typeof(&PortInfo::net), &PortInfo::net, deref_and_wrap<NetInfo>>::def_wrap(pi_cls,
|
||||||
|
"net");
|
||||||
|
readwrite_wrapper<PortInfo &, typeof(&PortInfo::type), &PortInfo::type, pass_through<PortType>,
|
||||||
|
pass_through<PortType>>::def_wrap(pi_cls, "type");
|
||||||
|
|
||||||
|
typedef std::vector<PortRef> PortVector;
|
||||||
|
typedef std::unordered_map<WireId, PipMap> WireMap;
|
||||||
|
|
||||||
|
auto ni_cls = class_<ContextualWrapper<NetInfo &>>("NetInfo", no_init);
|
||||||
|
readwrite_wrapper<NetInfo &, typeof(&NetInfo::name), &NetInfo::name, conv_to_str<IdString>,
|
||||||
|
conv_from_str<IdString>>::def_wrap(ni_cls, "name");
|
||||||
|
readwrite_wrapper<NetInfo &, typeof(&NetInfo::driver), &NetInfo::driver, wrap_context<PortRef &>,
|
||||||
|
unwrap_context<PortRef &>>::def_wrap(ni_cls, "driver");
|
||||||
|
readonly_wrapper<NetInfo &, typeof(&NetInfo::users), &NetInfo::users, wrap_context<PortVector &>>::def_wrap(
|
||||||
|
ni_cls, "users");
|
||||||
|
readonly_wrapper<NetInfo &, typeof(&NetInfo::wires), &NetInfo::wires, wrap_context<WireMap &>>::def_wrap(ni_cls,
|
||||||
|
"wires");
|
||||||
|
|
||||||
|
auto pr_cls = class_<ContextualWrapper<PortRef &>>("PortRef", no_init);
|
||||||
|
readonly_wrapper<PortRef &, typeof(&PortRef::cell), &PortRef::cell, deref_and_wrap<CellInfo>>::def_wrap(pr_cls,
|
||||||
|
"cell");
|
||||||
|
readwrite_wrapper<PortRef &, typeof(&PortRef::port), &PortRef::port, conv_to_str<IdString>,
|
||||||
|
conv_from_str<IdString>>::def_wrap(pr_cls, "port");
|
||||||
|
readwrite_wrapper<PortRef &, typeof(&PortRef::budget), &PortRef::budget, pass_through<delay_t>,
|
||||||
|
pass_through<delay_t>>::def_wrap(pr_cls, "budget");
|
||||||
|
|
||||||
def("parse_json", parse_json_shim);
|
def("parse_json", parse_json_shim);
|
||||||
def("load_design", load_design_shim, return_value_policy<manage_new_object>());
|
def("load_design", load_design_shim, return_value_policy<manage_new_object>());
|
||||||
|
|
||||||
WRAP_MAP(AttrMap, pass_through<std::string>, "AttrMap");
|
WRAP_MAP(AttrMap, pass_through<std::string>, "AttrMap");
|
||||||
|
WRAP_MAP(PortMap, wrap_context<PortInfo &>, "PortMap");
|
||||||
|
WRAP_MAP(PinMap, conv_to_str<IdString>, "PinMap");
|
||||||
|
|
||||||
arch_wrap_python();
|
arch_wrap_python();
|
||||||
}
|
}
|
||||||
|
@ -276,6 +276,11 @@ template <typename T, typename value_conv> struct map_wrapper
|
|||||||
x.base[PythonConversion::string_converter<K>().from_str(x.ctx, i)] = v;
|
x.base[PythonConversion::string_converter<K>().from_str(x.ctx, i)] = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t len(wrapped_map &x)
|
||||||
|
{
|
||||||
|
return x.base.size();
|
||||||
|
}
|
||||||
|
|
||||||
static void del(T const &x, std::string const &i)
|
static void del(T const &x, std::string const &i)
|
||||||
{
|
{
|
||||||
K k = PythonConversion::string_converter<K>().from_str(x.ctx, i);
|
K k = PythonConversion::string_converter<K>().from_str(x.ctx, i);
|
||||||
@ -293,7 +298,7 @@ template <typename T, typename value_conv> struct map_wrapper
|
|||||||
typename rw::iter_wrap().wrap(iter_name);
|
typename rw::iter_wrap().wrap(iter_name);
|
||||||
class_<wrapped_map>(map_name, no_init)
|
class_<wrapped_map>(map_name, no_init)
|
||||||
.def("__iter__", rw::iter)
|
.def("__iter__", rw::iter)
|
||||||
.def("__len__", &T::size)
|
.def("__len__", len)
|
||||||
.def("__getitem__", get)
|
.def("__getitem__", get)
|
||||||
.def("__setitem__", set, with_custodian_and_ward<1, 2>());
|
.def("__setitem__", set, with_custodian_and_ward<1, 2>());
|
||||||
}
|
}
|
||||||
@ -394,6 +399,11 @@ template <typename T> struct map_wrapper_uptr
|
|||||||
x.base[PythonConversion::string_converter<K>().from_str(x.ctx, i)] = typename T::mapped_type(v);
|
x.base[PythonConversion::string_converter<K>().from_str(x.ctx, i)] = typename T::mapped_type(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t len(wrapped_map &x)
|
||||||
|
{
|
||||||
|
return x.base.size();
|
||||||
|
}
|
||||||
|
|
||||||
static void del(T const &x, std::string const &i)
|
static void del(T const &x, std::string const &i)
|
||||||
{
|
{
|
||||||
K k = PythonConversion::string_converter<K>().from_str(x.ctx, i);
|
K k = PythonConversion::string_converter<K>().from_str(x.ctx, i);
|
||||||
@ -411,7 +421,7 @@ template <typename T> struct map_wrapper_uptr
|
|||||||
typename rw::iter_wrap().wrap(iter_name);
|
typename rw::iter_wrap().wrap(iter_name);
|
||||||
class_<wrapped_map>(map_name, no_init)
|
class_<wrapped_map>(map_name, no_init)
|
||||||
.def("__iter__", rw::iter)
|
.def("__iter__", rw::iter)
|
||||||
.def("__len__", &T::size)
|
.def("__len__", len)
|
||||||
.def("__getitem__", get)
|
.def("__getitem__", get)
|
||||||
.def("__setitem__", set, with_custodian_and_ward<1, 2>());
|
.def("__setitem__", set, with_custodian_and_ward<1, 2>());
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,7 @@ template <typename T> inline Context *get_ctx(typename WrapIfNotContext<T>::mayb
|
|||||||
{
|
{
|
||||||
return wrp_ctx.ctx;
|
return wrp_ctx.ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> inline Context *get_ctx<Context>(WrapIfNotContext<Context>::maybe_wrapped_t &unwrp_ctx)
|
template <> inline Context *get_ctx<Context>(WrapIfNotContext<Context>::maybe_wrapped_t &unwrp_ctx)
|
||||||
{
|
{
|
||||||
return &unwrp_ctx;
|
return &unwrp_ctx;
|
||||||
@ -70,6 +71,7 @@ template <typename T> inline T &get_base(typename WrapIfNotContext<T>::maybe_wra
|
|||||||
{
|
{
|
||||||
return wrp_ctx.base;
|
return wrp_ctx.base;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> inline Context &get_base<Context>(WrapIfNotContext<Context>::maybe_wrapped_t &unwrp_ctx)
|
template <> inline Context &get_base<Context>(WrapIfNotContext<Context>::maybe_wrapped_t &unwrp_ctx)
|
||||||
{
|
{
|
||||||
return unwrp_ctx;
|
return unwrp_ctx;
|
||||||
@ -80,6 +82,10 @@ template <typename T> ContextualWrapper<T> wrap_ctx(Context *ctx, T x) { return
|
|||||||
// Dummy class, to be implemented by users
|
// Dummy class, to be implemented by users
|
||||||
template <typename T> struct string_converter;
|
template <typename T> struct string_converter;
|
||||||
|
|
||||||
|
class bad_wrap
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
// Action options
|
// Action options
|
||||||
template <typename T> struct pass_through
|
template <typename T> struct pass_through
|
||||||
{
|
{
|
||||||
@ -92,6 +98,7 @@ template <typename T> struct pass_through
|
|||||||
template <typename T> struct wrap_context
|
template <typename T> struct wrap_context
|
||||||
{
|
{
|
||||||
inline ContextualWrapper<T> operator()(Context *ctx, T x) { return ContextualWrapper<T>(ctx, x); }
|
inline ContextualWrapper<T> operator()(Context *ctx, T x) { return ContextualWrapper<T>(ctx, x); }
|
||||||
|
|
||||||
using arg_type = T;
|
using arg_type = T;
|
||||||
using ret_type = ContextualWrapper<T>;
|
using ret_type = ContextualWrapper<T>;
|
||||||
};
|
};
|
||||||
@ -99,6 +106,7 @@ template <typename T> struct wrap_context
|
|||||||
template <typename T> struct unwrap_context
|
template <typename T> struct unwrap_context
|
||||||
{
|
{
|
||||||
inline T operator()(Context *ctx, ContextualWrapper<T> x) { return x.base; }
|
inline T operator()(Context *ctx, ContextualWrapper<T> x) { return x.base; }
|
||||||
|
|
||||||
using ret_type = T;
|
using ret_type = T;
|
||||||
using arg_type = ContextualWrapper<T>;
|
using arg_type = ContextualWrapper<T>;
|
||||||
};
|
};
|
||||||
@ -106,6 +114,7 @@ template <typename T> struct unwrap_context
|
|||||||
template <typename T> struct conv_from_str
|
template <typename T> struct conv_from_str
|
||||||
{
|
{
|
||||||
inline T operator()(Context *ctx, std::string x) { return string_converter<T>().from_str(ctx, x); }
|
inline T operator()(Context *ctx, std::string x) { return string_converter<T>().from_str(ctx, x); }
|
||||||
|
|
||||||
using ret_type = T;
|
using ret_type = T;
|
||||||
using arg_type = std::string;
|
using arg_type = std::string;
|
||||||
};
|
};
|
||||||
@ -113,10 +122,24 @@ template <typename T> struct conv_from_str
|
|||||||
template <typename T> struct conv_to_str
|
template <typename T> struct conv_to_str
|
||||||
{
|
{
|
||||||
inline std::string operator()(Context *ctx, T x) { return string_converter<T>().to_str(ctx, x); }
|
inline std::string operator()(Context *ctx, T x) { return string_converter<T>().to_str(ctx, x); }
|
||||||
|
|
||||||
using ret_type = std::string;
|
using ret_type = std::string;
|
||||||
using arg_type = T;
|
using arg_type = T;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T> struct deref_and_wrap
|
||||||
|
{
|
||||||
|
inline ContextualWrapper<T&> operator()(Context *ctx, T *x)
|
||||||
|
{
|
||||||
|
if (x == nullptr)
|
||||||
|
throw bad_wrap();
|
||||||
|
return ContextualWrapper<T&>(ctx, *x);
|
||||||
|
}
|
||||||
|
|
||||||
|
using arg_type = T *;
|
||||||
|
using ret_type = ContextualWrapper<T&>;
|
||||||
|
};
|
||||||
|
|
||||||
// Function wrapper
|
// Function wrapper
|
||||||
// Zero parameters, one return
|
// Zero parameters, one return
|
||||||
template <typename Class, typename FuncT, FuncT fn, typename rv_conv> struct fn_wrapper_0a
|
template <typename Class, typename FuncT, FuncT fn, typename rv_conv> struct fn_wrapper_0a
|
||||||
@ -133,6 +156,7 @@ template <typename Class, typename FuncT, FuncT fn, typename rv_conv> struct fn_
|
|||||||
|
|
||||||
template <typename WrapCls> static void def_wrap(WrapCls cls_, const char *name) { cls_.def(name, wrapped_fn); }
|
template <typename WrapCls> static void def_wrap(WrapCls cls_, const char *name) { cls_.def(name, wrapped_fn); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// One parameter, one return
|
// One parameter, one return
|
||||||
template <typename Class, typename FuncT, FuncT fn, typename rv_conv, typename arg1_conv> struct fn_wrapper_1a
|
template <typename Class, typename FuncT, FuncT fn, typename rv_conv, typename arg1_conv> struct fn_wrapper_1a
|
||||||
{
|
{
|
||||||
@ -204,6 +228,7 @@ template <typename Class, typename FuncT, FuncT fn> struct fn_wrapper_0a_v
|
|||||||
|
|
||||||
template <typename WrapCls> static void def_wrap(WrapCls cls_, const char *name) { cls_.def(name, wrapped_fn); }
|
template <typename WrapCls> static void def_wrap(WrapCls cls_, const char *name) { cls_.def(name, wrapped_fn); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// One parameter, void
|
// One parameter, void
|
||||||
template <typename Class, typename FuncT, FuncT fn, typename arg1_conv> struct fn_wrapper_1a_v
|
template <typename Class, typename FuncT, FuncT fn, typename arg1_conv> struct fn_wrapper_1a_v
|
||||||
{
|
{
|
||||||
@ -262,11 +287,15 @@ template <typename Class, typename MemT, MemT mem, typename v_conv> struct reado
|
|||||||
using class_type = typename WrapIfNotContext<Class>::maybe_wrapped_t;
|
using class_type = typename WrapIfNotContext<Class>::maybe_wrapped_t;
|
||||||
using conv_val_type = typename v_conv::ret_type;
|
using conv_val_type = typename v_conv::ret_type;
|
||||||
|
|
||||||
static conv_val_type wrapped_getter(class_type &cls)
|
static object wrapped_getter(class_type &cls)
|
||||||
{
|
{
|
||||||
Context *ctx = get_ctx<Class>(cls);
|
Context *ctx = get_ctx<Class>(cls);
|
||||||
Class &base = get_base<Class>(cls);
|
Class &base = get_base<Class>(cls);
|
||||||
return v_conv()(ctx, (base.*mem));
|
try {
|
||||||
|
return object(v_conv()(ctx, (base.*mem)));
|
||||||
|
} catch (bad_wrap &) {
|
||||||
|
return object();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename WrapCls> static void def_wrap(WrapCls cls_, const char *name)
|
template <typename WrapCls> static void def_wrap(WrapCls cls_, const char *name)
|
||||||
@ -275,6 +304,38 @@ template <typename Class, typename MemT, MemT mem, typename v_conv> struct reado
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Wrapped getter/setter
|
||||||
|
template <typename Class, typename MemT, MemT mem, typename get_conv, typename set_conv> struct readwrite_wrapper
|
||||||
|
{
|
||||||
|
using class_type = typename WrapIfNotContext<Class>::maybe_wrapped_t;
|
||||||
|
using conv_val_type = typename get_conv::ret_type;
|
||||||
|
|
||||||
|
static object wrapped_getter(class_type &cls)
|
||||||
|
{
|
||||||
|
Context *ctx = get_ctx<Class>(cls);
|
||||||
|
Class &base = get_base<Class>(cls);
|
||||||
|
try {
|
||||||
|
return object(get_conv()(ctx, (base.*mem)));
|
||||||
|
} catch (bad_wrap &) {
|
||||||
|
return object();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using conv_arg_type = typename set_conv::arg_type;
|
||||||
|
|
||||||
|
static void wrapped_setter(class_type &cls, conv_arg_type val)
|
||||||
|
{
|
||||||
|
Context *ctx = get_ctx<Class>(cls);
|
||||||
|
Class &base = get_base<Class>(cls);
|
||||||
|
(base.*mem) = set_conv()(ctx, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename WrapCls> static void def_wrap(WrapCls cls_, const char *name)
|
||||||
|
{
|
||||||
|
cls_.add_property(name, wrapped_getter, wrapped_setter);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace PythonConversion
|
} // namespace PythonConversion
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
@ -21,5 +21,5 @@ for cell, cinfo in sorted(ctx.cells, key=lambda x: x.first):
|
|||||||
print("\t\t{}: {}".format(param, val))
|
print("\t\t{}: {}".format(param, val))
|
||||||
|
|
||||||
if cinfo.bel.index != -1:
|
if cinfo.bel.index != -1:
|
||||||
print("\tBel: {}".format(ctx.getBelName(cinfo.bel)))
|
print("\tBel: {}".format(cinfo.bel))
|
||||||
print()
|
print()
|
||||||
|
Loading…
Reference in New Issue
Block a user