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([])
|
self.connect_inst([])
|
||||||
return inst
|
return inst
|
||||||
|
|
||||||
def add_via_stack(self, offset, direction, from_layer, to_layer,
|
def add_via_stack(self, offset, from_layer, to_layer,
|
||||||
size=[1,1]):
|
direction=None,
|
||||||
|
size=[1, 1]):
|
||||||
"""
|
"""
|
||||||
Punch a stack of vias from a start layer to a target layer.
|
Punch a stack of vias from a start layer to a target layer.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return self.__add_via_stack_internal(offset=offset,
|
return self.__add_via_stack_internal(offset=offset,
|
||||||
direction=direction,
|
direction=direction,
|
||||||
from_layer=from_layer,
|
from_layer=from_layer,
|
||||||
|
|
@ -531,8 +531,9 @@ class layout():
|
||||||
last_via=None,
|
last_via=None,
|
||||||
size=size)
|
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,
|
||||||
size=[1,1]):
|
direction=None,
|
||||||
|
size=[1, 1]):
|
||||||
"""
|
"""
|
||||||
Punch a stack of vias from a start layer to a target layer by the center
|
Punch a stack of vias from a start layer to a target layer by the center
|
||||||
coordinate accounting for mirroring and rotation.
|
coordinate accounting for mirroring and rotation.
|
||||||
|
|
@ -545,7 +546,6 @@ class layout():
|
||||||
last_via=None,
|
last_via=None,
|
||||||
size=size)
|
size=size)
|
||||||
|
|
||||||
|
|
||||||
def __add_via_stack_internal(self, offset, direction, from_layer, to_layer,
|
def __add_via_stack_internal(self, offset, direction, from_layer, to_layer,
|
||||||
via_func, last_via, size):
|
via_func, last_via, size):
|
||||||
"""
|
"""
|
||||||
|
|
@ -581,7 +581,6 @@ class layout():
|
||||||
last_via=via,
|
last_via=via,
|
||||||
size=size)
|
size=size)
|
||||||
|
|
||||||
|
|
||||||
def add_ptx(self, offset, mirror="R0", rotate=0, width=1, mults=1, tx_type="nmos"):
|
def add_ptx(self, offset, mirror="R0", rotate=0, width=1, mults=1, tx_type="nmos"):
|
||||||
"""Adds a ptx module to the design."""
|
"""Adds a ptx module to the design."""
|
||||||
import ptx
|
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. """
|
""" 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.
|
# 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 num in range(0, self.rows):
|
||||||
for pin_name in ["vdd", "gnd"]:
|
for pin_name in ["vdd", "gnd"]:
|
||||||
# The nand and inv are the same height rows...
|
# 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
|
# Find the x offsets for where the vias/pins should be placed
|
||||||
a_xoffset = self.nand_inst[0].rx()
|
a_xoffset = self.nand_inst[0].lx()
|
||||||
b_xoffset = self.inv2_inst[0].lx()
|
|
||||||
for num in range(self.rows):
|
for num in range(self.rows):
|
||||||
# this will result in duplicate polygons for rails, but who cares
|
# 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)
|
supply_pin = self.inv2_inst[num].get_pin(name)
|
||||||
|
|
||||||
# Add pins in two locations
|
# Add pins in two locations
|
||||||
for xoffset in [a_xoffset, b_xoffset]:
|
for xoffset in [a_xoffset]:
|
||||||
pin_pos = vector(xoffset, supply_pin.cy())
|
pin_pos = vector(xoffset, supply_pin.cy())
|
||||||
self.add_power_pin(name, pin_pos)
|
self.add_power_pin(name, pin_pos)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -267,8 +267,8 @@ class pgate(design.design):
|
||||||
|
|
||||||
def determine_width(self):
|
def determine_width(self):
|
||||||
""" Determine the width based on the well contacts (assumed to be on the right side) """
|
""" Determine the width based on the well contacts (assumed to be on the right side) """
|
||||||
# Width is determined by well contact and spacing
|
# 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
|
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
|
self.well_width = self.width + 2 * self.nwell_enclose_active
|
||||||
# Height is an input parameter, so it is not recomputed.
|
# Height is an input parameter, so it is not recomputed.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ from tech import parameter
|
||||||
from vector import vector
|
from vector import vector
|
||||||
from globals import OPTS
|
from globals import OPTS
|
||||||
from sram_factory import factory
|
from sram_factory import factory
|
||||||
|
from tech import drc
|
||||||
|
|
||||||
class precharge(design.design):
|
class precharge(design.design):
|
||||||
"""
|
"""
|
||||||
|
|
@ -30,7 +30,10 @@ class precharge(design.design):
|
||||||
self.width = self.bitcell.width
|
self.width = self.bitcell.width
|
||||||
self.bitcell_bl = bitcell_bl
|
self.bitcell_bl = bitcell_bl
|
||||||
self.bitcell_br = bitcell_br
|
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
|
# Creates the netlist and layout
|
||||||
# Since it has variable height, it is not a pgate.
|
# Since it has variable height, it is not a pgate.
|
||||||
self.create_netlist()
|
self.create_netlist()
|
||||||
|
|
@ -50,6 +53,7 @@ class precharge(design.design):
|
||||||
self.create_ptx()
|
self.create_ptx()
|
||||||
|
|
||||||
def create_layout(self):
|
def create_layout(self):
|
||||||
|
|
||||||
self.place_ptx()
|
self.place_ptx()
|
||||||
self.connect_poly()
|
self.connect_poly()
|
||||||
self.route_en()
|
self.route_en()
|
||||||
|
|
@ -120,17 +124,18 @@ class precharge(design.design):
|
||||||
contact_xdiff = self.pmos.get_pin("S").lx()
|
contact_xdiff = self.pmos.get_pin("S").lx()
|
||||||
|
|
||||||
# adds the lower pmos to layout
|
# 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.lower_pmos_position = vector(max(bl_xoffset - contact_xdiff,
|
||||||
self.nwell_enclose_active),
|
self.nwell_enclose_active),
|
||||||
self.pmos.active_offset.y)
|
self.pmos.active_offset.y)
|
||||||
self.lower_pmos_inst.place(self.lower_pmos_position)
|
self.lower_pmos_inst.place(self.lower_pmos_position)
|
||||||
|
|
||||||
# adds the upper pmos(s) to layout
|
# 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_pos = self.lower_pmos_position + vector(0, ydiff)
|
||||||
self.upper_pmos1_inst.place(self.upper_pmos1_pos)
|
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
|
upper_pmos2_pos = self.upper_pmos1_pos + overlap_offset
|
||||||
self.upper_pmos2_inst.place(upper_pmos2_pos)
|
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
|
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
|
# adds the en contact to connect the gates to the en rail on metal1
|
||||||
offset = self.lower_pmos_inst.get_pin("G").ul() \
|
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,
|
self.add_via_center(layers=self.poly_stack,
|
||||||
offset=offset)
|
offset=offset)
|
||||||
|
if layer == "m2":
|
||||||
|
self.add_via_center(layers=self.m1_stack,
|
||||||
|
offset=offset)
|
||||||
|
|
||||||
|
|
||||||
# adds the en rail on metal1
|
# adds the en rail on metal1
|
||||||
self.add_layout_pin_segment_center(text="en_bar",
|
self.add_layout_pin_segment_center(text="en_bar",
|
||||||
layer="m1",
|
layer=layer,
|
||||||
start=offset.scale(0, 1),
|
start=offset.scale(0, 1),
|
||||||
end=offset.scale(0, 1) + vector(self.width, 0))
|
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
|
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
|
# adds the BL on metal 2
|
||||||
offset = vector(self.bitcell.get_pin(self.bitcell_bl).cx(), 0) \
|
offset = vector(layer_space - 0.5 * layer_width, 0)
|
||||||
- vector(0.5 * self.m2_width, 0)
|
|
||||||
self.bl_pin = self.add_layout_pin(text="bl",
|
self.bl_pin = self.add_layout_pin(text="bl",
|
||||||
layer="m2",
|
layer=layer,
|
||||||
offset=offset,
|
offset=offset,
|
||||||
height=self.height)
|
height=self.height)
|
||||||
|
|
||||||
# adds the BR on metal 2
|
# adds the BR on metal 2
|
||||||
offset = vector(self.bitcell.get_pin(self.bitcell_br).cx(), 0) \
|
offset = vector(self.width - layer_space - 0.5 * layer_width, 0)
|
||||||
- vector(0.5 * self.m2_width, 0)
|
|
||||||
self.br_pin = self.add_layout_pin(text="br",
|
self.br_pin = self.add_layout_pin(text="br",
|
||||||
layer="m2",
|
layer=layer,
|
||||||
offset=offset,
|
offset=offset,
|
||||||
height=self.height)
|
height=self.height)
|
||||||
|
|
||||||
|
|
@ -225,11 +240,12 @@ class precharge(design.design):
|
||||||
self.add_bitline_contacts()
|
self.add_bitline_contacts()
|
||||||
self.connect_pmos_m2(self.lower_pmos_inst.get_pin("S"),
|
self.connect_pmos_m2(self.lower_pmos_inst.get_pin("S"),
|
||||||
self.get_pin("bl"))
|
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.connect_pmos_m2(self.upper_pmos1_inst.get_pin("S"),
|
||||||
self.get_pin("bl"))
|
self.get_pin("bl"))
|
||||||
self.connect_pmos_m1(self.lower_pmos_inst.get_pin("D"),
|
self.connect_pmos_m2(self.upper_pmos2_inst.get_pin("D"),
|
||||||
self.get_pin("br"))
|
|
||||||
self.connect_pmos_m1(self.upper_pmos2_inst.get_pin("D"),
|
|
||||||
self.get_pin("br"))
|
self.get_pin("br"))
|
||||||
|
|
||||||
def add_bitline_contacts(self):
|
def add_bitline_contacts(self):
|
||||||
|
|
@ -237,34 +253,28 @@ class precharge(design.design):
|
||||||
Adds contacts/via from metal1 to metal2 for bit-lines
|
Adds contacts/via from metal1 to metal2 for bit-lines
|
||||||
"""
|
"""
|
||||||
|
|
||||||
upper_pin = self.upper_pmos1_inst.get_pin("S")
|
|
||||||
|
# BL
|
||||||
lower_pin = self.lower_pmos_inst.get_pin("S")
|
lower_pin = self.lower_pmos_inst.get_pin("S")
|
||||||
|
self.lower_via = self.add_via_center(layers=self.m1_stack,
|
||||||
# BL goes up to M2 at the transistor
|
offset=lower_pin.center(),
|
||||||
self.bl_contact =self.add_via_center(layers=self.m1_stack,
|
|
||||||
offset=upper_pin.center(),
|
|
||||||
directions=("V", "V"))
|
directions=("V", "V"))
|
||||||
self.add_via_center(layers=self.m1_stack,
|
|
||||||
offset=lower_pin.center(),
|
|
||||||
directions=("V", "V"))
|
|
||||||
|
|
||||||
# BR routes over on M1 first
|
lower_pin = self.lower_pmos_inst.get_pin("D")
|
||||||
self.add_via_center(layers=self.m1_stack,
|
self.lower_via = self.add_via_center(layers=self.m1_stack,
|
||||||
offset=vector(self.br_pin.cx(), upper_pin.cy()),
|
offset=lower_pin.center(),
|
||||||
directions=("V", "V"))
|
directions=("V", "V"))
|
||||||
self.add_via_center(layers=self.m1_stack,
|
|
||||||
offset=vector(self.br_pin.cx(), lower_pin.cy()),
|
|
||||||
directions=("V", "V"))
|
|
||||||
|
|
||||||
def connect_pmos_m1(self, pmos_pin, bit_pin):
|
# BR
|
||||||
"""
|
upper_pin = self.upper_pmos1_inst.get_pin("S")
|
||||||
Connect a pmos pin to bitline pin
|
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())
|
upper_pin = self.upper_pmos2_inst.get_pin("D")
|
||||||
right_pos = vector(max(pmos_pin.cx(), bit_pin.cx()), pmos_pin.cy())
|
self.upper_via2 = self.add_via_center(layers=self.m1_stack,
|
||||||
|
offset=upper_pin.center(),
|
||||||
self.add_path("m1", [left_pos, right_pos] )
|
directions=("V", "V"))
|
||||||
|
|
||||||
def connect_pmos_m2(self, pmos_pin, bit_pin):
|
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())
|
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())
|
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):
|
def get_en_cin(self):
|
||||||
"""Get the relative capacitance of the enable in the precharge cell"""
|
"""Get the relative capacitance of the enable in the precharge cell"""
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue