From ce5adbffdbd93f1ac9370f5d70e1ca1c46e9a8bf Mon Sep 17 00:00:00 2001 From: Stefan Frederik Date: Mon, 14 Dec 2020 16:31:20 +0100 Subject: [PATCH] added flatten_savenodes.awk for flattening in-subcircuit .save instructions --- src/Makefile.in | 6 +- src/break.awk | 2 +- src/flatten_savenodes.awk | 155 ++++++++++++++++++++ src/xschem.tcl | 4 +- xschem_library/examples/mos_power_ampli.sch | 12 ++ xschem_library/examples/poweramp.sch | 11 +- xschem_library/examples/rlc.sch | 1 - xschem_library/ngspice/led_driver.sch | 6 +- xschem_library/ngspice/solar_panel.sch | 6 +- 9 files changed, 192 insertions(+), 11 deletions(-) create mode 100755 src/flatten_savenodes.awk diff --git a/src/Makefile.in b/src/Makefile.in index 1c1f6712..e8567b8a 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -11,9 +11,9 @@ put /local/src { # list all files that need to be installed in "$(XSHAREDIR)" put /local/install_shares { keys.help xschem.help xschem.tcl break.awk convert_to_verilog2001.awk - flatten.awk flatten_tedax.awk make_sym.awk symgen.awk order_labels.awk sort_labels.awk spice.awk - tedax.awk verilog.awk vhdl.awk hspice_backannotate.tcl change_index.tcl resources.tcl - xschemrc ngspice_backannotate.tcl rawtovcd gschemtoxschem.awk + flatten.awk flatten_tedax.awk flatten_savenodes.awk make_sym.awk symgen.awk order_labels.awk + sort_labels.awk spice.awk tedax.awk verilog.awk vhdl.awk hspice_backannotate.tcl + change_index.tcl resources.tcl xschemrc ngspice_backannotate.tcl rawtovcd gschemtoxschem.awk } # generate a list of objects from the list of source files diff --git a/src/break.awk b/src/break.awk index 4d08e9b1..e415f0a4 100755 --- a/src/break.awk +++ b/src/break.awk @@ -31,7 +31,7 @@ BEGIN{ quote=0 } first = substr($0,1,1) # dont break .include lines as ngspice chokes on these. - if(tolower($1) ~ /\.include|\.lib|\.title/) nobreak = 1 + if(tolower($1) ~ /\.include|\.lib|\.title|\.save/) nobreak = 1 else nobreak = 0 # 20151203 faster executionif no {}' present if($0 ~/[{}']/ || quote) { diff --git a/src/flatten_savenodes.awk b/src/flatten_savenodes.awk new file mode 100755 index 00000000..b25679c1 --- /dev/null +++ b/src/flatten_savenodes.awk @@ -0,0 +1,155 @@ +#!/usr/bin/awk -f +# +# File: flatten.awk +# +# This file is part of XSCHEM, +# a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit +# simulation. +# Copyright (C) 1998-2020 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 +# +# flatten .SAVE netlist lines + +BEGIN{ + # topcell=toupper(ARGV[2]) + # ARGC=2 + first_subckt = 1 + pathsep="." +} + +{ + up = toupper($0) + if(up ~/^[ \t]*\.END([ \t]+|$)/ ) do_end = $0 + else if(up ~/^[ \t]*\.SAVE[ \t]+/){ + if(toupper($2) !="ALL") do_save = 1 + gsub(/V\([ \t]*/, "V( ", up) + gsub(/[ \t]*\)/, " )", up) + } else print + $0=up + if($0 ~ /^\**\.SUBCKT/ && first_subckt) { + topcell=$2 + sub(/^\*\*/,"",$0) + } + if($0 ~ /^\**\.ENDS/ && first_subckt) { + first_subckt = 0 + sub(/^\*\*/,"",$0) + } + if($0 ~/^\+/) # join folded lines + { + a[lines-1]=a[lines-1] " " substr($0,2); next + } + a[lines++]=$0 +} + +END{ + for(j=0;j=2;k--) { + if(line[k] !~ /=/) { + if(subname=="") {subname=line[k]; subname_pos=k } + else if( (subname,ports) in subckt && k" subname + if( (subname,"first") in subckt) # 30032003 do not expand subcircuit call if undefined subckt + expand(subname,pathnode line[1],portlist) + # print "*--------END___" pathnode line[1] "->" subname + } + else { + if(line[1] ~ /^\.SAVE$/) { + printf ".SAVE " + for(k = 2; k <= num; k++) { + if(k > 2) printf " " + if(line[k] ~ /^V\($/) { + printf "V(%s)",getnode(name,pathnode,portarray,line[k+1]) + k += 2 + } else { + printf "%s", line[k] + } + } + printf "\n" + } + if(line[1] ~ /^\V/ && do_save == 1) { + if(name !=topcell) + printf ".SAVE I(V.%s)\n", pathnode line[1] + else + printf ".SAVE I(%s)\n", line[1] + } + } + } +} + +function getnode(name, path, portarray, node) +# return the full path-name of in subckt +# in path , called with ports +{ + if(name!=topcell) { # if we are in top cell, nothing to do + if(name SUBSEP "port" SUBSEP node in subckt) + return portarray[subckt[name,"port",node]] # is a port, return port mapping + if(!(node in global)) return path node # local node + } + return node # if is a top level or global (not a port) just return +} + diff --git a/src/xschem.tcl b/src/xschem.tcl index bf7e2f7d..4eaca1eb 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -122,7 +122,9 @@ proc netlist {source_file show netlist_file} { } if {$flat_netlist==0} { eval exec {awk -f ${XSCHEM_SHAREDIR}/spice.awk -- $hspice $source_file | \ - awk -f ${XSCHEM_SHAREDIR}/break.awk > $netlist_dir/$netlist_file} + awk -f ${XSCHEM_SHAREDIR}/break.awk | \ + awk -f ${XSCHEM_SHAREDIR}/flatten_savenodes.awk \ + > $netlist_dir/$netlist_file} } else { eval exec {awk -f ${XSCHEM_SHAREDIR}/spice.awk -- $hspice $source_file | \ awk -f ${XSCHEM_SHAREDIR}/flatten.awk | awk -f ${XSCHEM_SHAREDIR}/break.awk > $netlist_dir/$netlist_file} diff --git a/xschem_library/examples/mos_power_ampli.sch b/xschem_library/examples/mos_power_ampli.sch index 11bac982..6e7d5c79 100644 --- a/xschem_library/examples/mos_power_ampli.sch +++ b/xschem_library/examples/mos_power_ampli.sch @@ -94,6 +94,8 @@ N 340 -1180 560 -1180 {lab=VPP} N 1110 -1180 1110 -790 { lab=VPP} N 560 -1180 1110 -1180 {lab=VPP} N 230 -950 800 -950 { lab=#net2} +N 1360 -920 1570 -920 {lab=TEST[3:0]} +N 1360 -860 1360 -840 { lab=VSS} C {ipin.sym} 530 -160 0 0 {name=p0 lab=PLUS} C {ipin.sym} 530 -120 0 0 {name=p2 lab=VPP} C {ipin.sym} 530 -100 0 0 {name=p3 lab=VNN} @@ -408,3 +410,13 @@ load $netlist_dir/$rawfile table_set $rawfile\\" unset rawfile" } +C {spice_probe.sym} 1010 -760 0 0 {name=p40 analysis=tran} +C {spice_probe.sym} 1000 -440 0 0 {name=p56 analysis=tran} +C {spice_probe.sym} 420 -790 0 0 {name=p57 analysis=tran} +C {spice_probe.sym} 280 -950 0 0 {name=p58 analysis=tran} +C {spice_probe.sym} 180 -720 0 0 {name=p59 analysis=tran} +C {lab_wire.sym} 1420 -920 0 0 {name=l3 lab=TEST[3:0]} +C {spice_probe.sym} 1510 -920 0 0 {name=p60 analysis=tran} +C {res.sym} 1360 -890 0 1 {name=R8[3:0] m=1 value=200 net_name=true} +C {lab_pin.sym} 1360 -840 0 0 {name=p61 lab=VSS} +C {spice_probe.sym} 1020 -1120 0 0 {name=p62 analysis=tran} diff --git a/xschem_library/examples/poweramp.sch b/xschem_library/examples/poweramp.sch index 10f20b7c..1e925a73 100644 --- a/xschem_library/examples/poweramp.sch +++ b/xschem_library/examples/poweramp.sch @@ -116,11 +116,11 @@ vvss vss 0 dc 0 ** SPICE models for active devices and put them into the below ** referenced file in simulation directory. .include \\"models_poweramp.txt\\" -.save all -.option savecurrents +* .save all +* .option savecurrents * .FOUR 20k v(outm,outp) * .probe i(*) -* .probe p(r*) p(v*) +.save p(r*) p(v*) "} C {vsource.sym} 160 -1200 0 0 {name=V1 value="dc 50 pwl 0 0 1m 50"} C {vsource.sym} 160 -1140 0 0 {name=V0 value="dc 50 pwl 0 0 1m 50"} @@ -254,3 +254,8 @@ load $netlist_dir/$rawfile table_set $rawfile\\" unset rawfile" } +C {spice_probe.sym} 730 -700 0 0 {name=p40 analysis=tran} +C {spice_probe.sym} 740 -240 0 0 {name=p41 analysis=tran} +C {spice_probe.sym} 670 -1250 0 0 {name=p42 analysis=tran} +C {spice_probe.sym} 680 -1170 0 0 {name=p43 analysis=tran} +C {spice_probe.sym} 960 -1250 0 0 {name=p44 analysis=tran} diff --git a/xschem_library/examples/rlc.sch b/xschem_library/examples/rlc.sch index eb4c97a0..c4d8b371 100644 --- a/xschem_library/examples/rlc.sch +++ b/xschem_library/examples/rlc.sch @@ -19,7 +19,6 @@ C {code_shown.sym} 640 -210 0 0 {name=STIMULI only_toplevel=true tclcommand="xschem edit_vi_prop" value=" - .tran 10n 800u uic .save all "} diff --git a/xschem_library/ngspice/led_driver.sch b/xschem_library/ngspice/led_driver.sch index e7da1ad5..ee86504a 100644 --- a/xschem_library/ngspice/led_driver.sch +++ b/xschem_library/ngspice/led_driver.sch @@ -61,7 +61,7 @@ C {code_shown.sym} 1050 -240 0 0 {name=s1 value="* .control * write led_driver.raw * tran 5n 1000u uic * .endc -.save all +* .save all .tran 5n 1000u uic "} C {ammeter.sym} 750 -470 3 0 {name=VVled} @@ -107,3 +107,7 @@ C {bsource.sym} 880 -670 0 0 {name=B1 VAR=V FUNC="pwl(V(VLED,VCC), } C {lab_pin.sym} 880 -640 0 0 {name=l9 sig_type=std_logic lab=0} C {lab_pin.sym} 880 -730 0 0 {name=l10 sig_type=std_logic lab=COMP} +C {spice_probe.sym} 780 -470 0 0 {name=p1 analysis=tran} +C {spice_probe.sym} 90 -640 0 0 {name=p2 analysis=tran} +C {spice_probe.sym} 410 -460 0 0 {name=p3 analysis=tran} +C {spice_probe.sym} 290 -400 0 0 {name=p4 analysis=tran} diff --git a/xschem_library/ngspice/solar_panel.sch b/xschem_library/ngspice/solar_panel.sch index dca89bac..616debb7 100644 --- a/xschem_library/ngspice/solar_panel.sch +++ b/xschem_library/ngspice/solar_panel.sch @@ -96,7 +96,7 @@ C {code_shown.sym} 245 -245 0 0 {name=CONTROL value="* .control * write led_driver.raw * .endc .option savecurrents -.save all +*.save all .tran 5n 200u uic * .dc VP 0 21 0.01 " net_name=true} @@ -185,3 +185,7 @@ C {ammeter.sym} 860 -400 2 0 {name=Vdiode net_name=true} C {launcher.sym} 655 -165 0 0 {name=h1 descr="Simulate + gaw reload" tclcommand="set sim(spice,default) 1; set sim(spice,1,fg) 1; set sim(spice,1,st) 0;xschem netlist; xschem simulate; gaw_cmd reload_all" net_name=true} +C {spice_probe.sym} 1160 -480 0 0 {name=p1 analysis=tran} +C {spice_probe.sym} 360 -450 0 0 {name=p2 analysis=tran} +C {spice_probe.sym} 860 -550 0 1 {name=p3 analysis=tran} +C {spice_probe.sym} 100 -450 0 1 {name=p4 analysis=tran}