• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Community Forums
  2. Custom IC SKILL
  3. bug in dbTransformPoint()?

Stats

  • Locked Locked
  • Replies 2
  • Subscribers 143
  • Views 14667
  • Members are here 0
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

bug in dbTransformPoint()?

Kevin Earls
Kevin Earls over 6 years ago

Anyone ever notice the bug in dbTransformPoint() when the orient is "R90" or "R270"?

I wrote skill code to place a poly via on Pcells automatically. But when I wanted to get the relative offset of the xy of a poly via (child of device) to the device's xy,
I found that dbTransformPoint gives different results based on the orientation.
Or am I somehow using dbTransformPoint() incorrectly?
The code below works except the values are minus'ed (negative values are positive, and visa-versa) when the orient is "R90" or "R270".
 

(foreach obj geGetSelectedSet()
    (foreach via (setof s obj~>children s~>objType=="stdVia")
           (printf "%6s (%6s) => %L\n"
obj~>name
obj~>orient
dbTransformPoint(mapcar('difference via~>xy obj~>xy)
list(0:0 obj~>orient 1.0)))))
    I1 (   R90) => (-2.15 -2.05)
    I2 ( MYR90) => (2.15 2.05)
    I3 (  R180) => (2.15 2.05)
    I4 (    MX) => (2.15 2.05)
    I8 (  R270) => (-2.15 -2.05)
    I0 (    R0) => (2.15 2.05)
    I5 (    MY) => (2.15 2.05)
    I7 ( MXR90) => (2.15 2.05)



Working with Virtuoso 6.17-64b

  • Cancel
  • Andrew Beckett
    Andrew Beckett over 6 years ago

    No, there's not a bug. It's really hard to see what you're comparing but it's very clear from some simple experiments that the transformation does the rotation of the coordinate around the origin, then applies the offset in the transformation. With the orientation if it's a compound orientation such as MYR90, it does it left to right (mirror in Y then rotate (anticlockwise) by 90 degrees). 

    So, for example:

    orients=list("R90" "MYR90" "R180" "MX" "R270" "R0" "MY" "MXR90")
    xy=2.15:2.05
    first=foreach(mapcar orient orients cons(orient dbTransformPoint(xy list(0:0 orient 1))))

    This produces:

    (
      ("R90" -2.05 2.15)
      ("MYR90" -2.05 -2.15)
      ("R180" -2.15 -2.05)
      ("MX" 2.15 -2.05)
      ("R270" 2.05 -2.15)
      ("R0" 2.15 2.05)
      ("MY" -2.15 2.05)
      ("MXR90" 2.05 2.15)
    )

    You can see that these are all correct. In your case the differences between the two origins are probably not the same so I'm not quite comparing like with what you're doing, but the transformation is absolutely correct. 

    second=foreach(mapcar orient orients cons(orient dbTransformPoint(xy list(-1:2.5 orient 1))))

    (
      ("R90" -1.05 3.15)
      ("MYR90" -1.05 -1.15)
      ("R180" -1.15 -1.05)
      ("MX" 3.15 -1.05)
      ("R270" 3.05 -1.15)
      ("R0" 3.15 3.05)
      ("MY" -1.15 3.05)
      ("MXR90" 3.05 3.15)
    )

    You can see that this is just a fixed offset of -1:2.5 from above, so the offset is applied afterwards.

    If you're just looking at the relative offset from the xy of the via to the xy of the device, isn't that just the difference in the xy values? I'm not sure why you would need to transform anything? Perhaps I've misunderstood what you're hoping to calculate?

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Kevin Earls
    Kevin Earls over 6 years ago in reply to Andrew Beckett

    I really doubted that I had found a bug, but I couldn't quite grasp what was going wrong. My goal with this code was to get the _relative_ offset between an absolute point to an instance's xy based on if the instance was at 0:0 "R0". I calculate the relative offset for the via by reading the shapes bBoxes in the PCell master. All of these values are relative to the device's origin. I then place the via by transforming the relative xy by using the device's transform. That works perfectly. But I also need to go the other way, take the absolute via xy and calculate the relative offset to the device. The via's xy is now an absolute value, so I need to transform that back to the relative offset from the device. Hence, my (incorrect) use of the dbTransformPoint.

    After some thought and experimentation and some help from others. I came up with this code that calculates what I want.

    (procedure getRelativeOffset(obj pt)
    (let (offset)
        ; return the x and y offset of a point relative to the obj~>xy as if the orientation was "R0"
        offset = dbInvertTransform(dbInvertTransform(list(mapcar('difference pt obj~>xy) obj~>orient 1.0)))
        car(offset)
    ))
    (defun dbInvertTransform (transform)
        dbConcatTransform(transform cons(0:0 cdr(transform)))
    )

    The key revelation was that you can combine orientations by itself, twice (for R90 and R270), and get back to R0.
    R0+R0=R0
    R90+R90=R180
    R180+R180=R0
    R270+R270=R180
    MX+MX=R0
    MY+MY=R0
    MXR90+MXR90=R0
    MYR90+MYR90=R0

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel

Community Guidelines

The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.

© 2025 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information