Update pnor2 to new placement logic

This commit is contained in:
Matt Guthaus 2019-08-07 16:01:05 -07:00
parent ae46a464b9
commit c2655fcaa9
1 changed files with 45 additions and 31 deletions

View File

@ -5,12 +5,13 @@
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
# #
import contact
import pgate import pgate
import debug import debug
from tech import drc, parameter, spice from tech import drc, parameter, spice
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
import contact import logical_effort
from sram_factory import factory from sram_factory import factory
class pnor2(pgate.pgate): class pnor2(pgate.pgate):
@ -38,28 +39,30 @@ class pnor2(pgate.pgate):
pgate.pgate.__init__(self, name, height) pgate.pgate.__init__(self, name, height)
def add_pins(self):
""" Adds pins for spice netlist """
pin_list = ["A", "B", "Z", "vdd", "gnd"]
dir_list = ["INPUT", "INPUT", "OUTPUT", "INOUT", "INOUT"]
self.add_pin_list(pin_list, dir_list)
def create_netlist(self): def create_netlist(self):
self.add_pins() self.add_pins()
self.add_ptx()
self.create_ptx() self.create_ptx()
self.setup_layout_constants()
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.add_supply_rails()
self.add_ptx() self.setup_layout_constants()
self.route_supply_rails()
self.place_ptx()
self.connect_rails() self.connect_rails()
self.add_well_contacts() self.add_well_contacts()
self.extend_wells(self.well_pos) self.extend_wells(self.well_pos)
self.route_inputs() self.route_inputs()
self.route_output() self.route_output()
def create_ptx(self): def add_pins(self):
""" Adds pins for spice netlist """
pin_list = ["A", "B", "Z", "vdd", "gnd"]
dir_list = ["INPUT", "INPUT", "OUTPUT", "INOUT", "INOUT"]
self.add_pin_list(pin_list, dir_list)
def add_ptx(self):
""" Create the PMOS and NMOS transistors. """ """ Create the PMOS and NMOS transistors. """
self.nmos = factory.create(module_type="ptx", self.nmos = factory.create(module_type="ptx",
width=self.nmos_width, width=self.nmos_width,
@ -104,7 +107,7 @@ class pnor2(pgate.pgate):
self.top_bottom_space = max(0.5*self.m1_width + self.m1_space + extra_contact_space, self.top_bottom_space = max(0.5*self.m1_width + self.m1_space + extra_contact_space,
drc("poly_extend_active"), self.poly_space) drc("poly_extend_active"), self.poly_space)
def add_supply_rails(self): def route_supply_rails(self):
""" Add vdd/gnd rails to the top and bottom. """ """ Add vdd/gnd rails to the top and bottom. """
self.add_layout_pin_rect_center(text="gnd", self.add_layout_pin_rect_center(text="gnd",
layer="metal1", layer="metal1",
@ -116,7 +119,31 @@ class pnor2(pgate.pgate):
offset=vector(0.5*self.width,self.height), offset=vector(0.5*self.width,self.height),
width=self.width) width=self.width)
def add_ptx(self): def create_ptx(self):
"""
Add PMOS and NMOS to the layout at the upper-most and lowest position
to provide maximum routing in channel
"""
self.pmos1_inst=self.add_inst(name="pnor2_pmos1",
mod=self.pmos)
self.connect_inst(["vdd", "A", "net1", "vdd"])
self.pmos2_inst = self.add_inst(name="pnor2_pmos2",
mod=self.pmos)
self.connect_inst(["net1", "B", "Z", "vdd"])
self.nmos1_inst=self.add_inst(name="pnor2_nmos1",
mod=self.nmos)
self.connect_inst(["Z", "A", "gnd", "gnd"])
self.nmos2_inst=self.add_inst(name="pnor2_nmos2",
mod=self.nmos)
self.connect_inst(["Z", "B", "gnd", "gnd"])
def place_ptx(self):
""" """
Add PMOS and NMOS to the layout at the upper-most and lowest position Add PMOS and NMOS to the layout at the upper-most and lowest position
to provide maximum routing in channel to provide maximum routing in channel
@ -124,29 +151,16 @@ class pnor2(pgate.pgate):
pmos1_pos = vector(self.pmos.active_offset.x, pmos1_pos = vector(self.pmos.active_offset.x,
self.height - self.pmos.active_height - self.top_bottom_space) self.height - self.pmos.active_height - self.top_bottom_space)
self.pmos1_inst=self.add_inst(name="pnor2_pmos1", self.pmos1_inst.place(pmos1_pos)
mod=self.pmos,
offset=pmos1_pos)
self.connect_inst(["vdd", "A", "net1", "vdd"])
self.pmos2_pos = pmos1_pos + self.overlap_offset self.pmos2_pos = pmos1_pos + self.overlap_offset
self.pmos2_inst = self.add_inst(name="pnor2_pmos2", self.pmos2_inst.place(self.pmos2_pos)
mod=self.pmos,
offset=self.pmos2_pos)
self.connect_inst(["net1", "B", "Z", "vdd"])
nmos1_pos = vector(self.pmos.active_offset.x, self.top_bottom_space) nmos1_pos = vector(self.pmos.active_offset.x, self.top_bottom_space)
self.nmos1_inst=self.add_inst(name="pnor2_nmos1", self.nmos1_inst.place(nmos1_pos)
mod=self.nmos,
offset=nmos1_pos)
self.connect_inst(["Z", "A", "gnd", "gnd"])
self.nmos2_pos = nmos1_pos + self.overlap_offset self.nmos2_pos = nmos1_pos + self.overlap_offset
self.nmos2_inst=self.add_inst(name="pnor2_nmos2", self.nmos2_inst.place(self.nmos2_pos)
mod=self.nmos,
offset=self.nmos2_pos)
self.connect_inst(["Z", "B", "gnd", "gnd"])
# Output position will be in between the PMOS and NMOS # Output position will be in between the PMOS and NMOS
self.output_pos = vector(0,0.5*(pmos1_pos.y+nmos1_pos.y+self.nmos.active_height)) self.output_pos = vector(0,0.5*(pmos1_pos.y+nmos1_pos.y+self.nmos.active_height))