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.
|
# Module does not have pins, but has empty pin list.
|
||||||
self.pins = []
|
self.pins = []
|
||||||
self.create_layout()
|
self.create_layout()
|
||||||
self.add_boundary()
|
|
||||||
|
|
||||||
def create_layout(self):
|
def create_layout(self):
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ class layout():
|
||||||
self.name = name
|
self.name = name
|
||||||
self.width = None
|
self.width = None
|
||||||
self.height = None
|
self.height = None
|
||||||
|
self.boundary = None
|
||||||
self.insts = [] # Holds module/cell layout instances
|
self.insts = [] # Holds module/cell layout instances
|
||||||
self.objs = [] # Holds all other objects (labels, geometries, etc)
|
self.objs = [] # Holds all other objects (labels, geometries, etc)
|
||||||
self.pin_map = {} # Holds name->pin_layout map for all pins
|
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)
|
lowesty2 = min(inst.by() for inst in self.insts)
|
||||||
else:
|
else:
|
||||||
lowestx2=lowesty2=None
|
lowestx2=lowesty2=None
|
||||||
if lowestx1==None:
|
|
||||||
|
if lowestx1==None and lowestx2==None:
|
||||||
|
return None
|
||||||
|
elif lowestx1==None:
|
||||||
return vector(lowestx2,lowesty2)
|
return vector(lowestx2,lowesty2)
|
||||||
elif lowestx2==None:
|
elif lowestx2==None:
|
||||||
return vector(lowestx1,lowesty1)
|
return vector(lowestx1,lowesty1)
|
||||||
|
|
@ -101,7 +105,9 @@ class layout():
|
||||||
highesty2 = max(inst.uy() for inst in self.insts)
|
highesty2 = max(inst.uy() for inst in self.insts)
|
||||||
else:
|
else:
|
||||||
highestx2=highesty2=None
|
highestx2=highesty2=None
|
||||||
if highestx1==None:
|
if highestx1==None and highestx2==None:
|
||||||
|
return None
|
||||||
|
elif highestx1==None:
|
||||||
return vector(highestx2,highesty2)
|
return vector(highestx2,highesty2)
|
||||||
elif highestx2==None:
|
elif highestx2==None:
|
||||||
return vector(highestx1,highesty1)
|
return vector(highestx1,highesty1)
|
||||||
|
|
@ -500,6 +506,33 @@ class layout():
|
||||||
for pin_name in self.pin_map.keys():
|
for pin_name in self.pin_map.keys():
|
||||||
for pin in self.pin_map[pin_name]:
|
for pin in self.pin_map[pin_name]:
|
||||||
pin.gds_write_file(gds_layout)
|
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)
|
self.visited.append(self.name)
|
||||||
|
|
||||||
def gds_write(self, gds_name):
|
def gds_write(self, gds_name):
|
||||||
|
|
@ -937,16 +970,22 @@ class layout():
|
||||||
"""
|
"""
|
||||||
self.create_channel_route(netlist, offset, layer_stack, vertical=False)
|
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 """
|
""" Add boundary for debugging dimensions """
|
||||||
if "stdc" in techlayer.keys():
|
if "stdc" in techlayer.keys():
|
||||||
boundary_layer = "stdc"
|
boundary_layer = "stdc"
|
||||||
else:
|
else:
|
||||||
boundary_layer = "boundary"
|
boundary_layer = "boundary"
|
||||||
self.add_rect(layer=boundary_layer,
|
if ur == None:
|
||||||
offset=offset,
|
self.boundary = self.add_rect(layer=boundary_layer,
|
||||||
height=self.height,
|
offset=ll,
|
||||||
width=self.width)
|
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"):
|
def add_enclosure(self, insts, layer="nwell"):
|
||||||
""" Add a layer that surrounds the given instances. Useful
|
""" Add a layer that surrounds the given instances. Useful
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ class dummy_pbitcell(design.design):
|
||||||
|
|
||||||
self.create_netlist()
|
self.create_netlist()
|
||||||
self.create_layout()
|
self.create_layout()
|
||||||
|
self.add_boundary()
|
||||||
|
|
||||||
def create_netlist(self):
|
def create_netlist(self):
|
||||||
self.add_pins()
|
self.add_pins()
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ class replica_pbitcell(design.design):
|
||||||
|
|
||||||
self.create_netlist()
|
self.create_netlist()
|
||||||
self.create_layout()
|
self.create_layout()
|
||||||
|
self.add_boundary()
|
||||||
|
|
||||||
def create_netlist(self):
|
def create_netlist(self):
|
||||||
self.add_pins()
|
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, "wl{}".format(port))
|
||||||
self.copy_layout_pin(self.prbc_inst, "vdd")
|
self.copy_layout_pin(self.prbc_inst, "vdd")
|
||||||
self.copy_layout_pin(self.prbc_inst, "gnd")
|
self.copy_layout_pin(self.prbc_inst, "gnd")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,14 @@ class ptx(design.design):
|
||||||
# We must always create ptx layout for pbitcell
|
# We must always create ptx layout for pbitcell
|
||||||
# some transistor sizes in other netlist depend on pbitcell
|
# some transistor sizes in other netlist depend on pbitcell
|
||||||
self.create_layout()
|
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):
|
def create_layout(self):
|
||||||
"""Calls all functions related to the generation of the layout"""
|
"""Calls all functions related to the generation of the layout"""
|
||||||
self.setup_layout_constants()
|
self.setup_layout_constants()
|
||||||
|
|
@ -66,7 +73,6 @@ class ptx(design.design):
|
||||||
self.add_well_implant()
|
self.add_well_implant()
|
||||||
self.add_poly()
|
self.add_poly()
|
||||||
self.add_active_contacts()
|
self.add_active_contacts()
|
||||||
self.translate_all(self.active_offset)
|
|
||||||
|
|
||||||
# for run-time, we won't check every transitor DRC independently
|
# for run-time, we won't check every transitor DRC independently
|
||||||
# but this may be uncommented for debug purposes
|
# 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
|
drc["active_enclosure_active_contact"] = 0.005
|
||||||
# Reserved for asymmetric enclosures
|
# Reserved for asymmetric enclosures
|
||||||
drc["active_extend_active_contact"] = 0.005
|
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
|
# CONTACT.6 Minimum spacing of contact and gate
|
||||||
drc["active_contact_to_gate"] = 0.0375 #changed from 0.035
|
drc["active_contact_to_gate"] = 0.0375 #changed from 0.035
|
||||||
# CONTACT.7 Minimum spacing of contact and poly
|
# 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
|
# CONTACT.1 Minimum width of contact
|
||||||
drc["minwidth_poly_contact"] = 0.065
|
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
|
# Reserved for asymmetric enclosures
|
||||||
drc["active_extend_contact"] = 0.005
|
drc["active_extend_contact"] = 0.005
|
||||||
# CONTACT.5 Minimum enclosure of poly around contact
|
# 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_
|
drc["active_enclosure_active_contact"] = _lambda_
|
||||||
# Reserved for asymmetric enclosure
|
# Reserved for asymmetric enclosure
|
||||||
drc["active_extend_active_contact"] = _lambda_
|
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
|
# Reserved for other technologies
|
||||||
drc["active_contact_to_gate"] = 2*_lambda_
|
drc["active_contact_to_gate"] = 2*_lambda_
|
||||||
# 5.4 Minimum spacing to gate of transistor
|
# 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_
|
drc["minwidth_poly_contact"] = 2*_lambda_
|
||||||
# 5.3 Minimum contact spacing
|
# 5.3 Minimum contact spacing
|
||||||
drc["poly_contact_to_poly_contact"] = 3*_lambda_
|
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
|
# 5.2.b Minimum poly overlap
|
||||||
drc["poly_enclosure_poly_contact"] = _lambda_
|
drc["poly_enclosure_poly_contact"] = _lambda_
|
||||||
# Reserved for asymmetric enclosures
|
# Reserved for asymmetric enclosures
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue