taps in main array and decoder

This commit is contained in:
Jacob Walker
2023-03-30 11:30:50 -07:00
parent f7aed247fd
commit 559300e5cc
14 changed files with 692 additions and 425 deletions
+57 -67
View File
@@ -19,25 +19,25 @@ class rom_precharge_array(design):
"""
An array of inverters to create the inverted address lines for the rom decoder
"""
def __init__(self, cols, pmos_size=None, name="", route_layer="li", strap_spacing=None):
def __init__(self, cols, name="", route_layer="li", strap_spacing=None, strap_layer="m2", tap_direction="row"):
self.cols = cols
self.route_layer = route_layer
self.strap_layer = strap_layer
self.tap_direction = tap_direction
if self.route_layer == "m1" :
self.supply_layer = "li"
else:
self.supply_layer = "m1"
if name=="":
name = "rom_inv_array_{0}".format(cols)
# if pmos_size == None:
# self.pmos_size = dff.height * 0.5
# else:
# self.pmos_size = inv_size
if strap_spacing != None:
self.strap_spacing = strap_spacing
else:
self.strap_spacing = 0
if "li" in layer:
self.inv_layer = "li"
else:
self.inv_layer = "m1"
if strap_spacing != 0:
self.num_straps = ceil(self.cols / self.strap_spacing)
@@ -62,28 +62,30 @@ class rom_precharge_array(design):
self.height = self.pmos.width
self.place_instances()
self.create_layout_pins()
self.add_well_tap()
self.route_supply()
self.connect_taps()
self.add_boundary()
self.extend_well()
def add_boundary(self):
# self.translate_all(self.well_ll)
ur = self.find_highest_coords()
self.add_label(layer="nwell", text="upper right",offset=ur)
# ur = vector(ur.x, ur.y - self.well_ll.y)
super().add_boundary(vector(0, 0), ur)
self.width = self.cols * self.pmos.width
self.height = ur.y
self.width = ur.x
def create_modules(self):
self.pmos = factory.create(module_type="rom_precharge_cell", module_name="precharge_cell", route_layer=self.route_layer)
self.pmos = factory.create(module_type="rom_precharge_cell", module_name="precharge_cell", route_layer=self.route_layer, supply_layer=self.supply_layer)
# For layout constants
self.dummy = factory.create(module_type="rom_base_cell")
self.poly_tap = factory.create(module_type="rom_poly_tap", strap_length=self.strap_spacing)
self.poly_tap = factory.create(module_type="rom_poly_tap", tx_type="pmos", add_tap=(self.tap_direction == "col"))
def add_pins(self):
for col in range(self.cols):
@@ -96,33 +98,34 @@ class rom_precharge_array(design):
self.pmos_insts = []
self.tap_insts = []
self.tap_insts.append(self.add_inst(name="tap_0", mod=self.poly_tap))
self.connect_inst([])
self.create_poly_tap(-1)
for col in range(self.cols):
if col % self.strap_spacing == 0:
self.create_poly_tap(col)
self.create_precharge_tx(col)
# if col % self.strap_spacing == 0:
# name = "tap_c{}".format(col)
# tap = self.add_inst(name=name, mod=self.poly_tap)
# self.array_insts.append(tap)
# self.tap_insts.append(tap)
# self.connect_inst([])
name = "Xpmos_c{0}".format(col)
pmos = self.add_inst(name=name, mod=self.pmos)
self.array_insts.append(pmos)
self.pmos_insts.append(pmos)
bl = "pre_bl{0}_out".format(col)
self.connect_inst(["vdd", "gate", bl, "vdd"])
print(self.array_insts)
def create_precharge_tx(self, col):
name = "Xpmos_c{0}".format(col)
pmos = self.add_inst(name=name, mod=self.pmos)
self.array_insts.append(pmos)
self.pmos_insts.append(pmos)
bl = "pre_bl{0}_out".format(col)
self.connect_inst(["vdd", "gate", bl])
def create_poly_tap(self, col):
name = "tap_c{}".format( col)
new_tap = self.add_inst(name=name, mod=self.poly_tap)
self.tap_insts.append(new_tap)
self.connect_inst([])
def place_instances(self):
self.add_label("ZERO", self.route_layer)
self.array_pos = []
strap_num = 0
strap_num = 1
cell_y = 0
# columns are bit lines4
cell_x = 0
@@ -130,12 +133,19 @@ class rom_precharge_array(design):
self.tap_insts[0].place(vector(cell_x, cell_y))
for col in range(self.cols):
if col % self.strap_spacing == 0:
self.tap_insts[strap_num].place(vector(cell_x, cell_y))
strap_num += 1
if self.tap_direction == "col":
cell_x += self.poly_tap.pitch_offset
# if col % self.strap_spacing == 0 :
# self.tap_insts[strap_num].place(vector(cell_x, cell_y))
# self.add_label("debug", "li", vector(cell_x, cell_y))
# cell_x += self.poly_tap.width
# strap_num += 1
self.pmos_insts[col].place(vector(cell_x, cell_y))
self.add_label("debug", "li", vector(cell_x, cell_y))
@@ -143,51 +153,31 @@ class rom_precharge_array(design):
def create_layout_pins(self):
self.copy_layout_pin(self.tap_insts[0], "via", "gate")
self.copy_layout_pin(self.tap_insts[0], "poly_tap", "gate")
for col in range(self.cols):
source_pin = self.pmos_insts[col].get_pin("D")
bl = "pre_bl{0}_out".format(col)
self.add_layout_pin_rect_center(bl, self.route_layer, source_pin.center())
def add_well_tap(self):
layer_stack = self.active_stack
contact_x = self.pmos_insts[self.cols - 1].rx() + self.active_space
contact_offset = vector(contact_x, self.pmos.height * 0.5)
self.nwell_contact = self.add_via_center(layers=layer_stack,
offset=contact_offset,
implant_type="n",
well_type="n",
directions=("V", "V"))
def route_supply(self):
start_pin = self.pmos_insts[0].get_pin("S").lx()
end_pin = self.pmos_insts[-1].get_pin("S").rx()
spacing = drc["{0}_to_{0}".format(self.route_layer)]
start = vector(start_pin, -2*spacing)
end = vector(end_pin, -2*spacing)
self.vdd = self.add_layout_pin_segment_center("vdd", "m1", start, end)
for i in range(self.cols):
start = self.pmos_insts[i].get_pin("S").center()
end = vector(start.x, self.vdd.cy())
self.add_segment_center(self.route_layer, start, end)
self.add_via_stack_center(end, self.route_layer, "m1")
# self.vdd = self.add_layout_pin_segment_center("vdd", self.supply_layer, start, end)
# vdd = [self.pmos_insts[i].get_pin("vdd") for i in range(self.cols)]routeroute_horizon_horizon
self.route_horizontal_pins("vdd", insts=self.pmos_insts)
# connect nwell tap to vdd
start = end
end = vector(self.nwell_contact.cx(), start.y)
self.add_segment_center(self.route_layer, start, end)
start = end - vector(0, 0.5 * self.mcon_width)
end = self.nwell_contact.center()
self.add_segment_center(self.route_layer, start, end)
def connect_taps(self):
array_pins = [self.tap_insts[i].get_pin("poly_tap") for i in range(len(self.tap_insts))]
self.connect_row_pins(layer=self.strap_layer, pins=array_pins, name=None, round=False)
def extend_well(self):
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_ll = vector(0, well_y)
self.add_rect("nwell", well_ll, self.width , self.height - well_y)