From af0209ec96286022ce14276de9da936164723405 Mon Sep 17 00:00:00 2001 From: Jacob Walker Date: Tue, 28 Feb 2023 21:10:52 -0800 Subject: [PATCH] passing code style --- compiler/base/hierarchy_layout.py | 4 +- compiler/modules/pinvbuf.py | 6 +- compiler/modules/rom_address_control_array.py | 4 +- compiler/modules/rom_address_control_buf.py | 5 - compiler/modules/rom_base_array.py | 61 ++++----- compiler/modules/rom_base_bank.py | 118 +++++++++--------- compiler/modules/rom_base_cell.py | 40 +++--- compiler/modules/rom_column_mux.py | 2 +- compiler/modules/rom_column_mux_array.py | 10 +- compiler/modules/rom_control_logic.py | 24 ++-- compiler/modules/rom_decoder.py | 28 ++--- compiler/modules/rom_poly_tap.py | 8 +- compiler/modules/rom_precharge_array.py | 14 +-- compiler/modules/rom_precharge_cell.py | 14 +-- compiler/modules/rom_wordline_driver_array.py | 4 +- compiler/tests/05_rom_base_bank_2kB_test.py | 2 +- 16 files changed, 170 insertions(+), 174 deletions(-) diff --git a/compiler/base/hierarchy_layout.py b/compiler/base/hierarchy_layout.py index c1227cc2..00833f77 100644 --- a/compiler/base/hierarchy_layout.py +++ b/compiler/base/hierarchy_layout.py @@ -703,7 +703,7 @@ class layout(): bins = {} for pin in pins: y = pin.cy() - if round: + if round: y = round_to_grid(y) try: bins[y].append(pin) @@ -794,7 +794,7 @@ class layout(): bins = {} for pin in pins: x = pin.cx() - if round: + if round: x = round_to_grid(x) try: bins[x].append(pin) diff --git a/compiler/modules/pinvbuf.py b/compiler/modules/pinvbuf.py index c277dd2a..c71c6da9 100644 --- a/compiler/modules/pinvbuf.py +++ b/compiler/modules/pinvbuf.py @@ -142,7 +142,7 @@ class pinvbuf(pgate): # end_point = vector(a4_pin.cx(), a4_pin.by() - self.m1_space - self.contact_space) self.add_path(route_stack[2], [z1_pin.center(), mid_point, end_point]) - + self.add_via_stack_center(from_layer=z1_pin.layer, to_layer=route_stack[2], offset=z1_pin.center()) @@ -151,11 +151,11 @@ class pinvbuf(pgate): to_layer=route_stack[2], offset=end_point) - + self.add_segment_center(a4_pin.layer, end_point, a4_pin.center()) else: # inv1 Z to inv4 A (up and over) - + mid_point = vector(z1_pin.cx(), a4_pin.cy()) self.add_wire(route_stack, [z1_pin.center(), mid_point, a4_pin.center()]) diff --git a/compiler/modules/rom_address_control_array.py b/compiler/modules/rom_address_control_array.py index e02d0443..e4fdf019 100644 --- a/compiler/modules/rom_address_control_array.py +++ b/compiler/modules/rom_address_control_array.py @@ -26,7 +26,7 @@ class rom_address_control_array(design): name = "rom_inv_array_{0}".format(cols) if inv_height == None: self.inv_height = dff.height * 0.5 - else: + else: self.inv_height = inv_height @@ -46,7 +46,7 @@ class rom_address_control_array(design): def create_layout(self): self.width = self.cols * self.addr_control.width - self.height = self.addr_control.height + self.height = self.addr_control.height self.setup_layout_constants() self.place_instances() self.route_clk() diff --git a/compiler/modules/rom_address_control_buf.py b/compiler/modules/rom_address_control_buf.py index c0950dda..b69ccb1b 100644 --- a/compiler/modules/rom_address_control_buf.py +++ b/compiler/modules/rom_address_control_buf.py @@ -130,8 +130,6 @@ class rom_address_control_buf(design): self.add_via_stack_center(from_layer=self.inv_layer, to_layer=self.route_layer, offset=self.addr_bar_nand.get_pin("A").center()) self.add_segment_center(self.route_layer, clk_offset, vector(clk_offset.x, clk2_pin.cy())) - - # Route first NAND output to second NAND input start = A_out.center() end = Aint_in.center() @@ -139,18 +137,15 @@ class rom_address_control_buf(design): self.add_via_stack_center(Aint_in.center(), self.inv_layer, "m2") self.add_via_stack_center(A_out.center(), self.inv_layer, "m2") - # Route first NAND to output pin self.add_segment_center("m2", end, vector(end.x, self.addr_bar_nand.uy())) self.add_layout_pin_rect_center("A_out", offset=vector(end.x, self.addr_bar_nand.uy() - 0.5 * self.m2_width), layer="m2") - # Route second NAND to output pin self.add_via_stack_center(Abar_out.center(), self.inv_layer, "m2") self.add_segment_center("m2", Abar_out.center(), vector(Abar_out.cx(), self.addr_bar_nand.uy())) self.add_layout_pin_rect_center("Abar_out", offset=vector(Abar_out.cx(), self.addr_bar_nand.uy() - 0.5 * self.m2_width), layer="m2") - # Route inverter output to NAND end = vector(Abar_int_out.cx(), Abar_in.cy() + 0.5 * self.interconnect_width) self.add_segment_center(self.inv_layer, Abar_int_out.center(), end) diff --git a/compiler/modules/rom_base_array.py b/compiler/modules/rom_base_array.py index c6af1470..af9d81d4 100644 --- a/compiler/modules/rom_base_array.py +++ b/compiler/modules/rom_base_array.py @@ -11,7 +11,7 @@ import math from .bitcell_base_array import bitcell_base_array from openram.base import vector from openram import OPTS -from openram.sram_factory import factory +from openram.sram_factory import factory from openram.tech import drc, layer class rom_base_array(bitcell_base_array): @@ -24,13 +24,13 @@ class rom_base_array(bitcell_base_array): self.tap_direction = tap_direction self.pitch_match = pitch_match self.bitline_layer = bitline_layer - self.strap_spacing = strap_spacing + self.strap_spacing = strap_spacing self.wordline_layer = wordline_layer self.data_col_size = self.column_size self.tap_spacing = tap_spacing if strap_spacing != 0: - self.array_col_size = self.column_size + math.ceil(self.column_size / strap_spacing) + self.array_col_size = self.column_size + math.ceil(self.column_size / strap_spacing) else: self.array_col_size = self.column_size self.create_all_bitline_names() @@ -41,7 +41,7 @@ class rom_base_array(bitcell_base_array): def create_netlist(self): self.add_modules() self.add_pins() - + self.create_cell_instances() self.create_precharge_inst() @@ -68,28 +68,28 @@ class rom_base_array(bitcell_base_array): ur = vector(ur.x, ur.y - self.m1_width) super().add_boundary(vector(0, 0), ur) self.width = ur.x - self.height = ur.y - + self.height = ur.y + def add_modules(self): - self.zero_cell = factory.create(module_name="rom_base_zero_cell", - module_type="rom_base_cell", - bitline_layer=self.bitline_layer, + self.zero_cell = factory.create(module_name="rom_base_zero_cell", + module_type="rom_base_cell", + bitline_layer=self.bitline_layer, bit_value=0) - self.one_cell = factory.create(module_name="rom_base_one_cell", - module_type="rom_base_cell", - bitline_layer=self.bitline_layer, + self.one_cell = factory.create(module_name="rom_base_one_cell", + module_type="rom_base_cell", + bitline_layer=self.bitline_layer, bit_value=1) if self.tap_direction == "row": - self.poly_tap = factory.create(module_type="rom_poly_tap") - else: + self.poly_tap = factory.create(module_type="rom_poly_tap") + else: self.poly_tap = factory.create(module_type="rom_poly_tap", add_tap=True) - self.precharge_array = factory.create(module_type="rom_precharge_array", - cols=self.column_size, - strap_spacing=self.strap_spacing, - route_layer=self.bitline_layer, + self.precharge_array = factory.create(module_type="rom_precharge_array", + cols=self.column_size, + strap_spacing=self.strap_spacing, + route_layer=self.bitline_layer, strap_layer=self.wordline_layer, tap_direction=self.tap_direction) @@ -112,7 +112,8 @@ class rom_base_array(bitcell_base_array): self.cell_inst = {} self.cell_list = [] self.current_row = 0 - #list of current bitline interconnect nets, starts as the same as the bitline list and is updated when new insts of cells are added + # 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): @@ -126,7 +127,7 @@ class rom_base_array(bitcell_base_array): 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) @@ -151,7 +152,7 @@ class rom_base_array(bitcell_base_array): # when col = 0, bl_h is connected to precharge, otherwise connect to previous bl connection # when col = col_size - 1 connected column_sizeto gnd otherwise create new bl connection - if row == self.row_size : + if row == self.row_size: bl_l = self.int_bl_list[col] bl_h = "gnd" @@ -168,16 +169,16 @@ class rom_base_array(bitcell_base_array): self.connect_inst([bl_h, bl_l, "precharge", "gnd"]) elif self.data[row][col] == 1: new_inst = self.add_inst(name=name, mod=self.one_cell) - self.connect_inst([bl_h, bl_l, self.wordline_names[0][row], "gnd"]) - else: + self.connect_inst([bl_h, bl_l, self.wordline_names[0][row], "gnd"]) + else: new_inst = self.add_inst(name=name, mod=self.zero_cell) self.connect_inst([bl_h, self.wordline_names[0][row], "gnd"]) - return new_inst + return new_inst def create_precharge_inst(self): prechrg_pins = self.bitline_names[0].copy() - + prechrg_pins.append("precharge") prechrg_pins.append("vdd") self.precharge_inst = self.add_inst(name="bitcell_array_precharge", mod=self.precharge_array) @@ -215,14 +216,14 @@ class rom_base_array(bitcell_base_array): cell_y = row * (self.zero_cell.height) + pitch_offset cell_x = 0 - for col in range(self.column_size): + for col in range(self.column_size): if col % self.strap_spacing == 0: self.strap_pos[row, col] = vector(cell_x, cell_y) self.tap_inst[row, col].place(self.strap_pos[row, col]) if self.tap_direction == "col": - cell_x += self.poly_tap.pitch_offset + cell_x += self.poly_tap.pitch_offset self.cell_pos[row, col] = vector(cell_x, cell_y) self.cell_inst[row, col].place(self.cell_pos[row, col]) @@ -247,7 +248,7 @@ class rom_base_array(bitcell_base_array): end = drain.center() self.add_segment_center(self.bitline_layer, start, end) self.place_well_tap(row, col) - + def place_well_tap(self, row, col): cell = self.cell_inst[row, col] source = cell.get_pin("S") @@ -271,7 +272,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) self.add_layout_pin_rect_center("gnd", self.wordline_layer, tap_pos) def place_precharge(self): @@ -279,7 +280,7 @@ class rom_base_array(bitcell_base_array): self.precharge_inst.place(offset=self.precharge_offset) self.copy_layout_pin(self.precharge_inst, "vdd") self.copy_layout_pin(self.precharge_inst, "gate", "precharge") - + def place_wordline_contacts(self): for wl in range(self.row_size): diff --git a/compiler/modules/rom_base_bank.py b/compiler/modules/rom_base_bank.py index f3d4a506..a8b9f011 100644 --- a/compiler/modules/rom_base_bank.py +++ b/compiler/modules/rom_base_bank.py @@ -30,7 +30,7 @@ class rom_base_bank(design): self.num_inputs = ceil(log(self.rows, 2)) self.col_bits = ceil(log(self.words_per_row, 2)) self.row_bits = self.num_inputs - + # self.data = [[0, 1, 0, 1], [1, 1, 1, 1], [1, 1, 0, 0], [0, 0, 1, 0]] self.strap_spacing = strap_spacing self.tap_spacing = 8 @@ -38,7 +38,7 @@ class rom_base_bank(design): self.bitline_layer = "m1" self.wordline_layer = "m2" - + if "li" in layer: self.route_stack = self.m1_stack else: @@ -52,7 +52,7 @@ class rom_base_bank(design): Reads a hexadecimal file from a given directory to be used as the data written to the ROM endian is either "big" or "little" word_size is the number of bytes per word - sets the row and column size based on the size of binary input, tries to keep array as square as possible, + sets the row and column size based on the size of binary input, tries to keep array as square as possible, """ def read_binary(self, data_file, word_size=2, endian="big", scramble_bits=False): @@ -70,7 +70,7 @@ class rom_base_bank(design): bin_data = [int(x) for x in bin_data] # data size in bytes - data_size = len(bin_data) / 8 + data_size = len(bin_data) / 8 num_words = int(data_size / word_size) bytes_per_col = sqrt(num_words) @@ -88,11 +88,11 @@ class rom_base_bank(design): if len(row_data) < bits_per_row: row_data = [0] * (bits_per_row - len(row_data)) + row_data chunked_data.append(row_data) - - + + # if endian == "big": - - + + self.data = chunked_data if scramble_bits: scrambled_chunked = [] @@ -104,9 +104,9 @@ class rom_base_bank(design): scambled_data.append(row_data[bit + word * self.word_size]) scrambled_chunked.append(scambled_data) self.data = scrambled_chunked - - - + + + # self.data.reverse() debug.info(1, "Read rom binary: length {0} bytes, {1} words, set number of cols to {2}, rows to {3}, with {4} words per row".format(data_size, num_words, self.cols, self.rows, self.words_per_row)) @@ -117,7 +117,7 @@ class rom_base_bank(design): self.add_pins() - + def create_layout(self): self.create_instances() self.place_instances() @@ -144,7 +144,7 @@ class rom_base_bank(design): self.interconnect_layer_pitch = drc["{0}_to_{0}".format(self.interconnect_layer)] def add_pins(self): - + self.add_pin("clk", "INPUT") self.add_pin("CS", "INPUT") @@ -163,59 +163,59 @@ class rom_base_bank(design): def add_modules(self): # TODO: provide technology-specific calculation of these parameters - # in sky130 the address control buffer is composed of 2 size 2 NAND gates, + # 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 # a single min sized nmos makes up 1/4 of the input capacitance of a min sized inverter bitcell_effort = 0.25 - # Takes into account inverter sizing + # Takes into account inverter sizing wordline_effort = bitcell_effort * 0.5 # a single min sized pmos plus a single min sized nmos have approximately half the gate capacitance of a min inverter # an additional 0.2 accounts for the long wire capacitance and add delay to gaurentee the read timing precharge_cell_effort = 0.5 + 0.2 - self.array = factory.create(module_type="rom_base_array", - cols=self.cols, - rows=self.rows, - strap_spacing=self.strap_spacing, - bitmap=self.data, + self.array = factory.create(module_type="rom_base_array", + cols=self.cols, + rows=self.rows, + strap_spacing=self.strap_spacing, + bitmap=self.data, bitline_layer=self.bitline_layer, wordline_layer=self.wordline_layer, pitch_match=True, - tap_spacing=self.tap_spacing) - - - self.decode_array = factory.create(module_name="rom_row_decode", - module_type="rom_decoder", - num_outputs=self.rows, - strap_spacing=self.strap_spacing, - route_layer=self.route_layer, + tap_spacing=self.tap_spacing) + + + self.decode_array = factory.create(module_name="rom_row_decode", + module_type="rom_decoder", + num_outputs=self.rows, + strap_spacing=self.strap_spacing, + route_layer=self.route_layer, fanout=(self.cols)*wordline_effort ) - - self.column_mux = factory.create(module_type="rom_column_mux_array", + + self.column_mux = factory.create(module_type="rom_column_mux_array", columns=self.cols, word_size=self.word_size, tap_spacing=self.strap_spacing, bitline_layer=self.interconnect_layer, input_layer=self.bitline_layer) - + self.column_decode = factory.create(module_name="rom_column_decode", - module_type="rom_decoder", - num_outputs=self.words_per_row, - strap_spacing=self.strap_spacing, - route_layer=self.route_layer, + module_type="rom_decoder", + num_outputs=self.words_per_row, + strap_spacing=self.strap_spacing, + route_layer=self.route_layer, fanout=2, invert_outputs=True ) - self.control_logic = factory.create(module_type="rom_control_logic", + self.control_logic = factory.create(module_type="rom_control_logic", num_outputs=(self.cols + self.words_per_row * precharge_cell_effort) \ - + (addr_control_buffer_effort * self.col_bits), + + (addr_control_buffer_effort * self.col_bits), clk_fanout=(self.row_bits * addr_control_buffer_effort) + (precharge_cell_effort * self.rows), height=self.column_decode.height ) - + self.bitline_inv = factory.create(module_type="rom_wordline_driver_array", module_name="rom_bitline_inverter", rows=self.cols, @@ -247,7 +247,7 @@ class rom_base_bank(design): bitline_bar = ["bl_b_{}".format(bl) for bl in range(self.cols)] pre_buf_outputs = ["rom_out_prebuf_{}".format(bit) for bit in range(self.word_size)] outputs = ["rom_out_{}".format(bl) for bl in range(self.word_size)] - + array_pins = bitlines + wordlines + prechrg + vdd + gnd @@ -283,7 +283,7 @@ class rom_base_bank(design): - + def place_instances(self): self.place_row_decoder() self.place_data_array() @@ -297,10 +297,10 @@ class rom_base_bank(design): def place_row_decoder(self): self.decode_offset = vector(0, self.control_inst.height ) self.decode_inst.place(offset=self.decode_offset) - + def place_data_array(self): # We approximate the correct position for the array - array_x = self.decode_inst.width + (2) * ( self.route_layer_width + self.route_layer_pitch ) + array_x = self.decode_inst.width + (2) * ( self.route_layer_width + self.route_layer_pitch ) array_y = self.decode_array.buf_inst.height - self.array.precharge_inst.cy() - self.array.zero_cell.height * 0.5 self.array_offset = vector(array_x ,array_y) self.array_inst.place(offset=self.array_offset) @@ -308,7 +308,7 @@ class rom_base_bank(design): # now move array to correct alignment with decoder array_align = self.decode_inst.get_pin("wl_0").cy() - self.array_inst.get_pin("wl_0_0").cy() self.array_inst.place(offset=(self.array_offset + vector(0, array_align))) - + def place_bitline_inverter(self): self.bitline_inv_inst.place(offset=[0,0], rotate=90) inv_y_offset = self.array_inst.by() - self.bitline_inv_inst.width - 2 * self.m1_pitch @@ -316,14 +316,14 @@ class rom_base_bank(design): inv_x_offset = self.array_inst.get_pin("bl_0_0").cx() - self.bitline_inv_inst.get_pin("out_0").cx() self.inv_offset = vector(inv_x_offset, inv_y_offset) self.bitline_inv_inst.place(offset=self.inv_offset, rotate=90) - + def place_control_logic(self): self.control_offset = vector(self.col_decode_inst.lx() - self.control_inst.width - 3 * self.m1_pitch, self.decode_inst.by() - self.control_logic.height - self.m1_pitch) self.control_inst.place(offset=self.control_offset) def place_col_decoder(self): - col_decode_y = self.mux_inst.get_pin("sel_0").cy() - self.col_decode_inst.get_pin("wl_0").cy() + col_decode_y = self.mux_inst.get_pin("sel_0").cy() - self.col_decode_inst.get_pin("wl_0").cy() self.col_decode_offset = vector(self.decode_inst.width - self.col_decode_inst.width, col_decode_y) self.col_decode_inst.place(offset=self.col_decode_offset) @@ -333,13 +333,13 @@ class rom_base_bank(design): mux_x_offset = self.bitline_inv_inst.get_pin("out_0").cx() - self.mux_inst.get_pin("bl_0").cx() self.mux_offset = vector(mux_x_offset, mux_y_offset) self.mux_inst.place(offset=self.mux_offset) - + def place_output_buffer(self): - output_x = self.col_decode_inst.rx() + self.output_inv_inst.height + output_x = self.col_decode_inst.rx() + self.output_inv_inst.height output_y = self.mux_inst.by() - self.word_size * self.m1_pitch self.output_inv_offset = vector(output_x, output_y) self.output_inv_inst.place(offset=self.output_inv_offset, rotate=270) - + def route_decode_outputs(self): # for the row decoder route_pins = [self.array_inst.get_pin("wl_0_{}".format(wl)) for wl in range(self.rows)] @@ -369,11 +369,11 @@ class rom_base_bank(design): self.add_segment_center(self.interconnect_layer, start, end) - + def route_precharge(self): prechrg_control = self.control_inst.get_pin("prechrg") - + col_decode_prechrg = self.col_decode_inst.get_pin("precharge_r") col_decode_clk = self.col_decode_inst.get_pin("clk") array_prechrg = self.array_inst.get_pin("precharge") @@ -401,19 +401,19 @@ class rom_base_bank(design): self.add_via_stack_center(from_layer=self.route_stack[0], to_layer=col_decode_prechrg.layer, offset=end) - + start = mid1 mid1 = vector(self.control_inst.rx(), start.y) mid2 = vector(mid1.x, col_decode_clk.cy()) end = col_decode_clk.center() self.add_path(self.route_stack[0], [start, mid1, mid2, end]) - # self.add_segment_center(col_decode_prechrg.layer, end, col_decode_prechrg.center()) + # self.add_segment_center(col_decode_prechrg.layer, end, col_decode_prechrg.center()) # Route precharge to main array # end = vector(col_decode_prechrg.cx(), array_prechrg.cy()) mid = vector(col_decode_prechrg.cx(), array_prechrg.cy() ) - self.add_path(self.route_stack[0], [array_prechrg.center(), mid, col_decode_prechrg.center()]) + self.add_path(self.route_stack[0], [array_prechrg.center(), mid, col_decode_prechrg.center()]) def route_clock(self): @@ -423,8 +423,8 @@ class rom_base_bank(design): self.add_via_stack_center(from_layer=self.route_stack[2], to_layer=clk_out.layer, offset=clk_out.center()) - - # Route clock to row decoder + + # Route clock to row decoder mid = vector(self.control_inst.rx() + self.m1_pitch, clk_out.cy()) addr_control_clk = row_decode_clk.rc() + vector( 2 * self.route_layer_pitch + self.route_layer_width, 0) @@ -474,7 +474,7 @@ class rom_base_bank(design): - + def place_top_level_pins(self): self.copy_layout_pin(self.control_inst, "CS") self.copy_layout_pin(self.control_inst, "clk_in", "clk") @@ -487,10 +487,10 @@ class rom_base_bank(design): for msb in range(self.col_bits, self.row_bits + self.col_bits): name = "addr_{}".format(msb) - pin_num = msb - self.col_bits + pin_num = msb - self.col_bits self.copy_layout_pin(self.decode_inst, "A{}".format(pin_num), name) - - + + def route_supplies(self): diff --git a/compiler/modules/rom_base_cell.py b/compiler/modules/rom_base_cell.py index efe9e40f..b19bcd88 100644 --- a/compiler/modules/rom_base_cell.py +++ b/compiler/modules/rom_base_cell.py @@ -23,15 +23,15 @@ class rom_base_cell(design): self.create_netlist() self.create_layout() - - def create_netlist(self): + + def create_netlist(self): self.add_pins() self.add_modules() - - + + def create_layout(self): - + self.create_tx() self.setup_drc_offsets() self.add_boundary() @@ -41,22 +41,22 @@ 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) + 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 + #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 @@ -66,19 +66,19 @@ class rom_base_cell(design): # 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 + #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): height = self.cell_inst.width + self.active_space - #cell width with offsets applied, height becomes width when the cells are rotated + #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 if width > height: @@ -87,10 +87,10 @@ class rom_base_cell(design): else: self.width = height self.height = height - + super().add_boundary() - + def add_modules(self): self.nmos = factory.create(module_type="ptx", @@ -103,14 +103,14 @@ class rom_base_cell(design): def create_tx(self): self.cell_inst = self.add_inst( name=self.name + "_nmos", - mod=self.nmos, + mod=self.nmos, ) if self.bit_value == 0: self.connect_inst(["bl", "wl", "bl", "gnd"]) else: self.connect_inst(["bl_h", "wl", "bl_l", "gnd"]) - + def add_pins(self): if self.bit_value == 0 : pin_list = ["bl", "wl", "gnd"] @@ -119,7 +119,7 @@ class rom_base_cell(design): pin_list = ["bl_h", "bl_l", "wl", "gnd"] dir_list = ["INOUT", "INOUT", "INPUT", "GROUND"] - self.add_pin_list(pin_list, dir_list) + self.add_pin_list(pin_list, dir_list) def place_tx(self): @@ -127,7 +127,7 @@ class rom_base_cell(design): 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) # self.add_label("CELL ZERO", self.route_layer) self.copy_layout_pin(self.cell_inst, "S", "S") diff --git a/compiler/modules/rom_column_mux.py b/compiler/modules/rom_column_mux.py index 85fe8489..1830c53b 100644 --- a/compiler/modules/rom_column_mux.py +++ b/compiler/modules/rom_column_mux.py @@ -42,7 +42,7 @@ class rom_column_mux(pgate): 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)) diff --git a/compiler/modules/rom_column_mux_array.py b/compiler/modules/rom_column_mux_array.py index 856eea71..60e0da6b 100644 --- a/compiler/modules/rom_column_mux_array.py +++ b/compiler/modules/rom_column_mux_array.py @@ -54,14 +54,14 @@ class rom_column_mux_array(design): self.setup_layout_constants() self.place_array() self.add_routing() - + # Find the highest shapes to determine height before adding well highest = self.find_highest_coords() self.height = highest.y self.add_layout_pins() if "pwell" in layer: self.add_enclosure(self.mux_inst, "pwell") - + self.add_boundary() self.DRC_LVS() @@ -154,7 +154,7 @@ class rom_column_mux_array(design): def add_vertical_poly_rail(self): """ Connect the poly to the address rails """ - + # Offset to the first transistor gate in the pass gate for col in range(self.columns): # which select bit should this column connect to depends on the position in the word @@ -209,8 +209,8 @@ class rom_column_mux_array(design): 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_control_logic.py b/compiler/modules/rom_control_logic.py index a469b184..af8b81a0 100644 --- a/compiler/modules/rom_control_logic.py +++ b/compiler/modules/rom_control_logic.py @@ -25,7 +25,7 @@ class rom_control_logic(design): self.gate_height = 20 * self.m1_pitch self.driver_height = self.gate_height - + self.clk_fanout = clk_fanout if "li" in layer: @@ -49,21 +49,21 @@ class rom_control_logic(design): self.route_insts() def add_modules(self): - self.buf_mod = factory.create(module_type="pdriver", - module_name="rom_clock_driver", + self.buf_mod = factory.create(module_type="pdriver", + module_name="rom_clock_driver", height=self.gate_height, fanout=self.clk_fanout + 2, add_wells=True, ) - self.nand_mod = factory.create(module_type="pnand2", - module_name="rom_control_nand", - height=self.gate_height, + self.nand_mod = factory.create(module_type="pnand2", + module_name="rom_control_nand", + height=self.gate_height, add_wells=False) - self.driver_mod = factory.create(module_type="pdriver", - module_name="rom_precharge_driver", - inverting=True, - fanout=self.output_size, - height=self.driver_height, + self.driver_mod = factory.create(module_type="pdriver", + module_name="rom_precharge_driver", + inverting=True, + fanout=self.output_size, + height=self.driver_height, add_wells=True) def add_pins(self): @@ -75,7 +75,7 @@ class rom_control_logic(design): self.add_pin("gnd", "GROUND") def create_instances(self): - + self.buf_inst = self.add_inst(name="clk_driver", mod=self.buf_mod) self.connect_inst(["clk_in", "clk_out", "vdd", "gnd"]) diff --git a/compiler/modules/rom_decoder.py b/compiler/modules/rom_decoder.py index fe817383..41b3902f 100644 --- a/compiler/modules/rom_decoder.py +++ b/compiler/modules/rom_decoder.py @@ -21,7 +21,7 @@ class rom_decoder(design): self.num_outputs = num_outputs self.num_inputs = ceil(log(num_outputs, 2)) self.create_decode_map() - + super().__init__(name) b = factory.create(module_type=OPTS.bitcell) @@ -48,7 +48,7 @@ class rom_decoder(design): self.place_input_buffer() self.place_driver() self.route_outputs() - + self.connect_inputs() self.route_supplies() self.add_boundary() @@ -62,7 +62,7 @@ class rom_decoder(design): ur = vector(ur.x, ur.y) super().add_boundary(ll, ur) self.width = ur.x - self.height = ur.y + self.height = ur.y def setup_layout_constants(self): self.inv_route_width = drc["minwidth_{}".format(self.inv_route_layer)] @@ -87,7 +87,7 @@ class rom_decoder(design): else: bin_digit = int(addr[addr_idx]) - col_array.append(bin_digit) + col_array.append(bin_digit) if bin_digit == 0 : inv_col_array.append(1) else : inv_col_array.append(0) @@ -109,19 +109,19 @@ class rom_decoder(design): def add_modules(self): - self.control_array = factory.create(module_type="rom_address_control_array", + self.control_array = factory.create(module_type="rom_address_control_array", cols=self.num_inputs) - self.wordline_buf = factory.create(module_type="rom_wordline_driver_array", module_name="{}_wordline_buffer".format(self.name), - rows=self.num_outputs, + self.wordline_buf = factory.create(module_type="rom_wordline_driver_array", module_name="{}_wordline_buffer".format(self.name), + rows=self.num_outputs, fanout=ceil(self.fanout), invert_outputs=self.invert_outputs, tap_spacing=self.strap_spacing) - - self.array_mod = factory.create(module_type="rom_base_array", - module_name="{}_array".format(self.name), - cols=self.num_outputs, - rows=2 * self.num_inputs, + + self.array_mod = factory.create(module_type="rom_base_array", + module_name="{}_array".format(self.name), + cols=self.num_outputs, + rows=2 * self.num_inputs, bitmap=self.decode_map, strap_spacing = self.strap_spacing, bitline_layer=self.output_layer, @@ -190,7 +190,7 @@ class rom_decoder(design): self.array_inst.place(offset, rotate=90) def place_driver(self): - + offset = vector(self.array_inst.height + self.m1_width, self.array_inst.by()) self.wordline_buf_inst.place(offset) @@ -226,7 +226,7 @@ class rom_decoder(design): addr_bar_out_pin = self.buf_inst.get_pin("Abar{}_out".format(i)) addr_middle = vector(addr_pin.cx(), addr_out_pin.cy()) - + addr_bar_middle = vector(addr_bar_pin.cx(), addr_bar_out_pin.cy()) self.add_path(self.inv_route_layer, [addr_out_pin.center(), addr_middle, addr_pin.center()]) diff --git a/compiler/modules/rom_poly_tap.py b/compiler/modules/rom_poly_tap.py index a31b86d4..d7a1b3b2 100644 --- a/compiler/modules/rom_poly_tap.py +++ b/compiler/modules/rom_poly_tap.py @@ -37,11 +37,11 @@ class rom_poly_tap(design): self.extend_poly() def add_boundary(self): - contact_width = self.poly_contact.width + 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 + self.width = contact_width + self.pitch_offset super().add_boundary() @@ -89,7 +89,7 @@ class rom_poly_tap(design): 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 + tap_y = self.via.cy() + self.dummy.width * 0.5 contact_pos = vector(tap_x, tap_y) # edge of the next nmos @@ -105,7 +105,7 @@ class rom_poly_tap(design): implant_type="p", well_type="p", directions="nonpref") - self.add_power_pin(name="gnd", + self.add_power_pin(name="gnd", loc=contact_pos, start_layer=self.active_stack[2]) self.add_layout_pin_rect_center("active_tap", self.supply_stack[0], contact_pos) \ No newline at end of file diff --git a/compiler/modules/rom_precharge_array.py b/compiler/modules/rom_precharge_array.py index 6b5c13e9..efaa1b23 100644 --- a/compiler/modules/rom_precharge_array.py +++ b/compiler/modules/rom_precharge_array.py @@ -32,14 +32,14 @@ class rom_precharge_array(design): name = "rom_inv_array_{0}".format(cols) if strap_spacing != None: - self.strap_spacing = strap_spacing + self.strap_spacing = strap_spacing else: self.strap_spacing = 0 if strap_spacing != 0: self.num_straps = ceil(self.cols / self.strap_spacing) - self.array_col_size = self.cols + self.num_straps + self.array_col_size = self.cols + self.num_straps else: self.num_straps = 0 self.array_col_size = self.cols @@ -54,7 +54,7 @@ class rom_precharge_array(design): self.create_instances() def create_layout(self): - self.width = self.cols * self.pmos.width + self.width = self.cols * self.pmos.width self.height = self.pmos.width self.place_instances() self.create_layout_pins() @@ -70,7 +70,7 @@ class rom_precharge_array(design): self.add_label(layer="nwell", text="upper right",offset=ur) # ur = vector(ur.x, ur.y - self.well_ll.y) super().add_boundary(vector(0, 0), ur) - self.height = ur.y + self.height = ur.y self.width = ur.x def create_modules(self): @@ -118,8 +118,8 @@ class rom_precharge_array(design): self.add_label("ZERO", self.route_layer) self.array_pos = [] - strap_num = 0 - cell_y = 0 + strap_num = 0 + cell_y = 0 # columns are bit lines cell_x = 0 @@ -163,7 +163,7 @@ class rom_precharge_array(design): start = vector(tap_pin.cx(), tap_pin.by()) end = vector(start.x, tap.mod.get_pin("poly_tap").cy()) self.add_segment_center(layer="poly", start=start, end=end) - offset_start = vector(end.x - self.poly_tap.width + self.poly_extend_active, end.y) + offset_start = vector(end.x - self.poly_tap.width + self.poly_extend_active, end.y) offset_end = end + vector(0.5*self.poly_width, 0) self.add_segment_center(layer="poly", start=offset_start, end=offset_end) diff --git a/compiler/modules/rom_precharge_cell.py b/compiler/modules/rom_precharge_cell.py index 13cc8c2b..90146d99 100644 --- a/compiler/modules/rom_precharge_cell.py +++ b/compiler/modules/rom_precharge_cell.py @@ -21,7 +21,7 @@ class rom_precharge_cell(rom_base_cell): def create_layout(self): super().create_layout() - + self.place_tap() self.extend_well() @@ -37,27 +37,27 @@ class rom_precharge_cell(rom_base_cell): def create_tx(self): self.cell_inst = self.add_inst( name="precharge_pmos", - mod=self.pmos, + mod=self.pmos, ) self.connect_inst(["bitline", "gate", "vdd", "vdd"]) - def add_pins(self): + def add_pins(self): pin_list = ["vdd", "gate", "bitline"] dir_list = ["POWER", "INPUT", "OUTPUT"] - self.add_pin_list(pin_list, dir_list) + self.add_pin_list(pin_list, dir_list) def setup_drc_offsets(self): 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 + #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 + #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): @@ -82,7 +82,7 @@ class rom_precharge_cell(rom_base_cell): directions="nonpref") self.add_via_stack_center(offset=pos, from_layer=self.active_stack[2], - to_layer=self.supply_layer) + to_layer=self.supply_layer) bitline_offset = vector( 2 * (drc("minwidth_{}".format(self.bitline_layer)) + drc("{0}_to_{0}".format(self.bitline_layer))) ,0) diff --git a/compiler/modules/rom_wordline_driver_array.py b/compiler/modules/rom_wordline_driver_array.py index 56df91a9..7dfc2d1a 100644 --- a/compiler/modules/rom_wordline_driver_array.py +++ b/compiler/modules/rom_wordline_driver_array.py @@ -74,7 +74,7 @@ class rom_wordline_driver_array(design): height=b.height, add_wells=False, flip_io=self.flip_io) - + else: self.wl_driver = factory.create(module_type="pbuf_dec", size=self.fanout, @@ -136,7 +136,7 @@ class rom_wordline_driver_array(design): # output each WL on the right if self.flip_io: wl_offset = out_pin.lc() - vector(1.6 * route_width, 0) - + else: wl_offset = out_pin.rc() - vector( 0.5 * route_width, 0) diff --git a/compiler/tests/05_rom_base_bank_2kB_test.py b/compiler/tests/05_rom_base_bank_2kB_test.py index 983895de..b5087f3d 100644 --- a/compiler/tests/05_rom_base_bank_2kB_test.py +++ b/compiler/tests/05_rom_base_bank_2kB_test.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # See LICENSE for licensing information. # -# Copyright (c) 2016-2021 Regents of the University of California and The Board +# Copyright (c) 2016-2023 Regents of the University of California and The Board # of Regents for the Oklahoma Agricultural and Mechanical College # (acting for and on behalf of Oklahoma State University) # All rights reserved.