From 8bf37ca708c4e7749beb2fc6ca41bf54783ed7e7 Mon Sep 17 00:00:00 2001 From: mrg Date: Wed, 26 May 2021 17:38:09 -0700 Subject: [PATCH] Connect dnwell taps to gnd --- compiler/base/hierarchy_layout.py | 60 ++++++++++++++++++++++++------- compiler/base/lef.py | 37 +++++++++---------- compiler/router/router.py | 4 +-- compiler/sram/sram_base.py | 2 +- 4 files changed, 70 insertions(+), 33 deletions(-) diff --git a/compiler/base/hierarchy_layout.py b/compiler/base/hierarchy_layout.py index e65dcfa3..e603bdc3 100644 --- a/compiler/base/hierarchy_layout.py +++ b/compiler/base/hierarchy_layout.py @@ -1378,6 +1378,12 @@ class layout(): layer_stack = self.active_stack tap_spacing = 2 nwell_offset = vector(self.nwell_width, self.nwell_width) + + # Every nth tap is connected to gnd + period = 5 + + # BOTTOM + count = 0 loc = ll + nwell_offset.scale(tap_spacing, 0) end_loc = lr - nwell_offset.scale(tap_spacing, 0) while loc.x < end_loc.x: @@ -1385,11 +1391,19 @@ class layout(): offset=loc, implant_type="n", well_type="n") - self.add_via_stack_center(from_layer="li", - to_layer="m1", - offset=loc) + if count % period: + self.add_via_stack_center(from_layer="li", + to_layer="m1", + offset=loc) + else: + self.add_power_pin(name="gnd", + loc=loc, + start_layer="li") + count += 1 loc += nwell_offset.scale(tap_spacing, 0) + # TOP + count = 0 loc = ul + nwell_offset.scale(tap_spacing, 0) end_loc = ur - nwell_offset.scale(tap_spacing, 0) while loc.x < end_loc.x: @@ -1397,11 +1411,19 @@ class layout(): offset=loc, implant_type="n", well_type="n") - self.add_via_stack_center(from_layer="li", - to_layer="m2", - offset=loc) + if count % period: + self.add_via_stack_center(from_layer="li", + to_layer="m1", + offset=loc) + else: + self.add_power_pin(name="gnd", + loc=loc, + start_layer="li") + count += 1 loc += nwell_offset.scale(tap_spacing, 0) + # LEFT + count = 0 loc = ll + nwell_offset.scale(0, tap_spacing) end_loc = ul - nwell_offset.scale(0, tap_spacing) while loc.y < end_loc.y: @@ -1409,11 +1431,19 @@ class layout(): offset=loc, implant_type="n", well_type="n") - self.add_via_stack_center(from_layer="li", - to_layer="m2", - offset=loc) + if count % period: + self.add_via_stack_center(from_layer="li", + to_layer="m2", + offset=loc) + else: + self.add_power_pin(name="gnd", + loc=loc, + start_layer="li") + count += 1 loc += nwell_offset.scale(0, tap_spacing) + # RIGHT + count = 0 loc = lr + nwell_offset.scale(0, tap_spacing) end_loc = ur - nwell_offset.scale(0, tap_spacing) while loc.y < end_loc.y: @@ -1421,9 +1451,15 @@ class layout(): offset=loc, implant_type="n", well_type="n") - self.add_via_stack_center(from_layer="li", - to_layer="m2", - offset=loc) + if count % period: + self.add_via_stack_center(from_layer="li", + to_layer="m2", + offset=loc) + else: + self.add_power_pin(name="gnd", + loc=loc, + start_layer="li") + count += 1 loc += nwell_offset.scale(0, tap_spacing) # Add the gnd ring diff --git a/compiler/base/lef.py b/compiler/base/lef.py index 9db18ab1..ce1eef1c 100644 --- a/compiler/base/lef.py +++ b/compiler/base/lef.py @@ -110,24 +110,25 @@ class lef: # For each pin, remove the blockage and add the pin for pin_name in self.pins: - pin = self.get_pin(pin_name) - inflated_pin = pin.inflated_pin(multiple=1) - another_iteration_needed = True - while another_iteration_needed: - another_iteration_needed = False - old_blockages = list(self.blockages[pin.layer]) - for blockage in old_blockages: - if blockage.overlaps(inflated_pin): - intersection_shape = blockage.intersection(inflated_pin) - # If it is zero area, don't add the pin - if intersection_shape[0][0]==intersection_shape[1][0] or intersection_shape[0][1]==intersection_shape[1][1]: - continue - another_iteration_needed = True - # Remove the old blockage and add the new ones - self.blockages[pin.layer].remove(blockage) - intersection_pin = pin_layout("", intersection_shape, inflated_pin.layer) - new_blockages = blockage.cut(intersection_pin) - self.blockages[pin.layer].extend(new_blockages) + pins = self.get_pins(pin_name) + for pin in pins: + inflated_pin = pin.inflated_pin(multiple=1) + another_iteration_needed = True + while another_iteration_needed: + another_iteration_needed = False + old_blockages = list(self.blockages[pin.layer]) + for blockage in old_blockages: + if blockage.overlaps(inflated_pin): + intersection_shape = blockage.intersection(inflated_pin) + # If it is zero area, don't add the pin + if intersection_shape[0][0]==intersection_shape[1][0] or intersection_shape[0][1]==intersection_shape[1][1]: + continue + another_iteration_needed = True + # Remove the old blockage and add the new ones + self.blockages[pin.layer].remove(blockage) + intersection_pin = pin_layout("", intersection_shape, inflated_pin.layer) + new_blockages = blockage.cut(intersection_pin) + self.blockages[pin.layer].extend(new_blockages) def lef_write_header(self): """ Header of LEF file """ diff --git a/compiler/router/router.py b/compiler/router/router.py index dbd90c5e..dcfde6cf 100644 --- a/compiler/router/router.py +++ b/compiler/router/router.py @@ -898,7 +898,7 @@ class router(router_tech): Adds a supply pin to the perimeter and resizes the bounding box. """ pg = pin_group(name, [], self) - if name == "vdd": + if name == "gnd": offset = width + 1 else: offset = 1 @@ -927,7 +927,7 @@ class router(router_tech): pg = pin_group(name, [], self) # Offset the vdd inside one ring width # Units are in routing grids - if name == "vdd": + if name == "gnd": offset = width + 1 else: offset = 1 diff --git a/compiler/sram/sram_base.py b/compiler/sram/sram_base.py index 0c569335..a7530e0b 100644 --- a/compiler/sram/sram_base.py +++ b/compiler/sram/sram_base.py @@ -209,7 +209,7 @@ class sram_base(design, verilog, lef): self.add_lvs_correspondence_points() - #self.offset_all_coordinates() + self.offset_all_coordinates() highest_coord = self.find_highest_coords() self.width = highest_coord[0]