mirror of
https://github.com/The-OpenROAD-Project/OpenLane.git
synced 2026-05-29 00:23:55 +08:00
=== Flow Scripts === + Support OpenROAD ODB format as the primary format in which data is stored after placement + Create `manipulate_layout` to centralize calling odbpy scripts + Add `CURRENT_POWERED_NETLIST` to list of "current" variables, separate from `CURRENT_NETLIST` to avoid confusion ~ Update `scripts/odbpy/reader.py:OdbReader` and *all dependent scripts* now to use `odb` inputs and outputs. Add new `--output-def` flag to continue saving a DEF layout of the result. ~ Verbosity now a global variable, not an environment variable ~ Streamline saving using `scripts/utils/utils.tcl:run_openroad_script`: new `-save` option added that will automatically handle setting and unsetting `SAVE_` variables and `CURRENT_` variables ~ Rewrite Diode Insertion Strategy 3 iterations to be readable by human beings ~ `scripts/tcl_commands/all.tcl:heal_antenna_violators` now only uses `CURRENT_DEF` ~ `scripts/tcl_commands/all.tcl:set_netlist` updated to support flags and arguments properly, `-lec` now only works if `LEC_ENABLE` is set to `1`. Invocations updated ~ Usage of `scripts/tcl_commands/all.tcl:trim_lib` updated: no longer has any optional arguments. Documentation updated. ~ `scripts/tcl_commands/all.tcl:write_verilog` now uses `write_views.tcl` with the `-save` option. Documentation updated to reflect the fact it no longer calls `set_netlist`. ~ Fix various python invocations ~ Move `scripts/tcl_commands/routing.tcl:gen_pdn` to `floorplan` ~ Update `scripts/or_issue.py` to handle `odb` inputs and outputs ~ Update `scripts/tcl_commands/lvs.tcl:write_powered_verilog`, `scripts/tcl_commands/routing.tcl:power_routing` to use `-odb` as an input instead of `-def` (and, if applicable, `-output_odb` *alongside* `-output_def`) - Remove various scripts that rely on text manipulation (incl. `scripts/simple_cts.py`- thank you for your service) - Remove vestiges of site widening - Remove `-canonical` optional from `scripts/tcl_commands/all.tcl:write_verilog` (dubious/undocumented utility) - Remove `verilog_to_verilogPower` (unused) - Remove `zeroize_origin_lef` - Remove `PREV_NETLIST` variable - Remove various invocations of `scripts/tcl_commands/utils.tcl:write_verilog`, replace with `-save` arguments ## OpenROAD Scripts + Create OpenROAD script `common` folder, isolating common code into a folder instead of the preceding chaos + OpenROAD scripts now use a unified script for reading and writing views: `scripts/openroad/common/io.tcl`: `read` reads the `.odb` database + relevant liberty and sdc files and `write` writes any views specified as `SAVE_` variables: see the file for documentation ~ Update Copyright & Licensing for all OpenROAD scripts ~ Rewrite `scripts/odbpy/defutil.py:merge_components` to use odb ~ `scripts/odbpy/defutil.py:replace_pins` -> `relocate_pins`, with a partial rewrite and re-documentation. ~ `scripts/odbpy/defutil.py:add_def_obstructions` -> `add_obstructions` ~ `scripts/openroad/write_verilog.tcl` -> `write_view.tcl`, since it is literally just a "read" and a "write" call now ~ Partially rewrite `scripts/odbpy/power_utils.py:write_powered_def`, the most disgusting function in the codebase - Remove `scripts/odbpy/defutil.py:merge_pins` (unused)
266 lines
7.4 KiB
Python
Executable File
266 lines
7.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# Copyright 2021 Efabless Corporation
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# 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.
|
|
|
|
# Note to maintainers/contributors:
|
|
#
|
|
# Ensure you don't use f strings, non-comment type hints or any other features
|
|
# that wouldn't work on Python 3.3
|
|
#
|
|
# Inevitably, some people won't read the Readme and then complain that the issue
|
|
# survey doesn't work on their older Python versions. As long as it's compatible
|
|
# with Python 3.3, this script will tell them that their python version is
|
|
# below the minimum supported.
|
|
|
|
import io
|
|
import os
|
|
import sys
|
|
import getpass
|
|
import textwrap
|
|
import subprocess
|
|
from os.path import abspath, dirname
|
|
|
|
openlane_dir = dirname(abspath(__file__))
|
|
is_root = os.geteuid() == 0
|
|
|
|
# Commands
|
|
def tool_list():
|
|
from dependencies.tool import Tool
|
|
|
|
tools = Tool.from_metadata_yaml(open("./dependencies/tool_metadata.yml").read())
|
|
for tool in tools.values():
|
|
print("%s %s" % (tool.name, tool.version_string))
|
|
|
|
|
|
def local_install():
|
|
from dependencies.installer import Installer
|
|
|
|
installer = Installer()
|
|
installer.run()
|
|
|
|
|
|
def docker_config():
|
|
from dependencies.env_info import ContainerInfo
|
|
|
|
cinfo = ContainerInfo.get()
|
|
if cinfo is None:
|
|
raise Exception("No container engine found.")
|
|
|
|
if cinfo.engine == "docker":
|
|
if cinfo.rootless:
|
|
print("-u 0", end="")
|
|
else:
|
|
uid = (
|
|
subprocess.check_output(["id", "-u", getpass.getuser()])
|
|
.decode("utf8")
|
|
.strip()
|
|
)
|
|
gid = (
|
|
subprocess.check_output(["id", "-g", getpass.getuser()])
|
|
.decode("utf8")
|
|
.strip()
|
|
)
|
|
print("--user %s:%s" % (uid, gid), end="")
|
|
|
|
|
|
def issue_survey():
|
|
sys.path.append(os.path.dirname(__file__))
|
|
from dependencies.env_info import OSInfo
|
|
from dependencies.version import parse as vp
|
|
|
|
alerts = open(os.devnull, "w")
|
|
|
|
final_report = ""
|
|
|
|
os_info = OSInfo.get()
|
|
final_report += textwrap.dedent(
|
|
"""\
|
|
Kernel: %s v%s
|
|
"""
|
|
% (os_info.kernel, os_info.kernel_version)
|
|
)
|
|
|
|
if os_info.distro is not None:
|
|
final_report += textwrap.dedent(
|
|
"""\
|
|
Distribution: %s %s
|
|
"""
|
|
% (os_info.distro, (os_info.distro_version or ""))
|
|
)
|
|
|
|
python_version = vp(os_info.python_version)
|
|
minimum_python_version = vp("3.6")
|
|
python_message = "OK"
|
|
python_ok = True
|
|
if python_version < minimum_python_version:
|
|
python_message = "BELOW MINIMUM: UPDATE PYTHON"
|
|
python_ok = False
|
|
|
|
final_report += textwrap.dedent(
|
|
"""\
|
|
Python: v%s (%s)
|
|
"""
|
|
% (python_version, python_message)
|
|
)
|
|
|
|
if os_info.container_info is not None:
|
|
container_version = vp(os_info.container_info.version)
|
|
|
|
container_message = "UNSUPPORTED"
|
|
if "docker" in os_info.container_info.engine:
|
|
container_message = "OK"
|
|
minimum_docker_version = vp("19.03.12")
|
|
if container_version < minimum_docker_version:
|
|
container_message = "BELOW MINIMUM: UPDATE DOCKER"
|
|
|
|
final_report += textwrap.dedent(
|
|
"""\
|
|
Container Engine: %s v%s (%s)
|
|
"""
|
|
% (os_info.container_info.engine, container_version, container_message)
|
|
)
|
|
elif os.path.exists(
|
|
"/git_version"
|
|
): # i.e. if running inside the OpenLane container
|
|
print("Alert: Running in container.", file=alerts)
|
|
final_report = (
|
|
textwrap.dedent(
|
|
"""\
|
|
WARNING: issue-survey appears to be running inside the OpenLane
|
|
container.
|
|
|
|
This makes it difficult to rule out issues with your
|
|
environment.
|
|
|
|
Unless instructed specifically to do so, please run this command
|
|
outside the OpenLane container.
|
|
---\n
|
|
"""
|
|
)
|
|
+ final_report
|
|
)
|
|
else:
|
|
alert = (
|
|
"Critical Alert: No Docker or Docker-compatible container engine was found."
|
|
)
|
|
final_report += "%s\n" % alert
|
|
print(alert, file=alerts)
|
|
|
|
if python_ok:
|
|
from dependencies.get_tag import get_tag
|
|
|
|
final_report += textwrap.dedent(
|
|
"""\
|
|
OpenLane Git Version: %s
|
|
"""
|
|
% get_tag()
|
|
)
|
|
|
|
pip_ok = True
|
|
try:
|
|
import pip # noqa F401
|
|
except ImportError:
|
|
pip_ok = False
|
|
|
|
alert = (
|
|
"pip: " + "INSTALLED"
|
|
if pip_ok
|
|
else "NOT FOUND: Please install pip using your operating system's package manager."
|
|
)
|
|
|
|
final_report += "%s\n" % alert
|
|
print(alert, file=alerts)
|
|
|
|
if pip_ok:
|
|
venv_ok = True
|
|
try:
|
|
import venv # noqa F401
|
|
except ImportError:
|
|
venv_ok = False
|
|
|
|
alert = (
|
|
"python-venv: " + "INSTALLED"
|
|
if venv_ok
|
|
else "NOT FOUND: Please install python-venv using your operating system's package manager."
|
|
)
|
|
final_report += "%s\n" % alert
|
|
print(alert, file=alerts)
|
|
|
|
if python_ok:
|
|
from dependencies.verify_versions import verify_versions
|
|
|
|
with io.StringIO() as f:
|
|
status = "OK"
|
|
try:
|
|
mismatches = verify_versions(
|
|
no_tools=True, report_file=f, pdk=os.getenv("PDK") or "sky130A"
|
|
)
|
|
if mismatches:
|
|
status = "MISMATCH"
|
|
except Exception:
|
|
status = "FAILED"
|
|
f.write("Failed to verify sky130A.")
|
|
f.write("\n")
|
|
final_report += "---\nPDK Version Verification Status: %s\n%s" % (
|
|
status,
|
|
f.getvalue(),
|
|
)
|
|
|
|
try:
|
|
git_log = subprocess.check_output(
|
|
[
|
|
"git",
|
|
"log",
|
|
r"--format=%h %cI %s - %an - %gs (%D)",
|
|
"-n",
|
|
"3",
|
|
]
|
|
).decode("utf8")
|
|
|
|
final_report += "---\nGit Log (Last 3 Commits)\n\n" + git_log
|
|
|
|
remotes = subprocess.check_output(["git", "remote", "-v", "show"]).decode(
|
|
"utf8"
|
|
)
|
|
|
|
final_report += "---\nGit Remotes\n\n" + remotes
|
|
except subprocess.CalledProcessError:
|
|
pass
|
|
|
|
print(final_report, end="")
|
|
|
|
|
|
# Entry Point
|
|
def main():
|
|
args = sys.argv[1:]
|
|
commands = {
|
|
"tool-list": tool_list,
|
|
"local-install": local_install,
|
|
"docker-config": docker_config,
|
|
"issue-survey": issue_survey,
|
|
}
|
|
|
|
if len(args) < 1 or args[0] not in commands.keys():
|
|
print(
|
|
"Usage: %s (%s)" % (sys.argv[0], "|".join(commands.keys())), file=sys.stderr
|
|
)
|
|
sys.exit(os.EX_USAGE)
|
|
|
|
commands[args[0]]()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|