def get_module_instance(module_dir: str) -> AsModule:

    module = AsModule()
    toplevel_file = "hardware/hdl/vhdl/as_canny_pipeline.vhd"
    module.files = []
    module.dependencies = [
        "as_regmgr",
        "as_generic_filter_module",
        "as_pipeline_flush",
        "as_edge_threshold",
        "as_edge_nms",
        "as_cordic_direction",
        "as_gradient_weight",
        "as_edge_list",
        "as_feature_counter",
        "helpers",
        "as_2d_conv_filter_internal",
        "as_pipeline_row",
        "as_window_pipeline_helper",
    ]
    module.show_in_browser = True
    module.dev_status = AsModule.DevStatus.BETA
    module.module_type = AsModule.ModuleTypes.HARDWARE_SW_CTRL
    module.module_category = "Image Processing Pipeline"

    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module(module_dir + "/" + toplevel_file)

    return module
def add_templates():
    """This function is called when AsAutomatics initializes.
       It is used to construct all interface templates and assign them to the
       AsModule class for use when discovering interfaces in modules."""

    # When new interfaces are developed and added, add the interface to
    # AsAutomatics using a copy of one of the lines below.
    AsModule.add_global_interface_template(AsStream())
    AsModule.add_global_interface_template(AXIMasterMemoryInternal())
    AsModule.add_global_interface_template(CameraInputOV7670())
    AsModule.add_global_interface_template(AXISlaveRegisterInterface())
    AsModule.add_global_interface_template(SlaveRegisterInterfaceTemplate())
Beispiel #3
0
def get_module_instance(module_dir):

    module = AsModule()
    toplevel_file = "hardware/hdl/vhdl/as_base_registers.vhd"

    module.dependencies = ["as_regmgr"]

    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module("{mdir}/{toplevel}".format(mdir=module_dir,
                                                      toplevel=toplevel_file))

    return module
Beispiel #4
0
def get_module_instance(module_dir: str) -> AsModule:
    
    module = AsModule()
    toplevel_file = "hardware/hdl/vhdl/as_gauss.vhd"

    module.dependencies = ["as_regmgr", "as_window_buff_nxm", "as_generic_filter_module", "as_pipeline_flush"]

    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module("{mdir}/{toplevel}"
                           .format(mdir=module_dir, toplevel=toplevel_file))

    return module
Beispiel #5
0
def get_module_instance(module_dir: str) -> AsModule:
    module = AsModule()
    toplevel_file = "hardware/hdl/vhdl/as_threshold.vhd"

    module.files = []
    module.dependencies = []
    module.show_in_browser = True
    module.dev_status = AsModule.DevStatus.STABLE
    module.module_type = AsModule.ModuleTypes.HARDWARE_SW_CTRL
    module.module_category = "Image Processing Operations"

    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module(module_dir + "/" + toplevel_file)

    return module
Beispiel #6
0
def get_module_instance(module_dir: str) -> AsModule:
    module = AsModule()

    toplevel_file = "hardware/hdl/vhdl/fifo/fifo_fwft.vhd"
    module.files = []
    module.dependencies = ["helpers", "ram"]
    module.show_in_browser = False
    module.dev_status = AsModule.DevStatus.STABLE
    module.module_type = AsModule.ModuleTypes.HARDWARE
    module.module_category = "Internal Submodules"

    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module(module_dir + "/" + toplevel_file)

    return module
Beispiel #7
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
Beispiel #8
0
def get_module_instance(module_dir: str) -> AsModule:

    module = AsModule()
    toplevel_file = "hardware/hdl/vhdl/as_reorder.vhd"
    module.files = []
    module.dependencies = []
    module.show_in_browser = True
    module.dev_status = AsModule.DevStatus.STABLE
    module.module_type = AsModule.ModuleTypes.HARDWARE
    module.module_category = "As Stream Infrastructure"

    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module(module_dir + "/" + toplevel_file)

    return module
Beispiel #9
0
def get_module_instance(module_dir: str) -> AsModule:

    module = AsModule()

    toplevel_file = "hardware/hdl/vhdl/as_memwriter.vhd"
    module.files = ["hardware/hdl/vhdl/as_mem_address_generator.vhd"]
    module.dependencies = ["as_regmgr", "helpers", "fifo_fwft"]
    module.show_in_browser = True
    module.dev_status = AsModule.DevStatus.STABLE
    module.module_type = AsModule.ModuleTypes.HARDWARE_SW_CTRL
    module.module_category = "Memory IO"

    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module(module_dir + "/" + toplevel_file)

    return module
Beispiel #10
0
def get_module_instance(module_dir: str) -> AsModule:

    module = AsModule()
    toplevel_file = "hardware/hdl/vhdl/as_picam.vhd"
    module.files = []
    module.dependencies = ["as_regmgr"]

    module.show_in_browser = True
    module.dev_status = AsModule.DevStatus.ALPHA
    module.module_type = AsModule.ModuleTypes.HARDWARE_SW_CTRL
    module.module_category = "External IO"

    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module(module_dir + "/" + toplevel_file)

    return module
def get_module_instance(module_dir: str) -> AsModule:

    module = AsModule()
    toplevel_file = "hardware/hdl/vhdl/as_stream_strobe_counter.vhd"
    module.files = []
    module.dependencies = []

    module.show_in_browser = True
    module.dev_status = AsModule.DevStatus.BETA
    module.module_type = AsModule.ModuleTypes.HARDWARE_SW_CTRL
    module.module_category = "Debugging Modules"

    # Automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module(module_dir + "/" + toplevel_file)

    return module
Beispiel #12
0
def add_global_interface_template(template: Interface) -> bool:
    """! @brief Add a new interface template class to use
    for all modules that are imported.
    @param template: An instance of the interface template to add.
                     Must inherit from the class Interface.
    @return True if the template was successfully added,
            False if a template of this name already exists."""
    return AsModule.add_global_interface_template(template)
def get_module_instance(module_dir: str) -> AsModule:
    module = AsModule()

    module.add_local_interface_template(AXISlaveExternal())

    toplevel_file = "hardware/hdl/vhdl/AXI/AXI_Slave.vhd"
    module.files = []
    module.dependencies = ["fifo_fwft", "helpers"]

    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module("{mdir}/{toplevel}".format(mdir=module_dir,
                                                      toplevel=toplevel_file))

    module.get_generic("C_S_AXI_DATA_WIDTH").set_value(None)
    module.get_generic("C_S_AXI_ADDR_WIDTH").set_value(None)

    return module
 def register_module(self, module: AsModule):
     """Add a module to this repository object."""
     if module.entity_name not in self.module_names:
         self.module_names.append(module.entity_name)
         if isinstance(module, AsWindowModule):
             self.window_modules.append(module.entity_name)
         self.modules[module.entity_name] = module
         module.repository_name = self.name
         return True
     return False
def get_module_instance(module_dir):

    module = AsModule()
    toplevel_file = "hardware/hdl/vhdl/as_base_registers.vhd"

    module.dependencies = ["as_regmgr"]
    module.show_in_browser = False
    module.dev_status = AsModule.DevStatus.WORK_IN_PROGRESS
    module.module_type = AsModule.ModuleTypes.HARDWARE_SW_CTRL
    module.module_category = "ASTERICS Infrastructure"

    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module(module_dir + "/" + toplevel_file)

    return module
def get_module_instance(module_dir: str) -> AsModule:
    module = AsModule()
    module.add_local_interface_template(SWRegInterface())

    toplevel_file = "hardware/hdl/vhdl/register_interface/as_regmgr.vhd"
    module.files = [("hardware/hdl/vhdl/register_interface/"
                     "as_generic_regslice.vhd")]
    module.dependencies = ["helpers"]

    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module("{mdir}/{toplevel}"
                           .format(mdir=module_dir, toplevel=toplevel_file))
    

    # Configuration method. This method is automatically executed
    # by Automatics during the connection process, only if the module was
    # automatically instantiated.
    # This way we can access information only available at runtime.
    def auto_inst_config(mod, inst_from):
        # inst_from is the module that automatically instantiated this module
        # mod is the instance of this module that was automatically instantiated
        mod.set_generic_value("REG_ADDR_WIDTH", "c_slave_reg_addr_width")
        mod.set_generic_value("REG_DATA_WIDTH", "C_S_AXI_DATA_WIDTH")
        mod.set_generic_value("MODULE_ADDR_WIDTH", "c_module_addr_width")
        base_addr_generic = \
            vstatic.REGMGR_BASEADDR_VAL.format(inst_from.name)
        mod.set_generic_value("MODULE_BASEADDR", base_addr_generic)
        regmgr_count = "_" + mod.name[-1] if mod.name[-1].isdigit() else ""
        target = vstatic.REGMGR_SW_DATA_OUT_TARGET \
                            .format(inst_from.name, regmgr_count)
        mod.set_port_fixed_value("sw_data_out", target)
        if not regmgr_count:
            regif = inst_from.register_ifs[0]
        else:
            regif = inst_from.register_ifs[int(regmgr_count.strip("_"))]
        mod.set_generic_value("REG_COUNT", str(regif.reg_count))
        mod.get_interface("out", if_type="slv_reg_interface") \
                .to_external = False

    # !Important! Assign the configuration function to this module instance
    module.auto_inst_config = auto_inst_config
    # Return the module instance to Automatics
    return module
def get_module_instance(module_dir: str) -> AsModule:

    module = AsModule()
    toplevel_file = "hardware/hdl/vhdl/as_iic.vhd"
    module.files = []
    module.dependencies = ["helpers", "as_regmgr"]

    module.add_local_interface_template(IIC_Interface())

    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module("{mdir}/{toplevel}".format(mdir=module_dir,
                                                      toplevel=toplevel_file))

    return module
Beispiel #18
0
 def register_module(self, module: AsModule):
     """! @brief Add a module to this repository object."""
     if module.entity_name not in self.module_names:
         self.module_names.append(module.entity_name)
         if isinstance(module, AsWindowModule):
             self.window_modules.append(module.entity_name)
         self.modules[module.entity_name] = module
         module.repository_name = self.name
         try:
             self.module_categories[module.module_category].append(module)
         except KeyError:
             self.module_categories[module.module_category] = [module]
         return True
     return False
Beispiel #19
0
def get_module_instance(module_dir: str) -> AsModule:

    module = AsModule()
    toplevel_file = "hardware/hdl/vhdl/as_single_conv_filter.vhd"

    module.dependencies = [
        "as_regmgr",
        "as_window_buff_nxm",
        "as_generic_filter_module",
        "as_pipeline_flush",
    ]
    module.show_in_browser = True
    module.dev_status = AsModule.DevStatus.UNMAINTAINED
    module.module_type = AsModule.ModuleTypes.HARDWARE_SW_CTRL
    module.module_category = "Image Processing Operations"

    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module(module_dir + "/" + toplevel_file)

    return module
 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))
def get_module_instance(module_dir: str) -> AsModule:

    module = AsModule()
    toplevel_file = "hdl/vhdl/as_gensync.vhd"
    module.files = []
    module.dependencies = []

    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module("{mdir}/hardware/{toplevel}".format(
        mdir=module_dir, toplevel=toplevel_file))

    return module
Beispiel #22
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
def get_module_instance(module_dir: str) -> AsModule:

    module = AsModule()

    toplevel_file = "hardware/hdl/vhdl/as_memwriter.vhd"
    module.files = ["hardware/hdl/vhdl/as_mem_address_generator.vhd"]
    module.dependencies = ["as_regmgr", "helpers", "fifo_fwft"]

    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module("{mdir}/{toplevel}".format(mdir=module_dir,
                                                      toplevel=toplevel_file))

    return module
def get_module_instance(module_dir: str) -> AsModule:

    module = AsModule()
    toplevel_file = "hardware/hdl/vhdl/as_mux.vhd"

    module.dependencies = []

    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module("{mdir}/{toplevel}".format(mdir=module_dir,
                                                      toplevel=toplevel_file))

    sel_reg = module.get_port("sel_reg")
    sel_reg.set_port_type("external")
    sel_reg.add_rule("external_port", "make_external")

    return module
Beispiel #25
0
    def define_module_to_wrap(self, module: AsModule):
        self.modules = [module]
        module.modlevel += 1
        self.name = module.name
        self.entity_name = module.name + "_wrapper"
        self.generics = []
        self.standard_port_templates = module.standard_port_templates
        set_delay(self, get_delay(module))
        for inter in module.interfaces:
            self.add_interface(inter)
        for port in module.ports:
            self.add_port(port)
        for port in module.standard_ports:
            self.add_standard_port(port)
        if isinstance(module, AsWindowModule):
            self.vhdl_libraries.append("as_generic_filter")
            setattr(self, "window_interfaces", module.window_interfaces)
            module.window_interfaces = []

        module.interfaces = []
        module.ports = []
        module.standard_ports = []

        full_port_list = self.get_full_port_list(include_signals=False)

        for port in full_port_list:
            nport = port.duplicate()
            if nport.port_type == "interface":
                nport.set_port_type("single")
            module.add_port(nport)
            if port.direction == "in":
                nport.incoming = port
                port.outgoing.append(nport)
            else:
                nport.outgoing.append(port)
                port.incoming = nport
def get_module_instance(module_dir: str) -> AsModule:
    module = AsModule()

    module.files = ["hardware/hdl/vhdl/pkg/as_generic_filter_pkg.vhd"]
    module.dependencies = []

    # As this is not a typical Automatics module (no VHDL entity)
    # we manually set the necessary attributes,
    # so Automatics can work with it normally
    module.module_dir = module_dir
    module.repository_name = "default"
    module.name = "as_generic_filter"
    module.entity_name = "as_generic_filter"
    module.generics = []
    module.standard_ports = []
    module.ports = []
    module.interfaces = []

    # Automatic module discovery would run into errors (no entity in 'as_generic_filter_pkg')
    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    #module.discover_module("{mdir}/{toplevel}"
    #                       .format(mdir=module_dir, toplevel=toplevel_file))

    return module
Beispiel #27
0
def get_module_instance(module_dir: str) -> AsModule:

    module = AsModule()

    module.add_local_interface_template(AXIMasterExternal())

    toplevel_file = "hardware/hdl/vhdl/AXI/AXI_Master.vhd"
    module.files = []
    module.dependencies = []
    module.show_in_browser = True
    module.dev_status = AsModule.DevStatus.STABLE
    module.module_type = AsModule.ModuleTypes.HARDWARE
    module.module_category = "IO Infrastructure"

    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module(module_dir + "/" + toplevel_file)

    internal_memory = module.get_interface("out")
    internal_memory.to_external = False
    internal_memory.instantiate_in_top = None

    module.get_generic("C_M_AXI_DATA_WIDTH").set_value(None)
    module.get_generic("C_M_AXI_ADDR_WIDTH").set_value(None)

    module.brief_description = "AXI Master interface. Usually automatically inserted by Automatics. Contains Xilinx-specific HDL code!"

    return module
Beispiel #28
0
def get_module_instance(module_dir: str) -> AsModule:
    
    module = AsModule()
    toplevel_file = "hardware/hdl/vhdl/as_sensor_ov7670.vhd"
    
    module.files = []
    module.dependencies = ["as_regmgr"]

    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module("{mdir}/{toplevel}"
                           .format(mdir=module_dir, toplevel=toplevel_file))

    module.iic_masters = []
    module.iic_masters_available = ("XILINX_PL_IIC", "XILINX_PS_IIC", "AS_IIC")

    # Special function definitions for as_sensor_ov7670 module:
    def add_iic_master(self, iic_type: str):
        self.iic_masters.append(iic_type)
        LOG.info("Added IIC master '%s' to '%s'", iic_type, self.name)
    
    def set_iic_masters(self, iic_types: list):
        self.iic_masters = iic_types

    def list_iic_masters(self):
        print("IIC masters available for '{}':".format(self.name))
        for iic in self.iic_masters_available:
            print(" - '{}'".format(iic))
        print("")

    def overwrite_sw_additions(self) -> list:
        additions = []
        for master in self.iic_masters:
            additions.append("#define AS_USING_{}".format(master.upper()))
        return additions
    
    # Assign functions to module instance
    # The call to "__get__(module)" is necessary and "binds" the method
    # the instance AsModule instance "module" that was created here!
    # Syntax:
    # module.<function_name (user script)> = <function to add>.__get__(module)
    module.set_iic_masters = set_iic_masters.__get__(module)
    module.add_iic_master = add_iic_master.__get__(module)
    module.list_iic_masters = list_iic_masters.__get__(module)
    module.get_software_additions = overwrite_sw_additions.__get__(module)

    return module
Beispiel #29
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
Beispiel #30
0
def manage_data_widths(source: Port, sink: Port) -> bool:
    """This function checks if the data widths of both ports are compatible.
    It resolves the data widths by replacing the generics with their respective
    values and compares the resolved versions. The port objects aren't modified.
    Exception: For toplevel modules an automatic propagation of generics is
    attempted if the specific case is clear cut.
    Parameters:
    source and sink: Both Port objects to compare and adjust.
    Returns: Boolean value: True on success, else False.
    """
    # Determine data flow direction
    if source.get_direction_normalized() == "in":
        pin = source
        pout = sink
    else:
        pin = sink
        pout = source

    # Get "state" of data widths (are they fixed?)
    pin_res = is_data_width_resolved(pin.data_width)
    pout_res = is_data_width_resolved(pout.data_width)

    # If fixed and matching -> OK
    if pin_res and pout_res:
        if pin.data_width == pout.data_width:
            return True

    LOG.debug(
        "Data widths of '%s' and '%s' not resolved, resolving...",
        pin.code_name,
        pout.code_name,
    )
    # Evaluate data widths
    pin_rdw = resolve_data_width(pin)
    pout_rdw = resolve_data_width(pout)

    # Do they match now? Yes -> OK
    if pin_rdw == pout_rdw:
        LOG.debug("Data widths resolved successfully!")
        return True
    # Else: Warn user; automatic adjustment requires more development!
    # The simple "beta" version caused more problems than it was worth...

    # For toplevel modules (AXI Master / Slave):
    # Attempt automatic management of the generics in very simple cases
    # as it is inconvenient for the user to manually resolve toplevel
    # problems (especially for auto-instantiated modules like AXI_Masters)
    pin_mod = AsModule.get_parent_module(pin)
    pout_mod = AsModule.get_parent_module(pout)
    # If either port's module is directly instantiated in toplevel
    if (pin_mod.modlevel < 2) or (pout_mod.modlevel < 2):
        igen = pin.generics
        ogen = pout.generics

        # If both ports have exactly one generic
        if len(igen) == 1 and len(ogen) == 1:
            igen = igen[0]
            ogen = ogen[0]
            # Store current values
            igen_v = igen.value
            ogen_v = ogen.value
            # Propagate the source generic to the sink port
            igen.value = ogen
            pin_rdw = resolve_data_width(pin)
            # Did that resolve the difference?
            if pin_rdw == pout_rdw:
                LOG.debug(
                    ("Generic Auto-Propagation: For ports '%s' and "
                     "'%s' of modules '%s' and '%s': Set value of "
                     "generic '%s' to generic '%s' of module '%s'."),
                    pout.code_name,
                    pin.code_name,
                    pin_mod.name,
                    pout_mod.name,
                    igen.code_name,
                    ogen.code_name,
                    pout_mod.name,
                )
                return True
            # If not, reverse the propagation and try the other way around
            igen.value = igen_v
            ogen.value = igen
            pin_rdw = resolve_data_width(pin)
            pout_rdw = resolve_data_width(pout)
            # Did that work?
            if pin_rdw == pout_rdw:
                LOG.debug(
                    ("Generic Auto-Propagation: For ports '%s' and "
                     "'%s' of modules '%s' and '%s': Set value of "
                     "generic '%s' to generic '%s' of module '%s'."),
                    pout.code_name,
                    pin.code_name,
                    pin_mod.name,
                    pout_mod.name,
                    ogen.code_name,
                    igen.code_name,
                    pin_mod.name,
                )
                return True
            # If not, reverse the propagation and print the user warning
            ogen.value = ogen_v
            pout_rdw = resolve_data_width(pout)
        # Gather some data to generate a useful user message
        # Involved Generic names
        all_gens = []
        all_gens.extend(pout.generics)
        all_gens.extend(pin.generics)
        all_gens = [gen.code_name for gen in all_gens]
        # Module names
        pout_mod = pout_mod.name
        pin_mod = pin_mod.name
        # Data width strings
        pout_dw = Port.data_width_to_string(pout.data_width)
        pout_rdw = Port.data_width_to_string(pout_rdw)
        pin_dw = Port.data_width_to_string(pin.data_width)
        pin_rdw = Port.data_width_to_string(pin_rdw)

        # User warning message
        LOG.error(
            ("Data widths between ports '%s' and '%s' of modules "
             "'%s' and '%s' differ and must be adjusted manually!\n"
             "Data widths: For port '%s': (%s) - resolved as (%s) | "
             "For port '%s': (%s) - resolved as (%s).\n"
             "Use generics '%s' of the respective modules."),
            pout.code_name,
            pin.code_name,
            pout_mod,
            pin_mod,
            pout.code_name,
            pout_dw,
            pout_rdw,
            pin.code_name,
            pin_dw,
            pin_rdw,
            all_gens,
        )

    # Special case for "slv_reg_interface" connections to as_regmgr
    if (pin.parent.type == "slv_reg_interface") and (pout.parent.type
                                                     == "slv_reg_interface"):
        if pin_mod.entity_name == "as_regmgr":
            pin.data_width = copy(pout.data_width)
            return True
        if pout_mod.entity_name == "as_regmgr":
            pout.data_width = copy(pin.data_width)
            return True

    return False