diff --git a/compiler/modules/rom_bank.py b/compiler/modules/rom_bank.py index 9148766c..56a24740 100644 --- a/compiler/modules/rom_bank.py +++ b/compiler/modules/rom_bank.py @@ -113,8 +113,7 @@ class rom_bank(design,rom_verilog): # FIXME: Somehow ROM layout behaves weird and doesn't add all the pin # shapes before routing supplies init_bbox = self.get_bbox() - if OPTS.route_supplies: - self.route_supplies(init_bbox) + self.route_supplies(init_bbox) # Route the pins to the perimeter if OPTS.perimeter_pins: # We now route the escape routes far enough out so that they will @@ -368,8 +367,11 @@ class rom_bank(design,rom_verilog): # Route precharge to col decoder start = prechrg_control.center() - mid1 = vector(self.control_inst.rx() + self.interconnect_layer_pitch, prechrg_control.cy()) - mid2 = vector(self.control_inst.rx() + self.interconnect_layer_pitch, col_decode_prechrg.cy()) + + path_x = self.control_inst.rx() + 1.2 * self.route_layer_pitch + + mid1 = vector(path_x, prechrg_control.cy()) + mid2 = vector(path_x, col_decode_prechrg.cy()) end = col_decode_prechrg.center() self.add_path(self.route_stack[0], [start, mid1, mid2, end]) @@ -378,7 +380,7 @@ class rom_bank(design,rom_verilog): offset=end) start = mid1 - mid1 = vector(self.control_inst.rx() + self.interconnect_layer_pitch, start.y) + mid1 = vector(path_x, 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]) @@ -388,6 +390,10 @@ class rom_bank(design,rom_verilog): 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_via_stack_center(from_layer=self.route_stack[0], + to_layer=array_prechrg.layer, + offset=array_prechrg.center()) + def route_clock(self): clk_out = self.control_inst.get_pin("clk_out") @@ -409,6 +415,10 @@ class rom_bank(design,rom_verilog): to_layer=row_decode_clk.layer, offset=addr_control_clk) + self.add_via_stack_center(from_layer=self.route_stack[2], + to_layer=row_decode_prechrg.layer, + offset=row_decode_prechrg.center()) + self.add_segment_center(row_decode_clk.layer, addr_control_clk, row_decode_clk.rc()) def route_array_outputs(self): @@ -417,7 +427,7 @@ class rom_bank(design,rom_verilog): inv_out_pins = [self.bitline_inv_inst.get_pin("out_{}".format(bl)) for bl in range(self.cols)] mux_pins = [self.mux_inst.get_pin("bl_{}".format(bl)) for bl in range(self.cols)] - self.connect_col_pins(self.interconnect_layer, array_out_pins + inv_in_pins, round=True, directions="nonpref") + self.connect_col_pins(self.route_stack[2], array_out_pins + inv_in_pins, round=True, directions="nonpref") self.connect_col_pins(self.interconnect_layer, inv_out_pins + mux_pins, round=True, directions="nonpref") def route_output_buffers(self): @@ -450,34 +460,36 @@ class rom_bank(design,rom_verilog): for inst in self.insts: self.copy_power_pins(inst, pin_name) - from openram.router import supply_router as router - rtr = router(layers=self.supply_stack, - design=self, - bbox=bbox, - pin_type=OPTS.supply_pin_type) - rtr.route() + if OPTS.route_supplies: - if OPTS.supply_pin_type in ["left", "right", "top", "bottom", "ring"]: - # Find the lowest leftest pin for vdd and gnd - for pin_name in ["vdd", "gnd"]: - # Copy the pin shape(s) to rectangles - for pin in self.get_pins(pin_name): - self.add_rect(layer=pin.layer, - offset=pin.ll(), - width=pin.width(), - height=pin.height()) + from openram.router import supply_router as router + rtr = router(layers=self.supply_stack, + design=self, + bbox=bbox, + pin_type=OPTS.supply_pin_type) + rtr.route() - # Remove the pin shape(s) - self.remove_layout_pin(pin_name) + if OPTS.supply_pin_type in ["left", "right", "top", "bottom", "ring"]: + # Find the lowest leftest pin for vdd and gnd + for pin_name in ["vdd", "gnd"]: + # Copy the pin shape(s) to rectangles + for pin in self.get_pins(pin_name): + self.add_rect(layer=pin.layer, + offset=pin.ll(), + width=pin.width(), + height=pin.height()) - # Get new pins - pins = rtr.get_new_pins(pin_name) - for pin in pins: - self.add_layout_pin(pin_name, - pin.layer, - pin.ll(), - pin.width(), - pin.height()) + # Remove the pin shape(s) + self.remove_layout_pin(pin_name) + + # Get new pins + pins = rtr.get_new_pins(pin_name) + for pin in pins: + self.add_layout_pin(pin_name, + pin.layer, + pin.ll(), + pin.width(), + pin.height()) def route_escape_pins(self, bbox): pins_to_route = [] diff --git a/compiler/modules/rom_base_array.py b/compiler/modules/rom_base_array.py index 981375e4..3a0848ee 100644 --- a/compiler/modules/rom_base_array.py +++ b/compiler/modules/rom_base_array.py @@ -22,7 +22,9 @@ class rom_base_array(bitcell_base_array): self.data = bitmap self.tap_direction = tap_direction - self.pitch_match = pitch_match + # This attribute is redundant with the tap direction + # TODO: consolidate pitch matching logic to just be based on tap direction + self.pitch_match = tap_direction == "row" self.bitline_layer = bitline_layer self.strap_spacing = strap_spacing self.wordline_layer = wordline_layer @@ -89,7 +91,6 @@ class rom_base_array(bitcell_base_array): self.poly_tap = factory.create(module_type="rom_poly_tap", add_active_tap=True) self.end_poly_tap = factory.create(module_type="rom_poly_tap", place_poly=True) - print("poly tap width", self.poly_tap.width, "height", self.poly_tap.height, self.tap_direction) self.precharge_array = factory.create(module_type="rom_precharge_array", cols=self.column_size, strap_spacing=self.strap_spacing, @@ -102,7 +103,6 @@ class rom_base_array(bitcell_base_array): self.route_pitch = drc("{0}_to_{0}".format(self.bitline_layer)) def add_pins(self): - print(self.get_wordline_names()) for bl_name in self.get_bitline_names(): self.add_pin(bl_name, "OUTPUT") for wl_name in self.get_wordline_names(): @@ -234,12 +234,10 @@ class rom_base_array(bitcell_base_array): bottom = vector(pin.cx(), pin.by()) top = vector(pin.cx(), gnd_y) self.add_via_stack_center(offset=top, from_layer=self.bitline_layer, to_layer=self.supply_stack[0]) - # self.add_via_center(offset=bottom, layers=self.supply_stack) self.add_layout_pin_rect_ends(name="gnd", layer=self.supply_stack[0], start=bottom, end=top) self.remove_layout_pin("gnd_tmp") - # self.add_segment_center(layer=self.supply_stack[2], start=vector(min_x, bottom.y), end=vector(max_x, bottom.y)) self.add_segment_center(layer=self.bitline_layer, start=gnd_l, end=vector(min_x, gnd_l.y)) self.add_segment_center(layer=self.bitline_layer, start=gnd_r, end=vector(max_x, gnd_r.y)) @@ -333,7 +331,6 @@ class rom_base_array(bitcell_base_array): else: output_layer = "m3" rail_y = self.precharge_inst.get_pins("vdd")[0].cy() - print("cols ", self.bitline_names[0]) for bl in range(self.column_size): src_pin = self.cell_list[0][bl].get_pin("S") diff --git a/compiler/modules/rom_base_cell.py b/compiler/modules/rom_base_cell.py index 1f47b88f..da57ff23 100644 --- a/compiler/modules/rom_base_cell.py +++ b/compiler/modules/rom_base_cell.py @@ -80,7 +80,6 @@ class rom_base_cell(design): self.cell_inst = self.add_inst( name=self.name + "_nmos", mod=self.nmos, ) - print("bitmos", self.cell_inst.height, self.cell_inst.width) if self.bit_value == 0: self.connect_inst(["bl", "wl", "bl", "gnd"]) diff --git a/compiler/modules/rom_decoder.py b/compiler/modules/rom_decoder.py index 4540aadd..8ea798a6 100644 --- a/compiler/modules/rom_decoder.py +++ b/compiler/modules/rom_decoder.py @@ -231,6 +231,14 @@ class rom_decoder(design): self.add_path(self.inv_route_layer, [addr_out_pin.center(), addr_middle, addr_pin.center()]) self.add_path(self.inv_route_layer, [addr_bar_out_pin.center(), addr_bar_middle, addr_bar_pin.center()]) + + self.add_via_stack_center(offset=addr_pin.center(), + from_layer=addr_pin.layer, + to_layer=self.inv_route_layer) + + self.add_via_stack_center(offset=addr_bar_pin.center(), + from_layer=addr_bar_pin.layer, + to_layer=self.inv_route_layer) self.copy_layout_pin(self.buf_inst, "A{}_in".format(i), "A{}".format(i)) def route_supplies(self): diff --git a/compiler/modules/rom_poly_tap.py b/compiler/modules/rom_poly_tap.py index e5bb288c..803211e4 100644 --- a/compiler/modules/rom_poly_tap.py +++ b/compiler/modules/rom_poly_tap.py @@ -35,7 +35,6 @@ class rom_poly_tap(design): def create_layout(self): self.place_via() - # self.extend_poly() if self.add_tap or self.place_poly: self.place_active_tap() @@ -47,7 +46,6 @@ class rom_poly_tap(design): contact_width = self.poly_contact.width self.height = self.dummy.height self.width = contact_width + self.pitch_offset - print("pitch off", self.pitch_offset) super().add_boundary() def place_via(self): @@ -83,12 +81,9 @@ class rom_poly_tap(design): tap_y = self.via.cy() + self.dummy.width * 0.5 contact_pos = vector(tap_x, tap_y) - # edge of the next nmos - active_edge = self.dummy.width - self.dummy.cell_inst.height - self.poly_extend_active - # edge of the active contact - tap_edge = tap_x + 0.5 * self.active_contact.height - self.pitch_offset += (self.active_space * 2) - (tap_edge - active_edge) + self.contact_x_offset + # This pitch offset is used throughout the memory bank to make sure the pitch of the decoder outputs matches the pitch of the array inputs + self.pitch_offset = 0.5 * self.active_contact.width + self.active_space + 0.5 * self.contact_width + self.active_enclose_contact if self.tx_type == "nmos" and self.add_tap: self.add_via_center(layers=self.active_stack, diff --git a/compiler/modules/rom_precharge_cell.py b/compiler/modules/rom_precharge_cell.py index 6a2f4ac7..f9517b6b 100644 --- a/compiler/modules/rom_precharge_cell.py +++ b/compiler/modules/rom_precharge_cell.py @@ -24,7 +24,6 @@ class rom_precharge_cell(rom_base_cell): self.place_tap() self.extend_well() - print("precharge", self.height, self.width) def add_modules(self): @@ -44,7 +43,6 @@ class rom_precharge_cell(rom_base_cell): self.cell_inst = self.add_inst( name="precharge_pmos", mod=self.pmos, ) - print("premos", self.cell_inst.height, self.cell_inst.width) self.connect_inst(["bitline", "gate", "vdd", "vdd"]) def add_pins(self): @@ -58,7 +56,6 @@ 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) def extend_well(self): - print(self.nwell_enclose_active) well_y = self.get_pin("vdd").cy() - 0.5 * self.tap.height - self.nwell_enclose_active well_ll = vector(0, well_y) height = self.get_pin("D").cy() + self.nwell_enclose_active - well_y @@ -91,5 +88,4 @@ class rom_precharge_cell(rom_base_cell): pass def short_gate(self): - print("not shorting") pass \ No newline at end of file