checkpoint from tt submission

This commit is contained in:
Jesse Cirimelli-Low
2026-01-14 12:08:26 -08:00
parent 5a74605117
commit 53d53ec271
18 changed files with 154 additions and 113 deletions
+4 -4
View File
@@ -611,10 +611,10 @@ class simulation():
Gets the signal name associated with the bitlines in the bank.
"""
# FIXME: change to a solution that does not depend on the technology
if OPTS.tech_name == "sky130" and len(self.all_ports) == 1:
cell_mod = factory.create(module_type=OPTS.bitcell, version="opt1")
else:
cell_mod = factory.create(module_type=OPTS.bitcell)
#if OPTS.tech_name == "sky130" and len(self.all_ports) == 1:
# cell_mod = factory.create(module_type=OPTS.bitcell, version="opt1")
#else:
cell_mod = factory.create(module_type=OPTS.bitcell)
cell_bl = cell_mod.get_bl_name(port)
cell_br = cell_mod.get_br_name(port)
+1 -1
View File
@@ -67,7 +67,7 @@ def parse_args():
dest="num_sim_threads"),
optparse.make_option("-v", "--verbose",
action="count",
dest="verbose_level",
dest="5",
help="Increase the verbosity level"),
optparse.make_option("-t", "--tech",
dest="tech_name",
+28 -3
View File
@@ -158,10 +158,35 @@ class bitcell_base_array(design):
height=wl_pin.height())
def route_supplies(self):
vdd_found = False
gnd_found = False
for inst in self.insts:
for pin_name in ["vdd", "gnd"]:
if pin_name in inst.mod.get_pin_names():
self.copy_layout_pin(inst, pin_name)
if 'vdd' in inst.mod.get_pin_names():
vdd_found = True
if 'gnd' in inst.mod.get_pin_names():
gnd_found = True
power_name = 'vdd'
ground_name = 'gnd'
if vdd_found is False or gnd_found is False:
from openram.tech import cell_properties
try:
power_name = cell_properties.power_name
except:
pass
try:
ground_name = cell_properties.ground_name
except:
pass
for inst in self.insts:
if power_name in inst.mod.get_pin_names():
self.copy_layout_pin(inst, power_name, new_name='vdd')
if ground_name in inst.mod.get_pin_names():
self.copy_layout_pin(inst, ground_name , new_name='gnd')
def add_layout_pins(self):
""" Add the layout pins """
@@ -107,6 +107,7 @@ class capped_replica_bitcell_array(bitcell_base_array):
self.row_cap_left = factory.create(module_type=row_cap_module_type,
cols=1,
column_offset=0,
row_offset=len(self.left_rbl)+len(self.right_rbl),
rows=self.row_size + self.extra_rows,
location="left")
@@ -117,6 +118,7 @@ class capped_replica_bitcell_array(bitcell_base_array):
# + bitcell columns
# + right replica column(s)
column_offset=len(self.left_rbl) + self.column_size + self.rbl[0],
row_offset=len(self.left_rbl)+len(self.right_rbl),
rows=self.row_size + self.extra_rows,
location="right")
@@ -181,7 +183,7 @@ class capped_replica_bitcell_array(bitcell_base_array):
# Top/bottom dummy rows or col caps
self.dummy_row_insts = []
self.dummy_row_insts.append(self.add_inst(name="dummy_row_bot",
mod=self.col_cap_bottom))
mod=self.col_cap_bottom,))
self.connect_inst(self.bitline_pin_list + ["gnd"] * len(self.col_cap_bottom.get_wordline_names()) + self.supplies)
self.dummy_row_insts.append(self.add_inst(name="dummy_row_top",
mod=self.col_cap_top))
@@ -217,7 +219,7 @@ class capped_replica_bitcell_array(bitcell_base_array):
self.capped_rba_height = self.dummy_col_insts[0].height
#self.route_power_ring(self.supply_stack[2], self.supply_stack[0])
self.route_power_ring(self.supply_stack[2], self.supply_stack[0])
self.route_supplies()
self.route_unused_wordlines()
@@ -289,6 +291,7 @@ class capped_replica_bitcell_array(bitcell_base_array):
self.dummy_col_insts[1].place(offset=offset)
def add_layout_pins(self):
for pin_name in self.used_wordline_names + self.bitline_pin_list:
pin = self.replica_bitcell_array_inst.get_pin(pin_name)
@@ -308,6 +311,7 @@ class capped_replica_bitcell_array(bitcell_base_array):
offset=pin_offset,
width=pin_width,
height=pin_height)
def route_supplies(self):
@@ -322,8 +326,8 @@ class capped_replica_bitcell_array(bitcell_base_array):
if top:
inst = self.dummy_row_insts[1]
if "vdd" in inst.mod.pins:
array_pins = inst.get_pins("vdd")
if 'vdd' in inst.mod.pins:
array_pins = inst.get_pins('vdd')
for array_pin in array_pins:
supply_pin = self.top_vdd_pin
self.add_path(array_pin.layer, [array_pin.center(), vector(array_pin.center()[0], supply_pin.center()[1])])
@@ -331,7 +335,7 @@ class capped_replica_bitcell_array(bitcell_base_array):
to_layer = supply_pin.layer,
offset = vector(array_pin.center()[0], supply_pin.center()[1]))
array_pins = inst.get_pins("gnd")
array_pins = inst.get_pins('gnd')
for array_pin in array_pins:
supply_pin = self.top_gnd_pin
self.add_path(array_pin.layer, [array_pin.center(), vector(array_pin.center()[0], supply_pin.center()[1])])
@@ -340,8 +344,8 @@ class capped_replica_bitcell_array(bitcell_base_array):
offset = vector(array_pin.center()[0], supply_pin.center()[1]))
if bottom:
inst = self.dummy_row_insts[0]
if "vdd" in inst.mod.pins:
array_pins = inst.get_pins("vdd")
if 'vdd' in inst.mod.pins:
array_pins = inst.get_pins('vdd')
for array_pin in array_pins:
supply_pin = self.bottom_vdd_pin
self.add_path(array_pin.layer, [array_pin.center(), vector(array_pin.center()[0], supply_pin.center()[1])])
@@ -349,7 +353,7 @@ class capped_replica_bitcell_array(bitcell_base_array):
to_layer = supply_pin.layer,
offset = vector(array_pin.center()[0], supply_pin.center()[1]))
array_pins = inst.get_pins("gnd")
array_pins = inst.get_pins('gnd')
for array_pin in array_pins:
supply_pin = self.bottom_gnd_pin
self.add_path(array_pin.layer, [array_pin.center(), vector(array_pin.center()[0], supply_pin.center()[1])])
@@ -358,8 +362,8 @@ class capped_replica_bitcell_array(bitcell_base_array):
offset = vector(array_pin.center()[0], supply_pin.center()[1]))
if left:
inst = self.dummy_col_insts[0]
if "vdd" in inst.mod.pins:
array_pins = inst.get_pins("vdd")
if 'vnd' in inst.mod.pins:
array_pins = inst.get_pins('vnd')
for array_pin in array_pins:
supply_pin = self.left_vdd_pin
self.add_path(array_pin.layer, [array_pin.center(), vector(supply_pin.center()[0], array_pin.center()[1])])
@@ -367,7 +371,7 @@ class capped_replica_bitcell_array(bitcell_base_array):
to_layer = supply_pin.layer,
offset = vector(supply_pin.center()[0], array_pin.center()[1]))
array_pins = inst.get_pins("gnd")
array_pins = inst.get_pins('gnd')
for array_pin in array_pins:
supply_pin = self.left_gnd_pin
self.add_path(array_pin.layer, [array_pin.center(), vector(supply_pin.center()[0], array_pin.center()[1])])
@@ -376,8 +380,8 @@ class capped_replica_bitcell_array(bitcell_base_array):
offset = vector(supply_pin.center()[0], array_pin.center()[1]))
if right:
inst = self.dummy_col_insts[1]
if "vdd" in inst.mod.pins:
array_pins = inst.get_pins("vdd")
if 'vdd' in inst.mod.pins:
array_pins = inst.get_pins('vdd')
for array_pin in array_pins:
supply_pin = self.right_vdd_pin
self.add_path(array_pin.layer, [array_pin.center(), vector(supply_pin.center()[0], array_pin.center()[1])])
@@ -385,29 +389,30 @@ class capped_replica_bitcell_array(bitcell_base_array):
to_layer = supply_pin.layer,
offset = vector(supply_pin.center()[0], array_pin.center()[1]))
array_pins = inst.get_pins("gnd")
array_pins = inst.get_pins('gnd')
for array_pin in array_pins:
supply_pin = self.right_gnd_pin
self.add_path(array_pin.layer, [array_pin.center(), vector(supply_pin.center()[0], array_pin.center()[1])])
self.add_via_stack_center(from_layer = array_pin.layer,
to_layer = supply_pin.layer,
offset = vector(supply_pin.center()[0], array_pin.center()[1]))
offset = vector(supply_pin.center()[0], array_pin.center()[1]))
def route_unused_wordlines(self):
"""
Connect the unused RBL and dummy wordlines to gnd
"""
# This grounds all the dummy row word lines
for inst in self.dummy_row_insts:
for wl_name in self.col_cap_top.get_wordline_names():
for wl_name in inst.mod.get_wordline_names():
pin = inst.get_pin(wl_name)
self.connect_side_pin(pin, "left", self.left_gnd_locs[0].x)
self.connect_side_pin(pin, "right", self.right_gnd_locs[0].x)
self.connect_side_pin(pin, "left", self.left_gnd_pin.cx())
self.connect_side_pin(pin, "right", self.right_gnd_pin.cx())
# Ground the unused replica wordlines
for wl_name in self.unused_wordline_names:
pin = self.replica_bitcell_array_inst.get_pin(wl_name)
self.connect_side_pin(pin, "left", self.left_gnd_locs[0].x)
self.connect_side_pin(pin, "right", self.right_gnd_locs[0].x)
self.connect_side_pin(pin, "left", self.left_gnd_pin.cx())
self.connect_side_pin(pin, "right", self.right_gnd_pin.cx())
def route_side_pin(self, name, side, offset_multiple=1):
"""
+2 -1
View File
@@ -6,7 +6,8 @@
from openram.sram_factory import factory
from openram import OPTS
from .bitcell_base_array import bitcell_base_array
from openram.base import geometry
from .pattern import pattern
class col_cap_array(bitcell_base_array):
"""
+7 -7
View File
@@ -14,7 +14,7 @@ class dummy_array(bitcell_base_array):
Generate a dummy row/column for the replica array.
"""
def __init__(self, rows, cols, column_offset=0, row_offset=0 ,mirror=0, location="", name=""):
def __init__(self, rows, cols, column_offset=0, row_offset=0 ,mirror=0, location="", name="", left_rbl=0, right_rbl=0):
super().__init__(rows=rows, cols=cols, column_offset=column_offset, name=name)
self.location = location
self.row_offset = row_offset
@@ -57,14 +57,14 @@ class dummy_array(bitcell_base_array):
self.cell_inst={}
if self.cell.mirror.y:
core_block = [[0 for x in range(2)] for y in range(2)]
core_block[(0+self.mirror) %2][0] = geometry.instance("core_0_0", mod=self.dummy_cell, is_bitcell=True)
core_block[(1+self.mirror) %2][0] = geometry.instance("core_1_0", mod=self.dummy_cell, is_bitcell=True, mirror='MX')
core_block[(0+self.mirror) %2][1] = geometry.instance("core_0_1", mod=self.dummy_cell, is_bitcell=True, mirror='MY')
core_block[(1+self.mirror) %2][1] = geometry.instance("core_1_1", mod=self.dummy_cell, is_bitcell=True, mirror='XY')
core_block[(0+self.mirror) %2][(1+self.column_offset+self.row_offset) %2] = geometry.instance("core_0_0", mod=self.dummy_cell, is_bitcell=True, mirror='MX')
core_block[(1+self.mirror) %2][(1+self.column_offset+self.row_offset) %2] = geometry.instance("core_1_0", mod=self.dummy_cell, is_bitcell=True)
core_block[(0+self.mirror) %2][(0+self.column_offset+self.row_offset) %2] = geometry.instance("core_0_1", mod=self.dummy_cell, is_bitcell=True, mirror='XY')
core_block[(1+self.mirror) %2][(0+self.column_offset+self.row_offset) %2] = geometry.instance("core_1_1", mod=self.dummy_cell, is_bitcell=True, mirror='MY')
else:
core_block = [[0 for x in range(1)] for y in range(2)]
core_block[(0+self.mirror) %2][0] = geometry.instance("core_0_0", mod=self.dummy_cell, is_bitcell=True)
core_block[(1+self.mirror) %2][0] = geometry.instance("core_1_0", mod=self.dummy_cell, is_bitcell=True, mirror='MX')
core_block[(0+self.mirror) %2][(1+self.column_offset) %2] = geometry.instance("core_0_0", mod=self.dummy_cell, is_bitcell=True, mirror='MX')
core_block[(1+self.mirror) %2][(1+self.column_offset) %2] = geometry.instance("core_1_0", mod=self.dummy_cell, is_bitcell=True)
self.pattern = pattern(self, "dummy_array", core_block, num_rows=self.row_size, num_cols=self.column_size, name_template="bit_r{0}_c{1}")
+1 -1
View File
@@ -187,7 +187,7 @@ class pattern():
inst.place((x, y), inst.mirror, inst.rotate)
def place_array(self):
(self.row_max, self.col_max) = list(self.parent_design.all_inst.keys())[-1]
y = 0
for row in range(self.row_max+1):
+3 -2
View File
@@ -95,17 +95,18 @@ class replica_column(bitcell_base_array):
# Replic bit specifies which other bit (in the full range (0,total_size) to make a replica cell.
# All other cells are dummies
if (row == self.replica_bit) or (row >= self.row_start and row < self.row_end):
if current_row % 2 == 0:
if current_row % 2 == 1:
core_block[row][0] = geometry.instance("rbc_{}".format(row), mod=self.replica_cell, is_bitcell=True)
else:
core_block[row][0] = geometry.instance("rbc_{}".format(row), mod=self.replica_cell, is_bitcell=True, mirror='MX')
else:
if current_row % 2 == 0:
if current_row % 2 == 1:
core_block[row][0] = geometry.instance("rbc_{}".format(row), mod=self.dummy_cell, is_bitcell=True)
else:
core_block[row][0] = geometry.instance("rbc_{}".format(row), mod=self.dummy_cell, is_bitcell=True, mirror='MX')
current_row += 1
if self.cell.mirror.y:
for row in range(self.total_size):
if self.column_offset % 2 == 0:
+6 -6
View File
@@ -141,12 +141,12 @@ class sram_config:
+ " Bank addr size: {}".format(self.bank_addr_size))
num_ports = OPTS.num_rw_ports + OPTS.num_r_ports + OPTS.num_w_ports
if num_ports == 1:
if ((self.num_cols + num_ports + self.num_spare_cols) % self.array_col_multiple != 0):
debug.error("Invalid number of cols including rbl(s): {}. Total cols must be divisible by {}".format(self.num_cols + num_ports + self.num_spare_cols, self.array_col_multiple), -1)
if ((self.num_rows + num_ports) % self.array_row_multiple != 0):
debug.error("invalid number of rows including dummy row(s): {}. Total cols must be divisible by {}".format(self.num_rows + num_ports, self.array_row_multiple), -1)
#if num_ports == 1:
# if ((self.num_cols + num_ports + self.num_spare_cols) % self.array_col_multiple != 0):
# debug.error("Invalid number of cols including rbl(s): {}. Total cols must be divisible by {}".format(self.num_cols + num_ports + self.num_spare_cols, self.array_col_multiple), -1)#
#
# if ((self.num_rows + num_ports) % self.array_row_multiple != 0):
# debug.error("invalid number of rows including dummy row(s): {}. Total cols must be divisible by {}".format(self.num_rows + num_ports, self.array_row_multiple), -1)
def estimate_words_per_row(self, tentative_num_cols, word_size):
"""
+1 -1
View File
@@ -31,7 +31,7 @@ class array_test(openram_test):
num_spare_rows = 0
num_spare_cols = 0
a = factory.create(module_type="bitcell_array", cols=8 + num_spare_cols, rows=8 + num_spare_rows)
a = factory.create(module_type="bitcell_array", cols=2 + num_spare_cols, rows=2 + num_spare_rows)
self.local_check(a)
openram.end_openram()
@@ -26,7 +26,7 @@ class capped_replica_bitcell_array_norbl_1rw_test(openram_test):
openram.setup_bitcell()
debug.info(2, "Testing 7x5 capped replica array for 1rw cell without replica column or dummy row")
a = factory.create(module_type="capped_replica_bitcell_array", cols=7, rows=5, rbl=[0, 0])
a = factory.create(module_type="capped_replica_bitcell_array", cols=8, rows=6, rbl=[0, 0])
self.local_check(a)
openram.end_openram()
@@ -26,7 +26,7 @@ class replica_bitcell_array_leftrbl_1rw_test(openram_test):
openram.setup_bitcell()
debug.info(2, "Testing 7x5 replica array for 1rw cell with left replica column")
a = factory.create(module_type="replica_bitcell_array", cols=7, rows=5, rbl=[1, 0], left_rbl=[0])
a = factory.create(module_type="replica_bitcell_array", cols=8, rows=8, rbl=[1, 0], left_rbl=[0])
self.local_check(a)
openram.end_openram()
+3 -1
View File
@@ -24,7 +24,9 @@ class single_bank_test(openram_test):
from openram import sram_config
c = sram_config(word_size=4,
num_words=16)
num_words=16,
num_spare_cols=1,
num_spare_rows=1)
c.num_words=32
c.words_per_row=2