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
###############################################################################
# Copyright (c) 2013-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.
# =============================================================================
#   @userware
#       Detect Cells Directly Connected to Input 2
#   @section
#       Analyze the Loaded Database
#   @description
#       Detect and highlight any FF/latches (with specific std cell name
#       pattern) that is directly connected to the input ports (directly driven
#       by input ports without any buffers/inverters).
#   @files
#       cust22/directlyConnectedFlops2.tcl
#   @tag
#       zdb
###############################################################################


# -----------------------------------------------------------------------------
# _findDirectlyConnectedFFs2 - Detect and highlight any FF/latches (with
#                              specific std cell name) where one of the given
#                              input pins is directly connected (without any
#                              buffers/inverters) to a top level input ports.
# -----------------------------------------------------------------------------
#
proc _findDirectlyConnectedFFs2 {db} {
    ##
    # Return if the database is empty.
    #
    if {$db == {}} {
        return
    }

    ##
    # Set the name of the created report file.
    #
    set reportFile "directlyConnectedFlops.txt"

    ##
    # Initialize a hash table with the std cell name pattern as the key and a
    # list of input ports as the value.  All given input ports at all
    # instances of these cells are investigated.
    #
    array set stdCellFFConfig {
        "SEL_FDNRBQ_1"          "D"
        "DFFRS"                 "d"
    }

    ##
    # Loop over all cells and ports of each cell and clear the red flag.
    #
    $db foreach cell cell {
        $db flag $cell clear red
        $db foreach port $cell port {$db flag $port clear red}
    }

    ##
    # Iterate over all keys of the 'stdCellFFConfig' hash table and try to find
    # a cell with this name in the current design.  If a cell could be found
    # then loop over all values for the key and try find ports with the given
    # names.  Mark all cells and ports that match with the 'red' flag.
    #
    foreach {cellName portList} [array get stdCellFFConfig] {
        ##
        # Search the cell and flag with 'red' if found.
        #
        set cell [$db search cell $cellName]
        if {[$db oid isnull $cell]} {
            zmessage print WAR "Could not find cell '$cellName'."
            continue
        }
        $db flag $cell set red

        ##
        # Search each port and flag with 'red' if found.
        #
        foreach portName $portList {
            set notFound 0
            set port [$db search port $cell $portName]
            if {[$db oid isnull $port]} {
                set notFound 1
            }

            if {$notFound} {
                set port [$db search portBus $cell $portName]
                if {![$db oid isnull $port]} {
                    set notFound 0
                }
            }

            if {$notFound} {
                zmessage print WAR \
                    "Could not find port '$portName' at $cellName."
                continue
            }

            $db flag $port set red
            if {[$db oid type $port] == "portBus"} {
                $db foreach port $port subPort {$db flag $subPort set red}
            }
        }
    }

    ##
    # Loop over all top modules in the topList and inside the top find all
    # instances of the red flagged cell.
    #
    array set _result {}
    $db foreach top top {
        $db flat foreach instOfCell red $top inst {
            $db foreach pin $inst pin {
                if {![$db flag [$db down $pin] is red]} {
                    continue
                }
                if {![$db isConnected $pin]} {
                    continue
                }

                set net [$db connectedNet $pin]
                $db flat foreach pin $net conPin {
                    if {[$db oid type $conPin] == "port"} {
                        if {[$db directionOf $conPin] == "input"} {
                            set signal [$db oid convertTo signal $net]
                            $db flathilight $inst   set 0
                            $db flathilight $pin    set 1
                            $db     hilight $conPin set 1
                            $db flathilight $signal set 1
                            set _result($pin) [list $conPin $signal]
                        }
                    }
                }
            }
        }
    }

    gui highlight changed

    ##
    # Create the report file.
    #
    set report [open $reportFile "w"]
    set resultList {}
    foreach {pin conDetail} [array get _result] {
        lappend resultList $pin [lindex $conDetail 0] [lindex $conDetail 1]
        lappend resultList "----"

        set inst   [$db oid convertTo inst $pin]
        set port   [lindex $conDetail 0]
        set signal [lindex $conDetail 1]
        set pName  [$db oid pname $pin]
        puts $report "$inst:$pName\t$port\t$signal"
    }
    close $report

    ##
    # Show the result in the 'Mem' tab.
    #
    gui window show Mem
    gui mem append $resultList
}


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