feat(precheck): check if power pins have USE in definition (#139)

* feat(precheck): check if power pins have `USE` in definition

* fix: expect zero or more spaces, instead of one or more

* feat(precheck): check for missing `USE POWER`

* feat(precheck): check for missing `USE GROUND`

* feat(precheck): add simple README with link to LEF/DEF reference manual
This commit is contained in:
kris j
2025-11-20 08:57:05 +02:00
committed by GitHub
parent e80e10658b
commit 9a14f318d6
3 changed files with 136 additions and 1 deletions
+26 -1
View File
@@ -154,7 +154,7 @@ def boundary_check(gds: str, tech: str):
def power_pin_check(verilog: str, lef: str, uses_3v3: bool):
"""Ensure that VPWR / VGND are present,
"""Ensure that VPWR / VGND are present and have USE definitions,
and that VAPWR is present if and only if 'uses_3v3' is set."""
verilog_s = open(verilog).read().replace("VPWR", "VDPWR")
lef_s = open(lef).read().replace("VPWR", "VDPWR")
@@ -163,6 +163,12 @@ def power_pin_check(verilog: str, lef: str, uses_3v3: bool):
verilog_s = re.sub("//.*", "", verilog_s)
verilog_s = re.sub("/\\*.*?\\*/", "", verilog_s, flags=(re.DOTALL | re.MULTILINE))
# this looks for a line beginning with "PIN", captures the name of the pin and the body up until its "END"
PIN_PATTERN = re.compile(
r"^\s*PIN (VPWR|VDPWR|VAPWR|VGND)\s*([\s\S]+?(?=^\s*END \1))",
flags=re.MULTILINE,
)
for ft, s in (("Verilog", verilog_s), ("LEF", lef_s)):
for pwr, ex in (("VGND", True), ("VDPWR", True), ("VAPWR", uses_3v3)):
if (pwr in s) and not ex:
@@ -170,6 +176,25 @@ def power_pin_check(verilog: str, lef: str, uses_3v3: bool):
if not (pwr in s) and ex:
raise PrecheckFailure(f"{ft} doesn't contain {pwr}")
for match in PIN_PATTERN.finditer(lef_s):
pin, definition = match.groups()
match pin:
case "VPWR" | "VDPWR" | "VAPWR":
if "USE POWER" not in definition:
raise PrecheckFailure(
f"{pin} does not have a corresponding 'USE POWER ;'"
)
case "VGND":
if "USE GROUND" not in definition:
raise PrecheckFailure(
f"{pin} does not have a corresponding 'USE GROUND ;'"
)
case _:
raise PrecheckFailure(f"unhandled {pin}")
def layer_check(gds: str, tech: str):
"""Check that there are no invalid layers in the GDS file."""