Generalize pgate width based on nwell/pwell contacts

This commit is contained in:
mrg 2020-02-25 17:09:07 +00:00
parent e80677caf7
commit 266d68c395
5 changed files with 21 additions and 41 deletions

View File

@ -264,3 +264,12 @@ class pgate(design.design):
# offset=implant_offset,
# width=implant_width,
# height=implant_height)
def determine_width(self):
""" Determine the width based on the well contacts (assumed to be on the right side) """
# Width is determined by well contact and spacing
self.width = max(self.nwell_contact.rx(), self.pwell_contact.rx()) + self.m1_space
self.well_width = self.width + 2 * self.nwell_enclose_active
# Height is an input parameter, so it is not recomputed.

View File

@ -51,9 +51,9 @@ class pinv(pgate.pgate):
def create_layout(self):
""" Calls all functions related to the generation of the layout """
self.setup_layout_constants()
self.place_ptx()
self.add_well_contacts()
self.determine_width()
self.extend_wells()
self.route_supply_rails()
self.connect_rails()
@ -147,21 +147,6 @@ class pinv(pgate.pgate):
debug.check(self.pmos_width >= drc("minwidth_tx"),
"Cannot finger PMOS transistors to fit cell height.")
def setup_layout_constants(self):
"""
Compute the width and height
"""
# the width is determined the multi-finger PMOS device width plus
# the well contact width, spacing between them
# space is for power supply contact to nwell m1 spacing
self.width = self.pmos.active_offset.x + self.pmos.active_width \
+ self.active_space + contact.nwell_contact.width \
+ 0.5 * self.nwell_enclose_active \
+ self.m1_space
# This includes full enclosures on each end
self.well_width = self.width + 2*self.nwell_enclose_active
# Height is an input parameter, so it is not recomputed.
def add_ptx(self):
""" Create the PMOS and NMOS transistors. """

View File

@ -49,10 +49,11 @@ class pnand2(pgate.pgate):
""" Calls all functions related to the generation of the layout """
self.setup_layout_constants()
self.route_supply_rails()
self.place_ptx()
self.connect_rails()
self.add_well_contacts()
self.determine_width()
self.route_supply_rails()
self.connect_rails()
self.extend_wells()
self.route_inputs()
self.route_output()
@ -96,15 +97,6 @@ class pnand2(pgate.pgate):
# source and drain pins
self.overlap_offset = self.pmos.get_pin("D").ll() - self.pmos.get_pin("S").ll()
# Two PMOS devices and a well contact. Separation between each.
# Enclosure space on the sides.
self.width = 2 * self.pmos.active_width + contact.active_contact.width \
+ 2 * self.active_space \
+ 0.5 * self.nwell_enclose_active
self.well_width = self.width + 2 * self.nwell_enclose_active
# Height is an input parameter, so it is not recomputed.
# This is the extra space needed to ensure DRC rules
# to the active contacts
extra_contact_space = max(-self.nmos.get_pin("D").by(), 0)

View File

@ -57,13 +57,15 @@ class pnand3(pgate.pgate):
""" Calls all functions related to the generation of the layout """
self.setup_layout_constants()
self.route_supply_rails()
self.place_ptx()
self.connect_rails()
self.add_well_contacts()
self.determine_width()
self.route_supply_rails()
self.connect_rails()
self.extend_wells()
self.route_inputs()
self.route_output()
def add_ptx(self):
""" Create the PMOS and NMOS transistors. """
@ -90,14 +92,6 @@ class pnand3(pgate.pgate):
overlap_xoffset = self.pmos.get_pin("D").ll().x - self.pmos.get_pin("S").ll().x
self.ptx_offset = vector(overlap_xoffset, 0)
# Two PMOS devices and a well contact. Separation between each.
# Enclosure space on the sides.
self.width = 3 * self.pmos.active_width + self.pmos.active_contact.width \
+ 2 * self.active_space + 0.5 * self.nwell_enclose_active \
- self.ptx_offset.x
self.well_width = self.width + 2 * self.nwell_enclose_active
# Height is an input parameter, so it is not recomputed.
# This is the extra space needed to ensure DRC rules
# to the active contacts
nmos = factory.create(module_type="ptx", tx_type="nmos")
@ -164,7 +158,6 @@ class pnand3(pgate.pgate):
self.pmos3_pos = pmos2_pos + self.ptx_offset
self.pmos3_inst.place(self.pmos3_pos)
nmos1_pos = vector(self.pmos.active_offset.x,
self.top_bottom_space)
self.nmos1_inst.place(nmos1_pos)
@ -189,7 +182,7 @@ class pnand3(pgate.pgate):
self.connect_pin_to_rail(self.nmos1_inst, "S", "gnd")
self.connect_pin_to_rail(self.pmos1_inst, "S", "vdd")
self.connect_pin_to_rail(self.pmos1_inst, "S", "vdd")
self.connect_pin_to_rail(self.pmos2_inst, "D", "vdd")

View File

@ -48,10 +48,11 @@ class pnor2(pgate.pgate):
""" Calls all functions related to the generation of the layout """
self.setup_layout_constants()
self.route_supply_rails()
self.place_ptx()
self.connect_rails()
self.add_well_contacts()
self.determine_width()
self.route_supply_rails()
self.connect_rails()
self.extend_wells()
self.route_inputs()
self.route_output()