diff --git a/compiler/base/hierarchy_layout.py b/compiler/base/hierarchy_layout.py index d33d552d..899e4806 100644 --- a/compiler/base/hierarchy_layout.py +++ b/compiler/base/hierarchy_layout.py @@ -476,6 +476,13 @@ class layout(): # debug.info(4, "instance list: " + ",".join(x.name for x in self.insts)) return self.insts[-1] + def add_existing_inst(self, inst): + self.mods.add(inst.mod) + self.inst_names.add(self.name) + self.insts.append(inst) + debug.info(3, "adding existing instance{}".format(self.insts[-1])) + return self.insts[-1] + def get_inst(self, name): """ Retrieve an instance by name """ for inst in self.insts: diff --git a/compiler/modules/bitcell_array.py b/compiler/modules/bitcell_array.py index f8d0f031..10e57747 100644 --- a/compiler/modules/bitcell_array.py +++ b/compiler/modules/bitcell_array.py @@ -10,7 +10,8 @@ from openram.tech import drc, spice from openram.sram_factory import factory from openram import OPTS from .bitcell_base_array import bitcell_base_array - +from .pattern import pattern +from openram.base import geometry, instance class bitcell_array(bitcell_base_array): """ @@ -42,7 +43,7 @@ class bitcell_array(bitcell_base_array): def create_layout(self): - self.place_array("bit_r{0}_c{1}") + self.place_array() self.add_layout_pins() @@ -56,19 +57,29 @@ class bitcell_array(bitcell_base_array): """ Add the modules used in this design """ self.cell = factory.create(module_type=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.cell) - self.connect_inst(self.get_bitcell_pins(row, col)) + # 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.cell) + # self.connect_inst(self.get_bitcell_pins(row, col)) + # + # # If it is a "core" cell, it could be trimmed for sim time + # if col>0 and col0 and row0 and col0 and row List[int]: + for row in block: + row_height = row[0].height + for inst in row: + debug.check(row_height == inst.height, "intrablock instances within the same row are different heights") + + for y in range(len(block[0])): + debug.check(all([row[y].width for row in block]), "intrablock instances within the same column are different widths") + + block_width = sum([instance.width for instance in block[0]]) + block_height = sum([row[0].height for row in block]) + + return [block_width, block_height] + + def verify_interblock_dimensions(self) -> None: + """ + Ensure the individual blocks are valid and interblock dimensions are valid + """ + debug.check(len(self.core_block) >= 1, "invalid core_block dimension: core_block rows must be >=1") + debug.check(len(self.core_block[0]) >= 1, "invalid core_block dimension: core_block cols must be >=1") + if self.x_block and self.y_block: + debug.check(self.xy_block is not None, "must have xy_block if both x_block and y_block are provided") + + + (self.core_block_width, self.core_block_height) = self.compute_and_verify_intrablock_dimensions(self.core_block) + if self.x_block: + (self.x_block_width, self.x_block_height) = self.compute_and_verify_intrablock_dimensions(self.x_block) + if self.y_block: + (self.y_block_width, self.y_block_height) = self.compute_and_verify_intrablock_dimensions(self.y_block) + if self.xy_block: + (self.xy_block_width, self.xy_block_height) = self.compute_and_verify_intrablock_dimensions(self.xy_block) + if(self.x_block): + debug.check(self.core_block_width * self.cores_per_x_block == self.x_block_width, "core_block does not align with x_block") + if(self.y_block): + debug.check(self.core_block_height * self.cores_per_y_block == self.y_block_height, "core_block does not aligns with y_block") + if(self.xy_block): + debug.check(self.xy_block_height == self.x_block_height, "xy_block does not align with x_block") + debug.check(self.xy_block_width == self.y_block_width, "xy_block does not align with y_block") + + def place_block(self, block: block, x: float, y: float, x_count: int, y_count: int) -> None: + return + + + def connect_block(self, block: block, x: int, y: int) -> None: + for dy in range(len(block)): + for dx in range(len(block[0])): + inst = block[dy][dx] + print(inst.name) + self.parent_design.cell_inst[x + dx, y + dy] = self.parent_design.add_existing_inst(inst) + self.parent_design.connect_inst(self.parent_design.get_bitcell_pins(x+dx, y+dy)) + + + def connect_array(self) -> None: + x = 0 + y = 0 + self.connect_block(self.core_block, x,y) + + + def place_array(self) -> None: + + array_x = 0 + array_y = 0 + # if(self.initial_x_block and self.initial_y_block): + # self.place_block(array, self.xy_block, array_x, array_y) + # array_x += self.xy_block_width + # if(self.initial_x_block): + # self.place_block(array, self.xy_block, array_x, array_y) + # array_x += self.x_block_width + self.connect_array() + self.place_block(self.core_block, array_x, array_y, 0, 0) + + + def connect_pins(self, array: design) -> None: + array.connect_isnt() +