Open dvancil opened 6 days ago
Hi,
can you share the exact code that is making problems? Both SKILL and Python. I can then take a look if something went wrong while translating.
procedure(DVMovePins() cv=geGetWindowCellView() foreach(term cv~>terminals ; iterate over all the pins for this terminal foreach(pin term~>pins pinFig=pin~>fig net=term~>net ; only do this if there aren't more than one inst term unless(cdr(net~>instTerms) instTerm=car(net~>instTerms) childTerm=instTerm~>term childPinFig=car(instTerm~>term~>pins)~>fig ; location within the instance master location=centerBox(childPinFig~>bBox) ; transform to the top level coordinate system location=dbTransformPoint(location instTerm~>inst~>transform) pinFigLocation=centerBox(pinFig~>bBox) ; calculate the overall transform to move the pin to the new location ;transform=dbConcatTransform(list(-xCoord(pinFigLocation):-yCoord(pinFigLocation) "R0" 1) location) transform=dbConcatTransform(list(-xCoord(pinFigLocation):-yCoord(pinFigLocation) "R0" 1) list(xCoord(location):yCoord(location) "R0" 1)) dbMoveFig(pinFig cv transform) ) ) ) )
Python (seems terribly long by comparison):#this code moves the pin shapes but not the labels
import sys from skillbridge import Workspace
class Pin: def init(self, net_name, bBox, label=None): self.net = Net(net_name) self.bBox = bBox self.label = label # Associate label with pin
class Label: def init(self, text, location): self.text = text self.location = location
class Net: def init(self, name): self.name = name
class Instance: def init(self, pin): self.pin = pin
class Shape: def init(self, pin): self.pin = pin
class Terminal: def init(self, name, pins): self.name = name self.pins = pins
class CellView: def init(self, libName, cellName, viewName, instances, shapes, terminals, labels): self.libName = libName self.cellName = cellName self.viewName = viewName self.instances = instances self.shapes = shapes self.terminals = terminals self.labels = labels
def get_current_cell_view(): try: ws = Workspace.open() # Initialize the workspace print("Workspace opened successfully.")
cv = ws.ge.get_edit_cell_view() # Get the currently open cell view
if cv:
print(f"Cell view opened: {cv.libName}, {cv.cellName}, {cv.viewName}")
instances = cv.instances if cv.instances is not None else [] # Ensure instances is not None
shapes = cv.shapes if cv.shapes is not None else [] # Ensure shapes is not None
terminals = cv.terminals if cv.terminals is not None else [] # Ensure terminals is not None
labels = cv.labels if cv.labels is not None else [] # Ensure labels is not None
return CellView(cv.libName, cv.cellName, cv.viewName, instances, shapes, terminals, labels)
print("Failed to open cell view.")
except Exception as e:
print(f"An error occurred: {e}")
return None
def centerBox(bBox): """Calculate the center of a bounding box.""" center_x = (bBox[0][0] + bBox[1][0]) / 2 center_y = (bBox[0][1] + bBox[1][1]) / 2 return [center_x, center_y]
def dbTransformPoint(point, transform): """Transform a point using the given transformation.""" x, y = point dx, dy = transform # Extract the first two elements directly return [x + dx, y + dy]
def dbConcatTransform(transform1, transform2): """Concatenate two transformations.""" x1, y1 = transform1 x2, y2 = transform2 return [x1 + x2, y1 + y2]
def dbMoveFig(pinFig, cv, transform): """Move the pin figure to the new location.""" new_location = dbTransformPoint(centerBox(pinFig.bBox), transform) pinFig.bBox = [[new_location[0] - 0.1, new_location[1] - 0.1], [new_location[0] + 0.1, new_location[1] + 0.1]] print(f"Moved pin to new location: {new_location}")
def dbMoveLabel(label, transform): """Move the label to the new location.""" new_location = dbTransformPoint(label.location, transform) label.location = new_location print(f"Moved label to new location: {new_location}")
def DVgetPinInfo(file=None): cv = get_current_cell_view() if cv is not None:
inst_pins = [x.pin for x in cv.instances if hasattr(x, 'pin') and x.pin is not None]
shape_pins = [x.pin for x in cv.shapes if hasattr(x, 'pin') and x.pin is not None]
if inst_pins or shape_pins:
all_pins = inst_pins + shape_pins
file_ptr = None
if isinstance(file, str):
file_ptr = open(file, 'w')
elif file is not None:
file_ptr = file
else:
file_ptr = sys.stdout
output_str = f"{cv.libName} {cv.cellName} {cv.viewName} contains the following pins:\n"
for pin in all_pins:
if pin and pin.net: # Check if pin is not None and has a net attribute
bBox = getattr(pin.fig, 'b_box', None) if hasattr(pin, 'fig') else None
layer = getattr(pin.fig, 'layer_name', 'Unknown') if hasattr(pin, 'fig') else 'Unknown'
purpose = getattr(pin.fig, 'purpose', 'Unknown') if hasattr(pin, 'fig') else 'Unknown'
if bBox:
x_dim = abs(bBox[1][0] - bBox[0][0])
y_dim = abs(bBox[1][1] - bBox[0][1])
center_x = (bBox[0][0] + bBox[1][0]) / 2
center_y = (bBox[0][1] + bBox[1][1]) / 2
output_str += f"Name: {pin.net.name:<5} bBox: {bBox} x_dim: {x_dim:.2f} y_dim: {y_dim:.2f} center: ({center_x:.2f}, {center_y:.2f}) layer: {layer} purpose: {purpose}\n"
else:
output_str += f"Name: {pin.net.name:<5} bBox: None layer: {layer} purpose: {purpose}\n"
print(output_str.strip(), file=file_ptr)
print(output_str.strip())
if file_ptr not in (sys.stdout, None):
file_ptr.close()
def DVMovePins(): cv = get_current_cell_view() if cv is not None: for term in cv.terminals: for pin in term.pins: pinFig = pin.fig net = term.net if len(net.instTerms) == 1: instTerm = net.instTerms[0] childTerm = instTerm.term childPinFig = childTerm.pins[0].fig location = centerBox(childPinFig.bBox) print(f"Original location: {location}") print(f"Transform: {instTerm.inst.transform}") location = dbTransformPoint(location, instTerm.inst.transform[0]) # Extract the first element which is the list print(f"Transformed location: {location}") pinFigLocation = centerBox(pinFig.bBox) transform = dbConcatTransform([-pinFigLocation[0], -pinFigLocation[1]], [location[0], location[1]]) print(f"Pin original location: {pinFigLocation}") print(f"Transform to apply: {transform}") dbMoveFig(pinFig, cv, transform) print(f"Pin new location: {centerBox(pinFig.bBox)}")
if pin.label:
dbMoveLabel(pin.label, transform)
DVgetPinInfo('output.txt') DVMovePins()
That's a lot of code. Can you try to isolate the parts that reproduce the problem. Otherwise it will take quite some time for me to go through all of that. I will do it when i find enough time, but a minimal example would really help me.
Yes, I apologize for that. An attempted "direct" translation of the Skill code to Skillbridge failed to move the label with its associated pin (pins move just fine, but not labels). I continued going deeper trying to select and move the labels with the pins. The standard Skill routine moves the labels with the pins automatically (as does any manual movement of pins in the Virtuoso tool--actually, you have to go out of your way to disassociate the label from its pin). I will try to recover (or recreate) the first and much simpler version of Skillbridge I had for this function. I would be nice to have this working in Skillbridge, but I also wanted to see if you know a way to run a regular Skill routine from Python/Skillbridge (load and execute in Cadence from Python). I have ways of doing it through a shell script, but would like to roll it into my Python code. Thanks you for your help.
OK, here is the starting (and much less convoluted) version. This correctly moves all pins to their XL compatible locations, but fails to move the labels.
import sys from skillbridge import Workspace
class Pin: def init(self, net_name, bBox): self.net = Net(net_name) self.bBox = bBox
class Net: def init(self, name): self.name = name
class Terminal: def init(self, name, pins): self.name = name self.pins = pins
class CellView: def init(self, libName, cellName, viewName, terminals): self.libName = libName self.cellName = cellName self.viewName = viewName self.terminals = terminals
def get_current_cell_view(): try: ws = Workspace.open() # Initialize the workspace print("Workspace opened successfully.") cv = ws.ge.get_edit_cell_view() # Get the currently open cell view if cv: print(f"Cell view opened: {cv.libName}, {cv.cellName}, {cv.viewName}") terminals = cv.terminals if cv.terminals is not None else [] # Ensure terminals is not None return CellView(cv.libName, cv.cellName, cv.viewName, terminals) print("Failed to open cell view.") except Exception as e: print(f"An error occurred: {e}") return None
def centerBox(bBox): """Calculate the center of a bounding box.""" center_x = round((bBox[0][0] + bBox[1][0]) / 2, 2) center_y = round((bBox[0][1] + bBox[1][1]) / 2, 2) return [center_x, center_y]
def dbTransformPoint(point, transform): """Transform a point using the given transformation.""" x, y = point dx, dy = transform # Extract the first two elements directly return [round(x + dx, 2), round(y + dy, 2)]
def dbConcatTransform(transform1, transform2): """Concatenate two transformations.""" x1, y1 = transform1 x2, y2 = transform2 return [round(x1 + x2, 2), round(y1 + y2, 2)]
def dbMoveFig(pinFig, cv, transform): """Move the pin figure to the new location.""" new_location = dbTransformPoint(centerBox(pinFig.bBox), transform) pinFig.bBox = [[new_location[0] - 0.1, new_location[1] - 0.1], [new_location[0] + 0.1, new_location[1] + 0.1]]
def DVMovePins(): cv = get_current_cell_view() if cv is not None: for term in cv.terminals: for pin in term.pins: pinFig = pin.fig net = term.net if len(net.instTerms) == 1: instTerm = net.instTerms[0] childTerm = instTerm.term childPinFig = childTerm.pins[0].fig location = centerBox(childPinFig.bBox) location = dbTransformPoint(location, instTerm.inst.transform[0]) # Extract the first element which is the list pinFigLocation = centerBox(pinFig.bBox) transform = dbConcatTransform([-pinFigLocation[0], -pinFigLocation[1]], [location[0], location[1]]) dbMoveFig(pinFig, cv, transform) else: print("No cell view found.")
DVMovePins()
I have a standard Skill routine that selects pins and snaps them to their XL compatible locations and the labels automatically move with them. The Skillbridge equivalent I've put together so far fails to move the labels with the pins. Is there something (an attribute, etc) I need to search for to select and move labels?