diff --git a/compiler/modules/rom_address_control_array.py b/compiler/modules/rom_address_control_array.py index e4fdf019..e6226e06 100644 --- a/compiler/modules/rom_address_control_array.py +++ b/compiler/modules/rom_address_control_array.py @@ -56,10 +56,8 @@ class rom_address_control_array(design): def create_modules(self): - self.addr_control = factory.create(module_type="rom_address_control_buf", size=self.inv_height) - # For layout constants - # self.poly_tap = factory.create(module_type="rom_poly_tap", strap_length=0) + def add_pins(self): for col in range(self.cols): diff --git a/compiler/modules/rom_address_control_buf.py b/compiler/modules/rom_address_control_buf.py index b69ccb1b..9e092ff0 100644 --- a/compiler/modules/rom_address_control_buf.py +++ b/compiler/modules/rom_address_control_buf.py @@ -41,16 +41,13 @@ class rom_address_control_buf(design): self.height = self.inv.width + 2 * self.nand.width self.setup_layout_constants() self.place_instances() - # self.place_vias() self.route_gates() self.route_sources() self.add_boundary() def create_modules(self): - # self.inv1_mod = factory.create(module_type="pinv", module_name="inv_array_end_mod", height=self.inv_size, add_wells=False) self.inv = factory.create(module_type="pinv_dec", module_name="inv_array_mod", add_wells=False, size=self.size) - # self.end_inv = factory.create(module_type="pinv", module_name="inv_array_end_mod", size=self.size, add_wells=True) self.nand = factory.create(module_type="nand2_dec", height=self.inv.height) # For layout constants self.cell = factory.create(module_type="rom_base_cell") @@ -101,7 +98,6 @@ class rom_address_control_buf(design): def route_gates(self): clk1_pin = self.addr_nand.get_pin("A") clk2_pin = self.addr_bar_nand.get_pin("A") - # self.add_label("HERE I AM", "poly", clk_pins.cl()) Abar_out = self.addr_bar_nand.get_pin("Z") A_out = self.addr_nand.get_pin("Z") diff --git a/compiler/modules/rom_base_array.py b/compiler/modules/rom_base_array.py index af9d81d4..99171450 100644 --- a/compiler/modules/rom_base_array.py +++ b/compiler/modules/rom_base_array.py @@ -115,21 +115,17 @@ class rom_base_array(bitcell_base_array): # list of current bitline interconnect nets, # starts as the same as the bitline list and is updated when new insts of cells are added self.int_bl_list = self.bitline_names[0].copy() - #When rotated correctly rows are word lines + for row in range(self.row_size + 1): row_list = [] - # for each new strap placed, offset the column index refrenced to get correct bit in the data array - # cols are bit lines for col in range(self.column_size): if col % self.strap_spacing == 0: self.create_poly_tap(row, col) new_inst = self.create_cell(row, col) - self.cell_inst[row, col] = new_inst - row_list.append(new_inst) name = "tap_r{0}_c{1}".format(row, self.array_col_size) @@ -206,8 +202,8 @@ class rom_base_array(bitcell_base_array): def place_array(self): self.cell_pos = {} self.strap_pos = {} - # rows are wordlines pitch_offset = 0 + for row in range(self.row_size + 1): if row % self.tap_spacing == 0 and self.pitch_match and row != self.row_size: @@ -228,7 +224,6 @@ class rom_base_array(bitcell_base_array): self.cell_pos[row, col] = vector(cell_x, cell_y) self.cell_inst[row, col].place(self.cell_pos[row, col]) cell_x += self.zero_cell.width - # self.add_label("debug", "li", self.cell_pos[row, col]) self.strap_pos[row, self.column_size] = vector(cell_x, cell_y) self.tap_inst[row, self.column_size].place(self.strap_pos[row, self.column_size]) @@ -338,24 +333,6 @@ class rom_base_array(bitcell_base_array): array_pins = [self.tap_list[i].get_pin("poly_tap") for i in range(len(self.tap_list))] self.connect_row_pins(layer=self.wordline_layer, pins=array_pins, name=None, round=False) - # self.connect_row_pins(layer="poly", pins=array_pins, name=None, round=False) if self.tap_direction == "col": - self.route_vertical_pins("active_tap", insts=self.tap_list, layer=self.supply_stack[0], full_width=False) - - def get_next_cell_in_bl(self, row_start, col): - for row in range(row_start + 1, self.row_size): - if self.data[row][col] == 1: - return row - return -1 - - - - def get_current_bl_interconnect(self, col): - """Get interconnect net for bitline(col) currently being connected """ - return "bli_{0}_{1}".format(self.current_row, col) - - def create_next_bl_interconnect(self, row, col): - """create a new net name for a bitline interconnect""" - self.current_row = row - return "bli_{0}_{1}".format(row, col) \ No newline at end of file + self.route_vertical_pins("active_tap", insts=self.tap_list, layer=self.supply_stack[0], full_width=False) \ No newline at end of file diff --git a/compiler/modules/rom_base_bank.py b/compiler/modules/rom_base_bank.py index a8b9f011..f8ab2eff 100644 --- a/compiler/modules/rom_base_bank.py +++ b/compiler/modules/rom_base_bank.py @@ -11,7 +11,7 @@ from openram.base import vector from openram.base import design from openram import OPTS, debug from openram.sram_factory import factory -from openram.tech import drc, layer +from openram.tech import drc, layer, parameter class rom_base_bank(design): @@ -165,7 +165,9 @@ class rom_base_bank(design): # TODO: provide technology-specific calculation of these parameters # in sky130 the address control buffer is composed of 2 size 2 NAND gates, # with a beta of 3, each of these gates has gate capacitance of 2 min sized inverters, therefor a load of 4 - addr_control_buffer_effort = 4 + + + addr_control_buffer_effort = parameter['beta'] + 1 # a single min sized nmos makes up 1/4 of the input capacitance of a min sized inverter bitcell_effort = 0.25 diff --git a/compiler/modules/rom_base_cell.py b/compiler/modules/rom_base_cell.py index b19bcd88..7663b420 100644 --- a/compiler/modules/rom_base_cell.py +++ b/compiler/modules/rom_base_cell.py @@ -23,13 +23,10 @@ class rom_base_cell(design): self.create_netlist() self.create_layout() - - def create_netlist(self): self.add_pins() self.add_modules() - def create_layout(self): self.create_tx() @@ -41,34 +38,10 @@ class rom_base_cell(design): if self.bit_value == 0: self.short_gate() - - - # Calculates offsets of cell width and height so that tiling of cells does not violate any drc rules def setup_drc_offsets(self): - - self.poly_size = (self.cell_inst.width + self.active_space) - (self.cell_inst.height + 2 * self.poly_extend_active) - #nmos contact to gate distance - self.contact_to_gate = 0.5 * (self.nmos.width - 2 * self.nmos.contact_width - self.nmos.poly_width - 2 * self.active_enclose_contact) - - #height offset to account for active-to-active spacing between adjacent bitlines - self.poly_extend_active_spacing = abs( 2 * self.nmos.poly_extend_active - drc("active_to_active") ) - - #contact to contact distance, minimum cell width before drc offsets - self.base_width = self.nmos.width - 2 * self.active_enclose_contact - self.nmos.contact_width - - #width offset to account for active-to-active spacing between cells on the same bitline - #this is calculated as a negative value - self.cell_diffusion_offset = ((self.base_width - 2 * self.active_enclose_contact - self.nmos.contact_width) - drc("active_to_active")) * 0.5 - - # width offset to account for poly-active spacing between base and dummy cells on the same bitline - self.poly_active_offset = 0.5 * (self.base_width - 2 * self.cell_diffusion_offset - (self.poly_width + 2 * self.active_enclose_contact + self.nmos.contact_width)) - self.poly_to_active - - #so that the poly taps are far enough apart - self.poly_tap_offset = (self.base_width - self.cell_diffusion_offset - self.poly_contact.width - self.poly_active_offset) - drc("poly_to_poly") - def add_boundary(self): @@ -76,8 +49,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 - # cell height with offsets applied, width becomes height when the cells are rotated, if the offsets are positive (greater than 0) they are not applied - # height = self.base_width - min(self.cell_diffusion_offset, 0) - min(self.poly_active_offset, 0) - min(self.poly_tap_offset, 0) + # make the cells square so the pitch of wordlines will match bitlines diff --git a/compiler/modules/rom_column_mux.py b/compiler/modules/rom_column_mux.py index 1830c53b..43d3bdab 100644 --- a/compiler/modules/rom_column_mux.py +++ b/compiler/modules/rom_column_mux.py @@ -30,19 +30,12 @@ class rom_column_mux(pgate): self.output_layer= output_layer super().__init__(name) - - - def get_bl_names(self): - return "bl" - - def create_netlist(self): self.add_pins() self.add_ptx() def create_layout(self): - self.pin_layer = self.input_layer self.pin_pitch = getattr(self, "{}_pitch".format(self.pin_layer)) self.pin_width = getattr(self, "{}_width".format(self.pin_layer)) @@ -54,7 +47,6 @@ class rom_column_mux(pgate): else: self.col_mux_stack = self.m1_stack - self.place_ptx() self.width = self.bitcell.width @@ -108,14 +100,6 @@ class rom_column_mux(pgate): + vector(0.5 * self.bitcell.width- 0.5 * self.nmos.active_width, 0) self.nmos_lower.place(nmos_lower_position) - # # This aligns it directly above the other tx with gates abutting - # nmos_upper_position = nmos_lower_position \ - # + vector(0, self.nmos.active_height + max(self.active_space, self.poly_space)) - # self.nmos_upper.place(nmos_upper_position) - - # if cell_props.pgate.add_implants: - # self.extend_implants() - def connect_poly(self): """ Connect the poly gate of the two pass transistors """ @@ -137,7 +121,6 @@ class rom_column_mux(pgate): """ Connect the bitlines to the mux transistors """ bl_pin = self.get_pin("bl") - # br_pin = self.get_pin("br") bl_out_pin = self.get_pin("bl_out") nmos_lower_s_pin = self.nmos_lower.get_pin("S") @@ -166,31 +149,11 @@ class rom_column_mux(pgate): self.add_path(self.output_layer, [bl_out_pin.uc(), mid1, mid2, nmos_lower_d_pin.center()]) - - - def extend_implants(self): - """ - Add top-to-bottom implants for adjacency issues in s8. - """ - # Route to the bottom - ll = (self.nmos_lower.ll() - vector(2 * [self.implant_enclose_active])).scale(1, 0) - # Don't route to the top - ur = self.nmos_upper.ur() + vector(self.implant_enclose_active, 0) - self.add_rect("nimplant", - ll, - ur.x - ll.x, - ur.y - ll.y) - def add_pn_wells(self): """ Add a well and implant over the whole cell. Also, add the pwell contact (if it exists) """ - # if(cell_props.use_strap == True and OPTS.num_ports == 1): - # strap = factory.create(module_type=cell_props.strap_module, version=cell_props.strap_version) - # rbc_width = self.bitcell.width + strap.width - # else: - # rbc_width = self.bitcell.width # Add it to the right, aligned in between the two tx active_pos = vector(self.bitcell.width, self.nmos_lower.uy() + self.active_contact.height + self.active_space) diff --git a/compiler/modules/rom_column_mux_array.py b/compiler/modules/rom_column_mux_array.py index 60e0da6b..31f6bbee 100644 --- a/compiler/modules/rom_column_mux_array.py +++ b/compiler/modules/rom_column_mux_array.py @@ -30,7 +30,6 @@ class rom_column_mux_array(design): self.words_per_row = int(self.columns / self.word_size) self.input_layer = input_layer self.tap_spacing = tap_spacing - # self.sel_layer = layer_props.column_mux_array.select_layer self.sel_layer = sel_layer self.sel_pitch = getattr(self, self.sel_layer + "_pitch") @@ -107,12 +106,6 @@ class rom_column_mux_array(design): # For every column, add a pass gate for col_num, xoffset in enumerate(self.offsets[0:self.columns]): - # if self.cell.mirror.y and (col_num + self.column_offset) % 2: - # mirror = "MY" - # xoffset = xoffset + self.mux.width - # else: - # mirror = "" - offset = vector(xoffset, self.route_height) self.mux_inst[col_num].place(offset=offset) @@ -206,11 +199,6 @@ class rom_column_mux_array(design): offset=bl_out_offset_begin, directions=self.via_directions) - - def add_taps(self): - pass - - def graph_exclude_columns(self, column_include_num): """ Excludes all columns muxes unrelated to the target bit being simulated. diff --git a/compiler/modules/rom_decoder.py b/compiler/modules/rom_decoder.py index 41b3902f..760af8c4 100644 --- a/compiler/modules/rom_decoder.py +++ b/compiler/modules/rom_decoder.py @@ -14,9 +14,10 @@ from openram.tech import drc class rom_decoder(design): def __init__(self, num_outputs, fanout, strap_spacing, name="", route_layer="m1", output_layer="m1", invert_outputs=False): - # word lines/ rows / inputs in the base array become the address lines / cols / inputs in the decoder - # bit lines / cols / outputs in the base array become the word lines / rows / outputs in the decoder - # array gets rotated 90deg so that rows/cols switch + # word lines in the base array become the address lines/cols in the decoder + # bit lines in the base array become the word lines/rows in the decoder + # array gets rotated 90deg so rows/cols switch + self.strap_spacing=strap_spacing self.num_outputs = num_outputs self.num_inputs = ceil(log(num_outputs, 2)) @@ -204,8 +205,6 @@ class rom_decoder(design): self.copy_layout_pin(self.wordline_buf_inst, "out_{}".format(j), "wl_{}".format(j)) offset = self.wordline_buf_inst.get_pin("out_{}".format(j)).center() - # self.add_via_stack_center(offset, self.output_layer, self.wordline_buf.route_layer) - array_pins = [self.array_inst.get_pin("bl_0_{}".format(bl)) for bl in range(self.num_outputs)] driver_pins = [self.wordline_buf_inst.get_pin("in_{}".format(bl)) for bl in range(self.num_outputs)] @@ -233,8 +232,6 @@ class rom_decoder(design): self.add_path(self.inv_route_layer, [addr_bar_out_pin.center(), addr_bar_middle, addr_bar_pin.center()]) self.copy_layout_pin(self.buf_inst, "A{}_in".format(i), "A{}".format(i)) - # self.add_segment_center(self.inv_route_layer, addr_bar_middle + vector(0, self.inv_route_width * 0.5), addr_bar_out_pin.center() + vector(0, self.inv_route_width * 0.5), self.inv_route_width) - def route_supplies(self): self.copy_layout_pin(self.array_inst, "vdd") diff --git a/compiler/modules/rom_poly_tap.py b/compiler/modules/rom_poly_tap.py index 7176b9e9..df698ca6 100644 --- a/compiler/modules/rom_poly_tap.py +++ b/compiler/modules/rom_poly_tap.py @@ -38,8 +38,6 @@ class rom_poly_tap(design): def add_boundary(self): contact_width = self.poly_contact.width - - # offset = self.active_space - (contact_width - self.active_enclose_contact - self.active_extend_contact) self.height = self.dummy.height self.width = contact_width + self.pitch_offset @@ -82,7 +80,6 @@ class rom_poly_tap(design): def place_active_tap(self): gap = self.poly_extend_active - 0.5 * ( self.active_contact.height - self.poly_contact.width ) offset = self.active_space - gap - # tap_x = self.via.cx() + self.contact_width + self.active_enclose_contact + self.poly_enclose_contact tap_x = self.via.cx() + offset tap_y = self.via.cy() + self.dummy.width * 0.5 contact_pos = vector(tap_x, tap_y) diff --git a/compiler/modules/rom_precharge_array.py b/compiler/modules/rom_precharge_array.py index efaa1b23..8bd1b976 100644 --- a/compiler/modules/rom_precharge_array.py +++ b/compiler/modules/rom_precharge_array.py @@ -149,8 +149,6 @@ class rom_precharge_array(design): def route_supply(self): - # self.vdd = self.add_layout_pin_segment_center("vdd", self.supply_layer, start, end) - # vdd = [self.pmos_insts[i].get_pin("vdd") for i in range(self.cols)]routeroute_horizon_horizon 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 90146d99..4489ccc9 100644 --- a/compiler/modules/rom_precharge_cell.py +++ b/compiler/modules/rom_precharge_cell.py @@ -51,20 +51,10 @@ class rom_precharge_cell(rom_base_cell): self.poly_size = (self.cell_inst.width + self.active_space) - (self.cell_inst.height + 2 * self.poly_extend_active) - #contact to contact distance, minimum cell width before drc offsets - self.base_width = self.pmos.width - 2 * self.active_enclose_contact - self.pmos.contact_width - - # width offset to account for poly-active spacing between base and dummy cells on the same bitline - self.poly_active_offset = 0.5 * (self.base_width - (self.poly_width + 2 * self.active_enclose_contact + self.pmos.contact_width)) - self.poly_to_active - - #so that the poly taps are far enough apart - self.poly_tap_offset = (self.base_width - self.poly_contact.width - self.poly_active_offset) - drc("poly_to_poly") - def extend_well(self): well_y = self.get_pin("vdd").cy() - 0.5 * self.nwell_width well_ll = vector(0, well_y) - # height = self.active_width + 2 * self.well_enclose_active height = self.get_pin("D").cy() + 0.5 * self.nwell_width - well_y self.add_rect("nwell", well_ll, self.width , height) diff --git a/compiler/modules/rom_wordline_driver_array.py b/compiler/modules/rom_wordline_driver_array.py index 7dfc2d1a..7acdaf9c 100644 --- a/compiler/modules/rom_wordline_driver_array.py +++ b/compiler/modules/rom_wordline_driver_array.py @@ -88,8 +88,6 @@ class rom_wordline_driver_array(design): """ if layer_props.wordline_driver.vertical_supply: - # self.route_vertical_pins("vdd", self.wld_inst) - # self.route_vertical_pins("gnd", self.wld_inst) self.route_vertical_pins("vdd", [self], layer=self.supply_layer) self.route_vertical_pins("gnd", [self], layer=self.supply_layer) else: