mirror of https://github.com/VLSIDA/OpenRAM.git
Generalize pgate width based on nwell/pwell contacts
This commit is contained in:
parent
e80677caf7
commit
266d68c395
|
|
@ -264,3 +264,12 @@ class pgate(design.design):
|
||||||
# offset=implant_offset,
|
# offset=implant_offset,
|
||||||
# width=implant_width,
|
# width=implant_width,
|
||||||
# height=implant_height)
|
# 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.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,9 +51,9 @@ class pinv(pgate.pgate):
|
||||||
|
|
||||||
def create_layout(self):
|
def create_layout(self):
|
||||||
""" Calls all functions related to the generation of the layout """
|
""" Calls all functions related to the generation of the layout """
|
||||||
self.setup_layout_constants()
|
|
||||||
self.place_ptx()
|
self.place_ptx()
|
||||||
self.add_well_contacts()
|
self.add_well_contacts()
|
||||||
|
self.determine_width()
|
||||||
self.extend_wells()
|
self.extend_wells()
|
||||||
self.route_supply_rails()
|
self.route_supply_rails()
|
||||||
self.connect_rails()
|
self.connect_rails()
|
||||||
|
|
@ -147,21 +147,6 @@ class pinv(pgate.pgate):
|
||||||
debug.check(self.pmos_width >= drc("minwidth_tx"),
|
debug.check(self.pmos_width >= drc("minwidth_tx"),
|
||||||
"Cannot finger PMOS transistors to fit cell height.")
|
"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):
|
def add_ptx(self):
|
||||||
""" Create the PMOS and NMOS transistors. """
|
""" Create the PMOS and NMOS transistors. """
|
||||||
|
|
|
||||||
|
|
@ -49,10 +49,11 @@ class pnand2(pgate.pgate):
|
||||||
""" Calls all functions related to the generation of the layout """
|
""" Calls all functions related to the generation of the layout """
|
||||||
|
|
||||||
self.setup_layout_constants()
|
self.setup_layout_constants()
|
||||||
self.route_supply_rails()
|
|
||||||
self.place_ptx()
|
self.place_ptx()
|
||||||
self.connect_rails()
|
|
||||||
self.add_well_contacts()
|
self.add_well_contacts()
|
||||||
|
self.determine_width()
|
||||||
|
self.route_supply_rails()
|
||||||
|
self.connect_rails()
|
||||||
self.extend_wells()
|
self.extend_wells()
|
||||||
self.route_inputs()
|
self.route_inputs()
|
||||||
self.route_output()
|
self.route_output()
|
||||||
|
|
@ -96,15 +97,6 @@ class pnand2(pgate.pgate):
|
||||||
# source and drain pins
|
# source and drain pins
|
||||||
self.overlap_offset = self.pmos.get_pin("D").ll() - self.pmos.get_pin("S").ll()
|
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
|
# This is the extra space needed to ensure DRC rules
|
||||||
# to the active contacts
|
# to the active contacts
|
||||||
extra_contact_space = max(-self.nmos.get_pin("D").by(), 0)
|
extra_contact_space = max(-self.nmos.get_pin("D").by(), 0)
|
||||||
|
|
|
||||||
|
|
@ -57,13 +57,15 @@ class pnand3(pgate.pgate):
|
||||||
""" Calls all functions related to the generation of the layout """
|
""" Calls all functions related to the generation of the layout """
|
||||||
|
|
||||||
self.setup_layout_constants()
|
self.setup_layout_constants()
|
||||||
self.route_supply_rails()
|
|
||||||
self.place_ptx()
|
self.place_ptx()
|
||||||
self.connect_rails()
|
|
||||||
self.add_well_contacts()
|
self.add_well_contacts()
|
||||||
|
self.determine_width()
|
||||||
|
self.route_supply_rails()
|
||||||
|
self.connect_rails()
|
||||||
self.extend_wells()
|
self.extend_wells()
|
||||||
self.route_inputs()
|
self.route_inputs()
|
||||||
self.route_output()
|
self.route_output()
|
||||||
|
|
||||||
|
|
||||||
def add_ptx(self):
|
def add_ptx(self):
|
||||||
""" Create the PMOS and NMOS transistors. """
|
""" 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
|
overlap_xoffset = self.pmos.get_pin("D").ll().x - self.pmos.get_pin("S").ll().x
|
||||||
self.ptx_offset = vector(overlap_xoffset, 0)
|
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
|
# This is the extra space needed to ensure DRC rules
|
||||||
# to the active contacts
|
# to the active contacts
|
||||||
nmos = factory.create(module_type="ptx", tx_type="nmos")
|
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_pos = pmos2_pos + self.ptx_offset
|
||||||
self.pmos3_inst.place(self.pmos3_pos)
|
self.pmos3_inst.place(self.pmos3_pos)
|
||||||
|
|
||||||
|
|
||||||
nmos1_pos = vector(self.pmos.active_offset.x,
|
nmos1_pos = vector(self.pmos.active_offset.x,
|
||||||
self.top_bottom_space)
|
self.top_bottom_space)
|
||||||
self.nmos1_inst.place(nmos1_pos)
|
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.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")
|
self.connect_pin_to_rail(self.pmos2_inst, "D", "vdd")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,10 +48,11 @@ class pnor2(pgate.pgate):
|
||||||
""" Calls all functions related to the generation of the layout """
|
""" Calls all functions related to the generation of the layout """
|
||||||
|
|
||||||
self.setup_layout_constants()
|
self.setup_layout_constants()
|
||||||
self.route_supply_rails()
|
|
||||||
self.place_ptx()
|
self.place_ptx()
|
||||||
self.connect_rails()
|
|
||||||
self.add_well_contacts()
|
self.add_well_contacts()
|
||||||
|
self.determine_width()
|
||||||
|
self.route_supply_rails()
|
||||||
|
self.connect_rails()
|
||||||
self.extend_wells()
|
self.extend_wells()
|
||||||
self.route_inputs()
|
self.route_inputs()
|
||||||
self.route_output()
|
self.route_output()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue