From b1000870244dbb1a73198e23a859825865938b4c Mon Sep 17 00:00:00 2001 From: David Shah Date: Fri, 29 Nov 2019 16:25:11 +0000 Subject: python: Add bindings for hierarchy structures Signed-off-by: David Shah --- common/arch_pybindings_shared.h | 4 ++++ common/nextpnr.h | 8 ++++---- common/pybindings.cc | 24 ++++++++++++++++++++---- ecp5/arch_pybindings.cc | 2 ++ frontend/frontend_base.h | 1 + generic/arch_pybindings.cc | 2 ++ ice40/arch_pybindings.cc | 2 ++ python/report_hierarchy.py | 10 ++++++++++ 8 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 python/report_hierarchy.py diff --git a/common/arch_pybindings_shared.h b/common/arch_pybindings_shared.h index f681af92..89a61dad 100644 --- a/common/arch_pybindings_shared.h +++ b/common/arch_pybindings_shared.h @@ -5,6 +5,10 @@ readonly_wrapper>::def_wrap(ctx_cls, "nets"); readonly_wrapper>::def_wrap( ctx_cls, "net_aliases"); +readonly_wrapper>::def_wrap( + ctx_cls, "hierarchy"); +readwrite_wrapper, + conv_from_str>::def_wrap(ctx_cls, "top_module"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getNetByAlias"); diff --git a/common/nextpnr.h b/common/nextpnr.h index ceea2088..7dfebd62 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -530,7 +530,7 @@ struct TimingConstraint // 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 @@ struct HierachicalPort bool upto; }; -struct HierachicalCell +struct HierarchicalCell { IdString name, type, parent, fullpath; // Name inside cell instance -> global name std::unordered_map leaf_cells, nets; - std::unordered_map ports; + std::unordered_map ports; // Name inside cell instance -> global name std::unordered_map hier_cells; }; @@ -643,7 +643,7 @@ struct BaseCtx std::unordered_map> cells; // Hierarchical (non-leaf) cells by full path - std::unordered_map hierarchy; + std::unordered_map hierarchy; // This is the root of the above structure IdString top_module; diff --git a/common/pybindings.cc b/common/pybindings.cc index 53830284..3b2a3744 100644 --- a/common/pybindings.cc +++ b/common/pybindings.cc @@ -131,7 +131,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 IdIdMap; typedef std::unordered_map> RegionMap; class_("BaseCtx", no_init); @@ -157,8 +157,8 @@ BOOST_PYTHON_MODULE(MODULE_NAME) conv_from_str>::def_wrap(ci_cls, "bel"); readwrite_wrapper, pass_through>::def_wrap(ci_cls, "belStrength"); - readonly_wrapper>::def_wrap(ci_cls, - "pins"); + readonly_wrapper>::def_wrap(ci_cls, + "pins"); fn_wrapper_1a_v>::def_wrap( ci_cls, "addInput"); @@ -230,9 +230,25 @@ BOOST_PYTHON_MODULE(MODULE_NAME) readonly_wrapper>::def_wrap(region_cls, "wires"); + auto hierarchy_cls = class_>("HierarchicalCell", no_init); + readwrite_wrapper, conv_from_str>::def_wrap(hierarchy_cls, "name"); + readwrite_wrapper, conv_from_str>::def_wrap(hierarchy_cls, "type"); + readwrite_wrapper, conv_from_str>::def_wrap(hierarchy_cls, "parent"); + readwrite_wrapper, conv_from_str>::def_wrap(hierarchy_cls, "fullpath"); + + readonly_wrapper>::def_wrap(hierarchy_cls, "leaf_cells"); + readonly_wrapper>::def_wrap(hierarchy_cls, "nets"); + readonly_wrapper>::def_wrap(hierarchy_cls, "hier_cells"); WRAP_MAP(AttrMap, conv_to_str, "AttrMap"); WRAP_MAP(PortMap, wrap_context, "PortMap"); - WRAP_MAP(PinMap, conv_to_str, "PinMap"); + WRAP_MAP(IdIdMap, conv_to_str, "IdIdMap"); WRAP_MAP(WireMap, wrap_context, "WireMap"); WRAP_MAP_UPTR(RegionMap, "RegionMap"); diff --git a/ecp5/arch_pybindings.cc b/ecp5/arch_pybindings.cc index da6d3e50..cd5e31c3 100644 --- a/ecp5/arch_pybindings.cc +++ b/ecp5/arch_pybindings.cc @@ -49,6 +49,7 @@ void arch_wrap_python() typedef std::unordered_map> CellMap; typedef std::unordered_map> NetMap; typedef std::unordered_map AliasMap; + typedef std::unordered_map HierarchyMap; auto belpin_cls = class_>("BelPin", no_init); readonly_wrapper>::def_wrap(belpin_cls, "bel"); @@ -64,6 +65,7 @@ void arch_wrap_python() WRAP_MAP_UPTR(CellMap, "IdCellMap"); WRAP_MAP_UPTR(NetMap, "IdNetMap"); + WRAP_MAP(HierarchyMap, wrap_context, "HierarchyMap"); } NEXTPNR_NAMESPACE_END diff --git a/frontend/frontend_base.h b/frontend/frontend_base.h index be764266..9e16cb24 100644 --- a/frontend/frontend_base.h +++ b/frontend/frontend_base.h @@ -500,6 +500,7 @@ template struct GenericFrontend 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 8526e409..2600cac0 100644 --- a/generic/arch_pybindings.cc +++ b/generic/arch_pybindings.cc @@ -141,6 +141,7 @@ void arch_wrap_python() typedef std::unordered_map> CellMap; typedef std::unordered_map> NetMap; + typedef std::unordered_map HierarchyMap; readonly_wrapper>::def_wrap(ctx_cls, "cells"); @@ -231,6 +232,7 @@ void arch_wrap_python() WRAP_MAP_UPTR(CellMap, "IdCellMap"); WRAP_MAP_UPTR(NetMap, "IdNetMap"); + WRAP_MAP(HierarchyMap, wrap_context, "HierarchyMap"); WRAP_VECTOR(const std::vector, conv_to_str); } diff --git a/ice40/arch_pybindings.cc b/ice40/arch_pybindings.cc index cef7c58f..e2022091 100644 --- a/ice40/arch_pybindings.cc +++ b/ice40/arch_pybindings.cc @@ -59,6 +59,7 @@ void arch_wrap_python() typedef std::unordered_map> CellMap; typedef std::unordered_map> NetMap; + typedef std::unordered_map HierarchyMap; typedef std::unordered_map AliasMap; auto belpin_cls = class_>("BelPin", no_init); @@ -75,6 +76,7 @@ void arch_wrap_python() WRAP_MAP_UPTR(CellMap, "IdCellMap"); WRAP_MAP_UPTR(NetMap, "IdNetMap"); + WRAP_MAP(HierarchyMap, wrap_context, "HierarchyMap"); } NEXTPNR_NAMESPACE_END diff --git a/python/report_hierarchy.py b/python/report_hierarchy.py new file mode 100644 index 00000000..6d409a9b --- /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]) + -- cgit v1.2.3