Update mirroring in port_data for bitcell mirrored arrays

This commit is contained in:
mrg 2020-06-05 11:29:31 -07:00
parent 2e7f9395f2
commit a62b85a6b1
12 changed files with 43 additions and 52 deletions

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 """

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

@ -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
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

@ -26,11 +26,11 @@ class single_level_column_mux_test(openram_test):
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
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

@ -28,17 +28,13 @@ class precharge_1rw_1r_test(openram_test):
OPTS.num_w_ports = 0 OPTS.num_w_ports = 0
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

@ -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

@ -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):