From cddb16dabce5c1d945c9bb80a21ea871ca564a5f Mon Sep 17 00:00:00 2001 From: mrg Date: Wed, 24 Jun 2020 09:17:39 -0700 Subject: [PATCH] Separate active and poly contact to gate rule --- compiler/base/design.py | 3 ++- compiler/pgates/pnand2.py | 4 ++-- compiler/pgates/pnand3.py | 7 +++---- compiler/pgates/precharge.py | 2 +- compiler/pgates/ptx.py | 6 +++--- technology/freepdk45/tech/tech.py | 4 ++-- technology/scn4m_subm/tech/tech.py | 4 ++-- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/compiler/base/design.py b/compiler/base/design.py index 1fded37e..2b2d7711 100644 --- a/compiler/base/design.py +++ b/compiler/base/design.py @@ -205,7 +205,8 @@ class design(hierarchy_design): 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("active_contact_to_gate", self.active_contact_to_gate) + print("poly_contact_to_gate", self.poly_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) diff --git a/compiler/pgates/pnand2.py b/compiler/pgates/pnand2.py index 12323885..9cc530c0 100644 --- a/compiler/pgates/pnand2.py +++ b/compiler/pgates/pnand2.py @@ -184,7 +184,7 @@ class pnand2(pgate.pgate): # doesn't use nmos uy because that is calculated using offset + poly height active_top = self.nmos1_inst.by() + self.nmos1_inst.mod.active_height active_to_poly_contact = active_top + self.poly_to_active + 0.5 * contact.poly_contact.first_layer_height - active_to_poly_contact2 = active_top + drc("contact_to_gate") + 0.5 * self.route_layer_width + active_to_poly_contact2 = active_top + self.poly_contact_to_gate + 0.5 * self.route_layer_width self.inputA_yoffset = max(active_contact_to_poly_contact, active_to_poly_contact, active_to_poly_contact2) @@ -200,7 +200,7 @@ class pnand2(pgate.pgate): # active_contact_to_poly_contact = self.output_yoffset - self.route_layer_space - 0.5 * contact.poly_contact.second_layer_height # active_bottom = self.pmos1_inst.by() # active_to_poly_contact = active_bottom - self.poly_to_active - 0.5 * contact.poly_contact.first_layer_height - # active_to_poly_contact2 = active_bottom - drc("contact_to_gate") - 0.5 * self.route_layer_width + # active_to_poly_contact2 = active_bottom - self.poly_contact_to_gate - 0.5 * self.route_layer_width # self.inputB_yoffset = min(active_contact_to_poly_contact, # active_to_poly_contact, # active_to_poly_contact2) diff --git a/compiler/pgates/pnand3.py b/compiler/pgates/pnand3.py index e227d7af..03652b9b 100644 --- a/compiler/pgates/pnand3.py +++ b/compiler/pgates/pnand3.py @@ -222,7 +222,7 @@ class pnand3(pgate.pgate): # doesn't use nmos uy because that is calculated using offset + poly height active_top = self.nmos1_inst.by() + self.nmos1_inst.mod.active_height active_to_poly_contact = active_top + self.poly_to_active + 0.5 * contact.poly_contact.first_layer_height - active_to_poly_contact2 = active_top + drc("contact_to_gate") + 0.5 * self.route_layer_width + active_to_poly_contact2 = active_top + self.poly_contact_to_gate + 0.5 * self.route_layer_width self.inputA_yoffset = max(active_contact_to_poly_contact, active_to_poly_contact, active_to_poly_contact2) @@ -233,15 +233,14 @@ class pnand3(pgate.pgate): "A", position="left") - # Put B right on the well line - self.inputB_yoffset = self.inputA_yoffset + non_contact_pitch + self.inputB_yoffset = self.inputA_yoffset + 1.2 * self.m3_pitch self.route_input_gate(self.pmos2_inst, self.nmos2_inst, self.inputB_yoffset, "B", position="center") - self.inputC_yoffset = self.inputB_yoffset + non_contact_pitch + self.inputC_yoffset = self.inputB_yoffset + 1.2 * self.m3_pitch self.route_input_gate(self.pmos3_inst, self.nmos3_inst, self.inputC_yoffset, diff --git a/compiler/pgates/precharge.py b/compiler/pgates/precharge.py index fdce1a35..dc016cab 100644 --- a/compiler/pgates/precharge.py +++ b/compiler/pgates/precharge.py @@ -196,7 +196,7 @@ class precharge(design.design): pin_offset = self.lower_pmos_inst.get_pin("G").lr() # This is an extra space down for some techs with contact to active spacing contact_space = max(self.poly_space, - self.contact_to_gate) + 0.5 * contact.poly_contact.first_layer_height + self.poly_contact_to_gate) + 0.5 * contact.poly_contact.first_layer_height offset = pin_offset - vector(0, contact_space) self.add_via_stack_center(from_layer="poly", to_layer=self.en_layer, diff --git a/compiler/pgates/ptx.py b/compiler/pgates/ptx.py index 9af08e61..8be003b2 100644 --- a/compiler/pgates/ptx.py +++ b/compiler/pgates/ptx.py @@ -196,7 +196,7 @@ class ptx(design.design): # This is the spacing between the poly gates self.min_poly_pitch = self.poly_space + self.poly_width self.contacted_poly_pitch = self.poly_space + contact.poly_contact.width - self.contact_pitch = 2 * self.contact_to_gate + self.poly_width + self.contact_width + self.contact_pitch = 2 * self.active_contact_to_gate + self.poly_width + self.contact_width self.poly_pitch = max(self.min_poly_pitch, self.contacted_poly_pitch, self.contact_pitch) @@ -206,7 +206,7 @@ class ptx(design.design): # Active width is determined by enclosure on both ends and contacted pitch, # at least one poly and n-1 poly pitches self.active_width = 2 * self.end_to_contact + self.active_contact.width \ - + 2 * self.contact_to_gate + self.poly_width + (self.mults - 1) * self.poly_pitch + + 2 * self.active_contact_to_gate + self.poly_width + (self.mults - 1) * self.poly_pitch # Active height is just the transistor width self.active_height = self.tx_width @@ -321,7 +321,7 @@ class ptx(design.design): """ # poly is one contacted spacing from the end and down an extension poly_offset = self.contact_offset \ - + vector(0.5 * self.active_contact.width + 0.5 * self.poly_width + self.contact_to_gate, 0) + + vector(0.5 * self.active_contact.width + 0.5 * self.poly_width + self.active_contact_to_gate, 0) # poly_positions are the bottom center of the poly gates self.poly_positions = [] diff --git a/technology/freepdk45/tech/tech.py b/technology/freepdk45/tech/tech.py index c0379e44..6de01254 100644 --- a/technology/freepdk45/tech/tech.py +++ b/technology/freepdk45/tech/tech.py @@ -234,9 +234,9 @@ drc.add_enclosure("active", enclosure = 0.005) # CONTACT.6 Minimum spacing of contact and gate -drc["contact_to_gate"] = 0.0375 #changed from 0.035 +drc["active_contact_to_gate"] = 0.0375 #changed from 0.035 # CONTACT.7 Minimum spacing of contact and poly -drc["contact_to_poly"] = 0.090 +drc["poly_contact_to_gate"] = 0.090 # CONTACT.1 Minimum width of contact # CONTACT.2 Minimum spacing of contact diff --git a/technology/scn4m_subm/tech/tech.py b/technology/scn4m_subm/tech/tech.py index 745b381e..55826ec5 100644 --- a/technology/scn4m_subm/tech/tech.py +++ b/technology/scn4m_subm/tech/tech.py @@ -217,9 +217,9 @@ drc.add_enclosure("active", layer = "contact", enclosure = _lambda_) # Reserved for other technologies -drc["contact_to_gate"] = 2*_lambda_ +drc["active_contact_to_gate"] = 2*_lambda_ # 5.4 Minimum spacing to gate of transistor -drc["contact_to_poly"] = 2*_lambda_ +drc["poly_contact_to_gate"] = 2*_lambda_ # 6.1 Exact contact size # 5.3 Minimum contact spacing