def HTypeFromIntfMapItem( interfaceMapItem: Union[Tuple[HdlType, Optional[str]], Tuple[Union[Interface, RtlSignalBase], str], Tuple[List[Union[Interface, RtlSignalBase]], str], Union[Interface, RtlSignalBase]]): isTerminal = False if isinstance(interfaceMapItem, (InterfaceBase, RtlSignalBase)): dtype, nameOrPrefix = _HTypeFromIntfMap(interfaceMapItem) isTerminal = True else: typeOrListOfInterfaces, nameOrPrefix = interfaceMapItem if isinstance(typeOrListOfInterfaces, list) and \ not isinstance(typeOrListOfInterfaces, IntfMap): # list of HType instances for array parts = [] arrayItem_t = None for item in typeOrListOfInterfaces: if isinstance(item, IntfMap): t = HTypeFromIntfMap(item) else: t = HTypeFromIntfMapItem(item).dtype if arrayItem_t is None: arrayItem_t = t else: assert arrayItem_t == t, ( "all items in array has to have same type", arrayItem_t, t) parts.append(t) dtype = arrayItem_t[len(parts)] elif isinstance(typeOrListOfInterfaces, HdlType): dtype = typeOrListOfInterfaces isTerminal = True elif isinstance(typeOrListOfInterfaces, (InterfaceBase, RtlSignalBase)): # renamed interface, ignore original name dtype = _HTypeFromIntfMap(typeOrListOfInterfaces)[0] isTerminal = True elif isinstance(typeOrListOfInterfaces, IntfMap): dtype = HTypeFromIntfMap(typeOrListOfInterfaces) else: # tuple (tuple of interfaces, prefix) assert isinstance(typeOrListOfInterfaces, tuple), typeOrListOfInterfaces dtype = HTypeFromIntfMap(typeOrListOfInterfaces) assert isinstance(nameOrPrefix, str) or nameOrPrefix is None, nameOrPrefix assert isinstance(dtype, HdlType) f = HStructField(dtype, nameOrPrefix) if not isTerminal: f.meta = HStructFieldMeta(split=True) return f
def HdlType_select(t: HStruct, fieldsToUse: filed_filter_t): """ Select fields from type structure (rest will become padding) :param t: HdlType type instance :param fieldsToUse: dict {name:{...}} or set of names to select, dictionary is used to select nested fields in HStruct/HUnion fields/array items (f.e. {"struct1": {"field1", "field2"}, "field3":{}} will select field1 and 2 from struct1 and field3 from root) """ template = [] fieldsToUse = fieldsToUse foundNames = set() if isinstance(t, (HArray, HStream)): assert len(fieldsToUse) <= 1, ( "select only on item 0, because it has to be same for all array items", fieldsToUse) k, v = list(fieldsToUse.items())[0] assert k == 0 new_t = copy(t) new_t.elment = HdlType_select(t.element_t, v) return new_t elif isinstance(t, (Bits, HEnum)): # scalar return t else: # struct/Union for f in t.fields: name = None subfields = [] if f.name is not None: try: if isinstance(fieldsToUse, dict): subfields = fieldsToUse[f.name] name = f.name else: if f.name in fieldsToUse: name = f.name except KeyError: name = None if name is not None and subfields: new_t = HdlType_select(f.dtype, subfields) template.append(HStructField(new_t, name)) else: template.append(HStructField(f.dtype, name)) if f.name is not None: foundNames.add(f.name) if isinstance(fieldsToUse, dict): fieldsToUse = set(fieldsToUse.keys()) assert fieldsToUse.issubset(foundNames) return t.__class__(*template)
def HStruct_selectFields(structT, fieldsToUse): """ Select fields from structure (rest will become spacing) :param structT: HStruct type instance :param fieldsToUse: dict {name:{...}} or set of names to select, dictionary is used to select nested fields in HStruct or HUnion fields (f.e. {"struct1": {"field1", "field2"}, "field3":{}} will select field1 and 2 from struct1 and field3 from root) """ template = [] fieldsToUse = fieldsToUse foundNames = set() for f in structT.fields: name = None subfields = [] if f.name is not None: try: if isinstance(fieldsToUse, dict): subfields = fieldsToUse[f.name] name = f.name else: if f.name in fieldsToUse: name = f.name except KeyError: name = None if name is not None and subfields: fields = HStruct_selectFields(f.dtype, subfields) template.append(HStructField(fields, name)) else: template.append(HStructField(f.dtype, name)) if f.name is not None: foundNames.add(f.name) if isinstance(fieldsToUse, dict): fieldsToUse = set(fieldsToUse.keys()) assert fieldsToUse.issubset(foundNames) return HStruct(*template)
def __init__(self, *template, name=None, const=False): """ :param template: list of tuples (type, name) or HStructField objects name can be None (= padding) :param name: optional name used for debugging purposes """ super(HUnion, self).__init__(const=const) self.fields = OrderedDict() self.field_by_name = self.fields self.name = name bit_length = None class UnionVal(UnionValBase): pass for f in template: try: field = HStructField(*f) except TypeError: field = f if not isinstance(field, HStructField): raise TypeError( "Template for struct field %s is not" " in valid format" % repr(f)) assert field.name is not None self.fields[field.name] = field t = field.dtype if bit_length is None: bit_length = t.bit_length() else: _bit_length = t.bit_length() if _bit_length != bit_length: raise TypeError( field.name, " has different size than others") memberHandler = HUnionMemberHandler(field) p = property(fget=memberHandler.get, fset=memberHandler.set) setattr(UnionVal, field.name, p) self.__bit_length_val = bit_length self.__hash = hash((self.name, tuple(self.fields.items()))) usedNames = set(self.fields.keys()) assert not protectedNames.intersection( usedNames), protectedNames.intersection(usedNames) if name is not None: UnionVal.__name__ = name + "Val" self.valueCls = UnionVal