Update contact well support.

Add asymmetric tap overlap support in DRC rules.
Add static nwell and pwell contact in class for measurements.
This commit is contained in:
mrg 2020-02-05 18:21:01 +00:00
parent 304971ff60
commit 4526986de3
1 changed files with 32 additions and 10 deletions

View File

@ -42,6 +42,8 @@ class contact(hierarchy_design.hierarchy_design):
if implant_type or well_type:
self.add_comment("implant type: {}\n".format(implant_type))
self.add_comment("well_type: {}\n".format(well_type))
self.is_well_contact = implant_type == well_type
self.layer_stack = layer_stack
self.dimensions = dimensions
@ -114,7 +116,12 @@ class contact(hierarchy_design.hierarchy_design):
self.first_layer_minwidth = drc("minwidth_{0}".format(self.first_layer_name))
self.first_layer_enclosure = drc("{0}_enclose_{1}".format(self.first_layer_name, self.via_layer_name))
self.first_layer_extend = drc("{0}_extend_{1}".format(self.first_layer_name, self.via_layer_name))
# If there's a different rule for active
# FIXME: Make this more elegant
if self.is_well_contact and self.first_layer_name == "active" and "tap_extend_contact" in drc.keys():
self.first_layer_extend = drc("tap_extend_contact")
else:
self.first_layer_extend = drc("{0}_extend_{1}".format(self.first_layer_name, self.via_layer_name))
self.second_layer_minwidth = drc("minwidth_{0}".format(self.second_layer_name))
self.second_layer_enclosure = drc("{0}_enclose_{1}".format(self.second_layer_name, self.via_layer_name))
@ -232,17 +239,17 @@ class contact(hierarchy_design.hierarchy_design):
well_layer = "{}well".format(self.well_type)
if well_layer in tech.layer:
well_width_rule = drc("minwidth_" + well_layer)
well_enclose_active = drc(well_layer + "_enclose_active")
well_width = max(self.first_layer_width + 2 * well_enclose_active,
well_width_rule)
well_height = max(self.first_layer_height + 2 * well_enclose_active,
well_width_rule)
self.well_enclose_active = drc(well_layer + "_enclose_active")
self.well_width = max(self.first_layer_width + 2 * self.well_enclose_active,
well_width_rule)
self.well_height = max(self.first_layer_height + 2 * self.well_enclose_active,
well_width_rule)
center_pos = vector(0.5*self.width, 0.5*self.height)
well_position = center_pos - vector(0.5*well_width, 0.5*well_height)
well_position = center_pos - vector(0.5*self.well_width, 0.5*self.well_height)
self.add_rect(layer=well_layer,
offset=well_position,
width=well_width,
height=well_height)
width=self.well_width,
height=self.well_height)
def analytical_power(self, corner, load):
""" Get total power of a module """
@ -261,6 +268,21 @@ for layer_stack in tech.layer_stacks:
else:
setattr(module, layer1 + "_via", cont)
# Set up a static for each well contact for measurements
if "nwell" in tech.layer:
cont = factory.create(module_type="contact",
layer_stack=tech.active_stack,
implant_type="n",
well_type="n")
module = sys.modules[__name__]
setattr(module, "nwell_contact", cont)
if "pwell" in tech.layer:
cont = factory.create(module_type="contact",
layer_stack=tech.active_stack,
implant_type="p",
well_type="p")
module = sys.modules[__name__]
setattr(module, "pwell_contact", cont)