Skip to content
Closed
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
14 changes: 14 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,20 @@ register_toolchains(
dev_dependency = True,
)

# sv-lang (via tools/OpenROAD) pulls in rules_pycross, whose toolchain
# extension fails on Python 3.8 (transitively registered via or-tools ->
# pybind11_abseil, dropped from rules_python 2.0.0's MINOR_MAPPING).
# pycross.configure_environments is root-honored only, so the workaround
# must be mirrored here from tools/OpenROAD/MODULE.bazel.
bazel_dep(name = "rules_pycross", version = "0.8.1", dev_dependency = True)

pycross = use_extension(
"@rules_pycross//pycross/extensions:pycross.bzl",
"pycross",
dev_dependency = True,
)
pycross.configure_environments(python_versions = ["3.13"])

python = use_extension("@rules_python//python/extensions:python.bzl", "python")
python.toolchain(
ignore_root_user_error = True,
Expand Down
142 changes: 141 additions & 1 deletion flow/designs/asap7/gcd/BUILD
Original file line number Diff line number Diff line change
@@ -1,3 +1,143 @@
load("@bazel-orfs//:openroad.bzl", "orfs_run")
load("@orfs_designs//:designs.bzl", "DESIGNS")
load("@rules_shell//shell:sh_test.bzl", "sh_test")
load("//flow/designs:design.bzl", "design")

design(config = "config.mk")
# SYNTH_USE_SYN is make-only for now: bazel-orfs's synth stage always
# runs the yosys flow and neither stages the Verilog sources nor sets
# VERILOG_FILES for the OpenROAD synthesis step, so the built-in
# synthesizer opt-in must not reach the bazel arguments.
design(
config = "config.mk",
local_arguments = ["SYNTH_USE_SYN"],
)

# Stage-boundary .odb/.sdc stems shared by the normal per-stage flow
# targets and the single-process flow below; gcd_single_flow_test
# compares each of these files pairwise between the two flows.
SINGLE_FLOW_STAGES = {
"floorplan": "2_floorplan",
"place": "3_place",
"cts": "4_cts",
"grt": "5_1_grt",
"route": "5_route",
"final": "6_final",
}

# Substep files the single-process flow also writes, declared so the
# action keeps them and a human can inspect them on failure.
SINGLE_FLOW_EXTRA_OUTS = [
"2_1_floorplan.odb",
"2_1_floorplan.sdc",
"2_2_floorplan_macro.odb",
"2_3_floorplan_tapcell.odb",
"2_4_floorplan_pdn.odb",
"3_1_place_gp_skip_io.odb",
"3_2_place_iop.odb",
"3_3_place_gp.odb",
"3_4_place_resized.odb",
"3_5_place_dp.odb",
"4_1_cts.odb",
"5_2_route.odb",
"5_3_fillcell.odb",
"6_1_fill.odb",
"6_1_fill.sdc",
]

# The whole flow, floorplan through finish, as one Tcl script in a
# single OpenROAD process (scripts/flow.tcl). The synth stage config
# only carries synth-scoped variables, so the design's full argument
# set rides along; FLOW_VARIANT=single keeps the output paths clear of
# the regular stage targets' declared outputs in this package.
orfs_run(
name = "gcd_single_flow",
src = ":gcd_synth",
outs = [
"results/asap7/gcd/single/{}.{}".format(stem, ext)
for stem in SINGLE_FLOW_STAGES.values()
for ext in [
"odb",
"sdc",
]
] + [
"results/asap7/gcd/single/" + name
for name in SINGLE_FLOW_EXTRA_OUTS
],
arguments = {
k: v
for k, v in DESIGNS["asap7/gcd"]["arguments"].items()
if k != "SYNTH_USE_SYN"
} | {
"FLOW_VARIANT": "single",
},
script = ":single_flow.tcl",
variant = "single",
)

# Normal-flow stage outputs, one filegroup per compared file.
[
filegroup(
name = "gcd_base_{}_{}".format(stage, ext),
srcs = [":gcd_" + stage],
output_group = "{}.{}".format(stem, ext),
)
for stage, stem in SINGLE_FLOW_STAGES.items()
for ext in [
"odb",
"sdc",
]
]

# Byte-compare each stage boundary's .odb/.sdc between the per-stage
# flow and the single-process flow: equal files prove the
# single-process mode is equivalent to the per-stage flow, not merely
# that it runs to completion. check_same.sh takes file pairs:
# file_a file_b ... (.sdc pair first: check_same.sh stops at a binary
# diff, and the .sdc verdict should be reported before that).
#
# Known divergence, deliberately left failing so it gets root-caused
# rather than papered over: from the grt stage on, the grt-stage
# repair_timing inserts one extra buffer (8 vs 7 on asap7/gcd) when the
# process continues from the in-memory CTS state instead of reloading
# 4_cts.odb, even though the 4_cts.odb/.sdc it starts from are
# byte-identical (all .sdc match through the whole flow).
[
sh_test(
name = "gcd_single_flow_{}_test".format(stage),
srcs = ["@openroad//test/orfs:check_same.sh"],
args = [
arg
for ext in [
"sdc",
"odb",
]
for arg in [
"$(location :gcd_base_{}_{})".format(stage, ext),
"$(location :results/asap7/gcd/single/{}.{})".format(stem, ext),
]
],
data = [
":gcd_base_{}_{}".format(stage, ext)
for ext in [
"sdc",
"odb",
]
] + [
":results/asap7/gcd/single/{}.{}".format(stem, ext)
for ext in [
"sdc",
"odb",
]
],
tags = ["orfs"],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The grt, route, and final stages are known to diverge and are intended to be kept as manual test targets so they do not run and fail during wildcard test execution (e.g., bazel test //...). However, they are currently missing the manual tag. Adding the manual tag to these stages will prevent them from running automatically.

Suggested change
tags = ["orfs"],
tags = ["orfs"] + (["manual"] if stage in ["grt", "route", "final"] else []),

)
for stage, stem in SINGLE_FLOW_STAGES.items()
]

test_suite(
name = "gcd_single_flow_test",
tests = [
":gcd_single_flow_{}_test".format(stage)
for stage in SINGLE_FLOW_STAGES
],
)
Comment on lines +137 to +143

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The gcd_single_flow_test suite currently includes all stages, including the diverging grt, route, and final stages. This causes the test suite to fail. To ensure the test suite only runs and enforces the passing stages (floorplan, place, cts), we should exclude the manual/diverging stages from the suite.

Suggested change
test_suite(
name = "gcd_single_flow_test",
tests = [
":gcd_single_flow_{}_test".format(stage)
for stage in SINGLE_FLOW_STAGES
],
)
test_suite(
name = "gcd_single_flow_test",
tests = [
":gcd_single_flow_{}_test".format(stage)
for stage in SINGLE_FLOW_STAGES
if stage not in ["grt", "route", "final"]
],
)

10 changes: 10 additions & 0 deletions flow/designs/asap7/gcd/single_flow.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Seed this variant's results dir with the synthesis outputs, then run
# the whole flow in this single OpenROAD process. Under bazel-orfs the
# synthesis results are staged in the src stage's variant folder and
# exposed via ODB_FILE, while RESULTS_DIR points at this run's own
# variant folder.
file mkdir $::env(RESULTS_DIR)
file copy -force $::env(ODB_FILE) $::env(RESULTS_DIR)/1_synth.odb
file copy -force [file rootname $::env(ODB_FILE)].sdc $::env(RESULTS_DIR)/1_synth.sdc

source $::env(SCRIPTS_DIR)/flow.tcl
41 changes: 41 additions & 0 deletions flow/scripts/flow.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Runs all OpenROAD stages of the flow, from 1_synth.odb/.sdc through
# the final report, in a single OpenROAD process. Produces the same
# .odb/.sdc files in $RESULTS_DIR as the stage-per-process make flow:
# the file copy -force lines mirror the Makefile do-copy recipes.

# Enable keeping variables between stages
set ::env(KEEP_VARS) 1

# Floorplan
source $::env(SCRIPTS_DIR)/floorplan.tcl
source $::env(SCRIPTS_DIR)/macro_place.tcl
source $::env(SCRIPTS_DIR)/tapcell.tcl
source $::env(SCRIPTS_DIR)/pdn.tcl
file copy -force $::env(RESULTS_DIR)/2_4_floorplan_pdn.odb $::env(RESULTS_DIR)/2_floorplan.odb
file copy -force $::env(RESULTS_DIR)/2_1_floorplan.sdc $::env(RESULTS_DIR)/2_floorplan.sdc

# Place
source $::env(SCRIPTS_DIR)/global_place_skip_io.tcl
source $::env(SCRIPTS_DIR)/io_placement.tcl
source $::env(SCRIPTS_DIR)/global_place.tcl
source $::env(SCRIPTS_DIR)/resize.tcl
source $::env(SCRIPTS_DIR)/detail_place.tcl
file copy -force $::env(RESULTS_DIR)/3_5_place_dp.odb $::env(RESULTS_DIR)/3_place.odb
file copy -force $::env(RESULTS_DIR)/2_floorplan.sdc $::env(RESULTS_DIR)/3_place.sdc

# CTS (cts.tcl itself writes 4_cts.sdc)
source $::env(SCRIPTS_DIR)/cts.tcl
file copy -force $::env(RESULTS_DIR)/4_1_cts.odb $::env(RESULTS_DIR)/4_cts.odb

# Route
source $::env(SCRIPTS_DIR)/global_route.tcl
source $::env(SCRIPTS_DIR)/detail_route.tcl
source $::env(SCRIPTS_DIR)/fillcell.tcl
file copy -force $::env(RESULTS_DIR)/5_3_fillcell.odb $::env(RESULTS_DIR)/5_route.odb
file copy -force $::env(RESULTS_DIR)/5_1_grt.sdc $::env(RESULTS_DIR)/5_route.sdc

# Finish
source $::env(SCRIPTS_DIR)/density_fill.tcl
file copy -force $::env(RESULTS_DIR)/5_route.sdc $::env(RESULTS_DIR)/6_1_fill.sdc
file copy -force $::env(RESULTS_DIR)/5_route.sdc $::env(RESULTS_DIR)/6_final.sdc
source $::env(SCRIPTS_DIR)/final_report.tcl
Comment thread
oharboe marked this conversation as resolved.