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))
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 _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