|  | import re | 
|  |  | 
|  | # ============================================================================= | 
|  |  | 
|  | # A regex used for fixing pin names | 
|  | RE_PIN_NAME = re.compile(r"^([A-Za-z0-9_]+)(?:\[([0-9]+)\])?$") | 
|  |  | 
|  | # ============================================================================= | 
|  |  | 
|  |  | 
|  | def get_pin_name(name): | 
|  | """ | 
|  | Returns the pin name and its index in bus. If a pin is not a member of | 
|  | a bus then the index is None | 
|  |  | 
|  | >>> get_pin_name("WIRE") | 
|  | ('WIRE', None) | 
|  | >>> get_pin_name("DATA[12]") | 
|  | ('DATA', 12) | 
|  | """ | 
|  |  | 
|  | match = re.match(r"(?P<name>.*)\[(?P<idx>[0-9]+)\]$", name) | 
|  | if match: | 
|  | return match.group("name"), int(match.group("idx")) | 
|  | else: | 
|  | return name, None | 
|  |  | 
|  |  | 
|  | def fixup_pin_name(name): | 
|  | """ | 
|  | Renames a pin to make its name suitable for VPR. | 
|  |  | 
|  | >>> fixup_pin_name("A_WIRE") | 
|  | 'A_WIRE' | 
|  | >>> fixup_pin_name("ADDRESS[17]") | 
|  | 'ADDRESS_17' | 
|  | >>> fixup_pin_name("DATA[11]_X") | 
|  | Traceback (most recent call last): | 
|  | ... | 
|  | AssertionError: DATA[11]_X | 
|  | """ | 
|  |  | 
|  | match = RE_PIN_NAME.match(name) | 
|  | assert match is not None, name | 
|  |  | 
|  | groups = match.groups() | 
|  | if groups[1] is None: | 
|  | return groups[0] | 
|  | else: | 
|  | return "{}_{}".format(*groups) | 
|  |  | 
|  |  | 
|  | # ============================================================================= | 
|  |  | 
|  |  | 
|  | def yield_muxes(switchbox): | 
|  | """ | 
|  | Yields all muxes of a switchbox. Returns tuples with: | 
|  | (stage, switch, mux) | 
|  | """ | 
|  |  | 
|  | for stage in switchbox.stages.values(): | 
|  | for switch in stage.switches.values(): | 
|  | for mux in switch.muxes.values(): | 
|  | yield stage, switch, mux | 
|  |  | 
|  |  | 
|  | # ============================================================================= | 
|  |  | 
|  |  | 
|  | def get_quadrant_for_loc(loc, quadrants): | 
|  | """ | 
|  | Assigns a quadrant to the given location. Returns None if no one matches. | 
|  | """ | 
|  |  | 
|  | for quadrant in quadrants.values(): | 
|  | if loc.x >= quadrant.x0 and loc.x <= quadrant.x1: | 
|  | if loc.y >= quadrant.y0 and loc.y <= quadrant.y1: | 
|  | return quadrant | 
|  |  | 
|  | return None | 
|  |  | 
|  |  | 
|  | def get_loc_of_cell(cell_name, tile_grid): | 
|  | """ | 
|  | Returns loc of a cell with the given name in the tilegrid. | 
|  | """ | 
|  |  | 
|  | # Look for a tile that has the cell | 
|  | for loc, tile in tile_grid.items(): | 
|  | if tile is None: | 
|  | continue | 
|  |  | 
|  | cell_names = [c.name for c in tile.cells] | 
|  | if cell_name in cell_names: | 
|  | return loc | 
|  |  | 
|  | # Not found | 
|  | return None | 
|  |  | 
|  |  | 
|  | def find_cell_in_tile(cell_name, tile): | 
|  | """ | 
|  | Finds a cell instance with the given name inside the given tile. | 
|  | Returns the Cell object if found and None otherwise. | 
|  | """ | 
|  | for cell in tile.cells: | 
|  | if cell.name == cell_name: | 
|  | return cell | 
|  |  | 
|  | return None | 
|  |  | 
|  |  | 
|  | # ============================================================================= | 
|  |  | 
|  |  | 
|  | def add_named_item(item_dict, item, item_name): | 
|  | """ | 
|  | Adds a named item to the given dict if not already there. If it is there | 
|  | then returns the one from the dict. | 
|  | """ | 
|  |  | 
|  | if item_name not in item_dict: | 
|  | item_dict[item_name] = item | 
|  |  | 
|  | return item_dict[item_name] | 
|  |  | 
|  |  | 
|  | # ============================================================================= | 
|  |  | 
|  |  | 
|  | def natural_keys(text): | 
|  | """ | 
|  | alist.sort(key=natural_keys) sorts in human order | 
|  | http://nedbatchelder.com/blog/200712/human_sorting.html | 
|  | (See Toothy's implementation in the comments) | 
|  |  | 
|  | https://stackoverflow.com/questions/5967500/how-to-correctly-sort-a-string-with-a-number-inside | 
|  | """ | 
|  |  | 
|  | def atoi(text): | 
|  | return int(text) if text.isdigit() else text | 
|  |  | 
|  | return [atoi(c) for c in re.split(r'(\d+)', text)] |