def rectMerge(rect1, rect2): rect = odb.Rect(min(rect1.xMin(), rect2.xMin()), min(rect1.yMin(), rect2.yMin()), max(rect1.xMax(), rect2.xMax()), max(rect1.yMax(), rect2.yMax())) return rect
def transformRect(rect, orient): transform = odb.dbTransform(orient) rect_ll = odb.Point(*rect.ll()) rect_ur = odb.Point(*rect.ur()) transform.apply(rect_ll) transform.apply(rect_ur) rect = odb.Rect(rect_ll, rect_ur) return rect
def rectIntersection(rect1, rect2): rect = odb.Rect() if rectOverlaps(rect1, rect2): rect.set_xlo(max(rect1.xMin(), rect2.xMin())) rect.set_ylo(max(rect1.yMin(), rect2.yMin())) rect.set_xhi(min(rect1.xMax(), rect2.xMax())) rect.set_yhi(min(rect1.yMax(), rect2.yMax())) return rect
def boxes2Rects(boxes, transform): rects = [] for box in boxes: ur = odb.Point(box.xMin(), box.yMin()) ll = odb.Point(box.xMax(), box.yMax()) transform.apply(ll) transform.apply(ur) pin_layer = box.getTechLayer() rects.append({"layer": pin_layer, "rect": odb.Rect(ll, ur)}) return rects
def createWireBox(rect_width, rect_height, rect_x, rect_y, layer, net, reorient="R0"): rect = odb.Rect(0, 0, rect_width, rect_height) rect.moveTo(rect_x, rect_y) rect = transformRect(rect, reorient) box = {"rect": rect, "layer": layer, "net": net} return box
def getShapesOverlappingBBox(llx, lly, urx, ury, layers=[], ext_orient="R0"): shapes_overlapping = [] rect_bbox = odb.Rect(llx, lly, urx, ury) for box in ALL_BOXES: box_layer = box["layer"] ignore_box = (len(layers) != 0) for layer in layers: if equalLayers(layer, box_layer): ignore_box = False break if not ignore_box: rect_box = transformRect(box["rect"], ext_orient) if rectOverlaps(rect_box, rect_bbox): shapes_overlapping.append(box) return shapes_overlapping
def gridify(rect): x1, y1 = rect.ll() x2, y2 = rect.ur() if (x2 - x1) % 2 != 0: x1 += 5 # 0.005 microns ! return odb.Rect(x1, y1, x2, y2)
# account for obstructions from_layer = box["layer"] to_layer = nearest_stripe_box["layer"] # prefer the highest possible connecting layer (antenna reasons) connecting_layer = from_layer if not isHighestRoutingLayer(to_layer): connecting_layer = getUpperRoutingLayer(to_layer) elif not isLowestRoutingLayer(to_layer): connecting_layer = getLowerRoutingLayer(to_layer) print("Connecting with", connecting_layer.getName(), "to", to_layer.getName()) wire_rect = odb.Rect(projection_x_min, pad_pin_rect.yMin(), projection_x_max, stripe_rect.yMin()) # adjust width MAX_SPACING = getTechMaxSpacing( (set(layersBetween(from_layer, connecting_layer)).union( layersBetween(connecting_layer, to_layer)))) # note that the box is move away from the pad to evade interactions with # nearby pads overlapping_boxes = getShapesOverlappingBBox( wire_rect.xMin() - MAX_SPACING, wire_rect.yMin(), wire_rect.xMax() + MAX_SPACING, wire_rect.yMax() - MAX_SPACING, ext_orient=pad_pin_orient_inv, layers=list( set(layersBetween(connecting_layer, to_layer)) - set([to_layer])))
bterm = pin_placement[side][i] slot = slots[i] pin_name = bterm.getName() pins = bterm.getBPins() if len(pins) > 0: print("Warning:", pin_name, "already has shapes. Modifying them") assert len(pins) == 1 pin_bpin = pins[0] else: pin_bpin = odb.dbBPin_create(bterm) pin_bpin.setPlacementStatus("PLACED") if side in ["#N", "#S"]: rect = odb.Rect(0, 0, V_WIDTH, LENGTH) if side == "#N": y = BLOCK_UR_Y - LENGTH else: y = BLOCK_LL_Y rect.moveTo(slot - V_WIDTH // 2, y) odb.dbBox_create(pin_bpin, V_LAYER, *rect.ll(), *rect.ur()) else: rect = odb.Rect(0, 0, LENGTH, H_WIDTH) if side == "#E": x = BLOCK_UR_X - LENGTH else: x = BLOCK_LL_X rect.moveTo(x, slot - H_WIDTH // 2) odb.dbBox_create(pin_bpin, H_LAYER, *rect.ll(), *rect.ur())
bterm = pin_placement[side][i] slot = slots[i] pin_name = bterm.getName() pins = bterm.getBPins() if len(pins) > 0: print("Warning:", pin_name, "already has shapes. Modifying them") assert len(pins) == 1 pin_bpin = pins[0] else: pin_bpin = odb.dbBPin_create(bterm) pin_bpin.setPlacementStatus("PLACED") if side in ["#N", "#S"]: rect = odb.Rect(0, 0, V_WIDTH, LENGTH + V_EXTENSION) if side == "#N": y = BLOCK_UR_Y - LENGTH else: y = BLOCK_LL_Y - V_EXTENSION rect.moveTo(slot - V_WIDTH // 2, y) odb.dbBox_create(pin_bpin, V_LAYER, *rect.ll(), *rect.ur()) else: rect = odb.Rect(0, 0, LENGTH + H_EXTENSION, H_WIDTH) if side == "#E": x = BLOCK_UR_X - LENGTH else: x = BLOCK_LL_X - H_EXTENSION rect.moveTo(x, slot - H_WIDTH // 2) odb.dbBox_create(pin_bpin, H_LAYER, *rect.ll(), *rect.ur())