mirror of https://github.com/VLSIDA/OpenRAM.git
updata io_pin_placer
This commit is contained in:
parent
ee6be23cfa
commit
61f5ff6ec4
|
|
@ -13,9 +13,6 @@ from .router import router
|
|||
import re
|
||||
|
||||
class io_pin_placer(router):
|
||||
"""
|
||||
This is the signal escape router that uses the Hanan grid graph method.
|
||||
"""
|
||||
|
||||
def __init__(self, layers, design, bbox=None):
|
||||
|
||||
|
|
@ -30,6 +27,9 @@ class io_pin_placer(router):
|
|||
self.io_pins_added_right = []
|
||||
self.io_pins_added_up = []
|
||||
self.io_pins_added_down = []
|
||||
|
||||
# fake_pins, use for rename
|
||||
self.io_pins_fake =[]
|
||||
|
||||
|
||||
def get_closest_edge(self, point):
|
||||
|
|
@ -51,8 +51,162 @@ class io_pin_placer(router):
|
|||
if min_diff == ur_diff_x:
|
||||
return "right", True
|
||||
return "top", False
|
||||
|
||||
|
||||
|
||||
def initial_position(self, pins): # pins is list []
|
||||
""" Set the IO pin center at the perimeter """
|
||||
pattern_clk = r'^clk'
|
||||
pattern_addr0 = r'^addr0'
|
||||
pattern_addr1 = r'^addr1'
|
||||
pattern_dout0 = r'^dout0'
|
||||
pattern_dout1 = r'^dout1'
|
||||
pattern_din = r'^din'
|
||||
pattern_wmask = r'^wmask'
|
||||
pattern_spare_wen = r'^spare_wen'
|
||||
pattern_web = r'^web'
|
||||
pattern_csb = r'^csb'
|
||||
for pin in pins:
|
||||
c = pin.center()
|
||||
# Find the closest edge
|
||||
edge, vertical = self.get_closest_edge(c)
|
||||
if re.match(pattern_clk, pin.name):# clk, should be placed at horizontal edge
|
||||
if edge == "bottom" or edge == "left":
|
||||
edge = "bottom"
|
||||
elif edge == "top" or edge == "right":
|
||||
edge = "top"
|
||||
self.store_position(pin, edge, vertical)
|
||||
if re.match(pattern_addr0, pin.name): # all the addr0[] should be placed at left edge
|
||||
if edge == "top" or edge == "left":
|
||||
edge = "left"
|
||||
vertical = True
|
||||
elif edge == "bottom": # but for big sram, addr0[] may have pins at bottom, which is allowed
|
||||
vertical = False
|
||||
self.store_position(pin, edge, vertical)
|
||||
if re.match(pattern_addr1, pin.name): # all the addr1[] should be placed at right edge
|
||||
if edge == "bottom" or edge == "right":
|
||||
edge = "right"
|
||||
vertical = True
|
||||
elif edge == "top": # but for big sram, addr1[] may have pins at top, which is allowed
|
||||
vertical = False
|
||||
self.store_position(pin, edge, vertical)
|
||||
if re.match(pattern_din, pin.name): # din
|
||||
self.store_position(pin, edge, vertical)
|
||||
if re.match(pattern_wmask, pin.name): # wmask
|
||||
self.store_position(pin, edge, vertical)
|
||||
if re.match(pattern_spare_wen, pin.name): # spare_wen
|
||||
self.store_position(pin, edge, vertical)
|
||||
if re.match(pattern_csb, pin.name):# csb
|
||||
self.store_position(pin, edge, vertical)
|
||||
if re.match(pattern_web, pin.name): # web
|
||||
self.store_position(pin, edge, vertical)
|
||||
# special handle the dout pins, if r/rw ports
|
||||
for pin in pins:
|
||||
if re.match(pattern_dout0, pin.name):
|
||||
edge = "bottom"
|
||||
vertical = False
|
||||
self.store_dout_position(pin, edge, vertical)
|
||||
if re.match(pattern_dout1, pin.name):
|
||||
edge = "top"
|
||||
vertical = False
|
||||
self.store_dout_position(pin, edge, vertical)
|
||||
|
||||
|
||||
def check_overlap(self, pin_position, edge):
|
||||
""" Return the suggested position to aviod overlap """
|
||||
ll, ur = self.bbox
|
||||
c = pin_position # original source pin center
|
||||
offset = 0.95 + 0.19 # FIX: this is the magic number to overcome the ovetflow problem at the boundary, may need a method
|
||||
add_distance = 0
|
||||
|
||||
if edge == "bottom":
|
||||
fake_center = vector(c.x, ll.y - self.track_wire * 2 + offset)
|
||||
pin_to_close = any(abs(pin_added.center().x - fake_center.x) < (0.4 + self.half_wire * 4)for pin_added in self.io_pins_added_down)
|
||||
via_to_close = False
|
||||
# if cannot direct place below the source pin, need move towards right, and ensure the min. distance between vias
|
||||
while pin_to_close or via_to_close:
|
||||
debug.warning("overlap, changing position")
|
||||
add_distance = add_distance + 0.1
|
||||
fake_center = vector(c.x + add_distance, ll.y - self.track_wire * 2 + offset)
|
||||
pin_to_close = any(abs(pin_added.center().x - fake_center.x) < (0.4 + self.half_wire * 4)for pin_added in self.io_pins_added_down)
|
||||
via_to_close = abs(fake_center.x - c.x) < 0.6
|
||||
if edge == "top":
|
||||
fake_center = vector(c.x, ur.y + self.track_wire * 2 - offset)
|
||||
pin_to_close = any(abs(pin_added.center().x - fake_center.x) < (0.4 + self.half_wire * 4)for pin_added in self.io_pins_added_up)
|
||||
via_to_close = False
|
||||
# if cannot direct place below the source pin, need move towards right, and ensure the min. distance between vias
|
||||
while pin_to_close or via_to_close:
|
||||
debug.warning("overlap, changing position")
|
||||
add_distance = add_distance + 0.1
|
||||
fake_center = vector(c.x + add_distance, ur.y + self.track_wire * 2 - offset)
|
||||
pin_to_close = any(abs(pin_added.center().x - fake_center.x) < (0.4 + self.half_wire * 4)for pin_added in self.io_pins_added_up)
|
||||
via_to_close = abs(fake_center.x - c.x) < 0.6
|
||||
|
||||
return fake_center
|
||||
|
||||
|
||||
def store_dout_position(self, pin, edge, vertical):
|
||||
pin_position = pin.center()
|
||||
pin_position = self.check_overlap(pin_position, edge)
|
||||
# store the center position, rect, layer of fake pin, here make sure the pin in the gds will be big enough
|
||||
layer = self.get_layer(int(not vertical))
|
||||
half_wire_vector = vector([self.half_wire] * 2)
|
||||
nll = pin_position - half_wire_vector - half_wire_vector
|
||||
nur = pin_position + half_wire_vector + half_wire_vector
|
||||
rect = [nll, nur]
|
||||
#fake_pin = [pin.name() + "_" + "fake", pin_position, rect, layer]
|
||||
fake_pin = graph_shape(name=pin.name + "_" + "fake",
|
||||
rect=rect,
|
||||
layer_name_pp=layer)
|
||||
|
||||
if edge == "left":
|
||||
self.io_pins_added_left.append(fake_pin)
|
||||
elif edge == "bottom":
|
||||
self.io_pins_added_down.append(fake_pin)
|
||||
elif edge == "right":
|
||||
self.io_pins_added_right.append(fake_pin)
|
||||
elif edge == "top":
|
||||
self.io_pins_added_up.append(fake_pin)
|
||||
|
||||
self.io_pins_fake.append(fake_pin)
|
||||
debug.warning("pin added: {0}".format(fake_pin))
|
||||
|
||||
|
||||
def store_position(self, pin, edge, vertical): # also need to store the source pin
|
||||
ll, ur = self.bbox
|
||||
c = pin.center()
|
||||
offset = 0.95 + 0.19 # FIX: this is the magic number to overcome the ovetflow problem at the boundary, may need a method
|
||||
if edge == "left":
|
||||
fake_center = vector(ll.x - self.track_wire * 2 + offset, c.y)
|
||||
if edge == "bottom":
|
||||
fake_center = vector(c.x, ll.y - self.track_wire * 2 + offset)
|
||||
if edge == "right":
|
||||
fake_center = vector(ur.x + self.track_wire * 2 - offset, c.y)
|
||||
if edge == "top":
|
||||
fake_center = vector(c.x, ur.y + self.track_wire * 2 - offset)
|
||||
# store the center position, rect, layer of fake pin, here make sure the pin in the gds will be big enough
|
||||
layer = self.get_layer(int(not vertical))
|
||||
half_wire_vector = vector([self.half_wire] * 2)
|
||||
nll = fake_center - half_wire_vector - half_wire_vector
|
||||
nur = fake_center + half_wire_vector + half_wire_vector
|
||||
rect = [nll, nur]
|
||||
#fake_pin = [pin.name() + "_" + "fake", fake_center, rect, layer]
|
||||
fake_pin = graph_shape(name=pin.name + "_" + "fake",
|
||||
rect=rect,
|
||||
layer_name_pp=layer)
|
||||
|
||||
if edge == "left":
|
||||
self.io_pins_added_left.append(fake_pin)
|
||||
elif edge == "bottom":
|
||||
self.io_pins_added_down.append(fake_pin)
|
||||
elif edge == "right":
|
||||
self.io_pins_added_right.append(fake_pin)
|
||||
elif edge == "top":
|
||||
self.io_pins_added_up.append(fake_pin)
|
||||
|
||||
self.io_pins_fake.append(fake_pin)
|
||||
debug.warning("pin added: {0}".format(fake_pin))
|
||||
|
||||
|
||||
def create_fake_pin(self, pin):
|
||||
""" Create a fake pin on the perimeter orthogonal to the given pin. """
|
||||
|
||||
|
|
@ -63,51 +217,70 @@ class io_pin_placer(router):
|
|||
print(pin.name)
|
||||
# Find the closest edge
|
||||
edge, vertical = self.get_closest_edge(c)
|
||||
# Relocate the pin position of addr/dout
|
||||
pattern_addr = r'^addr'
|
||||
pattern_dout = r'^dout'
|
||||
if re.match(pattern_addr, pin.name):# all the addr[] should be placed at vertical edge
|
||||
if edge == "top" or edge == "left":
|
||||
edge = "left"
|
||||
vertical = True
|
||||
elif edge == "bottom" or edge == "right":
|
||||
edge = "right"
|
||||
vertical = True
|
||||
|
||||
if re.match(pattern_dout, pin.name):# all the dout[] should be placed at horizontal edge
|
||||
if edge == "bottom" or edge == "right":
|
||||
edge = "bottom"
|
||||
vertical = False
|
||||
elif edge == "top" or edge == "left":
|
||||
edge = "top"
|
||||
vertical = False
|
||||
|
||||
offset = 0.95 + 0.19 # FIX: this is the magic number to overcome the ovetflow problem at the boundary, may need a method
|
||||
add_distance = 0
|
||||
# Keep the fake pin out of the SRAM layout are so that they won't be
|
||||
# blocked by previous signals if they're on the same orthogonal line
|
||||
if edge == "left":
|
||||
fake_center = vector(ll.x - self.track_wire * 2 + offset, c.y)
|
||||
is_too_close = any(abs(pin_added.center().y - fake_center.y) < (0.8 + self.half_wire * 4)for pin_added in self.io_pins_added_left)
|
||||
is_too_close = any(abs(pin_added.center().y - fake_center.y) < (0.4 + self.half_wire * 4)for pin_added in self.io_pins_added_left)
|
||||
while is_too_close:
|
||||
debug.warning("overlap, changing position")
|
||||
add_distance = add_distance + 0.8 + self.half_wire * 4
|
||||
add_distance = add_distance + 0.1#+ 0.4 + self.half_wire * 4
|
||||
fake_center = vector(ll.x - self.track_wire * 2 + offset, c.y + add_distance)
|
||||
is_too_close = any(abs(pin_added.center().y - fake_center.y) < (0.8 + self.half_wire * 4)for pin_added in self.io_pins_added_left)
|
||||
is_too_close = any(abs(pin_added.center().y - fake_center.y) < (0.4 + self.half_wire * 4)for pin_added in self.io_pins_added_left)
|
||||
|
||||
if edge == "bottom":
|
||||
fake_center = vector(c.x, ll.y - self.track_wire * 2 + offset)
|
||||
is_too_close = any(abs(pin_added.center().x - fake_center.x) < (0.8 + self.half_wire * 4)for pin_added in self.io_pins_added_down)
|
||||
is_too_close = any(abs(pin_added.center().x - fake_center.x) < (0.4 + self.half_wire * 4)for pin_added in self.io_pins_added_down)
|
||||
while is_too_close:
|
||||
debug.warning("overlap, changing position")
|
||||
add_distance = add_distance + 0.8 + self.half_wire * 4
|
||||
add_distance = add_distance + 0.1#0.4 + self.half_wire * 4
|
||||
fake_center = vector(c.x + add_distance, ll.y - self.track_wire * 2 + offset)
|
||||
is_too_close = any(abs(pin_added.center().x - fake_center.x) < (0.8 + self.half_wire * 4)for pin_added in self.io_pins_added_down)
|
||||
is_too_close = any(abs(pin_added.center().x - fake_center.x) < (0.4 + self.half_wire * 4)for pin_added in self.io_pins_added_down)
|
||||
|
||||
if edge == "right":
|
||||
fake_center = vector(ur.x + self.track_wire * 2 - offset, c.y)
|
||||
is_too_close = any(abs(pin_added.center().y - fake_center.y) < (0.8 + self.half_wire * 4)for pin_added in self.io_pins_added_right)
|
||||
is_too_close = any(abs(pin_added.center().y - fake_center.y) < (0.4 + self.half_wire * 4)for pin_added in self.io_pins_added_right)
|
||||
while is_too_close:
|
||||
debug.warning("overlap, changing position")
|
||||
add_distance = add_distance + 0.8 + self.half_wire * 4
|
||||
add_distance = add_distance + 0.1#0.4 + self.half_wire * 4
|
||||
fake_center = vector(ur.x + self.track_wire * 2 - offset, c.y + add_distance)
|
||||
# debug
|
||||
for pin_added in self.io_pins_added_right:
|
||||
dis = abs(pin_added.center().y - fake_center.y)
|
||||
debug.warning("current position is {0}".format(fake_center))
|
||||
debug.warning("distance from {0} is {1}".format(pin_added, dis))
|
||||
debug.warning("must disrance is {0}".format(0.8 + self.half_wire * 4))
|
||||
is_too_close = any(abs(pin_added.center().y - fake_center.y) < (0.8 + self.half_wire * 4)for pin_added in self.io_pins_added_right)
|
||||
debug.warning("must disrance is {0}".format(0.4 + self.half_wire * 4))
|
||||
is_too_close = any(abs(pin_added.center().y - fake_center.y) < (0.4 + self.half_wire * 4)for pin_added in self.io_pins_added_right)
|
||||
|
||||
if edge == "top":
|
||||
fake_center = vector(c.x, ur.y + self.track_wire * 2 - offset)
|
||||
is_too_close = any(abs(pin_added.center().x - fake_center.x) < (0.8 + self.half_wire * 4)for pin_added in self.io_pins_added_up)
|
||||
is_too_close = any(abs(pin_added.center().x - fake_center.x) < (0.4 + self.half_wire * 4)for pin_added in self.io_pins_added_up)
|
||||
while is_too_close:
|
||||
debug.warning("overlap, changing position")
|
||||
add_distance = add_distance + 0.8 + self.half_wire * 4
|
||||
add_distance = add_distance + 0.1#0.4 + self.half_wire * 4
|
||||
fake_center = vector(c.x + add_distance, ur.y + self.track_wire * 2 - offset)
|
||||
is_too_close = any(abs(pin_added.center().x - fake_center.x) < (0.8 + self.half_wire * 4)for pin_added in self.io_pins_added_up)
|
||||
is_too_close = any(abs(pin_added.center().x - fake_center.x) < (0.4 + self.half_wire * 4)for pin_added in self.io_pins_added_up)
|
||||
|
||||
# Create the fake pin shape, here make sure the pin in the gds will be big enough
|
||||
layer = self.get_layer(int(not vertical))
|
||||
|
|
@ -133,11 +306,11 @@ class io_pin_placer(router):
|
|||
self.io_pins_added_up.append(pin)
|
||||
debug.warning("pin added: {0}".format(pin))
|
||||
|
||||
return pin
|
||||
return pin, vertical, add_distance
|
||||
|
||||
|
||||
def add_io_pins(self, pin_names):
|
||||
""" Add IO pins on the edges without routing them. """
|
||||
""" Add IO pins on the edges WITHOUT routing them. """
|
||||
debug.info(1, "Adding IO pins on the perimeter...")
|
||||
|
||||
# Prepare GDS reader (if necessary for pin/blockage identification)
|
||||
|
|
@ -147,16 +320,188 @@ class io_pin_placer(router):
|
|||
for name in pin_names:
|
||||
self.find_pins(name)# this will add the pins to the self.pins
|
||||
|
||||
# Replace layout pins with those on the perimeter
|
||||
# inital position
|
||||
pin_list = []
|
||||
for name in self.pins:
|
||||
pin = next(iter(self.pins[name]))
|
||||
fake_pin = self.create_fake_pin(pin)
|
||||
self.design.replace_layout_pin(name, fake_pin) # if do not have replace_layout_pin, final gds won't have io pins
|
||||
|
||||
|
||||
pin_list.append(pin)
|
||||
|
||||
self.initial_position(pin_list)
|
||||
|
||||
# Change IO pin names, which means "internal name" will be used, and internal io pins will not have label such as "dout0[0]"
|
||||
self.replace_layout_pins(pin_names)
|
||||
|
||||
|
||||
def add_io_pins_connected(self, pin_names):
|
||||
""" Add IO pins on the edges WITH routing them. """
|
||||
debug.info(1, "Adding IO pins on the perimeter...")
|
||||
|
||||
# Prepare GDS reader (if necessary for pin/blockage identification)
|
||||
self.prepare_gds_reader()
|
||||
|
||||
# Find pins to be added (without routing)
|
||||
for name in pin_names:
|
||||
self.find_pins(name)# this will add the pins to the self.pins
|
||||
debug.warning("the pins in pin_name -> {0}".format(name))
|
||||
|
||||
# inital position
|
||||
pin_list = []
|
||||
for name in self.pins:
|
||||
pin = next(iter(self.pins[name]))
|
||||
pin_list.append(pin)
|
||||
debug.warning("the pins in self.pins -> {0}".format(name))
|
||||
|
||||
self.initial_position(pin_list)
|
||||
|
||||
# add fake io pins at the perimeter, which will be used for routing
|
||||
for fake_pin in self.io_pins_fake:
|
||||
self.design.add_layout_pin(text=fake_pin.name,
|
||||
layer=fake_pin.layer,
|
||||
offset=fake_pin.ll(),
|
||||
width=fake_pin.width(),
|
||||
height=fake_pin.height())
|
||||
|
||||
# connect the source_pin and io_pin(target)
|
||||
self.connect_pins(pin_names)
|
||||
|
||||
# remove the fake pin before change the name, in order to avoid possible problem
|
||||
for fake_pin in self.io_pins_fake:
|
||||
self.remove_io_pins(fake_pin.name)
|
||||
|
||||
# Change IO pin names, which means "internal name" will be used, and internal io pins will not have label such as "dout0[0]"
|
||||
self.replace_layout_pins(pin_names)
|
||||
|
||||
|
||||
def connect_pins(self, pin_names): # pin_names should be a list
|
||||
""" Add IO pins on the edges, and connect them to the internal one, not-graph like process """
|
||||
debug.info(1, "connecting to io pins...")
|
||||
pattern_dout = r'^dout'
|
||||
for pin_name in pin_names:
|
||||
# get pin pairs ready
|
||||
source_pin = next(iter(self.pins[pin_name]))
|
||||
for fake_pin in self.io_pins_fake:
|
||||
if pin_name + "_" + "fake" == fake_pin.name:
|
||||
target_pin = fake_pin
|
||||
break
|
||||
# special hanlde dout pins
|
||||
if re.match(pattern_dout, pin_name):
|
||||
number_str = re.findall(r'\[(\d+)\]', pin_name)
|
||||
if number_str:
|
||||
number = int(number_str[0])
|
||||
if number % 2 == 0:
|
||||
is_up = True
|
||||
else:
|
||||
is_up = False
|
||||
point_list = self.decide_point(source_pin, target_pin, is_up)
|
||||
self.add_wire(point_list)
|
||||
# other pins
|
||||
else:
|
||||
debug.warning("source{0}".format(source_pin.center()))
|
||||
debug.warning("target{0}".format(target_pin.center()))
|
||||
point_list = self.decide_point(source_pin, target_pin)
|
||||
debug.warning("point_list->{0}".format(point_list))
|
||||
self.add_wire(point_list)
|
||||
|
||||
|
||||
def add_wire(self, point_list):
|
||||
if len(point_list) == 2:
|
||||
# direct connect
|
||||
self.add_line(point_list[0], point_list[1])
|
||||
elif len(point_list) == 4:
|
||||
# intermediate points
|
||||
self.add_line(point_list[0], point_list[1])
|
||||
self.add_via(point_list[1])
|
||||
self.add_line(point_list[1], point_list[2])
|
||||
self.add_via(point_list[2])
|
||||
self.add_line(point_list[2], point_list[3])
|
||||
|
||||
|
||||
def add_line(self, point_1, point_2):
|
||||
if round(point_1.y, 3) == round(point_2.y, 3):
|
||||
# horizontal m3
|
||||
self.design.add_path(self.get_layer(False), [point_1, point_2])
|
||||
else:
|
||||
# vertical m4
|
||||
self.design.add_path(self.get_layer(True), [point_1, point_2])
|
||||
|
||||
|
||||
def add_via(self, point):
|
||||
# currently only m3-m4 vias are supported in this method
|
||||
# usd in order to make "z" shape routing only
|
||||
self.design.add_via_stack_center(from_layer=self.get_layer(False),
|
||||
to_layer=self.get_layer(True),
|
||||
offset=point)
|
||||
|
||||
|
||||
def add_start_via(self, point):
|
||||
# currently only m3-m4 vias are supported in this method
|
||||
# used in source_pin only
|
||||
self.design.add_via_stack_center(from_layer=self.get_layer(False),
|
||||
to_layer=self.get_layer(True),
|
||||
offset=point)
|
||||
|
||||
|
||||
def decide_point(self, source_pin, target_pin, is_up=False):
|
||||
ll, ur = self.bbox
|
||||
offset = 0.95 + 0.19 # FIX: this is the magic number to overcome the ovetflow problem at the boundary, may need a method
|
||||
# internal -> left
|
||||
if round(target_pin.center().x, 3) == round(ll.x - self.track_wire * 2 + offset, 3):
|
||||
# direct connect possible
|
||||
return [source_pin.rc(), target_pin.lc()] # FIX: not sure if shape overlap in met3 allowed, but seems OK
|
||||
# internal -> right
|
||||
if round(target_pin.center().x, 3) == round(ur.x + self.track_wire * 2 - offset, 3):
|
||||
# direct connect possible
|
||||
return [source_pin.lc(), target_pin.rc()]
|
||||
# internal -> top, need to add start_via m3->m4
|
||||
if round(target_pin.center().y, 3) == round(ur.y + self.track_wire * 2 - offset, 3):
|
||||
self.add_start_via(source_pin.center())
|
||||
if round(target_pin.center().x, 3) == round(source_pin.center().x, 3):
|
||||
# direct connect possible
|
||||
return [source_pin.bc(), target_pin.uc()]
|
||||
else:
|
||||
# need intermediate point
|
||||
via_basic_y = self.design.bank.height + 3 # 3 is magic number, make sure out of bank area
|
||||
is_up = not is_up# Be attention, for channel at the top, the is_up should be inverted! Otherwise will cause overlap!
|
||||
if is_up:
|
||||
via_basic_y = via_basic_y + 0.5
|
||||
else:
|
||||
via_basic_y = via_basic_y - 0.5
|
||||
point_1 = vector(source_pin.center().x, via_basic_y)
|
||||
point_2 = vector(target_pin.center().x, via_basic_y)
|
||||
return [source_pin.bc(), point_1, point_2, target_pin.uc()]
|
||||
# internal -> bottom, need to add start_via m3->m4
|
||||
if round(target_pin.center().y, 3) == round(ll.y - self.track_wire * 2 + offset, 3):
|
||||
self.add_start_via(source_pin.center())
|
||||
if round(target_pin.center().x, 3) == round(source_pin.center().x, 3):
|
||||
# direct connect possible
|
||||
return [source_pin.uc(), target_pin.bc()]
|
||||
else:
|
||||
# need intermediate point
|
||||
via_basic_y = ll.y + 21 # 21 is magic number, make sure out of dff area
|
||||
if is_up:
|
||||
via_basic_y = via_basic_y + 0.5
|
||||
else:
|
||||
via_basic_y = via_basic_y - 0.5
|
||||
point_1 = vector(source_pin.center().x, via_basic_y)
|
||||
point_2 = vector(target_pin.center().x, via_basic_y)
|
||||
return [source_pin.uc(), point_1, point_2, target_pin.bc()]
|
||||
|
||||
|
||||
def remove_io_pins(self, pin_name):
|
||||
# remove io pin in gds, so we could reroute
|
||||
self.design.remove_layout_pin(pin_name)
|
||||
|
||||
|
||||
def replace_layout_pins(self, pin_names):
|
||||
""" Change the IO pin names with new ones around the perimeter. """
|
||||
for pin_name in pin_names:
|
||||
perimeter_pin_name = pin_name + "_" + "fake"
|
||||
for pin in self.io_pins_fake:
|
||||
if pin.name == perimeter_pin_name:
|
||||
perimeter_pin = pin
|
||||
self.design.replace_layout_pin(pin_name, perimeter_pin)
|
||||
break
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue