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
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"])
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
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"
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)
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()
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)
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])
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"])
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()
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