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

Add setting to control antenna_trim_shape #811

Merged
merged 1 commit into from
Oct 22, 2023
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
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