Skip to content

Commit

Permalink
Fix Odb.RemoveRoutingObstructions failing with non-integer coordinates (
Browse files Browse the repository at this point in the history
#553)

* `Odb.Remove*Obstructions`
  * Rework obstruction matching code to not use IEEE 754 in any capacity
  * Fixed bug where non-integral obstructions would not be matched correctly
    (thanks @urish!)

Co-authored-by: Mohamed Gaber <[email protected]>
  • Loading branch information
urish and donn authored Sep 22, 2024
1 parent f74e88d commit bc56ad4
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 18 deletions.
10 changes: 10 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@
## Documentation
-->

# 2.1.7

## Steps

* `Odb.Remove*Obstructions`

* Rework obstruction matching code to not use IEEE 754 in any capacity
* Fixed bug where non-integral obstructions would not be matched correctly
(thanks @urish!)

# 2.1.6

## Steps
Expand Down
31 changes: 14 additions & 17 deletions openlane/scripts/odbpy/defutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import os
import re
import sys
from decimal import Decimal

from reader import click_odb, click
from typing import Tuple, List
Expand Down Expand Up @@ -456,7 +457,7 @@ def replace_instance_prefixes(original_prefix, new_prefix, reader):
cli.add_command(replace_instance_prefixes)


def parse_obstructions(obstructions):
def parse_obstructions(obstructions) -> List[Tuple[str, List[int]]]:
RE_NUMBER = r"[\-]?[0-9]+(\.[0-9]+)?"
RE_OBS = (
r"(?P<layer>\S+)\s+"
Expand All @@ -483,7 +484,7 @@ def parse_obstructions(obstructions):
sys.exit(FORMAT_ERROR)
else:
layer = m.group("layer")
bbox = [float(x) for x in m.group("bbox").split()]
bbox = [Decimal(x) for x in m.group("bbox").split()]
obs_list.append((layer, bbox))

return obs_list
Expand Down Expand Up @@ -526,41 +527,37 @@ def add_obstructions(reader, input_lefs, obstructions):
)
@click_odb
def remove_obstructions(reader, input_lefs, obstructions):
obs_list = parse_obstructions(obstructions)
dbu: int = reader.tech.getDbUnitsPerMicron()
existing_obstructions: List[Tuple[str, List[int], odb.dbObstruction]] = []
dbu = reader.tech.getDbUnitsPerMicron()

def to_microns(x):
return int(x / dbu)

for odb_obstruction in reader.block.getObstructions():
bbox = odb_obstruction.getBBox()
existing_obstructions.append(
(
bbox.getTechLayer().getName(),
[
to_microns(bbox.xMin()),
to_microns(bbox.yMin()),
to_microns(bbox.xMax()),
to_microns(bbox.yMax()),
bbox.xMin(),
bbox.yMin(),
bbox.xMax(),
bbox.yMax(),
],
odb_obstruction,
)
)

for obs in obs_list:
layer = obs[0]
bbox = obs[1]
bbox = [int(x * dbu) for x in bbox]
for obs in parse_obstructions(obstructions):
layer, bbox = obs
bbox = [int(x * dbu) for x in bbox] # To dbus
found = False
if reader.tech.findLayer(layer) is None:
print(f"[ERROR] layer {layer} doesn't exist.", file=sys.stderr)
sys.exit(METAL_LAYER_ERROR)
for odb_obstruction in existing_obstructions:
if odb_obstruction[0:2] == obs:
odb_layer, odb_bbox, odb_obj = odb_obstruction
if (odb_layer, odb_bbox) == (layer, bbox):
print(f"Removing obstruction on {layer} at {bbox} (DBU)…")
found = True
odb.dbObstruction_destroy(odb_obstruction[2])
odb.dbObstruction_destroy(odb_obj)
if found:
break
if not found:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "openlane"
version = "2.1.6"
version = "2.1.7"
description = "An infrastructure for implementing chip design flows"
authors = ["Efabless Corporation and Contributors <[email protected]>"]
readme = "Readme.md"
Expand Down

0 comments on commit bc56ad4

Please sign in to comment.