diff --git a/Makefile b/Makefile index 90707053..d64c41b6 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/compiler/modules/bitcell_array.py b/compiler/modules/bitcell_array.py index e2292df5..c2948059 100644 --- a/compiler/modules/bitcell_array.py +++ b/compiler/modules/bitcell_array.py @@ -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) diff --git a/compiler/modules/capped_replica_bitcell_array.py b/compiler/modules/capped_replica_bitcell_array.py index c255f0d3..d87ad247 100644 --- a/compiler/modules/capped_replica_bitcell_array.py +++ b/compiler/modules/capped_replica_bitcell_array.py @@ -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) diff --git a/compiler/modules/col_cap_array.py b/compiler/modules/col_cap_array.py index dffe9459..0d60dc57 100644 --- a/compiler/modules/col_cap_array.py +++ b/compiler/modules/col_cap_array.py @@ -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")] diff --git a/compiler/modules/dummy_array.py b/compiler/modules/dummy_array.py index 85970e6f..b6b72913 100644 --- a/compiler/modules/dummy_array.py +++ b/compiler/modules/dummy_array.py @@ -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) diff --git a/compiler/modules/replica_bitcell_array.py b/compiler/modules/replica_bitcell_array.py index e338a48b..433f03f5 100644 --- a/compiler/modules/replica_bitcell_array.py +++ b/compiler/modules/replica_bitcell_array.py @@ -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): diff --git a/compiler/modules/replica_column.py b/compiler/modules/replica_column.py index 855def17..d3790050 100644 --- a/compiler/modules/replica_column.py +++ b/compiler/modules/replica_column.py @@ -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() diff --git a/compiler/modules/row_cap_array.py b/compiler/modules/row_cap_array.py index c4ad50ce..dc2ba951 100644 --- a/compiler/modules/row_cap_array.py +++ b/compiler/modules/row_cap_array.py @@ -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]) diff --git a/technology/sky130/tech/tech_configs/tech_cypress_cell.py b/technology/sky130/tech/tech_configs/tech_cypress_cell.py index bfc44ff5..b62bdacf 100644 --- a/technology/sky130/tech/tech_configs/tech_cypress_cell.py +++ b/technology/sky130/tech/tech_configs/tech_cypress_cell.py @@ -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',