mirror of
https://github.com/VLSIDA/OpenRAM.git
synced 2026-08-22 06:07:31 +02:00
dual port rba lvs clean again with cell library changes
This commit is contained in:
@@ -19,8 +19,8 @@ class bitcell_array(bitcell_base_array):
|
|||||||
Creates a rows x cols array of memory cells.
|
Creates a rows x cols array of memory cells.
|
||||||
Assumes bit-lines and word lines are connected by abutment.
|
Assumes bit-lines and word lines are connected by abutment.
|
||||||
"""
|
"""
|
||||||
def __init__(self, rows, cols, column_offset=0, name="", left_rbl=None, right_rbl=None):
|
def __init__(self, rows, cols, column_offset=0, row_offset=0, name="", left_rbl=None, right_rbl=None):
|
||||||
super().__init__(rows=rows, cols=cols, column_offset=column_offset, name=name)
|
super().__init__(rows=rows, cols=cols, column_offset=column_offset, row_offset=row_offset, name=name)
|
||||||
debug.info(1, "Creating {0} {1} x {2}".format(self.name, rows, cols))
|
debug.info(1, "Creating {0} {1} x {2}".format(self.name, rows, cols))
|
||||||
self.add_comment("rows: {0} cols: {1}".format(rows, cols))
|
self.add_comment("rows: {0} cols: {1}".format(rows, cols))
|
||||||
|
|
||||||
@@ -59,18 +59,21 @@ class bitcell_array(bitcell_base_array):
|
|||||||
self.cell = factory.create(module_type=OPTS.bitcell)
|
self.cell = factory.create(module_type=OPTS.bitcell)
|
||||||
|
|
||||||
def create_instances(self):
|
def create_instances(self):
|
||||||
|
r = self.row_offset
|
||||||
|
c = self.column_offset
|
||||||
self.cell_inst={}
|
self.cell_inst={}
|
||||||
if self.cell.mirror.y:
|
if self.cell.mirror.y:
|
||||||
core_block = [[0 for x in range(2)] for y in range(2)]
|
core_block = [[0 for x in range(2)] for y in range(2)]
|
||||||
core_block[0][0] = geometry.instance("core_0_0", mod=self.cell, is_bitcell=True)
|
core_block[(0 + r) % 2][(0+c) %2] = geometry.instance(f"core_{(0 + r)%2}_{(0+c)%2}", mod=self.cell, is_bitcell=True, mirror='XY')
|
||||||
core_block[1][0] = geometry.instance("core_1_0", mod=self.cell, is_bitcell=True, mirror='MX')
|
core_block[(0 + r) % 2][(1+c) %2] = geometry.instance(f"core_{(0 + r)%2}_{(1+c)%2}", mod=self.cell, is_bitcell=True, mirror='MX')
|
||||||
core_block[0][1] = geometry.instance("core_0_1", mod=self.cell, is_bitcell=True, mirror='MY')
|
core_block[(1 + r) % 2][(0+c) %2] = geometry.instance(f"core_{(1 + r)%2}_{(0+c)%2}", mod=self.cell, is_bitcell=True, mirror='MY')
|
||||||
core_block[1][1] = geometry.instance("core_1_1", mod=self.cell, is_bitcell=True, mirror='XY')
|
core_block[(1 + r) % 2][(1+c) %2] = geometry.instance(f"core_{(1 + r)%2}_{(1+c)%2}", mod=self.cell, is_bitcell=True, mirror='')
|
||||||
else:
|
else:
|
||||||
core_block = [[0 for x in range(1)] for y in range(2)]
|
core_block = [[0 for x in range(1)] for y in range(2)]
|
||||||
core_block[0][0] = geometry.instance("core_0_0", mod=self.cell, is_bitcell=True)
|
core_block[(0 + self.row_offset) % 2][(0+self.column_offset) %2] = geometry.instance("core_0_0", mod=self.cell, is_bitcell=True)
|
||||||
core_block[1][0] = geometry.instance("core_1_0", mod=self.cell, is_bitcell=True, mirror='MX')
|
core_block[(1 + self.row_offset) % 2][(0+self.column_offset) %2] = geometry.instance("core_1_0", mod=self.cell, is_bitcell=True, mirror='MX')
|
||||||
|
print(r, c)
|
||||||
|
print(core_block)
|
||||||
|
|
||||||
self.pattern = pattern(self, "bitcell_array", core_block, num_rows=self.row_size, num_cols=self.column_size,name_template="bit_r{0}_c{1}")
|
self.pattern = pattern(self, "bitcell_array", core_block, num_rows=self.row_size, num_cols=self.column_size,name_template="bit_r{0}_c{1}")
|
||||||
self.pattern.connect_array()
|
self.pattern.connect_array()
|
||||||
|
|||||||
@@ -16,14 +16,14 @@ class bitcell_base_array(design):
|
|||||||
"""
|
"""
|
||||||
Abstract base class for bitcell-arrays -- bitcell, dummy, replica
|
Abstract base class for bitcell-arrays -- bitcell, dummy, replica
|
||||||
"""
|
"""
|
||||||
def __init__(self, name, rows, cols, column_offset):
|
def __init__(self, name, rows, cols, column_offset, row_offset):
|
||||||
super().__init__(name)
|
super().__init__(name)
|
||||||
debug.info(1, "Creating {0} {1} x {2}".format(self.name, rows, cols))
|
debug.info(1, "Creating {0} {1} x {2}".format(self.name, rows, cols))
|
||||||
|
|
||||||
self.column_size = cols
|
self.column_size = cols
|
||||||
self.row_size = rows
|
self.row_size = rows
|
||||||
self.column_offset = column_offset
|
self.column_offset = column_offset
|
||||||
|
self.row_offset = row_offset
|
||||||
# Bitcell for port names only
|
# Bitcell for port names only
|
||||||
self.cell = factory.create(module_type=OPTS.bitcell)
|
self.cell = factory.create(module_type=OPTS.bitcell)
|
||||||
|
|
||||||
@@ -170,6 +170,18 @@ class bitcell_base_array(design):
|
|||||||
|
|
||||||
power_name = 'vdd'
|
power_name = 'vdd'
|
||||||
ground_name = 'gnd'
|
ground_name = 'gnd'
|
||||||
|
|
||||||
|
if vdd_found == False or gnd_found == False:
|
||||||
|
for inst in self.insts:
|
||||||
|
if 'VDD' in inst.mod.get_pin_names():
|
||||||
|
vdd_found = True
|
||||||
|
power_name = 'VDD'
|
||||||
|
|
||||||
|
if 'GND' in inst.mod.get_pin_names():
|
||||||
|
gnd_found = True
|
||||||
|
ground_name = 'GND'
|
||||||
|
|
||||||
|
|
||||||
if vdd_found is False or gnd_found is False:
|
if vdd_found is False or gnd_found is False:
|
||||||
from openram.tech import cell_properties
|
from openram.tech import cell_properties
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class capped_replica_bitcell_array(bitcell_base_array):
|
|||||||
sides of a bitcell array.
|
sides of a bitcell array.
|
||||||
"""
|
"""
|
||||||
def __init__(self, rows, cols, rbl=None, left_rbl=None, right_rbl=None, name=""):
|
def __init__(self, rows, cols, rbl=None, left_rbl=None, right_rbl=None, name=""):
|
||||||
super().__init__(name, rows, cols, column_offset=0)
|
super().__init__(name, rows, cols, column_offset=0, row_offset=0)
|
||||||
debug.info(1, "Creating {0} {1} x {2} rbls: {3} left_rbl: {4} right_rbl: {5}".format(self.name,
|
debug.info(1, "Creating {0} {1} x {2} rbls: {3} left_rbl: {4} right_rbl: {5}".format(self.name,
|
||||||
rows,
|
rows,
|
||||||
cols,
|
cols,
|
||||||
|
|||||||
@@ -8,12 +8,13 @@ from openram import OPTS
|
|||||||
from .bitcell_base_array import bitcell_base_array
|
from .bitcell_base_array import bitcell_base_array
|
||||||
from openram.base import geometry
|
from openram.base import geometry
|
||||||
from .pattern import pattern
|
from .pattern import pattern
|
||||||
|
from math import ceil
|
||||||
|
|
||||||
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.
|
||||||
"""
|
"""
|
||||||
def __init__(self, rows, cols, column_offset=0, mirror=0, location="", name="",left_rbl=[],right_rbl=[]):
|
def __init__(self, rows, cols, column_offset=0, row_offset=0, mirror=0, location="", name="",left_rbl=[],right_rbl=[]):
|
||||||
super().__init__(rows=rows, cols=cols, column_offset=column_offset, name=name)
|
super().__init__(rows=rows, cols=cols, column_offset=column_offset, name=name)
|
||||||
self.mirror = mirror
|
self.mirror = mirror
|
||||||
self.location = location
|
self.location = location
|
||||||
@@ -38,28 +39,44 @@ class col_cap_array(bitcell_base_array):
|
|||||||
|
|
||||||
def create_layout(self):
|
def create_layout(self):
|
||||||
|
|
||||||
self.place_array("dummy_r{0}_c{1}", self.mirror)
|
self.place_array()
|
||||||
self.add_layout_pins()
|
self.add_layout_pins()
|
||||||
|
|
||||||
self.height = self.dummy_cell.height
|
#self.height = self.dummy_cell.height
|
||||||
self.width = self.column_size * self.cell.width
|
#self.width = self.column_size * self.cell.width
|
||||||
|
|
||||||
self.add_boundary()
|
self.add_boundary()
|
||||||
self.DRC_LVS()
|
self.DRC_LVS()
|
||||||
|
|
||||||
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_{}".format(OPTS.bitcell))
|
self.colend = factory.create(module_type="col_cap_{}".format(OPTS.bitcell))
|
||||||
|
|
||||||
|
# def create_instances(self):
|
||||||
|
# """ Create the module instances used in this design """
|
||||||
|
# self.cell_inst = {}
|
||||||
|
# for col in range(self.column_size):
|
||||||
|
# for row in range(self.row_size):
|
||||||
|
# name = "bit_r{0}_c{1}".format(row, col)
|
||||||
|
# self.cell_inst[row, col]=self.add_inst(name=name,
|
||||||
|
# mod=self.dummy_cell)
|
||||||
|
# self.connect_inst(self.get_bitcell_pins(row, col))
|
||||||
|
|
||||||
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={}
|
||||||
for col in range(self.column_size):
|
if self.location == "top":
|
||||||
for row in range(self.row_size):
|
bit_row = [geometry.instance("00_colend", mod=self.colend, is_bitcell=True, mirror="MY")]\
|
||||||
name = "bit_r{0}_c{1}".format(row, col)
|
+ [geometry.instance("01_colend", mod=self.colend, is_bitcell=True)]
|
||||||
self.cell_inst[row, col]=self.add_inst(name=name,
|
elif self.location == "bottom":
|
||||||
mod=self.dummy_cell)
|
bit_row = [geometry.instance("00_colend", mod=self.colend, is_bitcell=True, mirror="XY")]\
|
||||||
self.connect_inst(self.get_bitcell_pins(row, col))
|
+ [geometry.instance("01_colend", mod=self.colend, is_bitcell=True, mirror="MX")]
|
||||||
|
|
||||||
|
bit_row = pattern.rotate_list(bit_row, self.column_offset * 2)
|
||||||
|
bit_block = []
|
||||||
|
pattern.append_row_to_block(bit_block, bit_row)
|
||||||
|
self.pattern = pattern(self, "col_cap_array_" + self.location , bit_block, num_rows=self.row_size, num_cols=self.column_size, num_cores_x=ceil(self.column_size/2), num_cores_y=ceil(self.row_size/2), name_template="col_cap_array" + self.location + "_r{0}_c{1}")
|
||||||
|
self.pattern.connect_array()
|
||||||
|
|
||||||
def get_bitcell_pins(self, row, col):
|
def get_bitcell_pins(self, row, col):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class dummy_array(bitcell_base_array):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, rows, cols, column_offset=0, row_offset=0 ,mirror=0, location="", name="", left_rbl=0, right_rbl=0):
|
def __init__(self, rows, cols, column_offset=0, row_offset=0 ,mirror=0, location="", name="", left_rbl=0, right_rbl=0):
|
||||||
super().__init__(rows=rows, cols=cols, column_offset=column_offset, name=name)
|
super().__init__(rows=rows, cols=cols, column_offset=column_offset, row_offset=row_offset, name=name)
|
||||||
self.location = location
|
self.location = location
|
||||||
self.row_offset = row_offset
|
self.row_offset = row_offset
|
||||||
self.mirror = mirror
|
self.mirror = mirror
|
||||||
@@ -55,17 +55,20 @@ class dummy_array(bitcell_base_array):
|
|||||||
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={}
|
||||||
|
r = self.row_offset
|
||||||
|
c = self.column_offset
|
||||||
if self.cell.mirror.y:
|
if self.cell.mirror.y:
|
||||||
core_block = [[0 for x in range(2)] for y in range(2)]
|
core_block = [[0 for x in range(2)] for y in range(2)]
|
||||||
core_block[(0+self.mirror) %2][(0+self.column_offset+self.row_offset) %2] = geometry.instance("core_0_0", mod=self.dummy_cell, is_bitcell=True, mirror='MX')
|
core_block[(0 + r) % 2][(0+c) %2] = geometry.instance(f"core_{(0 + r)%2}_{(0+c)%2}", mod=self.dummy_cell, is_bitcell=True, mirror='XY')
|
||||||
core_block[(1+self.mirror) %2][(0+self.column_offset+self.row_offset) %2] = geometry.instance("core_1_0", mod=self.dummy_cell, is_bitcell=True)
|
core_block[(0 + r) % 2][(1+c) %2] = geometry.instance(f"core_{(0 + r)%2}_{(1+c)%2}", mod=self.dummy_cell, is_bitcell=True, mirror='MX')
|
||||||
core_block[(0+self.mirror) %2][(1+self.column_offset+self.row_offset) %2] = geometry.instance("core_0_1", mod=self.dummy_cell, is_bitcell=True, mirror='XY')
|
core_block[(1 + r) % 2][(0+c) %2] = geometry.instance(f"core_{(1 + r)%2}_{(0+c)%2}", mod=self.dummy_cell, is_bitcell=True, mirror='MY')
|
||||||
core_block[(1+self.mirror) %2][(1+self.column_offset+self.row_offset) %2] = geometry.instance("core_1_1", mod=self.dummy_cell, is_bitcell=True, mirror='MY')
|
core_block[(1 + r) % 2][(1+c) %2] = geometry.instance(f"core_{(1 + r)%2}_{(1+c)%2}", mod=self.dummy_cell, is_bitcell=True, mirror='')
|
||||||
else:
|
else:
|
||||||
core_block = [[0 for x in range(1)] for y in range(2)]
|
core_block = [[0 for x in range(1)] for y in range(2)]
|
||||||
core_block[(1+self.mirror) %2][(0+self.column_offset) %2] = geometry.instance("core_0_0", mod=self.dummy_cell, is_bitcell=True, mirror='MX')
|
core_block[(0 + self.row_offset) % 2][(0+self.column_offset) %2] = geometry.instance("core_0_0", mod=self.dummy_cell, is_bitcell=True)
|
||||||
core_block[(0+self.mirror) %2][(0+self.column_offset) %2] = geometry.instance("core_1_0", mod=self.dummy_cell, is_bitcell=True)
|
core_block[(1 + self.row_offset) % 2][(0+self.column_offset) %2] = geometry.instance("core_1_0", mod=self.dummy_cell, is_bitcell=True, mirror='MX')
|
||||||
|
print(r, c)
|
||||||
|
print(core_block)
|
||||||
|
|
||||||
self.pattern = pattern(self, "dummy_array", core_block, num_rows=self.row_size, num_cols=self.column_size, name_template="bit_r{0}_c{1}")
|
self.pattern = pattern(self, "dummy_array", core_block, num_rows=self.row_size, num_cols=self.column_size, name_template="bit_r{0}_c{1}")
|
||||||
self.pattern.connect_array()
|
self.pattern.connect_array()
|
||||||
|
|||||||
@@ -147,7 +147,6 @@ class pattern():
|
|||||||
|
|
||||||
def connect_array(self) -> None:
|
def connect_array(self) -> None:
|
||||||
|
|
||||||
#debug_array = [[None]*12 for _ in range(6)]
|
|
||||||
row = 0
|
row = 0
|
||||||
col = 0
|
col = 0
|
||||||
for i in range(self.num_cores_y):
|
for i in range(self.num_cores_y):
|
||||||
@@ -183,7 +182,7 @@ class pattern():
|
|||||||
y += inst.height
|
y += inst.height
|
||||||
if "Y" in inst.mirror:
|
if "Y" in inst.mirror:
|
||||||
x += inst.width
|
x += inst.width
|
||||||
#print('placing inst {} at {}'.format(inst, offset))
|
print('placing inst {} at {}'.format(inst, offset))
|
||||||
inst.place((x, y), inst.mirror, inst.rotate)
|
inst.place((x, y), inst.mirror, inst.rotate)
|
||||||
|
|
||||||
def place_array(self):
|
def place_array(self):
|
||||||
@@ -193,7 +192,7 @@ class pattern():
|
|||||||
for row in range(self.row_max+1):
|
for row in range(self.row_max+1):
|
||||||
x = 0
|
x = 0
|
||||||
for col in range(self.col_max+1):
|
for col in range(self.col_max+1):
|
||||||
inst = self.parent_design.all_inst[self.row_max - row, col]
|
inst = self.parent_design.all_inst[row, col]
|
||||||
self.place_inst(inst, (x, y))
|
self.place_inst(inst, (x, y))
|
||||||
x += inst.width
|
x += inst.width
|
||||||
y += inst.height
|
y += inst.height
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class replica_bitcell_array(bitcell_base_array):
|
|||||||
replica bitcell and dummy bitcell (BL/BR disconnected).
|
replica bitcell and dummy bitcell (BL/BR disconnected).
|
||||||
"""
|
"""
|
||||||
def __init__(self, rows, cols, rbl=None, left_rbl=None, right_rbl=None, name=""):
|
def __init__(self, rows, cols, rbl=None, left_rbl=None, right_rbl=None, name=""):
|
||||||
super().__init__(name=name, rows=rows, cols=cols, column_offset=0)
|
super().__init__(name=name, rows=rows, cols=cols, column_offset=0, row_offset=0)
|
||||||
debug.info(1, "Creating {0} {1} x {2} rbls: {3} left_rbl: {4} right_rbl: {5}".format(self.name,
|
debug.info(1, "Creating {0} {1} x {2} rbls: {3} left_rbl: {4} right_rbl: {5}".format(self.name,
|
||||||
rows,
|
rows,
|
||||||
cols,
|
cols,
|
||||||
@@ -77,6 +77,7 @@ class replica_bitcell_array(bitcell_base_array):
|
|||||||
# Bitcell array
|
# Bitcell array
|
||||||
self.bitcell_array = factory.create(module_type="bitcell_array",
|
self.bitcell_array = factory.create(module_type="bitcell_array",
|
||||||
column_offset=len(self.left_rbl),
|
column_offset=len(self.left_rbl),
|
||||||
|
row_offset=len(self.left_rbl),
|
||||||
cols=self.column_size,
|
cols=self.column_size,
|
||||||
rows=self.row_size,
|
rows=self.row_size,
|
||||||
left_rbl=self.left_rbl,
|
left_rbl=self.left_rbl,
|
||||||
@@ -110,20 +111,17 @@ class replica_bitcell_array(bitcell_base_array):
|
|||||||
|
|
||||||
for port in self.all_ports:
|
for port in self.all_ports:
|
||||||
if port in self.left_rbl:
|
if port in self.left_rbl:
|
||||||
row_offset = self.row_size
|
|
||||||
mirror = row_offset % 2 + 1
|
|
||||||
elif port in self.right_rbl:
|
|
||||||
row_offset = 0
|
row_offset = 0
|
||||||
mirror = 0
|
elif port in self.right_rbl:
|
||||||
|
row_offset = self.row_size + len(self.left_rbl)
|
||||||
else:
|
else:
|
||||||
continue
|
row_offset = 0
|
||||||
|
|
||||||
self.dummy_rows[port] = factory.create(module_type="dummy_array",
|
self.dummy_rows[port] = factory.create(module_type="dummy_array",
|
||||||
cols=self.column_size,
|
cols=self.column_size,
|
||||||
rows=1,
|
rows=1,
|
||||||
row_offset=row_offset,
|
row_offset=row_offset,
|
||||||
column_offset=len(self.left_rbl),
|
column_offset=len(self.left_rbl))
|
||||||
mirror=mirror)
|
|
||||||
|
|
||||||
def add_pins(self):
|
def add_pins(self):
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class replica_column(bitcell_base_array):
|
|||||||
self.row_start = rbl[0]
|
self.row_start = rbl[0]
|
||||||
# End of regular word line rows
|
# End of regular word line rows
|
||||||
self.row_end = self.row_start + rows
|
self.row_end = self.row_start + rows
|
||||||
super().__init__(rows=self.row_size, cols=1, column_offset=column_offset, name=name)
|
super().__init__(rows=self.row_size, cols=1, column_offset=column_offset, row_offset=0, name=name)
|
||||||
|
|
||||||
self.rows = rows
|
self.rows = rows
|
||||||
self.left_rbl = rbl[0]
|
self.left_rbl = rbl[0]
|
||||||
@@ -95,12 +95,12 @@ class replica_column(bitcell_base_array):
|
|||||||
# Replic bit specifies which other bit (in the full range (0,total_size) to make a replica cell.
|
# Replic bit specifies which other bit (in the full range (0,total_size) to make a replica cell.
|
||||||
# All other cells are dummies
|
# All other cells are dummies
|
||||||
if (row == self.replica_bit) or (row >= self.row_start and row < self.row_end):
|
if (row == self.replica_bit) or (row >= self.row_start and row < self.row_end):
|
||||||
if current_row % 2 == 1:
|
if current_row % 2 == 0:
|
||||||
core_block[row][0] = geometry.instance("rbc_{}".format(row), mod=self.replica_cell, is_bitcell=True)
|
core_block[row][0] = geometry.instance("rbc_{}".format(row), mod=self.replica_cell, is_bitcell=True)
|
||||||
else:
|
else:
|
||||||
core_block[row][0] = geometry.instance("rbc_{}".format(row), mod=self.replica_cell, is_bitcell=True, mirror='MX')
|
core_block[row][0] = geometry.instance("rbc_{}".format(row), mod=self.replica_cell, is_bitcell=True, mirror='MX')
|
||||||
else:
|
else:
|
||||||
if current_row % 2 == 1:
|
if current_row % 2 == 0:
|
||||||
core_block[row][0] = geometry.instance("rbc_{}".format(row), mod=self.dummy_cell, is_bitcell=True)
|
core_block[row][0] = geometry.instance("rbc_{}".format(row), mod=self.dummy_cell, is_bitcell=True)
|
||||||
else:
|
else:
|
||||||
core_block[row][0] = geometry.instance("rbc_{}".format(row), mod=self.dummy_cell, is_bitcell=True, mirror='MX')
|
core_block[row][0] = geometry.instance("rbc_{}".format(row), mod=self.dummy_cell, is_bitcell=True, mirror='MX')
|
||||||
|
|||||||
@@ -6,16 +6,19 @@
|
|||||||
from openram.sram_factory import factory
|
from openram.sram_factory import factory
|
||||||
from openram import OPTS
|
from openram import OPTS
|
||||||
from .bitcell_base_array import bitcell_base_array
|
from .bitcell_base_array import bitcell_base_array
|
||||||
|
from .pattern import pattern
|
||||||
|
from openram.base import geometry
|
||||||
|
from math import ceil
|
||||||
|
|
||||||
class row_cap_array(bitcell_base_array):
|
class row_cap_array(bitcell_base_array):
|
||||||
"""
|
"""
|
||||||
Generate a dummy row/column for the replica array.
|
Generate a dummy row/column for the replica array.
|
||||||
"""
|
"""
|
||||||
def __init__(self, rows, cols, column_offset=0, mirror=0, location="", name=""):
|
def __init__(self, rows, cols, column_offset=0, row_offset=0, mirror=0, location="", name=""):
|
||||||
super().__init__(rows=rows, cols=cols, column_offset=column_offset, name=name)
|
super().__init__(rows=rows, cols=cols, column_offset=column_offset, name=name)
|
||||||
self.mirror = mirror
|
self.mirror = mirror
|
||||||
self.location = location
|
self.location = location
|
||||||
|
self.row_offset = row_offset
|
||||||
#self.no_instances = True
|
#self.no_instances = True
|
||||||
self.create_netlist()
|
self.create_netlist()
|
||||||
if not OPTS.netlist_only:
|
if not OPTS.netlist_only:
|
||||||
@@ -33,7 +36,7 @@ class row_cap_array(bitcell_base_array):
|
|||||||
|
|
||||||
def create_layout(self):
|
def create_layout(self):
|
||||||
|
|
||||||
self.place_array("dummy_r{0}_c{1}", self.mirror)
|
self.place_array()
|
||||||
self.add_layout_pins()
|
self.add_layout_pins()
|
||||||
|
|
||||||
self.width = max([x.rx() for x in self.insts])
|
self.width = max([x.rx() for x in self.insts])
|
||||||
@@ -44,19 +47,37 @@ 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_{}".format(OPTS.bitcell))
|
self.row_cap = factory.create(module_type="row_cap_{}".format(OPTS.bitcell))
|
||||||
|
|
||||||
self.cell = factory.create(module_type=OPTS.bitcell)
|
self.cell = factory.create(module_type=OPTS.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.all_inst={}
|
||||||
for col in range(self.column_size):
|
self.cell_inst={}
|
||||||
|
|
||||||
|
bit_block = []
|
||||||
|
|
||||||
|
if self.location == "left":
|
||||||
|
#top_corner = geometry.instance("row_cap_top_corner", mod=self.top_corner, is_bitcell=False, mirror="MY")
|
||||||
|
#bottom_corner = geometry.instance("row_cap_bottom_corner", mod=self.bottom_corner, is_bitcell=False, mirror="XY")
|
||||||
|
rowend = geometry.instance("row_cap_rowend", mod=self.row_cap, is_bitcell=True, mirror="")
|
||||||
|
rowend_m = geometry.instance("row_cap_rowend_m", mod=self.row_cap, is_bitcell=True, mirror="MX")
|
||||||
|
elif self.location == "right":
|
||||||
|
#top_corner = geometry.instance("row_cap_top_corner", mod=self.top_corner, is_bitcell=False)
|
||||||
|
#bottom_corner = geometry.instance("row_cap_bottom_corner", mod=self.bottom_corner, is_bitcell=False, mirror="MX")
|
||||||
|
rowend = geometry.instance("row_cap_rowend", mod=self.row_cap, is_bitcell=True, mirror="MY")
|
||||||
|
rowend_m = geometry.instance("row_cap_rowend_m", mod=self.row_cap, is_bitcell=True, mirror="XY")
|
||||||
|
#pattern.append_row_to_block(bit_block, [top_corner])
|
||||||
for row in range(0, self.row_size):
|
for row in range(0, self.row_size):
|
||||||
name = "bit_r{0}_c{1}".format(row, col)
|
if row % 2 == 1:
|
||||||
self.cell_inst[row, col]=self.add_inst(name=name,
|
pattern.append_row_to_block(bit_block, [rowend])
|
||||||
mod=self.dummy_cell)
|
else:
|
||||||
self.connect_inst(self.get_bitcell_pins(row, col))
|
pattern.append_row_to_block(bit_block, [rowend_m])
|
||||||
|
|
||||||
|
#pattern.append_row_to_block(bit_block, [bottom_corner])
|
||||||
|
self.pattern = pattern(self, "row_cap_array_" + self.location, bit_block, num_rows=self.row_size, num_cols=self.column_size, num_cores_x=ceil(self.column_size/2), num_cores_y=ceil(self.row_size/2), name_template="row_cap_array" + self.location + "_r{0}_c{1}")
|
||||||
|
self.pattern.connect_array_raw()
|
||||||
|
|
||||||
def get_bitcell_pins(self, row, col):
|
def get_bitcell_pins(self, row, col):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -26,3 +26,4 @@ num_sim_threads = 1
|
|||||||
#analytical_delay = False
|
#analytical_delay = False
|
||||||
import os
|
import os
|
||||||
exec(open(os.path.join(os.path.dirname(__file__), 'sky130_sram_common.py')).read())
|
exec(open(os.path.join(os.path.dirname(__file__), 'sky130_sram_common.py')).read())
|
||||||
|
#tech_file = "tech_custom_cell"
|
||||||
@@ -19,8 +19,8 @@ class sky130_bitcell_array(bitcell_array, sky130_bitcell_base_array):
|
|||||||
Creates a rows x cols array of memory cells.
|
Creates a rows x cols array of memory cells.
|
||||||
Assumes bit-lines and word lines are connected by abutment.
|
Assumes bit-lines and word lines are connected by abutment.
|
||||||
"""
|
"""
|
||||||
def __init__(self, rows, cols, column_offset=0, name="",left_rbl=None, right_rbl=None):
|
def __init__(self, rows, cols, column_offset=0, row_offset=0, name="",left_rbl=None, right_rbl=None):
|
||||||
super().__init__(rows=rows, cols=cols, column_offset=column_offset, name=name)
|
super().__init__(rows=rows, cols=cols, column_offset=column_offset, row_offset=row_offset, name=name)
|
||||||
self.left_rbl = left_rbl
|
self.left_rbl = left_rbl
|
||||||
self.right_rbl = right_rbl
|
self.right_rbl = right_rbl
|
||||||
|
|
||||||
|
|||||||
@@ -15,5 +15,5 @@ sys.path.append("{}/{}".format(dir_path,'tech_configs'))
|
|||||||
|
|
||||||
if not hasattr(OPTS, 'tech_file'):
|
if not hasattr(OPTS, 'tech_file'):
|
||||||
OPTS.tech_file = 'tech_cypress_cell'
|
OPTS.tech_file = 'tech_cypress_cell'
|
||||||
#TODO: FIX THIS TERRIBLE HACK JUST FOR TESTING
|
#TODO: FIX THIS TERRIBLE HACK JUST FOR TESTING EXECUTING
|
||||||
exec('from {} import *'.format(OPTS.tech_file))
|
exec('from {} import *'.format(OPTS.tech_file))
|
||||||
|
|||||||
Reference in New Issue
Block a user