Ejemplo n.º 1
0
 def _get_ref_map(
         self,
         prefix: edgir.LocalPath) -> IdentityDict[Refable, edgir.LocalPath]:
     return super()._get_ref_map(prefix) + IdentityDict(
         [(self.name(), edgir.localpath_concat(prefix, edgir.NAME))], *[
             param._get_ref_map(edgir.localpath_concat(prefix, name))
             for (name, param) in self._parameters.items()
         ], *[
             port._get_ref_map(edgir.localpath_concat(prefix, name))
             for (name, port) in self._ports.items()
         ])
Ejemplo n.º 2
0
    def _get_ref_map(
            self,
            prefix: edgir.LocalPath) -> IdentityDict[Refable, edgir.LocalPath]:
        if self.__class__ == PortAdapter:  # TODO: hack to allow this to elaborate as abstract class while being invalid
            return IdentityDict()

        # return super().get_ref_map(prefix) +  # TODO: dedup w/ BaseBlock, and does this break anything?
        return IdentityDict(
            *[
                param._get_ref_map(edgir.localpath_concat(prefix, name))
                for (name, param) in self._parameters.items()
            ], self.src._get_ref_map(edgir.localpath_concat(prefix, 'src')),
            self.dst._get_ref_map(edgir.localpath_concat(prefix, 'dst')))
Ejemplo n.º 3
0
    def _def_to_proto(self) -> edgir.Link:
        for cls in self._get_bases_of(
                BaseBlock
        ):  # type: ignore  # TODO avoid 'only concrete class' error
            assert issubclass(cls, Link)

        pb = self._populate_def_proto_block_base(edgir.Link())
        pb = self._populate_def_proto_block_contents(pb)
        pb = self._populate_def_proto_param_init(pb)
        # specifically ignore the port initializers

        # actually generate the links and connects
        ref_map = self._get_ref_map(edgir.LocalPath())
        self._connects.finalize()
        self._links_order: Dict[str, str] = self.Metadata({})
        for name, connect in self._connects.items_ordered():
            self._links_order[str(len(self._links_order))] = f"{name}"

            connect_elts = connect.generate_connections()
            assert connect_elts is not None and connect_elts.link_type is not None, "bad connect definition in link"

            link_path = edgir.localpath_concat(edgir.LocalPath(), name)
            pb.links[
                name].lib_elem.target.name = connect_elts.link_type._static_def_name(
                )

            for idx, (self_port, link_port_path) in enumerate(
                    connect_elts.bridged_connects):
                # TODO handle Vector types
                if isinstance(
                        self_port, DerivedVector
                ):  # TODO unify once we get rid of ref_map, especially to be more robust
                    pb.constraints[
                        f"(export){name}_{idx}"].exported.exterior_port.map_extract.container.ref.CopyFrom(
                            ref_map[self_port.base])
                    pb.constraints[
                        f"(export){name}_{idx}"].exported.exterior_port.map_extract.path.steps.add(
                        ).name = self_port.base._get_elt_sample()._name_of(
                            self_port.target)
                else:
                    pb.constraints[
                        f"(export){name}_{idx}"].exported.exterior_port.ref.CopyFrom(
                            ref_map[self_port])
                pb.constraints[
                    f"(export){name}_{idx}"].exported.internal_block_port.ref.CopyFrom(
                        edgir.localpath_concat(link_path, link_port_path))
                self._namespace_order.append(f"(export){name}_{idx}")

        return pb
Ejemplo n.º 4
0
 def _get_ref_map(
         self,
         prefix: edgir.LocalPath) -> IdentityDict[Refable, edgir.LocalPath]:
     return super()._get_ref_map(prefix) + IdentityDict(*[
         block._get_ref_map(edgir.localpath_concat(prefix, name))
         for (name, block) in self._blocks.items()
     ])
Ejemplo n.º 5
0
 def _get_ref_map(
         self,
         prefix: edgir.LocalPath) -> IdentityDict[Refable, edgir.LocalPath]:
     if self._link_instance is not None:
         link_refs = self._link_instance._get_ref_map(
             edgir.localpath_concat(prefix, edgir.CONNECTED_LINK))
     else:
         link_refs = IdentityDict([])
     return super()._get_ref_map(prefix) + IdentityDict[
         Refable, edgir.LocalPath](
             [(self.is_connected(),
               edgir.localpath_concat(prefix, edgir.IS_CONNECTED)),
              (self.name(), edgir.localpath_concat(prefix, edgir.NAME))], *[
                  param._get_ref_map(edgir.localpath_concat(prefix, name))
                  for name, param in self._parameters.items()
              ]) + link_refs
Ejemplo n.º 6
0
    def _populate_def_proto_hierarchy(
            self, pb: edgir.HierarchyBlock) -> edgir.HierarchyBlock:
        self._blocks.finalize()
        self._connects.finalize()
        self._chains.finalize()

        ref_map = self._get_ref_map(edgir.LocalPath())

        # opportunistic check in the frontend that all internal ports marked connected are connected
        all_connected_ports = IdentitySet[BasePort]()
        for name, connect in self._connects.items():
            if len(connect.ports) > 1:
                all_connected_ports.update(connect.ports)

        for name, block in self._blocks.items():
            pb.blocks[name].lib_elem.target.name = block._get_def_name()

        # actually generate the links and connects
        link_chain_names = IdentityDict[
            ConnectedPorts, List[str]]()  # prefer chain name where applicable
        # TODO generate into primary data structures
        for name, chain in self._chains.items_ordered():
            for i, connect in enumerate(chain.links):
                link_chain_names.setdefault(connect, []).append(f"{name}_{i}")

        for name, connect in self._connects.items_ordered():
            if connect in link_chain_names:
                if not name.startswith('anon_'):
                    pass  # prefer a named link above all else
                else:
                    name = link_chain_names[connect][
                        0]  # arbitrarily pick the first one for now, TODO disambiguate?

            connect_elts = connect.generate_connections()
            if connect_elts is None:  # single port net - effectively discard
                pass
            elif connect_elts.link_type is None:  # generate direct export
                pb.constraints[
                    f"(conn){name}"].exported.exterior_port.ref.CopyFrom(
                        ref_map[connect_elts.bridged_connects[0][0]])
                pb.constraints[
                    f"(conn){name}"].exported.internal_block_port.ref.CopyFrom(
                        ref_map[connect_elts.direct_connects[0][0]])
                self._namespace_order.append(f"(conn){name}")
            else:  # generate link
                link_path = edgir.localpath_concat(edgir.LocalPath(), name)

                self._namespace_order.append(f"{name}")
                pb.links[
                    name].lib_elem.target.name = connect_elts.link_type._static_def_name(
                    )

                for idx, (self_port, link_port_path) in enumerate(
                        connect_elts.bridged_connects):
                    assert isinstance(self_port, Port)
                    assert self_port.bridge_type is not None

                    port_name = self._name_of(self_port)
                    pb.blocks[
                        f"(bridge){port_name}"].lib_elem.target.name = self_port.bridge_type._static_def_name(
                        )
                    self._namespace_order.append(f"(bridge){port_name}")
                    bridge_path = edgir.localpath_concat(
                        edgir.LocalPath(), f"(bridge){port_name}")

                    pb.constraints[
                        f"(bridge){name}_b{idx}"].exported.exterior_port.ref.CopyFrom(
                            ref_map[self_port])
                    pb.constraints[
                        f"(bridge){name}_b{idx}"].exported.internal_block_port.ref.CopyFrom(
                            edgir.localpath_concat(bridge_path, 'outer_port'))
                    self._namespace_order.append(f"(bridge){name}_b{idx}")

                    pb.constraints[
                        f"(conn){name}_b{idx}"].connected.block_port.ref.CopyFrom(
                            edgir.localpath_concat(bridge_path, 'inner_link'))
                    pb.constraints[
                        f"(conn){name}_b{idx}"].connected.link_port.ref.CopyFrom(
                            edgir.localpath_concat(link_path, link_port_path))
                    self._namespace_order.append(f"(conn){name}_b{idx}")

                for idx, (subelt_port, link_port_path) in enumerate(
                        connect_elts.direct_connects):
                    pb.constraints[
                        f"(conn){name}_d{idx}"].connected.block_port.ref.CopyFrom(
                            ref_map[subelt_port])
                    pb.constraints[
                        f"(conn){name}_d{idx}"].connected.link_port.ref.CopyFrom(
                            edgir.localpath_concat(link_path, link_port_path))
                    self._namespace_order.append(f"(conn){name}_d{idx}")

        # generate block initializers
        for (block_name, block) in self._blocks.items():
            for (block_param_name, block_param) in block._init_params.items():
                if block_param.initializer is not None:
                    pb.constraints[
                        f'(init){block_name}.{block_param_name}'].CopyFrom(  # TODO better name
                            AssignBinding.make_assign(
                                block_param,
                                block_param._to_expr_type(
                                    block_param.initializer), ref_map))
                    self._namespace_order.append(
                        f'(init){block_name}.{block_param_name}')

        # generate H-block-specific order
        for name in self._blocks.keys_ordered():
            self._namespace_order.append(name)

        return pb