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
###############################################################################
# Copyright (c) 2009-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
#       Highlight for Voltage
#   @section
#       Miscellaneous Userware Examples
#   @description
#       This example shows how to use the waveform parser to
#             - read a DC analysis result file
#             - traverse all curves defined in this file
#             - create voltage attributes on corresponding nets in the schematic
#
#       - Load the spice netlist "demo/spice/Fig24_30/Fig24_30.sp".
#       - Load this userware file.
#       - Open the DC simulation result "demo/spice/Fig24_30/dcOp.dc"
#       - From the menu select "View->Select Attributes" and change
#         "Net Attributes -> Net" to "%volt"
#         The generated attributes are visible on the nets of the schematic.
#   @files
#       analogWave/create_attributes_for_voltage.tcl
#   @example
#       demo/spice/Fig24_30/Fig24_30.sp
#       demo/spice/Fig24_30/dcOp.dc
#   @tag
#       gui analog
###############################################################################


# -----------------------------------------------------------------------------
# create_voltage_attributes_for_section -
# -----------------------------------------------------------------------------
#
proc create_voltage_attributes_for_section {section_id} {
    ##
    # The name of the current StarVision zdb is required to generate attributes.
    #
    set db [gui database get]

    ##
    # This function generates a mapping for the waveform section defined by
    # $section_id and the currently loaded schematic.
    # This mapping is required to map curve names to oids.
    #
    af_sv_compute_mapping ${section_id}

    ##
    # As we want to traverse all variables in the section we have to get the
    # number of variables defined in the section.
    # The first variables might be sweep variables holding the x-axis values.
    # They aren't interesting here.
    #
    set nb_sweep_variables [af_wp_find_section_property $section_id \
                                    "prop_section_number_of_sweep_variables"]
    set nb_all_variables [af_wp_find_section_property $section_id \
                                    "prop_section_total_number_of_variables"]

    for {set curve_index $nb_sweep_variables} \
        {$curve_index<$nb_all_variables} \
        {incr curve_index} \
    {
        ##
        # Here we retrieve some information on the current variable.
        #
        set curve_name [af_wp_find_curve_property $section_id $curve_index \
                                                        "prop_variable_name"]
        set curve_data_type [af_wp_find_curve_property $section_id \
                                        $curve_index "prop_variable_data_type"]
        set curve_unit [af_wp_find_curve_property $section_id $curve_index \
                                                    "prop_variable_y_axis_unit"]

        ##
        # Here we apply the mapping computed above. For a given curve name it
        # returns a matching oid.
        #
        set oid [af_sv_apply_mapping_waveform_to_oid $curve_name]

        puts "The curve $curve_name is mapped to the oid $oid"

        ##
        # We only generate voltage attributes here.
        #
        if {($oid != "") && ($curve_unit == "volt")} {
            ##
            # Here we create an iterator for the specific curve.
            #
            set iterator [af_wp_curve_value_iterator_define $section_id \
                                                            $curve_index]

            ##
            # This iterator allows to iterate over all curve values.
            # However here we only use the first iterator value.
            #
            set value [af_wp_curve_value_iterator_read_next $iterator]

            ##
            # The string value "bad_index" is returned when the iterator
            # reaches the end.
            #
            if {$value != "bad_index"} {
                if {[string is double $value]} {
                    ##
                    # The iterator returns a single double value.
                    # We use it to generate an attribute for the net defined
                    # by $oid.
                    #
                    $db flatattr $oid set "${curve_unit}=${value}"
                } elseif {[string is list $value]} {
                    ##
                    # The iterator might define a list of two values with
                    # x- and y-axis data.
                    # In this case we create an annotation from the y-axis
                    # value.
                    #
                    set value [lindex $value 1]
                    if {[string is double $value]} {
                        $db flatattr $oid set "${curve_unit}=${value}"
                    }
                }
            }

            ##
            # destroy the iterator
            #
            af_wp_curve_value_iterator_release $iterator
        }
    }
}


##
#
#
set script_path [file dirname [file normalize [info script]]]

##
# This function loads the waveform parser
#       and makes the functions af_wp_... and af_sv_... available.
#
af_waveform_parser_create

##
# Define a file with dc voltages over the file dialog.
#
set file_name "${script_path}/../Fig24_30/dcOp.dc"
set file_name [tk_getOpenFile -title "Open DC File"     \
                              -initialdir  $script_path \
                              -initialfile ${file_name}]

##
# Clear all data in the waveform parser.
#
af_wp_release_all

##
# Parse the file
#
set rc [af_wp_read_file ${file_name}]
if {$rc == "ok"} {
    ##
    # Each file might define several data sections for example for several
    # runs with different parameters.
    #
    set nb_sections [af_wp_get_number_of_sections]

    if {${nb_sections} > 0} {
        ##
        # At least one section has been parsed. We use the first one here.
        # We need to work with the section_id. This section_id doesn't change,
        # even if other files are parsed, reloaded or released.
        #
        set section_id [af_wp_get_section_identifier 0]

        ##
        # Call the above function to create attributes.
        #
        create_voltage_attributes_for_section $section_id

        ##
        # We inform the gui that attributes have changed.
        #
        gui attribute changed
    }
} else {
    zmessage print ERR "failed to load file ${file_name}"
}

##
# Everything is released.
#
af_wp_release_all

##
# unloads the waveform parser
#
af_waveform_parser_delete