diff --git a/.github/workflows/tcl-lint.yaml b/.github/workflows/tcl-lint.yaml new file mode 100644 index 00000000..9c78edbd --- /dev/null +++ b/.github/workflows/tcl-lint.yaml @@ -0,0 +1,31 @@ +name: Tcl Linting and Formatting + +on: [push, pull_request] + +jobs: + tcl-lint: + runs-on: ubuntu-latest + name: Tcl Code Quality + + steps: + - name: Checkout source + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install tclint + run: pip install tclint + + - name: Check Tcl formatting with tclfmt + run: | + # Check if all Tcl files are formatted correctly (excluding src/xschem.tcl) + tclfmt --check --exclude "src/xschem.tcl" . + + - name: Run tclint on Tcl files + run: | + # Run tclint with the configuration file + # This will check all .tcl files except those excluded in .tclint.toml + find . -name "*.tcl" -type f ! -path "./src/xschem.tcl" -exec tclint -c .tclint.toml {} \; diff --git a/.tclint.toml b/.tclint.toml new file mode 100644 index 00000000..42ed23ca --- /dev/null +++ b/.tclint.toml @@ -0,0 +1,20 @@ +# Tclint configuration for xschem +# https://github.com/nmoroze/tclint + +# Exclude files that cause parsing errors or are too complex for tclint +exclude = [ + "src/xschem.tcl", # Has parsing issues with bareword in expression +] + +# Ignore certain rules that are too strict for this codebase +# command-args: Many eval and expr commands use dynamic arguments +# unbraced-expr: Legacy code style, would require extensive refactoring +ignore = [ + "command-args", + "unbraced-expr", +] + +[style] +# Extend the default line length to 180 characters +# Many lines in the codebase are long due to complex Tcl command chains and embedded strings +line-length = 180 diff --git a/src/add_custom_button.tcl b/src/add_custom_button.tcl index 91c0d50d..a6ac39d0 100644 --- a/src/add_custom_button.tcl +++ b/src/add_custom_button.tcl @@ -8,8 +8,8 @@ set topwin [xschem get top_path] ## Add a "MyButton" button to toolbar_list if {[lsearch -exact $toolbar_list MyButton] < 0} { - lappend toolbar_list MyButton - set MyButtonData { + lappend toolbar_list MyButton + set MyButtonData { R0lGODlhGAAYAPcAACIiIiMjIyUlJSYmJicnJykpKSoqKisrKywsLDAwMDExMTIyMjMzMzQ0NDU1 NTY2Njc3Nzg4ODk5OTo6Oj09PT4+Pj8/P0FBQUJCQkNDQ0REREVFRUZGRklJSUxMTE1NTU5OTlFR UVJSUlNTU1lZWVpaWltbW1xcXF1dXV5eXl9fX2FhYWNjY2RkZGZmZmdnZ2hoaGlpaWtra2xsbG1t @@ -33,15 +33,14 @@ if {[lsearch -exact $toolbar_list MyButton] < 0} { Ow== } - ## Create an image object. Name should be img - image create photo imgMyButton - imgMyButton put $MyButtonData - + ## Create an image object. Name should be img + image create photo imgMyButton + imgMyButton put $MyButtonData } ## Create the toolbar button ## constructor name tcl command tooltip topwindow -toolbar_add MyButton { puts SMILE! } "SMILE!" $topwin +toolbar_add MyButton { puts SMILE! } "SMILE!" $topwin ## Destroy and rebuild the toolbar, but see better option here under ... # toolbar_hide # toolbar_show diff --git a/src/add_custom_menu.tcl b/src/add_custom_menu.tcl index 88983861..22781fb1 100644 --- a/src/add_custom_menu.tcl +++ b/src/add_custom_menu.tcl @@ -2,18 +2,17 @@ ## Create a menu entry 'Test' before 'Netlist'. '$topwin.menubar' is xschem's main menu. proc add_menu {} { - set topwin [xschem get top_path] - $topwin.menubar insert Netlist cascade -label Test -menu $topwin.menubar.test - menu $topwin.menubar.test -tearoff 0 + set topwin [xschem get top_path] + $topwin.menubar insert Netlist cascade -label Test -menu $topwin.menubar.test + menu $topwin.menubar.test -tearoff 0 - ## Create a couple of entries - $topwin.menubar.test add command -label "Test entry 1" -command { + ## Create a couple of entries + $topwin.menubar.test add command -label "Test entry 1" -command { puts Hello } - $topwin.menubar.test add command -label "Test entry 2" -command { + $topwin.menubar.test add command -label "Test entry 2" -command { puts World } } add_menu - diff --git a/src/change_index.tcl b/src/change_index.tcl index f0855bdf..acd3aaa1 100644 --- a/src/change_index.tcl +++ b/src/change_index.tcl @@ -1,19 +1,17 @@ - # increments index of bussed label by $incr proc change_index {incr} { - - set sel [xschem selected_set] - foreach i $sel { - set mylabel [xschem getprop instance $i lab] - regsub {.*\[} $mylabel {} myindex - regsub {\].*} $myindex {} myindex - regsub {\[.*} $mylabel {} mybasename - if { [regexp {^[0-9][0-9]*$} $myindex] } { - set myindex [expr $myindex + $incr] - set mylabel "$mybasename\[$myindex\]" - xschem setprop instance $i lab $mylabel + set sel [xschem selected_set] + foreach i $sel { + set mylabel [xschem getprop instance $i lab] + regsub {.*\[} $mylabel {} myindex + regsub {\].*} $myindex {} myindex + regsub {\[.*} $mylabel {} mybasename + if {[regexp {^[0-9][0-9]*$} $myindex]} { + set myindex [expr $myindex + $incr] + set mylabel "$mybasename\[$myindex\]" + xschem setprop instance $i lab $mylabel + } } - } } bind .drw + {change_index 1} diff --git a/src/create_graph.tcl b/src/create_graph.tcl index c5db207a..cc2f2315 100644 --- a/src/create_graph.tcl +++ b/src/create_graph.tcl @@ -1,21 +1,21 @@ # # File: create_graph.tcl -# +# # This file is part of XSCHEM, -# a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit +# a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit # simulation. # Copyright (C) 1998-2024 Stefan Frederik Schippers -# +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA @@ -23,34 +23,33 @@ # procedure to create a graph in an empty xschem window and display waveforms proc create_graph {title rawfile node {analysis tran} {color {4 5 6 7 8 9 10 11 12 13 14}}} { - # clear window if not already empty - xschem clear force + # clear window if not already empty + xschem clear force - # add title text - xschem text 30 -350 0 0 $title {} 0.5 1 - # clear loaded raw file if any - xschem raw_clear - # set current layer to graph layer (grey, layer 2) - xschem set rectcolor 2 - # create a 300x400 rectangle - xschem rect 0 -300 400 0 - # make it a graph - xschem setprop rect 2 0 flags graph - # read a simulation raw file - xschem raw_read $rawfile $analysis - # add nodes to display - xschem setprop rect 2 0 node $node - # set node colors - xschem setprop rect 2 0 color $color - # set thinner graph line widths - xschem setprop rect 2 0 linewidth_mult 0.5 - # make xschem display full the graph rectangle - xschem zoom_full - # full zoom graph data on x axis - xschem setprop rect 2 0 fullxzoom - # full zoom graph data on y axis - xschem setprop rect 2 0 fullyzoom - # clear modified flag so we can quit without xschem asking to save changed file. - xschem set_modify 0 + # add title text + xschem text 30 -350 0 0 $title {} 0.5 1 + # clear loaded raw file if any + xschem raw_clear + # set current layer to graph layer (grey, layer 2) + xschem set rectcolor 2 + # create a 300x400 rectangle + xschem rect 0 -300 400 0 + # make it a graph + xschem setprop rect 2 0 flags graph + # read a simulation raw file + xschem raw_read $rawfile $analysis + # add nodes to display + xschem setprop rect 2 0 node $node + # set node colors + xschem setprop rect 2 0 color $color + # set thinner graph line widths + xschem setprop rect 2 0 linewidth_mult 0.5 + # make xschem display full the graph rectangle + xschem zoom_full + # full zoom graph data on x axis + xschem setprop rect 2 0 fullxzoom + # full zoom graph data on y axis + xschem setprop rect 2 0 fullyzoom + # clear modified flag so we can quit without xschem asking to save changed file. + xschem set_modify 0 } - diff --git a/src/gtkwave_server.tcl b/src/gtkwave_server.tcl index 2baccb8a..0b832e86 100644 --- a/src/gtkwave_server.tcl +++ b/src/gtkwave_server.tcl @@ -1,27 +1,26 @@ proc gtkwave_getdata {sock} { - global gtkwave_server_getdata - if {[eof $sock] || [catch {gets $sock gtkwave_server_getdata(line,$sock)}]} { - close $sock - puts "Close $gtkwave_server_getdata(addr,$sock)" - unset gtkwave_server_getdata(addr,$sock) - unset gtkwave_server_getdata(line,$sock) - unset gtkwave_server_getdata(res,$sock) - } else { - puts "tcp--> $gtkwave_server_getdata(line,$sock)" - # gtkwave command must be executed at global scope... - uplevel #0 [list catch $gtkwave_server_getdata(line,$sock) gtkwave_server_getdata(res,$sock)] - puts $sock "$gtkwave_server_getdata(res,$sock)" - } + global gtkwave_server_getdata + if {[eof $sock] || [catch {gets $sock gtkwave_server_getdata(line,$sock)}]} { + close $sock + puts "Close $gtkwave_server_getdata(addr,$sock)" + unset gtkwave_server_getdata(addr,$sock) + unset gtkwave_server_getdata(line,$sock) + unset gtkwave_server_getdata(res,$sock) + } else { + puts "tcp--> $gtkwave_server_getdata(line,$sock)" + # gtkwave command must be executed at global scope... + uplevel #0 [list catch $gtkwave_server_getdata(line,$sock) gtkwave_server_getdata(res,$sock)] + puts $sock "$gtkwave_server_getdata(res,$sock)" + } } proc gtkwave_server {sock addr port} { - global gtkwave_server_getdata - puts "Accept $sock from $addr port $port" - fconfigure $sock -buffering line - set gtkwave_server_getdata(addr,$sock) [list $addr $port] - fileevent $sock readable [list gtkwave_getdata $sock] + global gtkwave_server_getdata + puts "Accept $sock from $addr port $port" + fconfigure $sock -buffering line + set gtkwave_server_getdata(addr,$sock) [list $addr $port] + fileevent $sock readable [list gtkwave_getdata $sock] } set gtkwave_port 2022 socket -server gtkwave_server $gtkwave_port - diff --git a/src/hspice_backannotate.tcl b/src/hspice_backannotate.tcl index 429e682c..2fe55648 100644 --- a/src/hspice_backannotate.tcl +++ b/src/hspice_backannotate.tcl @@ -1,140 +1,140 @@ # # File: hspice_backannotate.tcl -# +# # This file is part of XSCHEM, -# a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit +# a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit # simulation. # Copyright (C) 1998-2024 Stefan Frederik Schippers -# +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA proc read_hspice_log {f} { - global current_probe voltage - set fd [open $f] - while {[gets $fd line] >= 0} { - regsub -all {\r} $line {} line - regsub {^ *\+} $line { + } line - if [regexp {\*\*\*\*\*\*.*operating point information} $line] { + global current_probe voltage + set fd [open $f] + while {[gets $fd line] >= 0} { + regsub -all {\r} $line {} line + regsub {^ *\+} $line { + } line + if [regexp {\*\*\*\*\*\*.*operating point information} $line] { set vnodes 1 } - if [regexp {\*\*\*\*.*voltage sources} $line] { + if [regexp {\*\*\*\*.*voltage sources} $line] { set vnodes 0 set vsources 1 } - if [regexp {total voltage source power} $line] { + if [regexp {total voltage source power} $line] { set vsources 0 } - if { [lindex $line 0] == {element} && $vsources } { - set vsource_name $line - } - if { [lindex $line 0] == {current} && $vsources } { - for {set i 1} {$i < [llength $line]} { incr i } { - set vsource [lindex $vsource_name $i] - set current [lindex $line $i] - if {[regexp {^0:} $vsource]} { - if {[regsub {^.*:} $vsource {} vsource]} { - set current_probe($vsource) $current - puts "$vsource --> $current" - } + if {[lindex $line 0] == {element} && $vsources} { + set vsource_name $line } - } - } - if { [lindex $line 0] == {+} && $vnodes} { - regsub -all {=} $line { = } line - for { set i 1} {$i < [llength $line]} { set i [expr $i+3]} { - set node [lindex $line $i] - set volt [lindex $line [expr $i+2]] - if {[regsub {^0:} $node {} node]} { - set voltage($node) $volt - puts "$node --> $volt" + if {[lindex $line 0] == {current} && $vsources} { + for {set i 1} {$i < [llength $line]} {incr i} { + set vsource [lindex $vsource_name $i] + set current [lindex $line $i] + if {[regexp {^0:} $vsource]} { + if {[regsub {^.*:} $vsource {} vsource]} { + set current_probe($vsource) $current + puts "$vsource --> $current" + } + } + } + } + if {[lindex $line 0] == {+} && $vnodes} { + regsub -all {=} $line { = } line + for {set i 1} {$i < [llength $line]} {set i [expr $i+3]} { + set node [lindex $line $i] + set volt [lindex $line [expr $i+2]] + if {[regsub {^0:} $node {} node]} { + set voltage($node) $volt + puts "$node --> $volt" + } + } } - } } - } - close $fd + close $fd } -proc get_voltage { n } { - global voltage - if { abs($voltage([string tolower $n])) < 1e-3 } { - return [format %.4e $voltage([string tolower $n])] - } else { - return [format %.4g $voltage([string tolower $n])] - } - # return DELETE +proc get_voltage {n} { + global voltage + if {abs($voltage([string tolower $n])) < 1e-3} { + return [format %.4e $voltage([string tolower $n])] + } else { + return [format %.4g $voltage([string tolower $n])] + } + # return DELETE } -proc get_diff_voltage { p m } { - global voltage - return [format %.4e [expr $voltage([string tolower $p]) - $voltage([string tolower $m]) ] ] - # return DELETE +proc get_diff_voltage {p m} { + global voltage + return [format %.4e [expr $voltage([string tolower $p]) - $voltage([string tolower $m])]] + # return DELETE } -proc get_current { n } { - global current_probe - if {abs($current_probe([string tolower $n])) <1e-3} { - return [format %.4e $current_probe([string tolower $n])] - } else { - return [format %.4g $current_probe([string tolower $n])] - } - # return DELETE +proc get_current {n} { + global current_probe + if {abs($current_probe([string tolower $n])) < 1e-3} { + return [format %.4e $current_probe([string tolower $n])] + } else { + return [format %.4g $current_probe([string tolower $n])] + } + # return DELETE } proc annotate {} { - ### disable screen redraw and undo when looping to speed up performance - ### but save state on undo stack before doing backannotations. - xschem push_undo - xschem set no_undo 1 - xschem set no_draw 1 - - read_hspice_log $::netlist_dir/hspice.out - set lastinst [xschem get instances] - for { set i 0 } { $i < $lastinst } {incr i } { - set name [xschem getprop instance $i name] - set type [xschem getprop instance $i cell::type] - if { $type == "probe"} { - set net [xschem instance_net $i p] - if {[catch {xschem setprop -fast instance $i voltage [get_voltage $net]} err]} { - puts "1 error : $err net: $net" - } + ### disable screen redraw and undo when looping to speed up performance + ### but save state on undo stack before doing backannotations. + xschem push_undo + xschem set no_undo 1 + xschem set no_draw 1 + + read_hspice_log $::netlist_dir/hspice.out + set lastinst [xschem get instances] + for {set i 0} {$i < $lastinst} {incr i} { + set name [xschem getprop instance $i name] + set type [xschem getprop instance $i cell::type] + if {$type == "probe"} { + set net [xschem instance_net $i p] + if {[catch {xschem setprop -fast instance $i voltage [get_voltage $net]} err]} { + puts "1 error : $err net: $net" + } + } + if {$type == "current_probe"} { + if {[catch {xschem setprop -fast instance $i current [get_current $name]} err]} { + puts "2 error : $err" + } + } + if {$type == "differential_probe"} { + set netp [xschem instance_net $i p] + set netm [xschem instance_net $i m] + if {[catch {xschem setprop -fast instance $i voltage [get_diff_voltage $netp $netm]} err]} { + puts "3 error : $err" + } + } + # puts "$i $name $type" } - if { $type == "current_probe"} { - if {[catch {xschem setprop -fast instance $i current [get_current $name]} err]} { - puts "2 error : $err" - } - } - if { $type == "differential_probe"} { - set netp [xschem instance_net $i p] - set netm [xschem instance_net $i m] - if {[catch {xschem setprop -fast instance $i voltage [get_diff_voltage $netp $netm]} err]} { - puts "3 error : $err" - } - } - # puts "$i $name $type" - } - - # re-enable undo and draw - xschem set no_undo 0 - xschem set no_draw 0 - xschem redraw - - ### xschem setprop instructions have not altered circuit topology so - ### in this case a connectivity rebuild is not needed. - # xschem rebuild_connectivity - # - # + + # re-enable undo and draw + xschem set no_undo 0 + xschem set no_draw 0 + xschem redraw + + ### xschem setprop instructions have not altered circuit topology so + ### in this case a connectivity rebuild is not needed. + # xschem rebuild_connectivity + # + # } diff --git a/src/mouse_bindings.tcl b/src/mouse_bindings.tcl index 2f45cd88..6a48e40e 100644 --- a/src/mouse_bindings.tcl +++ b/src/mouse_bindings.tcl @@ -35,82 +35,130 @@ # $b: mouse button: 1..9 ################################################################################ -proc mouse_buttons { b m } { - # filter out Cap-Lock, Num-Lock, and Undefined keys - set m [ expr { $m & ~(2+16+32) } ] - # puts "modifier state: $m" - switch $m { - # None - 0 { switch $b { - 8 { xschem zoom_full center } - 9 { xschem unhilight_all } } } - # Shift - 1 { switch $b { - 8 { xschem set_modify 1; xschem save } - 9 { } } } - # Cntl - 4 { switch $b { - 8 { } - 9 { } } } - # Shift+Cntl - 5 { switch $b { - 8 { } - 9 { } } } - # Alt - 8 { switch $b { - 8 { } - 9 { } } } - # Shift+Alt - 9 { switch $b { - 8 { } - 9 { } } } - # Cntl+Alt - 12 { switch $b { - 8 { } - 9 { } } } - # Shift+Cntl+Alt - 13 { switch $b { - 8 { } - 9 { } } } - # Winkey - 64 { switch $b { - 8 { } - 9 { } } } - # Shift+Winkey - 65 { switch $b { - 8 { } - 9 { } } } - # Cntl+Winkey - 68 { switch $b { - 8 { } - 9 { } } } - # Shift+Cntl+Winkey - 69 { switch $b { - 8 { } - 9 { } } } - # Alt+Winkey - 72 { switch $b { - 8 { } - 9 { } } } - # Shift+Alt+Winkey - 73 { switch $b { - 8 { } - 9 { } } } - # Cntl+Alt+Winkey - 76 { switch $b { - 8 { } - 9 { } } } - # Shift+Cntl+Alt+Winkey - 77 { switch $b { - 8 { } - 9 { } } } - } +proc mouse_buttons {b m} { + # filter out Cap-Lock, Num-Lock, and Undefined keys + set m [expr {$m & ~(2 + 16 + 32)}] + # puts "modifier state: $m" + switch $m { + # {None} + 0 { + switch $b { + 8 {xschem zoom_full center} + 9 {xschem unhilight_all} + } + } + # {Shift} + 1 { + switch $b { + 8 {xschem set_modify 1; xschem save} + 9 {} + } + } + # {Cntl} + 4 { + switch $b { + 8 {} + 9 {} + } + } + # {Shift+Cntl} + 5 { + switch $b { + 8 {} + 9 {} + } + } + # {Alt} + 8 { + switch $b { + 8 {} + 9 {} + } + } + # {Shift+Alt} + 9 { + switch $b { + 8 {} + 9 {} + } + } + # {Cntl+Alt} + 12 { + switch $b { + 8 {} + 9 {} + } + } + # {Shift+Cntl+Alt} + 13 { + switch $b { + 8 {} + 9 {} + } + } + # {Winkey} + 64 { + switch $b { + 8 {} + 9 {} + } + } + # {Shift+Winkey} + 65 { + switch $b { + 8 {} + 9 {} + } + } + # {Cntl+Winkey} + 68 { + switch $b { + 8 {} + 9 {} + } + } + # {Shift+Cntl+Winkey} + 69 { + switch $b { + 8 {} + 9 {} + } + } + # {Alt+Winkey} + 72 { + switch $b { + 8 {} + 9 {} + } + } + # {Shift+Alt+Winkey} + 73 { + switch $b { + 8 {} + 9 {} + } + } + # {Cntl+Alt+Winkey} + 76 { + switch $b { + 8 {} + 9 {} + } + } + # {Shift+Cntl+Alt+Winkey} + 77 { + switch $b { + 8 {} + 9 {} + } + } + } } -# the global variable 'has_x' is provided by xschem. It is defined to '1' +# the global variable 'has_x' is provided by xschem. It is defined to '1' # if graphics has been initialized. -if { [ info exists has_x ] } { -# puts "Loading ~/.xschem/mouse_bindings.tcl" - bind .drw {+mouse_buttons %b %s} +if {[info exists has_x]} { + # puts "Loading ~/.xschem/mouse_bindings.tcl" + bind .drw {+mouse_buttons %b %s} } diff --git a/src/ngspice_backannotate.tcl b/src/ngspice_backannotate.tcl index 57044006..72178ec7 100644 --- a/src/ngspice_backannotate.tcl +++ b/src/ngspice_backannotate.tcl @@ -1,96 +1,96 @@ # # File: ngspice_backannotate.tcl -# +# # This file is part of XSCHEM, -# a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit +# a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit # simulation. # Copyright (C) 1998-2024 Stefan Frederik Schippers -# +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA proc ngspice::read_raw_dataset {arr fp} { - upvar $arr var + upvar $arr var - unset -nocomplain var - set variables 0 - while {[gets $fp line] >= 0} { - if {$line eq "Binary:"} break - - if {[regexp {^No\. Variables:} $line]} { - set n_vars [lindex $line end] - } - if {[regexp {^No\. Points:} $line]} { - set n_points [lindex $line end] + unset -nocomplain var + set variables 0 + while {[gets $fp line] >= 0} { + if {$line eq "Binary:"} {break} + + if {[regexp {^No\. Variables:} $line]} { + set n_vars [lindex $line end] + } + if {[regexp {^No\. Points:} $line]} { + set n_points [lindex $line end] + } + if {$variables} { + set nodename [string tolower [lindex $line 1]] + regsub -all {:} $nodename {.} nodename + set var($nodename) {} + set idx([lindex $line 0]) $nodename + } + if {[regexp {^Variables:} $line]} { + set variables 1 + } } if {$variables} { - set nodename [string tolower [lindex $line 1]] - regsub -all {:} $nodename {.} nodename - set var($nodename) {} - set idx([lindex $line 0]) $nodename - } - if {[regexp {^Variables:} $line]} { - set variables 1 - } - } - if {$variables} { - if { $n_points == 1} { - set bindata [read $fp [expr {8 * $n_vars * $n_points}]] - binary scan $bindata d[expr {$n_vars * $n_points}] data - for {set p 0} {$p < $n_points} { incr p} { - for {set v 0} {$v < $n_vars} { incr v} { - lappend var($idx($v)) [lindex $data [expr {$p * $n_vars + $v}]] - # puts "-->|$idx($v)|$var($idx($v))|" + if {$n_points == 1} { + set bindata [read $fp [expr {8 * $n_vars * $n_points}]] + binary scan $bindata d[expr {$n_vars * $n_points}] data + for {set p 0} {$p < $n_points} {incr p} { + for {set v 0} {$v < $n_vars} {incr v} { + lappend var($idx($v)) [lindex $data [expr {$p * $n_vars + $v}]] + # puts "-->|$idx($v)|$var($idx($v))|" + } + } } - } + set var(n\ vars) $n_vars + set var(n\ points) $n_points } - set var(n\ vars) $n_vars - set var(n\ points) $n_points - } } proc ngspice::read_raw {{f {}}} { - upvar ngspice::ngspice_data arr + upvar ngspice::ngspice_data arr - if { $f eq {}} { - set rawfile "$::netlist_dir/[file rootname [file tail [xschem get schname 0]]].raw" - } else { - set rawfile $f - } - if { ![file exists $rawfile] } { - puts "no raw file found: $rawfile" - return - } - set fp [open $rawfile r] - fconfigure $fp -translation binary - set ngspice::op_point_read 0 - ## not needed: done in ngspice::read_ngspice_raw - # array unset ngspice::ngspice_data - while 1 { - ngspice::read_raw_dataset arr $fp - if { [info exists arr(n\ points)] } { - if { $arr(n\ points) == 1 } { - set ngspice::op_point_read 1; break - } - } else break; - } - close $fp - puts {Raw file read ...} - if { !$ngspice::op_point_read } { - puts "no operating point found!" - } + if {$f eq {}} { + set rawfile "$::netlist_dir/[file rootname [file tail [xschem get schname 0]]].raw" + } else { + set rawfile $f + } + if {![file exists $rawfile]} { + puts "no raw file found: $rawfile" + return + } + set fp [open $rawfile r] + fconfigure $fp -translation binary + set ngspice::op_point_read 0 + ## not needed: done in ngspice::read_ngspice_raw + # array unset ngspice::ngspice_data + while 1 { + ngspice::read_raw_dataset arr $fp + if {[info exists arr(n\ points)]} { + if {$arr(n\ points) == 1} { + set ngspice::op_point_read 1; break + } + } else {break} + } + close $fp + puts {Raw file read ...} + if {!$ngspice::op_point_read} { + puts "no operating point found!" + } } # if { [info exists ::has_x] } {bind .drw {puts {Annotating...}; ngspice::annotate} } diff --git a/src/place_pins.tcl b/src/place_pins.tcl index c74a4807..53f74178 100644 --- a/src/place_pins.tcl +++ b/src/place_pins.tcl @@ -1,4 +1,3 @@ - # from a 'pinlist' file like the one below: # vss 1 # vccsa 2 @@ -9,27 +8,25 @@ # # place pin symbols (like ipin.sym, opin.sym, iopin.sym, # or devices/ipin.sym depending on your search path setting) in current schematic. -# Pins are placed at growing y coordinates (going down in xschem coordinate system) +# Pins are placed at growing y coordinates (going down in xschem coordinate system) # parameters: # filename: name for the file holding the list of pins. -# 2 columns are assumed: pin name and pin number +# 2 columns are assumed: pin name and pin number # symname: name of the pin to place (ipin.sym, opin.sym, devices/ipin.sym, ...). # x, y: coordinate for first pin # spacing: vertical spacing between one pin and the following. # -proc place_pins {filename symname {x 0} {y 0} {spacing 40}} { - set i 0 - set fd [open $filename r] - set pinlist [read -nonewline $fd] - close $fd - foreach {name num} $pinlist { - puts "$name num" - # xschem instance sym_name x y rot flip [prop] [n] - xschem instance $symname $x $y 0 0 "name=p$num lab=$name" $i - incr i - incr y $spacing - } - xschem redraw +proc place_pins {filename symname {x 0} {y 0} {spacing 40}} { + set i 0 + set fd [open $filename r] + set pinlist [read -nonewline $fd] + close $fd + foreach {name num} $pinlist { + puts "$name num" + # xschem instance sym_name x y rot flip [prop] [n] + xschem instance $symname $x $y 0 0 "name=p$num lab=$name" $i + incr i + incr y $spacing + } + xschem redraw } - - diff --git a/src/place_sym_pins.tcl b/src/place_sym_pins.tcl index a74e4b30..68af44d3 100644 --- a/src/place_sym_pins.tcl +++ b/src/place_sym_pins.tcl @@ -7,42 +7,40 @@ # LDPRECH 6 # # place pin objects (squares on layer 5) and labels in the current symbol window. -# pins are placed at growing y coordinates (going down in xschem coordinate system) +# pins are placed at growing y coordinates (going down in xschem coordinate system) # parameters: # filename: name for the file holding the list of pins. -# 2 columns are assumed: pin name and pin number +# 2 columns are assumed: pin name and pin number # dir: pin direction (in, out or inout) # x, y: coordinate for first pin # spacing: vertical spacing between one pin and the following. # -proc place_sym_pins {filename dir {x 0} {y 0} {spacing 20}} { - set fd [open $filename r] - set pinlist [read -nonewline $fd] - if {$dir == {in} } { - set flip 0 - set offset 25 - set line_offset 20 - } else { - set flip 1 - set offset -25 - set line_offset -20 - } - close $fd - foreach {name num} $pinlist { - puts "$name num" - set x1 [expr {$x - 2.5}] - set x2 [expr {$x + 2.5}] - set y1 [expr {$y - 2.5}] - set y2 [expr {$y + 2.5}] - xschem set rectcolor 5 ;# symbol pin layer - xschem rect $x1 $y1 $x2 $y2 -1 "name=$name dir=$dir" 0 - xschem set rectcolor 4 ;# symbol line color - xschem line $x $y [expr {$x + $line_offset}] $y {} 0 - xschem text [expr {$x + $offset}] [expr {$y - 4}] 0 $flip $name {} 0.2 0 - incr y $spacing - } - xschem set schsymbolprop "type=subcircuit\nformat=\"@name @pinlist @symname\"\ntemplate=\"name=X1\"" - xschem redraw +proc place_sym_pins {filename dir {x 0} {y 0} {spacing 20}} { + set fd [open $filename r] + set pinlist [read -nonewline $fd] + if {$dir == {in}} { + set flip 0 + set offset 25 + set line_offset 20 + } else { + set flip 1 + set offset -25 + set line_offset -20 + } + close $fd + foreach {name num} $pinlist { + puts "$name num" + set x1 [expr {$x - 2.5}] + set x2 [expr {$x + 2.5}] + set y1 [expr {$y - 2.5}] + set y2 [expr {$y + 2.5}] + xschem set rectcolor 5 ;# symbol pin layer + xschem rect $x1 $y1 $x2 $y2 -1 "name=$name dir=$dir" 0 + xschem set rectcolor 4 ;# symbol line color + xschem line $x $y [expr {$x + $line_offset}] $y {} 0 + xschem text [expr {$x + $offset}] [expr {$y - 4}] 0 $flip $name {} 0.2 0 + incr y $spacing + } + xschem set schsymbolprop "type=subcircuit\nformat=\"@name @pinlist @symname\"\ntemplate=\"name=X1\"" + xschem redraw } - - diff --git a/src/resources.tcl b/src/resources.tcl index 3df46aa7..27f83e7a 100644 --- a/src/resources.tcl +++ b/src/resources.tcl @@ -1,28 +1,26 @@ # # File: resources.tcl -# +# # This file is part of XSCHEM, -# a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit +# a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit # simulation. # Copyright (C) 1998-2024 Stefan Frederik Schippers -# +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - ## ## Tcl Resources for XSchem toolbars ## @@ -41,14 +39,14 @@ ## # so we set white background and eliminate alpha channel (unsupported in gif). ## convert -background white -alpha remove -alpha off paste.png -transparent white gif:-|base64 ## -## Following shell function (and call) converts a png base64 encoded to proper +## Following shell function (and call) converts a png base64 encoded to proper ## gif89a base64 encoded format: ## to_gif () { ## echo "image create photo $1 -data \"" ## echo -n "$2" | base64 -d |convert -background white -alpha remove -alpha off - -transparent white gif:- |base64 ## echo '"' ## } -## +## ## to_gif imgFileOpen "...." ## @@ -69,7 +67,7 @@ # # set light colorscheme, set transparent svg background # # draw image inside the border in green color # # set line with 40 disable change line width, redraw -# # move away the border, full zoom the image +# # move away the border, full zoom the image # # export svg: # xschem print svg 1.svg 400 400 0 0 100 100 # # edit svg, change .l4 layer from green to black (#000000) @@ -77,21 +75,19 @@ # gm convert -size 16x16 1.svg 1.png # convert -background white -alpha remove -alpha off 1.png -transparent white 1.gif # base64 1.gif -# # the output is the 16x16 image with transparent background, antialiasing +# # the output is the 16x16 image with transparent background, antialiasing # # and base64 encoded # # # # # # - ## FILE -if { $dark_gui_colorscheme == 0 } { - -image create photo ximgFileOpen -ximgFileOpen put " +if {$dark_gui_colorscheme == 0} { + image create photo ximgFileOpen + ximgFileOpen put " R0lGODlhGAAYAPYAAAAAAAEBAQMDAwQEBAUFBQcHBwgICAkJCQsLCw0NDRISEhMTExcXFxkZGRwc HB0dHR4eHiEhISYmJisrKywsLDAwMDExMTIyMjY2Njc3Nzk5OUREREVFRUZGRk5OTlRUVFlZWVpa Wl1dXV5eXmBgYGhoaGlpaW1tbW5ubm9vb3BwcHl5eXp6en19fYGBgYKCgouLi5OTk5SUlJWVlZ2d @@ -105,8 +101,8 @@ KuHi4+Ti3ysLubbr7LoLEOrt8gAIEBcJ8/MIFx0L+fILOoBg8K8dAxAoIBRkBwFFiwgL10V4IUNC RFsSZNigcJEUBRs6OHbEdEEHEQwjMWEgkqRDSgAdkjihgcKRzZs4b6Kg4WSSz58+AwEAOw== " -image create photo ximgFileSave -ximgFileSave put " + image create photo ximgFileSave + ximgFileSave put " R0lGODlhGAAYAPUAAAAAAAEBAQICAgMDAwQEBAUFBQcHBzExMT4+Pj8/P0FBQUNDQ0REREVFRUdH R0hISElJSV9fX2BgYGFhYWJiYmVlZWdnZ2hoaGlpaW1tbW5ubm9vb3BwcHNzc3R0dJOTk6Ghoaam pqqqqq2trbGxsbKysrOzs7a2trq6usHBwcLCwsPDw8TExMbGxsfHx8rKytXV1ebm5urq6uzs7O3t @@ -117,8 +113,8 @@ GrCdkwbCwp6lprLGycqxQrPKz8fN0NDMOs7TxtXX2Gza3Mne36XVa+JskUMkZeIGDSdETE5P8/T0 HiRpSvr7/ENBADs= " -image create photo ximgFileReload -ximgFileReload put " + image create photo ximgFileReload + ximgFileReload put " R0lGODlhGAAYAPYAAAAAAAEBAQICAgQEBAUFBQcHBwgICAsLCw0NDQ4ODg8PDxMTExQUFBoaGhsb GxwcHB8fHyAgICEhIScnJysrKywsLDg4OD4+Pj8/P0BAQEFBQUJCQkZGRk9PT1VVVVZWVmFhYWdn Z2hoaGlpaWtra2xsbHNzc4yMjJaWlpqamqSkpKWlpaqqqq2trbOzs7a2tri4uL6+vsHBwcPDw8TE @@ -132,10 +128,10 @@ Sz0l2BTNJIY3EyY+hiTmhj4nQofuwueFSEVK9O+SS/XB7kkCCAxDChQIEypUmAIDMGTOIjYjQCGB xIvPKqhYRqCjx48gPRrQsELIjhsyUqpcyXLljiL+YsqcSXNRIAA7 " -## EDIT + ## EDIT -image create photo ximgEditUndo -ximgEditUndo put " + image create photo ximgEditUndo + ximgEditUndo put " R0lGODlhGAAYAPYAAAAAAAEBAQICAgMDAwUFBQcHBw0NDQ4ODg8PDxAQEBERERMTExQUFBUVFRcX FxgYGBkZGRsbGxwcHB0dHR4eHiAgICIiIioqKiwsLENDQ0REREtLS1NTU1RUVFxcXGFhYWdnZ2ho aGlpaWpqamxsbHJycnR0dHV1dXd3d3h4eHx8fICAgISEhIWFhYaGhoqKipCQkJGRkZSUlJWVlZqa @@ -149,8 +145,8 @@ mEIox7oFBgXJCShFhkIpra4ZODc0MyskGxUFEjTWhEYlILgaNWiKER4wPEDg0OMQlBIVREl60iJD C3/XoqTYhChLlhsrhAjDFEXFC0VTfOwYaUiJkkVRgpEilAXjzJs4GQUCADs= " -image create photo ximgEditRedo -ximgEditRedo put " + image create photo ximgEditRedo + ximgEditRedo put " R0lGODlhGAAYAPYAAAAAAAEBAQICAgUFBQcHBw0NDQ4ODhAQEBERERISEhUVFRcXFxgYGBoaGhwc HB0dHR4eHiAgICEhISMjIyoqKkNDQ0REREtLS1NTU1ZWVl1dXWBgYGdnZ2hoaGlpaWpqamtra2xs bG1tbXJycnNzc3R0dHV1dXZ2dnd3d3h4eHt7e3x8fH9/f4KCgoODg4SEhIWFhYeHh4qKipCQkJGR @@ -164,8 +160,8 @@ BhxIpUYlBs0EBr+z6SNEpU83vhMXITE2Nzg5FsCaRIU9MkDQQIOHkieETjUooYqQlBYVYpA6xAHA hBFOClkREgOHFWMJF5TgpHGHD4SJZLAgqRFJRkVKlCSSAtKTzZs4bwYCADs= " -image create photo ximgEditCopy -ximgEditCopy put " + image create photo ximgEditCopy + ximgEditCopy put " R0lGODlhGAAYAPYAAAAAAAcHBwoKCg4ODhAQEBERESUlJSsrKywsLC0tLS4uLi8vLzAwMDExMTMz Mzg4ODk5OTo6OkBAQEFBQURERFJSUlNTU1RUVFVVVVpaWmFhYWRkZGVlZXd3d35+foGBgYODg4SE hIWFhYaGhoiIiJWVlZaWlpmZmZ+fn6urq66urq+vr7S0tLW1tbm5ubu7u76+vr+/v8DAwMTExMzM @@ -180,8 +176,8 @@ Ax+oUPWg0WORDRugaOTIGIQCgAiKZBBKVBIABZLjygVhoS0myRYdWCjq4eEDxiA4W5AcSrQoo0AA Ow== " -image create photo ximgEditCut -ximgEditCut put " + image create photo ximgEditCut + ximgEditCut put " R0lGODlhGAAYAPcAAAAAAAEBAQICAgMDAwQEBAUFBQYGBgcHBwgICAkJCQsLCwwMDA0NDQ4ODhAQ EBERERISEhMTExUVFRYWFhcXFxoaGhsbGx0dHR4eHh8fHyIiIiMjIyQkJCUlJScnJysrKywsLC0t LS8vLzExMTMzMzU1NTY2Njg4ODk5OTo6Ojs7Ozw8PD4+Pj8/P0JCQkNDQ0REREVFRUhISExMTE5O @@ -205,8 +201,8 @@ gWFhFgALMz0ZRURSS7HwBmWUSNWBBTSkFVMMczRiE046iUTJIXnkEchQI5WkQwwLqESZSE9dlBFH AIDwUUgNmeHED+VRxGJtI85oI0MBAQA7 " -image create photo ximgEditPaste -ximgEditPaste put " + image create photo ximgEditPaste + ximgEditPaste put " R0lGODlhGAAYAPYAAAAAAAEBAQUFBQoKCgsLCw4ODg8PDxAQEBkZGRsbGx0dHR8fHyAgICEhISMj IyYmJicnJy0tLS4uLi8vLzAwMDIyMjMzMzU1NTg4ODk5OUFBQUJCQkREREVFRUZGRkxMTE1NTVBQ UFFRUVRUVFdXV1paWl1dXWpqanR0dHd3d3h4eHx8fH19fX5+foODg4iIiI2NjY+Pj5ycnJ6enqCg @@ -221,8 +217,8 @@ J3szKJwwlIRDAYcFxYF0J7ATBwAZgqhcuXLXuVTUjPm64C2mTF7IVPkI0eKFz58/VZAQ4q2o0aOp AgEAOw== " -image create photo ximgEditDelete -ximgEditDelete put " + image create photo ximgEditDelete + ximgEditDelete put " R0lGODlhGAAYAPUAAAAAAAEBAQICAgMDAwYGBgcHBw0NDRAQEBQUFBUVFRkZGRoaGi4uLjAwMDEx MTw8PD09PUBAQEZGRklJSVNTU1RUVFhYWICAgIGBgYuLi4+Pj5KSkpOTk5ubm6ioqKmpqaqqqra2 tre3t8PDw8bGxsfHx8zMzM3Nzdra2vHx8fLy8vPz8/T09Pb29vn5+fr6+vz8/P39/f7+/gAAAAAA @@ -232,8 +228,8 @@ FQYFEiRUSjIfDwMHFBYJAw8eYEsyHQwDnAMMHZdMYgecBhl7TiwaBqWnTjOZDZ2eoE2MjgkVFqQP H6FHfX8GFIMUhoiKSG4Kh3N1d3moR2JkZkNoDGuLV1lbXV9Pv7DJr+Xm5+ivQQA7 " -image create photo ximgEditDuplicate -ximgEditDuplicate put " + image create photo ximgEditDuplicate + ximgEditDuplicate put " R0lGODlhGAAYAPcAAAAAAAEBAQICAgMDAwQEBAUFBQYGBgcHBwgICAkJCQsLCwwMDA0NDRERERIS EhMTExQUFBkZGRoaGhwcHB0dHR4eHh8fHyIiIiQkJCcnJygoKCkpKSsrKywsLC4uLi8vLzMzMzQ0 NDY2Njk5OTs7Oz09PT4+Pj8/P0BAQEFBQUREREdHR0lJSUpKSktLS09PT1JSUlRUVFVVVVdXV1pa @@ -257,8 +253,8 @@ GMRjA77OJPUJhJxSHO03iGMDPRFgI+jlNFAiCA5UxYID6tcRQQoCcJ5MMADBw4cghsgDECUsqIYD v6W4AEF13LBCCTDCiAIKMs5IYwku6EAQZIz16GOPhfwYEAA7 " -image create photo ximgEditMove -ximgEditMove put " + image create photo ximgEditMove + ximgEditMove put " R0lGODlhGAAYAPYAAAAAAAEBAQICAgYGBgcHBwkJCQsLCxQUFBkZGRoaGhsbGx8fHyEhISIiIiMj IyUlJTc3Nzs7Oz4+Pj8/P0VFRUdHR0lJSUtLS05OTlJSUmRkZGdnZ2lpaWpqanNzc3h4eH19fYqK io2NjZCQkJiYmJmZmZycnJ+fn6GhoaampqqqqrS0tLi4uMLCwsPDw9TU1NbW1uDg4OPj4+Tk5OXl @@ -272,8 +268,8 @@ kUElLtbEGBUriEEiyczMGgoFFSk7xBLBwAMSJvb4wA4dDAXJcKCVQQUDADjwIEOgjVAQZ8iA4CDE qHKCgnwgkQPjoCCePIoc6TEQADs= " -image create photo ximgEditPushSch -ximgEditPushSch put " + image create photo ximgEditPushSch + ximgEditPushSch put " R0lGODlhGAAYAPUAAAAAAAEBAQICAgYGBhAQEBMTExUVFRYWFhgYGBoaGhsbGxwcHB0dHSAgIC4u LjExMTc3Nz4+PnR0dHh4eHx8fIODg4SEhIeHh4iIiIuLi5KSkpOTk5aWlpycnKCgoLCwsNzc3N7e 3t/f3+Dg4OLi4uTk5OXl5ebm5ufn5+np6ezs7PPz8/T09Pb29vr6+vz8/P39/f7+/gAAAAAAAAAA @@ -283,8 +279,8 @@ fStWQy0eDwsJA4EDCQsOHS1EMCEYBYFcBRUhh0QkGAubAAkXIUgwKBQNgQsTJKBGMCoTrmILEimz R7UUCVwJu72qKRcHWgcVKMVKogkHGKlMRiEbG9TVeiuG29/g1UEAOw== " -image create photo ximgEditPushSym -ximgEditPushSym put " + image create photo ximgEditPushSym + ximgEditPushSym put " R0lGODlhGAAYAPUAAAAAAAUFBQoKCgwMDBISEhcXFxsbGx8fHyAgICcnJygoKCwsLDIyMjQ0NDg4 OD09PUNDQ01NTVJSUlVVVVtbW15eXmVlZWpqam1tbXJycoaGho+Pj5mZmZ2dnaqqqq+vr7e3t7i4 uLy8vMLCwsrKys/Pz9PT09jY2N3d3eLi4ujo6O7u7vLy8vf39/v7+wAAAAAAAAAAAAAAAAAAAAAA @@ -295,8 +291,8 @@ CAlvE18oAQAhTRQAGXS5DRYWF0PIGHQKZtEA01+GzRYYvghvEl8nxLMvZg9aK6ELRB8eHw8Aq6yS JiMbBgABa00LolgIgKgyASAABBkwMQkCADs= " -image create photo ximgEditPop -ximgEditPop put " + image create photo ximgEditPop + ximgEditPop put " R0lGODlhGAAYAPUAAAAAAAEBAQICAgYGBhAQEBMTExUVFRYWFhgYGBoaGhsbGxwcHB0dHSAgIC4u LjExMTc3Nz4+PnR0dHh4eHx8fIODg4SEhIeHh4iIiIuLi5KSkpOTk5aWlpycnKCgoLCwsNzc3N7e 3t/f3+Dg4OLi4uTk5OXl5ebm5ufn5+np6ezs7PPz8/T09Pb29vr6+vz8/P39/f7+/gAAAAAAAAAA @@ -306,13 +302,13 @@ DRNpSCMYDIODCF1GMCEYBoyMBF11Mi0eDwwIA5UAAwgIDx0rRDAtJSUjEKEQI6wtmakRoREua7eV uVEuvIy+S8C4usTBg8NKxb3HzMl6y3YfGxzX2BsftV/d3t9LQQA7 " -## OPTION + ## OPTION -## VIEW + ## VIEW -image create photo ximgViewZoomIn -ximgViewZoomIn put " + image create photo ximgViewZoomIn + ximgViewZoomIn put " R0lGODlhGAAYAPUAAAAAAAEBAQYGBggICBERERISEhMTExQUFBoaGjc3Nzg4OD4+PkFBQUJCQklJ SUpKSktLS0xMTF5eXl9fX2BgYGxsbHd3d3l5eXp6enx8fIODg4SEhIWFhZGRkZKSkpOTk5SUlLu7 u7y8vL29vcDAwMHBwcLCws/Pz9DQ0NHR0dbW1tfX19ra2tvb29zc3N3d3eDg4O7u7u/v7/X19fb2 @@ -324,8 +320,8 @@ mqepeBMzfKT3sfnWHFg1RAQuUwBBiRqyqJSaBDBgJJhUqQ8GQGsEETKE4YUSHSsw2HmlhkAGFmKU 3GDRIcLIOwcivOFDxcqGCRG2dPnSaUwOkiYlSqCw5JPKESNjggAAOw== " -image create photo ximgViewZoomOut -ximgViewZoomOut put " + image create photo ximgViewZoomOut + ximgViewZoomOut put " R0lGODlhGAAYAPUAAAAAAAEBAQYGBggICBERERISEhMTExQUFBoaGjc3Nz4+PkFBQUJCQklJSUpK SktLS0xMTF5eXl9fX2BgYHd3d3l5eXp6enx8fIODg4SEhIWFhZGRkZKSkpOTk5SUlLu7u7y8vL29 vcDAwMHBwcLCws/Pz9DQ0NHR0dbW1tfX19ra2tvb29zc3N3d3eDg4O7u7u/v7/X19fb29vf39/r6 @@ -336,8 +332,8 @@ vTU2LghqDCO1twC5Nr6+wMIAxKWnqa3UCrBqDbRVEqGCE2FCGYrdagecQyCn5AAQIESImd0EHjF9 FoChhC1KcxbxggQuqOCTpIaKDRDGrTkAwUOLR1SsZJAAYUuDCV/AjXnnBEq9jVSOGBkTBAA7 " -image create photo ximgViewZoomBox -ximgViewZoomBox put " + image create photo ximgViewZoomBox + ximgViewZoomBox put " R0lGODlhGAAYAPYAAAAAAAEBAQICAgQEBAUFBQYGBgcHBwgICAoKCgsLCwwMDBYWFhcXFxoaGhsb Gx0dHSMjIysrKzQ0NDY2NkBAQEFBQUJCQkNDQ0lJSUpKSk1NTVFRUVJSUlZWVldXV1tbW1xcXF5e XmJiYmNjY2RkZGlpaWpqamtra3t7e4aGho+Pj5aWlpeXl5ubm6ampqurq66urq+vr7i4uLq6uru7 @@ -352,8 +348,8 @@ DwcBWlA0SO6ixEFL3nG05HFivn0OeWA06a+hxZUbHZaM+fJjPpfxZubD4K2Ez59Af4bgpTFfCgi3 ktoaQKEGSB0pMFCgMOHC1KlVr1L4AEMgSESKwIZVlAjUoEAAOw== " -image create photo ximgViewToggleColors -ximgViewToggleColors put " + image create photo ximgViewToggleColors + ximgViewToggleColors put " R0lGODlhGAAYAPYAAAAAAAEBAQICAg8PDxERERISEhMTExQUFBUVFRYWFhkZGRsbGx4eHiUlJSYm JicnJykpKSoqKj4+PkJCQkNDQ0RERE5OTk9PT1FRUVJSUlRUVFdXV1hYWFlZWVpaWltbW2JiYmNj Y2RkZGdnZ2hoaGpqamtra2xsbG9vb3BwcHFxcXJycnNzc3R0dICAgIGBgYKCgo6Ojo+Pj5CQkJGR @@ -370,8 +366,8 @@ m5ak2bMkybpUuzZoVq2xuXb1EgQsQilCQ0oMQ5eqR9IxXmaVKEKIEkRMFjJwGhQmSREq9wY5ohAp 9T1DJaCkDgQAOw== " -image create photo ximgViewRedraw -ximgViewRedraw put " + image create photo ximgViewRedraw + ximgViewRedraw put " R0lGODlhGAAYAPYAAAAAAAEBAQICAgMDAwQEBAUFBQYGBgkJCQoKCgsLCwwMDA8PDxAQEBERERMT ExQUFBUVFRsbGxwcHB8fHyQkJCkpKSsrKy0tLS4uLjExMTQ0NDg4ODo6Ojs7Ozw8PD09PUREREVF RUZGRkdHR0lJSUpKSkxMTE5OTk9PT1JSUlNTU1VVVVdXV1hYWF5eXl9fX2BgYGFhYWJiYmNjY2Rk @@ -386,16 +382,16 @@ kDOxjFEU0YSJCxEBdeU4KOBDky9Z0nGi0wYGOQE+4uSjtMXESx/D7NAxEuqXCSk5w6hCeAHGE2bD pKSo8MHFjzEzTXVhwgQdnaimAgEAOw== " -## PROPERTIES + ## PROPERTIES -## LAYERS + ## LAYERS -## TOOLS + ## TOOLS -image create photo ximgToolInsertSymbol -ximgToolInsertSymbol put " + image create photo ximgToolInsertSymbol + ximgToolInsertSymbol put " R0lGODlhGAAYAPUAAAAAAAYGBgkJCRcXFxoaGh0dHSAgICYmJiwsLDMzMzg4OEdHR0hISFFRUWtr a2xsbHd3d3l5eYKCgoWFhYiIiJGRkZmZmZ6enqOjo6enp6qqqqysrLu7u7+/v8vLy83Nzdra2t3d 3enp6fPz8/f39wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -405,8 +401,8 @@ EFsQShdbDkYhWxFLBgADGhobQ40Aj0oJXpeOS3RdIRYWE59KkZOVBXmIWw9DnF0Ne31/QyQdHBhb CnFwc1wVRx9oZwFqR1nGXGBKUFRUVk7U1dbX2EVBADs= " -image create photo ximgToolInsertText -ximgToolInsertText put " + image create photo ximgToolInsertText + ximgToolInsertText put " R0lGODlhGAAYAPUAAAAAAAMDAwQEBAgICBERERMTExUVFRYWFh8fHyAgICIiIjQ0NERERFVVVVZW VlhYWGZmZnd3d3h4eH19fY2NjZSUlKCgoKqqqqurq7u7u729vcvLy83NzdDQ0NHR0dLS0t3d3eHh 4eLi4u3t7e7u7vLy8vX19fb29vz8/P39/f7+/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -416,8 +412,8 @@ GoUkaIiJZhQQjY6NEiVmHHxTZiULBJqbmgofiqChomQmDJynnAYSVZSVdQRVKhMNtLW2thejurtc QQA7 " -image create photo ximgToolInsertWire -ximgToolInsertWire put " + image create photo ximgToolInsertWire + ximgToolInsertWire put " R0lGODlhGAAYAPUAAAQEBA8PDzs7Ozw8PD09PUREREVFRU5OTk9PT1BQUGJiYmNjY2RkZGVlZWho aGlpaXd3d3h4eHx8fH19fX5+foaGhoeHh5OTk5SUlJubm6WlpaampsHBwcnJycrKysvLy8/Pz9DQ 0NTU1NXV1dnZ2dra2ujo6O7u7u/v7/Hx8fLy8vz8/P39/f7+/gAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -427,15 +423,15 @@ GWN/QhwAAByHRImLjUOPjJEuk5WWipSRl5WdnJqVgYOFjXcCCQl8fnUlEQpxc4dmD0cMa4cpGF5g Yo0hVVdZkU0ghpFHWkEAOw== " -image create photo ximgToolInsertLine -ximgToolInsertLine put " + image create photo ximgToolInsertLine + ximgToolInsertLine put " R0lGODlhGAAYAPMAAAQEBAcHByAgICEhIcHBwcLCwsjIyMnJyfLy8gAAAAAAAAAAAAAAAAAAAAAA AAAAACH5BAEAAAkALAAAAAAYABgAAAQ1MMlJq7046827/2AojmTZIQahrmxRGAhmDAFg33gwGDKN /wAd74JiGVWvmGnJbDqf0Kg0EwEAOw== " -image create photo ximgToolInsertRect -ximgToolInsertRect put " + image create photo ximgToolInsertRect + ximgToolInsertRect put " R0lGODlhGAAYAPQAAAAAAAgICAkJCQsLCxsbG0BAQEFBQV5eXl9fX2BgYGFhYWlpaWpqapaWlp6e np+fn8TExMXFxeTk5Pn5+fr6+v39/QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEA ABYALAAAAAAYABgAAAWPoCVWVFlO56SaVCW+FnQUdG3bBwSLzgD8wGBw4NhZGoDBgcFsOg++hhFJ @@ -443,8 +439,8 @@ kBhhEgJAuqNar6LsdgqogsNaLsx7tojVL/b5TTbP0/UvmN4t6698a35tgXGDd2N9dnt4in9GhSJy jImCi4CNlo87kUeHlHCSSUtOpVCVLz1Cq0BERjI3sTUKOjskJiorLCYuIiEAOw== " -image create photo ximgToolInsertPolygon -ximgToolInsertPolygon put " + image create photo ximgToolInsertPolygon + ximgToolInsertPolygon put " R0lGODlhGAAYAPUAAAEBAQUFBQoKCg8PDxMTExcXFxoaGh4eHiYmJiwsLDExMTY2Njk5OUBAQEpK SlRUVFdXV1lZWV5eXmRkZGdnZ3d3d39/f4KCgoqKio6OjpCQkJmZmaampqqqqq6urrCwsLu7u76+ vsTExMnJyc7OztPT09nZ2eHh4ebm5ujo6Ozs7PPz8/j4+Pv7+wAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -455,8 +451,8 @@ vVmILhcAB0YHvr6tQyNRJS4dURgb0tPTyUQFABguhQ1rRBIADSRRHt5DnwJlxOZCKWDa7EKFAAOd 8cFRuvcu4wDN+8HgeQsCADs= " -image create photo ximgToolInsertArc -ximgToolInsertArc put " + image create photo ximgToolInsertArc + ximgToolInsertArc put " R0lGODlhGAAYAPUAAAMDAwQEBAwMDA8PDxYWFh8fHyEhISwsLDExMTk5OUREREVFRU9PT1dXV15e XmBgYGZmZm5ubnR0dHd3d4GBgYSEhIqKio+Pj5ycnKKioqenp6qqqrm5ucnJydbW1tjY2Nzc3OHh 4ebm5ujo6Orq6vLy8vX19fn5+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -466,8 +462,8 @@ Jk4ACWyDSyYJTxOKVyFxAR6QTBlPDZZMgAAgm0obTxWgQyd5CKVDDE9WqhNPHaooogAbsxxPGLi6 sxpPt6oUsbMPTyWzGwEOs0tBADs= " -image create photo ximgToolInsertCircle -ximgToolInsertCircle put " + image create photo ximgToolInsertCircle + ximgToolInsertCircle put " R0lGODlhGAAYAPYAAAAAAAEBAQICAgYGBgcHBwgICAkJCQoKCgsLCwwMDBMTExQUFBUVFRkZGRoa GhsbGxwcHB0dHR4eHh8fHykpKSoqKjQ0NDU1NTY2Njc3Nzw8PD09PT4+Pj8/P0pKSktLS0xMTFBQ UFFRUVJSUlNTU2BgYGFhYWNjY2dnZ2hoaGlpaWpqam1tbW9vb3BwcHFxcXJycn19fX5+fn9/f4CA @@ -483,8 +479,8 @@ H+nLUISoPDI/jK2AZAQViUcT6YEgoCFJJG4LFIBzSqjcuX5QXBB49kPaJGo7IHa50CYp1wICvXIU UaKkSI5ix5KNM6UhgSoNHz68iqWhRjh/XZKs0FBBEydPK5L0K3qox41FjR45DQQAOw== " -image create photo ximgToolSearch -ximgToolSearch put " + image create photo ximgToolSearch + ximgToolSearch put " R0lGODlhGAAYAPUAAAAAAAoKChISEhYWFhkZGSIiIicnJysrKy0tLTMzMzc3Nzg4OEBAQFFRUVdX V1tbW11dXWNjY2RkZGpqamxsbHFxcXR0dLm5ub+/v8HBwcbGxsnJyc7Ozs/Pz+/v7/Hx8fj4+AAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -494,8 +490,8 @@ UQIADFFtCVFeB1ELg4WHeVUYR34AgEhxAAd0Ql1VeFEOVQeWQmxVBlshHghfYVcBE60fpVerAQAB Eq0hGxQLBgsVUBK7ARG/SBHJvsxGEM/R0tTVRNO80NhC2gkg3UMPCR7iROHnR0EAOw== " -image create photo ximgToolJoinTrim -ximgToolJoinTrim put " + image create photo ximgToolJoinTrim + ximgToolJoinTrim put " R0lGODlhGAAYAPUAAAAAAAEBAQMDAwQEBAUFBQsLCw0NDQ4ODhAQEBERERMTExQUFBkZGRoaGh8f HycnJykpKSoqKi4uLlRUVFdXV1hYWF9fX2NjY2RkZGVlZWhoaGlpaW9vb3BwcHJycnNzc3l5eXx8 fIqKio2NjZCQkJiYmJubm5+fn6amprm5ub6+vr+/v8TExMbGxsjIyMnJycvLy87Ozs/Pz9HR0dLS @@ -505,8 +501,8 @@ dX6AgRkzfn+BgQweiotCKBcblhkikZKbnJ2enjckFhmWFyicOCEPjQAbnTgceoGumzwzHqy0kjAX BXizkjwsFAhxHh4OGZI6JxIACBczOCAjwbwQFTI6PTeaizAnK4W1POOLQQA7 " -image create photo ximgToolBreak -ximgToolBreak put " + image create photo ximgToolBreak + ximgToolBreak put " R0lGODlhGAAYAPUAAAAAAAEBAQICAgMDAwoKCgsLCw8PDxAQEBERERMTExUVFRYWFicnJywsLDEx MVFRUVJSUlNTU1RUVFZWVldXV1hYWFpaWlxcXF1dXWFhYWJiYmNjY2VlZWZmZmlpaXR0dHZ2dnl5 eZqamqKioqamprS0tLa2tre3t7q6uru7u7+/v8DAwMTExMXFxcbGxsfHx8jIyMnJycrKysvLy8zM @@ -516,18 +512,18 @@ LWEgf2gMESs5PScnbW4iKDpCOY1tOjmVXzqekZdCVyIzkSUlPTktEQwZLZxVHxSFF3gNIrBLHQcU F3G8KrlKHmMFFy2RxFsDHTOYZcpbFKXJYwoVKM9VJBlRHSAn2pHj5EZBADs= " -## SYMBOL + ## SYMBOL -## HIGHLIGHT + ## HIGHLIGHT -## SIMULATE + ## SIMULATE -## HELP + ## HELP -## ACTION BUTTONS + ## ACTION BUTTONS -image create photo ximgSimulate -ximgSimulate put " + image create photo ximgSimulate + ximgSimulate put " R0lGODlhGAAYAPUAAAAAAAEBAQQEBAkJCQ8PDxoaGhsbGx4eHi8vLzY2Njw8PD09PUVFRUxMTE1N TVVVVV5eXnZ2dnp6ep2dnaCgoKGhoaioqL6+vsHBwcLCwtDQ0NHR0dbW1tfX19ra2tzc3OPj4+Tk 5OXl5ejo6Onp6e/v7/Hx8fj4+Pn5+fr6+vv7+/7+/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -537,8 +533,8 @@ FG1KgIFyBhF+SIiJAIslh3mBgxQfbo4HiQgSGJNLIJUAB3V3TWdpa4ZvXwdiZGZXWZpUUB6NXLu8 vb68QQA7 " -image create photo ximgNetlist -ximgNetlist put " + image create photo ximgNetlist + ximgNetlist put " R0lGODlhGAAYAPUAAAAAAAUFBQcHBxERERISEiIiIiUlJSsrKzMzMzo6Oj8/P0tLS1JSUl5eXmBg YHNzc3d3d3x8fIKCgoaGhoiIiI6OjpGRkZaWlpmZmZ6enqOjo6enp6ioqK6urrGxsbq6usHBwcXF xcvLy9TU1NnZ2d3d3eXl5enp6e/v7/b29vn5+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -549,8 +545,8 @@ ZBWcEZOXkH6UCXlEfAANjytiJldWIshufX+AskZ6KykHcnMAIRDj5B6fYQAaCOvsEudLkWRZW3Zf TCkZF4T6hBlN/wCNBAEAOw== " -image create photo ximgWaves -ximgWaves put " + image create photo ximgWaves + ximgWaves put " R0lGODlhGAAYAPUAAAEBAQUFBQsLCwwMDBISEhcXFxwcHCUlJTIyMj4+PktLS1FRUV1dXWNjY2Vl ZXV1dXp6eoeHh4uLi5OTk5iYmJmZmaOjo6ioqKqqqru7u729vcPDw8fHx8nJyc/Pz9DQ0NXV1dvb 29zc3OLi4uXl5enp6e3t7fHx8fX19QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -560,13 +556,9 @@ JoUcaSRrAgAaWxV+EUOLbWkjlBiTaQ6SlGkoAW0bcGoQQwQRIqkiHyUpJB4iICEpKB0iIR5EUUUP YQS/BGJiwGNyRAidyWnGQw0AChnR0tPRggSEhYUMAJtPKZmUCd7fygvjpyGqqR3jzO26Zu9DHgMQ Hh33+fj6/PghygCTiRiASp3Bg+pIpHjwQZ5DJUEAADs= " - - } else { - - -image create photo ximgWaves -ximgWaves put " + image create photo ximgWaves + ximgWaves put " R0lGODlhGAAYAPUAAAAAAAoKCg4ODhISEhYWFhoaGh0dHSMjIyQkJCoqKi8vLzAwMDY2Njg4ODw8 PEJCQkRERFVVVVxcXGZmZmxsbHR0dHh4eIWFhYqKipqampycnKKioq6urrS0tMHBwc3Nzdra2uPj 4+jo6O3t7fPz8/T09Pr6+v7+/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -577,8 +569,8 @@ Jm0OcGoXQyMWB6kHCgQABQsHCQgAAQwHCAtEUUUYYSO/I2JiwGNyRB+dyWnGQxonHRDR0tPRgiOE hYUbJ5tPAJmUHt7fyhzjpwiqqQzjzO26Zu9DCyQXCwz3+fj6/PgIygCTHSCBSp3Bg+oKAMCgQJ5D JUEAADs= " -image create photo ximgViewZoomIn -ximgViewZoomIn put " + image create photo ximgViewZoomIn + ximgViewZoomIn put " R0lGODlhGAAYAPUAAAAAAAEBAQQEBAoKChERER8fHyIiIiUlJSgoKC8vLzAwMD4+PkNDQ0RERGtr a25ubnt7e3x8fIODg4WFhYiIiJOTk5+fn6CgoLOzs7a2tr29vcHBwcfHx8jIyOXl5evr6+7u7vf3 9/n5+f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -589,8 +581,8 @@ cpcCmY4QQwMWlZYCoqkXTwAKlCMiHRsbHRVfFRy2HYAjGAlCDBplHgVCq0PKBR5lGgtCC8Ujx1/K 12zNzwtssWW0thy5ABW1Gxy/wUIEqJWho3MXA3ee76vxZh+lQwyyoPg0cTJ1aE6HAgU6OIKEZ8Ie M33+BJpg4AiCCXFSlQEhgVCbAw8wZJTzAYOaO0ikQLiA4UqWLSi9sFuyIEEkmTiRBAEAOw== " -image create photo ximgToolInsertArc -ximgToolInsertArc put " + image create photo ximgToolInsertArc + ximgToolInsertArc put " R0lGODlhGAAYAPUAAAAAAAYGBgoKCg0NDRcXFxkZGR4eHiMjIykpKTY2NkZGRlVVVVhYWF1dXWNj Y3BwcHV1dXt7e35+foiIiJGRkZmZmZ+fn6GhoaioqLCwsLq6uru7u8bGxs7OztPT097e3uDg4Onp 6fDw8Pv7+/z8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -599,16 +591,16 @@ Z2FtbWE9MC40NTQ1NDUALAAAAAAYABgAAAaHQIAQQDAcCoGhcsnUkJ6kkceyEDCvA6j2KZoQrktG ZTKhZEBa0SMJBh8kIaim0G4HIKLnx1BvIzp6dH1XAk4kHGyDSwIcTxOKVwZxIwiQTA1PGJZMgCQH m0oLTxGgQwF5HaVDGU9WqhNPCaoAoiQLswpPDri6swxPt6oSsbMWTwOzCyMXs0tBADs= " -image create photo ximgSimulate -ximgSimulate put " + image create photo ximgSimulate + ximgSimulate put " R0lGODlhGAAYAPQAAAAAAAEBAQUFBQ4ODhAQEBcXFxsbGxwcHCMjIyUlJSkpKS8vLz4+PkFBQVdX V19fX2JiYoWFhYmJiaGhoaqqqrOzs7q6usPDw8nJydDQ0OHh4eTk5PDw8Pb29vv7+////yH5BAAA AAAAIf8LSW1hZ2VNYWdpY2sOZ2FtbWE9MC40NTQ1NDUALAAAAAAYABgAAAVxICCOZGmeaKqubKsK izK4ZnFVTiHQo6F5m0ljx/N9PhxMJEFsGTbHD5ACObie0aiSMVths8eO5cFUfcHHjaSLOqPVBDMU LX4gmicjOBNhxFcHc0caVFZOGkdJS3hePxpCjCwGNzmRLDAJbDybnJ2enCEAOw== " -image create photo ximgToolSearch -ximgToolSearch put " + image create photo ximgToolSearch + ximgToolSearch put " R0lGODlhGAAYAPUAAAAAAAcHBw4ODhAQEDExMTY2Njk5OT4+PkBAQEZGRouLi46OjpOTk5WVlZub m5ycnKKioqSkpKioqK6urr+/v8fHx8jIyMzMzNLS0tTU1NjY2N3d3ebm5unp6e3t7fX19f///wAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -618,8 +610,8 @@ Z2FtbWE9MC40NTQ1NDUALAAAAAAYABgAAAakQIBwSCwajwBDo7KpMArI42ACqlpBEkF0OMhYO5eO Ql1VeFESVRmWQmxVGlsAAxhfYVcfDa0CpVerHyAfDq0ABQwVGhULUA67Hw+/SA/JvsxGEM/R0tTV RNO80NhC2hcB3UMRFwPiROHnR0EAOw== " -image create photo ximgEditUndo -ximgEditUndo put " + image create photo ximgEditUndo + ximgEditUndo put " R0lGODlhGAAYAPUAAAAAAAICAgUFBQoKChISEhUVFRgYGB8fHyMjIyUlJSsrKy4uLjMzMzk5OT09 PUJCQklJSVFRUVpaWmFhYWVlZWpqam9vb3V1dXp6en9/f4ODg4eHh4iIiI2NjZOTk5eXl5iYmJ6e nqOjo6ysrLS0tLu7u7y8vNXV1d/f3+Pj4+bm5urq6u/v7/Ly8vj4+Pz8/AAAAAAAAAAAAAAAAAAA @@ -629,8 +621,8 @@ Z2FtbWE9MC40NTQ1NDUALAAAAAAYABgAAAaoQIBwSCwaj8ikcskUIhBNZAFTiRoLGdXHSjR0Ui8Q eC4tLoUsHAmcG2xtJhITFBUZHiQoLikUkkQIHSptYkMDCA8WIiojDkcFHShhSAYYJhi4RAQbWkoT GZtHBBoXSgMNEEkHf0oE5WNE0uns7UxBADs= " -image create photo ximgEditPop -ximgEditPop put " + image create photo ximgEditPop + ximgEditPop put " R0lGODlhGAAYAPUAAAAAAAICAgUFBQkJCQwMDBMTExYWFhsbGx8fHyEhIU9PT19fX2NjY2lpaWxs bHR0dHd3d3h4eHx8fIODg4eHh4uLi8HBwcjIyM7Ozt/f3+Li4ufn5+rq6uzs7O/v7/n5+f///wAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -639,8 +631,8 @@ Z2FtbWE9MC40NTQ1NDUALAAAAAAYABgAAAaNQIBwSCwaj8ikkkggLJUIhyPxPCIeG06EWh0asCBQ R3LoAgqTTTi8oRiqBUpmvdZU3krDZE5fZyhlSFcafX0bW0cJDxyFhR2IRAMLGBobH40gHxsbGAxO kQcHCBeYFwihA0oWmBYCVauNrU8CsIWyS7Ssrri1fbdKubG7wL10v0oKDg3LzA4KZtDR0lVBADs= " -image create photo ximgFileSave -ximgFileSave put " + image create photo ximgFileSave + ximgFileSave put " R0lGODlhGAAYAPUAAAAAAAEBAQUFBQoKChMTExUVFRkZGSoqKjU1NTk5OT4+PkVFRUlJSU5OTlJS UlVVVVlZWV5eXmxsbIuLi4yMjJGRkZaWlpiYmJ2dnaCgoLa2trq6ury8vMHBwc7Ozvj4+P///wAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -650,8 +642,8 @@ Zbz5eCCE4sTrVRQPCoOi23EMiBb2xz0UcEAUCGwaC3h6fEICHYAIXV4Thl57RIogFQmOIBaRIJNE ixQJbJqcHw2UEhcPDJmbQ3mSFQ0KCgsKCQgMFa2ckh+/v52jpK/DxseuQrDHzMTKzc3JAMvQw9LU 1WzX2cbb3KPSa99skEMNZd8fGwxETE5P8PHxEw1pSvf4+UNBADs= " -image create photo ximgEditCopy -ximgEditCopy put " + image create photo ximgEditCopy + ximgEditCopy put " R0lGODlhGAAYAPUAAAAAAAEBAQQEBAgICA0NDRMTExgYGCgoKDMzMzs7Oz8/P0FBQUZGRkpKSktL S1RUVGZmZmlpaXd3d3l5eX5+foGBgYiIiJqamp6enqWlpaurq6ysrLu7u8XFxcfHx8zMzM7OztDQ 0NTU1Nra2u7u7u/v7/Hx8fX19fj4+P///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -661,8 +653,8 @@ Z2FtbWE9MC40NTQ1NDUALAAAAAAYABgAAAa+QAEqRSwaiwuAcqk0HJ/FCZNZIGYg2CyWQnxMl9VU gpoAISkhiRCLeUsaKRuSqJZpYICvaJ+UoRclF4knJb6/viahIqSJUEdSShMgyQAYIxrR0tMgHQNo aAQIBEsHB2AIBdgAHIdKCkRJ5Ckc46OlAA6a7+MOFg5KBBUU1/H34wADCmQSBAA7 " -image create photo ximgEditDelete -ximgEditDelete put " + image create photo ximgEditDelete + ximgEditDelete put " R0lGODlhGAAYAPQAAAAAAAEBAQUFBQsLCw4ODiUlJTMzMzk5OTw8PEhISFZWVldXV2RkZGxsbHBw cHR0dH5+fqenp6urq6ysrLa2trm5ub+/v8PDw8/Pz9HR0ebm5urq6u/v7/Ly8vj4+Pz8/CH5BAAA AAAAIf8LSW1hZ2VNYWdpY2sOZ2FtbWE9MC40NTQ1NDUALAAAAAAYABgAAAWPICCOZGmeaKqubMsK @@ -670,8 +662,8 @@ KMwSRjGQQ2EQK9FkFgVJYcE0eCkCRPOhJEQJykcDQcYOFE9HgjhIOp7KQaZSXD6cSWTzuQhdjMxn /skwXCIfZ955WFsDDh18fngADBh0dXcuZh8bEhF7bi9YWhNdE2BiZCdKGmFPAFFTVSo+QG8iRBlH PTU3Izk7LZ0ktoa5uru8KCEAOw== " -image create photo ximgToolInsertPolygon -ximgToolInsertPolygon put " + image create photo ximgToolInsertPolygon + ximgToolInsertPolygon put " R0lGODlhGAAYAPUAAAAAAAQEBAcHBwwMDBMTExcXFxkZGR4eHiYmJiwsLDExMTY2Njs7O0FBQURE RE9PT1FRUVVVVVlZWWZmZm9vb3FxcXV1dX19fYCAgIiIiJubm6GhoaampqioqLW1tb+/v8bGxsnJ yc7OztPT09nZ2eHh4eXl5ejo6Ozs7PDw8PX19fr6+v7+/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -681,8 +673,8 @@ cdCJribRrRiAGEVLC0B6/UhFPQThvBrIZDNEe00GIFEoakOCTBxRIQdLUSBxTRosJEpLIlkaBkwS LCsDTAV+USkVmEMEUQ9EDA6wDhQoWSQORYUaQxVgvVmIABcsJUYlvr6tQwtRCQARURYT0tPTyUQn LBYAhR9rRBssHwpREN5DnyplxOZCBWDa7EKFLCmd8cFRuvcA4yzN+8HgeQsCADs= " -image create photo ximgViewRedraw -ximgViewRedraw put " + image create photo ximgViewRedraw + ximgViewRedraw put " R0lGODlhGAAYAPUAAAAAAAICAgUFBQoKCg0NDRISEhcXFxsbGx4eHiUlJSgoKC0tLTAwMDc3Nz8/ P0JCQkZGRktLS0xMTFFRUVZWVlpaWl9fX2FhYWdnZ25ubnd3d3h4eH5+foCAgISEhI+Pj5ubm5+f n6Ghoaenp6qqqq2trbOzs7a2trm5ubu7u8LCwsfHx8vLy9LS0tbW1tvb2+Tk5Orq6u/v7/Dw8Pb2 @@ -693,8 +685,8 @@ NjQlCmRbAhZznycPbwIUqH0pE6wNKTWfKxQDrAkkajY1LBWSUwILFRcQFCMzNCoXBWWDzCkREiIp uW8dvjYqEQkMpFsDIZ82GeJlCybmGXhCFWB9Jg7vCGm/LSEQiW8OJS5UiMBw4J0QBRIkjDI4JAgA Ow== " -image create photo ximgFileOpen -ximgFileOpen put " + image create photo ximgFileOpen + ximgFileOpen put " R0lGODlhGAAYAPUAAAAAAAEBAQcHBwgICA8PDxMTExcXFx8fHyYmJi4uLjY2Njk5OT8/P0NDQ0VF RUpKSldXV2JiYmtra3R0dH19fYKCgoaGho+Pj5GRkZaWlp+fn6Kioqampqurq7Gxsbm5ucbGxsnJ yc3NzdPT09nZ2d7e3uHh4ebm5ujo6Ozs7PLy8vT09Pr6+v///wAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -704,8 +696,8 @@ dgWSOBgLhlq9QAyEh45YzGK16njWSoMQJjx3eXV3V4OEIRBCAwgLCwqNjY8Kko6TCwldFhgYF52e n6CemxYpdnOnqHcpJqapri0rJiIqr68rIh8pta4pHxwou6koHBgmwagmGBUlx6clFBIkzXMkEhAj 02IjEA3Y2VciDQkh31chCQYf5S0fBgIRGE7y8/TzGBECXvr7SUEAOw== " -image create photo ximgToolJoinTrim -ximgToolJoinTrim put " + image create photo ximgToolJoinTrim + ximgToolJoinTrim put " R0lGODlhGAAYAPUAAAAAAAICAgUFBScnJykpKS4uLjAwMDQ0NDs7O0BAQEZGRllZWWBgYGdnZ29v b3JycnV1dYODg4aGho2NjZCQkJaWlpqampycnKCgoKenp6ioqNHR0dbW1tjY2ODg4Obm5uvr6+/v 7/Ly8vT09Pr6+v///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -715,8 +707,8 @@ idPYEi0fy0RUEmkU5mGlRCK1L4e4vMQnUQp6e3wlFoCBAHODHxOGegsXFZEWEI2HlpeYmUkEDhgW kRcLhwMRHYMlFZYDFHZ8qYcFE6evegcXI3SugQgaIW0TEx4WegIMGyUhFwUDEg+BthwZBkgElWYH DAma20EAOw== " -image create photo ximgViewToggleColors -ximgViewToggleColors put " + image create photo ximgViewToggleColors + ximgViewToggleColors put " R0lGODlhGAAYAPUAAAAAAAICAgYGBg0NDQ4ODhERERQUFBsbGx0dHSEhISUlJSsrKy4uLjMzMzU1 NT09PUFBQUVFRUtLS09PT1JSUmNjY21tbXFxcX19fYuLi42NjZCQkJWVlZiYmJ2dnaSkpKenp6io qK2trbGxsbu7u7y8vMHBwdXV1dnZ2eTk5Obm5urq6uzs7PDw8P7+/gAAAAAAAAAAAAAAAAAAAAAA @@ -728,8 +720,8 @@ FQUFCwwJHCUjaRgsEkPWrL1nIiRH4OLk5rq7LRgGEyElHAkMC9rRF7/Otcq2rRuXEyTeVJPHKpmo JbNUgLh1rledWABKnboQDR0IBQ+JULKUIdMKTp4WjAwJwAGhOgQaJFrUACYkZULizLl4J88eLSF+ TowhAoFDIFFnJvwCICAOhwdEqODMOEIErCENHiDAKMRJiShcpRjhoABjEAA7 " -image create photo ximgEditDuplicate -ximgEditDuplicate put " + image create photo ximgEditDuplicate + ximgEditDuplicate put " R0lGODlhGAAYAPUAAAAAAAEBAQQEBAkJCQ0NDRERERQUFBsbGx8fHyAgICUlJSoqKi8vLzIyMjU1 NTk5OT8/P0FBQUdHR0lJSVFRUVZWVl1dXWJiYmVlZWtra25ubnJycnd3d319fYCAgISEhIuLi42N jZKSkpaWlpubm5+fn6KioqWlpaioqK2trbS0tLi4uL+/v8LCwsTExMvLy9HR0dfX19vb293d3eLi @@ -742,8 +734,8 @@ AAMA4BuTggIGGm9qkICAQEiGGWOIDNRxY8OAA6psiGhA5AGKkEPc6VgBAZWJlXc6wBQy8FAWQlQE nGTYCWCknV1aMBDtWVPZkKE6RL5JIWKE1atYR4hoQfSBDX1gbxBRUGJFi7NnWbBIq3ZtCxUkiiCb S5fugLpBAAA7 " -image create photo ximgToolBreak -ximgToolBreak put " + image create photo ximgToolBreak + ximgToolBreak put " R0lGODlhGAAYAPQAAAAAAAMDAwQEBDMzMzQ0NDo6Oj8/P0BAQEVFRUhISEtLS1lZWWVlZYaGhomJ iYuLi5aWlpmZmZ6enqOjo6enp6ioqKysrM7OztPT09jY2Onp6erq6u/v7/T09Pz8/P///yH5BAAA AAAAIf8LSW1hZ2VNYWdpY2sOZ2FtbWE9MC40NTQ1NDUALAAAAAAYABgAAAWGICCOZGmeaKqaAtJA @@ -751,8 +743,8 @@ MBQta4lM26d/UF0SlB3PRxpEhD0igCDpIJWHCufToVQ2EeXiQqUUgA+lMWMxCAAKhXLJQIwE53V8 LZ8jGIR1GiAoWDISBUoPFV8TUxgMShEcFRNOjQdKEEIdE4KTQhEEcz6UOxV5a586GxQInSsLEjER DwqpdLKzIiEAOw== " -image create photo ximgNetlist -ximgNetlist put " + image create photo ximgNetlist + ximgNetlist put " R0lGODlhGAAYAPUAAAAAAAYGBgkJCRAQEBYWFhoaGiIiIiYmJisrKzQ0NDo6Oj4+PkVFRU5OTlFR UVdXV1xcXGFhYWZmZmlpaW5ubnFxcXd3d3l5eX19fYODg4iIiIyMjJ+fn6Ghoa2trbS0tMDAwMXF xczMzNTU1Nra2t3d3e3t7fj4+Pr6+v///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -762,8 +754,8 @@ GIkiBjyKojhZHhJSqAdRS/GaPsK28J1KXYZiBxKDgwx5DVAPEX19HAEAWmyMk30oIANiCBabnAsA KJSUKCQQKRMlqKkbn6GTKCYTY0egKLW1jKMGa2QVnBmTl5B+lCF5RHwpHY8AYgVXVgnGbn1/gLJG egACI3JzKQoa4eINn2EpECLp6hjlS5FkWVt2X0wCEROE+IQRTf3+RkEAADs= " -image create photo ximgFileReload -ximgFileReload put " + image create photo ximgFileReload + ximgFileReload put " R0lGODlhGAAYAPUAAAAAAAICAgYGBggICA0NDRISEhQUFBsbGyEhISQkJCoqKiwsLDExMTMzMzg4 OD4+PkFBQUdHR0lJSUxMTFJSUlVVVVpaWltbW2VlZWlpaXNzc4yMjJOTk5SUlJ6enqqqqrCwsLm5 ub6+vsDAwMfHx9PT09TU1NjY2N/f3+Pj4+Xl5evr6+zs7PHx8ff39/r6+v///wAAAAAAAAAAAAAA @@ -773,8 +765,8 @@ Z2FtbWE9MC40NTQ1NDUALAAAAAAYABgAAAavQIBwSCwaj8ikcskkEhiCJnLhcQyUA8Nhyz0YKK0Q DAAJHJgmjR1GDicbCEYdpkYIGgVHroKnRQIESLWBt1K8gL5NwH8jGBnIycrKGCOAiI7RjS8mLdLX jyUXiy/d3t/g3i4iFwULDg/p6uvs6wu6UvHy8/TxQQA7 " -image create photo ximgEditRedo -ximgEditRedo put " + image create photo ximgEditRedo + ximgEditRedo put " R0lGODlhGAAYAPUAAAAAAAEBAQUFBQoKChISEhoaGh8fHyIiIiQkJCkpKSwsLDQ0NDk5OT4+PkJC QkpKSlNTU1paWmFhYWVlZWtra25ubnV1dXh4eH19fYCAgIeHh4uLi42NjZOTk5eXl5iYmKKioqmp qbS0tLu7u7y8vNXV1dzc3OHh4eXl5ejo6O/v7/Hx8fj4+P///wAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -784,16 +776,16 @@ d+j9eg7NwqOy6ZRacFRHoTxANqQTC85vqTwLRwIJGG99hy0rIHREAgohKoiSJhgCRAmQkogrH2hD CBsriCwre3CkHAlEAxN6JiIdFxQTEhEjfFmqRA0hJyAVDgYDRGUoG55DAhgkF2JXLSYcW0UKFxJK Hikb00UPDMNJFhncRQfkRwZVSJZj7e7v7kEAOw== " -image create photo ximgToolInsertText -ximgToolInsertText put " + image create photo ximgToolInsertText + ximgToolInsertText put " R0lGODlhGAAYAPQAAAAAAAEBAQoKCg0NDRERER0dHSIiIi0tLTIyMkJCQkRERFVVVV9fX2tra3Jy coKCgoeHh4iIiJmZmaenp6qqqru7u8vLy93d3eDg4Orq6u7u7vv7+////wAAAAAAAAAAACH5BAAA AAAAIf8LSW1hZ2VNYWdpY2sOZ2FtbWE9MC40NTQ1NDUALAAAAAAYABgAAAVrICCOREkMwqiuKnFx cNywtHjE+FTXTOT7j8JuSCwad4eFcslcCmmGDW6Ky9QKUioVsysovuBwYkw4ms9Fh2TNXkMGRYRW VhxYNPg8/nJA+/+AQwIVeoV6GRA0cnNUGjUPFJGSk5MLgZeYOyEAOw== " -image create photo ximgEditCut -ximgEditCut put " + image create photo ximgEditCut + ximgEditCut put " R0lGODlhGAAYAPUAAAAAAAEBAQQEBAsLCw8PDxAQEBUVFRkZGR8fHyIiIiUlJSoqKi4uLjMzMzU1 NTo6Ojw8PERERElJSUxMTFRUVFVVVVpaWl1dXWJiYmRkZGpqamxsbHJycnV1dXp6en5+foeHh4uL i46OjpKSkpaWlpubm56enqKioqampqioqK2trbGxsbe3t7q6ury8vMHBwcTExMnJyc7OztPT09TU @@ -805,8 +797,8 @@ IiwZk0YDCRAKfA5yWTEaCAhoRwIID+EAD+Q+PTgnDerLITDP0Sc5Pjtw7EjlYluRBSJy8OBVxpiM DhZK3Jg3Ixk+UTZGYPgwI9WqAgAYfJAhi9aBRz0kUbKEaYiBCy86+XgxoY8PEoEGvXhQRECiNBo4 VoBi08LBgDhz6vQ0wIABAj4AwPAQ02KHmTRCqsDI4mMGF6xCmIQwodEW2CH4zqo1EgQAOw== " -image create photo ximgEditMove -ximgEditMove put " + image create photo ximgEditMove + ximgEditMove put " R0lGODlhGAAYAPUAAAAAAAICAgYGBgoKCgwMDBERERcXFxsbGxwcHCkpKTw8PEdHR0tLS1VVVVlZ WV5eXmNjY2ZmZmdnZ29vb3JycnV1dYKCgoeHh4yMjJWVlZubm62trbGxsbS0tLi4uMHBwcTExMjI yNra2tzc3OTk5Ovr6/b29vn5+f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -816,8 +808,8 @@ ZYQykc7odGlzzJBR8Lg8/hEYHx/TfA+vGwUNHWYaGYWGhhoUSQsdHHZVRgoRVQSPRAIEVREKkH8c HgxJFISHhxokJh4OA38ffHsnHxCtr3sjGUcbJWm8JCcoIxgIYV7FBwghIxVgnUMXEQXNRFvS1dbS QQA7 " -image create photo ximgViewZoomBox -ximgViewZoomBox put " + image create photo ximgViewZoomBox + ximgViewZoomBox put " R0lGODlhGAAYAPUAAAAAAAEBAQYGBgsLCwwMDBISEhUVFRsbGx0dHSMjIyoqKjExMTc3Nzg4OEFB QUVFRUdHR1FRUVRUVFlZWWRkZGlpaXBwcHl5eYSEhJaWlpubm5ycnKGhoaSkpKmpqa6urrKysra2 try8vL+/v8nJycvLy9TU1Nzc3OLi4uTk5Onp6fPz8/X19fv7+/7+/gAAAAAAAAAAAAAAAAAAAAAA @@ -828,8 +820,8 @@ LhlUQgMPHyosJBYHQo6hogAEDBITDwhHaa6vAgoLl0etr0IFGyEPQwLAwQcoLhXHya8HKS4Uz6DB ANLNRNCi2s6318EI0+B83VTf1rne5evY6r/i0e5HIZwZ+fr7+hx51UcunKBDcE6LEQ6IJLgQYsQI Eg4jQow4okMEX0SSKNG4UWORIAA7 " -image create photo ximgToolInsertSymbol -ximgToolInsertSymbol put " + image create photo ximgToolInsertSymbol + ximgToolInsertSymbol put " R0lGODlhGAAYAPUAAAAAAAgICAwMDBYWFiIiIiUlJTIyMjQ0NEBAQERERFNTU1VVVVhYWFxcXGFh YWZmZm5ubnd3d3p6en19fYaGhoiIiJOTk5SUlK6urre3t7i4uMfHx8zMzNPT09nZ2d/f3+Li4uXl 5ejo6Pb29vn5+f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -839,16 +831,16 @@ wGBgeM/cSXHj9VTe8Eqmw40QQ15NUjEqjQpDBRERFVsVSg5bF0YEWxRLHyUiCwsKQ40lj0ocXpeO S3RdBA8PEp9KkZOVIHmIWxZDnF0Ye31/QwEICQ1bG3Fwc1wQRwZoZyRqR1nGXGBKUFRUVk7U1dbX 2EVBADs= " -image create photo ximgToolInsertWire -ximgToolInsertWire put " + image create photo ximgToolInsertWire + ximgToolInsertWire put " R0lGODlhGAAYAPQAAAAAAAEBAQ4ODhERERcXFyUlJSoqKi8vLzAwMDY2Nj4+PllZWWRkZGtra2xs bHh4eIODg4eHh5aWlpubm52dna+vr7Gxsbu7u8PDw8TExPDw8Pv7+wAAAAAAAAAAAAAAACH5BAAA AAAAIf8LSW1hZ2VNYWdpY2sOZ2FtbWE9MC40NTQ1NDUALAAAAAAYABgAAAV0ICCOZGmeppAkAuqK CDRN0PGegnM9z9W0N5IhMhFJIoYgqSAjEGgFJWmBsVgwCylpwNBoGECtSLHZKMQkshk9Up/ZADc8 Xn6z5XD8vQ7nesFsCxkVFVhoBREUTlBiQxIiE0hiAg07PT9oBzI0NmwqCGFzNyEAOw== " -image create photo ximgEditPushSch -ximgEditPushSch put " + image create photo ximgEditPushSch + ximgEditPushSch put " R0lGODlhGAAYAPQAAAAAAAICAgUFBQkJCQwMDBMTExYWFhgYGB0dHSEhIU9PT19fX2NjY2lpaWxs bHd3d3h4eHx8fIODg4eHh4uLi8HBwcjIyM7OztHR0d/f3+Pj4+Xl5enp6ezs7Pn5+f///yH5BAAA AAAAIf8LSW1hZ2VNYWdpY2sOZ2FtbWE9MC40NTQ1NDUALAAAAAAYABgAAAWLICCOZGmeaKquLKA4 @@ -856,16 +848,16 @@ TSw7SitUX67nlcDeu13vhwvyfCug8TNMFo1NlRKKlD6DURPhcEBYlh9LgksoDRYXzcYD9mw0GMag lHh0wLtOJHFCPDR4HxsQfCgHEhlgGhMIKwUTiUEaFAYtBRIbOxuULSIGEBw5HBEHnSN+GxwPhaYi CQ4OrK0iBGWzt7gkIQA7 " -image create photo ximgToolInsertRect -ximgToolInsertRect put " + image create photo ximgToolInsertRect + ximgToolInsertRect put " R0lGODlhGAAYAPMAAAAAAAICAgUFBQYGBhsbGzs7O2FhYWlpaZWVlZ6enqGhob+/v+Tk5PT09P// /wAAACH5BAAAAAAAIf8LSW1hZ2VNYWdpY2sOZ2FtbWE9MC40NTQ1NDUALAAAAAAYABgAAASAEEgg qr1YzF3U+mAYKsUmGY2jrizbGCZwOI2C3HiupEc8M4TYhsBw9Ey/oFBCNPocwCWzeNwkpYBmdXKV ap9RLxWsXH6R0LLwbE1j2Vy32IkOm8d1dQwu6d7pbXZreIF6Jnwycn9bfTQ2OZA7gBMoLZYrLzEd IpwgCSUxGaIWGxEAOw== " -image create photo ximgEditPaste -ximgEditPaste put " + image create photo ximgEditPaste + ximgEditPaste put " R0lGODlhGAAYAPUAAAAAAAICAgoKCg8PDxERERQUFB8fHyIiIiQkJCwsLDExMTQ0NEREREpKSlNT U1VVVVxcXF9fX2FhYXJycnd3d3x8fIGBgYeHh4uLi5WVlaKioqWlpaioqK+vr7Kysru7u729vcbG xsrKys/Pz9HR0dnZ2d/f3+Li4uTk5O/v7/Hx8fT09Pr6+v///wAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -875,14 +867,14 @@ xFKwgrtoKOECebjfb4hFYExQGtBScs/nh7RUUCd9hEkkRhtEUCAtIwyPkJAmLRxGBAwHiy0gaQAk lJ2MnGmflQAOHxaao2ilRh6BT6KdrgAYjau0oEYDUbOku2i/rbsVKR9GBSYsm7qmsCtGC3usXbUS IxlGAh8qzcCmwt/E4V0fLSEH6uvreuVRk4V9Ip3x8nuHaQkdFhT+//8ucDDQqaDBg2iCAAA7 " -image create photo ximgToolInsertLine -ximgToolInsertLine put " + image create photo ximgToolInsertLine + ximgToolInsertLine put " R0lGODlhGAAYAPIAAAAAAA0NDTc3Nz09PT4+Pt7e3vj4+Pv7+yH5BAAAAAAAIf8LSW1hZ2VNYWdp Y2sOZ2FtbWE9MC40NTQ1NDUALAAAAAAYABgAAAMtCLrc/jDKSau9OOvNew0CIY6kKASQUBxs67KF kK5vHUNgqROn5//AoHBILEoSADs= " -image create photo ximgToolInsertCircle -ximgToolInsertCircle put " + image create photo ximgToolInsertCircle + ximgToolInsertCircle put " R0lGODlhGAAYAPUAAAAAAAEBAQUFBQkJCQ4ODhISEiEhISYmJi8vLz4+PkBAQEdHR0tLS0xMTFJS UlZWVlhYWGtra2xsbHx8fH5+foKCgo+Pj5KSkpWVlZiYmJycnKysrLOzs7S0tMPDw8jIyNXV1dbW 1uLi4uTk5Ovr6+zs7PPz8/b29vj4+P7+/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -894,8 +886,8 @@ SSMcCdVECh0jFhba3N1CCR0iS9IN5qQe2BBXEu4Azc+8vsDdBRnFTrI+tOvmIBCGJwzKbHASjBUH FB4WWKpAosSmYJ9CqTpgAYUiB42gPOJgx0KlIXRIoMAjoYECBQ0kABJEKMwYDybOeOjQgY0bGQ8U OHUasACDFSxauGBYUGvVsSRLmjQVEgQAOw== " -image create photo ximgEditPushSym -ximgEditPushSym put " + image create photo ximgEditPushSym + ximgEditPushSym put " R0lGODlhGAAYAPUAAAAAAAQEBAgICA0NDRERERcXFx0dHSIiIicnJywsLDAwMDU1NT09PUNDQ0dH R0hISFBQUFVVVWJiYmZmZnBwcHl5eY2NjZKSkpWVlZqamqGhoaSkpKqqqq2trbKysry8vMLCwsfH x8vLy83NzdPT09fX19jY2N/f3+Dg4OTk5Ojo6O3t7fPz8/X19fr6+v///wAAAAAAAAAAAAAAAAAA @@ -905,8 +897,8 @@ KHTCvsQh08Iq6LDM2NPkC6io4OcEXegwYV0fBHtDBiJRKxmDTAIeKBKKCAeSkwsHCAV0HnhYKhgH ViObZi1eQxITE4Yak6wIChJ+LktDZiFaAyFnAUMmJyZvHF8HLi8OTRsvFnS5IhkZGEPIF3QlZtEv 01+GzRkXvidvHV8IxLMAZiBaBKEkRBARECAvq6ySCQwUKS8ua00kolhWPKjCAeCLExYwMQkCADs= " -image create photo ximgViewZoomOut -ximgViewZoomOut put " + image create photo ximgViewZoomOut + ximgViewZoomOut put " R0lGODlhGAAYAPUAAAAAAAICAgQEBAoKChAQEB8fHyIiIiUlJSgoKC8vLz4+PkNDQ0RERGtra25u bnt7e3x8fIODg4WFhYiIiJ+fn6CgoLOzs7a2tr29vcHBwcjIyOXl5evr6+7u7vf39/n5+f///wAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA diff --git a/src/utile/utile.tcl b/src/utile/utile.tcl index ead5443b..0ae6b349 100755 --- a/src/utile/utile.tcl +++ b/src/utile/utile.tcl @@ -1,193 +1,190 @@ #!/bin/sh # File: utile.tcl -# +# # This file is part of XSCHEM, # a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit # simulation. # Copyright (C) 1998-2023 Stefan Frederik Schippers -# +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - # the next line restarts using wish \ exec wish "$0" "$@" proc text_window {w filename} { - catch {destroy $w} - toplevel $w - wm title $w "(IN)UTILE ALIAS FILE" - wm iconname $w "ALIAS" - - frame $w.buttons - pack $w.buttons -side bottom -fill x -pady 2m - button $w.buttons.dismiss -text Dismiss -command "destroy $w" - button $w.buttons.code -text "See Code" -command "showCode $w" - pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 - - text $w.text -relief sunken -bd 2 -yscrollcommand "$w.scroll set" -setgrid 1 \ - -height 30 - scrollbar $w.scroll -command "$w.text yview" - pack $w.scroll -side right -fill y - pack $w.text -expand yes -fill both - set fileid [open $filename "r"] - $w.text insert 0.0 [read $fileid] - close $fileid -} + catch {destroy $w} + toplevel $w + wm title $w "(IN)UTILE ALIAS FILE" + wm iconname $w "ALIAS" -proc entry_line {txtlabel} { - global entry1 - toplevel .ent2 -class Dialog - set X [expr [winfo pointerx .ent2] - 60] - set Y [expr [winfo pointery .ent2] - 35] - wm geometry .ent2 "+$X+$Y" - label .ent2.l1 -text $txtlabel - entry .ent2.e1 -width 40 - .ent2.e1 delete 0 end - .ent2.e1 insert 0 $entry1 - button .ent2.b1 -text "OK" -command \ - { - set entry1 [.ent2.e1 get ] - destroy .ent2 - } - bind .ent2 { - set entry1 [.ent2.e1 get ] - destroy .ent2 - } - pack .ent2.l1 -side top -fill x - pack .ent2.e1 -side top -fill both -expand yes - pack .ent2.b1 -side top -fill x - grab set .ent2 - focus .ent2.e1 - tkwait window .ent2 - return $entry1 + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text Dismiss -command "destroy $w" + button $w.buttons.code -text "See Code" -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + text $w.text -relief sunken -bd 2 -yscrollcommand "$w.scroll set" -setgrid 1 \ + -height 30 + scrollbar $w.scroll -command "$w.text yview" + pack $w.scroll -side right -fill y + pack $w.text -expand yes -fill both + set fileid [open $filename "r"] + $w.text insert 0.0 [read $fileid] + close $fileid } - +proc entry_line {txtlabel} { + global entry1 + toplevel .ent2 -class Dialog + set X [expr [winfo pointerx .ent2] - 60] + set Y [expr [winfo pointery .ent2] - 35] + wm geometry .ent2 "+$X+$Y" + label .ent2.l1 -text $txtlabel + entry .ent2.e1 -width 40 + .ent2.e1 delete 0 end + .ent2.e1 insert 0 $entry1 + button .ent2.b1 -text "OK" -command \ + { + set entry1 [.ent2.e1 get ] + destroy .ent2 + } + bind .ent2 { + set entry1 [.ent2.e1 get ] + destroy .ent2 + } + pack .ent2.l1 -side top -fill x + pack .ent2.e1 -side top -fill both -expand yes + pack .ent2.b1 -side top -fill x + grab set .ent2 + focus .ent2.e1 + tkwait window .ent2 + return $entry1 +} proc write_data {w f} { - set fid [open $f "w"] - set t [$w get 0.0 {end - 1 chars}] - puts -nonewline $fid $t - close $fid + set fid [open $f "w"] + set t [$w get 0.0 {end - 1 chars}] + puts -nonewline $fid $t + close $fid } - + proc read_data {w f} { - set fid [open $f "r"] - set t [read $fid] - $w delete 0.0 end - $w insert 0.0 $t - close $fid + set fid [open $f "r"] + set t [read $fid] + $w delete 0.0 end + $w insert 0.0 $t + close $fid } proc template {w f} { - set fid [open $f "r"] - set t [read $fid] - $w insert 0.0 $t - close $fid + set fid [open $f "r"] + set t [read $fid] + $w insert 0.0 $t + close $fid } proc new_window {w filename} { - catch {destroy $w} - toplevel $w - wm title $w "(IN)UTILE NEW WINDOW" - wm iconname $w "STIM.WIND" - set fileid [open $filename "RDONLY CREAT"] - set testo [read $fileid] - close $fileid - frame $w.buttons - pack $w.buttons -side bottom -fill x -pady 2m - text $w.text -relief sunken -bd 2 -yscrollcommand "$w.scroll set" -setgrid 1 \ - -height 30 - $w.text insert 0.0 $testo - scrollbar $w.scroll -command "$w.text yview" - button $w.buttons.translate -text Translate -command "write_data $w.text $filename; \ + catch {destroy $w} + toplevel $w + wm title $w "(IN)UTILE NEW WINDOW" + wm iconname $w "STIM.WIND" + set fileid [open $filename "RDONLY CREAT"] + set testo [read $fileid] + close $fileid + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + text $w.text -relief sunken -bd 2 -yscrollcommand "$w.scroll set" -setgrid 1 \ + -height 30 + $w.text insert 0.0 $testo + scrollbar $w.scroll -command "$w.text yview" + button $w.buttons.translate -text Translate -command "write_data $w.text $filename; \ translate $filename ; get_time" - button $w.buttons.dismiss -text Dismiss -command "destroy $w" - pack $w.buttons.dismiss $w.buttons.translate -side left -expand 1 - - pack $w.scroll -side right -fill y - pack $w.text -expand yes -fill both -} - -proc get_time {} { - set fileid [open "inutile.simulationtime" "RDONLY"] - .buttons.time delete 0 end - .buttons.time insert 0 [read -nonewline $fileid] - close $fileid - file delete "inutile.simulationtime" -} - - -proc alias_window {w filename} { - catch {destroy $w} - toplevel $w - wm title $w "(IN)UTILE ALIAS FILE: $filename" - wm iconname $w "ALIAS" + button $w.buttons.dismiss -text Dismiss -command "destroy $w" + pack $w.buttons.dismiss $w.buttons.translate -side left -expand 1 - set fileid [open $filename "RDONLY CREAT"] - set testo [read $fileid] - close $fileid - frame $w.buttons - pack $w.buttons -side bottom -fill x -pady 2m - text $w.text -relief sunken -bd 2 -yscrollcommand "$w.scroll set" -setgrid 1 \ - -height 30 - scrollbar $w.scroll -command "$w.text yview" - button $w.buttons.dismiss -text Dismiss -command "destroy $w" - button $w.buttons.save -text Save -command "write_data $w.text $filename" - button $w.buttons.load -text Reload -command "read_data $w.text $filename" - pack $w.buttons.dismiss $w.buttons.save $w.buttons.load -side left -expand 1 - - pack $w.scroll -side right -fill y - pack $w.text -expand yes -fill both - $w.text insert 0.0 $testo -} + pack $w.scroll -side right -fill y + pack $w.text -expand yes -fill both +} + +proc get_time {} { + set fileid [open "inutile.simulationtime" "RDONLY"] + .buttons.time delete 0 end + .buttons.time insert 0 [read -nonewline $fileid] + close $fileid + file delete "inutile.simulationtime" +} + + +proc alias_window {w filename} { + catch {destroy $w} + toplevel $w + wm title $w "(IN)UTILE ALIAS FILE: $filename" + wm iconname $w "ALIAS" + + set fileid [open $filename "RDONLY CREAT"] + set testo [read $fileid] + close $fileid + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + text $w.text -relief sunken -bd 2 -yscrollcommand "$w.scroll set" -setgrid 1 \ + -height 30 + scrollbar $w.scroll -command "$w.text yview" + button $w.buttons.dismiss -text Dismiss -command "destroy $w" + button $w.buttons.save -text Save -command "write_data $w.text $filename" + button $w.buttons.load -text Reload -command "read_data $w.text $filename" + pack $w.buttons.dismiss $w.buttons.save $w.buttons.load -side left -expand 1 + + pack $w.scroll -side right -fill y + pack $w.text -expand yes -fill both + $w.text insert 0.0 $testo +} proc help_window {w filename} { - catch {destroy $w} - toplevel $w - wm title $w "(IN)UTILE ALIAS FILE" - wm iconname $w "ALIAS" - - frame $w.buttons - pack $w.buttons -side bottom -fill x -pady 2m - button $w.buttons.dismiss -text Dismiss -command "destroy $w" - button $w.buttons.save -text Save -command "write_data $w.text $filename" - pack $w.buttons.dismiss $w.buttons.save -side left -expand 1 - - text $w.text -relief sunken -bd 2 -yscrollcommand "$w.scroll set" -setgrid 1 \ - -height 30 -width 90 - scrollbar $w.scroll -command "$w.text yview" - pack $w.scroll -side right -fill y - pack $w.text -expand yes -fill both - set fileid [open $filename "RDONLY CREAT"] - $w.text insert 0.0 [read $fileid] - close $fileid -} + catch {destroy $w} + toplevel $w + wm title $w "(IN)UTILE ALIAS FILE" + wm iconname $w "ALIAS" + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text Dismiss -command "destroy $w" + button $w.buttons.save -text Save -command "write_data $w.text $filename" + pack $w.buttons.dismiss $w.buttons.save -side left -expand 1 + + text $w.text -relief sunken -bd 2 -yscrollcommand "$w.scroll set" -setgrid 1 \ + -height 30 -width 90 + scrollbar $w.scroll -command "$w.text yview" + pack $w.scroll -side right -fill y + pack $w.text -expand yes -fill both + set fileid [open $filename "RDONLY CREAT"] + $w.text insert 0.0 [read $fileid] + close $fileid +} proc translate {f} { - global tcl_platform - set OS [lindex $tcl_platform(os) 0] - if {$OS == "Windows"} { - eval exec "utile.bat $f" - } else { - eval exec "utile $f" - } + global tcl_platform + set OS [lindex $tcl_platform(os) 0] + if {$OS == "Windows"} { + eval exec "utile.bat $f" + } else { + eval exec "utile $f" + } } @@ -195,50 +192,50 @@ wm title . "(IN)UTILE (Stefan Schippers, sschippe)" wm iconname . "(IN)UTILE" set filename [lindex $argv 0] -if { ![string compare $filename ""] } then { - wm withdraw . - tk_messageBox -type ok -message "Please give a file name as argument" - exit +if {![string compare $filename ""]} then { + wm withdraw . + tk_messageBox -type ok -message "Please give a file name as argument" + exit } set entry1 {} frame .buttons pack .buttons -side bottom -fill x -pady 2m -button .buttons.translate -text Translate -command " \ +button .buttons.translate -text Translate -command " \ write_data .text $filename; translate $filename ; get_time " button .buttons.dismiss -text Dismiss -command "destroy ." button .buttons.code -text "Help" -command {help_window .help $env(UTILE3_PATH)/utile.txt} text .text -relief sunken -bd 2 -yscrollcommand ".scroll set" -setgrid 1 \ - -height 30 + -height 30 scrollbar .scroll -command ".text yview" button .buttons.save -text Save -command { set entry1 $filename;set filename [entry_line {Filename}] - write_data .text $filename + write_data .text $filename } button .buttons.load -text Reload -command { set entry1 $filename;set filename [entry_line {Filename}] - read_data .text $filename + read_data .text $filename } button .buttons.send -text "Template" -command { if { ![string compare [.text get 0.0 {end - 1 chars}] ""] } then { - template .text $env(UTILE3_PATH)/template.stimuli + template .text $env(UTILE3_PATH)/template.stimuli } } label .buttons.timelab -text "time:" -entry .buttons.time -width 11 +entry .buttons.time -width 11 button .buttons.new -text new_window -command "new_window .new_win new_window_stimuli" pack .buttons.dismiss .buttons.code \ - .buttons.load .buttons.save .buttons.translate \ - .buttons.send .buttons.new .buttons.timelab .buttons.time -side left -expand 1 + .buttons.load .buttons.save .buttons.translate \ + .buttons.send .buttons.new .buttons.timelab .buttons.time -side left -expand 1 pack .scroll -side right -fill y pack .text -expand yes -fill both # 20140408 -if { [file exists $filename] } { - set fileid [open $filename "RDONLY"] - .text insert 0.0 [read $fileid] - close $fileid +if {[file exists $filename]} { + set fileid [open $filename "RDONLY"] + .text insert 0.0 [read $fileid] + close $fileid } @@ -247,11 +244,8 @@ regsub {\..*$} $tmp {} lines for {set i 1} {$i <= $lines} {incr i} { - set tmp [.text get $i.0 "$i.0 lineend"] - if [regexp {^(include)|(\.include)} $tmp ] { - alias_window .tw$i [lindex $tmp 1] + set tmp [.text get $i.0 "$i.0 lineend"] + if [regexp {^(include)|(\.include)} $tmp] { + alias_window .tw$i [lindex $tmp 1] } -} - - - +} diff --git a/tests/create_save.tcl b/tests/create_save.tcl index 61664bb6..4388a8c1 100644 --- a/tests/create_save.tcl +++ b/tests/create_save.tcl @@ -1,21 +1,21 @@ # # File: create_save.tcl -# +# # This file is part of XSCHEM, -# a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit +# a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit # simulation. # Copyright (C) 1998-2022 Stefan Frederik Schippers -# +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA @@ -29,38 +29,38 @@ file delete -force $testname/results file mkdir $testname/results proc create_save {} { - global testname pathlist xschem_cmd num_fatals - set results_dir ${testname}/results - if {[file exists ${testname}/tests]} { - set ff [lsort [glob -directory ${testname}/tests -tails \{.*,*\}]] - foreach f $ff { - if {$f eq {..} || $f eq {.}} {continue} - if {[regexp {\.(tcl)$} $f ]} { - set fn_sch [regsub {tcl$} $f {sch}] - set a [catch "open \"$results_dir/$fn_sch\" w" fd] - if {!$a} { - puts $fd "v {xschem version=2.9.5 file_version=1.1}" - puts $fd "G {}" - puts $fd "V {}" - puts $fd "S {}" - puts $fd "E {}" - close $fd - set filename [regsub {\.tcl$} $f {}] - set output ${filename}_debug.txt - if {[catch {eval exec {$xschem_cmd ${results_dir}/$fn_sch --pipe -d 1 --script ${testname}/tests/${f} 2> ${results_dir}/$output}} msg]} { - puts "FATAL: $msg" - incr num_fatals - } else { - lappend pathlist $output - lappend pathlist "${filename}.sch" - cleanup_debug_file ${results_dir}/$output - cleanup_debug_file ${results_dir}/$fn_sch - } + global testname pathlist xschem_cmd num_fatals + set results_dir ${testname}/results + if {[file exists ${testname}/tests]} { + set ff [lsort [glob -directory ${testname}/tests -tails \{.*,*\}]] + foreach f $ff { + if {$f eq {..} || $f eq {.}} {continue} + if {[regexp {\.(tcl)$} $f]} { + set fn_sch [regsub {tcl$} $f {sch}] + set a [catch "open \"$results_dir/$fn_sch\" w" fd] + if {!$a} { + puts $fd "v {xschem version=2.9.5 file_version=1.1}" + puts $fd "G {}" + puts $fd "V {}" + puts $fd "S {}" + puts $fd "E {}" + close $fd + set filename [regsub {\.tcl$} $f {}] + set output ${filename}_debug.txt + if {[catch {eval exec {$xschem_cmd ${results_dir}/$fn_sch --pipe -d 1 --script ${testname}/tests/${f} 2> ${results_dir}/$output}} msg]} { + puts "FATAL: $msg" + incr num_fatals + } else { + lappend pathlist $output + lappend pathlist "${filename}.sch" + cleanup_debug_file ${results_dir}/$output + cleanup_debug_file ${results_dir}/$fn_sch + } + } + } } - } } - } } create_save -print_results $testname $pathlist $num_fatals \ No newline at end of file +print_results $testname $pathlist $num_fatals diff --git a/tests/create_save/tests/0_examples_top.tcl b/tests/create_save/tests/0_examples_top.tcl index 44139398..3c63cd84 100644 --- a/tests/create_save/tests/0_examples_top.tcl +++ b/tests/create_save/tests/0_examples_top.tcl @@ -1,11 +1,11 @@ -xschem line 910 -560 960 -540 -xschem line 880 -680 1200 -680 -xschem line 900 -540 950 -560 -xschem line 900 -550 950 -530 -xschem line 910 -530 960 -550 -xschem rect 940 -510 960 -450 -xschem rect 900 -490 970 -470 -xschem rect 910 -510 930 -450 +xschem line 910 -560 960 -540 +xschem line 880 -680 1200 -680 +xschem line 900 -540 950 -560 +xschem line 900 -550 950 -530 +xschem line 910 -530 960 -550 +xschem rect 940 -510 960 -450 +xschem rect 900 -490 970 -470 +xschem rect 910 -510 930 -450 xschem wire 870 -300 990 -300 {lab=#net1} xschem wire 910 -340 910 -250 {lab=#net2} xschem wire 910 -270 970 -270 {lab=#net2} @@ -31,4 +31,4 @@ xschem instance ../xschem_library/devices/bus_connect.sym 500 -530 0 0 {name=l3 xschem instance ../xschem_library/devices/bus_connect_nolab.sym 400 -530 0 0 {name=r1} xschem instance ../xschem_library/devices/lab_pin.sym 410 -600 3 1 {name=l4 sig_type=std_logic lab=BUS[2]} xschem save -xschem exit closewindow \ No newline at end of file +xschem exit closewindow diff --git a/tests/create_save/tests/pcb_test1.tcl b/tests/create_save/tests/pcb_test1.tcl index a68a1956..f3ad86e4 100644 --- a/tests/create_save/tests/pcb_test1.tcl +++ b/tests/create_save/tests/pcb_test1.tcl @@ -4,25 +4,25 @@ xschem delete xschem set rectcolor 20 xschem rect 350 -550 940 -290 xschem wire 310 -330 380 -330 {lab=INPUT_B} -xschem wire 310 -370 380 -370 {lab=INPUT_A} -xschem wire 760 -420 830 -420 {lab=B} -xschem wire 760 -460 830 -460 {lab=A} -xschem wire 480 -350 520 -350 {lab=B} -xschem wire 930 -440 970 -440 {lab=OUTPUT_Y} -xschem wire 310 -440 380 -440 {lab=INPUT_F} -xschem wire 310 -480 380 -480 {lab=INPUT_E} -xschem wire 480 -460 520 -460 {lab=A} -xschem wire 550 -190 670 -190 {lab=VCCFILT} -xschem wire 590 -130 590 -110 {lab=ANALOG_GND} -xschem wire 790 -190 940 -190 {lab=VCC5} -xschem wire 890 -130 890 -110 {lab=ANALOG_GND} -xschem wire 730 -110 890 -110 {lab=ANALOG_GND} -xschem wire 730 -160 730 -110 {lab=ANALOG_GND} -xschem wire 590 -110 730 -110 {lab=ANALOG_GND} -xschem wire 520 -460 760 -460 {lab=A} -xschem wire 580 -420 760 -420 {lab=B} -xschem wire 580 -420 580 -350 {lab=B} -xschem wire 520 -350 580 -350 {lab=B} +xschem wire 310 -370 380 -370 {lab=INPUT_A} +xschem wire 760 -420 830 -420 {lab=B} +xschem wire 760 -460 830 -460 {lab=A} +xschem wire 480 -350 520 -350 {lab=B} +xschem wire 930 -440 970 -440 {lab=OUTPUT_Y} +xschem wire 310 -440 380 -440 {lab=INPUT_F} +xschem wire 310 -480 380 -480 {lab=INPUT_E} +xschem wire 480 -460 520 -460 {lab=A} +xschem wire 550 -190 670 -190 {lab=VCCFILT} +xschem wire 590 -130 590 -110 {lab=ANALOG_GND} +xschem wire 790 -190 940 -190 {lab=VCC5} +xschem wire 890 -130 890 -110 {lab=ANALOG_GND} +xschem wire 730 -110 890 -110 {lab=ANALOG_GND} +xschem wire 730 -160 730 -110 {lab=ANALOG_GND} +xschem wire 590 -110 730 -110 {lab=ANALOG_GND} +xschem wire 520 -460 760 -460 {lab=A} +xschem wire 580 -420 760 -420 {lab=B} +xschem wire 580 -420 580 -350 {lab=B} +xschem wire 520 -350 580 -350 {lab=B} xschem instance ../xschem_library/pcb/74ls00.sym 420 -350 0 0 {name=U1:2 risedel=100 falldel=200} xschem instance ../xschem_library/pcb/74ls00.sym 870 -440 0 0 {name=U1:1 risedel=100 falldel=200} xschem instance ../xschem_library/devices/lab_pin.sym 970 -440 0 1 {name=p0 lab=OUTPUT_Y} @@ -76,4 +76,4 @@ xschem instance ../xschem_library/devices/lab_pin.sym 40 -350 0 1 {name=l5 lab=I xschem instance ../xschem_library/devices/lab_pin.sym 40 -410 0 1 {name=l6 lab=INPUT_E verilog_type=reg} xschem instance ../xschem_library/devices/lab_pin.sym 40 -390 0 1 {name=l7 lab=INPUT_F verilog_type=reg} xschem save -xschem exit closewindow \ No newline at end of file +xschem exit closewindow diff --git a/tests/create_save/tests/pcb_voltage_protection.tcl b/tests/create_save/tests/pcb_voltage_protection.tcl index 83a7044f..659f8e71 100644 --- a/tests/create_save/tests/pcb_voltage_protection.tcl +++ b/tests/create_save/tests/pcb_voltage_protection.tcl @@ -37,20 +37,20 @@ vvss vss 0 dc 0 * .tran 5u 7m uic ** models are generally not free: you must download -** SPICE models for active devices and put them into the below +** SPICE models for active devices and put them into the below ** referenced file in netlist/simulation directory. .include \\"models_pcb_voltage_protection.txt\\" .dc VVCC 0 8 0.004 .save all "} -xschem instance ../xschem_library/devices/pnp.sym 580 -390 0 0 {name=Q6 -model=BC857 -device=BC857 +xschem instance ../xschem_library/devices/pnp.sym 580 -390 0 0 {name=Q6 +model=BC857 +device=BC857 footprint=SOT23 url="https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=2ahUKEwijlfagu4zfAhUN0xoKHTPBAb0QFjAAegQIAhAC&url=http%3A%2F%2Fwww.onsemi.com%2Fpub%2FCollateral%2FPN2907-D.PDF&usg=AOvVaw2wgr87fGZgGfBRhXzHGwZM"} xschem instance ../xschem_library/devices/zener.sym 330 -190 2 0 {name=x3 -model=BZX5V1 -device=BZX5V1 +model=BZX5V1 +device=BZX5V1 footprint=acy(300) xxxspiceprefix="#D#"} xschem instance ../xschem_library/devices/gnd.sym 330 -130 0 0 {name=l13 lab=VSS} @@ -61,9 +61,9 @@ xschem instance ../xschem_library/devices/res.sym 600 -190 0 0 {name=R5 m=1 valu xschem instance ../xschem_library/devices/gnd.sym 600 -130 0 0 {name=l16 lab=VSS} xschem instance ../xschem_library/devices/lab_wire.sym 360 -390 0 0 {name=l0 lab=B} xschem instance ../xschem_library/devices/res.sym 330 -340 0 0 {name=R2 m=1 value=510 footprint=1206 device=resistor} -xschem instance ../xschem_library/devices/pmos.sym 750 -360 0 0 {name=M2 -model=IRLML6402 -device=IRLML6402 +xschem instance ../xschem_library/devices/pmos.sym 750 -360 0 0 {name=M2 +model=IRLML6402 +device=IRLML6402 footprint=SOT23 spiceprefix=X m=1 @@ -72,14 +72,14 @@ xschem instance ../xschem_library/devices/led.sym 650 -290 0 0 {name=x1 model=D1 xschem instance ../xschem_library/devices/lab_pin.sym 170 -340 0 1 {name=p6 lab=VOUT} xschem instance ../xschem_library/devices/lab_pin.sym 170 -360 0 1 {name=p7 lab=VSS} xschem instance ../xschem_library/devices/lab_pin.sym 170 -380 0 1 {name=p8 lab=VCC} -xschem instance ../xschem_library/devices/zener.sym 250 -190 2 0 {name=x4 -model=BZX5V1 +xschem instance ../xschem_library/devices/zener.sym 250 -190 2 0 {name=x4 +model=BZX5V1 device=BZX5V1 -area=1 -footprint=minimelf +area=1 +footprint=minimelf spice_ignore=true} xschem instance ../xschem_library/devices/gnd.sym 250 -130 0 0 {name=l1 lab=VSS} xschem instance ../xschem_library/devices/res.sym 550 -290 0 0 {name=R1 m=1 value=47K footprint=1206 device=resistor} xschem instance ../xschem_library/devices/lab_wire.sym 330 -260 0 0 {name=l3 lab=Z} xschem save -xschem exit closewindow \ No newline at end of file +xschem exit closewindow diff --git a/tests/create_save/tests/rom8k.tcl b/tests/create_save/tests/rom8k.tcl index 1cfa9475..7a407f0c 100644 --- a/tests/create_save/tests/rom8k.tcl +++ b/tests/create_save/tests/rom8k.tcl @@ -1,33 +1,33 @@ xschem set rectcolor 3 -xschem line 850 -270 850 -60 -xschem line 1050 -270 1050 -60 -xschem line 1250 -270 1250 -60 +xschem line 850 -270 850 -60 +xschem line 1050 -270 1050 -60 +xschem line 1250 -270 1250 -60 xschem set rectcolor 8 -xschem line 820 -220 850 -220 -xschem line 850 -220 850 -180 -xschem line 850 -180 950 -180 -xschem line 950 -220 950 -180 -xschem line 950 -220 1050 -220 -xschem line 1050 -220 1050 -180 -xschem line 1050 -180 1150 -180 -xschem line 1150 -220 1150 -180 -xschem line 1150 -220 1250 -220 -xschem line 1250 -220 1250 -180 -xschem line 1250 -180 1300 -180 -xschem line 950 -160 950 -120 -xschem line 950 -160 980 -160 -xschem line 980 -160 980 -120 -xschem line 980 -120 1150 -120 -xschem line 1150 -160 1150 -120 -xschem line 1150 -160 1180 -160 -xschem line 1180 -160 1180 -120 -xschem line 1180 -120 1300 -120 -xschem line 820 -120 950 -120 +xschem line 820 -220 850 -220 +xschem line 850 -220 850 -180 +xschem line 850 -180 950 -180 +xschem line 950 -220 950 -180 +xschem line 950 -220 1050 -220 +xschem line 1050 -220 1050 -180 +xschem line 1050 -180 1150 -180 +xschem line 1150 -220 1150 -180 +xschem line 1150 -220 1250 -220 +xschem line 1250 -220 1250 -180 +xschem line 1250 -180 1300 -180 +xschem line 950 -160 950 -120 +xschem line 950 -160 980 -160 +xschem line 980 -160 980 -120 +xschem line 980 -120 1150 -120 +xschem line 1150 -160 1150 -120 +xschem line 1150 -160 1180 -160 +xschem line 1180 -160 1180 -120 +xschem line 1180 -120 1300 -120 +xschem line 820 -120 950 -120 xschem set rectcolor 7 -xschem rect 950 -250 980 -80 -xschem rect 1150 -250 1180 -80 +xschem rect 950 -250 980 -80 +xschem rect 1150 -250 1180 -80 xschem set rectcolor 21 -xschem rect 10 -970 240 -750 +xschem rect 10 -970 240 -750 xschem wire 150 -580 150 -560 {lab=vss} xschem wire 150 -420 150 -400 {lab=vss} xschem wire 10 -270 10 -250 {lab=vss} @@ -53,7 +53,7 @@ vvss vss 0 0 *.dc vvcc 0 2 0.1 .tran 0.2n 480n uic -** download models from here: +** download models from here: ** http://www.amarketplaceofideas.com/wp-content/uploads/2014/11/180nm-V1.7z ** and save to 'models_rom8k.txt' in simulation directory .include models_rom8k.txt @@ -215,4 +215,4 @@ xschem instance ../xschem_library/devices/spice_probe.sym 1670 -740 0 0 {name=p4 xschem instance ../xschem_library/devices/lab_pin.sym 1670 -790 0 0 {name=l4 lab=LDBL[0,16,32,1,17,33,2,18,34]} xschem instance ../xschem_library/devices/spice_probe.sym 1670 -790 0 0 {name=p91 analysis=tran} xschem save -xschem exit closewindow \ No newline at end of file +xschem exit closewindow diff --git a/tests/create_save/tests/simple_inv.tcl b/tests/create_save/tests/simple_inv.tcl index 395b8e56..aaf6d741 100644 --- a/tests/create_save/tests/simple_inv.tcl +++ b/tests/create_save/tests/simple_inv.tcl @@ -1,17 +1,17 @@ -xschem instance ../xschem_library/devices/nmos.sym 30 20 0 0 {name=MN1} -xschem instance ../xschem_library/devices/pmos.sym 30 -70 0 0 {name=MP1} -xschem instance ../xschem_library/devices/vdd.sym 50 -130 0 0 {name=VDD} -xschem instance ../xschem_library/devices/gnd.sym 50 80 0 0 {name=GND} -xschem instance ../xschem_library/devices/ipin.sym -40 -70 0 0 {lab=in} -xschem instance ../xschem_library/devices/opin.sym 110 -20 0 0 {lab=out} -xschem wire 50 -40 50 -10 -xschem wire 50 -20 110 -20 -xschem wire 50 -130 50 -100 -xschem wire 50 50 50 80 -xschem wire -50 -70 10 -70 -xschem wire -10 20 10 20 -xschem wire -10 -70 -10 20 -xschem select_all -xschem hilight -xschem save -xschem exit closewindow \ No newline at end of file +xschem instance ../xschem_library/devices/nmos.sym 30 20 0 0 {name=MN1} +xschem instance ../xschem_library/devices/pmos.sym 30 -70 0 0 {name=MP1} +xschem instance ../xschem_library/devices/vdd.sym 50 -130 0 0 {name=VDD} +xschem instance ../xschem_library/devices/gnd.sym 50 80 0 0 {name=GND} +xschem instance ../xschem_library/devices/ipin.sym -40 -70 0 0 {lab=in} +xschem instance ../xschem_library/devices/opin.sym 110 -20 0 0 {lab=out} +xschem wire 50 -40 50 -10 +xschem wire 50 -20 110 -20 +xschem wire 50 -130 50 -100 +xschem wire 50 50 50 80 +xschem wire -50 -70 10 -70 +xschem wire -10 20 10 20 +xschem wire -10 -70 -10 20 +xschem select_all +xschem hilight +xschem save +xschem exit closewindow diff --git a/tests/netlisting.tcl b/tests/netlisting.tcl index b06d5150..a3d15660 100644 --- a/tests/netlisting.tcl +++ b/tests/netlisting.tcl @@ -1,21 +1,21 @@ # # File: netlisting.tcl -# +# # This file is part of XSCHEM, -# a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit +# a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit # simulation. # Copyright (C) 1998-2022 Stefan Frederik Schippers -# +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA @@ -26,7 +26,7 @@ set pathlist {} set num_fatals 0 if {![file exists $testname]} { - file mkdir $testname + file mkdir $testname } file delete -force $testname/results @@ -35,83 +35,83 @@ file mkdir $testname/results set xschem_library_path "../xschem_library" proc netlisting {dir fn} { - global xschem_library_path testname pathlist xschem_cmd - if { [regexp {\.sch$} $fn ] } { - puts "Testing ($testname) $dir/$fn" - set output_dir $dir - regsub -all $xschem_library_path $output_dir {} output_dir - regsub {^/} $output_dir {} output_dir - # Spice Netlist - run_xschem_netlist vhdl $output_dir $dir $fn - run_xschem_netlist v $output_dir $dir $fn - run_xschem_netlist tdx $output_dir $dir $fn - run_xschem_netlist spice $output_dir $dir $fn - } + global xschem_library_path testname pathlist xschem_cmd + if {[regexp {\.sch$} $fn]} { + puts "Testing ($testname) $dir/$fn" + set output_dir $dir + regsub -all $xschem_library_path $output_dir {} output_dir + regsub {^/} $output_dir {} output_dir + # Spice Netlist + run_xschem_netlist vhdl $output_dir $dir $fn + run_xschem_netlist v $output_dir $dir $fn + run_xschem_netlist tdx $output_dir $dir $fn + run_xschem_netlist spice $output_dir $dir $fn + } } proc netlisting_dir {dir} { - set ff [lsort [glob -directory $dir -tails \{.*,*\}]] - foreach f $ff { - if {$f eq {..} || $f eq {.}} { - continue + set ff [lsort [glob -directory $dir -tails \{.*,*\}]] + foreach f $ff { + if {$f eq {..} || $f eq {.}} { + continue + } + set fpath "$dir/$f" + if {[file isdirectory $fpath]} { + netlisting_dir $fpath + } else { + netlisting $dir $f + } } - set fpath "$dir/$f" - if {[file isdirectory $fpath]} { - netlisting_dir $fpath - } else { - netlisting $dir $f - } - } } proc run_xschem_netlist {type output_dir dir fn} { - global testname pathlist xschem_cmd num_fatals - set cwd [pwd] - set fn_debug [join [list $output_dir , [regsub {\.} $fn {_}] "_${type}_debug.txt"] ""] - regsub {./} $fn_debug {_} fn_debug - set sch_name [regsub {\.sch} $fn {}] - set fn_netlist [join [list $sch_name "." $type] ""] - set output [join [list $cwd / $testname / results / $fn_debug] ""] - set netlist_output_dir [join [list $cwd / $testname / results ] ""] - puts "Output: $fn_debug" - set opt s - if {$type eq "vhdl"} {set opt V} - if {$type eq "v"} {set opt w} - if {$type eq "tdx"} {set opt t} - set netlist_failed 0 ;# not used here but might be used in the future. - set general_failure 0 - - cd $dir - set catch_status [catch {eval exec {$xschem_cmd $fn -q -x -r -$opt -o $netlist_output_dir -n 2> $output}} msg opt] - cd $cwd - if {$catch_status} { - set error_code [dict get $opt -errorcode] - # in case of child process error $error_code will be {CHILDSTATUS 11731 10}, second item is processID, - # 3rd item is child process exit code. In case of netlisting error xschem exit code is 10 - if {[regexp {^CHILDSTATUS.* 10$} $error_code]} { - set netlist_failed 1 - } elseif {$error_code ne {NONE}} { - set general_failure 1 + global testname pathlist xschem_cmd num_fatals + set cwd [pwd] + set fn_debug [join [list $output_dir , [regsub {\.} $fn {_}] "_${type}_debug.txt"] ""] + regsub {./} $fn_debug {_} fn_debug + set sch_name [regsub {\.sch} $fn {}] + set fn_netlist [join [list $sch_name "." $type] ""] + set output [join [list $cwd / $testname / results / $fn_debug] ""] + set netlist_output_dir [join [list $cwd / $testname / results] ""] + puts "Output: $fn_debug" + set opt s + if {$type eq "vhdl"} {set opt V} + if {$type eq "v"} {set opt w} + if {$type eq "tdx"} {set opt t} + set netlist_failed 0 ;# not used here but might be used in the future. + set general_failure 0 + + cd $dir + set catch_status [catch {eval exec {$xschem_cmd $fn -q -x -r -$opt -o $netlist_output_dir -n 2> $output}} msg opt] + cd $cwd + if {$catch_status} { + set error_code [dict get $opt -errorcode] + # in case of child process error $error_code will be {CHILDSTATUS 11731 10}, second item is processID, + # 3rd item is child process exit code. In case of netlisting error xschem exit code is 10 + if {[regexp {^CHILDSTATUS.* 10$} $error_code]} { + set netlist_failed 1 + } elseif {$error_code ne {NONE}} { + set general_failure 1 + } + } + if {$general_failure} { + puts "FATAL: $xschem_cmd $fn -q -x -r -$opt -o $netlist_output_dir -n 2> $output : $msg" + incr num_fatals + } else { + lappend pathlist $fn_debug + lappend pathlist $fn_netlist + cleanup_debug_file $output } - } - if {$general_failure} { - puts "FATAL: $xschem_cmd $fn -q -x -r -$opt -o $netlist_output_dir -n 2> $output : $msg" - incr num_fatals - } else { - lappend pathlist $fn_debug - lappend pathlist $fn_netlist - cleanup_debug_file $output - } } netlisting_dir $xschem_library_path # Intermediate netlisting name (.*) will keep changing, so delete them for easier diff set ff [glob -directory "$testname/results" \{.*\}] foreach f $ff { - if {$f eq "$testname/results/.." || $f eq "$testname/results/."} { - continue - } - file delete $f + if {$f eq "$testname/results/.." || $f eq "$testname/results/."} { + continue + } + file delete $f } print_results $testname $pathlist $num_fatals diff --git a/tests/open_close.tcl b/tests/open_close.tcl index 860177e0..cbc5c5eb 100644 --- a/tests/open_close.tcl +++ b/tests/open_close.tcl @@ -1,21 +1,21 @@ # # File: open_close.tcl -# +# # This file is part of XSCHEM, -# a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit +# a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit # simulation. # Copyright (C) 1998-2022 Stefan Frederik Schippers -# +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA @@ -26,7 +26,7 @@ set pathlist {} set num_fatals 0 if {![file exists $testname]} { - file mkdir $testname + file mkdir $testname } file delete -force $testname/results @@ -35,45 +35,45 @@ file mkdir $testname/results set xschem_library_path "../xschem_library" proc open_close {dir fn} { - global xschem_library_path testname pathlist xschem_cmd - set fpath "$dir/$fn" - if { [regexp {\.(sym|sch)$} $fn ] } { - puts "Testing (open_close) $fpath" - set output_dir $dir - regsub -all $xschem_library_path $output_dir {} output_dir - regsub {^/} $output_dir {} output_dir - regsub {/} $output_dir {,} output_dir - set fn_debug [join [list $output_dir , [regsub {\.} $fn {_}] "_debug.txt"] ""] - set output [join [list $testname / results / $fn_debug] ""] - puts "Output: $fn_debug" - set cwd [pwd] - cd $dir - set catch_status [catch {eval exec {$xschem_cmd $fn -q -x -r -d 1 2> $cwd/$output}} msg] - cd $cwd - if {$catch_status} { - puts "FATAL: $xschem_cmd $fn -q -x -r -d 1 2> $cwd/$output : $msg" - incr num_fatals - } else { - lappend pathlist $fn_debug - cleanup_debug_file $output + global xschem_library_path testname pathlist xschem_cmd + set fpath "$dir/$fn" + if {[regexp {\.(sym|sch)$} $fn]} { + puts "Testing (open_close) $fpath" + set output_dir $dir + regsub -all $xschem_library_path $output_dir {} output_dir + regsub {^/} $output_dir {} output_dir + regsub {/} $output_dir {,} output_dir + set fn_debug [join [list $output_dir , [regsub {\.} $fn {_}] "_debug.txt"] ""] + set output [join [list $testname / results / $fn_debug] ""] + puts "Output: $fn_debug" + set cwd [pwd] + cd $dir + set catch_status [catch {eval exec {$xschem_cmd $fn -q -x -r -d 1 2> $cwd/$output}} msg] + cd $cwd + if {$catch_status} { + puts "FATAL: $xschem_cmd $fn -q -x -r -d 1 2> $cwd/$output : $msg" + incr num_fatals + } else { + lappend pathlist $fn_debug + cleanup_debug_file $output + } } - } } proc open_close_dir {dir} { - set ff [lsort [glob -directory $dir -tails \{.*,*\}]] - foreach f $ff { - if {$f eq {..} || $f eq {.}} { - continue + set ff [lsort [glob -directory $dir -tails \{.*,*\}]] + foreach f $ff { + if {$f eq {..} || $f eq {.}} { + continue + } + set fpath "$dir/$f" + if {[file isdirectory $fpath]} { + open_close_dir $fpath + } else { + open_close $dir $f + } } - set fpath "$dir/$f" - if {[file isdirectory $fpath]} { - open_close_dir $fpath - } else { - open_close $dir $f - } - } } open_close_dir $xschem_library_path -print_results $testname $pathlist $num_fatals \ No newline at end of file +print_results $testname $pathlist $num_fatals diff --git a/tests/run_regression.tcl b/tests/run_regression.tcl index c5f46127..7532d724 100644 --- a/tests/run_regression.tcl +++ b/tests/run_regression.tcl @@ -1,21 +1,21 @@ # # File: run_regression.tcl -# +# # This file is part of XSCHEM, -# a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit +# a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit # simulation. # Copyright (C) 1998-2023 Stefan Frederik Schippers -# +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA @@ -24,16 +24,16 @@ set tcases [list "create_save" "open_close" "netlisting"] set log_fn "results.log" proc summarize_all {fn fd} { - puts $fd "$fn" - set b [catch "open \"$fn\" r" fdread] - set num_fail 0 - if (!$b) { + puts $fd "$fn" + set b [catch "open \"$fn\" r" fdread] + set num_fail 0 + if (!$b) { while {[gets $fdread line] >=0} { - if { [regexp {[FAIL]$} $line] || [regexp {[GOLD\?]$} $line] || [regexp {^[FATAL]} $line]} { - puts $fd $line + if { [regexp {[FAIL]$} $line] || [regexp {[GOLD\?]$} $line] || [regexp {^[FATAL]} $line]} { + puts $fd $line incr num_fail - } - } + } + } puts $fd "Total num fail: $num_fail" close $fdread } else { @@ -43,17 +43,17 @@ proc summarize_all {fn fd} { set a [catch "open \"$log_fn\" w" fd] if {!$a} { -foreach tc $tcases { - puts "Start source ${tc}.tcl" - if {[catch {eval exec {tclsh ${tc}.tcl} > ${tc}_output.txt} msg]} { - puts "Something seems to have gone wrong with $tc, but we will ignore it: $msg" + foreach tc $tcases { + puts "Start source ${tc}.tcl" + if {[catch {eval exec {tclsh ${tc}.tcl} > ${tc}_output.txt} msg]} { + puts "Something seems to have gone wrong with $tc, but we will ignore it: $msg" + } + summarize_all ${tc}.log $fd + puts "Finish source ${tc}.tcl" } - summarize_all ${tc}.log $fd - puts "Finish source ${tc}.tcl" - } - close $fd + close $fd } else { - puts "Couldn't open $log_fn to write. Investigate please." + puts "Couldn't open $log_fn to write. Investigate please." } source test_utility.tcl diff --git a/tests/test_utility.tcl b/tests/test_utility.tcl index c22f4bbb..8632f9b4 100644 --- a/tests/test_utility.tcl +++ b/tests/test_utility.tcl @@ -1,21 +1,21 @@ # # File: xschem_test_utility.tcl -# +# # This file is part of XSCHEM, -# a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit +# a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit # simulation. # Copyright (C) 1998-2022 Stefan Frederik Schippers -# +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA @@ -25,59 +25,58 @@ set xschem_cmd "xschem" # From Glenn Jackman (Stack Overflow answer) proc comp_file {file1 file2} { - # optimization: check file size first - set equal 0 - if {[file size $file1] == [file size $file2]} { - set fh1 [open $file1 r] - set fh2 [open $file2 r] - set equal [string equal [read $fh1] [read $fh2]] - close $fh1 - close $fh2 - } - return $equal + # optimization: check file size first + set equal 0 + if {[file size $file1] == [file size $file2]} { + set fh1 [open $file1 r] + set fh2 [open $file2 r] + set equal [string equal [read $fh1] [read $fh2]] + close $fh1 + close $fh2 + } + return $equal } proc print_results {testname pathlist num_fatals} { - - if {[file exists ${testname}/gold]} { - set a [catch "open \"$testname.log\" w" fd] - if {$a} { - puts "Couldn't open $f" - } else { - set i 0 - set num_fail 0 - set num_gold 0 - foreach f $pathlist { - incr i - if {![file exists $testname/gold/$f]} { - puts $fd "$i. $f: GOLD?" - incr num_gold - continue - } - if {![file exists $testname/results/$f]} { - puts $fd "$i. $f: RESULT?" - continue - } - if ([comp_file $testname/gold/$f $testname/results/$f]) { + if {[file exists ${testname}/gold]} { + set a [catch "open \"$testname.log\" w" fd] + if {$a} { + puts "Couldn't open $f" + } else { + set i 0 + set num_fail 0 + set num_gold 0 + foreach f $pathlist { + incr i + if {![file exists $testname/gold/$f]} { + puts $fd "$i. $f: GOLD?" + incr num_gold + continue + } + if {![file exists $testname/results/$f]} { + puts $fd "$i. $f: RESULT?" + continue + } + if ([comp_file $testname/gold/$f $testname/results/$f]) { puts $fd "$i. $f: PASS" } else { - puts $fd "$i. $f: FAIL" + puts $fd "$i. $f: FAIL" incr num_fail } - } - puts $fd "Summary:" - puts $fd "Num failed: $num_fail Num missing gold: $num_gold Num passed: [expr $i-$num_fail-$num_gold]" - if {$num_fatals} { - puts $fd "FATAL: $num_fatals. Please search for FATAL in its output file for more detail" - } - close $fd + } + puts $fd "Summary:" + puts $fd "Num failed: $num_fail Num missing gold: $num_gold Num passed: [expr $i-$num_fail-$num_gold]" + if {$num_fatals} { + puts $fd "FATAL: $num_fatals. Please search for FATAL in its output file for more detail" + } + close $fd + } + } else { + puts "No gold folder. Set results as gold please." } - } else { - puts "No gold folder. Set results as gold please." - } } # Edit lines that change each time regression is ran proc cleanup_debug_file {output} { - eval exec {awk -f cleanup_debug_file.awk $output} + eval exec {awk -f cleanup_debug_file.awk $output} } diff --git a/tests/xschemtest.tcl b/tests/xschemtest.tcl index 049b6efc..78cb86e1 100644 --- a/tests/xschemtest.tcl +++ b/tests/xschemtest.tcl @@ -13,128 +13,128 @@ ## optionally with logging to catch memory leaks: # xschem -d 3 -l log --script /path/to/xschemtest.tcl ## and then running: xschemtest -## running this test with different xschem versions with profiling enabled (-pg) +## running this test with different xschem versions with profiling enabled (-pg) ## allows to see differences in number of function calls / time spent. ## move schematic and redraw in a loop. proc draw_test {{filelist {-}} {hide_graphs 0}} { - global show_pin_net_names hide_empty_graphs - set hide_empty_graphs $hide_graphs - set show_pin_net_names 1 - foreach f $filelist { - if { $f ne {-}} { - xschem load [abs_sym_path $f] + global show_pin_net_names hide_empty_graphs + set hide_empty_graphs $hide_graphs + set show_pin_net_names 1 + foreach f $filelist { + if {$f ne {-}} { + xschem load [abs_sym_path $f] + } + xschem search regex 1 lab . ;# select all nets + xschem hilight ;# hilight all selected nets and labels + xschem unselect_all + set increment 5.0 + set n 30.0 + set a [time { + for {set i 0} {$i < $n} {incr i} { + set x [xschem get xorigin] + set y [xschem get yorigin] + set x [expr {$x + $increment}] + set y [expr {$y + $increment}] + xschem origin $x $y + xschem redraw + } + }] + set a [lindex $a 0] + set fps [expr {$n / $a * 1e6}] ;# calculate drawing frames per second + puts "$f: draw speed: $fps fps" } - xschem search regex 1 lab . ;# select all nets - xschem hilight ;# hilight all selected nets and labels - xschem unselect_all - set increment 5.0 - set n 30.0 - set a [time { - for { set i 0 } { $i < $n } { incr i} { - set x [xschem get xorigin] - set y [xschem get yorigin] - set x [expr {$x +$increment}] - set y [expr {$y +$increment}] - xschem origin $x $y - xschem redraw - } - }] - set a [lindex $a 0] - set fps [expr {$n / $a * 1e6} ] ;# calculate drawing frames per second - puts "$f: draw speed: $fps fps" - } - set show_pin_net_names 0 + set show_pin_net_names 0 } -proc test_windows { {tabs 0} {destroy 1} } { - global tabbed_interface +proc test_windows {{tabs 0} {destroy 1}} { + global tabbed_interface - xschem clear force - set tabbed_interface $tabs - setup_tabbed_interface - xschem load [abs_sym_path testbench.sch] - xschem load_new_window [abs_sym_path poweramp.sch] - xschem load_new_window [abs_sym_path mos_power_ampli.sch] - xschem load_new_window [abs_sym_path rom8k.sch] - xschem load_new_window [abs_sym_path autozero_comp.sch] - xschem load_new_window [abs_sym_path LCC_instances.sch] - xschem load_new_window [abs_sym_path simulate_ff.sch] - xschem load_new_window [abs_sym_path led_driver.sch] - xschem load_new_window [abs_sym_path solar_panel.sch] - update - if {[xschem new_schematic ntabs] == 8} {set res OK} else {set res FAIL} - if {$tabs} { - puts "test tabbed windows: $res" - } else { - puts "test multiple windows: $res" - } - if {$destroy} { - after 2000 - xschem new_schematic destroy_all xschem clear force - } + set tabbed_interface $tabs + setup_tabbed_interface + xschem load [abs_sym_path testbench.sch] + xschem load_new_window [abs_sym_path poweramp.sch] + xschem load_new_window [abs_sym_path mos_power_ampli.sch] + xschem load_new_window [abs_sym_path rom8k.sch] + xschem load_new_window [abs_sym_path autozero_comp.sch] + xschem load_new_window [abs_sym_path LCC_instances.sch] + xschem load_new_window [abs_sym_path simulate_ff.sch] + xschem load_new_window [abs_sym_path led_driver.sch] + xschem load_new_window [abs_sym_path solar_panel.sch] + update + if {[xschem new_schematic ntabs] == 8} {set res OK} else {set res FAIL} + if {$tabs} { + puts "test tabbed windows: $res" + } else { + puts "test multiple windows: $res" + } + if {$destroy} { + after 2000 + xschem new_schematic destroy_all + xschem clear force + } } ## select all loaded schematic and paste 32 times in different places, ## check if number of elements after paste matches. proc copy_paste_test {{f mos_power_ampli.sch}} { - xschem load [abs_sym_path $f] - xschem zoom_box -18000 -18000 18000 18000 - xschem select_all - set n [xschem get lastsel] - xschem copy - for { set i 3000 } {$i < 12001} { set i [expr {$i + 3000}]} { - xschem paste 0 $i - xschem paste 0 -$i - xschem paste $i 0 - xschem paste -$i 0 - xschem paste $i $i - xschem paste $i -$i - xschem paste -$i $i - xschem paste -$i -$i - } - update - xschem select_all - set m [xschem get lastsel] - if { $m == $n * 33 } { - puts "Copy / paste 32 additional circuits: $m elements == $n * 33. OK" - } else { - puts "Copy / paste 32 additional circuits: $m elements != $n * 33. FAIL" - } - xschem unselect_all - xschem clear force + xschem load [abs_sym_path $f] + xschem zoom_box -18000 -18000 18000 18000 + xschem select_all + set n [xschem get lastsel] + xschem copy + for {set i 3000} {$i < 12001} {set i [expr {$i + 3000}]} { + xschem paste 0 $i + xschem paste 0 -$i + xschem paste $i 0 + xschem paste -$i 0 + xschem paste $i $i + xschem paste $i -$i + xschem paste -$i $i + xschem paste -$i -$i + } + update + xschem select_all + set m [xschem get lastsel] + if {$m == $n * 33} { + puts "Copy / paste 32 additional circuits: $m elements == $n * 33. OK" + } else { + puts "Copy / paste 32 additional circuits: $m elements != $n * 33. FAIL" + } + xschem unselect_all + xschem clear force } ## draw a grid of long vertical wires and small horizontal wire segments ## after a trim wire operation vertical wires are cut at intersection points. proc draw_trim_wiregrid {} { - xschem unhilight_all - xschem clear force - xschem set no_undo 1 - for {set i 0} {$i < 129} {incr i} { - set x [expr {$i * 40.0}] - set y [expr {128.0*40}] - xschem wire $x 0 $x $y - } - for {set i 0} {$i < 129} {incr i} { - for {set j 0} {$j < 128} {incr j} { - set x1 [expr {$j * 40}] - set x2 [expr {$j * 40 + 40}] - set y [expr {$i * 40}] - xschem wire $x1 $y $x2 $y + xschem unhilight_all + xschem clear force + xschem set no_undo 1 + for {set i 0} {$i < 129} {incr i} { + set x [expr {$i * 40.0}] + set y [expr {128.0 * 40}] + xschem wire $x 0 $x $y } - } - xschem set no_undo 0 - xschem zoom_full - update ;# so updated window will be visible. - xschem trim_wires ;# will also draw result - update - xschem select_all - set n [xschem get lastsel] - xschem unselect_all - ## if all wires trimmed correctly we should have 129*128*2 = 33024 segments. - if {$n == 33024} { puts "Trim wire test: $n segments, OK"} else { puts "Trim wire test FAIL"} - xschem clear force + for {set i 0} {$i < 129} {incr i} { + for {set j 0} {$j < 128} {incr j} { + set x1 [expr {$j * 40}] + set x2 [expr {$j * 40 + 40}] + set y [expr {$i * 40}] + xschem wire $x1 $y $x2 $y + } + } + xschem set no_undo 0 + xschem zoom_full + update ;# so updated window will be visible. + xschem trim_wires ;# will also draw result + update + xschem select_all + set n [xschem get lastsel] + xschem unselect_all + ## if all wires trimmed correctly we should have 129*128*2 = 33024 segments. + if {$n == 33024} {puts "Trim wire test: $n segments, OK"} else {puts "Trim wire test FAIL"} + xschem clear force } @@ -142,54 +142,54 @@ proc draw_trim_wiregrid {} { ## so we simply check if existing and size > 0. ## view parameter allows to view print file (works on linux) proc print_test {{view 0}} { - global OS - foreach {f t} { + global OS + foreach {f t} { autozero_comp.sch png mos_power_ampli.sch svg simulate_ff.sch pdf } { - set filepath [abs_sym_path $f] - set printfile [file rootname $f].$t - xschem load $filepath - puts "Printing: $printfile in $t format" - xschem print $t $printfile - if {$view && $OS ne {Windows}} { - execute 0 xdg-open $printfile - alert_ "Opening print file. Check if $printfile print file looks fine" + set filepath [abs_sym_path $f] + set printfile [file rootname $f].$t + xschem load $filepath + puts "Printing: $printfile in $t format" + xschem print $t $printfile + if {$view && $OS ne {Windows}} { + execute 0 xdg-open $printfile + alert_ "Opening print file. Check if $printfile print file looks fine" + } + if {[file exists $printfile] && [file size $printfile] > 0} { + puts "Print file $printfile exists. [file size $printfile] bytes. OK" + } else { + puts "Print file $printfile not existing or empty. FAIL" + } + file delete $printfile } - if {[file exists $printfile] && [file size $printfile] > 0} { - puts "Print file $printfile exists. [file size $printfile] bytes. OK" - } else { - puts "Print file $printfile not existing or empty. FAIL" - } - file delete $printfile - } - xschem clear force + xschem clear force } ## test xschem's own simulation engine ## there is no built in testing, just see if it works. proc test_xschem_simulation {{f simulate_ff.sch}} { - global tclstop OS - xschem load [abs_sym_path $f] - ## search element with tclcommand attribute - if {$OS ne {Windows}} { - xschem search regex 1 tclcommand {} - } else { - xschem search exact 1 name h3 - } - ## join transform a list element {foo} into a plain string foo - set instname [join [xschem selected_set]] - ## run tcl testbench - eval [xschem getprop instance $instname tclcommand] - puts "Xschem simulation test done. OK" + global tclstop OS + xschem load [abs_sym_path $f] + ## search element with tclcommand attribute + if {$OS ne {Windows}} { + xschem search regex 1 tclcommand {} + } else { + xschem search exact 1 name h3 + } + ## join transform a list element {foo} into a plain string foo + set instname [join [xschem selected_set]] + ## run tcl testbench + eval [xschem getprop instance $instname tclcommand] + puts "Xschem simulation test done. OK" } ## netlist some files in various formats and check netlist with known gold hashes ## hashes should be calculated in same way on windows and linux. proc netlist_test {} { - global netlist_dir - foreach {f t h} { + global netlist_dir + foreach {f t h} { rom8k.sch spice 1420163769 greycnt.sch verilog 1945914565 autozero_comp.sch spice 1472671699 @@ -206,41 +206,41 @@ proc netlist_test {} { test_symbolgen.sch spice 4216484684 test_mosgen.sch spice 2380524013 } { - xschem set netlist_type $t - xschem load [abs_sym_path $f] - if {$t eq {verilog}} { set t v} - if {$t eq {tedax}} { set t tdx} - set netlist_file $netlist_dir/[file rootname $f].$t - file delete $netlist_file - xschem netlist - ## check netlist hashes, compare with gold hashes - set netlist_hash [xschem hash_file $netlist_file 1] - if { $netlist_hash == $h } { - puts "$f netlist check OK" - } else { - puts "$f netlist check, expected hash: ${h}, calculated hash: ${netlist_hash}, FAIL" + xschem set netlist_type $t + xschem load [abs_sym_path $f] + if {$t eq {verilog}} {set t v} + if {$t eq {tedax}} {set t tdx} + set netlist_file $netlist_dir/[file rootname $f].$t + file delete $netlist_file + xschem netlist + ## check netlist hashes, compare with gold hashes + set netlist_hash [xschem hash_file $netlist_file 1] + if {$netlist_hash == $h} { + puts "$f netlist check OK" + } else { + puts "$f netlist check, expected hash: ${h}, calculated hash: ${netlist_hash}, FAIL" + } } - } } proc xschemtest {{view 0}} { - set t [time { - ## make sure ERC window will not pop up above schematic while doing tests - wm deiconify .infotext - lower .infotext + set t [time { + ## make sure ERC window will not pop up above schematic while doing tests + wm deiconify .infotext + lower .infotext - netlist_test - print_test $view - draw_test [list 0_examples_top.sch rom8k.sch greycnt.sch autozero_comp.sch \ - loading.sch mos_power_ampli.sch LCC_instances.sch simulate_ff.sch] + netlist_test + print_test $view + draw_test [list 0_examples_top.sch rom8k.sch greycnt.sch autozero_comp.sch \ + loading.sch mos_power_ampli.sch LCC_instances.sch simulate_ff.sch] - copy_paste_test mos_power_ampli.sch - draw_trim_wiregrid - test_xschem_simulation simulate_ff.sch - test_windows 0 ;# windows - test_windows 1 ;# tabs - }] - puts "Test time: [lindex $t 0] microseconds" + copy_paste_test mos_power_ampli.sch + draw_trim_wiregrid + test_xschem_simulation simulate_ff.sch + test_windows 0 ;# windows + test_windows 1 ;# tabs + }] + puts "Test time: [lindex $t 0] microseconds" } ## this is the test to run from xschem console after sourcing this file diff --git a/xschem_library/analyses/lib_init.tcl b/xschem_library/analyses/lib_init.tcl index 3d82bc15..a819194f 100644 --- a/xschem_library/analyses/lib_init.tcl +++ b/xschem_library/analyses/lib_init.tcl @@ -1,4 +1,4 @@ -# Analyses library for visual circuit analysis setup. +# Analyses library for visual circuit analysis setup. # Copyright (C) 2025 Arpad Buermen # # This program is free software; you can redistribute it and/or modify @@ -16,612 +16,609 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA namespace eval ::analyses { - -# Parenthesize string if not empty -proc parenthesize {str} { - if {[string length $str] > 0} { - return "( $str )" - } else { - return "$str" + # Parenthesize string if not empty + proc parenthesize {str} { + if {[string length $str] > 0} { + return "( $str )" + } else { + return "$str" + } } -} -# Indent a multiline string -proc indent {str indent} { - set lines [split $str \n] - set indented_lines [lmap line $lines {string cat $indent $line}] - return [join $indented_lines \n] -} + # Indent a multiline string + proc indent {str indent} { + set lines [split $str \n] + set indented_lines [lmap line $lines {string cat $indent $line}] + return [join $indented_lines \n] + } -# Helper function for display -# props: flat list of name-type pairs -# type can be -# N .. normal, print value -# G .. given, print if parameter is given (not empty string) -# SG .. string given, if quoted, print it out, otherwise just print given -# NV .. normal, value only -proc format_props {symname props} { - set args {} - foreach {propname type} $props { - set val [ xschem getprop instance $symname $propname ] - set len [string len $val] - set quoted [expr {[string index $val 0] eq "\""}] - if {$len > 0} { - if { $type eq "N" } { - lappend args "$propname=$val" - } elseif { $type eq "NV" } { - lappend args "$val" - } elseif { $type eq "G" } { - lappend args "$propname given" - } elseif { $type eq "SG" } { - if {$quoted} { + # Helper function for display + # props: flat list of name-type pairs + # type can be + # N .. normal, print value + # G .. given, print if parameter is given (not empty string) + # SG .. string given, if quoted, print it out, otherwise just print given + # NV .. normal, value only + proc format_props {symname props} { + set args {} + foreach {propname type} $props { + set val [xschem getprop instance $symname $propname] + set len [string len $val] + set quoted [expr {[string index $val 0] eq "\""}] + if {$len > 0} { + if {$type eq "N"} { lappend args "$propname=$val" - } else { + } elseif {$type eq "NV"} { + lappend args "$val" + } elseif {$type eq "G"} { lappend args "$propname given" + } elseif {$type eq "SG"} { + if {$quoted} { + lappend args "$propname=$val" + } else { + lappend args "$propname given" + } } } } + return [join $args "\n"] } - return [join $args "\n"] -} -# Helper function for spectre/spice netlisting -# N .. normal -# NV .. normal, value only -# UNV .. unquote, normal, value only -# S .. string (dump quoted) -proc format_args {symname props} { - set str "" - set args {} - foreach {propname type} $props { - set val [ xschem getprop instance $symname $propname ] - set len [string len $val] - # Unquote value if requested - if { $type eq "UNV" } { - if {[string match "\"*\"" $val]} { - set val [string range $val 1 end-1] - } - } - # Add to formatted arguments list - if {$len > 0} { - set first false - if { $type eq "N" } { - lappend args "$propname=$val" - } elseif { $type eq "NV" } { - lappend args "$val" - } elseif { $type eq "UNV" } { - lappend args "$val" - } elseif { $type eq "S" } { - lappend args "$propname=\"$val\"" + # Helper function for spectre/spice netlisting + # N .. normal + # NV .. normal, value only + # UNV .. unquote, normal, value only + # S .. string (dump quoted) + proc format_args {symname props} { + set str "" + set args {} + foreach {propname type} $props { + set val [xschem getprop instance $symname $propname] + set len [string len $val] + # Unquote value if requested + if {$type eq "UNV"} { + if {[string match "\"*\"" $val]} { + set val [string range $val 1 end-1] + } + } + # Add to formatted arguments list + if {$len > 0} { + set first false + if {$type eq "N"} { + lappend args "$propname=$val" + } elseif {$type eq "NV"} { + lappend args "$val" + } elseif {$type eq "UNV"} { + lappend args "$val" + } elseif {$type eq "S"} { + lappend args "$propname=\"$val\"" + } } } + return [join $args " "] } - return [join $args " "] -} -# Display output order -proc display_order {symname} { - set names [list order NV] - set txt [format_props $symname $names] - if {[string length $txt] > 0} { - return "#$txt" - } else { - return "unordered (#0)" - } -} - -# Display simulator name -proc display_simulator {symname} { - set names [list simulator NV] - return [format_props $symname $names] -} - -# Display sweep -proc display_sweep {symname} { - set names [list sweep N instance N model N parameter N "option" N "variable" N from N to N step N mode N points N "values" N continuation N] - return [format_props $symname $names] -} - -# Display verbatim block -proc display_verbatim {symname} { - return [format_props $symname [list verbatim NV]] -} - -# Display OP analysis -proc display_op {symname} { - set names [list sweep N nodeset SG store N write N] - return [format_props $symname $names] -} - -# Display 1D DC sweep analysis -proc display_dc1d {symname} { - set names [list sweep N instance N model N parameter N "option" N "variable" N from N to N step N mode N points N "values" N continuation N nodeset SG store N write N] - return [format_props $symname $names] -} - -# Display DCINC analysis -proc display_dcinc {symname} { - set names [list sweep N nodeset SG store N write N writeop N] - return [format_props $symname $names] -} - -# Display DCXF analysis -proc display_dcxf {symname} { - set names [list sweep N outp N outn N in N nodeset SG store N write N writeop N] - return [format_props $symname $names] -} - -# Display AC analysis -proc display_ac {symname} { - set names [list sweep N from N to N step N mode N points N values N nodeset SG store N write N writeop N] - return [format_props $symname $names] -} - -# Display XF analysis -proc display_acxf {symname} { - set names [list sweep N outp N outn N from N to N step N mode N points N values N nodeset SG store N write N writeop N] - return [format_props $symname $names] -} - -# Display NOISE analysis -proc display_noise {symname} { - set names [list sweep N outp N outn N in N from N to N step N mode N points N values N ptssum N nodeset SG store N write N writeop N] - return [format_props $symname $names] -} - -# Display TRAN analysis -proc display_tran {symname} { - set names [list sweep N step N stop N start N maxstep N icmode N nodeset SG ic SG store N write N] - return [format_props $symname $names] -} - -# Display HB analysis -proc display_hb {symname} { - set names [list sweep N freq N nharm N immax N truncate N samplefac N nper N sample N harmonic N imorder N nodeset N store N write N] - return [format_props $symname $names] -} - -# Display postprocessing -proc display_postprocess {symname} { - set names [list file N] - return [format_props $symname $names] -} - -# -# Netlister -# - -proc netlister {netlist_type} { - set cmds {} - set types [dict create] - set prefix "netlist_command_" - foreach {name symfile type} [xschem instance_list] { - # Do not netlist entry point symbol - if {[string match netlist_command_header $type]} { - continue - } - # Collect only symbols of type netlist_* - if {[string match netlist_* $type]} { - dict set types $name $type - } - if {[string match $prefix* $type]} { - # Get order - set order [xschem getprop instance $name order] - if {[string len $order] == 0} { - set order 0 - } - # Append as sublist - lappend cmds [list $order $name $type] - } - } - # Sort - set cmds [lsort -integer -index 0 $cmds] - # Loop and format - set blocks {} - foreach tuple $cmds { - lassign $tuple order name type - set suffix [string range $type [string length $prefix] end] - # Construct formatter function name - set func [join [list "format_" "$suffix" "_" "$netlist_type"] ""] - try { - # Format analysis and post analysis script - set retval [$func $name] - # retval has 2 members: - # - command and - # - post-command (for writing results in ngpice, empty string for spectre) - lassign $retval cmd postcmd - # Format sweep and add it to analysis - set swcmd [format_sweep_chain_$netlist_type $name $cmd types] - # Wrap (swept) analysis and post analysis script in a block - if {[string length $swcmd] > 0} { - lappend blocks [wrap_analysis_$netlist_type $swcmd $postcmd] - } - } on error msg { - puts "Error formatting $name: $msg" - continue - } - } - return [wrap_control_$netlist_type $blocks] -} - - -# -# Netlister for VACASK -# - -# Wrap analysis -proc wrap_analysis_spectre {cmds postcmd} { - return "$cmds" -} - -# Wrap in control block -proc wrap_control_spectre {cmds} { - set control [indent [join $cmds "\n\n"] " "] - return [join [list "//// begin user architecture code" "control" "$control" "endc" "//// end user architecture code"] "\n"] -} - -# Add sweep chain to analysis -proc format_sweep_chain_spectre {name anstr types} { - upvar 1 $types typesdict - set sweep [ xschem getprop instance $name sweep ] - set sweeplist {} - format_sweep_spectre $name sweeplist typesdict - # Do we have any sweeps - if {[llength $sweeplist] > 0} { - # Yes, reverse sweep chain - set sweeplist [lreverse $sweeplist] - # Join sweeps - set sweeps [join "$sweeplist" "\n"] - return "$sweeps\n $anstr" - } else { - return "$anstr" - } -} - -# Sweep formatter, construct sweep chain, innermost first -proc format_sweep_spectre {parent sweeplist types} { - upvar 1 $sweeplist swl - upvar 1 $types typesdict - set sweep [ xschem getprop instance $parent sweep ] - if {[string length $sweep] > 0} { - # Parent has sweep property - set tag [ xschem getprop instance $sweep tag ] - set type [dict get $typesdict $sweep] - if {[string length $tag] > 0 && ($type eq "netlist_modifier_sweep")} { - # Sweep has tag property - try { - lappend swl [format_single_sweep_spectre $sweep] - } on error msg { - # Stop traversing chain on error - error "$sweep: $msg" - } - # Recursion into parent sweep - format_sweep_spectre $sweep swl typesdict - } - } -} - -# Fomat a single sweep -proc format_single_sweep_spectre {sweep} { - set tag [ xschem getprop instance $sweep tag ] - return "sweep $tag ( [format_sweep_spectre_params $sweep] [format_sweep_spectre_range $sweep] )" -} - -# Sweep formatter, what to sweep -proc format_sweep_spectre_params {name} { - return [format_args $name [list instance N model N parameter N "option" N "variable" N]] -} - -# Sweep formatter, how to sweep -proc format_sweep_spectre_range {name} { - return [format_args $name [list from N to N step N mode N points N "values" N continuation N]] -} - -# Analysis formatters -proc format_verbatim_spectre {name} { - set sim [ xschem getprop instance $name simulator ] - set dump false - if {[string length $sim]==0} { - set dump true - } else { - try { - if {[sim_is_$sim]} { - set dump true - } - } on error msg {} - } - if { !$dump } { - return "" - } - return [list [format_args $name [list verbatim NV]] ""] -} - -proc format_analysis_op_spectre {name} { - set args [format_args $name [list nodeset N store N write N]] - return [list "analysis $name op [parenthesize $args]" ""] -} - -proc format_analysis_dc1d_spectre {name} { - # OP formatting - set args [format_args $name [list nodeset N store N write N]] - set anstr "analysis $name op [parenthesize $args]" - # 1D sweep formatting - set swp [format_single_sweep_spectre $name] - return [list "$swp\n $anstr" ""] -} - -proc format_analysis_dcinc_spectre {name} { - set args [format_args $name [list nodeset N store N write N writeop N]] - return [list "analysis $name dcinc [parenthesize $args]" ""] -} - -proc format_signal_output_spectre {name} { - set outp [ xschem getprop instance $name outp ] - set outn [ xschem getprop instance $name outn ] - set vecstr "\[ $outp" - if {[string length $outn] > 0} { - append vecstr ", $outn" - } - append vecstr " \]" - return $vecstr -} - -proc format_analysis_dcxf_spectre {name} { - set args "out=[format_signal_output_spectre $name] " - append args [format_args $name [list nodeset N store N write N writeop N]] - return [list "analysis $name dcxf [parenthesize $args]" ""] -} - -proc format_analysis_ac_spectre {name} { - set args "[format_sweep_spectre_range $name] " - append args [format_args $name [list nodeset N store N write N writeop N]] - return [list "analysis $name ac [parenthesize $args]" ""] -} - -proc format_analysis_acxf_spectre {name} { - set args "out=[format_signal_output_spectre $name] " - append args "[format_sweep_spectre_range $name] " - append args [format_args $name [list nodeset N store N write N writeop N]] - return [list "analysis $name acxf [parenthesize $args]" ""] -} - -proc format_analysis_noise_spectre {name} { - set args "out=[format_signal_output_spectre $name] " - append args "[format_args $name [list in N]] " - append args "[format_sweep_spectre_range $name] " - append args [format_args $name [list nodeset N store N write N writeop N]] - return [list "analysis $name noise [parenthesize $args]" ""] -} - -proc format_analysis_tran_spectre {name} { - set args [format_args $name [list step N stop N start N maxstep N icmode N nodeset N ic N store N write N]] - return [list "analysis $name tran [parenthesize $args]" ""] -} - -proc format_analysis_hb_spectre {name} { - set args [format_args $name [list freq N nharm N immax N truncate N samplefac N nper N sample N harmonic N imorder N nodeset N store N write N]] - return [list "analysis $name hb [parenthesize $args]" ""] -} - -proc format_postprocess_spectre {name} { - set tool [format_args $name [list tool NV]] - set file [format_args $name [list file NV]] - return [list "postprocess($tool, $file)" ""] -} - - -# -# Netlister for Ngspice -# - -# Wrap analysis -proc wrap_analysis_spice {cmds postcmd} { - set txt "" - if {[string length $postcmd] > 0} { - append txt "destroy all\n" - } - append txt $cmds - if {[string length $postcmd] > 0} { - # Write only if analysis succeeded - # append txt "\nif $#plots gt 1\n$postcmd\nend" - append txt "\n$postcmd" - } - return $txt -} - -# Wrap in control block -proc wrap_control_spice {cmds} { - set control [join $cmds "\n\n"] - return [join [list "**** begin user architecture code" ".control" "set filetype=binary" "" "$control" ".endc" "**** end user architecture code"] "\n"] -} - -# Add sweep chain to analysis -proc format_sweep_chain_spice {name anstr types} { - upvar 1 $types typesdict - # Get analysis type (op/dc1d or ac/noise) - set antype [dict get $typesdict $name] - # Is it a dec/oct/lin sweep - if {$antype eq "netlist_command_analysis_ac"} { - set decoctlin true - } elseif {$antype eq "netlist_command_analysis_noise"} { - set decoctlin true - } elseif {$antype eq "netlist_command_analysis_op"} { - # For swept op rename analysis to dc - set decoctlin false - set anstr "dc" - } else { - set decoctlin false - } - set sweep [ xschem getprop instance $name sweep ] - set sweeplist {} - format_sweep_spice $decoctlin $name sweeplist typesdict - # Limit sweep dimension for analyses - if {[string match "netlist_command_analysis_*" $antype]} { - if {$antype eq "netlist_command_analysis_op"} { - if {[llength $sweeplist] > 2} { - error "sweep dimension can be at most 2" - } - } elseif {$antype eq "netlist_command_analysis_dc1d"} { - if {[llength $sweeplist] > 1} { - error "sweep dimension can be at most 2" - } + # Display output order + proc display_order {symname} { + set names [list order NV] + set txt [format_props $symname $names] + if {[string length $txt] > 0} { + return "#$txt" } else { - if {[llength $sweeplist] > 0} { - error "sweep is not suported" - } + return "unordered (#0)" } } - # Do we have any sweeps - if {[llength $sweeplist] > 0} { - # Yes, join sweeps - set sweeps [join $sweeplist " "] - return "$anstr $sweeps" - } else { - return "$anstr" - } -} -# Sweep formatter, construct sweep chain, innermost first -proc format_sweep_spice {decoctlin parent sweeplist types} { - upvar 1 $sweeplist swl - upvar 1 $types typesdict - set sweep [ xschem getprop instance $parent sweep ] - if {[string length $sweep] > 0} { - # Parent has sweep property - set tag [ xschem getprop instance $sweep tag ] - set type [dict get $typesdict $sweep] - if {[string length $tag] > 0 && ($type eq "netlist_modifier_sweep")} { - # Sweep has tag property + # Display simulator name + proc display_simulator {symname} { + set names [list simulator NV] + return [format_props $symname $names] + } + + # Display sweep + proc display_sweep {symname} { + set names [list sweep N instance N model N parameter N "option" N "variable" N from N to N step N mode N points N "values" N continuation N] + return [format_props $symname $names] + } + + # Display verbatim block + proc display_verbatim {symname} { + return [format_props $symname [list verbatim NV]] + } + + # Display OP analysis + proc display_op {symname} { + set names [list sweep N nodeset SG store N write N] + return [format_props $symname $names] + } + + # Display 1D DC sweep analysis + proc display_dc1d {symname} { + set names [list sweep N instance N model N parameter N "option" N "variable" N from N to N step N mode N points N "values" N continuation N nodeset SG store N write N] + return [format_props $symname $names] + } + + # Display DCINC analysis + proc display_dcinc {symname} { + set names [list sweep N nodeset SG store N write N writeop N] + return [format_props $symname $names] + } + + # Display DCXF analysis + proc display_dcxf {symname} { + set names [list sweep N outp N outn N in N nodeset SG store N write N writeop N] + return [format_props $symname $names] + } + + # Display AC analysis + proc display_ac {symname} { + set names [list sweep N from N to N step N mode N points N values N nodeset SG store N write N writeop N] + return [format_props $symname $names] + } + + # Display XF analysis + proc display_acxf {symname} { + set names [list sweep N outp N outn N from N to N step N mode N points N values N nodeset SG store N write N writeop N] + return [format_props $symname $names] + } + + # Display NOISE analysis + proc display_noise {symname} { + set names [list sweep N outp N outn N in N from N to N step N mode N points N values N ptssum N nodeset SG store N write N writeop N] + return [format_props $symname $names] + } + + # Display TRAN analysis + proc display_tran {symname} { + set names [list sweep N step N stop N start N maxstep N icmode N nodeset SG ic SG store N write N] + return [format_props $symname $names] + } + + # Display HB analysis + proc display_hb {symname} { + set names [list sweep N freq N nharm N immax N truncate N samplefac N nper N sample N harmonic N imorder N nodeset N store N write N] + return [format_props $symname $names] + } + + # Display postprocessing + proc display_postprocess {symname} { + set names [list file N] + return [format_props $symname $names] + } + + # + # Netlister + # + + proc netlister {netlist_type} { + set cmds {} + set types [dict create] + set prefix "netlist_command_" + foreach {name symfile type} [xschem instance_list] { + # Do not netlist entry point symbol + if {[string match netlist_command_header $type]} { + continue + } + # Collect only symbols of type netlist_* + if {[string match netlist_* $type]} { + dict set types $name $type + } + if {[string match $prefix* $type]} { + # Get order + set order [xschem getprop instance $name order] + if {[string len $order] == 0} { + set order 0 + } + # Append as sublist + lappend cmds [list $order $name $type] + } + } + # Sort + set cmds [lsort -integer -index 0 $cmds] + # Loop and format + set blocks {} + foreach tuple $cmds { + lassign $tuple order name type + set suffix [string range $type [string length $prefix] end] + # Construct formatter function name + set func [join [list "format_" "$suffix" "_" "$netlist_type"] ""] try { - lappend swl [format_single_sweep_spice $decoctlin $sweep] + # Format analysis and post analysis script + set retval [$func $name] + # retval has 2 members: + # - command and + # - post-command (for writing results in ngpice, empty string for spectre) + lassign $retval cmd postcmd + # Format sweep and add it to analysis + set swcmd [format_sweep_chain_$netlist_type $name $cmd types] + # Wrap (swept) analysis and post analysis script in a block + if {[string length $swcmd] > 0} { + lappend blocks [wrap_analysis_$netlist_type $swcmd $postcmd] + } } on error msg { - # Stop traversing chain on error - error "$sweep: $msg" + puts "Error formatting $name: $msg" + continue } - # Recursion into parent sweep - format_sweep_spice $decoctlin $sweep swl typesdict + } + return [wrap_control_$netlist_type $blocks] + } + + + # + # Netlister for VACASK + # + + # Wrap analysis + proc wrap_analysis_spectre {cmds postcmd} { + return "$cmds" + } + + # Wrap in control block + proc wrap_control_spectre {cmds} { + set control [indent [join $cmds "\n\n"] " "] + return [join [list "//// begin user architecture code" "control" "$control" "endc" "//// end user architecture code"] "\n"] + } + + # Add sweep chain to analysis + proc format_sweep_chain_spectre {name anstr types} { + upvar 1 $types typesdict + set sweep [xschem getprop instance $name sweep] + set sweeplist {} + format_sweep_spectre $name sweeplist typesdict + # Do we have any sweeps + if {[llength $sweeplist] > 0} { + # Yes, reverse sweep chain + set sweeplist [lreverse $sweeplist] + # Join sweeps + set sweeps [join "$sweeplist" "\n"] + return "$sweeps\n $anstr" + } else { + return "$anstr" } } -} -# Fomat a single sweep -proc format_single_sweep_spice {decoctlin sweep} { - return "[format_sweep_spice_params $sweep] [format_sweep_spice_range $decoctlin $sweep]" -} - -# Sweep formatter, what to sweep -proc format_sweep_spice_params {name} { - return [format_args $name [list instance UNV]] -} - -# Sweep formatter, how to sweep -proc format_sweep_spice_range {decoctlin name} { - if {$decoctlin} { - return [format_args $name [list mode UNV points NV from NV to NV]] - } else { - return [format_args $name [list from NV to NV step NV]] + # Sweep formatter, construct sweep chain, innermost first + proc format_sweep_spectre {parent sweeplist types} { + upvar 1 $sweeplist swl + upvar 1 $types typesdict + set sweep [xschem getprop instance $parent sweep] + if {[string length $sweep] > 0} { + # Parent has sweep property + set tag [xschem getprop instance $sweep tag] + set type [dict get $typesdict $sweep] + if {[string length $tag] > 0 && ($type eq "netlist_modifier_sweep")} { + # Sweep has tag property + try { + lappend swl [format_single_sweep_spectre $sweep] + } on error msg { + # Stop traversing chain on error + error "$sweep: $msg" + } + # Recursion into parent sweep + format_sweep_spectre $sweep swl typesdict + } + } } -} -# Each formatter returns a list with two elements -# - analysis -# - rawfile write script / post-command script - -proc format_verbatim_spice {name} { - return [list [format_verbatim_spectre $name] ""] -} - -proc format_analysis_op_spice {name} { - return [list "op" "write $name.raw"] -} - -proc format_analysis_dc1d_spice {name} { - # 1D sweep formatting - set swp [format_single_sweep_spice false $name] - return [list "dc $swp" "write $name.raw"] -} - -proc format_analysis_dcinc_spice {name} { - error "dcinc is not supported by Ngspice" -} - -proc format_signal_output_spice {name} { - set outp [ xschem getprop instance $name outp ] - set outn [ xschem getprop instance $name outn ] - # If outp starts with v(, use it literally, ignore outn - if {[string match "v(*" $outp]} { - return $outp + # Fomat a single sweep + proc format_single_sweep_spectre {sweep} { + set tag [xschem getprop instance $sweep tag] + return "sweep $tag ( [format_sweep_spectre_params $sweep] [format_sweep_spectre_range $sweep] )" } - # If outp starts with i(, use it literally, ignore outn - if {[string match "i(*" $outp]} { - return $outp + + # Sweep formatter, what to sweep + proc format_sweep_spectre_params {name} { + return [format_args $name [list instance N model N parameter N "option" N "variable" N]] } - # Unquote outp, outn - if {[string match "\"*\"" $outp]} { - set outp [string range $outp 1 end-1] + + # Sweep formatter, how to sweep + proc format_sweep_spectre_range {name} { + return [format_args $name [list from N to N step N mode N points N "values" N continuation N]] } - if {[string match "\"*\"" $outn]} { - set outn [string range $outn 1 end-1] + + # Analysis formatters + proc format_verbatim_spectre {name} { + set sim [xschem getprop instance $name simulator] + set dump false + if {[string length $sim] == 0} { + set dump true + } else { + try { + if {[sim_is_$sim]} { + set dump true + } + } on error msg {} + } + if {!$dump} { + return "" + } + return [list [format_args $name [list verbatim NV]] ""] } - # Is outn empty - if {[string length $outn] == 0} { - return "v($outp)" - } else { - return "v($outp,$outn)" + + proc format_analysis_op_spectre {name} { + set args [format_args $name [list nodeset N store N write N]] + return [list "analysis $name op [parenthesize $args]" ""] } -} -proc format_analysis_dcxf_spice {name} { - set output "[format_signal_output_spice $name]" - return [list "tf $output [format_args $name [list in UNV]]" "write $name.raw"] -} - -proc format_analysis_ac_spice {name} { - set swp "[format_sweep_spice_range true $name] " - return [list "ac $swp" "write $name.raw"] -} - -proc format_analysis_acxf_spice {name} { - error "acxf is not supported by Ngspice" -} - -proc format_analysis_noise_spice {name} { - set output "[format_signal_output_spice $name]" - set swp "[format_sweep_spice_range true $name]" - set writer "write $name-integrated.raw\nsetplot previous\nwrite $name.raw" - return [list "noise $output [format_args $name [list in UNV]] $swp [format_args $name [list ptssum NV]]" "$writer"] -} - -proc format_analysis_tran_spice {name} { - set args [format_args $name [list step NV stop NV start NV maxstep NV]] - set icmode [format_args $name [list icmode UNV]] - if {$icmode eq "uic"} { - append args " uic" + proc format_analysis_dc1d_spectre {name} { + # OP formatting + set args [format_args $name [list nodeset N store N write N]] + set anstr "analysis $name op [parenthesize $args]" + # 1D sweep formatting + set swp [format_single_sweep_spectre $name] + return [list "$swp\n $anstr" ""] } - return [list "tran $args" "write $name.raw"] -} -proc format_analysis_hb_spice {name} { - error "hb is not supported by Ngspice" -} + proc format_analysis_dcinc_spectre {name} { + set args [format_args $name [list nodeset N store N write N writeop N]] + return [list "analysis $name dcinc [parenthesize $args]" ""] + } -proc format_postprocess_spice {name} { - global tcl_platform - set tool [format_args $name [list tool NV]] - if {![string match "\"*\"" $tool]} { - # Not quoted, check if it is PYTHON (VACASK variable for autodetected Python) - if {$tool eq "PYTHON"} { - if {$tcl_platform(platform) eq "windows"} { - set tool "python.exe" + proc format_signal_output_spectre {name} { + set outp [xschem getprop instance $name outp] + set outn [xschem getprop instance $name outn] + set vecstr "\[ $outp" + if {[string length $outn] > 0} { + append vecstr ", $outn" + } + append vecstr " \]" + return $vecstr + } + + proc format_analysis_dcxf_spectre {name} { + set args "out=[format_signal_output_spectre $name] " + append args [format_args $name [list nodeset N store N write N writeop N]] + return [list "analysis $name dcxf [parenthesize $args]" ""] + } + + proc format_analysis_ac_spectre {name} { + set args "[format_sweep_spectre_range $name] " + append args [format_args $name [list nodeset N store N write N writeop N]] + return [list "analysis $name ac [parenthesize $args]" ""] + } + + proc format_analysis_acxf_spectre {name} { + set args "out=[format_signal_output_spectre $name] " + append args "[format_sweep_spectre_range $name] " + append args [format_args $name [list nodeset N store N write N writeop N]] + return [list "analysis $name acxf [parenthesize $args]" ""] + } + + proc format_analysis_noise_spectre {name} { + set args "out=[format_signal_output_spectre $name] " + append args "[format_args $name [list in N]] " + append args "[format_sweep_spectre_range $name] " + append args [format_args $name [list nodeset N store N write N writeop N]] + return [list "analysis $name noise [parenthesize $args]" ""] + } + + proc format_analysis_tran_spectre {name} { + set args [format_args $name [list step N stop N start N maxstep N icmode N nodeset N ic N store N write N]] + return [list "analysis $name tran [parenthesize $args]" ""] + } + + proc format_analysis_hb_spectre {name} { + set args [format_args $name [list freq N nharm N immax N truncate N samplefac N nper N sample N harmonic N imorder N nodeset N store N write N]] + return [list "analysis $name hb [parenthesize $args]" ""] + } + + proc format_postprocess_spectre {name} { + set tool [format_args $name [list tool NV]] + set file [format_args $name [list file NV]] + return [list "postprocess($tool, $file)" ""] + } + + + # + # Netlister for Ngspice + # + + # Wrap analysis + proc wrap_analysis_spice {cmds postcmd} { + set txt "" + if {[string length $postcmd] > 0} { + append txt "destroy all\n" + } + append txt $cmds + if {[string length $postcmd] > 0} { + # Write only if analysis succeeded + # append txt "\nif $#plots gt 1\n$postcmd\nend" + append txt "\n$postcmd" + } + return $txt + } + + # Wrap in control block + proc wrap_control_spice {cmds} { + set control [join $cmds "\n\n"] + return [join [list "**** begin user architecture code" ".control" "set filetype=binary" "" "$control" ".endc" "**** end user architecture code"] "\n"] + } + + # Add sweep chain to analysis + proc format_sweep_chain_spice {name anstr types} { + upvar 1 $types typesdict + # Get analysis type (op/dc1d or ac/noise) + set antype [dict get $typesdict $name] + # Is it a dec/oct/lin sweep + if {$antype eq "netlist_command_analysis_ac"} { + set decoctlin true + } elseif {$antype eq "netlist_command_analysis_noise"} { + set decoctlin true + } elseif {$antype eq "netlist_command_analysis_op"} { + # For swept op rename analysis to dc + set decoctlin false + set anstr "dc" + } else { + set decoctlin false + } + set sweep [xschem getprop instance $name sweep] + set sweeplist {} + format_sweep_spice $decoctlin $name sweeplist typesdict + # Limit sweep dimension for analyses + if {[string match "netlist_command_analysis_*" $antype]} { + if {$antype eq "netlist_command_analysis_op"} { + if {[llength $sweeplist] > 2} { + error "sweep dimension can be at most 2" + } + } elseif {$antype eq "netlist_command_analysis_dc1d"} { + if {[llength $sweeplist] > 1} { + error "sweep dimension can be at most 2" + } } else { - set tool "python3" + if {[llength $sweeplist] > 0} { + error "sweep is not suported" + } + } + } + # Do we have any sweeps + if {[llength $sweeplist] > 0} { + # Yes, join sweeps + set sweeps [join $sweeplist " "] + return "$anstr $sweeps" + } else { + return "$anstr" + } + } + + # Sweep formatter, construct sweep chain, innermost first + proc format_sweep_spice {decoctlin parent sweeplist types} { + upvar 1 $sweeplist swl + upvar 1 $types typesdict + set sweep [xschem getprop instance $parent sweep] + if {[string length $sweep] > 0} { + # Parent has sweep property + set tag [xschem getprop instance $sweep tag] + set type [dict get $typesdict $sweep] + if {[string length $tag] > 0 && ($type eq "netlist_modifier_sweep")} { + # Sweep has tag property + try { + lappend swl [format_single_sweep_spice $decoctlin $sweep] + } on error msg { + # Stop traversing chain on error + error "$sweep: $msg" + } + # Recursion into parent sweep + format_sweep_spice $decoctlin $sweep swl typesdict } } } - # Keep quotes around tool and file - set file [format_args $name [list file NV]] - return [list "shell $tool $file" ""] -} -} + # Fomat a single sweep + proc format_single_sweep_spice {decoctlin sweep} { + return "[format_sweep_spice_params $sweep] [format_sweep_spice_range $decoctlin $sweep]" + } + # Sweep formatter, what to sweep + proc format_sweep_spice_params {name} { + return [format_args $name [list instance UNV]] + } + + # Sweep formatter, how to sweep + proc format_sweep_spice_range {decoctlin name} { + if {$decoctlin} { + return [format_args $name [list mode UNV points NV from NV to NV]] + } else { + return [format_args $name [list from NV to NV step NV]] + } + } + + # Each formatter returns a list with two elements + # - analysis + # - rawfile write script / post-command script + + proc format_verbatim_spice {name} { + return [list [format_verbatim_spectre $name] ""] + } + + proc format_analysis_op_spice {name} { + return [list "op" "write $name.raw"] + } + + proc format_analysis_dc1d_spice {name} { + # 1D sweep formatting + set swp [format_single_sweep_spice false $name] + return [list "dc $swp" "write $name.raw"] + } + + proc format_analysis_dcinc_spice {name} { + error "dcinc is not supported by Ngspice" + } + + proc format_signal_output_spice {name} { + set outp [xschem getprop instance $name outp] + set outn [xschem getprop instance $name outn] + # If outp starts with v(, use it literally, ignore outn + if {[string match "v(*" $outp]} { + return $outp + } + # If outp starts with i(, use it literally, ignore outn + if {[string match "i(*" $outp]} { + return $outp + } + # Unquote outp, outn + if {[string match "\"*\"" $outp]} { + set outp [string range $outp 1 end-1] + } + if {[string match "\"*\"" $outn]} { + set outn [string range $outn 1 end-1] + } + # Is outn empty + if {[string length $outn] == 0} { + return "v($outp)" + } else { + return "v($outp,$outn)" + } + } + + proc format_analysis_dcxf_spice {name} { + set output "[format_signal_output_spice $name]" + return [list "tf $output [format_args $name [list in UNV]]" "write $name.raw"] + } + + proc format_analysis_ac_spice {name} { + set swp "[format_sweep_spice_range true $name] " + return [list "ac $swp" "write $name.raw"] + } + + proc format_analysis_acxf_spice {name} { + error "acxf is not supported by Ngspice" + } + + proc format_analysis_noise_spice {name} { + set output "[format_signal_output_spice $name]" + set swp "[format_sweep_spice_range true $name]" + set writer "write $name-integrated.raw\nsetplot previous\nwrite $name.raw" + return [list "noise $output [format_args $name [list in UNV]] $swp [format_args $name [list ptssum NV]]" "$writer"] + } + + proc format_analysis_tran_spice {name} { + set args [format_args $name [list step NV stop NV start NV maxstep NV]] + set icmode [format_args $name [list icmode UNV]] + if {$icmode eq "uic"} { + append args " uic" + } + return [list "tran $args" "write $name.raw"] + } + + proc format_analysis_hb_spice {name} { + error "hb is not supported by Ngspice" + } + + proc format_postprocess_spice {name} { + global tcl_platform + set tool [format_args $name [list tool NV]] + if {![string match "\"*\"" $tool]} { + # Not quoted, check if it is PYTHON (VACASK variable for autodetected Python) + if {$tool eq "PYTHON"} { + if {$tcl_platform(platform) eq "windows"} { + set tool "python.exe" + } else { + set tool "python3" + } + } + } + # Keep quotes around tool and file + set file [format_args $name [list file NV]] + return [list "shell $tool $file" ""] + } +} diff --git a/xschem_library/generators/mosgen.tcl b/xschem_library/generators/mosgen.tcl index 708dcffb..353b5e61 100755 --- a/xschem_library/generators/mosgen.tcl +++ b/xschem_library/generators/mosgen.tcl @@ -5,7 +5,7 @@ exec tclsh "$0" "$@" set model [lindex $argv 0] if {$model eq {nfet_g5v0d10v5}} { -puts { + puts { v {xschem version=3.1.0 file_version=1.2} G {} @@ -13,16 +13,16 @@ K {type=nmos lvs_format="@spiceprefix@name @pinlist sky130_fd_pr__@model L=@L W=@W nf=@nf m=@mult" format="@spiceprefix@name @pinlist sky130_fd_pr__@model L=@L W=@W + nf=@nf ad=@ad as=@as pd=@pd ps=@ps -+ nrd=@nrd nrs=@nrs sa=@sa sb=@sb sd=@sd ++ nrd=@nrd nrs=@nrs sa=@sa sb=@sb sd=@sd + mult=@mult m=@mult" template="name=M1 L=0.5 W=1 nf=1 mult=1 -ad=\\"'int((nf+1)/2) * W/nf * 0.29'\\" +ad=\\"'int((nf+1)/2) * W/nf * 0.29'\\" pd=\\"'2*int((nf+1)/2) * (W/nf + 0.29)'\\" -as=\\"'int((nf+2)/2) * W/nf * 0.29'\\" +as=\\"'int((nf+2)/2) * W/nf * 0.29'\\" ps=\\"'2*int((nf+2)/2) * (W/nf + 0.29)'\\" nrd=\\"'0.29 / W'\\" nrs=\\"'0.29 / W'\\" sa=0 sb=0 sd=0 @@ -59,22 +59,22 @@ T {tcleval(id=[to_eng [ngspice::get_node [subst -nocommand \{i(\\@m.$\{path\}@sp hide=true} } } elseif {$model eq {pfet_g5v0d10v5}} { -puts {v {xschem version=3.1.0 file_version=1.2} + puts {v {xschem version=3.1.0 file_version=1.2} G {} K {type=pmos lvs_format="@spiceprefix@name @pinlist sky130_fd_pr__@model L=@L W=@W nf=@nf m=@mult" format="@spiceprefix@name @pinlist sky130_fd_pr__@model L=@L W=@W + nf=@nf ad=@ad as=@as pd=@pd ps=@ps -+ nrd=@nrd nrs=@nrs sa=@sa sb=@sb sd=@sd ++ nrd=@nrd nrs=@nrs sa=@sa sb=@sb sd=@sd + mult=@mult m=@mult" template="name=M1 L=0.5 W=1 nf=1 mult=1 -ad=\\"'int((nf+1)/2) * W/nf * 0.29'\\" +ad=\\"'int((nf+1)/2) * W/nf * 0.29'\\" pd=\\"'2*int((nf+1)/2) * (W/nf + 0.29)'\\" -as=\\"'int((nf+2)/2) * W/nf * 0.29'\\" +as=\\"'int((nf+2)/2) * W/nf * 0.29'\\" ps=\\"'2*int((nf+2)/2) * (W/nf + 0.29)'\\" nrd=\\"'0.29 / W'\\" nrs=\\"'0.29 / W'\\" sa=0 sb=0 sd=0 @@ -112,22 +112,22 @@ T {tcleval(id=[to_eng [ngspice::get_node [subst -nocommand \{i(\\@m.$\{path\}@sp hide=true} } } elseif {$model eq {pfet_01v8}} { -puts {v {xschem version=3.1.0 file_version=1.2} + puts {v {xschem version=3.1.0 file_version=1.2} G {} K {type=pmos lvs_format="@spiceprefix@name @pinlist sky130_fd_pr__@model L=@L W=@W nf=@nf m=@mult" format="@spiceprefix@name @pinlist sky130_fd_pr__@model L=@L W=@W + nf=@nf ad=@ad as=@as pd=@pd ps=@ps -+ nrd=@nrd nrs=@nrs sa=@sa sb=@sb sd=@sd ++ nrd=@nrd nrs=@nrs sa=@sa sb=@sb sd=@sd + mult=@mult m=@mult" template="name=M1 L=0.15 W=1 nf=1 mult=1 -ad=\\"'int((nf+1)/2) * W/nf * 0.29'\\" +ad=\\"'int((nf+1)/2) * W/nf * 0.29'\\" pd=\\"'2*int((nf+1)/2) * (W/nf + 0.29)'\\" -as=\\"'int((nf+2)/2) * W/nf * 0.29'\\" +as=\\"'int((nf+2)/2) * W/nf * 0.29'\\" ps=\\"'2*int((nf+2)/2) * (W/nf + 0.29)'\\" nrd=\\"'0.29 / W'\\" nrs=\\"'0.29 / W'\\" sa=0 sb=0 sd=0 @@ -164,25 +164,23 @@ hide=true} T {tcleval(id=[to_eng [ngspice::get_node [subst -nocommand \{i(\\@m.$\{path\}@spiceprefix@name\\.msky130_fd_pr__@model\\[id])\}]]] )} 32.5 -30 0 0 0.15 0.15 {layer=15 hide=true} } - - -} else { ;# default: nfet_01v8 -puts {v {xschem version=3.1.0 file_version=1.2 } +} else { # default: nfet_01v8 + puts {v {xschem version=3.1.0 file_version=1.2 } G {} K {type=nmos lvs_format="@spiceprefix@name @pinlist sky130_fd_pr__@model L=@L W=@W nf=@nf m=@mult" format="@spiceprefix@name @pinlist sky130_fd_pr__@model L=@L W=@W + nf=@nf ad=@ad as=@as pd=@pd ps=@ps -+ nrd=@nrd nrs=@nrs sa=@sa sb=@sb sd=@sd ++ nrd=@nrd nrs=@nrs sa=@sa sb=@sb sd=@sd + mult=@mult m=@mult" template="name=M1 L=0.15 W=1 -nf=1 +nf=1 mult=1 -ad=\\"'int((nf+1)/2) * W/nf * 0.29'\\" +ad=\\"'int((nf+1)/2) * W/nf * 0.29'\\" pd=\\"'2*int((nf+1)/2) * (W/nf + 0.29)'\\" -as=\\"'int((nf+2)/2) * W/nf * 0.29'\\" +as=\\"'int((nf+2)/2) * W/nf * 0.29'\\" ps=\\"'2*int((nf+2)/2) * (W/nf + 0.29)'\\" nrd=\\"'0.29 / W'\\" nrs=\\"'0.29 / W'\\" sa=0 sb=0 sd=0 diff --git a/xschem_library/generators/res.tcl b/xschem_library/generators/res.tcl index 02c47fe7..7d9f1520 100755 --- a/xschem_library/generators/res.tcl +++ b/xschem_library/generators/res.tcl @@ -2,34 +2,34 @@ # the next line restarts using wish \ exec tclsh "$0" "$@" proc from_eng {i} { - set n 1 - set str {k } - if {[scan $i "%g%s" n str] < 2} { set str {}} - set str [string tolower $str] - if { [regexp {^meg} $str] } { set str {meg} } else { - set suffix [string index $str 0] - } - set mult [switch $suffix { - a { expr {1e-18}} - f { expr {1e-15}} - p { expr {1e-12}} - n { expr { 1e-9}} - u { expr {1e-6}} - m { expr {1e-3}} - k { expr {1e3}} - meg { expr {1e6}} - g { expr {1e9}} - t { expr {1e12}} - default { expr {1.0}} - }] - return [expr {$n * $mult}] -} + set n 1 + set str {k } + if {[scan $i "%g%s" n str] < 2} {set str {}} + set str [string tolower $str] + if {[regexp {^meg} $str]} {set str {meg}} else { + set suffix [string index $str 0] + } + set mult [switch $suffix { + a {expr {1e-18}} + f {expr {1e-15}} + p {expr {1e-12}} + n {expr {1e-9}} + u {expr {1e-6}} + m {expr {1e-3}} + k {expr {1e3}} + meg {expr {1e6}} + g {expr {1e9}} + t {expr {1e12}} + default {expr {1.0}} + }] + return [expr {$n * $mult}] +} set arg1 [lindex $argv 0] -if {$arg1 eq {}} { puts stderr "empty arg"; set arg1 1K} +if {$arg1 eq {}} {puts stderr "empty arg"; set arg1 1K} if {[from_eng $arg1] > 0.1} { -puts stderr "res value=|$arg1|" -puts "v {xschem version=3.4.0 file_version=1.2 + puts stderr "res value=|$arg1|" + puts "v {xschem version=3.4.0 file_version=1.2 } G {} K {type=resistor @@ -61,8 +61,7 @@ T {@#1:net_name} 10 20 0 0 0.15 0.15 {layer=15} T {m=@m} -15 1.25 0 1 0.2 0.2 {} T {@spice_get_current} 12.5 -16.25 0 0 0.2 0.2 {layer=15}" } else { - -puts "v {xschem version=3.4.0 file_version=1.2 + puts "v {xschem version=3.4.0 file_version=1.2 } G {} K {type=show_label diff --git a/xschem_library/generators/schematicgen.tcl b/xschem_library/generators/schematicgen.tcl index bcfa36f9..8d04e273 100755 --- a/xschem_library/generators/schematicgen.tcl +++ b/xschem_library/generators/schematicgen.tcl @@ -3,8 +3,8 @@ exec tclsh "$0" "$@" set arg1 [lindex $argv 0] -if { $arg1 eq {inv}} { -puts {v {xschem version=3.1.0 file_version=1.2} +if {$arg1 eq {inv}} { + puts {v {xschem version=3.1.0 file_version=1.2} G { y <= not a after 0.1 ns ;} K {} @@ -31,7 +31,7 @@ C {lab_pin.sym} 190 -130 0 0 {name=p3 lab=0} C {n.sym} 170 -180 0 0 {name=m1 model=cmosn w=wn l=lln m=1} } } else { -puts {v {xschem version=3.1.0 file_version=1.2} + puts {v {xschem version=3.1.0 file_version=1.2} G { y <= not a after 0.1 ns ;} K {} diff --git a/xschem_library/generators/symbolgen.tcl b/xschem_library/generators/symbolgen.tcl index afd78e60..599601a1 100755 --- a/xschem_library/generators/symbolgen.tcl +++ b/xschem_library/generators/symbolgen.tcl @@ -5,8 +5,8 @@ exec tclsh "$0" "$@" set arg1 [lindex $argv 0] set rout [lindex $argv 1] # puts stderr "arg1=|$arg1| $rout=|$rout|" -if { $arg1 eq {inv}} { -puts "v {xschem version=3.1.0 file_version=1.2} +if {$arg1 eq {inv}} { + puts "v {xschem version=3.1.0 file_version=1.2} K {type=subcircuit xvhdl_primitive=true xverilog_primitive=true @@ -29,7 +29,7 @@ T {y} 7.5 -6.5 0 1 0.2 0.2 {} T {a} -17.5 -6.5 0 0 0.2 0.2 {} " } else { -puts "v {xschem version=3.1.0 file_version=1.2} + puts "v {xschem version=3.1.0 file_version=1.2} K {type=subcircuit xvhdl_primitive=true xverilog_primitive=true diff --git a/xschem_library/generators/tier.tcl b/xschem_library/generators/tier.tcl index eed2d70f..f2a723b1 100755 --- a/xschem_library/generators/tier.tcl +++ b/xschem_library/generators/tier.tcl @@ -19,13 +19,12 @@ E {} B 5 -2.5 -2.5 2.5 2.5 {name=P dir=inout }" if {[regexp -nocase {^(VCC|VDD|VPP)$} $arg1]} { -puts "L 4 -20 -40 20 -40 {} + puts "L 4 -20 -40 20 -40 {} L 4 0 -40 0 0 {} T {@#0:net_name} 5 -13.75 0 0 0.15 0.15 {layer=15} T {@lab} -15 -53.75 0 0 0.2 0.2 {}" } else { -puts "P 4 7 0 0 0 20 -10 20 0 40 10 20 0 20 0 0 {fill=true} + puts "P 4 7 0 0 0 20 -10 20 0 40 10 20 0 20 0 0 {fill=true} T {@#0:net_name} 5 10 0 0 0.15 0.15 {layer=15} T {@lab} -15 45 0 0 0.2 0.2 {}" } -