• 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. Schematic net/inst name mapping: case-insensitive to case...

Stats

  • Locked Locked
  • Replies 9
  • Subscribers 144
  • Views 6684
  • 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

Schematic net/inst name mapping: case-insensitive to case-sensitive

tweeks
tweeks over 13 years ago
Here's a fun SKILL problem to chew on:

I have a tool that reads SPF (Standard Parasitic Format) files and spits out case-INsensitive hierarchical net and instance names. I want to probe them in Virtuoso Schematic Editor (latest version) using geAddNetProbe().

Problem: how to map the case-insensitive names from the SPF tool like this

"/rtop/r<0>/rdb<0>/decovst/nd_share"

to names that will be recognized by geAddNetProbe() like this:

"/rtop/r<0>/rdb<0>/DECOVST/nd_share"

(in this case, "DECOVST" is in upper-case in the Virtuoso schematic.)

You can assume there will never be a schematic with two instance or net names differentiated only by case.

I'd like to avoid traversing the entire hierarchy to build a mapping table of every instance and net name, but as I comb the SKILL docs, it's starting to look like there is no other way....

   --tweeks
  • Cancel
Parents
  • tweeks
    tweeks over 13 years ago

    Thanks Derek & Andrew for the thoughtful advice.

    I thought I'd share my SKILL++ implementation of #2. You were right: it wasn't much code at all.

    ;;; Macros
    
    ;; For those who are tired of (sprintf nil ...)
    ;; Using defmacro instead of defun protects the args from being eval'd twice.
    (defmacro format (string @rest objects)
      `(sprintf nil ,string ,@objects))
    
    (defmacro find (var xs body)
      "First element in XS matching the predicate BODY."
      `(car (exists ,var ,xs ,body)))
    
    ;;; General functions
    
    (defun caseInsensitivelyEqual (r s "tt")
      "Compare two strings case-insensitively."
      (eqv (upperCase r) (upperCase s)))
    
    (defun dropLast (xs "l")
      (if (cddr xs)
          (cons (car xs) (dropLast (cdr xs)))
        (list (car xs))))
    
    ;; foldl :: (b -> a -> b) -> b -> [a] -> b
    (defun foldl (f e xs "ugl")
      (if (null xs)
          e
        (foldl f (f e (car xs)) (cdr xs))))
    
    ;;; Specific functions
    
    ;; Instance name constructor and destructor
    ;; bkInstName . mkInstName = id
    
    ;; (mkInstName "foo")   => "foo"
    ;; (mkInstName "foo" 3) => "foo<3>"
    (defun mkInstName (baseName @optional instNum "tg")
      (strcat baseName (if instNum (format "<%d>" instNum) "")))
    
    ;; (bkInstName "foo")    => ("foo" nil)
    ;; (bkInstName "foo<3>") => ("foo" 3)
    (defun bkInstName (name "t")
      (destructuringBind (baseName @optional instNum) (parseString name "<>")
        (list baseName (when instNum (atoi instNum)))))
    
    ;; (baseName "foo")    => "foo"
    ;; (baseName "foo<3>") => "foo"
    (defun baseName (name "t")
      (car (bkInstName name)))
    
    ;; (instNum "foo")    => nil
    ;; (instNum "foo<3>") => 3
    (defun instNum (name "t")
      (cadr (bkInstName name)))
    
    ;; (findNetName cv "vss") => "VSS"
    (defun findNetName (cv name "dt")
      (or (find sigName cv->sigNames
            (caseInsensitivelyEqual sigName name))
          (error "Can't find net %L in cellview %L"
                 name (list cv->libName cv->cellName cv->viewName))))
    
    (defun findInst (cv name "dt")
      (or (find inst cv->instances
            (caseInsensitivelyEqual inst->baseName (baseName name)))
          (error "Can't find instance %L in cellview %L"
                 name (list cv->libName cv->cellName cv->viewName))))
    
    ;; nextInst :: (cellView, pathString) -> instName -> (cellView, pathString)
    (defun nextInst (cvPath instName "lt")
      (destructuringBind (cv path) cvPath
        (let ((inst (findInst cv instName)))
          (list (dbGetAnyInstSwitchMaster inst "schematic")
                (strcat path "/" (mkInstName inst->baseName (instNum instName)))))))
    
    ;; resolve :: cellView -> [instName] -> (cellView, pathString)
    (defun resolve (cv path "dl")
      (foldl nextInst (list cv "") path))
    
    ;; (correctCase 'inst cv "/RtOp/TrKwLbLk/TrKrOw/DeCoVsT")
    ;;   => "/rtop/trkwlblk/trkrow/DECOVST"
    ;; (correctCase 'net cv "/RtOp/TrKwLbLk/TrKrOw/DeCoVsT/nEt06")
    ;;   => "/rtop/trkwlblk/trkrow/DECOVST/net06"
    (defun correctCase (objType topCv path "sdt")
      (let ((p (parseString path "/")))
        (if (eq objType 'inst)
            (cadr (resolve topCv p))
          (destructuringBind (botCv correctPath) (resolve topCv (dropLast p))
            (strcat correctPath "/" (findNetName botCv (car (last p))))))))
    
    
    
    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Reply
  • tweeks
    tweeks over 13 years ago

    Thanks Derek & Andrew for the thoughtful advice.

    I thought I'd share my SKILL++ implementation of #2. You were right: it wasn't much code at all.

    ;;; Macros
    
    ;; For those who are tired of (sprintf nil ...)
    ;; Using defmacro instead of defun protects the args from being eval'd twice.
    (defmacro format (string @rest objects)
      `(sprintf nil ,string ,@objects))
    
    (defmacro find (var xs body)
      "First element in XS matching the predicate BODY."
      `(car (exists ,var ,xs ,body)))
    
    ;;; General functions
    
    (defun caseInsensitivelyEqual (r s "tt")
      "Compare two strings case-insensitively."
      (eqv (upperCase r) (upperCase s)))
    
    (defun dropLast (xs "l")
      (if (cddr xs)
          (cons (car xs) (dropLast (cdr xs)))
        (list (car xs))))
    
    ;; foldl :: (b -> a -> b) -> b -> [a] -> b
    (defun foldl (f e xs "ugl")
      (if (null xs)
          e
        (foldl f (f e (car xs)) (cdr xs))))
    
    ;;; Specific functions
    
    ;; Instance name constructor and destructor
    ;; bkInstName . mkInstName = id
    
    ;; (mkInstName "foo")   => "foo"
    ;; (mkInstName "foo" 3) => "foo<3>"
    (defun mkInstName (baseName @optional instNum "tg")
      (strcat baseName (if instNum (format "<%d>" instNum) "")))
    
    ;; (bkInstName "foo")    => ("foo" nil)
    ;; (bkInstName "foo<3>") => ("foo" 3)
    (defun bkInstName (name "t")
      (destructuringBind (baseName @optional instNum) (parseString name "<>")
        (list baseName (when instNum (atoi instNum)))))
    
    ;; (baseName "foo")    => "foo"
    ;; (baseName "foo<3>") => "foo"
    (defun baseName (name "t")
      (car (bkInstName name)))
    
    ;; (instNum "foo")    => nil
    ;; (instNum "foo<3>") => 3
    (defun instNum (name "t")
      (cadr (bkInstName name)))
    
    ;; (findNetName cv "vss") => "VSS"
    (defun findNetName (cv name "dt")
      (or (find sigName cv->sigNames
            (caseInsensitivelyEqual sigName name))
          (error "Can't find net %L in cellview %L"
                 name (list cv->libName cv->cellName cv->viewName))))
    
    (defun findInst (cv name "dt")
      (or (find inst cv->instances
            (caseInsensitivelyEqual inst->baseName (baseName name)))
          (error "Can't find instance %L in cellview %L"
                 name (list cv->libName cv->cellName cv->viewName))))
    
    ;; nextInst :: (cellView, pathString) -> instName -> (cellView, pathString)
    (defun nextInst (cvPath instName "lt")
      (destructuringBind (cv path) cvPath
        (let ((inst (findInst cv instName)))
          (list (dbGetAnyInstSwitchMaster inst "schematic")
                (strcat path "/" (mkInstName inst->baseName (instNum instName)))))))
    
    ;; resolve :: cellView -> [instName] -> (cellView, pathString)
    (defun resolve (cv path "dl")
      (foldl nextInst (list cv "") path))
    
    ;; (correctCase 'inst cv "/RtOp/TrKwLbLk/TrKrOw/DeCoVsT")
    ;;   => "/rtop/trkwlblk/trkrow/DECOVST"
    ;; (correctCase 'net cv "/RtOp/TrKwLbLk/TrKrOw/DeCoVsT/nEt06")
    ;;   => "/rtop/trkwlblk/trkrow/DECOVST/net06"
    (defun correctCase (objType topCv path "sdt")
      (let ((p (parseString path "/")))
        (if (eq objType 'inst)
            (cadr (resolve topCv p))
          (destructuringBind (botCv correctPath) (resolve topCv (dropLast p))
            (strcat correctPath "/" (findNetName botCv (car (last p))))))))
    
    
    
    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Children
No Data

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