def resolve_generic(port: Port) -> bool: """! @brief Make sure Generics within port's data width exist in its parent module. This method makes sure that the Generics in port's data width exist in the VDHL entity of port's entity. Port may also be a GlueSignal Process: 1. Extract Generic strings from port's data width 2. Match those strings to Generic objects in Port and the parent module 3. Check if the Generic value is set; Check for and match linked Generic 4. If necessary, substitute the Generic(s) with a match in group module 5. If possible, use the defined value of the Generic 6. Update port's data width and try to evaluate it. @param port: The data width attribute of this port will be resolved. @return True if the resolve function ran, False if nothing was done.""" port.data_width = __resolve_generic__(port.data_width, port) try: port.line_width = __resolve_generic__(port.line_width, port) return all( (dw.is_resolved() for dw in (port.data_width, port.line_width))) except AttributeError: pass return port.data_width.is_resolved()
def __get_ports__(self, file_obj) -> int: while True: # Get the next line with some code in it test = self.__peek_next_clean_line__(file_obj) # If that line is not a port declaration (no ':'), return if ":" not in test: return len(self.found_ports) # Advance to the next line line = self.__next_clean_line__(file_obj) # Clean and split the input line = line.strip("\n; ") words = line.split(":", 1) # Split the part after the ':' on the first whitespace params = words[1].strip().split(maxsplit=1) # Now we should have this arrangement for the code: # <port name> : <direction> ' ' <data type>[(<data width>)] # words[0] : words[1] # : params[0] ' ' params[1] '(' direction = params[0] name = words[0].strip() # Get the cleaned name LOG.debug("Found port '%s' in line '%s'", name, line) # If there's a parenthenses, we need to decode the data width parens_pos = params[1].find("(") if parens_pos > -1: # Extract data type and pass the data width definition data_type = params[1][:parens_pos] parens = params[1][parens_pos:] data_width = self.__get_data_width__(parens[1:-1]) LOG.debug("Data width translated as '%s'", data_width) else: # If no data width definition is present, assume width 1 data_type = params[1] data_width = Port.DataWidth(1, None, None) # Instantiate and add a new Port to the found ports list port = Port( name=name, code_name=name, direction=direction, data_type=data_type, data_width=data_width, ) if self.window_module and data_type == PIPE_WINDOW_TYPE: if len(data_width) < 3: LOG.error( ("Data type '%s' requires 3 dimensions! " "Instead got: '%s' - in file '%s'"), PIPE_WINDOW_TYPE, parens, self.vhdl_file, ) else: port.window_config = data_width[:2] port.data_width = data_width[2] LOG.debug( "Found window in '%s' for '%s': '%s'", self.entity_name, name, port.window_config, ) elif self.window_module and data_type == PIPE_LINE_TYPE: if len(data_width) < 2: LOG.error( ("Data type '%s' requires 2 dimensions! " "Instead got: '%s' - in file '%s'"), PIPE_LINE_TYPE, parens, self.vhdl_file, ) else: port.data_width = data_width[1] port.line_width = data_width[0] LOG.debug( "Found generic line in '%s' for '%s': '%s'", self.entity_name, name, port.line_width, ) self.found_ports.append(port)