fixing contact placement for gf180 in rom

This commit is contained in:
SWalker
2023-10-31 23:24:21 -07:00
parent b279791762
commit 75f7a5847f
12 changed files with 232 additions and 192 deletions
+13 -2
View File
@@ -10,6 +10,8 @@ from openram.base import design
from openram.sram_factory import factory
from openram.base import vector
from openram.tech import layer, drc
from openram import OPTS
@@ -111,16 +113,25 @@ class rom_address_control_buf(design):
Aint_in = self.addr_bar_nand.get_pin("B")
A_in = self.inv_inst.get_pin("A")
vdd_rail = self.addr_nand.get_pin("vdd")
# Find the center of the pmos poly/gate
poly_right = clk1_pin.cx() + self.poly_enclose_contact + 0.5 * self.contact_width
ppoly_center = poly_right - 0.7 * self.poly_width
poly_y = A_out.cy()
if OPTS.tech_name == "gf180mcu":
poly_y = vdd_rail.cy() + 0.5 * drc("minwidth_tx") * 3 + self.poly_extend_active
ppoly_center = A_out.cx() + 0.5 * self.interconnect_width + 0.5 * self.poly_width
else:
ppoly_center = poly_right - 0.7 * self.poly_width
poly_y = A_out.cy()
contact_offset = vector(ppoly_center, clk2_pin.cy())
self.add_layout_pin_rect_center("cont", offset=contact_offset, layer="poly")
self.add_layout_pin_rect_center("ppoly", offset=vector(ppoly_center, poly_y), layer="poly")
# Route the two shared clk inputs together by connecting poly
self.add_segment_center("poly", contact_offset, vector(ppoly_center, A_out.cy()))
self.add_segment_center("poly", contact_offset, vector(ppoly_center, poly_y))
clk_offset = vector(clk2_pin.cx(), self.addr_nand.uy())
+7 -3
View File
@@ -88,6 +88,8 @@ class rom_base_array(bitcell_base_array):
else:
self.poly_tap = factory.create(module_type="rom_poly_tap", add_active_tap=True)
self.end_poly_tap = factory.create(module_type="rom_poly_tap", place_poly=True)
print("poly tap width", self.poly_tap.width, "height", self.poly_tap.height, self.tap_direction)
self.precharge_array = factory.create(module_type="rom_precharge_array",
cols=self.column_size,
strap_spacing=self.strap_spacing,
@@ -100,6 +102,7 @@ class rom_base_array(bitcell_base_array):
self.route_pitch = drc("{0}_to_{0}".format(self.bitline_layer))
def add_pins(self):
print(self.get_wordline_names())
for bl_name in self.get_bitline_names():
self.add_pin(bl_name, "OUTPUT")
for wl_name in self.get_wordline_names():
@@ -215,7 +218,7 @@ class rom_base_array(bitcell_base_array):
self.remove_layout_pin("gnd")
active_tap_pins = [self.active_tap_list[i].get_pin("active_tap") for i in range(len(self.active_tap_list))]
self.connect_col_pins(layer=self.supply_stack[0], pins=active_tap_pins, name="gnd_tmp")
self.connect_col_pins(layer=self.supply_stack[0], pins=active_tap_pins, name="gnd_tmp", directions="nonpref")
gnd_y = gnd_l.y
min_x = float('inf')
@@ -246,7 +249,6 @@ class rom_base_array(bitcell_base_array):
self.cell_pos = {}
self.strap_pos = {}
pitch_offset = 0
for row in range(self.row_size + 1):
if row % self.tap_spacing == 0 and self.pitch_match and row != self.row_size:
@@ -331,7 +333,7 @@ class rom_base_array(bitcell_base_array):
else:
output_layer = "m3"
rail_y = self.precharge_inst.get_pins("vdd")[0].cy()
print("cols ", self.bitline_names[0])
for bl in range(self.column_size):
src_pin = self.cell_list[0][bl].get_pin("S")
@@ -382,3 +384,5 @@ class rom_base_array(bitcell_base_array):
poly_tap_pins = [self.poly_tap_list[i].get_pin("poly_tap") for i in range(len(self.poly_tap_list))]
self.connect_row_pins(layer=self.wordline_layer, pins=poly_tap_pins)
self.connect_row_pins(layer="poly", pins=poly_tap_pins)
+8 -7
View File
@@ -9,15 +9,19 @@ from math import ceil, log
from openram.sram_factory import factory
from openram.base import vector, design
from openram import OPTS
from openram.tech import drc
from openram.tech import drc, layer
class rom_decoder(design):
def __init__(self, num_outputs, fanout, strap_spacing, name="", route_layer="m1", output_layer="m1", invert_outputs=False):
# word lines in the base array become the address lines/cols in the decoder
# bit lines in the base array become the word lines/rows in the decoder
# array gets rotated 90deg so rows/cols switch
if "li" in layer:
self.output_layer = "m1"
self.inv_route_layer = "m2"
else:
self.output_layer = "m1"
self.inv_route_layer = "m3"
self.strap_spacing=strap_spacing
self.num_outputs = num_outputs
self.num_inputs = ceil(log(num_outputs, 2))
@@ -28,8 +32,6 @@ class rom_decoder(design):
b = factory.create(module_type=OPTS.bitcell)
self.cell_height = b.height
self.route_layer = route_layer
self.output_layer = output_layer
self.inv_route_layer = "m2"
self.fanout=fanout
self.invert_outputs=invert_outputs
self.create_netlist()
@@ -203,13 +205,12 @@ class rom_decoder(design):
for j in range(self.num_outputs):
self.copy_layout_pin(self.wordline_buf_inst, "out_{}".format(j), "wl_{}".format(j))
offset = self.wordline_buf_inst.get_pin("out_{}".format(j)).center()
array_pins = [self.array_inst.get_pin("bl_0_{}".format(bl)) for bl in range(self.num_outputs)]
driver_pins = [self.wordline_buf_inst.get_pin("in_{}".format(bl)) for bl in range(self.num_outputs)]
route_pins = array_pins + driver_pins
self.connect_row_pins(self.output_layer, route_pins, round=True)
self.connect_row_pins(self.inv_route_layer, route_pins, round=True)
def connect_inputs(self):
+5 -8
View File
@@ -35,17 +35,19 @@ class rom_poly_tap(design):
def create_layout(self):
self.place_via()
self.add_boundary()
# self.extend_poly()
if self.add_tap or self.place_poly:
self.place_active_tap()
self.add_boundary()
def add_boundary(self):
contact_width = self.poly_contact.width
self.height = self.dummy.height
self.width = contact_width + self.pitch_offset
print("pitch off", self.pitch_offset)
super().add_boundary()
def place_via(self):
@@ -60,14 +62,9 @@ class rom_poly_tap(design):
contact_x = contact_width * 0.5 + self.contact_x_offset
self.contact_offset = vector(contact_x, contact_y)
if OPTS.tech_name == "sky130":
directions="pref"
else:
directions="nonpref"
self.via = self.add_via_stack_center(from_layer="poly",
to_layer=self.strap_layer,
offset=self.contact_offset,
directions=directions)
offset=self.contact_offset)
self.add_layout_pin_rect_center("poly_tap", self.strap_layer, self.contact_offset)
def extend_poly(self):
+10 -11
View File
@@ -17,24 +17,17 @@ class rom_precharge_array(design):
"""
An array of inverters to create the inverted address lines for the rom decoder
"""
def __init__(self, cols, name="", bitline_layer="m2", strap_spacing=None, strap_layer="m3", tap_direction="row"):
def __init__(self, cols, name="", bitline_layer="m2", strap_spacing=0, strap_layer="m3", tap_direction="row"):
self.cols = cols
self.strap_layer = strap_layer
self.bitline_layer = bitline_layer
self.tap_direction = tap_direction
self.strap_spacing = strap_spacing
if "li" in layer:
self.supply_layer = "li"
else:
self.supply_layer = "m1"
if strap_spacing != None:
self.strap_spacing = strap_spacing
else:
self.strap_spacing = 0
if strap_spacing != 0:
self.num_straps = ceil(self.cols / self.strap_spacing)
self.array_col_size = self.cols + self.num_straps
@@ -158,11 +151,17 @@ class rom_precharge_array(design):
self.add_segment_center(layer="poly", start=offset_start, end=offset_end)
self.add_segment_center(layer="poly", start=self.pmos_insts[-1].get_pin("G").center(), end=offset_end)
gate_y = self.pmos_insts[0].get_pin('G').cy()
start = vector( self.get_pin("gate").lx(), gate_y)
end = vector( self.get_pin("precharge_r").rx(), gate_y )
self.add_segment_center(layer="poly", start=start, end=end)
def extend_well(self):
self.well_offset = self.pmos.tap_offset
well_y = self.pmos_insts[0].get_pin("vdd").cy() - 0.5 * self.nwell_width
well_y = self.get_pin("vdd").cy() - 0.5 * self.nwell_width
well_y = self.get_pin("vdd").by() - self.nwell_enclose_active
well_ll = vector(0, well_y)
self.add_rect("nwell", well_ll, self.width , self.height - well_y)
@@ -214,7 +214,8 @@ class rom_wordline_driver_array(design):
directions="nonpref")
self.add_via_stack_center(offset=offset,
from_layer=self.active_stack[2],
to_layer=self.supply_layer)
to_layer=self.supply_layer,
directions="nonpref")
if well_type == "p":
pin = "gnd_tap"
self.gnd_taps.append(self.add_layout_pin_rect_center(text=pin, layer=self.supply_layer, offset=offset))