From 73930d400c5902e4a16855c275991be0ec9da5c6 Mon Sep 17 00:00:00 2001 From: Kareem Farid Date: Tue, 16 Jan 2024 19:40:03 +0200 Subject: [PATCH] Allow cells matching `TRISTATE_CELLS` in `SYNTH_CHECKS_ALLOW_TRISTATE` (#343) * Renamed GPIO_PADS_PREFIX to GPIO_PAD_CELLS, accepting with translation behavior * Created `TRISTATE_CELLS` for parity with OpenLane, accepting (multiple) wildcards and `TRISTATE_CELL_PREFIX` with translation behavior ## Testing * Added test for both hand-instantiating tri-state buffers AND high-impedance derived tri-state buffers --------- Co-authored-by: Mohamed Gaber --- openlane/config/flow.py | 19 +++++++++++++++-- openlane/steps/yosys.py | 46 +++++++++++++++++++++++++++++++++-------- test/steps/all | 2 +- 3 files changed, 55 insertions(+), 12 deletions(-) diff --git a/openlane/config/flow.py b/openlane/config/flow.py index a61009bea..5814873d5 100644 --- a/openlane/config/flow.py +++ b/openlane/config/flow.py @@ -14,12 +14,19 @@ import os from decimal import Decimal -from typing import List, Optional, Dict, Union, Tuple +from typing import List, Optional, Dict, Sequence, Union, Tuple from .variable import Variable, Macro from ..common import Path, get_script_dir +def _prefix_to_wildcard(prefixes_raw: Union[str, Sequence[str]]): + prefixes = prefixes_raw + if isinstance(prefixes, str): + prefixes = prefixes.split() + return [f"{prefix}*" for prefix in prefixes] + + pdk_variables = [ # Core/Common Variable( @@ -78,9 +85,10 @@ pdk=True, ), Variable( - "GPIO_PADS_PREFIX", + "GPIO_PAD_CELLS", Optional[List[str]], "A list of pad cell name prefixes.", + deprecated_names=[("GPIO_PADS_PREFIX", _prefix_to_wildcard)], pdk=True, ), Variable( @@ -170,6 +178,13 @@ deprecated_names=["STD_CELL_POWER_PINS"], pdk=True, ), + Variable( + "TRISTATE_CELLS", + Optional[List[str]], + "A list of cell names or wildcards of tri-state buffers.", + deprecated_names=[("TRISTATE_CELL_PREFIX", _prefix_to_wildcard)], + pdk=True, + ), Variable( "FILL_CELL", List[str], diff --git a/openlane/steps/yosys.py b/openlane/steps/yosys.py index de24f3582..ff00d1570 100644 --- a/openlane/steps/yosys.py +++ b/openlane/steps/yosys.py @@ -15,8 +15,9 @@ import re import io import json -import subprocess +import fnmatch import textwrap +import subprocess from decimal import Decimal from abc import abstractmethod from typing import List, Literal, Optional, Tuple @@ -31,26 +32,52 @@ starts_with_whitespace = re.compile(r"^\s+.+$") +yosys_cell_rx = r"cell\s+\S+\s+\((\S+)\)" + + +def _check_any_tristate( + cells: List[str], + tristate_patterns: List[str], +): + for cell in cells: + for tristate_pattern in tristate_patterns: + if fnmatch.fnmatch(cell, tristate_pattern): + return True + + return False + def _parse_yosys_check( report: io.TextIOBase, + tristate_patterns: Optional[List[str]] = None, tristate_okay: bool = False, ) -> int: verbose("Parsing synthesis checks…") errors_encountered: int = 0 + last_warning = None current_warning = None + tristate_patterns = tristate_patterns or [] + for line in report: if line.startswith("Warning:") or line.startswith("Found and reported"): - if current_warning is not None: - if tristate_okay and "tribuf" in current_warning: - debug("Ignoring tristate-related error:") - debug(current_warning) - else: - debug("Encountered check error:") - debug(current_warning) - errors_encountered += 1 + last_warning = current_warning current_warning = line + if last_warning is None: + continue + + cells = re.findall(yosys_cell_rx, last_warning) + + if tristate_okay and ( + ("tribuf" in last_warning) + or _check_any_tristate(cells, tristate_patterns) + ): + debug("Ignoring tristate-related error:") + debug(last_warning) + else: + debug("Encountered check error:") + debug(last_warning) + errors_encountered += 1 elif ( starts_with_whitespace.match(line) is not None and current_warning is not None @@ -384,6 +411,7 @@ def run(self, state_in: State, **kwargs) -> Tuple[ViewsUpdate, MetricsUpdate]: if os.path.exists(check_error_count_file): metric_updates["synthesis__check_error__count"] = _parse_yosys_check( open(check_error_count_file), + self.config["TRISTATE_CELLS"], self.config["SYNTH_CHECKS_ALLOW_TRISTATE"], ) diff --git a/test/steps/all b/test/steps/all index 04d71f3a8..4283de670 160000 --- a/test/steps/all +++ b/test/steps/all @@ -1 +1 @@ -Subproject commit 04d71f3a84b4954abe7323c19b32aa63323a6deb +Subproject commit 4283de670621a210d086cd56f77502ea2c8b99c4