From b6c3580e249db400077cf982d92cd52ff55b602a Mon Sep 17 00:00:00 2001 From: mrg Date: Mon, 9 May 2022 11:44:46 -0700 Subject: [PATCH] Fix width of replica routes. Don't enclose pins if they overlap sufficiently. --- compiler/base/pin_layout.py | 2 +- compiler/modules/replica_bitcell_array.py | 12 ++++++-- compiler/router/router.py | 36 ++++++++++++++++------- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/compiler/base/pin_layout.py b/compiler/base/pin_layout.py index 7ba6cdca..2058d137 100644 --- a/compiler/base/pin_layout.py +++ b/compiler/base/pin_layout.py @@ -189,7 +189,7 @@ class pin_layout: if max_x - min_x == 0 or max_y - min_y == 0: return None - return [vector(min_x, min_y), vector(max_x, max_y)] + return pin_layout("", [vector(min_x, min_y), vector(max_x, max_y)], self.layer) def xoverlaps(self, other): """ Check if shape has x overlap """ diff --git a/compiler/modules/replica_bitcell_array.py b/compiler/modules/replica_bitcell_array.py index cbfc6ec2..0c86f3a6 100644 --- a/compiler/modules/replica_bitcell_array.py +++ b/compiler/modules/replica_bitcell_array.py @@ -6,6 +6,7 @@ import debug from bitcell_base_array import bitcell_base_array +from contact import contact from tech import drc, spice, preferred_directions from tech import cell_properties as props from vector import vector @@ -588,6 +589,9 @@ class replica_bitcell_array(bitcell_base_array): top_loc = vector(self.width + offset_multiple * self.vertical_pitch, self.height) layer = self.supply_stack[2] + top_via = contact(layer_stack=self.supply_stack, + directions=("H", "H")) + # self.add_layout_pin_rect_ends(text=name, # layer=layer, @@ -596,7 +600,8 @@ class replica_bitcell_array(bitcell_base_array): self.add_layout_pin_segment_center(text=name, layer=layer, start=bot_loc, - end=top_loc) + end=top_loc, + width=top_via.second_layer_width) return (bot_loc, top_loc) @@ -612,6 +617,8 @@ class replica_bitcell_array(bitcell_base_array): right_loc = vector(self.width, self.height + offset_multiple * self.horizontal_pitch) layer = self.supply_stack[0] + side_via = contact(layer_stack=self.supply_stack, + directions=("V", "V")) # self.add_layout_pin_rect_ends(text=name, # layer=layer, @@ -620,7 +627,8 @@ class replica_bitcell_array(bitcell_base_array): self.add_layout_pin_segment_center(text=name, layer=layer, start=left_loc, - end=right_loc) + end=right_loc, + width=side_via.first_layer_height) return (left_loc, right_loc) diff --git a/compiler/router/router.py b/compiler/router/router.py index 6e5d5b4e..37db7af1 100644 --- a/compiler/router/router.py +++ b/compiler/router/router.py @@ -670,6 +670,17 @@ class router(router_tech): return set([best_coord]) + def break_on_grids(self, tracks, xvals, yvals): + track_list = [] + for x in xvals: + for y in yvals: + track_list.append(vector3d(x, y, 0)) + track_list.append(vector3d(x, y, 1)) + + for current in tracks: + if current in track_list: + breakpoint() + def divide_pin_to_tracks(self, pin, tracks): """ Return a list of pin shape parts that are in the tracks. @@ -682,16 +693,11 @@ class router(router_tech): overlap_pins = [] for track in tracks: track_pin = self.convert_track_to_shape_pin(track) - overlap_rect = track_pin.intersection(pin) - if not overlap_rect: - continue - overlap_pin = pin_layout(pin.name, - overlap_rect, - pin.layer) + overlap_pin = track_pin.intersection(pin) # If pin is smaller than minwidth, in one dimension, skip it. min_pin_width = drc("minwidth_{0}". format(pin.layer)) - if overlap_pin.width() < min_pin_width and overlap_pin.height() < min_pin_width: + if not overlap_pin or (overlap_pin.width() < min_pin_width and overlap_pin.height() < min_pin_width): continue else: overlap_pins.append(overlap_pin) @@ -1173,17 +1179,27 @@ class router(router_tech): if len(path_tracks) == 0 or len(components) == 0: return + # Find the track pin + track_pins = [self.convert_tracks_to_pin(x) for x in path_tracks] + # Convert the off-grid pin into parts in each routing grid offgrid_pin_parts = [] for component in components: pg = self.pin_groups[pin_name][component] for pin in pg.pins: + # Layer min with + min_width = drc("minwidth_{}".format(pin.layer)) + + # If we intersect, by a min_width, we are done! + for track_pin in track_pins: + intersection = pin.intersection(track_pin) + if intersection and intersection.width() > min_width and intersection.height() > min_width: + return + + #self.break_on_grids(pg.grids, xvals=[68], yvals=range(93,100)) partial_pin_parts = self.divide_pin_to_tracks(pin, pg.grids) offgrid_pin_parts.extend(partial_pin_parts) - # Find the track pin - track_pins = [self.convert_tracks_to_pin(x) for x in path_tracks] - # Find closest part closest_track_pin, closest_part_pin = self.find_closest_pin(track_pins, offgrid_pin_parts)