Add bbox for special DRC rule boundary

This commit is contained in:
Matthew Guthaus 2019-12-05 23:14:25 +00:00
parent 8f473b26a9
commit 7397f110c5
7 changed files with 57 additions and 27 deletions

View File

@ -48,7 +48,6 @@ class contact(hierarchy_design.hierarchy_design):
# Module does not have pins, but has empty pin list.
self.pins = []
self.create_layout()
self.add_boundary()
def create_layout(self):

View File

@ -32,6 +32,7 @@ class layout():
self.name = name
self.width = None
self.height = None
self.boundary = None
self.insts = [] # Holds module/cell layout instances
self.objs = [] # Holds all other objects (labels, geometries, etc)
self.pin_map = {} # Holds name->pin_layout map for all pins
@ -80,7 +81,10 @@ class layout():
lowesty2 = min(inst.by() for inst in self.insts)
else:
lowestx2=lowesty2=None
if lowestx1==None:
if lowestx1==None and lowestx2==None:
return None
elif lowestx1==None:
return vector(lowestx2,lowesty2)
elif lowestx2==None:
return vector(lowestx1,lowesty1)
@ -101,7 +105,9 @@ class layout():
highesty2 = max(inst.uy() for inst in self.insts)
else:
highestx2=highesty2=None
if highestx1==None:
if highestx1==None and highestx2==None:
return None
elif highestx1==None:
return vector(highestx2,highesty2)
elif highestx2==None:
return vector(highestx1,highesty1)
@ -500,6 +506,33 @@ class layout():
for pin_name in self.pin_map.keys():
for pin in self.pin_map[pin_name]:
pin.gds_write_file(gds_layout)
# If it's not a premade cell
# and we didn't add our own boundary,
# we should add a boundary just for DRC in some technologies
if not self.is_library_cell and not self.boundary:
# If there is a boundary layer, and we didn't create one, add one.
if "stdc" in techlayer.keys():
boundary_layer = "stdc"
elif "boundary" in techlayer.keys():
boundary_layer = "boundary"
else:
boundary_layer = None
if boundary_layer:
boundary = [self.find_lowest_coords(), self.find_highest_coords()]
height = boundary[1][1] - boundary[0][1]
width = boundary[1][0] - boundary[0][0]
(layer_number, layer_purpose) = techlayer[boundary_layer]
gds_layout.addBox(layerNumber=layer_number,
purposeNumber=layer_purpose,
offsetInMicrons=boundary[0],
width=width,
height=height,
center=False)
debug.info(0, "Adding {0} boundary {1}".format(self.name, boundary))
self.visited.append(self.name)
def gds_write(self, gds_name):
@ -937,16 +970,22 @@ class layout():
"""
self.create_channel_route(netlist, offset, layer_stack, vertical=False)
def add_boundary(self, offset=vector(0,0)):
def add_boundary(self, ll=vector(0,0), ur=None):
""" Add boundary for debugging dimensions """
if "stdc" in techlayer.keys():
boundary_layer = "stdc"
else:
boundary_layer = "boundary"
self.add_rect(layer=boundary_layer,
offset=offset,
height=self.height,
width=self.width)
if ur == None:
self.boundary = self.add_rect(layer=boundary_layer,
offset=ll,
height=self.height,
width=self.width)
else:
self.boundary = self.add_rect(layer=boundary_layer,
offset=ll,
height=ur.y-ll.y,
width=ur.x-ll.x)
def add_enclosure(self, insts, layer="nwell"):
""" Add a layer that surrounds the given instances. Useful

View File

@ -30,6 +30,7 @@ class dummy_pbitcell(design.design):
self.create_netlist()
self.create_layout()
self.add_boundary()
def create_netlist(self):
self.add_pins()

View File

@ -30,6 +30,7 @@ class replica_pbitcell(design.design):
self.create_netlist()
self.create_layout()
self.add_boundary()
def create_netlist(self):
self.add_pins()
@ -84,4 +85,4 @@ class replica_pbitcell(design.design):
self.copy_layout_pin(self.prbc_inst, "wl{}".format(port))
self.copy_layout_pin(self.prbc_inst, "vdd")
self.copy_layout_pin(self.prbc_inst, "gnd")

View File

@ -58,7 +58,14 @@ class ptx(design.design):
# We must always create ptx layout for pbitcell
# some transistor sizes in other netlist depend on pbitcell
self.create_layout()
ll = self.find_lowest_coords()
ur = self.find_highest_coords()
self.add_boundary(ll, ur)
# (0,0) will be the corner ofthe active area (not the larger well)
self.translate_all(self.active_offset)
def create_layout(self):
"""Calls all functions related to the generation of the layout"""
self.setup_layout_constants()
@ -66,7 +73,6 @@ class ptx(design.design):
self.add_well_implant()
self.add_poly()
self.add_active_contacts()
self.translate_all(self.active_offset)
# for run-time, we won't check every transitor DRC independently
# but this may be uncommented for debug purposes

View File

@ -160,10 +160,6 @@ drc["active_contact_to_active_contact"] = 0.075
drc["active_enclosure_active_contact"] = 0.005
# Reserved for asymmetric enclosures
drc["active_extend_active_contact"] = 0.005
# CONTACT.5 Minimum enclosure of poly around contact
drc["poly_enclosure_active_contact"] = 0.005
# Reserved for asymmetric enclosures
drc["poly_extend_active_contact"] = 0.005
# CONTACT.6 Minimum spacing of contact and gate
drc["active_contact_to_gate"] = 0.0375 #changed from 0.035
# CONTACT.7 Minimum spacing of contact and poly
@ -171,10 +167,6 @@ drc["active_contact_to_poly"] = 0.090
# CONTACT.1 Minimum width of contact
drc["minwidth_poly_contact"] = 0.065
# CONTACT.2 Minimum spacing of contact
drc["poly_contact_to_poly_contact"] = 0.075
# CONTACT.4 Minimum enclosure of active around contact
drc["active_enclosure_poly_contact"] = 0.005
# Reserved for asymmetric enclosures
drc["active_extend_contact"] = 0.005
# CONTACT.5 Minimum enclosure of poly around contact

View File

@ -148,10 +148,6 @@ drc["active_contact_to_active_contact"] = 3*_lambda_
drc["active_enclosure_active_contact"] = _lambda_
# Reserved for asymmetric enclosure
drc["active_extend_active_contact"] = _lambda_
# 5.2.b Minimum poly overlap
drc["poly_enclosure_active_contact"] = _lambda_
# Reserved for asymmetric enclosures
drc["poly_extend_active_contact"] = _lambda_
# Reserved for other technologies
drc["active_contact_to_gate"] = 2*_lambda_
# 5.4 Minimum spacing to gate of transistor
@ -161,10 +157,6 @@ drc["active_contact_to_poly"] = 2*_lambda_
drc["minwidth_poly_contact"] = 2*_lambda_
# 5.3 Minimum contact spacing
drc["poly_contact_to_poly_contact"] = 3*_lambda_
# 6.2.b Minimum active overlap
drc["active_enclosure_poly_contact"] = _lambda_
# Reserved for asymmetric enclosure
drc["active_extend_poly_contact"] = _lambda_
# 5.2.b Minimum poly overlap
drc["poly_enclosure_poly_contact"] = _lambda_
# Reserved for asymmetric enclosures