From 127632ca70f5a91b866b9fc314bb947d76ae31b8 Mon Sep 17 00:00:00 2001 From: Mike Inouye Date: Fri, 15 Mar 2024 18:56:27 +0000 Subject: [PATCH 1/3] Fix support for hybrid height technologies in place_and_route rule. --- pdk/open_road_configuration.bzl | 3 ++ pdk/proto/pdk_info.proto | 3 +- place_and_route/build_defs.bzl | 41 +++++++++++++++------------ place_and_route/open_road.bzl | 7 +++-- place_and_route/private/floorplan.bzl | 14 +++++---- 5 files changed, 40 insertions(+), 28 deletions(-) diff --git a/pdk/open_road_configuration.bzl b/pdk/open_road_configuration.bzl index 29ceb232..7784dd10 100644 --- a/pdk/open_road_configuration.bzl +++ b/pdk/open_road_configuration.bzl @@ -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.", @@ -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, @@ -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(), diff --git a/pdk/proto/pdk_info.proto b/pdk/proto/pdk_info.proto index 817df177..f4e7defd 100644 --- a/pdk/proto/pdk_info.proto +++ b/pdk/proto/pdk_info.proto @@ -1,6 +1,6 @@ syntax = "proto2"; -package bazel_rules_hdl.pdk; +package third_party.bazel_rules_hdl.pdk; message PdkInfoProto { repeated string cell_lef_paths = 1; @@ -27,6 +27,7 @@ message PdkInfoProto { optional string rc_script_configuration_path = 22; map 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; } diff --git a/place_and_route/build_defs.bzl b/place_and_route/build_defs.bzl index b749e194..5ae62981 100644 --- a/place_and_route/build_defs.bzl +++ b/place_and_route/build_defs.bzl @@ -26,27 +26,30 @@ 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) + 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()) @@ -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, diff --git a/place_and_route/open_road.bzl b/place_and_route/open_road.bzl index e5e9e9d7..83e60b92 100644 --- a/place_and_route/open_road.bzl +++ b/place_and_route/open_road.bzl @@ -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) diff --git a/place_and_route/private/floorplan.bzl b/place_and_route/private/floorplan.bzl index 42bea7c0..e218a89b 100644 --- a/place_and_route/private/floorplan.bzl +++ b/place_and_route/private/floorplan.bzl @@ -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, @@ -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") @@ -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)) @@ -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, ), @@ -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, From 85de99b6655db86a0244adc627e19720b0ebe1ce Mon Sep 17 00:00:00 2001 From: Mike Inouye Date: Fri, 15 Mar 2024 18:58:30 +0000 Subject: [PATCH 2/3] Fix support for hybrid height technologies in place_and_route rule. --- pdk/proto/pdk_info.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdk/proto/pdk_info.proto b/pdk/proto/pdk_info.proto index f4e7defd..7d58be1b 100644 --- a/pdk/proto/pdk_info.proto +++ b/pdk/proto/pdk_info.proto @@ -1,6 +1,6 @@ syntax = "proto2"; -package third_party.bazel_rules_hdl.pdk; +package bazel_rules_hdl.pdk; message PdkInfoProto { repeated string cell_lef_paths = 1; From 546b554f7750b177ed3ac9267bfdde1ff6313082 Mon Sep 17 00:00:00 2001 From: Mike Inouye Date: Fri, 15 Mar 2024 19:03:24 +0000 Subject: [PATCH 3/3] Fix support for hybrid height technologies in place_and_route rule. --- place_and_route/build_defs.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/place_and_route/build_defs.bzl b/place_and_route/build_defs.bzl index 5ae62981..9ff8e61c 100644 --- a/place_and_route/build_defs.bzl +++ b/place_and_route/build_defs.bzl @@ -47,10 +47,10 @@ def _place_and_route_impl(ctx): 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 - output_files.append(output_def) output_files.append(open_road_provider.output_db) output_files.extend(open_road_provider.logs.to_list())