mirror of https://github.com/VLSIDA/OpenRAM.git
col_mux.py changes
This commit is contained in:
parent
7920b0cef9
commit
63bea67fb5
|
|
@ -7,7 +7,7 @@
|
|||
#
|
||||
import pgate
|
||||
import debug
|
||||
from tech import drc
|
||||
from tech import drc, layer
|
||||
from vector import vector
|
||||
from sram_factory import factory
|
||||
import logical_effort
|
||||
|
|
@ -22,13 +22,13 @@ class single_level_column_mux(pgate.pgate):
|
|||
for optimal speed
|
||||
"""
|
||||
def __init__(self, name, tx_size=8, bitcell_bl="bl", bitcell_br="br"):
|
||||
|
||||
|
||||
debug.info(2, "creating single column mux cell: {0}".format(name))
|
||||
|
||||
self.tx_size = int(tx_size)
|
||||
self.bitcell_bl = bitcell_bl
|
||||
self.bitcell_br = bitcell_br
|
||||
|
||||
|
||||
pgate.pgate.__init__(self, name)
|
||||
|
||||
def get_bl_names(self):
|
||||
|
|
@ -41,9 +41,9 @@ class single_level_column_mux(pgate.pgate):
|
|||
self.add_modules()
|
||||
self.add_pins()
|
||||
self.add_ptx()
|
||||
|
||||
|
||||
def create_layout(self):
|
||||
|
||||
|
||||
self.pin_height = 2 * self.m2_width
|
||||
self.width = self.bitcell.width
|
||||
self.height = self.nmos_upper.uy() + self.pin_height
|
||||
|
|
@ -59,39 +59,42 @@ class single_level_column_mux(pgate.pgate):
|
|||
self.ptx_width = self.tx_size * drc("minwidth_tx")
|
||||
self.nmos = factory.create(module_type="ptx", width=self.ptx_width)
|
||||
self.add_mod(self.nmos)
|
||||
|
||||
|
||||
def add_pins(self):
|
||||
self.add_pin_list(["bl", "br", "bl_out", "br_out", "sel", "gnd"])
|
||||
|
||||
def add_bitline_pins(self):
|
||||
""" Add the top and bottom pins to this cell """
|
||||
|
||||
bl_pos = vector(self.bitcell.get_pin(self.bitcell_bl).lx(), 0)
|
||||
br_pos = vector(self.bitcell.get_pin(self.bitcell_br).lx(), 0)
|
||||
bl_pin=self.bitcell.get_pin(self.bitcell_bl)
|
||||
br_pin=self.bitcell.get_pin(self.bitcell_br)
|
||||
|
||||
bl_pos = vector(bl_pin.lx(), 0)
|
||||
br_pos = vector(br_pin.lx(), 0)
|
||||
|
||||
# bl and br
|
||||
self.add_layout_pin(text="bl",
|
||||
layer="m2",
|
||||
layer=bl_pin.layer,
|
||||
offset=bl_pos + vector(0, self.height - self.pin_height),
|
||||
height=self.pin_height)
|
||||
self.add_layout_pin(text="br",
|
||||
layer="m2",
|
||||
layer=br_pin.layer,
|
||||
offset=br_pos + vector(0, self.height - self.pin_height),
|
||||
height=self.pin_height)
|
||||
|
||||
|
||||
# bl_out and br_out
|
||||
self.add_layout_pin(text="bl_out",
|
||||
layer="m2",
|
||||
layer=bl_pin.layer,
|
||||
offset=bl_pos,
|
||||
height=self.pin_height)
|
||||
self.add_layout_pin(text="br_out",
|
||||
layer="m2",
|
||||
layer=br_pin.layer,
|
||||
offset=br_pos,
|
||||
height=self.pin_height)
|
||||
|
||||
def add_ptx(self):
|
||||
""" Create the two pass gate NMOS transistors to switch the bitlines"""
|
||||
|
||||
|
||||
# Space it in the center
|
||||
nmos_lower_position = self.nmos.active_offset.scale(0,1) \
|
||||
+ vector(0.5 * self.bitcell.width- 0.5 * self.nmos.active_width, 0)
|
||||
|
|
@ -102,7 +105,7 @@ class single_level_column_mux(pgate.pgate):
|
|||
|
||||
# This aligns it directly above the other tx with gates abutting
|
||||
nmos_upper_position = nmos_lower_position \
|
||||
+ vector(0, self.nmos.active_height + self.poly_space)
|
||||
+ vector(0, self.nmos.active_height + self.active_space)
|
||||
self.nmos_upper = self.add_inst(name="mux_tx2",
|
||||
mod=self.nmos,
|
||||
offset=nmos_upper_position)
|
||||
|
|
@ -110,12 +113,11 @@ class single_level_column_mux(pgate.pgate):
|
|||
|
||||
def connect_poly(self):
|
||||
""" Connect the poly gate of the two pass transistors """
|
||||
|
||||
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.nmos_lower.get_pin("G").ll(),
|
||||
height=height)
|
||||
offset=self.nmos_lower.get_pin("G").ul() - vector(0,self.poly_extend_active),
|
||||
height=self.active_space)
|
||||
|
||||
def connect_bitlines(self):
|
||||
""" Connect the bitlines to the mux transistors """
|
||||
|
|
@ -131,36 +133,42 @@ class single_level_column_mux(pgate.pgate):
|
|||
nmos_upper_s_pin = self.nmos_upper.get_pin("S")
|
||||
nmos_upper_d_pin = self.nmos_upper.get_pin("D")
|
||||
|
||||
# If li exists, use li and m1 for the mux, otherwise use m1 and m2
|
||||
if "li" in layer:
|
||||
col_mux_stack = self.li_stack
|
||||
else:
|
||||
col_mux_stack = self.m1_stack
|
||||
|
||||
# Add vias to bl, br_out, nmos_upper/S, nmos_lower/D
|
||||
self.add_via_center(layers=self.m1_stack,
|
||||
self.add_via_center(layers=col_mux_stack,
|
||||
offset=bl_pin.bc(),
|
||||
directions=("V", "V"))
|
||||
self.add_via_center(layers=self.m1_stack,
|
||||
self.add_via_center(layers=col_mux_stack,
|
||||
offset=br_out_pin.uc(),
|
||||
directions=("V", "V"))
|
||||
self.add_via_center(layers=self.m1_stack,
|
||||
self.add_via_center(layers=col_mux_stack,
|
||||
offset=nmos_upper_s_pin.center(),
|
||||
directions=("V", "V"))
|
||||
self.add_via_center(layers=self.m1_stack,
|
||||
self.add_via_center(layers=col_mux_stack,
|
||||
offset=nmos_lower_d_pin.center(),
|
||||
directions=("V", "V"))
|
||||
|
||||
|
||||
# bl -> nmos_upper/D on metal1
|
||||
# bl_out -> nmos_upper/S on metal2
|
||||
self.add_path("m1",
|
||||
self.add_path(col_mux_stack[0],
|
||||
[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.4) \
|
||||
+ nmos_upper_s_pin.bc().scale(0, 0.4)
|
||||
mid2 = bl_out_pin.uc().scale(0, 0.4) \
|
||||
+ nmos_upper_s_pin.bc().scale(1, 0.4)
|
||||
self.add_path("m2",
|
||||
[bl_out_pin.uc(), mid1, mid2, nmos_upper_s_pin.bc()])
|
||||
|
||||
+ nmos_upper_s_pin.bc().scale(1, 0.4)
|
||||
self.add_path(col_mux_stack[2],
|
||||
[bl_out_pin.uc(), mid1, mid2, nmos_upper_s_pin.center()])
|
||||
|
||||
# br -> nmos_lower/D on metal2
|
||||
# br_out -> nmos_lower/S on metal1
|
||||
self.add_path("m1",
|
||||
self.add_path(col_mux_stack[0],
|
||||
[br_out_pin.uc(),
|
||||
vector(nmos_lower_s_pin.cx(), br_out_pin.uy()),
|
||||
nmos_lower_s_pin.center()])
|
||||
|
|
@ -169,9 +177,9 @@ class single_level_column_mux(pgate.pgate):
|
|||
+ 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("m2",
|
||||
[br_pin.bc(), mid1, mid2, nmos_lower_d_pin.uc()])
|
||||
|
||||
self.add_path(col_mux_stack[2],
|
||||
[br_pin.bc(), mid1, mid2, nmos_lower_d_pin.center()])
|
||||
|
||||
def add_wells(self):
|
||||
"""
|
||||
Add a well and implant over the whole cell. Also, add the
|
||||
|
|
@ -192,11 +200,12 @@ class single_level_column_mux(pgate.pgate):
|
|||
start_layer="m1")
|
||||
|
||||
# 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)
|
||||
|
||||
if "pwell" in layer:
|
||||
self.add_rect(layer="pwell",
|
||||
offset=vector(0, 0),
|
||||
width=self.bitcell.width,
|
||||
height=self.height)
|
||||
|
||||
def get_stage_effort(self, corner, slew, load):
|
||||
"""
|
||||
Returns relative delay that the column mux.
|
||||
|
|
@ -211,4 +220,3 @@ class single_level_column_mux(pgate.pgate):
|
|||
load,
|
||||
parasitic_delay,
|
||||
False)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue