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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
###############################################################################
# Copyright (c) 2012-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
#       Alternative implementation to create a flat version of a design
#       this time using the '$db flat foreach ...' API.
#       In this version the leaf cells can (optionally) be defined by the user.
###############################################################################


##
# The flattening algorithm can be stop at a specific level. This list defines
# the names of all (non-primitive) leaf cells.
#
set leafCellList {}


# -----------------------------------------------------------------------------
# _makeFlatName -  Create a flat object name.
# -----------------------------------------------------------------------------
#
proc _makeFlatName {db inst hierSep} {
    set flatName ""
    foreach path [$db oid path $inst] {
        append flatName ${path}${hierSep}
    }
    append flatName [$db oid oname $inst]
    return $flatName
}


# -----------------------------------------------------------------------------
# flatDesign2 - Loop over all tops, unfold the design tree and call doRmHier.
# -----------------------------------------------------------------------------
#
proc flatDesign2 {db} {
    global leafCellList

    ##
    # Return if the database is empty.
    #
    if {$db == {}} {
        return
    }

    ##
    # Remove the callback that is installed with 'Gui"RegisterDataBaseChanged'
    # because at the end of this procedure 'gui database changed' is called.
    #
    gui database removeChangedCallback "flatDesign2"

    ##
    # Enable the progress bar.
    #
    zprogress begin

    ##
    # Get the current hierarchy separator.
    #
    set hierSep [$db oper hiersep get]

    ##
    # Push 100% to the progress bar.
    #
    zprogress push "flat" 1.0

    ##
    # Set the 'libcell' flag at all user defined leaf cells.
    #
    foreach leaf $leafCellList {
        set cell [$db search cell $leaf]
        if {[$db oid isnull $cell]} {
            continue
        }
        $db flag $cell set libcell
    }
    if {[llength $leafCellList] > 0} {
        $db setPrimitive -libcell
    }

    ##
    # Flag all primitives with the blue flag.
    #
    $db foreach primitive primitive {$db flag $primitive set blue}

    ##
    # Get a list with all top modules, also count the number of signals and
    # flat instances for accurate progress updates.
    #
    set topList   {}
    set instCount 0
    set sigCount  0
    $db foreach top top {
        lappend topList $top
        $db flat foreach instOfCell blue $top inst   {incr instCount}
        $db flat foreach signal          $top signal {incr sigCount }
    }

    ##
    # Currently this implementation can only handle one top module.
    #
    if {[llength $topList] > 1} {
        error "This function can only handle one top."
    }

    ##
    # Now loop over the only top and create a flat version of the design in a
    # new top module.
    #
    set oldTopName ""
    set newTopName ""
    foreach top $topList {
        set oldTopName [$db oid oname $top]
        set newTopName "${oldTopName}__NEW__FLAT___TOP__"

        $db load module $newTopName -top

        zprogress push "instances" 0.3
        set i 0
        $db flat foreach instOfCell blue $top inst {
            if {[zprogress update "" [incr i] $instCount]} {
                break
            }

            set cmd     [list $db load inst]
            lappend cmd [_makeFlatName $db $inst $hierSep]
            lappend cmd [$db oid cname $inst]
            foreach flag [$db flag $inst get] {lappend cmd -flag $flag}
            foreach attr [$db attr $inst get] {lappend cmd -attr $attr}
            eval $cmd
        }
        if {[zprogress pop]} {
            break
        }

        zprogress push "connectivity" 1.0
        set s 0
        $db flat foreach signal $top signal {
            if {[zprogress update "" [incr s] $sigCount]} {
                break
            }

            if {[$db isPgNet $signal]} {
                set netName [$db oid oname $signal]
            } else {
                set netName [_makeFlatName $db $signal $hierSep]
            }

            set cmd [list $db load net $netName]

            foreach flag [$db flag $signal get] {lappend cmd -flag $flag}
            foreach attr [$db attr $signal get] {lappend cmd -attr $attr}

            $db flat foreach pin $signal pin {
                if {[$db oid type $pin] == "port"} {
                    $db load port [$db oid oname $pin] [$db directionOf $pin]
                    lappend cmd -port [$db oid oname $pin]
                } else {
                    set inst     [$db oid convertTo inst $pin]
                    set instName [_makeFlatName $db $inst $hierSep]
                    lappend cmd -pin $instName [$db oid pname $pin]
                }
            }
            eval $cmd
        }
        if {[zprogress pop]} {
            break
        }
    }

    if {[zprogress pop]} {
        return
    }

    ##
    # Finish the progress bar.
    #
    zprogress end

    ##
    # Define the flat module as the new top.
    #
    if {($oldTopName != "") && ($newTopName != "")} {
        set newTopOid [$db search top $newTopName]
        $db oper deftop $newTopOid
        $db oper rename $newTopOid $oldTopName
        $db oper deleteUnused
        $db oper bulk wrong
    }

    ##
    # Scan the database for a new unused character used as the
    # new hierarchy separator.
    #
    set hiersep [$db oper hiersep scan]
    $db hiersep $hiersep

    ##
    # Reset the 'libcell' flag.
    #
    foreach leaf $leafCellList {
        set cell [$db search cell $leaf]
        if {[$db oid isnull $cell]} {
            continue
        }
        $db flag $cell clear libcell
    }

    ##
    # Inform the GUI that the database has changed.
    #
    gui database changed $db
}


# -----------------------------------------------------------------------------
# flatDesign2FromMenu - Called from main menu.
# -----------------------------------------------------------------------------
#
proc flatDesign2FromMenu {} {
    flatDesign2 [gui database get]
}


# =============================================================================
# Add "Flat Design" to a new Userware main menu.
# =============================================================================
#
gui menu command {"Userware" "Flat Design 2"} {flatDesign2FromMenu}


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