diff --git a/compiler/modules/rom_base_array.py b/compiler/modules/rom_base_array.py index 9c380624..6907d588 100644 --- a/compiler/modules/rom_base_array.py +++ b/compiler/modules/rom_base_array.py @@ -202,8 +202,8 @@ class rom_base_array(bitcell_base_array): pitch = drc["{0}_to_{0}".format(self.wordline_layer)] drain_l = self.cell_list[self.row_size][0].get_pin("D") drain_r = self.cell_list[self.row_size][self.column_size - 1].get_pin("D") - gnd_l = drain_l.center() + vector(-0.5 * self.route_width, pitch + via_width + self.route_pitch) - gnd_r = drain_r.center() + vector(0.5 * self.route_width, pitch + via_width + self.route_pitch) + gnd_l = drain_l.center() + vector(-0.5 * self.route_width, 0.5 * pitch + via_width + self.route_pitch) + gnd_r = drain_r.center() + vector(0.5 * self.route_width, 0.5 * pitch + via_width + self.route_pitch) self.add_layout_pin_rect_ends(name="gnd", layer=self.bitline_layer, start=gnd_l, end=gnd_r) @@ -310,7 +310,7 @@ class rom_base_array(bitcell_base_array): directions="nonpref") self.add_via_stack_center(offset=tap_pos, from_layer=self.active_stack[2], - to_layer=self.wordline_layer) + to_layer=self.wordline_layer, directions="nonpref") self.gnd_taps.append(self.add_layout_pin_rect_center("gnd_tap", self.wordline_layer, tap_pos)) def place_precharge(self): @@ -326,6 +326,10 @@ class rom_base_array(bitcell_base_array): def place_bitline_contacts(self): + if "li" in layer: + output_layer = "m1" + else: + output_layer = "m3" rail_y = self.precharge_inst.get_pins("vdd")[0].cy() for bl in range(self.column_size): @@ -340,9 +344,12 @@ class rom_base_array(bitcell_base_array): output_pos = vector(corrected.x, rail_y) - self.add_segment_center(self.bitline_layer, corrected, output_pos) + if output_layer != self.bitline_layer: + self.add_via_stack_center(from_layer=self.bitline_layer, to_layer=output_layer, offset=corrected) - self.add_layout_pin_rect_center(self.bitline_names[0][bl], self.bitline_layer, output_pos ) + self.add_segment_center(output_layer, corrected, output_pos) + + self.add_layout_pin_rect_center(self.bitline_names[0][bl], output_layer, output_pos ) def route_precharge(self): for bl in range(self.column_size): diff --git a/compiler/modules/rom_base_cell.py b/compiler/modules/rom_base_cell.py index 28fc07f0..2c8bf669 100644 --- a/compiler/modules/rom_base_cell.py +++ b/compiler/modules/rom_base_cell.py @@ -15,10 +15,16 @@ from openram.tech import drc class rom_base_cell(design): - def __init__(self, name="", bitline_layer="li", bit_value=1, add_well=False): + def __init__(self, name="", bitline_layer=None, bit_value=1, add_well=False): super().__init__(name) self.bit_value = bit_value - self.bitline_layer = bitline_layer + + if bitline_layer is None and OPTS.tech_name == "sky130": + self.bitline_layer = "li" + elif bitline_layer is None: + self.bitline_layer = "m1" + else: + self.bitline_layer = bitline_layer self.add_well=add_well self.create_netlist() self.create_layout() @@ -41,6 +47,7 @@ class rom_base_cell(design): # Calculates offsets of cell width and height so that tiling of cells does not violate any drc rules def setup_drc_offsets(self): + self.bitline_width = drc(f"minwidth_{self.bitline_layer}") self.poly_size = (self.cell_inst.width + self.active_space) - (self.cell_inst.height + 2 * self.poly_extend_active) def add_boundary(self): @@ -50,9 +57,7 @@ class rom_base_cell(design): #cell width with offsets applied, height becomes width when the cells are rotated width = self.cell_inst.height + 2 * self.poly_extend_active - # make the cells square so the pitch of wordlines will match bitlines - if width > height: self.width = width self.height = width @@ -62,7 +67,6 @@ class rom_base_cell(design): super().add_boundary() - def add_modules(self): self.nmos = factory.create(module_type="ptx", @@ -72,7 +76,6 @@ class rom_base_cell(design): add_drain_contact=self.bitline_layer ) - def create_tx(self): self.cell_inst = self.add_inst( name=self.name + "_nmos", mod=self.nmos, @@ -82,7 +85,6 @@ class rom_base_cell(design): else: self.connect_inst(["bl_h", "wl", "bl_l", "gnd"]) - def add_pins(self): if self.bit_value == 0 : pin_list = ["bl", "wl", "gnd"] @@ -95,10 +97,7 @@ class rom_base_cell(design): def place_tx(self): - # sizing_offset = self.cell_inst.height - drc["minwidth_tx"] tx_offset = vector(self.poly_extend_active + self.cell_inst.height + self.poly_size,- 0.5 * self.contact_width - self.active_enclose_contact) - # add rect of poly to account for offset from drc spacing - # self.add_rect_center("poly", poly_offset, self.poly_extend_active_spacing, self.poly_width) self.cell_inst.place(tx_offset, rotate=90) @@ -113,13 +112,10 @@ class rom_base_cell(design): end = poly_offset + vector(self.poly_size, 0) self.add_segment_center("poly", start, end) - def place_bitline(self): - start = self.get_pin("D").center() - end = start + vector(0, 2 * self.active_enclose_contact + 0.5 * self.contact_width + self.active_space) - self.add_segment_center(self.bitline_layer, start, end) + end = start + vector(0, 2 * self.active_enclose_contact + self.contact_width + self.active_space) + self.add_segment_center(self.bitline_layer, start, end, self.bitline_width * 2) def short_gate(self): - self.add_segment_center(self.bitline_layer, self.get_pin("D").center(), self.get_pin("S").center()) \ No newline at end of file diff --git a/compiler/modules/rom_poly_tap.py b/compiler/modules/rom_poly_tap.py index c16323b6..a9aaeb99 100644 --- a/compiler/modules/rom_poly_tap.py +++ b/compiler/modules/rom_poly_tap.py @@ -13,9 +13,9 @@ from openram.tech import drc class rom_poly_tap(design): - def __init__(self, name="", cell_name=None, tx_type="nmos", strap_layer="m2", add_active_tap=False, place_poly=None): + def __init__(self, name="", cell_name=None, tx_type="nmos", strap_layer="m2", add_active_tap=False, place_poly=False): super().__init__(name, cell_name) - self.strap_layer=strap_layer + self.strap_layer = strap_layer self.tx_type = tx_type self.add_tap = add_active_tap if place_poly is None: @@ -36,9 +36,10 @@ class rom_poly_tap(design): self.place_via() self.add_boundary() + self.extend_poly() + if self.add_tap or self.place_poly: self.place_active_tap() - self.extend_poly() def add_boundary(self): contact_width = self.poly_contact.width @@ -59,9 +60,14 @@ class rom_poly_tap(design): contact_x = contact_width * 0.5 + self.contact_x_offset self.contact_offset = vector(contact_x, contact_y) + if OPTS.tech_name == "sky130": + directions="pref" + else: + directions="nonpref" self.via = self.add_via_stack_center(from_layer="poly", to_layer=self.strap_layer, - offset=self.contact_offset) + offset=self.contact_offset, + directions=directions) self.add_layout_pin_rect_center("poly_tap", self.strap_layer, self.contact_offset) def extend_poly(self): @@ -69,8 +75,8 @@ class rom_poly_tap(design): if self.tx_type == "pmos": y_offset = -self.height start = self.via.center() + vector(0, y_offset) - - self.add_segment_center("poly", start, vector(self.via.cx() + self.pitch_offset, self.via.cy() + y_offset)) + if self.place_poly: + self.add_segment_center("poly", start, vector(self.via.cx() + self.pitch_offset, self.via.cy() + y_offset)) self.add_segment_center("poly", start, vector(0, self.via.cy() + y_offset)) def place_active_tap(self): diff --git a/compiler/modules/rom_precharge_array.py b/compiler/modules/rom_precharge_array.py index a450c968..819f14ed 100644 --- a/compiler/modules/rom_precharge_array.py +++ b/compiler/modules/rom_precharge_array.py @@ -125,7 +125,6 @@ class rom_precharge_array(design): # columns are bit lines cell_x = 0 - for col in range(self.cols): if col % self.strap_spacing == 0: @@ -136,7 +135,6 @@ class rom_precharge_array(design): cell_x += self.poly_tap.pitch_offset self.pmos_insts[col].place(vector(cell_x, cell_y)) - self.add_label("debug", "li", vector(cell_x, cell_y)) cell_x += self.pmos.width self.tap_insts[strap_num].place(vector(cell_x, cell_y + self.poly_tap.height)) @@ -150,7 +148,6 @@ class rom_precharge_array(design): self.add_layout_pin_rect_center(bl, self.bitline_layer, source_pin.center()) def route_supply(self): - self.route_horizontal_pins("vdd", insts=self.pmos_insts, layer=self.strap_layer) def connect_taps(self): diff --git a/compiler/modules/rom_precharge_cell.py b/compiler/modules/rom_precharge_cell.py index 3d4730aa..1777e507 100644 --- a/compiler/modules/rom_precharge_cell.py +++ b/compiler/modules/rom_precharge_cell.py @@ -26,7 +26,10 @@ class rom_precharge_cell(rom_base_cell): self.extend_well() def add_modules(self): - width = pgate.nearest_bin("pmos", drc["minwidth_tx"]) + if OPTS.tech_name == "sky130": + width = pgate.nearest_bin("pmos", drc["minwidth_tx"]) + else: + width = drc("minwidth_tx") self.pmos = factory.create(module_type="ptx", module_name="pre_pmos_mod", tx_type="pmos", @@ -60,8 +63,7 @@ class rom_precharge_cell(rom_base_cell): def place_tap(self): source = self.cell_inst.get_pin("S") - - tap_y = source.cy() - self.contact_width - 2 * self.active_enclose_contact - self.active_space + tap_y = source.cy() - self.contact_width - 5 * self.active_enclose_contact - self.active_space self.tap_offset = abs(tap_y) pos = vector(source.cx(), tap_y ) @@ -83,4 +85,8 @@ class rom_precharge_cell(rom_base_cell): self.remove_layout_pin("S") def place_bitline(self): + pass + + def short_gate(self): + print("not shorting") pass \ No newline at end of file