mirror of https://github.com/VLSIDA/OpenRAM.git
Cleanup.
This commit is contained in:
parent
449b0a7c28
commit
fc4685c7f7
|
|
@ -7,8 +7,10 @@
|
||||||
#
|
#
|
||||||
import hierarchy_design
|
import hierarchy_design
|
||||||
import debug
|
import debug
|
||||||
from tech import *
|
from tech import drc
|
||||||
|
import tech
|
||||||
from vector import vector
|
from vector import vector
|
||||||
|
from sram_factory import factory
|
||||||
|
|
||||||
|
|
||||||
class contact(hierarchy_design.hierarchy_design):
|
class contact(hierarchy_design.hierarchy_design):
|
||||||
|
|
@ -65,7 +67,8 @@ class contact(hierarchy_design.hierarchy_design):
|
||||||
if self.implant_type and self.well_type:
|
if self.implant_type and self.well_type:
|
||||||
self.create_implant_well_enclosures()
|
self.create_implant_well_enclosures()
|
||||||
elif self.implant_type or self.well_type:
|
elif self.implant_type or self.well_type:
|
||||||
debug.error(-1, "Must define both implant and well type or none at all.")
|
debug.error(-1,
|
||||||
|
"Must define both implant and well type or none.")
|
||||||
|
|
||||||
def setup_layers(self):
|
def setup_layers(self):
|
||||||
""" Locally assign the layer names. """
|
""" Locally assign the layer names. """
|
||||||
|
|
@ -75,7 +78,7 @@ class contact(hierarchy_design.hierarchy_design):
|
||||||
self.second_layer_name = second_layer
|
self.second_layer_name = second_layer
|
||||||
|
|
||||||
# Contacts will have unique per first layer
|
# Contacts will have unique per first layer
|
||||||
if via_layer in layer.keys():
|
if via_layer in tech.layer.keys():
|
||||||
self.via_layer_name = via_layer
|
self.via_layer_name = via_layer
|
||||||
elif via_layer == "contact":
|
elif via_layer == "contact":
|
||||||
if first_layer in ("active", "poly"):
|
if first_layer in ("active", "poly"):
|
||||||
|
|
@ -86,8 +89,6 @@ class contact(hierarchy_design.hierarchy_design):
|
||||||
debug.error("Invalid via layer {}".format(via_layer), -1)
|
debug.error("Invalid via layer {}".format(via_layer), -1)
|
||||||
else:
|
else:
|
||||||
debug.error("Invalid via layer {}".format(via_layer), -1)
|
debug.error("Invalid via layer {}".format(via_layer), -1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def setup_layout_constants(self):
|
def setup_layout_constants(self):
|
||||||
""" Determine the design rules for the enclosure layers """
|
""" Determine the design rules for the enclosure layers """
|
||||||
|
|
@ -127,7 +128,9 @@ class contact(hierarchy_design.hierarchy_design):
|
||||||
else:
|
else:
|
||||||
debug.error("Invalid first layer direction.", -1)
|
debug.error("Invalid first layer direction.", -1)
|
||||||
|
|
||||||
# In some technologies, the minimum width may be larger than the overlap requirement around the via, so
|
# In some technologies,
|
||||||
|
# the minimum width may be larger than
|
||||||
|
# the overlap requirement around the via, so
|
||||||
# check this for each dimension.
|
# check this for each dimension.
|
||||||
if self.directions[1] == "V":
|
if self.directions[1] == "V":
|
||||||
self.second_layer_horizontal_enclosure = max(second_layer_enclosure,
|
self.second_layer_horizontal_enclosure = max(second_layer_enclosure,
|
||||||
|
|
@ -146,11 +149,14 @@ class contact(hierarchy_design.hierarchy_design):
|
||||||
""" Create the contact array at the origin"""
|
""" Create the contact array at the origin"""
|
||||||
# offset for the via array
|
# offset for the via array
|
||||||
self.via_layer_position = vector(
|
self.via_layer_position = vector(
|
||||||
max(self.first_layer_horizontal_enclosure, self.second_layer_horizontal_enclosure),
|
max(self.first_layer_horizontal_enclosure,
|
||||||
max(self.first_layer_vertical_enclosure, self.second_layer_vertical_enclosure))
|
self.second_layer_horizontal_enclosure),
|
||||||
|
max(self.first_layer_vertical_enclosure,
|
||||||
|
self.second_layer_vertical_enclosure))
|
||||||
|
|
||||||
for i in range(self.dimensions[1]):
|
for i in range(self.dimensions[1]):
|
||||||
offset = self.via_layer_position + vector(0, self.contact_pitch * i)
|
offset = self.via_layer_position + vector(0,
|
||||||
|
self.contact_pitch * i)
|
||||||
for j in range(self.dimensions[0]):
|
for j in range(self.dimensions[0]):
|
||||||
self.add_rect(layer=self.via_layer_name,
|
self.add_rect(layer=self.via_layer_name,
|
||||||
offset=offset,
|
offset=offset,
|
||||||
|
|
@ -161,7 +167,7 @@ class contact(hierarchy_design.hierarchy_design):
|
||||||
def create_nitride_cut_enclosure(self):
|
def create_nitride_cut_enclosure(self):
|
||||||
""" Special layer that encloses poly contacts in some processes """
|
""" Special layer that encloses poly contacts in some processes """
|
||||||
# Check if there is a special poly nitride cut layer
|
# Check if there is a special poly nitride cut layer
|
||||||
if "npc" not in layer.keys():
|
if "npc" not in tech.layer.keys():
|
||||||
return
|
return
|
||||||
|
|
||||||
# Only add for poly layers
|
# Only add for poly layers
|
||||||
|
|
@ -175,7 +181,6 @@ class contact(hierarchy_design.hierarchy_design):
|
||||||
offset=self.second_layer_position,
|
offset=self.second_layer_position,
|
||||||
width=self.second_layer_width,
|
width=self.second_layer_width,
|
||||||
height=self.second_layer_height)
|
height=self.second_layer_height)
|
||||||
|
|
||||||
|
|
||||||
def create_first_layer_enclosure(self):
|
def create_first_layer_enclosure(self):
|
||||||
# this is if the first and second layers are different
|
# this is if the first and second layers are different
|
||||||
|
|
@ -224,35 +229,33 @@ class contact(hierarchy_design.hierarchy_design):
|
||||||
return self.return_power()
|
return self.return_power()
|
||||||
|
|
||||||
|
|
||||||
from sram_factory import factory
|
|
||||||
|
|
||||||
# This is not instantiated and used for calculations only.
|
# This is not instantiated and used for calculations only.
|
||||||
# These are static 1x1 contacts to reuse in all the design modules.
|
# These are static 1x1 contacts to reuse in all the design modules.
|
||||||
well = factory.create(module_type="contact",
|
well = factory.create(module_type="contact",
|
||||||
layer_stack=active_stack,
|
layer_stack=tech.active_stack,
|
||||||
directions=("H", "V"))
|
directions=("H", "V"))
|
||||||
active = factory.create(module_type="contact",
|
active = factory.create(module_type="contact",
|
||||||
layer_stack=active_stack,
|
layer_stack=tech.active_stack,
|
||||||
directions=("H", "V"))
|
directions=("H", "V"))
|
||||||
poly = factory.create(module_type="contact",
|
poly = factory.create(module_type="contact",
|
||||||
layer_stack=poly_stack,
|
layer_stack=tech.poly_stack,
|
||||||
directions=("V", "H"))
|
directions=("V", "H"))
|
||||||
if "li" in layer.keys():
|
if "li" in tech.layer.keys():
|
||||||
lim1 = factory.create(module_type="contact",
|
lim1 = factory.create(module_type="contact",
|
||||||
layer_stack=li_stack,
|
layer_stack=tech.li_stack,
|
||||||
directions=("V", "H"))
|
directions=("V", "H"))
|
||||||
else:
|
else:
|
||||||
lim1 = None
|
lim1 = None
|
||||||
|
|
||||||
m1m2 = factory.create(module_type="contact",
|
m1m2 = factory.create(module_type="contact",
|
||||||
layer_stack=m1_stack,
|
layer_stack=tech.m1_stack,
|
||||||
directions=("H", "V"))
|
directions=("H", "V"))
|
||||||
m2m3 = factory.create(module_type="contact",
|
m2m3 = factory.create(module_type="contact",
|
||||||
layer_stack=m2_stack,
|
layer_stack=tech.m2_stack,
|
||||||
directions=("V", "H"))
|
directions=("V", "H"))
|
||||||
if "m4" in layer.keys():
|
if "m4" in tech.layer.keys():
|
||||||
m3m4 = factory.create(module_type="contact",
|
m3m4 = factory.create(module_type="contact",
|
||||||
layer_stack=m3_stack,
|
layer_stack=tech.m3_stack,
|
||||||
directions=("H", "V"))
|
directions=("H", "V"))
|
||||||
else:
|
else:
|
||||||
m3m4 = None
|
m3m4 = None
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import contact
|
||||||
from globals import OPTS
|
from globals import OPTS
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
||||||
class design(hierarchy_design):
|
class design(hierarchy_design):
|
||||||
"""
|
"""
|
||||||
This is the same as the hierarchy_design class except it contains
|
This is the same as the hierarchy_design class except it contains
|
||||||
|
|
@ -24,16 +25,23 @@ class design(hierarchy_design):
|
||||||
self.setup_layer_constants()
|
self.setup_layer_constants()
|
||||||
self.setup_multiport_constants()
|
self.setup_multiport_constants()
|
||||||
|
|
||||||
|
|
||||||
def setup_layer_constants(self):
|
def setup_layer_constants(self):
|
||||||
""" These are some layer constants used in many places in the compiler."""
|
"""
|
||||||
|
These are some layer constants used
|
||||||
|
in many places in the compiler.
|
||||||
|
"""
|
||||||
|
|
||||||
import tech
|
import tech
|
||||||
|
|
||||||
self.m1_pitch = max(contact.m1m2.width, contact.m1m2.height) + max(self.m1_space, self.m2_space)
|
# This is contact direction independent pitch,
|
||||||
self.m2_pitch = max(contact.m2m3.width, contact.m2m3.height) + max(self.m2_space, self.m3_space)
|
# 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:
|
if "m4" in tech.layer:
|
||||||
self.m3_pitch = max(contact.m3m4.width, contact.m3m4.height) + max(self.m3_space, self.m4_space)
|
max_m3m4_contact = max(contact.m3m4.width, contact.m3m4.height)
|
||||||
|
self.m3_pitch = max_m3m4_contact + max(self.m3_space, self.m4_space)
|
||||||
else:
|
else:
|
||||||
self.m3_pitch = self.m2_pitch
|
self.m3_pitch = self.m2_pitch
|
||||||
|
|
||||||
|
|
@ -44,15 +52,17 @@ class design(hierarchy_design):
|
||||||
self.m3_stack = tech.m3_stack
|
self.m3_stack = tech.m3_stack
|
||||||
|
|
||||||
def setup_drc_constants(self):
|
def setup_drc_constants(self):
|
||||||
""" These are some DRC constants used in many places in the compiler."""
|
"""
|
||||||
from tech import drc, layer
|
These are some DRC constants used in many places
|
||||||
|
in the compiler.
|
||||||
|
"""
|
||||||
# Make some local rules for convenience
|
# Make some local rules for convenience
|
||||||
|
from tech import drc
|
||||||
for rule in drc.keys():
|
for rule in drc.keys():
|
||||||
# Single layer width rules
|
# Single layer width rules
|
||||||
match = re.search(r"minwidth_(.*)", rule)
|
match = re.search(r"minwidth_(.*)", rule)
|
||||||
if match:
|
if match:
|
||||||
if match.group(1)=="active_contact":
|
if match.group(1) == "active_contact":
|
||||||
setattr(self, "contact_width", drc(match.group(0)))
|
setattr(self, "contact_width", drc(match.group(0)))
|
||||||
else:
|
else:
|
||||||
setattr(self, match.group(1)+"_width", drc(match.group(0)))
|
setattr(self, match.group(1)+"_width", drc(match.group(0)))
|
||||||
|
|
@ -64,11 +74,12 @@ class design(hierarchy_design):
|
||||||
|
|
||||||
# Single layer spacing rules
|
# Single layer spacing rules
|
||||||
match = re.search(r"(.*)_to_(.*)", rule)
|
match = re.search(r"(.*)_to_(.*)", rule)
|
||||||
if match and match.group(1)==match.group(2):
|
if match and match.group(1) == match.group(2):
|
||||||
setattr(self, match.group(1)+"_space", drc(match.group(0)))
|
setattr(self, match.group(1)+"_space", drc(match.group(0)))
|
||||||
elif match and match.group(1)!=match.group(2):
|
elif match and match.group(1) != match.group(2):
|
||||||
if match.group(2)=="poly_active":
|
if match.group(2) == "poly_active":
|
||||||
setattr(self, match.group(1)+"_to_contact", drc(match.group(0)))
|
setattr(self, match.group(1)+"_to_contact",
|
||||||
|
drc(match.group(0)))
|
||||||
else:
|
else:
|
||||||
setattr(self, match.group(0), drc(match.group(0)))
|
setattr(self, match.group(0), drc(match.group(0)))
|
||||||
|
|
||||||
|
|
@ -102,7 +113,8 @@ class design(hierarchy_design):
|
||||||
print("well_enclose_active", self.well_enclose_active)
|
print("well_enclose_active", self.well_enclose_active)
|
||||||
print("implant_enclose_active", self.implant_enclose_active)
|
print("implant_enclose_active", self.implant_enclose_active)
|
||||||
print("implant_space", self.implant_space)
|
print("implant_space", self.implant_space)
|
||||||
import sys; sys.exit(1)
|
import sys
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
def setup_multiport_constants(self):
|
def setup_multiport_constants(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,11 @@
|
||||||
#
|
#
|
||||||
import unittest
|
import unittest
|
||||||
from testutils import *
|
from testutils import *
|
||||||
import sys,os
|
import sys
|
||||||
|
import os
|
||||||
sys.path.append(os.getenv("OPENRAM_HOME"))
|
sys.path.append(os.getenv("OPENRAM_HOME"))
|
||||||
import globals
|
import globals
|
||||||
from globals import OPTS
|
|
||||||
import debug
|
|
||||||
|
|
||||||
class wire_test(openram_test):
|
class wire_test(openram_test):
|
||||||
|
|
||||||
|
|
@ -31,7 +31,8 @@ class wire_test(openram_test):
|
||||||
layer_stack = stack[::-1]
|
layer_stack = stack[::-1]
|
||||||
else:
|
else:
|
||||||
layer_stack = stack
|
layer_stack = stack
|
||||||
|
|
||||||
|
# Just make a conservative spacing. Make it wire pitch instead?
|
||||||
min_space = 2 * (tech.drc["minwidth_{}".format(layer_stack[0])] +
|
min_space = 2 * (tech.drc["minwidth_{}".format(layer_stack[0])] +
|
||||||
tech.drc["minwidth_{}".format(layer_stack[2])])
|
tech.drc["minwidth_{}".format(layer_stack[2])])
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue