From 2e181196455f46a218c4c1e689d677562ff8946e Mon Sep 17 00:00:00 2001 From: Stefan Frederik Date: Thu, 17 Dec 2020 18:26:46 +0100 Subject: [PATCH] remove "m=1" in xyce spice netlists as xyce does not handle m param. Translate spice_probe ".save" to xyce ".print tran", handle different hierarchical expansion of voltage/current nodes in xyce for hierarchical ammeter/spice_probe probes --- src/flatten_savenodes.awk | 71 ++++++++++++++------ src/spice.awk | 60 +++++++++-------- src/xschem.tcl | 15 +++-- xschem_library/devices/ammeter.sym | 5 +- xschem_library/devices/spice_probe.sym | 9 +-- xschem_library/devices/spice_probe_vdiff.sym | 9 +-- xschem_library/examples/mos_power_ampli.sch | 22 +++--- xschem_library/examples/poweramp_xyce.sch | 55 +++++++++++++-- xschem_library/examples/rlc.sch | 6 +- xschem_library/ngspice/solar_panel_xyce.sch | 13 +--- xschem_library/rom8k/rom8k.sch | 2 +- 11 files changed, 172 insertions(+), 95 deletions(-) diff --git a/src/flatten_savenodes.awk b/src/flatten_savenodes.awk index b25679c1..c9f42d5b 100755 --- a/src/flatten_savenodes.awk +++ b/src/flatten_savenodes.awk @@ -28,22 +28,43 @@ BEGIN{ # ARGC=2 first_subckt = 1 pathsep="." + + + + while( ARGV[1] ~ /^[-]/) { + if(ARGV[1] == "-hspice") hspice = 1 + if(ARGV[1] == "-xyce") { xyce = 1} + for(i=2; i<= ARGC;i++) { + ARGV[i-1] = ARGV[i] + } + ARGC-- + } + + if(xyce==1) pathsep = ":" + +} + +/^\*\*\*\* begin user architecture code/{ + user_code = 1 +} +/^\*\*\*\* end user architecture code/{ + user_code = 0 } { - up = toupper($0) - if(up ~/^[ \t]*\.END([ \t]+|$)/ ) do_end = $0 - else if(up ~/^[ \t]*\.SAVE[ \t]+/){ + if(toupper($1) ==".END" ) do_end = $0 + else if(toupper($1) ~/^\.(SAVE|PRINT)$/ && user_code == 0) { if(toupper($2) !="ALL") do_save = 1 - gsub(/V\([ \t]*/, "V( ", up) - gsub(/[ \t]*\)/, " )", up) + gsub(/[vV]\([ \t]*/, "V( ", $0) + gsub(/[iI]\([ \t]*/, "I( ", $0) + gsub(/[ \t]*\)/, " )", $0) + gsub(/[ \t]*,[ \t]*/, " , ", $0) } else print - $0=up - if($0 ~ /^\**\.SUBCKT/ && first_subckt) { + if(toupper($0) ~ /^\**\.SUBCKT/ && first_subckt) { topcell=$2 sub(/^\*\*/,"",$0) } - if($0 ~ /^\**\.ENDS/ && first_subckt) { + if(toupper($0) ~ /^\**\.ENDS/ && first_subckt) { first_subckt = 0 sub(/^\*\*/,"",$0) } @@ -58,9 +79,9 @@ END{ for(j=0;j=2;k--) { if(line[k] !~ /=/) { @@ -118,25 +139,31 @@ function expand(name, path,ports, # func. params # print "*--------END___" pathnode line[1] "->" subname } else { - if(line[1] ~ /^\.SAVE$/) { - printf ".SAVE " + if(toupper(line[1]) ~ /^\.(SAVE|PRINT)$/ && toupper(line[2]) !~/^ALL$/) { + printf line[1] " " for(k = 2; k <= num; k++) { if(k > 2) printf " " - if(line[k] ~ /^V\($/) { - printf "V(%s)",getnode(name,pathnode,portarray,line[k+1]) + if(line[k] ~ /^[iI]\($/ && line[k+2]==")" && do_save == 1) { + if(name != topcell) + if(xyce==1) + printf "I(%s)", pathnode line[k+1] + else + printf "I(V.%s)", pathnode line[k+1] + else + printf "I(%s)", line[k+1] + k+=2 + } else if(line[k] ~ /^[vV]\($/ && line[k+2]==")") { + printf "V(%s)", getnode(name,pathnode,portarray,line[k+1]) k += 2 + } else if(line[k] ~ /^[vV]\($/ && line[k+2] == "," && line[k+4] == ")") { + printf "V(%s, %s)", getnode(name,pathnode,portarray,line[k+1]), getnode(name,pathnode,portarray,line[k+3]) + k += 4 } 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] - } } } } diff --git a/src/spice.awk b/src/spice.awk index 5fcc9906..260295f8 100755 --- a/src/spice.awk +++ b/src/spice.awk @@ -26,9 +26,10 @@ BEGIN{ lines = 0; first=1 user_code=0 #20180129 - # 20081209 hspice syntax variants - if( ARGV[1] == "-hspice" ) { - hspice=1 + + while( ARGV[1] ~ /^[-]/) { + if(ARGV[1] == "-hspice") hspice = 1 + if(ARGV[1] == "-xyce") { xyce = 1} for(i=2; i<= ARGC;i++) { ARGV[i-1] = ARGV[i] } @@ -58,16 +59,22 @@ END{ $0=yy line[lines++] = $0 - - ## place to insert processing awk hooks - ## resolve parametric instance name vector multiplicity substitute_instance_param() - - ## /place to insert processing awk hooks for(i=0; i matches ?n and ?-n - if($1 ==".probe" && $4 ~/^\?-?[0-9]+$/ && $7 ~/^\?-?[0-9]+$/ && NF==9) { + if(tolower($1) ==".print" && $4 ~/^\?-?[0-9]+$/ && $7 ~/^\?-?[0-9]+$/ && NF==9) { num1=split($5,name,",") num2=split($8,name2,",") @@ -230,49 +235,50 @@ function process( i, iprefix) print $1 " " $2 " " $3 " " name[(i-1)%num1+1] " , " name2[(i-1)%num2+1] " " $9 } + # Ngspice # .save v( ?1 DL[3],DL[2],DL[1],DL[0] , ?1 WL[3],WL{2],WL[1],WL[0] ) # ............ .......... --> matches ?n and ?-n - } else if($1 ==".save" && $3 ~/^\?-?[0-9]+$/ && $6 ~/^\?-?[0-9]+$/ && NF==8) { + } else if(tolower($1) ==".save" && $3 ~/^\?-?[0-9]+$/ && $6 ~/^\?-?[0-9]+$/ && NF==8) { num1=split($4,name,",") num2=split($7,name2,",") +d num = num1>num2? num1: num2 for(i=1;i<=num;i++) { print $1 " " $2 " " name[(i-1)%num1+1] " , " name2[(i-1)%num2+1] " " $8 } - - # .probe tran v( ?1 LDY1_B[1],LDY1_B[0] ) + # Xyce + # .print tran v( ?1 LDY1_B[1],LDY1_B[0] ) # ............ --> matches ?n and ?-n - } else if($1 ==".probe" && $4 ~/^\?-?[0-9]+$/ && NF==6) { + } else if(tolower($1) ==".print" && $4 ~/^\?-?[0-9]+$/ && NF==6) { num=split($5,name,",") for(i=1;i<=num;i++) { print $1 " " $2 " " $3 " " name[i] " " $6 } - # .save v( ?1 LDY1_B[1],LDY1_B[0] ) + + # Ngspice + # .save v( ?1 LDY1_B[1],LDY1_B[0] ) # ............ --> matches ?n and ?-n - } else if($1 ==".save" && $3 ~/^\?-?[0-9]+$/ && NF==5) { + } else if(tolower($1) ==".save" && $3 ~/^\?-?[0-9]+$/ && NF==5) { num=split($4,name,",") for(i=1;i<=num;i++) { print $1 " " $2 " " name[i] " " $5 } - - # .probe i( v1[15],v1[14],v1[13],v1[12],v1[11],v1[10],v1[9],v1[8],v1[7],v1[6],v1[5],v1[4],v1[3],v1[2],v1[1],v1[0] ) - } else if($0 ~ /^\.(probe|save) +[iIvVxX] *\(.*\)/) { + # .save i( v1[15],v1[14],v1[13],v1[12],v1[11],v1[10],v1[9],v1[8],v1[7],v1[6],v1[5],v1[4],v1[3],v1[2],v1[1],v1[0] ) + } else if(tolower($0) ~ /^[ \t]*\.(print|save) +.* +[ivx] *\(.*\)/) { num=$0 sub(/.*\( */,"",num) sub(/ *\).*/,"",num) + sub(/^\?[0-9]+/,"", num) # .print tran file=test1.raw format=raw v(?1 C2) <-- remove ?1 num=split(num,name,",") num1 = $0 - sub(/^.*probe */,"",num1) sub(/^.*save */,"",num1) + sub(/^.*print */,"",num1) sub(/\(.*/,"(",num1) for(i=1;i<=num;i++) { - if($0 ~ /^\.probe/) - print ".probe " num1 name[i] ")" - else - print ".save " num1 name[i] ")" + print $1 " " num1 name[i] ")" } } else if( $1 ~ /^\*\.(ipin|opin|iopin)/ ) { num=split($2,name,",") diff --git a/src/xschem.tcl b/src/xschem.tcl index 59e7d02c..8cfd2859 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -116,17 +116,22 @@ proc netlist {source_file show netlist_file} { if {$tcl_debug <= -1} { puts "netlist: source_file=$source_file, netlist_type=$netlist_type" } if {$netlist_type eq {spice}} { if { $hspice_netlist == 1 } { - set hspice {-hspice} + set simulator {-hspice} } else { - set hspice {} + set simulator {} + } + if { [sim_is_xyce] } { + set xyce {-xyce} + } else { + set xyce {} } if {$flat_netlist==0} { - eval exec {awk -f ${XSCHEM_SHAREDIR}/spice.awk -- $hspice $source_file | \ + eval exec {awk -f ${XSCHEM_SHAREDIR}/spice.awk -- $simulator $xyce $source_file | \ awk -f ${XSCHEM_SHAREDIR}/break.awk | \ - awk -f ${XSCHEM_SHAREDIR}/flatten_savenodes.awk \ + awk -f ${XSCHEM_SHAREDIR}/flatten_savenodes.awk -- $simulator $xyce \ > $netlist_dir/$netlist_file} } else { - eval exec {awk -f ${XSCHEM_SHAREDIR}/spice.awk -- $hspice $source_file | \ + eval exec {awk -f ${XSCHEM_SHAREDIR}/spice.awk -- $simulator $xyce $source_file | \ awk -f ${XSCHEM_SHAREDIR}/flatten.awk | awk -f ${XSCHEM_SHAREDIR}/break.awk > $netlist_dir/$netlist_file} } if ![string compare $show "show"] { diff --git a/xschem_library/devices/ammeter.sym b/xschem_library/devices/ammeter.sym index 05b061ce..2445fcc3 100644 --- a/xschem_library/devices/ammeter.sym +++ b/xschem_library/devices/ammeter.sym @@ -1,7 +1,8 @@ -v {xschem version=2.9.8 file_version=1.2} +v {xschem version=2.9.9 file_version=1.2 } G {} K {type=current_probe -format="@name @pinlist 0" +format="@name @pinlist 0 +.save I( ?1 @name )" template="name=Vmeas"} V {} S {} diff --git a/xschem_library/devices/spice_probe.sym b/xschem_library/devices/spice_probe.sym index e3f89ef7..bd52712c 100644 --- a/xschem_library/devices/spice_probe.sym +++ b/xschem_library/devices/spice_probe.sym @@ -1,11 +1,12 @@ -v {xschem version=2.9.7 file_version=1.2} -G {type=probe +v {xschem version=2.9.9 file_version=1.2 } +G {} +K {type=probe vhdl_ignore=true spice_ignore=false verilog_ignore=true tedax_ignore=true -format=".save v( @@p )" -template="name=p1 analysis=tran"} +format=".save @attrs v( @@p )" +template="name=p1 attrs=\\"\\""} V {} S {} E {} diff --git a/xschem_library/devices/spice_probe_vdiff.sym b/xschem_library/devices/spice_probe_vdiff.sym index b172ed06..d6faa2ed 100644 --- a/xschem_library/devices/spice_probe_vdiff.sym +++ b/xschem_library/devices/spice_probe_vdiff.sym @@ -1,7 +1,8 @@ -v {xschem version=2.9.5_RC6 file_version=1.1} -G {type=differential_probe -format=".probe @analysis v( @@p , @@m )" -template="name=p1 analysis=tran"} +v {xschem version=2.9.9 file_version=1.2 } +G {} +K {type=differential_probe +format=".save v( @@p , @@m )" +template="name=p1"} V {} S {} E {} diff --git a/xschem_library/examples/mos_power_ampli.sch b/xschem_library/examples/mos_power_ampli.sch index 68c3db58..f349b3a1 100644 --- a/xschem_library/examples/mos_power_ampli.sch +++ b/xschem_library/examples/mos_power_ampli.sch @@ -1,10 +1,8 @@ -v {xschem version=2.9.8 file_version=1.2} +v {xschem version=2.9.9 file_version=1.2 } G {} K {} V {} -S { -* .probe v(ga,sa) v(gb,sb) -* .probe p(q*) p(r*) i(r*) p(xm1) p(xm2) i(d*)} +S {} E {} L 15 270 -460 340 -390 {} L 15 270 -330 340 -390 {} @@ -218,8 +216,8 @@ C {ammeter.sym} 700 -440 3 0 {name=v4 net_name=true current=0.01939} C {ammeter.sym} 690 -680 0 0 {name=v5 net_name=true current=0.006273} C {ammeter.sym} 180 -870 0 1 {name=v6 net_name=true current=0.01952} C {ammeter.sym} 840 -890 0 0 {name=v7 net_name=true current=0.01947} -C {spice_probe_vdiff.sym} 860 -410 0 0 {name=p37 analysis=tran voltage=3.684} -C {spice_probe_vdiff.sym} 860 -730 0 0 {name=p38 analysis=tran voltage=3.685} +C {spice_probe_vdiff.sym} 860 -410 0 0 {name=p37 voltage=3.684} +C {spice_probe_vdiff.sym} 860 -730 0 0 {name=p38 voltage=3.685} C {ammeter.sym} 1300 -590 3 0 {name=v8 net_name=true current=0.02782} C {opin.sym} 600 -130 0 0 {name=p5 lab=OUT} C {ipin.sym} 530 -180 0 0 {name=p1 lab=MINUS} @@ -408,9 +406,9 @@ 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 {spice_probe.sym} 1020 -1120 0 0 {name=p62 analysis=tran} +C {spice_probe.sym} 1010 -760 0 0 {name=p40 } +C {spice_probe.sym} 1000 -440 0 0 {name=p56 } +C {spice_probe.sym} 420 -790 0 0 {name=p57} +C {spice_probe.sym} 280 -950 0 0 {name=p58 } +C {spice_probe.sym} 180 -720 0 0 {name=p59 } +C {spice_probe.sym} 1020 -1120 0 0 {name=p62 } diff --git a/xschem_library/examples/poweramp_xyce.sch b/xschem_library/examples/poweramp_xyce.sch index f06ea59c..c799fff9 100644 --- a/xschem_library/examples/poweramp_xyce.sch +++ b/xschem_library/examples/poweramp_xyce.sch @@ -1,5 +1,6 @@ -v {xschem version=2.9.5_RC8 file_version=1.1} +v {xschem version=2.9.9 file_version=1.2 } G {} +K {} V {} S {} E {} @@ -89,17 +90,14 @@ N 580 -1120 580 -1110 {lab=VSS} C {code.sym} 1050 -580 0 0 {name=STIMULI only_toplevel=true tclcommand="xschem edit_vi_prop" -value=".option PARHIER=LOCAL RUNLVL=6 post MODMONTE=1 warn maxwarns=400 -.option ITL4=20000 ITL5=0 -* .option sampling_method = SRS +value="* .option sampling_method = SRS * .option method=gear vvss vss 0 dc 0 -.temp 30 .param frequ=20e3 .param gain=42 * .tran \{2e-3/frequ\} \{1e-3 + 160/frequ\} uic -.tran 1e-7 0.009 uic +.tran 6e-7 0.06 uic ** models are generally not free: you must download ** SPICE models for active devices and put them into the below @@ -177,3 +175,48 @@ C {lab_pin.sym} 350 -270 0 0 {name=p19 lab=FB} C {lab_pin.sym} 350 -730 0 0 {name=p25 lab=FBN} C {title.sym} 160 -30 0 0 {name=l2 author="Stefan Schippers"} C {lab_pin.sym} 880 -1250 0 0 {name=p27 lab=IN_INT} +C {launcher.sym} 990 -120 0 0 {name=h2 +descr="Ctrl-Click +Clear all probes" +tclcommand=" + xschem push_undo + xschem set no_undo 1 + xschem set no_draw 1 + + set lastinst [xschem get instances] + for \{ set i 0 \} \{ $i < $lastinst \} \{incr i \} \{ + set type [xschem getprop instance $i cell::type] + if \{ [regexp \{(^|/)probe$\} $type ] \} \{ + xschem setprop $i voltage fast + \} + if \{ [regexp \{current_probe$\} $type ] \} \{ + xschem setprop $i current fast + \} + if \{ [regexp \{differential_probe$\} $type ] \} \{ + xschem setprop $i voltage fast + \} + \} + xschem set no_undo 0 + xschem set no_draw 0 + xschem redraw +" +} +C {launcher.sym} 990 -190 0 0 {name=h3 +descr="Load file into gaw" +comment=" + This launcher gets raw filename from current schematic using 'xschem get schname' + and stripping off path and suffix. It then loads raw file into gaw. + This allow to use it in any schematic without changes. +" +tclcommand=" +set rawfile [file tail [file rootname [xschem get schname]]].raw +gaw_cmd \\"tabledel $rawfile +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 c4d8b371..fc54fa63 100644 --- a/xschem_library/examples/rlc.sch +++ b/xschem_library/examples/rlc.sch @@ -1,16 +1,17 @@ -v {xschem version=2.9.8 file_version=1.2} +v {xschem version=2.9.9 file_version=1.2 } G {} K {} V {} S {} E {} N 280 -520 280 -420 {lab=#net1} -N 480 -460 480 -240 {lab=0} N 280 -240 480 -240 {lab=0} N 280 -360 280 -300 {lab=C} N 280 -620 480 -620 {lab=A} N 480 -620 480 -520 {lab=A} N 280 -620 280 -580 {lab=A} +N 480 -320 480 -240 {} +N 480 -460 480 -380 {} C {title.sym} 160 -30 0 0 {name=l1 author="Stefan Schippers"} C {launcher.sym} 320 -100 0 0 {name=h1 descr="NGSPICE Manual" @@ -31,3 +32,4 @@ net_name=true} C {ind.sym} 280 -390 0 0 {name=L1 value=10mH net_name=true} C {vsource.sym} 280 -270 0 0 {name=V1 value="pwl 0 0 100u 0 101u 3" net_name=true} C {lab_show.sym} 280 -450 0 0 {name=l3} +C {ammeter.sym} 480 -350 0 0 {name=Vmeas} diff --git a/xschem_library/ngspice/solar_panel_xyce.sch b/xschem_library/ngspice/solar_panel_xyce.sch index 315b9587..a4ca633a 100644 --- a/xschem_library/ngspice/solar_panel_xyce.sch +++ b/xschem_library/ngspice/solar_panel_xyce.sch @@ -1,5 +1,6 @@ -v {xschem version=2.9.5_RC8 file_version=1.1} +v {xschem version=2.9.9 file_version=1.2 } G {} +K {} V {} S {} E {} @@ -93,15 +94,7 @@ N 820 -530 860 -530 {lab=SW} N 370 -450 385 -450 {lab=PANEL} N 570 -250 860 -250 {lab=0} C {title.sym} 160 -40 0 0 {name=l1 author="Stefan Schippers"} -C {code_shown.sym} 345 -235 0 0 {name=CONTROL value="* .control -* save all -* tran 5n 1000u uic -* write led_driver.raw -* .endc -* .save all -.tran 5n 1000u uic -* .dc VP 0 21 0.01 -"} +C {code_shown.sym} 305 -205 0 0 {name=CONTROL value=".tran 5n 1000u uic"} C {code.sym} 15 -225 0 0 {name=MODELS value=".MODEL DIODE D(IS=1.139e-08 RS=0.99 CJO=9.3e-12 VJ=1.6 M=0.411 BV=30 EG=0.7 ) .MODEL SWMOD1 VSWITCH VON=0.01 VOFF=-0.01 RON=0.01 ROFF=1e7 "} diff --git a/xschem_library/rom8k/rom8k.sch b/xschem_library/rom8k/rom8k.sch index d63bf39d..f7837258 100644 --- a/xschem_library/rom8k/rom8k.sch +++ b/xschem_library/rom8k/rom8k.sch @@ -1,4 +1,4 @@ -v {xschem version=2.9.8 file_version=1.2} +v {xschem version=2.9.9 file_version=1.2 } G {} K {} V {}