mirror of https://github.com/VLSIDA/OpenRAM.git
Update contact types.
Use preferred directions in tech files. Programmatically generate based on interconnect stacks.
This commit is contained in:
parent
fc4685c7f7
commit
8e151553e4
|
|
@ -11,6 +11,7 @@ from tech import drc
|
|||
import tech
|
||||
from vector import vector
|
||||
from sram_factory import factory
|
||||
import sys
|
||||
|
||||
|
||||
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=""):
|
||||
# This will ignore the name parameter since
|
||||
# we can guarantee a unique name here
|
||||
|
|
@ -43,7 +44,11 @@ class contact(hierarchy_design.hierarchy_design):
|
|||
|
||||
self.layer_stack = layer_stack
|
||||
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.implant_type = implant_type
|
||||
self.well_type = well_type
|
||||
|
|
@ -228,35 +233,14 @@ class contact(hierarchy_design.hierarchy_design):
|
|||
""" Get total power of a module """
|
||||
return self.return_power()
|
||||
|
||||
|
||||
# This is not instantiated and used for calculations only.
|
||||
# These are static 1x1 contacts to reuse in all the design modules.
|
||||
well = factory.create(module_type="contact",
|
||||
layer_stack=tech.active_stack,
|
||||
directions=("H", "V"))
|
||||
active = factory.create(module_type="contact",
|
||||
layer_stack=tech.active_stack,
|
||||
directions=("H", "V"))
|
||||
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
|
||||
|
||||
# Set up a static for each layer to be used for measurements
|
||||
for layer_stack in tech.layer_stacks:
|
||||
(layer1, via, layer2) = layer_stack
|
||||
cont = factory.create(module_type="contact",
|
||||
layer_stack=layer_stack)
|
||||
module = sys.modules[__name__]
|
||||
# Create the contact as just the concat of the layer names
|
||||
setattr(module, layer1 + layer2, cont)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -26,30 +26,41 @@ class design(hierarchy_design):
|
|||
self.setup_multiport_constants()
|
||||
|
||||
def setup_layer_constants(self):
|
||||
"""
|
||||
"""
|
||||
These are some layer constants used
|
||||
in many places in the compiler.
|
||||
"""
|
||||
|
||||
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,
|
||||
# i.e. we take the maximum contact dimension
|
||||
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
|
||||
# Set the stack as a local helper
|
||||
setattr(self, key, layer_stack)
|
||||
|
||||
self.poly_stack = tech.poly_stack
|
||||
self.active_stack = tech.active_stack
|
||||
self.m1_stack = tech.m1_stack
|
||||
self.m2_stack = tech.m2_stack
|
||||
self.m3_stack = tech.m3_stack
|
||||
# Add the pitch
|
||||
setattr(self,
|
||||
"{}_pitch".format(layer_stack[0]),
|
||||
self.compute_pitch(layer_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):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -56,6 +56,13 @@ beol_stacks = [m1_stack,
|
|||
|
||||
layer_stacks = feol_stacks + beol_stacks
|
||||
|
||||
preferred_directions = {"poly": "V",
|
||||
"active": "H",
|
||||
"m1": "H",
|
||||
"m2": "V",
|
||||
"m3": "H",
|
||||
"m4": "V"}
|
||||
|
||||
###################################################
|
||||
# GDS Layer Map
|
||||
###################################################
|
||||
|
|
|
|||
|
|
@ -56,6 +56,12 @@ beol_stacks = [m1_stack,
|
|||
|
||||
layer_stacks = feol_stacks + beol_stacks
|
||||
|
||||
preferred_directions = {"poly": "V",
|
||||
"active": "H",
|
||||
"m1": "H",
|
||||
"m2": "V",
|
||||
"m3": "H",
|
||||
"m4": "V"}
|
||||
|
||||
###################################################
|
||||
##GDS Layer Map
|
||||
|
|
|
|||
Loading…
Reference in New Issue