aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/nextpnr.cc21
-rw-r--r--common/nextpnr.h3
-rw-r--r--common/pybindings.cc18
-rw-r--r--common/pywrappers.h26
-rw-r--r--ecp5/arch_pybindings.cc7
-rw-r--r--ice40/arch_pybindings.cc7
6 files changed, 81 insertions, 1 deletions
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<Region> 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<IdString, std::string> AttrMap;
typedef std::unordered_map<IdString, PortInfo> PortMap;
typedef std::unordered_map<IdString, IdString> PinMap;
+ typedef std::unordered_map<IdString, std::unique_ptr<Region>> RegionMap;
class_<BaseCtx, BaseCtx *, boost::noncopyable>("BaseCtx", no_init);
@@ -135,6 +136,8 @@ BOOST_PYTHON_MODULE(MODULE_NAME)
typedef std::vector<PortRef> PortRefVector;
typedef std::unordered_map<WireId, PipMap> WireMap;
+ typedef std::unordered_set<BelId> BelSet;
+ typedef std::unordered_set<WireId> WireSet;
auto ni_cls = class_<ContextualWrapper<NetInfo &>>("NetInfo", no_init);
readwrite_wrapper<NetInfo &, decltype(&NetInfo::name), &NetInfo::name, conv_to_str<IdString>,
@@ -163,10 +166,25 @@ BOOST_PYTHON_MODULE(MODULE_NAME)
def("parse_json", parse_json_shim);
def("load_design", load_design_shim, return_value_policy<manage_new_object>());
+ auto region_cls = class_<ContextualWrapper<Region &>>("Region", no_init);
+ readwrite_wrapper<Region &, decltype(&Region::name), &Region::name, conv_to_str<IdString>,
+ conv_from_str<IdString>>::def_wrap(region_cls, "name");
+ readwrite_wrapper<Region &, decltype(&Region::constr_bels), &Region::constr_bels, pass_through<bool>,
+ pass_through<bool>>::def_wrap(region_cls, "constr_bels");
+ readwrite_wrapper<Region &, decltype(&Region::constr_wires), &Region::constr_wires, pass_through<bool>,
+ pass_through<bool>>::def_wrap(region_cls, "constr_bels");
+ readwrite_wrapper<Region &, decltype(&Region::constr_pips), &Region::constr_pips, pass_through<bool>,
+ pass_through<bool>>::def_wrap(region_cls, "constr_pips");
+ readonly_wrapper<Region &, decltype(&Region::bels), &Region::bels, wrap_context<BelSet &>>::def_wrap(region_cls,
+ "bels");
+ readonly_wrapper<Region &, decltype(&Region::wires), &Region::wires, wrap_context<WireSet &>>::def_wrap(region_cls,
+ "wires");
+
WRAP_MAP(AttrMap, pass_through<std::string>, "AttrMap");
WRAP_MAP(PortMap, wrap_context<PortInfo &>, "PortMap");
WRAP_MAP(PinMap, conv_to_str<IdString>, "PinMap");
WRAP_MAP(WireMap, wrap_context<PipMap &>, "WireMap");
+ WRAP_MAP_UPTR(RegionMap, "RegionMap");
WRAP_VECTOR(PortRefVector, wrap_context<PortRef &>);
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 <typename Class, typename FuncT, FuncT fn, typename arg1_conv, typename
template <typename WrapCls> static void def_wrap(WrapCls cls_, const char *name) { cls_.def(name, wrapped_fn); }
};
-// Three parameters, one return
+// Three parameters, no return
template <typename Class, typename FuncT, FuncT fn, typename arg1_conv, typename arg2_conv, typename arg3_conv>
struct fn_wrapper_3a_v
{
@@ -288,6 +288,30 @@ struct fn_wrapper_3a_v
template <typename WrapCls> static void def_wrap(WrapCls cls_, const char *name) { cls_.def(name, wrapped_fn); }
};
+// Five parameters, no return
+template <typename Class, typename FuncT, FuncT fn, typename arg1_conv, typename arg2_conv, typename arg3_conv,
+ typename arg4_conv, typename arg5_conv>
+struct fn_wrapper_5a_v
+{
+ using class_type = typename WrapIfNotContext<Class>::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<Class>(cls);
+ Class &base = get_base<Class>(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 <typename WrapCls> static void def_wrap(WrapCls cls_, const char *name) { cls_.def(name, wrapped_fn); }
+};
+
// Wrapped getter
template <typename Class, typename MemT, MemT mem, typename v_conv> struct readonly_wrapper
{
diff --git a/ecp5/arch_pybindings.cc b/ecp5/arch_pybindings.cc
index 5e73a673..18d21112 100644
--- a/ecp5/arch_pybindings.cc
+++ b/ecp5/arch_pybindings.cc
@@ -133,6 +133,13 @@ void arch_wrap_python()
fn_wrapper_2a_v<Context, decltype(&Context::addClock), &Context::addClock, conv_from_str<IdString>,
pass_through<float>>::def_wrap(ctx_cls, "addClock");
+ fn_wrapper_5a_v<Context, decltype(&Context::createRectangularRegion), &Context::createRectangularRegion,
+ conv_from_str<IdString>, pass_through<int>, pass_through<int>, pass_through<int>,
+ pass_through<int>>::def_wrap(ctx_cls, "createRectangularRegion");
+ fn_wrapper_2a_v<Context, decltype(&Context::addBelToRegion), &Context::addBelToRegion, conv_from_str<IdString>,
+ conv_from_str<BelId>>::def_wrap(ctx_cls, "addBelToRegion");
+ fn_wrapper_2a_v<Context, decltype(&Context::constrainCellToRegion), &Context::constrainCellToRegion,
+ conv_from_str<IdString>, conv_from_str<IdString>>::def_wrap(ctx_cls, "constrainCellToRegion");
WRAP_RANGE(Bel, conv_to_str<BelId>);
WRAP_RANGE(Wire, conv_to_str<WireId>);
diff --git a/ice40/arch_pybindings.cc b/ice40/arch_pybindings.cc
index f0ca584b..bc0bfb84 100644
--- a/ice40/arch_pybindings.cc
+++ b/ice40/arch_pybindings.cc
@@ -144,6 +144,13 @@ void arch_wrap_python()
fn_wrapper_2a_v<Context, decltype(&Context::addClock), &Context::addClock, conv_from_str<IdString>,
pass_through<float>>::def_wrap(ctx_cls, "addClock");
+ fn_wrapper_5a_v<Context, decltype(&Context::createRectangularRegion), &Context::createRectangularRegion,
+ conv_from_str<IdString>, pass_through<int>, pass_through<int>, pass_through<int>,
+ pass_through<int>>::def_wrap(ctx_cls, "createRectangularRegion");
+ fn_wrapper_2a_v<Context, decltype(&Context::addBelToRegion), &Context::addBelToRegion, conv_from_str<IdString>,
+ conv_from_str<BelId>>::def_wrap(ctx_cls, "addBelToRegion");
+ fn_wrapper_2a_v<Context, decltype(&Context::constrainCellToRegion), &Context::constrainCellToRegion,
+ conv_from_str<IdString>, conv_from_str<IdString>>::def_wrap(ctx_cls, "constrainCellToRegion");
WRAP_RANGE(Bel, conv_to_str<BelId>);
WRAP_RANGE(Wire, conv_to_str<WireId>);