sky130 cypress dp working with offset relative to crba

This commit is contained in:
Jesse Cirimelli-Low 2026-04-27 17:24:13 -07:00
parent 3e569feebf
commit c7f3ac33cd
9 changed files with 47 additions and 39 deletions

View File

@ -13,7 +13,7 @@ SRAM_LIB_GIT_REPO ?= https://github.com/vlsida/sky130_fd_bd_sram.git
# Use this for development
#SRAM_LIB_GIT_REPO ?= git@github.com:VLSIDA/sky130_fd_bd_sram.git
#SRAM_LIB_GIT_REPO ?= https://github.com/google/skywater-pdk-libs-sky130_fd_bd_sram.git
SRAM_LIB_GIT_COMMIT ?= 3ad211667d2b7ee0d1092dcc204e6da5a2a3886c
SRAM_LIB_GIT_COMMIT ?= fc63b12883b4bf458ee8c756ba64c37063e1ffb9
SKY130_PDK ?= $(PDK_ROOT)/sky130A
GF180_PDK ?= $(PDK_ROOT)/gf180mcuD

View File

@ -64,10 +64,10 @@ class bitcell_array(bitcell_base_array):
self.cell_inst={}
if self.cell.mirror.y:
core_block = [[0 for x in range(2)] for y in range(2)]
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[(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[(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 + r) % 2][(1+c) %2] = geometry.instance(f"core_{(1 + r)%2}_{(1+c)%2}", mod=self.cell, is_bitcell=True, mirror='')
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='')
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='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='MX')
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='XY')
else:
core_block = [[0 for x in range(1)] for y in range(2)]
core_block[(0 + self.row_offset) % 2][(0+self.column_offset) %2] = geometry.instance("core_0_0", mod=self.cell, is_bitcell=True)

View File

@ -73,6 +73,8 @@ class capped_replica_bitcell_array(bitcell_base_array):
cols=self.column_size,
rows=self.row_size,
rbl=self.rbl,
column_offset=1,
row_offset=1,
left_rbl=self.left_rbl,
right_rbl=self.right_rbl)

View File

@ -65,10 +65,10 @@ class col_cap_array(bitcell_base_array):
def create_instances(self):
""" Create the module instances used in this design """
self.cell_inst={}
if self.location == "top":
if self.row_offset % 2 == 0:
bit_row = [geometry.instance("00_colend", mod=self.colend, is_bitcell=True, mirror="MY")]\
+ [geometry.instance("01_colend", mod=self.colend, is_bitcell=True)]
elif self.location == "bottom":
else:
bit_row = [geometry.instance("00_colend", mod=self.colend, is_bitcell=True, mirror="XY")]\
+ [geometry.instance("01_colend", mod=self.colend, is_bitcell=True, mirror="MX")]

View File

@ -59,10 +59,10 @@ class dummy_array(bitcell_base_array):
c = self.column_offset
if self.cell.mirror.y:
core_block = [[0 for x in range(2)] for y in range(2)]
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[(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[(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 + r) % 2][(1+c) %2] = geometry.instance(f"core_{(1 + r)%2}_{(1+c)%2}", mod=self.dummy_cell, is_bitcell=True, mirror='')
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='')
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='MY')
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='MX')
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='XY')
else:
core_block = [[0 for x in range(1)] for y in range(2)]
core_block[(0 + self.row_offset) % 2][(0+self.column_offset) %2] = geometry.instance("core_0_0", mod=self.dummy_cell, is_bitcell=True)

View File

@ -24,8 +24,8 @@ class replica_bitcell_array(bitcell_base_array):
Requires a regular bitcell array and (if using replica topology)
replica bitcell and dummy bitcell (BL/BR disconnected).
"""
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, row_offset=0)
def __init__(self, rows, cols, rbl=None, left_rbl=None, right_rbl=None, column_offset=0, row_offset=0, name=""):
super().__init__(name=name, rows=rows, cols=cols, column_offset=column_offset, row_offset=row_offset)
debug.info(1, "Creating {0} {1} x {2} rbls: {3} left_rbl: {4} right_rbl: {5}".format(self.name,
rows,
cols,
@ -35,6 +35,9 @@ class replica_bitcell_array(bitcell_base_array):
self.add_comment("rows: {0} cols: {1}".format(rows, cols))
self.add_comment("rbl: {0} left_rbl: {1} right_rbl: {2}".format(rbl, left_rbl, right_rbl))
self.column_offset=column_offset
self.row_offset=row_offset
self.column_size = cols
self.row_size = rows
# This is how many RBLs are in all the arrays
@ -76,8 +79,8 @@ class replica_bitcell_array(bitcell_base_array):
""" Array and dummy/replica columns """
# Bitcell array
self.bitcell_array = factory.create(module_type="bitcell_array",
column_offset=len(self.left_rbl)+ 1, #add 1 to account for left row_cap
row_offset=len(self.left_rbl)+1, #add 1 to account for bottom col_cap
column_offset=len(self.left_rbl)+ self.column_offset,
row_offset=len(self.left_rbl)+ self.row_offset,
cols=self.column_size,
rows=self.row_size,
left_rbl=self.left_rbl,
@ -92,18 +95,18 @@ class replica_bitcell_array(bitcell_base_array):
if port in self.left_rbl:
# These go top down starting from the bottom of the bitcell array.
replica_bit = self.rbl[0] - port - 1
column_offset = 1
rbc_offset = 0
elif port in self.right_rbl:
# These go bottom up starting from the top of the bitcell array.
replica_bit = self.rbl[0] + self.row_size + port - 1
column_offset = len(self.left_rbl) + self.column_size + 1
rbc_offset = len(self.left_rbl) + self.column_size
else:
continue
self.replica_columns[port] = factory.create(module_type="replica_column",
rows=self.row_size,
rbl=self.rbl,
column_offset=column_offset,
column_offset=rbc_offset + self.column_offset,
replica_bit=replica_bit)
# Dummy row (for replica wordlines)
@ -111,17 +114,17 @@ class replica_bitcell_array(bitcell_base_array):
for port in self.all_ports:
if port in self.left_rbl:
row_offset = 0
dummy_offset = 0
elif port in self.right_rbl:
row_offset = self.row_size + len(self.left_rbl)
dummy_offset = self.row_size + len(self.left_rbl)
else:
row_offset = 0
dummy_offset = 0
self.dummy_rows[port] = factory.create(module_type="dummy_array",
cols=self.column_size,
rows=1,
row_offset=row_offset+1, #add 1 to account for bottom col_cap
column_offset=len(self.left_rbl)+1) #add 1 to account for left row_cap
row_offset=dummy_offset + self.row_offset,
column_offset=len(self.left_rbl) + self.row_offset)
def add_pins(self):

View File

@ -94,26 +94,28 @@ class replica_column(bitcell_base_array):
# Regular array cells are replica cells
# Replic bit specifies which other bit (in the full range (0,total_size) to make a replica cell.
# All other cells are dummies
if (row == self.replica_bit) or (row >= self.row_start and row < self.row_end):
if current_row % 2 == 0:
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='MY')
else:
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, mirror='XY')
else:
if current_row % 2 == 0:
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='MY')
else:
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, mirror='XY')
current_row += 1
if self.cell.mirror.y:
for row in range(self.total_size):
if self.column_offset % 2 == 0:
if core_block[row][0].mirror=='MX':
core_block[row][0].mirror='XY'
if core_block[row][0].mirror=='MY':
core_block[row][0].mirror=''
else:
core_block[row][0].mirror='MY'
core_block[row][0].mirror='MX'
self.pattern = pattern(self, "bitcell_array", core_block, num_rows=self.total_size, num_cols=self.column_size, name_template="rbc_r{0}_c{1}")
self.pattern.connect_array()

View File

@ -19,6 +19,7 @@ class row_cap_array(bitcell_base_array):
self.mirror = mirror
self.location = location
self.row_offset = row_offset
self.column_offset = column_offset
#self.no_instances = True
self.create_netlist()
if not OPTS.netlist_only:
@ -58,19 +59,19 @@ class row_cap_array(bitcell_base_array):
bit_block = []
if self.location == "left":
if self.column_offset % 2 == 0:
#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":
rowend = geometry.instance("row_cap_rowend", mod=self.row_cap, is_bitcell=True, mirror="MX")
rowend_m = geometry.instance("row_cap_rowend_m", mod=self.row_cap, is_bitcell=True, mirror="")
else:
#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")
rowend = geometry.instance("row_cap_rowend", mod=self.row_cap, is_bitcell=True, mirror="XY")
rowend_m = geometry.instance("row_cap_rowend_m", mod=self.row_cap, is_bitcell=True, mirror="MY")
#pattern.append_row_to_block(bit_block, [top_corner])
for row in range(0, self.row_size):
if row % 2 == 1:
if row % 2 == 0:
pattern.append_row_to_block(bit_block, [rowend])
else:
pattern.append_row_to_block(bit_block, [rowend_m])

View File

@ -95,7 +95,7 @@ cell_properties.bitcell_1port.gnd_dir = "H"
cell_properties.bitcell_2port.mirror.x = True
cell_properties.bitcell_2port.mirror.y = True
cell_properties.bitcell_2port.end_caps = True
cell_properties.bitcell_2port.has_corners = True
cell_properties.bitcell_2port.has_corners = False
cell_properties.bitcell_2port.port_order = ['bl0', 'br0', 'bl1', 'br1', 'wl0', 'wl1', 'vdd', 'gnd']
cell_properties.bitcell_2port.port_map = {'bl0': 'BL0',
'br0': 'BR0',