Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hotfix: crash when macro lib files are gzipped #629

Merged
merged 2 commits into from
Jan 5, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,19 @@
## Documentation
-->

# 2.3.2

## Steps

* `Yosys.*`
* Fixed blackbox Verilog and lib models causing a crash if they are
gzipped and/or have the extension `.gz`.

## Tool Updates

* Relaxed requirement on `httpx` to include `0.28.X`, which has no removals
compared to `0.27.0`.

# 2.3.1

## Tool Updates
Expand Down
26 changes: 26 additions & 0 deletions openlane/common/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import os
import re
import glob
import gzip
import typing
import fnmatch
import pathlib
Expand All @@ -29,6 +30,7 @@
SupportsFloat,
Union,
)

import httpx

from .types import AnyPath, Path
Expand Down Expand Up @@ -374,3 +376,27 @@ def process_list_file(from_file: AnyPath) -> List[str]:

def _get_process_limit() -> int:
return int(os.getenv("_OPENLANE_MAX_CORES", os.cpu_count() or 1))


def gzopen(filename, mode="rt"):
"""
This method (tries to?) emulate the gzopen from the Linux Standard Base,
specifically this part:

If path refers to an uncompressed file, and mode refers to a read mode,
gzopen() shall attempt to open the file and return a gzFile object suitable
for reading directly from the file without any decompression.

gzip.open does not have this behavior.
"""
try:
g = gzip.open(filename, mode=mode)
# Incredibly, it won't actually try to figure out if it's a gzipped
# file until you try to read from it.
if "r" in mode:
g.read(1)
g.seek(0)
return g
except gzip.BadGzipFile:
g.close()
return open(filename, mode=mode)
8 changes: 4 additions & 4 deletions openlane/common/toolbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
from deprecated.sphinx import deprecated


from .misc import mkdirp
from .misc import mkdirp, gzopen
from .types import Path
from .metrics import aggregate_metrics
from .generic_dict import GenericImmutableDict, is_string
Expand Down Expand Up @@ -388,9 +388,9 @@ class State(IntEnum):
excluded_cells_filter = Filter(excluded_cells)

for file in input_lib_files:
input_lib_stream = open(file)
out_filename = f"{uuid.uuid4().hex}.lib"
out_path = os.path.join(self.tmp_dir, out_filename)
input_lib_stream = gzopen(file)
# can't be gzip -- abc cannot read gzipped lib files
out_path = os.path.join(self.tmp_dir, f"{uuid.uuid4().hex}.lib")

state = State.initial
brace_count = 0
Expand Down
4 changes: 1 addition & 3 deletions openlane/scripts/pyosys/synthesize.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import os
import sys
import json
import shutil

Expand Down Expand Up @@ -280,9 +279,8 @@ def synthesize(
d.run_pass("plugin", "-i", "ghdl")
d.run_pass("ghdl", *vhdl_files, "-e", config["DESIGN_NAME"])
else:
print(
ys.log_error(
"Script called inappropriately: config must include either VERILOG_FILES or VHDL_FILES.",
file=sys.stderr,
)
exit(1)

Expand Down
16 changes: 11 additions & 5 deletions openlane/scripts/pyosys/ys_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import sys
from typing import Iterable, List, Union

Expand All @@ -20,7 +21,7 @@
try:
from pyosys import libyosys as ys
except ImportError:
print(
ys.log_error(
"Could not find pyosys in 'PYTHONPATH'-- make sure Yosys is compiled with ENABLE_PYTHON set to 1.",
file=sys.stderr,
)
Expand Down Expand Up @@ -122,11 +123,16 @@ def _Design_add_blackbox_models(
define_args = [f"-D{define}" for define in defines]

for model in models:
if model.endswith(".v") or model.endswith(".sv") or model.endswith(".vh"):
model_path, ext = os.path.splitext(model)
if ext == ".gz":
kareefardi marked this conversation as resolved.
Show resolved Hide resolved
# Yosys transparently handles gzip compression
model_path, ext = os.path.splitext(model_path)

if ext in [".v", ".sv", ".vh"]:
self.run_pass(
"read_verilog", "-sv", "-lib", *include_args, *define_args, model
)
elif model.endswith(".lib"):
elif ext in [".lib"]:
self.run_pass(
"read_liberty",
"-lib",
Expand All @@ -136,8 +142,8 @@ def _Design_add_blackbox_models(
model,
)
else:
print(
f"[ERROR] Black-box model '{model}' has an unrecognized file extension.",
ys.log_error(
f"Black-box model '{model}' has an unrecognized file extension: '{ext}'.",
file=sys.stderr,
)
sys.stderr.flush()
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "openlane"
version = "2.3.1"
version = "2.3.2"
description = "An infrastructure for implementing chip design flows"
authors = ["Efabless Corporation and Contributors <[email protected]>"]
readme = "Readme.md"
Expand All @@ -21,7 +21,7 @@ lxml = ">=4.9.0"
deprecated = ">=1.2.10,<2"
libparse = ">=0.3.1,<1"
psutil = ">=5.9.0"
httpx = ">=0.22.0,<0.28"
httpx = ">=0.22.0,<0.29"
klayout = ">=0.29.0,<0.30.0"
rapidfuzz = ">=3.9.0,<4"
ioplace-parser = ">=0.3.0,<0.5.0"
Expand Down
Loading