Skip to content

Commit f626145

Browse files
authored
Merge pull request #4229 from oharboe/bazel-orfs-update
Bazel orfs update
2 parents 6c587df + 5d5949a commit f626145

16 files changed

Lines changed: 417 additions & 5212 deletions

File tree

.bazelrc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
11
build --incompatible_strict_action_env
22
build --cxxopt "-std=c++20" --host_cxxopt "-std=c++20"
3+
4+
# Don't track MODULE.bazel.lock. Resolved versions ride along with the
5+
# pinned BCR + git_override(commit=…) coordinates in MODULE.bazel and
6+
# downstream cache hits are what we actually care about. Tracking the
7+
# lockfile just means every bazel-orfs / yosys / openroad bump produces
8+
# a 1000-line lock diff that buries the real change. Matches what
9+
# bazel-orfs itself does (its own .bazelrc:7).
10+
common --lockfile_mode=off
11+
312
try-import %workspace%/user.bazelrc

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ bazel-bin
102102
bazel-out
103103
bazel-OpenROAD-flow-scripts
104104
bazel-testlogs
105+
MODULE.bazel.lock
105106

106107
# python venv
107108
venv/

MODULE.bazel

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ bazel_dep(name = "rules_shell", version = "0.6.1")
2020
# time.
2121

2222
bazel_dep(name = "toolchains_llvm", version = "1.5.0", dev_dependency = True)
23-
2423
bazel_dep(name = "openroad", dev_dependency = True)
2524
local_path_override(
2625
module_name = "openroad",
@@ -37,14 +36,23 @@ git_override(
3736
bazel_dep(name = "bazel-orfs", dev_dependency = True)
3837
bazel_dep(name = "bazel-orfs-verilog", dev_dependency = True)
3938

40-
BAZEL_ORFS_COMMIT = "717655415dd4446ca4e2fc09907465c75cb23912"
39+
BAZEL_ORFS_COMMIT = "ce6efd96dfe39a9c4ef244f8712386f071545d77"
4140

4241
BAZEL_ORFS_REMOTE = "https://github.com/The-OpenROAD-Project/bazel-orfs.git"
4342

4443
# To bump version, run: bazelisk run @bazel-orfs//:bump
4544
git_override(
4645
module_name = "bazel-orfs",
4746
commit = BAZEL_ORFS_COMMIT,
47+
patch_strip = 1,
48+
patches = [
49+
# Adds orfs_design(user_sources=[VAR,...]) / orfs_flow(user_sources={...})
50+
# so design-private SOURCE_VARS path hooks (e.g. SDC_FILE_EXTRA in
51+
# flow/designs/asap7/mock-cpu) bypass the variables.yaml validator
52+
# without polluting the ORFS-wide variable schema. Drop once upstream
53+
# bazel-orfs lands the user_sources= API.
54+
"//bazel:0001-orfs_design-add-user_sources.patch",
55+
],
4856
remote = BAZEL_ORFS_REMOTE,
4957
)
5058

@@ -79,7 +87,10 @@ llvm.toolchain(
7987
)
8088
use_repo(llvm, "llvm_toolchain")
8189

82-
register_toolchains("@llvm_toolchain//:all", dev_dependency = True)
90+
register_toolchains(
91+
"@llvm_toolchain//:all",
92+
dev_dependency = True,
93+
)
8394

8495
python = use_extension("@rules_python//python/extensions:python.bzl", "python")
8596
python.toolchain(

MODULE.bazel.lock

Lines changed: 0 additions & 5190 deletions
This file was deleted.
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
From 58df356479d6d9f04aa0bc3ac3676d3b89d26813 Mon Sep 17 00:00:00 2001
2+
From: =?UTF-8?q?=C3=98yvind=20Harboe?= <oyvind@ascenium.com>
3+
Date: Thu, 14 May 2026 18:48:12 +0200
4+
Subject: [PATCH] orfs_design/orfs_flow: add user_sources= for design-private
5+
path hooks
6+
MIME-Version: 1.0
7+
Content-Type: text/plain; charset=UTF-8
8+
Content-Transfer-Encoding: 8bit
9+
10+
Symmetric to user_arguments=, but for source-typed (path-label) vars:
11+
a variable that the config_mk_parser classifies as a SOURCE_VAR (path
12+
staged into the sandbox via _map_source_file) but that is read only
13+
by user-supplied .tcl/.mk and has no entry in ORFS variables.yaml.
14+
15+
Today such a variable bumps into check_variables(sources.keys()) in
16+
orfs_flow and fails the load phase, even though the file itself is
17+
staged correctly. user_arguments= doesn't help because it pops from
18+
arguments, not sources.
19+
20+
The motivating case is SDC_FILE_EXTRA — set by
21+
flow/designs/asap7/mock-cpu/config.mk and source'd from that design's
22+
io.tcl, with no ORFS-side consumer. SDC_FILE_EXTRA is in this file's
23+
SOURCE_VARS list, so its value is path-staged; making it work without
24+
declaring it as a global ORFS variable is what user_sources= is for.
25+
26+
API:
27+
- orfs_design() gains user_sources=[VAR, ...]. Each named var is
28+
popped from sources and forwarded as orfs_flow(user_sources={...}).
29+
- orfs_flow() gains user_sources={VAR: [label, ...]}. Merged into
30+
sources before _orfs_pass so files are still staged, but the key
31+
set skips check_variables. Same shadowing guard as user_arguments=:
32+
collision with a known ORFS variable fails fast.
33+
34+
Mirrors user_arguments= in both surface and intent.
35+
36+
Signed-off-by: Øyvind Harboe <oyvind@ascenium.com>
37+
---
38+
private/flow.bzl | 19 +++++++++++++++++--
39+
private/orfs_design.bzl | 19 ++++++++++++++++++-
40+
2 files changed, 35 insertions(+), 3 deletions(-)
41+
42+
diff --git a/private/flow.bzl b/private/flow.bzl
43+
index fd9001f..b59d059 100644
44+
--- a/private/flow.bzl
45+
+++ b/private/flow.bzl
46+
@@ -171,6 +171,7 @@ def orfs_flow(
47+
verilog_files = [],
48+
macros = [],
49+
sources = {},
50+
+ user_sources = {},
51+
stage_sources = {},
52+
stage_arguments = {},
53+
renamed_inputs = {},
54+
@@ -213,6 +214,12 @@ def orfs_flow(
55+
validating against ORFS variables.yaml. Use for vars read only by user-supplied .tcl/.mk
56+
(e.g. ARRAY_COLS in a project's MACRO_PLACEMENT_TCL). Keys that collide with known ORFS
57+
variables are rejected — route those through 'arguments' instead.
58+
+ user_sources: dictionary of project-specific source-typed (path-label) env vars to expose
59+
+ to every stage without validating against ORFS variables.yaml. The path is still staged
60+
+ into the sandbox like a normal source — only the variable name skips the validator.
61+
+ Use for path hooks read only by user-supplied .tcl/.mk (e.g. an extra-SDC hook
62+
+ source'd from the design's own io.tcl). Keys that collide with known ORFS variables
63+
+ are rejected — route those through 'sources' instead.
64+
extra_arguments: dictionary keyed by ORFS stages with lists of .json argument file labels.
65+
These .json files are merged into the stage config, providing computed arguments
66+
that flow through OrfsInfo to subsequent stages.
67+
@@ -269,6 +276,14 @@ def orfs_flow(
68+
) +
69+
"Use arguments= for ORFS variables; reserve user_arguments= for project-specific env vars.",
70+
)
71+
+ shadowed_srcs = sorted([k for k in user_sources if k in ALL_VARIABLE_TO_STAGES])
72+
+ if shadowed_srcs:
73+
+ fail(
74+
+ "user_sources contains known ORFS variable(s): {shadowed}. ".format(
75+
+ shadowed = ", ".join(shadowed_srcs),
76+
+ ) +
77+
+ "Use sources= for ORFS variables; reserve user_sources= for project-specific path hooks.",
78+
+ )
79+
if abstract_stage and last_stage:
80+
fail("abstract_stage and last_stage are mutually exclusive")
81+
if variant == "base":
82+
@@ -281,7 +296,7 @@ def orfs_flow(
83+
top = top,
84+
verilog_files = verilog_files,
85+
macros = macros,
86+
- sources = sources,
87+
+ sources = sources | user_sources,
88+
stage_sources = stage_sources,
89+
stage_arguments = stage_arguments,
90+
renamed_inputs = renamed_inputs,
91+
@@ -319,7 +334,7 @@ def orfs_flow(
92+
top = top,
93+
verilog_files = verilog_files,
94+
macros = macros,
95+
- sources = sources,
96+
+ sources = sources | user_sources,
97+
stage_sources = stage_sources,
98+
stage_arguments = stage_arguments,
99+
renamed_inputs = {},
100+
diff --git a/private/orfs_design.bzl b/private/orfs_design.bzl
101+
index 554da44..d53d4bd 100644
102+
--- a/private/orfs_design.bzl
103+
+++ b/private/orfs_design.bzl
104+
@@ -47,7 +47,7 @@ def _convert_sources(sources, pkg):
105+
result[var] = converted
106+
return result
107+
108+
-def orfs_design(name = None, config = "config.mk", platform = None, design = None, designs = None, mock_openroad = None, mock_yosys = None, user_arguments = [], local_arguments = []): # buildifier: disable=unused-variable
109+
+def orfs_design(name = None, config = "config.mk", platform = None, design = None, designs = None, mock_openroad = None, mock_yosys = None, user_arguments = [], user_sources = [], local_arguments = []): # buildifier: disable=unused-variable
110+
"""Create orfs_flow() targets for a design based on its parsed config.mk.
111+
112+
Usage:
113+
@@ -79,6 +79,13 @@ def orfs_design(name = None, config = "config.mk", platform = None, design = Non
114+
Routed through orfs_flow(user_arguments=...) to bypass the
115+
variables.yaml validator instead of being checked as known
116+
ORFS arguments.
117+
+ user_sources: List of source-typed variable names (vars in
118+
+ SOURCE_VARS) that are project-specific path hooks read only
119+
+ by user-supplied .tcl/.mk, not by ORFS itself (e.g. a
120+
+ per-design extra-SDC hook source'd from the design's own
121+
+ io.tcl). Routed through orfs_flow(user_sources=...) so the
122+
+ file is still staged into the sandbox, but the variable
123+
+ name bypasses the variables.yaml validator.
124+
local_arguments: List of variable names that are only used for
125+
$(VAR) expansion within the same config.mk and are not read
126+
by ORFS or by any user .tcl/.mk (e.g. VERILOG_FILES_BLACKBOX,
127+
@@ -195,6 +202,15 @@ def orfs_design(name = None, config = "config.mk", platform = None, design = Non
128+
if var in arguments:
129+
user_args[var] = arguments.pop(var)
130+
131+
+ # Same idea for source-typed (path-label) project-specific knobs:
132+
+ # variables that are in SOURCE_VARS (so the parser staged the path
133+
+ # as a label) but are read only by user .tcl/.mk and have no
134+
+ # variables.yaml entry.
135+
+ user_srcs = {}
136+
+ for var in user_sources:
137+
+ if var in sources:
138+
+ user_srcs[var] = sources.pop(var)
139+
+
140+
# Default SYNTH_NUM_PARTITIONS to a static value so that the action graph
141+
# is identical across machines and remote cache hits are possible. Users
142+
# who prefer local parallelism over caching can pass NUM_CPUS explicitly.
143+
@@ -213,6 +229,7 @@ def orfs_design(name = None, config = "config.mk", platform = None, design = Non
144+
arguments = arguments,
145+
user_arguments = user_args,
146+
sources = sources,
147+
+ user_sources = user_srcs,
148+
macros = macros if macros else [],
149+
stage_data = {"synth": extra_data} if extra_data else {},
150+
tags = tags,
151+
--
152+
2.51.0
153+

bazel/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
exports_files(glob(["*.patch"]))

docs/user/FlowVariables.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ configuration file.
173173
| <a name="LEC_AUX_VERILOG_FILES"></a>LEC_AUX_VERILOG_FILES| Additional Verilog files (e.g. blackbox stubs) to include in LEC equivalence checks. Appended to the generated Verilog netlist before running the formal equivalence check.| |
174174
| <a name="LEC_CHECK"></a>LEC_CHECK| Perform a formal equivalence check between before and after netlists. If this fails, report an issue to OpenROAD.| 0|
175175
| <a name="LIB_FILES"></a>LIB_FILES| A Liberty file of the standard cell library with PVT characterization, input and output characteristics, timing and power definitions for each cell.| |
176+
| <a name="LIB_MODEL"></a>LIB_MODEL| Selects between NLDM and CCS timing models for the ASAP7 platform. Valid values: NLDM (default), CCS. Used in flow/platforms/asap7/config.mk to pick the LIB_DIR subdirectory and accumulate the corresponding $(CORNER)_$(LIB_MODEL)_LIB_FILES list, and in flow/scripts/load.tcl to gate CCS-specific Tcl branches.| NLDM|
176177
| <a name="MACRO_BLOCKAGE_HALO"></a>MACRO_BLOCKAGE_HALO| Distance beyond the edges of a macro that will also be covered by the blockage generated for that macro. Note that the default macro blockage halo comes from the largest of the specified MACRO_PLACE_HALO x or y values. This variable overrides that calculation.| |
177178
| <a name="MACRO_EXTENSION"></a>MACRO_EXTENSION| Sets the number of GCells added to the blockages boundaries from macros.| |
178179
| <a name="MACRO_PLACEMENT_TCL"></a>MACRO_PLACEMENT_TCL| Specifies the path of a TCL file on how to place macros manually. The user may choose to place just some of the macros in the design. The macro placer will handle the remaining unplaced macros.| |
@@ -188,6 +189,7 @@ configuration file.
188189
| <a name="MAX_REPAIR_TIMING_ITER"></a>MAX_REPAIR_TIMING_ITER| Maximum number of iterations for repair setup and repair hold.| |
189190
| <a name="MAX_ROUTING_LAYER"></a>MAX_ROUTING_LAYER| The highest metal layer name to be used in routing.| |
190191
| <a name="MIN_BUF_CELL_AND_PORTS"></a>MIN_BUF_CELL_AND_PORTS| Used to insert a buffer cell to pass through wires. Used in synthesis.| |
192+
| <a name="MIN_CLK_ROUTING_LAYER"></a>MIN_CLK_ROUTING_LAYER| The lowest metal layer name to be used for clock-net routing in global routing. Used in flow/platforms/*/fastroute.tcl as the lower bound of `set_routing_layers -clock`. Typically higher than MIN_ROUTING_LAYER so clock nets prefer the upper, lower-RC layers. No `stages:` list because floorplan.tcl also `source`s the platform fastroute.tcl.| |
191193
| <a name="MIN_PLACE_STEP_COEF"></a>MIN_PLACE_STEP_COEF| Sets the minimum phi coefficient (pcof_min / µ_k Lower Bound) for global placement optimization. This parameter controls the step size lower bound in the RePlAce Nesterov optimization algorithm. Lower values may improve convergence but can increase runtime. Valid range: 0.95-1.05| 0.95|
192194
| <a name="MIN_ROUTING_LAYER"></a>MIN_ROUTING_LAYER| The lowest metal layer name to be used in routing.| |
193195
| <a name="NUM_CORES"></a>NUM_CORES| Passed to `openroad -threads $(NUM_CORES)`, defaults to numbers of cores in system as determined by system specific code in Makefile, `nproc` is tried first. OpenROAD does not limit itself to this number of cores across OpenROAD running instances, which can lead to overprovisioning in contexts such as bazel-orfs where there could be many routing, or place jobs running at the same time.| |
@@ -643,7 +645,9 @@ configuration file.
643645
- [KLAYOUT_TECH_FILE](#KLAYOUT_TECH_FILE)
644646
- [LAYER_PARASITICS_FILE](#LAYER_PARASITICS_FILE)
645647
- [LIB_FILES](#LIB_FILES)
648+
- [LIB_MODEL](#LIB_MODEL)
646649
- [MACRO_EXTENSION](#MACRO_EXTENSION)
650+
- [MIN_CLK_ROUTING_LAYER](#MIN_CLK_ROUTING_LAYER)
647651
- [PLATFORM](#PLATFORM)
648652
- [PLATFORM_TCL](#PLATFORM_TCL)
649653
- [PROCESS](#PROCESS)

flow/BUILD

Lines changed: 97 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
load("@bazel-orfs//:openroad.bzl", "orfs_pdk")
22

3+
# Expose every individual file under platforms/ as a public source-file
4+
# target, so designs in other packages can refer to e.g.
5+
# //flow:platforms/asap7/verilog/fakeram7_64x28.sv directly. This is the
6+
# label form bazel-orfs's config_mk_parser produces for VERILOG_FILES /
7+
# ADDITIONAL_LEFS / ADDITIONAL_LIBS that point at platform-provided files.
8+
# Exclude package BUILD files so they aren't claimed as source labels by
9+
# any future sub-package under platforms/.
10+
exports_files(
11+
glob(
12+
["platforms/**/*"],
13+
exclude = [
14+
"platforms/**/BUILD",
15+
"platforms/**/BUILD.bazel",
16+
],
17+
),
18+
visibility = ["//visibility:public"],
19+
)
20+
321
# files shared between scripts/synth.sh and scripts/flow.sh steps
422
MAKEFILE_SHARED = [
523
"scripts/variables.json",
@@ -47,27 +65,96 @@ filegroup(
4765
pdk = pdk,
4866
)
4967
for ext in {
50-
"asap7": ["cfg", "gds", "lef", "lib", "lib.gz", "lyt", "mk", "rules", "sdc", "sv", "tcl", "v"],
51-
"gf180": ["cfg", "gds", "lef", "lib.gz", "lyt", "mk", "rules", "tcl", "v"],
52-
"ihp-sg13g2": ["gds", "json", "lef", "lib", "lyt", "mk", "rules", "tcl", "v"],
53-
"nangate45": ["cfg", "gds", "lef", "lib", "lyt", "mk", "rules", "tcl", "v"],
54-
"sky130hd": ["gds", "lef", "lib", "lyt", "mk", "rules", "tcl", "tlef", "v"],
55-
"sky130hs": ["gds", "lef", "lib", "lyt", "mk", "rules", "tcl", "tlef", "v"],
68+
"asap7": [
69+
"cfg",
70+
"gds",
71+
"lef",
72+
"lib",
73+
"lib.gz",
74+
"lyt",
75+
"mk",
76+
"rules",
77+
"sdc",
78+
"sv",
79+
"tcl",
80+
"v",
81+
],
82+
"gf180": [
83+
"cfg",
84+
"gds",
85+
"lef",
86+
"lib.gz",
87+
"lyt",
88+
"mk",
89+
"rules",
90+
"tcl",
91+
"v",
92+
],
93+
"ihp-sg13g2": [
94+
"gds",
95+
"json",
96+
"lef",
97+
"lib",
98+
"lyt",
99+
"mk",
100+
"rules",
101+
"tcl",
102+
"v",
103+
],
104+
"nangate45": [
105+
"cfg",
106+
"gds",
107+
"lef",
108+
"lib",
109+
"lyt",
110+
"mk",
111+
"rules",
112+
"tcl",
113+
"v",
114+
],
115+
"sky130hd": [
116+
"gds",
117+
"lef",
118+
"lib",
119+
"lyt",
120+
"mk",
121+
"rules",
122+
"tcl",
123+
"tlef",
124+
"v",
125+
],
126+
"sky130hs": [
127+
"gds",
128+
"lef",
129+
"lib",
130+
"lyt",
131+
"mk",
132+
"rules",
133+
"tcl",
134+
"tlef",
135+
"v",
136+
],
56137
}.get(pdk, [])
57138
] + [
58139
"platforms/common/**/*.v",
59140
]),
141+
config = ":platforms/{pdk}/config.mk".format(pdk = pdk),
60142
libs = glob([
61143
"platforms/{pdk}/**/*.{ext}".format(
62-
pdk = pdk,
63144
ext = ext,
145+
pdk = pdk,
64146
)
65147
for ext in {
66-
"asap7": ["lib", "lib.gz"],
148+
"asap7": [
149+
"lib",
150+
"lib.gz",
151+
],
67152
"gf180": ["lib.gz"],
68-
}.get(pdk, ["lib"])
153+
}.get(
154+
pdk,
155+
["lib"],
156+
)
69157
]),
70-
config = ":platforms/{pdk}/config.mk".format(pdk = pdk),
71158
visibility = ["//visibility:public"],
72159
) for pdk in [
73160
"asap7",

flow/designs/asap7/mock-alu/BUILD

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
load("//flow/designs:design.bzl", "design")
22

3-
design(config = "config.mk")
3+
design(
4+
config = "config.mk",
5+
user_arguments = [
6+
"MOCK_ALU_OPERATIONS",
7+
"MOCK_ALU_WIDTH",
8+
],
9+
)

0 commit comments

Comments
 (0)