Add enclosing well to column mux. Move well contact to cell boundary.

This commit is contained in:
Matt Guthaus 2018-06-29 11:35:29 -07:00
parent 3becf92e7c
commit 69921b0844
1 changed files with 40 additions and 34 deletions

View File

@ -31,7 +31,7 @@ class single_level_column_mux(design.design):
self.add_ptx()
self.pin_height = 2*self.m2_width
self.width = self.bitcell.width
self.height = self.nmos2.uy() + self.pin_height
self.height = self.nmos_upper.uy() + self.pin_height
self.connect_poly()
self.add_bitline_pins()
self.connect_bitlines()
@ -67,32 +67,32 @@ class single_level_column_mux(design.design):
def add_ptx(self):
""" Create the two pass gate NMOS transistors to switch the bitlines"""
# Adds nmos1,nmos2 to the module
# Adds nmos_lower,nmos_upper to the module
self.nmos = ptx(width=self.ptx_width)
self.add_mod(self.nmos)
# Space it in the center
nmos1_position = self.nmos.active_offset.scale(0,1) + vector(0.5*self.bitcell.width-0.5*self.nmos.active_width,0)
self.nmos1=self.add_inst(name="mux_tx1",
nmos_lower_position = self.nmos.active_offset.scale(0,1) + vector(0.5*self.bitcell.width-0.5*self.nmos.active_width,0)
self.nmos_lower=self.add_inst(name="mux_tx1",
mod=self.nmos,
offset=nmos1_position)
offset=nmos_lower_position)
self.connect_inst(["bl", "sel", "bl_out", "gnd"])
# This aligns it directly above the other tx with gates abutting
nmos2_position = nmos1_position + vector(0,self.nmos.active_height + self.poly_space)
self.nmos2=self.add_inst(name="mux_tx2",
nmos_upper_position = nmos_lower_position + vector(0,self.nmos.active_height + self.poly_space)
self.nmos_upper=self.add_inst(name="mux_tx2",
mod=self.nmos,
offset=nmos2_position)
offset=nmos_upper_position)
self.connect_inst(["br", "sel", "br_out", "gnd"])
def connect_poly(self):
""" Connect the poly gate of the two pass transistors """
height=self.nmos2.get_pin("G").uy() - self.nmos1.get_pin("G").by()
height=self.nmos_upper.get_pin("G").uy() - self.nmos_lower.get_pin("G").by()
self.add_layout_pin(text="sel",
layer="poly",
offset=self.nmos1.get_pin("G").ll(),
offset=self.nmos_lower.get_pin("G").ll(),
height=height)
@ -105,36 +105,36 @@ class single_level_column_mux(design.design):
br_out_pin = self.get_pin("br_out")
# These are on metal1
nmos1_s_pin = self.nmos1.get_pin("S")
nmos1_d_pin = self.nmos1.get_pin("D")
nmos2_s_pin = self.nmos2.get_pin("S")
nmos2_d_pin = self.nmos2.get_pin("D")
nmos_lower_s_pin = self.nmos_lower.get_pin("S")
nmos_lower_d_pin = self.nmos_lower.get_pin("D")
nmos_upper_s_pin = self.nmos_upper.get_pin("S")
nmos_upper_d_pin = self.nmos_upper.get_pin("D")
# Add vias to bl, br_out, nmos2/S, nmos1/D
# Add vias to bl, br_out, nmos_upper/S, nmos_lower/D
self.add_via_center(layers=("metal1","via1","metal2"),
offset=bl_pin.bc())
self.add_via_center(layers=("metal1","via1","metal2"),
offset=br_out_pin.uc())
self.add_via_center(layers=("metal1","via1","metal2"),
offset=nmos2_s_pin.center())
offset=nmos_upper_s_pin.center())
self.add_via_center(layers=("metal1","via1","metal2"),
offset=nmos1_d_pin.center())
offset=nmos_lower_d_pin.center())
# bl -> nmos2/D on metal1
# bl_out -> nmos2/S on metal2
self.add_path("metal1",[bl_pin.ll(), vector(nmos2_d_pin.cx(),bl_pin.by()), nmos2_d_pin.center()])
# bl -> nmos_upper/D on metal1
# bl_out -> nmos_upper/S on metal2
self.add_path("metal1",[bl_pin.ll(), vector(nmos_upper_d_pin.cx(),bl_pin.by()), nmos_upper_d_pin.center()])
# halfway up, move over
mid1 = bl_out_pin.uc().scale(1,0.5)+nmos2_s_pin.bc().scale(0,0.5)
mid2 = bl_out_pin.uc().scale(0,0.5)+nmos2_s_pin.bc().scale(1,0.5)
self.add_path("metal2",[bl_out_pin.uc(), mid1, mid2, nmos2_s_pin.bc()])
mid1 = bl_out_pin.uc().scale(1,0.5)+nmos_upper_s_pin.bc().scale(0,0.5)
mid2 = bl_out_pin.uc().scale(0,0.5)+nmos_upper_s_pin.bc().scale(1,0.5)
self.add_path("metal2",[bl_out_pin.uc(), mid1, mid2, nmos_upper_s_pin.bc()])
# br -> nmos1/D on metal2
# br_out -> nmos1/S on metal1
self.add_path("metal1",[br_out_pin.uc(), vector(nmos1_s_pin.cx(),br_out_pin.uy()), nmos1_s_pin.center()])
# br -> nmos_lower/D on metal2
# br_out -> nmos_lower/S on metal1
self.add_path("metal1",[br_out_pin.uc(), vector(nmos_lower_s_pin.cx(),br_out_pin.uy()), nmos_lower_s_pin.center()])
# halfway up, move over
mid1 = br_pin.bc().scale(1,0.5)+nmos1_d_pin.uc().scale(0,0.5)
mid2 = br_pin.bc().scale(0,0.5)+nmos1_d_pin.uc().scale(1,0.5)
self.add_path("metal2",[br_pin.bc(), mid1, mid2, nmos1_d_pin.uc()])
mid1 = br_pin.bc().scale(1,0.5)+nmos_lower_d_pin.uc().scale(0,0.5)
mid2 = br_pin.bc().scale(0,0.5)+nmos_lower_d_pin.uc().scale(1,0.5)
self.add_path("metal2",[br_pin.bc(), mid1, mid2, nmos_lower_d_pin.uc()])
def add_wells(self):
@ -144,11 +144,11 @@ class single_level_column_mux(design.design):
"""
# Add it to the right, aligned in between the two tx
active_pos = self.nmos2.lr().scale(0,0.5) + self.nmos1.ur().scale(1,0.5)
self.add_via_center(layers=("active", "contact", "metal1"),
offset=active_pos,
implant_type="p",
well_type="p")
active_pos = vector(self.bitcell.width,self.nmos_upper.by())
active_via = self.add_via_center(layers=("active", "contact", "metal1"),
offset=active_pos,
implant_type="p",
well_type="p")
# Add the M1->M2->M3 stack
@ -159,6 +159,12 @@ class single_level_column_mux(design.design):
self.add_layout_pin_rect_center(text="gnd",
layer="metal3",
offset=active_pos)
# Add well enclosure over all the tx and contact
self.add_rect(layer="pwell",
offset=vector(0,0),
width=self.bitcell.width,
height=self.height)