• 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 Design
  3. Question about skill script for Schematic rules checks

Stats

  • Locked Locked
  • Replies 2
  • Subscribers 125
  • Views 4292
  • 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

Question about skill script for Schematic rules checks

gkasap92
gkasap92 over 1 year ago

Hello,

I would like to ask 2 questions,

 

  1. I have created a script which reads the pin names of every schematic and checks if the naming format is correct.
    We would like to “pass” this script in Schematic rules checks up, thus every time a designer does not follow the correct format in the naming the schematic rules check will not allow to save the schematic.

 

  1. Could we also do the same with voltage markers on VDD & VSS only? My ideal goal would be if the designer has not put a voltage marker could not save the schematic.
    currently I have created a script which again reads every schematic and with the command: dbGetNetVoltageRange I print the Values of the voltage markers.

thank you in advance

  • Cancel
  • Andrew Beckett
    Andrew Beckett over 1 year ago

    Here's how you can easily add custom checks which are controllable in the same way as built-in checks, and you can set the severity appropriately. The checks aren't what you want, but you get the idea.

    /* abExampleSchematicCheckNew.ils
    
    Author     A.D.Beckett
    Group      Custom IC (UK), Cadence Design Systems Ltd.
    Language   SKILL
    Date       Oct 28, 2011 
    Modified   Jan 06, 2020 
    By         A.D.Beckett
    
    This is a reimplementation of some of the checks in abExampleSchematicCheck.ils
    but taking advantage of the new interface in IC615 to register checks with
    the system. As a result it is much simpler, and does not have to take care
    of creating marker objects itself; also gives the user the ability to override
    the check, or change the severity if needed.
    
    To register, call:
    
    abRegExampleSchematicCheckNew(?customerName "Your Customer Name")
    
    (with no arguments, it just calls the rule group "Customer")
    
    To enable just the category check, and disable the other checks
    
    abRegExampleSchematicCheckNew(
        ?customerName "ACME Corp"
        ?pdkName "gpdk090"
        ?category "Hidden"
        ?namingSeverity nil
        ?redundantNoConnSeverity nil
    )
    
    The ?namingSeverity, ?categorySeverity and ?redundantNoConnSeverity can be 
    set to 'error 'warning and 'ignored to set the default severity (or nil 
    if you don't want the check at all). The user can then override if needed 
    on Check->Rule Setup.
    
    ***************************************************
    
    SCCS Info: @(#) abExampleSchematicCheckNew.ils 01/06/20.15:01:09 1.5
    
    */
    
    ;------------------------------------------------------------------------
    ; The let is to create a lexical scope, so that there can be
    ; private functions which are used for some of the implementation
    ;------------------------------------------------------------------------
    let((checkPdkName categName categCache)
    
        /***********************************************************************
        *                                                                      *
        *      abRegExampleSchematicCheckNew ([?customerName "Customer"]       *
        *         [?namingSeverity 'error] [?categorySeverity 'error]          *
        *                 [?redundantNoConnSeverity 'warning]                  *
        *               [?pdkName nil] [?category "do_not_use"]                *
        *                                  )                                   *
        *                                                                      *
        *   PUBLIC GLOBAL function used to register the new check group and    *
        * some specific checks. In this case if the ?namingSeverity is non-nil *
        *   then it does a naming convention check; if ?categorySeverity is    *
        *     non-nil (and pdkName and category are strings) then a check      *
        *   for any component from that PDK and in an illegal category (such   *
        *          as "do_not_use" or "hidden") flags a check failure.         *
        *  ?redundantNoConnSeverity controls the check for any nets with two   *
        *  or more instTerms which aren't noConn components where there is a   *
        *                            noConn connected                          *
        *                                                                      *
        ***********************************************************************/
        defglobalfun(abRegExampleSchematicCheckNew (@key 
                (namingSeverity 'error) (categorySeverity 'error)
                (redundantNoConnSeverity 'warning)
                (customerName "Customer") pdkName (category "do_not_use"))
            ;----------------------------------------------------------------
            ; This registers a new tab on Check->Rules Setup
            ;----------------------------------------------------------------
            schRegisterCheckGroup(
                ?name concat(customerName)
                ?description strcat(customerName " checks")
            )
            ;----------------------------------------------------------------
            ; This registers the specific rules and default severity
            ;----------------------------------------------------------------
            when(symbolp(namingSeverity)
                schRegisterCheckRule(
                    ?title "Naming conventions"
                    ?name 'namingConventions
                    ?groupName concat(customerName)
                    ?severity namingSeverity
                    ?checkCB checkNamingConventions
                )
            )
    
            when(stringp(pdkName) && stringp(category) && symbolp(categorySeverity)
                checkPdkName=pdkName
                categName=category
                schRegisterCheckRule(
                    ?title sprintf(nil "Components from %s category" categName)
                    ?name 'illegalCategory
                    ?groupName concat(customerName)
                    ?severity categorySeverity
                    ?checkCB checkComponentsInCategory
                )
            )
    
            when(symbolp(redundantNoConnSeverity)
                schRegisterCheckRule(
                    ?title "Redundant noConn"
                    ?name 'redundantNoConn
                    ?groupName concat(customerName)
                    ?severity redundantNoConnSeverity
                    ?checkCB checkRedundantNoConn
                )
            )
        )
    
        /*********************************************************************
        *                                                                    *
        *               checkNamingConventions(cv ruleObject)                *
        *                                                                    *
        * INTERNAL function used to actually implement the naming convention *
        *                               check.                               *
        *                                                                    *
        *********************************************************************/
        defun(checkNamingConventions (cv ruleObject)
            let((obj label netTable signals sigTable)
                ;------------------------------------------------------------
                ; Check that terminal names are in upper case
                ;------------------------------------------------------------
                foreach(term cv~>terminals
                    unless(term~>name==upperCase(term~>name)
                        ;----------------------------------------------------
                        ; Place the marker on the first pin - no need to
                        ; put it on every pin if there are multiple pins
                        ;----------------------------------------------------
                        obj=car(term~>pins~>fig) || cv
                        schReportCheckFailure(
                            ?object obj
                            ?checkRule ruleObject
                            ?short "Terminals not upper case"
                            ?message
                                sprintf(nil "Terminals must be in upper case: %s" 
                                    term~>name
                                ) 
                        ) 
                    ) ; unless
                ) ; foreach
                ;------------------------------------------------------------
                ; Check for internal nets which have a lower case name
                ;------------------------------------------------------------
                foreach(net cv~>nets
                    ;--------------------------------------------------------
                    ; Only worry about nets which have a label
                    ;--------------------------------------------------------
                    label=car(exists(fig net~>figs fig~>objType=="label"))
                    when(label
                        when(exists(sig net~>signals 
                            ;------------------------------------------------
                            ; Check that the signal is not part of a 
                            ; terminal, and is not in lowercase
                            ;------------------------------------------------
                            !sig~>memTerms && sig~>name!=lowerCase(sig~>name))
                            schReportCheckFailure(
                                ?object label
                                ?checkRule ruleObject
                                ?short "Internal nets not lower case"
                                ?message
                                    sprintf(nil "Internal net names must be in lower case: %s"
                                        net~>name
                                    ) 
                            ) 
                        ) ; when there is a lower internal net name on net
                    ) ; when there's a label
                ) ; foreach
                ;------------------------------------------------------------
                ; Check for any nets which only differ in case
                ;------------------------------------------------------------
                ;------------------------------------------------------------
                ; record all the signals together in a table indexed by
                ; the flattened case. Then use a table to record all
                ; member nets which have a mixed-case problem
                ;------------------------------------------------------------
                sigTable=makeTable('sigTable nil)
                netTable=makeTable('netTable nil)
                foreach(sig cv~>signals
                    sigTable[lowerCase(sig~>name)]=
                        cons(sig sigTable[lowerCase(sig~>name)])
                ) ; foreach
                foreach(tableEntry sigTable
                    signals=sigTable[tableEntry]
                    ;--------------------------------------------------------
                    ; If there was more than one signal with the
                    ; same flattened case, then there's
                    ; a mixed name problem. Record the member nets
                    ; in a table (to avoid duplication)
                    ;--------------------------------------------------------
                    when(cdr(signals)
                        foreach(sig signals
                            foreach(memNet sig~>memNets
                                netTable[car(memNet)]=signals
                            ) ; foreach memNet
                        ) ; foreach sig
                    ) ; when
                ) ; foreach 
                foreach(net netTable
                    ;--------------------------------------------------------
                    ; Find something suitable to put the marker on
                    ;--------------------------------------------------------
                    cond(
                        ;----------------------------------------------------
                        ; Use the pin if there is one
                        ;----------------------------------------------------
                        (net~>term~>pins
                            obj=car(net~>term~>pins~>fig)
                        )
                        ;----------------------------------------------------
                        ; Otherwise use the label
                        ;----------------------------------------------------
                        (obj=car(
                            exists(shape net~>figs 
                                shape~>objType=="label"))
                            t
                        )
                        ;----------------------------------------------------
                        ; Next try a wire
                        ;----------------------------------------------------
                        (obj=car(
                                exists(shape net~>figs
                                    shape~>objType=="line" ||
                                    shape~>objType=="path")
                            )
                            t
                        )
                        ;----------------------------------------------------
                        ; Finally, if nothing else, use the cellView
                        ;----------------------------------------------------
                        (t
                            obj=cv
                        )
                    ) ; cond
                    schReportCheckFailure(
                        ?object obj 
                        ?checkRule ruleObject
                        ?short "Net differing only in case"
                        ?message
                            sprintf(nil 
                                "Net %L cannot differ only in case from others: %L" 
                                net~>name
                                netTable[net]~>name
                            )
                    )
                ) ; foreach
            ) ; let
        ) ; defun checkNamingConventions
    
        /***************************************************************
        *                                                              *
        *             checkRedundantNoConn(cv ruleObject)              *
        *                                                              *
        *  Internal function to check if there are any noConn objects  *
        * on nets that don't need them (i.e. if there are two or more  *
        * non-noConninstTerms connected to a net that has at least one *
        *                            noConn                            *
        *                                                              *
        ***************************************************************/
        defun(checkRedundantNoConn (cv ruleObject)
            let((noConnCount noConns instTermCount)
                foreach(net cv~>nets
                    noConnCount=0
                    ;--------------------------------------------------------
                    ; If there's a terminal on the net, that counts too
                    ;--------------------------------------------------------
                    instTermCount=if(net~>term then 1 else 0)
                    noConns=nil
                    foreach(instTerm net~>instTerms
                        ;----------------------------------------------------
                        ; Uses the schType to determine if this is a noConn
                        ; or not
                        ;----------------------------------------------------
                        if(instTerm~>inst~>master~>schType=="noConn" then
                            noConnCount++
                            noConns=cons(instTerm~>inst noConns)
                        else
                            instTermCount++
                        )
                    )
                    when(noConnCount>0 && instTermCount>=2
                        foreach(noConn noConns
                            schReportCheckFailure(
                                ?object noConn 
                                ?checkRule ruleObject
                                ?short "Redundant noConn"
                                ?message
                                    "noConn on net with two or more connections"
                            )
                        )
                    )
                )
                t
            )
        )
    
        /***************************************************************
        *                                                              *
        *          checkComponentsInCategory (cv ruleObject)           *
        *                                                              *
        * INTERNAL function. Check for any components in the specified *
        *   category from the given pdk library name (specified when   *
        *          abRegExampleSchematicCheckNew was called).          *
        *                                                              *
        ***************************************************************/
        defun(checkComponentsInCategory (cv ruleObject)
            let((catId libId)
                /***************************************************************
                *                                                              *
                *                traverseCategory (libId catId)                *
                *                                                              *
                *   Local function to recursively traverse the category and    *
                *      update the cache with any cells in sub-categories       *
                *                                                              *
                ***************************************************************/
                defun(traverseCategory (libId catId)
                    let((subCatId)
                        foreach(catMember catId && ddCatGetCatMembers(catId)
                            case(cadr(catMember)
                                ("cell" categCache[car(catMember)]=t)
                                ("category" 
                                    subCatId=ddCatOpen(libId car(catMember) "r")
                                    when(subCatId
                                        traverseCategory(libId subCatId)
                                        ddCatClose(subCatId)
                                    )
                                )
                            )
                        )
                    )
                )
                ;------------------------------------------------------------
                ; If the cache has not been populated yet, do so now
                ;------------------------------------------------------------
                when(checkPdkName && !categCache
                    libId=ddGetObj(checkPdkName)
                    when(libId
                        categCache=makeTable('categCache nil)
                        catId=ddCatOpen(libId categName "r")
                        when(catId
                            traverseCategory(libId catId)
                            ddCatClose(catId)
                        )
                    )
                )
                ;------------------------------------------------------------
                ; Check for any instances which are from the PDK, and are
                ; in the cache of the disallowed category
                ;------------------------------------------------------------
                when(checkPdkName && categCache
                    foreach(inst cv~>instances
                        when(inst~>libName==checkPdkName && 
                                categCache[inst~>cellName]
                            schReportCheckFailure(
                                ?object inst 
                                ?checkRule ruleObject
                                ?short "Component from illegal category"
                                ?message
                                    sprintf(nil "%s is in the %s category of %s" 
                                        inst~>cellName
                                        categName
                                        checkPdkName
                                    ) ; sprintf
                            )
                        )
                    )
                ) 
            ) 
        )
    
    )
    

    • Cancel
    • Vote Up +1 Vote Down
    • Cancel
  • gkasap92
    gkasap92 over 1 year ago in reply to Andrew Beckett

    thanks very much!!! I i will try it 

    • 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