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