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
24 changes: 22 additions & 2 deletions private/flow.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,14 @@ load(
"orfs_squashed",
"orfs_synth_rule",
)
load("//private:stages.bzl", "STAGE_METADATA", "check_variables", "get_sources", "get_stage_args")
load(
"//private:stages.bzl",
"ALL_VARIABLE_TO_STAGES",
"STAGE_METADATA",
"check_variables",
"get_sources",
"get_stage_args",
)

# Stages with an ODB that open.tcl can load for web_save_report.
_HTML_STAGES = ["floorplan", "place", "cts", "grt", "route", "final"]
Expand Down Expand Up @@ -167,6 +174,7 @@ def orfs_flow(
stage_arguments = {},
renamed_inputs = {},
arguments = {},
user_arguments = {},
extra_arguments = {},
extra_configs = {},
abstract_stage = None,
Expand Down Expand Up @@ -198,6 +206,10 @@ def orfs_flow(
Use stage_arguments only to override the automatic stage assignment.
renamed_inputs: dictionary keyed by ORFS stages to rename inputs
arguments: dictionary of additional arguments to the flow, automatically assigned to stages
user_arguments: dictionary of project-specific env vars to expose to every stage without
validating against ORFS variables.yaml. Use for vars read only by user-supplied .tcl/.mk
(e.g. ARRAY_COLS in a project's MACRO_PLACEMENT_TCL). Keys that collide with known ORFS
variables are rejected — route those through 'arguments' instead.
extra_arguments: dictionary keyed by ORFS stages with lists of .json argument file labels.
These .json files are merged into the stage config, providing computed arguments
that flow through OrfsInfo to subsequent stages.
Expand Down Expand Up @@ -229,6 +241,14 @@ def orfs_flow(
"""
check_variables(arguments.keys(), "arguments")
check_variables(sources.keys(), "sources")
shadowed = sorted([k for k in user_arguments if k in ALL_VARIABLE_TO_STAGES])
if shadowed:
fail(
"user_arguments contains known ORFS variable(s): {shadowed}. ".format(
shadowed = ", ".join(shadowed),
) +
"Use arguments= for ORFS variables; reserve user_arguments= for project-specific env vars.",
)
if abstract_stage and last_stage:
fail("abstract_stage and last_stage are mutually exclusive")
if variant == "base":
Expand All @@ -245,7 +265,7 @@ def orfs_flow(
stage_sources = stage_sources,
stage_arguments = stage_arguments,
renamed_inputs = renamed_inputs,
arguments = arguments,
arguments = arguments | user_arguments,
extra_arguments = extra_arguments,
extra_configs = extra_configs,
abstract_stage = abstract_stage,
Expand Down
24 changes: 24 additions & 0 deletions test/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,30 @@ orfs_flow(
verilog_files = LB_VERILOG_FILES,
)

# Exercises user_arguments: project-specific env vars that intentionally
# bypass the variables.yaml spell-check. Loading this target proves the
# feature works; `bazelisk test //...` picks it up via build_test below.
# buildifier: disable=duplicated-name
orfs_flow(
name = "lb_32x128",
arguments = LB_ARGS,
last_stage = "floorplan",
openroad = "//mock/openroad/src/bin:openroad",
previous_stage = {"floorplan": ":lb_32x128_synth"},
stage_sources = LB_STAGE_SOURCES,
user_arguments = {
"ARRAY_COLS": "4",
"USER_PROJECT_KNOB": "42",
},
variant = "user_args",
verilog_files = LB_VERILOG_FILES,
)

build_test(
name = "lb_32x128_user_args_build_test",
targets = [":lb_32x128_user_args_floorplan"],
)

# Pin placement generation: shares synth, runs own floorplan without pinned IO.
# buildifier: disable=duplicated-name
orfs_flow(
Expand Down
9 changes: 9 additions & 0 deletions test/spelling_error/test_spelling_errors.sh
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ expect_failure multiple_typos "CORE_UTILIZATON, PLACE_DENSTY"
# Control: valid variables load fine
expect_success valid

# user_arguments bypasses the spell-check for project-specific env vars
expect_success user_args_pass

# user_arguments refuses to shadow a known ORFS variable
expect_failure user_args_shadow "user_arguments contains known ORFS variable(s): CORE_UTILIZATION"

# Multiple shadowed vars are listed sorted in the error
expect_failure user_args_multiple_shadow "CORE_UTILIZATION, PLACE_DENSITY"

echo
echo "=== Results: ${pass} passed, ${fail} failed ==="
[ "$fail" -eq 0 ]
13 changes: 13 additions & 0 deletions test/spelling_error/user_args_multiple_shadow/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Multiple known ORFS variables placed in user_arguments.
# Expected: both are listed, sorted, in the shadow error.

load("@bazel-orfs//:openroad.bzl", "orfs_flow")

orfs_flow(
name = "user_args_multiple_shadow",
user_arguments = {
"PLACE_DENSITY": "0.5",
"CORE_UTILIZATION": "20",
},
verilog_files = ["//:rtl/dummy.v"],
)
16 changes: 16 additions & 0 deletions test/spelling_error/user_args_pass/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# user_arguments bypasses variables.yaml spell-check.
# Expected: package loads without errors.

load("@bazel-orfs//:openroad.bzl", "orfs_flow")

orfs_flow(
name = "user_args_pass",
arguments = {
"CORE_UTILIZATION": "20",
},
user_arguments = {
"MY_PROJECT_KNOB": "42",
"ARRAY_COLS": "4",
},
verilog_files = ["//:rtl/dummy.v"],
)
12 changes: 12 additions & 0 deletions test/spelling_error/user_args_shadow/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# user_arguments must not shadow a known ORFS variable.
# Expected error: user_arguments contains known ORFS variable(s): CORE_UTILIZATION

load("@bazel-orfs//:openroad.bzl", "orfs_flow")

orfs_flow(
name = "user_args_shadow",
user_arguments = {
"CORE_UTILIZATION": "20",
},
verilog_files = ["//:rtl/dummy.v"],
)
Loading