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
|
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
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
###################################################
|
###################################################
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue