mirror of
https://github.com/VLSIDA/OpenRAM.git
synced 2026-09-02 02:57:53 +02:00
Change path to wire_path for Anaconda package conflict
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
from tech import drc
|
||||
from tech import layer as techlayer
|
||||
import debug
|
||||
from vector import vector
|
||||
from utils import snap_to_grid
|
||||
|
||||
def create_rectilinear_route(my_list):
|
||||
""" Add intermediate nodes if it isn't rectilinear. Also skip
|
||||
repeated nodes. Also, convert to vector if the aren't."""
|
||||
pl = [snap_to_grid(x) for x in my_list]
|
||||
|
||||
my_list = []
|
||||
for index in range(len(pl) - 1):
|
||||
if pl[index] != pl[index + 1]:
|
||||
my_list.append(vector(pl[index]))
|
||||
if (pl[index][0] != pl[index + 1][0]) and (pl[index][1] != pl[index + 1][1]):
|
||||
my_list.append(vector(pl[index][0], pl[index + 1][1]))
|
||||
my_list.append(vector(pl[-1]))
|
||||
return my_list
|
||||
|
||||
class wire_path():
|
||||
"""
|
||||
Object metal wire_path; given the layer type
|
||||
Add a wire_path of minimium metal width between a set of points.
|
||||
The points should be rectilinear to control the bend points. If
|
||||
not, it will always go down first. The points are the center of the wire_path.
|
||||
If width is not given, it uses minimum layer width.
|
||||
"""
|
||||
def __init__(self, obj, layer, position_list, width=None):
|
||||
self.obj = obj
|
||||
self.layer_name = layer
|
||||
self.layer_id = techlayer[layer]
|
||||
if width==None:
|
||||
self.layer_width = drc["minwidth_{0}".format(layer)]
|
||||
else:
|
||||
self.layer_width = width
|
||||
self.position_list = position_list
|
||||
self.pins = [] # used for matching parm lengths
|
||||
self.switch_pos_list = []
|
||||
self.create_layout()
|
||||
|
||||
|
||||
def create_layout(self):
|
||||
self.create_rectilinear()
|
||||
self.connect_corner()
|
||||
self.create_rectangles()
|
||||
# wires and wire_paths should not be offset to (0,0)
|
||||
|
||||
def create_rectilinear(self):
|
||||
""" Add intermediate nodes if it isn't rectilinear. Also skip
|
||||
repeated nodes. Also, convert to vector if the aren't."""
|
||||
self.position_list = create_rectilinear_route(self.position_list)
|
||||
|
||||
def connect_corner(self):
|
||||
""" Add a corner square at every corner of the wire_path."""
|
||||
from itertools import tee,islice
|
||||
nwise = lambda g,n=2: zip(*(islice(g,i,None) for i,g in enumerate(tee(g,n))))
|
||||
threewise=nwise(self.position_list,3)
|
||||
|
||||
for (a, offset, c) in list(threewise):
|
||||
# add a exceptions to prevent a corner when we retrace back in the same direction
|
||||
if a[0] == c[0]:
|
||||
continue
|
||||
if a[1] == c[1]:
|
||||
continue
|
||||
corner_offset = [offset[0] - 0.5 * self.layer_width,
|
||||
offset[1] - 0.5 * self.layer_width]
|
||||
self.draw_corner_wire(corner_offset)
|
||||
|
||||
|
||||
def draw_corner_wire(self, offset):
|
||||
""" This function adds the corner squares since the center
|
||||
line convention only draws to the center of the corner."""
|
||||
self.obj.add_rect(layer=self.layer_name,
|
||||
offset=offset,
|
||||
width=self.layer_width,
|
||||
height=self.layer_width)
|
||||
|
||||
def create_rectangles(self):
|
||||
""" Create the actual rectangles on teh appropriate layers
|
||||
using the position list of the corners. """
|
||||
pl = self.position_list # position list
|
||||
for index in range(len(pl) - 1):
|
||||
# if we have x motion
|
||||
if pl[index][0] != pl[index + 1][0]:
|
||||
line_length = pl[index + 1][0] - pl[index][0]
|
||||
offset = [pl[index][0],
|
||||
pl[index][1] - 0.5 * self.layer_width]
|
||||
if line_length < 0:
|
||||
offset = [offset[0] + line_length,
|
||||
offset[1]]
|
||||
self.add_line(layer_name=self.layer_name,
|
||||
length=abs(line_length),
|
||||
offset=offset,
|
||||
orientation="horizontal",
|
||||
layer_width=self.layer_width)
|
||||
# if we have y motion
|
||||
elif pl[index][1] != pl[index + 1][1]:
|
||||
line_length = pl[index + 1][1] - pl[index][1]
|
||||
offset = [pl[index][0] - 0.5 * self.layer_width,
|
||||
pl[index][1]]
|
||||
if line_length < 0:
|
||||
offset = [offset[0],
|
||||
offset[1] + line_length]
|
||||
self.add_line(layer_name=self.layer_name,
|
||||
length=abs(line_length),
|
||||
offset=offset,
|
||||
orientation="vertical",
|
||||
layer_width=self.layer_width)
|
||||
|
||||
def add_line(self, layer_name, length, offset, orientation, layer_width):
|
||||
"""
|
||||
straight line object with layer_minwidth
|
||||
(orientation: "vertical" or "horizontal") default is vertical
|
||||
"""
|
||||
|
||||
width = layer_width
|
||||
height = length
|
||||
|
||||
if orientation == "horizontal":
|
||||
width = length
|
||||
height = layer_width
|
||||
self.obj.add_rect(layer=layer_name,
|
||||
offset=offset,
|
||||
width=width,
|
||||
height=height)
|
||||
Reference in New Issue
Block a user