예제 #1
0
    def is_entity_a_bus(self, root=None, index=None):
        """
        Returns true if the entity at the specified index is a bus

        Args:
            root(SOMBus): The bus where the devcies are
                leave blank for the top of the tree
            index(Integer): The index of the entity within the root bus

        Return (Boolean):
            True: entity is a bus
            False: entity is not a bus

        Raises:
            SDBError:
                index is not supplied
        """
        if index is None:
            raise SDBError("index is None, this should be an integer")

        if root is None:
            root = self.root

        n = root.get_child_from_index(index)
        if isinstance(n, SOMBus):
            return True

        return False
예제 #2
0
 def get_bus_type_as_int(self):
     if self.d["SDB_BUS_TYPE"].lower() == "wishbone":
         return 0
     elif self.d["SDB_BUS_TYPE"].lower() == "storage":
         return 1
     else:
         raise SDBError("Unknown Bus Type: %s" % self.d["SDB_BUS_TYPE"])
예제 #3
0
def parse_rom_element(rom, addr=0, debug=False):
    entity = sdbc()
    possible_magic = rom[addr + 0] << 24 | \
                     rom[addr + 1] << 16 | \
                     rom[addr + 2] <<  8 | \
                     rom[addr + 3] <<  0

    if (possible_magic == SDB_INTERCONNECT_MAGIC):
        #if debug: print "Found Interconnect!"
        _parse_rom_interconnect_element(entity, rom, addr, debug)
        entity.d["SDB_RECORD_TYPE"] = SDB_RECORD_TYPE_INTERCONNECT
    elif rom[addr + 63] == SDB_RECORD_TYPE_DEVICE:
        _parse_rom_device_element(entity, rom, addr, debug)
        entity.d["SDB_RECORD_TYPE"] = SDB_RECORD_TYPE_DEVICE
    elif rom[addr + 63] == SDB_RECORD_TYPE_BRIDGE:
        _parse_rom_bridge_element(entity, rom, addr, debug)
        entity.d["SDB_RECORD_TYPE"] = SDB_RECORD_TYPE_BRIDGE
    elif rom[addr + 63] == SDB_RECORD_TYPE_INTEGRATION:
        _parse_integration_element(entity, rom, addr, debug)
        entity.d["SDB_RECORD_TYPE"] = SDB_RECORD_TYPE_INTEGRATION
    elif rom[addr + 63] == SDB_RECORD_TYPE_REPO_URL:
        _parse_repo_url_element(entity, rom, addr, debug)
        entity.d["SDB_RECORD_TYPE"] = SDB_RECORD_TYPE_REPO_URL
    elif rom[addr + 63] == SDB_RECORD_TYPE_SYNTHESIS:
        _parse_synthesis_element(entity, rom, addr, debug)
        entity.d["SDB_RECORD_TYPE"] = SDB_RECORD_TYPE_SYNTHESIS
    elif rom[addr + 63] == SDB_RECORD_TYPE_EMPTY:
        entity.d["SDB_RECORD_TYPE"] = SDB_RECORD_TYPE_EMPTY
    else:
        data = " ".join(["0x%02X" % i for i in rom])
        raise SDBError(
            "Info: Unrecognized Record @ addr 0x%04X (record: 0x%02X)\nFull element: %s"
            % (addr, rom[addr + 63], data))
    return entity
예제 #4
0
    def initialize_root(self,
                        name="top",
                        version=sdbc.SDB_VERSION,
                        vendor_id=0x8000000000000000,
                        entity_id=0x00000000,
                        bus_type="wishbone"):

        c = self.root.get_component()
        c.d["SDB_NAME"] = name
        if version > sdbc.SDB_VERSION:
            raise SDBError("Version %d is greater than known version! (%d)" %
                           (version, sdbc.SDB_VERSION))
        c.d["SDB_VERSION"] = version

        if not is_valid_bus_type(bus_type):
            raise SDBError("%s is not a valid bus type" % bus_type)
        c.d["SDB_BUS_TYPE"] = "wishbone"
예제 #5
0
 def _translate_buf_width_to_rom_version(self):
     value = int(self.d["SDB_ABI_DEVICE_WIDTH"])
     if value == 8:
         return 0
     if value == 16:
         return 1
     if value == 32:
         return 2
     if value == 64:
         return 3
     raise SDBError("Unknown Device Width: %d" % value)
예제 #6
0
    def get_bus_name(self, bus):
        """
        Returns the name of the bus

        Args:
            bus (SOMBus): bus

        Return:
            Nothing

        Raises:
            SOBError: bus does not exist
        """
        if bus is None:
            raise SDBError("Bus doesn't exist")

        elif not isinstance(bus, SOMBus):
            raise SDBError("Bus is not an SOMBus")

        return bus.get_component().get_name()
예제 #7
0
    def set_bus_name(self, bus, name):
        """
        Names the bus

        Args:
            bus (SOMBus): bus to rename
            name (String): name

        Return:
            Nothing

        Raises:
            SDBError: bus does not exist
        """
        if bus is None:
            raise SDBError("Bus doesn't exist")

        elif not isinstance(bus, SOMBus):
            raise SDBError("Bus is not an SOMBus")

        c = bus.get_component()
        c.set_name(name)
예제 #8
0
def _parse_rom_interconnect_element(entity, rom, addr, debug=False):
    entity.d["SDB_NRECS"] = hex(rom[addr + 4] << 8 | \
                              rom[addr + 5] << 0)
    #if debug: print "Number of Records: %d" % entity.d["SDB_NRECS"]
    entity.d["SDB_VERSION"] = rom[addr + 6]
    if rom[addr + 7] == 0:
        entity.d["SDB_BUS_TYPE"] = "wishbone"
    elif rom[addr + 7] == 1:
        entity.d["SDB_BUS_TYPE"] = "storage"
    _parse_rom_component_element(entity, rom, addr, debug)
    if rom[addr + 63] != 0x00:
        raise SDBError(
            "Interconnect element record does not match type: 0x%02X" %
            rom[addr + 63])
예제 #9
0
    def remove_bus(self, bus):
        """
        Remove a bus from the SOM

        Args:
            bus (SOMBus): bus to remove

        Return (SOMBus):
            An orphaned SOMBus

        Raises:
            SOMError:   User attempted to remove root
                        User attempted to remove non-existent bus
        """
        parent = bus.get_parent()
        if parent is None:
            raise SDBError("Cannot remove root, use reset_som to reset SOM")
        try:
            parent.remove_child(bus)
        except ValueError as ex:
            raise SDBError("Attempted to remove a non-existent bus from a "\
                            "parent bus: Parent Bus: %s, Child Bus: %s" %
                            parent.c.d["SDB_NAME"],
                            bus.c.d["SDB_NAME"])
예제 #10
0
    def insert_component(self, root=None, component=None, pos=-1):
        """
        insert a new component into a bus, if root is left empty then
        insert this component into the root

        Args:
            root(SOMBus): The bus where this component should
                be located
            component(SDBComponent): the element in which to add this
                component into
                This component can only be a entity, or informative item
            pos(integer): the location where to put the component, leave blank
                for the end

        Return
            (SOMComponent): the generated SOMComponent is already inserted into
            the tree

        Raises:
            Nothing
        """
        if root is None:
            #print "root is None, Using base root!"
            root = self.root
        else:
            #print "Using custom root..."
            #print ""
            #print ""
            pass

        #Extrapolate the size of the component
        if component.is_interconnect() or component.is_bridge():
            raise SDBError("Only component can be inserted, not %s", component)

        leaf = SOMComponent(root, component)
        root.insert_child(leaf, pos)
        self._update()
예제 #11
0
def _parse_bus(som, bus, rom, addr):
    """Recursive function used to parse a bus,
    when a sub bus is found then parse that bus
    """

    #This first element is a Known interconnect
    num_devices = 0
    if bus is None:
        #This is the top element
        som = SOM()
        som.initialize_root()
        bus = som.get_root()

    #print "Address: 0x%02X" % addr
    try:
        entity = parse_rom_element(rom, addr)
    except SDBError as e:
        print("Error when parsing bus @ 0x%08X" % addr)
        raise SDBError(e)

    if not entity.is_interconnect():
        raise SDBError("Rom data does not point to an interconnect")
    num_devices = entity.get_number_of_records_as_int()
    #print "entity: %s" % entity
    som.set_bus_component(bus, entity)

    #print "Number of entities to parse: %d" % num_devices
    #Get the spacing and size of each device for calculating spacing
    entity_size = []
    entity_addr_start = []
    #Add 1 to the number of devices so we account for the empty
    for i in range(1, (num_devices + 1)):
        #print "Working on %d" % i
        I = (i * RECORD_LENGTH) + addr
        entity = parse_rom_element(rom, I)

        #Gather spacing data to analyze later
        end = long(entity.get_end_address_as_int())
        start = long(entity.get_start_address_as_int())
        entity_addr_start.append(start)
        entity_size.append(end - start)

        if entity.is_bridge():
            #print "Found a bus: %s" % entity.get_name()
            #print "start: 0x%08X" % start
            sub_bus = som.insert_bus(root=bus, name=entity.get_name())

            #print "Bridge address: 0x%08X" % entity.get_bridge_address_as_int()
            #Set address as 2 X higher because SDB is using a 64 bit bus, but
            #ROM in FPGA is only 32 bits
            _parse_bus(som, sub_bus, rom,
                       entity.get_bridge_address_as_int() * 8)
        else:
            #print "Found a non bus: %s" % entity.get_name()
            som.insert_component(root=bus, component=entity)

    spacing = 0
    prev_start = None
    prev_size = None
    for i in range(num_devices):
        #print "i: %d" % i
        size = entity_size[i]
        start_addr = entity_addr_start[i]
        #print "\tStart: 0x%08X" % start_addr
        if prev_start is None:
            prev_size = size
            prev_start = start_addr
            continue

        potential_spacing = (start_addr - prev_start)
        #print "\tPotential Spacing: 0x%08X" % potential_spacing
        #print "\tPrevious Size: 0x%08X" % prev_size
        if potential_spacing > prev_size:
            if potential_spacing > 0 and spacing == 0:
                #print "\t\tSpacing > 0"
                spacing = potential_spacing
            if spacing > potential_spacing:
                #print "\t\tSpacing: 0x%08X > 0x%08X" % (spacing, potential_spacing)
                spacing = potential_spacing

        prev_size = size
        prev_start = start_addr

    #print "\tspacing for %s: 0x%08X" % (bus.get_name(), spacing)
    #bus.set_child_spacing(spacing)
    som.set_child_spacing(bus, spacing)
    return som