Beispiel #1
0
    def import_file(self, path:str):

        # minidom does not provide file position data. Using a bare SourceRef
        # for everything created during this import
        self.src_ref = SourceRef(filename=path)
        self._current_regwidth = 32
        self._addressUnitBits = 8

        dom = minidom.parse(path)

        addressBlock_s = self.seek_to_top_addressBlocks(dom)

        # Parse all the addressBlock elements found
        addrmap_or_mems = []
        for addressBlock in addressBlock_s:
            addrmap_or_mem = self.parse_addressBlock(addressBlock)
            if addrmap_or_mem is not None:
                addrmap_or_mems.append(addrmap_or_mem)

        if not addrmap_or_mems:
            self.msg.fatal(
                "'memoryMap' must contain at least one 'addressBlock' element",
                self.src_ref
            )

        if (len(addrmap_or_mems) == 1) and (addrmap_or_mems[0].addr_offset == 0):
            # OK to drop the hierarchy implied by the enclosing memoryMap
            # since it is only a wrapper around a single addressBlock at base
            # offset 0
            # This addressBlock will be the top component that is registered
            # in $root
            top_component = addrmap_or_mems[0]

            #  de-instantiate the addrmap
            top_component.type_name = top_component.inst_name
            top_component.is_instance = False
            top_component.inst_name = None
            top_component.external = None
            top_component.inst_src_ref = None
            top_component.addr_offset = None

        else:
            # memoryMap encloses multiple addressBlock components, or the single
            # one uses a meaningful address offset.
            # In order to preserve this information, encapsulate them in a
            # top-level parent that is named after the memoryMap

            # Get the top-level memoryMap's element values
            d = self.flatten_element_values(addressBlock_s[0].parentNode)

            # Check for required name
            if 'name' not in d:
                self.msg.fatal("memoryMap is missing required tag 'name'", self.src_ref)

            # Create component instance to represent the memoryMap
            C = comp.Addrmap()
            C.def_src_ref = self.src_ref
            C.original_def = C

            # Collect properties and other values
            C.type_name = d['name']

            if 'displayName' in d:
                self.assign_property(C, "name", d['displayName'], self.src_ref)

            if 'description' in d:
                self.assign_property(C, "desc", d['description'], self.src_ref)

            # Insert all the addrmap_or_mems as children
            C.children = addrmap_or_mems

            top_component = C

        # register it with the root namespace
        self.register_root_component(top_component)
Beispiel #2
0
    def parse_addressBlock(self, addressBlock):
        """
        Parses an addressBlock and returns an instantiated addrmap or mem
        component.

        If addressBlock is empty or usage specifies 'reserved' then returns
        None
        """
        # Schema:
        #   {nameGroup}
        #       name (required) --> inst_name
        #       displayName --> prop:name
        #       description --> prop:desc
        #   accessHandles
        #   isPresent --> prop:ispresent
        #   baseAddress (required) --> addr_offset
        #   {addressBlockDefinitionGroup}
        #       typeIdentifier
        #       range (required) --> divide by width and set prop:mementries if Mem
        #       width (required) --> prop:memwidth if Mem
        #       {memoryBlockData}
        #           usage --> Mem vs Addrmap instance
        #           volatile
        #           access --> prop:sw if Mem
        #           parameters
        #       {registerData}
        #           register --> children
        #           registerFile --> children
        #   vendorExtensions

        d = self.flatten_element_values(addressBlock)

        if 'usage' in d == "reserved":
            # 1685-2014 6.9.4.2-a.1.iii: defines the entire range of the
            # addressBlock as reserved or for unknown usage to IP-XACT. This
            # type shall not contain registers.
            return None

        # Check for required values
        required = {'name', 'baseAddress', 'range', 'width'}
        missing = required - set(d.keys())
        for m in missing:
            self.msg.fatal("addressBlock is missing required tag '%s'" % m, self.src_ref)

        # Create component instance
        if d.get('usage', None) == "memory":
            is_memory = True
            C = comp.Mem()
        else:
            is_memory = False
            C = comp.Addrmap()
        C.def_src_ref = self.src_ref
        C.is_instance = True
        C.inst_src_ref = self.src_ref
        C.original_def = C

        # Collect properties and other values
        C.inst_name = d['name']
        C.type_name = d['name']


        if 'displayName' in d:
            self.assign_property(C, "name", d['displayName'], self.src_ref)

        if 'description' in d:
            self.assign_property(C, "desc", d['description'], self.src_ref)

        if 'isPresent' in d:
            self.assign_property(C, "ispresent", d['isPresent'], self.src_ref)

        C.addr_offset = self.AU_to_bytes(d['baseAddress'])

        self._current_regwidth = d['width']
        if is_memory:
            self.assign_property(C, "memwidth", d['width'], self.src_ref)
            self.assign_property(
                C, "mementries",
                (d['range'] * self._addressUnitBits) // (d['width']),
                self.src_ref
            )

            if 'access' in d:
                self.assign_property(C, "sw", d['access'], self.src_ref)

        if 'access' in d:
            self._current_addressBlock_access = d['access']
        else:
            self._current_addressBlock_access = rdltypes.AccessType.rw

        # collect children
        for child_el in d['child_els']:
            if child_el.localName == "register":
                R = self.parse_register(child_el)
                if R:
                    C.children.append(R)
            elif child_el.localName == "registerFile" and not is_memory:
                R = self.parse_registerFile(child_el)
                if R:
                    C.children.append(R)
            else:
                self.msg.error(
                    "Invalid child element <%s> found in <%s:addressBlock>"
                    % (child_el.tagName, self.ns),
                    self.src_ref
                )

        if 'vendorExtensions' in d:
            C = self.addressBlock_vendorExtensions(d['vendorExtensions'], C)

        if not is_memory and not C.children:
            # If a register addressBlock has no children, skip it
            return None

        return C