Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
141 changes: 21 additions & 120 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,12 @@ vars:
gf180mcuD) echo "gf180mcu" ;;
*) echo ""; echo "Unknown PDK: {{.PDK}}" >&2; exit 1 ;;
esac
PDK_ORFS:
sh: |
case "{{.PDK}}" in
ihp-sg13g2) echo "ihp-sg13g2" ;;
sky130A) echo "sky130hd" ;;
gf180mcuD) echo "gf180" ;;
*) echo ""; echo "Unknown PDK: {{.PDK}}" >&2; exit 1 ;;
esac
PDK_HASH:
sh: |
case "{{.PDK}}" in
ihp-sg13g2) echo "5cccb161f7492697cfa52eb14dc03beb00bdca9e" ;;
sky130A) echo "7b70722e33c03fcb5dabcf4d479fb0822d9251c9" ;;
gf180mcuD) echo "7b70722e33c03fcb5dabcf4d479fb0822d9251c9" ;;
ihp-sg13g2) echo "ee974c3adc69d0f36adbf20577079f0df419d702" ;;
sky130A) echo "f6eeac7dad085ffcc829ccfd721f7b4ce39edcf7" ;;
gf180mcuD) echo "f6eeac7dad085ffcc829ccfd721f7b4ce39edcf7" ;;
*) echo ""; echo "Unknown PDK: {{.PDK}}" >&2; exit 1 ;;
esac

Expand Down Expand Up @@ -107,96 +99,23 @@ tasks:
- "{{.RUN}} 'IP_ROOT={{.PWD}}/sources/{{.ip}}/ sbt \"runMain digital.peripherals.io.gpio.GpioExport\"'"

build:
desc: Runs ORFS physical implementation for the given ip/macro/PDK.
vars:
ORFS_ENV: source {{.OPENROAD_FLOW_ROOT}}/../env.sh
ORFS: >-
make -C {{.OPENROAD_FLOW_ROOT}}
YOSYS_EXE=$YOSYS_EXE
OPENROAD_EXE=$OPENROAD_EXE
IP_ROOT={{.PWD}}/sources/{{.ip}}/
DESIGN_CONFIG={{.PWD}}/sources/{{.ip}}/{{.PDK}}/flow/orfs/{{.macro}}/config.mk
WORK_HOME={{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/orfs
CDL: "{{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/orfs/results/{{.PDK_ORFS}}/{{.macro}}/base/6_final.cdl"
cmds:
- "{{.CONTAINER_CHECK}}"
- "{{.PDK_CHECK}}"
- task: lib-sbt-publishLocal
vars:
project: "modules/elements/vexiiriscv"
- "{{.RUN}} '{{.ORFS_ENV}} && {{.ORFS}} {{if .stage}}{{.stage}}{{end}}'"
- "{{.RUN}} '{{.ORFS_ENV}} && {{.ORFS}} generate_abstract'"
- "{{.RUN}} '{{.ORFS_ENV}} && {{.ORFS}} {{.CDL}}'"
- "{{.RUN}} '{{.ORFS_ENV}} && {{.ORFS}} metadata-generate'"
- "{{.RUN}} '{{.ORFS_ENV}} && {{.ORFS}} metadata-check'"

update-metadata:
desc: Updates the OpenROAD metadata for the given ip/macro/PDK.
vars:
ORFS_ENV: source {{.OPENROAD_FLOW_ROOT}}/../env.sh
ORFS: >-
make -C {{.OPENROAD_FLOW_ROOT}}
YOSYS_EXE=$YOSYS_EXE
OPENROAD_EXE=$OPENROAD_EXE
IP_ROOT={{.PWD}}/sources/{{.ip}}/
DESIGN_CONFIG={{.PWD}}/sources/{{.ip}}/{{.PDK}}/flow/orfs/{{.macro}}/config.mk
WORK_HOME={{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/orfs
CDL: "{{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/orfs/objects/{{.PDK_ORFS}}/{{.macro}}/base/6_final_concat.cdl"
cmds:
- "{{.CONTAINER_CHECK}}"
- "{{.RUN}} '{{.ORFS_ENV}} && {{.ORFS}} metadata-generate'"
- "{{.RUN}} '{{.ORFS_ENV}} && {{.ORFS}} update_rules'"

build-librelane:
desc: Runs LibreLane physical implementation for the given ip/macro/PDK.
vars:
LIBRELANE_CMD: >-
PYTHONPATH={{.PWD}}/tools/librelane python3 -m librelane
--force-run-dir {{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/librelane
PYTHONPATH={{.PWD}}/tools/librelane:{{.PWD}}/tools/librelane-plugins python3 -m librelane
--pdk {{.PDK}} --pdk-root {{.PDK_ROOT}}
--force-run-dir {{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/librelane/{{.PDK}}
{{.PWD}}/sources/{{.ip}}/{{.PDK}}/flow/librelane/{{.macro}}.yml
cmds:
- "{{.CONTAINER_CHECK}}"
- "{{.PDK_CHECK}}"
- "mkdir -p {{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/librelane"
- task: lib-sbt-publishLocal
vars:
project: "modules/elements/vexiiriscv"
- "rm -rf {{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/librelane/{{.PDK}}"
- "mkdir -p {{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/librelane/{{.PDK}}"
- "{{.RUN}} '{{.LIBRELANE_CMD}}'"

check-logs:
desc: Scans ORFS build logs for warnings and errors for the given ip/macro/PDK.
cmds:
- "{{.CONTAINER_CHECK}}"
- "{{.RUN}} 'find {{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/orfs/logs/{{.PDK_ORFS}}/{{.macro}}/ -type f -iname \"*.log\" -exec grep -v -e \"already destroyed\" -e \"XDG_RUNTIME_DIR not set\" -i {} \\+ |
grep --color -e WARNING -e ERROR'"
- "{{.RUN}} 'find {{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/orfs/reports/{{.PDK_ORFS}}/{{.macro}}/ -type f -iname \"6_finish.rpt\" -exec grep \"violation count\" {} \\+'"

run-drc:
desc: Runs KLayout DRC sign-off for the given ip/macro/PDK.
vars:
DRC_CMD: >-
bash {{.PWD}}/scripts/run_drc.sh
--gds {{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/orfs/results/{{.PDK_ORFS}}/{{.macro}}/base/6_final.gds
--topcell {{.macro}}
--run-dir {{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/verification/{{.PDK}}/drc/
--jobs {{numCPU}}
cmds:
- "{{.CONTAINER_CHECK}}"
- "{{.RUN}} '{{.DRC_CMD}}'"

run-lvs:
desc: Runs KLayout LVS sign-off for the given ip/macro/PDK.
vars:
ORFS_RESULTS: "{{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/orfs/results/{{.PDK_ORFS}}/{{.macro}}/base"
ORFS_OBJECTS: "{{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/orfs/objects/{{.PDK_ORFS}}/{{.macro}}/base"
LVS_CMD: >-
bash {{.PWD}}/scripts/run_lvs.sh
--gds {{.ORFS_RESULTS}}/6_final.gds
--topcell {{.macro}}
--netlist {{.ORFS_RESULTS}}/6_final.cdl
--netlist-concat {{.ORFS_OBJECTS}}/6_final_concat.cdl
--run-dir {{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/verification/{{.PDK}}/lvs/
cmds:
- "{{.CONTAINER_CHECK}}"
- "{{.RUN}} '{{.LVS_CMD}}'"

run-test:
desc: Runs cocotb simulation tests for the given ip/macro/PDK.
vars:
Expand All @@ -215,46 +134,28 @@ tasks:
cmds:
- "venv/bin/reuse --root {{.PWD}}/sources/{{.ip}}/ lint"

view-drc:
desc: Opens DRC results in KLayout for the given ip/macro/PDK.
vars:
GDS: "{{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/orfs/results/{{.PDK_ORFS}}/{{.macro}}/base/6_final.gds"
DRC_DB: "{{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/verification/{{.PDK}}/drc/{{.macro}}_drc.lyrdb"
cmds:
- "{{.CONTAINER_CHECK}}"
- "{{.RUN}} 'klayout -n {{.TECH}} -e {{.GDS}} -m {{.DRC_DB}}'"

view-lvs:
desc: Opens LVS results in KLayout for the given ip/macro/PDK.
vars:
GDS: "{{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/orfs/results/{{.PDK_ORFS}}/{{.macro}}/base/6_final.gds"
LVS_DB: "{{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/verification/{{.PDK}}/lvs/6_final.lvsdb"
cmds:
- "{{.CONTAINER_CHECK}}"
- "{{.RUN}} 'klayout -n {{.TECH}} -e {{.GDS}} -mn {{.LVS_DB}}'"

view-openroad:
openroad:
desc: Opens the final ODB in the OpenROAD GUI for the given ip/macro/PDK.
vars:
ODB: "{{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/orfs/results/{{.PDK_ORFS}}/{{.macro}}/base/{{if .stage}}{{.stage}}{{else}}6_final{{end}}.odb"
ODB: "{{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/librelane/{{.PDK}}/final/odb/{{.macro}}.odb"
cmds:
- "{{.CONTAINER_CHECK}}"
- "{{.RUN}} '{{.OPENROAD_EXE}} -gui <(echo read_db {{.ODB}})'"

view-klayout:
desc: Opens the final GDS in KLayout for the given ip/macro/PDK.
klayout:
desc: |
Opens the final GDS in KLayout for the given ip/macro/PDK.
Use mode=drc to also load the KLayout DRC marker database.
vars:
GDS: "{{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/orfs/results/{{.PDK_ORFS}}/{{.macro}}/base/6_final.gds"
GDS: "{{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/librelane/{{.PDK}}/final/gds/{{.macro}}.gds"
DRC_DB: "{{.BUILD_ROOT}}/{{.ip}}/{{.macro}}/librelane/{{.PDK}}/65-klayout-drc/reports/drc.klayout.lyrdb"
DRC_FLAG: '{{if eq .mode "drc"}}-m {{.DRC_DB}}{{end}}'
cmds:
- "{{.CONTAINER_CHECK}}"
- "{{.RUN}} 'klayout -n {{.TECH}} -e {{.GDS}}'"
- "{{.RUN}} 'klayout -n {{.TECH}} -e {{.GDS}} {{.DRC_FLAG}}'"

default:
cmds:
- task: build
- task: run-drc
# LVS is not stable yet. Skip for now.
#- task: run-lvs
- task: run-test
- task: check-logs
- task: check-license
6 changes: 2 additions & 4 deletions ipfab/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,11 @@ archive and publish once all macros are ready.

::

# 1. Build the IP with ORFS (produces build/ artefacts)
# 1. Build the IP with LibreLane (produces build/ artefacts)
task ip=digital/peripherals/io/gpio macro=gpio_apb_32b PDK=ihp-sg13g2 build

# 2. Run sign-off (DRC/LVS/simulation)
task ip=digital/peripherals/io/gpio macro=gpio_apb_32b PDK=ihp-sg13g2 run-drc
# 2. Run some checks
task ip=digital/peripherals/io/gpio macro=gpio_apb_32b PDK=ihp-sg13g2 run-test
task ip=digital/peripherals/io/gpio macro=gpio_apb_32b PDK=ihp-sg13g2 check-logs
task ip=digital/peripherals/io/gpio macro=gpio_apb_32b PDK=ihp-sg13g2 check-license

# 3. Package each macro
Expand Down
96 changes: 44 additions & 52 deletions ipfab/ipfab/ipfab.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,10 @@
IPXACT_NS = "http://www.accellera.org/XMLSchema/IPXACT/1685-2014"
XSI_NS = "http://www.w3.org/2001/XMLSchema-instance"

# Map canonical PDK names to their ORFS platform directory names.
_ORFS_PDK_MAP = {
"ihp-sg13g2": "ihp-sg13g2",
"sky130A": "sky130hd",
"gf180mcuD": "gf180",
}

# Map canonical corner names to PDK-specific ORFS output suffixes.
# PDKs not listed here use the defaults (slow/typ/fast).
_CORNER_MAP = {
"gf180mcuD": {"slow": "WC", "typ": "TT", "fast": "BC"},
"gf180mcuD": {"slow": "ss_125C_4v50", "typ": "tt_025C_5v00", "fast": "ff_n40C_5v50"},
"sky130A": {"slow": "ss_100C_1v60", "typ": "tt_025C_1v80", "fast": "ff_n40C_1v95"},
"ihp-sg13g2": {"slow": "slow_1p08V_125C", "typ": "typ_1p20V_25C", "fast": "fast_1p32V_m40C"},
}


Expand Down Expand Up @@ -66,7 +59,7 @@ def _corners(pdk: str) -> dict:


def func_package(args):
"""Assemble a package directory from sources and ORFS build artefacts."""
"""Assemble a package directory from sources and LibreLane build artefacts."""
_check_clean_repo(args.allow_dirty)
git = _git_info()

Expand All @@ -89,7 +82,7 @@ def func_package(args):

print(f"Copying source files from {src_dir}")
shutil.copytree(src_dir, pkg_dir, dirs_exist_ok=True,
ignore=shutil.ignore_patterns("__pycache__", args.pdk))
ignore=shutil.ignore_patterns("__pycache__", args.pdk, *_CORNER_MAP))

pdk_src_dir = src_dir / args.pdk
if pdk_src_dir.is_dir():
Expand All @@ -109,43 +102,46 @@ def _package_macro(pkg_dir, args, macro):
for dir_ in ("gds", "lef", "netlist", "lib", f"reports/{macro}", f"signoff/{macro}"):
(pkg_dir / dir_).mkdir(parents=True, exist_ok=True)

orfs_pdk = args.orfs_pdk or _ORFS_PDK_MAP.get(args.pdk, args.pdk)
report_dir = build_dir / f"orfs/reports/{orfs_pdk}/{macro}/base/"
result_dir = build_dir / f"orfs/results/{orfs_pdk}/{macro}/base/"
object_dir = build_dir / f"orfs/objects/{orfs_pdk}/{macro}/base/"
print(f"Copying build artifacts for {macro} from {result_dir}")
shutil.copy(result_dir / "6_final.gds", pkg_dir / f"gds/{macro}.gds")
shutil.copy(result_dir / f"{macro}.lef", pkg_dir / f"lef/{macro}.lef")
shutil.copy(result_dir / "6_final.v", pkg_dir / f"netlist/{macro}.v")
shutil.copy(result_dir / "6_final.sdc", pkg_dir / f"netlist/{macro}.sdc")
shutil.copy(result_dir / "6_final.spef", pkg_dir / f"netlist/{macro}.spef")
shutil.copy(result_dir / "6_final.cdl", pkg_dir / f"netlist/{macro}.cdl")
final_dir = build_dir / "librelane" / args.pdk / "final"
if not final_dir.is_dir():
raise FileNotFoundError(f"LibreLane final directory not found: {final_dir}")
print(f"Copying build artifacts for {macro} from {final_dir}")
shutil.copy(final_dir / f"gds/{macro}.gds", pkg_dir / f"gds/{macro}.gds")
shutil.copy(final_dir / f"lef/{macro}.lef", pkg_dir / f"lef/{macro}.lef")
shutil.copy(final_dir / f"nl/{macro}.nl.v", pkg_dir / f"netlist/{macro}.v")
shutil.copy(final_dir / f"sdc/{macro}.sdc", pkg_dir / f"netlist/{macro}.sdc")
shutil.copy(final_dir / f"spef/nom/{macro}.nom.spef", pkg_dir / f"netlist/{macro}.spef")
shutil.copy(final_dir / f"spice/{macro}.spice", pkg_dir / f"netlist/{macro}.cdl")
c = _corners(args.pdk)
shutil.copy(result_dir / f"{macro}_{c['slow']}.lib", pkg_dir / f"lib/{macro}_slow.lib")
shutil.copy(result_dir / f"{macro}_{c['typ']}.lib", pkg_dir / f"lib/{macro}_typ.lib")
shutil.copy(result_dir / f"{macro}_{c['fast']}.lib", pkg_dir / f"lib/{macro}_fast.lib")

shutil.copy(report_dir / "6_finish.rpt", pkg_dir / "reports" / macro)
for f in report_dir.rglob("*.webp"):
shutil.copy(f, pkg_dir / "reports" / macro)

verification_dir = build_dir / f"verification/{args.pdk}"
for check in ("drc", "lvs", "test"):
check_src = verification_dir / check
check_dst = pkg_dir / "signoff" / macro / check
if not check_src.is_dir():
continue
check_dst.mkdir(parents=True, exist_ok=True)
if check == "drc":
for f in check_src.glob("*.lyrdb"):
shutil.copy(f, check_dst)
elif check == "lvs":
for f in check_src.glob("*.lvsdb"):
shutil.copy(f, check_dst)
elif check == "test":
results = check_src / "results.xml"
if results.exists():
shutil.copy(results, check_dst)
for name in ("slow", "typ", "fast"):
corner = f"nom_{c[name]}"
shutil.copy(final_dir / f"lib/{corner}/{macro}__{corner}.lib",
pkg_dir / f"lib/{macro}_{name}.lib")

metrics = final_dir / "metrics.json"
if metrics.exists():
shutil.copy(metrics, pkg_dir / "reports" / macro)
render = final_dir / f"render/{macro}.png"
if render.exists():
shutil.copy(render, pkg_dir / "reports" / macro)

librelane_dir = build_dir / "librelane" / args.pdk
signoff_dir = pkg_dir / "signoff" / macro

drc = sorted(librelane_dir.glob("*-klayout-drc/reports/drc.klayout.lyrdb"))
if drc:
(signoff_dir / "drc").mkdir(parents=True, exist_ok=True)
shutil.copy(drc[-1], signoff_dir / "drc")

lvs = sorted(librelane_dir.glob("*-netgen-lvs/reports/lvs.netgen.rpt"))
if lvs:
(signoff_dir / "lvs").mkdir(parents=True, exist_ok=True)
shutil.copy(lvs[-1], signoff_dir / "lvs")

test_results = build_dir / f"verification/{args.pdk}/test/results.xml"
if test_results.exists():
(signoff_dir / "test").mkdir(parents=True, exist_ok=True)
shutil.copy(test_results, signoff_dir / "test")


def _update_manifest(pkg_dir: Path, macro: str, pdk: str,
Expand Down Expand Up @@ -475,10 +471,6 @@ def arguments():

parser_package = subparsers.add_parser("package", parents=[common], help="Package a macro")
parser_package.add_argument("--macro", type=str, required=True)
parser_package.add_argument(
"--orfs-pdk", type=str, default=None,
help="ORFS PDK name if different from --pdk (e.g. gf180mcuD uses orfs-pdk gf180)",
)
parser_package.add_argument(
"--allow-dirty", action="store_true",
help="Allow packaging from a repository with uncommitted changes",
Expand Down
6 changes: 4 additions & 2 deletions manifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ SPDX-License-Identifier: CERN-OHL-W-2.0

<default remote="github" sync-j="8" />

<project name="aesc-silicon/elements-nafarr" path="modules/elements/nafarr" revision="fe097a0d2a26bc4c4d8472d7b3093f82291fa32d" />
<project name="aesc-silicon/elements-zibal" path="modules/elements/zibal" revision="e2d3a60339fcbf6951c8db21d28220e8e9f41cf2" />
<project name="aesc-silicon/elements-nafarr" path="modules/elements/nafarr" revision="2aeca3c25b8beca693c80c4fc0730006faa13cc5" />
<project name="aesc-silicon/elements-zibal" path="modules/elements/zibal" revision="170a70d250f9d6065bee66d0afe6a684475a70ae" />
<project name="SpinalHDL/SpinalCrypto" path="modules/elements/SpinalCrypto" revision="f2a4ae9db5e9434c5589d0651efec8719103498e" />
<project name="SpinalHDL/VexiiRiscv" path="modules/elements/vexiiriscv" revision="03587f948b91f84197ecdbd958ba490977fd5671" />
<project name="aesc-silicon/elements-vexriscv" path="modules/elements/vexriscv" revision="6814d54a341562beb330d407bb9898024367e447" />
<project name="aesc-silicon/OpenROAD-flow-scripts" path="tools/OpenROAD-flow-scripts" revision="e2cedfb48aaa471f6be518eef262ece8fab87827" />
<project name="aesc-silicon/librelane" path="tools/librelane" revision="62261f57ff8663fea71862f7b26a302776e5938c" />
<project name="aesc-silicon/librelane-plugins" path="tools/librelane-plugins" revision="f5476945820f7be95117164a6c0b8824217707c8" />
</manifest>
2 changes: 1 addition & 1 deletion podman-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ volumes:
cache:
services:
elements:
image: docker.io/dnltz/elements:v2.3
image: docker.io/dnltz/elements:v2.6
container_name: ipforge_container
environment:
- DISPLAY=${DISPLAY}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#
# SPDX-License-Identifier: CERN-OHL-W-2.0

create_clock [get_ports clk] -name clk -period 20.0 -waveform {0 10.0}
create_clock [get_ports clk] -name clk -period 30.0 -waveform {0 15.0}
set_ideal_network [get_ports clk]
set_clock_uncertainty 0.15 [get_clocks clk]
set_clock_transition 0.25 [get_clocks clk]
Expand Down
Loading
Loading