Exemple #1
0
def get_port_matching(module: AsModule, name_fragment: str) -> Port:
    """Return the first port from 'module' with 'name_fragment'
    in its 'code_name' attribute."""
    for port in module.get_full_port_list():
        if name_fragment in port.code_name:
            return port
    return None
 def __write_entity__(self, module: AsModule, file):
     """Generate and write the entity description of a given module
     to the output file."""
     # "Start" the entity description
     file.write("entity {} is\n".format(module.entity_name))
     # Generate the generic list
     self.generic_list = self.__convert_generic_entity_list__(module.generics)
     # Generate the port list
     self.port_list = self.__convert_port_entity_list__(module.get_full_port_list())
     # Write both lists to the file
     # Check if there are generics
     if self.generic_list:
         self.__write_list_to_file__(self.generic_list, file, "  generic(\n")
     self.__write_list_to_file__(self.port_list, file, "  port(\n")
     # "End" the entity description
     file.write("end entity {};\n".format(module.entity_name))
Exemple #3
0
    def _generate_entity(self, module: AsModule, file) -> list:
        """! @brief Generate and write the entity description of a given module
        to the output file."""
        # "Start" the entity description
        out_list = ["entity {} is".format(module.entity_name)]
        # Check if there are generics
        if module.generics:
            out_list.append("  generic(")
            # Generate the generic list
            out_list.extend(
                vhdl_write.convert_generic_entity_list(module.generics))

        out_list.append("  port(")
        # Generate the port list
        out_list.extend(
            vhdl_write.convert_port_entity_list(
                module.get_full_port_list(include_signals=False)))
        out_list.append("end entity {};\n".format(module.entity_name))
        return out_list
Exemple #4
0
    def _instantiate_module(self, module: AsModule) -> str:
        """! @brief Generate VHDL code as a list of strings to instantiate 'module'.
        Handles generic assignment and port mapping."""

        # -> Generating the generic map <-
        gen_str = []
        if module.generics:
            gen_str.append("  generic map(")
            for tgen in module.generics:
                # If the generic was set by the user in the generator,
                # use that value
                if isinstance(tgen.value, Generic):
                    ret = tgen.value.code_name
                else:
                    ret = tgen.get_value()
                    # Skip generics that use the default value
                    if ret == tgen.default_value:
                        continue
                gen_str.append("    {} => {},".format(tgen.code_name, ret))
        if len(gen_str) > 1:
            # Remove the last comma "," and add a closing bracket
            gen_str[-1] = gen_str[-1].strip(",")
            gen_str.append("  )\n")
            gen_str = "\n".join(gen_str)
        else:
            gen_str = ""

        # -> Generating the port map <-
        port_str = ["  port map("]
        full_port_list = module.get_full_port_list(include_signals=False)
        # For every port of this module:
        for port in full_port_list:
            # Target of the port map
            target = None

            # Determine the format for this ports port map line
            if full_port_list.index(port) < len(full_port_list) - 1:
                templ_str = "    {} => {},"
            else:
                templ_str = "    {} => {}\n  );"

            # -> Has glue signal <-
            # Port mapping target is the port's glue signal
            if port.glue_signal:
                glue = port.glue_signal
                try:
                    target = glue if isinstance(glue, str) else glue.code_name
                except AttributeError:
                    raise AsConnectionError(
                        port,
                        "Unsuitable object assigned as glue signal of port! "
                        "'{}: {}'".format(type(glue), str(glue)),
                    )
                # If this glue signal should be included in the signal list
                if isinstance(glue, GlueSignal) and glue.is_signal:
                    # Add the glue signal to the signal list
                    # Assemble vhdl signal declaration string
                    glue_signal_str = "  signal {} : {};".format(
                        glue.code_name, as_help.get_printable_datatype(glue))
                    # Make sure the same glue signal is not declared twice
                    if glue_signal_str not in self.signal_list:
                        self.signal_list.append(glue_signal_str)

            else:  # -> No glue signal present <-
                # Port mapping target is one of the connected ports,
                # depending on port direction
                target = (port.incoming
                          if port.get_direction_normalized() == "in" else
                          port.outgoing[0] if port.outgoing else None)
                # If the target is a Port object: use the code_name as target
                if isinstance(target, Port):
                    target = target.code_name
                # For strings: use the string as is (eg. for static values)
                elif isinstance(target, str):
                    target = target
                else:
                    target = None

                if not target:  # -> No target <-
                    # If the target is 'None': get neutral value
                    if port.get_direction_normalized() == "in":
                        target = port.get_neutral_value()
                    else:
                        target = "open"
                    # And warn the user of an unconnected port
                    if port.optional:
                        LOG.debug(
                            ("Optional port '%s' of module '%s' was "
                             "left unconnected, automatically set to [%s]!"),
                            port.code_name,
                            get_parent_module(port).name,
                            target,
                        )
                    else:
                        LOG.info(
                            ("Port '%s' of module '%s' was left "
                             "unconnected, automatically set to [%s]!"),
                            port.code_name,
                            get_parent_module(port).name,
                            target,
                        )
            # Insert the values in the format string and add to the return list
            port_str.append(templ_str.format(port.code_name, target))
        port_str = "\n".join(port_str)

        # --> OUT
        entity_keyword_str = ("" if isinstance(module, AsModuleWrapper) else
                              " entity")
        out_str = as_static.MODULE_INSTANTIATION_TEMPLATE.format(
            module_name=module.name,
            entity_name=module.entity_name,
            entity_keyword=entity_keyword_str,
            port_map=port_str,
            generic_map=gen_str,
        )
        return out_str
    def __instantiate_module__(self, module: AsModule) -> Sequence[str]:
        """Generate VHDL code as a list of strings to instantiate 'module'.
        Handles generic assignment and port mapping."""
        out = [
            "\n  -- Instantiate module {}:\n".format(module.name),
            "  {} : entity {}\n".format(
                "as_main_impl" if module.name == "as_main" else module.name,
                module.entity_name,
            ),
        ]
        gen_str = []
        if module.generics:
            gen_str.append("  generic map(\n")
            for tgen in module.generics:
                # If the generic was set by the user in the generator,
                # use that value
                if isinstance(tgen.value, Generic):
                    ret = tgen.value.code_name
                else:
                    ret = self.__get_printable_generic_value__(tgen)
                    # Skip generics that use the default value
                    if ret == tgen.default_value:
                        continue
                gen_str.append("    {} => {},\n".format(tgen.code_name, ret))
        if len(gen_str) > 1:
            # Replace the comma in the last generic mapping with a brace ')'
            gen_str[-1] = ")".join(gen_str[-1].rsplit(",", maxsplit=1))
            out.extend(gen_str)
        out.append("  port map(\n")

        full_port_list = module.get_full_port_list(include_signals=False)
        # For every port of this module:
        for port in full_port_list:
            # Target of the port map
            target = None

            # Determine the format for this ports port map line
            if full_port_list.index(port) < len(full_port_list) - 1:
                templ_str = "    {} => {},\n"
            else:
                templ_str = "    {} => {});\n"

            # Port mapping target is the port's glue signal
            if port.glue_signal and isinstance(port.glue_signal, GlueSignal):
                glue = port.glue_signal
                target = glue.code_name

                # If this glue signal should be included in the signal list
                if glue.is_signal:
                    # Add the glue signal to the signal list
                    # Assemble vhdl signal declaration string
                    glue_signal_str = "  signal {} : {};\n".format(
                        glue.code_name, as_help.get_printable_datatype(glue)
                    )
                    # Make sure the same glue signal is not declared twice
                    if glue_signal_str not in self.signal_list:
                        self.signal_list.append(glue_signal_str)
            else:  # If no glue signal present:
                # Port mapping target is one of the connected ports,
                # depending on port direction
                target = (
                    port.incoming
                    if port.get_direction_normalized() == "in"
                    else port.outgoing[0]
                    if port.outgoing
                    else None
                )
                # If the target is a Port object: use the code_name as target
                if isinstance(target, Port):
                    target = target.code_name
                # For strings: use the string as is (eg. for static values)
                elif isinstance(target, str):
                    target = target
                else:
                    target = None

                if not target:
                    # If the target is 'None': get neutral value
                    if port.get_direction_normalized() == "in":
                        target = port.get_neutral_value()
                    else:
                        target = "open"
                    # And warn the user of an unconnected port
                    if port.optional:
                        LOG.debug(
                            (
                                "Optional port '%s' of module '%s' was "
                                "left unconnected, automatically set to [%s]!"
                            ),
                            port.code_name,
                            AsModule.get_parent_module(port).name,
                            target,
                        )
                    else:
                        LOG.info(
                            (
                                "Port '%s' of module '%s' was left "
                                "unconnected, automatically set to [%s]!"
                            ),
                            port.code_name,
                            AsModule.get_parent_module(port).name,
                            target,
                        )
            # Insert the values in the format string and add to the return list
            out.append(templ_str.format(port.code_name, target))
        return out