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,
|
||||
# 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.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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. """
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Reference in New Issue