Merge branch 'dev' into discrete_models

This commit is contained in:
jcirimel 2020-06-06 01:48:06 -07:00
commit 5d5ed552e3
54 changed files with 312 additions and 390 deletions

View File

@ -450,26 +450,27 @@ class layout():
path=coordinates, path=coordinates,
layer_widths=layer_widths) layer_widths=layer_widths)
def add_zjog(self, layer, start, end, first_direction="H", fixed_offset=None): def add_zjog(self, layer, start, end, first_direction="H", var_offset=0.5, fixed_offset=None):
""" """
Add a simple jog at the halfway point. Add a simple jog at the halfway point.
If layer is a single value, it is a path. If layer is a single value, it is a path.
If layer is a tuple, it is a wire with preferred directions. If layer is a tuple, it is a wire with preferred directions.
""" """
neg_offset = 1.0 - var_offset
# vertical first # vertical first
if first_direction == "V": if first_direction == "V":
if fixed_offset: if fixed_offset:
mid1 = vector(start.x, fixed_offset) mid1 = vector(start.x, fixed_offset)
else: else:
mid1 = vector(start.x, 0.5 * start.y + 0.5 * end.y) mid1 = vector(start.x, neg_offset * start.y + var_offset * end.y)
mid2 = vector(end.x, mid1.y) mid2 = vector(end.x, mid1.y)
# horizontal first # horizontal first
elif first_direction == "H": elif first_direction == "H":
if fixed_offset: if fixed_offset:
mid1 = vector(fixed_offset, start.y) mid1 = vector(fixed_offset, start.y)
else: else:
mid1 = vector(0.5 * start.x + 0.5 * end.x, start.y) mid1 = vector(neg_offset * start.x + var_offset * end.x, start.y)
mid2 = vector(mid1, end.y) mid2 = vector(mid1, end.y)
else: else:
debug.error("Invalid direction for jog -- must be H or V.") debug.error("Invalid direction for jog -- must be H or V.")

View File

@ -214,25 +214,18 @@ def setup_bitcell():
if OPTS.num_r_ports > 0: if OPTS.num_r_ports > 0:
ports += "{}r".format(OPTS.num_r_ports) ports += "{}r".format(OPTS.num_r_ports)
OPTS.bitcell = "bitcell_"+ports if ports != "":
OPTS.replica_bitcell = "replica_bitcell_"+ports OPTS.bitcell_suffix = "_" + ports
OPTS.dummy_bitcell = "dummy_bitcell_"+ports OPTS.bitcell = "bitcell" + OPTS.bitcell_suffix
else:
OPTS.replica_bitcell = "replica_" + OPTS.bitcell
OPTS.replica_bitcell = "dummy_" + OPTS.bitcell
# See if bitcell exists # See if bitcell exists
try: try:
__import__(OPTS.bitcell) __import__(OPTS.bitcell)
__import__(OPTS.replica_bitcell)
__import__(OPTS.dummy_bitcell)
except ImportError: except ImportError:
# Use the pbitcell if we couldn't find a custom bitcell # Use the pbitcell if we couldn't find a custom bitcell
# or its custom replica bitcell # or its custom replica bitcell
# Use the pbitcell (and give a warning if not in unit test mode) # Use the pbitcell (and give a warning if not in unit test mode)
OPTS.bitcell = "pbitcell" OPTS.bitcell = "pbitcell"
OPTS.replica_bitcell = "replica_pbitcell"
OPTS.replica_bitcell = "dummy_pbitcell"
if not OPTS.is_unit_test: if not OPTS.is_unit_test:
debug.warning("Using the parameterized bitcell which may have suboptimal density.") debug.warning("Using the parameterized bitcell which may have suboptimal density.")
debug.info(1, "Using bitcell: {}".format(OPTS.bitcell)) debug.info(1, "Using bitcell: {}".format(OPTS.bitcell))

View File

@ -798,22 +798,34 @@ class bank(design.design):
for row in range(self.num_rows): for row in range(self.num_rows):
# The mid guarantees we exit the input cell to the right. # The mid guarantees we exit the input cell to the right.
driver_wl_pos = self.port_address_inst[port].get_pin("wl_{}".format(row)).rc() driver_wl_pin = self.port_address_inst[port].get_pin("wl_{}".format(row))
bitcell_wl_pos = self.bitcell_array_inst.get_pin(self.wl_names[port] + "_{}".format(row)).lc() driver_wl_pos = driver_wl_pin.rc()
bitcell_wl_pin = self.bitcell_array_inst.get_pin(self.wl_names[port] + "_{}".format(row))
bitcell_wl_pos = bitcell_wl_pin.lc()
mid1 = driver_wl_pos.scale(0, 1) + vector(0.5 * self.port_address_inst[port].rx() + 0.5 * self.bitcell_array_inst.lx(), 0) mid1 = driver_wl_pos.scale(0, 1) + vector(0.5 * self.port_address_inst[port].rx() + 0.5 * self.bitcell_array_inst.lx(), 0)
mid2 = mid1.scale(1, 0) + bitcell_wl_pos.scale(0.5, 1) mid2 = mid1.scale(1, 0) + bitcell_wl_pos.scale(0.5, 1)
self.add_path("m1", [driver_wl_pos, mid1, mid2, bitcell_wl_pos]) self.add_path(driver_wl_pin.layer, [driver_wl_pos, mid1, mid2, bitcell_wl_pos])
self.add_via_stack_center(from_layer=driver_wl_pin.layer,
to_layer=bitcell_wl_pin.layer,
offset=bitcell_wl_pos,
directions=("H", "H"))
def route_port_address_right(self, port): def route_port_address_right(self, port):
""" Connecting Wordline driver output to Bitcell WL connection """ """ Connecting Wordline driver output to Bitcell WL connection """
for row in range(self.num_rows): for row in range(self.num_rows):
# The mid guarantees we exit the input cell to the right. # The mid guarantees we exit the input cell to the right.
driver_wl_pos = self.port_address_inst[port].get_pin("wl_{}".format(row)).lc() driver_wl_pin = self.port_address_inst[port].get_pin("wl_{}".format(row))
bitcell_wl_pos = self.bitcell_array_inst.get_pin(self.wl_names[port] + "_{}".format(row)).rc() driver_wl_pos = driver_wl_pin.lc()
bitcell_wl_pin = self.bitcell_array_inst.get_pin(self.wl_names[port] + "_{}".format(row))
bitcell_wl_pos = bitcell_wl_pin.rc()
mid1 = driver_wl_pos.scale(0, 1) + vector(0.5 * self.port_address_inst[port].lx() + 0.5 * self.bitcell_array_inst.rx(), 0) mid1 = driver_wl_pos.scale(0, 1) + vector(0.5 * self.port_address_inst[port].lx() + 0.5 * self.bitcell_array_inst.rx(), 0)
mid2 = mid1.scale(1, 0) + bitcell_wl_pos.scale(0, 1) mid2 = mid1.scale(1, 0) + bitcell_wl_pos.scale(0, 1)
self.add_path("m1", [driver_wl_pos, mid1, mid2, bitcell_wl_pos]) self.add_path(driver_wl_pin.layer, [driver_wl_pos, mid1, mid2, bitcell_wl_pos])
self.add_via_stack_center(from_layer=driver_wl_pin.layer,
to_layer=bitcell_wl_pin.layer,
offset=bitcell_wl_pos,
directions=("H", "H"))
def route_column_address_lines(self, port): def route_column_address_lines(self, port):
""" Connecting the select lines of column mux to the address bus """ """ Connecting the select lines of column mux to the address bus """

View File

@ -8,6 +8,7 @@ from sram_factory import factory
from globals import OPTS from globals import OPTS
from tech import cell_properties from tech import cell_properties
class col_cap_array(bitcell_base_array): class col_cap_array(bitcell_base_array):
""" """
Generate a dummy row/column for the replica array. Generate a dummy row/column for the replica array.
@ -35,8 +36,7 @@ class col_cap_array(bitcell_base_array):
def add_modules(self): def add_modules(self):
""" Add the modules used in this design """ """ Add the modules used in this design """
# self.dummy_cell = factory.create(module_type="col_cap_bitcell_1rw_1r") # TODO: make module_type generic self.dummy_cell = factory.create(module_type="col_cap_{}".format(OPTS.bitcell))
self.dummy_cell = factory.create(module_type="col_cap_bitcell")
self.add_mod(self.dummy_cell) self.add_mod(self.dummy_cell)
self.cell = factory.create(module_type="bitcell") self.cell = factory.create(module_type="bitcell")

View File

@ -38,12 +38,11 @@ class dummy_array(bitcell_base_array):
def add_modules(self): def add_modules(self):
""" Add the modules used in this design """ """ Add the modules used in this design """
self.dummy_cell = factory.create(module_type="dummy_bitcell") self.dummy_cell = factory.create(module_type="dummy_{}".format(OPTS.bitcell))
self.add_mod(self.dummy_cell) self.add_mod(self.dummy_cell)
self.cell = factory.create(module_type="bitcell") self.cell = factory.create(module_type="bitcell")
def create_instances(self): def create_instances(self):
""" Create the module instances used in this design """ """ Create the module instances used in this design """
self.cell_inst = {} self.cell_inst = {}

View File

@ -48,11 +48,18 @@ class hierarchical_decoder(design.design):
self.setup_layout_constants() self.setup_layout_constants()
self.place_pre_decoder() self.place_pre_decoder()
self.place_row_decoder() self.place_row_decoder()
self.height = max(self.predecoder_height, self.row_decoder_height) + self.bus_space
self.route_inputs() self.route_inputs()
self.route_outputs() self.route_outputs()
self.route_decoder_bus() self.route_decoder_bus()
self.route_vdd_gnd() self.route_vdd_gnd()
self.offset_all_coordinates() self.offset_all_coordinates()
self.width = self.and_inst[0].rx() + self.m1_space
self.add_boundary() self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
@ -178,21 +185,6 @@ class hierarchical_decoder(design.design):
# Extra bus space for supply contacts # Extra bus space for supply contacts
self.input_routing_width = self.num_inputs * self.bus_pitch + self.bus_space self.input_routing_width = self.num_inputs * self.bus_pitch + self.bus_space
# Calculates height and width of row-decoder
# Calculates height and width of hierarchical decoder
# Add extra pitch for good measure
self.height = max(self.predecoder_height, self.row_decoder_height) + self.bus_space
if (self.num_inputs == 4 or self.num_inputs == 5):
self.nand_width = self.and2.width
else:
self.nand_width = self.and3.width
self.width = self.input_routing_width \
+ self.predecoder_width \
+ self.internal_routing_width \
+ self.nand_width \
+ self.m1_space
def route_inputs(self): def route_inputs(self):
""" Create input bus for the predecoders """ """ Create input bus for the predecoders """
# Find the left-most predecoder # Find the left-most predecoder

View File

@ -93,7 +93,7 @@ class port_address(design.design):
decoder_out_pos = decoder_out_pin.rc() decoder_out_pos = decoder_out_pin.rc()
driver_in_pin = self.wordline_driver_inst.get_pin("in_{}".format(row)) driver_in_pin = self.wordline_driver_inst.get_pin("in_{}".format(row))
driver_in_pos = driver_in_pin.lc() driver_in_pos = driver_in_pin.lc()
self.add_zjog(self.route_layer, decoder_out_pos, driver_in_pos) self.add_zjog(self.route_layer, decoder_out_pos, driver_in_pos, var_offset=0.3)
self.add_via_stack_center(from_layer=decoder_out_pin.layer, self.add_via_stack_center(from_layer=decoder_out_pin.layer,
to_layer=self.route_layer, to_layer=self.route_layer,

View File

@ -178,14 +178,17 @@ class port_data(design.design):
# Extra column +1 is for RBL # Extra column +1 is for RBL
# Precharge will be shifted left if needed # Precharge will be shifted left if needed
# Column offset is set to port so extra column can be on left or right
# and mirroring happens correctly
self.precharge_array = factory.create(module_type="precharge_array", self.precharge_array = factory.create(module_type="precharge_array",
columns=self.num_cols + 1, columns=self.num_cols + 1,
port=self.port,
bitcell_bl=self.bl_names[self.port], bitcell_bl=self.bl_names[self.port],
bitcell_br=self.br_names[self.port]) bitcell_br=self.br_names[self.port],
column_offset=self.port - 1)
self.add_mod(self.precharge_array) self.add_mod(self.precharge_array)
if self.port in self.read_ports: if self.port in self.read_ports:
# RBLs don't get a sense amp
self.sense_amp_array = factory.create(module_type="sense_amp_array", self.sense_amp_array = factory.create(module_type="sense_amp_array",
word_size=self.word_size, word_size=self.word_size,
words_per_row=self.words_per_row) words_per_row=self.words_per_row)
@ -194,9 +197,9 @@ class port_data(design.design):
self.sense_amp_array = None self.sense_amp_array = None
if self.col_addr_size > 0: if self.col_addr_size > 0:
# RBLs dont get a col mux
self.column_mux_array = factory.create(module_type="column_mux_array", self.column_mux_array = factory.create(module_type="column_mux_array",
columns=self.num_cols, columns=self.num_cols,
port=self.port,
word_size=self.word_size, word_size=self.word_size,
bitcell_bl=self.bl_names[self.port], bitcell_bl=self.bl_names[self.port],
bitcell_br=self.br_names[self.port]) bitcell_br=self.br_names[self.port])
@ -205,17 +208,18 @@ class port_data(design.design):
self.column_mux_array = None self.column_mux_array = None
if self.port in self.write_ports: if self.port in self.write_ports:
# RBLs dont get a write driver
self.write_driver_array = factory.create(module_type="write_driver_array", self.write_driver_array = factory.create(module_type="write_driver_array",
columns=self.num_cols, columns=self.num_cols,
word_size=self.word_size, word_size=self.word_size,
write_size=self.write_size) write_size=self.write_size)
self.add_mod(self.write_driver_array) self.add_mod(self.write_driver_array)
if self.write_size is not None: if self.write_size is not None:
# RBLs don't get a write mask
self.write_mask_and_array = factory.create(module_type="write_mask_and_array", self.write_mask_and_array = factory.create(module_type="write_mask_and_array",
columns=self.num_cols, columns=self.num_cols,
word_size=self.word_size, word_size=self.word_size,
write_size=self.write_size, write_size=self.write_size)
port = self.port)
self.add_mod(self.write_mask_and_array) self.add_mod(self.write_mask_and_array)
else: else:
self.write_mask_and_array = None self.write_mask_and_array = None
@ -248,13 +252,6 @@ class port_data(design.design):
self.precharge = factory.create(module_type="precharge", self.precharge = factory.create(module_type="precharge",
bitcell_bl=self.bl_names[0], bitcell_bl=self.bl_names[0],
bitcell_br=self.br_names[0]) bitcell_br=self.br_names[0])
# We create a dummy here to get bl/br names to add those pins to this
# module, which happens before we create the real precharge_array
self.precharge_array = factory.create(module_type="precharge_array",
columns=self.num_cols + 1,
port=self.port,
bitcell_bl=self.bl_names[self.port],
bitcell_br=self.br_names[self.port])
def create_precharge_array(self): def create_precharge_array(self):
""" Creating Precharge """ """ Creating Precharge """
@ -732,8 +729,8 @@ class port_data(design.design):
top_bl, top_br = top_bl_pin.bc(), top_br_pin.bc() top_bl, top_br = top_bl_pin.bc(), top_br_pin.bc()
layer_pitch = getattr(self, "{}_pitch".format(top_bl_pin.layer)) layer_pitch = getattr(self, "{}_pitch".format(top_bl_pin.layer))
self.add_zjog(bot_bl_pin.layer, bot_bl, top_bl, "V", top_bl_pin.by() - layer_pitch) self.add_zjog(bot_bl_pin.layer, bot_bl, top_bl, "V", fixed_offset=top_bl_pin.by() - layer_pitch)
self.add_zjog(bot_br_pin.layer, bot_br, top_br, "V", top_bl_pin.by() - 2 * layer_pitch) self.add_zjog(bot_br_pin.layer, bot_br, top_br, "V", fixed_offset=top_bl_pin.by() - 2 * layer_pitch)
def graph_exclude_precharge(self): def graph_exclude_precharge(self):
"""Precharge adds a loop between bitlines, can be excluded to reduce complexity""" """Precharge adds a loop between bitlines, can be excluded to reduce complexity"""

View File

@ -18,16 +18,16 @@ class precharge_array(design.design):
of bit line columns, height is the height of the bit-cell array. of bit line columns, height is the height of the bit-cell array.
""" """
def __init__(self, name, columns, port, size=1, bitcell_bl="bl", bitcell_br="br"): def __init__(self, name, columns, size=1, bitcell_bl="bl", bitcell_br="br", column_offset=0):
design.design.__init__(self, name) design.design.__init__(self, name)
debug.info(1, "Creating {0}".format(self.name)) debug.info(1, "Creating {0}".format(self.name))
self.add_comment("cols: {0} size: {1} bl: {2} br: {3}".format(columns, size, bitcell_bl, bitcell_br)) self.add_comment("cols: {0} size: {1} bl: {2} br: {3}".format(columns, size, bitcell_bl, bitcell_br))
self.columns = columns self.columns = columns
self.size = size self.size = size
self.port = port
self.bitcell_bl = bitcell_bl self.bitcell_bl = bitcell_bl
self.bitcell_br = bitcell_br self.bitcell_br = bitcell_br
self.column_offset = column_offset
self.create_netlist() self.create_netlist()
if not OPTS.netlist_only: if not OPTS.netlist_only:
@ -106,7 +106,7 @@ class precharge_array(design.design):
xoffset = 0 xoffset = 0
for i in range(self.columns): for i in range(self.columns):
tempx = xoffset tempx = xoffset
if cell_properties.bitcell.mirror.y and (i + 1 + self.port) % 2: if cell_properties.bitcell.mirror.y and (i + self.column_offset) % 2:
mirror = "MY" mirror = "MY"
tempx = tempx + self.pc_cell.width tempx = tempx + self.pc_cell.width
else: else:

View File

@ -32,8 +32,10 @@ class replica_bitcell_array(design.design):
self.right_rbl = right_rbl self.right_rbl = right_rbl
self.bitcell_ports = bitcell_ports self.bitcell_ports = bitcell_ports
debug.check(left_rbl+right_rbl==len(self.all_ports),"Invalid number of RBLs for port configuration.") debug.check(left_rbl + right_rbl == len(self.all_ports),
debug.check(left_rbl+right_rbl==len(self.bitcell_ports),"Bitcell ports must match total RBLs.") "Invalid number of RBLs for port configuration.")
debug.check(left_rbl + right_rbl == len(self.bitcell_ports),
"Bitcell ports must match total RBLs.")
# Two dummy rows/cols plus replica for each port # Two dummy rows/cols plus replica for each port
self.extra_rows = 2 + left_rbl + right_rbl self.extra_rows = 2 + left_rbl + right_rbl
@ -47,7 +49,6 @@ class replica_bitcell_array(design.design):
# the replica bitcell in the control logic # the replica bitcell in the control logic
# self.offset_all_coordinates() # self.offset_all_coordinates()
def create_netlist(self): def create_netlist(self):
""" Create and connect the netlist """ """ Create and connect the netlist """
self.add_modules() self.add_modules()
@ -118,7 +119,6 @@ class replica_bitcell_array(design.design):
mirror=0) mirror=0)
self.add_mod(self.dummy_row) self.add_mod(self.dummy_row)
# If there are bitcell end caps, replace the dummy cells on the edge of the bitcell array with end caps. # If there are bitcell end caps, replace the dummy cells on the edge of the bitcell array with end caps.
try: try:
end_caps_enabled = cell_properties.bitcell.end_caps end_caps_enabled = cell_properties.bitcell.end_caps
@ -131,7 +131,7 @@ class replica_bitcell_array(design.design):
self.edge_row = factory.create(module_type=edge_row_module_type, self.edge_row = factory.create(module_type=edge_row_module_type,
cols=self.column_size, cols=self.column_size,
rows=1, rows=1,
# dummy column + left replica column # dummy column + left replica column(s)
column_offset=1 + self.left_rbl, column_offset=1 + self.left_rbl,
mirror=0) mirror=0)
self.add_mod(self.edge_row) self.add_mod(self.edge_row)
@ -149,9 +149,9 @@ class replica_bitcell_array(design.design):
self.edge_col_right = factory.create(module_type=edge_col_module_type, self.edge_col_right = factory.create(module_type=edge_col_module_type,
cols=1, cols=1,
# dummy column # dummy column
# + left replica column # + left replica column(s)
# + bitcell columns # + bitcell columns
# + right replica column # + right replica column(s)
column_offset = 1 + self.left_rbl + self.column_size + self.right_rbl, column_offset = 1 + self.left_rbl + self.column_size + self.right_rbl,
rows=self.row_size + self.extra_rows, rows=self.row_size + self.extra_rows,
mirror=(self.left_rbl + 1) %2) mirror=(self.left_rbl + 1) %2)
@ -195,7 +195,6 @@ class replica_bitcell_array(design.design):
# Left/right dummy columns are connected identically to the replica column # Left/right dummy columns are connected identically to the replica column
self.dummy_col_wl_names = self.replica_col_wl_names self.dummy_col_wl_names = self.replica_col_wl_names
# Per port bitline names # Per port bitline names
self.replica_bl_names = {} self.replica_bl_names = {}
self.replica_wl_names = {} self.replica_wl_names = {}
@ -211,10 +210,8 @@ class replica_bitcell_array(design.design):
self.replica_bl_names[port] = bl_names self.replica_bl_names[port] = bl_names
wl_names = ["rbl_{0}_{1}".format(x, port) for x in self.cell.get_all_wl_names()] wl_names = ["rbl_{0}_{1}".format(x, port) for x in self.cell.get_all_wl_names()]
#wl_names[port] = "rbl_wl{}".format(port)
self.replica_wl_names[port] = wl_names self.replica_wl_names[port] = wl_names
# External pins # External pins
self.add_pin_list(self.bitcell_array_bl_names, "INOUT") self.add_pin_list(self.bitcell_array_bl_names, "INOUT")
# Need to sort by port order since dictionary values may not be in order # Need to sort by port order since dictionary values may not be in order
@ -231,7 +228,6 @@ class replica_bitcell_array(design.design):
self.add_pin("vdd", "POWER") self.add_pin("vdd", "POWER")
self.add_pin("gnd", "GROUND") self.add_pin("gnd", "GROUND")
def create_instances(self): def create_instances(self):
""" Create the module instances used in this design """ """ Create the module instances used in this design """
@ -252,7 +248,6 @@ class replica_bitcell_array(design.design):
mod=self.replica_columns[port]) mod=self.replica_columns[port])
self.connect_inst(self.replica_bl_names[port] + self.replica_col_wl_names + supplies) self.connect_inst(self.replica_bl_names[port] + self.replica_col_wl_names + supplies)
# Dummy rows under the bitcell array (connected with with the replica cell wl) # Dummy rows under the bitcell array (connected with with the replica cell wl)
self.dummy_row_replica_inst = {} self.dummy_row_replica_inst = {}
for port in range(self.left_rbl + self.right_rbl): for port in range(self.left_rbl + self.right_rbl):
@ -260,7 +255,6 @@ class replica_bitcell_array(design.design):
mod=self.dummy_row) mod=self.dummy_row)
self.connect_inst(self.dummy_row_bl_names + self.replica_wl_names[port] + supplies) self.connect_inst(self.dummy_row_bl_names + self.replica_wl_names[port] + supplies)
# Top/bottom dummy rows or col caps # Top/bottom dummy rows or col caps
self.dummy_row_bot_inst=self.add_inst(name="dummy_row_bot", self.dummy_row_bot_inst=self.add_inst(name="dummy_row_bot",
mod=self.edge_row) mod=self.edge_row)
@ -269,7 +263,6 @@ class replica_bitcell_array(design.design):
mod=self.edge_row) mod=self.edge_row)
self.connect_inst(self.dummy_row_bl_names + [x + "_top" for x in self.dummy_cell_wl_names] + supplies) self.connect_inst(self.dummy_row_bl_names + [x + "_top" for x in self.dummy_cell_wl_names] + supplies)
# Left/right Dummy columns # Left/right Dummy columns
self.dummy_col_left_inst=self.add_inst(name="dummy_col_left", self.dummy_col_left_inst=self.add_inst(name="dummy_col_left",
mod=self.edge_col_left) mod=self.edge_col_left)
@ -295,10 +288,12 @@ class replica_bitcell_array(design.design):
for bit in range(self.right_rbl): for bit in range(self.right_rbl):
self.replica_col_inst[self.left_rbl + bit].place(offset=offset.scale(bit, -self.left_rbl - 1) + self.bitcell_array_inst.lr()) self.replica_col_inst[self.left_rbl + bit].place(offset=offset.scale(bit, -self.left_rbl - 1) + self.bitcell_array_inst.lr())
# FIXME: These depend on the array size itself
# Far top dummy row (first row above array is NOT flipped) # Far top dummy row (first row above array is NOT flipped)
flip_dummy = self.right_rbl % 2 flip_dummy = self.right_rbl % 2
self.dummy_row_top_inst.place(offset=offset.scale(0, self.right_rbl + flip_dummy) + self.bitcell_array_inst.ul(), self.dummy_row_top_inst.place(offset=offset.scale(0, self.right_rbl + flip_dummy) + self.bitcell_array_inst.ul(),
mirror="MX" if flip_dummy else "R0") mirror="MX" if flip_dummy else "R0")
# FIXME: These depend on the array size itself
# Far bottom dummy row (first row below array IS flipped) # Far bottom dummy row (first row below array IS flipped)
flip_dummy = (self.left_rbl + 1) % 2 flip_dummy = (self.left_rbl + 1) % 2
self.dummy_row_bot_inst.place(offset=offset.scale(0, -self.left_rbl - 1 + flip_dummy), self.dummy_row_bot_inst.place(offset=offset.scale(0, -self.left_rbl - 1 + flip_dummy),
@ -316,7 +311,6 @@ class replica_bitcell_array(design.design):
self.dummy_row_replica_inst[self.left_rbl + bit].place(offset=offset.scale(0, bit + bit % 2) + self.bitcell_array_inst.ul(), self.dummy_row_replica_inst[self.left_rbl + bit].place(offset=offset.scale(0, bit + bit % 2) + self.bitcell_array_inst.ul(),
mirror="MX" if bit % 2 else "R0") mirror="MX" if bit % 2 else "R0")
self.translate_all(offset.scale(-1 - self.left_rbl, -1 - self.left_rbl)) self.translate_all(offset.scale(-1 - self.left_rbl, -1 - self.left_rbl))
self.add_layout_pins() self.add_layout_pins()
@ -325,7 +319,6 @@ class replica_bitcell_array(design.design):
self.DRC_LVS() self.DRC_LVS()
def add_layout_pins(self): def add_layout_pins(self):
""" Add the layout pins """ """ Add the layout pins """
@ -351,7 +344,6 @@ class replica_bitcell_array(design.design):
width=pin.width(), width=pin.width(),
height=self.height) height=self.height)
# Replica wordlines # Replica wordlines
for port in range(self.left_rbl + self.right_rbl): for port in range(self.left_rbl + self.right_rbl):
inst = self.replica_col_inst[port] inst = self.replica_col_inst[port]
@ -416,8 +408,6 @@ class replica_bitcell_array(design.design):
def analytical_power(self, corner, load): def analytical_power(self, corner, load):
"""Power of Bitcell array and bitline in nW.""" """Power of Bitcell array and bitline in nW."""
from tech import drc, parameter
# Dynamic Power from Bitline # Dynamic Power from Bitline
bl_wire = self.gen_bl_wire() bl_wire = self.gen_bl_wire()
cell_load = 2 * bl_wire.return_input_cap() cell_load = 2 * bl_wire.return_input_cap()

View File

@ -5,12 +5,12 @@
# #
import debug import debug
import design import design
from tech import drc, cell_properties from tech import cell_properties
import contact
from sram_factory import factory from sram_factory import factory
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
class replica_column(design.design): class replica_column(design.design):
""" """
Generate a replica bitline column for the replica array. Generate a replica bitline column for the replica array.
@ -32,7 +32,8 @@ class replica_column(design.design):
self.total_size = self.left_rbl + rows + self.right_rbl + 2 self.total_size = self.left_rbl + rows + self.right_rbl + 2
self.column_offset = column_offset self.column_offset = column_offset
debug.check(replica_bit!=0 and replica_bit!=rows,"Replica bit cannot be the dummy row.") debug.check(replica_bit != 0 and replica_bit != rows,
"Replica bit cannot be the dummy row.")
debug.check(replica_bit <= left_rbl or replica_bit >= self.total_size - right_rbl - 1, debug.check(replica_bit <= left_rbl or replica_bit >= self.total_size - right_rbl - 1,
"Replica bit cannot be in the regular array.") "Replica bit cannot be in the regular array.")
@ -68,15 +69,15 @@ class replica_column(design.design):
self.add_pin("gnd", "GROUND") self.add_pin("gnd", "GROUND")
def add_modules(self): def add_modules(self):
self.replica_cell = factory.create(module_type="replica_bitcell") self.replica_cell = factory.create(module_type="replica_{}".format(OPTS.bitcell))
self.add_mod(self.replica_cell) self.add_mod(self.replica_cell)
self.dummy_cell = factory.create(module_type="dummy_bitcell") self.dummy_cell = factory.create(module_type="dummy_{}".format(OPTS.bitcell))
self.add_mod(self.dummy_cell) self.add_mod(self.dummy_cell)
try: try:
edge_module_type = ("col_cap_bitcell" if cell_properties.bitcell.end_caps else "dummy_bitcell") edge_module_type = ("col_cap" if cell_properties.bitcell.end_caps else "dummy")
except AttributeError: except AttributeError:
edge_module_type = "dummy_bitcell" edge_module_type = "dummy"
self.edge_cell = factory.create(module_type=edge_module_type) self.edge_cell = factory.create(module_type=edge_module_type + "_" + OPTS.bitcell)
self.add_mod(self.edge_cell) self.add_mod(self.edge_cell)
# Used for pin names only # Used for pin names only
self.cell = factory.create(module_type="bitcell") self.cell = factory.create(module_type="bitcell")
@ -129,10 +130,8 @@ class replica_column(design.design):
xoffset = self.replica_cell.width xoffset = self.replica_cell.width
for row in range(self.total_size): for row in range(self.total_size):
dir_x = False # name = "bit_r{0}_{1}".format(row, "rbl")
name = "bit_r{0}_{1}".format(row,"rbl") dir_x = cell_properties.bitcell.mirror.x and (row + rbl_offset) % 2
if cell_properties.bitcell.mirror.x and (row+rbl_offset)%2:
dir_x = True
offset = vector(xoffset, self.cell.height * (row + (row + rbl_offset) % 2)) offset = vector(xoffset, self.cell.height * (row + (row + rbl_offset) % 2))
@ -216,7 +215,6 @@ class replica_column(design.design):
return bitcell_pins return bitcell_pins
def exclude_all_but_replica(self): def exclude_all_but_replica(self):
"""Excludes all bits except the replica cell (self.replica_bit).""" """Excludes all bits except the replica cell (self.replica_bit)."""

View File

@ -35,7 +35,7 @@ class row_cap_array(bitcell_base_array):
def add_modules(self): def add_modules(self):
""" Add the modules used in this design """ """ Add the modules used in this design """
self.dummy_cell = factory.create(module_type="row_cap_bitcell_1rw_1r") # TODO: make module_type generic self.dummy_cell = factory.create(module_type="row_cap_{}".format(OPTS.bitcell))
self.add_mod(self.dummy_cell) self.add_mod(self.dummy_cell)
self.cell = factory.create(module_type="bitcell") self.cell = factory.create(module_type="bitcell")

View File

@ -20,7 +20,7 @@ class sense_amp_array(design.design):
Dynamically generated sense amp array for all bitlines. Dynamically generated sense amp array for all bitlines.
""" """
def __init__(self, name, word_size, words_per_row): def __init__(self, name, word_size, words_per_row, column_offset=0):
design.design.__init__(self, name) design.design.__init__(self, name)
debug.info(1, "Creating {0}".format(self.name)) debug.info(1, "Creating {0}".format(self.name))
self.add_comment("word_size {0}".format(word_size)) self.add_comment("word_size {0}".format(word_size))
@ -28,6 +28,7 @@ class sense_amp_array(design.design):
self.word_size = word_size self.word_size = word_size
self.words_per_row = words_per_row self.words_per_row = words_per_row
self.column_offset = column_offset
self.row_size = self.word_size * self.words_per_row self.row_size = self.word_size * self.words_per_row
self.create_netlist() self.create_netlist()
@ -102,25 +103,22 @@ class sense_amp_array(design.design):
def place_sense_amp_array(self): def place_sense_amp_array(self):
from tech import cell_properties from tech import cell_properties
if self.bitcell.width > self.amp.width: if self.bitcell.width > self.amp.width:
amp_spacing = self.bitcell.width * self.words_per_row amp_spacing = self.bitcell.width
else: else:
amp_spacing = self.amp.width * self.words_per_row amp_spacing = self.amp.width
for i in range(0, self.word_size): for i in range(0, self.row_size, self.words_per_row):
xoffset = amp_spacing * i index = int(i / self.words_per_row)
xoffset = i * amp_spacing
# align the xoffset to the grid of bitcells. This way we if cell_properties.bitcell.mirror.y and (i + self.column_offset) % 2:
# know when to do the mirroring.
grid_x = int(xoffset / self.amp.width)
if cell_properties.bitcell.mirror.y and grid_x % 2:
mirror = "MY" mirror = "MY"
xoffset = xoffset + self.amp.width xoffset = xoffset + self.amp.width
else: else:
mirror = "" mirror = ""
amp_position = vector(xoffset, 0) amp_position = vector(xoffset, 0)
self.local_insts[i].place(offset=amp_position, mirror=mirror) self.local_insts[index].place(offset=amp_position, mirror=mirror)
def add_layout_pins(self): def add_layout_pins(self):
for i in range(len(self.local_insts)): for i in range(len(self.local_insts)):

View File

@ -20,17 +20,17 @@ class single_level_column_mux_array(design.design):
Array of column mux to read the bitlines through the 6T. Array of column mux to read the bitlines through the 6T.
""" """
def __init__(self, name, columns, port, word_size, bitcell_bl="bl", bitcell_br="br"): def __init__(self, name, columns, word_size, bitcell_bl="bl", bitcell_br="br", column_offset=0):
design.design.__init__(self, name) design.design.__init__(self, name)
debug.info(1, "Creating {0}".format(self.name)) debug.info(1, "Creating {0}".format(self.name))
self.add_comment("cols: {0} word_size: {1} bl: {2} br: {3}".format(columns, word_size, bitcell_bl, bitcell_br)) self.add_comment("cols: {0} word_size: {1} bl: {2} br: {3}".format(columns, word_size, bitcell_bl, bitcell_br))
self.columns = columns self.columns = columns
self.port = port
self.word_size = word_size self.word_size = word_size
self.words_per_row = int(self.columns / self.word_size) self.words_per_row = int(self.columns / self.word_size)
self.bitcell_bl = bitcell_bl self.bitcell_bl = bitcell_bl
self.bitcell_br = bitcell_br self.bitcell_br = bitcell_br
self.column_offset = column_offset
if "li" in layer: if "li" in layer:
self.col_mux_stack = self.li_stack self.col_mux_stack = self.li_stack
@ -118,7 +118,7 @@ class single_level_column_mux_array(design.design):
# For every column, add a pass gate # For every column, add a pass gate
for col_num in range(self.columns): for col_num in range(self.columns):
xoffset = col_num * self.mux.width xoffset = col_num * self.mux.width
if cell_properties.bitcell.mirror.y and (col_num + self.port) % 2: if cell_properties.bitcell.mirror.y and (col_num + self.column_offset) % 2:
mirror = "MY" mirror = "MY"
xoffset = xoffset + self.mux.width xoffset = xoffset + self.mux.width
else: else:

View File

@ -18,7 +18,7 @@ class write_driver_array(design.design):
Dynamically generated write driver array of all bitlines. Dynamically generated write driver array of all bitlines.
""" """
def __init__(self, name, columns, word_size, write_size=None): def __init__(self, name, columns, word_size, write_size=None, column_offset=0):
design.design.__init__(self, name) design.design.__init__(self, name)
debug.info(1, "Creating {0}".format(self.name)) debug.info(1, "Creating {0}".format(self.name))
self.add_comment("columns: {0}".format(columns)) self.add_comment("columns: {0}".format(columns))
@ -27,6 +27,7 @@ class write_driver_array(design.design):
self.columns = columns self.columns = columns
self.word_size = word_size self.word_size = word_size
self.write_size = write_size self.write_size = write_size
self.column_offset = column_offset
self.words_per_row = int(columns / word_size) self.words_per_row = int(columns / word_size)
if self.write_size: if self.write_size:
@ -128,7 +129,7 @@ class write_driver_array(design.design):
index = int(i / self.words_per_row) index = int(i / self.words_per_row)
xoffset = i * self.driver_spacing xoffset = i * self.driver_spacing
if cell_properties.bitcell.mirror.y and i % 2: if cell_properties.bitcell.mirror.y and (i + self.column_offset) % 2:
mirror = "MY" mirror = "MY"
xoffset = xoffset + self.driver.width xoffset = xoffset + self.driver.width
else: else:

View File

@ -18,7 +18,7 @@ class write_mask_and_array(design.design):
The write mask AND array goes between the write driver array and the sense amp array. The write mask AND array goes between the write driver array and the sense amp array.
""" """
def __init__(self, name, columns, word_size, write_size, port=0): def __init__(self, name, columns, word_size, write_size, column_offset=0):
design.design.__init__(self, name) design.design.__init__(self, name)
debug.info(1, "Creating {0}".format(self.name)) debug.info(1, "Creating {0}".format(self.name))
self.add_comment("columns: {0}".format(columns)) self.add_comment("columns: {0}".format(columns))
@ -28,7 +28,7 @@ class write_mask_and_array(design.design):
self.columns = columns self.columns = columns
self.word_size = word_size self.word_size = word_size
self.write_size = write_size self.write_size = write_size
self.port = port self.column_offset = column_offset
self.words_per_row = int(columns / word_size) self.words_per_row = int(columns / word_size)
self.num_wmasks = int(word_size / write_size) self.num_wmasks = int(word_size / write_size)

View File

@ -124,26 +124,23 @@ class options(optparse.Values):
purge_temp = True purge_temp = True
# These are the default modules that can be over-riden # These are the default modules that can be over-riden
bitcell_suffix = ""
bank_select = "bank_select" bank_select = "bank_select"
bitcell_array = "bitcell_array" bitcell_array = "bitcell_array"
bitcell = "bitcell" bitcell = "bitcell"
col_cap_bitcell = "col_cap_bitcell"
column_mux_array = "single_level_column_mux_array" column_mux_array = "single_level_column_mux_array"
control_logic = "control_logic" control_logic = "control_logic"
decoder = "hierarchical_decoder" decoder = "hierarchical_decoder"
delay_chain = "delay_chain" delay_chain = "delay_chain"
dff_array = "dff_array" dff_array = "dff_array"
dff = "dff" dff = "dff"
dummy_bitcell = "dummy_bitcell"
inv_dec = "pinv" inv_dec = "pinv"
nand2_dec = "pnand2" nand2_dec = "pnand2"
nand3_dec = "pnand3" nand3_dec = "pnand3"
nand4_dec = "pnand4" # Not available right now nand4_dec = "pnand4" # Not available right now
precharge_array = "precharge_array" precharge_array = "precharge_array"
ptx = "ptx" ptx = "ptx"
replica_bitcell = "replica_bitcell"
replica_bitline = "replica_bitline" replica_bitline = "replica_bitline"
row_cap_bitcell = "row_cap_bitcell"
sense_amp_array = "sense_amp_array" sense_amp_array = "sense_amp_array"
sense_amp = "sense_amp" sense_amp = "sense_amp"
tri_gate_array = "tri_gate_array" tri_gate_array = "tri_gate_array"

View File

@ -22,10 +22,10 @@ class single_level_column_mux_1rw_1r_test(openram_test):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
globals.init_openram(config_file) globals.init_openram(config_file)
OPTS.bitcell = "bitcell_1rw_1r"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
globals.setup_bitcell()
debug.info(2, "Checking column mux port 0") debug.info(2, "Checking column mux port 0")
tx = factory.create(module_type="single_level_column_mux", tx_size=8, bitcell_bl="bl0", bitcell_br="br0") tx = factory.create(module_type="single_level_column_mux", tx_size=8, bitcell_bl="bl0", bitcell_br="br0")

View File

@ -23,12 +23,10 @@ class bitcell_1rw_1r_array_test(openram_test):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
globals.init_openram(config_file) globals.init_openram(config_file)
OPTS.bitcell = "bitcell_1rw_1r"
OPTS.replica_bitcell = "replica_bitcell_1rw_1r"
OPTS.dummy_bitcell="dummy_bitcell_1rw_1r"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
globals.setup_bitcell()
debug.info(2, "Testing 4x4 array for cell_1rw_1r") debug.info(2, "Testing 4x4 array for cell_1rw_1r")
a = factory.create(module_type="bitcell_array", cols=4, rows=4) a = factory.create(module_type="bitcell_array", cols=4, rows=4)

View File

@ -1,38 +0,0 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2019 Regents of the University of California
# All rights reserved.
#
import unittest
from testutils import *
import sys,os
sys.path.append(os.getenv("OPENRAM_HOME"))
import globals
from globals import OPTS
from sram_factory import factory
import debug
class replica_bitcell_array_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
globals.init_openram(config_file)
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 0
OPTS.num_w_ports = 0
factory.reset()
debug.info(2, "Testing 4x4 array for bitcell")
a = factory.create(module_type="replica_bitcell_array", cols=4, rows=4, left_rbl=1, right_rbl=0, bitcell_ports=[0])
self.local_check(a)
globals.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = globals.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main(testRunner=debugTestRunner())

View File

@ -23,10 +23,10 @@ class hierarchical_decoder_1rw_1r_test(openram_test):
globals.init_openram(config_file) globals.init_openram(config_file)
# Use the 2 port cell since it is usually bigger/easier # Use the 2 port cell since it is usually bigger/easier
OPTS.bitcell = "bitcell_1rw_1r"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
globals.setup_bitcell()
# Checks 2x4 and 2-input NAND decoder # Checks 2x4 and 2-input NAND decoder
debug.info(1, "Testing 16 row sample for hierarchical_decoder") debug.info(1, "Testing 16 row sample for hierarchical_decoder")

View File

@ -21,10 +21,10 @@ class hierarchical_decoder_pbitcell_test(openram_test):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
globals.init_openram(config_file) globals.init_openram(config_file)
# check hierarchical decoder for multi-port # check hierarchical decoder for multi-port
OPTS.bitcell = "pbitcell"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
OPTS.num_r_ports = 0 OPTS.num_r_ports = 0
globals.setup_bitcell()
factory.reset() factory.reset()
debug.info(1, "Testing 16 row sample for hierarchical_decoder (multi-port case)") debug.info(1, "Testing 16 row sample for hierarchical_decoder (multi-port case)")

View File

@ -22,11 +22,10 @@ class hierarchical_predecode2x4_1rw_1r_test(openram_test):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
globals.init_openram(config_file) globals.init_openram(config_file)
# Use the 2 port cell since it is usually bigger/easier
OPTS.bitcell = "bitcell_1rw_1r"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
globals.setup_bitcell()
debug.info(1, "Testing sample for hierarchy_predecode2x4") debug.info(1, "Testing sample for hierarchy_predecode2x4")
a = factory.create(module_type="hierarchical_predecode2x4") a = factory.create(module_type="hierarchical_predecode2x4")

View File

@ -22,10 +22,10 @@ class hierarchical_predecode2x4_pbitcell_test(openram_test):
globals.init_openram(config_file) globals.init_openram(config_file)
# checking hierarchical precode 2x4 for multi-port # checking hierarchical precode 2x4 for multi-port
OPTS.bitcell = "pbitcell"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
OPTS.num_r_ports = 0 OPTS.num_r_ports = 0
globals.setup_bitcell()
debug.info(1, "Testing sample for hierarchy_predecode2x4 (multi-port case)") debug.info(1, "Testing sample for hierarchy_predecode2x4 (multi-port case)")
a = factory.create(module_type="hierarchical_predecode2x4") a = factory.create(module_type="hierarchical_predecode2x4")

View File

@ -23,10 +23,10 @@ class hierarchical_predecode3x8_1rw_1r_test(openram_test):
globals.init_openram(config_file) globals.init_openram(config_file)
# Use the 2 port cell since it is usually bigger/easier # Use the 2 port cell since it is usually bigger/easier
OPTS.bitcell = "bitcell_1rw_1r"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
globals.setup_bitcell()
debug.info(1, "Testing sample for hierarchy_predecode3x8") debug.info(1, "Testing sample for hierarchy_predecode3x8")
a = factory.create(module_type="hierarchical_predecode3x8") a = factory.create(module_type="hierarchical_predecode3x8")

View File

@ -22,10 +22,10 @@ class hierarchical_predecode3x8_pbitcell_test(openram_test):
globals.init_openram(config_file) globals.init_openram(config_file)
# checking hierarchical precode 3x8 for multi-port # checking hierarchical precode 3x8 for multi-port
OPTS.bitcell = "pbitcell"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
OPTS.num_r_ports = 0 OPTS.num_r_ports = 0
globals.setup_bitcell()
debug.info(1, "Testing sample for hierarchy_predecode3x8 (multi-port case)") debug.info(1, "Testing sample for hierarchy_predecode3x8 (multi-port case)")
a = factory.create(module_type="hierarchical_predecode3x8") a = factory.create(module_type="hierarchical_predecode3x8")

View File

@ -20,17 +20,17 @@ class single_level_column_mux_test(openram_test):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
globals.init_openram(config_file) globals.init_openram(config_file)
OPTS.bitcell = "bitcell_1rw_1r"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
globals.setup_bitcell()
debug.info(1, "Testing sample for 4-way column_mux_array port 0") debug.info(1, "Testing sample for 4-way column_mux_array port 0")
a = factory.create(module_type="single_level_column_mux_array", columns=8, port=0, word_size=2, bitcell_bl="bl0", bitcell_br="br0") a = factory.create(module_type="single_level_column_mux_array", columns=8, word_size=2, bitcell_bl="bl0", bitcell_br="br0")
self.local_check(a) self.local_check(a)
debug.info(1, "Testing sample for 4-way column_mux_array port 1") debug.info(1, "Testing sample for 4-way column_mux_array port 1")
a = factory.create(module_type="single_level_column_mux_array", columns=8, port=0, word_size=2, bitcell_bl="bl1", bitcell_br="br1") a = factory.create(module_type="single_level_column_mux_array", columns=8, word_size=2, bitcell_bl="bl1", bitcell_br="br1")
self.local_check(a) self.local_check(a)
globals.end_openram() globals.end_openram()

View File

@ -29,19 +29,19 @@ class single_level_column_mux_pbitcell_test(openram_test):
factory.reset() factory.reset()
debug.info(1, "Testing sample for 2-way column_mux_array in multi-port") debug.info(1, "Testing sample for 2-way column_mux_array in multi-port")
a = factory.create(module_type="single_level_column_mux_array", columns=16, port=0, word_size=8, bitcell_bl="bl0", bitcell_br="br0") a = factory.create(module_type="single_level_column_mux_array", columns=16, word_size=8, bitcell_bl="bl0", bitcell_br="br0")
self.local_check(a) self.local_check(a)
debug.info(1, "Testing sample for 4-way column_mux_array in multi-port") debug.info(1, "Testing sample for 4-way column_mux_array in multi-port")
a = factory.create(module_type="single_level_column_mux_array", columns=16, port=0, word_size=4, bitcell_bl="bl0", bitcell_br="br0") a = factory.create(module_type="single_level_column_mux_array", columns=16, word_size=4, bitcell_bl="bl0", bitcell_br="br0")
self.local_check(a) self.local_check(a)
debug.info(1, "Testing sample for 8-way column_mux_array in multi-port (innermost connections)") debug.info(1, "Testing sample for 8-way column_mux_array in multi-port (innermost connections)")
a = factory.create(module_type="single_level_column_mux_array", columns=32, port=0, word_size=4, bitcell_bl="bl0", bitcell_br="br0") a = factory.create(module_type="single_level_column_mux_array", columns=32, word_size=4, bitcell_bl="bl0", bitcell_br="br0")
self.local_check(a) self.local_check(a)
debug.info(1, "Testing sample for 8-way column_mux_array in multi-port (outermost connections)") debug.info(1, "Testing sample for 8-way column_mux_array in multi-port (outermost connections)")
a = factory.create(module_type="single_level_column_mux_array", columns=32, port=3, word_size=4, bitcell_bl="bl2", bitcell_br="br2") a = factory.create(module_type="single_level_column_mux_array", columns=32, word_size=4, bitcell_bl="bl2", bitcell_br="br2", column_offset=3)
self.local_check(a) self.local_check(a)
globals.end_openram() globals.end_openram()

View File

@ -21,15 +21,15 @@ class single_level_column_mux_test(openram_test):
globals.init_openram(config_file) globals.init_openram(config_file)
debug.info(1, "Testing sample for 2-way column_mux_array") debug.info(1, "Testing sample for 2-way column_mux_array")
a = factory.create(module_type="single_level_column_mux_array", columns=16, port=0, word_size=8) a = factory.create(module_type="single_level_column_mux_array", columns=16, word_size=8)
self.local_check(a) self.local_check(a)
debug.info(1, "Testing sample for 4-way column_mux_array") debug.info(1, "Testing sample for 4-way column_mux_array")
a = factory.create(module_type="single_level_column_mux_array", columns=16, port=0, word_size=4) a = factory.create(module_type="single_level_column_mux_array", columns=16, word_size=4)
self.local_check(a) self.local_check(a)
debug.info(1, "Testing sample for 8-way column_mux_array") debug.info(1, "Testing sample for 8-way column_mux_array")
a = factory.create(module_type="single_level_column_mux_array", columns=32, port=0, word_size=4) a = factory.create(module_type="single_level_column_mux_array", columns=32, word_size=4)
self.local_check(a) self.local_check(a)
globals.end_openram() globals.end_openram()

View File

@ -22,23 +22,19 @@ class precharge_1rw_1r_test(openram_test):
globals.init_openram(config_file) globals.init_openram(config_file)
# check precharge array in multi-port # check precharge array in multi-port
OPTS.bitcell = "bitcell_1rw_1r"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
globals.setup_bitcell()
factory.reset() factory.reset()
debug.info(2, "Checking 3 column precharge array for 1RW/1R bitcell") debug.info(2, "Checking 3 column precharge array for 1RW/1R bitcell (port 0)")
pc = factory.create(module_type="precharge_array", columns=3, port=0, bitcell_bl="bl0", bitcell_br="br0") pc = factory.create(module_type="precharge_array", columns=3, bitcell_bl="bl0", bitcell_br="br0")
self.local_check(pc) self.local_check(pc)
# debug.info(2, "Checking 3 column precharge array for pbitcell (innermost connections)") debug.info(2, "Checking 3 column precharge array for 1RW/1R bitcell (port 1)")
# pc = precharge_array.precharge_array(name="pre3", columns=3, bitcell_bl="bl0", bitcell_br="br0") pc = factory.create(module_type="precharge_array", columns=3, bitcell_bl="bl0", bitcell_br="br0", column_offset=1)
# self.local_check(pc) self.local_check(pc)
# debug.info(2, "Checking 3 column precharge array for pbitcell (outermost connections)")
# pc = precharge_array.precharge_array(name="pre4", columns=3, bitcell_bl="bl2", bitcell_br="br2")
# self.local_check(pc)
globals.end_openram() globals.end_openram()

View File

@ -21,9 +21,8 @@ class precharge_test(openram_test):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
globals.init_openram(config_file) globals.init_openram(config_file)
# check precharge array in single port
debug.info(2, "Checking 3 column precharge") debug.info(2, "Checking 3 column precharge")
pc = factory.create(module_type="precharge_array", columns=3, port=0) pc = factory.create(module_type="precharge_array", columns=3)
self.local_check(pc) self.local_check(pc)
globals.end_openram() globals.end_openram()

View File

@ -23,10 +23,10 @@ class wordline_driver_array_1rw_1r_test(openram_test):
globals.init_openram(config_file) globals.init_openram(config_file)
# Use the 2 port cell since it is usually bigger/easier # Use the 2 port cell since it is usually bigger/easier
OPTS.bitcell = "bitcell_1rw_1r"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
globals.setup_bitcell()
# check wordline driver for single port # check wordline driver for single port
debug.info(2, "Checking driver") debug.info(2, "Checking driver")

View File

@ -21,7 +21,6 @@ class sense_amp_test(openram_test):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
globals.init_openram(config_file) globals.init_openram(config_file)
# check sense amp array for single port
debug.info(2, "Testing sense_amp_array for word_size=4, words_per_row=1") debug.info(2, "Testing sense_amp_array for word_size=4, words_per_row=1")
a = factory.create(module_type="sense_amp_array", word_size=4, words_per_row=1) a = factory.create(module_type="sense_amp_array", word_size=4, words_per_row=1)
self.local_check(a) self.local_check(a)

View File

@ -19,23 +19,19 @@ class replica_bitcell_array_test(openram_test):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
globals.init_openram(config_file) globals.init_openram(config_file)
OPTS.bitcell = "bitcell_1rw_1r"
OPTS.replica_bitcell = "replica_bitcell_1rw_1r"
OPTS.dummy_bitcell="dummy_bitcell_1rw_1r"
OPTS.col_cap_bitcell="col_cap_bitcell_1rw_1r"
OPTS.row_cap_bitcell="row_cap_bitcell_1rw_1r"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
globals.setup_bitcell()
debug.info(2, "Testing 4x4 array for cell_1rw_1r")
a = factory.create(module_type="replica_bitcell_array", cols=4, rows=4, left_rbl=2, right_rbl=0, bitcell_ports=[0,1])
self.local_check(a)
debug.info(2, "Testing 4x4 array for cell_1rw_1r") debug.info(2, "Testing 4x4 array for cell_1rw_1r")
a = factory.create(module_type="replica_bitcell_array", cols=4, rows=4, left_rbl=1, right_rbl=1, bitcell_ports=[0, 1]) a = factory.create(module_type="replica_bitcell_array", cols=4, rows=4, left_rbl=1, right_rbl=1, bitcell_ports=[0, 1])
self.local_check(a) self.local_check(a)
debug.info(2, "Testing 4x4 array for cell_1rw_1r")
a = factory.create(module_type="replica_bitcell_array", cols=4, rows=4, left_rbl=2, right_rbl=0, bitcell_ports=[0, 1])
self.local_check(a)
globals.end_openram() globals.end_openram()
# run the test from the command line # run the test from the command line

View File

@ -19,7 +19,12 @@ class replica_bitcell_array_test(openram_test):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
globals.init_openram(config_file) globals.init_openram(config_file)
debug.info(2, "Testing 4x4 array for 6t_cell") OPTS.num_rw_ports = 1
OPTS.num_r_ports = 0
OPTS.num_w_ports = 0
factory.reset()
debug.info(2, "Testing 4x4 array for bitcell")
a = factory.create(module_type="replica_bitcell_array", cols=4, rows=4, left_rbl=1, right_rbl=0, bitcell_ports=[0]) a = factory.create(module_type="replica_bitcell_array", cols=4, rows=4, left_rbl=1, right_rbl=0, bitcell_ports=[0])
self.local_check(a) self.local_check(a)

View File

@ -21,15 +21,19 @@ class port_address_1rw_1r_test(openram_test):
globals.init_openram(config_file) globals.init_openram(config_file)
# Use the 2 port cell since it is usually bigger/easier # Use the 2 port cell since it is usually bigger/easier
OPTS.bitcell = "bitcell_1rw_1r"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
globals.setup_bitcell()
debug.info(1, "Port address 16 rows") debug.info(1, "Port address 16 rows")
a = factory.create("port_address", cols=16, rows=16) a = factory.create("port_address", cols=16, rows=16)
self.local_check(a) self.local_check(a)
debug.info(1, "Port address 512 rows")
a = factory.create("port_address", cols=256, rows=512)
self.local_check(a)
globals.end_openram() globals.end_openram()
# run the test from the command line # run the test from the command line

View File

@ -24,6 +24,10 @@ class port_address_test(openram_test):
a = factory.create("port_address", cols=16, rows=16) a = factory.create("port_address", cols=16, rows=16)
self.local_check(a) self.local_check(a)
debug.info(1, "Port address 512 rows")
a = factory.create("port_address", cols=256, rows=512)
self.local_check(a)
globals.end_openram() globals.end_openram()
# run the test from the command line # run the test from the command line

View File

@ -13,6 +13,7 @@ from globals import OPTS
from sram_factory import factory from sram_factory import factory
import debug import debug
class port_data_1rw_1r_test(openram_test): class port_data_1rw_1r_test(openram_test):
def runTest(self): def runTest(self):
@ -20,10 +21,10 @@ class port_data_1rw_1r_test(openram_test):
globals.init_openram(config_file) globals.init_openram(config_file)
from sram_config import sram_config from sram_config import sram_config
OPTS.bitcell = "bitcell_1rw_1r"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
globals.setup_bitcell()
c = sram_config(word_size=4, c = sram_config(word_size=4,
num_words=16) num_words=16)

View File

@ -22,12 +22,10 @@ class single_bank_1rw_1r_test(openram_test):
globals.init_openram(config_file) globals.init_openram(config_file)
from sram_config import sram_config from sram_config import sram_config
OPTS.bitcell = "bitcell_1rw_1r"
OPTS.replica_bitcell = "replica_bitcell_1rw_1r"
OPTS.dummy_bitcell="dummy_bitcell_1rw_1r"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
globals.setup_bitcell()
c = sram_config(word_size=4, c = sram_config(word_size=4,
num_words=16) num_words=16)

View File

@ -22,13 +22,10 @@ class single_bank_1w_1r_test(openram_test):
globals.init_openram(config_file) globals.init_openram(config_file)
from sram_config import sram_config from sram_config import sram_config
OPTS.bitcell = "bitcell_1w_1r"
OPTS.replica_bitcell = "replica_bitcell_1w_1r"
OPTS.dummy_bitcell="dummy_bitcell_1w_1r"
OPTS.num_rw_ports = 0 OPTS.num_rw_ports = 0
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
OPTS.num_w_ports = 1 OPTS.num_w_ports = 1
globals.setup_bitcell()
c = sram_config(word_size=4, c = sram_config(word_size=4,
num_words=16) num_words=16)

View File

@ -22,6 +22,10 @@ class single_bank_wmask_1rw_1r_test(openram_test):
globals.init_openram(config_file) globals.init_openram(config_file)
from sram_config import sram_config from sram_config import sram_config
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1
OPTS.num_w_ports = 0
globals.setup_bitcell()
c = sram_config(word_size=8, c = sram_config(word_size=8,
write_size=4, write_size=4,

View File

@ -24,11 +24,10 @@ class psram_1bank_2mux_1rw_1w_test(openram_test):
from sram_config import sram_config from sram_config import sram_config
OPTS.bitcell = "pbitcell" OPTS.bitcell = "pbitcell"
OPTS.replica_bitcell="replica_pbitcell"
OPTS.dummy_bitcell="dummy_pbitcell"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_w_ports = 1 OPTS.num_w_ports = 1
OPTS.num_r_ports = 0 OPTS.num_r_ports = 0
globals.setup_bitcell()
c = sram_config(word_size=4, c = sram_config(word_size=4,
num_words=32, num_words=32,

View File

@ -24,11 +24,10 @@ class psram_1bank_2mux_1w_1r_test(openram_test):
from sram_config import sram_config from sram_config import sram_config
OPTS.bitcell = "pbitcell" OPTS.bitcell = "pbitcell"
OPTS.replica_bitcell="replica_pbitcell"
OPTS.dummy_bitcell="dummy_pbitcell"
OPTS.num_rw_ports = 0 OPTS.num_rw_ports = 0
OPTS.num_w_ports = 1 OPTS.num_w_ports = 1
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
globals.setup_bitcell()
c = sram_config(word_size=4, c = sram_config(word_size=4,
num_words=32, num_words=32,

View File

@ -22,14 +22,12 @@ class psram_1bank_2mux_test(openram_test):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
globals.init_openram(config_file) globals.init_openram(config_file)
from sram_config import sram_config from sram_config import sram_config
OPTS.bitcell = "pbitcell"
OPTS.replica_bitcell="replica_pbitcell"
OPTS.dummy_bitcell="dummy_pbitcell"
# testing layout of sram using pbitcell with 1 RW port (a 6T-cell equivalent) OPTS.bitcell = "pbitcell"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
OPTS.num_r_ports = 0 OPTS.num_r_ports = 0
globals.setup_bitcell()
c = sram_config(word_size=4, c = sram_config(word_size=4,
num_words=32, num_words=32,

View File

@ -24,11 +24,10 @@ class psram_1bank_4mux_1rw_1r_test(openram_test):
from sram_config import sram_config from sram_config import sram_config
OPTS.bitcell = "pbitcell" OPTS.bitcell = "pbitcell"
OPTS.replica_bitcell="replica_pbitcell"
OPTS.dummy_bitcell="dummy_pbitcell"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
globals.setup_bitcell()
c = sram_config(word_size=4, c = sram_config(word_size=4,
num_words=64, num_words=64,

View File

@ -22,12 +22,10 @@ class sram_1bank_2mux_1rw_1r_test(openram_test):
globals.init_openram(config_file) globals.init_openram(config_file)
from sram_config import sram_config from sram_config import sram_config
OPTS.bitcell = "bitcell_1rw_1r"
OPTS.replica_bitcell = "replica_bitcell_1rw_1r"
OPTS.dummy_bitcell="dummy_bitcell_1rw_1r"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
globals.setup_bitcell()
c = sram_config(word_size=4, c = sram_config(word_size=4,
num_words=32, num_words=32,

View File

@ -23,12 +23,10 @@ class psram_1bank_2mux_1w_1r_test(openram_test):
globals.init_openram(config_file) globals.init_openram(config_file)
from sram_config import sram_config from sram_config import sram_config
OPTS.bitcell = "bitcell_1w_1r"
OPTS.replica_bitcell="replica_bitcell_1w_1r"
OPTS.dummy_bitcell="dummy_bitcell_1w_1r"
OPTS.num_rw_ports = 0 OPTS.num_rw_ports = 0
OPTS.num_w_ports = 1 OPTS.num_w_ports = 1
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
globals.setup_bitcell()
c = sram_config(word_size=4, c = sram_config(word_size=4,
num_words=32, num_words=32,

View File

@ -22,12 +22,10 @@ class sram_1bank_8mux_1rw_1r_test(openram_test):
globals.init_openram(config_file) globals.init_openram(config_file)
from sram_config import sram_config from sram_config import sram_config
OPTS.bitcell = "bitcell_1rw_1r"
OPTS.replica_bitcell = "replica_bitcell_1rw_1r"
OPTS.dummy_bitcell="dummy_bitcell_1rw_1r"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
globals.setup_bitcell()
c = sram_config(word_size=2, c = sram_config(word_size=2,
num_words=128, num_words=128,

View File

@ -22,12 +22,10 @@ class sram_1bank_nomux_1rw_1r_test(openram_test):
globals.init_openram(config_file) globals.init_openram(config_file)
from sram_config import sram_config from sram_config import sram_config
OPTS.bitcell = "bitcell_1rw_1r"
OPTS.replica_bitcell = "replica_bitcell_1rw_1r"
OPTS.dummy_bitcell = "dummy_bitcell_1rw_1r"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
globals.setup_bitcell()
c = sram_config(word_size=4, c = sram_config(word_size=4,
num_words=16, num_words=16,

View File

@ -24,12 +24,10 @@ class psram_1bank_nomux_func_test(openram_test):
OPTS.analytical_delay = False OPTS.analytical_delay = False
OPTS.netlist_only = True OPTS.netlist_only = True
OPTS.trim_netlist = False OPTS.trim_netlist = False
OPTS.bitcell = "bitcell_1rw_1r"
OPTS.replica_bitcell = "replica_bitcell_1rw_1r"
OPTS.dummy_bitcell="dummy_bitcell_1rw_1r"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
globals.setup_bitcell()
# This is a hack to reload the characterizer __init__ with the spice version # This is a hack to reload the characterizer __init__ with the spice version
from importlib import reload from importlib import reload

View File

@ -26,13 +26,10 @@ class sram_wmask_1w_1r_func_test(openram_test):
OPTS.analytical_delay = False OPTS.analytical_delay = False
OPTS.netlist_only = True OPTS.netlist_only = True
OPTS.trim_netlist = False OPTS.trim_netlist = False
OPTS.bitcell = "bitcell_1w_1r"
OPTS.replica_bitcell = "replica_bitcell_1w_1r"
OPTS.dummy_bitcell = "dummy_bitcell_1w_1r"
OPTS.num_rw_ports = 0 OPTS.num_rw_ports = 0
OPTS.num_w_ports = 1 OPTS.num_w_ports = 1
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
globals.setup_bitcell()
# This is a hack to reload the characterizer __init__ with the spice version # This is a hack to reload the characterizer __init__ with the spice version
from importlib import reload from importlib import reload

View File

@ -5,18 +5,16 @@
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
# #
import unittest,warnings import unittest
import pdb,traceback import sys, os, glob
import sys,os,glob,copy
import shutil
sys.path.append(os.getenv("OPENRAM_HOME")) sys.path.append(os.getenv("OPENRAM_HOME"))
from globals import OPTS from globals import OPTS
import debug import debug
class openram_test(unittest.TestCase): class openram_test(unittest.TestCase):
""" Base unit test that we have some shared classes in. """ """ Base unit test that we have some shared classes in. """
def local_drc_check(self, w): def local_drc_check(self, w):
self.reset() self.reset()
@ -56,24 +54,26 @@ class openram_test(unittest.TestCase):
# Only allow DRC to fail and LVS to pass if we are using magic # Only allow DRC to fail and LVS to pass if we are using magic
if "magic" in OPTS.drc_exe and lvs_result == 0 and drc_result != 0: if "magic" in OPTS.drc_exe and lvs_result == 0 and drc_result != 0:
# import shutil
# zip_file = "/tmp/{0}_{1}".format(a.name, os.getpid()) # zip_file = "/tmp/{0}_{1}".format(a.name, os.getpid())
# debug.info(0, "Archiving failed files to {}.zip".format(zip_file)) # debug.info(0, "Archiving failed files to {}.zip".format(zip_file))
# shutil.make_archive(zip_file, 'zip', OPTS.openram_temp) # shutil.make_archive(zip_file, 'zip', OPTS.openram_temp)
debug.warning("DRC failed but LVS passed: {}".format(a.name)) debug.warning("DRC failed but LVS passed: {}".format(a.name))
# self.fail("DRC failed but LVS passed: {}".format(a.name)) # self.fail("DRC failed but LVS passed: {}".format(a.name))
elif drc_result != 0: elif drc_result != 0:
# import shutil
# zip_file = "/tmp/{0}_{1}".format(a.name, os.getpid()) # zip_file = "/tmp/{0}_{1}".format(a.name, os.getpid())
# debug.info(0,"Archiving failed files to {}.zip".format(zip_file)) # debug.info(0,"Archiving failed files to {}.zip".format(zip_file))
# shutil.make_archive(zip_file, 'zip', OPTS.openram_temp) # shutil.make_archive(zip_file, 'zip', OPTS.openram_temp)
self.fail("DRC failed: {}".format(a.name)) self.fail("DRC failed: {}".format(a.name))
if lvs_result != 0: if lvs_result != 0:
# import shutil
# zip_file = "/tmp/{0}_{1}".format(a.name, os.getpid()) # zip_file = "/tmp/{0}_{1}".format(a.name, os.getpid())
# debug.info(0,"Archiving failed files to {}.zip".format(zip_file)) # debug.info(0,"Archiving failed files to {}.zip".format(zip_file))
# shutil.make_archive(zip_file, 'zip', OPTS.openram_temp) # shutil.make_archive(zip_file, 'zip', OPTS.openram_temp)
self.fail("LVS mismatch: {}".format(a.name)) self.fail("LVS mismatch: {}".format(a.name))
# For debug... # For debug...
# import pdb; pdb.set_trace() # import pdb; pdb.set_trace()
if OPTS.purge_temp: if OPTS.purge_temp:
@ -98,7 +98,7 @@ class openram_test(unittest.TestCase):
debug.info(1, "Finding feasible period for current test.") debug.info(1, "Finding feasible period for current test.")
delay_obj.set_load_slew(load, slew) delay_obj.set_load_slew(load, slew)
test_port = delay_obj.read_ports[0] # Only test one port, assumes other ports have similar period. test_port = delay_obj.read_ports[0] # Only test one port, assumes other ports have similar period.
delay_obj.analysis_init(probe_address="1"*sram.addr_size, probe_data=(sram.word_size-1)) delay_obj.analysis_init(probe_address="1" * sram.addr_size, probe_data=sram.word_size - 1)
delay_obj.find_feasible_period_one_port(test_port) delay_obj.find_feasible_period_one_port(test_port)
return delay_obj.period return delay_obj.period
@ -141,8 +141,6 @@ class openram_test(unittest.TestCase):
debug.error("Results exceeded {:.1f}% tolerance compared to golden results:\n".format(error_tolerance * 100) + data_string) debug.error("Results exceeded {:.1f}% tolerance compared to golden results:\n".format(error_tolerance * 100) + data_string)
return data_matches return data_matches
def isclose(self, key, value, actual_value, error_tolerance=1e-2): def isclose(self, key, value, actual_value, error_tolerance=1e-2):
""" This is used to compare relative values. """ """ This is used to compare relative values. """
import debug import debug
@ -169,13 +167,9 @@ class openram_test(unittest.TestCase):
# Get normalization value # Get normalization value
norm_value = abs(max(value1, value2)) norm_value = abs(max(value1, value2))
# Edge case where greater is a zero
if norm_value == 0:
min_value = abs(min(value1, value2))
return abs(value1 - value2) / norm_value return abs(value1 - value2) / norm_value
def relative_compare(self, value, actual_value, error_tolerance): def relative_compare(self, value, actual_value, error_tolerance):
""" This is used to compare relative values. """ """ This is used to compare relative values. """
if (value==actual_value): # if we don't need a relative comparison! if (value==actual_value): # if we don't need a relative comparison!
@ -227,7 +221,6 @@ class openram_test(unittest.TestCase):
debug.info(3, "line1_floats: " + str(line1_floats)) debug.info(3, "line1_floats: " + str(line1_floats))
debug.info(3, "line2_floats: " + str(line2_floats)) debug.info(3, "line2_floats: " + str(line2_floats))
# 2. Remove the floats from the string # 2. Remove the floats from the string
for f in line1_floats: for f in line1_floats:
line1=line1.replace(f, "", 1) line1=line1.replace(f, "", 1)
@ -275,7 +268,6 @@ class openram_test(unittest.TestCase):
# Never reached # Never reached
return False return False
def isdiff(self, filename1, filename2): def isdiff(self, filename1, filename2):
""" This is used to compare two files and display the diff if they are different.. """ """ This is used to compare two files and display the diff if they are different.. """
import debug import debug
@ -305,6 +297,9 @@ class openram_test(unittest.TestCase):
debug.info(2, "MATCH {0} {1}".format(filename1, filename2)) debug.info(2, "MATCH {0} {1}".format(filename1, filename2))
return True return True
def dbg():
import pdb; pdb.set_trace()
def header(filename, technology): def header(filename, technology):
# Skip the header for gitlab regression # Skip the header for gitlab regression
@ -323,10 +318,14 @@ def header(filename, technology):
print("|=========" + OPTS.openram_temp.center(60) + "=========|") print("|=========" + OPTS.openram_temp.center(60) + "=========|")
print("|==============================================================================|") print("|==============================================================================|")
def debugTestRunner(post_mortem=None): def debugTestRunner(post_mortem=None):
"""unittest runner doing post mortem debugging on failing tests""" """unittest runner doing post mortem debugging on failing tests"""
import pdb
import traceback
if post_mortem is None and not OPTS.purge_temp: if post_mortem is None and not OPTS.purge_temp:
post_mortem = pdb.post_mortem post_mortem = pdb.post_mortem
class DebugTestResult(unittest.TextTestResult): class DebugTestResult(unittest.TextTestResult):
def addError(self, test, err): def addError(self, test, err):
# called before tearDown() # called before tearDown()
@ -334,6 +333,7 @@ def debugTestRunner(post_mortem=None):
if post_mortem: if post_mortem:
post_mortem(err[2]) post_mortem(err[2])
super(DebugTestResult, self).addError(test, err) super(DebugTestResult, self).addError(test, err)
def addFailure(self, test, err): def addFailure(self, test, err):
traceback.print_exception(*err) traceback.print_exception(*err)
if post_mortem: if post_mortem: