Skip to content

Commit

Permalink
Add bottom_via_layer api for power_straps.by_tracks (#815)
Browse files Browse the repository at this point in the history
The default setting "rail" uses the stdcell rail layer.
This can be set to a different metal layer if desired�
  • Loading branch information
jerryz123 authored Nov 3, 2023
1 parent 27dcf6c commit cf30e0d
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 7 deletions.
5 changes: 5 additions & 0 deletions hammer/config/defaults.yml
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,11 @@ par:
generate_rail_layer: true # If true, generates straps on the stdcell rail layer - technology.core.std_cell_rail_layer
# type: bool

bottom_via_layer: "rail" # Sets what the lowest power strap layer should generate vias to
# Usually should be set to rail, which will use technology.core.std_cell_rail_layer as this setting
# Otherwise should be set to some layer name
# type: str

# DRC settings
drc.inputs:
# DRC settings
Expand Down
4 changes: 4 additions & 0 deletions hammer/config/defaults_types.yml
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,10 @@ par:
# type: bool
generate_rail_layer: bool

# Indicates bottom layer to via to during power strap generation
# type: str
bottom_via_layer: str

# DRC settings
drc.inputs:
# Top RTL module.
Expand Down
16 changes: 11 additions & 5 deletions hammer/vlsi/hammer_vlsi_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -649,13 +649,19 @@ def generate_power_straps_tcl(self) -> List[str]:
generate_rail_layer = self.get_setting("{}.generate_rail_layer".format(namespace))
ground_net_names = list(map(lambda x: x.name, self.get_independent_ground_nets())) # type: List[str]
power_net_names = list(map(lambda x: x.name, self.get_independent_power_nets())) # type: List[str]
bottom_via_option = self.get_setting("{}.bottom_via_layer".format(namespace))
if bottom_via_option == "rail":
bottom_via_layer = self.get_setting("technology.core.std_cell_rail_layer")
else:
bottom_via_layer = bottom_via_option

def get_weight(s: Supply) -> int:
# Check that it's not None
assert isinstance(s.weight, int)
return s.weight
weights = list(map(get_weight, self.get_independent_power_nets())) # type: List[int]
assert len(ground_net_names) == 1, "FIXME, I am assuming there's only 1 ground net"
return self.specify_all_power_straps_by_tracks(layers, ground_net_names[0], power_net_names, weights, bbox, pin_layers, generate_rail_layer)
return self.specify_all_power_straps_by_tracks(layers, bottom_via_layer, ground_net_names[0], power_net_names, weights, bbox, pin_layers, generate_rail_layer)
else:
raise NotImplementedError("Power strap generation method %s is not implemented" % method)

Expand Down Expand Up @@ -706,7 +712,7 @@ def specify_power_straps_by_tracks(self, layer_name: str, bottom_via_layer: str,
self._get_power_straps_for_hardmacros(layer_name, pitch, width, spacing, offset, bbox, nets)
return self.specify_power_straps(layer_name, bottom_via_layer, blockage_spacing, pitch, width, spacing, offset, bbox, nets, add_pins, antenna_trim_shape)

def specify_all_power_straps_by_tracks(self, layer_names: List[str], ground_net: str, power_nets: List[str], power_weights: List[int], bbox: Optional[List[Decimal]], pin_layers: List[str], generate_rail_layer: bool) -> List[str]:
def specify_all_power_straps_by_tracks(self, layer_names: List[str], bottom_via_layer: str, ground_net: str, power_nets: List[str], power_weights: List[int], bbox: Optional[List[Decimal]], pin_layers: List[str], generate_rail_layer: bool) -> List[str]:
"""
Generate a list of TCL commands that will create power straps on a given set of layers by specifying the desired per-track track consumption and utilization.
This will build standard cell power strap rails first. Layer-specific parameters are read from the hammer config:
Expand All @@ -717,6 +723,7 @@ def specify_all_power_straps_by_tracks(self, layer_names: List[str], ground_net:
These settings are all overridable by appending an underscore followed by the metal name (e.g. power_utilization_M3).
:param layer_names: The list of metal layer names on which to create straps.
:param bottom_via_layer: The layer the lowest-strap layer will via down to. Usually the stdcell rail layer
:param ground_net: The name of the ground net in this design. Only 1 ground net is supported.
:param power_nets: A list of power nets to create (not ground).
:param power_weights: Specifies the power strap placement pattern for multiple-domain designs (e.g. ["VDDA", "VDDB"] with [2, 1] will produce 2 VDDA straps for ever 1 VDDB strap).
Expand All @@ -737,10 +744,9 @@ def specify_all_power_straps_by_tracks(self, layer_names: List[str], ground_net:
blockage_spacing = coerce_to_grid(float(self._get_by_tracks_metal_setting("blockage_spacing", rail_layer_name)), rail_layer.grid_unit)
# TODO does the CPF help this, or do we need to be more explicit about the bbox for each domain
output.extend(self.specify_std_cell_power_straps(blockage_spacing, bbox, [ground_net] + power_nets))
# The layer to via down to
bottom_via_layer = rail_layer_name

# The last layer we used
last = rail_layer
last = self.get_stackup().get_metal(bottom_via_layer)

substrate_json = [] # type: List[Dict[str, Any]]

Expand Down
8 changes: 6 additions & 2 deletions tests/test_power_straps.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ def simple_straps_options() -> Dict[str, Any]:
power_utilization_M8 = 1.0
track_start_M5 = 1
track_offset_M5 = 1.2
bottom_via_layer = "rail"

# VSS comes before VDD
nets = ["VSS", "VDD"]
Expand All @@ -110,7 +111,8 @@ def simple_straps_options() -> Dict[str, Any]:
"power_utilization": power_utilization,
"power_utilization_M8": power_utilization_M8,
"track_start_M5": track_start_M5,
"track_offset_M5": track_offset_M5
"track_offset_M5": track_offset_M5,
"bottom_via_layer": bottom_via_layer
}
}
return straps_options
Expand All @@ -123,6 +125,7 @@ def multiple_domains_straps_options() -> Dict[str, Any]:
track_spacing = 0
power_utilization = 0.2
power_utilization_M8 = 1.0
bottom_via_layer = "rail"

straps_options = {
"vlsi.inputs.supplies": {
Expand All @@ -139,7 +142,8 @@ def multiple_domains_straps_options() -> Dict[str, Any]:
"track_width": track_width,
"track_spacing": track_spacing,
"power_utilization": power_utilization,
"power_utilization_M8": power_utilization_M8
"power_utilization_M8": power_utilization_M8,
"bottom_via_layer": bottom_via_layer
}
}
return straps_options
Expand Down

0 comments on commit cf30e0d

Please sign in to comment.