diff --git a/compiler/base/contact.py b/compiler/base/contact.py index c3fa810d..2aa3ada5 100644 --- a/compiler/base/contact.py +++ b/compiler/base/contact.py @@ -1,11 +1,11 @@ -import design +import hierarchy_design import debug import utils from tech import drc from vector import vector -class contact(design.design): +class contact(hierarchy_design.hierarchy_design): """ Object for a contact shape with its conductor enclosures. Creates a contact array minimum active or poly enclosure and metal1 enclosure. @@ -31,7 +31,7 @@ class contact(design.design): dimensions[0], dimensions[1]) - design.design.__init__(self, name) + hierarchy_design.hierarchy_design.__init__(self, name) debug.info(4, "create contact object {0}".format(name)) self.layer_stack = layer_stack @@ -167,4 +167,5 @@ active = contact(layer_stack=("active", "contact", "poly")) poly = contact(layer_stack=("poly", "contact", "metal1")) m1m2 = contact(layer_stack=("metal1", "via1", "metal2")) m2m3 = contact(layer_stack=("metal2", "via2", "metal3")) +#m3m4 = contact(layer_stack=("metal3", "via3", "metal4")) diff --git a/compiler/base/design.py b/compiler/base/hierarchy_design.py similarity index 70% rename from compiler/base/design.py rename to compiler/base/hierarchy_design.py index 794bb79a..2af96f7d 100644 --- a/compiler/base/design.py +++ b/compiler/base/hierarchy_design.py @@ -7,7 +7,7 @@ import os from globals import OPTS -class design(hierarchy_spice.spice, hierarchy_layout.layout): +class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): """ Design Class for all modules to inherit the base features. Class consisting of a set of modules and instances of these modules @@ -23,7 +23,6 @@ class design(hierarchy_spice.spice, hierarchy_layout.layout): hierarchy_layout.layout.__init__(self, name) hierarchy_spice.spice.__init__(self, name) - self.setup_drc_constants() # Check if the name already exists, if so, give an error # because each reference must be a unique name. @@ -38,8 +37,8 @@ class design(hierarchy_spice.spice, hierarchy_layout.layout): 'sram', 'hierarchical_predecode2x4', 'hierarchical_predecode3x8'] - if name not in design.name_map: - design.name_map.append(name) + if name not in hierarchy_design.name_map: + hierarchy_design.name_map.append(name) else: for ok_names in ok_list: if ok_names in self.__class__.__name__: @@ -47,27 +46,6 @@ class design(hierarchy_spice.spice, hierarchy_layout.layout): else: debug.error("Duplicate layout reference name {0} of class {1}. GDS2 requires names be unique.".format(name,self.__class__),-1) - def setup_drc_constants(self): - """ These are some DRC constants used in many places in the compiler.""" - from tech import drc - self.well_width = drc["minwidth_well"] - self.poly_width = drc["minwidth_poly"] - self.poly_space = drc["poly_to_poly"] - self.m1_width = drc["minwidth_metal1"] - self.m1_space = drc["metal1_to_metal1"] - self.m2_width = drc["minwidth_metal2"] - self.m2_space = drc["metal2_to_metal2"] - self.m3_width = drc["minwidth_metal3"] - self.m3_space = drc["metal3_to_metal3"] - self.active_width = drc["minwidth_active"] - self.contact_width = drc["minwidth_contact"] - - self.poly_to_active = drc["poly_to_active"] - self.poly_extend_active = drc["poly_extend_active"] - self.contact_to_gate = drc["contact_to_gate"] - self.well_enclose_active = drc["well_enclosure_active"] - self.implant_enclose_active = drc["implant_enclosure_active"] - self.implant_space = drc["implant_to_implant"] def get_layout_pins(self,inst): """ Return a map of pin locations of the instance offset """ @@ -125,9 +103,3 @@ class design(hierarchy_spice.spice, hierarchy_layout.layout): text+=str(i)+",\n" return text - def analytical_power(self, proc, vdd, temp, load): - """ Get total power of a module """ - total_module_power = self.return_power() - for inst in self.insts: - total_module_power += inst.mod.analytical_power(proc, vdd, temp, load) - return total_module_power diff --git a/compiler/modules/bank.py b/compiler/modules/bank.py index 3ed6c222..db58441a 100644 --- a/compiler/modules/bank.py +++ b/compiler/modules/bank.py @@ -161,10 +161,6 @@ class bank(design.design): else: self.num_col_addr_lines = 0 - # M1/M2 routing pitch is based on contacted pitch - self.m1_pitch = contact.m1m2.height + max(self.m1_space,self.m2_space) - self.m2_pitch = contact.m2m3.height + max(self.m2_space,self.m3_space) - # The width of this bus is needed to place other modules (e.g. decoder) # A width on each side too self.central_bus_width = self.m2_pitch * self.num_control_lines + 2*self.m2_width diff --git a/compiler/modules/bank_select.py b/compiler/modules/bank_select.py index d0b3070a..2abfb3c6 100644 --- a/compiler/modules/bank_select.py +++ b/compiler/modules/bank_select.py @@ -56,10 +56,6 @@ class bank_select(design.design): def calculate_module_offsets(self): - # M1/M2 routing pitch is based on contacted pitch - self.m1_pitch = contact.m1m2.height + max(self.m1_space,self.m2_space) - self.m2_pitch = contact.m2m3.height + max(self.m2_space,self.m3_space) - self.xoffset_nand = self.inv4x.width + 2*self.m2_pitch + drc["pwell_to_nwell"] self.xoffset_nor = self.inv4x.width + 2*self.m2_pitch + drc["pwell_to_nwell"] self.xoffset_inv = max(self.xoffset_nand + self.nand2.width, self.xoffset_nor + self.nor2.width) diff --git a/compiler/modules/control_logic.py b/compiler/modules/control_logic.py index 33501158..8526cb43 100644 --- a/compiler/modules/control_logic.py +++ b/compiler/modules/control_logic.py @@ -86,10 +86,6 @@ class control_logic(design.design): # These aren't for instantiating, but we use them to get the dimensions #self.poly_contact_offset = vector(0.5*contact.poly.width,0.5*contact.poly.height) - # M1/M2 routing pitch is based on contacted pitch - self.m1_pitch = max(contact.m1m2.width,contact.m1m2.height) + max(drc["metal1_to_metal1"],drc["metal2_to_metal2"]) - self.m2_pitch = max(contact.m2m3.width,contact.m2m3.height) + max(drc["metal2_to_metal2"],drc["metal3_to_metal3"]) - # Have the cell gap leave enough room to route an M2 wire. # Some cells may have pwell/nwell spacing problems too when the wells are different heights. #self.cell_gap = max(self.m2_pitch,drc["pwell_to_nwell"]) diff --git a/compiler/modules/hierarchical_decoder.py b/compiler/modules/hierarchical_decoder.py index 0398b9a6..375201eb 100644 --- a/compiler/modules/hierarchical_decoder.py +++ b/compiler/modules/hierarchical_decoder.py @@ -90,9 +90,6 @@ class hierarchical_decoder(design.design): debug.error("Invalid number of inputs for hierarchical decoder",-1) def setup_layout_constants(self): - self.m1_pitch = contact.m1m2.height + max(self.m1_space,self.m2_space) - self.m2_pitch = contact.m2m3.height + max(self.m2_space,self.m3_space) - self.predec_groups = [] # This array is a 2D array. # Distributing vertical rails to different groups. One group belongs to one pre-decoder. diff --git a/compiler/modules/hierarchical_predecode.py b/compiler/modules/hierarchical_predecode.py index e0d05d92..d111b02b 100644 --- a/compiler/modules/hierarchical_predecode.py +++ b/compiler/modules/hierarchical_predecode.py @@ -50,10 +50,6 @@ class hierarchical_predecode(design.design): debug.error("Invalid number of predecode inputs.",-1) def setup_constraints(self): - # use a conservative douple spacing just to get rid of annoying via DRCs - 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) - # The rail offsets are indexed by the label self.rails = {} diff --git a/compiler/modules/replica_bitline.py b/compiler/modules/replica_bitline.py index 8d1d6242..f4c8995f 100644 --- a/compiler/modules/replica_bitline.py +++ b/compiler/modules/replica_bitline.py @@ -53,11 +53,6 @@ class replica_bitline(design.design): # These aren't for instantiating, but we use them to get the dimensions self.poly_contact_offset = vector(0.5*contact.poly.width,0.5*contact.poly.height) - # M1/M2 routing pitch is based on contacted pitch - 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) - - # Quadrant 1: Replica bitline and such are not rotated, but they must be placed far enough # away from the delay chain/inverter with space for three M2 tracks self.bitcell_offset = vector(0,self.replica_bitcell.height) diff --git a/compiler/modules/single_level_column_mux_array.py b/compiler/modules/single_level_column_mux_array.py index 31614ae1..777958a5 100644 --- a/compiler/modules/single_level_column_mux_array.py +++ b/compiler/modules/single_level_column_mux_array.py @@ -57,7 +57,6 @@ class single_level_column_mux_array(design.design): def setup_layout_constants(self): self.column_addr_size = num_of_inputs = int(self.words_per_row / 2) self.width = self.columns * self.mux.width - self.m1_pitch = contact.m1m2.width + max(drc["metal1_to_metal1"],drc["metal2_to_metal2"]) # one set of metal1 routes for select signals and a pair to interconnect the mux outputs bl/br # one extra route pitch is to space from the sense amp self.route_height = (self.words_per_row + 3)*self.m1_pitch diff --git a/compiler/sram.py b/compiler/sram.py index 0c144fb7..a8689742 100644 --- a/compiler/sram.py +++ b/compiler/sram.py @@ -48,12 +48,6 @@ class sram(design.design): design.design.__init__(self, name) - # M1/M2 routing pitch is based on contacted pitch of the biggest layer - 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) - self.m3_pitch = max(contact.m2m3.width,contact.m2m3.height) + max(self.m2_space,self.m3_space) - - self.control_size = 6 self.bank_to_bus_distance = 5*self.m3_width