mirror of
https://github.com/The-OpenROAD-Project/OpenLane.git
synced 2026-05-29 00:23:55 +08:00
Versioning Improvements (#510)
* Get OpenLane version * Remove OpenPhySyn and Antmicro Yosys * Time-based tag names, current -> latest * Made local installer comply with new versioning scheme * Made Docker Get Commit/Repo Info From YAML file ~ Updater now also updates just the YAML file ~ Main makefile PDK option also consults the YAML file ~ Updated CI to reflect the above changes + reduce redundancy (Cleanup and Deploy Folded) * CI Bugfix * One Final CI Fix
This commit is contained in:
32
.github/scripts/generate_tag.py
vendored
32
.github/scripts/generate_tag.py
vendored
@@ -15,6 +15,7 @@
|
||||
# limitations under the License.
|
||||
import re
|
||||
import os
|
||||
import datetime
|
||||
import subprocess
|
||||
from gh import gh
|
||||
|
||||
@@ -22,24 +23,14 @@ new_tag = "NO_NEW_TAG"
|
||||
|
||||
print("Getting latest release index…")
|
||||
|
||||
lri = None
|
||||
for tag in gh.openlane.tags:
|
||||
_, name = tag
|
||||
if "release-" in name:
|
||||
relevant_component = name.split("-")[1]
|
||||
lri = relevant_component.split(".")[0]
|
||||
print("Getting the latest tag…")
|
||||
|
||||
prefix = lri if lri is not None else "v0"
|
||||
|
||||
print("Using prefix %s, getting the latest tag…" % prefix)
|
||||
|
||||
latest_tag = "%s.0" % prefix # Base case: Will create prefix.1
|
||||
latest_tag_commit = "dad497fccc1b48f4f16e570b0214b6f0e1fc2f9b" # Base case: First commit, always > 2
|
||||
latest_tag = None
|
||||
latest_tag_commit = None
|
||||
for tag in gh.openlane.tags:
|
||||
commit, name = tag
|
||||
if name.startswith(prefix):
|
||||
latest_tag = name
|
||||
latest_tag_commit = commit
|
||||
latest_tag = name
|
||||
latest_tag_commit = commit
|
||||
|
||||
commit_count = int(subprocess.check_output(["git", "rev-list", "--count", "%s..%s" % (latest_tag_commit, "HEAD")]))
|
||||
|
||||
@@ -48,14 +39,9 @@ if commit_count == 0:
|
||||
gh.export_env("NEW_TAG", "NO_NEW_TAG")
|
||||
exit(0)
|
||||
|
||||
new_tag = None
|
||||
if not latest_tag.startswith("v"):
|
||||
new_tag = "%s.1" % prefix
|
||||
print("Last tag (%s) lacked a v, replacing with %s…" % (latest_tag, new_tag))
|
||||
else:
|
||||
current = int(latest_tag.split(".")[1])
|
||||
new = current + 1
|
||||
new_tag = "%s.%i" % (prefix, new)
|
||||
now = datetime.datetime.now()
|
||||
|
||||
new_tag = now.strftime("%Y.%m.%d_%H.%M.%S")
|
||||
|
||||
print("Naming new tag %s." % new_tag)
|
||||
gh.export_env("NEW_TAG", new_tag)
|
||||
16
.github/scripts/gh.py
vendored
16
.github/scripts/gh.py
vendored
@@ -93,17 +93,7 @@ class Repo(object):
|
||||
tags.append((hash, name))
|
||||
self._tags = tags
|
||||
return self._tags
|
||||
|
||||
# Helper Functions
|
||||
def match_branch(self, line):
|
||||
match = re.match(self.branch_rx, line)
|
||||
if match is not None:
|
||||
return match[1]
|
||||
|
||||
def match_line(self, line):
|
||||
match = re.match(self.extraction_rx, line)
|
||||
if match is not None:
|
||||
return match[1]
|
||||
|
||||
|
||||
def out_of_date(self):
|
||||
return self.commit != self.latest_commit
|
||||
@@ -132,8 +122,8 @@ if os.getenv("GITHUB_ACTIONS") != "true":
|
||||
|
||||
export_env = export_env_alt
|
||||
|
||||
if os.getenv("TOOL") is None or os.getenv("PDK_ROOT") is None:
|
||||
print("Environment variables \"TOOL\" and \"PDK_ROOT\" are required.")
|
||||
if os.getenv("PDK_ROOT") is None:
|
||||
print("Environment variables required: \"PDK_ROOT\"")
|
||||
exit(os.EX_CONFIG)
|
||||
|
||||
origin = os.getenv("REPO_URL")
|
||||
|
||||
49
.github/scripts/update_common.py
vendored
49
.github/scripts/update_common.py
vendored
@@ -1,49 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2020 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.
|
||||
import re
|
||||
from gh import gh
|
||||
|
||||
def process_update_on_repos(repos, files):
|
||||
changed = False
|
||||
for repo in repos:
|
||||
print("Processing %s…" % repo.name)
|
||||
if not repo.out_of_date():
|
||||
print("%s's commit is already on latest. No action required." % repo.name)
|
||||
continue
|
||||
|
||||
# print("Checking if branch was already created…")
|
||||
# branch_commit = None
|
||||
# for branch in gh.openlane.branches:
|
||||
# _, name = branch
|
||||
# branch_commit = repo.match_branch(name) or branch_commit
|
||||
|
||||
# if branch_commit is not None and branch_commit == repo.latest_commit:
|
||||
# print("Branch was already created for the latest commit. No update required.")
|
||||
# continue
|
||||
|
||||
# if branch_commit is not None:
|
||||
# print("Branch is out of date. Updating…")
|
||||
# else:
|
||||
# print("No matching branch found. Updating…")
|
||||
|
||||
changed = True
|
||||
|
||||
for file in files:
|
||||
fstr = open(file).read()
|
||||
new_fstr = re.sub(repo.commit, repo.latest_commit, fstr)
|
||||
with open(file, 'w') as f:
|
||||
f.write(new_fstr)
|
||||
return changed
|
||||
51
.github/scripts/update_pdk.py
vendored
51
.github/scripts/update_pdk.py
vendored
@@ -1,51 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2020 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.
|
||||
import re
|
||||
import os
|
||||
import subprocess
|
||||
from gh import gh
|
||||
from update_common import process_update_on_repos
|
||||
|
||||
makefile = os.path.join(gh.root, "Makefile")
|
||||
documentation = os.path.join(gh.root, "docs", "source", "Manual_PDK_installation.md")
|
||||
print("Reading Makefile…")
|
||||
|
||||
skywater = gh.Repo(
|
||||
"Skywater PDK",
|
||||
"https://github.com/google/skywater-pdk.git",
|
||||
r"refs/heads/CID\-latest\-pdk(?:\-(\w+)-(?:\w+))?",
|
||||
r"SKYWATER_COMMIT\s*\?=\s*(\w+)"
|
||||
)
|
||||
|
||||
open_pdks = gh.Repo(
|
||||
"Open PDKs",
|
||||
"https://github.com/rtimothyedwards/open_pdks",
|
||||
r"refs/heads/CID\-latest\-pdk(?:\-(?:\w+)-(\w+))?",
|
||||
r"OPEN_PDKS_COMMIT\s*\?=\s*(\w+)"
|
||||
)
|
||||
|
||||
with open(makefile) as f:
|
||||
for line in f:
|
||||
skywater.commit = skywater.match_line(line) or skywater.commit
|
||||
open_pdks.commit = open_pdks.match_line(line) or open_pdks.commit
|
||||
|
||||
print("Found %s:%s. (latest: %s)" % (skywater.url, skywater.commit, skywater.latest_commit))
|
||||
print("Found %s:%s. (latest: %s)" % (open_pdks.url, open_pdks.commit, open_pdks.latest_commit))
|
||||
|
||||
changed = process_update_on_repos([skywater, open_pdks], [makefile, documentation])
|
||||
gh.export_env("SKYWATER_COMMIT_HASH", skywater.latest_commit)
|
||||
gh.export_env("OPEN_PDKS_COMMIT_HASH", open_pdks.latest_commit)
|
||||
gh.export_env("NO_UPDATE", "false" if changed else "true")
|
||||
46
.github/scripts/update_tool.py
vendored
46
.github/scripts/update_tool.py
vendored
@@ -1,46 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2020 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.
|
||||
import re
|
||||
import os
|
||||
import subprocess
|
||||
from gh import gh
|
||||
from update_common import process_update_on_repos
|
||||
|
||||
dockerfile = os.path.join(gh.root, "docker_build", "docker", gh.tool, "Dockerfile")
|
||||
print("Reading Dockerfile %s…" % dockerfile)
|
||||
repo = None
|
||||
commit = None
|
||||
repo_rx = r"ARG\s+(?:\w+?)_REPO\s*=\s*([^\s]+)"
|
||||
commit_rx = r"ARG\s+(?:\w+?)_COMMIT\s*=\s*([^\s]+)"
|
||||
with open(dockerfile) as f:
|
||||
for line in f:
|
||||
repo_match = re.match(repo_rx, line)
|
||||
if repo_match is not None:
|
||||
repo = repo_match[1]
|
||||
commit_match = re.match(commit_rx, line)
|
||||
if commit_match is not None:
|
||||
commit = commit_match[1]
|
||||
|
||||
tool = gh.Repo(
|
||||
gh.tool, repo, r"refs/heads/CID\-latest\-tools\-%s(?:\-(\w+))?" % gh.tool
|
||||
)
|
||||
tool.commit = commit
|
||||
|
||||
print("Found %s@%s (latest: %s)." % (tool.url, tool.commit, tool.latest_commit))
|
||||
|
||||
changed = process_update_on_repos([tool], [dockerfile])
|
||||
gh.export_env("TOOL_COMMIT_HASH", tool.latest_commit)
|
||||
gh.export_env("NO_UPDATE", "false" if changed else "true")
|
||||
70
.github/scripts/update_tools.py
vendored
Normal file
70
.github/scripts/update_tools.py
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2020 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.
|
||||
import os
|
||||
import sys
|
||||
import yaml
|
||||
import argparse
|
||||
from gh import gh
|
||||
|
||||
dependencies_path = os.path.join(gh.root, "dependencies")
|
||||
metadata_path = os.path.join(dependencies_path, "tool_metadata.yml")
|
||||
|
||||
sys.path.append(dependencies_path)
|
||||
|
||||
from tool import Tool
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("tools", nargs="+")
|
||||
args = parser.parse_args()
|
||||
|
||||
tools = Tool.from_metadata_yaml(open(metadata_path).read())
|
||||
|
||||
# Handle Multiline Strings Properly / https://stackoverflow.com/a/33300001
|
||||
def represent_str(dumper: yaml.Dumper, data: str):
|
||||
if "\n" in data:
|
||||
return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='|')
|
||||
return dumper.represent_scalar('tag:yaml.org,2002:str', data)
|
||||
yaml.add_representer(str, represent_str)
|
||||
dump_options = { 'sort_keys': False }
|
||||
|
||||
changes = False
|
||||
for tool_name in args.tools:
|
||||
tool = tools[tool_name]
|
||||
|
||||
repo = gh.Repo(
|
||||
tool_name, tool.repo
|
||||
)
|
||||
repo.commit = tool.commit
|
||||
|
||||
print("Found %s@%s (latest: %s)." % (repo.url, repo.commit, repo.latest_commit))
|
||||
|
||||
if repo.commit != repo.latest_commit:
|
||||
changes = True
|
||||
metadata_str = open(metadata_path).read()
|
||||
metadata = yaml.safe_load(metadata_str)
|
||||
for tool in metadata:
|
||||
if tool['name'] == tool_name:
|
||||
tool['commit'] = repo.latest_commit
|
||||
metadata_str = yaml.dump(metadata, **dump_options)
|
||||
with open(metadata_path, "w") as f:
|
||||
f.write(metadata_str)
|
||||
|
||||
if len(args.tools) == 1:
|
||||
gh.export_env("TOOL_COMMIT_HASH", repo.latest_commit)
|
||||
else:
|
||||
gh.export_env(f"{tool_name.upper()}_COMMIT_HASH", repo.latest_commit)
|
||||
|
||||
gh.export_env("NO_UPDATE", "0" if changes else "1")
|
||||
44
.github/workflows/openlane_ci.yml
vendored
44
.github/workflows/openlane_ci.yml
vendored
@@ -127,21 +127,19 @@ jobs:
|
||||
env:
|
||||
TEST_SET: completeTestSet${{ matrix.testset }}
|
||||
run: cd ${GITHUB_WORKSPACE}/ && python3 ${GITHUB_WORKSPACE}/.github/scripts/run_tests.py
|
||||
cleanup:
|
||||
needs: test
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Delete Artifact
|
||||
uses: geekyeggo/delete-artifact@v1
|
||||
with:
|
||||
name: docker-image
|
||||
deploy:
|
||||
cleanup_and_deploy:
|
||||
name: Cleanup (and Possibly Deployment)
|
||||
needs: test
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check If Going To Push An Image To Docker
|
||||
# Ruby snippet to print 0 if this is a PR or if there is no DOCKERHUB_USER secret set, otherwise, 1
|
||||
run: |
|
||||
export PUSHING=$(ruby -e 'if ("${{ github.event_name }}" != "pull_request" && "${{ secrets.DOCKERHUB_USER }}" != ""); print(1) else print(0) end')
|
||||
echo "PUSHING=$PUSHING" >> $GITHUB_ENV
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
if: ${{ env.PUSHING == '1' }}
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -167,6 +165,7 @@ jobs:
|
||||
run: echo "IMAGE_NAME=openlane:intermediate" >> $GITHUB_ENV
|
||||
|
||||
- name: Download Docker Image
|
||||
if: ${{ env.PUSHING == '1' }}
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: docker-image
|
||||
@@ -178,43 +177,42 @@ jobs:
|
||||
name: docker-image
|
||||
|
||||
- name: Import Docker Image
|
||||
if: ${{ env.PUSHING == '1' }}
|
||||
run: docker load --input /tmp/image.tar
|
||||
|
||||
- name: Write Main Branch
|
||||
if: ${{ env.PUSHING == '1' }}
|
||||
run: |
|
||||
echo "MAIN_BRANCH=${{ secrets.MAIN_BRANCH }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Create Tag (If scheduled or dispatched)
|
||||
if: ${{ (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && env.BRANCH_NAME == env.MAIN_BRANCH }}
|
||||
if: ${{ env.PUSHING == '1' && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && env.BRANCH_NAME == env.MAIN_BRANCH }}
|
||||
run: cd ${GITHUB_WORKSPACE}/ && python3 ${GITHUB_WORKSPACE}/.github/scripts/generate_tag.py
|
||||
|
||||
- name: Tag Commit (If scheduled or dispatched)
|
||||
if: ${{ (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && env.NEW_TAG != 'NO_NEW_TAG' }}
|
||||
if: ${{ env.PUSHING == '1' && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && env.NEW_TAG != 'NO_NEW_TAG' }}
|
||||
uses: tvdias/github-tagger@v0.0.1
|
||||
with:
|
||||
tag: "${{ env.NEW_TAG }}"
|
||||
repo-token: "${{ secrets.MY_TOKEN }}"
|
||||
|
||||
- name: Login to DockerHub
|
||||
if: ${{ env.PUSHING == '1' }}
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USER }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Docker Push (Branch Name)
|
||||
if: ${{ env.PUSHING == '1' }}
|
||||
run: |
|
||||
TAG=${{ env.BRANCH_NAME }}
|
||||
if [ "$TAG" = "${{ secrets.MAIN_BRANCH }}" ]; then
|
||||
TAG=latest
|
||||
fi
|
||||
|
||||
docker image tag ${{ env.IMAGE_NAME }} ${{ secrets.DOCKER_IMAGE }}:$TAG
|
||||
docker push ${{ secrets.DOCKER_IMAGE }}:$TAG
|
||||
docker image tag ${{ env.IMAGE_NAME }} ${{ secrets.DOCKER_IMAGE }}:${{ env.BRANCH_NAME }}
|
||||
docker push ${{ secrets.DOCKER_IMAGE }}:${{ env.BRANCH_NAME }}
|
||||
|
||||
- name: Docker Push (Tag) (If scheduled or dispatched)
|
||||
if: ${{ (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && env.NEW_TAG != 'NO_NEW_TAG' }}
|
||||
if: ${{ env.PUSHING == '1' && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && env.NEW_TAG != 'NO_NEW_TAG' }}
|
||||
run: |
|
||||
docker image tag ${{ env.IMAGE_NAME }} ${{ secrets.DOCKER_IMAGE }}:${{ env.NEW_TAG }}
|
||||
docker image tag ${{ env.IMAGE_NAME }} ${{ secrets.DOCKER_IMAGE }}:current
|
||||
docker image tag ${{ env.IMAGE_NAME }} ${{ secrets.DOCKER_IMAGE }}:latest
|
||||
docker push ${{ secrets.DOCKER_IMAGE }}:${{ env.NEW_TAG }}
|
||||
docker push ${{ secrets.DOCKER_IMAGE }}:current
|
||||
docker push ${{ secrets.DOCKER_IMAGE }}:latest
|
||||
|
||||
12
.github/workflows/tool_updater.yml
vendored
12
.github/workflows/tool_updater.yml
vendored
@@ -40,14 +40,14 @@ jobs:
|
||||
run: echo "TOOL=${{ matrix.tools }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Update TOOL
|
||||
run: cd ${GITHUB_WORKSPACE}/ && python3 ${GITHUB_WORKSPACE}/.github/scripts/update_tool.py
|
||||
run: cd ${GITHUB_WORKSPACE}/ && python3 ${GITHUB_WORKSPACE}/.github/scripts/update_tools.py ${{ env.TOOL }}
|
||||
|
||||
- name: Build TOOL
|
||||
if: ${{ env.NO_UPDATE == 'false' }}
|
||||
if: ${{ env.NO_UPDATE != '1' }}
|
||||
run: cd ${GITHUB_WORKSPACE}/docker_build && make build-${{ env.TOOL }}
|
||||
|
||||
- name: Create Pull Request
|
||||
if: ${{ env.NO_UPDATE == 'false' }}
|
||||
if: ${{ env.NO_UPDATE != '1' }}
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
with:
|
||||
token: ${{ secrets.MY_TOKEN }}
|
||||
@@ -82,10 +82,10 @@ jobs:
|
||||
ref: ${{ secrets.MAIN_BRANCH }}
|
||||
|
||||
- name: Update PDK
|
||||
run: python3 ${GITHUB_WORKSPACE}/.github/scripts/update_pdk.py
|
||||
run: python3 ${GITHUB_WORKSPACE}/.github/scripts/update_tools.py sky130 open_pdks
|
||||
|
||||
- name: Create Pull Request
|
||||
if: ${{ env.NO_UPDATE == 'false' }}
|
||||
if: ${{ env.NO_UPDATE != '1' }}
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
with:
|
||||
token: ${{ secrets.MY_TOKEN }}
|
||||
@@ -97,7 +97,7 @@ jobs:
|
||||
commit-message: |
|
||||
[BOT] Update PDK
|
||||
|
||||
sky130 -> ${{ env.SKYWATER_COMMIT_HASH }}
|
||||
sky130 -> ${{ env.SKY130_COMMIT_HASH }}
|
||||
open_pdks -> ${{ env.OPEN_PDKS_COMMIT_HASH }}
|
||||
base: ${{ env.BRANCH_NAME }}
|
||||
branch: pdk-update-branch
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -29,3 +29,6 @@ default.cvcrc
|
||||
|
||||
# PDK
|
||||
pdks/
|
||||
|
||||
# Misc
|
||||
/resolved_version
|
||||
11
Makefile
11
Makefile
@@ -48,7 +48,8 @@ SPECIAL_VOLTAGE_LIBRARY ?= sky130_fd_sc_hvl
|
||||
IO_LIBRARY ?= sky130_fd_io
|
||||
INSTALL_SRAM ?= disabled
|
||||
|
||||
IMAGE_NAME ?= efabless/openlane:current
|
||||
CURRENT_TAG ?= $(shell python3 ./get_tag.py)
|
||||
IMAGE_NAME ?= efabless/openlane:$(CURRENT_TAG)
|
||||
TEST_DESIGN ?= spm
|
||||
DESIGN_LIST ?= spm
|
||||
BENCHMARK ?= regression_results/benchmark_results/SW_HD.csv
|
||||
@@ -57,8 +58,8 @@ FASTEST_TEST_SET_TAG ?= FASTEST_TEST_SET
|
||||
COMPLETE_TEST_SET_TAG ?= COMPLETE_TEST_SET
|
||||
PRINT_REM_DESIGNS_TIME ?= 0
|
||||
|
||||
SKYWATER_COMMIT ?= 00bdbcf4a3aa922cc1f4a0d0cd8b80dbd73149d3
|
||||
OPEN_PDKS_COMMIT ?= 1d93a6bd9d6e481acfdf88f26aa3bb0600303d98
|
||||
SKYWATER_COMMIT ?= $(shell python3 ./dependencies/tool.py sky130 -f commit)
|
||||
OPEN_PDKS_COMMIT ?= $(shell python3 ./dependencies/tool.py open_pdks -f commit)
|
||||
|
||||
ENV_COMMAND ?= docker run --rm -v $(OPENLANE_DIR):/openLANE_flow -v $(PDK_ROOT):$(PDK_ROOT) -e PDK_ROOT=$(PDK_ROOT) $(DOCKER_UID_OPTIONS) $(IMAGE_NAME)
|
||||
|
||||
@@ -87,7 +88,7 @@ $(PDK_ROOT)/:
|
||||
mkdir -p $(PDK_ROOT)
|
||||
|
||||
$(PDK_ROOT)/skywater-pdk:
|
||||
git clone https://github.com/google/skywater-pdk.git $(PDK_ROOT)/skywater-pdk
|
||||
git clone $(shell python3 ./dependencies/tool.py sky130 -f repo) $(PDK_ROOT)/skywater-pdk
|
||||
|
||||
.PHONY: skywater-pdk
|
||||
skywater-pdk: $(PDK_ROOT)/ $(PDK_ROOT)/skywater-pdk
|
||||
@@ -117,7 +118,7 @@ all-skywater-libraries: skywater-pdk
|
||||
|
||||
### OPEN_PDKS
|
||||
$(PDK_ROOT)/open_pdks:
|
||||
git clone https://github.com/rtimothyedwards/open_pdks $(PDK_ROOT)/open_pdks
|
||||
git clone $(shell python3 ./dependencies/tool.py open_pdks -f repo) $(PDK_ROOT)/open_pdks
|
||||
|
||||
.PHONY: open_pdks
|
||||
open_pdks: $(PDK_ROOT)/ $(PDK_ROOT)/open_pdks
|
||||
|
||||
13
README.md
13
README.md
@@ -31,7 +31,12 @@ This documentation is also available at [ReadTheDocs](https://openlane.readthedo
|
||||
- [Videos And Tutorials](#videos-and-tutorials)
|
||||
|
||||
# Prerequisites
|
||||
At a minimum:
|
||||
|
||||
- Docker 19.03.12+
|
||||
- GNU Make
|
||||
- Python 3.6+ with PIP
|
||||
- Pyyaml: `pip3 install pyyaml`
|
||||
|
||||
## Dockerless Install
|
||||
Please see [LOCAL_INSTALL.md](./LOCAL_INSTALL.md).
|
||||
@@ -44,7 +49,6 @@ You can start setting up the Sky130 PDK and OpenLane by running:
|
||||
cd openlane/
|
||||
make openlane
|
||||
```
|
||||
* Note that `make openlane` always pulls the **latest** version of OpenLane: to get a specific tag, you need to invoke `IMAGE_NAME=efabless/openlane:v0.18 make openlane`, for example.
|
||||
|
||||
---
|
||||
|
||||
@@ -119,7 +123,7 @@ To setup OpenLane you can pull the Docker container by following these instructi
|
||||
|
||||
```bash
|
||||
git clone https://github.com/The-OpenROAD-Project/OpenLane.git
|
||||
docker pull efabless/openlane:current
|
||||
make openlane
|
||||
```
|
||||
For curious users: For more details about the docker container and its process, the [following instructions][1] walk you through the process of using docker containers to build the needed tools then integrate them into OpenLane flow. **You Don't Need To Re-Build It.**
|
||||
|
||||
@@ -359,8 +363,7 @@ OpenLane flow consists of several stages. By default all flow steps are run in s
|
||||
3. **Placement**
|
||||
1. `RePLace` - Performs global placement
|
||||
2. `Resizer` - Performs optional optimizations on the design
|
||||
3. `OpenPhySyn` - Performs timing optimizations on the design
|
||||
4. `OpenDP` - Perfroms detailed placement to legalize the globally placed components
|
||||
3. `OpenDP` - Perfroms detailed placement to legalize the globally placed components
|
||||
4. **CTS**
|
||||
1. `TritonCTS` - Synthesizes the clock distribution network (the clock tree)
|
||||
5. **Routing**
|
||||
@@ -381,7 +384,7 @@ OpenLane integrated several key open source tools over the execution stages:
|
||||
- RTL Synthesis, Technology Mapping, and Formal Verification : [yosys + abc][4]
|
||||
- Static Timing Analysis: [OpenSTA][8]
|
||||
- Floor Planning: [init_fp][5], [ioPlacer][6], [pdn][16] and [tapcell][7]
|
||||
- Placement: [RePLace][9] (Global), [Resizer][15] and [OpenPhySyn][28] (Optimizations), and [OpenDP][10] (Detailed)
|
||||
- Placement: [RePLace][9] (Global), [Resizer][15] and [OpenPhySyn][28] (formerly), and [OpenDP][10] (Detailed)
|
||||
- Clock Tree Synthesis: [TritonCTS][11]
|
||||
- Fill Insertion: [OpenDP/filler_placement][10]
|
||||
- Routing: [FastRoute][12] or [CU-GR][36] (Global) and [TritonRoute][13] (Detailed)
|
||||
|
||||
@@ -103,9 +103,6 @@ These variables are optional that can be specified in the design configuration f
|
||||
| `PL_RANDOM_GLB_PLACEMENT` | Specifies whether the placer should run random placement or not. This is useful if the design is tiny (less than 100 cells). 0 = false, 1 = true <br> (Default: `0`) |
|
||||
| `PL_RANDOM_INITIAL_PLACEMENT` | Specifies whether the placer should run random placement or not followed by replace's initial placement. This is useful if the design is tiny (less than 100 cells). 0 = false, 1 = true <br> (Default: `0`) |
|
||||
| `PL_ROUTABILITY_DRIVEN` | Specifies whether the placer should use routability driven placement. 0 = false, 1 = true <br> (Default: `0`) |
|
||||
| `PL_OPENPHYSYN_OPTIMIZATIONS` | Specifies whether OpenPhySyn should be used to perform timing optimizations or not. 0 = false, 1 = true <br> (Default: `0`) |
|
||||
| `PSN_ENABLE_RESIZING` | Enables driver resizing by OpenPhySyn. 0 = Disabled, 1 = Enabled <br> (Default: `1`)|
|
||||
| `PSN_ENABLE_PIN_SWAP` | Enables pin swapping for timing optimization by OpenPhySyn. 0 = Disabled, 1 = Enabled <br> (Default: `1`)|
|
||||
| `PL_RESIZER_DESIGN_OPTIMIZATIONS` | Specifies whether resizer design optimizations should be performed or not. 0 = false, 1 = true <br> (Default: `1`) |
|
||||
| `PL_RESIZER_TIMING_OPTIMIZATIONS` | Specifies whether resizer timing optimizations should be performed or not. 0 = false, 1 = true <br> (Default: `1`) |
|
||||
| `PL_RESIZER_MAX_WIRE_LENGTH` | Specifies the maximum wire length cap used by resizer to insert buffers. If set to 0, no buffers will be inserted. Value in microns. <br> (Default: `0`)|
|
||||
|
||||
@@ -20,7 +20,6 @@ set ::env(PL_RANDOM_GLB_PLACEMENT) 0
|
||||
set ::env(PL_BASIC_PLACEMENT) 0
|
||||
set ::env(PL_SKIP_INITIAL_PLACEMENT) 0
|
||||
set ::env(PL_RANDOM_INITIAL_PLACEMENT) 0
|
||||
set ::env(PL_OPENPHYSYN_OPTIMIZATIONS) 0
|
||||
set ::env(PSN_ENABLE_RESIZING) 1
|
||||
set ::env(PSN_ENABLE_PIN_SWAP) 1
|
||||
set ::env(PL_ESTIMATE_PARASITICS) 1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
https://repo.ius.io/ius-release-el7.rpm
|
||||
https://www.klayout.org/downloads/CentOS_7/klayout-0.26.9-0.x86_64.rpm
|
||||
https://www.klayout.org/downloads/CentOS_7/klayout-0.27.3-0.x86_64.rpm
|
||||
|
||||
centos-release-scl
|
||||
devtoolset-8
|
||||
64
dependencies/get_all_yum.rb
vendored
64
dependencies/get_all_yum.rb
vendored
@@ -1,64 +0,0 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# 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.
|
||||
|
||||
# This is a simple script that looks for all the yum packages installed by the
|
||||
# Docker images. It's finicky and will likely require human cleanup for the results.
|
||||
|
||||
# The ubuntu list was manually translated from the results for centos7.
|
||||
|
||||
require 'set'
|
||||
|
||||
dockerfiles = `find ../docker_build | grep Dockerfile`.split("\n")
|
||||
|
||||
yum_packages_set = Set.new
|
||||
|
||||
for file in dockerfiles
|
||||
str = File.read(file)
|
||||
|
||||
entries = str.split("\n")
|
||||
i = 0
|
||||
while i < entries.count
|
||||
if not entries[i].end_with?("\\")
|
||||
i += 1
|
||||
next
|
||||
end
|
||||
eil = entries[i].length
|
||||
entries[i] = entries[i][...eil - 1] + entries[i + 1]
|
||||
entries.delete_at(i + 1)
|
||||
end
|
||||
|
||||
|
||||
for entry in entries
|
||||
|
||||
yum_rx = /\s*yum\s+(?:\-y\s+)?install\s+([^&]+)/
|
||||
matches = entry.scan(yum_rx)
|
||||
if matches.count == 0
|
||||
next
|
||||
end
|
||||
for match in matches
|
||||
packages = match[0].split(/\s+/)
|
||||
yum_packages_set.merge(packages)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
yum_package_list_raw = Array(yum_packages_set).sort
|
||||
yum_package_list = yum_package_list_raw.filter { |p|
|
||||
not p.start_with?("-") and
|
||||
not p.include?("/") and
|
||||
not p.include?(".")
|
||||
}
|
||||
puts yum_package_list
|
||||
1
dependencies/python/compile_time.txt
vendored
Normal file
1
dependencies/python/compile_time.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
cmake
|
||||
8
dependencies/python/run_time.txt
vendored
Normal file
8
dependencies/python/run_time.txt
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
click
|
||||
pyyaml
|
||||
pyinstaller
|
||||
matplotlib
|
||||
jinja2<3.0.0
|
||||
pandas
|
||||
install
|
||||
XlsxWriter
|
||||
4
dependencies/requirements.txt
vendored
4
dependencies/requirements.txt
vendored
@@ -1,4 +0,0 @@
|
||||
cmake
|
||||
click
|
||||
pyyaml
|
||||
pyinstaller
|
||||
81
dependencies/tool.py
vendored
Normal file
81
dependencies/tool.py
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
# 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.
|
||||
|
||||
import yaml
|
||||
from typing import Dict, List
|
||||
|
||||
class Tool(object):
|
||||
def __init__(self, name, repo, commit, build_script="make && make install", in_install=True, in_container=True):
|
||||
self.name = name
|
||||
self.repo = repo
|
||||
self.commit = commit
|
||||
self.build_script = build_script
|
||||
self.in_install = in_install
|
||||
self.in_container = in_container
|
||||
|
||||
@property
|
||||
def repo_pretty(self):
|
||||
gh_prefix = "https://github.com/"
|
||||
repo = self.repo
|
||||
if repo is not None and repo.startswith(gh_prefix):
|
||||
return repo[len(gh_prefix):]
|
||||
return repo
|
||||
|
||||
@property
|
||||
def version_string(self) -> str:
|
||||
return f"{self.repo or 'None'}:{self.commit or 'None'}"
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<Tool {self.name} (using {self.repo_pretty or 'None'}@{self.commit or 'None'})>"
|
||||
|
||||
@staticmethod
|
||||
def from_metadata_yaml(metadata_yaml: str) -> Dict[str, 'Tool']:
|
||||
final_dict = {}
|
||||
tool_list = yaml.load(metadata_yaml, Loader=yaml.SafeLoader)
|
||||
for tool in tool_list:
|
||||
final_dict[tool['name']] = Tool(
|
||||
name=tool['name'],
|
||||
repo=tool['repo'],
|
||||
commit=tool['commit'],
|
||||
build_script=tool['build'],
|
||||
in_container=tool.get('in_container') or True,
|
||||
in_install=tool.get('in_install') or True
|
||||
)
|
||||
return final_dict
|
||||
|
||||
def main():
|
||||
import os
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description="Get Tool Info")
|
||||
parser.add_argument("--docker-args", action="store_true")
|
||||
parser.add_argument("--field", "-f")
|
||||
parser.add_argument("tool")
|
||||
tools = Tool.from_metadata_yaml(open(os.path.join(os.path.dirname(__file__), "tool_metadata.yml")).read())
|
||||
args = parser.parse_args()
|
||||
|
||||
tool = tools[args.tool]
|
||||
|
||||
if args.docker_args:
|
||||
print(f"--build-arg {tool.name.upper()}_REPO={tool.repo} --build-arg {tool.name.upper()}_COMMIT={tool.commit}", end="")
|
||||
elif args.field:
|
||||
field = tool.__dict__[args.field]
|
||||
print(field, end="")
|
||||
else:
|
||||
print("Either --field or --docker-args is required.")
|
||||
exit(os.EX_USAGE)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
159
dependencies/tool_metadata.py
vendored
159
dependencies/tool_metadata.py
vendored
@@ -1,159 +0,0 @@
|
||||
# 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.
|
||||
|
||||
from typing import Dict
|
||||
|
||||
class Tool(object):
|
||||
map: Dict[str, 'Tool'] = {}
|
||||
|
||||
def __init__(self, name, repo=None, commit=None, install_command="make && make install", skip=False, clone_depth=None):
|
||||
self.name = name
|
||||
self.repo = repo
|
||||
self.commit = commit
|
||||
self.install_command = install_command
|
||||
self.skip = skip
|
||||
self.clone_depth = str(clone_depth) if clone_depth is not None else None
|
||||
Tool.map[self.name] = self
|
||||
|
||||
@property
|
||||
def repo_pretty(self):
|
||||
gh_prefix = "https://github.com/"
|
||||
repo = self.repo
|
||||
if repo is not None and repo.startswith(gh_prefix):
|
||||
return repo[len(gh_prefix):]
|
||||
return repo
|
||||
|
||||
@property
|
||||
def version_string(self):
|
||||
return f"{self.repo or 'None'}:{self.commit or 'None'}"
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<Tool {self.name} (using {self.repo_pretty or 'None'}@{self.commit or 'None'})>"
|
||||
|
||||
|
||||
Tool(
|
||||
"antmicro_yosys",
|
||||
install_command="\
|
||||
make PREFIX=$PREFIX/antmicro config-gcc &&\
|
||||
make PREFIX=$PREFIX/antmicro -j$(nproc) &&\
|
||||
make PREFIX=$PREFIX/antmicro install\
|
||||
",
|
||||
skip=True
|
||||
)
|
||||
|
||||
Tool(
|
||||
"cugr",
|
||||
install_command="\
|
||||
xxd -i src/flute/POST9.dat > src/flute/POST9.c &&\
|
||||
xxd -i src/flute/POWV9.dat > src/flute/POWV9.c &&\
|
||||
rm -rf build/ &&\
|
||||
mkdir -p build/ &&\
|
||||
cd build &&\
|
||||
cmake ../src &&\
|
||||
make -j$(nproc) &&\
|
||||
cp iccad19gr $PREFIX/bin/cugr\
|
||||
"
|
||||
)
|
||||
|
||||
Tool(
|
||||
"cvc",
|
||||
install_command="\
|
||||
autoreconf -i &&\
|
||||
autoconf &&\
|
||||
./configure --disable-nls --prefix=$PREFIX &&\
|
||||
make install\
|
||||
"
|
||||
)
|
||||
|
||||
Tool(
|
||||
"drcu",
|
||||
install_command="\
|
||||
rm -rf build/ &&\
|
||||
mkdir -p build/ &&\
|
||||
cd build &&\
|
||||
cmake ../src &&\
|
||||
make -j$(nproc) &&\
|
||||
cp ispd19dr $PREFIX/bin/drcu\
|
||||
"
|
||||
)
|
||||
|
||||
Tool(
|
||||
"magic",
|
||||
install_command="\
|
||||
./configure --prefix=$PREFIX &&\
|
||||
make -j$(nproc) &&\
|
||||
make install\
|
||||
"
|
||||
)
|
||||
|
||||
Tool(
|
||||
"netgen",
|
||||
install_command="\
|
||||
./configure --prefix=$PREFIX &&\
|
||||
make -j$(nproc) &&\
|
||||
make install\
|
||||
"
|
||||
)
|
||||
|
||||
Tool(
|
||||
"openphysyn",
|
||||
install_command="\
|
||||
mkdir -p ./build &&\
|
||||
cd ./build &&\
|
||||
cmake .. &&\
|
||||
make -DCMAKE_BUILD_TYPE=release -j$(nproc)&&\
|
||||
cp Psn $PREFIX/bin/Psn\
|
||||
",
|
||||
skip=True
|
||||
)
|
||||
|
||||
Tool(
|
||||
"openroad_app",
|
||||
install_command="\
|
||||
mkdir -p ./build &&\
|
||||
cd ./build &&\
|
||||
cmake -DCMAKE_INSTALL_PREFIX=$PREFIX/bin .. &&\
|
||||
make -j$(nproc)\
|
||||
",
|
||||
skip=True
|
||||
)
|
||||
|
||||
Tool(
|
||||
"padring",
|
||||
install_command="\
|
||||
bash ./bootstrap.sh &&\
|
||||
cd build &&\
|
||||
ninja &&\
|
||||
cp padring $PREFIX/bin\
|
||||
"
|
||||
)
|
||||
|
||||
Tool(
|
||||
"qflow", # We just want vlog_to_verilog though
|
||||
install_command="\
|
||||
./configure &&\
|
||||
cd src &&\
|
||||
make -j$(nproc) vlog2Verilog &&\
|
||||
cp vlog2Verilog $PREFIX/bin\
|
||||
"
|
||||
)
|
||||
|
||||
Tool(
|
||||
"yosys",
|
||||
install_command="\
|
||||
make PREFIX=$PREFIX config-gcc &&\
|
||||
make PREFIX=$PREFIX -j$(nproc) &&\
|
||||
make PREFIX=$PREFIX install\
|
||||
"
|
||||
)
|
||||
86
dependencies/tool_metadata.yml
vendored
Normal file
86
dependencies/tool_metadata.yml
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
- name: cugr
|
||||
repo: https://github.com/ax3ghazy/cu-gr
|
||||
commit: 1632b4b450cbd3e5b6bdc9bf92c96cadde6a01b9
|
||||
build: |
|
||||
xxd -i src/flute/POST9.dat > src/flute/POST9.c
|
||||
xxd -i src/flute/POWV9.dat > src/flute/POWV9.c
|
||||
rm -rf build/
|
||||
mkdir -p build/
|
||||
cd build
|
||||
cmake ../src
|
||||
make -j$(nproc)
|
||||
cp iccad19gr $PREFIX/bin/cugr
|
||||
- name: cvc
|
||||
repo: https://github.com/d-m-bailey/cvc
|
||||
commit: 38c74b0857ecf8f05a1bfde81d197b5a3d33a531
|
||||
build: |
|
||||
autoreconf -i
|
||||
autoconf
|
||||
./configure --disable-nls --prefix=$PREFIX
|
||||
make install
|
||||
- name: drcu
|
||||
repo: https://github.com/cuhk-eda/dr-cu
|
||||
commit: 427b4a4f03bb98d8a78b1712fe9e52cfb83a8347
|
||||
build: |
|
||||
rm -rf build/
|
||||
mkdir -p build/
|
||||
cd build
|
||||
cmake ../src
|
||||
make -j$(nproc)
|
||||
cp ispd19dr $PREFIX/bin/drcu
|
||||
- name: magic
|
||||
repo: https://github.com/rtimothyedwards/magic
|
||||
commit: 958d6f16701c1ee25e27440381b5c2c37b5fee7c
|
||||
build: |
|
||||
./configure --prefix=$PREFIX
|
||||
make -j$(nproc)
|
||||
make install
|
||||
- name: netgen
|
||||
repo: https://github.com/rtimothyedwards/netgen
|
||||
commit: 738c1f7b3705bca2f1cc66fbc1cfb20f12d49a06
|
||||
build: |
|
||||
./configure --prefix=$PREFIX
|
||||
make -j$(nproc)
|
||||
make install
|
||||
- name: padring
|
||||
repo: https://github.com/ax3ghazy/padring
|
||||
commit: a88faf5a4faef75ff241276599fef81c3653cb70
|
||||
build: |
|
||||
bash ./bootstrap.sh
|
||||
cd build
|
||||
ninja
|
||||
cp padring $PREFIX/bin
|
||||
- name: qflow
|
||||
repo: https://github.com/RTimothyEdwards/qflow
|
||||
commit: a550469b63e910ede6e3022e2886bca96462c540
|
||||
build: |
|
||||
# Note we only grab the vlog2verilog tool.
|
||||
./configure
|
||||
cd src
|
||||
make -j$(nproc) vlog2Verilog
|
||||
cp vlog2Verilog $PREFIX/bin
|
||||
- name: yosys
|
||||
repo: https://github.com/YosysHQ/yosys
|
||||
commit: d061b0e41a2023b5e72794563b94d6a9b5ab41a1
|
||||
build: |
|
||||
make PREFIX=$PREFIX config-gcc
|
||||
make PREFIX=$PREFIX -j$(nproc)
|
||||
make PREFIX=$PREFIX install
|
||||
- name: openroad_app
|
||||
repo: https://github.com/The-OpenROAD-Project/OpenROAD
|
||||
commit: 4d4d7205fd0292dbf3fae55fad9109b3f0bd5786
|
||||
build: mkdir -p ./build cd ./build cmake -DCMAKE_INSTALL_PREFIX=$PREFIX/bin .. make
|
||||
-j$(nproc)
|
||||
in_install: false
|
||||
- name: open_pdks
|
||||
repo: https://github.com/rtimothyedwards/open_pdks
|
||||
commit: 1d93a6bd9d6e481acfdf88f26aa3bb0600303d98
|
||||
build: ''
|
||||
in_install: false
|
||||
in_container: false
|
||||
- name: sky130
|
||||
repo: https://github.com/google/skywater-pdk
|
||||
commit: 00bdbcf4a3aa922cc1f4a0d0cd8b80dbd73149d3
|
||||
build: ''
|
||||
in_install: false
|
||||
in_container: false
|
||||
50
dependencies/ubuntu-20.04/run_time.txt
vendored
Normal file
50
dependencies/ubuntu-20.04/run_time.txt
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
https://www.klayout.org/downloads/Ubuntu-20/klayout_0.27.3-1_amd64.deb
|
||||
|
||||
xvfb
|
||||
autoconf
|
||||
autopoint
|
||||
bison
|
||||
bzip2
|
||||
libcairo-dev
|
||||
clang
|
||||
csh
|
||||
curl
|
||||
flex
|
||||
gawk
|
||||
gcc
|
||||
gdb
|
||||
gettext
|
||||
git
|
||||
graphviz
|
||||
help2man
|
||||
libeigen3-dev
|
||||
libsm-dev
|
||||
libx11-dev
|
||||
libffi-dev
|
||||
libgomp1
|
||||
libjpeg9-dev
|
||||
libxml2-dev
|
||||
libxslt-dev
|
||||
libffi-dev
|
||||
libspdlog-dev
|
||||
make
|
||||
ncurses-dev
|
||||
ninja-build
|
||||
patch
|
||||
libpcre2-dev
|
||||
python3
|
||||
python3-pip
|
||||
python3.6-dev
|
||||
python3.6-tk
|
||||
libreadline-dev
|
||||
strace
|
||||
swig
|
||||
tcl-dev
|
||||
tk-dev
|
||||
tcllib
|
||||
tclx8.4-dev
|
||||
texinfo
|
||||
neovim
|
||||
wget
|
||||
xdot
|
||||
zlib1g
|
||||
@@ -4,7 +4,7 @@ DOCKERFILE_PATH ?= ./Dockerfile
|
||||
IMAGE_NAME ?= efabless/openlane:current
|
||||
#ROOT = sudo
|
||||
|
||||
TOOLS = klayout cugr drcu yosys antmicro_yosys magic openroad_app padring netgen vlogtoverilog openphysyn cvc
|
||||
TOOLS = klayout cugr drcu yosys magic openroad_app padring netgen vlogtoverilog cvc
|
||||
|
||||
TOOL_BUILD_TARGETS = $(foreach tool,$(TOOLS),build-$(tool))
|
||||
TOOL_EXPORT_TARGETS_PHONY = $(foreach tool,$(TOOLS),export-$(tool))
|
||||
@@ -16,7 +16,7 @@ build-all: $(TOOL_BUILD_TARGETS) export-all
|
||||
|
||||
$(TOOL_BUILD_TARGETS): build-% : ./docker/%/Dockerfile
|
||||
mkdir -p logs/docker
|
||||
docker build $(DOCKER_BUILD_OPTS) -t $* docker/$* | tee logs/docker/$*.build.txt
|
||||
docker build $(DOCKER_BUILD_OPTS) $(shell python3 ../dependencies/tool.py --docker-args $*) -t $* docker/$* | tee logs/docker/$*.build.txt
|
||||
${MAKE} export-$*
|
||||
|
||||
# ==============================================================================
|
||||
|
||||
@@ -39,7 +39,7 @@ make build-<tool>
|
||||
The following are the available tools:
|
||||
|
||||
```bash
|
||||
klayout cugr drcu yosys magic openroad_app padring netgen vlogtoverilog openphysyn cvc
|
||||
klayout cugr drcu yosys magic openroad_app padring netgen vlogtoverilog cvc
|
||||
```
|
||||
|
||||
### Rebuilding
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
# Copyright 2020 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.
|
||||
|
||||
# syntax = docker/dockerfile:1.0-experimental
|
||||
FROM centos:centos7 as build
|
||||
|
||||
RUN yum groupinstall -y "Development Tools"
|
||||
RUN yum -y install centos-release-scl && \
|
||||
yum -y install curl libffi-devel readline-devel tcl tcl-devel graphviz xdot
|
||||
|
||||
RUN yum -y install bison flex gawk git zlib-devel
|
||||
|
||||
# Install dev and runtime dependencies
|
||||
RUN yum -y install devtoolset-8 devtoolset-8-libatomic-devel
|
||||
|
||||
ENV CC=/opt/rh/devtoolset-8/root/usr/bin/gcc \
|
||||
CPP=/opt/rh/devtoolset-8/root/usr/bin/cpp \
|
||||
CXX=/opt/rh/devtoolset-8/root/usr/bin/g++ \
|
||||
PATH=/opt/rh/devtoolset-8/root/usr/bin:$PATH \
|
||||
LD_LIBRARY_PATH=/opt/rh/devtoolset-8/root/usr/lib64:/opt/rh/devtoolset-8/root/usr/lib:/opt/rh/devtoolset-8/root/usr/lib64/dyninst:/opt/rh/devtoolset-8/root/usr/lib/dyninst:/opt/rh/devtoolset-8/root/usr/lib64:/opt/rh/devtoolset-8/root/usr/lib:$LD_LIBRARY_PATH
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
RUN yum install -y https://repo.ius.io/ius-release-el7.rpm
|
||||
RUN yum install -y python36u python36u-pip
|
||||
RUN alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 60
|
||||
|
||||
|
||||
#ENV CC=/opt/rh/devtoolset-6/root/usr/bin/gcc \
|
||||
#CPP=/opt/rh/devtoolset-6/root/usr/bin/cpp \
|
||||
#CXX="/opt/rh/devtoolset-6/root/usr/bin/g++" \
|
||||
#PATH=/opt/rh/devtoolset-6/root/usr/bin:$PATH \
|
||||
#LD_LIBRARY_PATH=/opt/rh/devtoolset-6/root/usr/lib64:/opt/rh/devtoolset-6/root/usr/lib:/opt/rh/devtoolset-6/root/usr/lib64/dyninst:/opt/rh/devtoolset-6/root/usr/lib/dyninst:/opt/rh/devtoolset-6/root/usr/lib64:/opt/rh/devtoolset-6/root/usr/lib:$LD_LIBRARY_PATH
|
||||
|
||||
#RUN yum install -y clang
|
||||
|
||||
# https://github.com/YosysHQ/yosys/issues/332
|
||||
RUN yum install -y wget autoconf && \
|
||||
wget https://ftp.gnu.org/gnu/bison/bison-3.0.1.tar.gz && \
|
||||
tar -xvzf bison-3.0.1.tar.gz && \
|
||||
cd bison-3.0.1 && \
|
||||
./configure && \
|
||||
make -j$(nproc) && \
|
||||
make install
|
||||
|
||||
# download public key for github.com
|
||||
# RUN mkdir -p -m 0600 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts
|
||||
|
||||
# git clone yosys
|
||||
ARG ANTMICRO_YOSYS_REPO=https://github.com/antmicro/yosys
|
||||
ARG ANTMICRO_YOSYS_COMMIT=fe58e937ef87fdb157dd89c365bb6a570fe616ea
|
||||
RUN git clone ${ANTMICRO_YOSYS_REPO} yosys && \
|
||||
cd yosys && \
|
||||
git checkout ${ANTMICRO_YOSYS_COMMIT}
|
||||
|
||||
# build yosys
|
||||
WORKDIR yosys
|
||||
|
||||
|
||||
RUN make PREFIX=/build/antmicro config-gcc \
|
||||
&& make PREFIX=/build/antmicro -j$(nproc) \
|
||||
&& make PREFIX=/build/antmicro install
|
||||
|
||||
|
||||
RUN mkdir -p /build/version
|
||||
RUN date +"Build Timestamp: %Y-%m-%d_%H-%M-%S" > /build/version/yosys.version
|
||||
RUN git rev-parse HEAD >> /build/version/yosys.version
|
||||
RUN tar -czf /build.tar.gz /build
|
||||
@@ -1,89 +0,0 @@
|
||||
# Copyright 2020 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.
|
||||
|
||||
# syntax = docker/dockerfile:1.0-experimental
|
||||
FROM centos:centos7 AS build
|
||||
|
||||
# Install Development Environment
|
||||
RUN yum groupinstall -y "Development Tools"
|
||||
RUN yum install -y wget git
|
||||
|
||||
RUN yum -y install centos-release-scl && \
|
||||
yum -y install devtoolset-8 \
|
||||
devtoolset-8-libatomic-devel tcl-devel tcl tk libstdc++ tk-devel pcre-devel \
|
||||
python36u python36u-libs python36u-devel python36u-pip && \
|
||||
yum clean -y all && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV CC=/opt/rh/devtoolset-8/root/usr/bin/gcc \
|
||||
CPP=/opt/rh/devtoolset-8/root/usr/bin/cpp \
|
||||
CXX="/opt/rh/devtoolset-8/root/usr/bin/g++ -lrt" \
|
||||
PATH=/opt/rh/devtoolset-8/root/usr/bin:$PATH \
|
||||
LD_LIBRARY_PATH=/opt/rh/devtoolset-8/root/usr/lib64:/opt/rh/devtoolset-8/root/usr/lib:/opt/rh/devtoolset-8/root/usr/lib64/dyninst:/opt/rh/devtoolset-8/root/usr/lib/dyninst:/opt/rh/devtoolset-8/root/usr/lib64:/opt/rh/devtoolset-8/root/usr/lib:$LD_LIBRARY_PATH
|
||||
|
||||
|
||||
|
||||
# Install CMake
|
||||
RUN wget https://cmake.org/files/v3.14/cmake-3.14.0-Linux-x86_64.sh && \
|
||||
chmod +x cmake-3.14.0-Linux-x86_64.sh && \
|
||||
./cmake-3.14.0-Linux-x86_64.sh --skip-license --prefix=/usr/local && rm -rf cmake-3.14.0-Linux-x86_64.sh \
|
||||
&& yum clean -y all
|
||||
|
||||
# Install dev and runtime dependencies
|
||||
RUN yum install -y tcl-devel tcl tk libstdc++ tk-devel pcre-devel
|
||||
|
||||
# Install epel repo
|
||||
RUN wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm && \
|
||||
yum install -y epel-release-latest-7.noarch.rpm && rm -rf epel-release-latest-7.noarch.rpm \
|
||||
&& yum clean -y all
|
||||
|
||||
RUN yum install -y https://repo.ius.io/ius-release-el7.rpm
|
||||
|
||||
# Install SWIG
|
||||
RUN yum remove -y swig \
|
||||
&& wget https://github.com/swig/swig/archive/rel-4.0.1.tar.gz \
|
||||
&& tar xfz rel-4.0.1.tar.gz \
|
||||
&& rm -rf rel-4.0.1.tar.gz \
|
||||
&& cd swig-rel-4.0.1 \
|
||||
&& ./autogen.sh && ./configure --prefix=/usr && make -j $(nproc) && make install \
|
||||
&& cd .. \
|
||||
&& rm -rf swig-rel-4.0.1
|
||||
|
||||
|
||||
# Installing boost for build dependency
|
||||
RUN wget https://dl.bintray.com/boostorg/release/1.68.0/source/boost_1_68_0.tar.bz2 && \
|
||||
tar -xf boost_1_68_0.tar.bz2 && \
|
||||
cd boost_1_68_0 && \
|
||||
./bootstrap.sh -with-libraries=program_options,log,filesystem && \
|
||||
./b2 -j$(nproc) install
|
||||
|
||||
ARG OPENPHYSYN_REPO=https://github.com/scale-lab/OpenPhySyn
|
||||
ARG OPENPHYSYN_COMMIT=6bb80c5f9312a302b7c29cf1a4ddb93ace47d122
|
||||
RUN git clone --recursive ${OPENPHYSYN_REPO} && \
|
||||
cd OpenPhySyn && \
|
||||
git checkout ${OPENPHYSYN_COMMIT}
|
||||
|
||||
|
||||
# Build
|
||||
WORKDIR OpenPhySyn
|
||||
RUN mkdir build && mkdir /build
|
||||
RUN cd build && cmake .. -DCMAKE_BUILD_TYPE=release && make -j 4 && make install
|
||||
RUN mkdir /build/bin && cp build/Psn /build/bin/
|
||||
|
||||
|
||||
|
||||
RUN mkdir -p /build/version
|
||||
RUN date +"Build Timestamp: %Y-%m-%d_%H-%M-%S" > /build/version/openphysyn.version
|
||||
RUN git rev-parse HEAD >> /build/version/openphysyn.version
|
||||
RUN tar -czf /build.tar.gz /build
|
||||
Binary file not shown.
Binary file not shown.
@@ -42,7 +42,7 @@
|
||||
|
||||
**Note**: You can use different directories for sky130-source and local-path. However, in the instructions we are using $PDK_ROOT to facilitate the installation process
|
||||
|
||||
**WARNING**: Please, don't move `sk130A` from the installed directory because the generated .mag files contain absolute paths. Moving it will result in producing an invalid GDS.
|
||||
**WARNING**: Please, don't move `sky130A` from the installed directory because the generated .mag files contain absolute paths. Moving it will result in producing an invalid GDS.
|
||||
|
||||
- To set the STD_CELL_LIBRARY (the default value is set to sky130_fd_sc_hd)
|
||||
- Open [configuration/general.tcl](../configuration/general.tcl)
|
||||
|
||||
@@ -183,7 +183,6 @@ Most of the following commands' implementation exists in this [file][7]
|
||||
| `add_macro_placement <macro_name> <x_coordinate> <y_coordinate> [<orientation>]` | | Writes a configuration file to be processed by `manual_macro_placement` by setting the initial placement of the macro `<macro_name>` to location (`<x_coordinate>`,`<y_coordinate>`) on the chip with the option of specifying the `<orientation>` as well. The line written will be appened to this configuration file `/run_path/tmp/macro_placements.cfg`. |
|
||||
| `manual_macro_placement [f]` | | Uses the configuration file generated by `add_macro_placement` (`/run_path/tmp/macro_placements.cfg`) to manually initialize the placement of the macros to the locations determined in the file. It works on the currently processed design and it overwrites the `CURRENT_DEF`. if `f` is passed as the first argument, the placement will be fixed and final, and the placement tools will not be allowed to change it.|
|
||||
| `basic_macro_placement` | | Runs basic macro placement on the chip level using the openroad app, and it writes into `::env(CURRENT_DEF).macro_placement.def`. |
|
||||
| `run_openPhySyn` | | Runs OpenPhySyn timing optimizations: capacitance_violations, transition_violations, fanout_violations, and negative_slack_violations. |
|
||||
| `run_resizer_design` | | Runs resizer design optimizations to insert buffers on nets to repair max slew, max capacitance, max fanout violations, and on long wires to reduce RC delay in the wire. It also resizes cells. |
|
||||
| `run_resizer_timing` | | Runs resizer timing optimizations which repairs setup and hold violations. |
|
||||
| `run_placement`| | Runs global placement (`global_placement_or` or `random_global_placement` based on the value of `PL_RANDOM_GLB_PLACEMENT`), then applies the optional optimizations `repair_wire_length` followed by `run_openPhySyn` if enabled, then runs the detailed placement (`detailed_placement_or`). |
|
||||
|
||||
@@ -118,14 +118,6 @@ The only optimization we use from resizer is the wire length optimization which
|
||||
|
||||
However, you can enable that by setting `PL_RESIZER_OVERBUFFER` to `1` and then determine the maximum wire length by setting this value `MAX_WIRE_LENGTH`.
|
||||
|
||||
#### OpenPhySyn optimizations:
|
||||
|
||||
The timing OpenPhySyn optimizations are enabled by default and you can control that using this flag `PL_OPENPHYSYN_OPTIMIZATIONS`.
|
||||
|
||||
You can also control resizing and pin swapping using these flags: `PSN_ENABLE_RESIZING` and `PSN_ENABLE_PIN_SWAP`.
|
||||
|
||||
You can read more about those configurations [here][0].
|
||||
|
||||
### Detailed Placement:
|
||||
|
||||
The only value to consider here is the `CELL_PAD` which is usually selected for each (PDK,STD_CELL_LIBRARY) and should mostly be left as is. However, typically for the skywater libraries the value should be 4~6.
|
||||
|
||||
36
get_tag.py
Normal file
36
get_tag.py
Normal file
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2020 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.
|
||||
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
tag = None
|
||||
|
||||
try:
|
||||
tag = subprocess.check_output(["git", "describe", "--tags", "--abbrev=0"]).decode("utf8").strip()
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
if tag is None:
|
||||
try:
|
||||
tag = open("./resolved_version").read()
|
||||
except:
|
||||
print("Please input the version of OpenLane you'd like to pull: ", file=sys.stderr)
|
||||
tag = input()
|
||||
with open("./resolved_version", "w") as f:
|
||||
f.write(tag)
|
||||
|
||||
print(tag, end="")
|
||||
@@ -29,7 +29,7 @@ import subprocess
|
||||
from os.path import join, abspath, dirname, exists
|
||||
from typing import Tuple, Union, List
|
||||
|
||||
from dependencies.tool_metadata import Tool
|
||||
from dependencies.tool import Tool
|
||||
|
||||
openlane_dir = dirname(abspath(__file__))
|
||||
is_root = os.geteuid() == 0
|
||||
@@ -112,34 +112,8 @@ def download(url, ext):
|
||||
target.close()
|
||||
return path
|
||||
|
||||
def compile_tool_data():
|
||||
dockerfiles = glob.glob(join(openlane_dir, "docker_build", "**", "Dockerfile"), recursive=True)
|
||||
docker_lines = "\n".join([open(x).read() for x in dockerfiles]).split("\n")
|
||||
for line in docker_lines:
|
||||
repo_rx = r"ARG\s+(\w+)_REPO\s*=\s*([^\s]+)"
|
||||
commit_rx = r"ARG\s+(\w+)_COMMIT\s*=\s*([^\s]+)"
|
||||
|
||||
repo_match = re.match(repo_rx, line)
|
||||
commit_match = re.match(commit_rx, line)
|
||||
|
||||
if repo_match:
|
||||
name = repo_match[1].lower(); repo = repo_match[2]
|
||||
|
||||
tool = Tool.map.get(name)
|
||||
if tool is None:
|
||||
print(f"Tool {name} not found, skipping...")
|
||||
continue
|
||||
tool.repo = repo
|
||||
if commit_match:
|
||||
name = commit_match[1].lower(); commit = commit_match[2]
|
||||
|
||||
tool = Tool.map.get(name)
|
||||
if tool is None:
|
||||
print(f"Tool {name} not found, skipping...")
|
||||
continue
|
||||
tool.commit = commit
|
||||
|
||||
def run_installer():
|
||||
tools = Tool.from_metadata_yaml(open("./dependencies/tool_metadata.yml").read())
|
||||
if input_options("RISK_ACKNOWLEDGED", "I affirm that I have read LOCAL_INSTALL.md and agree to the outlined risks.", ["n", "y"]) != "y":
|
||||
return
|
||||
|
||||
@@ -160,7 +134,7 @@ OpenLane Local Installer ALPHA
|
||||
|
||||
This version of OpenLane was tested with this version of OpenRoad:
|
||||
|
||||
{Tool.map["openroad_app"].version_string}
|
||||
{tools["openroad_app"].version_string}
|
||||
""")
|
||||
|
||||
os_pick = input_options("OS", "Which UNIX/Unix-like OS are you using?", ["ubuntu-20.04", "centos7", "other"])
|
||||
@@ -168,11 +142,10 @@ OpenLane Local Installer ALPHA
|
||||
gcc_bin = os.getenv("CC") or "gcc"
|
||||
gxx_bin = os.getenv("CXX") or "g++"
|
||||
try:
|
||||
if not os_pick == "centos7":
|
||||
if not os_pick == "centos7": # The reason we ignore centos7 is that we're going to just use devtoolset-8 anyway.
|
||||
gcc_ver_output = subprocess.run([gcc_bin, "--version"], stdout=subprocess.PIPE)
|
||||
gx_ver_output = subprocess.run([gxx_bin, "--version"], stdout=subprocess.PIPE)
|
||||
if "clang" in gcc_ver_output.stdout.decode("utf-8") + gx_ver_output.stdout.decode("utf-8"):
|
||||
# The reason we ignore centos7 is that we're going to just use devtoolset-8 anyway.
|
||||
print(f"""
|
||||
We've detected that you're using Clang as your default C or C++ compiler.
|
||||
Unfortunately, Clang is not compatible with some of the tools being
|
||||
@@ -203,13 +176,19 @@ OpenLane Local Installer ALPHA
|
||||
|
||||
pip_action = input_options("PIP_DEPS", "Install PIP dependencies?", ["no", "system", "user"])
|
||||
if pip_action != "no":
|
||||
python_directory = join(openlane_dir, "dependencies", "python")
|
||||
requirements_files = [os.path.join(python_directory, file) for file in os.listdir(python_directory)]
|
||||
final_list = []
|
||||
for file in requirements_files:
|
||||
final_list.append("-r")
|
||||
final_list.append(file)
|
||||
|
||||
sh(
|
||||
"python3",
|
||||
"-m",
|
||||
"pip",
|
||||
"install",
|
||||
"-r",
|
||||
join(openlane_dir, "dependencies", "requirements.txt"),
|
||||
*final_list,
|
||||
root=pip_action == "system"
|
||||
)
|
||||
|
||||
@@ -217,12 +196,18 @@ OpenLane Local Installer ALPHA
|
||||
if os_pick != "other":
|
||||
install_packages = input_options("INSTALL_PACKAGES", "Do you want to install packages for development?", ["no", "yes"])
|
||||
if install_packages != "no":
|
||||
def cat_all(dir):
|
||||
result = ""
|
||||
for file in os.listdir(dir):
|
||||
result += open(join(dir, file)).read()
|
||||
result += "\n"
|
||||
return result
|
||||
if os_pick == "centos7":
|
||||
yum_packages = open(join(openlane_dir, 'dependencies', 'centos7.txt')).read().strip().split("\n")
|
||||
yum_packages = cat_all(join(openlane_dir, 'dependencies', 'centos7')).strip().split("\n")
|
||||
|
||||
sh("yum", "install", "-y", *yum_packages)
|
||||
if os_pick == "ubuntu-20.04":
|
||||
raw = open(join(openlane_dir, 'dependencies', 'ubuntu20.04.txt')).read().strip().split("\n")
|
||||
raw = cat_all(join(openlane_dir, 'dependencies', 'ubuntu-20.04')).strip().split("\n")
|
||||
|
||||
apt_packages = []
|
||||
apt_debs = []
|
||||
@@ -274,8 +259,8 @@ OpenLane Local Installer ALPHA
|
||||
for folder in ["repos", "versions"]:
|
||||
sh("mkdir", "-p", folder)
|
||||
|
||||
for tool in Tool.map.values():
|
||||
if tool.skip:
|
||||
for tool in tools.values():
|
||||
if not tool.in_install:
|
||||
continue
|
||||
installed_version = ""
|
||||
version_path = f"versions/{tool.name}"
|
||||
@@ -301,7 +286,7 @@ OpenLane Local Installer ALPHA
|
||||
sh("git", "submodule", "update", "--init")
|
||||
sh("git", "checkout", tool.commit)
|
||||
subprocess.run([
|
||||
"bash", "-c", tool.install_command
|
||||
"bash", "-c", tool.build_script
|
||||
], env=run_env, check=True)
|
||||
|
||||
with open(version_path, "w") as f:
|
||||
@@ -311,7 +296,6 @@ OpenLane Local Installer ALPHA
|
||||
f.write("""#!/bin/bash
|
||||
OL_DIR="$(dirname "$(test -L "$0" && readlink "$0" || echo "$0")")"
|
||||
|
||||
export NO_DIAMOND_SEARCH_HEIGHT=1
|
||||
export PATH=$OL_DIR/bin:$PATH
|
||||
|
||||
FLOW_TCL=${FLOW_TCL:-$OL_DIR/flow.tcl}
|
||||
@@ -337,9 +321,9 @@ def main():
|
||||
help="List the tools and exit."
|
||||
)
|
||||
args = parser.parse_args()
|
||||
compile_tool_data()
|
||||
if args.list_tools:
|
||||
for tool in Tool.map.values():
|
||||
tools = Tool.from_metadata_yaml(open("./dependencies/tool_metadata.yml").read())
|
||||
for tool in tools.values():
|
||||
print(f"{tool.name}: {tool.version_string}")
|
||||
else:
|
||||
run_installer()
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
| `vias` | The number of vias in the final design. Extracted from tritonRoute logs. |
|
||||
| `wns` | Worst Negative Slack. Reported after Synthesis. Extracted from OpenSTA. |
|
||||
| `pl_wns` | Worst Negative Slack. Reported after global placement and before optimizations using estimate parasitics. Extracted from RePlAce/OpenSTA. If the report wasn't found, the value from the previous STA report is used. |
|
||||
| `opt_wns` | Worst Negative Slack. Reported after OpenPhySyn optimizations. Extracted from OpenSTA. If the report wasn't found, the value from the previous STA report is used. |
|
||||
| `opt_wns` | Worst Negative Slack. Extracted from OpenSTA. If the report wasn't found, the value from the previous STA report is used. |
|
||||
| `fastroute_tns` | Worst Negative Slack. Reported after global routing using estimate parasitics. Extracted from FastRoute/OpenSTA. If the report wasn't found, the value from the previous STA report is used. |
|
||||
| `spef_wns` | Worst Negative Slack. Reported after routing and spef extraction. Extracted from OpenSTA. If the report wasn't found, the value from the previous STA report is used. |
|
||||
| `tns` | Total Negative Slack. Reported after Synthesis. Extracted from OpenSTA. |
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
#Psn ; # or ./build/Psn if not installed in the global path
|
||||
#BSD 3-Clause License
|
||||
#Copyright (c) 2019, SCALE Lab, Brown University
|
||||
#All rights reserved.
|
||||
#Redistribution and use in source and binary forms, with or without
|
||||
#modification, are permitted provided that the following conditions are met:
|
||||
#* Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#* Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#* Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
#AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
#IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
#DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
#FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
#DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
#SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
#CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
#OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
#OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import_lib $::env(LIB_OPT)
|
||||
import_lef $::env(MERGED_LEF_UNPADDED)
|
||||
import_def $::env(CURRENT_DEF)
|
||||
read_sdc $::env(BASE_SDC_FILE)
|
||||
|
||||
set_wire_rc $::env(WIRE_RC_LAYER)
|
||||
|
||||
puts "=============== Initial Reports ============="
|
||||
report_checks
|
||||
report_check_types -max_slew -max_capacitance -violators
|
||||
puts "Capacitance violations: [llength [capacitance_violations]]"
|
||||
puts "Transition violations: [llength [transition_violations]]"
|
||||
report_wns
|
||||
report_tns
|
||||
|
||||
puts "Initial area: [expr round([design_area] * 10E12) ] um2"
|
||||
|
||||
puts "OpenPhySyn timing repair:"
|
||||
|
||||
set opts ""
|
||||
|
||||
if { $::env(PSN_ENABLE_RESIZING) == 0 } {
|
||||
set opts "$opts -resize_disabled"
|
||||
}
|
||||
|
||||
if { $::env(PSN_ENABLE_PIN_SWAP) == 0 } {
|
||||
set opts "$opts -pin_swap_disabled"
|
||||
}
|
||||
|
||||
|
||||
repair_timing -capacitance_violations -transition_violations -fanout_violations -negative_slack_violations $opts
|
||||
|
||||
puts "=============== Final Reports ============="
|
||||
report_checks
|
||||
report_checks > $::env(openphysyn_report_file_tag)_allchecks.rpt
|
||||
report_check_types -max_slew -max_capacitance -violators
|
||||
report_check_types -max_slew -max_capacitance -violators > $::env(openphysyn_report_file_tag)_violators.rpt
|
||||
puts "Capacitance violations: [llength [capacitance_violations]]"
|
||||
puts "Transition violations: [llength [transition_violations]]"
|
||||
report_wns
|
||||
report_wns > $::env(openphysyn_report_file_tag)_wns.rpt
|
||||
report_tns
|
||||
report_tns > $::env(openphysyn_report_file_tag)_tns.rpt
|
||||
|
||||
puts "Final area: [expr round([design_area] * 10E12) ] um2"
|
||||
|
||||
puts "Export optimized design"
|
||||
export_def $::env(SAVE_DEF)
|
||||
exit 0
|
||||
|
||||
@@ -26,18 +26,12 @@ routed_runtime_rpt=${path}/reports/routed_runtime.txt
|
||||
total_runtime_rpt=${path}/reports/total_runtime.txt
|
||||
wns_rpt=$(python3 $3/get_file_name.py -p ${path}/reports/synthesis/ -o opensta_wns.rpt 2>&1)
|
||||
pl_wns_rpt=$(python3 $3/get_file_name.py -p ${path}/reports/placement/ -o replace.log 2>&1)
|
||||
opt_wns_rpt=$(python3 $3/get_file_name.py -p ${path}/reports/synthesis/ -o opensta_post_openphysyn_wns.rpt 2>&1)
|
||||
if ! [ -f $opt_wns_rpt ]; then
|
||||
opt_wns_rpt=$(python3 $3/get_file_name.py -p ${path}/reports/synthesis/ -o opensta_post_resizer_timing_wns.rpt 2>&1)
|
||||
fi
|
||||
opt_wns_rpt=$(python3 $3/get_file_name.py -p ${path}/reports/synthesis/ -o opensta_post_resizer_timing_wns.rpt 2>&1)
|
||||
fr_wns_rpt=$(python3 $3/get_file_name.py -p ${path}/logs/routing/ -o fastroute.log 2>&1)
|
||||
spef_wns_rpt=$(python3 $3/get_file_name.py -p ${path}/reports/synthesis/ -o opensta_spef_wns.rpt 2>&1)
|
||||
tns_rpt=$(python3 $3/get_file_name.py -p ${path}/reports/synthesis/ -o opensta_tns.rpt 2>&1)
|
||||
pl_tns_rpt=$(python3 $3/get_file_name.py -p ${path}/reports/placement/ -o replace.log 2>&1)
|
||||
opt_tns_rpt=$(python3 $3/get_file_name.py -p ${path}/reports/synthesis/ -o opensta_post_openphysyn_tns.rpt 2>&1)
|
||||
if ! [ -f $opt_tns_rpt ]; then
|
||||
opt_tns_rpt=$(python3 $3/get_file_name.py -p ${path}/reports/synthesis/ -o opensta_post_resizer_timing_tns.rpt 2>&1)
|
||||
fi
|
||||
opt_tns_rpt=$(python3 $3/get_file_name.py -p ${path}/reports/synthesis/ -o opensta_post_resizer_timing_tns.rpt 2>&1)
|
||||
fr_tns_rpt=$(python3 $3/get_file_name.py -p ${path}/reports/routing/ -o fastroute.log 2>&1)
|
||||
spef_tns_rpt=$(python3 $3/get_file_name.py -p ${path}/reports/synthesis/ -o opensta_spef_tns.rpt 2>&1)
|
||||
HPWL_rpt=$(python3 $3/get_file_name.py -p ${path}/logs/placement/ -o replace.log 2>&1)
|
||||
@@ -180,7 +174,7 @@ if ! [[ $wns ]]; then wns=-1; fi
|
||||
pl_wns=$(grep "wns" $pl_wns_rpt -s | tail -1 |sed -r 's/wns //')
|
||||
if ! [[ $pl_wns ]]; then pl_wns=$wns; fi
|
||||
|
||||
#Extracting Info from OpenPhySyn
|
||||
#Extracting Info from OpenSTA
|
||||
opt_wns=$(grep "wns" $opt_wns_rpt -s | tail -1 |sed -r 's/wns //')
|
||||
if ! [[ $opt_wns ]]; then opt_wns=$pl_wns; fi
|
||||
|
||||
@@ -200,7 +194,7 @@ if ! [[ $tns ]]; then tns=-1; fi
|
||||
pl_tns=$(grep "tns" $pl_tns_rpt -s | tail -1 |sed -r 's/tns //')
|
||||
if ! [[ $pl_tns ]]; then pl_tns=$tns; fi
|
||||
|
||||
#Extracting Info from OpenPhySyn
|
||||
#Extracting Info from OpenSTA
|
||||
opt_tns=$(grep "tns" $opt_tns_rpt -s | tail -1 |sed -r 's/tns //')
|
||||
if ! [[ $opt_tns ]]; then opt_tns=$pl_tns; fi
|
||||
|
||||
|
||||
@@ -442,7 +442,6 @@ proc prep {args} {
|
||||
{pdn floorplan/pdn}
|
||||
{tapcell floorplan/tapcell}
|
||||
{replaceio placement/replace}
|
||||
{openphysyn placement/openphysyn}
|
||||
{resizer placement/resizer}
|
||||
{opendp placement/opendp}
|
||||
{addspacers routing/addspacers}
|
||||
|
||||
@@ -28,7 +28,6 @@ detailed_placement_or
|
||||
basic_macro_placement
|
||||
run_placement
|
||||
repair_wire_length
|
||||
run_openPhySyn
|
||||
init_design
|
||||
global_routing_or
|
||||
global_routing
|
||||
|
||||
@@ -151,52 +151,11 @@ proc run_placement {args} {
|
||||
set ::env(PL_TARGET_DENSITY) $old_pl_target_density
|
||||
}
|
||||
|
||||
run_openPhySyn
|
||||
run_resizer_design
|
||||
detailed_placement_or
|
||||
scrot_klayout -layout $::env(CURRENT_DEF)
|
||||
}
|
||||
|
||||
proc run_openPhySyn {args} {
|
||||
if { $::env(PL_OPENPHYSYN_OPTIMIZATIONS) == 1} {
|
||||
puts_info "Running OpenPhySyn Timing Optimizations..."
|
||||
TIMER::timer_start
|
||||
if { ! [info exists ::env(LIB_OPT)]} {
|
||||
set ::env(LIB_OPT) $::env(TMP_DIR)/opt.lib
|
||||
trim_lib -input $::env(LIB_SLOWEST) -output $::env(LIB_OPT) -drc_exclude_only
|
||||
}
|
||||
set report_tag_saver $::env(openphysyn_report_file_tag)
|
||||
set ::env(openphysyn_report_file_tag) [index_file $::env(openphysyn_report_file_tag)]
|
||||
|
||||
set ::env(SAVE_DEF) [index_file $::env(openphysyn_tmp_file_tag).def 0]
|
||||
try_catch Psn $::env(SCRIPTS_DIR)/openPhySyn.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(openphysyn_log_file_tag).log 0]
|
||||
set_def $::env(SAVE_DEF)
|
||||
set ::env(openphysyn_report_file_tag) $report_tag_saver
|
||||
|
||||
TIMER::timer_stop
|
||||
exec echo "[TIMER::get_runtime]" >> [index_file $::env(openphysyn_log_file_tag)_runtime.txt 0]
|
||||
|
||||
write_verilog $::env(yosys_result_file_tag)_optimized.v
|
||||
set_netlist $::env(yosys_result_file_tag)_optimized.v
|
||||
|
||||
if { $::env(LEC_ENABLE) && [file exists $::env(PREV_NETLIST)] } {
|
||||
logic_equiv_check -rhs $::env(PREV_NETLIST) -lhs $::env(CURRENT_NETLIST)
|
||||
}
|
||||
|
||||
set report_tag_holder $::env(opensta_report_file_tag)
|
||||
set log_tag_holder $::env(opensta_log_file_tag)
|
||||
set ::env(opensta_report_file_tag) $::env(opensta_report_file_tag)_post_openphysyn
|
||||
set ::env(opensta_log_file_tag) $::env(opensta_log_file_tag)_post_openphysyn
|
||||
run_sta
|
||||
set ::env(opensta_report_file_tag) $report_tag_holder
|
||||
set ::env(opensta_log_file_tag) $log_tag_holder
|
||||
|
||||
} else {
|
||||
puts_info "Skipping OpenPhySyn Timing Optimizations."
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
proc run_resizer_timing {args} {
|
||||
if { $::env(PL_RESIZER_TIMING_OPTIMIZATIONS) == 1} {
|
||||
puts_info "Running Resizer Timing Optimizations..."
|
||||
|
||||
Reference in New Issue
Block a user