1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
###############################################################################
# Copyright (c) 2015-2024 by Altair Engineering, Inc.
# All rights reserved.
#
# Altair Engineering, Inc. makes this software available as part of the Vision
# tool platform.  As long as you are a licensee of the Vision tool platform
# you may make copies of the software and modify it to be used within the
# Vision tool platform, but you must include all of this notice on any copy.
# Redistribution without written permission to any third party, with or
# without modification, is not permitted.
# Altair Engineering, Inc. does not warrant that this software is error free
# or fit for any purpose.  Altair Engineering, Inc. disclaims any liability for
# all claims, expenses, losses, damages and costs any user may incur as a
# result of using, copying or modifying the software.
# =============================================================================
#   @script
#       Replace BUF
###############################################################################


# =============================================================================
# ReplaceBuf - Update the cell referenced of all built-in buffer instances
#              with a new cell, e.g. coming from a library.
# =============================================================================
#
proc ReplaceBuf {bufferCellName db} {
    ##
    # Return if the database is empty.
    #
    if {$db == {}} {
        return
    }

    ##
    # Get the cell OID of the buffer given by its name.
    #
    set bufferCell [$db search cell $bufferCellName]
    if {[$db oid isnull $bufferCell]} {
        error "Buffer '$bufferCellName' not found."
    }

    ##
    # Set the Boolean variables indicating which method was used to update
    # the cellRef of the Buf instances.
    #
    set operUsed  0
    set zombieSet 0

    $db foreach module module {
        ##
        # Need to create a list with all instances to process because the
        # updateCellRef procedure may change the instance list.
        #
        set instList {}
        $db foreach inst $module inst {
            if {[$db primFuncOf $inst] == "BUF"} {lappend instList $inst}
        }


        ##
        # Now loop only over 'Buf' instances and update the cellRef.
        #
        foreach inst $instList {
            set oldCell [$db down $inst]
            if {[$db identicalInterface $oldCell $bufferCell]} {
                set operUsed 1
                $db oper changecellref -updateOIDs $inst $bufferCellName
            } else {
                set zombieSet 1

                ##
                # Get the current connectivity.
                #
                array set _conNet {input {} output {}}
                $db foreach pin $inst pin {
                    set dir [$db directionOf $pin]
                    set _conNet($dir) [$db connectedNet $pin]
                }

                ##
                # get the name of the existing instance.
                #
                set iName [$db oid oname $inst]

                ##
                # Rename the existing instance and flag it as a zombie.
                #
                $db flag $inst set zombie
                $db oper rename $inst "__zombie__${iName}__zombie__"

                ##
                # Load an instance of the new buffer cell.
                #
                $db reloadModule [$db oid oname $module]
                $db load inst $iName $bufferCellName

                ##
                # Add the connectivity to the new inst.
                #
                $db foreach port $bufferCell port {
                    set dir     [$db directionOf $port]
                    set pinName [$db oid oname   $port]
                    set netName [$db oid oname   $_conNet($dir)]
                    $db load net $netName -pin $iName $pinName
                }
            }
        }
    }

    ##
    # Only call the expensive update calls if necessary.
    #
    if {$zombieSet} {
        $db deleteZombies
    }
    if {$operUsed}  {
        $db oper changecellref -updateOIDs
    }

    ##
    # Inform the GUI that the database was modified.
    #
    gui database modified
}


##
# Use gui database runOrRegisterChangedCallback to immediately run
# ReplaceBuf ni01d1_ll
# if we have a database, or otherwise register the proc to be executed after
# the database is available.
#
gui database runOrRegisterChangedCallback [list ReplaceBuf ni01d1_ll]