diff --git a/compiler/modules/base_array.py b/compiler/modules/base_array.py index 40481c59..08a52c21 100644 --- a/compiler/modules/base_array.py +++ b/compiler/modules/base_array.py @@ -13,13 +13,14 @@ class bitcell_base_array(design.design): """ Abstract base class for bitcell-arrays -- bitcell, dummy """ - def __init__(self, cols, rows, name): + def __init__(self, cols, rows, name, column_offset): design.design.__init__(self, name) debug.info(1, "Creating {0} {1} x {2}".format(self.name, rows, cols)) self.add_comment("rows: {0} cols: {1}".format(rows, cols)) self.column_size = cols self.row_size = rows + self.column_offset = column_offset def add_pins(self): row_list = self.cell.get_all_wl_names() @@ -82,6 +83,23 @@ class bitcell_base_array(design.design): for pin in inst.get_pins(pin_name): self.add_power_pin(name=pin_name, loc=pin.center(), vertical=True, start_layer=pin.layer) + def _adjust_x_offset(self, xoffset, col, col_offset): + tempx = xoffset + dir_y = False + # If we mirror the current cell on the y axis adjust the x position + if cell_properties.bitcell.mirror.y and (col + col_offset) % 2: + tempx = xoffset + self.cell.width + dir_y = True + return (tempx, dir_y) + + def _adjust_y_offset(self, yoffset, row, row_offset): + tempy = yoffset + dir_x = False + # If we mirror the current cell on the x axis adjust the y position + if cell_properties.bitcell.mirror.x and (row + row_offset) % 2: + tempy = yoffset + self.cell.height + dir_x = True + return (tempy, dir_x) def place_array(self, name_template, row_offset=0): @@ -92,16 +110,22 @@ class bitcell_base_array(design.design): xoffset = 0.0 for col in range(self.column_size): yoffset = 0.0 + tempx, dir_y = self._adjust_x_offset(xoffset, col, self.column_offset) + for row in range(self.row_size): name = name_template.format(row, col) - if cell_properties.bitcell.mirror.x and (row + row_offset) % 2: - tempy = yoffset + self.cell.height + tempy, dir_x = self._adjust_y_offset(yoffset, row, row_offset) + + if dir_x and dir_y: + dir_key = "XY" + elif dir_x: dir_key = "MX" + elif dir_y: + dir_key = "MY" else: - tempy = yoffset dir_key = "" - self.cell_inst[row,col].place(offset=[xoffset, tempy], + self.cell_inst[row,col].place(offset=[tempx, tempy], mirror=dir_key) yoffset += self.cell.height xoffset += self.cell.width diff --git a/compiler/modules/bitcell_array.py b/compiler/modules/bitcell_array.py index 4c1c798b..636408df 100644 --- a/compiler/modules/bitcell_array.py +++ b/compiler/modules/bitcell_array.py @@ -20,8 +20,8 @@ class bitcell_array(bitcell_base_array): and word line is connected by abutment. Connects the word lines and bit lines. """ - def __init__(self, cols, rows, name): - super().__init__(cols, rows, name) + def __init__(self, cols, rows, name, column_offset=0): + super().__init__(cols, rows, name, column_offset) self.create_netlist() if not OPTS.netlist_only: diff --git a/compiler/modules/dummy_array.py b/compiler/modules/dummy_array.py index 88717b56..997330e1 100644 --- a/compiler/modules/dummy_array.py +++ b/compiler/modules/dummy_array.py @@ -16,8 +16,8 @@ class dummy_array(bitcell_base_array): """ Generate a dummy row/column for the replica array. """ - def __init__(self, cols, rows, mirror=0, name=""): - super().__init__(cols, rows, name) + def __init__(self, cols, rows, column_offset=0, mirror=0, name=""): + super().__init__(cols, rows, name, column_offset) self.mirror = mirror self.create_netlist() diff --git a/compiler/modules/replica_bitcell_array.py b/compiler/modules/replica_bitcell_array.py index 74962ba2..9cf5c5a2 100644 --- a/compiler/modules/replica_bitcell_array.py +++ b/compiler/modules/replica_bitcell_array.py @@ -86,6 +86,7 @@ class replica_bitcell_array(design.design): # Bitcell array self.bitcell_array = factory.create(module_type="bitcell_array", + column_offset=1 + self.left_rbl, cols=self.column_size, rows=self.row_size) self.add_mod(self.bitcell_array) @@ -95,12 +96,17 @@ class replica_bitcell_array(design.design): for bit in range(self.left_rbl+self.right_rbl): if bit=self.total_size-right_rbl-1, @@ -96,14 +98,31 @@ class replica_column(design.design): # Flip the mirrors if we have an odd number of replica+dummy rows at the bottom # so that we will start with mirroring rather than not mirroring rbl_offset = (self.left_rbl+1)%2 - + + # if our bitcells are mirrored on the y axis, check if we are in global + # column that needs to be flipped. + dir_y = False + xoffset = 0 + if cell_properties.bitcell.mirror.y and self.column_offset % 2: + dir_y = True + xoffset = self.replica_cell.width + for row in range(self.total_size): + dir_x = False name = "bit_r{0}_{1}".format(row,"rbl") - offset = vector(0,self.cell.height*(row+(row+rbl_offset)%2)) if cell_properties.bitcell.mirror.x and (row+rbl_offset)%2: + dir_x = True + + offset = vector(xoffset,self.cell.height*(row+(row+rbl_offset)%2)) + + if dir_x and dir_y: + dir_key = "XY" + elif dir_x: dir_key = "MX" + elif dir_y: + dir_key = "MY" else: - dir_key = "R0" + dir_key = "" self.cell_inst[row].place(offset=offset, mirror=dir_key)