Update contact types.

Use preferred directions in tech files.
Programmatically generate based on interconnect stacks.
This commit is contained in:
Matthew Guthaus 2019-12-17 23:45:07 +00:00
parent fc4685c7f7
commit 8e151553e4
4 changed files with 58 additions and 50 deletions

View File

@ -11,6 +11,7 @@ from tech import drc
import tech import tech
from vector import vector from vector import vector
from sram_factory import factory from sram_factory import factory
import sys
class contact(hierarchy_design.hierarchy_design): class contact(hierarchy_design.hierarchy_design):
@ -28,7 +29,7 @@ class contact(hierarchy_design.hierarchy_design):
""" """
def __init__(self, layer_stack, dimensions=(1, 1), directions=("V", "V"), def __init__(self, layer_stack, dimensions=(1, 1), directions=None,
implant_type=None, well_type=None, name=""): implant_type=None, well_type=None, name=""):
# This will ignore the name parameter since # This will ignore the name parameter since
# we can guarantee a unique name here # we can guarantee a unique name here
@ -43,7 +44,11 @@ class contact(hierarchy_design.hierarchy_design):
self.layer_stack = layer_stack self.layer_stack = layer_stack
self.dimensions = dimensions self.dimensions = dimensions
self.directions = directions if directions:
self.directions = directions
else:
self.directions = (tech.preferred_directions[layer_stack[0]],
tech.preferred_directions[layer_stack[2]])
self.offset = vector(0, 0) self.offset = vector(0, 0)
self.implant_type = implant_type self.implant_type = implant_type
self.well_type = well_type self.well_type = well_type
@ -229,34 +234,13 @@ class contact(hierarchy_design.hierarchy_design):
return self.return_power() return self.return_power()
# This is not instantiated and used for calculations only. # Set up a static for each layer to be used for measurements
# These are static 1x1 contacts to reuse in all the design modules. for layer_stack in tech.layer_stacks:
well = factory.create(module_type="contact", (layer1, via, layer2) = layer_stack
layer_stack=tech.active_stack, cont = factory.create(module_type="contact",
directions=("H", "V")) layer_stack=layer_stack)
active = factory.create(module_type="contact", module = sys.modules[__name__]
layer_stack=tech.active_stack, # Create the contact as just the concat of the layer names
directions=("H", "V")) setattr(module, layer1 + layer2, cont)
poly = factory.create(module_type="contact",
layer_stack=tech.poly_stack,
directions=("V", "H"))
if "li" in tech.layer.keys():
lim1 = factory.create(module_type="contact",
layer_stack=tech.li_stack,
directions=("V", "H"))
else:
lim1 = None
m1m2 = factory.create(module_type="contact",
layer_stack=tech.m1_stack,
directions=("H", "V"))
m2m3 = factory.create(module_type="contact",
layer_stack=tech.m2_stack,
directions=("V", "H"))
if "m4" in tech.layer.keys():
m3m4 = factory.create(module_type="contact",
layer_stack=tech.m3_stack,
directions=("H", "V"))
else:
m3m4 = None

View File

@ -32,24 +32,35 @@ class design(hierarchy_design):
""" """
import tech import tech
for key in dir(tech):
# Single layer width rules
match = re.match(r".*_stack$", key)
if match:
layer_stack = getattr(tech, key)
# This is contact direction independent pitch, # Set the stack as a local helper
# i.e. we take the maximum contact dimension setattr(self, key, layer_stack)
max_m1m2_contact = max(contact.m1m2.width, contact.m1m2.height)
self.m1_pitch = max_m1m2_contact + max(self.m1_space, self.m2_space)
max_m2m3_contact = max(contact.m2m3.width, contact.m2m3.height)
self.m2_pitch = max_m2m3_contact + max(self.m2_space, self.m3_space)
if "m4" in tech.layer:
max_m3m4_contact = max(contact.m3m4.width, contact.m3m4.height)
self.m3_pitch = max_m3m4_contact + max(self.m3_space, self.m4_space)
else:
self.m3_pitch = self.m2_pitch
self.poly_stack = tech.poly_stack # Add the pitch
self.active_stack = tech.active_stack setattr(self,
self.m1_stack = tech.m1_stack "{}_pitch".format(layer_stack[0]),
self.m2_stack = tech.m2_stack self.compute_pitch(layer_stack))
self.m3_stack = tech.m3_stack
def compute_pitch(self, layer_stack):
"""
This is contact direction independent pitch,
i.e. we take the maximum contact dimension
"""
(layer1, via, layer2) = layer_stack
contact1 = getattr(contact, layer1 + layer2)
max_contact = max(contact1.width, contact1.height)
layer1_space = getattr(self, layer1+"_space")
layer2_space = getattr(self, layer2+"_space")
pitch = max_contact + max(layer1_space, layer2_space)
return pitch
def setup_drc_constants(self): def setup_drc_constants(self):
""" """

View File

@ -56,6 +56,13 @@ beol_stacks = [m1_stack,
layer_stacks = feol_stacks + beol_stacks layer_stacks = feol_stacks + beol_stacks
preferred_directions = {"poly": "V",
"active": "H",
"m1": "H",
"m2": "V",
"m3": "H",
"m4": "V"}
################################################### ###################################################
# GDS Layer Map # GDS Layer Map
################################################### ###################################################

View File

@ -56,6 +56,12 @@ beol_stacks = [m1_stack,
layer_stacks = feol_stacks + beol_stacks layer_stacks = feol_stacks + beol_stacks
preferred_directions = {"poly": "V",
"active": "H",
"m1": "H",
"m2": "V",
"m3": "H",
"m4": "V"}
################################################### ###################################################
##GDS Layer Map ##GDS Layer Map