From fc4685c7f70214c6601ff0d44b328f47de4ced1b Mon Sep 17 00:00:00 2001 From: Matthew Guthaus Date: Tue, 17 Dec 2019 23:07:01 +0000 Subject: [PATCH] Cleanup. --- compiler/base/contact.py | 47 ++++++++++++++++++---------------- compiler/base/design.py | 42 +++++++++++++++++++----------- compiler/tests/03_wire_test.py | 9 ++++--- 3 files changed, 57 insertions(+), 41 deletions(-) diff --git a/compiler/base/contact.py b/compiler/base/contact.py index c5b1ef9e..24b0e866 100644 --- a/compiler/base/contact.py +++ b/compiler/base/contact.py @@ -7,8 +7,10 @@ # import hierarchy_design import debug -from tech import * +from tech import drc +import tech from vector import vector +from sram_factory import factory class contact(hierarchy_design.hierarchy_design): @@ -65,7 +67,8 @@ class contact(hierarchy_design.hierarchy_design): if self.implant_type and self.well_type: self.create_implant_well_enclosures() 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): """ Locally assign the layer names. """ @@ -75,7 +78,7 @@ class contact(hierarchy_design.hierarchy_design): self.second_layer_name = second_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 elif via_layer == "contact": 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) else: debug.error("Invalid via layer {}".format(via_layer), -1) - - def setup_layout_constants(self): """ Determine the design rules for the enclosure layers """ @@ -127,7 +128,9 @@ class contact(hierarchy_design.hierarchy_design): else: 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. if self.directions[1] == "V": 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""" # offset for the via array self.via_layer_position = vector( - max(self.first_layer_horizontal_enclosure, self.second_layer_horizontal_enclosure), - max(self.first_layer_vertical_enclosure, self.second_layer_vertical_enclosure)) + max(self.first_layer_horizontal_enclosure, + self.second_layer_horizontal_enclosure), + max(self.first_layer_vertical_enclosure, + self.second_layer_vertical_enclosure)) 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]): self.add_rect(layer=self.via_layer_name, offset=offset, @@ -161,7 +167,7 @@ class contact(hierarchy_design.hierarchy_design): def create_nitride_cut_enclosure(self): """ Special layer that encloses poly contacts in some processes """ # Check if there is a special poly nitride cut layer - if "npc" not in layer.keys(): + if "npc" not in tech.layer.keys(): return # Only add for poly layers @@ -175,7 +181,6 @@ class contact(hierarchy_design.hierarchy_design): offset=self.second_layer_position, width=self.second_layer_width, height=self.second_layer_height) - def create_first_layer_enclosure(self): # this is if the first and second layers are different @@ -224,35 +229,33 @@ class contact(hierarchy_design.hierarchy_design): return self.return_power() -from sram_factory import factory - # 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=active_stack, + layer_stack=tech.active_stack, directions=("H", "V")) active = factory.create(module_type="contact", - layer_stack=active_stack, + layer_stack=tech.active_stack, directions=("H", "V")) poly = factory.create(module_type="contact", - layer_stack=poly_stack, + layer_stack=tech.poly_stack, directions=("V", "H")) -if "li" in layer.keys(): +if "li" in tech.layer.keys(): lim1 = factory.create(module_type="contact", - layer_stack=li_stack, + layer_stack=tech.li_stack, directions=("V", "H")) else: lim1 = None m1m2 = factory.create(module_type="contact", - layer_stack=m1_stack, + layer_stack=tech.m1_stack, directions=("H", "V")) m2m3 = factory.create(module_type="contact", - layer_stack=m2_stack, + layer_stack=tech.m2_stack, directions=("V", "H")) -if "m4" in layer.keys(): +if "m4" in tech.layer.keys(): m3m4 = factory.create(module_type="contact", - layer_stack=m3_stack, + layer_stack=tech.m3_stack, directions=("H", "V")) else: m3m4 = None diff --git a/compiler/base/design.py b/compiler/base/design.py index 2b11111d..1066cbc0 100644 --- a/compiler/base/design.py +++ b/compiler/base/design.py @@ -10,6 +10,7 @@ import contact from globals import OPTS import re + class design(hierarchy_design): """ 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_multiport_constants() - 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 - - self.m1_pitch = max(contact.m1m2.width, contact.m1m2.height) + max(self.m1_space, self.m2_space) - self.m2_pitch = max(contact.m2m3.width, contact.m2m3.height) + max(self.m2_space, self.m3_space) + + # 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: - 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: self.m3_pitch = self.m2_pitch @@ -44,15 +52,17 @@ class design(hierarchy_design): self.m3_stack = tech.m3_stack 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 + from tech import drc for rule in drc.keys(): # Single layer width rules match = re.search(r"minwidth_(.*)", rule) if match: - if match.group(1)=="active_contact": + if match.group(1) == "active_contact": setattr(self, "contact_width", drc(match.group(0))) else: setattr(self, match.group(1)+"_width", drc(match.group(0))) @@ -64,11 +74,12 @@ class design(hierarchy_design): # Single layer spacing rules 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))) - elif match and match.group(1)!=match.group(2): - if match.group(2)=="poly_active": - setattr(self, match.group(1)+"_to_contact", drc(match.group(0))) + elif match and match.group(1) != match.group(2): + if match.group(2) == "poly_active": + setattr(self, match.group(1)+"_to_contact", + drc(match.group(0))) else: 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("implant_enclose_active", self.implant_enclose_active) print("implant_space", self.implant_space) - import sys; sys.exit(1) + import sys + sys.exit(1) def setup_multiport_constants(self): """ diff --git a/compiler/tests/03_wire_test.py b/compiler/tests/03_wire_test.py index bd4b9345..61e21985 100755 --- a/compiler/tests/03_wire_test.py +++ b/compiler/tests/03_wire_test.py @@ -8,11 +8,11 @@ # import unittest from testutils import * -import sys,os +import sys +import os sys.path.append(os.getenv("OPENRAM_HOME")) import globals -from globals import OPTS -import debug + class wire_test(openram_test): @@ -31,7 +31,8 @@ class wire_test(openram_test): layer_stack = stack[::-1] else: layer_stack = stack - + + # Just make a conservative spacing. Make it wire pitch instead? min_space = 2 * (tech.drc["minwidth_{}".format(layer_stack[0])] + tech.drc["minwidth_{}".format(layer_stack[2])])