OpenRAM/compiler/router/graph_shape.py

106 lines
2.8 KiB
Python
Raw Normal View History

# See LICENSE for licensing information.
#
# Copyright (c) 2016-2023 Regents of the University of California, Santa Cruz
# All rights reserved.
#
from openram.base.pin_layout import pin_layout
2023-06-06 04:33:45 +02:00
from openram.base.vector import vector
from openram.tech import drc
from .graph_utils import snap
2023-07-13 21:07:55 +02:00
class graph_shape(pin_layout):
"""
This class inherits the pin_layout class to change some of its behavior for
2023-07-13 21:07:55 +02:00
the graph router.
"""
2023-07-25 19:26:23 +02:00
def __init__(self, name, rect, layer_name_pp, core=None):
pin_layout.__init__(self, name, rect, layer_name_pp)
# Snap the shape to the grid here
ll, ur = self.rect
self.rect = [snap(ll), snap(ur)]
2023-07-25 19:26:23 +02:00
# Core is the original shape from which this shape is inflated
self.core = core
def center(self):
""" Override the default `center` behavior. """
return snap(super().center())
def height(self):
""" Override the default `height` behavior. """
return snap(super().height())
def width(self):
""" Override the default `width` behavior. """
return snap(super().width())
2023-07-25 19:26:23 +02:00
def get_core(self):
2023-07-21 17:26:54 +02:00
"""
2023-07-25 19:26:23 +02:00
Return `self` if `self.core` is None. Otherwise, return `self.core`.
2023-07-21 17:26:54 +02:00
"""
2023-07-25 19:26:23 +02:00
if self.core is None:
2023-07-21 17:26:54 +02:00
return self
2023-07-25 19:26:23 +02:00
return self.core
2023-07-21 17:26:54 +02:00
def inflated_pin(self, spacing=None, multiple=0.5, extra_spacing=0):
""" Override the default inflated_pin behavior. """
ll, ur = self.inflate(spacing, multiple)
extra = vector([extra_spacing] * 2)
newll = ll - extra
newur = ur + extra
2023-06-06 04:33:45 +02:00
inflated_area = (newll, newur)
return graph_shape(self.name, inflated_area, self.layer, self)
def multiply(self, scale):
""" Multiply the width and height with the scale value. """
width = (self.width() * (scale - 1)) / 2
height = (self.height() * (scale - 1)) / 2
ll, ur = self.rect
newll = vector(ll.x - width, ll.y - height)
newur = vector(ur.x + width, ur.y + height)
self.rect = [snap(newll), snap(newur)]
def core_contained_by_any(self, shape_list):
"""
Return if the core of this shape is contained by any shape's core in the
given list.
"""
self_core = self.get_core()
for shape in shape_list:
shape_core = shape.get_core()
if shape_core.contains(self_core):
return True
return False
def aligns(self, other):
""" Return if the other shape aligns with this shape. """
# Shapes must overlap to be able to align
if not self.overlaps(other):
return False
ll, ur = self.rect
oll, our = other.rect
if ll.x == oll.x and ur.x == our.x:
return True
if ll.y == oll.y and ur.y == our.y:
return True
return False