diff --git a/compiler/base/contact.py b/compiler/base/contact.py index 5f169e07..c5b1ef9e 100644 --- a/compiler/base/contact.py +++ b/compiler/base/contact.py @@ -104,11 +104,11 @@ class contact(hierarchy_design.hierarchy_design): # The enclosure rule applies to symmetric enclosure component. first_layer_minwidth = drc("minwidth_{0}".format(self.first_layer_name)) - first_layer_enclosure = drc("{0}_enclosure_{1}".format(self.first_layer_name, self.via_layer_name)) + first_layer_enclosure = drc("{0}_enclose_{1}".format(self.first_layer_name, self.via_layer_name)) first_layer_extend = drc("{0}_extend_{1}".format(self.first_layer_name, self.via_layer_name)) second_layer_minwidth = drc("minwidth_{0}".format(self.second_layer_name)) - second_layer_enclosure = drc("{0}_enclosure_{1}".format(self.second_layer_name, self.via_layer_name)) + second_layer_enclosure = drc("{0}_enclose_{1}".format(self.second_layer_name, self.via_layer_name)) second_layer_extend = drc("{0}_extend_{1}".format(self.second_layer_name, self.via_layer_name)) # In some technologies, the minimum width may be larger @@ -204,16 +204,16 @@ class contact(hierarchy_design.hierarchy_design): height=self.second_layer_height) def create_implant_well_enclosures(self): - implant_position = self.first_layer_position - [drc("implant_enclosure_active")] * 2 - implant_width = self.first_layer_width + 2 * drc("implant_enclosure_active") - implant_height = self.first_layer_height + 2 * drc("implant_enclosure_active") + implant_position = self.first_layer_position - [drc("implant_enclose_active")] * 2 + implant_width = self.first_layer_width + 2 * drc("implant_enclose_active") + implant_height = self.first_layer_height + 2 * drc("implant_enclose_active") self.add_rect(layer="{}implant".format(self.implant_type), offset=implant_position, width=implant_width, height=implant_height) - well_position = self.first_layer_position - [drc("well_enclosure_active")] * 2 - well_width = self.first_layer_width + 2 * drc("well_enclosure_active") - well_height = self.first_layer_height + 2 * drc("well_enclosure_active") + well_position = self.first_layer_position - [drc("well_enclose_active")] * 2 + well_width = self.first_layer_width + 2 * drc("well_enclose_active") + well_height = self.first_layer_height + 2 * drc("well_enclose_active") self.add_rect(layer="{}well".format(self.well_type), offset=well_position, width=well_width, @@ -250,7 +250,7 @@ m1m2 = factory.create(module_type="contact", m2m3 = factory.create(module_type="contact", layer_stack=m2_stack, directions=("V", "H")) -if "metal4" in layer.keys(): +if "m4" in layer.keys(): m3m4 = factory.create(module_type="contact", layer_stack=m3_stack, directions=("H", "V")) diff --git a/compiler/base/design.py b/compiler/base/design.py index 7ee1624d..3b6ae914 100644 --- a/compiler/base/design.py +++ b/compiler/base/design.py @@ -8,7 +8,7 @@ from hierarchy_design import hierarchy_design import contact from globals import OPTS - +import re class design(hierarchy_design): """ @@ -32,7 +32,7 @@ class design(hierarchy_design): 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) - if "metal4" 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) else: self.m3_pitch = self.m2_pitch @@ -46,36 +46,62 @@ class design(hierarchy_design): def setup_drc_constants(self): """ These are some DRC constants used in many places in the compiler.""" from tech import drc, layer - 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") - if "metal4" in layer: - self.m4_width = drc("minwidth_metal4") - self.m4_space = drc("metal4_to_metal4") - self.active_width = drc("minwidth_active") - self.active_space = drc("active_to_body_active") - if "contact" in layer: - self.contact_width = drc("minwidth_contact") - else: - self.contact_width = drc("minwidth_active_contact") - self.poly_to_active = drc("poly_to_active") - self.poly_extend_active = drc("poly_extend_active") - if "contact" in layer: - self.poly_to_contact = drc("poly_to_contact") - else: - self.poly_to_contact = drc("poly_to_active_contact") - 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") - + # Make some local rules for convenience + for rule in drc.keys(): + # Single layer width rules + match = re.search(r"minwidth_(.*)", rule) + if match: + 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))) + + # Single layer area rules + match = re.search(r"minarea_(.*)", rule) + if match: + setattr(self, match.group(0), drc(match.group(0))) + + # Single layer spacing rules + match = re.search(r"(.*)_to_(.*)", rule) + 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))) + else: + setattr(self, match.group(0), drc(match.group(0))) + + match = re.search(r"(.*)_enclose_(.*)", rule) + if match: + setattr(self, match.group(0), drc(match.group(0))) + + match = re.search(r"(.*)_extend_(.*)", rule) + if match: + setattr(self, match.group(0), drc(match.group(0))) + + # These are for debugging previous manual rules + # print("poly_width", self.poly_width) + # print("poly_space", self.poly_space) + # print("m1_width", self.m1_width) + # print("m1_space", self.m1_space) + # print("m2_width", self.m2_width) + # print("m2_space", self.m2_space) + # print("m3_width", self.m3_width) + # print("m3_space", self.m3_space) + # print("m4_width", self.m4_width) + # print("m4_space", self.m4_space) + # print("active_width", self.active_width) + # print("active_space", self.active_space) + # print("contact_width", self.contact_width) + # print("poly_to_active", self.poly_to_active) + # print("poly_extend_active", self.poly_extend_active) + # print("poly_to_contact", self.poly_to_contact) + # print("contact_to_gate", self.contact_to_gate) + # print("well_enclose_active", self.well_enclose_active) + # print("implant_enclose_active", self.implant_enclose_active) + # print("implant_space", self.implant_space) + def setup_multiport_constants(self): """ These are contants and lists that aid multiport design. diff --git a/compiler/base/hierarchy_layout.py b/compiler/base/hierarchy_layout.py index ad1e3edb..7f23e942 100644 --- a/compiler/base/hierarchy_layout.py +++ b/compiler/base/hierarchy_layout.py @@ -61,7 +61,7 @@ class layout(): y_dir = 1 else: # we lose a rail after every 2 gates - base_offset=vector(x_offset, (inv_num+1) * height - (inv_num%2)*drc["minwidth_metal1"]) + base_offset=vector(x_offset, (inv_num+1) * height - (inv_num%2)*drc["minwidth_m1"]) y_dir = -1 return (base_offset,y_dir) @@ -388,9 +388,9 @@ class layout(): def get_preferred_direction(self, layer): """ Return the preferred routing directions """ - if layer in ["metal1", "metal3", "metal5"]: + if layer in ["m1", "m3", "m5"]: return "H" - elif layer in ["active", "poly", "metal2", "metal4"]: + elif layer in ["active", "poly", "m2", "m4"]: return "V" else: return "N" @@ -682,12 +682,12 @@ class layout(): return line_positions def connect_horizontal_bus(self, mapping, inst, bus_offsets, - layer_stack=("metal1","via1","metal2")): + layer_stack=("m1", "via1", "m2")): """ Horizontal version of connect_bus. """ self.connect_bus(mapping, inst, bus_offsets, layer_stack, True) def connect_vertical_bus(self, mapping, inst, bus_offsets, - layer_stack=("metal1","via1","metal2")): + layer_stack=("m1", "via1", "m2")): """ Vertical version of connect_bus. """ self.connect_bus(mapping, inst, bus_offsets, layer_stack, False) @@ -734,15 +734,15 @@ class layout(): rotate=90) def get_layer_pitch(self, layer): """ Return the track pitch on a given layer """ - if layer=="metal1": + if layer=="m1": return (self.m1_pitch,self.m1_pitch-self.m1_space,self.m1_space) - elif layer=="metal2": + elif layer=="m2": return (self.m2_pitch,self.m2_pitch-self.m2_space,self.m2_space) - elif layer=="metal3": + elif layer=="m3": return (self.m3_pitch,self.m3_pitch-self.m3_space,self.m3_space) - elif layer=="metal4": + elif layer=="m4": from tech import layer as tech_layer - if "metal4" in tech_layer: + if "m4" in tech_layer: return (self.m3_pitch,self.m3_pitch-self.m4_space,self.m4_space) else: return (self.m3_pitch,self.m3_pitch-self.m3_space,self.m3_space) @@ -1006,16 +1006,16 @@ class layout(): """ pins=inst.get_pins(name) for pin in pins: - if pin.layer=="metal3": + if pin.layer=="m3": self.add_layout_pin(name, pin.layer, pin.ll(), pin.width(), pin.height()) - elif pin.layer=="metal1": + elif pin.layer=="m1": self.add_power_pin(name, pin.center()) else: debug.warning("{0} pins of {1} should be on metal3 or metal1 for supply router.".format(name,inst.name)) - def add_power_pin(self, name, loc, vertical=False, start_layer="metal1"): + def add_power_pin(self, name, loc, vertical=False, start_layer="m1"): """ Add a single power pin from M3 down to M1 at the given center location. The starting layer is specified to determine which vias are needed. @@ -1025,24 +1025,24 @@ class layout(): else: direction=("H","H") - if start_layer=="metal1": + if start_layer=="m1": self.add_via_center(layers=self.m1_stack, offset=loc, directions=direction) - if start_layer=="metal1" or start_layer=="metal2": + if start_layer=="m1" or start_layer=="m2": via=self.add_via_center(layers=self.m2_stack, offset=loc, directions=direction) - if start_layer=="metal3": + if start_layer=="m3": self.add_layout_pin_rect_center(text=name, - layer="metal3", + layer="m3", offset=loc) else: self.add_layout_pin_rect_center(text=name, - layer="metal3", + layer="m3", offset=loc, width=via.width, height=via.height) @@ -1064,7 +1064,7 @@ class layout(): # LEFT vertical rails offset = ll + vector(-2*self.supply_rail_pitch, -2*self.supply_rail_pitch) left_gnd_pin=self.add_layout_pin(text="gnd", - layer="metal2", + layer="m2", offset=offset, width=self.supply_rail_width, height=height) @@ -1072,7 +1072,7 @@ class layout(): offset = ll + vector(-1*self.supply_rail_pitch, -1*self.supply_rail_pitch) left_vdd_pin=self.add_layout_pin(text="vdd", - layer="metal2", + layer="m2", offset=offset, width=self.supply_rail_width, height=height) @@ -1080,14 +1080,14 @@ class layout(): # RIGHT vertical rails offset = vector(ur.x,ll.y) + vector(0,-2*self.supply_rail_pitch) right_gnd_pin = self.add_layout_pin(text="gnd", - layer="metal2", + layer="m2", offset=offset, width=self.supply_rail_width, height=height) offset = vector(ur.x,ll.y) + vector(self.supply_rail_pitch,-1*self.supply_rail_pitch) right_vdd_pin=self.add_layout_pin(text="vdd", - layer="metal2", + layer="m2", offset=offset, width=self.supply_rail_width, height=height) @@ -1095,14 +1095,14 @@ class layout(): # BOTTOM horizontal rails offset = ll + vector(-2*self.supply_rail_pitch, -2*self.supply_rail_pitch) bottom_gnd_pin=self.add_layout_pin(text="gnd", - layer="metal1", + layer="m1", offset=offset, width=width, height=self.supply_rail_width) offset = ll + vector(-1*self.supply_rail_pitch, -1*self.supply_rail_pitch) bottom_vdd_pin=self.add_layout_pin(text="vdd", - layer="metal1", + layer="m1", offset=offset, width=width, height=self.supply_rail_width) @@ -1110,14 +1110,14 @@ class layout(): # TOP horizontal rails offset = vector(ll.x, ur.y) + vector(-2*self.supply_rail_pitch,0) top_gnd_pin=self.add_layout_pin(text="gnd", - layer="metal1", + layer="m1", offset=offset, width=width, height=self.supply_rail_width) offset = vector(ll.x, ur.y) + vector(-1*self.supply_rail_pitch, self.supply_rail_pitch) top_vdd_pin=self.add_layout_pin(text="vdd", - layer="metal1", + layer="m1", offset=offset, width=width, height=self.supply_rail_width) @@ -1139,7 +1139,7 @@ class layout(): from sram_factory import factory while True: c=factory.create(module_type="contact", - layer_stack=("metal1","via1","metal2"), + layer_stack=self.m1_stack, dimensions=(self.supply_vias, self.supply_vias)) if c.second_layer_width < self.supply_rail_width and c.second_layer_height < self.supply_rail_width: self.supply_vias += 1 diff --git a/compiler/bitcells/pbitcell.py b/compiler/bitcells/pbitcell.py index 8f9cd602..bdb9161b 100644 --- a/compiler/bitcells/pbitcell.py +++ b/compiler/bitcells/pbitcell.py @@ -364,11 +364,11 @@ class pbitcell(bitcell_base.bitcell_base): self.inverter_pmos_right.get_pin("G").bc()]) # connect output (drain/source) of inverters - self.add_path("metal1", + self.add_path("m1", [self.inverter_nmos_left.get_pin("D").uc(), self.inverter_pmos_left.get_pin("D").bc()], width=contact.active.second_layer_width) - self.add_path("metal1", + self.add_path("m1", [self.inverter_nmos_right.get_pin("S").uc(), self.inverter_pmos_right.get_pin("S").bc()], width=contact.active.second_layer_width) @@ -404,7 +404,7 @@ class pbitcell(bitcell_base.bitcell_base): # Add rails for vdd and gnd gnd_ypos = self.m1_offset - self.total_ports * self.m1_pitch self.gnd_position = vector(0, gnd_ypos) - self.add_rect_center(layer="metal1", + self.add_rect_center(layer="m1", offset=self.gnd_position, width=self.width) self.add_power_pin("gnd", vector(0, gnd_ypos)) @@ -416,7 +416,7 @@ class pbitcell(bitcell_base.bitcell_base): + self.inverter_pmos.active_height \ + self.vdd_offset self.vdd_position = vector(0, vdd_ypos) - self.add_rect_center(layer="metal1", + self.add_rect_center(layer="m1", offset=self.vdd_position, width=self.width) self.add_power_pin("vdd", vector(0, vdd_ypos)) @@ -489,7 +489,7 @@ class pbitcell(bitcell_base.bitcell_base): rwwl_ypos = self.m1_offset - k * self.m1_pitch self.rwwl_positions[k] = vector(0, rwwl_ypos) self.add_layout_pin_rect_center(text=self.rw_wl_names[k], - layer="metal1", + layer="m1", offset=self.rwwl_positions[k], width=self.width) @@ -499,7 +499,7 @@ class pbitcell(bitcell_base.bitcell_base): + 0.5 * self.m2_width self.rwbl_positions[k] = vector(rwbl_xpos, self.center_ypos) self.add_layout_pin_rect_center(text=self.rw_bl_names[k], - layer="metal2", + layer="m2", offset=self.rwbl_positions[k], height=self.height) @@ -509,7 +509,7 @@ class pbitcell(bitcell_base.bitcell_base): - 0.5 * self.m2_width self.rwbr_positions[k] = vector(rwbr_xpos, self.center_ypos) self.add_layout_pin_rect_center(text=self.rw_br_names[k], - layer="metal2", + layer="m2", offset=self.rwbr_positions[k], height=self.height) @@ -586,7 +586,7 @@ class pbitcell(bitcell_base.bitcell_base): - k * self.m1_pitch self.wwl_positions[k] = vector(0, wwl_ypos) self.add_layout_pin_rect_center(text=self.w_wl_names[k], - layer="metal1", + layer="m1", offset=self.wwl_positions[k], width=self.width) @@ -596,7 +596,7 @@ class pbitcell(bitcell_base.bitcell_base): + 0.5 * self.m2_width self.wbl_positions[k] = vector(wbl_xpos, self.center_ypos) self.add_layout_pin_rect_center(text=self.w_bl_names[k], - layer="metal2", + layer="m2", offset=self.wbl_positions[k], height=self.height) @@ -606,7 +606,7 @@ class pbitcell(bitcell_base.bitcell_base): - 0.5 * self.m2_width self.wbr_positions[k] = vector(wbr_xpos, self.center_ypos) self.add_layout_pin_rect_center(text=self.w_br_names[k], - layer="metal2", + layer="m2", offset=self.wbr_positions[k], height=self.height) @@ -713,7 +713,7 @@ class pbitcell(bitcell_base.bitcell_base): - k * self.m1_pitch self.rwl_positions[k] = vector(0, rwl_ypos) self.add_layout_pin_rect_center(text=self.r_wl_names[k], - layer="metal1", + layer="m1", offset=self.rwl_positions[k], width=self.width) @@ -723,7 +723,7 @@ class pbitcell(bitcell_base.bitcell_base): + 0.5 * self.m2_width self.rbl_positions[k] = vector(rbl_xpos, self.center_ypos) self.add_layout_pin_rect_center(text=self.r_bl_names[k], - layer="metal2", + layer="m2", offset=self.rbl_positions[k], height=self.height) @@ -733,7 +733,7 @@ class pbitcell(bitcell_base.bitcell_base): - 0.5 * self.m2_width self.rbr_positions[k] = vector(rbr_xpos, self.center_ypos) self.add_layout_pin_rect_center(text=self.r_br_names[k], - layer="metal2", + layer="m2", offset=self.rbr_positions[k], height=self.height) @@ -775,7 +775,7 @@ class pbitcell(bitcell_base.bitcell_base): offset=port_contact_offset) self.add_path("poly", [gate_offset, port_contact_offset]) - self.add_path("metal1", + self.add_path("m1", [port_contact_offset, wl_contact_offset]) else: @@ -789,7 +789,7 @@ class pbitcell(bitcell_base.bitcell_base): directions=("H", "H")) self.add_path("poly", [gate_offset, port_contact_offset]) - self.add_path("metal2", + self.add_path("m2", [port_contact_offset, wl_contact_offset]) def route_bitlines(self): @@ -827,7 +827,7 @@ class pbitcell(bitcell_base.bitcell_base): self.add_via_center(layers=self.m1_stack, offset=port_contact_offest) - self.add_path("metal2", + self.add_path("m2", [port_contact_offest, bl_offset], width=contact.m1m2.height) for k in range(self.total_ports): @@ -839,7 +839,7 @@ class pbitcell(bitcell_base.bitcell_base): self.add_via_center(layers=self.m1_stack, offset=port_contact_offest) - self.add_path("metal2", + self.add_path("m2", [port_contact_offest, br_offset], width=contact.m1m2.height) def route_supply(self): @@ -866,17 +866,17 @@ class pbitcell(bitcell_base.bitcell_base): offset=supply_offset, directions=("H", "H")) - self.add_path("metal2", [position, supply_offset]) + self.add_path("m2", [position, supply_offset]) # route inverter pmos to vdd vdd_pos_left = vector(self.inverter_nmos_left.get_pin("S").uc().x, self.vdd_position.y) - self.add_path("metal1", + self.add_path("m1", [self.inverter_pmos_left.get_pin("S").uc(), vdd_pos_left]) vdd_pos_right = vector(self.inverter_nmos_right.get_pin("D").uc().x, self.vdd_position.y) - self.add_path("metal1", + self.add_path("m1", [self.inverter_pmos_right.get_pin("D").uc(), vdd_pos_right]) def route_readwrite_access(self): @@ -889,14 +889,14 @@ class pbitcell(bitcell_base.bitcell_base): self.cross_couple_lower_ypos) Q_pos = vector(self.inverter_nmos_left.get_pin("D").lx(), self.cross_couple_lower_ypos) - self.add_path("metal1", + self.add_path("m1", [self.readwrite_nmos_left[k].get_pin("D").uc(), mid, Q_pos]) mid = vector(self.readwrite_nmos_right[k].get_pin("S").uc().x, self.cross_couple_lower_ypos) Q_bar_pos = vector(self.inverter_nmos_right.get_pin("S").rx(), self.cross_couple_lower_ypos) - self.add_path("metal1", + self.add_path("m1", [self.readwrite_nmos_right[k].get_pin("S").uc(), mid, Q_bar_pos]) def route_write_access(self): @@ -909,14 +909,14 @@ class pbitcell(bitcell_base.bitcell_base): self.cross_couple_lower_ypos) Q_pos = vector(self.inverter_nmos_left.get_pin("D").lx(), self.cross_couple_lower_ypos) - self.add_path("metal1", + self.add_path("m1", [self.write_nmos_left[k].get_pin("D").uc(), mid, Q_pos]) mid = vector(self.write_nmos_right[k].get_pin("S").uc().x, self.cross_couple_lower_ypos) Q_bar_pos = vector(self.inverter_nmos_right.get_pin("S").rx(), self.cross_couple_lower_ypos) - self.add_path("metal1", + self.add_path("m1", [self.write_nmos_right[k].get_pin("S").uc(), mid, Q_bar_pos]) def route_read_access(self): @@ -960,7 +960,7 @@ class pbitcell(bitcell_base.bitcell_base): mid = vector(self.read_access_nmos_left[k].get_pin("G").uc().x, self.cross_couple_upper_ypos) - self.add_path("metal1", + self.add_path("m1", [port_contact_offset, mid, left_storage_contact]) port_contact_offset = self.read_access_nmos_right[k].get_pin("G").uc() \ @@ -975,7 +975,7 @@ class pbitcell(bitcell_base.bitcell_base): mid = vector(self.read_access_nmos_right[k].get_pin("G").uc().x, self.cross_couple_upper_ypos) - self.add_path("metal1", + self.add_path("m1", [port_contact_offset, mid, right_storage_contact]) def extend_well(self): @@ -1076,7 +1076,7 @@ class pbitcell(bitcell_base.bitcell_base): """ Q_bar_pos = self.inverter_pmos_right.get_pin("S").center() vdd_pos = self.inverter_pmos_right.get_pin("D").center() - self.add_path("metal1", [Q_bar_pos, vdd_pos]) + self.add_path("m1", [Q_bar_pos, vdd_pos]) def get_storage_net_names(self): """ diff --git a/compiler/drc/design_rules.py b/compiler/drc/design_rules.py index cf54bdb3..05168b77 100644 --- a/compiler/drc/design_rules.py +++ b/compiler/drc/design_rules.py @@ -9,7 +9,7 @@ import debug from drc_value import * from drc_lut import * -class design_rules(): +class design_rules(dict): """ This is a class that implements the design rules structures. """ @@ -43,7 +43,9 @@ class design_rules(): else: debug.error("Must call complex DRC rule {} with arguments.".format(b),-1) - + def keys(self): + return self.rules.keys() + def add_layer(self, name, width, spacing, area=0): # Minimum width self.add("minwidth_{}".format(name), width) @@ -53,7 +55,7 @@ class design_rules(): self.add("minarea_{}".format(name), area) def add_enclosure(self, name, layer, enclosure, extension=None): - self.add("{0}_enclosure_{1}".format(name, layer), enclosure) + self.add("{0}_enclose_{1}".format(name, layer), enclosure) # Reserved for asymmetric enclosures if extension: self.add("{0}_extend_{1}".format(name, layer), extension) diff --git a/compiler/modules/bank.py b/compiler/modules/bank.py index b1ce2d55..4527044c 100644 --- a/compiler/modules/bank.py +++ b/compiler/modules/bank.py @@ -333,7 +333,7 @@ class bank(design.design): self.col_addr_bus_width = self.m2_pitch*self.num_col_addr_lines # A space for wells or jogging m2 - self.m2_gap = max(2*drc("pwell_to_nwell") + drc("well_enclosure_active"), + self.m2_gap = max(2*drc("pwell_to_nwell") + drc("well_enclose_active"), 3*self.m2_pitch) @@ -605,7 +605,7 @@ class bank(design.design): out_pos = self.bank_select_inst[port].get_pin(gated_bank_sel_signals[signal]).rc() name = self.control_signals[port][signal] bus_pos = vector(self.bus_xoffset[port][name].x, out_pos.y) - self.add_path("metal3",[out_pos, bus_pos]) + self.add_path("m3",[out_pos, bus_pos]) self.add_via_center(layers=self.m2_stack, offset=bus_pos) self.add_via_center(layers=self.m1_stack, @@ -648,7 +648,7 @@ class bank(design.design): control_bus_offset = vector(-self.m2_pitch * self.num_control_lines[0] - self.m2_pitch, self.min_y_offset) # The control bus is routed up to two pitches below the bitcell array control_bus_length = self.main_bitcell_array_bottom - self.min_y_offset - 2*self.m1_pitch - self.bus_xoffset[0] = self.create_bus(layer="metal2", + self.bus_xoffset[0] = self.create_bus(layer="m2", pitch=self.m2_pitch, offset=control_bus_offset, names=self.control_signals[0], @@ -663,7 +663,7 @@ class bank(design.design): control_bus_offset = vector(self.bitcell_array_right + self.m2_pitch, self.max_y_offset - control_bus_length) # The bus for the right port is reversed so that the rbl_wl is closest to the array - self.bus_xoffset[1] = self.create_bus(layer="metal2", + self.bus_xoffset[1] = self.create_bus(layer="m2", pitch=self.m2_pitch, offset=control_bus_offset, names=list(reversed(self.control_signals[1])), @@ -817,7 +817,7 @@ class bank(design.design): bitcell_wl_pos = self.bitcell_array_inst.get_pin(self.wl_names[port]+"_{}".format(row)).lc() mid1 = driver_wl_pos.scale(0,1) + vector(0.5*self.port_address_inst[port].rx() + 0.5*self.bitcell_array_inst.lx(),0) mid2 = mid1.scale(1,0)+bitcell_wl_pos.scale(0.5,1) - self.add_path("metal1", [driver_wl_pos, mid1, mid2, bitcell_wl_pos]) + self.add_path("m1", [driver_wl_pos, mid1, mid2, bitcell_wl_pos]) def route_port_address_right(self, port): @@ -829,7 +829,7 @@ class bank(design.design): bitcell_wl_pos = self.bitcell_array_inst.get_pin(self.wl_names[port]+"_{}".format(row)).rc() mid1 = driver_wl_pos.scale(0,1) + vector(0.5*self.port_address_inst[port].lx() + 0.5*self.bitcell_array_inst.rx(),0) mid2 = mid1.scale(1,0)+bitcell_wl_pos.scale(0,1) - self.add_path("metal1", [driver_wl_pos, mid1, mid2, bitcell_wl_pos]) + self.add_path("m1", [driver_wl_pos, mid1, mid2, bitcell_wl_pos]) def route_column_address_lines(self, port): """ Connecting the select lines of column mux to the address bus """ @@ -878,7 +878,7 @@ class bank(design.design): wl_name = "wl_{}".format(i) wl_pin = self.bitcell_array_inst.get_pin(wl_name) self.add_label(text=wl_name, - layer="metal1", + layer="m1", offset=wl_pin.center()) # Add the bitline names @@ -888,10 +888,10 @@ class bank(design.design): bl_pin = self.bitcell_array_inst.get_pin(bl_name) br_pin = self.bitcell_array_inst.get_pin(br_name) self.add_label(text=bl_name, - layer="metal2", + layer="m2", offset=bl_pin.center()) self.add_label(text=br_name, - layer="metal2", + layer="m2", offset=br_pin.center()) # # Add the data output names to the sense amp output @@ -899,7 +899,7 @@ class bank(design.design): # data_name = "data_{}".format(i) # data_pin = self.sense_amp_array_inst.get_pin(data_name) # self.add_label(text="sa_out_{}".format(i), - # layer="metal2", + # layer="m2", # offset=data_pin.center()) # Add labels on the decoder @@ -909,7 +909,7 @@ class bank(design.design): pin_name = "in_{}".format(i) data_pin = self.wordline_driver_inst[port].get_pin(pin_name) self.add_label(text=data_name, - layer="metal1", + layer="m1", offset=data_pin.center()) @@ -941,7 +941,7 @@ class bank(design.design): for (control_signal, pin_pos) in connection: control_mid_pos = self.bus_xoffset[port][control_signal] control_pos = vector(self.bus_xoffset[port][control_signal].x ,pin_pos.y) - self.add_wire(("metal1","via1","metal2"), [control_mid_pos, control_pos, pin_pos]) + self.add_wire(self.m1_stack, [control_mid_pos, control_pos, pin_pos]) self.add_via_center(layers=self.m1_stack, offset=control_pos) @@ -956,7 +956,7 @@ class bank(design.design): mid_pos = pin_pos - vector(0,2*self.m2_gap) # to route down to the top of the bus control_x_offset = self.bus_xoffset[port][control_signal].x control_pos = vector(control_x_offset, mid_pos.y) - self.add_wire(("metal1","via1","metal2"),[pin_pos, mid_pos, control_pos]) + self.add_wire(self.m1_stack,[pin_pos, mid_pos, control_pos]) self.add_via_center(layers=self.m1_stack, offset=control_pos) diff --git a/compiler/modules/bank_select.py b/compiler/modules/bank_select.py index 14b6b203..4b49750d 100644 --- a/compiler/modules/bank_select.py +++ b/compiler/modules/bank_select.py @@ -208,18 +208,18 @@ class bank_select(design.design): xoffset_bank_sel = bank_sel_inv_pin.lx() bank_sel_line_pos = vector(xoffset_bank_sel, 0) bank_sel_line_end = vector(xoffset_bank_sel, self.yoffset_maxpoint) - self.add_path("metal2", [bank_sel_line_pos, bank_sel_line_end]) - self.add_via_center(layers=("metal1","via1","metal2"), + self.add_path("m2", [bank_sel_line_pos, bank_sel_line_end]) + self.add_via_center(layers=self.m1_stack, offset=bank_sel_inv_pin.lc()) # Route the pin to the left edge as well bank_sel_pin_pos=vector(0, 0) bank_sel_pin_end=vector(bank_sel_line_pos.x, bank_sel_pin_pos.y) self.add_layout_pin_segment_center(text="bank_sel", - layer="metal3", + layer="m3", start=bank_sel_pin_pos, end=bank_sel_pin_end) - self.add_via_center(layers=("metal2","via2","metal3"), + self.add_via_center(layers=self.m2_stack, offset=bank_sel_pin_end, directions=("H","H")) @@ -227,10 +227,10 @@ class bank_select(design.design): bank_sel_bar_pin = self.bank_sel_inv.get_pin("Z") xoffset_bank_sel_bar = bank_sel_bar_pin.rx() self.add_label_pin(text="bank_sel_bar", - layer="metal2", + layer="m2", offset=vector(xoffset_bank_sel_bar, 0), height=self.inv4x.height) - self.add_via_center(layers=("metal1","via1","metal2"), + self.add_via_center(layers=self.m1_stack, offset=bank_sel_bar_pin.rc()) @@ -251,13 +251,13 @@ class bank_select(design.design): out_position = logic_inst.get_pin("Z").rc() + vector(0.5*self.m1_width,0) in_position = inv_inst.get_pin("A").lc() + vector(0.5*self.m1_width,0) post = inv_inst.get_pin("A").rc() - self.add_path("metal1", [pre, out_position, in_position, post]) + self.add_path("m1", [pre, out_position, in_position, post]) # Connect the logic B input to bank_sel/bank_sel_bar logic_pos = logic_inst.get_pin("B").lc() - vector(0.5*contact.m1m2.height,0) input_pos = vector(xoffset_bank_signal, logic_pos.y) - self.add_path("metal2",[logic_pos, input_pos]) + self.add_path("m2",[logic_pos, input_pos]) self.add_via_center(layers=self.m1_stack, offset=logic_pos, directions=("H","H")) @@ -273,7 +273,7 @@ class bank_select(design.design): offset=logic_pos, directions=("H","H")) self.add_layout_pin_segment_center(text=input_name, - layer="metal3", + layer="m3", start=input_pos, end=logic_pos) @@ -294,7 +294,7 @@ class bank_select(design.design): for n in ["vdd", "gnd"]: supply_pin = self.inv_inst[num].get_pin(n) supply_offset = supply_pin.ll().scale(0,1) - self.add_rect(layer="metal1", + self.add_rect(layer="m1", offset=supply_offset, width=self.width) @@ -308,20 +308,20 @@ class bank_select(design.design): offset=pin_pos, directions=("H","H")) self.add_layout_pin_rect_center(text=n, - layer="metal3", + layer="m3", offset=pin_pos) # Add vdd/gnd supply rails gnd_pin = inv_inst.get_pin("gnd") left_gnd_pos = vector(0, gnd_pin.cy()) self.add_layout_pin_segment_center(text="gnd", - layer="metal1", + layer="m1", start=left_gnd_pos, end=gnd_pin.rc()) vdd_pin = inv_inst.get_pin("vdd") left_vdd_pos = vector(0, vdd_pin.cy()) self.add_layout_pin_segment_center(text="vdd", - layer="metal1", + layer="m1", start=left_vdd_pos, end=vdd_pin.rc()) diff --git a/compiler/modules/bitcell_array.py b/compiler/modules/bitcell_array.py index b1b61487..bf43736b 100644 --- a/compiler/modules/bitcell_array.py +++ b/compiler/modules/bitcell_array.py @@ -173,7 +173,7 @@ class bitcell_array(design.design): width = 0 else: width = self.width - wl_wire = self.generate_rc_net(int(self.column_size), width, drc("minwidth_metal1")) + wl_wire = self.generate_rc_net(int(self.column_size), width, drc("minwidth_m1")) wl_wire.wire_c = 2*spice["min_tx_gate_c"] + wl_wire.wire_c # 2 access tx gate per cell return wl_wire @@ -183,7 +183,7 @@ class bitcell_array(design.design): else: height = self.height bl_pos = 0 - bl_wire = self.generate_rc_net(int(self.row_size-bl_pos), height, drc("minwidth_metal1")) + bl_wire = self.generate_rc_net(int(self.row_size-bl_pos), height, drc("minwidth_m1")) bl_wire.wire_c =spice["min_tx_drain_c"] + bl_wire.wire_c # 1 access tx d/s per cell return bl_wire diff --git a/compiler/modules/control_logic.py b/compiler/modules/control_logic.py index 3256c9ac..dbb7c3b7 100644 --- a/compiler/modules/control_logic.py +++ b/compiler/modules/control_logic.py @@ -371,7 +371,7 @@ class control_logic(design.design): height = self.control_logic_center.y - self.m2_pitch offset = vector(self.ctrl_dff_array.width,0) - self.rail_offsets = self.create_vertical_bus("metal2", self.m2_pitch, offset, self.internal_bus_list, height) + self.rail_offsets = self.create_vertical_bus("m2", self.m2_pitch, offset, self.internal_bus_list, height) def create_instances(self): @@ -483,8 +483,8 @@ class control_logic(design.design): vdd_ypos = self.p_en_bar_nand_inst.get_pin("vdd").by() in_pos = vector(self.rail_offsets["rbl_bl_delay"].x,vdd_ypos) mid1 = vector(out_pos.x,in_pos.y) - self.add_wire(("metal1","via1","metal2"),[out_pos, mid1, in_pos]) - self.add_via_center(layers=("metal1","via1","metal2"), + self.add_wire(self.m1_stack,[out_pos, mid1, in_pos]) + self.add_via_center(layers=self.m1_stack, offset=in_pos) @@ -509,10 +509,10 @@ class control_logic(design.design): clk_pin = self.clk_buf_inst.get_pin("A") clk_pos = clk_pin.center() self.add_layout_pin_segment_center(text="clk", - layer="metal2", + layer="m2", start=clk_pos, end=clk_pos.scale(1,0)) - self.add_via_center(layers=("metal1","via1","metal2"), + self.add_via_center(layers=self.m1_stack, offset=clk_pos) @@ -521,9 +521,9 @@ class control_logic(design.design): mid1 = vector(out_pos.x,2*self.m2_pitch) mid2 = vector(self.rail_offsets["clk_buf"].x, mid1.y) bus_pos = self.rail_offsets["clk_buf"] - self.add_wire(("metal3","via2","metal2"),[out_pos, mid1, mid2, bus_pos]) + self.add_wire(("m3","via2","m2"),[out_pos, mid1, mid2, bus_pos]) # The pin is on M1, so we need another via as well - self.add_via_center(layers=("metal1","via1","metal2"), + self.add_via_center(layers=self.m1_stack, offset=self.clk_buf_inst.get_pin("Z").center()) self.connect_output(self.clk_buf_inst, "Z", "clk_buf") @@ -552,21 +552,21 @@ class control_logic(design.design): out_pos = self.clk_bar_inst.get_pin("Z").center() in_pos = self.gated_clk_bar_inst.get_pin("B").center() mid1 = vector(in_pos.x,out_pos.y) - self.add_path("metal1",[out_pos, mid1, in_pos]) + self.add_path("m1",[out_pos, mid1, in_pos]) # This is the second gate over, so it needs to be on M3 clkbuf_map = zip(["A"], ["cs"]) - self.connect_vertical_bus(clkbuf_map, self.gated_clk_bar_inst, self.rail_offsets, ("metal3", "via2", "metal2")) + self.connect_vertical_bus(clkbuf_map, self.gated_clk_bar_inst, self.rail_offsets, ("m3", "via2", "m2")) # The pin is on M1, so we need another via as well - self.add_via_center(layers=("metal1","via1","metal2"), + self.add_via_center(layers=self.m1_stack, offset=self.gated_clk_bar_inst.get_pin("A").center()) # This is the second gate over, so it needs to be on M3 clkbuf_map = zip(["Z"], ["gated_clk_bar"]) - self.connect_vertical_bus(clkbuf_map, self.gated_clk_bar_inst, self.rail_offsets, ("metal3", "via2", "metal2")) + self.connect_vertical_bus(clkbuf_map, self.gated_clk_bar_inst, self.rail_offsets, ("m3", "via2", "m2")) # The pin is on M1, so we need another via as well - self.add_via_center(layers=("metal1","via1","metal2"), + self.add_via_center(layers=self.m1_stack, offset=self.gated_clk_bar_inst.get_pin("Z").center()) def create_gated_clk_buf_row(self): @@ -587,9 +587,9 @@ class control_logic(design.design): clkbuf_map = zip(["Z"], ["gated_clk_buf"]) - self.connect_vertical_bus(clkbuf_map, self.gated_clk_buf_inst, self.rail_offsets, ("metal3", "via2", "metal2")) + self.connect_vertical_bus(clkbuf_map, self.gated_clk_buf_inst, self.rail_offsets, ("m3", "via2", "m2")) # The pin is on M1, so we need another via as well - self.add_via_center(layers=("metal1","via1","metal2"), + self.add_via_center(layers=self.m1_stack, offset=self.gated_clk_buf_inst.get_pin("Z").center()) def create_wlen_row(self): @@ -637,7 +637,7 @@ class control_logic(design.design): out_pos = self.p_en_bar_nand_inst.get_pin("Z").rc() in_pos = self.p_en_bar_driver_inst.get_pin("A").lc() mid1 = vector(out_pos.x,in_pos.y) - self.add_wire(("metal1","via1","metal2"),[out_pos, mid1,in_pos]) + self.add_wire(self.m1_stack,[out_pos, mid1,in_pos]) self.connect_output(self.p_en_bar_driver_inst, "Z", "p_en_bar") @@ -694,9 +694,9 @@ class control_logic(design.design): # Connect to rail rbl_map = zip(["Z"], ["rbl_bl_delay_bar"]) - self.connect_vertical_bus(rbl_map, self.rbl_bl_delay_inv_inst, self.rail_offsets, ("metal3", "via2", "metal2")) + self.connect_vertical_bus(rbl_map, self.rbl_bl_delay_inv_inst, self.rail_offsets, ("m3", "via2", "m2")) # The pin is on M1, so we need another via as well - self.add_via_center(layers=("metal1","via1","metal2"), + self.add_via_center(layers=self.m1_stack, offset=self.rbl_bl_delay_inv_inst.get_pin("Z").center()) @@ -754,14 +754,14 @@ class control_logic(design.design): dff_out_map = zip(["dout_bar_0", "dout_0"], ["cs", "cs_bar"]) else: dff_out_map = zip(["dout_bar_0"], ["cs"]) - self.connect_vertical_bus(dff_out_map, self.ctrl_dff_inst, self.rail_offsets, ("metal3", "via2", "metal2")) + self.connect_vertical_bus(dff_out_map, self.ctrl_dff_inst, self.rail_offsets, ("m3", "via2", "m2")) # Connect the clock rail to the other clock rail in_pos = self.ctrl_dff_inst.get_pin("clk").uc() mid_pos = in_pos + vector(0,2*self.m2_pitch) rail_pos = vector(self.rail_offsets["clk_buf"].x, mid_pos.y) - self.add_wire(("metal1","via1","metal2"),[in_pos, mid_pos, rail_pos]) - self.add_via_center(layers=("metal1","via1","metal2"), + self.add_wire(self.m1_stack,[in_pos, mid_pos, rail_pos]) + self.add_via_center(layers=self.m1_stack, offset=rail_pos) self.copy_layout_pin(self.ctrl_dff_inst, "din_0", "csb") @@ -786,7 +786,7 @@ class control_logic(design.design): out_pin = inst.get_pin(pin_name) right_pos=out_pin.center() + vector(self.width-out_pin.cx(),0) self.add_layout_pin_segment_center(text=out_name, - layer="metal1", + layer="m1", start=out_pin.center(), end=right_pos) @@ -799,19 +799,19 @@ class control_logic(design.design): for inst in self.row_end_inst: pins = inst.get_pins("vdd") for pin in pins: - if pin.layer == "metal1": + if pin.layer == "m1": row_loc = pin.rc() pin_loc = vector(max_row_x_loc, pin.rc().y) self.add_power_pin("vdd", pin_loc) - self.add_path("metal1", [row_loc, pin_loc]) + self.add_path("m1", [row_loc, pin_loc]) pins = inst.get_pins("gnd") for pin in pins: - if pin.layer == "metal1": + if pin.layer == "m1": row_loc = pin.rc() pin_loc = vector(max_row_x_loc, pin.rc().y) self.add_power_pin("gnd", pin_loc) - self.add_path("metal1", [row_loc, pin_loc]) + self.add_path("m1", [row_loc, pin_loc]) self.copy_layout_pin(self.delay_inst,"gnd") self.copy_layout_pin(self.delay_inst,"vdd") @@ -828,14 +828,14 @@ class control_logic(design.design): """ # pin=self.clk_inv1.get_pin("Z") # self.add_label_pin(text="clk1_bar", - # layer="metal1", + # layer="m1", # offset=pin.ll(), # height=pin.height(), # width=pin.width()) # pin=self.clk_inv2.get_pin("Z") # self.add_label_pin(text="clk2", - # layer="metal1", + # layer="m1", # offset=pin.ll(), # height=pin.height(), # width=pin.width()) diff --git a/compiler/modules/delay_chain.py b/compiler/modules/delay_chain.py index bc932a26..a07576d4 100644 --- a/compiler/modules/delay_chain.py +++ b/compiler/modules/delay_chain.py @@ -132,11 +132,11 @@ class delay_chain(design.design): pin1_pos = pin1.center() pin2_pos = pin2.center() if pin1_pos.y == pin2_pos.y: - self.add_path("metal2", [pin1_pos, pin2_pos]) + self.add_path("m2", [pin1_pos, pin2_pos]) else: mid_point = vector(pin2_pos.x, 0.5*(pin1_pos.y+pin2_pos.y)) # Written this way to guarantee it goes right first if we are switching rows - self.add_path("metal2", [pin1_pos, vector(pin1_pos.x,mid_point.y), mid_point, vector(mid_point.x,pin2_pos.y), pin2_pos]) + self.add_path("m2", [pin1_pos, vector(pin1_pos.x,mid_point.y), mid_point, vector(mid_point.x,pin2_pos.y), pin2_pos]) def route_inverters(self): """ Add metal routing for each of the fanout stages """ @@ -146,22 +146,22 @@ class delay_chain(design.design): for load in self.load_inst_map[inv]: # Drop a via on each A pin a_pin = load.get_pin("A") - self.add_via_center(layers=("metal1","via1","metal2"), + self.add_via_center(layers=self.m1_stack, offset=a_pin.center()) - self.add_via_center(layers=("metal2","via2","metal3"), + self.add_via_center(layers=self.m2_stack, offset=a_pin.center()) # Route an M3 horizontal wire to the furthest z_pin = inv.get_pin("Z") a_pin = inv.get_pin("A") a_max = self.rightest_load_inst[inv].get_pin("A") - self.add_via_center(layers=("metal1","via1","metal2"), + self.add_via_center(layers=self.m1_stack, offset=a_pin.center()) - self.add_via_center(layers=("metal1","via1","metal2"), + self.add_via_center(layers=self.m1_stack, offset=z_pin.center()) - self.add_via_center(layers=("metal2","via2","metal3"), + self.add_via_center(layers=self.m2_stack, offset=z_pin.center()) - self.add_path("metal3",[z_pin.center(), a_max.center()]) + self.add_path("m3",[z_pin.center(), a_max.center()]) # Route Z to the A of the next stage @@ -172,7 +172,7 @@ class delay_chain(design.design): y_mid = (z_pin.cy() + next_a_pin.cy())/2 mid1_point = vector(z_pin.cx(), y_mid) mid2_point = vector(next_a_pin.cx(), y_mid) - self.add_path("metal2",[z_pin.center(), mid1_point, mid2_point, next_a_pin.center()]) + self.add_path("m2",[z_pin.center(), mid1_point, mid2_point, next_a_pin.center()]) def add_layout_pins(self): @@ -205,10 +205,10 @@ class delay_chain(design.design): # input is A pin of first inverter a_pin = self.driver_inst_list[0].get_pin("A") - self.add_via_center(layers=("metal1","via1","metal2"), + self.add_via_center(layers=self.m1_stack, offset=a_pin.center()) self.add_layout_pin(text="in", - layer="metal2", + layer="m2", offset=a_pin.ll().scale(1,0), height=a_pin.cy()) @@ -216,12 +216,12 @@ class delay_chain(design.design): # output is A pin of last load inverter last_driver_inst = self.driver_inst_list[-1] a_pin = self.rightest_load_inst[last_driver_inst].get_pin("A") - self.add_via_center(layers=("metal1","via1","metal2"), + self.add_via_center(layers=self.m1_stack, offset=a_pin.center()) mid_point = vector(a_pin.cx()+3*self.m2_width,a_pin.cy()) - self.add_path("metal2",[a_pin.center(), mid_point, mid_point.scale(1,0)]) + self.add_path("m2",[a_pin.center(), mid_point, mid_point.scale(1,0)]) self.add_layout_pin_segment_center(text="out", - layer="metal2", + layer="m2", start=mid_point, end=mid_point.scale(1,0)) diff --git a/compiler/modules/dff_array.py b/compiler/modules/dff_array.py index 89b29476..6ba020c7 100644 --- a/compiler/modules/dff_array.py +++ b/compiler/modules/dff_array.py @@ -124,7 +124,7 @@ class dff_array(design.design): for row in range(self.rows): for col in range(self.columns): din_pin = self.dff_insts[row,col].get_pin("D") - debug.check(din_pin.layer=="metal2","DFF D pin not on metal2") + debug.check(din_pin.layer=="m2","DFF D pin not on metal2") self.add_layout_pin(text=self.get_din_name(row,col), layer=din_pin.layer, offset=din_pin.ll(), @@ -132,7 +132,7 @@ class dff_array(design.design): height=din_pin.height()) dout_pin = self.dff_insts[row,col].get_pin("Q") - debug.check(dout_pin.layer=="metal2","DFF Q pin not on metal2") + debug.check(dout_pin.layer=="m2","DFF Q pin not on metal2") self.add_layout_pin(text=self.get_dout_name(row,col), layer=dout_pin.layer, offset=dout_pin.ll(), @@ -144,20 +144,20 @@ class dff_array(design.design): # Create vertical spines to a single horizontal rail clk_pin = self.dff_insts[0,0].get_pin("clk") clk_ypos = 2*self.m3_pitch+self.m3_width - debug.check(clk_pin.layer=="metal2","DFF clk pin not on metal2") + debug.check(clk_pin.layer=="m2","DFF clk pin not on metal2") self.add_layout_pin_segment_center(text="clk", - layer="metal3", + layer="m3", start=vector(0,clk_ypos), end=vector(self.width,clk_ypos)) for col in range(self.columns): clk_pin = self.dff_insts[0,col].get_pin("clk") # Make a vertical strip for each column - self.add_rect(layer="metal2", + self.add_rect(layer="m2", offset=clk_pin.ll().scale(1,0), width=self.m2_width, height=self.height) # Drop a via to the M3 pin - self.add_via_center(layers=("metal2","via2","metal3"), + self.add_via_center(layers=self.m2_stack, offset=vector(clk_pin.cx(),clk_ypos)) def get_clk_cin(self): diff --git a/compiler/modules/dff_buf.py b/compiler/modules/dff_buf.py index f6fc1cf2..9e2ff0aa 100644 --- a/compiler/modules/dff_buf.py +++ b/compiler/modules/dff_buf.py @@ -112,12 +112,12 @@ class dff_buf(design.design): mid_x_offset = 0.5*(a1_pin.cx() + q_pin.cx()) mid1 = vector(mid_x_offset, q_pin.cy()) mid2 = vector(mid_x_offset, a1_pin.cy()) - self.add_path("metal3", [q_pin.center(), mid1, mid2, a1_pin.center()]) - self.add_via_center(layers=("metal2","via2","metal3"), + self.add_path("m3", [q_pin.center(), mid1, mid2, a1_pin.center()]) + self.add_via_center(layers=self.m2_stack, offset=q_pin.center()) - self.add_via_center(layers=("metal2","via2","metal3"), + self.add_via_center(layers=self.m2_stack, offset=a1_pin.center()) - self.add_via_center(layers=("metal1","via1","metal2"), + self.add_via_center(layers=self.m1_stack, offset=a1_pin.center()) # Route inv1 z to inv2 a @@ -126,14 +126,14 @@ class dff_buf(design.design): mid_x_offset = 0.5*(z1_pin.cx() + a2_pin.cx()) self.mid_qb_pos = vector(mid_x_offset, z1_pin.cy()) mid2 = vector(mid_x_offset, a2_pin.cy()) - self.add_path("metal1", [z1_pin.center(), self.mid_qb_pos, mid2, a2_pin.center()]) + self.add_path("m1", [z1_pin.center(), self.mid_qb_pos, mid2, a2_pin.center()]) def add_layout_pins(self): # Continous vdd rail along with label. vdd_pin=self.dff_inst.get_pin("vdd") self.add_layout_pin(text="vdd", - layer="metal1", + layer="m1", offset=vdd_pin.ll(), width=self.width, height=vdd_pin.height()) @@ -141,7 +141,7 @@ class dff_buf(design.design): # Continous gnd rail along with label. gnd_pin=self.dff_inst.get_pin("gnd") self.add_layout_pin(text="gnd", - layer="metal1", + layer="m1", offset=gnd_pin.ll(), width=self.width, height=vdd_pin.height()) @@ -164,18 +164,18 @@ class dff_buf(design.design): mid_pos = dout_pin.center() + vector(self.m1_pitch,0) q_pos = mid_pos - vector(0,self.m2_pitch) self.add_layout_pin_rect_center(text="Q", - layer="metal2", + layer="m2", offset=q_pos) - self.add_path("metal1", [dout_pin.center(), mid_pos, q_pos]) - self.add_via_center(layers=("metal1","via1","metal2"), + self.add_path("m1", [dout_pin.center(), mid_pos, q_pos]) + self.add_via_center(layers=self.m1_stack, offset=q_pos) qb_pos = self.mid_qb_pos + vector(0,self.m2_pitch) self.add_layout_pin_rect_center(text="Qb", - layer="metal2", + layer="m2", offset=qb_pos) - self.add_path("metal1", [self.mid_qb_pos, qb_pos]) - self.add_via_center(layers=("metal1","via1","metal2"), + self.add_path("m1", [self.mid_qb_pos, qb_pos]) + self.add_via_center(layers=self.m1_stack, offset=qb_pos) def get_clk_cin(self): diff --git a/compiler/modules/dff_buf_array.py b/compiler/modules/dff_buf_array.py index 2fafee76..8b8e21dc 100644 --- a/compiler/modules/dff_buf_array.py +++ b/compiler/modules/dff_buf_array.py @@ -142,7 +142,7 @@ class dff_buf_array(design.design): for row in range(self.rows): for col in range(self.columns): din_pin = self.dff_insts[row,col].get_pin("D") - debug.check(din_pin.layer=="metal2","DFF D pin not on metal2") + debug.check(din_pin.layer=="m2","DFF D pin not on metal2") self.add_layout_pin(text=self.get_din_name(row,col), layer=din_pin.layer, offset=din_pin.ll(), @@ -150,7 +150,7 @@ class dff_buf_array(design.design): height=din_pin.height()) dout_pin = self.dff_insts[row,col].get_pin("Q") - debug.check(dout_pin.layer=="metal2","DFF Q pin not on metal2") + debug.check(dout_pin.layer=="m2","DFF Q pin not on metal2") self.add_layout_pin(text=self.get_dout_name(row,col), layer=dout_pin.layer, offset=dout_pin.ll(), @@ -158,7 +158,7 @@ class dff_buf_array(design.design): height=dout_pin.height()) dout_bar_pin = self.dff_insts[row,col].get_pin("Qb") - debug.check(dout_bar_pin.layer=="metal2","DFF Qb pin not on metal2") + debug.check(dout_bar_pin.layer=="m2","DFF Qb pin not on metal2") self.add_layout_pin(text=self.get_dout_bar_name(row,col), layer=dout_bar_pin.layer, offset=dout_bar_pin.ll(), @@ -169,28 +169,28 @@ class dff_buf_array(design.design): # Create vertical spines to a single horizontal rail clk_pin = self.dff_insts[0,0].get_pin("clk") clk_ypos = 2*self.m3_pitch+self.m3_width - debug.check(clk_pin.layer=="metal2","DFF clk pin not on metal2") + debug.check(clk_pin.layer=="m2","DFF clk pin not on metal2") if self.columns==1: self.add_layout_pin(text="clk", - layer="metal2", + layer="m2", offset=clk_pin.ll().scale(1,0), width=self.m2_width, height=self.height) else: self.add_layout_pin_segment_center(text="clk", - layer="metal3", + layer="m3", start=vector(0,clk_ypos), end=vector(self.width,clk_ypos)) for col in range(self.columns): clk_pin = self.dff_insts[0,col].get_pin("clk") # Make a vertical strip for each column - self.add_rect(layer="metal2", + self.add_rect(layer="m2", offset=clk_pin.ll().scale(1,0), width=self.m2_width, height=self.height) # Drop a via to the M3 pin - self.add_via_center(layers=("metal2","via2","metal3"), + self.add_via_center(layers=self.m2_stack, offset=vector(clk_pin.cx(),clk_ypos)) def get_clk_cin(self): diff --git a/compiler/modules/dff_inv.py b/compiler/modules/dff_inv.py index 207a5ad0..9dcb84c5 100644 --- a/compiler/modules/dff_inv.py +++ b/compiler/modules/dff_inv.py @@ -97,13 +97,13 @@ class dff_inv(design.design): mid_x_offset = 0.5*(a1_pin.cx() + q_pin.cx()) mid1 = vector(mid_x_offset, q_pin.cy()) mid2 = vector(mid_x_offset, a1_pin.cy()) - self.add_path("metal3", + self.add_path("m3", [q_pin.center(), mid1, mid2, a1_pin.center()]) - self.add_via_center(layers=("metal2","via2","metal3"), + self.add_via_center(layers=self.m2_stack, offset=q_pin.center()) - self.add_via_center(layers=("metal2","via2","metal3"), + self.add_via_center(layers=self.m2_stack, offset=a1_pin.center()) - self.add_via_center(layers=("metal1","via1","metal2"), + self.add_via_center(layers=self.m1_stack, offset=a1_pin.center()) @@ -112,7 +112,7 @@ class dff_inv(design.design): # Continous vdd rail along with label. vdd_pin=self.dff_inst.get_pin("vdd") self.add_layout_pin(text="vdd", - layer="metal1", + layer="m1", offset=vdd_pin.ll(), width=self.width, height=vdd_pin.height()) @@ -120,7 +120,7 @@ class dff_inv(design.design): # Continous gnd rail along with label. gnd_pin=self.dff_inst.get_pin("gnd") self.add_layout_pin(text="gnd", - layer="metal1", + layer="m1", offset=gnd_pin.ll(), width=self.width, height=vdd_pin.height()) @@ -146,9 +146,9 @@ class dff_inv(design.design): dout_pin = self.inv1_inst.get_pin("Z") self.add_layout_pin_rect_center(text="Qb", - layer="metal2", + layer="m2", offset=dout_pin.center()) - self.add_via_center(layers=("metal1","via1","metal2"), + self.add_via_center(layers=self.m1_stack, offset=dout_pin.center()) def get_clk_cin(self): diff --git a/compiler/modules/dff_inv_array.py b/compiler/modules/dff_inv_array.py index 760a2337..aadb4257 100644 --- a/compiler/modules/dff_inv_array.py +++ b/compiler/modules/dff_inv_array.py @@ -140,7 +140,7 @@ class dff_inv_array(design.design): for row in range(self.rows): for col in range(self.columns): din_pin = self.dff_insts[row,col].get_pin("D") - debug.check(din_pin.layer=="metal2","DFF D pin not on metal2") + debug.check(din_pin.layer=="m2","DFF D pin not on metal2") self.add_layout_pin(text=self.get_din_name(row,col), layer=din_pin.layer, offset=din_pin.ll(), @@ -148,7 +148,7 @@ class dff_inv_array(design.design): height=din_pin.height()) dout_pin = self.dff_insts[row,col].get_pin("Q") - debug.check(dout_pin.layer=="metal2","DFF Q pin not on metal2") + debug.check(dout_pin.layer=="m2","DFF Q pin not on metal2") self.add_layout_pin(text=self.get_dout_name(row,col), layer=dout_pin.layer, offset=dout_pin.ll(), @@ -156,7 +156,7 @@ class dff_inv_array(design.design): height=dout_pin.height()) dout_bar_pin = self.dff_insts[row,col].get_pin("Qb") - debug.check(dout_bar_pin.layer=="metal2","DFF Qb pin not on metal2") + debug.check(dout_bar_pin.layer=="m2","DFF Qb pin not on metal2") self.add_layout_pin(text=self.get_dout_bar_name(row,col), layer=dout_bar_pin.layer, offset=dout_bar_pin.ll(), @@ -167,27 +167,27 @@ class dff_inv_array(design.design): # Create vertical spines to a single horizontal rail clk_pin = self.dff_insts[0,0].get_pin("clk") clk_ypos = 2*self.m3_pitch+self.m3_width - debug.check(clk_pin.layer=="metal2","DFF clk pin not on metal2") + debug.check(clk_pin.layer=="m2","DFF clk pin not on metal2") if self.columns==1: self.add_layout_pin(text="clk", - layer="metal2", + layer="m2", offset=clk_pin.ll().scale(1,0), width=self.m2_width, height=self.height) else: self.add_layout_pin_segment_center(text="clk", - layer="metal3", + layer="m3", start=vector(0,clk_ypos), end=vector(self.width,clk_ypos)) for col in range(self.columns): clk_pin = self.dff_insts[0,col].get_pin("clk") # Make a vertical strip for each column - self.add_rect(layer="metal2", + self.add_rect(layer="m2", offset=clk_pin.ll().scale(1,0), width=self.m2_width, height=self.height) # Drop a via to the M3 pin - self.add_via_center(layers=("metal2","via2","metal3"), + self.add_via_center(layers=self.m2_stack, offset=vector(clk_pin.cx(),clk_ypos)) def get_clk_cin(self): diff --git a/compiler/modules/dummy_array.py b/compiler/modules/dummy_array.py index f1f433ce..1e5a2121 100644 --- a/compiler/modules/dummy_array.py +++ b/compiler/modules/dummy_array.py @@ -122,7 +122,7 @@ class dummy_array(design.design): for cell_column in column_list: bl_pin = self.cell_inst[0,col].get_pin(cell_column) self.add_layout_pin(text=cell_column+"_{0}".format(col), - layer="metal2", + layer="m2", offset=bl_pin.ll(), width=bl_pin.width(), height=self.height) @@ -131,7 +131,7 @@ class dummy_array(design.design): for cell_row in row_list: wl_pin = self.cell_inst[row,0].get_pin(cell_row) self.add_layout_pin(text=cell_row+"_{0}".format(row), - layer="metal1", + layer="m1", offset=wl_pin.ll(), width=self.width, height=wl_pin.height()) diff --git a/compiler/modules/hierarchical_decoder.py b/compiler/modules/hierarchical_decoder.py index 9c7cafd8..bb637ed1 100644 --- a/compiler/modules/hierarchical_decoder.py +++ b/compiler/modules/hierarchical_decoder.py @@ -173,7 +173,7 @@ class hierarchical_decoder(design.design): input_offset=vector(min_x - self.input_routing_width,0) input_bus_names = ["addr_{0}".format(i) for i in range(self.num_inputs)] - self.input_rails = self.create_vertical_pin_bus(layer="metal2", + self.input_rails = self.create_vertical_pin_bus(layer="m2", pitch=self.m2_pitch, offset=input_offset, names=input_bus_names, @@ -225,7 +225,7 @@ class hierarchical_decoder(design.design): offset=input_offset) self.add_via_center(layers=self.m2_stack, offset=output_offset) - self.add_path(("metal3"), [input_offset, output_offset]) + self.add_path(("m3"), [input_offset, output_offset]) def add_pins(self): @@ -467,11 +467,11 @@ class hierarchical_decoder(design.design): # ensure the bend is in the middle mid1_pos = vector(0.5*(zr_pos.x+al_pos.x), zr_pos.y) mid2_pos = vector(0.5*(zr_pos.x+al_pos.x), al_pos.y) - self.add_path("metal1", [zr_pos, mid1_pos, mid2_pos, al_pos]) + self.add_path("m1", [zr_pos, mid1_pos, mid2_pos, al_pos]) z_pin = self.inv_inst[row].get_pin("Z") self.add_layout_pin(text="decode_{0}".format(row), - layer="metal1", + layer="m1", offset=z_pin.ll(), width=z_pin.width(), height=z_pin.height()) @@ -485,7 +485,7 @@ class hierarchical_decoder(design.design): if (self.num_inputs >= 4): input_offset = vector(0.5*self.m2_width,0) input_bus_names = ["predecode_{0}".format(i) for i in range(self.total_number_of_predecoder_outputs)] - self.predecode_rails = self.create_vertical_pin_bus(layer="metal2", + self.predecode_rails = self.create_vertical_pin_bus(layer="m2", pitch=self.m2_pitch, offset=input_offset, names=input_bus_names, @@ -570,7 +570,7 @@ class hierarchical_decoder(design.design): start = self.nand_inst[num].get_pin(pin_name).lc() end = self.inv_inst[num].get_pin(pin_name).rc() mid = (start+end).scale(0.5,0.5) - self.add_rect_center(layer="metal1", + self.add_rect_center(layer="m1", offset=mid, width=end.x-start.x) @@ -584,7 +584,7 @@ class hierarchical_decoder(design.design): def route_predecode_rail(self, rail_name, pin): """ Connect the routing rail to the given metal1 pin """ rail_pos = vector(self.predecode_rails[rail_name].x,pin.lc().y) - self.add_path("metal1", [rail_pos, pin.lc()]) + self.add_path("m1", [rail_pos, pin.lc()]) self.add_via_center(layers=self.m1_stack, offset=rail_pos) @@ -597,7 +597,7 @@ class hierarchical_decoder(design.design): rail_pos = vector(self.predecode_rails[rail_name].x,mid_point.y) self.add_via_center(layers=self.m1_stack, offset=pin.center()) - self.add_wire(("metal3","via2","metal2"), [rail_pos, mid_point, pin.uc()]) + self.add_wire(("m3","via2","m2"), [rail_pos, mid_point, pin.uc()]) self.add_via_center(layers=self.m2_stack, offset=rail_pos) diff --git a/compiler/modules/hierarchical_predecode.py b/compiler/modules/hierarchical_predecode.py index 0de67cae..dec04073 100644 --- a/compiler/modules/hierarchical_predecode.py +++ b/compiler/modules/hierarchical_predecode.py @@ -73,7 +73,7 @@ class hierarchical_predecode(design.design): """ Create all of the rails for the inputs and vdd/gnd/inputs_bar/inputs """ input_names = ["in_{}".format(x) for x in range(self.number_of_inputs)] offset = vector(0.5*self.m2_width,2*self.m1_width) - self.input_rails = self.create_vertical_pin_bus(layer="metal2", + self.input_rails = self.create_vertical_pin_bus(layer="m2", pitch=self.m2_pitch, offset=offset, names=input_names, @@ -83,7 +83,7 @@ class hierarchical_predecode(design.design): non_invert_names = ["A_{}".format(x) for x in range(self.number_of_inputs)] decode_names = invert_names + non_invert_names offset = vector(self.x_off_inv_1 + self.inv.width + 2*self.m2_pitch, 2*self.m1_width) - self.decode_rails = self.create_vertical_bus(layer="metal2", + self.decode_rails = self.create_vertical_bus(layer="m2", pitch=self.m2_pitch, offset=offset, names=decode_names, @@ -183,7 +183,7 @@ class hierarchical_predecode(design.design): a_pin = "A_{}".format(num) in_pos = vector(self.input_rails[in_pin].x,y_offset) a_pos = vector(self.decode_rails[a_pin].x,y_offset) - self.add_path("metal1",[in_pos, a_pos]) + self.add_path("m1",[in_pos, a_pos]) self.add_via_center(layers = self.m1_stack, offset=[self.input_rails[in_pin].x, y_offset]) self.add_via_center(layers = self.m1_stack, @@ -201,11 +201,11 @@ class hierarchical_predecode(design.design): # ensure the bend is in the middle mid1_pos = vector(0.5*(zr_pos.x+al_pos.x), zr_pos.y) mid2_pos = vector(0.5*(zr_pos.x+al_pos.x), al_pos.y) - self.add_path("metal1", [zr_pos, mid1_pos, mid2_pos, al_pos]) + self.add_path("m1", [zr_pos, mid1_pos, mid2_pos, al_pos]) z_pin = self.inv_inst[num].get_pin("Z") self.add_layout_pin(text="out_{}".format(num), - layer="metal1", + layer="m1", offset=z_pin.ll(), height=z_pin.height(), width=z_pin.width()) @@ -226,7 +226,7 @@ class hierarchical_predecode(design.design): inv_out_pos = self.in_inst[inv_num].get_pin("Z").rc() right_pos = inv_out_pos + vector(self.inv.width - self.inv.get_pin("Z").lx(),0) rail_pos = vector(self.decode_rails[out_pin].x,y_offset) - self.add_path("metal1", [inv_out_pos, right_pos, vector(right_pos.x, y_offset), rail_pos]) + self.add_path("m1", [inv_out_pos, right_pos, vector(right_pos.x, y_offset), rail_pos]) self.add_via_center(layers = self.m1_stack, offset=rail_pos) @@ -234,7 +234,7 @@ class hierarchical_predecode(design.design): #route input inv_in_pos = self.in_inst[inv_num].get_pin("A").lc() in_pos = vector(self.input_rails[in_pin].x,inv_in_pos.y) - self.add_path("metal1", [in_pos, inv_in_pos]) + self.add_path("m1", [in_pos, inv_in_pos]) self.add_via_center(layers=self.m1_stack, offset=in_pos) @@ -255,7 +255,7 @@ class hierarchical_predecode(design.design): for rail_pin,gate_pin in zip(index_lst,gate_lst): pin_pos = self.nand_inst[k].get_pin(gate_pin).lc() rail_pos = vector(self.decode_rails[rail_pin].x, pin_pos.y) - self.add_path("metal1", [rail_pos, pin_pos]) + self.add_path("m1", [rail_pos, pin_pos]) self.add_via_center(layers=self.m1_stack, offset=rail_pos) @@ -275,7 +275,7 @@ class hierarchical_predecode(design.design): for n in ["vdd", "gnd"]: nand_pin = self.nand_inst[num].get_pin(n) supply_offset = nand_pin.ll().scale(0,1) - self.add_rect(layer="metal1", + self.add_rect(layer="m1", offset=supply_offset, width=self.inv_inst[num].rx()) diff --git a/compiler/modules/multibank.py b/compiler/modules/multibank.py index 3459f5e0..33076bfb 100644 --- a/compiler/modules/multibank.py +++ b/compiler/modules/multibank.py @@ -160,7 +160,7 @@ class multibank(design.design): self.central_bus_width = self.m2_pitch * self.num_control_lines + 2*self.m2_width # A space for wells or jogging m2 - self.m2_gap = max(2*drc("pwell_to_nwell"] + drc["well_enclosure_active"), + self.m2_gap = max(2*drc("pwell_to_nwell"] + drc["well_enclose_active"), 2*self.m2_pitch) @@ -451,7 +451,7 @@ class multibank(design.design): # Connect the inverter output to the central bus out_pos = self.bank_select_inst.get_pin(gated_name).rc() bus_pos = vector(self.bus_xoffset[gated_name], out_pos.y) - self.add_path("metal3",[out_pos, bus_pos]) + self.add_path("m3",[out_pos, bus_pos]) self.add_via_center(layers=self.m2_stack, offset=bus_pos, rotate=90) @@ -512,7 +512,7 @@ class multibank(design.design): # 2 pitches on the right for vias/jogs to access the inputs control_bus_offset = vector(-self.m2_pitch * self.num_control_lines - self.m2_width, 0) control_bus_length = self.bitcell_array_inst.uy() - self.bus_xoffset = self.create_vertical_bus(layer="metal2", + self.bus_xoffset = self.create_vertical_bus(layer="m2", pitch=self.m2_pitch, offset=control_bus_offset, names=self.control_signals, @@ -530,9 +530,9 @@ class multibank(design.design): bitcell_br = self.bitcell_array_inst.get_pin("br_{}".format(i)).uc() yoffset = 0.5*(precharge_bl.y+bitcell_bl.y) - self.add_path("metal2",[precharge_bl, vector(precharge_bl.x,yoffset), + self.add_path("m2",[precharge_bl, vector(precharge_bl.x,yoffset), vector(bitcell_bl.x,yoffset), bitcell_bl]) - self.add_path("metal2",[precharge_br, vector(precharge_br.x,yoffset), + self.add_path("m2",[precharge_br, vector(precharge_br.x,yoffset), vector(bitcell_br.x,yoffset), bitcell_br]) @@ -550,9 +550,9 @@ class multibank(design.design): bitcell_br = self.bitcell_array_inst.get_pin("br_{}".format(i)).bc() yoffset = 0.5*(col_mux_bl.y+bitcell_bl.y) - self.add_path("metal2",[col_mux_bl, vector(col_mux_bl.x,yoffset), + self.add_path("m2",[col_mux_bl, vector(col_mux_bl.x,yoffset), vector(bitcell_bl.x,yoffset), bitcell_bl]) - self.add_path("metal2",[col_mux_br, vector(col_mux_br.x,yoffset), + self.add_path("m2",[col_mux_br, vector(col_mux_br.x,yoffset), vector(bitcell_br.x,yoffset), bitcell_br]) def route_sense_amp_to_col_mux_or_bitcell_array(self): @@ -573,9 +573,9 @@ class multibank(design.design): yoffset = 0.5*(sense_amp_bl.y+connect_bl.y) - self.add_path("metal2",[sense_amp_bl, vector(sense_amp_bl.x,yoffset), + self.add_path("m2",[sense_amp_bl, vector(sense_amp_bl.x,yoffset), vector(connect_bl.x,yoffset), connect_bl]) - self.add_path("metal2",[sense_amp_br, vector(sense_amp_br.x,yoffset), + self.add_path("m2",[sense_amp_br, vector(sense_amp_br.x,yoffset), vector(connect_br.x,yoffset), connect_br]) def route_sense_amp_to_trigate(self): @@ -590,7 +590,7 @@ class multibank(design.design): offset=tri_gate_in) self.add_via_center(layers=self.m2_stack, offset=sa_data_out) - self.add_path("metal3",[sa_data_out,tri_gate_in]) + self.add_path("m3",[sa_data_out,tri_gate_in]) def route_sense_amp_out(self): """ Add pins for the sense amp output """ @@ -644,14 +644,14 @@ class multibank(design.design): driver_in_pos = self.wordline_driver_inst.get_pin("in_{}".format(i)).lc() mid1 = decoder_out_pos.scale(0.5,1)+driver_in_pos.scale(0.5,0) mid2 = decoder_out_pos.scale(0.5,0)+driver_in_pos.scale(0.5,1) - self.add_path("metal1", [decoder_out_pos, mid1, mid2, driver_in_pos]) + self.add_path("m1", [decoder_out_pos, mid1, mid2, driver_in_pos]) # The mid guarantees we exit the input cell to the right. driver_wl_pos = self.wordline_driver_inst.get_pin("wl_{}".format(i)).rc() bitcell_wl_pos = self.bitcell_array_inst.get_pin("wl_{}".format(i)).lc() mid1 = driver_wl_pos.scale(0.5,1)+bitcell_wl_pos.scale(0.5,0) mid2 = driver_wl_pos.scale(0.5,0)+bitcell_wl_pos.scale(0.5,1) - self.add_path("metal1", [driver_wl_pos, mid1, mid2, bitcell_wl_pos]) + self.add_path("m1", [driver_wl_pos, mid1, mid2, bitcell_wl_pos]) @@ -698,8 +698,8 @@ class multibank(design.design): else: mid1_pos = vector(decode_out_pos.x + delta_offset + (self.num_col_addr_lines-i)*self.m2_pitch,decode_out_pos.y) mid2_pos = vector(mid1_pos.x,mux_addr_pos.y) - #self.add_wire(("metal1","via1","metal2"),[decode_out_pos, mid1_pos, mid2_pos, mux_addr_pos]) - self.add_path("metal1",[decode_out_pos, mid1_pos, mid2_pos, mux_addr_pos]) + #self.add_wire(self.m1_stack,[decode_out_pos, mid1_pos, mid2_pos, mux_addr_pos]) + self.add_path("m1",[decode_out_pos, mid1_pos, mid2_pos, mux_addr_pos]) @@ -715,7 +715,7 @@ class multibank(design.design): wl_name = "wl_{}".format(i) wl_pin = self.bitcell_array_inst.get_pin(wl_name) self.add_label(text=wl_name, - layer="metal1", + layer="m1", offset=wl_pin.center()) # Add the bitline names @@ -725,10 +725,10 @@ class multibank(design.design): bl_pin = self.bitcell_array_inst.get_pin(bl_name) br_pin = self.bitcell_array_inst.get_pin(br_name) self.add_label(text=bl_name, - layer="metal2", + layer="m2", offset=bl_pin.center()) self.add_label(text=br_name, - layer="metal2", + layer="m2", offset=br_pin.center()) # # Add the data output names to the sense amp output @@ -736,7 +736,7 @@ class multibank(design.design): # data_name = "data_{}".format(i) # data_pin = self.sense_amp_array_inst.get_pin(data_name) # self.add_label(text="sa_out_{}".format(i), - # layer="metal2", + # layer="m2", # offset=data_pin.center()) # Add labels on the decoder @@ -745,7 +745,7 @@ class multibank(design.design): pin_name = "in_{}".format(i) data_pin = self.wordline_driver_inst.get_pin(pin_name) self.add_label(text=data_name, - layer="metal1", + layer="m1", offset=data_pin.center()) @@ -765,7 +765,7 @@ class multibank(design.design): for (control_signal, pin_pos) in connection: control_pos = vector(self.bus_xoffset[control_signal].x ,pin_pos.y) - self.add_path("metal1", [control_pos, pin_pos]) + self.add_path("m1", [control_pos, pin_pos]) self.add_via_center(layers=self.m1_stack, offset=control_pos, rotate=90) @@ -776,7 +776,7 @@ class multibank(design.design): mid_pos = pin_pos + vector(0,self.m1_pitch) control_x_offset = self.bus_xoffset[control_signal].x control_pos = vector(control_x_offset + self.m1_width, mid_pos.y) - self.add_wire(("metal1","via1","metal2"),[pin_pos, mid_pos, control_pos]) + self.add_wire(self.m1_stack,[pin_pos, mid_pos, control_pos]) control_via_pos = vector(control_x_offset, mid_pos.y) self.add_via_center(layers=self.m1_stack, offset=control_via_pos, @@ -791,13 +791,13 @@ class multibank(design.design): if self.num_banks > 1: # it's not an input pin if we have multiple banks self.add_label_pin(text=ctrl, - layer="metal2", + layer="m2", offset=vector(x_offset, self.min_y_offset), width=self.m2_width, height=self.max_y_offset-self.min_y_offset) else: self.add_layout_pin(text=ctrl, - layer="metal2", + layer="m2", offset=vector(x_offset, self.min_y_offset), width=self.m2_width, height=self.max_y_offset-self.min_y_offset) @@ -807,12 +807,12 @@ class multibank(design.design): """ Helper routine to connect an unrotated/mirrored oriented instance to the rails """ in_pin = inst.get_pin(pin).lc() rail_pos = vector(self.rail_1_x_offsets[rail], in_pin.y) - self.add_wire(("metal3","via2","metal2"),[in_pin, rail_pos, rail_pos - vector(0,self.m2_pitch)]) + self.add_wire(("m3","via2","m2"),[in_pin, rail_pos, rail_pos - vector(0,self.m2_pitch)]) # Bring it up to M2 for M2/M3 routing - self.add_via(layers=("metal1","via1","metal2"), + self.add_via(layers=self.m1_stack, offset=in_pin + contact.m1m2.offset, rotate=90) - self.add_via(layers=("metal2","via2","metal3"), + self.add_via(layers=self.m2_stack, offset=in_pin + self.m2m3_via_offset, rotate=90) @@ -821,10 +821,10 @@ class multibank(design.design): """ Helper routine to connect an unrotated/mirrored oriented instance to the rails """ in_pin = inst.get_pin(pin).rc() rail_pos = vector(self.rail_1_x_offsets[rail], in_pin.y) - self.add_wire(("metal3","via2","metal2"),[in_pin, rail_pos, rail_pos - vector(0,self.m2_pitch)]) - self.add_via(layers=("metal1","via1","metal2"), + self.add_wire(("m3","via2","m2"),[in_pin, rail_pos, rail_pos - vector(0,self.m2_pitch)]) + self.add_via(layers=self.m1_stack, offset=in_pin + contact.m1m2.offset, rotate=90) - self.add_via(layers=("metal2","via2","metal3"), + self.add_via(layers=self.m2_stack, offset=in_pin + self.m2m3_via_offset, rotate=90) diff --git a/compiler/modules/port_address.py b/compiler/modules/port_address.py index 0a624c60..7f1fdd49 100644 --- a/compiler/modules/port_address.py +++ b/compiler/modules/port_address.py @@ -92,7 +92,7 @@ class port_address(design.design): driver_in_pos = self.wordline_driver_inst.get_pin("in_{}".format(row)).lc() mid1 = decoder_out_pos.scale(0.5,1)+driver_in_pos.scale(0.5,0) mid2 = decoder_out_pos.scale(0.5,0)+driver_in_pos.scale(0.5,1) - self.add_path("metal1", [decoder_out_pos, mid1, mid2, driver_in_pos]) + self.add_path("m1", [decoder_out_pos, mid1, mid2, driver_in_pos]) @@ -149,7 +149,7 @@ class port_address(design.design): """ # A space for wells or jogging m2 - self.m2_gap = max(2*drc("pwell_to_nwell") + drc("well_enclosure_active"), + self.m2_gap = max(2*drc("pwell_to_nwell") + drc("well_enclose_active"), 3*self.m2_pitch) row_decoder_offset = vector(0,0) diff --git a/compiler/modules/port_data.py b/compiler/modules/port_data.py index a5bc4399..33ecdd01 100644 --- a/compiler/modules/port_data.py +++ b/compiler/modules/port_data.py @@ -212,7 +212,7 @@ class port_data(design.design): # A space for wells or jogging m2 between modules - self.m2_gap = max(2*drc("pwell_to_nwell") + drc("well_enclosure_active"), + self.m2_gap = max(2*drc("pwell_to_nwell") + drc("well_enclose_active"), 3*self.m2_pitch) @@ -479,7 +479,7 @@ class port_data(design.design): offset=end_pos) # Route between write mask AND array and write driver array - self.add_wire(("metal1","via1","metal2"), [beg_pos, middle_pos, end_pos]) + self.add_wire(self.m1_stack, [beg_pos, middle_pos, end_pos]) def route_column_mux_to_precharge_array(self, port): @@ -655,9 +655,9 @@ class port_data(design.design): top_br = top_inst.get_pin(top_br_name.format(col+top_start_bit)).bc() yoffset = 0.5*(top_bl.y+bottom_bl.y) - self.add_path("metal2",[bottom_bl, vector(bottom_bl.x,yoffset), + self.add_path("m2",[bottom_bl, vector(bottom_bl.x,yoffset), vector(top_bl.x,yoffset), top_bl]) - self.add_path("metal2",[bottom_br, vector(bottom_br.x,yoffset), + self.add_path("m2",[bottom_br, vector(bottom_br.x,yoffset), vector(top_br.x,yoffset), top_br]) def graph_exclude_precharge(self): diff --git a/compiler/modules/precharge_array.py b/compiler/modules/precharge_array.py index 2d98ba14..c2617f50 100644 --- a/compiler/modules/precharge_array.py +++ b/compiler/modules/precharge_array.py @@ -68,10 +68,10 @@ class precharge_array(design.design): def add_layout_pins(self): self.add_layout_pin(text="en_bar", - layer="metal1", + layer="m1", offset=self.pc_cell.get_pin("en_bar").ll(), width=self.width, - height=drc("minwidth_metal1")) + height=drc("minwidth_m1")) for inst in self.local_insts: self.copy_layout_pin(inst, "vdd") @@ -80,15 +80,15 @@ class precharge_array(design.design): inst = self.local_insts[i] bl_pin = inst.get_pin("bl") self.add_layout_pin(text="bl_{0}".format(i), - layer="metal2", + layer="m2", offset=bl_pin.ll(), - width=drc("minwidth_metal2"), + width=drc("minwidth_m2"), height=bl_pin.height()) br_pin = inst.get_pin("br") self.add_layout_pin(text="br_{0}".format(i), - layer="metal2", + layer="m2", offset=br_pin.ll(), - width=drc("minwidth_metal2"), + width=drc("minwidth_m2"), height=bl_pin.height()) diff --git a/compiler/modules/replica_bitcell_array.py b/compiler/modules/replica_bitcell_array.py index 639d0714..74962ba2 100644 --- a/compiler/modules/replica_bitcell_array.py +++ b/compiler/modules/replica_bitcell_array.py @@ -399,7 +399,7 @@ class replica_bitcell_array(design.design): else: height = self.height bl_pos = 0 - bl_wire = self.generate_rc_net(int(self.row_size-bl_pos), height, drc("minwidth_metal1")) + bl_wire = self.generate_rc_net(int(self.row_size-bl_pos), height, drc("minwidth_m1")) bl_wire.wire_c =spice["min_tx_drain_c"] + bl_wire.wire_c # 1 access tx d/s per cell return bl_wire diff --git a/compiler/modules/replica_column.py b/compiler/modules/replica_column.py index c3f63b19..5552ed55 100644 --- a/compiler/modules/replica_column.py +++ b/compiler/modules/replica_column.py @@ -116,7 +116,7 @@ class replica_column(design.design): for bl_name in self.cell.get_all_bitline_names(): bl_pin = self.cell_inst[0].get_pin(bl_name) self.add_layout_pin(text=bl_name, - layer="metal2", + layer="m2", offset=bl_pin.ll(), width=bl_pin.width(), height=self.height) @@ -125,7 +125,7 @@ class replica_column(design.design): for wl_name in self.cell.get_all_wl_names(): wl_pin = self.cell_inst[row].get_pin(wl_name) self.add_layout_pin(text="{0}_{1}".format(wl_name,row), - layer="metal1", + layer="m1", offset=wl_pin.ll().scale(0,1), width=self.width, height=wl_pin.height()) diff --git a/compiler/modules/sense_amp_array.py b/compiler/modules/sense_amp_array.py index 21ee4a8d..2447e4b8 100644 --- a/compiler/modules/sense_amp_array.py +++ b/compiler/modules/sense_amp_array.py @@ -102,13 +102,13 @@ class sense_amp_array(design.design): self.add_via_center(layers=self.m2_stack, offset=gnd_pos) self.add_layout_pin_rect_center(text="gnd", - layer="metal3", + layer="m3", offset=gnd_pos) vdd_pos = inst.get_pin("vdd").center() self.add_via_center(layers=self.m2_stack, offset=vdd_pos) self.add_layout_pin_rect_center(text="vdd", - layer="metal3", + layer="m3", offset=vdd_pos) bl_pin = inst.get_pin("bl") @@ -116,18 +116,18 @@ class sense_amp_array(design.design): dout_pin = inst.get_pin("dout") self.add_layout_pin(text="bl_{0}".format(i), - layer="metal2", + layer="m2", offset=bl_pin.ll(), width=bl_pin.width(), height=bl_pin.height()) self.add_layout_pin(text="br_{0}".format(i), - layer="metal2", + layer="m2", offset=br_pin.ll(), width=br_pin.width(), height=br_pin.height()) self.add_layout_pin(text="data_{0}".format(i), - layer="metal2", + layer="m2", offset=dout_pin.ll(), width=dout_pin.width(), height=dout_pin.height()) @@ -137,10 +137,10 @@ class sense_amp_array(design.design): # add sclk rail across entire array sclk_offset = self.amp.get_pin("en").ll().scale(0,1) self.add_layout_pin(text="en", - layer="metal1", + layer="m1", offset=sclk_offset, width=self.width, - height=drc("minwidth_metal1")) + height=drc("minwidth_m1")) def input_load(self): return self.amp.input_load() diff --git a/compiler/modules/single_level_column_mux_array.py b/compiler/modules/single_level_column_mux_array.py index 3e6420b9..09f21cfa 100644 --- a/compiler/modules/single_level_column_mux_array.py +++ b/compiler/modules/single_level_column_mux_array.py @@ -113,13 +113,13 @@ class single_level_column_mux_array(design.design): mux_inst = self.mux_inst[col_num] offset = mux_inst.get_pin("bl").ll() self.add_layout_pin(text="bl_{}".format(col_num), - layer="metal2", + layer="m2", offset=offset, height=self.height-offset.y) offset = mux_inst.get_pin("br").ll() self.add_layout_pin(text="br_{}".format(col_num), - layer="metal2", + layer="m2", offset=offset, height=self.height-offset.y) @@ -137,7 +137,7 @@ class single_level_column_mux_array(design.design): for j in range(self.words_per_row): offset = vector(0, self.route_height + (j-self.words_per_row)*self.m1_pitch) self.add_layout_pin(text="sel_{}".format(j), - layer="metal1", + layer="m1", offset=offset, width=self.mux.width * self.columns) @@ -155,7 +155,7 @@ class single_level_column_mux_array(design.design): # use the y offset from the sel pin and the x offset from the gate offset = vector(gate_offset.x,self.get_pin("sel_{}".format(sel_index)).cy()) # Add the poly contact with a shift to account for the rotation - self.add_via_center(layers=("metal1", "contact", "poly"), + self.add_via_center(layers=("m1", "contact", "poly"), offset=offset) self.add_path("poly", [offset, gate_offset]) @@ -176,16 +176,16 @@ class single_level_column_mux_array(design.design): # These will be located below the select lines. Yes, these are M2 width # to ensure vias are enclosed and M1 min width rules. width = self.m2_width + self.mux.width * (self.words_per_row - 1) - self.add_path("metal1", [bl_out_offset, bl_out_offset+vector(width,0)]) - self.add_path("metal1", [br_out_offset, br_out_offset+vector(width,0)]) + self.add_path("m1", [bl_out_offset, bl_out_offset+vector(width,0)]) + self.add_path("m1", [br_out_offset, br_out_offset+vector(width,0)]) # Extend the bitline output rails and gnd downward on the first bit of each n-way mux self.add_layout_pin_segment_center(text="bl_out_{}".format(int(j/self.words_per_row)), - layer="metal2", + layer="m2", start=bl_out_offset, end=bl_out_offset_end) self.add_layout_pin_segment_center(text="br_out_{}".format(int(j/self.words_per_row)), - layer="metal2", + layer="m2", start=br_out_offset, end=br_out_offset_end) @@ -200,8 +200,8 @@ class single_level_column_mux_array(design.design): else: - self.add_path("metal2", [ bl_out_offset, bl_out_offset_end]) - self.add_path("metal2", [ br_out_offset, br_out_offset_end]) + self.add_path("m2", [ bl_out_offset, bl_out_offset_end]) + self.add_path("m2", [ br_out_offset, br_out_offset_end]) # This via is on the right of the wire self.add_via_center(layers=self.m1_stack, diff --git a/compiler/modules/tri_gate_array.py b/compiler/modules/tri_gate_array.py index 501e2389..e7ebd802 100644 --- a/compiler/modules/tri_gate_array.py +++ b/compiler/modules/tri_gate_array.py @@ -83,14 +83,14 @@ class tri_gate_array(design.design): in_pin = self.tri_inst[i].get_pin("in") self.add_layout_pin(text="in_{0}".format(index), - layer="metal2", + layer="m2", offset=in_pin.ll(), width=in_pin.width(), height=in_pin.height()) out_pin = self.tri_inst[i].get_pin("out") self.add_layout_pin(text="out_{0}".format(index), - layer="metal2", + layer="m2", offset=out_pin.ll(), width=out_pin.width(), height=out_pin.height()) @@ -103,21 +103,21 @@ class tri_gate_array(design.design): self.add_via_center(layers=self.m2_stack, offset=pin_pos) self.add_layout_pin_rect_center(text=n, - layer="metal3", + layer="m3", offset=pin_pos) width = self.tri.width * self.columns - (self.words_per_row - 1) * self.tri.width en_pin = self.tri_inst[0].get_pin("en") self.add_layout_pin(text="en", - layer="metal1", + layer="m1", offset=en_pin.ll().scale(0, 1), width=width, - height=drc("minwidth_metal1")) + height=drc("minwidth_m1")) enbar_pin = self.tri_inst[0].get_pin("en_bar") self.add_layout_pin(text="en_bar", - layer="metal1", + layer="m1", offset=enbar_pin.ll().scale(0, 1), width=width, - height=drc("minwidth_metal1")) \ No newline at end of file + height=drc("minwidth_m1")) \ No newline at end of file diff --git a/compiler/modules/wordline_driver.py b/compiler/modules/wordline_driver.py index 99365659..2af2c8c9 100644 --- a/compiler/modules/wordline_driver.py +++ b/compiler/modules/wordline_driver.py @@ -142,7 +142,7 @@ class wordline_driver(design.design): # Wordline enable connection en_offset = [self.m1_width + 2 * self.m1_space, 0] en_pin = self.add_layout_pin(text="en", - layer="metal2", + layer="m2", offset=en_offset, width=self.m2_width, height=self.height) @@ -155,7 +155,7 @@ class wordline_driver(design.design): a_pin = nand_inst.get_pin("A") a_pos = a_pin.lc() clk_offset = vector(en_pin.bc().x, a_pos.y) - self.add_segment_center(layer="metal1", + self.add_segment_center(layer="m1", start=clk_offset, end=a_pos) self.add_via_center(layers=self.m1_stack, @@ -167,7 +167,7 @@ class wordline_driver(design.design): # ensure the bend is in the middle mid1_pos = vector(0.5*(zr_pos.x+al_pos.x), zr_pos.y) mid2_pos = vector(0.5*(zr_pos.x+al_pos.x), al_pos.y) - self.add_path("metal1", [zr_pos, mid1_pos, mid2_pos, al_pos]) + self.add_path("m1", [zr_pos, mid1_pos, mid2_pos, al_pos]) # connect the decoder input pin to nand2 B b_pin = nand_inst.get_pin("B") @@ -182,7 +182,7 @@ class wordline_driver(design.design): # must under the clk line in M1 self.add_layout_pin_segment_center(text="in_{0}".format(row), - layer="metal1", + layer="m1", start=input_offset, end=mid_via_offset) self.add_via_center(layers=self.m1_stack, @@ -190,7 +190,7 @@ class wordline_driver(design.design): directions=("V", "V")) # now connect to the nand2 B - self.add_path("metal2", [mid_via_offset, b_pos]) + self.add_path("m2", [mid_via_offset, b_pos]) contact_offset = b_pos - vector(0.5 * contact.m1m2.height, 0) self.add_via_center(layers=self.m1_stack, offset=contact_offset, @@ -199,7 +199,7 @@ class wordline_driver(design.design): # output each WL on the right wl_offset = inv2_inst.get_pin("Z").rc() self.add_layout_pin_segment_center(text="wl_{0}".format(row), - layer="metal1", + layer="m1", start=wl_offset, end=wl_offset - vector(self.m1_width, 0)) diff --git a/compiler/modules/write_driver_array.py b/compiler/modules/write_driver_array.py index 4dfa938c..ac4dab00 100644 --- a/compiler/modules/write_driver_array.py +++ b/compiler/modules/write_driver_array.py @@ -120,20 +120,20 @@ class write_driver_array(design.design): for i in range(self.word_size): din_pin = self.driver_insts[i].get_pin("din") self.add_layout_pin(text="data_{0}".format(i), - layer="metal2", + layer="m2", offset=din_pin.ll(), width=din_pin.width(), height=din_pin.height()) bl_pin = self.driver_insts[i].get_pin("bl") self.add_layout_pin(text="bl_{0}".format(i), - layer="metal2", + layer="m2", offset=bl_pin.ll(), width=bl_pin.width(), height=bl_pin.height()) br_pin = self.driver_insts[i].get_pin("br") self.add_layout_pin(text="br_{0}".format(i), - layer="metal2", + layer="m2", offset=br_pin.ll(), width=br_pin.width(), height=br_pin.height()) @@ -146,7 +146,7 @@ class write_driver_array(design.design): self.add_via_center(layers=self.m2_stack, offset=pin_pos) self.add_layout_pin_rect_center(text=n, - layer="metal3", + layer="m3", offset=pin_pos) if self.write_size: for bit in range(self.num_wmasks): @@ -165,7 +165,7 @@ class write_driver_array(design.design): height=en_pin.height()) else: self.add_layout_pin(text="en", - layer="metal1", + layer="m1", offset=self.driver_insts[0].get_pin("en").ll().scale(0,1), width=self.width) diff --git a/compiler/modules/write_mask_and_array.py b/compiler/modules/write_mask_and_array.py index 3a4ec651..40f386d2 100644 --- a/compiler/modules/write_mask_and_array.py +++ b/compiler/modules/write_mask_and_array.py @@ -114,7 +114,7 @@ class write_mask_and_array(design.design): # Extend metal3 to edge of AND array in multiport en_to_edge = self.and2.width - beg_en_pin.cx() self.add_layout_pin(text="en", - layer="metal3", + layer="m3", offset=beg_en_pin.bc(), width=end_en_pin.cx() - beg_en_pin.cx() + en_to_edge) self.add_via_center(layers=self.m1_stack, @@ -123,7 +123,7 @@ class write_mask_and_array(design.design): offset=vector(end_en_pin.cx() + en_to_edge, end_en_pin.cy())) else: self.add_layout_pin(text="en", - layer="metal3", + layer="m3", offset=beg_en_pin.bc(), width=end_en_pin.cx() - beg_en_pin.cx()) @@ -146,7 +146,7 @@ class write_mask_and_array(design.design): for n in ["gnd","vdd"]: pin = self.and2_insts[i].get_pin(n) next_pin = self.and2_insts[i+1].get_pin(n) - self.add_path("metal1",[pin.center(),next_pin.center()]) + self.add_path("m1",[pin.center(),next_pin.center()]) def get_cin(self): """Get the relative capacitance of all the input connections in the bank""" diff --git a/compiler/pgates/pand2.py b/compiler/pgates/pand2.py index d410a8c7..23fd5e5b 100644 --- a/compiler/pgates/pand2.py +++ b/compiler/pgates/pand2.py @@ -76,14 +76,14 @@ class pand2(pgate.pgate): a2_pin = self.inv_inst.get_pin("A") mid1_point = vector(0.5 * (z1_pin.cx() + a2_pin.cx()), z1_pin.cy()) mid2_point = vector(mid1_point, a2_pin.cy()) - self.add_path("metal1", + self.add_path("m1", [z1_pin.center(), mid1_point, mid2_point, a2_pin.center()]) def add_layout_pins(self): # Continous vdd rail along with label. vdd_pin = self.inv_inst.get_pin("vdd") self.add_layout_pin(text="vdd", - layer="metal1", + layer="m1", offset=vdd_pin.ll().scale(0, 1), width=self.width, height=vdd_pin.height()) @@ -91,7 +91,7 @@ class pand2(pgate.pgate): # Continous gnd rail along with label. gnd_pin = self.inv_inst.get_pin("gnd") self.add_layout_pin(text="gnd", - layer="metal1", + layer="m1", offset=gnd_pin.ll().scale(0, 1), width=self.width, height=vdd_pin.height()) diff --git a/compiler/pgates/pand3.py b/compiler/pgates/pand3.py index b02e18e4..dd1d87f7 100644 --- a/compiler/pgates/pand3.py +++ b/compiler/pgates/pand3.py @@ -76,14 +76,14 @@ class pand3(pgate.pgate): a2_pin = self.inv_inst.get_pin("A") mid1_point = vector(0.5 * (z1_pin.cx()+a2_pin.cx()), z1_pin.cy()) mid2_point = vector(mid1_point, a2_pin.cy()) - self.add_path("metal1", + self.add_path("m1", [z1_pin.center(), mid1_point, mid2_point, a2_pin.center()]) def add_layout_pins(self): # Continous vdd rail along with label. vdd_pin = self.inv_inst.get_pin("vdd") self.add_layout_pin(text="vdd", - layer="metal1", + layer="m1", offset=vdd_pin.ll().scale(0, 1), width=self.width, height=vdd_pin.height()) @@ -91,7 +91,7 @@ class pand3(pgate.pgate): # Continous gnd rail along with label. gnd_pin = self.inv_inst.get_pin("gnd") self.add_layout_pin(text="gnd", - layer="metal1", + layer="m1", offset=gnd_pin.ll().scale(0, 1), width=self.width, height=vdd_pin.height()) diff --git a/compiler/pgates/pbuf.py b/compiler/pgates/pbuf.py index 0149f75f..3171324b 100644 --- a/compiler/pgates/pbuf.py +++ b/compiler/pgates/pbuf.py @@ -78,13 +78,13 @@ class pbuf(pgate.pgate): z1_pin = self.inv1_inst.get_pin("Z") a2_pin = self.inv2_inst.get_pin("A") mid_point = vector(z1_pin.cx(), a2_pin.cy()) - self.add_path("metal1", [z1_pin.center(), mid_point, a2_pin.center()]) + self.add_path("m1", [z1_pin.center(), mid_point, a2_pin.center()]) def add_layout_pins(self): # Continous vdd rail along with label. vdd_pin = self.inv1_inst.get_pin("vdd") self.add_layout_pin(text="vdd", - layer="metal1", + layer="m1", offset=vdd_pin.ll().scale(0, 1), width=self.width, height=vdd_pin.height()) @@ -92,7 +92,7 @@ class pbuf(pgate.pgate): # Continous gnd rail along with label. gnd_pin = self.inv1_inst.get_pin("gnd") self.add_layout_pin(text="gnd", - layer="metal1", + layer="m1", offset=gnd_pin.ll().scale(0, 1), width=self.width, height=vdd_pin.height()) diff --git a/compiler/pgates/pdriver.py b/compiler/pgates/pdriver.py index bb7739b7..5aa5393e 100644 --- a/compiler/pgates/pdriver.py +++ b/compiler/pgates/pdriver.py @@ -140,7 +140,7 @@ class pdriver(pgate.pgate): z_inst_list.append(self.inv_inst_list[x].get_pin("Z")) a_inst_list.append(self.inv_inst_list[x + 1].get_pin("A")) mid_point = vector(z_inst_list[x].cx(), a_inst_list[x].cy()) - self.add_path("metal1", + self.add_path("m1", [z_inst_list[x].center(), mid_point, a_inst_list[x].center()]) @@ -148,7 +148,7 @@ class pdriver(pgate.pgate): # Continous vdd rail along with label. vdd_pin = self.inv_inst_list[0].get_pin("vdd") self.add_layout_pin(text="vdd", - layer="metal1", + layer="m1", offset=vdd_pin.ll().scale(0, 1), width=self.width, height=vdd_pin.height()) @@ -156,7 +156,7 @@ class pdriver(pgate.pgate): # Continous gnd rail along with label. gnd_pin = self.inv_inst_list[0].get_pin("gnd") self.add_layout_pin(text="gnd", - layer="metal1", + layer="m1", offset=gnd_pin.ll().scale(0, 1), width=self.width, height=vdd_pin.height()) diff --git a/compiler/pgates/pgate.py b/compiler/pgates/pgate.py index b55ad9c3..d5f2395b 100644 --- a/compiler/pgates/pgate.py +++ b/compiler/pgates/pgate.py @@ -59,7 +59,7 @@ class pgate(design.design): debug.error("Invalid supply name.", -1) if abs(height) > 0: - self.add_rect(layer="metal1", + self.add_rect(layer="m1", offset=source_pin.ll(), height=height, width=source_pin.width()) @@ -120,7 +120,7 @@ class pgate(design.design): directions=directions) self.add_layout_pin_rect_center(text=name, - layer="metal1", + layer="m1", offset=contact_offset, width=contact_m1_width, height=contact_m1_height) @@ -172,7 +172,7 @@ class pgate(design.design): # To the right a spacing away from the pmos right active edge contact_xoffset = pmos_pos.x + pmos.active_width \ - + drc("active_to_body_active") + + self.active_space # Must be at least an well enclosure of active down # from the top of the well @@ -189,7 +189,7 @@ class pgate(design.design): directions=("H", "V"), implant_type="n", well_type="n") - self.add_rect_center(layer="metal1", + self.add_rect_center(layer="m1", offset=contact_offset + vector(0, 0.5 * (self.height-contact_offset.y)), width=self.nwell_contact.mod.second_layer_width, height=self.height - contact_offset.y) @@ -227,7 +227,7 @@ class pgate(design.design): # To the right a spacing away from the nmos right active edge contact_xoffset = nmos_pos.x + nmos.active_width \ - + drc("active_to_body_active") + + self.active_space # Must be at least an well enclosure of active up # from the bottom of the well contact_yoffset = max(nmos_pos.y, @@ -243,7 +243,7 @@ class pgate(design.design): directions=("H", "V"), implant_type="p", well_type="p") - self.add_rect_center(layer="metal1", + self.add_rect_center(layer="m1", offset=contact_offset.scale(1,0.5), width=self.pwell_contact.mod.second_layer_width, height=contact_offset.y) diff --git a/compiler/pgates/pinv.py b/compiler/pgates/pinv.py index 5c53480b..1ff5b67b 100644 --- a/compiler/pgates/pinv.py +++ b/compiler/pgates/pinv.py @@ -96,14 +96,14 @@ class pinv(pgate.pgate): tx_height = nmos.poly_height + pmos.poly_height # rotated m1 pitch or poly to active spacing min_channel = max(contact.poly.width + self.m1_space, - contact.poly.width + 2 * drc("poly_to_active")) + contact.poly.width + 2 * self.poly_to_active) # This is the extra space needed to ensure DRC rules # to the active contacts extra_contact_space = max(-nmos.get_pin("D").by(), 0) # This is a poly-to-poly of a flipped cell self.top_bottom_space = max(0.5*self.m1_width + self.m1_space + extra_contact_space, - drc("poly_extend_active"), self.poly_space) + self.poly_extend_active, self.poly_space) total_height = tx_height + min_channel + 2 * self.top_bottom_space debug.check(self.height > total_height, "Cell height {0} too small for simple min height {1}.".format(self.height, @@ -153,7 +153,7 @@ class pinv(pgate.pgate): # the well width is determined the multi-finger PMOS device width plus # the well contact width and half well enclosure on both sides self.well_width = self.pmos.active_width + self.pmos.active_contact.width \ - + drc("active_to_body_active") + 2*drc("well_enclosure_active") + + self.active_space + 2*self.well_enclose_active self.width = self.well_width # Height is an input parameter, so it is not recomputed. @@ -178,12 +178,12 @@ class pinv(pgate.pgate): def route_supply_rails(self): """ Add vdd/gnd rails to the top and bottom. """ self.add_layout_pin_rect_center(text="gnd", - layer="metal1", + layer="m1", offset=vector(0.5 * self.width, 0), width=self.width) self.add_layout_pin_rect_center(text="vdd", - layer="metal1", + layer="m1", offset=vector(0.5 * self.width, self.height), width=self.width) @@ -238,7 +238,7 @@ class pinv(pgate.pgate): # Pick point at right most of NMOS and connect down to PMOS nmos_drain_pos = nmos_drain_pin.bc() pmos_drain_pos = vector(nmos_drain_pos.x, pmos_drain_pin.uc().y) - self.add_path("metal1", [nmos_drain_pos, pmos_drain_pos]) + self.add_path("m1", [nmos_drain_pos, pmos_drain_pos]) # Remember the mid for the output mid_drain_offset = vector(nmos_drain_pos.x, self.output_pos.y) @@ -247,13 +247,13 @@ class pinv(pgate.pgate): # This extends the output to the edge of the cell output_offset = mid_drain_offset.scale(0, 1) + vector(self.width, 0) self.add_layout_pin_segment_center(text="Z", - layer="metal1", + layer="m1", start=mid_drain_offset, end=output_offset) else: # This leaves the output as an internal pin (min sized) self.add_layout_pin_rect_center(text="Z", - layer="metal1", + layer="m1", offset=mid_drain_offset \ + vector(0.5 * self.m1_width, 0)) diff --git a/compiler/pgates/pinvbuf.py b/compiler/pgates/pinvbuf.py index 579e1198..b8ecb3bf 100644 --- a/compiler/pgates/pinvbuf.py +++ b/compiler/pgates/pinvbuf.py @@ -114,13 +114,13 @@ class pinvbuf(pgate.pgate): z1_pin = self.inv1_inst.get_pin("Z") a2_pin = self.inv2_inst.get_pin("A") mid_point = vector(z1_pin.cx(), a2_pin.cy()) - self.add_path("metal1", [z1_pin.center(), mid_point, a2_pin.center()]) + self.add_path("m1", [z1_pin.center(), mid_point, a2_pin.center()]) # inv2 Z to inv3 A z2_pin = self.inv2_inst.get_pin("Z") a3_pin = self.inv3_inst.get_pin("A") mid_point = vector(z2_pin.cx(), a3_pin.cy()) - self.add_path("metal1", [z2_pin.center(), mid_point, a3_pin.center()]) + self.add_path("m1", [z2_pin.center(), mid_point, a3_pin.center()]) # inv1 Z to inv4 A (up and over) z1_pin = self.inv1_inst.get_pin("Z") @@ -136,7 +136,7 @@ class pinvbuf(pgate.pgate): # Continous vdd rail along with label. vdd_pin = self.inv1_inst.get_pin("vdd") self.add_layout_pin(text="vdd", - layer="metal1", + layer="m1", offset=vdd_pin.ll().scale(0, 1), width=self.width, height=vdd_pin.height()) @@ -144,7 +144,7 @@ class pinvbuf(pgate.pgate): # Continous vdd rail along with label. gnd_pin = self.inv4_inst.get_pin("gnd") self.add_layout_pin(text="gnd", - layer="metal1", + layer="m1", offset=gnd_pin.ll().scale(0, 1), width=self.width, height=gnd_pin.height()) @@ -152,28 +152,28 @@ class pinvbuf(pgate.pgate): # Continous gnd rail along with label. gnd_pin = self.inv1_inst.get_pin("gnd") self.add_layout_pin(text="gnd", - layer="metal1", + layer="m1", offset=gnd_pin.ll().scale(0, 1), width=self.width, height=vdd_pin.height()) z_pin = self.inv4_inst.get_pin("Z") self.add_layout_pin_rect_center(text="Z", - layer="metal2", + layer="m2", offset=z_pin.center()) self.add_via_center(layers=self.m1_stack, offset=z_pin.center()) zb_pin = self.inv3_inst.get_pin("Z") self.add_layout_pin_rect_center(text="Zb", - layer="metal2", + layer="m2", offset=zb_pin.center()) self.add_via_center(layers=self.m1_stack, offset=zb_pin.center()) a_pin = self.inv1_inst.get_pin("A") self.add_layout_pin_rect_center(text="A", - layer="metal2", + layer="m2", offset=a_pin.center()) self.add_via_center(layers=self.m1_stack, offset=a_pin.center()) diff --git a/compiler/pgates/pnand2.py b/compiler/pgates/pnand2.py index 4623048c..8acde2ce 100644 --- a/compiler/pgates/pnand2.py +++ b/compiler/pgates/pnand2.py @@ -99,8 +99,8 @@ class pnand2(pgate.pgate): # Two PMOS devices and a well contact. Separation between each. # Enclosure space on the sides. self.well_width = 2 * self.pmos.active_width + contact.active.width \ - + 2 * drc("active_to_body_active") \ - + 2 * drc("well_enclosure_active") + + 2 * self.active_space \ + + 2 * self.well_enclose_active self.width = self.well_width # Height is an input parameter, so it is not recomputed. @@ -110,17 +110,17 @@ class pnand2(pgate.pgate): extra_contact_space = max(-self.nmos.get_pin("D").by(), 0) # This is a poly-to-poly of a flipped cell self.top_bottom_space = max(0.5 * self.m1_width + self.m1_space + extra_contact_space, - drc("poly_extend_active"), self.poly_space) + self.poly_extend_active, self.poly_space) def route_supply_rails(self): """ Add vdd/gnd rails to the top and bottom. """ self.add_layout_pin_rect_center(text="gnd", - layer="metal1", + layer="m1", offset=vector(0.5*self.width, 0), width=self.width) self.add_layout_pin_rect_center(text="vdd", - layer="metal1", + layer="m1", offset=vector(0.5 * self.width, self.height), width=self.width) @@ -235,13 +235,13 @@ class pnand2(pgate.pgate): offset=out_offset) # PMOS1 to mid-drain to NMOS2 drain - self.add_path("metal2", + self.add_path("m2", [top_pin_offset, mid1_offset, out_offset, mid2_offset, bottom_pin_offset]) # This extends the output to the edge of the cell self.add_layout_pin_rect_center(text="Z", - layer="metal1", + layer="m1", offset=out_offset, width=contact.m1m2.first_layer_height, height=contact.m1m2.first_layer_width) diff --git a/compiler/pgates/pnand3.py b/compiler/pgates/pnand3.py index 6d885e25..7a773497 100644 --- a/compiler/pgates/pnand3.py +++ b/compiler/pgates/pnand3.py @@ -92,7 +92,7 @@ class pnand3(pgate.pgate): # Two PMOS devices and a well contact. Separation between each. # Enclosure space on the sides. self.well_width = 3 * self.pmos.active_width + self.pmos.active_contact.width \ - + 2 * drc("active_to_body_active") + 2 * drc("well_enclosure_active") \ + + 2 * self.active_space + 2 * self.well_enclose_active \ - self.overlap_offset.x self.width = self.well_width # Height is an input parameter, so it is not recomputed. @@ -107,18 +107,18 @@ class pnand3(pgate.pgate): # This is a poly-to-poly of a flipped cell self.top_bottom_space = max(0.5 * self.m1_width + self.m1_space \ + extra_contact_space, - drc("poly_extend_active"), + self.poly_extend_active, self.poly_space) def route_supply_rails(self): """ Add vdd/gnd rails to the top and bottom. """ self.add_layout_pin_rect_center(text="gnd", - layer="metal1", + layer="m1", offset=vector(0.5 * self.width, 0), width=self.width) self.add_layout_pin_rect_center(text="vdd", - layer="metal1", + layer="m1", offset=vector(0.5 * self.width, self.height), width=self.width) @@ -205,7 +205,7 @@ class pnand3(pgate.pgate): self.m1_space + 0.5 *contact.poly.width + 0.5 * self.m1_width) active_spacing = max(self.m1_space, - 0.5 * contact.poly.first_layer_width + drc("poly_to_active")) + 0.5 * contact.poly.first_layer_width + self.poly_to_active) inputC_yoffset = self.nmos3_pos.y + self.nmos.active_height + active_spacing self.route_input_gate(self.pmos3_inst, self.nmos3_inst, @@ -245,16 +245,16 @@ class pnand3(pgate.pgate): offset=nmos3_pin.center()) # PMOS3 and NMOS3 are drain aligned - self.add_path("metal2", [pmos3_pin.bc(), nmos3_pin.uc()]) + self.add_path("m2", [pmos3_pin.bc(), nmos3_pin.uc()]) # Route in the A input track (top track) mid_offset = vector(nmos3_pin.center().x, self.inputA_yoffset) - self.add_path("metal2", [pmos1_pin.bc(), mid_offset, nmos3_pin.uc()]) + self.add_path("m2", [pmos1_pin.bc(), mid_offset, nmos3_pin.uc()]) # This extends the output to the edge of the cell self.add_via_center(layers=self.m1_stack, offset=mid_offset) self.add_layout_pin_rect_center(text="Z", - layer="metal1", + layer="m1", offset=mid_offset, width=contact.m1m2.first_layer_width, height=contact.m1m2.first_layer_height) diff --git a/compiler/pgates/pnor2.py b/compiler/pgates/pnor2.py index a79d19a0..d75df0a9 100644 --- a/compiler/pgates/pnor2.py +++ b/compiler/pgates/pnor2.py @@ -97,9 +97,8 @@ class pnor2(pgate.pgate): # Enclosure space on the sides. self.well_width = 2 * self.pmos.active_width \ + self.pmos.active_contact.width \ - + 2 * drc("active_to_body_active") \ - + 2 * drc("well_enclosure_active") - + + 2 * self.active_space \ + + 2 * self.well_enclose_active self.width = self.well_width # Height is an input parameter, so it is not recomputed. @@ -108,18 +107,18 @@ class pnor2(pgate.pgate): extra_contact_space = max(-self.nmos.get_pin("D").by(), 0) # This is a poly-to-poly of a flipped cell self.top_bottom_space = max(0.5 * self.m1_width + self.m1_space + extra_contact_space, - drc("poly_extend_active"), + self.poly_extend_active, self.poly_space) def route_supply_rails(self): """ Add vdd/gnd rails to the top and bottom. """ self.add_layout_pin_rect_center(text="gnd", - layer="metal1", + layer="m1", offset=vector(0.5 * self.width, 0), width=self.width) self.add_layout_pin_rect_center(text="vdd", - layer="metal1", + layer="m1", offset=vector(0.5 * self.width, self.height), width=self.width) @@ -226,15 +225,15 @@ class pnor2(pgate.pgate): mid3_offset = mid2_offset + vector(self.m2_width, 0) # PMOS1 to mid-drain to NMOS2 drain - self.add_path("metal2", + self.add_path("m2", [pmos_pin.bc(), mid2_offset, mid3_offset]) - self.add_path("metal2", + self.add_path("m2", [nmos_pin.rc(), mid1_offset, mid2_offset]) # This extends the output to the edge of the cell self.add_via_center(layers=self.m1_stack, offset=mid3_offset) self.add_layout_pin_rect_center(text="Z", - layer="metal1", + layer="m1", offset=mid3_offset, width=contact.m1m2.first_layer_height, height=contact.m1m2.first_layer_width) diff --git a/compiler/pgates/precharge.py b/compiler/pgates/precharge.py index 9641a1f3..784bb418 100644 --- a/compiler/pgates/precharge.py +++ b/compiler/pgates/precharge.py @@ -72,7 +72,7 @@ class precharge(design.design): # Adds the rail across the width of the cell vdd_position = vector(0.5 * self.width, self.height) - self.add_rect_center(layer="metal1", + self.add_rect_center(layer="m1", offset=vdd_position, width=self.width, height=self.m1_width) @@ -80,7 +80,7 @@ class precharge(design.design): pmos_pin = self.upper_pmos2_inst.get_pin("S") # center of vdd rail pmos_vdd_pos = vector(pmos_pin.cx(), vdd_position.y) - self.add_path("metal1", [pmos_pin.uc(), pmos_vdd_pos]) + self.add_path("m1", [pmos_pin.uc(), pmos_vdd_pos]) # Add vdd pin above the transistor self.add_power_pin("vdd", pmos_pin.center(), vertical=True) @@ -164,7 +164,7 @@ class precharge(design.design): # adds the en rail on metal1 self.add_layout_pin_segment_center(text="en_bar", - layer="metal1", + layer="m1", start=offset.scale(0, 1), end=offset.scale(0, 1) + vector(self.width, 0)) @@ -176,7 +176,7 @@ class precharge(design.design): # adds the contact from active to metal1 well_contact_pos = self.upper_pmos1_inst.get_pin("D").center().scale(1, 0) \ + vector(0, self.upper_pmos1_inst.uy() + contact.well.height / 2 \ - + drc("well_extend_active")) + + self.well_extend_active) self.add_via_center(layers=self.active_stack, offset=well_contact_pos, implant_type="n", @@ -200,7 +200,7 @@ class precharge(design.design): offset = vector(self.bitcell.get_pin(self.bitcell_bl).cx(), 0) \ - vector(0.5 * self.m2_width, 0) self.bl_pin = self.add_layout_pin(text="bl", - layer="metal2", + layer="m2", offset=offset, height=self.height) @@ -208,7 +208,7 @@ class precharge(design.design): offset = vector(self.bitcell.get_pin(self.bitcell_br).cx(), 0) \ - vector(0.5 * self.m2_width, 0) self.br_pin = self.add_layout_pin(text="br", - layer="metal2", + layer="m2", offset=offset, height=self.height) @@ -258,7 +258,7 @@ class precharge(design.design): left_pos = vector(min(pmos_pin.cx(), bit_pin.cx()), pmos_pin.cy()) right_pos = vector(max(pmos_pin.cx(), bit_pin.cx()), pmos_pin.cy()) - self.add_path("metal1", [left_pos, right_pos] ) + self.add_path("m1", [left_pos, right_pos] ) def connect_pmos_m2(self, pmos_pin, bit_pin): """ @@ -268,7 +268,7 @@ class precharge(design.design): left_pos = vector(min(pmos_pin.cx(), bit_pin.cx()), pmos_pin.cy()) right_pos = vector(max(pmos_pin.cx(), bit_pin.cx()), pmos_pin.cy()) - self.add_path("metal2", [left_pos, right_pos], self.bl_contact.height) + self.add_path("m2", [left_pos, right_pos], self.bl_contact.height) def get_en_cin(self): """Get the relative capacitance of the enable in the precharge cell""" diff --git a/compiler/pgates/ptristate_inv.py b/compiler/pgates/ptristate_inv.py index 4a17b46a..5c0028b2 100644 --- a/compiler/pgates/ptristate_inv.py +++ b/compiler/pgates/ptristate_inv.py @@ -73,7 +73,7 @@ class ptristate_inv(pgate.pgate): # Two PMOS devices and a well contact. Separation between each. # Enclosure space on the sides. - self.well_width = 2 * self.pmos.active_width + drc("well_enclosure_active") + self.well_width = 2 * self.pmos.active_width + self.well_enclose_active # Add an extra space because we route the output on the right of the S/D self.width = self.well_width + 0.5 * self.m1_space @@ -101,12 +101,12 @@ class ptristate_inv(pgate.pgate): def route_supply_rails(self): """ Add vdd/gnd rails to the top and bottom. """ self.add_layout_pin_rect_center(text="gnd", - layer="metal1", + layer="m1", offset=vector(0.5 * self.width, 0), width=self.width) self.add_layout_pin_rect_center(text="vdd", - layer="metal1", + layer="m1", offset=vector(0.5 * self.width, self.height), width=self.width) @@ -181,7 +181,7 @@ class ptristate_inv(pgate.pgate): pmos_drain_pos = pmos_drain_pin.ur() self.add_layout_pin(text="out", - layer="metal1", + layer="m1", offset=nmos_drain_pos, height=pmos_drain_pos.y - nmos_drain_pos.y) diff --git a/compiler/pgates/ptx.py b/compiler/pgates/ptx.py index 61610a88..9907485f 100644 --- a/compiler/pgates/ptx.py +++ b/compiler/pgates/ptx.py @@ -91,8 +91,8 @@ class ptx(design.design): # " ".join(self.pins))) # Just make a guess since these will actually # be decided in the layout later. - area_sd = 2.5 * drc("minwidth_poly") * self.tx_width - perimeter_sd = 2 * drc("minwidth_poly") + 2 * self.tx_width + area_sd = 2.5 * self.poly_width * self.tx_width + perimeter_sd = 2 * self.poly_width + 2 * self.tx_width main_str = "M{{0}} {{1}} {0} m={1} w={2}u l={3}u ".format(spice[self.tx_type], self.mults, self.tx_width, @@ -136,7 +136,7 @@ class ptx(design.design): self.contact_pitch = 2 * self.contact_to_gate + self.contact_width + self.poly_width # The enclosure of an active contact. Not sure about second term. - active_enclose_contact = max(drc("active_enclosure_contact"), + active_enclose_contact = max(self.active_enclose_contact, (self.active_width - self.contact_width) / 2) # This is the distance from the edge of poly to the contacted end of active @@ -180,11 +180,11 @@ class ptx(design.design): # Min area results are just flagged for now. - debug.check(self.active_width * self.active_height >= drc("minarea_active"), + debug.check(self.active_width * self.active_height >= self.minarea_active, "Minimum active area violated.") # We do not want to increase the poly dimensions to fix # an area problem as it would cause an LVS issue. - debug.check(self.poly_width * self.poly_height >= drc("minarea_poly"), + debug.check(self.poly_width * self.poly_height >= self.minarea_poly, "Minimum poly area violated.") def connect_fingered_poly(self, poly_positions): @@ -219,7 +219,7 @@ class ptx(design.design): layer="poly", offset=poly_offset, width=poly_width, - height=drc("minwidth_poly")) + height=self.poly_width) def connect_fingered_active(self, drain_positions, source_positions): @@ -249,12 +249,12 @@ class ptx(design.design): self.remove_layout_pin("S") # remove the individual connections # Add each vertical segment for a in source_positions: - self.add_path(("metal1"), + self.add_path(("m1"), [a, a + pin_offset.scale(source_dir, source_dir)]) # Add a single horizontal pin self.add_layout_pin_segment_center(text="S", - layer="metal1", + layer="m1", start=source_positions[0] + source_offset - end_offset, end=source_positions[-1] + source_offset + end_offset) @@ -263,10 +263,10 @@ class ptx(design.design): self.remove_layout_pin("D") # remove the individual connections # Add each vertical segment for a in drain_positions: - self.add_path(("metal1"), [a,a+drain_offset]) + self.add_path(("m1"), [a,a+drain_offset]) # Add a single horizontal pin self.add_layout_pin_segment_center(text="D", - layer="metal1", + layer="m1", start=drain_positions[0] + drain_offset - end_offset, end=drain_positions[-1] + drain_offset + end_offset) @@ -313,7 +313,7 @@ class ptx(design.design): height=self.active_height) # If the implant must enclose the active, shift offset # and increase width/height - enclose_width = drc("implant_enclosure_active") + enclose_width = self.implant_enclose_active enclose_offset = [enclose_width] * 2 self.add_rect(layer="{}implant".format(self.implant_type), offset=self.active_offset - enclose_offset, @@ -380,7 +380,7 @@ class ptx(design.design): implant_type=self.implant_type, well_type=self.well_type) self.add_layout_pin_rect_center(text="S", - layer="metal1", + layer="m1", offset=pos, width=contact.mod.second_layer_width, height=contact.mod.second_layer_height) @@ -394,7 +394,7 @@ class ptx(design.design): implant_type=self.implant_type, well_type=self.well_type) self.add_layout_pin_rect_center(text="D", - layer="metal1", + layer="m1", offset=pos, width=contact.mod.second_layer_width, height=contact.mod.second_layer_height) diff --git a/compiler/pgates/pwrite_driver.py b/compiler/pgates/pwrite_driver.py index a808737b..2dc356c3 100644 --- a/compiler/pgates/pwrite_driver.py +++ b/compiler/pgates/pwrite_driver.py @@ -131,26 +131,26 @@ class pwrite_driver(design.design): bl_xoffset = left_x bl_out=vector(bl_xoffset, self.height) bl_in=self.bl_inst.get_pin("out").center() - self.add_via_center(layers=("metal1","via1","metal2"), + self.add_via_center(layers=self.m1_stack, offset=bl_in) bl_mid = vector(bl_out.x,bl_in.y) - self.add_path("metal2", [bl_in, bl_mid, bl_out]) + self.add_path("m2", [bl_in, bl_mid, bl_out]) self.add_layout_pin_rect_center(text="bl", - layer="metal2", + layer="m2", offset=bl_out) br_xoffset = right_x br_out=vector(br_xoffset, self.height) br_in=self.br_inst.get_pin("out").center() - self.add_via_center(layers=("metal1","via1","metal2"), + self.add_via_center(layers=self.m1_stack, offset=br_in) br_mid = vector(br_out.x,br_in.y) - self.add_path("metal2", [br_in, br_mid, br_out]) + self.add_path("m2", [br_in, br_mid, br_out]) self.add_layout_pin_rect_center(text="br", - layer="metal2", + layer="m2", offset=br_out) #br_xoffset = b.get_pin("br".cx() @@ -162,19 +162,19 @@ class pwrite_driver(design.design): track_xoff = self.get_m2_track(1) din_loc = self.din_inst.get_pin("A").center() - self.add_via_stack("metal1", "metal2", din_loc) + self.add_via_stack("m1", "m2", din_loc) din_track = vector(track_xoff,din_loc.y) br_in = self.br_inst.get_pin("in").center() - self.add_via_stack("metal1", "metal2", br_in) + self.add_via_stack("m1", "m2", br_in) br_track = vector(track_xoff,br_in.y) din_in = vector(track_xoff,0) - self.add_path("metal2", [din_in, din_track, din_loc, din_track, br_track, br_in]) + self.add_path("m2", [din_in, din_track, din_loc, din_track, br_track, br_in]) self.add_layout_pin_rect_center(text="din", - layer="metal2", + layer="m2", offset=din_in) def route_din_bar(self): @@ -183,19 +183,19 @@ class pwrite_driver(design.design): track_xoff = self.get_m4_track(self.din_bar_track) din_bar_in = self.din_inst.get_pin("Z").center() - self.add_via_stack("metal1", "metal3", din_bar_in) + self.add_via_stack("m1", "m3", din_bar_in) din_bar_track = vector(track_xoff,din_bar_in.y) bl_in = self.bl_inst.get_pin("in").center() - self.add_via_stack("metal1", "metal3", bl_in) + self.add_via_stack("m1", "m3", bl_in) bl_track = vector(track_xoff,bl_in.y) din_in = vector(track_xoff,0) - self.add_wire(("metal3","via3","metal4"), [din_bar_in, din_bar_track, bl_track, bl_in]) + self.add_wire(self.m3_stack, [din_bar_in, din_bar_track, bl_track, bl_in]) self.add_layout_pin_rect_center(text="din", - layer="metal4", + layer="m4", offset=din_in) @@ -206,22 +206,22 @@ class pwrite_driver(design.design): # This M2 pitch is a hack since the A and Z pins align horizontally en_bar_loc = self.en_inst.get_pin("Z").uc() en_bar_track = vector(track_xoff, en_bar_loc.y) - self.add_via_stack("metal1", "metal3", en_bar_loc) + self.add_via_stack("m1", "m3", en_bar_loc) # This is a U route to the right down then left bl_en_loc = self.bl_inst.get_pin("en_bar").center() bl_en_track = vector(track_xoff, bl_en_loc.y) - self.add_via_stack("metal1", "metal3", bl_en_loc) + self.add_via_stack("m1", "m3", bl_en_loc) br_en_loc = self.br_inst.get_pin("en_bar").center() br_en_track = vector(track_xoff, bl_en_loc.y) - self.add_via_stack("metal1", "metal3", br_en_loc) + self.add_via_stack("m1", "m3", br_en_loc) # L shape - self.add_wire(("metal3","via3","metal4"), + self.add_wire(self.m3_stack, [en_bar_loc, en_bar_track, bl_en_track]) # U shape - self.add_wire(("metal3","via3","metal4"), + self.add_wire(self.m3_stack, [bl_en_loc, bl_en_track, br_en_track, br_en_loc]) @@ -233,30 +233,30 @@ class pwrite_driver(design.design): # The en pin will be over the vdd rail vdd_yloc = self.en_inst.get_pin("vdd").cy() self.add_layout_pin_segment_center(text="en", - layer="metal3", + layer="m3", start=vector(0,vdd_yloc), end=vector(self.width,vdd_yloc)) en_loc = self.en_inst.get_pin("A").center() en_rail = vector(en_loc.x, vdd_yloc) - self.add_via_stack("metal1", "metal2", en_loc) - self.add_path("metal2", [en_loc, en_rail]) - self.add_via_stack("metal2", "metal3", en_rail) + self.add_via_stack("m1", "m2", en_loc) + self.add_path("m2", [en_loc, en_rail]) + self.add_via_stack("m2", "m3", en_rail) # Start point in the track on the pin rail en_track = vector(track_xoff, vdd_yloc) - self.add_via_stack("metal3", "metal4", en_track) + self.add_via_stack("m3", "m4", en_track) # This is a U route to the right down then left bl_en_loc = self.bl_inst.get_pin("en").center() bl_en_track = vector(track_xoff, bl_en_loc.y) - self.add_via_stack("metal1", "metal3", bl_en_loc) + self.add_via_stack("m1", "m3", bl_en_loc) br_en_loc = self.br_inst.get_pin("en").center() br_en_track = vector(track_xoff, bl_en_loc.y) - self.add_via_stack("metal1", "metal3", br_en_loc) + self.add_via_stack("m1", "m3", br_en_loc) # U shape - self.add_wire(("metal3","via3","metal4"), + self.add_wire(self.m3_stack, [en_track, bl_en_track, bl_en_loc, bl_en_track, br_en_track, br_en_loc]) @@ -284,7 +284,7 @@ class pwrite_driver(design.design): # Continous vdd rail along with label. vdd_pin=inst.get_pin("vdd") self.add_layout_pin(text="vdd", - layer="metal1", + layer="m1", offset=vdd_pin.ll().scale(0,1), width=self.width, height=vdd_pin.height()) @@ -292,7 +292,7 @@ class pwrite_driver(design.design): # Continous gnd rail along with label. gnd_pin=inst.get_pin("gnd") self.add_layout_pin(text="gnd", - layer="metal1", + layer="m1", offset=gnd_pin.ll().scale(0,1), width=self.width, height=vdd_pin.height()) diff --git a/compiler/pgates/single_level_column_mux.py b/compiler/pgates/single_level_column_mux.py index 525c1680..18b4b10f 100644 --- a/compiler/pgates/single_level_column_mux.py +++ b/compiler/pgates/single_level_column_mux.py @@ -65,21 +65,21 @@ class single_level_column_mux(pgate.pgate): # bl and br self.add_layout_pin(text="bl", - layer="metal2", + layer="m2", offset=bl_pos + vector(0, self.height - self.pin_height), height=self.pin_height) self.add_layout_pin(text="br", - layer="metal2", + layer="m2", offset=br_pos + vector(0, self.height - self.pin_height), height=self.pin_height) # bl_out and br_out self.add_layout_pin(text="bl_out", - layer="metal2", + layer="m2", offset=bl_pos, height=self.pin_height) self.add_layout_pin(text="br_out", - layer="metal2", + layer="m2", offset=br_pos, height=self.pin_height) @@ -141,7 +141,7 @@ class single_level_column_mux(pgate.pgate): # bl -> nmos_upper/D on metal1 # bl_out -> nmos_upper/S on metal2 - self.add_path("metal1", + self.add_path("m1", [bl_pin.ll(), vector(nmos_upper_d_pin.cx(), bl_pin.by()), nmos_upper_d_pin.center()]) # halfway up, move over @@ -149,12 +149,12 @@ class single_level_column_mux(pgate.pgate): + nmos_upper_s_pin.bc().scale(0, 0.4) mid2 = bl_out_pin.uc().scale(0, 0.4) \ + nmos_upper_s_pin.bc().scale(1, 0.4) - self.add_path("metal2", + self.add_path("m2", [bl_out_pin.uc(), mid1, mid2, nmos_upper_s_pin.bc()]) # br -> nmos_lower/D on metal2 # br_out -> nmos_lower/S on metal1 - self.add_path("metal1", + self.add_path("m1", [br_out_pin.uc(), vector(nmos_lower_s_pin.cx(), br_out_pin.uy()), nmos_lower_s_pin.center()]) @@ -163,7 +163,7 @@ class single_level_column_mux(pgate.pgate): + nmos_lower_d_pin.uc().scale(0,0.5) mid2 = br_pin.bc().scale(0,0.5) \ + nmos_lower_d_pin.uc().scale(1,0.5) - self.add_path("metal2", + self.add_path("m2", [br_pin.bc(), mid1, mid2, nmos_lower_d_pin.uc()]) def add_wells(self): @@ -186,7 +186,7 @@ class single_level_column_mux(pgate.pgate): self.add_via_center(layers=self.m2_stack, offset=active_pos) self.add_layout_pin_rect_center(text="gnd", - layer="metal3", + layer="m3", offset=active_pos) # Add well enclosure over all the tx and contact diff --git a/compiler/sram/sram_1bank.py b/compiler/sram/sram_1bank.py index 6c887790..151c8a70 100644 --- a/compiler/sram/sram_1bank.py +++ b/compiler/sram/sram_1bank.py @@ -261,18 +261,18 @@ class sram_1bank(sram_base): # This is the steiner point where the net branches out clk_steiner_pos = vector(mid1_pos.x, control_clk_buf_pos.y) - self.add_path("metal1", [control_clk_buf_pos, clk_steiner_pos]) - self.add_via_center(layers=("metal1","via1","metal2"), + self.add_path("m1", [control_clk_buf_pos, clk_steiner_pos]) + self.add_via_center(layers=self.m1_stack, offset=clk_steiner_pos) # Note, the via to the control logic is taken care of above - self.add_wire(("metal3","via2","metal2"),[row_addr_clk_pos, mid1_pos, clk_steiner_pos]) + self.add_wire(("m3","via2","m2"),[row_addr_clk_pos, mid1_pos, clk_steiner_pos]) if self.col_addr_dff: dff_clk_pin = self.col_addr_dff_insts[port].get_pin("clk") dff_clk_pos = dff_clk_pin.center() mid_pos = vector(clk_steiner_pos.x, dff_clk_pos.y) - self.add_wire(("metal3","via2","metal2"),[dff_clk_pos, mid_pos, clk_steiner_pos]) + self.add_wire(("m3","via2","m2"),[dff_clk_pos, mid_pos, clk_steiner_pos]) if port in self.write_ports: data_dff_clk_pin = self.data_dff_insts[port].get_pin("clk") @@ -280,8 +280,8 @@ class sram_1bank(sram_base): mid_pos = vector(clk_steiner_pos.x, data_dff_clk_pos.y) # In some designs, the steiner via will be too close to the mid_pos via # so make the wire as wide as the contacts - self.add_path("metal2",[mid_pos, clk_steiner_pos], width=max(m2m3.width,m2m3.height)) - self.add_wire(("metal3","via2","metal2"),[data_dff_clk_pos, mid_pos, clk_steiner_pos]) + self.add_path("m2",[mid_pos, clk_steiner_pos], width=max(m2m3.width,m2m3.height)) + self.add_wire(("m3","via2","m2"),[data_dff_clk_pos, mid_pos, clk_steiner_pos]) if self.write_size: wmask_dff_clk_pin = self.wmask_dff_insts[port].get_pin("clk") @@ -289,8 +289,8 @@ class sram_1bank(sram_base): mid_pos = vector(clk_steiner_pos.x, wmask_dff_clk_pos.y) # In some designs, the steiner via will be too close to the mid_pos via # so make the wire as wide as the contacts - self.add_path("metal2", [mid_pos, clk_steiner_pos], width=max(m2m3.width, m2m3.height)) - self.add_wire(("metal3", "via2", "metal2"), [wmask_dff_clk_pos, mid_pos, clk_steiner_pos]) + self.add_path("m2", [mid_pos, clk_steiner_pos], width=max(m2m3.width, m2m3.height)) + self.add_wire(("m3", "via2", "m2"), [wmask_dff_clk_pos, mid_pos, clk_steiner_pos]) def route_control_logic(self): @@ -323,8 +323,8 @@ class sram_1bank(sram_base): flop_pos = flop_pin.center() bank_pos = bank_pin.center() mid_pos = vector(bank_pos.x,flop_pos.y) - self.add_wire(("metal3","via2","metal2"),[flop_pos, mid_pos,bank_pos]) - self.add_via_center(layers=("metal2","via2","metal3"), + self.add_wire(("m3","via2","m2"),[flop_pos, mid_pos,bank_pos]) + self.add_via_center(layers=self.m2_stack, offset=flop_pos) def route_col_addr_dff(self): @@ -336,7 +336,7 @@ class sram_1bank(sram_base): offset = self.col_addr_dff_insts[port].ul() + vector(0, 2*self.m1_pitch) bus_names = ["addr_{}".format(x) for x in range(self.col_addr_size)] - col_addr_bus_offsets = self.create_horizontal_bus(layer="metal1", + col_addr_bus_offsets = self.create_horizontal_bus(layer="m1", pitch=self.m1_pitch, offset=offset, names=bus_names, diff --git a/compiler/sram/sram_2bank.py b/compiler/sram/sram_2bank.py index e1224795..dace1ed9 100644 --- a/compiler/sram/sram_2bank.py +++ b/compiler/sram/sram_2bank.py @@ -103,25 +103,25 @@ class sram_2bank(sram_base): for n in self.control_logic_outputs + ["vdd", "gnd"]: pins = self.control_logic_inst.get_pins(n) for pin in pins: - if pin.layer=="metal2": + if pin.layer=="m2": pin_pos = pin.bc() break rail_pos = vector(pin_pos.x,self.horz_control_bus_positions[n].y) - self.add_path("metal2",[pin_pos,rail_pos]) - self.add_via_center(("metal1","via1","metal2"),rail_pos) + self.add_path("m2",[pin_pos,rail_pos]) + self.add_via_center(self.m1_stack,rail_pos) # connect the control logic cross bar for n in self.control_logic_outputs: cross_pos = vector(self.vert_control_bus_positions[n].x,self.horz_control_bus_positions[n].y) - self.add_via_center(("metal1","via1","metal2"),cross_pos) + self.add_via_center(self.m1_stack,cross_pos) # connect the bank select signals to the vertical bus for i in range(self.num_banks): pin = self.bank_inst[i].get_pin("bank_sel") pin_pos = pin.rc() if i==0 else pin.lc() rail_pos = vector(self.vert_control_bus_positions["bank_sel[{}]".format(i)].x,pin_pos.y) - self.add_path("metal3",[pin_pos,rail_pos]) - self.add_via_center(("metal2","via2","metal3"),rail_pos) + self.add_path("m3",[pin_pos,rail_pos]) + self.add_via_center(self.m2_stack,rail_pos) def route_single_msb_address(self): """ Route one MSB address bit for 2-bank SRAM """ @@ -129,37 +129,37 @@ class sram_2bank(sram_base): # connect the bank MSB flop supplies vdd_pins = self.msb_address_inst.get_pins("vdd") for vdd_pin in vdd_pins: - if vdd_pin.layer != "metal1": continue + if vdd_pin.layer != "m1": continue vdd_pos = vdd_pin.bc() down_pos = vdd_pos - vector(0,self.m1_pitch) rail_pos = vector(vdd_pos.x,self.horz_control_bus_positions["vdd"].y) - self.add_path("metal1",[vdd_pos,down_pos]) - self.add_via_center(("metal1","via1","metal2"),down_pos,rotate=90) - self.add_path("metal2",[down_pos,rail_pos]) - self.add_via_center(("metal1","via1","metal2"),rail_pos) + self.add_path("m1",[vdd_pos,down_pos]) + self.add_via_center(self.m1_stack,down_pos,rotate=90) + self.add_path("m2",[down_pos,rail_pos]) + self.add_via_center(self.m1_stack,rail_pos) gnd_pins = self.msb_address_inst.get_pins("gnd") # Only add the ground connection to the lowest metal2 rail in the flop array # FIXME: SCMOS doesn't have a vertical rail in the cell, or we could use those lowest_y = None for gnd_pin in gnd_pins: - if gnd_pin.layer != "metal2": continue + if gnd_pin.layer != "m2": continue if lowest_y==None or gnd_pin.by()