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
@ -228,35 +233,14 @@ class contact(hierarchy_design.hierarchy_design):
""" Get total power of a module """ """ Get total power of a module """
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

@ -26,30 +26,41 @@ class design(hierarchy_design):
self.setup_multiport_constants() self.setup_multiport_constants()
def setup_layer_constants(self): def setup_layer_constants(self):
""" """
These are some layer constants used These are some layer constants used
in many places in the compiler. in many places in the compiler.
""" """
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