ecp_vlog: rename IO-related wires based on the package
diff --git a/tools/ecp_vlog.py b/tools/ecp_vlog.py index 8c3c59d..af49233 100644 --- a/tools/ecp_vlog.py +++ b/tools/ecp_vlog.py
@@ -2,7 +2,6 @@ import sys from collections import defaultdict from dataclasses import dataclass, field -from enum import IntEnum from functools import lru_cache from typing import Callable, ClassVar, Dict, List, Optional, Sequence, Set, Tuple, Type @@ -83,6 +82,7 @@ x: int id: Ident pin: Optional[Ident] = None + mod_name_map: ClassVar[Optional[Dict[str, str]]] = None @property def loc(self) -> pytrellis.Location: @@ -90,7 +90,10 @@ @property def mod_name(self) -> str: - return f"R{self.y}C{self.x}_{self.name}" + res = f"R{self.y}C{self.x}_{self.name}" + if self.mod_name_map: + return self.mod_name_map.get(res, res) + return res @property def name(self) -> str: @@ -358,8 +361,6 @@ # Verilog generation - - def filter_node(node: Node) -> bool: if node.pin is None: # This is a bit extreme, but we assume that all *useful* wires @@ -539,7 +540,8 @@ "D1MUX", ] - print(f""" + print( + f""" /* Use the cells_sim library from yosys/techlibs/ecp5 */ `include "../inc/cells_sim.v" module ECP5_SLICE( @@ -583,7 +585,8 @@ {", ".join(f".{pin}({pin})" for pin in cls.output_pins)} ); endmodule -""".strip()) +""".strip() + ) def print_instance(self, instname: str) -> None: print("ECP5_SLICE #(") @@ -626,9 +629,9 @@ "ADB11", "ADB12", "ADB13", - "CEB", # CER - "CLKA", # CLKW - "CLKB", # CLKR + "CEB", # CER + "CLKA", # CLKW + "CLKB", # CLKR # DI "DIA0", "DIA1", @@ -711,7 +714,8 @@ @classmethod def print_definition(cls) -> None: """ Print the Verilog code for the module definition """ - print(f""" + print( + f""" module ECP5_EBR( input {", ".join(cls.input_pins)}, output {", ".join(cls.output_pins)} @@ -744,7 +748,8 @@ /* TODO! */ endmodule -""".strip()) +""".strip() + ) def print_instance(self, instname: str) -> None: print("ECB5_EBR #(") @@ -877,16 +882,32 @@ def main(argv: List[str]) -> None: import argparse + import json parser = argparse.ArgumentParser("Convert a .bit file into a .v verilog file for simulation") parser.add_argument("bitfile", help="Input .bit file") + parser.add_argument("--package", help="Physical package (e.g. CABGA256), for renaming I/O-related wires") args = parser.parse_args(argv) pytrellis.load_database(database.get_db_root()) bitstream = pytrellis.Bitstream.read_bit(args.bitfile) chip = bitstream.deserialise_chip() + + if args.package: + dbfn = os.path.join(database.get_db_subdir(chip.info.family, chip.info.name), "iodb.json") + with open(dbfn, "r") as f: + iodb = json.load(f) + + # Rename PIO and IOLOGIC BELs based on their connected pins, for readability + mod_renames = {} + for pin_name, pin_data in iodb["packages"][args.package].items(): + mod_renames["R{row}C{col}_PIO{pio}".format(**pin_data)] = f"{pin_name}_PIO" + mod_renames["R{row}C{col}_IOLOGIC{pio}".format(**pin_data)] = f"{pin_name}_IOLOGIC" + + Node.mod_name_map = mod_renames + rgraph = chip.get_routing_graph() tiles_by_loc = make_tiles_by_loc(chip)