Skip to content

Commit 216554a

Browse files
authored
Merge pull request #88 from nanavati/yosys-step
Add a rule for creating single-file Yosys synthesis steps
2 parents 0dfa1dd + 0084458 commit 216554a

File tree

6 files changed

+236
-1
lines changed

6 files changed

+236
-1
lines changed

flows/flows.bzl

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,13 @@ def _run_step_with_inputs(ctx, step, inputs_dict, outputs_step_dict):
215215

216216
return dicts.add(inputs_dict, outputs_dict)
217217

218+
def target_to_file(target):
219+
all_files = target.files.to_list()
220+
if len(all_files) != 1:
221+
fail("Input target", target, "should provide exactly one file instead of", all_files)
222+
223+
return all_files[0]
224+
218225
def _run_flow_impl(ctx):
219226
if len(ctx.attr.output_names) != len(ctx.outputs.output_files):
220227
fail(
@@ -249,7 +256,9 @@ def _run_flow_impl(ctx):
249256
"lists should have the same length",
250257
)
251258

252-
inputs_dict = dict(zip(ctx.attr.input_names, ctx.attr.input_files))
259+
input_files = [target_to_file(target) for target in ctx.attr.input_files]
260+
261+
inputs_dict = dict(zip(ctx.attr.input_names, input_files))
253262

254263
for step in ctx.attr.flow:
255264
inputs_dict = _run_step_with_inputs(ctx, step, inputs_dict, outputs_step_dict)

flows/tests/BUILD.bazel

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
# Modular hardware flow tests
1616

17+
load("@bazel_skylib//rules:build_test.bzl", "build_test")
1718
load("@bazel_skylib//rules:diff_test.bzl", "diff_test")
1819
load("//flows:flows.bzl", "flow_binary", "run_flow")
1920
load("//flows/place_and_route:build_defs.bzl", "openroad_step")
@@ -58,3 +59,37 @@ flow_binary(
5859
"goodbye_openroad",
5960
],
6061
)
62+
63+
run_flow(
64+
name = "synth_sky130_adder",
65+
constants = {"top": "adder"},
66+
flow = ["//flows/yosys:synth_sky130"],
67+
input_files = ["verilog_adder.v"],
68+
input_names = ["rtl"],
69+
output_files = ["sky130_adder_test.v"],
70+
output_names = ["netlist"],
71+
)
72+
73+
# TODO(amfv): This only tests that adding the clock period constant
74+
# does not break synthesis. Figure out how to test that the clock
75+
# period is actually used properly.
76+
run_flow(
77+
name = "synth_sky130_adder_with_clock_period",
78+
constants = {
79+
"clock_period_ps": "2000",
80+
"top": "adder",
81+
},
82+
flow = ["//flows/yosys:synth_sky130"],
83+
input_files = ["verilog_adder.v"],
84+
input_names = ["rtl"],
85+
output_files = ["sky130_adder_with_clock_period_test.v"],
86+
output_names = ["netlist"],
87+
)
88+
89+
build_test(
90+
name = "synth_sky130_smoke",
91+
targets = [
92+
":synth_sky130_adder",
93+
":synth_sky130_adder_with_clock_period",
94+
],
95+
)

flows/tests/verilog_adder.v

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//Copyright 2021 Google LLC
2+
//
3+
//Licensed under the Apache License, Version 2.0 (the "License");
4+
//you may not use this file except in compliance with the License.
5+
//You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
//Unless required by applicable law or agreed to in writing, software
10+
//distributed under the License is distributed on an "AS IS" BASIS,
11+
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
//See the License for the specific language governing permissions and
13+
//limitations under the License.
14+
15+
16+
module adder(
17+
input [7:0] x,
18+
input [7:0] y,
19+
input carry_in,
20+
output carry_output_bit,
21+
output [7:0] sum,
22+
);
23+
assign {carry_output_bit, sum} = x + y + carry_in;
24+
endmodule

flows/yosys/BUILD.bazel

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Copyright 2022 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# Yosys synthesis step for modular flows.
16+
17+
load("@rules_pkg//:pkg.bzl", "pkg_tar")
18+
load("//flows:flows.bzl", "flow_binary")
19+
load("//flows/yosys:build_defs.bzl", "yosys_synth_file_step")
20+
21+
package(default_visibility = ["//flows:__subpackages__"])
22+
23+
exports_files(["synth.tcl"])
24+
25+
yosys_synth_file_step(
26+
name = "synth_sky130",
27+
standard_cells = "@com_google_skywater_pdk_sky130_fd_sc_hd//:sky130_fd_sc_hd",
28+
)
29+
30+
flow_binary(
31+
name = "synth_sky130_bin",
32+
flow = ["synth_sky130"],
33+
)
34+
35+
pkg_tar(
36+
name = "synth_sky130_pkg",
37+
srcs = [":synth_sky130_bin"],
38+
include_runfiles = True,
39+
strip_prefix = "./",
40+
)

flows/yosys/build_defs.bzl

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Copyright 2022 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Reimplementing place-and-route using composable and externalizable pieces"""
16+
17+
load("//flows:flows.bzl", "FlowStepInfo", "script_prefix")
18+
load("//pdk:build_defs.bzl", "StandardCellInfo")
19+
20+
def _yosys_synth_file_step_impl(ctx):
21+
yosys_executable = ctx.attr._yosys.files_to_run.executable
22+
yosys_runfiles = ctx.attr._yosys[DefaultInfo].default_runfiles
23+
24+
yosys_wrapper = ctx.actions.declare_file(ctx.attr.name)
25+
26+
standard_cells = ctx.attr.standard_cells[StandardCellInfo]
27+
28+
liberty = standard_cells.default_corner.liberty
29+
30+
synth_tcl = ctx.file.synth_tcl
31+
32+
cell_runfiles = ctx.runfiles(files = [synth_tcl, liberty, yosys_wrapper])
33+
34+
yosys_args = [
35+
"-q", # quiet mode only errors printed to stderr
36+
"-q", # second q don't print warnings
37+
"-Q", # Don't print header
38+
"-T", # Don't print footer
39+
"-c ${RUNFILES}/" + synth_tcl.short_path,
40+
]
41+
42+
commands = [script_prefix]
43+
commands.append("export LIBERTY=${RUNFILES}/" + liberty.short_path)
44+
45+
# TODO(amfv): Compute Yosys data environment variables properly instead of hardcoding them.
46+
commands.extend([
47+
"export YOSYS_DATDIR=${RUNFILES}/../at_clifford_yosys/techlibs/",
48+
"export ABC=${RUNFILES}/../edu_berkeley_abc/abc",
49+
])
50+
51+
exec_yosys = """{yosys} {args} "$@"\n""".format(
52+
yosys = "${RUNFILES}/" + yosys_executable.short_path,
53+
args = " ".join(yosys_args),
54+
)
55+
56+
commands.append(exec_yosys)
57+
58+
ctx.actions.write(
59+
output = yosys_wrapper,
60+
content = "\n".join(commands) + "\n",
61+
is_executable = True,
62+
)
63+
64+
return [
65+
FlowStepInfo(
66+
inputs = ["rtl"],
67+
outputs = ["netlist"],
68+
constants = ["top"], # , "clock_period"],
69+
executable_type = "yosys",
70+
arguments = [],
71+
),
72+
DefaultInfo(
73+
executable = yosys_wrapper,
74+
# TODO(amfv): Switch to runfiles.merge_all once our minimum Bazel version provides it.
75+
runfiles = cell_runfiles.merge(yosys_runfiles),
76+
),
77+
]
78+
79+
yosys_synth_file_step = rule(
80+
implementation = _yosys_synth_file_step_impl,
81+
attrs = {
82+
"_yosys": attr.label(
83+
default = Label("@at_clifford_yosys//:yosys"),
84+
executable = True,
85+
cfg = "exec",
86+
),
87+
"standard_cells": attr.label(
88+
doc = "Standard cells to use in yosys synthesis step",
89+
providers = [StandardCellInfo],
90+
),
91+
"synth_tcl": attr.label(
92+
default = Label("//flows/yosys:synth.tcl"),
93+
allow_single_file = True,
94+
doc = "Tcl script controlling Yosys synthesis, using the Flow Step API environment variables",
95+
),
96+
},
97+
)

flows/yosys/synth.tcl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Default Yosys synthesis tcl script for the yosys_synth_file_step rule.
2+
# It can be replaced by a user-defined script by overriding the synth_tcl
3+
# argument of that rule.
4+
5+
yosys -import
6+
7+
# read design
8+
set input_rtl $::env(INPUT_RTL)
9+
yosys read_verilog -sv -defer $input_rtl
10+
11+
# generic synthesis
12+
set top $::env(CONSTANT_TOP)
13+
yosys synth -top $top
14+
15+
# mapping to liberty
16+
set liberty $::env(LIBERTY)
17+
dfflibmap -liberty $liberty
18+
19+
if { [info exists ::env(CONSTANT_CLOCK_PERIOD_PS) ] } {
20+
abc -liberty $liberty -dff -g aig -D $::env(CONSTANT_CLOCK_PERIOD_PS)
21+
} else {
22+
abc -liberty $liberty -dff -g aig
23+
}
24+
25+
# write synthesized design
26+
set output $::env(OUTPUT_NETLIST)
27+
write_verilog $output
28+
29+
# print stats
30+
stat

0 commit comments

Comments
 (0)