mirror of https://github.com/VLSIDA/OpenRAM.git
Fix DRC spacing in Hanan router
This commit is contained in:
parent
48a148003a
commit
15b4e4dbe8
|
|
@ -8,6 +8,7 @@ from copy import deepcopy
|
||||||
from openram import debug
|
from openram import debug
|
||||||
from openram.base.vector import vector
|
from openram.base.vector import vector
|
||||||
from openram.base.vector3d import vector3d
|
from openram.base.vector3d import vector3d
|
||||||
|
from openram.tech import drc
|
||||||
from .direction import direction
|
from .direction import direction
|
||||||
from .hanan_node import hanan_node
|
from .hanan_node import hanan_node
|
||||||
from .hanan_probe import hanan_probe
|
from .hanan_probe import hanan_probe
|
||||||
|
|
@ -90,11 +91,12 @@ class hanan_graph:
|
||||||
# Create a copy of blockages
|
# Create a copy of blockages
|
||||||
blockages = self.router.blockages[:]
|
blockages = self.router.blockages[:]
|
||||||
# Create a copy of pins with different name than the routed pins
|
# Create a copy of pins with different name than the routed pins
|
||||||
for name, pins, in self.router.pins.items():
|
offset = self.router.layer_widths[0] / 2
|
||||||
|
for name, pins in self.router.pins.items():
|
||||||
if name == pin_name:
|
if name == pin_name:
|
||||||
continue
|
continue
|
||||||
for pin in pins:
|
for pin in pins:
|
||||||
blockages.append(deepcopy(pin).inflated_pin(multiple=1))
|
blockages.append(deepcopy(pin).inflated_pin(spacing=offset, multiple=1))
|
||||||
return blockages
|
return blockages
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -106,34 +108,26 @@ class hanan_graph:
|
||||||
|
|
||||||
x_values = set()
|
x_values = set()
|
||||||
y_values = set()
|
y_values = set()
|
||||||
offset = max(self.router.horiz_track_width, self.router.vert_track_width) / 2
|
|
||||||
|
|
||||||
# Add the source and target values
|
# Add the source and target values
|
||||||
for shape in [self.source, self.target]:
|
for shape in [self.source, self.target]:
|
||||||
aspect_ratio = shape.width() / shape.height()
|
aspect_ratio = shape.width() / shape.height()
|
||||||
# If the pin is tall or fat, add two points on the ends
|
# If the pin is tall or fat, add two points on the ends
|
||||||
if aspect_ratio <= 0.5: # Tall pin
|
if aspect_ratio <= 0.5: # Tall pin
|
||||||
uc = shape.uc()
|
points = [shape.uc(), shape.bc()]
|
||||||
bc = shape.bc()
|
|
||||||
points = [vector(uc.x, uc.y - offset),
|
|
||||||
vector(bc.x, bc.y + offset)]
|
|
||||||
elif aspect_ratio >= 2: # Fat pin
|
elif aspect_ratio >= 2: # Fat pin
|
||||||
lc = shape.lc()
|
points = [shape.lc(), shape.rc()]
|
||||||
rc = shape.rc()
|
|
||||||
points = [vector(lc.x + offset, lc.y),
|
|
||||||
vector(rc.x - offset, rc.y)]
|
|
||||||
else: # Square-like pin
|
else: # Square-like pin
|
||||||
center = shape.center()
|
points = [shape.center()]
|
||||||
x_values.add(center.x)
|
|
||||||
y_values.add(center.y)
|
|
||||||
continue
|
|
||||||
for p in points:
|
for p in points:
|
||||||
x_values.add(p.x)
|
x_values.add(p.x)
|
||||||
y_values.add(p.y)
|
y_values.add(p.y)
|
||||||
|
|
||||||
# Add corners for blockages
|
# Add corners for blockages
|
||||||
|
offset = drc["grid"]
|
||||||
for blockage in self.graph_blockages:
|
for blockage in self.graph_blockages:
|
||||||
ll, ur = blockage.rect
|
ll, ur = blockage.rect
|
||||||
|
# Add minimum offset to the blockage corner nodes to prevent overlaps
|
||||||
x_values.update([ll.x - offset, ur.x + offset])
|
x_values.update([ll.x - offset, ur.x + offset])
|
||||||
y_values.update([ll.y - offset, ur.y + offset])
|
y_values.update([ll.y - offset, ur.y + offset])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,7 @@ class hanan_router(router_tech):
|
||||||
""" """
|
""" """
|
||||||
debug.info(1, "Finding all blockages...")
|
debug.info(1, "Finding all blockages...")
|
||||||
|
|
||||||
|
blockages = []
|
||||||
for lpp in [self.vert_lpp, self.horiz_lpp]:
|
for lpp in [self.vert_lpp, self.horiz_lpp]:
|
||||||
shapes = self.layout.getAllShapes(lpp)
|
shapes = self.layout.getAllShapes(lpp)
|
||||||
for boundary in shapes:
|
for boundary in shapes:
|
||||||
|
|
@ -117,37 +118,31 @@ class hanan_router(router_tech):
|
||||||
ll = vector(boundary[0], boundary[1])
|
ll = vector(boundary[0], boundary[1])
|
||||||
ur = vector(boundary[2], boundary[3])
|
ur = vector(boundary[2], boundary[3])
|
||||||
rect = [ll, ur]
|
rect = [ll, ur]
|
||||||
new_shape = hanan_shape("blockage{}".format(len(self.blockages)),
|
new_shape = hanan_shape("blockage{}".format(len(blockages)),
|
||||||
rect,
|
rect,
|
||||||
lpp)
|
lpp)
|
||||||
# If there is a rectangle that is the same in the pins,
|
# If there is a rectangle that is the same in the pins,
|
||||||
# it isn't a blockage
|
# it isn't a blockage
|
||||||
if new_shape not in self.all_pins and not new_shape.contained_by_any(self.all_pins) and not self.blockage_contains(new_shape):
|
if new_shape.contained_by_any(self.all_pins) or new_shape.contained_by_any(blockages):
|
||||||
new_shape = new_shape.inflated_pin(multiple=1)
|
continue
|
||||||
# Remove blockages contained by this new blockage
|
# Remove blockages contained by this new blockage
|
||||||
for i in range(len(self.blockages) - 1, -1, -1):
|
for i in range(len(blockages) - 1, -1, -1):
|
||||||
blockage = self.blockages[i]
|
blockage = blockages[i]
|
||||||
# Remove the previous blockage contained by this new
|
# Remove the previous blockage contained by this new
|
||||||
# blockage
|
# blockage
|
||||||
if new_shape.contains(blockage):
|
if new_shape.contains(blockage):
|
||||||
self.blockages.remove(blockage)
|
blockages.remove(blockage)
|
||||||
# Merge the previous blockage into this new blockage if
|
# Merge the previous blockage into this new blockage if
|
||||||
# they are aligning
|
# they are aligning
|
||||||
elif new_shape.aligns(blockage):
|
elif new_shape.aligns(blockage):
|
||||||
new_shape.bbox([blockage])
|
new_shape.bbox([blockage])
|
||||||
self.blockages.remove(blockage)
|
blockages.remove(blockage)
|
||||||
self.blockages.append(new_shape)
|
blockages.append(new_shape)
|
||||||
|
|
||||||
|
# Inflate the shapes to prevent DRC errors
|
||||||
def blockage_contains(self, shape):
|
offset = self.layer_widths[0] / 2
|
||||||
"""
|
for blockage in blockages:
|
||||||
Return if this shape is contained by a blockage.
|
self.blockages.append(blockage.inflated_pin(spacing=offset, multiple=1))
|
||||||
"""
|
|
||||||
|
|
||||||
for blockage in self.blockages:
|
|
||||||
if blockage.contains(shape):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def add_path(self, path):
|
def add_path(self, path):
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
from openram.base.pin_layout import pin_layout
|
from openram.base.pin_layout import pin_layout
|
||||||
|
from openram.base.vector import vector
|
||||||
|
from openram.tech import drc
|
||||||
|
|
||||||
|
|
||||||
class hanan_shape(pin_layout):
|
class hanan_shape(pin_layout):
|
||||||
|
|
@ -20,7 +22,14 @@ class hanan_shape(pin_layout):
|
||||||
def inflated_pin(self, spacing=None, multiple=0.5):
|
def inflated_pin(self, spacing=None, multiple=0.5):
|
||||||
""" Override the default inflated_pin behavior. """
|
""" Override the default inflated_pin behavior. """
|
||||||
|
|
||||||
inflated_area = self.inflate(spacing, multiple)
|
if not spacing:
|
||||||
|
spacing = 0
|
||||||
|
drc_spacing = multiple * drc("{0}_to_{0}".format(self.layer))
|
||||||
|
spacing = vector([spacing + drc_spacing] * 2)
|
||||||
|
(ll, ur) = self.rect
|
||||||
|
newll = ll - spacing
|
||||||
|
newur = ur + spacing
|
||||||
|
inflated_area = (newll, newur)
|
||||||
return hanan_shape(self.name, inflated_area, self.layer)
|
return hanan_shape(self.name, inflated_area, self.layer)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue