python: Add bindings for hierarchy structures Signed-off-by: David Shah <dave@ds0.me>
diff --git a/common/arch_pybindings_shared.h b/common/arch_pybindings_shared.h index f681af9..89a61da 100644 --- a/common/arch_pybindings_shared.h +++ b/common/arch_pybindings_shared.h
@@ -5,6 +5,10 @@ readonly_wrapper<Context, decltype(&Context::nets), &Context::nets, wrap_context<NetMap &>>::def_wrap(ctx_cls, "nets"); readonly_wrapper<Context, decltype(&Context::net_aliases), &Context::net_aliases, wrap_context<AliasMap &>>::def_wrap( ctx_cls, "net_aliases"); +readonly_wrapper<Context, decltype(&Context::hierarchy), &Context::hierarchy, wrap_context<HierarchyMap &>>::def_wrap( + ctx_cls, "hierarchy"); +readwrite_wrapper<Context, decltype(&Context::top_module), &Context::top_module, conv_to_str<IdString>, + conv_from_str<IdString>>::def_wrap(ctx_cls, "top_module"); fn_wrapper_1a<Context, decltype(&Context::getNetByAlias), &Context::getNetByAlias, deref_and_wrap<NetInfo>, conv_from_str<IdString>>::def_wrap(ctx_cls, "getNetByAlias");
diff --git a/common/nextpnr.h b/common/nextpnr.h index ceea208..7dfebd6 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h
@@ -530,7 +530,7 @@ // Represents the contents of a non-leaf cell in a design // with hierarchy -struct HierachicalPort +struct HierarchicalPort { IdString name; PortType dir; @@ -539,12 +539,12 @@ bool upto; }; -struct HierachicalCell +struct HierarchicalCell { IdString name, type, parent, fullpath; // Name inside cell instance -> global name std::unordered_map<IdString, IdString> leaf_cells, nets; - std::unordered_map<IdString, HierachicalPort> ports; + std::unordered_map<IdString, HierarchicalPort> ports; // Name inside cell instance -> global name std::unordered_map<IdString, IdString> hier_cells; }; @@ -643,7 +643,7 @@ std::unordered_map<IdString, std::unique_ptr<CellInfo>> cells; // Hierarchical (non-leaf) cells by full path - std::unordered_map<IdString, HierachicalCell> hierarchy; + std::unordered_map<IdString, HierarchicalCell> hierarchy; // This is the root of the above structure IdString top_module;
diff --git a/common/pybindings.cc b/common/pybindings.cc index 5383028..3b2a374 100644 --- a/common/pybindings.cc +++ b/common/pybindings.cc
@@ -131,7 +131,7 @@ typedef std::unordered_map<IdString, Property> AttrMap; typedef std::unordered_map<IdString, PortInfo> PortMap; - typedef std::unordered_map<IdString, IdString> PinMap; + typedef std::unordered_map<IdString, IdString> IdIdMap; typedef std::unordered_map<IdString, std::unique_ptr<Region>> RegionMap; class_<BaseCtx, BaseCtx *, boost::noncopyable>("BaseCtx", no_init); @@ -157,8 +157,8 @@ conv_from_str<BelId>>::def_wrap(ci_cls, "bel"); readwrite_wrapper<CellInfo &, decltype(&CellInfo::belStrength), &CellInfo::belStrength, pass_through<PlaceStrength>, pass_through<PlaceStrength>>::def_wrap(ci_cls, "belStrength"); - readonly_wrapper<CellInfo &, decltype(&CellInfo::pins), &CellInfo::pins, wrap_context<PinMap &>>::def_wrap(ci_cls, - "pins"); + readonly_wrapper<CellInfo &, decltype(&CellInfo::pins), &CellInfo::pins, wrap_context<IdIdMap &>>::def_wrap(ci_cls, + "pins"); fn_wrapper_1a_v<CellInfo &, decltype(&CellInfo::addInput), &CellInfo::addInput, conv_from_str<IdString>>::def_wrap( ci_cls, "addInput"); @@ -230,9 +230,25 @@ readonly_wrapper<Region &, decltype(&Region::wires), &Region::wires, wrap_context<WireSet &>>::def_wrap(region_cls, "wires"); + auto hierarchy_cls = class_<ContextualWrapper<HierarchicalCell &>>("HierarchicalCell", no_init); + readwrite_wrapper<HierarchicalCell &, decltype(&HierarchicalCell::name), &HierarchicalCell::name, + conv_to_str<IdString>, conv_from_str<IdString>>::def_wrap(hierarchy_cls, "name"); + readwrite_wrapper<HierarchicalCell &, decltype(&HierarchicalCell::type), &HierarchicalCell::type, + conv_to_str<IdString>, conv_from_str<IdString>>::def_wrap(hierarchy_cls, "type"); + readwrite_wrapper<HierarchicalCell &, decltype(&HierarchicalCell::parent), &HierarchicalCell::parent, + conv_to_str<IdString>, conv_from_str<IdString>>::def_wrap(hierarchy_cls, "parent"); + readwrite_wrapper<HierarchicalCell &, decltype(&HierarchicalCell::fullpath), &HierarchicalCell::fullpath, + conv_to_str<IdString>, conv_from_str<IdString>>::def_wrap(hierarchy_cls, "fullpath"); + + readonly_wrapper<HierarchicalCell &, decltype(&HierarchicalCell::leaf_cells), &HierarchicalCell::leaf_cells, + wrap_context<IdIdMap &>>::def_wrap(hierarchy_cls, "leaf_cells"); + readonly_wrapper<HierarchicalCell &, decltype(&HierarchicalCell::nets), &HierarchicalCell::nets, + wrap_context<IdIdMap &>>::def_wrap(hierarchy_cls, "nets"); + readonly_wrapper<HierarchicalCell &, decltype(&HierarchicalCell::hier_cells), &HierarchicalCell::hier_cells, + wrap_context<IdIdMap &>>::def_wrap(hierarchy_cls, "hier_cells"); WRAP_MAP(AttrMap, conv_to_str<Property>, "AttrMap"); WRAP_MAP(PortMap, wrap_context<PortInfo &>, "PortMap"); - WRAP_MAP(PinMap, conv_to_str<IdString>, "PinMap"); + WRAP_MAP(IdIdMap, conv_to_str<IdString>, "IdIdMap"); WRAP_MAP(WireMap, wrap_context<PipMap &>, "WireMap"); WRAP_MAP_UPTR(RegionMap, "RegionMap");
diff --git a/ecp5/arch_pybindings.cc b/ecp5/arch_pybindings.cc index da6d3e5..cd5e31c 100644 --- a/ecp5/arch_pybindings.cc +++ b/ecp5/arch_pybindings.cc
@@ -49,6 +49,7 @@ typedef std::unordered_map<IdString, std::unique_ptr<CellInfo>> CellMap; typedef std::unordered_map<IdString, std::unique_ptr<NetInfo>> NetMap; typedef std::unordered_map<IdString, IdString> AliasMap; + typedef std::unordered_map<IdString, HierarchicalCell> HierarchyMap; auto belpin_cls = class_<ContextualWrapper<BelPin>>("BelPin", no_init); readonly_wrapper<BelPin, decltype(&BelPin::bel), &BelPin::bel, conv_to_str<BelId>>::def_wrap(belpin_cls, "bel"); @@ -64,6 +65,7 @@ WRAP_MAP_UPTR(CellMap, "IdCellMap"); WRAP_MAP_UPTR(NetMap, "IdNetMap"); + WRAP_MAP(HierarchyMap, wrap_context<HierarchicalCell &>, "HierarchyMap"); } NEXTPNR_NAMESPACE_END
diff --git a/frontend/frontend_base.h b/frontend/frontend_base.h index be76426..9e16cb2 100644 --- a/frontend/frontend_base.h +++ b/frontend/frontend_base.h
@@ -500,6 +500,7 @@ submod.prefix += '.'; submod.parent_path = m.path; submod.path = ctx->id(m.path.str(ctx) + "/" + name); + ctx->hierarchy[m.path].hier_cells[ctx->id(name)] = submod.path; // Do the submodule import auto type = impl.get_cell_type(cd); import_module(submod, name, type, mod_refs.at(ctx->id(type)));
diff --git a/generic/arch_pybindings.cc b/generic/arch_pybindings.cc index 8526e40..2600cac 100644 --- a/generic/arch_pybindings.cc +++ b/generic/arch_pybindings.cc
@@ -141,6 +141,7 @@ typedef std::unordered_map<IdString, std::unique_ptr<CellInfo>> CellMap; typedef std::unordered_map<IdString, std::unique_ptr<NetInfo>> NetMap; + typedef std::unordered_map<IdString, HierarchicalCell> HierarchyMap; readonly_wrapper<Context, decltype(&Context::cells), &Context::cells, wrap_context<CellMap &>>::def_wrap(ctx_cls, "cells"); @@ -231,6 +232,7 @@ WRAP_MAP_UPTR(CellMap, "IdCellMap"); WRAP_MAP_UPTR(NetMap, "IdNetMap"); + WRAP_MAP(HierarchyMap, wrap_context<HierarchicalCell &>, "HierarchyMap"); WRAP_VECTOR(const std::vector<IdString>, conv_to_str<IdString>); }
diff --git a/ice40/arch_pybindings.cc b/ice40/arch_pybindings.cc index cef7c58..e202209 100644 --- a/ice40/arch_pybindings.cc +++ b/ice40/arch_pybindings.cc
@@ -59,6 +59,7 @@ typedef std::unordered_map<IdString, std::unique_ptr<CellInfo>> CellMap; typedef std::unordered_map<IdString, std::unique_ptr<NetInfo>> NetMap; + typedef std::unordered_map<IdString, HierarchicalCell> HierarchyMap; typedef std::unordered_map<IdString, IdString> AliasMap; auto belpin_cls = class_<ContextualWrapper<BelPin>>("BelPin", no_init); @@ -75,6 +76,7 @@ WRAP_MAP_UPTR(CellMap, "IdCellMap"); WRAP_MAP_UPTR(NetMap, "IdNetMap"); + WRAP_MAP(HierarchyMap, wrap_context<HierarchicalCell &>, "HierarchyMap"); } NEXTPNR_NAMESPACE_END
diff --git a/python/report_hierarchy.py b/python/report_hierarchy.py new file mode 100644 index 0000000..6d409a9 --- /dev/null +++ b/python/report_hierarchy.py
@@ -0,0 +1,10 @@ +def visit(indent, data): + istr = " " * indent + print("{}{}: {}".format(istr, data.name, data.type)) + for lname, gname in data.leaf_cells: + print("{} {} -> {}".format(istr, lname, gname)) + for lname, gname in data.hier_cells: + visit(indent + 4, ctx.hierarchy[gname]) + +visit(0, ctx.hierarchy[ctx.top_module]) +