mirror of https://github.com/VLSIDA/OpenRAM.git
Incomplete precharge layer decoupling
This commit is contained in:
parent
bb2305d56a
commit
7ba9e09e12
|
|
@ -517,12 +517,12 @@ class layout():
|
|||
self.connect_inst([])
|
||||
return inst
|
||||
|
||||
def add_via_stack(self, offset, direction, from_layer, to_layer,
|
||||
def add_via_stack(self, offset, from_layer, to_layer,
|
||||
direction=None,
|
||||
size=[1, 1]):
|
||||
"""
|
||||
Punch a stack of vias from a start layer to a target layer.
|
||||
"""
|
||||
|
||||
return self.__add_via_stack_internal(offset=offset,
|
||||
direction=direction,
|
||||
from_layer=from_layer,
|
||||
|
|
@ -531,7 +531,8 @@ class layout():
|
|||
last_via=None,
|
||||
size=size)
|
||||
|
||||
def add_via_stack_center(self, offset, direction, from_layer, to_layer,
|
||||
def add_via_stack_center(self, offset, from_layer, to_layer,
|
||||
direction=None,
|
||||
size=[1, 1]):
|
||||
"""
|
||||
Punch a stack of vias from a start layer to a target layer by the center
|
||||
|
|
@ -545,7 +546,6 @@ class layout():
|
|||
last_via=None,
|
||||
size=size)
|
||||
|
||||
|
||||
def __add_via_stack_internal(self, offset, direction, from_layer, to_layer,
|
||||
via_func, last_via, size):
|
||||
"""
|
||||
|
|
@ -581,7 +581,6 @@ class layout():
|
|||
last_via=via,
|
||||
size=size)
|
||||
|
||||
|
||||
def add_ptx(self, offset, mirror="R0", rotate=0, width=1, mults=1, tx_type="nmos"):
|
||||
"""Adds a ptx module to the design."""
|
||||
import ptx
|
||||
|
|
|
|||
|
|
@ -521,7 +521,7 @@ class hierarchical_decoder(design.design):
|
|||
""" Add a pin for each row of vdd/gnd which are must-connects next level up. """
|
||||
|
||||
# The vias will be placed in the center and right of the cells, respectively.
|
||||
xoffset = self.nand_inst[0].cx()
|
||||
xoffset = self.nand_inst[0].rx()
|
||||
for num in range(0, self.rows):
|
||||
for pin_name in ["vdd", "gnd"]:
|
||||
# The nand and inv are the same height rows...
|
||||
|
|
|
|||
|
|
@ -75,8 +75,7 @@ class wordline_driver(design.design):
|
|||
"""
|
||||
|
||||
# Find the x offsets for where the vias/pins should be placed
|
||||
a_xoffset = self.nand_inst[0].rx()
|
||||
b_xoffset = self.inv2_inst[0].lx()
|
||||
a_xoffset = self.nand_inst[0].lx()
|
||||
for num in range(self.rows):
|
||||
# this will result in duplicate polygons for rails, but who cares
|
||||
|
||||
|
|
@ -90,7 +89,7 @@ class wordline_driver(design.design):
|
|||
supply_pin = self.inv2_inst[num].get_pin(name)
|
||||
|
||||
# Add pins in two locations
|
||||
for xoffset in [a_xoffset, b_xoffset]:
|
||||
for xoffset in [a_xoffset]:
|
||||
pin_pos = vector(xoffset, supply_pin.cy())
|
||||
self.add_power_pin(name, pin_pos)
|
||||
|
||||
|
|
|
|||
|
|
@ -267,8 +267,8 @@ class pgate(design.design):
|
|||
|
||||
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
|
||||
# Width is determined by well contact and spacing and allowing a supply via between each cell
|
||||
self.width = max(self.nwell_contact.rx(), self.pwell_contact.rx()) + self.m1_space + 0.5 * contact.m1_via.width
|
||||
self.well_width = self.width + 2 * self.nwell_enclose_active
|
||||
# Height is an input parameter, so it is not recomputed.
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ from tech import parameter
|
|||
from vector import vector
|
||||
from globals import OPTS
|
||||
from sram_factory import factory
|
||||
|
||||
from tech import drc
|
||||
|
||||
class precharge(design.design):
|
||||
"""
|
||||
|
|
@ -30,7 +30,10 @@ class precharge(design.design):
|
|||
self.width = self.bitcell.width
|
||||
self.bitcell_bl = bitcell_bl
|
||||
self.bitcell_br = bitcell_br
|
||||
|
||||
self.bitcell_bl_pin =self.bitcell.get_pin(self.bitcell_bl)
|
||||
self.bitcell_br_pin =self.bitcell.get_pin(self.bitcell_br)
|
||||
print(self.bitcell_bl_pin)
|
||||
print(self.bitcell_br_pin)
|
||||
# Creates the netlist and layout
|
||||
# Since it has variable height, it is not a pgate.
|
||||
self.create_netlist()
|
||||
|
|
@ -50,6 +53,7 @@ class precharge(design.design):
|
|||
self.create_ptx()
|
||||
|
||||
def create_layout(self):
|
||||
|
||||
self.place_ptx()
|
||||
self.connect_poly()
|
||||
self.route_en()
|
||||
|
|
@ -120,17 +124,18 @@ class precharge(design.design):
|
|||
contact_xdiff = self.pmos.get_pin("S").lx()
|
||||
|
||||
# adds the lower pmos to layout
|
||||
bl_xoffset = self.bitcell.get_pin(self.bitcell_bl).lx()
|
||||
bl_xoffset = self.bitcell_bl_pin.lx()
|
||||
self.lower_pmos_position = vector(max(bl_xoffset - contact_xdiff,
|
||||
self.nwell_enclose_active),
|
||||
self.pmos.active_offset.y)
|
||||
self.lower_pmos_inst.place(self.lower_pmos_position)
|
||||
|
||||
# adds the upper pmos(s) to layout
|
||||
ydiff = self.pmos.height + 2 * self.m1_space + contact.poly_contact.width
|
||||
ydiff = self.pmos.height + 4 * self.m2_space
|
||||
self.upper_pmos1_pos = self.lower_pmos_position + vector(0, ydiff)
|
||||
self.upper_pmos1_inst.place(self.upper_pmos1_pos)
|
||||
|
||||
# Second pmos to the right of the first
|
||||
upper_pmos2_pos = self.upper_pmos1_pos + overlap_offset
|
||||
self.upper_pmos2_inst.place(upper_pmos2_pos)
|
||||
|
||||
|
|
@ -162,15 +167,24 @@ class precharge(design.design):
|
|||
Adds the en input rail, en contact/vias, and connects to the pmos
|
||||
"""
|
||||
|
||||
if self.bitcell_bl_pin.layer == "m1":
|
||||
layer = "m2"
|
||||
else:
|
||||
layer = "m1"
|
||||
|
||||
# adds the en contact to connect the gates to the en rail on metal1
|
||||
offset = self.lower_pmos_inst.get_pin("G").ul() \
|
||||
+ vector(0, 0.5 * self.poly_space)
|
||||
+ vector(0, self.m2_pitch)
|
||||
self.add_via_center(layers=self.poly_stack,
|
||||
offset=offset)
|
||||
if layer == "m2":
|
||||
self.add_via_center(layers=self.m1_stack,
|
||||
offset=offset)
|
||||
|
||||
|
||||
# adds the en rail on metal1
|
||||
self.add_layout_pin_segment_center(text="en_bar",
|
||||
layer="m1",
|
||||
layer=layer,
|
||||
start=offset.scale(0, 1),
|
||||
end=offset.scale(0, 1) + vector(self.width, 0))
|
||||
|
||||
|
|
@ -201,20 +215,21 @@ class precharge(design.design):
|
|||
"""
|
||||
Adds both bit-line and bit-line-bar to the module
|
||||
"""
|
||||
layer_width = drc("minwidth_" + self.bitcell_br_pin.layer)
|
||||
layer_space = drc("{0}_to_{0}".format(self.bitcell_br_pin.layer))
|
||||
layer = self.bitcell_bl_pin.layer
|
||||
|
||||
# adds the BL on metal 2
|
||||
offset = vector(self.bitcell.get_pin(self.bitcell_bl).cx(), 0) \
|
||||
- vector(0.5 * self.m2_width, 0)
|
||||
offset = vector(layer_space - 0.5 * layer_width, 0)
|
||||
self.bl_pin = self.add_layout_pin(text="bl",
|
||||
layer="m2",
|
||||
layer=layer,
|
||||
offset=offset,
|
||||
height=self.height)
|
||||
|
||||
# adds the BR on metal 2
|
||||
offset = vector(self.bitcell.get_pin(self.bitcell_br).cx(), 0) \
|
||||
- vector(0.5 * self.m2_width, 0)
|
||||
offset = vector(self.width - layer_space - 0.5 * layer_width, 0)
|
||||
self.br_pin = self.add_layout_pin(text="br",
|
||||
layer="m2",
|
||||
layer=layer,
|
||||
offset=offset,
|
||||
height=self.height)
|
||||
|
||||
|
|
@ -225,11 +240,12 @@ class precharge(design.design):
|
|||
self.add_bitline_contacts()
|
||||
self.connect_pmos_m2(self.lower_pmos_inst.get_pin("S"),
|
||||
self.get_pin("bl"))
|
||||
self.connect_pmos_m2(self.lower_pmos_inst.get_pin("D"),
|
||||
self.get_pin("br"))
|
||||
|
||||
self.connect_pmos_m2(self.upper_pmos1_inst.get_pin("S"),
|
||||
self.get_pin("bl"))
|
||||
self.connect_pmos_m1(self.lower_pmos_inst.get_pin("D"),
|
||||
self.get_pin("br"))
|
||||
self.connect_pmos_m1(self.upper_pmos2_inst.get_pin("D"),
|
||||
self.connect_pmos_m2(self.upper_pmos2_inst.get_pin("D"),
|
||||
self.get_pin("br"))
|
||||
|
||||
def add_bitline_contacts(self):
|
||||
|
|
@ -237,34 +253,28 @@ class precharge(design.design):
|
|||
Adds contacts/via from metal1 to metal2 for bit-lines
|
||||
"""
|
||||
|
||||
upper_pin = self.upper_pmos1_inst.get_pin("S")
|
||||
lower_pin = self.lower_pmos_inst.get_pin("S")
|
||||
|
||||
# BL goes up to M2 at the transistor
|
||||
self.bl_contact =self.add_via_center(layers=self.m1_stack,
|
||||
offset=upper_pin.center(),
|
||||
directions=("V", "V"))
|
||||
self.add_via_center(layers=self.m1_stack,
|
||||
# BL
|
||||
lower_pin = self.lower_pmos_inst.get_pin("S")
|
||||
self.lower_via = self.add_via_center(layers=self.m1_stack,
|
||||
offset=lower_pin.center(),
|
||||
directions=("V", "V"))
|
||||
|
||||
# BR routes over on M1 first
|
||||
self.add_via_center(layers=self.m1_stack,
|
||||
offset=vector(self.br_pin.cx(), upper_pin.cy()),
|
||||
directions=("V", "V"))
|
||||
self.add_via_center(layers=self.m1_stack,
|
||||
offset=vector(self.br_pin.cx(), lower_pin.cy()),
|
||||
lower_pin = self.lower_pmos_inst.get_pin("D")
|
||||
self.lower_via = self.add_via_center(layers=self.m1_stack,
|
||||
offset=lower_pin.center(),
|
||||
directions=("V", "V"))
|
||||
|
||||
def connect_pmos_m1(self, pmos_pin, bit_pin):
|
||||
"""
|
||||
Connect a pmos pin to bitline pin
|
||||
"""
|
||||
# BR
|
||||
upper_pin = self.upper_pmos1_inst.get_pin("S")
|
||||
self.upper_via2 = self.add_via_center(layers=self.m1_stack,
|
||||
offset=upper_pin.center(),
|
||||
directions=("V", "V"))
|
||||
|
||||
left_pos = vector(min(pmos_pin.cx(), bit_pin.cx()), pmos_pin.cy())
|
||||
right_pos = vector(max(pmos_pin.cx(), bit_pin.cx()), pmos_pin.cy())
|
||||
|
||||
self.add_path("m1", [left_pos, right_pos] )
|
||||
upper_pin = self.upper_pmos2_inst.get_pin("D")
|
||||
self.upper_via2 = self.add_via_center(layers=self.m1_stack,
|
||||
offset=upper_pin.center(),
|
||||
directions=("V", "V"))
|
||||
|
||||
def connect_pmos_m2(self, pmos_pin, bit_pin):
|
||||
"""
|
||||
|
|
@ -274,7 +284,7 @@ class precharge(design.design):
|
|||
left_pos = vector(min(pmos_pin.cx(), bit_pin.cx()), pmos_pin.cy())
|
||||
right_pos = vector(max(pmos_pin.cx(), bit_pin.cx()), pmos_pin.cy())
|
||||
|
||||
self.add_path("m2", [left_pos, right_pos], self.bl_contact.height)
|
||||
self.add_path("m2", [left_pos, right_pos])
|
||||
|
||||
def get_en_cin(self):
|
||||
"""Get the relative capacitance of the enable in the precharge cell"""
|
||||
|
|
|
|||
Loading…
Reference in New Issue