Add Python helper functions for floorplanning

Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
David Shah 2018-12-14 12:16:29 +00:00
parent ae33ff397f
commit 493d6c3fb9
6 changed files with 81 additions and 1 deletions

View File

@ -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

View File

@ -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

View File

@ -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 &>);

View File

@ -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
{

View File

@ -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>);

View File

@ -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>);