def resolve_port(self, port, available_types, available_constants): ''' Resolve a port of the entity. `port`: The unresolved port object. `available_types`: A dictionary of known types. `available_constants`: A dictionary of known constants and generics. ''' if port.typ in available_types: resolved_typ = available_types[port.typ] elif isinstance(port.typ, str): raise resolution.ResolutionError( 'Failed to resolve port of type "{}". '.format(port.typ) + 'Perhaps a use statement is missing.') else: resolved_typ = port.typ.resolve(available_types, available_constants) resolved_port = Port(name=port.name, direction=port.direction, typ=resolved_typ) if resolved_port.typ.unconstrained: raise resolution.ResolutionError( 'Entity {}: Port {}: unconstrained port'.format( self.identifier, port.name)) return resolved_port
def resolve_expression(expression, constants): ''' Replace all strings in an expression with the appropriate `Constant` objects. ''' constant_dependencies = math_parser.get_constant_list(expression) missing_constants = set(constant_dependencies) - set(constants.keys()) if missing_constants: raise resolution.ResolutionError('Missing constants {}'.format(missing_constants)) if constant_dependencies: resolved_e = math_parser.make_substitute_function(constants)(expression) else: resolved_e = expression return resolved_e
def resolve(self, types, constants): ''' Replace references to types and constants to resolved types and constants. `types`: a dictionary of resolved types. `constants`: a dictionary of resolved constants. ''' if self.unconstrained_type_identifier is not None: if self.unconstrained_type_identifier not in types: raise resolution.ResolutionError( '{} is not a known type.'.format( self.unconstrained_type_identifier)) unconstrained_type = types[self.unconstrained_type_identifier] else: unconstrained_type = self.unconstrained_type.resolve( types, constants) size = resolve_expression(self.size, constants) return ConstrainedArray(identifier=self.identifier, unconstrained_type=unconstrained_type, size=size, constants=constants)
def resolve(self, packages, must_resolve=True): ''' Resolve the entity. This involves resolving the uses, constants and ports. ''' resolved_uses = package.resolve_uses(self.uses, packages, must_resolve=must_resolve) available_types, available_constants = package.combine_packages( [u.package for u in resolved_uses.values()]) available_constants_generics = package.exclusive_dict_merge( available_constants, self.generics) resolved_ports = collections.OrderedDict() for name, port in self.ports.items(): try: resolved_port = self.resolve_port( port=port, available_types=available_types, available_constants=available_constants_generics) resolved_ports[name] = resolved_port except resolution.ResolutionError as error: # If we can't resolve and `must_resolve` isn't True then we just # skip ports that we can't resolve. if must_resolve: error_msg = 'Failed to resolve port {} in entity {}.'.format( self.identifier, port.name) error_msg += ' ' + error.args[0] raise resolution.ResolutionError(error_msg) from error resolved_entity = Entity( identifier=self.identifier, generics=self.generics, ports=resolved_ports, uses=resolved_uses, ) return resolved_entity