From 50045e54e8801d61c8feaa497f3fd73bc3604d17 Mon Sep 17 00:00:00 2001 From: mrg Date: Tue, 3 May 2022 11:45:51 -0700 Subject: [PATCH] Fix a couple supply routing issues. --- compiler/base/hierarchy_layout.py | 22 +++++----- compiler/modules/column_mux_array.py | 5 ++- compiler/modules/replica_bitcell_array.py | 6 ++- compiler/pgates/column_mux.py | 7 ++-- compiler/pgates/precharge.py | 49 ++++++----------------- 5 files changed, 34 insertions(+), 55 deletions(-) diff --git a/compiler/base/hierarchy_layout.py b/compiler/base/hierarchy_layout.py index 5c986d75..ee97a7ac 100644 --- a/compiler/base/hierarchy_layout.py +++ b/compiler/base/hierarchy_layout.py @@ -657,12 +657,13 @@ class layout(): via_width=None via_height=0 + bot_y = min([pin.by() for (inst,pin) in v]) + top_y = max([pin.uy() for (inst,pin) in v]) + if full_width: - bot_y = 0 - top_y = self.height - else: - bot_y = min([pin.by() for (inst,pin) in v]) - top_y = max([pin.uy() for (inst,pin) in v]) + bot_y = min(0, bot_y) + top_y = max(self.height, top_y) + top_pos = vector(x, top_y + 0.5 * via_height) bot_pos = vector(x, bot_y - 0.5 * via_height) @@ -758,12 +759,13 @@ class layout(): via_height=None via_width=0 + left_x = min([pin.lx() for (inst,pin) in v]) + right_x = max([pin.rx() for (inst,pin) in v]) + if full_width: - left_x = 0 - right_x = self.width - else: - left_x = min([pin.lx() for (inst,pin) in v]) - right_x = max([pin.rx() for (inst,pin) in v]) + left_x = min(0, left_x) + right_x = max(self.width, right_x) + left_pos = vector(left_x + 0.5 * via_width, y) right_pos = vector(right_x + 0.5 * via_width, y) diff --git a/compiler/modules/column_mux_array.py b/compiler/modules/column_mux_array.py index 0fa35af0..36d4080e 100644 --- a/compiler/modules/column_mux_array.py +++ b/compiler/modules/column_mux_array.py @@ -147,13 +147,14 @@ class column_mux_array(design.design): offset=offset, height=self.height - offset.y) - for inst in self.mux_inst: - self.copy_layout_pin(inst, "gnd") + def route_supplies(self): + self.route_horizontal_pins("gnd", self.insts) def add_routing(self): self.add_horizontal_input_rail() self.add_vertical_poly_rail() self.route_bitlines() + self.route_supplies() def add_horizontal_input_rail(self): """ Create address input rails below the mux transistors """ diff --git a/compiler/modules/replica_bitcell_array.py b/compiler/modules/replica_bitcell_array.py index 785bb62b..cbfc6ec2 100644 --- a/compiler/modules/replica_bitcell_array.py +++ b/compiler/modules/replica_bitcell_array.py @@ -507,12 +507,14 @@ class replica_bitcell_array(bitcell_base_array): # There are always vertical pins for the WLs on the left/right if we have unused wordlines self.left_gnd_locs = self.route_side_pin("gnd", "left", left_right_mult) self.right_gnd_locs = self.route_side_pin("gnd","right", left_right_mult) - left_right_mult = 3 + # This needs to be big enough so that they aren't in the same supply routing grid + left_right_mult = 4 if gnd_dir == "V": self.top_gnd_locs = self.route_side_pin("gnd", "top", top_bot_mult) self.bot_gnd_locs = self.route_side_pin("gnd", "bot", top_bot_mult) - top_bot_mult = 3 + # This needs to be big enough so that they aren't in the same supply routing grid + top_bot_mult = 4 if vdd_dir == "V": self.top_vdd_locs = self.route_side_pin("vdd", "top", top_bot_mult) diff --git a/compiler/pgates/column_mux.py b/compiler/pgates/column_mux.py index a4a83dcc..bf489e87 100644 --- a/compiler/pgates/column_mux.py +++ b/compiler/pgates/column_mux.py @@ -240,10 +240,9 @@ class column_mux(pgate.pgate): self.add_via_center(layers=self.col_mux_stack, offset=active_pos) - # Add the M1->..->power_grid_layer stack - self.add_power_pin(name="gnd", - loc=active_pos, - start_layer="m1") + self.add_layout_pin_rect_center(text="gnd", + layer="m1", + offset=active_pos) # Add well enclosure over all the tx and contact if "pwell" in layer: diff --git a/compiler/pgates/precharge.py b/compiler/pgates/precharge.py index 8eff8c8f..22cef930 100644 --- a/compiler/pgates/precharge.py +++ b/compiler/pgates/precharge.py @@ -96,46 +96,21 @@ class precharge(design.design): Adds a vdd rail at the top of the cell """ - if OPTS.experimental_power: - pmos_pin = self.upper_pmos2_inst.get_pin("S") - pmos_pos = pmos_pin.center() - self.add_path(pmos_pin.layer, [pmos_pos, self.well_contact_pos]) + pmos_pin = self.upper_pmos2_inst.get_pin("S") + pmos_pos = pmos_pin.center() + self.add_path(pmos_pin.layer, [pmos_pos, self.well_contact_pos]) - self.add_via_stack_center(from_layer=pmos_pin.layer, - to_layer=self.supply_stack[0], + self.add_via_stack_center(from_layer=pmos_pin.layer, + to_layer=self.supply_stack[0], + offset=self.well_contact_pos) + + self.add_min_area_rect_center(layer=self.en_layer, offset=self.well_contact_pos, - directions=("V", "V")) + width=self.well_contact.mod.second_layer_width) - self.add_min_area_rect_center(layer=self.en_layer, - offset=self.well_contact_pos, - width=self.well_contact.mod.second_layer_width) - - self.add_layout_pin_rect_center(text="vdd", - layer=self.supply_stack[0], - offset=self.well_contact_pos) - else: - # Adds the rail across the width of the cell - vdd_position = vector(0.5 * self.width, self.height) - layer_width = drc("minwidth_" + self.en_layer) - self.add_rect_center(layer=self.en_layer, - offset=vdd_position, - width=self.width, - height=layer_width) - - pmos_pin = self.upper_pmos2_inst.get_pin("S") - - # center of vdd rail - pmos_vdd_pos = vector(pmos_pin.cx(), vdd_position.y) - self.add_path(self.en_layer, [pmos_pin.center(), pmos_vdd_pos]) - - self.add_power_pin("vdd", - self.well_contact_pos, - directions=("V", "V")) - - self.add_via_stack_center(from_layer=pmos_pin.layer, - to_layer=self.en_layer, - offset=pmos_pin.center(), - directions=("V", "V")) + self.add_layout_pin_rect_center(text="vdd", + layer=self.supply_stack[0], + offset=self.well_contact_pos) def create_ptx(self): """