Merge branch 'no_rbl' into delay_ctrl

This commit is contained in:
Sam Crow 2023-06-05 16:31:07 -07:00
commit 5fef78dbfa
39 changed files with 966 additions and 352 deletions

View File

@ -85,7 +85,8 @@ class bank(design):
for bit in range(self.word_size + self.num_spare_cols):
self.add_pin("dout{0}_{1}".format(port, bit), "OUTPUT")
for port in self.all_ports:
self.add_pin("rbl_bl_{0}_{0}".format(port), "OUTPUT")
if self.has_rbl:
self.add_pin("rbl_bl_{0}_{0}".format(port), "OUTPUT")
for port in self.write_ports:
for bit in range(self.word_size + self.num_spare_cols):
self.add_pin("din{0}_{1}".format(port, bit), "INPUT")
@ -114,11 +115,10 @@ class bank(design):
""" Create routing amoung the modules """
self.route_central_bus()
self.route_unused_wordlines()
for port in self.all_ports:
self.route_bitlines(port)
# self.route_rbl(port)
if self.has_rbl:
self.route_rbl(port)
self.route_port_address(port)
self.route_column_address_lines(port)
self.route_control_lines(port)
@ -360,6 +360,18 @@ class bank(design):
def add_modules(self):
""" Add all the modules using the class loader """
# delay control logic does not have RBLs
if OPTS.control_logic != "control_logic_delay":
self.has_rbl = True
rbl = [1, 1 if len(self.all_ports)>1 else 0]
left_rbl = [0]
right_rbl = [1] if len(self.all_ports)>1 else []
else:
self.has_rbl = False
rbl = [0, 0]
left_rbl = []
right_rbl = []
local_array_size = OPTS.local_array_size
if local_array_size > 0:
@ -372,21 +384,25 @@ class bank(design):
cols.append(local_array_size + final_size)
self.bitcell_array = factory.create(module_type="global_bitcell_array",
cols=cols,
rows=self.num_rows)
rows=self.num_rows,
rbl=rbl,
left_rbl=left_rbl,
right_rbl=right_rbl)
else:
self.bitcell_array = factory.create(module_type="capped_replica_bitcell_array",
cols=self.num_cols + self.num_spare_cols,
rows=self.num_rows,
rbl=[1, 1 if len(self.all_ports)>1 else 0],
left_rbl=[0],
right_rbl=[1] if len(self.all_ports)>1 else [])
rbl=rbl,
left_rbl=left_rbl,
right_rbl=right_rbl)
self.port_address = []
for port in self.all_ports:
self.port_address.append(factory.create(module_type="port_address",
cols=self.num_cols + self.num_spare_cols,
rows=self.num_rows,
port=port))
port=port,
has_rbl=self.has_rbl))
self.port_data = []
self.bit_offsets = self.get_column_offsets()
@ -394,6 +410,7 @@ class bank(design):
self.port_data.append(factory.create(module_type="port_data",
sram_config=self.sram_config,
port=port,
has_rbl=self.has_rbl,
bit_offsets=self.bit_offsets))
def create_bitcell_array(self):
@ -407,9 +424,10 @@ class bank(design):
# gnd
temp = self.bitcell_array.get_inouts()
temp.append("rbl_wl0")
if self.has_rbl:
temp.append("rbl_wl0")
temp.extend(self.bitcell_array.get_wordline_names())
if len(self.all_ports) > 1:
if len(self.all_ports) > 1 and self.has_rbl:
temp.append("rbl_wl1")
temp.append("vdd")
@ -432,7 +450,8 @@ class bank(design):
mod=self.port_data[port])
temp = []
temp.extend(["rbl_bl_{0}_{0}".format(port), "rbl_br_{0}_{0}".format(port)])
if self.has_rbl:
temp.extend(["rbl_bl_{0}_{0}".format(port), "rbl_br_{0}_{0}".format(port)])
temp.extend(self.bitcell_array.get_bitline_names(port))
if port in self.read_ports:
for bit in range(self.word_size + self.num_spare_cols):
@ -480,7 +499,8 @@ class bank(design):
temp.append("wl_en{}".format(port))
wordline_names = self.bitcell_array.get_wordline_names(port)
temp.extend(wordline_names)
temp.append("rbl_wl{}".format(port))
if self.has_rbl:
temp.append("rbl_wl{}".format(port))
temp.extend(["vdd", "gnd"])
self.connect_inst(temp)
@ -719,8 +739,9 @@ class bank(design):
inst2_br_name=inst2_br_name)
# Connect the replica bitlines
for (array_name, data_name) in zip(["rbl_bl_{0}_{0}".format(port), "rbl_br_{0}_{0}".format(port)], ["rbl_bl", "rbl_br"]):
self.connect_bitline(inst1, inst2, array_name, data_name)
if self.has_rbl:
for (array_name, data_name) in zip(["rbl_bl_{0}_{0}".format(port), "rbl_br_{0}_{0}".format(port)], ["rbl_bl", "rbl_br"]):
self.connect_bitline(inst1, inst2, array_name, data_name)
def route_port_data_out(self, port):
""" Add pins for the port data out """
@ -841,8 +862,13 @@ class bank(design):
def route_port_address_out(self, port, side="left"):
""" Connecting Wordline driver output to Bitcell WL connection """
driver_names = ["wl_{}".format(x) for x in range(self.num_rows)] + ["rbl_wl"]
rbl_wl_name = self.bitcell_array.get_rbl_wordline_names(port)[port]
driver_names = ["wl_{}".format(x) for x in range(self.num_rows)]
if self.has_rbl:
driver_names = driver_names + ["rbl_wl"]
rbl_wl_name = self.bitcell_array.get_rbl_wordline_names(port)[port]
else:
rbl_wl_name = None
# rbl_wl in next line will be ignored by zip once driver_names is exhausted in the no rbl case
for (driver_name, array_name) in zip(driver_names, self.bitcell_array.get_wordline_names(port) + [rbl_wl_name]):
# The mid guarantees we exit the input cell to the right.
driver_wl_pin = self.port_address_inst[port].get_pin(driver_name)
@ -875,7 +901,10 @@ class bank(design):
def route_port_address_right(self, port):
""" Connecting Wordline driver output to Bitcell WL connection """
driver_names = ["wl_{}".format(x) for x in range(self.num_rows)] + ["rbl_wl"]
driver_names = ["wl_{}".format(x) for x in range(self.num_rows)]
if self.has_rbl:
driver_names = driver_names + ["rbl_wl"]
# rbl_wl in next two lines will be ignored by zip once driver_names is exhausted in the no rbl case
rbl_wl_name = self.bitcell_array.get_rbl_wordline_names(port)[port]
for (driver_name, array_name) in zip(driver_names, self.bitcell_array.get_wordline_names(port) + [rbl_wl_name]):
# The mid guarantees we exit the input cell to the right.
@ -971,36 +1000,6 @@ class bank(design):
# layer="m1",
# offset=data_pin.center())
def route_unused_wordlines(self):
""" Connect the unused RBL and dummy wordlines to gnd """
gnd_wl_names = []
return
# Connect unused RBL WL to gnd
# All RBL WL names
array_rbl_names = set(self.bitcell_array.get_rbl_wordline_names())
# List of used RBL WL names
rbl_wl_names = set()
for port in self.all_ports:
rbl_wl_names.add(self.bitcell_array.get_rbl_wordline_names(port)[port])
gnd_wl_names = list((array_rbl_names - rbl_wl_names))
for wl_name in gnd_wl_names:
pin = self.bitcell_array_inst.get_pin(wl_name)
pin_layer = pin.layer
layer_pitch = 1.5 * getattr(self, "{}_pitch".format(pin_layer))
left_pin_loc = pin.lc()
right_pin_loc = pin.rc()
# Place the pins a track outside of the array
left_loc = left_pin_loc - vector(layer_pitch, 0)
right_loc = right_pin_loc + vector(layer_pitch, 0)
self.add_power_pin("gnd", left_loc, directions=("H", "H"))
self.add_power_pin("gnd", right_loc, directions=("H", "H"))
# Add a path to connect to the array
self.add_path(pin_layer, [left_loc, left_pin_loc])
self.add_path(pin_layer, [right_loc, right_pin_loc])
def route_control_lines(self, port):
""" Route the control lines of the entire bank """

View File

@ -33,7 +33,10 @@ class capped_replica_bitcell_array(bitcell_base_array):
self.column_size = cols
self.row_size = rows
# This is how many RBLs are in all the arrays
self.rbl = rbl
if rbl is not None:
self.rbl = rbl
else:
self.rbl = [0] * len(self.all_ports)
# This specifies which RBL to put on the left or right by port number
# This could be an empty list
if left_rbl is not None:
@ -64,28 +67,7 @@ class capped_replica_bitcell_array(bitcell_base_array):
self.create_instances()
def add_modules(self):
""" Array and dummy/replica columns
d or D = dummy cell (caps to distinguish grouping)
r or R = replica cell (caps to distinguish grouping)
b or B = bitcell
replica columns 1
v v
bdDDDDDDDDDDDDDDdb <- Dummy row
bdDDDDDDDDDDDDDDrb <- Dummy row
br--------------rb
br| Array |rb
br| row x col |rb
br--------------rb
brDDDDDDDDDDDDDDdb <- Dummy row
bdDDDDDDDDDDDDDDdb <- Dummy row
^^^^^^^^^^^^^^^
dummy rows cols x 1
^ dummy columns ^
1 x (rows + 4)
"""
""" Array and cap rows/columns """
self.replica_bitcell_array = factory.create(module_type="replica_bitcell_array",
cols=self.column_size,
@ -132,7 +114,7 @@ class capped_replica_bitcell_array(bitcell_base_array):
# + right replica column(s)
column_offset=1 + len(self.left_rbl) + self.column_size + self.rbl[0],
rows=self.row_size + self.extra_rows,
mirror=(self.rbl[0] + 1) %2)
mirror=(self.rbl[0] + 1) % 2)
def add_pins(self):
@ -219,6 +201,7 @@ class capped_replica_bitcell_array(bitcell_base_array):
# row-based or column based power and ground lines.
self.vertical_pitch = 1.1 * getattr(self, "{}_pitch".format(self.supply_stack[0]))
self.horizontal_pitch = 1.1 * getattr(self, "{}_pitch".format(self.supply_stack[2]))
# FIXME: custom sky130 replica module has a better version of this offset
self.unused_offset = vector(0.25, 0.25)
# This is a bitcell x bitcell offset to scale

View File

@ -20,14 +20,31 @@ class global_bitcell_array(bitcell_base_array):
Rows is an integer number for all local arrays.
Cols is a list of the array widths.
"""
def __init__(self, rows, cols, name=""):
def __init__(self, rows, cols, rbl=None, left_rbl=None, right_rbl=None, name=""):
# The total of all columns will be the number of columns
super().__init__(name=name, rows=rows, cols=sum(cols), column_offset=0)
self.column_sizes = cols
self.col_offsets = [0] + list(cumsum(cols)[:-1])
debug.check(len(self.all_ports)<=2, "Only support dual port or less in global bitcell array.")
self.rbl = [1, 1 if len(self.all_ports)>1 else 0]
debug.check(len(self.all_ports) < 3, "Only support dual port or less in global bitcell array.")
# This is how many RBLs are in all the arrays
if rbl is not None:
self.rbl = rbl
else:
self.rbl = [0] * len(self.all_ports)
# This specifies which RBL to put on the left or right by port number
# This could be an empty list
if left_rbl is not None:
self.left_rbl = left_rbl
else:
self.left_rbl = []
# This could be an empty list
if right_rbl is not None:
self.right_rbl = right_rbl
else:
self.right_rbl=[]
self.rbls = self.left_rbl + self.right_rbl
self.create_netlist()
if not OPTS.netlist_only:
@ -56,14 +73,13 @@ class global_bitcell_array(bitcell_base_array):
self.local_mods = []
# Special case of a single local array
# so it should contain the left and possibly right RBL
if len(self.column_sizes) == 1:
la = factory.create(module_type="local_bitcell_array",
rows=self.row_size,
cols=self.column_sizes[0],
rbl=self.rbl,
left_rbl=[0],
right_rbl=[1] if len(self.all_ports) > 1 else [])
left_rbl=self.left_rbl,
right_rbl=self.right_rbl)
self.local_mods.append(la)
return
@ -74,14 +90,14 @@ class global_bitcell_array(bitcell_base_array):
rows=self.row_size,
cols=cols,
rbl=self.rbl,
left_rbl=[0])
# Add the right RBL to the last subarray
elif i == len(self.column_sizes) - 1 and len(self.all_ports) > 1:
left_rbl=self.left_rbl)
# Add the right RBLs to the last subarray
elif i == len(self.column_sizes) - 1:
la = factory.create(module_type="local_bitcell_array",
rows=self.row_size,
cols=cols,
rbl=self.rbl,
right_rbl=[1])
right_rbl=self.right_rbl)
# Middle subarrays do not have any RBLs
else:
la = factory.create(module_type="local_bitcell_array",
@ -100,13 +116,16 @@ class global_bitcell_array(bitcell_base_array):
self.add_pin("gnd", "GROUND")
def add_bitline_pins(self):
# FIXME: aren't these already defined via inheritence by bitcell base array?
self.bitline_names = [[] for x in self.all_ports]
self.rbl_bitline_names = [[] for x in self.all_ports]
for port in self.all_ports:
self.rbl_bitline_names[0].append("rbl_bl_{}_0".format(port))
for port in self.all_ports:
self.rbl_bitline_names[0].append("rbl_br_{}_0".format(port))
# The bit is which port the RBL is for
for bit in self.rbls:
for port in self.all_ports:
self.rbl_bitline_names[bit].append("rbl_bl_{0}_{1}".format(port, bit))
for port in self.all_ports:
self.rbl_bitline_names[bit].append("rbl_br_{0}_{1}".format(port, bit))
for col in range(self.column_size):
for port in self.all_ports:
@ -114,21 +133,16 @@ class global_bitcell_array(bitcell_base_array):
for port in self.all_ports:
self.bitline_names[port].append("br_{0}_{1}".format(port, col))
if len(self.all_ports) > 1:
for port in self.all_ports:
self.rbl_bitline_names[1].append("rbl_bl_{}_1".format(port))
for port in self.all_ports:
self.rbl_bitline_names[1].append("rbl_br_{}_1".format(port))
# Make a flat list too
self.all_bitline_names = [x for sl in zip(*self.bitline_names) for x in sl]
# Make a flat list too
self.all_rbl_bitline_names = [x for sl in zip(*self.rbl_bitline_names) for x in sl]
self.add_pin_list(self.rbl_bitline_names[0], "INOUT")
for port in self.left_rbl:
self.add_pin_list(self.rbl_bitline_names[port], "INOUT")
self.add_pin_list(self.all_bitline_names, "INOUT")
if len(self.all_ports) > 1:
self.add_pin_list(self.rbl_bitline_names[1], "INOUT")
for port in self.right_rbl:
self.add_pin_list(self.rbl_bitline_names[port], "INOUT")
def add_wordline_pins(self):
@ -137,6 +151,8 @@ class global_bitcell_array(bitcell_base_array):
self.wordline_names = [[] for x in self.all_ports]
for bit in self.all_ports:
if self.rbl[bit] == 0:
continue
for port in self.all_ports:
self.rbl_wordline_names[port].append("rbl_wl_{0}_{1}".format(port, bit))
@ -239,17 +255,18 @@ class global_bitcell_array(bitcell_base_array):
start=left_pin.lc(),
end=right_pin.rc())
# Replica bitlines
self.copy_layout_pin(self.local_insts[0], "rbl_bl_0_0")
self.copy_layout_pin(self.local_insts[0], "rbl_br_0_0")
if len(self.rbls) > 0:
# Replica bitlines
self.copy_layout_pin(self.local_insts[0], "rbl_bl_0_0")
self.copy_layout_pin(self.local_insts[0], "rbl_br_0_0")
if len(self.all_ports) > 1:
self.copy_layout_pin(self.local_insts[0], "rbl_bl_1_0")
self.copy_layout_pin(self.local_insts[0], "rbl_br_1_0")
self.copy_layout_pin(self.local_insts[-1], "rbl_bl_0_1")
self.copy_layout_pin(self.local_insts[-1], "rbl_br_0_1")
self.copy_layout_pin(self.local_insts[-1], "rbl_bl_1_1")
self.copy_layout_pin(self.local_insts[-1], "rbl_br_1_1")
if len(self.all_ports) > 1:
self.copy_layout_pin(self.local_insts[0], "rbl_bl_1_0")
self.copy_layout_pin(self.local_insts[0], "rbl_br_1_0")
self.copy_layout_pin(self.local_insts[-1], "rbl_bl_0_1")
self.copy_layout_pin(self.local_insts[-1], "rbl_br_0_1")
self.copy_layout_pin(self.local_insts[-1], "rbl_bl_1_1")
self.copy_layout_pin(self.local_insts[-1], "rbl_br_1_1")
for inst in self.insts:
self.copy_power_pins(inst, "vdd")

View File

@ -31,7 +31,10 @@ class local_bitcell_array(bitcell_base_array):
self.rows = rows
self.cols = cols
# This is how many RBLs are in all the arrays
self.rbl = rbl
if rbl is not None:
self.rbl = rbl
else:
self.rbl = [0] * len(self.all_ports)
# This specifies which RBL to put on the left or right by port number
# This could be an empty list
if left_rbl is not None:
@ -84,8 +87,11 @@ class local_bitcell_array(bitcell_base_array):
left_rbl=self.left_rbl,
right_rbl=self.right_rbl)
# FIXME: this won't allow asymetric configurations such as rbl=[0, 1]
# but neither does a lot of this code...
rows = self.rows + (sum(self.rbl) != 0)
self.wl_array = factory.create(module_type="wordline_buffer_array",
rows=self.rows + 1,
rows=rows,
cols=self.cols)
def add_pins(self):
@ -136,7 +142,8 @@ class local_bitcell_array(bitcell_base_array):
self.wl_insts.append(self.add_inst(name="wl_driver{}".format(port),
mod=self.wl_array))
temp = []
temp += [self.get_rbl_wordline_names(port)[port]]
if self.rbl[port] != 0:
temp += [self.get_rbl_wordline_names(port)[port]]
if port == 0:
temp += self.get_wordline_names(port)
else:
@ -180,8 +187,9 @@ class local_bitcell_array(bitcell_base_array):
self.bitcell_array_inst.place(bitcell_array_offset)
if len(self.all_ports) > 1:
rbl_wl_adder = self.cell.height * (self.rbl[1] != 0)
wl_offset = vector(self.bitcell_array_inst.rx() + self.wl_array.width + driver_to_array_spacing,
self.bitcell_array.get_replica_bottom() + self.wl_array.height + self.cell.height)
self.bitcell_array.get_replica_bottom() + self.wl_array.height + rbl_wl_adder)
self.wl_insts[1].place(wl_offset,
mirror="XY")
@ -209,10 +217,16 @@ class local_bitcell_array(bitcell_base_array):
# Route the global wordlines
for port in self.all_ports:
if port == 0:
wordline_names = [self.get_rbl_wordline_names(port)[port]] + self.get_wordline_names(port)
if self.rbl[port] != 0:
if port == 0:
wordline_names = [self.get_rbl_wordline_names(port)[port]] + self.get_wordline_names(port)
else:
wordline_names = [self.get_rbl_wordline_names(port)[port]] + self.get_wordline_names(port)[::-1]
else:
wordline_names = [self.get_rbl_wordline_names(port)[port]] + self.get_wordline_names(port)[::-1]
if port == 0:
wordline_names = self.get_wordline_names(port)
else:
wordline_names = self.get_wordline_names(port)[::-1]
wordline_pins = self.wl_array.get_inputs()

View File

@ -18,11 +18,12 @@ class port_address(design):
Create the address port (row decoder and wordline driver)..
"""
def __init__(self, cols, rows, port, name=""):
def __init__(self, cols, rows, port, has_rbl, name=""):
self.num_cols = cols
self.num_rows = rows
self.port = port
self.has_rbl = has_rbl
self.addr_size = ceil(log(self.num_rows, 2))
if name == "":
@ -41,7 +42,8 @@ class port_address(design):
self.add_modules()
self.create_row_decoder()
self.create_wordline_driver()
self.create_rbl_driver()
if self.has_rbl:
self.create_rbl_driver()
def create_layout(self):
if "li" in layer:
@ -63,7 +65,8 @@ class port_address(design):
for bit in range(self.num_rows):
self.add_pin("wl_{0}".format(bit), "OUTPUT")
self.add_pin("rbl_wl", "OUTPUT")
if self.has_rbl:
self.add_pin("rbl_wl", "OUTPUT")
self.add_pin("vdd", "POWER")
self.add_pin("gnd", "GROUND")
@ -76,12 +79,13 @@ class port_address(design):
def route_supplies(self):
""" Propagate all vdd/gnd pins up to this level for all modules """
if layer_props.wordline_driver.vertical_supply:
self.copy_layout_pin(self.rbl_driver_inst, "vdd")
else:
rbl_pos = self.rbl_driver_inst.get_pin("vdd").rc()
self.add_power_pin("vdd", rbl_pos)
self.add_path("m4", [rbl_pos, self.wordline_driver_array_inst.get_pins("vdd")[0].rc()])
if self.has_rbl:
if layer_props.wordline_driver.vertical_supply:
self.copy_layout_pin(self.rbl_driver_inst, "vdd")
else:
rbl_pos = self.rbl_driver_inst.get_pin("vdd").rc()
self.add_power_pin("vdd", rbl_pos)
self.add_path("m4", [rbl_pos, self.wordline_driver_array_inst.get_pins("vdd")[0].rc()])
self.copy_layout_pin(self.wordline_driver_array_inst, "vdd")
self.copy_layout_pin(self.wordline_driver_array_inst, "gnd")
@ -90,11 +94,12 @@ class port_address(design):
self.copy_layout_pin(self.row_decoder_inst, "gnd")
# Also connect the B input of the RBL and_dec to vdd
if OPTS.local_array_size == 0:
rbl_b_pin = self.rbl_driver_inst.get_pin("B")
rbl_loc = rbl_b_pin.center() - vector(3 * self.m1_pitch, 0)
self.add_path(rbl_b_pin.layer, [rbl_b_pin.center(), rbl_loc])
self.add_power_pin("vdd", rbl_loc, start_layer=rbl_b_pin.layer)
if self.has_rbl:
if OPTS.local_array_size == 0:
rbl_b_pin = self.rbl_driver_inst.get_pin("B")
rbl_loc = rbl_b_pin.center() - vector(3 * self.m1_pitch, 0)
self.add_path(rbl_b_pin.layer, [rbl_b_pin.center(), rbl_loc])
self.add_power_pin("vdd", rbl_loc, start_layer=rbl_b_pin.layer)
def route_pins(self):
for row in range(self.addr_size):
@ -105,7 +110,8 @@ class port_address(design):
driver_name = "wl_{}".format(row)
self.copy_layout_pin(self.wordline_driver_array_inst, driver_name)
self.copy_layout_pin(self.rbl_driver_inst, "Z", "rbl_wl")
if self.has_rbl:
self.copy_layout_pin(self.rbl_driver_inst, "Z", "rbl_wl")
def route_internal(self):
for row in range(self.num_rows):
@ -130,19 +136,25 @@ class port_address(design):
en_pos = en_pin.bc()
else:
en_pos = en_pin.uc()
rbl_in_pin = self.rbl_driver_inst.get_pin("A")
rbl_in_pos = rbl_in_pin.center()
self.add_via_stack_center(from_layer=rbl_in_pin.layer,
to_layer=en_pin.layer,
offset=rbl_in_pos)
self.add_zjog(layer=en_pin.layer,
start=rbl_in_pos,
end=en_pos,
first_direction="V")
if self.has_rbl:
rbl_in_pin = self.rbl_driver_inst.get_pin("A")
rbl_in_pos = rbl_in_pin.center()
wl_en_offset = rbl_in_pos
self.add_via_stack_center(from_layer=rbl_in_pin.layer,
to_layer=en_pin.layer,
offset=rbl_in_pos)
self.add_zjog(layer=en_pin.layer,
start=rbl_in_pos,
end=en_pos,
first_direction="V")
else:
wl_en_offset = en_pos
self.add_layout_pin_rect_center(text="wl_en",
layer=en_pin.layer,
offset=rbl_in_pos)
offset=wl_en_offset)
def add_modules(self):
@ -164,16 +176,17 @@ class port_address(design):
# to compensate for the local array inverters
b = factory.create(module_type=OPTS.bitcell)
if local_array_size > 0:
# The local wordline driver will change the polarity
self.rbl_driver = factory.create(module_type="inv_dec",
size=driver_size,
height=b.height)
else:
# There is no local wordline driver
self.rbl_driver = factory.create(module_type="and2_dec",
size=driver_size,
height=b.height)
if self.has_rbl:
if local_array_size > 0:
# The local wordline driver will change the polarity
self.rbl_driver = factory.create(module_type="inv_dec",
size=driver_size,
height=b.height)
else:
# There is no local wordline driver
self.rbl_driver = factory.create(module_type="and2_dec",
size=driver_size,
height=b.height)
def create_row_decoder(self):
""" Create the hierarchical row decoder """
@ -231,16 +244,17 @@ class port_address(design):
wordline_driver_array_offset = vector(self.row_decoder_inst.rx(), 0)
self.wordline_driver_array_inst.place(wordline_driver_array_offset)
# This m4_pitch corresponds to the offset space for jog routing in the
# wordline_driver_array
rbl_driver_offset = wordline_driver_array_offset + vector(2 * self.m4_pitch, 0)
if self.has_rbl:
# This m4_pitch corresponds to the offset space for jog routing in the
# wordline_driver_array
rbl_driver_offset = wordline_driver_array_offset + vector(2 * self.m4_pitch, 0)
if self.port == 0:
self.rbl_driver_inst.place(rbl_driver_offset, "MX")
else:
rbl_driver_offset += vector(0,
self.wordline_driver_array.height)
self.rbl_driver_inst.place(rbl_driver_offset)
if self.port == 0:
self.rbl_driver_inst.place(rbl_driver_offset, "MX")
else:
rbl_driver_offset += vector(0,
self.wordline_driver_array.height)
self.rbl_driver_inst.place(rbl_driver_offset)
# Pass this up
self.predecoder_height = self.row_decoder.predecoder_height

View File

@ -18,13 +18,14 @@ from openram import OPTS
class port_data(design):
"""
Create the data port (column mux, sense amps, write driver, etc.) for the given port number.
Port 0 always has the RBL on the left while port 1 is on the right.
When RBLs present: port 0 always has the RBL on the left while port 1 is on the right.
"""
def __init__(self, sram_config, port, num_spare_cols=None, bit_offsets=None, name="",):
def __init__(self, sram_config, port, has_rbl, num_spare_cols=None, bit_offsets=None, name="",):
sram_config.set_local_config(self)
self.port = port
self.has_rbl = has_rbl
if self.write_size != self.word_size:
self.num_wmasks = int(math.ceil(self.word_size / self.write_size))
else:
@ -115,8 +116,9 @@ class port_data(design):
def add_pins(self):
""" Adding pins for port data module"""
self.add_pin("rbl_bl", "INOUT")
self.add_pin("rbl_br", "INOUT")
if self.has_rbl:
self.add_pin("rbl_bl", "INOUT")
self.add_pin("rbl_br", "INOUT")
for bit in range(self.num_cols):
self.add_pin("bl_{0}".format(bit), "INOUT")
self.add_pin("br_{0}".format(bit), "INOUT")
@ -202,15 +204,19 @@ class port_data(design):
precharge_width = cell.width + strap.width
else:
precharge_width = cell.width
if self.port == 0:
# Append an offset on the left
precharge_bit_offsets = [self.bit_offsets[0] - precharge_width] + self.bit_offsets
if self.has_rbl:
if self.port == 0:
# Append an offset on the left
precharge_bit_offsets = [self.bit_offsets[0] - precharge_width] + self.bit_offsets
else:
# Append an offset on the right
precharge_bit_offsets = self.bit_offsets + [self.bit_offsets[-1] + precharge_width]
else:
# Append an offset on the right
precharge_bit_offsets = self.bit_offsets + [self.bit_offsets[-1] + precharge_width]
precharge_bit_offsets = self.bit_offsets
# has_rbl is a boolean treated as 1 if true 0 if false typical python
self.precharge_array = factory.create(module_type="precharge_array",
columns=self.num_cols + self.num_spare_cols + 1,
columns=self.num_cols + self.num_spare_cols + self.has_rbl,
offsets=precharge_bit_offsets,
bitcell_bl=self.bl_names[self.port],
bitcell_br=self.br_names[self.port],
@ -294,7 +300,7 @@ class port_data(design):
mod=self.precharge_array)
temp = []
# Use left BLs for RBL
if self.port==0:
if self.port==0 and self.has_rbl:
temp.append("rbl_bl")
temp.append("rbl_br")
for bit in range(self.num_cols):
@ -306,7 +312,7 @@ class port_data(design):
temp.append("sparebr_{0}".format(bit))
# Use right BLs for RBL
if self.port==1:
if self.port==1 and self.has_rbl:
temp.append("rbl_bl")
temp.append("rbl_br")
temp.extend(["p_en_bar", "vdd"])
@ -558,7 +564,7 @@ class port_data(design):
inst1 = self.precharge_array_inst
inst1_bls_templ="{inst}_{bit}"
if self.port==0:
if self.port==0 and self.has_rbl:
start_bit=1
else:
start_bit=0
@ -683,11 +689,11 @@ class port_data(design):
""" Add the bitline pins for the given port """
# Connect one bitline to the RBL and offset the indices for the other BLs
if self.port==0:
if self.port==0 and self.has_rbl:
self.copy_layout_pin(self.precharge_array_inst, "bl_0", "rbl_bl")
self.copy_layout_pin(self.precharge_array_inst, "br_0", "rbl_br")
bit_offset=1
elif self.port==1:
elif self.port==1 and self.has_rbl:
self.copy_layout_pin(self.precharge_array_inst, "bl_{}".format(self.num_cols + self.num_spare_cols), "rbl_bl")
self.copy_layout_pin(self.precharge_array_inst, "br_{}".format(self.num_cols + self.num_spare_cols), "rbl_br")
bit_offset=0

View File

@ -36,7 +36,10 @@ class replica_bitcell_array(bitcell_base_array):
self.column_size = cols
self.row_size = rows
# This is how many RBLs are in all the arrays
self.rbl = rbl
if rbl is not None:
self.rbl = rbl
else:
self.rbl = [0] * len(self.all_ports)
# This specifies which RBL to put on the left or right by port number
# This could be an empty list
if left_rbl is not None:
@ -47,7 +50,7 @@ class replica_bitcell_array(bitcell_base_array):
if right_rbl is not None:
self.right_rbl = right_rbl
else:
self.right_rbl=[]
self.right_rbl = []
self.rbls = self.left_rbl + self.right_rbl
debug.check(sum(self.rbl) >= len(self.left_rbl) + len(self.right_rbl),
@ -64,28 +67,7 @@ class replica_bitcell_array(bitcell_base_array):
self.create_instances()
def add_modules(self):
""" Array and dummy/replica columns
d or D = dummy cell (caps to distinguish grouping)
r or R = replica cell (caps to distinguish grouping)
b or B = bitcell
replica columns 1
v v
bdDDDDDDDDDDDDDDdb <- Dummy row
bdDDDDDDDDDDDDDDrb <- Dummy row
br--------------rb
br| Array |rb
br| row x col |rb
br--------------rb
brDDDDDDDDDDDDDDdb <- Dummy row
bdDDDDDDDDDDDDDDdb <- Dummy row
^^^^^^^^^^^^^^^
dummy rows cols x 1
^ dummy columns ^
1 x (rows + 4)
"""
""" Array and dummy/replica columns """
# Bitcell array
self.bitcell_array = factory.create(module_type="bitcell_array",
column_offset=1 + len(self.left_rbl),
@ -97,6 +79,7 @@ class replica_bitcell_array(bitcell_base_array):
for port in self.all_ports:
if port in self.left_rbl:
# TODO: merge comments from other commit... to fix these comments...
# We will always have self.rbl[0] rows of replica wordlines below
# the array.
# These go from the top (where the bitcell array starts ) down
@ -123,7 +106,9 @@ class replica_bitcell_array(bitcell_base_array):
self.dummy_row = factory.create(module_type="dummy_array",
cols=self.column_size,
rows=1,
# dummy column + left replica column
# cap column + left replica column
# FIXME: these col offsets should really start at 0 because
# this is the left edge of the array... but changing them all is work
column_offset=1 + len(self.left_rbl),
mirror=0)
@ -175,6 +160,8 @@ class replica_bitcell_array(bitcell_base_array):
self.unused_wordline_names = []
for port in self.all_ports:
if self.rbl[port] == 0:
continue # TODO: there's probably a better way to do this check
for bit in self.all_ports:
self.rbl_wordline_names[port].append("rbl_wl_{0}_{1}".format(port, bit))
if bit != port:
@ -225,9 +212,12 @@ class replica_bitcell_array(bitcell_base_array):
self.dummy_row_replica_insts = []
# Note, this is the number of left and right even if we aren't adding the columns to this bitcell array!
for port in self.all_ports: # TODO: tie to self.rbl or whatever
self.dummy_row_replica_insts.append(self.add_inst(name="dummy_row_{}".format(port),
mod=self.dummy_row))
self.connect_inst(self.all_bitline_names + self.rbl_wordline_names[port] + self.supplies)
if self.rbl[port] != 0:
self.dummy_row_replica_insts.append(self.add_inst(name="dummy_row_{}".format(port),
mod=self.dummy_row))
self.connect_inst(self.all_bitline_names + self.rbl_wordline_names[port] + self.supplies)
else:
self.dummy_row_replica_insts.append(None)
def create_layout(self):
@ -249,8 +239,8 @@ class replica_bitcell_array(bitcell_base_array):
# Array was at (0, 0) but move everything so it is at the lower left
# We move DOWN the number of left RBL even if we didn't add the column to this bitcell array
# Note that this doesn't include the row/col cap
array_offset = self.bitcell_offset.scale(len(self.left_rbl), self.rbl[0])
self.translate_all(array_offset.scale(-1, -1))
array_offset = self.bitcell_offset.scale(-len(self.left_rbl), -self.rbl[0])
self.translate_all(array_offset)
self.add_layout_pins()
@ -359,7 +349,7 @@ class replica_bitcell_array(bitcell_base_array):
height=self.height)
def route_supplies(self):
""" just copy supply pins from all instances """
for inst in self.insts:
for pin_name in ["vdd", "gnd"]:
self.copy_layout_pin(inst, pin_name)

View File

@ -14,7 +14,7 @@ from openram.sram_factory import factory
from openram import OPTS
class capped_replica_bitcell_array_1rw_1r_test(openram_test):
class capped_replica_bitcell_array_bothrbl_1rw_1r_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
@ -25,13 +25,8 @@ class capped_replica_bitcell_array_1rw_1r_test(openram_test):
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 4x4 array left and right replica for dp cell")
a = factory.create(module_type="capped_replica_bitcell_array",
cols=4,
rows=4,
rbl=[1, 1],
left_rbl=[0],
right_rbl=[1])
debug.info(2, "Testing 4x4 capped replica array for 1rw1r cell with both replica columns")
a = factory.create(module_type="capped_replica_bitcell_array", cols=4, rows=4, rbl=[1, 1], left_rbl=[0], right_rbl=[1])
self.local_check(a)
openram.end_openram()

View File

@ -0,0 +1,40 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2023 Regents of the University of California, Santa Cruz
# All rights reserved.
#
import sys, os
import unittest
from testutils import *
import openram
from openram import debug
from openram.sram_factory import factory
from openram import OPTS
class capped_replica_bitcell_array_dummies_1rw_1r_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
openram.init_openram(config_file, is_unit_test=True)
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 4x4 capped replica array for 1rw1r cell with dummy rows only")
a = factory.create(module_type="capped_replica_bitcell_array", cols=4, rows=4, rbl=[1, 1])
self.local_check(a)
openram.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = openram.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main(testRunner=debugTestRunner())

View File

@ -0,0 +1,40 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2023 Regents of the University of California, Santa Cruz
# All rights reserved.
#
import sys, os
import unittest
from testutils import *
import openram
from openram import debug
from openram.sram_factory import factory
from openram import OPTS
class capped_replica_bitcell_array_dummies_1rw_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
openram.init_openram(config_file, is_unit_test=True)
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 0
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 7x5 capped replica array for 1rw cell with dummy row only")
a = factory.create(module_type="capped_replica_bitcell_array", cols=7, rows=5, rbl=[1, 0])
self.local_check(a)
openram.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = openram.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main(testRunner=debugTestRunner())

View File

@ -14,7 +14,7 @@ from openram.sram_factory import factory
from openram import OPTS
class capped_replica_bitcell_array_1rw_1r_test(openram_test):
class capped_replica_bitcell_array_leftrbl_1rw_1r_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
@ -25,16 +25,13 @@ class capped_replica_bitcell_array_1rw_1r_test(openram_test):
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 4x4 left replica array for dp cell")
a = factory.create(module_type="capped_replica_bitcell_array",
cols=4,
rows=4,
rbl=[1, 1],
left_rbl=[0])
debug.info(2, "Testing 4x4 capped replica array for 1rw1r cell with left replica column")
a = factory.create(module_type="capped_replica_bitcell_array", cols=4, rows=4, rbl=[1, 1], left_rbl=[0])
self.local_check(a)
openram.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = openram.parse_args()

View File

@ -14,7 +14,7 @@ from openram.sram_factory import factory
from openram import OPTS
class capped_replica_bitcell_array_test(openram_test):
class capped_replica_bitcell_array_leftrbl_1rw_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
@ -23,8 +23,9 @@ class capped_replica_bitcell_array_test(openram_test):
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 0
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 4x4 array for bitcell")
debug.info(2, "Testing 7x5 capped replica array for 1rw cell with left replica column")
a = factory.create(module_type="capped_replica_bitcell_array", cols=7, rows=5, rbl=[1, 0], left_rbl=[0])
self.local_check(a)

View File

@ -14,7 +14,7 @@ from openram.sram_factory import factory
from openram import OPTS
class capped_replica_bitcell_array_1rw_1r_test(openram_test):
class capped_replica_bitcell_array_norbl_1rw_1r_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
@ -25,11 +25,8 @@ class capped_replica_bitcell_array_1rw_1r_test(openram_test):
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 4x4 non-replica array for dp cell")
a = factory.create(module_type="capped_replica_bitcell_array",
cols=4,
rows=4,
rbl=[1, 1])
debug.info(2, "Testing 4x4 capped replica array for 1rw1r cell without replica columns or dummy rows")
a = factory.create(module_type="capped_replica_bitcell_array", cols=4, rows=4, rbl=[0, 0])
self.local_check(a)
openram.end_openram()

View File

@ -14,7 +14,7 @@ from openram.sram_factory import factory
from openram import OPTS
class capped_replica_bitcell_array_test(openram_test):
class capped_replica_bitcell_array_norbl_1rw_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
@ -23,9 +23,10 @@ class capped_replica_bitcell_array_test(openram_test):
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 0
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 4x4 array for bitcell")
a = factory.create(module_type="capped_replica_bitcell_array", cols=7, rows=5, rbl=[1, 0])
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])
self.local_check(a)
openram.end_openram()

View File

@ -14,7 +14,7 @@ from openram.sram_factory import factory
from openram import OPTS
class capped_replica_bitcell_array_1rw_1r_test(openram_test):
class capped_replica_bitcell_array_rightrbl_1rw_1r_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
@ -25,16 +25,13 @@ class capped_replica_bitcell_array_1rw_1r_test(openram_test):
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 4x4 left replica array for dp cell")
a = factory.create(module_type="capped_replica_bitcell_array",
cols=4,
rows=4,
rbl=[1, 1],
right_rbl=[1])
debug.info(2, "Testing 4x4 capped replica array for 1rw1r cell with right replica column")
a = factory.create(module_type="capped_replica_bitcell_array", cols=4, rows=4, rbl=[1, 1], right_rbl=[1])
self.local_check(a)
openram.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = openram.parse_args()

View File

@ -14,7 +14,7 @@ from openram.sram_factory import factory
from openram import OPTS
class replica_bitcell_array_1rw_1r_test(openram_test):
class replica_bitcell_array_bothrbl_1rw_1r_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
@ -25,13 +25,8 @@ class replica_bitcell_array_1rw_1r_test(openram_test):
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 4x4 array left and right replica for dp cell")
a = factory.create(module_type="replica_bitcell_array",
cols=4,
rows=4,
rbl=[1, 1],
left_rbl=[0],
right_rbl=[1])
debug.info(2, "Testing 4x4 replica array for 1rw1r cell with both replica columns")
a = factory.create(module_type="replica_bitcell_array", cols=4, rows=4, rbl=[1, 1], left_rbl=[0], right_rbl=[1])
self.local_check(a)
openram.end_openram()

View File

@ -0,0 +1,40 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2023 Regents of the University of California, Santa Cruz
# All rights reserved.
#
import sys, os
import unittest
from testutils import *
import openram
from openram import debug
from openram.sram_factory import factory
from openram import OPTS
class replica_bitcell_array_dummies_1rw_1r_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
openram.init_openram(config_file, is_unit_test=True)
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 4x4 replica array for 1rw1r cell with dummy rows only")
a = factory.create(module_type="replica_bitcell_array", cols=4, rows=4, rbl=[1, 1])
self.local_check(a)
openram.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = openram.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main(testRunner=debugTestRunner())

View File

@ -0,0 +1,40 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2023 Regents of the University of California, Santa Cruz
# All rights reserved.
#
import sys, os
import unittest
from testutils import *
import openram
from openram import debug
from openram.sram_factory import factory
from openram import OPTS
class replica_bitcell_array_dummies_1rw_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
openram.init_openram(config_file, is_unit_test=True)
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 0
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 7x5 replica array for 1rw cell with dummy row only")
a = factory.create(module_type="replica_bitcell_array", cols=7, rows=5, rbl=[1, 0])
self.local_check(a)
openram.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = openram.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main(testRunner=debugTestRunner())

View File

@ -14,7 +14,7 @@ from openram.sram_factory import factory
from openram import OPTS
class replica_bitcell_array_1rw_1r_test(openram_test):
class replica_bitcell_array_leftrbl_1rw_1r_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
@ -25,16 +25,13 @@ class replica_bitcell_array_1rw_1r_test(openram_test):
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 4x4 left replica array for dp cell")
a = factory.create(module_type="replica_bitcell_array",
cols=4,
rows=4,
rbl=[1, 1],
left_rbl=[0])
debug.info(2, "Testing 4x4 replica array for 1rw1r cell with left replica column")
a = factory.create(module_type="replica_bitcell_array", cols=4, rows=4, rbl=[1, 1], left_rbl=[0])
self.local_check(a)
openram.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = openram.parse_args()

View File

@ -14,7 +14,7 @@ from openram.sram_factory import factory
from openram import OPTS
class replica_bitcell_array_test(openram_test):
class replica_bitcell_array_leftrbl_1rw_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
@ -23,8 +23,9 @@ class replica_bitcell_array_test(openram_test):
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 0
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 4x4 array for 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])
self.local_check(a)

View File

@ -14,7 +14,7 @@ from openram.sram_factory import factory
from openram import OPTS
class replica_bitcell_array_1rw_1r_test(openram_test):
class replica_bitcell_array_norbl_1rw_1r_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
@ -25,11 +25,8 @@ class replica_bitcell_array_1rw_1r_test(openram_test):
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 4x4 non-replica array for dp cell")
a = factory.create(module_type="replica_bitcell_array",
cols=4,
rows=4,
rbl=[1, 1])
debug.info(2, "Testing 4x4 replica array for 1rw1r cell without replica columns or dummy rows")
a = factory.create(module_type="replica_bitcell_array", cols=4, rows=4, rbl=[0, 0])
self.local_check(a)
openram.end_openram()

View File

@ -14,7 +14,7 @@ from openram.sram_factory import factory
from openram import OPTS
class replica_bitcell_array_test(openram_test):
class replica_bitcell_array_norbl_1rw_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
@ -23,9 +23,10 @@ class replica_bitcell_array_test(openram_test):
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 0
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 4x4 array for bitcell")
a = factory.create(module_type="replica_bitcell_array", cols=7, rows=5, rbl=[1, 0])
debug.info(2, "Testing 7x5 replica array for 1rw cell without replica column or dummy row")
a = factory.create(module_type="replica_bitcell_array", cols=7, rows=5, rbl=[0, 0])
self.local_check(a)
openram.end_openram()

View File

@ -14,7 +14,7 @@ from openram.sram_factory import factory
from openram import OPTS
class replica_bitcell_array_1rw_1r_test(openram_test):
class replica_bitcell_array_rightrbl_1rw_1r_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
@ -25,16 +25,13 @@ class replica_bitcell_array_1rw_1r_test(openram_test):
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 4x4 left replica array for dp cell")
a = factory.create(module_type="replica_bitcell_array",
cols=4,
rows=4,
rbl=[1, 1],
right_rbl=[1])
debug.info(2, "Testing 4x4 replica array for 1rw1r cell with right replica column")
a = factory.create(module_type="replica_bitcell_array", cols=4, rows=4, rbl=[1, 1], right_rbl=[1])
self.local_check(a)
openram.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = openram.parse_args()

View File

@ -1,9 +1,7 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2023 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University)
# Copyright (c) 2016-2023 Regents of the University of California, Santa Cruz
# All rights reserved.
#
import sys, os
@ -11,24 +9,24 @@ import unittest
from testutils import *
import openram
from openram.sram_factory import factory
from openram import debug
from openram.sram_factory import factory
from openram import OPTS
# @unittest.skip("SKIPPING 05_global_bitcell_array_test")
class global_bitcell_array_test(openram_test):
class global_bitcell_array_norbl_1rw_1r_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
openram.init_openram(config_file, is_unit_test=True)
# debug.info(2, "Testing 2 x 4x4 global bitcell array for 6t_cell")
# a = factory.create(module_type="global_bitcell_array", cols=[4, 4], rows=4)
# self.local_check(a)
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 2 x 4x4 global bitcell array for 6t_cell")
a = factory.create(module_type="global_bitcell_array", cols=[10, 6], rows=4)
debug.info(2, "Testing 2 x 4x4 global bitcell array for 1rw1r cell without replica columns")
a = factory.create(module_type="global_bitcell_array", cols=[4, 4, 4], rows=4, rbl=[0, 0], left_rbl=[], right_rbl=[])
self.local_check(a)
openram.end_openram()

View File

@ -0,0 +1,40 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2023 Regents of the University of California, Santa Cruz
# All rights reserved.
#
import sys, os
import unittest
from testutils import *
import openram
from openram import debug
from openram.sram_factory import factory
from openram import OPTS
class global_bitcell_array_norbl_1rw_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
openram.init_openram(config_file, is_unit_test=True)
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 0
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 2 x 4x4 global bitcell array for 1rw cell without replica column")
a = factory.create(module_type="global_bitcell_array", cols=[4, 4], rows=4, rbl=[0, 0], left_rbl=[])
self.local_check(a)
openram.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = openram.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main(testRunner=debugTestRunner())

View File

@ -0,0 +1,40 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2023 Regents of the University of California, Santa Cruz
# All rights reserved.
#
import sys, os
import unittest
from testutils import *
import openram
from openram import debug
from openram.sram_factory import factory
from openram import OPTS
class global_bitcell_array_rbl_1rw_1r_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
openram.init_openram(config_file, is_unit_test=True)
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 2 x 4x4 global bitcell array for 1rw1r cell with replica columns")
a = factory.create(module_type="global_bitcell_array", cols=[4, 4, 4], rows=4, rbl=[1, 1], left_rbl=[0], right_rbl=[1])
self.local_check(a)
openram.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = openram.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main(testRunner=debugTestRunner())

View File

@ -0,0 +1,40 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2023 Regents of the University of California, Santa Cruz
# All rights reserved.
#
import sys, os
import unittest
from testutils import *
import openram
from openram import debug
from openram.sram_factory import factory
from openram import OPTS
class global_bitcell_array_rbl_1rw_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
openram.init_openram(config_file, is_unit_test=True)
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 0
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 2 x 4x4 global bitcell array for 1rw cell with left replica column")
a = factory.create(module_type="global_bitcell_array", cols=[4, 4], rows=4, rbl=[1, 0], left_rbl=[0])
self.local_check(a)
openram.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = openram.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main(testRunner=debugTestRunner())

View File

@ -1,55 +0,0 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2023 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University)
# All rights reserved.
#
import sys, os
import unittest
from testutils import *
import openram
from openram import debug
from openram.sram_factory import factory
from openram import OPTS
# @unittest.skip("SKIPPING 05_local_bitcell_array_test")
class local_bitcell_array_1rw_1r_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
openram.init_openram(config_file, is_unit_test=True)
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 4x4 local bitcell array for cell_1rw_1r without replica")
a = factory.create(module_type="local_bitcell_array", cols=4, rows=4, rbl=[1, 1])
self.local_check(a)
debug.info(2, "Testing 4x4 local bitcell array for cell_1rw_1r with replica column")
a = factory.create(module_type="local_bitcell_array", cols=4, rows=4, rbl=[1, 1], right_rbl=[1])
self.local_check(a)
debug.info(2, "Testing 4x4 local bitcell array for cell_1rw_1r with replica column")
a = factory.create(module_type="local_bitcell_array", cols=4, rows=4, rbl=[1, 1], left_rbl=[0])
self.local_check(a)
debug.info(2, "Testing 4x4 local bitcell array for cell_1rw_1r with replica column")
a = factory.create(module_type="local_bitcell_array", cols=4, rows=4, rbl=[1, 1], left_rbl=[0], right_rbl=[1])
self.local_check(a)
openram.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = openram.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main(testRunner=debugTestRunner())

View File

@ -1,9 +1,7 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2023 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University)
# Copyright (c) 2016-2023 Regents of the University of California, Santa Cruz
# All rights reserved.
#
import sys, os
@ -16,19 +14,19 @@ from openram.sram_factory import factory
from openram import OPTS
# @unittest.skip("SKIPPING 05_local_bitcell_array_test")
class local_bitcell_array_test(openram_test):
class local_bitcell_array_bothrbl_1rw_1r_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
openram.init_openram(config_file, is_unit_test=True)
debug.info(2, "Testing 4x4 local bitcell array for 6t_cell without replica")
a = factory.create(module_type="local_bitcell_array", cols=4, rows=4, rbl=[1, 0])
self.local_check(a)
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 4x4 local bitcell array for 6t_cell with replica column")
a = factory.create(module_type="local_bitcell_array", cols=4, rows=4, rbl=[1, 0], left_rbl=[0])
debug.info(2, "Testing 4x4 local bitcell array for 1rw1r cell with both replica columns")
a = factory.create(module_type="local_bitcell_array", cols=4, rows=4, rbl=[1, 1], left_rbl=[0], right_rbl=[1])
self.local_check(a)
openram.end_openram()

View File

@ -0,0 +1,40 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2023 Regents of the University of California, Santa Cruz
# All rights reserved.
#
import sys, os
import unittest
from testutils import *
import openram
from openram import debug
from openram.sram_factory import factory
from openram import OPTS
class local_bitcell_array_dummies_1rw_1r_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
openram.init_openram(config_file, is_unit_test=True)
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 4x4 local bitcell array for 1rw1r cell with dummy rows only")
a = factory.create(module_type="local_bitcell_array", cols=4, rows=4, rbl=[1, 1])
self.local_check(a)
openram.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = openram.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main(testRunner=debugTestRunner())

View File

@ -0,0 +1,40 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2023 Regents of the University of California, Santa Cruz
# All rights reserved.
#
import sys, os
import unittest
from testutils import *
import openram
from openram import debug
from openram.sram_factory import factory
from openram import OPTS
class local_bitcell_array_dummies_1rw_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
openram.init_openram(config_file, is_unit_test=True)
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 0
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 7x5 local bitcell array for 1rw cell with dummy row only")
a = factory.create(module_type="local_bitcell_array", cols=7, rows=5, rbl=[1, 0])
self.local_check(a)
openram.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = openram.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main(testRunner=debugTestRunner())

View File

@ -0,0 +1,40 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2023 Regents of the University of California, Santa Cruz
# All rights reserved.
#
import sys, os
import unittest
from testutils import *
import openram
from openram import debug
from openram.sram_factory import factory
from openram import OPTS
class local_bitcell_array_leftrbl_1rw_1r_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
openram.init_openram(config_file, is_unit_test=True)
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 4x4 local bitcell array for 1rw1r cell with left replica column")
a = factory.create(module_type="local_bitcell_array", cols=4, rows=4, rbl=[1, 1], left_rbl=[0])
self.local_check(a)
openram.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = openram.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main(testRunner=debugTestRunner())

View File

@ -0,0 +1,40 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2023 Regents of the University of California, Santa Cruz
# All rights reserved.
#
import sys, os
import unittest
from testutils import *
import openram
from openram import debug
from openram.sram_factory import factory
from openram import OPTS
class local_bitcell_array_leftrbl_1rw_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
openram.init_openram(config_file, is_unit_test=True)
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 0
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 7x5 local bitcell array for 1rw cell with left replica column")
a = factory.create(module_type="local_bitcell_array", cols=7, rows=5, rbl=[1, 0], left_rbl=[0])
self.local_check(a)
openram.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = openram.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main(testRunner=debugTestRunner())

View File

@ -0,0 +1,40 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2023 Regents of the University of California, Santa Cruz
# All rights reserved.
#
import sys, os
import unittest
from testutils import *
import openram
from openram import debug
from openram.sram_factory import factory
from openram import OPTS
class local_bitcell_array_norbl_1rw_1r_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
openram.init_openram(config_file, is_unit_test=True)
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 4x4 local bitcell array for 1rw1r cell without replica columns or dummy rows")
a = factory.create(module_type="local_bitcell_array", cols=4, rows=4, rbl=[0, 0])
self.local_check(a)
openram.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = openram.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main(testRunner=debugTestRunner())

View File

@ -0,0 +1,40 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2023 Regents of the University of California, Santa Cruz
# All rights reserved.
#
import sys, os
import unittest
from testutils import *
import openram
from openram import debug
from openram.sram_factory import factory
from openram import OPTS
class local_bitcell_array_norbl_1rw_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
openram.init_openram(config_file, is_unit_test=True)
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 0
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 7x5 local bitcell array for 1rw cell without replica column or dummy row")
a = factory.create(module_type="local_bitcell_array", cols=7, rows=5, rbl=[0, 0])
self.local_check(a)
openram.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = openram.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main(testRunner=debugTestRunner())

View File

@ -0,0 +1,40 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2023 Regents of the University of California, Santa Cruz
# All rights reserved.
#
import sys, os
import unittest
from testutils import *
import openram
from openram import debug
from openram.sram_factory import factory
from openram import OPTS
class local_bitcell_array_rightrbl_1rw_1r_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
openram.init_openram(config_file, is_unit_test=True)
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 4x4 local bitcell array for 1rw1r cell with right replica column")
a = factory.create(module_type="local_bitcell_array", cols=4, rows=4, rbl=[1, 1], right_rbl=[1])
self.local_check(a)
openram.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = openram.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main(testRunner=debugTestRunner())

View File

@ -16,25 +16,27 @@ from openram.sram_factory import factory
from openram import OPTS
# @unittest.skip("SKIPPING 05_global_bitcell_array_test")
class global_bitcell_array_test(openram_test):
class single_bank_nomux_norbl_1rw_1r_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
openram.init_openram(config_file, is_unit_test=True)
from openram import sram_config
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1
OPTS.num_w_ports = 0
openram.setup_bitcell()
debug.info(2, "Testing 2 x 4x4 global bitcell array for cell_1rw_1r")
a = factory.create(module_type="global_bitcell_array", cols=[4, 4], rows=4)
self.local_check(a)
c = sram_config(word_size=4,
num_words=16)
# debug.info(2, "Testing 4x4 local bitcell array for 6t_cell with replica column")
# a = factory.create(module_type="local_bitcell_array", cols=4, left_rbl=1, rows=4, ports=[0])
# self.local_check(a)
c.words_per_row=1
OPTS.control_logic = "control_logic_delay"
c.recompute_sizes()
debug.info(1, "No column mux")
a = factory.create(module_type="bank", sram_config=c)
self.local_check(a)
openram.end_openram()

View File

@ -0,0 +1,54 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2023 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University)
# All rights reserved.
#
import sys, os
import unittest
from testutils import *
import openram
from openram import debug
from openram.sram_factory import factory
from openram import OPTS
class single_bank_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
openram.init_openram(config_file, is_unit_test=True)
from openram import sram_config
if OPTS.tech_name == "sky130":
num_spare_rows = 1
num_spare_cols = 1
else:
num_spare_rows = 0
num_spare_cols = 0
c = sram_config(word_size=4,
num_words=16,
num_spare_cols=num_spare_cols,
num_spare_rows=num_spare_rows)
c.words_per_row=1
OPTS.control_logic = "control_logic_delay"
factory.reset()
c.recompute_sizes()
debug.info(1, "No column mux")
a = factory.create("bank", sram_config=c)
self.local_check(a)
openram.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = openram.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main(testRunner=debugTestRunner())

View File

@ -0,0 +1,58 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2023 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University)
# All rights reserved.
#
import sys, os
import unittest
from testutils import *
import openram
from openram import debug
from openram.sram_factory import factory
from openram import OPTS
class sram_1bank_nomux_norbl_1rw_1r_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
openram.init_openram(config_file, is_unit_test=True)
from openram import sram_config
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1
OPTS.num_w_ports = 0
openram.setup_bitcell()
c = sram_config(word_size=4,
num_words=16,
num_banks=1)
c.words_per_row=1
OPTS.control_logic = "control_logic_delay"
c.recompute_sizes()
debug.info(1, "Layout test for {}rw,{}r,{}w sram "
"with {} bit words, {} words, {} words per "
"row, {} banks".format(OPTS.num_rw_ports,
OPTS.num_r_ports,
OPTS.num_w_ports,
c.word_size,
c.num_words,
c.words_per_row,
c.num_banks))
a = factory.create(module_type="sram", sram_config=c)
self.local_check(a, final_verification=True)
openram.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = openram.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main(testRunner=debugTestRunner())