Skip to content

Commit

Permalink
Merge pull request #298 from hdl/hybrid_height
Browse files Browse the repository at this point in the history
Fix support for hybrid height technologies in place_and_route rule.
  • Loading branch information
mikesinouye committed Mar 15, 2024
2 parents eb7f96f + 546b554 commit e01e5dc
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 28 deletions.
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

0 comments on commit e01e5dc

Please sign in to comment.