Beispiel #1
0
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
Beispiel #2
0
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)
Beispiel #3
0
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)
Beispiel #4
0
    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