From cb8567c66f8daa6dc6356d503dc8ffa5bab3f9a7 Mon Sep 17 00:00:00 2001 From: Sage Walker Date: Mon, 11 Sep 2023 21:40:20 -0700 Subject: [PATCH] spacing tweaks for gf180 address control gate --- compiler/modules/pinv_dec.py | 6 ++-- compiler/modules/rom_address_control_array.py | 5 +-- compiler/modules/rom_address_control_buf.py | 33 +++++++++++-------- .../sp_lib/gf180mcu_3v3__nand2_1_dec.sp | 6 ++-- technology/gf180mcu/tech/tech.py | 31 ++++++++++------- 5 files changed, 50 insertions(+), 31 deletions(-) diff --git a/compiler/modules/pinv_dec.py b/compiler/modules/pinv_dec.py index 1ee75266..193fe6b1 100644 --- a/compiler/modules/pinv_dec.py +++ b/compiler/modules/pinv_dec.py @@ -242,10 +242,12 @@ class pinv_dec(pinv): source_pos = self.nmos_inst.get_pin("S").center() self.add_via_stack_center(offset=source_pos, from_layer=self.route_layer, - to_layer=self.supply_layer) + to_layer=self.supply_layer, + min_area=True) source_pos = self.pmos_inst.get_pin("S").center() self.add_via_stack_center(offset=source_pos, from_layer=self.route_layer, - to_layer=self.supply_layer) + to_layer=self.supply_layer, + min_area=True) diff --git a/compiler/modules/rom_address_control_array.py b/compiler/modules/rom_address_control_array.py index 9f59ca71..dc4cbf2e 100644 --- a/compiler/modules/rom_address_control_array.py +++ b/compiler/modules/rom_address_control_array.py @@ -21,11 +21,11 @@ class rom_address_control_array(design): self.size=inv_size self.cols = cols self.route_layer = route_layer - dff = factory.create(module_type="dff") if name=="": name = "rom_inv_array_{0}".format(cols) if inv_height == None: - self.inv_height = dff.height * 0.5 + + self.inv_height = drc("minwidth_{}".format(route_layer)) * 14 else: self.inv_height = inv_height @@ -34,6 +34,7 @@ class rom_address_control_array(design): self.inv_layer = "li" else: self.inv_layer = "m1" + self.route_layer = "m2" super().__init__(name) self.create_netlist() self.create_layout() diff --git a/compiler/modules/rom_address_control_buf.py b/compiler/modules/rom_address_control_buf.py index 9e092ff0..b9cbbf44 100644 --- a/compiler/modules/rom_address_control_buf.py +++ b/compiler/modules/rom_address_control_buf.py @@ -25,8 +25,11 @@ class rom_address_control_buf(design): self.size = size if "li" in layer: self.inv_layer = "li" + self.non_inverting_layer = "m2" else: self.inv_layer = "m1" + self.route_layer = "m2" + self.non_inverting_layer = "m3" super().__init__(name) self.create_netlist() self.create_layout() @@ -47,11 +50,11 @@ class rom_address_control_buf(design): def create_modules(self): - self.inv = factory.create(module_type="pinv_dec", module_name="inv_array_mod", add_wells=False, size=self.size) - self.nand = factory.create(module_type="nand2_dec", height=self.inv.height) # For layout constants self.cell = factory.create(module_type="rom_base_cell") + self.nand = factory.create(module_type="nand2_dec") + self.inv = factory.create(module_type="pinv_dec", module_name="inv_array_mod", add_wells=False, size=self.size, height=self.nand.height) def add_pins(self): self.add_pin("A_in", "INPUT") @@ -129,18 +132,18 @@ class rom_address_control_buf(design): # Route first NAND output to second NAND input start = A_out.center() end = Aint_in.center() - self.add_path("m2", [start, end]) - self.add_via_stack_center(Aint_in.center(), self.inv_layer, "m2") - self.add_via_stack_center(A_out.center(), self.inv_layer, "m2") + self.add_path(self.non_inverting_layer, [start, end]) + self.add_via_stack_center(Aint_in.center(), self.inv_layer, self.non_inverting_layer) + self.add_via_stack_center(A_out.center(), self.inv_layer, self.non_inverting_layer) # Route first NAND to output pin - self.add_segment_center("m2", end, vector(end.x, self.addr_bar_nand.uy())) - self.add_layout_pin_rect_center("A_out", offset=vector(end.x, self.addr_bar_nand.uy() - 0.5 * self.m2_width), layer="m2") + self.add_segment_center(self.non_inverting_layer, end, vector(end.x, self.addr_bar_nand.uy())) + self.add_layout_pin_rect_center("A_out", offset=vector(end.x, self.addr_bar_nand.uy() - 0.5 * self.m2_width), layer=self.non_inverting_layer) # Route second NAND to output pin - self.add_via_stack_center(Abar_out.center(), self.inv_layer, "m2") - self.add_segment_center("m2", Abar_out.center(), vector(Abar_out.cx(), self.addr_bar_nand.uy())) - self.add_layout_pin_rect_center("Abar_out", offset=vector(Abar_out.cx(), self.addr_bar_nand.uy() - 0.5 * self.m2_width), layer="m2") + self.add_via_stack_center(Abar_out.center(), self.inv_layer, self.non_inverting_layer) + self.add_segment_center(self.non_inverting_layer, Abar_out.center(), vector(Abar_out.cx(), self.addr_bar_nand.uy())) + self.add_layout_pin_rect_center("Abar_out", offset=vector(Abar_out.cx(), self.addr_bar_nand.uy() - 0.5 * self.m2_width), layer=self.non_inverting_layer) # Route inverter output to NAND end = vector(Abar_int_out.cx(), Abar_in.cy() + 0.5 * self.interconnect_width) @@ -166,14 +169,17 @@ class rom_address_control_buf(design): left_edge = self.inv_inst.get_pin("Z").cx() - 2 * self.contact_width - 2 * self.active_contact_to_gate - 4 * self.active_enclose_contact - self.poly_width - self.active_space contact_pos = vector(left_edge, source_pin.cy()) - + self.add_layout_pin_rect_center("left_edge", offset=contact_pos, layer="m1") self.add_via_center(layers=self.active_stack, offset=contact_pos, implant_type="n", well_type="n") self.add_via_stack_center(offset=contact_pos, from_layer=self.active_stack[2], - to_layer=self.route_layer) + to_layer=self.route_layer, + min_area=True) + + # self.add_segment_center(layer=self.) contact_pos = vector(left_edge, gnd_pin.cy()) self.add_via_center(layers=self.active_stack, @@ -182,4 +188,5 @@ class rom_address_control_buf(design): well_type="p") self.add_via_stack_center(offset=contact_pos, from_layer=self.active_stack[2], - to_layer=self.route_layer) \ No newline at end of file + to_layer=self.route_layer, + min_area=True) \ No newline at end of file diff --git a/technology/gf180mcu/sp_lib/gf180mcu_3v3__nand2_1_dec.sp b/technology/gf180mcu/sp_lib/gf180mcu_3v3__nand2_1_dec.sp index f2e114c0..bba3f127 100644 --- a/technology/gf180mcu/sp_lib/gf180mcu_3v3__nand2_1_dec.sp +++ b/technology/gf180mcu/sp_lib/gf180mcu_3v3__nand2_1_dec.sp @@ -1,6 +1,6 @@ -.subckt gf180mcu_3v3__nand2_1_dec A B Y VDD VSS +.subckt gf180mcu_3v3__nand2_1_dec A B Y VDD GND X0 VDD B Y VDD pfet_03p3 w=1.7u l=0.3u X1 Y A VDD VDD pfet_03p3 w=1.7u l=0.3u -X2 a_28_21# A Y VSS nfet_03p3 w=0.85u l=0.3u -X3 VSS B a_28_21# VSS nfet_03p3 w=0.85u l=0.3u +X2 a_28_21# A Y GND nfet_03p3 w=0.85u l=0.3u +X3 VSS B a_28_21# GND nfet_03p3 w=0.85u l=0.3u .ends \ No newline at end of file diff --git a/technology/gf180mcu/tech/tech.py b/technology/gf180mcu/tech/tech.py index 6edf199f..c6f2259f 100644 --- a/technology/gf180mcu/tech/tech.py +++ b/technology/gf180mcu/tech/tech.py @@ -24,6 +24,7 @@ File containing the process technology parameters for Global Foundaries 180nm tech_modules = d.module_type() tech_modules["bitcell_1port"] = "gf180_bitcell" +tech_modules["nand2_dec"] = "nand2_dec" ################################################### # Custom cell properties @@ -48,6 +49,14 @@ cell_properties.bitcell_1port.bl_layer = "m2" cell_properties.bitcell_1port.vdd_layer = "m1" cell_properties.bitcell_1port.gnd_layer = "m1" +cell_properties.nand2_dec.port_order = ['A', 'B', 'Z', 'vdd', 'gnd'] +cell_properties.nand2_dec.port_map = {'A': 'A', + 'B': 'B', + 'Z': 'Y', + 'vdd': 'VDD', + 'gnd': 'GND'} + + cell_properties.ptx.model_is_subckt = True cell_properties.use_strap = True @@ -194,7 +203,7 @@ drc["grid"] = 0.005 # minwidth_tx with contact (no dog bone transistors) drc["minwidth_tx"] = 0.5 # PL.2 Min gate width/channel length for 6V pmos (0.7 for 6V nmos) -drc["minlength_channel"] = 0.7 +drc["minlength_channel"] = 0.28 drc["minlength_channel_pmos"] = 0.55 drc["minlength_channel_nmos"] = 0.7 @@ -209,10 +218,10 @@ drc.add_layer("pwell", width=0.74, # 0.6 for 3.3v spacing=0.86) # equal potential -# PL.1 minwidth of interconnect poly 5/6V -# PL.3a poly spacing 5/6V +# PL.1 minwidth of interconnect poly 3v3 +# PL.3a poly spacing 3v3 drc.add_layer("poly", - width=0.2, + width=0.28, spacing=0.24) drc["poly_extend_active"] = 0.22 @@ -226,12 +235,12 @@ drc["poly_to_active"] = 0.1 #drc["poly_to_field_poly"] = 0.210 # -# DF.1a - minwidth of active (5/6V) -# DF.3a - minspacing of active of the same type (5/6V) -# DF.9 - minarea of active area=0.2025 (5/6V) +# DF.1a - minwidth of active (3v3) +# min space of tap to diff across butted junction +# DF.9 - minarea of active area=0.2025 drc.add_layer("active", - width=0.3, - spacing=0.36, + width=0.22, + spacing=0.33, area=0.2025) drc.add_enclosure("dnwell", @@ -292,12 +301,12 @@ drc.add_layer("m1", drc.add_enclosure("m1", layer="contact", - enclosure=0.06, + enclosure=0, extension=0.06) drc.add_enclosure("m1", layer="via1", - enclosure=0.06, + enclosure=0, extension=0.06) drc.add_layer("via1",