mirror of https://github.com/VLSIDA/OpenRAM.git
Update mirroring in port_data for bitcell mirrored arrays
This commit is contained in:
parent
2e7f9395f2
commit
a62b85a6b1
|
|
@ -178,14 +178,17 @@ class port_data(design.design):
|
|||
|
||||
# Extra column +1 is for RBL
|
||||
# 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",
|
||||
columns=self.num_cols + 1,
|
||||
port=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)
|
||||
|
||||
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",
|
||||
word_size=self.word_size,
|
||||
words_per_row=self.words_per_row)
|
||||
|
|
@ -194,9 +197,9 @@ class port_data(design.design):
|
|||
self.sense_amp_array = None
|
||||
|
||||
if self.col_addr_size > 0:
|
||||
# RBLs dont get a col mux
|
||||
self.column_mux_array = factory.create(module_type="column_mux_array",
|
||||
columns=self.num_cols,
|
||||
port=self.port,
|
||||
word_size=self.word_size,
|
||||
bitcell_bl=self.bl_names[self.port],
|
||||
bitcell_br=self.br_names[self.port])
|
||||
|
|
@ -205,17 +208,18 @@ class port_data(design.design):
|
|||
self.column_mux_array = None
|
||||
|
||||
if self.port in self.write_ports:
|
||||
# RBLs dont get a write driver
|
||||
self.write_driver_array = factory.create(module_type="write_driver_array",
|
||||
columns=self.num_cols,
|
||||
word_size=self.word_size,
|
||||
write_size=self.write_size)
|
||||
self.add_mod(self.write_driver_array)
|
||||
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",
|
||||
columns=self.num_cols,
|
||||
word_size=self.word_size,
|
||||
write_size=self.write_size,
|
||||
port = self.port)
|
||||
write_size=self.write_size)
|
||||
self.add_mod(self.write_mask_and_array)
|
||||
else:
|
||||
self.write_mask_and_array = None
|
||||
|
|
@ -248,13 +252,6 @@ class port_data(design.design):
|
|||
self.precharge = factory.create(module_type="precharge",
|
||||
bitcell_bl=self.bl_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):
|
||||
""" Creating Precharge """
|
||||
|
|
|
|||
|
|
@ -18,16 +18,16 @@ class precharge_array(design.design):
|
|||
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)
|
||||
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.columns = columns
|
||||
self.size = size
|
||||
self.port = port
|
||||
self.bitcell_bl = bitcell_bl
|
||||
self.bitcell_br = bitcell_br
|
||||
self.column_offset = column_offset
|
||||
|
||||
self.create_netlist()
|
||||
if not OPTS.netlist_only:
|
||||
|
|
@ -106,7 +106,7 @@ class precharge_array(design.design):
|
|||
xoffset = 0
|
||||
for i in range(self.columns):
|
||||
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"
|
||||
tempx = tempx + self.pc_cell.width
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class sense_amp_array(design.design):
|
|||
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)
|
||||
debug.info(1, "Creating {0}".format(self.name))
|
||||
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.words_per_row = words_per_row
|
||||
self.column_offset = column_offset
|
||||
self.row_size = self.word_size * self.words_per_row
|
||||
|
||||
self.create_netlist()
|
||||
|
|
@ -102,25 +103,22 @@ class sense_amp_array(design.design):
|
|||
def place_sense_amp_array(self):
|
||||
from tech import cell_properties
|
||||
if self.bitcell.width > self.amp.width:
|
||||
amp_spacing = self.bitcell.width * self.words_per_row
|
||||
amp_spacing = self.bitcell.width
|
||||
else:
|
||||
amp_spacing = self.amp.width * self.words_per_row
|
||||
amp_spacing = self.amp.width
|
||||
|
||||
for i in range(0, self.word_size):
|
||||
xoffset = amp_spacing * i
|
||||
for i in range(0, self.row_size, self.words_per_row):
|
||||
index = int(i / self.words_per_row)
|
||||
xoffset = i * amp_spacing
|
||||
|
||||
# align the xoffset to the grid of bitcells. This way we
|
||||
# know when to do the mirroring.
|
||||
grid_x = int(xoffset / self.amp.width)
|
||||
|
||||
if cell_properties.bitcell.mirror.y and grid_x % 2:
|
||||
if cell_properties.bitcell.mirror.y and (i + self.column_offset) % 2:
|
||||
mirror = "MY"
|
||||
xoffset = xoffset + self.amp.width
|
||||
else:
|
||||
mirror = ""
|
||||
|
||||
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):
|
||||
for i in range(len(self.local_insts)):
|
||||
|
|
|
|||
|
|
@ -20,17 +20,17 @@ class single_level_column_mux_array(design.design):
|
|||
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)
|
||||
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.columns = columns
|
||||
self.port = port
|
||||
self.word_size = word_size
|
||||
self.words_per_row = int(self.columns / self.word_size)
|
||||
self.bitcell_bl = bitcell_bl
|
||||
self.bitcell_br = bitcell_br
|
||||
self.column_offset = column_offset
|
||||
|
||||
if "li" in layer:
|
||||
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 col_num in range(self.columns):
|
||||
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"
|
||||
xoffset = xoffset + self.mux.width
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class write_driver_array(design.design):
|
|||
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)
|
||||
debug.info(1, "Creating {0}".format(self.name))
|
||||
self.add_comment("columns: {0}".format(columns))
|
||||
|
|
@ -27,6 +27,7 @@ class write_driver_array(design.design):
|
|||
self.columns = columns
|
||||
self.word_size = word_size
|
||||
self.write_size = write_size
|
||||
self.column_offset = column_offset
|
||||
self.words_per_row = int(columns / word_size)
|
||||
|
||||
if self.write_size:
|
||||
|
|
@ -128,7 +129,7 @@ class write_driver_array(design.design):
|
|||
index = int(i / self.words_per_row)
|
||||
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"
|
||||
xoffset = xoffset + self.driver.width
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
"""
|
||||
|
||||
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)
|
||||
debug.info(1, "Creating {0}".format(self.name))
|
||||
self.add_comment("columns: {0}".format(columns))
|
||||
|
|
@ -28,7 +28,7 @@ class write_mask_and_array(design.design):
|
|||
self.columns = columns
|
||||
self.word_size = word_size
|
||||
self.write_size = write_size
|
||||
self.port = port
|
||||
self.column_offset
|
||||
self.words_per_row = int(columns / word_size)
|
||||
self.num_wmasks = int(word_size / write_size)
|
||||
|
||||
|
|
|
|||
|
|
@ -26,11 +26,11 @@ class single_level_column_mux_test(openram_test):
|
|||
OPTS.num_w_ports = 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)
|
||||
|
||||
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)
|
||||
|
||||
globals.end_openram()
|
||||
|
|
|
|||
|
|
@ -29,19 +29,19 @@ class single_level_column_mux_pbitcell_test(openram_test):
|
|||
|
||||
factory.reset()
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
globals.end_openram()
|
||||
|
|
|
|||
|
|
@ -28,18 +28,14 @@ class precharge_1rw_1r_test(openram_test):
|
|||
OPTS.num_w_ports = 0
|
||||
|
||||
factory.reset()
|
||||
debug.info(2, "Checking 3 column precharge array for 1RW/1R bitcell")
|
||||
pc = factory.create(module_type="precharge_array", columns=3, port=0, bitcell_bl="bl0", bitcell_br="br0")
|
||||
debug.info(2, "Checking 3 column precharge array for 1RW/1R bitcell (port 0)")
|
||||
pc = factory.create(module_type="precharge_array", columns=3, bitcell_bl="bl0", bitcell_br="br0")
|
||||
self.local_check(pc)
|
||||
|
||||
debug.info(2, "Checking 3 column precharge array for 1RW/1R bitcell (port 1)")
|
||||
pc = factory.create(module_type="precharge_array", columns=3, bitcell_bl="bl0", bitcell_br="br0", column_offset=1)
|
||||
self.local_check(pc)
|
||||
|
||||
# debug.info(2, "Checking 3 column precharge array for pbitcell (innermost connections)")
|
||||
# pc = precharge_array.precharge_array(name="pre3", columns=3, bitcell_bl="bl0", bitcell_br="br0")
|
||||
# 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()
|
||||
|
||||
# run the test from the command line
|
||||
|
|
|
|||
|
|
@ -21,9 +21,8 @@ class precharge_test(openram_test):
|
|||
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
|
||||
globals.init_openram(config_file)
|
||||
|
||||
# check precharge array in single port
|
||||
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)
|
||||
|
||||
globals.end_openram()
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ class sense_amp_test(openram_test):
|
|||
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
|
||||
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")
|
||||
a = factory.create(module_type="sense_amp_array", word_size=4, words_per_row=1)
|
||||
self.local_check(a)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ from globals import OPTS
|
|||
from sram_factory import factory
|
||||
import debug
|
||||
|
||||
|
||||
class port_data_1rw_1r_test(openram_test):
|
||||
|
||||
def runTest(self):
|
||||
|
|
|
|||
Loading…
Reference in New Issue