mirror of https://github.com/VLSIDA/OpenRAM.git
Add bbox for special DRC rule boundary
This commit is contained in:
parent
8f473b26a9
commit
7397f110c5
|
|
@ -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):
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue