Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix support for hybrid height technologies in place_and_route rule. #298

Merged
merged 3 commits into from
Mar 15, 2024
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
3 changes: 3 additions & 0 deletions pdk/open_road_configuration.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ OpenRoadPdkInfo = provider(
"provider for openROAD configuration for a pdk",
fields = {
"cell_site": "LEF standard cell site name to use for floorplanning",
"additional_cell_sites": "Any additional LEF sites to make rows for hybrid height technologies.",
"tracks_file": "Track setup script",
"endcap_cell": "The endcap cell to use in place and route",
"tap_cell": "The tap cell to use in the place and route.",
Expand Down Expand Up @@ -57,6 +58,7 @@ def _open_road_pdk_configuration_impl(ctx):
return [
OpenRoadPdkInfo(
cell_site = ctx.attr.cell_site,
additional_cell_sites = ctx.attr.additional_cell_sites,
tracks_file = ctx.file.tracks_file,
tap_cell = ctx.attr.tap_cell,
pin_vertical_metal_layer = ctx.attr.pin_vertical_metal_layer,
Expand Down Expand Up @@ -91,6 +93,7 @@ open_road_pdk_configuration = rule(
implementation = _open_road_pdk_configuration_impl,
attrs = {
"cell_site": attr.string(mandatory = True, doc = "LEF standard cell site name."),
"additional_cell_sites": attr.string_list(doc = "Any additional LEF sites to make rows for hybrid height technologies."),
"tracks_file": attr.label(mandatory = True, allow_single_file = True, doc = "Track setup script."),
"pdn_config": attr.label(mandatory = True, allow_single_file = True, doc = "PDN Config."),
"tap_cell": attr.string(),
Expand Down
1 change: 1 addition & 0 deletions pdk/proto/pdk_info.proto
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ message PdkInfoProto {
optional string rc_script_configuration_path = 22;
map<string, float> global_routing_layer_adjustments = 23;
optional string cell_site = 24;
repeated string additional_cell_sites = 27;
optional string tapcell_tcl_path = 25;
optional string placement_padding_tcl_path = 26;
}
43 changes: 24 additions & 19 deletions place_and_route/build_defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -26,28 +26,31 @@ load("//place_and_route:private/place_pins.bzl", "place_pins")
load("//place_and_route:private/resize.bzl", "resize")
load("//synthesis:build_defs.bzl", "SynthesisInfo")

PLACE_AND_ROUTE_STEPS = [
("init_floor_plan", init_floor_plan, "pre_pnr"),
("place_pins", place_pins, ""),
("pdn_gen", pdn_gen, ""),
("global_placement", global_placement, "global_placement"),
("resize", resize, ""),
("clock_tree_synthesis", clock_tree_synthesis, ""),
("global_routing", global_routing, "post_pnr"),
("detailed_routing", detailed_routing, "post_detailed_route"),
]

def _place_and_route_impl(ctx):
# Throws an error if there is no OpenROAD configuration
assert_has_open_road_configuration(ctx.attr.synthesized_rtl[SynthesisInfo])

output_files = []
open_road_provider = None
for step_name, impl, export_def_name in PLACE_AND_ROUTE_STEPS:
open_road_provider = impl(ctx) if step_name == "init_floor_plan" else impl(ctx, open_road_provider)
if export_def_name != "":
open_road_provider, output_def = export_def(ctx, open_road_provider, export_def_name)
output_files.append(output_def)
if step_name == ctx.attr.stop_after_step:
break

open_road_provider = init_floor_plan(ctx)
open_road_provider, output_def = export_def(ctx, open_road_provider, "pre_pnr")
output_files.append(output_def)
open_road_provider = place_pins(ctx, open_road_provider)
open_road_provider = pdn_gen(ctx, open_road_provider)
open_road_provider = global_placement(ctx, open_road_provider)
open_road_provider, output_def = export_def(ctx, open_road_provider, "global_placement")
output_files.append(output_def)
open_road_provider = resize(ctx, open_road_provider)
open_road_provider = clock_tree_synthesis(ctx, open_road_provider)
open_road_provider = global_routing(ctx, open_road_provider)
if not ctx.attr.skip_detailed_routing:
open_road_provider = detailed_routing(ctx, open_road_provider)
output_files.append(open_road_provider.routed_def)
open_road_provider, output_def = export_def(ctx, open_road_provider, "post_pnr")
output_files.append(output_def)
output_files.append(open_road_provider.output_db)
output_files.extend(open_road_provider.logs.to_list())

Expand Down Expand Up @@ -79,9 +82,11 @@ place_and_route = rule(
executable = True,
cfg = "exec",
),
"skip_detailed_routing": attr.bool(
default = False,
doc = "Whether to skip detailed routing. This step is slow and is only required if requiring a fully manufacturable routed_def.",
"stop_after_step": attr.string(
doc = """
Stops the flow after the specified step. Leaving unspecified will run all pnr steps.
""",
values = [step[0] for step in PLACE_AND_ROUTE_STEPS],
),
"local_detailed_routing_execution": attr.bool(
default = False,
Expand Down
7 changes: 4 additions & 3 deletions place_and_route/open_road.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,15 @@ def timing_setup_commands(ctx):

netlist_target = ctx.attr.synthesized_rtl
liberty = netlist_target[SynthesisInfo].standard_cell_info.default_corner.liberty
additional_liberties = [corner.liberty for corner in netlist_target[SynthesisInfo].standard_cell_info.corners]
open_road_configuration = get_open_road_configuration(ctx.attr.synthesized_rtl[SynthesisInfo])
rc_script = open_road_configuration.rc_script_configuration

# Liberty Setup
inputs.append(liberty)
commands.append("read_liberty {liberty_file}".format(
liberty_file = liberty.path,
))
inputs.extend(additional_liberties)
for file in [liberty] + additional_liberties:
commands.append("read_liberty {liberty}".format(liberty = file.path))

# SDC/Clock Setup
clock_commands_struct = clock_commands(ctx)
Expand Down
14 changes: 8 additions & 6 deletions place_and_route/private/floorplan.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def _initialize_floorplan_command(ctx):
open_road_configuration = get_open_road_configuration(ctx.attr.synthesized_rtl[SynthesisInfo])

if ctx.attr.die_width_microns and ctx.attr.die_height_microns:
return "initialize_floorplan -site \"{site}\" -die_area {die_area} -core_area {core_area}".format(
return "initialize_floorplan -site \"{site}\" -additional_sites \"{additional_cell_sites}\" -die_area {die_area} -core_area {core_area}".format(
die_area = "\"0 0 {width} {height}\"".format(
width = ctx.attr.die_width_microns,
height = ctx.attr.die_height_microns,
Expand All @@ -36,14 +36,16 @@ def _initialize_floorplan_command(ctx):
uy = ctx.attr.die_height_microns - ctx.attr.core_padding_microns,
),
site = open_road_configuration.cell_site,
additional_cell_sites = " ".join(open_road_configuration.additional_cell_sites),
)

if ctx.attr.target_die_utilization_percentage:
utilization = ctx.attr.target_die_utilization_percentage #TODO(bazel): When bazel 4.0.0 is avaliable use float command
return "initialize_floorplan -site \"{site}\" -utilization {utilization} -core_space {core_space}".format(
return "initialize_floorplan -site \"{site}\" -additional_sites \"{additional_cell_sites}\" -utilization {utilization} -core_space {core_space}".format(
utilization = utilization,
core_space = ctx.attr.core_padding_microns,
site = open_road_configuration.cell_site,
additional_cell_sites = " ".join(open_road_configuration.additional_cell_sites),
)

fail("either (die_width_microns and die_height_microns) or `utilization` must be set")
Expand All @@ -63,6 +65,7 @@ def init_floor_plan(ctx):
netlist = netlist_target[SynthesisInfo].synthesized_netlist
top_module = netlist_target[SynthesisInfo].top_module
liberty = netlist_target[SynthesisInfo].standard_cell_info.default_corner.liberty
additional_liberties = [corner.liberty for corner in netlist_target[SynthesisInfo].standard_cell_info.corners]
tech_lef = netlist_target[SynthesisInfo].standard_cell_info.tech_lef
std_cell_lef = netlist_target[SynthesisInfo].standard_cell_info.cell_lef_definitions
verilog_based_power_results = ctx.actions.declare_file("{}_verilog_based_power_results.textproto".format(ctx.attr.name))
Expand All @@ -77,10 +80,9 @@ def init_floor_plan(ctx):
]
for file in std_cell_lef:
open_road_commands.append("read_lef {}".format(file.path))
for file in [liberty] + additional_liberties:
open_road_commands.append("read_liberty {liberty}".format(liberty = file.path))
open_road_commands.extend([
"read_liberty {liberty}".format(
liberty = liberty.path,
),
"read_verilog {verilog}".format(
verilog = netlist.path,
),
Expand All @@ -107,7 +109,7 @@ def init_floor_plan(ctx):
liberty,
tech_lef,
open_road_configuration.tracks_file,
] + std_cell_lef
] + std_cell_lef + additional_liberties

command_output = openroad_command(
ctx,
Expand Down
Loading