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)