From 54c4c1ee44950469b6b1b7721eb825fcf7d3431f Mon Sep 17 00:00:00 2001 From: Unai Martinez-Corral Date: Tue, 7 Feb 2023 21:34:39 +0100 Subject: [PATCH] f4pga: run black Signed-off-by: Unai Martinez-Corral --- f4pga/utils/pcf.py | 2 -- .../utils/quicklogic/convert_compile_opts.py | 4 --- f4pga/utils/quicklogic/pp3/arch_import.py | 9 ----- f4pga/utils/quicklogic/pp3/connections.py | 9 ----- .../quicklogic/pp3/create_default_fasm.py | 17 --------- f4pga/utils/quicklogic/pp3/create_ioplace.py | 2 -- .../pp3/create_place_constraints.py | 3 -- f4pga/utils/quicklogic/pp3/data_import.py | 36 ------------------- .../quicklogic/pp3/eos-s3/iomux_config.py | 4 --- f4pga/utils/quicklogic/pp3/fasm2bels.py | 14 -------- .../quicklogic/pp3/prepare_vpr_database.py | 32 ----------------- f4pga/utils/quicklogic/pp3/routing_import.py | 25 ------------- f4pga/utils/quicklogic/pp3/rr_utils.py | 9 ----- f4pga/utils/quicklogic/pp3/switchbox_model.py | 13 ------- f4pga/utils/quicklogic/pp3/tile_import.py | 3 -- f4pga/utils/quicklogic/pp3/timing.py | 7 ---- f4pga/utils/quicklogic/pp3/verilogmodule.py | 9 ----- f4pga/utils/quicklogic/pp3/vis_switchboxes.py | 5 --- .../quicklogic/process_sdc_constraints.py | 3 -- .../quicklogic/repacker/arch_xml_utils.py | 4 --- .../quicklogic/repacker/eblif_netlist.py | 11 ------ .../quicklogic/repacker/netlist_cleaning.py | 4 --- .../quicklogic/repacker/packed_netlist.py | 18 ---------- .../utils/quicklogic/repacker/pb_rr_graph.py | 13 ------- .../repacker/pb_rr_graph_netlist.py | 10 ------ .../quicklogic/repacker/pb_rr_graph_router.py | 6 ---- f4pga/utils/quicklogic/repacker/pb_type.py | 7 ---- f4pga/utils/quicklogic/repacker/repack.py | 30 ---------------- .../eblif_roundtrip/test_eblif_roundtrip.py | 2 -- .../tests/lut_padding/test_lut_padding.py | 1 - .../test_netlist_roundtrip.py | 2 -- .../quicklogic/yosys_fixup_cell_names.py | 1 - f4pga/utils/vpr_io_place.py | 2 -- f4pga/utils/xc7/create_ioplace.py | 2 +- f4pga/utils/xc7/create_place_constraints.py | 9 +---- f4pga/utils/xc7/fix_xc7_carry.py | 2 -- f4pga/utils/yosys_split_inouts.py | 5 --- f4pga/wrappers/sh/__init__.py | 2 -- 38 files changed, 2 insertions(+), 335 deletions(-) diff --git a/f4pga/utils/pcf.py b/f4pga/utils/pcf.py index 6c779d9..8490973 100644 --- a/f4pga/utils/pcf.py +++ b/f4pga/utils/pcf.py @@ -47,7 +47,6 @@ def parse_simple_pcf(f): assert len(args) == 3, args if args[0] == "set_io": - yield PcfIoConstraint( net=args[1], pad=args[2], @@ -56,7 +55,6 @@ def parse_simple_pcf(f): ) if args[0] == "set_clk": - yield PcfClkConstraint( pin=args[1], net=args[2], diff --git a/f4pga/utils/quicklogic/convert_compile_opts.py b/f4pga/utils/quicklogic/convert_compile_opts.py index 1b27d83..b26a1ab 100644 --- a/f4pga/utils/quicklogic/convert_compile_opts.py +++ b/f4pga/utils/quicklogic/convert_compile_opts.py @@ -43,7 +43,6 @@ def parse_options(lines, opts=None): # join all remaining ones into a single string opt_string = "" for line in lines: - # Remove comments pos = line.find("#") if pos != -1: @@ -60,7 +59,6 @@ def parse_options(lines, opts=None): # Remove all C/C++ style "/* ... */" comments while True: - # Find beginning of a block comment. Finish if none is found p0 = opt_string.find("/*") if p0 == -1: @@ -82,7 +80,6 @@ def parse_options(lines, opts=None): # Scan and process options parts = iter(shlex.split(opt_string)) while True: - # Get the option try: opt = next(parts) @@ -210,7 +207,6 @@ def translate_options(opts): # ============================================================================= if __name__ == "__main__": - # Read lines from stdin, parse options lines = sys.stdin.readlines() opts = parse_options(lines) diff --git a/f4pga/utils/quicklogic/pp3/arch_import.py b/f4pga/utils/quicklogic/pp3/arch_import.py index e438e1a..a168789 100755 --- a/f4pga/utils/quicklogic/pp3/arch_import.py +++ b/f4pga/utils/quicklogic/pp3/arch_import.py @@ -190,7 +190,6 @@ def write_tiles(xml_arch, arch_tile_types, tile_types, equivalent_sites): # Add tiles for tile_type, sub_tiles in arch_tile_types.items(): - xml = make_top_level_tile(tile_type, sub_tiles, tile_types, equivalent_sites) xml_tiles.append(xml) @@ -208,7 +207,6 @@ def write_pb_types(xml_arch, arch_pb_types, tile_types, nsmap): # Add pb_types for pb_type in arch_pb_types: - xml = make_top_level_pb_type(tile_types[pb_type], nsmap) xml_cplx.append(xml) @@ -275,7 +273,6 @@ def write_tilegrid(xml_arch, arch_tile_grid, loc_map, layout_name): # Individual tiles for flat_loc, tile in arch_tile_grid.items(): - if tile is None: continue @@ -342,7 +339,6 @@ def write_direct_connections(xml_arch, tile_grid, connections): # Populate connections conns = [c for c in connections if is_direct(c)] for connection in conns: - src_tile = get_tile(connection.src) dst_tile = get_tile(connection.dst) @@ -388,7 +384,6 @@ def write_direct_connections(xml_arch, tile_grid, connections): def main(): - # Parse arguments parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) @@ -417,7 +412,6 @@ def main(): # Flatten the VPR tilegrid flat_tile_grid = dict() for vpr_loc, tile in vpr_tile_grid.items(): - flat_loc = (vpr_loc.x, vpr_loc.y) if flat_loc not in flat_tile_grid: flat_tile_grid[flat_loc] = {} @@ -432,9 +426,7 @@ def main(): arch_models = set() for flat_loc, tiles in flat_tile_grid.items(): - if len(tiles): - # Group identical sub-tiles together, maintain their order sub_tiles = OrderedDict() for z, tile in tiles.items(): @@ -464,7 +456,6 @@ def main(): ) else: - # Add an empty location arch_tile_grid[flat_loc] = None diff --git a/f4pga/utils/quicklogic/pp3/connections.py b/f4pga/utils/quicklogic/pp3/connections.py index f390bc8..579354a 100644 --- a/f4pga/utils/quicklogic/pp3/connections.py +++ b/f4pga/utils/quicklogic/pp3/connections.py @@ -196,7 +196,6 @@ def build_tile_connections(tile_types, tile_grid, switchbox_types, switchbox_gri # A foreign connection elif sbox_pin.type == SwitchboxPinType.FOREIGN: - # Get the hop offset pin_name, hop = get_name_and_hop(sbox_pin.name) assert hop is not None, sbox_pin @@ -213,7 +212,6 @@ def build_tile_connections(tile_types, tile_grid, switchbox_types, switchbox_gri # Find the pin in the tile for pin in tile.pins: if pin.direction == OPPOSITE_DIRECTION[sbox_pin.direction]: - # Check if the pin name refers to the full tile pin name # ie. with the cell name. if pin.name == pin_name: @@ -283,7 +281,6 @@ def build_hop_connections(switchbox_types, switchbox_grid): # should go into a HOP input. dst_pins = [pin for pin in dst_switchbox.inputs.values() if pin.type == SwitchboxPinType.HOP] for dst_pin in dst_pins: - # Parse the name, determine hop offset. Skip non-hop wires. hop_name, hop_ofs = get_name_and_hop(dst_pin.name) if hop_ofs is None: @@ -346,7 +343,6 @@ def build_hop_connections(switchbox_types, switchbox_grid): def find_clock_cell(alias, tile_grid): - for loc, tile in tile_grid.items(): if tile is None: continue @@ -364,7 +360,6 @@ def find_clock_cell(alias, tile_grid): def build_gmux_qmux_connections(tile_types, tile_grid, switchbox_types, switchbox_grid, clock_cells): - # Define names of all global clock wires. # Each global clock mux as an implicitly defined output equal to its name. clock_wires = list(clock_cells.keys()) @@ -377,9 +372,7 @@ def build_gmux_qmux_connections(tile_types, tile_grid, switchbox_types, switchbo # Conections between clock cells (muxes) connections = [] for clock_cell in clock_cells.values(): - for pin_name, pin_conn in clock_cell.pin_map.items(): - # Destination pin name. Treat CAND and QMUX destinations # differently as there are going to be no tiles for them. if clock_cell.type in ["CAND", "QMUX"]: @@ -395,14 +388,12 @@ def build_gmux_qmux_connections(tile_types, tile_grid, switchbox_types, switchbo # This pin connects to a global clock wire if pin_conn in clock_wires: - # Get the other cell other_cell = clock_cells.get(pin_conn, None) # Not found in the clock cells. Probably it is the CLOCK cell # try finding it by its name / alias if other_cell is None: - src_loc, src_tile, src_cell = find_clock_cell(pin_conn, tile_grid) # Didint find the cell diff --git a/f4pga/utils/quicklogic/pp3/create_default_fasm.py b/f4pga/utils/quicklogic/pp3/create_default_fasm.py index af563e6..2b9844e 100755 --- a/f4pga/utils/quicklogic/pp3/create_default_fasm.py +++ b/f4pga/utils/quicklogic/pp3/create_default_fasm.py @@ -80,7 +80,6 @@ class SwitchboxConfigBuilder: # Create all mux nodes for stage, switch, mux in yield_muxes(self.switchbox): - # Create the node key = (stage.id, switch.id, mux.id) node = self.Node(self.NodeType.MUX, key) @@ -95,7 +94,6 @@ class SwitchboxConfigBuilder: # Create all source and sink nodes, populate their connections with mux # nodes. for pin in self.switchbox.pins: - # Node type if pin.direction == PinDirection.INPUT: node_type = self.NodeType.SOURCE @@ -107,7 +105,6 @@ class SwitchboxConfigBuilder: # Create one for each stage type stage_ids = set([loc.stage_id for loc in pin.locs]) for stage_id in stage_ids: - # Create the node key = pin.name node = self.Node(node_type, key) @@ -127,14 +124,12 @@ class SwitchboxConfigBuilder: # Populate connections for pin_loc in pin.locs: - # Get the correct node list stage_type = self.switchbox.stages[pin_loc.stage_id].type assert stage_type in self.nodes, stage_type nodes = self.nodes[stage_type] if pin.direction == PinDirection.INPUT: - # Get the mux node key = (pin_loc.stage_id, pin_loc.switch_id, pin_loc.mux_id) assert key in nodes, key @@ -164,7 +159,6 @@ class SwitchboxConfigBuilder: node.out.add(key) elif pin.direction == PinDirection.OUTPUT: - # Get the sink node key = pin.name assert key in nodes, key @@ -189,7 +183,6 @@ class SwitchboxConfigBuilder: # Populate mux to mux connections for conn in self.switchbox.connections: - # Get the correct node list stage_type = self.switchbox.stages[conn.dst.stage_id].type assert stage_type in self.nodes, stage_type @@ -242,7 +235,6 @@ class SwitchboxConfigBuilder: nodes = self.nodes[stage_type] def walk(node): - # Examine all driven nodes for sink_key in node.out: assert sink_key in nodes, sink_key @@ -250,7 +242,6 @@ class SwitchboxConfigBuilder: # The sink is free if sink_node.net is None: - # Assign it to the net sink_node.net = node.net if sink_node.type == self.NodeType.MUX: @@ -285,7 +276,6 @@ class SwitchboxConfigBuilder: for stage_type, nodes in self.nodes.items(): for key, node in nodes.items(): - if node.type == self.NodeType.MUX and node.sel is None: result = False print("WARNING: mux unconfigured", key) @@ -301,7 +291,6 @@ class SwitchboxConfigBuilder: for stage_type, nodes in self.nodes.items(): for key, node in nodes.items(): - # For muxes with active selection if node.type == self.NodeType.MUX and node.sel is not None: stage_id, switch_id, mux_id = key @@ -343,7 +332,6 @@ class SwitchboxConfigBuilder: nets = sorted(list(nets)) for i, net in enumerate(nets): - hue = i / len(nets) light = 0.33 saturation = 1.0 @@ -368,14 +356,12 @@ class SwitchboxConfigBuilder: # Stage types for stage_type, nodes in self.nodes.items(): - # Stage header dot.append(' subgraph "cluster_{}" {{'.format(stage_type)) dot.append(" label=\"Stage '{}'\";".format(stage_type)) # Nodes and internal mux edges for key, node in nodes.items(): - # Source node if node.type == self.NodeType.SOURCE: name = "{}_inp_{}".format(stage_type, key2str(key)) @@ -470,7 +456,6 @@ class SwitchboxConfigBuilder: # Mux to mux connections for key, node in nodes.items(): - # Source node if node.type == self.NodeType.SOURCE: pass @@ -536,7 +521,6 @@ class SwitchboxConfigBuilder: def main(): - # Parse arguments parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) @@ -653,7 +637,6 @@ def main(): # Power on all LOGIC cells for loc, tile in tile_grid.items(): - # Get the tile type object tile_type = tile_types[tile.type] diff --git a/f4pga/utils/quicklogic/pp3/create_ioplace.py b/f4pga/utils/quicklogic/pp3/create_ioplace.py index beab080..1bf6625 100755 --- a/f4pga/utils/quicklogic/pp3/create_ioplace.py +++ b/f4pga/utils/quicklogic/pp3/create_ioplace.py @@ -67,7 +67,6 @@ def main(): pad_alias_map = defaultdict(lambda: dict()) for pin_map_entry in csv.DictReader(args.map): - if pin_map_entry["type"] not in IOB_TYPES: continue @@ -88,7 +87,6 @@ def main(): used_pads = set() for pcf_constraint in parse_simple_pcf(args.pcf): - # Skip non-io constraints if type(pcf_constraint).__name__ != "PcfIoConstraint": continue diff --git a/f4pga/utils/quicklogic/pp3/create_place_constraints.py b/f4pga/utils/quicklogic/pp3/create_place_constraints.py index 72189b9..03fe6c0 100755 --- a/f4pga/utils/quicklogic/pp3/create_place_constraints.py +++ b/f4pga/utils/quicklogic/pp3/create_place_constraints.py @@ -95,7 +95,6 @@ def main(): io_constraints = {} for line in args.input: - # Strip, skip comments line = line.strip() if line.startswith("#"): @@ -119,7 +118,6 @@ def main(): BUF_CELL = {"type": "GMUX_IP", "ipin": "IP", "opin": "IZ"} for inp_net in eblif_data["inputs"]["args"]: - # This one is not constrained, skip it if inp_net not in io_constraints: continue @@ -159,7 +157,6 @@ def main(): # Emit constraints for GCLK cells for inp_net, iob_cell, con_net, buf_cell, clk_net in clock_connections: - src_loc = io_constraints[inp_net] if src_loc not in clock_to_gmux: eprint("ERROR: No GMUX location for input CLOCK pad for net '{}' at {}".format(inp_net, src_loc)) diff --git a/f4pga/utils/quicklogic/pp3/data_import.py b/f4pga/utils/quicklogic/pp3/data_import.py index cdbcc97..6b7693b 100755 --- a/f4pga/utils/quicklogic/pp3/data_import.py +++ b/f4pga/utils/quicklogic/pp3/data_import.py @@ -101,7 +101,6 @@ def parse_library(xml_library): cells = [] for xml_node in xml_library: - # Skip those if xml_node.tag in ["PortProperties"]: continue @@ -111,7 +110,6 @@ def parse_library(xml_library): # Load pins for xml_pins in itertools.chain(xml_node.findall("INPUT"), xml_node.findall("OUTPUT")): - # Pin direction if xml_pins.tag == "INPUT": direction = PinDirection.INPUT @@ -179,7 +177,6 @@ def parse_library(xml_library): def load_logic_cells(xml_placement, cellgrid, cells_library): - # Load "LOGIC" tiles xml_logic = xml_placement.find("LOGIC") assert xml_logic is not None @@ -218,10 +215,8 @@ def load_logic_cells(xml_placement, cellgrid, cells_library): def load_other_cells(xml_placement, cellgrid, cells_library): - # Loop over XML entries for xml in xml_placement: - # Got a "Cell" tag if xml.tag == "Cell": cell_name = xml.get("name") @@ -296,7 +291,6 @@ def make_tile_type_name(cells): def parse_placement(xml_placement, cells_library): - # Load tilegrid quadrants quadrants = {} @@ -342,14 +336,12 @@ def parse_placement(xml_placement, cells_library): tile_types = {} tile_types_at_loc = {} for loc, cells in cellgrid.items(): - # Generate type and assign type = make_tile_type_name(cells) tile_types_at_loc[loc] = type # A new type? complete its definition if type not in tile_types: - cell_types = [c.type for c in cells] cell_count = {t: len([c for c in cells if c.type == t]) for t in cell_types} @@ -360,11 +352,9 @@ def parse_placement(xml_placement, cells_library): # Make the final tilegrid tilegrid = {} for loc, type in tile_types_at_loc.items(): - # Group cells by type tile_cells_by_type = defaultdict(lambda: []) for cell in cellgrid[loc]: - tile_cells_by_type[cell.type].append(cell) # Create a list of cell instances within the tile @@ -413,10 +403,8 @@ def update_switchbox_pins(switchbox): for stage_id, stage in switchbox.stages.items(): for switch_id, switch in stage.switches.items(): for mux_id, mux in switch.muxes.items(): - # Add the mux output pin as top level output if necessary if mux.output.name is not None: - loc = SwitchboxPinLoc( stage_id=stage.id, switch_id=switch.id, @@ -444,7 +432,6 @@ def update_switchbox_pins(switchbox): # Add the mux input pins as top level inputs if necessary for pin in mux.inputs.values(): if pin.name is not None: - loc = SwitchboxPinLoc( stage_id=stage.id, switch_id=switch.id, @@ -458,7 +445,6 @@ def update_switchbox_pins(switchbox): # Add top-level input pins to the switchbox. keys = sorted(input_locs.keys(), key=lambda k: k[0]) for name, locs in {k: input_locs[k] for k in keys}.items(): - # Determine the pin type is_hop = is_regular_hop_wire(name) _, hop = get_name_and_hop(name) @@ -498,7 +484,6 @@ def parse_switchbox(xml_sbox, xml_common=None): # Load stages for xml_stage in stages: - # Get stage id stage_id = int(xml_stage.attrib["StageNumber"]) assert stage_id not in switchbox.stages, (stage_id, switchbox.stages.keys()) @@ -609,7 +594,6 @@ def parse_wire_mapping_table(xml_root, switchbox_grid, switchbox_types): # Rows xml_rows = [e for e in xml_root if e.tag.startswith("Row_")] for xml_row in xml_rows: - # Decode row range match = RE_LOC.match(xml_row.tag) assert match is not None, xml_row.tag @@ -623,7 +607,6 @@ def parse_wire_mapping_table(xml_root, switchbox_grid, switchbox_types): # Columns xml_cols = [e for e in xml_row if e.tag.startswith("Col_")] for xml_col in xml_cols: - # Decode column range match = RE_LOC.match(xml_col.tag) assert match is not None, xml_col.tag @@ -651,7 +634,6 @@ def parse_wire_mapping_table(xml_root, switchbox_grid, switchbox_types): for loc, xml_maps in yield_locs_and_maps(): for xml_map in xml_maps: - # Decode stage id match = RE_STAGE.match(xml_map.tag) assert match is not None, xml_map.tag @@ -662,7 +644,6 @@ def parse_wire_mapping_table(xml_root, switchbox_grid, switchbox_types): # Decode wire joints joints = {k: v for k, v in xml_map.attrib.items() if k.startswith("Join.")} for joint_key, joint_map in joints.items(): - # Decode the joint key match = RE_JOINT.match(joint_key) assert match is not None, joint_key @@ -711,7 +692,6 @@ def parse_port_mapping_table(xml_root, switchbox_grid): # Sections are named "*_Table" xml_tables = [e for e in xml_root if e.tag.endswith("_Table")] for xml_table in xml_tables: - # Get the origin origin = xml_table.tag.split("_")[0] assert origin in ["Left", "Right", "Top", "Bottom"], origin @@ -735,7 +715,6 @@ def parse_port_mapping_table(xml_root, switchbox_grid): # Parse the port mapping table(s) for port_mapping_xml in xml_table.findall("PortMappingTable"): - # Get the direction of the switchbox offset orientation = port_mapping_xml.attrib["Orientation"] if orientation == "Horizontal": @@ -762,7 +741,6 @@ def parse_port_mapping_table(xml_root, switchbox_grid): sbox_xmls = [e for e in index_xml if e.tag.startswith("SBox")] for sbox_xml in sbox_xmls: - offset = int(sbox_xml.attrib["Offset"]) mapped_name = sbox_xml.get("MTB_PortName", None) @@ -841,7 +819,6 @@ def parse_clock_network(xml_clock_network): # pin connection from the pinmap. This way the connections between # switchboxes which drive them can be used for generic routing. for cell_name in clock_cells.keys(): - cell = clock_cells[cell_name] pin_map = cell.pin_map @@ -879,7 +856,6 @@ def populate_clk_mux_port_maps(port_maps, clock_cells, tile_grid, cells_library) # Add map entries for mux_pin_name, sbox_pin_name in clock_cell.pin_map.items(): - # Get the pin definition to get its driection. cell_pin = [p for p in cell_pins if p.name == mux_pin_name] assert len(cell_pin) == 1, (clock_cell, mux_pin_name) @@ -905,7 +881,6 @@ def specialize_switchboxes_with_port_maps(switchbox_types, switchbox_grid, port_ """ for loc, port_map in port_maps.items(): - # No switchbox at that location if loc not in switchbox_grid: continue @@ -927,7 +902,6 @@ def specialize_switchboxes_with_port_maps(switchbox_types, switchbox_grid, port_ # Remap pin names did_remap = False for stage, switch, mux in yield_muxes(new_switchbox): - # Remap output alt_name = "{}.{}.{}".format(stage.id, switch.id, mux.id) @@ -973,7 +947,6 @@ def specialize_switchboxes_with_wire_maps(switchbox_types, switchbox_grid, port_ """ for loc, wire_map in wire_maps.items(): - # No switchbox at that location if loc not in switchbox_grid: continue @@ -995,7 +968,6 @@ def specialize_switchboxes_with_wire_maps(switchbox_types, switchbox_grid, port_ # Remap pin names did_remap = False for pin_loc, (wire_name, map_loc) in wire_map.items(): - # Get port map at the destination location of the wire that is # being remapped. assert map_loc in port_maps, (map_loc, wire_name) @@ -1051,7 +1023,6 @@ def find_special_cells(tile_grid): for loc, tile in tile_grid.items(): for cell_type, cell_names in tile.cell_names.items(): for (cell_name,) in cell_names: - # Skip LOGIC as it is always contained in a single tile if cell_name == "LOGIC": continue @@ -1077,7 +1048,6 @@ def parse_pinmap(xml_root, tile_grid): # Parse "PACKAGE" sections. for xml_package in xml_root.findall("PACKAGE"): - # Initialize map pkg_name = xml_package.attrib["name"] pkg_pin_map = defaultdict(lambda: set()) @@ -1108,7 +1078,6 @@ def parse_pinmap(xml_root, tile_grid): # Add the pin mapping for cell_name, cell_loc in zip(cell_names, cell_locs): - # Find the cell if cell_loc not in tile_grid: print("WARNING: No tile for package pin '{}' at '{}'".format(pin_name, cell_loc)) @@ -1181,7 +1150,6 @@ def import_data(xml_root): switchbox_grid = {} switchbox_types = {} for xml_node in xml_routing: - # Not a switchbox if not xml_node.tag.endswith("_SBOX"): continue @@ -1190,7 +1158,6 @@ def import_data(xml_root): xml_common = xml_node.find("COMMON_STAGES") for xml_sbox in xml_node: if xml_sbox != xml_common: - # Parse the switchbox definition switchbox = parse_switchbox(xml_sbox, xml_common) @@ -1264,7 +1231,6 @@ def import_routing_timing(csv_file): # Read and parse CSV with open(csv_file, "r") as fp: - # Read the first line, it should specify timing units line = fp.readline() line = line.strip().split(",") @@ -1288,7 +1254,6 @@ def import_routing_timing(csv_file): # Reformat switchbox_timings = {} for timing in data: - # Switchbox type switchbox_type = timing["SBox_Type"] if switchbox_type not in switchbox_timings: @@ -1334,7 +1299,6 @@ def import_routing_timing(csv_file): def main(): - # Parse arguments parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) diff --git a/f4pga/utils/quicklogic/pp3/eos-s3/iomux_config.py b/f4pga/utils/quicklogic/pp3/eos-s3/iomux_config.py index 4ddc344..be5cf3b 100755 --- a/f4pga/utils/quicklogic/pp3/eos-s3/iomux_config.py +++ b/f4pga/utils/quicklogic/pp3/eos-s3/iomux_config.py @@ -178,7 +178,6 @@ def main(): # Read the requested configurtion from a JSON file if args.json is not None: - if args.pcf is not None or args.eblif is not None: print("Use either '--json' or '--pcf' + '--eblif' options!") exit(-1) @@ -188,7 +187,6 @@ def main(): # Generate the config according to the EBLIF netlist and PCF constraints. else: - if args.json is not None or (args.eblif is None or args.pcf is None): print("Use either '--json' or '--pcf' + '--eblif' options!") exit(-1) @@ -197,7 +195,6 @@ def main(): pad_alias_map = {} for pin_map_entry in csv.DictReader(args.map): - if pin_map_entry["type"] not in IOB_TYPES: continue @@ -225,7 +222,6 @@ def main(): eblif_outputs = eblif["outputs"]["args"] for constraint in pcf: - pad_name = constraint.pad if pad_name not in pad_map and pad_name not in pad_alias_map: diff --git a/f4pga/utils/quicklogic/pp3/fasm2bels.py b/f4pga/utils/quicklogic/pp3/fasm2bels.py index a1ba195..291c214 100644 --- a/f4pga/utils/quicklogic/pp3/fasm2bels.py +++ b/f4pga/utils/quicklogic/pp3/fasm2bels.py @@ -516,7 +516,6 @@ class Fasm2Bels(object): c for c in self.connections if c.src.type == ConnectionType.TILE and c.dst.type == ConnectionType.TILE ] for connection in connections: - # Only to a GMUX at the given location dst = connection.dst if dst.loc != loc or "GMUX" not in dst.pin: @@ -567,7 +566,6 @@ class Fasm2Bels(object): connections = [c for c in self.connections if c.dst.type == ConnectionType.CLOCK] for connection in connections: - # Only to a QMUX at the given location dst = connection.dst if dst.loc != loc or "QMUX" not in dst.pin: @@ -605,7 +603,6 @@ class Fasm2Bels(object): # Make map entries for i in range(3): - # Calculate GMUX index for QCLKIN input of the QMUX idx = (gmux_idx + i) % 5 @@ -636,7 +633,6 @@ class Fasm2Bels(object): connections = [c for c in self.connections if c.dst.type == ConnectionType.CLOCK] for connection in connections: - # Only to a CAND at the given location # Note: Check also the row above. CAND cells are located in two # rows but with fasm features everything gets aligned to even rows @@ -679,7 +675,6 @@ class Fasm2Bels(object): gmux_map = dict() gmux_locs = [loc for loc, tile in self.vpr_tile_grid.items() if "GMUX" in tile.type] for loc in gmux_locs: - # Group GMUX input pin connections by GMUX cell names gmux_connections = defaultdict(lambda: dict()) for cell_pin, conn in self.designconnections[loc].items(): @@ -689,7 +684,6 @@ class Fasm2Bels(object): # Examine each GMUX config for gmux, connections in gmux_connections.items(): - # FIXME: Handle IS0 inversion (if any) # The IS0 pin has to be routed @@ -707,7 +701,6 @@ class Fasm2Bels(object): # IP selected if sel == 0: - # Create a global clock wire for the CLOCK pad match = re.match(r"GMUX(?P[0-9]+)", gmux) assert match is not None, gmux @@ -739,7 +732,6 @@ class Fasm2Bels(object): # IC selected else: - # Check if the IC pin has an active driver. If not then # discard the mux. if connections.get("IC", (None, None))[1] in [None, "GND", "VCC"]: @@ -776,7 +768,6 @@ class Fasm2Bels(object): qmux_map = defaultdict(lambda: dict()) qmux_locs = [loc for loc, tile in self.vpr_tile_grid.items() if "QMUX" in tile.type] for loc in qmux_locs: - # Group QMUX input pin connections by QMUX cell names qmux_connections = defaultdict(lambda: dict()) for cell_pin, conn in self.designconnections[loc].items(): @@ -786,7 +777,6 @@ class Fasm2Bels(object): # Examine each QMUX config for qmux, connections in qmux_connections.items(): - # FIXME: Handle IS0 and IS1 inversion (if any) # Both IS0 and IS1 must be routed to something @@ -814,7 +804,6 @@ class Fasm2Bels(object): # Input from the routing network selected, create a new wire if sel == 3: - # Check if the HSCKIN input is connected to an active # driver. If not then discard the QMUX if connections.get("HSCKIN", (None, None))[1] in [None, "GND", "VCC"]: @@ -832,7 +821,6 @@ class Fasm2Bels(object): # Input from a GMUX is selected, assign its wire here else: - # The GMUX is not active. Discard the QMUX gmux_loc, gmux_cell, gmux_pin = sel_map[sel] if gmux_cell not in gmux_map: @@ -867,7 +855,6 @@ class Fasm2Bels(object): # Process CAND for loc, all_features in self.colclk_data.items(): for cand, features in all_features.items(): - hilojoint = False enjoint = False @@ -980,7 +967,6 @@ def parse_pcf(pcf): if __name__ == "__main__": - # Parse arguments parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) diff --git a/f4pga/utils/quicklogic/pp3/prepare_vpr_database.py b/f4pga/utils/quicklogic/pp3/prepare_vpr_database.py index ac812ae..ad0bcb0 100755 --- a/f4pga/utils/quicklogic/pp3/prepare_vpr_database.py +++ b/f4pga/utils/quicklogic/pp3/prepare_vpr_database.py @@ -108,7 +108,6 @@ def process_cells_library(cells_library): vpr_cells_library = {} for cell_type, cell in cells_library.items(): - # If the cell is a QMUX add the missing QCLKIN1 and QCLKIN2 # input pins. if cell_type == "QMUX": @@ -146,7 +145,6 @@ def fixup_cand_loc(vpr_loc, phy_loc): def add_synthetic_cell_and_tile_types(tile_types, cells_library): - # Add a synthetic tile types for the VCC and GND const sources. # Models of the VCC and GND cells are already there in the cells_library. for const in ["VCC", "GND"]: @@ -238,7 +236,6 @@ def process_tilegrid(tile_types, tile_grid, clock_cells, cells_library, grid_siz # Generate the VPR tile grid for phy_loc, tile in tile_grid.items(): - # Limit the grid range if not is_loc_within_limit(phy_loc, grid_limit): continue @@ -249,11 +246,9 @@ def process_tilegrid(tile_types, tile_grid, clock_cells, cells_library, grid_siz # new tile type. tile_type = tile_types[tile.type] if "QMUX" in tile_type.cells or "CAND" in tile_type.cells: - # Store the stripped cells for cell in tile.cells: if cell.type in ["QMUX", "CAND"]: - # Find it in the physical clock cell list if cell.name not in clock_cells: print("WARNING: Clock cell '{}' not on the clock cell list!".format(cell.name)) @@ -298,7 +293,6 @@ def process_tilegrid(tile_types, tile_grid, clock_cells, cells_library, grid_siz # The tile contains a BIDIR or CLOCK cell. it is an IO tile tile_type = tile_types[tile.type] if "BIDIR" in tile_type.cells or "CLOCK" in tile_type.cells: - # For the BIDIR cell create a synthetic tile if "BIDIR" in tile_type.cells: assert tile_type.cells["BIDIR"] == 1 @@ -376,12 +370,10 @@ def process_tilegrid(tile_types, tile_grid, clock_cells, cells_library, grid_siz # The tile contains SDIOMUX cell(s). This is an IO tile. if "SDIOMUX" in tile_type.cells: - # Split the tile into individual SDIOMUX cells. Each one will be # inside a synthetic tile occupying different grid location. cells = [c for c in tile.cells if c.type == "SDIOMUX"] for i, cell in enumerate(cells): - # Create a synthetic tile that will hold just the SDIOMUX cell new_type = make_tile_type([cell], cells_library, tile_types) @@ -416,9 +408,7 @@ def process_tilegrid(tile_types, tile_grid, clock_cells, cells_library, grid_siz # GMUX, split individual GMUX cells into sub-tiles elif cell_type == "GMUX": - for i, cell in enumerate(tile.cells): - # Create a tile type for a single GMUX cell new_type = make_tile_type([cell], cells_library, tile_types) # New location @@ -443,7 +433,6 @@ def process_tilegrid(tile_types, tile_grid, clock_cells, cells_library, grid_siz # but in fact there is only one ASSP cell for the whole FPGA which is # "distributed" along top and left edge of the grid. if "ASSP" in tile_types: - # Verify that the location is empty assp_loc = Loc(x=1, y=1, z=0) assert is_loc_free(vpr_tile_grid, assp_loc), ("ASSP", assp_loc) @@ -461,7 +450,6 @@ def process_tilegrid(tile_types, tile_grid, clock_cells, cells_library, grid_siz # Insert synthetic VCC and GND source tiles. # FIXME: This assumes that the locations specified are empty! for const, loc in [("VCC", Loc(x=2, y=1, z=0)), ("GND", Loc(x=3, y=1, z=0))]: - # Verify that the location is empty assert is_loc_free(vpr_tile_grid, loc), (const, loc) @@ -496,7 +484,6 @@ def process_switchbox_grid(phy_switchbox_grid, loc_map, grid_offset, grid_limit= bwd_loc_map = loc_map.bwd def add_loc_map(phy_loc, vpr_loc): - if phy_loc in fwd_loc_map: assert fwd_loc_map[phy_loc] == vpr_loc, (phy_loc, vpr_loc) else: @@ -510,7 +497,6 @@ def process_switchbox_grid(phy_switchbox_grid, loc_map, grid_offset, grid_limit= # Remap locations vpr_switchbox_grid = {} for phy_loc, switchbox_type in phy_switchbox_grid.items(): - # Limit the grid range if not is_loc_within_limit(phy_loc, grid_limit): continue @@ -541,7 +527,6 @@ def process_connections(phy_connections, loc_map, vpr_tile_grid, phy_tile_grid, # Remap locations, create the VPR connection list vpr_connections = [] for connection in phy_connections: - # Reject connections that reach outsite the grid limit if not is_loc_within_limit(connection.src.loc, grid_limit): continue @@ -563,7 +548,6 @@ def process_connections(phy_connections, loc_map, vpr_tile_grid, phy_tile_grid, # If the connection mentions a GMUX cell, remap its Z location so # it points to the correct sub-tile if "GMUX" in ep.pin and ep.type == ConnectionType.TILE: - # Modify the cell name, use always "GMUX0" cell, pin = ep.pin.split("_", maxsplit=1) vpr_pin = "GMUX0_{}".format(pin) @@ -581,10 +565,8 @@ def process_connections(phy_connections, loc_map, vpr_tile_grid, phy_tile_grid, # Remap locations of connections that go to CLOCK pads. A physical # BIDIR+CLOCK tile is split into separate BIDIR and CLOCK tiles. for i, connection in enumerate(vpr_connections): - eps = [connection.src, connection.dst] for j, ep in enumerate(eps): - # This endpoint is not relevant to a CLOCK cell if not ep.pin.startswith("CLOCK"): continue @@ -619,10 +601,8 @@ def process_connections(phy_connections, loc_map, vpr_tile_grid, phy_tile_grid, } for i, connection in enumerate(vpr_connections): - eps = [connection.src, connection.dst] for j, ep in enumerate(eps): - # Must have "ASSP" and "FBIO_" in name and refer to a tile. if "ASSP" not in ep.pin: continue @@ -666,11 +646,9 @@ def process_connections(phy_connections, loc_map, vpr_tile_grid, phy_tile_grid, # Map connections going to/from them to their locations in the VPR grid for i, connection in enumerate(vpr_connections): - # Process connection endpoints eps = [connection.src, connection.dst] for j, ep in enumerate(eps): - if ep.type != ConnectionType.TILE: continue @@ -707,7 +685,6 @@ def process_connections(phy_connections, loc_map, vpr_tile_grid, phy_tile_grid, # Process connection endpoints eps = [connection.src, connection.dst] for j, ep in enumerate(eps): - if ep.type != ConnectionType.TILE: continue @@ -744,7 +721,6 @@ def process_connections(phy_connections, loc_map, vpr_tile_grid, phy_tile_grid, # "QCLKIN1=GMUX_2" etc. new_qmux_connections = [] for connection in vpr_connections: - # Get only those that target QCLKIN0 of a QMUX. if connection.dst.type != ConnectionType.CLOCK: continue @@ -784,11 +760,9 @@ def process_connections(phy_connections, loc_map, vpr_tile_grid, phy_tile_grid, # Handle QMUX connections. Instead of making them SWITCHBOX -> TILE convert # to SWITCHBOX -> CLOCK for i, connection in enumerate(vpr_connections): - # Process connection endpoints eps = [connection.src, connection.dst] for j, ep in enumerate(eps): - if ep.type != ConnectionType.TILE: continue @@ -839,7 +813,6 @@ def process_package_pinmap(package_pinmap, vpr_tile_grid, grid_limit=None): for pin_name, pins in package_pinmap.items(): for pin in pins: - # The loc is outside the grid limit, skip it. if not is_loc_within_limit(pin.loc, grid_limit): continue @@ -993,7 +966,6 @@ def load_sdf_timings(sdf_dir): for timing, timing_data in instance_data.items(): paths = timing_data["delay_paths"] for path_name, path_data in paths.items(): - for k in path_data.keys(): if path_data[k] is not None: path_data[k] *= scale @@ -1033,7 +1005,6 @@ def load_sdf_timings(sdf_dir): def main(): - # Parse arguments parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) @@ -1144,7 +1115,6 @@ def main(): print("Processing timing data...") if switchbox_timing is not None: - # The timing data seems to be the same for each switchbox type and is # stored under the SB_LC name. timing_data = switchbox_timing["SB_LC"] @@ -1163,7 +1133,6 @@ def main(): copy_switchbox_timing(switchbox, dst_switchbox) if cell_timings is not None: - sw = add_vpr_switches_for_cell("QMUX", cell_timings) vpr_switches.update(sw) @@ -1196,7 +1165,6 @@ def main(): for y in range(ymax + 1): line = " {:>2}: ".format(y) for x in range(xmax + 1): - tiles = {loc: tile for loc, tile in vpr_tile_grid.items() if loc.x == x and loc.y == y} count = len([t for t in tiles.values() if t is not None]) diff --git a/f4pga/utils/quicklogic/pp3/routing_import.py b/f4pga/utils/quicklogic/pp3/routing_import.py index a6f1b94..058403a 100755 --- a/f4pga/utils/quicklogic/pp3/routing_import.py +++ b/f4pga/utils/quicklogic/pp3/routing_import.py @@ -97,20 +97,17 @@ def is_local(connection): def get_vpr_switch_for_clock_cell(graph, cell, src, dst): - # Get a switch to model the mux delay properly. First try using # the cell name try: switch_name = "{}.{}.{}.{}".format(cell.type, cell.name, src, dst) switch_id = graph.get_switch_id(switch_name) except KeyError: - # Not found, try using the cell type try: switch_name = "{}.{}.{}.{}".format(cell.type, cell.type, src, dst) switch_id = graph.get_switch_id(switch_name) except KeyError: - # Still not found, use the generic one switch_id = graph.get_switch_id("generic") @@ -256,10 +253,8 @@ class QmuxModel(object): # Collect features for pin, net in pins.items(): - # Get switchbox routing features (already prefixed) for muxsel in self.ctrl_routes[pin][net]: - stage_id, switch_id, mux_id, pin_id = muxsel stage = self.switchbox_model.switchbox.stages[stage_id] @@ -309,7 +304,6 @@ class CandModel(object): self._build() def _build(self): - # Get segment id segment_id = self.graph.get_segment_id_from_name("clock") @@ -430,7 +424,6 @@ def build_tile_pin_to_node_map(graph, nodes_by_id, tile_types, tile_grid): # For each pin of the tile for pin in tile_types[tile.type].pins: - node_id = get_node_id_for_tile_pin(graph, loc, tile.type, pin.name) if node_id is None: print("WARNING: No node for pin '{}' at {}".format(pin.name, loc)) @@ -452,7 +445,6 @@ def build_tile_connection_map(graph, nodes_by_id, tile_grid, connections): # Adds entry to the map def add_to_map(conn_loc): - tile = tile_grid.get(conn_loc.loc, None) if tile is None: print("WARNING: No tile for pin '{} at {}".format(conn_loc.pin, conn_loc.loc)) @@ -578,7 +570,6 @@ def add_track_chain(graph, direction, u, v0, v1, segment_id, switch_id): # Add track chain for v in coords: - # Add track (node) if direction == "X": track = tracks.Track( @@ -665,7 +656,6 @@ def add_tracks_for_const_network(graph, const, tile_grid): # For each column add one that spand over the entire grid height const_node_map = {} for x in range(xmin, xmax): - # Add the column col_entry_node, _, col_node_map = add_track_chain(graph, "Y", x, ymin + 1, ymax - 1, segment_id, switch_id) @@ -725,7 +715,6 @@ def populate_hop_connections(graph, switchbox_models, connections): bar = progressbar_utils.progressbar conns = [c for c in connections if is_hop(c)] for connection in bar(conns): - # Get switchbox models src_switchbox_model = switchbox_models[connection.src.loc] dst_switchbox_model = switchbox_models[connection.dst.loc] @@ -756,7 +745,6 @@ def populate_tile_connections(graph, switchbox_models, connections, connection_l bar = progressbar_utils.progressbar conns = [c for c in connections if is_tile(c)] for connection in bar(conns): - # Connection to/from the local tile if is_local(connection): loc = connection.src.loc @@ -798,7 +786,6 @@ def populate_tile_connections(graph, switchbox_models, connections, connection_l # Connection to/from a foreign tile else: - # Get segment id and switch id segment_id = graph.get_segment_id_from_name("special") switch_id = graph.get_delayless_switch_id() @@ -817,10 +804,8 @@ def populate_tile_connections(graph, switchbox_models, connections, connection_l # Connect the track eps = [connection.src, connection.dst] for i, ep in enumerate(eps): - # Endpoint at tile if ep.type == ConnectionType.TILE: - # To tile if ep == connection.dst: if ep not in connection_loc_to_node: @@ -841,7 +826,6 @@ def populate_tile_connections(graph, switchbox_models, connections, connection_l # Endpoint at switchbox elif ep.type == ConnectionType.SWITCHBOX: - # No switchbox model at the loc, skip. if ep.loc not in switchbox_models: continue @@ -875,7 +859,6 @@ def populate_direct_connections(graph, connections, connection_loc_to_node): bar = progressbar_utils.progressbar conns = [c for c in connections if is_direct(c)] for connection in bar(conns): - # Get segment id and switch id if connection.src.pin.startswith("CLOCK"): switch_id = graph.get_delayless_switch_id() @@ -913,10 +896,8 @@ def populate_const_connections(graph, switchbox_models, tile_types, tile_grid, t # Connect the global const network to switchbox inputs for loc, switchbox_model in bar(switchbox_models.items()): - # Look for input connected to a const for pin in switchbox_model.switchbox.inputs.values(): - # Got a const input if pin.name in const_node_map: const_node = const_node_map[pin.name][loc] @@ -956,10 +937,8 @@ def populate_cand_connections(graph, switchbox_models, cand_node_map): bar = progressbar_utils.progressbar for loc, switchbox_model in bar(switchbox_models.items()): - # Look for input connected to a CAND for pin in switchbox_model.switchbox.inputs.values(): - # Got a CAND input if pin.name in cand_node_map: cand_node = cand_node_map[pin.name][loc] @@ -994,7 +973,6 @@ def create_quadrant_clock_tracks(graph, connections, connection_loc_to_node): bar = progressbar_utils.progressbar conns = [c for c in connections if is_clock(c)] for connection in bar(conns): - # Source is a tile if connection.src.type == ConnectionType.TILE: src_node = connection_loc_to_node.get(connection.src, None) @@ -1093,7 +1071,6 @@ def create_column_clock_tracks(graph, clock_cells, quadrants): cand_node_map = {} for cell in clock_cells.values(): - # A clock column is defined by a CAND cell if cell.type != "CAND": continue @@ -1146,7 +1123,6 @@ def yield_edges(edges): # Process edges for edge in edges: - # Reformat metadata if edge.metadata: metadata = [(meta.name, meta.value) for meta in edge.metadata] @@ -1172,7 +1148,6 @@ def yield_edges(edges): def main(): - # Parse arguments parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) diff --git a/f4pga/utils/quicklogic/pp3/rr_utils.py b/f4pga/utils/quicklogic/pp3/rr_utils.py index aff2155..87d4ee9 100644 --- a/f4pga/utils/quicklogic/pp3/rr_utils.py +++ b/f4pga/utils/quicklogic/pp3/rr_utils.py @@ -76,7 +76,6 @@ def add_edge(graph, src_node_id, dst_node_id, switch_id, meta_name=None, meta_va # in the opposite way. switch = graph.switch_map[switch_id] if switch.type in [rr.SwitchType.SHORT, rr.SwitchType.PASS_GATE]: - graph.add_edge(dst_node_id, src_node_id, switch_id, meta_name, meta_value) @@ -155,7 +154,6 @@ def connect(graph, src_node, dst_node, switch_id=None, segment_id=None, meta_nam chany_to_chany = src_node.type == rr.NodeType.CHANY and dst_node.type == rr.NodeType.CHANY chanx_to_chanx = src_node.type == rr.NodeType.CHANX and dst_node.type == rr.NodeType.CHANX if chany_to_chanx or chanx_to_chany: - # Check loc node_joint_location(src_node, dst_node) @@ -164,7 +162,6 @@ def connect(graph, src_node, dst_node, switch_id=None, segment_id=None, meta_nam # CHANX to CHANX or CHANY to CHANY elif chany_to_chany or chanx_to_chanx: - loc = node_joint_location(src_node, dst_node) direction = "X" if src_node.type == rr.NodeType.CHANY else "Y" @@ -178,13 +175,11 @@ def connect(graph, src_node, dst_node, switch_id=None, segment_id=None, meta_nam # OPIN to CHANX/CHANY elif src_node.type == rr.NodeType.OPIN and dst_node.type in [rr.NodeType.CHANX, rr.NodeType.CHANY]: - # All OPINs go right (towards +X) assert src_node.loc.side == tracks.Direction.RIGHT, src_node # Connected to CHANX if dst_node.type == rr.NodeType.CHANX: - loc = node_joint_location(src_node, dst_node) # Padding node @@ -197,7 +192,6 @@ def connect(graph, src_node, dst_node, switch_id=None, segment_id=None, meta_nam # Connected to CHANY elif dst_node.type == rr.NodeType.CHANY: - # Directly add_edge(graph, src_node.id, dst_node.id, switch_id, meta_name, meta_value) @@ -207,13 +201,11 @@ def connect(graph, src_node, dst_node, switch_id=None, segment_id=None, meta_nam # CHANX/CHANY to IPIN elif dst_node.type == rr.NodeType.IPIN and src_node.type in [rr.NodeType.CHANX, rr.NodeType.CHANY]: - # All IPINs go top (toward +Y) assert dst_node.loc.side == tracks.Direction.TOP, dst_node # Connected to CHANY if src_node.type == rr.NodeType.CHANY: - loc = node_joint_location(src_node, dst_node) # Padding node @@ -226,7 +218,6 @@ def connect(graph, src_node, dst_node, switch_id=None, segment_id=None, meta_nam # Connected to CHANX elif src_node.type == rr.NodeType.CHANX: - # Directly add_edge(graph, src_node.id, dst_node.id, switch_id, meta_name, meta_value) diff --git a/f4pga/utils/quicklogic/pp3/switchbox_model.py b/f4pga/utils/quicklogic/pp3/switchbox_model.py index 970dc28..d0ba6b6 100644 --- a/f4pga/utils/quicklogic/pp3/switchbox_model.py +++ b/f4pga/utils/quicklogic/pp3/switchbox_model.py @@ -151,7 +151,6 @@ class SwitchboxModel(object): # Expand all its inputs for pin_id, pin in mux.inputs.items(): - # An input goes to another mux, expand it if pin.name is None and pin_id in connections: connection = connections[pin_id] @@ -165,10 +164,8 @@ class SwitchboxModel(object): # This is a switchbox input elif pin.name is not None: - # We've hit the target if pin.name == target_name: - # Append the current mux and its selection final_route = list(route) final_route[-1] = tuple(list(final_route[-1]) + [pin_id]) @@ -268,7 +265,6 @@ class SwitchboxModel(object): # Input nodes + mux edges for pin in mux.inputs.values(): - key = (stage.id, switch.id, mux.id, pin.id) assert key not in self.mux_input_to_node @@ -347,7 +343,6 @@ class SwitchboxModel(object): for pin in self.switchbox.inputs.values(): for loc in pin.locs: - stage = self.switchbox.stages[loc.stage_id] switch = stage.switches[loc.switch_id] mux = switch.muxes[loc.mux_id] @@ -365,7 +360,6 @@ class SwitchboxModel(object): segment_id = self.graph.get_segment_id_from_name("sbox") for pin in self.switchbox.inputs.values(): - node = add_node(self.graph, self.loc, "Y", segment_id) assert pin.name not in self.input_to_node, pin.name @@ -373,7 +367,6 @@ class SwitchboxModel(object): # Create driver nodes, connect everything for (pin_name, vpr_switch), locs in driver_map.items(): - # Create the driver node drv_node = add_node(self.graph, self.loc, "X", segment_id) @@ -394,7 +387,6 @@ class SwitchboxModel(object): # Now connect the driver node with its loads switch_id = self.graph.get_switch_id("short") for loc in locs: - key = (loc.stage_id, loc.switch_id, loc.mux_id, loc.pin_id) dst_node = self.mux_input_to_node[key] @@ -411,7 +403,6 @@ class SwitchboxModel(object): # to the rr graph. For now if there is any fixed mux, remove the # whole switchbox. if len(self.fixed_muxsels): - # A list of muxes to avoid self.fixed_muxes = set([f[:3] for f in self.fixed_muxsels]) @@ -476,7 +467,6 @@ class QmuxSwitchboxModel(SwitchboxModel): ) for cell in self.qmux_cells.values(): - # Get IS0 and IS1 connection endpoints eps = {} for connection in self.connections: @@ -489,7 +479,6 @@ class QmuxSwitchboxModel(SwitchboxModel): # Find all routes for IS0 and IS1 pins that go to GND and VCC routes = {} for pin in PINS: - # Find the routes vcc_routes = self.get_switchbox_routes(self.switchbox, eps[pin].pin, "VCC") gnd_routes = self.get_switchbox_routes(self.switchbox, eps[pin].pin, "GND") @@ -512,10 +501,8 @@ class QmuxSwitchboxModel(SwitchboxModel): for cell_name, cell_routes in self.ctrl_routes.items(): for pin, pin_routes in cell_routes.items(): for net, net_routes in pin_routes.items(): - routes = [] for route in net_routes: - # Assume 3-stage switchbox assert len(route) == 3, "FIXME: Assuming 3-stage switchbox!" diff --git a/f4pga/utils/quicklogic/pp3/tile_import.py b/f4pga/utils/quicklogic/pp3/tile_import.py index 3d6f8fa..f8df6c4 100644 --- a/f4pga/utils/quicklogic/pp3/tile_import.py +++ b/f4pga/utils/quicklogic/pp3/tile_import.py @@ -193,14 +193,12 @@ def make_top_level_tile(tile_type, sub_tiles, tile_types, equivalent_tiles=None) # Equivalent sites xml_equiv = ET.SubElement(xml_sub_tile, "equivalent_sites") for site_type, site_pinmap in equivalent_sub_tiles.items(): - # Site tag pb_name = "PB-{}".format(site_type.upper()) xml_site = ET.SubElement(xml_equiv, "site", {"pb_type": pb_name, "pin_mapping": "custom"}) # Same type, map one-to-one if tile_type.upper() == site_type.upper() or site_pinmap is None: - all_pins = {**tile_pinlists["clock"], **tile_pinlists["input"], **tile_pinlists["output"]} for pin, count in all_pins.items(): @@ -211,7 +209,6 @@ def make_top_level_tile(tile_type, sub_tiles, tile_types, equivalent_tiles=None) # Explicit pinmap as a list of tuples (from, to) elif isinstance(site_pinmap, list): - for tl_pin, pb_pin in site_pinmap: ET.SubElement( xml_site, diff --git a/f4pga/utils/quicklogic/pp3/timing.py b/f4pga/utils/quicklogic/pp3/timing.py index e3fe5da..2fb6211 100644 --- a/f4pga/utils/quicklogic/pp3/timing.py +++ b/f4pga/utils/quicklogic/pp3/timing.py @@ -129,7 +129,6 @@ def compute_switchbox_timing_model(switchbox, timing_data): for pin in switchbox.inputs.values(): for loc in pin.locs: - dst_key = (loc.stage_id, loc.switch_id, loc.mux_id, loc.pin_id) src_key = (loc.stage_id, pin.name) @@ -138,11 +137,9 @@ def compute_switchbox_timing_model(switchbox, timing_data): # Compute timing model for each driver driver_timing = {} for driver, sinks in sink_map.items(): - # Collect timing data for each sink edge edge_timings = {} for stage_id, switch_id, mux_id, pin_id in sinks: - # Try getting timing data. If not found then probably we are # computing timing for VCC or GND input. try: @@ -211,7 +208,6 @@ def compute_switchbox_timing_model(switchbox, timing_data): # Compute error of the delay model for sink in sinks: - # Compute for this sink error = {} for n, true_delay in edge_timings[sink].items(): @@ -254,7 +250,6 @@ def populate_switchbox_timing(switchbox, driver_timing, sink_map, vpr_switches): # Populate timing data to the switchbox for driver, timing in driver_timing.items(): - # Driver VPR switch driver_vpr_switch = create_vpr_switch( type="mux", @@ -300,7 +295,6 @@ def copy_switchbox_timing(src_switchbox, dst_switchbox): # Mux timing for dst_stage, dst_switch, dst_mux in yield_muxes(dst_switchbox): - src_stage = src_switchbox.stages[dst_stage.id] src_switch = src_stage.switches[dst_switch.id] src_mux = src_switch.muxes[dst_mux.id] @@ -324,7 +318,6 @@ def add_vpr_switches_for_cell(cell_type, cell_timings): vpr_switches = {} for celltype, cell_data in timings.items(): for instance, inst_data in cell_data.items(): - # Add IOPATHs for timing, timing_data in inst_data.items(): if timing_data["type"].lower() != "iopath": diff --git a/f4pga/utils/quicklogic/pp3/verilogmodule.py b/f4pga/utils/quicklogic/pp3/verilogmodule.py index 8615a53..580e1b7 100644 --- a/f4pga/utils/quicklogic/pp3/verilogmodule.py +++ b/f4pga/utils/quicklogic/pp3/verilogmodule.py @@ -105,7 +105,6 @@ class VModule(object): } def group_vector_signals(self, signals, io=False): - # IOs beside name, have also direction, convert them to format # we can process if io: @@ -225,7 +224,6 @@ class VModule(object): str: Verilog entry """ if typ == "BIDIR": - # We do not emit the BIDIR cell for non inout IOs direction = self.get_io_config(parameters) if direction is None: @@ -337,7 +335,6 @@ class VModule(object): # check every connection pin if it has for pin in cellpins: - # Cell name and pin name match if cell_name in cell_input_names: if pin in cell_input_names[cell_name]: @@ -492,7 +489,6 @@ class VModule(object): loc, wire, ) in connections.items(): - # That wire is connected to something. Skip processing # of the cell here if loc is not None: @@ -561,10 +557,8 @@ class VModule(object): # Prune BELs that do not drive anythin (have all outputs disconnected) for loc, elements in list(self.elements.items()): for type, element in list(elements.items()): - # Handle IO cells if element.type in ["CLOCK", "BIDIR", "SDIOMUX"]: - if element.type == "CLOCK": direction = "input" else: @@ -576,7 +570,6 @@ class VModule(object): # Handle non-io cells else: - # Get connected pin names and output pin names connected_pins = set(element.ios.keys()) output_pins = set( @@ -596,7 +589,6 @@ class VModule(object): del self.elements[loc] def get_io_name(self, loc): - # default pin name name = loc2str(loc) + "_inout" # check if we have the original name for this io @@ -650,7 +642,6 @@ class VModule(object): for eloc, locelements in self.elements.items(): for element in locelements.values(): if element.type in ["CLOCK", "BIDIR", "SDIOMUX"]: - if element.type == "CLOCK": direction = "input" else: diff --git a/f4pga/utils/quicklogic/pp3/vis_switchboxes.py b/f4pga/utils/quicklogic/pp3/vis_switchboxes.py index 70362ca..5ae30fd 100755 --- a/f4pga/utils/quicklogic/pp3/vis_switchboxes.py +++ b/f4pga/utils/quicklogic/pp3/vis_switchboxes.py @@ -87,7 +87,6 @@ def switchbox_to_dot(switchbox, stage_types=("STREET", "HIGHWAY")): # Stages for stage in switchbox.stages.values(): - if stage.type not in stage_types: continue @@ -121,7 +120,6 @@ def switchbox_to_dot(switchbox, stage_types=("STREET", "HIGHWAY")): # Internal connections for conn in switchbox.connections: - if switchbox.stages[conn.src.stage_id].type not in stage_types: continue if switchbox.stages[conn.dst.stage_id].type not in stage_types: @@ -139,7 +137,6 @@ def switchbox_to_dot(switchbox, stage_types=("STREET", "HIGHWAY")): src_node = "input_{}".format(fixup_pin_name(pin.name)) for loc in pin.locs: - if switchbox.stages[loc.stage_id].type not in stage_types: continue @@ -153,7 +150,6 @@ def switchbox_to_dot(switchbox, stage_types=("STREET", "HIGHWAY")): dst_node = "output_{}".format(fixup_pin_name(pin.name)) for loc in pin.locs: - if switchbox.stages[loc.stage_id].type not in stage_types: continue @@ -171,7 +167,6 @@ def switchbox_to_dot(switchbox, stage_types=("STREET", "HIGHWAY")): def main(): - # Parse arguments parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) diff --git a/f4pga/utils/quicklogic/process_sdc_constraints.py b/f4pga/utils/quicklogic/process_sdc_constraints.py index 1744a9b..87f09c0 100644 --- a/f4pga/utils/quicklogic/process_sdc_constraints.py +++ b/f4pga/utils/quicklogic/process_sdc_constraints.py @@ -78,7 +78,6 @@ def expand_indices(items): # Process each item for item in items: - # Match using regex. If there is no match then pass the item through match = RE_INDICES.fullmatch(item) if not match: @@ -128,7 +127,6 @@ def process_get_ports(match, pad_to_net, valid_pins=None, valid_nets=None): # A helper mapping func. def map_pad_to_net(pad): - # Unescape square brackets pad = pad.replace("\\[", "[") pad = pad.replace("\\]", "]") @@ -175,7 +173,6 @@ def process_get_ports(match, pad_to_net, valid_pins=None, valid_nets=None): def main(): - # Parse arguments parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) diff --git a/f4pga/utils/quicklogic/repacker/arch_xml_utils.py b/f4pga/utils/quicklogic/repacker/arch_xml_utils.py index 5605b9e..5403165 100644 --- a/f4pga/utils/quicklogic/repacker/arch_xml_utils.py +++ b/f4pga/utils/quicklogic/repacker/arch_xml_utils.py @@ -75,7 +75,6 @@ def get_parent_pb_and_mode(xml_pbtype): # pb_type parent if xml_pbtype.tag == "pb_type": - if xml_parent.tag == "pb_type": return xml_parent, xml_parent @@ -83,7 +82,6 @@ def get_parent_pb_and_mode(xml_pbtype): return xml_parent.getparent(), xml_parent elif xml_pbtype.tag == "mode": - return xml_parent.getparent(), xml_pbtype @@ -152,7 +150,6 @@ def get_pb_and_port(xml_ic, port_spec): port = match.group("port") for xml_port in xml_pbtype: if xml_port.tag in ["input", "output", "clock"]: - # Got it if xml_port.attrib["name"] == port: return xml_pbtype, xml_port @@ -242,7 +239,6 @@ def yield_pins(xml_ic, port_spec, skip_index=True): # Yield individual pin names for i in indices: for j in bits: - name = match.group("pbtype") if i is not None: name += "[{}]".format(i) diff --git a/f4pga/utils/quicklogic/repacker/eblif_netlist.py b/f4pga/utils/quicklogic/repacker/eblif_netlist.py index e2a2485..0f998e4 100644 --- a/f4pga/utils/quicklogic/repacker/eblif_netlist.py +++ b/f4pga/utils/quicklogic/repacker/eblif_netlist.py @@ -38,7 +38,6 @@ class Cell: """ def __init__(self, type): - # Cell name. This one is for reference only. It won't be writteb back # with the .cname attribute. Use the cname field for that. self.name = None @@ -103,7 +102,6 @@ class Eblif: """ def __init__(self, model): - # Top-level module name self.model = model @@ -168,7 +166,6 @@ class Eblif: # Convert inputs for port in self.inputs: - cell = Cell("$input") cell.name = port cell.ports["inpad"] = port @@ -177,7 +174,6 @@ class Eblif: # Convert outputs for port in self.outputs: - cell = Cell("$output") cell.name = "out:" + port cell.cname = cell.name @@ -215,7 +211,6 @@ class Eblif: # Insert a buffer if the port name does not match the net name net = cell.ports["outpad"] if name != net: - cell = Cell("$lut") cell.name = name cell.ports["lut_in[0]"] = net @@ -421,10 +416,8 @@ class Eblif: # Cells for cell in self.cells.values(): - # A constant source if cell.type == "$const": - # Skip consts if not consts: continue @@ -435,7 +428,6 @@ class Eblif: # A LUT elif cell.type == "$lut": - # Identify LUT input pins and their bind indices nets = {} for port, net in cell.ports.items(): @@ -458,7 +450,6 @@ class Eblif: # A latch elif cell.type in ["$fe", "$re", "$ah", "$al", "$as"]: - line = ".latch {} {} {} {} {}".format( str(cell.ports["D"]), str(cell.ports["Q"]), cell.type[1:], str(cell.ports["clock"]), str(cell.init) ) @@ -466,13 +457,11 @@ class Eblif: # A generic latch controlled by a single global clock elif cell.type == "$latch": - line = ".latch {} {} {}".format(str(cell.ports["D"]), str(cell.ports["Q"]), str(cell.init)) lines.append(line) # A generic subcircuit else: - # The subcircuit along with its connections line = ".subckt {}".format(cell.type) for port, net in cell.ports.items(): diff --git a/f4pga/utils/quicklogic/repacker/netlist_cleaning.py b/f4pga/utils/quicklogic/repacker/netlist_cleaning.py index e69ce5c..bb7e015 100644 --- a/f4pga/utils/quicklogic/repacker/netlist_cleaning.py +++ b/f4pga/utils/quicklogic/repacker/netlist_cleaning.py @@ -45,7 +45,6 @@ def absorb_buffer_luts(netlist, outputs=False): # A pass-through LUT if cell.type == "$lut" and cell.init == [0, 1]: - # Get input and output nets assert INP_PORT in cell.ports, cell net_inp = cell.ports[INP_PORT] @@ -68,7 +67,6 @@ def absorb_buffer_luts(netlist, outputs=False): # Merge them downstream net_map = {} for cell in buffers.values(): - # Get input and output nets assert INP_PORT in cell.ports, cell net_inp = cell.ports[INP_PORT] @@ -83,7 +81,6 @@ def absorb_buffer_luts(netlist, outputs=False): # This cell drives a top-level output directly. Change input nets and # leave the output one if net_out in netlist.outputs: - # Replace the output net in all cells with the input one for c in netlist.cells.values(): for port, net in c.ports.items(): @@ -99,7 +96,6 @@ def absorb_buffer_luts(netlist, outputs=False): # A regular buffer else: - # Replace the output net in all cells with the input one for c in netlist.cells.values(): for port, net in c.ports.items(): diff --git a/f4pga/utils/quicklogic/repacker/packed_netlist.py b/f4pga/utils/quicklogic/repacker/packed_netlist.py index 47454f0..e57e8a5 100644 --- a/f4pga/utils/quicklogic/repacker/packed_netlist.py +++ b/f4pga/utils/quicklogic/repacker/packed_netlist.py @@ -190,7 +190,6 @@ class Block: """ def __init__(self, name, instance, mode=None, parent=None): - # Basic attributes self.name = name self.instance = instance @@ -230,7 +229,6 @@ class Block: xml_ports = elem.find(tag) if xml_ports is not None: for xml_port in xml_ports: - # Got a port rotation map if xml_port.tag == "port_rotation_map": port_name = xml_port.attrib["name"] @@ -257,7 +255,6 @@ class Block: # Recursively parse sub-blocks for xml_block in elem.findall("block"): - sub_block = Block.from_etree(xml_block) sub_block.parent = block @@ -265,11 +262,9 @@ class Block: # Parse attributes and parameters for tag, data in zip(["attributes", "parameters"], [block.attributes, block.parameters]): - # Find the list xml_list = elem.find(tag) if xml_list is not None: - # Only a leaf block can have attributes / parameters assert block.is_leaf, "Non-leaf block '{}' with {}".format(block.instance, tag) @@ -303,7 +298,6 @@ class Block: # Attributes / parameters if self.is_leaf: for tag, data in zip(["attributes", "parameters"], [self.attributes, self.parameters]): - xml_list = ET.Element(tag) sub_tag = tag[:-1] @@ -323,14 +317,12 @@ class Block: for key in keys: port = self.ports[key] if port.type == port_type: - # Encode port xml_port = port.to_etree() xml_ports.append(xml_port) # Rotation map if port.rotation_map: - # Encode rotation = [] for i in range(port.width): @@ -387,7 +379,6 @@ class Block: # Walk towards the tree root while block is not None: - # Type or type with index (instance) if with_indices: node = block.instance @@ -413,7 +404,6 @@ class Block: """ def walk(block): - if not block.is_leaf and not block.is_open: block.name = name @@ -429,14 +419,12 @@ class Block: """ def walk(block): - # Rename nets in port connections. Check whether the block itself # should be renamed as well (output pads need to be). rename_block = block.name.startswith("out:") for port in block.ports.values(): for pin, conn in port.connections.items(): - if isinstance(conn, str): port.connections[pin] = net_map.get(conn, conn) @@ -445,7 +433,6 @@ class Block: # Rename the leaf block if necessary if block.is_leaf and not block.is_open and rename_block: - if block.name in net_map: block.name = net_map[block.name] elif block.name.startswith("out:"): @@ -483,7 +470,6 @@ class Block: # Check parent and siblings if self.parent is not None: - # Parent if self.parent.type == block_type: return self.parent @@ -530,11 +516,9 @@ class Block: # Recursive walk function def walk(block): - # Examine block ports for port in block.ports.values(): for pin in range(port.width): - net = block.find_net_for_port(port.name, pin) if net: nets.add(net) @@ -553,7 +537,6 @@ class Block: """ def walk(block, parts): - # Check if instance matches instance = "{}[{}]".format(parts[0].name, parts[0].index) if block.instance != instance: @@ -594,7 +577,6 @@ class Block: """ def walk(block, count=0): - # This is a non-ope leaf, count it if block.is_leaf and not block.is_open: count += 1 diff --git a/f4pga/utils/quicklogic/repacker/pb_rr_graph.py b/f4pga/utils/quicklogic/repacker/pb_rr_graph.py index f1046cb..2bbea52 100644 --- a/f4pga/utils/quicklogic/repacker/pb_rr_graph.py +++ b/f4pga/utils/quicklogic/repacker/pb_rr_graph.py @@ -95,7 +95,6 @@ class Graph: """ def __init__(self): - # Nodes by id self.nodes = {} # Edges (assorted) @@ -170,7 +169,6 @@ class Graph: # Handler for "lut" pb_types. It creates an additional level of # hierarchy to match the representation in packed netlist. def process_lut(xml_pbtype, up_node_map, path): - # The parent is actually a leaf so it does not have any modes # However, the mode name must equal to the pb_type name. curr_path = path + "[{}].lut[0]".format(xml_pbtype.attrib["name"]) @@ -214,14 +212,12 @@ class Graph: # Process each mode for mode, xml_mode in xml_modes.items(): - # Append mode name to the current path curr_path = path + "[{}]".format(mode) # Enumerate childern, build their paths children = [] for xml_child, index in yield_pb_children(xml_mode): - child_path = ".".join([curr_path, "{}[{}]".format(xml_child.attrib["name"], index)]) children.append( @@ -294,7 +290,6 @@ class Graph: # Add nodes for xml_port in xml_pbtype: - if xml_port.tag in ["input", "output", "clock"]: width = int(xml_port.attrib["num_pins"]) @@ -337,7 +332,6 @@ class Graph: # A helper function def get_node_path(pin): - # Split parts parts = pin.split(".") assert len(parts) == 2, pin @@ -365,7 +359,6 @@ class Graph: # Process interconnects for xml_conn in xml_ic: - # Direct if xml_conn.tag == "direct": inps = list(yield_pins(xml_ic, xml_conn.attrib["input"], False)) @@ -390,7 +383,6 @@ class Graph: # Build edges for each input port for inp_port in inp_ports: - # Get input pins, should be only one inp_pins = list(yield_pins(xml_ic, inp_port, False)) assert len(inp_pins) == 1, xml_conn.attrib @@ -439,7 +431,6 @@ class Graph: net_colors = {} for i, net in enumerate(nets): - h = i / len(nets) l = 0.50 # noqa: E741 s = 1.0 @@ -455,7 +446,6 @@ class Graph: # Node color def node_color(node, highlight=False): - if highlight_nodes: if highlight: return "#FF2020" @@ -486,7 +476,6 @@ class Graph: # Edge color def edge_color(edge): - if color_by == "net": net = self.edge_net(edge) if net: @@ -508,7 +497,6 @@ class Graph: # Build nodes nodes = {} for node in self.nodes.values(): - if nets_only and node.net is None: continue @@ -555,7 +543,6 @@ class Graph: # Add edges for edge in self.edges: - if nets_only: if not self.edge_net(edge): continue diff --git a/f4pga/utils/quicklogic/repacker/pb_rr_graph_netlist.py b/f4pga/utils/quicklogic/repacker/pb_rr_graph_netlist.py index 98fd0bf..34f2e7a 100644 --- a/f4pga/utils/quicklogic/repacker/pb_rr_graph_netlist.py +++ b/f4pga/utils/quicklogic/repacker/pb_rr_graph_netlist.py @@ -64,7 +64,6 @@ def load_clb_nets_into_pb_graph(clb_block, clb_graph): # Annotate nodes with nets for node in clb_graph.nodes.values(): - # Disassemble node path parts parts = node.path.split(".") parts = [PathNode.from_string(p) for p in parts] @@ -125,7 +124,6 @@ def build_packed_netlist_from_pb_graph(clb_graph): nodes_up = {} for edge in clb_graph.edges: - # Check if the edge is active if clb_graph.edge_net(edge) is None: continue @@ -138,7 +136,6 @@ def build_packed_netlist_from_pb_graph(clb_graph): # Create the block hierarchy for nodes that have nets assigned. clb_block = None for node in clb_graph.nodes.values(): - # No net if node.net is None: continue @@ -183,7 +180,6 @@ def build_packed_netlist_from_pb_graph(clb_graph): # Add open blocks. for node in clb_graph.nodes.values(): - # Consider only nodes without nets if node.net: continue @@ -218,7 +214,6 @@ def build_packed_netlist_from_pb_graph(clb_graph): # Add block ports and their connections for node in clb_graph.nodes.values(): - # Disassemble node path parts parts = node.path.split(".") parts = [PathNode.from_string(p) for p in parts] @@ -237,14 +232,12 @@ def build_packed_netlist_from_pb_graph(clb_graph): port_name = parts[-1].name port_type = node.port_type.name.lower() if port_name not in block.ports: - # The relevant information will be updated as more nodes gets # discovered. port = packed_netlist.Port(name=port_name, type=port_type) block.ports[port_name] = port else: - port = block.ports[port_name] assert port.type == port_type, (port.type, port_type) @@ -265,7 +258,6 @@ def build_packed_netlist_from_pb_graph(clb_graph): # Got a driver, this is an intermediate port if driver_node is not None: - # Get the driver pb_type and port driver_path = clb_graph.nodes[driver_node].path.split(".") driver_path = [PathNode.from_string(driver_path[i]) for i in [-2, -1]] @@ -287,10 +279,8 @@ def build_packed_netlist_from_pb_graph(clb_graph): # Assign names to leaf blocks def leaf_walk(block): - # A leaf if block.is_leaf and not block.is_open: - # Identify all output pins that drive nets nets = [] for port in block.ports.values(): diff --git a/f4pga/utils/quicklogic/repacker/pb_rr_graph_router.py b/f4pga/utils/quicklogic/repacker/pb_rr_graph_router.py index 8a6ce8e..40302e2 100644 --- a/f4pga/utils/quicklogic/repacker/pb_rr_graph_router.py +++ b/f4pga/utils/quicklogic/repacker/pb_rr_graph_router.py @@ -77,7 +77,6 @@ class Router: sinks = {} for node in self.graph.nodes.values(): - if node.type not in [NodeType.SOURCE, NodeType.SINK]: continue @@ -100,7 +99,6 @@ class Router: # Make nets nets = set(sinks.keys()) | set(sources.keys()) for net_name in nets: - net = Net(net_name) # A net may or may not have a source node(s). If there are no @@ -130,7 +128,6 @@ class Router: top_level_sources = set() def walk_depth_first(node, curr_route=None): - # FIXME: Two possible places for optimization: # - create an edge lookup list indexed by dst node ids # - do not copy the current route list for each recursion level @@ -159,7 +156,6 @@ class Router: # Check all incoming edges for edge in self.graph.edges: if edge.dst_id == node.id: - # Recurse next_node = self.graph.nodes[edge.src_id] route = walk_depth_first(next_node, list(curr_route)) @@ -181,7 +177,6 @@ class Router: # Route all sinks to any of the net sources for sink in net.sinks: - # Find the route node = self.graph.nodes[sink] @@ -191,7 +186,6 @@ class Router: # No route found. Check if we have some free top-level ports that # we can use. if not route and top_level_sources: - # Use the frist one top_node_id = next(iter(top_level_sources)) top_node = self.graph.nodes[top_node_id] diff --git a/f4pga/utils/quicklogic/repacker/pb_type.py b/f4pga/utils/quicklogic/repacker/pb_type.py index 0e58d09..09b602f 100644 --- a/f4pga/utils/quicklogic/repacker/pb_type.py +++ b/f4pga/utils/quicklogic/repacker/pb_type.py @@ -96,7 +96,6 @@ class Port: # Selected pins if range_spec is not None: - # TODO: Compile the regex upfront match = re.fullmatch(r"((?P[0-9]+):)?(?P[0-9]+)", range_spec) assert match is not None, range_spec @@ -164,7 +163,6 @@ class Model: models = {} def walk(pb_type): - # This is a mode, recurse if isinstance(pb_type, Mode): for child in pb_type.pb_types.values(): @@ -172,7 +170,6 @@ class Model: # This is a pb_type. Make a model if it is a leaf elif isinstance(pb_type, PbType): - # Not a leaf, recurse for modes if not pb_type.is_leaf: for mode in pb_type.modes.values(): @@ -282,13 +279,11 @@ class PbType: # Build ports for xml_port in elem: if xml_port.tag in ["input", "output", "clock"]: - port = Port.from_etree(xml_port) pb_type.ports[port.name] = port # This is a native LUT leaf pb_type. Add one more level of hierarchy if is_leaf_pbtype(elem) and cls == "lut": - # Rename the default mode so that it matches the pb_type name mode = pb_type.modes["default"] mode.name = pb_type.name @@ -344,7 +339,6 @@ class PbType: # Walk the hierarchy along the path pbtype = self while True: - # Pop a node from the path part = path[0] path = path[1:] @@ -368,7 +362,6 @@ class PbType: # Mode not given else: - # No more path, return the pb_type if not path: return pbtype diff --git a/f4pga/utils/quicklogic/repacker/repack.py b/f4pga/utils/quicklogic/repacker/repack.py index 5fc6099..03701ba 100755 --- a/f4pga/utils/quicklogic/repacker/repack.py +++ b/f4pga/utils/quicklogic/repacker/repack.py @@ -85,7 +85,6 @@ class RepackingConstraint: """ def __init__(self, net, block_type, port_spec): - port = PathNode.from_string(port_spec) self.net = net @@ -144,7 +143,6 @@ def fixup_route_throu_luts(clb_block, new_net_ids): for port in block.ports.values(): for pin, conn in port.connections.items(): - if port.type in ["input", "clock"]: if blk_inp is None: blk_inp = Port(port, pin) @@ -221,10 +219,8 @@ def insert_buffers(nets, eblif, clb_block): """ def walk(block, net, collected_blocks): - # This is a leaf block if block.is_leaf: - # Check every input port connection, identify driving nets. Store # the block if at least one input is driven by the given net. for port in block.ports.values(): @@ -243,7 +239,6 @@ def insert_buffers(nets, eblif, clb_block): # Insert buffers for each new net for net_inp, net_out in nets: - # Insert the buffer cell. Here it is a LUT-1 configured as buffer. cell = Cell("$lut") cell.name = net_out @@ -259,7 +254,6 @@ def insert_buffers(nets, eblif, clb_block): # Remap block cell connections for block in blocks: - # Find cell for the block cell = eblif.find_cell(block.name) assert cell is not None, block @@ -321,7 +315,6 @@ def identify_blocks_to_repack(clb_block, repacking_rules): # This is not a leaf block else: - # Add the implicit LUT hierarchy to the path if is_lut: path.append(PathNode.from_string("lut[0]")) @@ -371,7 +364,6 @@ def fix_block_path(block_path, arch_path, change_mode=True): # Process the path for i in range(length): - # Parse both path nodes arch_node = PathNode.from_string(arch_path[i]) block_node = PathNode.from_string(block_path[i]) @@ -415,7 +407,6 @@ def identify_repack_target_candidates(clb_pbtype, path): """ def walk(arch_path, pbtype, pbtype_index, curr_path=None): - # Parse the path node if arch_path: path_node = PathNode.from_string(arch_path[0]) @@ -445,14 +436,12 @@ def identify_repack_target_candidates(clb_pbtype, path): # Recurse for mode_name, mode in pbtype.modes.items(): - # Check mode if given if path_node.mode is not None and path_node.mode != mode_name: continue # Recurse for children for child, i in mode.yield_children(): - # Recurse part = "{}[{}][{}]".format(pbtype_name, pbtype_index, mode_name) yield from walk(arch_path, child, i, curr_path + [part]) @@ -501,7 +490,6 @@ def annotate_net_endpoints(clb_graph, block, block_path=None, constraints=None, nodes_by_net = {} for node in clb_graph.nodes.values(): - # Consider only SOURCE and SINK nodes if node.type not in [NodeType.SOURCE, NodeType.SINK]: continue @@ -555,7 +543,6 @@ def annotate_net_endpoints(clb_graph, block, block_path=None, constraints=None, # Reassign top-level SOURCE and SINK nodes according to the constraints for constraint in constraints: - # Check if the constraint is for this block type if constraint.block_type != block_type: continue @@ -586,7 +573,6 @@ def annotate_net_endpoints(clb_graph, block, block_path=None, constraints=None, # port or vice-versa. node_types = set([node.type for node in nodes_by_net[constraint.net]]) if port_node.type not in node_types: - name_map = {NodeType.SINK: "output", NodeType.SOURCE: "input"} logging.warning( @@ -626,7 +612,6 @@ def rotate_truth_table(table, rotation_map): # Rotate new_table = [0 for i in range(2**width)] for daddr in range(2**width): - # Remap address bits saddr = 0 for i in range(width): @@ -711,7 +696,6 @@ def repack_netlist_cell(eblif, cell, block, src_pbtype, model, rule, def_map=Non # If the cell is a LUT then rotate its truth table. Append the rotated # truth table as a parameter to the repacked cell. if cell.type == "$lut": - # Build the init parameter init = rotate_truth_table(cell.init, lut_rotation) init = "".join(["1" if x else "0" for x in init][::-1]) @@ -729,7 +713,6 @@ def repack_netlist_cell(eblif, cell, block, src_pbtype, model, rule, def_map=Non # If the cell is a LUT-based const generator append the LUT parameter as # well. if cell.type == "$const": - assert lut_width == 0, (cell, lut_width) # Assume that the model is a LUT. Take its widest input port and use @@ -745,7 +728,6 @@ def repack_netlist_cell(eblif, cell, block, src_pbtype, model, rule, def_map=Non # Process parameters for "adder_lut4" if cell.type == "adder_lut4": - # Remap the Cin mux select to MODE if "IN2_IS_CIN" in cell.parameters: repacked_cell.parameters["MODE"] = cell.parameters["IN2_IS_CIN"] @@ -779,10 +761,8 @@ def syncrhonize_attributes_and_parameters(eblif, packed_netlist): """ def walk(block): - # This is a leaf if block.is_leaf and not block.is_open: - if any(block.instance.startswith(inst) for inst in ["outpad", "inpad"]): return @@ -845,7 +825,6 @@ def expand_port_maps(rules, clb_pbtypes): """ for rule in rules: - # Get src and dst pb_types path = [PathNode.from_string(p) for p in rule.src.split(".")] path = [PathNode(p.name, mode=p.mode) for p in path] @@ -860,7 +839,6 @@ def expand_port_maps(rules, clb_pbtypes): # Expand port map port_map = {} for src_port, dst_port in rule.port_map.items(): - # Get pin lists src_pins = list(src_pbtype.yield_port_pins(src_port)) dst_pins = list(dst_pbtype.yield_port_pins(dst_port)) @@ -894,7 +872,6 @@ def load_json_constraints(json_root): constraints = [] for json_constr in json_constrs: - constraint = RepackingConstraint( net=json_constr["net"], block_type=json_constr["tile"], port_spec=json_constr["pin"] ) @@ -918,7 +895,6 @@ def load_pcf_constraints(pcf): constraints = [] for pcf_constr in parse_simple_pcf(pcf): if type(pcf_constr).__name__ == "PcfClkConstraint": - # There are only "clb" and "io" tile types # We select the same global clock for # each tile where net is used @@ -956,7 +932,6 @@ def write_packed_netlist(fname, netlist): def main(): - # Parse arguments parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) @@ -1151,7 +1126,6 @@ def main(): iter_list = list(blocks_to_repack) blocks_to_repack = [] for block, rule in iter_list: - # Remap index of the destination block pointed by the path of the # rule. blk_path = block.get_path() @@ -1197,7 +1171,6 @@ def main(): # Check for conflicts repack_targets = set() for block, rule, (path, pbtype) in blocks_to_repack: - if path in repack_targets: logging.error("Multiple blocks are to be repacked into '{}'".format(path)) repack_targets.add(path) @@ -1295,7 +1268,6 @@ def main(): # Restore names of leaf blocks for src_block, rule, (dst_path, dst_pbtype) in blocks_to_repack: if dst_path in leaf_block_names: - search_path = dst_path.split(".", maxsplit=1)[1] dst_block = repacked_clb_block.get_block_by_path(search_path) assert dst_block is not None, dst_path @@ -1339,7 +1311,6 @@ def main(): # would cause top-level port renaming. logging.info("Cleaning repacked circuit netlist...") if absorb_buffer_luts: - net_map = netlist_cleaning.absorb_buffer_luts(eblif, outputs=True) # Synchronize packed netlist net names @@ -1384,7 +1355,6 @@ def main(): # Find the header line for i in range(len(placement)): if placement[i].startswith("Netlist_File:"): - # Replace the header placement[i] = "Netlist_File: {} Netlist_ID: {}\n".format( os.path.basename(net_out_fname), "SHA256:" + net_digest diff --git a/f4pga/utils/quicklogic/repacker/tests/eblif_roundtrip/test_eblif_roundtrip.py b/f4pga/utils/quicklogic/repacker/tests/eblif_roundtrip/test_eblif_roundtrip.py index d246dbe..9530ed3 100644 --- a/f4pga/utils/quicklogic/repacker/tests/eblif_roundtrip/test_eblif_roundtrip.py +++ b/f4pga/utils/quicklogic/repacker/tests/eblif_roundtrip/test_eblif_roundtrip.py @@ -27,7 +27,6 @@ from eblif_netlist import Eblif # noqa: E402 def test_netlist_roundtrip(): - basedir = os.path.dirname(__file__) golden_file = os.path.join(basedir, "netlist.golden.eblif") @@ -35,7 +34,6 @@ def test_netlist_roundtrip(): eblif = Eblif.from_file(golden_file) with tempfile.TemporaryDirectory() as tempdir: - # Write the EBLIF back output_file = os.path.join(tempdir, "netlist.output.eblif") eblif.to_file(output_file) diff --git a/f4pga/utils/quicklogic/repacker/tests/lut_padding/test_lut_padding.py b/f4pga/utils/quicklogic/repacker/tests/lut_padding/test_lut_padding.py index 4528e41..8c66a5f 100644 --- a/f4pga/utils/quicklogic/repacker/tests/lut_padding/test_lut_padding.py +++ b/f4pga/utils/quicklogic/repacker/tests/lut_padding/test_lut_padding.py @@ -57,7 +57,6 @@ def test_lut_padding(monkeypatch, lut_width, lut_inputs): net_in = os.path.join(basedir, "lut{}_{}.net".format(lut_width, lut_inputs)) with tempfile.TemporaryDirectory() as tempdir: - eblif_out = os.path.join(tempdir, "out.eblif") net_out = os.path.join(tempdir, "out.net") diff --git a/f4pga/utils/quicklogic/repacker/tests/packed_netlist_roundtrip/test_netlist_roundtrip.py b/f4pga/utils/quicklogic/repacker/tests/packed_netlist_roundtrip/test_netlist_roundtrip.py index e728925..ff43075 100644 --- a/f4pga/utils/quicklogic/repacker/tests/packed_netlist_roundtrip/test_netlist_roundtrip.py +++ b/f4pga/utils/quicklogic/repacker/tests/packed_netlist_roundtrip/test_netlist_roundtrip.py @@ -29,7 +29,6 @@ from packed_netlist import PackedNetlist # noqa: E402 def test_netlist_roundtrip(): - basedir = os.path.dirname(__file__) golden_file = os.path.join(basedir, "netlist.golden.net") @@ -42,7 +41,6 @@ def test_netlist_roundtrip(): xml_tree = ET.parse(golden_file, ET.XMLParser(remove_blank_text=True)) with tempfile.TemporaryDirectory() as tempdir: - # Transform and save the golden file sorted_golden_file = os.path.join(tempdir, "netlist.golden.sorted.net") with open(sorted_golden_file, "w") as fp: diff --git a/f4pga/utils/quicklogic/yosys_fixup_cell_names.py b/f4pga/utils/quicklogic/yosys_fixup_cell_names.py index 011b89d..f39916f 100644 --- a/f4pga/utils/quicklogic/yosys_fixup_cell_names.py +++ b/f4pga/utils/quicklogic/yosys_fixup_cell_names.py @@ -41,7 +41,6 @@ def fixup_cell_names(design): # Process cells cells = mod_data["cells"] for cell_name in list(cells.keys()): - # Fixup name if "." in cell_name: new_name = cell_name.replace(".", "_") diff --git a/f4pga/utils/vpr_io_place.py b/f4pga/utils/vpr_io_place.py index 216da00..42757ae 100644 --- a/f4pga/utils/vpr_io_place.py +++ b/f4pga/utils/vpr_io_place.py @@ -187,7 +187,6 @@ class IoPlace(object): # This is an inout net if net_name in self.inout_nets: for prefix, suffix in zip(["", "out:"], ["_$inp", "_$out"]): - match = NETNAME_REGEX.match(net_name) name = prefix + match.group(1) + suffix + match.group(2) @@ -225,7 +224,6 @@ class IoPlace(object): existing = constrained_blocks[name] if existing.x != constraint.x or existing.y != constraint.y or existing.z != constraint.z: - print("Error: block '{}' has multiple conflicting constraints!".format(name)) print("", constrained_blocks[name]) print("", constraint) diff --git a/f4pga/utils/xc7/create_ioplace.py b/f4pga/utils/xc7/create_ioplace.py index 706cfaa..df0f7fe 100644 --- a/f4pga/utils/xc7/create_ioplace.py +++ b/f4pga/utils/xc7/create_ioplace.py @@ -73,7 +73,7 @@ def p_main(blif, map, net, pcf=None, output=stdout, iostandard_defs_file=None, i net_to_pad |= set((constr.net, constr.pad) for constr in parse_simple_pcf(pcf)) # Check for conflicting pad constraints net_to_pad_map = dict() - for (net, pad) in net_to_pad: + for net, pad in net_to_pad: if net not in net_to_pad_map: net_to_pad_map[net] = pad elif pad != net_to_pad_map[net]: diff --git a/f4pga/utils/xc7/create_place_constraints.py b/f4pga/utils/xc7/create_place_constraints.py index 5ee85d9..6b78be5 100644 --- a/f4pga/utils/xc7/create_place_constraints.py +++ b/f4pga/utils/xc7/create_place_constraints.py @@ -124,7 +124,6 @@ class PlaceConstraints(object): existing = constrained_blocks[name] if existing.x != constraint.x or existing.y != constraint.y or existing.z != constraint.z: - print("Error: block '{}' has multiple conflicting constraints!".format(name)) print("", constrained_blocks[name]) print("", constraint) @@ -307,7 +306,7 @@ def eprint(*args, **kwargs): def get_cmt(cmt_dict, loc): """Returns the clock region of an input location.""" for k, v in cmt_dict.items(): - for (x, y) in v["vpr_loc"]: + for x, y in v["vpr_loc"]: if x == loc[0] and y == loc[1]: return v["clock_region"] @@ -421,7 +420,6 @@ class VprGrid(object): class ClockPlacer(object): def __init__(self, vpr_grid, io_locs, blif_data, roi, graph_limit, allow_bufg_logic_sources=False): - self.roi = roi self.cmt_to_bufg_tile = {} self.bufg_from_cmt = { @@ -573,7 +571,6 @@ class ClockPlacer(object): clock["sink_nets"].append(sink_net) if sink_net not in self.input_pins and sink_net not in self.clock_sources: - # Allow IBUFs. At this point we cannot distinguish between # IBUFs for clock and logic. if bel == "IBUF_VPR": @@ -608,7 +605,6 @@ class ClockPlacer(object): # Store the parent CMT in clock_cmts. for block, loc in block_locs.items(): if block in self.clock_blocks: - clock = self.clock_blocks[block] if CLOCKS[clock["subckt"]]["type"] == "BUFGCTRL": pass @@ -626,7 +622,6 @@ class ClockPlacer(object): # Any clocks that were previously constrained must be preserved for block, (loc_x, loc_y, _) in blocks.items(): if block in self.clock_blocks: - clock = self.clock_blocks[block] if CLOCKS[clock["subckt"]]["type"] == "BUFGCTRL": pass @@ -677,7 +672,6 @@ class ClockPlacer(object): ibuf_cmt_sinks = defaultdict(set) for net in self.clock_sources: - is_net_ibuf = False if net not in self.input_pins: @@ -688,7 +682,6 @@ class ClockPlacer(object): is_net_ibuf = True for clock_name in self.clock_sources[net]: - if clock_name in unused_blocks: continue diff --git a/f4pga/utils/xc7/fix_xc7_carry.py b/f4pga/utils/xc7/fix_xc7_carry.py index a8ec19d..d02246c 100644 --- a/f4pga/utils/xc7/fix_xc7_carry.py +++ b/f4pga/utils/xc7/fix_xc7_carry.py @@ -413,7 +413,6 @@ def create_bit_to_cell_map(design, top_module): for port, connections in cell["connections"].items(): is_output = port_directions[port] == "output" for bit_idx, bit in enumerate(connections): - list_of_cells = bit_to_cells.get(bit, None) if list_of_cells is None: list_of_cells = [None] @@ -570,7 +569,6 @@ def fixup_congested_rows(design, top_module, bit_to_cells, bit_to_nets, chain): # If this is the last CARRY4 in the chain, see if the # remaining part of the chain is idle. elif chain_idx == len(chain) - 1 and check_if_rest_of_carry4_is_unused(cellname, cell_idx + 1): - # Because the rest of the CARRY4 is idle, it is safe to # use the next row up to output the top of the carry. connections["S{}".format(cell_idx + 1)] = ["1'b0"] diff --git a/f4pga/utils/yosys_split_inouts.py b/f4pga/utils/yosys_split_inouts.py index d4fd30f..73fd1e2 100644 --- a/f4pga/utils/yosys_split_inouts.py +++ b/f4pga/utils/yosys_split_inouts.py @@ -168,7 +168,6 @@ def main(input: str, output: str = None): net_map = {} port_map = [] for name, port in inouts.items(): - # Remove the inout port from the module del module["ports"][name] nets -= get_nets(port["bits"]) @@ -215,10 +214,8 @@ def main(input: str, output: str = None): # Remove remapped nets for name, net in list(netnames.items()): - # Remove "bits" used by the net that were re-mapped. if len(set(net["bits"]) & set(net_map.keys())): - # Remove net["bits"] = ["x" if b in net_map else b for b in net["bits"]] @@ -250,7 +247,6 @@ def main(input: str, output: str = None): # Process cell connections for port_name, port_nets in list(connections.items()): - # Skip if no net of this connection were remapped if len(set(net_map.keys()) & set(port_nets)) == 0: continue @@ -259,7 +255,6 @@ def main(input: str, output: str = None): # versa. for dir in ["input", "output"]: if port_directions[port_name] == dir and port_name.endswith("$" + dir[:3]): - for i, n in enumerate(port_nets): if n in net_map: mapped_n = net_map[n][dir[0]] diff --git a/f4pga/wrappers/sh/__init__.py b/f4pga/wrappers/sh/__init__.py index b134a08..4bace98 100644 --- a/f4pga/wrappers/sh/__init__.py +++ b/f4pga/wrappers/sh/__init__.py @@ -144,7 +144,6 @@ def p_parse_vpr_args(vpr_options=None, log_suffix=None, isQuickLogic=False): def p_parse_vpr_args_xc7(vpr_options=None, log_suffix=None): - parser = ArgumentParser(description=__doc__, formatter_class=RawDescriptionHelpFormatter) parser.add_argument("--device", "-d", required=False, type=str, help="") parser.add_argument("--eblif", "-e", required=True, type=str, help="") @@ -253,7 +252,6 @@ def p_parse_vpr_args_xc7(vpr_options=None, log_suffix=None): def p_parse_vpr_args_quicklogic(vpr_options=None, log_suffix=None): - parser = ArgumentParser(description=__doc__, formatter_class=RawDescriptionHelpFormatter) parser.add_argument("--device", "-d", required=True, type=str, help="") parser.add_argument("--family", "-f", required=True, type=str, help="")