Skip to content

Commit

Permalink
openroad.bzl: Add orfs_canonicalize stage
Browse files Browse the repository at this point in the history
Signed-off-by: Eryk Szpotanski <[email protected]>
  • Loading branch information
eszpotanski committed Aug 13, 2024
1 parent 03d45fe commit 41a7844
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 38 deletions.
2 changes: 1 addition & 1 deletion BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ orfs_flow(

orfs_flow(
name = "L1MetadataArray",
abstract_stage = "route",
# abstract_stage = "route",
macros = ["tag_array_64x184_generate_abstract"],
stage_args = {
"synth": {
Expand Down
129 changes: 92 additions & 37 deletions openroad.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ OrfsDepInfo = provider(
],
)

CanonicalizeInfo = provider(
"The canonicalized synthesis input",
fields = ["rtlil"],
)

def _pdk_impl(ctx):
return [
DefaultInfo(
Expand Down Expand Up @@ -94,7 +99,7 @@ def _run_impl(ctx):
"ODB_FILE": ctx.attr.src[OrfsInfo].odb.path,
"TCL_LIBRARY": commonpath(ctx.files._tcl),
"GUI_ARGS": "-exit",
"GUI_SOURCE": ctx.file.script.path
"GUI_SOURCE": ctx.file.script.path,
},
inputs = depset(
ctx.files.src +
Expand Down Expand Up @@ -267,15 +272,6 @@ def flow_attrs():

def yosys_only_attrs():
return {
"verilog_files": attr.label_list(
allow_files = [
".v",
".sv",
],
allow_rules = [
],
providers = [DefaultInfo],
),
"deps": attr.label_list(
default = [],
providers = [OrfsInfo, TopInfo],
Expand Down Expand Up @@ -397,16 +393,26 @@ def _config_content(args):
def _data_arguments(ctx):
return {k: ctx.expand_location(v, ctx.attr.data) for k, v in ctx.attr.arguments.items()}

def _synth_impl(ctx):
def _yosys_impl(ctx, canonicalize):
all_arguments = _data_arguments(ctx) | _required_arguments(ctx) | _orfs_arguments(*[dep[OrfsInfo] for dep in ctx.attr.deps]) | _verilog_arguments(ctx) | _block_arguments(ctx)
config = ctx.actions.declare_file("results/{}/{}/base/1_synth.mk".format(_platform(ctx), _module_top(ctx)))
result_dir = "results/{}/{}/base/".format(_platform(ctx), _module_top(ctx))
config = ctx.actions.declare_file(result_dir + ("1_canonicalize.mk" if canonicalize else "1_synth.mk"))
ctx.actions.write(
output = config,
content = _config_content(all_arguments),
)

out = ctx.actions.declare_file("results/{}/{}/base/1_synth.v".format(_platform(ctx), _module_top(ctx)))
sdc = ctx.actions.declare_file("results/{}/{}/base/1_synth.sdc".format(_platform(ctx), _module_top(ctx)))
if canonicalize:
verilog_files = ctx.files.verilog_files
rtlil = []
out = [ctx.actions.declare_file(result_dir + "1_synth.rtlil")]
else:
verilog_files = []
rtlil = [ctx.attr.canonicalized[CanonicalizeInfo].rtlil]
out = [
ctx.actions.declare_file(result_dir + "1_synth.v"),
ctx.actions.declare_file(result_dir + "1_synth.sdc"),
]

transitive_inputs = [
ctx.attr.pdk[PdkInfo].files,
Expand All @@ -425,19 +431,28 @@ def _synth_impl(ctx):
transitive_inputs.append(datum.default_runfiles.files)
transitive_inputs.append(datum.default_runfiles.symlinks)

work_home = "/".join([ctx.genfiles_dir.path, ctx.label.package])
ctx.actions.run(
arguments = ["--file", ctx.file._makefile.path, "synth"],
arguments = ["--file", ctx.file._makefile.path] + (
["do-yosys-canonicalize"] if canonicalize else [
"yosys-dependencies",
"do-yosys",
"do-synth",
work_home + "/" + result_dir + "1_synth.sdc",
]
),
executable = "make",
env = {
"HOME": "/".join([ctx.genfiles_dir.path, ctx.label.package]),
"WORK_HOME": "/".join([ctx.genfiles_dir.path, ctx.label.package]),
"WORK_HOME": work_home,
"FLOW_HOME": ctx.file._makefile.dirname,
"DESIGN_CONFIG": config.path,
"ABC": ctx.executable._abc.path,
"YOSYS_CMD": ctx.executable._yosys.path,
},
inputs = depset(
ctx.files.verilog_files +
rtlil +
verilog_files +
ctx.files.data +
[
config,
Expand All @@ -447,28 +462,28 @@ def _synth_impl(ctx):
],
transitive = transitive_inputs,
),
outputs = [out, sdc],
outputs = out,
)

config_short = ctx.actions.declare_file("results/{}/{}/base/1_synth.short.mk".format(_platform(ctx), _module_top(ctx)))
config_short = ctx.actions.declare_file(result_dir + ("1_canonicalize.short.mk" if canonicalize else "1_synth.short.mk"))
ctx.actions.write(
output = config_short,
content = _config_content(_data_arguments(ctx) | _required_arguments(ctx) | _block_arguments(ctx) | _orfs_arguments(short = True, *[dep[OrfsInfo] for dep in ctx.attr.deps]) | _verilog_arguments(ctx, short = True)),
)

make = ctx.actions.declare_file("make_1_synth")
make = ctx.actions.declare_file("make_1_{}".format("canonicalize" if canonicalize else "synth"))
ctx.actions.expand_template(
template = ctx.file._make_template,
output = make,
substitutions = flow_substitutions(ctx) | yosys_substitutions(ctx) | {'"$@"': 'WORK_HOME="./{}" DESIGN_CONFIG="config.mk" "$@"'.format(ctx.label.package)},
substitutions = flow_substitutions(ctx) | yosys_substitutions(ctx) | {'"$@"': 'WORK_HOME="./{}" DESIGN_CONFIG="config.mk" {} "$@"'.format(ctx.label.package, "yosys-dependencies" if not canonicalize else "")},
)

exe = ctx.actions.declare_file(ctx.attr.name + ".sh")
ctx.actions.expand_template(
template = ctx.file._deploy_template,
output = exe,
substitutions = {
"${GENFILES}": " ".join([f.short_path for f in [out, sdc, config_short] + ctx.files.verilog_files + ctx.files.data]),
"${GENFILES}": " ".join([f.short_path for f in out + [config_short] + verilog_files + ctx.files.data]),
"${CONFIG}": config_short.short_path,
"${MAKE}": make.short_path,
},
Expand All @@ -478,34 +493,34 @@ def _synth_impl(ctx):
DefaultInfo(
executable = exe,
files = depset(
[out, sdc] + [dep[OrfsInfo].gds for dep in ctx.attr.deps if dep[OrfsInfo].gds] +
out + [dep[OrfsInfo].gds for dep in ctx.attr.deps if dep[OrfsInfo].gds] +
[dep[OrfsInfo].lef for dep in ctx.attr.deps if dep[OrfsInfo].lef] +
[dep[OrfsInfo].lib for dep in ctx.attr.deps if dep[OrfsInfo].lib],
),
runfiles = ctx.runfiles(
[out, sdc, config_short, make, ctx.executable._yosys, ctx.file._makefile] +
ctx.files.verilog_files + ctx.files.data,
out + [config_short, make, ctx.executable._yosys, ctx.file._makefile] +
verilog_files + rtlil + ctx.files.data,
transitive_files = depset(transitive = transitive_inputs),
),
),
OutputGroupInfo(
deps = depset(
[config] + ctx.files.verilog_files + ctx.files.data +
[config] + verilog_files + rtlil + ctx.files.data +
[dep[OrfsInfo].gds for dep in ctx.attr.deps if dep[OrfsInfo].gds] +
[dep[OrfsInfo].lef for dep in ctx.attr.deps if dep[OrfsInfo].lef] +
[dep[OrfsInfo].lib for dep in ctx.attr.deps if dep[OrfsInfo].lib],
),
logs = depset([]),
reports = depset([]),
**{f.basename: depset([f]) for f in [config, out, sdc]}
**{f.basename: depset([f]) for f in [config] + out}
),
OrfsDepInfo(
make = make,
config = config_short,
files = [config_short] + ctx.files.verilog_files + ctx.files.data,
files = [config_short] + verilog_files + rtlil + ctx.files.data,
runfiles = ctx.runfiles(transitive_files = depset(
[config_short, make, ctx.executable._yosys, ctx.file._makefile] +
ctx.files.verilog_files + ctx.files.data,
verilog_files + rtlil + ctx.files.data,
transitive = transitive_inputs,
)),
),
Expand All @@ -522,11 +537,36 @@ def _synth_impl(ctx):
TopInfo(
module_top = ctx.attr.module_top,
),
]
] + ([
CanonicalizeInfo(rtlil = out[0]),
] if canonicalize else [])

orfs_canonicalize = rule(
implementation = lambda ctx: _yosys_impl(ctx, True),
attrs = yosys_attrs() | {
"verilog_files": attr.label_list(
allow_files = [
".v",
".sv",
".rtlil",
],
allow_rules = [],
providers = [DefaultInfo],
),
},
provides = [DefaultInfo, OutputGroupInfo, OrfsDepInfo, OrfsInfo, PdkInfo, TopInfo, CanonicalizeInfo],
executable = True,
)

orfs_synth = rule(
implementation = _synth_impl,
attrs = yosys_attrs(),
implementation = lambda ctx: _yosys_impl(ctx, False),
attrs = yosys_attrs() | {
"canonicalized": attr.label(
doc = "The canonicalized input of the synthesis",
mandatory = True,
providers = [CanonicalizeInfo],
),
},
provides = [DefaultInfo, OutputGroupInfo, OrfsDepInfo, OrfsInfo, PdkInfo, TopInfo],
executable = True,
)
Expand Down Expand Up @@ -624,7 +664,7 @@ def _make_impl(ctx, stage, steps, result_names = [], object_names = [], log_name
ctx.actions.expand_template(
template = ctx.file._make_template,
output = make,
substitutions = flow_substitutions(ctx) | openroad_substitutions(ctx) | {'"$@"': 'WORK_HOME="./{}" DESIGN_CONFIG="config.mk" "$@"'.format(ctx.label.package)},
substitutions = flow_substitutions(ctx) | openroad_substitutions(ctx) | {'"$@"': 'WORK_HOME="./{}" DESIGN_CONFIG="config.mk" "$@"'.format(ctx.label.package)}, # , '"${STAGE_MAKE}"': ctx.attr.
)

exe = ctx.actions.declare_file(ctx.attr.name + ".sh")
Expand Down Expand Up @@ -828,6 +868,7 @@ orfs_abstract = rule(
)

STAGE_IMPLS = [
struct(stage = "canonicalize", impl = orfs_canonicalize),
struct(stage = "synth", impl = orfs_synth),
struct(stage = "floorplan", impl = orfs_floorplan),
struct(stage = "place", impl = orfs_place),
Expand Down Expand Up @@ -865,18 +906,32 @@ def orfs_flow(
break
steps.append(ABSTRACT_IMPL)

synth_step = steps[0]
canonicalize_step = steps[0]
canonicalize_step.impl(
name = "{}_{}".format(name, "canonicalize"),
arguments = stage_args.get(canonicalize_step.stage, {}),
data = stage_sources.get(canonicalize_step.stage, []),
deps = macros,
module_top = name,
verilog_files = verilog_files,
visibility = visibility,
)
orfs_deps(
name = "{}_{}_deps".format(name, canonicalize_step.stage),
src = "{}_{}".format(name, canonicalize_step.stage),
)

synth_step = steps[1]
synth_step.impl(
name = "{}_{}".format(name, synth_step.stage),
arguments = stage_args.get(synth_step.stage, {}),
data = stage_sources.get(synth_step.stage, []),
deps = macros,
canonicalized = "{}_{}".format(name, canonicalize_step.stage),
module_top = name,
verilog_files = verilog_files,
visibility = visibility,
)

for step, prev in zip(steps[1:], steps):
for step, prev in zip(steps[2:], steps[1:]):
step.impl(
name = "{}_{}".format(name, step.stage),
src = "{}_{}".format(name, prev.stage),
Expand Down

0 comments on commit 41a7844

Please sign in to comment.