diff options
-rw-r--r-- | common/pybindings.cc | 70 | ||||
-rw-r--r-- | common/pycontainers.h | 14 | ||||
-rw-r--r-- | common/pywrappers.h | 65 | ||||
-rw-r--r-- | python/dump_design.py | 2 |
4 files changed, 125 insertions, 26 deletions
diff --git a/common/pybindings.cc b/common/pybindings.cc index a85c5fe2..9bca307c 100644 --- a/common/pybindings.cc +++ b/common/pybindings.cc @@ -82,43 +82,71 @@ BOOST_PYTHON_MODULE(MODULE_NAME) .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 *, 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") .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); + typedef std::unordered_map<IdString, std::string> AttrMap; + typedef std::unordered_map<IdString, PortInfo> PortMap; + typedef std::unordered_map<IdString, IdString> PinMap; 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); - readonly_wrapper<CellInfo &, typeof(&CellInfo::type), &CellInfo::type, conv_to_str<IdString>>::def_wrap(ci_cls, - "type"); + readwrite_wrapper<CellInfo &, typeof(&CellInfo::name), &CellInfo::name, conv_to_str<IdString>, + 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( 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("load_design", load_design_shim, return_value_policy<manage_new_object>()); 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(); } diff --git a/common/pycontainers.h b/common/pycontainers.h index c8d2257b..260a9dd6 100644 --- a/common/pycontainers.h +++ b/common/pycontainers.h @@ -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; } + static size_t len(wrapped_map &x) + { + return x.base.size(); + } + static void del(T const &x, std::string const &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); class_<wrapped_map>(map_name, no_init) .def("__iter__", rw::iter) - .def("__len__", &T::size) + .def("__len__", len) .def("__getitem__", get) .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); } + static size_t len(wrapped_map &x) + { + return x.base.size(); + } + static void del(T const &x, std::string const &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); class_<wrapped_map>(map_name, no_init) .def("__iter__", rw::iter) - .def("__len__", &T::size) + .def("__len__", len) .def("__getitem__", get) .def("__setitem__", set, with_custodian_and_ward<1, 2>()); } diff --git a/common/pywrappers.h b/common/pywrappers.h index 560d645d..0643eb0a 100644 --- a/common/pywrappers.h +++ b/common/pywrappers.h @@ -61,6 +61,7 @@ template <typename T> inline Context *get_ctx(typename WrapIfNotContext<T>::mayb { return wrp_ctx.ctx; } + template <> inline Context *get_ctx<Context>(WrapIfNotContext<Context>::maybe_wrapped_t &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; } + template <> inline Context &get_base<Context>(WrapIfNotContext<Context>::maybe_wrapped_t &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 template <typename T> struct string_converter; +class bad_wrap +{ +}; + // Action options template <typename T> struct pass_through { @@ -92,6 +98,7 @@ template <typename T> struct pass_through template <typename T> struct wrap_context { inline ContextualWrapper<T> operator()(Context *ctx, T x) { return ContextualWrapper<T>(ctx, x); } + using arg_type = T; using ret_type = ContextualWrapper<T>; }; @@ -99,6 +106,7 @@ template <typename T> struct wrap_context template <typename T> struct unwrap_context { inline T operator()(Context *ctx, ContextualWrapper<T> x) { return x.base; } + using ret_type = T; using arg_type = ContextualWrapper<T>; }; @@ -106,6 +114,7 @@ template <typename T> struct unwrap_context template <typename T> struct conv_from_str { inline T operator()(Context *ctx, std::string x) { return string_converter<T>().from_str(ctx, x); } + using ret_type = T; using arg_type = std::string; }; @@ -113,10 +122,24 @@ template <typename T> struct conv_from_str template <typename T> struct conv_to_str { inline std::string operator()(Context *ctx, T x) { return string_converter<T>().to_str(ctx, x); } + using ret_type = std::string; 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 // Zero parameters, one return 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); } }; + // One parameter, one return 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); } }; + // One parameter, void 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 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); 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) @@ -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 NEXTPNR_NAMESPACE_END diff --git a/python/dump_design.py b/python/dump_design.py index 37309f6f..c75df9a1 100644 --- a/python/dump_design.py +++ b/python/dump_design.py @@ -21,5 +21,5 @@ for cell, cinfo in sorted(ctx.cells, key=lambda x: x.first): print("\t\t{}: {}".format(param, val)) if cinfo.bel.index != -1: - print("\tBel: {}".format(ctx.getBelName(cinfo.bel))) + print("\tBel: {}".format(cinfo.bel)) print() |