mirror of https://github.com/VLSIDA/OpenRAM.git
Add dnwell
This commit is contained in:
parent
cc91cdf008
commit
6493d1a7f4
|
|
@ -1161,6 +1161,8 @@ class layout():
|
|||
height=ur.y - ll.y,
|
||||
width=ur.x - ll.x)
|
||||
|
||||
self.bbox = [self.bounding_box.ll(), self.bounding_box.ur()]
|
||||
|
||||
def add_enclosure(self, insts, layer="nwell", extend=0, leftx=None, rightx=None, topy=None, boty=None):
|
||||
"""
|
||||
Add a layer that surrounds the given instances. Useful
|
||||
|
|
@ -1341,7 +1343,146 @@ class layout():
|
|||
layer=layer,
|
||||
offset=peri_pin_loc)
|
||||
|
||||
def add_power_ring(self, bbox):
|
||||
def add_dnwell(self, bbox=None, inflate=1):
|
||||
""" Create a dnwell, along with nwell moat at border. """
|
||||
|
||||
if "dnwell" not in techlayer:
|
||||
return
|
||||
|
||||
if not bbox:
|
||||
bbox = [self.find_lowest_coords(),
|
||||
self.find_highest_coords()]
|
||||
|
||||
# Find the corners
|
||||
[ll, ur] = bbox
|
||||
|
||||
# Possibly inflate the bbox
|
||||
nwell_offset = vector(self.nwell_width, self.nwell_width)
|
||||
ll -= nwell_offset.scale(inflate, inflate)
|
||||
ur += nwell_offset.scale(inflate, inflate)
|
||||
|
||||
# Other corners
|
||||
ul = vector(ll.x, ur.y)
|
||||
lr = vector(ur.x, ll.y)
|
||||
|
||||
# Add the dnwell
|
||||
self.add_rect("dnwell",
|
||||
offset=ll,
|
||||
height=ur.y - ll.y,
|
||||
width=ur.x - ll.x)
|
||||
|
||||
# Add the moat
|
||||
self.add_path("nwell", [ll, lr, ur, ul, ll - vector(0, 0.5 * self.nwell_width)])
|
||||
|
||||
# Add the taps
|
||||
layer_stack = self.active_stack
|
||||
tap_spacing = 2
|
||||
nwell_offset = vector(self.nwell_width, self.nwell_width)
|
||||
loc = ll + nwell_offset.scale(tap_spacing, 0)
|
||||
end_loc = lr - nwell_offset.scale(tap_spacing, 0)
|
||||
while loc.x < end_loc.x:
|
||||
self.add_via_center(layers=layer_stack,
|
||||
offset=loc,
|
||||
implant_type="n",
|
||||
well_type="n")
|
||||
self.add_via_stack_center(from_layer="li",
|
||||
to_layer="m1",
|
||||
offset=loc)
|
||||
loc += nwell_offset.scale(tap_spacing, 0)
|
||||
|
||||
loc = ul + nwell_offset.scale(tap_spacing, 0)
|
||||
end_loc = ur - nwell_offset.scale(tap_spacing, 0)
|
||||
while loc.x < end_loc.x:
|
||||
self.add_via_center(layers=layer_stack,
|
||||
offset=loc,
|
||||
implant_type="n",
|
||||
well_type="n")
|
||||
self.add_via_stack_center(from_layer="li",
|
||||
to_layer="m2",
|
||||
offset=loc)
|
||||
loc += nwell_offset.scale(tap_spacing, 0)
|
||||
|
||||
loc = ll + nwell_offset.scale(0, tap_spacing)
|
||||
end_loc = ul - nwell_offset.scale(0, tap_spacing)
|
||||
while loc.y < end_loc.y:
|
||||
self.add_via_center(layers=layer_stack,
|
||||
offset=loc,
|
||||
implant_type="n",
|
||||
well_type="n")
|
||||
self.add_via_stack_center(from_layer="li",
|
||||
to_layer="m2",
|
||||
offset=loc)
|
||||
loc += nwell_offset.scale(0, tap_spacing)
|
||||
|
||||
loc = lr + nwell_offset.scale(0, tap_spacing)
|
||||
end_loc = ur - nwell_offset.scale(0, tap_spacing)
|
||||
while loc.y < end_loc.y:
|
||||
self.add_via_center(layers=layer_stack,
|
||||
offset=loc,
|
||||
implant_type="n",
|
||||
well_type="n")
|
||||
self.add_via_stack_center(from_layer="li",
|
||||
to_layer="m2",
|
||||
offset=loc)
|
||||
loc += nwell_offset.scale(0, tap_spacing)
|
||||
|
||||
# Add the gnd ring
|
||||
self.add_ring([ll, ur])
|
||||
|
||||
def add_ring(self, bbox=None, width_mult=8, offset=0):
|
||||
"""
|
||||
Add a ring around the bbox
|
||||
"""
|
||||
# Ring size/space/pitch
|
||||
wire_width = self.m2_width * width_mult
|
||||
half_width = 0.5 * wire_width
|
||||
wire_space = self.m2_space
|
||||
wire_pitch = wire_width + wire_space
|
||||
|
||||
# Find the corners
|
||||
if not bbox:
|
||||
bbox = [self.find_lowest_coords(),
|
||||
self.find_highest_coords()]
|
||||
|
||||
[ll, ur] = bbox
|
||||
ul = vector(ll.x, ur.y)
|
||||
lr = vector(ur.x, ll.y)
|
||||
ll += vector(-offset * wire_pitch,
|
||||
-offset * wire_pitch)
|
||||
lr += vector(offset * wire_pitch,
|
||||
-offset * wire_pitch)
|
||||
ur += vector(offset * wire_pitch,
|
||||
offset * wire_pitch)
|
||||
ul += vector(-offset * wire_pitch,
|
||||
offset * wire_pitch)
|
||||
|
||||
half_offset = vector(half_width, half_width)
|
||||
self.add_path("m1", [ll - half_offset.scale(1, 0), lr + half_offset.scale(1, 0)], width=wire_width)
|
||||
self.add_path("m1", [ul - half_offset.scale(1, 0), ur + half_offset.scale(1, 0)], width=wire_width)
|
||||
self.add_path("m2", [ll - half_offset.scale(0, 1), ul + half_offset.scale(0, 1)], width=wire_width)
|
||||
self.add_path("m2", [lr - half_offset.scale(0, 1), ur + half_offset.scale(0, 1)], width=wire_width)
|
||||
|
||||
# Find the number of vias for this pitch
|
||||
supply_vias = 1
|
||||
from sram_factory import factory
|
||||
while True:
|
||||
c = factory.create(module_type="contact",
|
||||
layer_stack=self.m1_stack,
|
||||
dimensions=(supply_vias, supply_vias))
|
||||
if c.second_layer_width < wire_width and c.second_layer_height < wire_width:
|
||||
supply_vias += 1
|
||||
else:
|
||||
supply_vias -= 1
|
||||
break
|
||||
|
||||
via_points = [ll, lr, ur, ul]
|
||||
for pt in via_points:
|
||||
self.add_via_center(layers=self.m1_stack,
|
||||
offset=pt,
|
||||
size=(supply_vias,
|
||||
supply_vias))
|
||||
|
||||
def add_power_ring(self):
|
||||
"""
|
||||
Create vdd and gnd power rings around an area of the bounding box
|
||||
argument. Must have a supply_rail_width and supply_rail_pitch
|
||||
|
|
@ -1350,7 +1491,7 @@ class layout():
|
|||
modules..
|
||||
"""
|
||||
|
||||
[ll, ur] = bbox
|
||||
[ll, ur] = self.bbox
|
||||
|
||||
supply_rail_spacing = self.supply_rail_pitch - self.supply_rail_width
|
||||
height = (ur.y - ll.y) + 3 * self.supply_rail_pitch - supply_rail_spacing
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
# (acting for and on behalf of Oklahoma State University)
|
||||
# All rights reserved.
|
||||
#
|
||||
import debug
|
||||
import math
|
||||
|
||||
|
||||
class vector3d():
|
||||
"""
|
||||
This is the vector3d class to represent a 3D coordinate.
|
||||
|
|
@ -22,20 +22,20 @@ class vector3d():
|
|||
self.x = x[0]
|
||||
self.y = x[1]
|
||||
self.z = x[2]
|
||||
#will take inputs as the values of a coordinate
|
||||
# will take inputs as the values of a coordinate
|
||||
else:
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.z = z
|
||||
self._hash = hash((self.x,self.y,self.z))
|
||||
self._hash = hash((self.x, self.y, self.z))
|
||||
|
||||
def __str__(self):
|
||||
""" override print function output """
|
||||
return "v3d["+str(self.x)+", "+str(self.y)+", "+str(self.z)+"]"
|
||||
return "v3d[" + str(self.x) + ", " + str(self.y) + ", " + str(self.z) + "]"
|
||||
|
||||
def __repr__(self):
|
||||
""" override print function output """
|
||||
return "v3d["+str(self.x)+", "+str(self.y)+", "+str(self.z)+"]"
|
||||
return "v3d[" + str(self.x) + ", " + str(self.y) + ", " + str(self.z) + "]"
|
||||
|
||||
def __setitem__(self, index, value):
|
||||
"""
|
||||
|
|
@ -74,7 +74,6 @@ class vector3d():
|
|||
"""
|
||||
return vector3d(self.x + other[0], self.y + other[1], self.z + other[2])
|
||||
|
||||
|
||||
def __radd__(self, other):
|
||||
"""
|
||||
Override + function (right add)
|
||||
|
|
@ -98,7 +97,6 @@ class vector3d():
|
|||
"""
|
||||
return self._hash
|
||||
|
||||
|
||||
def __rsub__(self, other):
|
||||
"""
|
||||
Override - function (right)
|
||||
|
|
@ -107,7 +105,7 @@ class vector3d():
|
|||
|
||||
def rotate(self):
|
||||
""" pass a copy of rotated vector3d, without altering the vector3d! """
|
||||
return vector3d(self.y,self.x,self.z)
|
||||
return vector3d(self.y, self.x, self.z)
|
||||
|
||||
def scale(self, x_factor, y_factor=None,z_factor=None):
|
||||
""" pass a copy of scaled vector3d, without altering the vector3d! """
|
||||
|
|
@ -115,7 +113,7 @@ class vector3d():
|
|||
z_factor=x_factor[2]
|
||||
y_factor=x_factor[1]
|
||||
x_factor=x_factor[0]
|
||||
return vector3d(self.x*x_factor,self.y*y_factor,self.z*z_factor)
|
||||
return vector3d(self.x * x_factor, self.y * y_factor, self.z * z_factor)
|
||||
|
||||
def rotate_scale(self, x_factor, y_factor=None, z_factor=None):
|
||||
""" pass a copy of scaled vector3d, without altering the vector3d! """
|
||||
|
|
@ -123,25 +121,25 @@ class vector3d():
|
|||
z_factor=x_factor[2]
|
||||
y_factor=x_factor[1]
|
||||
x_factor=x_factor[0]
|
||||
return vector3d(self.y*x_factor,self.x*y_factor,self.z*z_factor)
|
||||
return vector3d(self.y * x_factor, self.x * y_factor, self.z * z_factor)
|
||||
|
||||
def floor(self):
|
||||
"""
|
||||
Override floor function
|
||||
"""
|
||||
return vector3d(int(math.floor(self.x)),int(math.floor(self.y)), self.z)
|
||||
return vector3d(int(math.floor(self.x)), int(math.floor(self.y)), self.z)
|
||||
|
||||
def ceil(self):
|
||||
"""
|
||||
Override ceil function
|
||||
"""
|
||||
return vector3d(int(math.ceil(self.x)),int(math.ceil(self.y)), self.z)
|
||||
return vector3d(int(math.ceil(self.x)), int(math.ceil(self.y)), self.z)
|
||||
|
||||
def round(self):
|
||||
"""
|
||||
Override round function
|
||||
"""
|
||||
return vector3d(int(round(self.x)),int(round(self.y)), self.z)
|
||||
return vector3d(int(round(self.x)), int(round(self.y)), self.z)
|
||||
|
||||
def __eq__(self, other):
|
||||
"""Override the default Equals behavior"""
|
||||
|
|
@ -164,30 +162,29 @@ class vector3d():
|
|||
|
||||
def max(self, other):
|
||||
""" Max of both values """
|
||||
return vector3d(max(self.x,other.x),max(self.y,other.y),max(self.z,other.z))
|
||||
return vector3d(max(self.x, other.x), max(self.y, other.y), max(self.z, other.z))
|
||||
|
||||
def min(self, other):
|
||||
""" Min of both values """
|
||||
return vector3d(min(self.x,other.x),min(self.y,other.y),min(self.z,other.z))
|
||||
return vector3d(min(self.x, other.x), min(self.y, other.y), min(self.z, other.z))
|
||||
|
||||
def distance(self, other):
|
||||
""" Return the manhattan distance between two values """
|
||||
return abs(self.x-other.x)+abs(self.y-other.y)
|
||||
return abs(self.x - other.x) + abs(self.y - other.y)
|
||||
|
||||
def euclidean_distance(self, other):
|
||||
""" Return the euclidean distance between two values """
|
||||
return math.sqrt((self.x-other.x)**2+(self.y-other.y)**2)
|
||||
|
||||
return math.sqrt((self.x - other.x)**2 + (self.y - other.y)**2)
|
||||
|
||||
def adjacent(self, other):
|
||||
""" Is the one grid adjacent in any planar direction to the other """
|
||||
if self == other + vector3d(1,0,0):
|
||||
if self == other + vector3d(1, 0, 0):
|
||||
return True
|
||||
elif self == other + vector3d(-1,0,0):
|
||||
elif self == other + vector3d(-1, 0, 0):
|
||||
return True
|
||||
elif self == other + vector3d(0,1,0):
|
||||
elif self == other + vector3d(0, 1, 0):
|
||||
return True
|
||||
elif self == other + vector3d(0,-1,0):
|
||||
elif self == other + vector3d(0, -1, 0):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
|
|
|||
Loading…
Reference in New Issue