mirror of https://github.com/VLSIDA/OpenRAM.git
Bitcell supply routing fixes.
Flatten and simplify 1rw 1r bitcell. Move bitcell vias to M3 if rotation is limited. Simplify replica bitcell vdd routing.
This commit is contained in:
parent
7e054a51e2
commit
90d1fa7c43
|
|
@ -926,22 +926,30 @@ class layout(lef.lef):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def add_power_pin(self, name, loc, rotate=90, m1_too=True):
|
def add_power_pin(self, name, loc, rotate=90, start_layer="metal1"):
|
||||||
"""
|
"""
|
||||||
Add a single power pin from M3 down to M1 at the given center location
|
Add a single power pin from M3 down to M1 at the given center location.
|
||||||
|
The starting layer is specified to determine which vias are needed.
|
||||||
"""
|
"""
|
||||||
if m1_too:
|
|
||||||
|
if start_layer=="metal1":
|
||||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||||
offset=loc,
|
offset=loc,
|
||||||
rotate=float(rotate))
|
rotate=float(rotate))
|
||||||
via=self.add_via_center(layers=("metal2", "via2", "metal3"),
|
if start_layer=="metal1" or start_layer=="metal2":
|
||||||
offset=loc,
|
via=self.add_via_center(layers=("metal2", "via2", "metal3"),
|
||||||
rotate=float(rotate))
|
offset=loc,
|
||||||
self.add_layout_pin_rect_center(text=name,
|
rotate=float(rotate))
|
||||||
layer="metal3",
|
if start_layer=="metal3":
|
||||||
offset=loc,
|
self.add_layout_pin_rect_center(text=name,
|
||||||
width=via.width,
|
layer="metal3",
|
||||||
height=via.height)
|
offset=loc)
|
||||||
|
else:
|
||||||
|
self.add_layout_pin_rect_center(text=name,
|
||||||
|
layer="metal3",
|
||||||
|
offset=loc,
|
||||||
|
width=via.width,
|
||||||
|
height=via.height)
|
||||||
|
|
||||||
def add_power_ring(self, bbox):
|
def add_power_ring(self, bbox):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ class pbitcell(design.design):
|
||||||
self.offset_all_coordinates()
|
self.offset_all_coordinates()
|
||||||
gnd_overlap = vector(0, 0.5*contact.well.width)
|
gnd_overlap = vector(0, 0.5*contact.well.width)
|
||||||
self.translate_all(gnd_overlap)
|
self.translate_all(gnd_overlap)
|
||||||
self.DRC_LVS()
|
|
||||||
|
|
||||||
def add_pins(self):
|
def add_pins(self):
|
||||||
""" add pins and set names for bitlines and wordlines """
|
""" add pins and set names for bitlines and wordlines """
|
||||||
|
|
@ -323,19 +323,20 @@ class pbitcell(design.design):
|
||||||
# Add rails for vdd and gnd
|
# Add rails for vdd and gnd
|
||||||
gnd_ypos = self.rowline_offset - self.total_ports*self.rowline_spacing
|
gnd_ypos = self.rowline_offset - self.total_ports*self.rowline_spacing
|
||||||
self.gnd_position = vector(0, gnd_ypos)
|
self.gnd_position = vector(0, gnd_ypos)
|
||||||
self.gnd = self.add_layout_pin_rect_center(text="gnd",
|
self.add_rect_center(layer="metal1",
|
||||||
layer="metal1",
|
offset=self.gnd_position,
|
||||||
offset=self.gnd_position,
|
width=self.width,
|
||||||
width=self.width,
|
height=self.m1_width)
|
||||||
height=self.m1_width)
|
self.add_power_pin("gnd", vector(0,gnd_ypos))
|
||||||
|
|
||||||
|
|
||||||
vdd_ypos = self.inverter_nmos_ypos + self.inverter_nmos.active_height + self.inverter_gap + self.inverter_pmos.active_height + self.vdd_offset
|
vdd_ypos = self.inverter_nmos_ypos + self.inverter_nmos.active_height + self.inverter_gap + self.inverter_pmos.active_height + self.vdd_offset
|
||||||
self.vdd_position = vector(0, vdd_ypos)
|
self.vdd_position = vector(0, vdd_ypos)
|
||||||
self.vdd = self.add_layout_pin_rect_center(text="vdd",
|
self.add_rect_center(layer="metal1",
|
||||||
layer="metal1",
|
offset=self.vdd_position,
|
||||||
offset=self.vdd_position,
|
width=self.width,
|
||||||
width=self.width,
|
height=self.m1_width)
|
||||||
height=self.m1_width)
|
self.add_power_pin("vdd", vector(0,vdd_ypos))
|
||||||
|
|
||||||
def create_readwrite_ports(self):
|
def create_readwrite_ports(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,8 @@ class bitcell_array(design.design):
|
||||||
inst = self.cell_inst[row,col]
|
inst = self.cell_inst[row,col]
|
||||||
for pin_name in ["vdd", "gnd"]:
|
for pin_name in ["vdd", "gnd"]:
|
||||||
for pin in inst.get_pins(pin_name):
|
for pin in inst.get_pins(pin_name):
|
||||||
self.add_power_pin(pin_name, pin.center(), 0, pin.layer=="metal1")
|
self.add_power_pin(pin_name, pin.center(), 0, pin.layer)
|
||||||
|
|
||||||
|
|
||||||
def analytical_delay(self, slew, load=0):
|
def analytical_delay(self, slew, load=0):
|
||||||
from tech import drc
|
from tech import drc
|
||||||
|
|
|
||||||
|
|
@ -265,15 +265,8 @@ class replica_bitline(design.design):
|
||||||
pin = self.rbl_inv_inst.get_pin("vdd")
|
pin = self.rbl_inv_inst.get_pin("vdd")
|
||||||
self.add_power_pin("vdd", pin.lc())
|
self.add_power_pin("vdd", pin.lc())
|
||||||
|
|
||||||
# Replica bitcell needs to be routed up to M3
|
|
||||||
pin=self.rbc_inst.get_pin("vdd")
|
pin=self.rbc_inst.get_pin("vdd")
|
||||||
# Don't rotate this via to vit in FreePDK45. In the custom cell, the pin cannot be placed
|
self.add_power_pin("vdd", pin.center(), 0, pin.layer)
|
||||||
# directly on vdd or there will be a drc error with a wordline. Place the pin slightly farther
|
|
||||||
# away then route to it. A better solution would be to rotate the m1 in the via or move the pin
|
|
||||||
# a m1_pitch below the entire cell.
|
|
||||||
pin_extension = pin.center() - vector(0,self.m1_pitch)
|
|
||||||
self.add_power_pin("vdd", pin_extension, rotate=0)
|
|
||||||
self.add_path("metal1", [pin.center(), pin_extension])
|
|
||||||
|
|
||||||
for pin in self.rbc_inst.get_pins("gnd"):
|
for pin in self.rbc_inst.get_pins("gnd"):
|
||||||
self.add_power_pin("gnd", pin.center())
|
self.add_power_pin("gnd", pin.center())
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue