Exemplo n.º 1
0
 def __init__(self, index, name, elt, *parent):
     elts = list(elt)
     self.expr = Expression(elts[0] if len(elts) else elt, self)
     ComplexType.__init__(self, name, elts[1:])        
     self.has_name = True
     self.index = 1
     self.lenfield_parent = list(parent) + [self]
     self.parents = list(parent)
     self.is_bitcase = True
Exemplo n.º 2
0
    def __init__(self, elt, member, *parent):
        Type.__init__(self, member.name)
        self.is_list = True
        self.member = member
        self.parents = list(parent)

        if elt.tag == 'list':
            elts = list(elt)
            self.expr = Expression(elts[0] if len(elts) else elt, self)

        self.size = member.size if member.fixed_size() else None
        self.nmemb = self.expr.nmemb if self.expr.fixed_size() else None
    def __init__(self, elt, member, *parent):
        Type.__init__(self, member.name)
        self.is_list = True
        self.member = member
        self.parents = list(parent)

        if elt.tag == 'list':
            elts = list(elt)
            self.expr = Expression(elts[0] if len(elts) else elt, self)
        elif elt.tag == 'valueparam':
            self.expr = Expression(elt, self)

        self.size = member.size if member.fixed_size() else None
        self.nmemb = self.expr.nmemb if self.expr.fixed_size() else None
Exemplo n.º 4
0
class BitcaseType(ComplexType):
    '''
    Derived class representing a struct data type.
    '''
    def __init__(self, index, name, elt, *parent):
        elts = list(elt)
        self.expr = Expression(elts[0] if len(elts) else elt, self)
        ComplexType.__init__(self, name, elts[1:])
        self.has_name = True
        self.index = 1
        self.lenfield_parent = list(parent) + [self]
        self.parents = list(parent)
        self.is_bitcase = True

    def make_member_of(self,
                       module,
                       switch_type,
                       field_type,
                       field_name,
                       visible,
                       wire,
                       auto,
                       enum=None):
        '''
        register BitcaseType with the corresponding SwitchType

        module is the global module object.
        complex_type is the structure object.
        see Field for the meaning of the other parameters.
        '''
        new_field = Field(self, field_type, field_name, visible, wire, auto,
                          enum)

        # We dump the _placeholder_byte if any bitcases are added.
        for (idx, field) in enumerate(switch_type.bitcases):
            if field == _placeholder_byte:
                switch_type.bitcases[idx] = new_field
                return

        switch_type.bitcases.append(new_field)

    def resolve(self, module):
        if self.resolved:
            return

        self.expr.resolve(module, self.parents + [self])

        # Resolve the bitcase expression
        ComplexType.resolve(self, module)
Exemplo n.º 5
0
    def __init__(self, elt, member, *parents):
        PrimitiveType.__init__(self, member.name, member.size)
        self.is_expr = True
        self.member = member
        self.parents = parents

        self.expr = Expression(list(elt)[0], self)
Exemplo n.º 6
0
    def __init__(self, elt, member, *parent):
        Type.__init__(self, member.name)
        self.is_expr = True
        self.member = member
        self.parent = parent

        self.expr = Expression(list(elt)[0], self)

        self.size = member.size
        self.nmemb = 1
Exemplo n.º 7
0
    def __init__(self, name, elt, *parents):
        ComplexType.__init__(self, name, elt)
        self.parents = parents
        # FIXME: switch cannot store lenfields, so it should just delegate the parents
        self.lenfield_parent = list(parents) + [self]
        # self.fields contains all possible fields collected from the Bitcase objects, 
        # whereas self.items contains the Bitcase objects themselves
        self.bitcases = []

        self.is_switch = True
        elts = list(elt)
        self.expr = Expression(elts[0] if len(elts) else elt, self)
Exemplo n.º 8
0
    def __init__(self, elt, member, *parent):
        Type.__init__(self, member.name)
        self.is_list = True
        self.member = member
        self.parents = list(parent)
        lenfield_name = False

        if elt.tag == 'list':
            elts = list(elt)
            self.expr = Expression(elts[0] if len(elts) else elt, self)
            is_list_in_parent = self.parents[0].elt.tag in ('request', 'event', 'reply', 'error')
            if not len(elts) and is_list_in_parent:
                self.expr = Expression(elt,self)
                self.expr.op = 'calculate_len'
            else:
                self.expr = Expression(elts[0] if len(elts) else elt, self)

        self.size = member.size if member.fixed_size() else None
        self.nmemb = self.expr.nmemb if self.expr.fixed_size() else None

        self.required_start_align = self.member.required_start_align
class BitcaseType(ComplexType):
    '''
    Derived class representing a struct data type.
    '''
    def __init__(self, index, name, elt, *parent):
        elts = list(elt)
        self.expr = Expression(elts[0] if len(elts) else elt, self)
        ComplexType.__init__(self, name, elts[1:])        
        self.has_name = True
        self.index = 1
        self.lenfield_parent = list(parent) + [self]
        self.parents = list(parent)
        self.is_bitcase = True

    def make_member_of(self, module, switch_type, field_type, field_name, visible, wire, auto, enum=None):
        '''
        register BitcaseType with the corresponding SwitchType

        module is the global module object.
        complex_type is the structure object.
        see Field for the meaning of the other parameters.
        '''
        new_field = Field(self, field_type, field_name, visible, wire, auto, enum)

        # We dump the _placeholder_byte if any bitcases are added.
        for (idx, field) in enumerate(switch_type.bitcases):
            if field == _placeholder_byte:
                switch_type.bitcases[idx] = new_field
                return

        switch_type.bitcases.append(new_field)

    def resolve(self, module):
        if self.resolved:
            return
        
        self.expr.resolve(module, self.parents+[self])

        # Resolve the bitcase expression
        ComplexType.resolve(self, module)
Exemplo n.º 10
0
 def __init__(self, index, name, elt, *parent):
     elts = list(elt)
     self.expr = []
     for sub_elt in elts:
         if sub_elt.tag == 'enumref':
             self.expr.append(Expression(sub_elt, self))
             elt.remove(sub_elt)
     ComplexType.__init__(self, name, elt)
     self.has_name = True
     self.index = 1
     self.lenfield_parent = list(parent) + [self]
     self.parents = list(parent)
     self.is_case_or_bitcase = True
Exemplo n.º 11
0
 def __init__(self, index, name, elt, *parent):
     elts = list(elt)
     self.expr = []
     fields = []
     for elt in elts:
         if elt.tag == 'enumref':
             self.expr.append(Expression(elt, self))
         else:
             fields.append(elt)
     ComplexType.__init__(self, name, fields)
     self.has_name = True
     self.index = 1
     self.lenfield_parent = list(parent) + [self]
     self.parents = list(parent)
     self.is_bitcase = True
Exemplo n.º 12
0
    def __init__(self, elt, member, *parent):
        Type.__init__(self, member.name)
        self.is_list = True
        self.member = member
        self.parents = list(parent)
        lenfield_name = False

        if elt.tag == 'list':
            elts = list(elt)
            self.expr = Expression(elts[0] if len(elts) else elt, self)
            is_list_in_parent = self.parents[0].elt.tag in ('request', 'event',
                                                            'reply', 'error')
            if not len(elts) and is_list_in_parent:
                self.expr = Expression(elt, self)
                self.expr.op = 'calculate_len'
            else:
                self.expr = Expression(elts[0] if len(elts) else elt, self)

        self.size = member.size if member.fixed_size() else None
        self.nmemb = self.expr.nmemb if self.expr.fixed_size() else None

        self.required_start_align = self.member.required_start_align
Exemplo n.º 13
0
class ListType(Type):
    '''
    Derived class which represents a list of some other datatype.  Fixed- or variable-sized.

    Public fields added:
    member is the datatype of the list elements.
    parent is the structure type containing the list.
    expr is an Expression object containing the length information, for variable-sized lists.
    '''
    def __init__(self, elt, member, *parent):
        Type.__init__(self, member.name)
        self.is_list = True
        self.member = member
        self.parents = list(parent)

        if elt.tag == 'list':
            elts = list(elt)
            self.expr = Expression(elts[0] if len(elts) else elt, self)

        self.size = member.size if member.fixed_size() else None
        self.nmemb = self.expr.nmemb if self.expr.fixed_size() else None

    def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto, enum=None):
        if not self.fixed_size():
            # We need a length field.
            # Ask our Expression object for it's name, type, and whether it's on the wire.
            lenfid = self.expr.lenfield_type
            lenfield_name = self.expr.lenfield_name
            lenwire = self.expr.lenwire
            needlen = True

            # See if the length field is already in the structure.
            for parent in self.parents:
                for field in parent.fields:
                    if field.field_name == lenfield_name:
                        needlen = False

            # It isn't, so we need to add it to the structure ourself.
            if needlen:
                type = module.get_type(lenfid)
                lenfield_type = module.get_type_name(lenfid)
                type.make_member_of(module, complex_type, lenfield_type, lenfield_name, True, lenwire, False, enum)

        # Add ourself to the structure by calling our original method.
        Type.make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto, enum)

    def resolve(self, module):
        if self.resolved:
            return
        self.member.resolve(module)
        self.expr.resolve(module, self.parents)

        # Find my length field again.  We need the actual Field object in the expr.
        # This is needed because we might have added it ourself above.
        if not self.fixed_size():
            for parent in self.parents:
                for field in parent.fields:
                    if field.field_name == self.expr.lenfield_name and field.wire:
                        self.expr.lenfield = field
                        break

        self.resolved = True

    def fixed_size(self):
        return self.member.fixed_size() and self.expr.fixed_size()
Exemplo n.º 14
0
class ListType(Type):
    '''
    Derived class which represents a list of some other datatype.  Fixed- or variable-sized.

    Public fields added:
    member is the datatype of the list elements.
    parent is the structure type containing the list.
    expr is an Expression object containing the length information, for variable-sized lists.
    '''
    def __init__(self, elt, member, *parent):
        Type.__init__(self, member.name)
        self.is_list = True
        self.member = member
        self.parents = list(parent)
        lenfield_name = False

        if elt.tag == 'list':
            elts = list(elt)
            self.expr = Expression(elts[0] if len(elts) else elt, self)
            is_list_in_parent = self.parents[0].elt.tag in ('request', 'event', 'reply', 'error')
            if not len(elts) and is_list_in_parent:
                self.expr = Expression(elt,self)
                self.expr.op = 'calculate_len'
            else:
                self.expr = Expression(elts[0] if len(elts) else elt, self)

        self.size = member.size if member.fixed_size() else None
        self.nmemb = self.expr.nmemb if self.expr.fixed_size() else None

        self.required_start_align = self.member.required_start_align

    def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto, enum=None):
        if not self.fixed_size():
            # We need a length field.
            # Ask our Expression object for it's name, type, and whether it's on the wire.
            lenfid = self.expr.lenfield_type
            lenfield_name = self.expr.lenfield_name
            lenwire = self.expr.lenwire
            needlen = True

            # See if the length field is already in the structure.
            for parent in self.parents:
                for field in parent.fields:
                    if field.field_name == lenfield_name:
                        needlen = False

            # It isn't, so we need to add it to the structure ourself.
            if needlen:
                type = module.get_type(lenfid)
                lenfield_type = module.get_type_name(lenfid)
                type.make_member_of(module, complex_type, lenfield_type, lenfield_name, True, lenwire, False, enum)

        # Add ourself to the structure by calling our original method.
        Type.make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto, enum)

    def resolve(self, module):
        if self.resolved:
            return
        self.member.resolve(module)
        self.expr.resolve(module, self.parents)

        self.required_start_align = self.member.required_start_align

        # Find my length field again.  We need the actual Field object in the expr.
        # This is needed because we might have added it ourself above.
        if not self.fixed_size():
            for parent in self.parents:
                for field in parent.fields:
                    if field.field_name == self.expr.lenfield_name and field.wire:
                        self.expr.lenfield = field
                        break

        self.resolved = True

    def fixed_size(self):
        return self.member.fixed_size() and self.expr.fixed_size()

    def unchecked_get_alignment_after(self, start_align, callstack, log):
        my_callstack = callstack[:]
        my_callstack.append(self)
        if start_align is None:
            log.fail(start_align, "", self, my_callstack, "start_align is None")
            return None
        if self.expr.fixed_size():
            # fixed number of elements
            num_elements = self.nmemb
            prev_alignment = None
            alignment = start_align
            while num_elements > 0:
                if alignment is None:
                    if log is not None:
                        log.fail(start_align, "", self, my_callstack,
                            ("fixed size list with size %d after %d iterations"
                            + ", at transition from alignment \"%s\"")
                            % (self.nmemb,
                               (self.nmemb - num_elements),
                               str(prev_alignment)))
                    return None
                prev_alignment = alignment
                alignment = self.member.get_alignment_after(prev_alignment, my_callstack, log)
                num_elements -= 1
            if log is not None:
                log.ok(start_align, "", self, my_callstack, alignment)
            return alignment
        else:
            # variable number of elements
            # check whether the number of elements is a multiple
            multiple = self.expr.get_multiple()
            assert multiple > 0

            # iterate until the combined alignment does not change anymore
            alignment = start_align
            while True:
                prev_multiple_alignment = alignment
                # apply "multiple" amount of changes sequentially
                prev_alignment = alignment
                for multiple_count in range(0, multiple):

                    after_alignment = self.member.get_alignment_after(prev_alignment, my_callstack, log)
                    if after_alignment is None:
                        if log is not None:
                            log.fail(start_align, "", self, my_callstack,
                                ("variable size list "
                                + "at transition from alignment \"%s\"")
                                % (str(prev_alignment)))
                        return None

                    prev_alignment = after_alignment

                # combine with the cumulatively combined alignment
                # (to model the variable number of entries)
                alignment = prev_multiple_alignment.combine_with(after_alignment)

                if alignment == prev_multiple_alignment:
                    # does not change anymore by adding more potential elements
                    # -> finished
                    if log is not None:
                        log.ok(start_align, "", self, my_callstack, alignment)
                    return alignment
Exemplo n.º 15
0
class ListType(Type):
    '''
    Derived class which represents a list of some other datatype.  Fixed- or variable-sized.

    Public fields added:
    member is the datatype of the list elements.
    parent is the structure type containing the list.
    expr is an Expression object containing the length information, for variable-sized lists.
    '''
    def __init__(self, elt, member, *parent):
        Type.__init__(self, member.name)
        self.is_list = True
        self.member = member
        self.parents = list(parent)
        lenfield_name = False

        if elt.tag == 'list':
            elts = list(elt)
            self.expr = Expression(elts[0] if len(elts) else elt, self)
            is_list_in_parent = self.parents[0].elt.tag in ('request', 'event',
                                                            'reply', 'error')
            if not len(elts) and is_list_in_parent:
                self.expr = Expression(elt, self)
                self.expr.op = 'calculate_len'
            else:
                self.expr = Expression(elts[0] if len(elts) else elt, self)

        self.size = member.size if member.fixed_size() else None
        self.nmemb = self.expr.nmemb if self.expr.fixed_size() else None

        self.required_start_align = self.member.required_start_align

    def make_member_of(self,
                       module,
                       complex_type,
                       field_type,
                       field_name,
                       visible,
                       wire,
                       auto,
                       enum=None):
        if not self.fixed_size():
            # We need a length field.
            # Ask our Expression object for it's name, type, and whether it's on the wire.
            lenfid = self.expr.lenfield_type
            lenfield_name = self.expr.lenfield_name
            lenwire = self.expr.lenwire
            needlen = True

            # See if the length field is already in the structure.
            for parent in self.parents:
                for field in parent.fields:
                    if field.field_name == lenfield_name:
                        needlen = False

            # It isn't, so we need to add it to the structure ourself.
            if needlen:
                type = module.get_type(lenfid)
                lenfield_type = module.get_type_name(lenfid)
                type.make_member_of(module, complex_type, lenfield_type,
                                    lenfield_name, True, lenwire, False, enum)

        # Add ourself to the structure by calling our original method.
        Type.make_member_of(self, module, complex_type, field_type, field_name,
                            visible, wire, auto, enum)

    def resolve(self, module):
        if self.resolved:
            return
        self.member.resolve(module)
        self.expr.resolve(module, self.parents)

        self.required_start_align = self.member.required_start_align

        # Find my length field again.  We need the actual Field object in the expr.
        # This is needed because we might have added it ourself above.
        if not self.fixed_size():
            for parent in self.parents:
                for field in parent.fields:
                    if field.field_name == self.expr.lenfield_name and field.wire:
                        self.expr.lenfield = field
                        break

        self.resolved = True

    def fixed_size(self):
        return self.member.fixed_size() and self.expr.fixed_size()

    def unchecked_get_alignment_after(self, start_align, callstack, log):
        my_callstack = callstack[:]
        my_callstack.append(self)
        if start_align is None:
            log.fail(start_align, "", self, my_callstack,
                     "start_align is None")
            return None
        if self.expr.fixed_size():
            # fixed number of elements
            num_elements = self.nmemb
            prev_alignment = None
            alignment = start_align
            while num_elements > 0:
                if alignment is None:
                    if log is not None:
                        log.fail(
                            start_align, "", self, my_callstack,
                            ("fixed size list with size %d after %d iterations"
                             + ", at transition from alignment \"%s\"") %
                            (self.nmemb,
                             (self.nmemb - num_elements), str(prev_alignment)))
                    return None
                prev_alignment = alignment
                alignment = self.member.get_alignment_after(
                    prev_alignment, my_callstack, log)
                num_elements -= 1
            if log is not None:
                log.ok(start_align, "", self, my_callstack, alignment)
            return alignment
        else:
            # variable number of elements
            # check whether the number of elements is a multiple
            multiple = self.expr.get_multiple()
            assert multiple > 0

            # iterate until the combined alignment does not change anymore
            alignment = start_align
            while True:
                prev_multiple_alignment = alignment
                # apply "multiple" amount of changes sequentially
                prev_alignment = alignment
                for multiple_count in range(0, multiple):

                    after_alignment = self.member.get_alignment_after(
                        prev_alignment, my_callstack, log)
                    if after_alignment is None:
                        if log is not None:
                            log.fail(start_align, "", self, my_callstack,
                                     ("variable size list " +
                                      "at transition from alignment \"%s\"") %
                                     (str(prev_alignment)))
                        return None

                    prev_alignment = after_alignment

                # combine with the cumulatively combined alignment
                # (to model the variable number of entries)
                alignment = prev_multiple_alignment.combine_with(
                    after_alignment)

                if alignment == prev_multiple_alignment:
                    # does not change anymore by adding more potential elements
                    # -> finished
                    if log is not None:
                        log.ok(start_align, "", self, my_callstack, alignment)
                    return alignment