From 493d6c3fb93fb7ffe96609ded9e392b327b2c86c Mon Sep 17 00:00:00 2001 From: David Shah Date: Fri, 14 Dec 2018 12:16:29 +0000 Subject: Add Python helper functions for floorplanning Signed-off-by: David Shah --- common/nextpnr.cc | 21 +++++++++++++++++++++ common/nextpnr.h | 3 +++ common/pybindings.cc | 18 ++++++++++++++++++ common/pywrappers.h | 26 +++++++++++++++++++++++++- 4 files changed, 67 insertions(+), 1 deletion(-) (limited to 'common') diff --git a/common/nextpnr.cc b/common/nextpnr.cc index bb941d3d..b0cbbbeb 100644 --- a/common/nextpnr.cc +++ b/common/nextpnr.cc @@ -421,4 +421,25 @@ void BaseCtx::addClock(IdString net, float freq) } } +void BaseCtx::createRectangularRegion(IdString name, int x0, int y0, int x1, int y1) +{ + std::unique_ptr new_region(new Region()); + new_region->name = name; + new_region->constr_bels = true; + new_region->constr_pips = false; + new_region->constr_wires = false; + for (int x = x0; x <= x1; x++) { + for (int y = y0; y <= y1; y++) { + for (auto bel : getCtx()->getBelsByTile(x, y)) + new_region->bels.insert(bel); + } + } + region[name] = std::move(new_region); +} +void BaseCtx::addBelToRegion(IdString name, BelId bel) { region[name]->bels.insert(bel); } +void BaseCtx::constrainCellToRegion(IdString cell, IdString region_name) +{ + cells[cell]->region = region[region_name].get(); +} + NEXTPNR_NAMESPACE_END diff --git a/common/nextpnr.h b/common/nextpnr.h index d58ae529..5967ecee 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -637,6 +637,9 @@ struct BaseCtx // Intended to simplify Python API void addClock(IdString net, float freq); + 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); }; NEXTPNR_NAMESPACE_END diff --git a/common/pybindings.cc b/common/pybindings.cc index 6cae889d..eee78b5e 100644 --- a/common/pybindings.cc +++ b/common/pybindings.cc @@ -104,6 +104,7 @@ BOOST_PYTHON_MODULE(MODULE_NAME) typedef std::unordered_map AttrMap; typedef std::unordered_map PortMap; typedef std::unordered_map PinMap; + typedef std::unordered_map> RegionMap; class_("BaseCtx", no_init); @@ -135,6 +136,8 @@ BOOST_PYTHON_MODULE(MODULE_NAME) typedef std::vector PortRefVector; typedef std::unordered_map WireMap; + typedef std::unordered_set BelSet; + typedef std::unordered_set WireSet; auto ni_cls = class_>("NetInfo", no_init); readwrite_wrapper, @@ -163,10 +166,25 @@ BOOST_PYTHON_MODULE(MODULE_NAME) def("parse_json", parse_json_shim); def("load_design", load_design_shim, return_value_policy()); + auto region_cls = class_>("Region", no_init); + readwrite_wrapper, + conv_from_str>::def_wrap(region_cls, "name"); + readwrite_wrapper, + pass_through>::def_wrap(region_cls, "constr_bels"); + readwrite_wrapper, + pass_through>::def_wrap(region_cls, "constr_bels"); + readwrite_wrapper, + pass_through>::def_wrap(region_cls, "constr_pips"); + readonly_wrapper>::def_wrap(region_cls, + "bels"); + readonly_wrapper>::def_wrap(region_cls, + "wires"); + WRAP_MAP(AttrMap, pass_through, "AttrMap"); WRAP_MAP(PortMap, wrap_context, "PortMap"); WRAP_MAP(PinMap, conv_to_str, "PinMap"); WRAP_MAP(WireMap, wrap_context, "WireMap"); + WRAP_MAP_UPTR(RegionMap, "RegionMap"); WRAP_VECTOR(PortRefVector, wrap_context); diff --git a/common/pywrappers.h b/common/pywrappers.h index 4e463afd..427c3623 100644 --- a/common/pywrappers.h +++ b/common/pywrappers.h @@ -269,7 +269,7 @@ template static void def_wrap(WrapCls cls_, const char *name) { cls_.def(name, wrapped_fn); } }; -// Three parameters, one return +// Three parameters, no return template struct fn_wrapper_3a_v { @@ -288,6 +288,30 @@ struct fn_wrapper_3a_v template static void def_wrap(WrapCls cls_, const char *name) { cls_.def(name, wrapped_fn); } }; +// Five parameters, no return +template +struct fn_wrapper_5a_v +{ + using class_type = typename WrapIfNotContext::maybe_wrapped_t; + using conv_arg1_type = typename arg1_conv::arg_type; + using conv_arg2_type = typename arg2_conv::arg_type; + using conv_arg3_type = typename arg3_conv::arg_type; + using conv_arg4_type = typename arg4_conv::arg_type; + using conv_arg5_type = typename arg5_conv::arg_type; + + static void wrapped_fn(class_type &cls, conv_arg1_type arg1, conv_arg2_type arg2, conv_arg3_type arg3, + conv_arg4_type arg4, conv_arg5_type arg5) + { + Context *ctx = get_ctx(cls); + Class &base = get_base(cls); + return (base.*fn)(arg1_conv()(ctx, arg1), arg2_conv()(ctx, arg2), arg3_conv()(ctx, arg3), + arg4_conv()(ctx, arg4), arg5_conv()(ctx, arg5)); + } + + template static void def_wrap(WrapCls cls_, const char *name) { cls_.def(name, wrapped_fn); } +}; + // Wrapped getter template struct readonly_wrapper { -- cgit v1.2.3