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,
|
height=ur.y - ll.y,
|
||||||
width=ur.x - ll.x)
|
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):
|
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
|
Add a layer that surrounds the given instances. Useful
|
||||||
|
|
@ -1341,7 +1343,146 @@ class layout():
|
||||||
layer=layer,
|
layer=layer,
|
||||||
offset=peri_pin_loc)
|
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
|
Create vdd and gnd power rings around an area of the bounding box
|
||||||
argument. Must have a supply_rail_width and supply_rail_pitch
|
argument. Must have a supply_rail_width and supply_rail_pitch
|
||||||
|
|
@ -1350,7 +1491,7 @@ class layout():
|
||||||
modules..
|
modules..
|
||||||
"""
|
"""
|
||||||
|
|
||||||
[ll, ur] = bbox
|
[ll, ur] = self.bbox
|
||||||
|
|
||||||
supply_rail_spacing = self.supply_rail_pitch - self.supply_rail_width
|
supply_rail_spacing = self.supply_rail_pitch - self.supply_rail_width
|
||||||
height = (ur.y - ll.y) + 3 * self.supply_rail_pitch - supply_rail_spacing
|
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)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
import debug
|
|
||||||
import math
|
import math
|
||||||
|
|
||||||
|
|
||||||
class vector3d():
|
class vector3d():
|
||||||
"""
|
"""
|
||||||
This is the vector3d class to represent a 3D coordinate.
|
This is the vector3d class to represent a 3D coordinate.
|
||||||
|
|
@ -74,7 +74,6 @@ class vector3d():
|
||||||
"""
|
"""
|
||||||
return vector3d(self.x + other[0], self.y + other[1], self.z + other[2])
|
return vector3d(self.x + other[0], self.y + other[1], self.z + other[2])
|
||||||
|
|
||||||
|
|
||||||
def __radd__(self, other):
|
def __radd__(self, other):
|
||||||
"""
|
"""
|
||||||
Override + function (right add)
|
Override + function (right add)
|
||||||
|
|
@ -98,7 +97,6 @@ class vector3d():
|
||||||
"""
|
"""
|
||||||
return self._hash
|
return self._hash
|
||||||
|
|
||||||
|
|
||||||
def __rsub__(self, other):
|
def __rsub__(self, other):
|
||||||
"""
|
"""
|
||||||
Override - function (right)
|
Override - function (right)
|
||||||
|
|
@ -178,7 +176,6 @@ class vector3d():
|
||||||
""" Return the euclidean distance between two values """
|
""" 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):
|
def adjacent(self, other):
|
||||||
""" Is the one grid adjacent in any planar direction to the 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):
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue