Skip to content

Commit

Permalink
Add setting to control antenna_trim_shape
Browse files Browse the repository at this point in the history
  • Loading branch information
jerryz123 committed Oct 21, 2023
1 parent 479b2e1 commit e3586f5
Show file tree
Hide file tree
Showing 8 changed files with 26 additions and 10 deletions.
4 changes: 4 additions & 0 deletions hammer/config/defaults.yml
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,10 @@ par:
# Overrideable by appending _<layer name>
# type: float

antenna_trim_shape: stripe # "none" or "stripe", specifies antenna trimming strategy
# Overrideable by appending _<layer name>
# type: str

pin_layers: [] # Layers to put power pins on
# type: List[str]

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 @@ -310,6 +310,10 @@ par:
# type: int
track_spacing: int

# Specifies antenna trimming strategy. none or stripe
# type: str
antenna_trim_shape: str

# Ratio of total routing tracks to dedicate to power straps, which is used to calculate set pitch
# type: float
power_utilization: float
Expand Down
4 changes: 3 additions & 1 deletion hammer/par/innovus/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1125,7 +1125,7 @@ def specify_std_cell_power_straps(self, blockage_spacing: Decimal, bbox: Optiona
results.append("add_stripes " + " ".join(options) + "\n")
return results

def specify_power_straps(self, layer_name: str, bottom_via_layer_name: str, blockage_spacing: Decimal, pitch: Decimal, width: Decimal, spacing: Decimal, offset: Decimal, bbox: Optional[List[Decimal]], nets: List[str], add_pins: bool) -> List[str]:
def specify_power_straps(self, layer_name: str, bottom_via_layer_name: str, blockage_spacing: Decimal, pitch: Decimal, width: Decimal, spacing: Decimal, offset: Decimal, bbox: Optional[List[Decimal]], nets: List[str], add_pins: bool, antenna_trim_shape: str) -> List[str]:
"""
Generate a list of TCL commands that will create power straps on a given layer.
This is a low-level, cad-tool-specific API. It is designed to be called by higher-level methods, so calling this directly is not recommended.
Expand All @@ -1141,6 +1141,7 @@ def specify_power_straps(self, layer_name: str, bottom_via_layer_name: str, bloc
:param bbox: The optional (2N)-point bounding box of the area to generate straps. By default the entire core area is used.
:param nets: A list of power nets to create (e.g. ["VDD", "VSS"], ["VDDA", "VSS", "VDDB"], ... etc.).
:param add_pins: True if pins are desired on this layer; False otherwise.
:param antenna_trim_shape: Strategy for trimming strap antennae. {none/stripe}
:return: A list of TCL commands that will generate power straps.
"""
# TODO check that this has been not been called after a higher-level metal and error if so
Expand All @@ -1149,6 +1150,7 @@ def specify_power_straps(self, layer_name: str, bottom_via_layer_name: str, bloc
results.extend([
"set_db add_stripes_stacked_via_top_layer {}".format(layer_name),
"set_db add_stripes_stacked_via_bottom_layer {}".format(bottom_via_layer_name),
"set_db add_stripes_trim_antenna_back_to_shape {{{}}}".format(antenna_trim_shape),
"set_db add_stripes_spacing_from_block {}".format(blockage_spacing)
])
layer = self.get_stackup().get_metal(layer_name)
Expand Down
5 changes: 3 additions & 2 deletions hammer/par/mockpar/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def parse_mock_power_straps_file(self) -> List[Dict[str, Any]]:
output.append(json.loads(line))
return output

def specify_power_straps(self, layer_name: str, bottom_via_layer_name: str, blockage_spacing: Decimal, pitch: Decimal, width: Decimal, spacing: Decimal, offset: Decimal, bbox: Optional[List[Decimal]], nets: List[str], add_pins: bool) -> List[str]:
def specify_power_straps(self, layer_name: str, bottom_via_layer_name: str, blockage_spacing: Decimal, pitch: Decimal, width: Decimal, spacing: Decimal, offset: Decimal, bbox: Optional[List[Decimal]], nets: List[str], add_pins: bool, antenna_trim_shape: str) -> List[str]:
self._power_straps_check_index(layer_name)
output_dict = {
"layer_name": layer_name,
Expand All @@ -62,7 +62,8 @@ def specify_power_straps(self, layer_name: str, bottom_via_layer_name: str, bloc
"offset": str(offset),
"bbox": [] if bbox is None else list(map(str, bbox)),
"nets": list(map(str, nets)),
"add_pins": add_pins
"add_pins": add_pins,
"antenna_trim_shape": antenna_trim_shape
}
return [json.dumps(output_dict, cls=HammerJSONEncoder)]

Expand Down
2 changes: 1 addition & 1 deletion hammer/par/nop/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def fill_outputs(self) -> bool:
self.hcells_list = []
return True

def specify_power_straps(self, layer_name: str, bottom_via_layer_name: str, blockage_spacing: Decimal, pitch: Decimal, width: Decimal, spacing: Decimal, offset: Decimal, bbox: Optional[List[Decimal]], nets: List[str], add_pins: bool) -> List[str]:
def specify_power_straps(self, layer_name: str, bottom_via_layer_name: str, blockage_spacing: Decimal, pitch: Decimal, width: Decimal, spacing: Decimal, offset: Decimal, bbox: Optional[List[Decimal]], nets: List[str], add_pins: bool, antenna_trim_shape: str) -> List[str]:
return []

def specify_std_cell_power_straps(self, blockage_spacing: Decimal, bbox: Optional[List[Decimal]], nets: List[str]) -> List[str]:
Expand Down
3 changes: 2 additions & 1 deletion hammer/par/openroad/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1882,7 +1882,7 @@ def specify_std_cell_power_straps(self, blockage_spacing: Decimal, bbox: Optiona
# -pitch {pitch}
return tcl

def specify_power_straps(self, layer_name: str, bottom_via_layer_name: str, blockage_spacing: Decimal, pitch: Decimal, width: Decimal, spacing: Decimal, offset: Decimal, bbox: Optional[List[Decimal]], nets: List[str], add_pins: bool) -> List[str]:
def specify_power_straps(self, layer_name: str, bottom_via_layer_name: str, blockage_spacing: Decimal, pitch: Decimal, width: Decimal, spacing: Decimal, offset: Decimal, bbox: Optional[List[Decimal]], nets: List[str], add_pins: bool, antenna_trim_shape: str) -> List[str]:
"""
Generate a list of TCL commands that will create power straps on a given layer.
This is a low-level, cad-tool-specific API. It is designed to be called by higher-level methods, so calling this directly is not recommended.
Expand All @@ -1898,6 +1898,7 @@ def specify_power_straps(self, layer_name: str, bottom_via_layer_name: str, bloc
:param bbox: The optional (2N)-point bounding box of the area to generate straps. By default the entire core area is used.
:param nets: A list of power nets to create (e.g. ["VDD", "VSS"], ["VDDA", "VSS", "VDDB"], ... etc.).
:param add_pins: True if pins are desired on this layer; False otherwise.
:param antenna_trim_shape: Strategy for trimming strap antennae. {none/stripe}
:return: A list of TCL commands that will generate power straps.
"""
pdn_cfg = [f" {layer_name} {{width {width} pitch {pitch} offset {offset}}}"]
Expand Down
11 changes: 7 additions & 4 deletions hammer/vlsi/hammer_vlsi_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@ def get_weight(s: Supply) -> int:
raise NotImplementedError("Power strap generation method %s is not implemented" % method)


def specify_power_straps_by_tracks(self, layer_name: str, bottom_via_layer: str, blockage_spacing: Decimal, track_pitch: int, track_width: int, track_spacing: int, track_start: int, track_offset: Decimal, bbox: Optional[List[Decimal]], nets: List[str], add_pins: bool, layer_is_all_power: bool) -> List[str]:
def specify_power_straps_by_tracks(self, layer_name: str, bottom_via_layer: str, blockage_spacing: Decimal, track_pitch: int, track_width: int, track_spacing: int, track_start: int, track_offset: Decimal, bbox: Optional[List[Decimal]], nets: List[str], add_pins: bool, layer_is_all_power: bool, antenna_trim_shape: str) -> List[str]:
"""
Generate a list of TCL commands that will create power straps on a given layer by specifying the desired track consumption.
This method assumes that power straps are built bottom-up, starting with standard cell rails.
Expand All @@ -675,6 +675,7 @@ def specify_power_straps_by_tracks(self, layer_name: str, bottom_via_layer: str,
:param nets: A list of power nets to create (e.g. ["VDD", "VSS"], ["VDDA", "VSS", "VDDB"], ... etc.).
:param add_pins: True if pins are desired on this layer; False otherwise.
:param layer_is_all_power: True if there will be no signal wires on this layer.
:param antenna_trim_shape: Strategy for trimming strap antennae. {none/stripe}
:return: A list of TCL commands that will generate power straps.
"""
# Note: even track_widths will be snapped to a half-track
Expand Down Expand Up @@ -702,7 +703,7 @@ def specify_power_straps_by_tracks(self, layer_name: str, bottom_via_layer: str,
if density > Decimal(85):
self.logger.warning("CAUTION! Your {layer} power strap density is {density}%. Check your technology's DRM to see if this violates maximum density rules.".format(layer=layer_name, density=density))
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)
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]) -> List[str]:
"""
Expand Down Expand Up @@ -752,6 +753,7 @@ def specify_all_power_straps_by_tracks(self, layer_names: List[str], ground_net:
track_start = int(self._get_by_tracks_metal_setting("track_start", layer_name))
track_pitch = self._get_by_tracks_track_pitch(layer_name)
track_offset = Decimal(str(self._get_by_tracks_metal_setting("track_offset", layer_name)))
antenna_trim_shape = self._get_by_tracks_metal_setting("antenna_trim_shape", layer_name)
offset = layer.offset # TODO this is relaxable if we can auto-recalculate this based on hierarchical setting

add_pins = layer_name in pin_layers
Expand All @@ -767,7 +769,7 @@ def specify_all_power_straps_by_tracks(self, layer_names: List[str], ground_net:
nets = [ground_net, power_nets[i]]
group_offset = offset + track_offset + track_pitch * i * layer.pitch
group_pitch = sum_weights * track_pitch
output.extend(self.specify_power_straps_by_tracks(layer_name, last.name, blockage_spacing, group_pitch, track_width, track_spacing, track_start, group_offset, bbox, nets, add_pins, layer_is_all_power))
output.extend(self.specify_power_straps_by_tracks(layer_name, last.name, blockage_spacing, group_pitch, track_width, track_spacing, track_start, group_offset, bbox, nets, add_pins, layer_is_all_power, antenna_trim_shape))
last = layer

self._dump_power_straps_for_hardmacros()
Expand Down Expand Up @@ -1031,7 +1033,7 @@ def _get_by_tracks_track_pitch(self, layer_name: str) -> int:
return round(consumed_tracks / power_utilization)

@abstractmethod
def specify_power_straps(self, layer_name: str, bottom_via_layer_name: str, blockage_spacing: Decimal, pitch: Decimal, width: Decimal, spacing: Decimal, offset: Decimal, bbox: Optional[List[Decimal]], nets: List[str], add_pins: bool) -> List[str]:
def specify_power_straps(self, layer_name: str, bottom_via_layer_name: str, blockage_spacing: Decimal, pitch: Decimal, width: Decimal, spacing: Decimal, offset: Decimal, bbox: Optional[List[Decimal]], nets: List[str], add_pins: bool, antenna_trim_shape: str) -> List[str]:
"""
Generate a list of TCL commands that will create power straps on a given layer.
This is a low-level, cad-tool-specific API. It is designed to be called by higher-level methods, so calling this directly is not recommended.
Expand All @@ -1047,6 +1049,7 @@ def specify_power_straps(self, layer_name: str, bottom_via_layer_name: str, bloc
:param bbox: The optional (2N)-point bounding box of the area to generate straps. By default the entire core area is used.
:param nets: A list of power nets to create (e.g. ["VDD", "VSS"], ["VDDA", "VSS", "VDDB"], ... etc.).
:param add_pins: True if pins are desired on this layer; False otherwise.
:param antenna_trim_shape: Strategy for trimming strap antennae. {none/stripe}
:return: A list of TCL commands that will generate power straps.
"""
# This should get overriden but be sure to use this check in your implementations
Expand Down
3 changes: 2 additions & 1 deletion hammer/vlsi/vendor/openroad.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,8 @@ def specify_power_straps(self, layer_name: str,
bottom_via_layer_name: str, blockage_spacing: Decimal, pitch: Decimal,
width: Decimal, spacing: Decimal, offset: Decimal,
bbox: Optional[List[Decimal]], nets: List[str],
add_pins: bool) -> List[str]:
add_pins: bool,
antenna_trim_shape: str) -> List[str]:
# TODO: currently using openroad's powerstrap script
return []

Expand Down

0 comments on commit e3586f5

Please sign in to comment.