2025-09-25 09:05:13 +02:00
# Analyses library for visual circuit analysis setup.
# Copyright (C) 2025 Arpad Buermen
#
# 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
2025-09-23 10:19:06 +02:00
namespace eval : : analyses {
# Parenthesize string if not empty
proc parenthesize { str } {
if { [ string length $str ] > 0 } {
return " ( $ s t r ) "
} else {
return " $ s t r "
}
}
# 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 " $ p r o p n a m e = $ v a l "
} elseif { $type eq " N V " } {
lappend args " $ v a l "
} elseif { $type eq " G " } {
lappend args " $ p r o p n a m e g i v e n "
} elseif { $type eq " S G " } {
if { $quoted } {
lappend args " $ p r o p n a m e = $ v a l "
} else {
lappend args " $ p r o p n a m e g i v e n "
}
}
}
}
return [ join $args " \n " ]
}
2025-09-23 14:12:07 +02:00
# Helper function for spectre/spice netlisting
2025-09-23 10:19:06 +02:00
# N .. normal
# NV .. normal, value only
2025-09-23 14:12:07 +02:00
# UNV .. unquote, normal, value only
2025-09-23 10:19:06 +02:00
# S .. string (dump quoted)
2025-09-23 14:12:07 +02:00
proc format_args { symname props} {
2025-09-23 10:19:06 +02:00
set str " "
set args { }
foreach { propname type} $props {
set val [ xschem getprop instance $symname $propname ]
set len [ string len $val ]
2025-09-23 14:12:07 +02:00
# Unquote value if requested
if { $type eq " U N V " } {
if { [ string match " \" * \" " $val ] } {
set val [ string range $val 1 end-1]
}
}
# Add to formatted arguments list
2025-09-23 10:19:06 +02:00
if { $len > 0 } {
set first false
if { $type eq " N " } {
lappend args " $ p r o p n a m e = $ v a l "
} elseif { $type eq " N V " } {
lappend args " $ v a l "
2025-09-23 14:12:07 +02:00
} elseif { $type eq " U N V " } {
lappend args " $ v a l "
2025-09-23 10:19:06 +02:00
} elseif { $type eq " S " } {
lappend args " $ p r o p n a m e = \" $ v a l \" "
}
}
}
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 " # $ t x t "
} else {
return " u n o r d e r e d ( # 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 " o p t i o n " N " v a r i a b l e " N from N to N step N mode N points N " v a l u e s " 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 " o p t i o n " N " v a r i a b l e " N from N to N step N mode N points N " v a l u e s " 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 } {
2025-09-23 14:12:07 +02:00
set names [ list sweep N outp N outn N in N nodeset SG store N write N writeop N]
2025-09-23 10:19:06 +02:00
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 ]
}
2025-09-23 14:12:07 +02:00
#
# Netlister
#
2025-09-23 10:19:06 +02:00
proc netlister { netlist_type } {
set cmds { }
set types [ dict create]
set prefix " n e t l i s t _ c o m m a n d _ "
foreach { name symfile type} [ xschem instance_list] {
2025-09-23 14:12:07 +02:00
# Do not netlist entry point symbol
if { [ string match netlist_command_header $type ] } {
continue
}
# Collect only symbols of type netlist_*
2025-09-23 10:19:06 +02:00
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 " f o r m a t _ " " $ s u f f i x " " _ " " $ n e t l i s t _ t y p e " ] " " ]
2025-09-24 13:16:44 +02:00
try {
# Format analysis and post analysis script
set retval [ $func $name ]
2025-11-19 14:00:59 +01:00
# retval has 2 members:
# - command and
# - post-command (for writing results in ngpice, empty string for spectre)
lassign $retval cmd postcmd
2025-09-24 13:16:44 +02:00
# 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 ]
2025-09-23 10:19:06 +02:00
}
2025-09-24 13:16:44 +02:00
} on error msg {
puts " E r r o r f o r m a t t i n g $ n a m e : $ m s g "
continue
}
2025-09-23 10:19:06 +02:00
}
2025-09-23 14:12:07 +02:00
return [ wrap_control_ $netlist_type $blocks ]
}
#
# Netlister for VACASK
#
2025-09-24 13:16:44 +02:00
# Wrap analysis
proc wrap_analysis_spectre { cmds postcmd} {
return " $ c m d s "
}
2025-09-23 14:12:07 +02:00
# Wrap in control block
proc wrap_control_spectre { cmds } {
2025-09-24 13:16:44 +02:00
set control [ indent [ join $cmds " \n \n " ] " " ]
2025-09-23 10:19:06 +02:00
return [ join [ list " / / / / b e g i n u s e r a r c h i t e c t u r e c o d e " " c o n t r o l " " $ c o n t r o l " " e n d c " " / / / / e n d u s e r a r c h i t e c t u r e c o d e " ] " \n " ]
}
2025-09-23 14:12:07 +02:00
# Add sweep chain to analysis
2025-09-23 10:19:06 +02:00
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
2025-09-24 13:16:44 +02:00
set sweeps [ join " $ s w e e p l i s t " " \n " ]
2025-09-23 10:19:06 +02:00
return " $ s w e e p s \n $ a n s t r "
} else {
return " $ a n s t r "
}
}
2025-09-23 14:12:07 +02:00
# Sweep formatter, construct sweep chain, innermost first
2025-09-23 10:19:06 +02:00
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 " n e t l i s t _ m o d i f i e r _ s w e e p " ) } {
# Sweep has tag property
try {
lappend swl [ format_single_sweep_spectre $sweep ]
2025-09-24 13:16:44 +02:00
} on error msg {
2025-09-23 10:19:06 +02:00
# Stop traversing chain on error
2025-09-24 13:16:44 +02:00
error " $ s w e e p : $ m s g "
2025-09-23 10:19:06 +02:00
}
# 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 " s w e e p $ t a g ( [ f o r m a t _ s w e e p _ s p e c t r e _ p a r a m s $ s w e e p ] [ f o r m a t _ s w e e p _ s p e c t r e _ r a n g e $ s w e e p ] ) "
}
2025-09-23 14:12:07 +02:00
# Sweep formatter, what to sweep
2025-09-23 10:19:06 +02:00
proc format_sweep_spectre_params { name } {
2025-09-23 14:12:07 +02:00
return [ format_args $name [ list instance N model N parameter N " o p t i o n " N " v a r i a b l e " N] ]
2025-09-23 10:19:06 +02:00
}
2025-09-23 14:12:07 +02:00
# Sweep formatter, how to sweep
2025-09-23 10:19:06 +02:00
proc format_sweep_spectre_range { name } {
2025-09-23 14:12:07 +02:00
return [ format_args $name [ list from N to N step N mode N points N " v a l u e s " N continuation N] ]
2025-09-23 10:19:06 +02:00
}
2025-09-23 14:12:07 +02:00
# Analysis formatters
2025-09-23 10:19:06 +02:00
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
}
2025-09-24 13:16:44 +02:00
} on error msg { }
2025-09-23 10:19:06 +02:00
}
if { ! $dump } {
return " "
}
2025-11-19 14:00:59 +01:00
return [ list [ format_args $name [ list verbatim NV] ] " " ]
2025-09-23 10:19:06 +02:00
}
proc format_analysis_op_spectre { name } {
2025-09-23 14:12:07 +02:00
set args [ format_args $name [ list nodeset N store N write N] ]
2025-11-19 14:00:59 +01:00
return [ list " a n a l y s i s $ n a m e o p [ p a r e n t h e s i z e $ a r g s ] " " " ]
2025-09-23 10:19:06 +02:00
}
proc format_analysis_dc1d_spectre { name } {
# OP formatting
2025-09-23 14:12:07 +02:00
set args [ format_args $name [ list nodeset N store N write N] ]
2025-09-23 10:19:06 +02:00
set anstr " a n a l y s i s $ n a m e o p [ p a r e n t h e s i z e $ a r g s ] "
# 1D sweep formatting
set swp [ format_single_sweep_spectre $name ]
2025-11-19 14:00:59 +01:00
return [ list " $ s w p \n $ a n s t r " " " ]
2025-09-23 10:19:06 +02:00
}
proc format_analysis_dcinc_spectre { name } {
2025-09-23 14:12:07 +02:00
set args [ format_args $name [ list nodeset N store N write N writeop N] ]
2025-11-19 14:00:59 +01:00
return [ list " a n a l y s i s $ n a m e d c i n c [ p a r e n t h e s i z e $ a r g s ] " " " ]
2025-09-23 10:19:06 +02:00
}
proc format_signal_output_spectre { name } {
set outp [ xschem getprop instance $name outp ]
set outn [ xschem getprop instance $name outn ]
set vecstr " \[ $ o u t p "
if { [ string length $outn ] > 0 } {
append vecstr " , $ o u t n "
}
append vecstr " \] "
return $vecstr
}
proc format_analysis_dcxf_spectre { name } {
set args " o u t = [ f o r m a t _ s i g n a l _ o u t p u t _ s p e c t r e $ n a m e ] "
2025-09-23 14:12:07 +02:00
append args [ format_args $name [ list nodeset N store N write N writeop N] ]
2025-11-19 14:00:59 +01:00
return [ list " a n a l y s i s $ n a m e d c x f [ p a r e n t h e s i z e $ a r g s ] " " " ]
2025-09-23 10:19:06 +02:00
}
proc format_analysis_ac_spectre { name } {
set args " [ f o r m a t _ s w e e p _ s p e c t r e _ r a n g e $ n a m e ] "
2025-09-23 14:12:07 +02:00
append args [ format_args $name [ list nodeset N store N write N writeop N] ]
2025-11-19 14:00:59 +01:00
return [ list " a n a l y s i s $ n a m e a c [ p a r e n t h e s i z e $ a r g s ] " " " ]
2025-09-23 10:19:06 +02:00
}
proc format_analysis_acxf_spectre { name } {
set args " o u t = [ f o r m a t _ s i g n a l _ o u t p u t _ s p e c t r e $ n a m e ] "
append args " [ f o r m a t _ s w e e p _ s p e c t r e _ r a n g e $ n a m e ] "
2025-09-23 14:12:07 +02:00
append args [ format_args $name [ list nodeset N store N write N writeop N] ]
2025-11-19 14:00:59 +01:00
return [ list " a n a l y s i s $ n a m e a c x f [ p a r e n t h e s i z e $ a r g s ] " " " ]
2025-09-23 10:19:06 +02:00
}
proc format_analysis_noise_spectre { name } {
set args " o u t = [ f o r m a t _ s i g n a l _ o u t p u t _ s p e c t r e $ n a m e ] "
2025-09-23 14:12:07 +02:00
append args " [ f o r m a t _ a r g s $ n a m e [ l i s t i n N ] ] "
2025-09-23 10:19:06 +02:00
append args " [ f o r m a t _ s w e e p _ s p e c t r e _ r a n g e $ n a m e ] "
2025-09-23 14:12:07 +02:00
append args [ format_args $name [ list nodeset N store N write N writeop N] ]
2025-11-19 14:00:59 +01:00
return [ list " a n a l y s i s $ n a m e n o i s e [ p a r e n t h e s i z e $ a r g s ] " " " ]
2025-09-23 10:19:06 +02:00
}
proc format_analysis_tran_spectre { name } {
2025-09-23 14:12:07 +02:00
set args [ format_args $name [ list step N stop N start N maxstep N icmode N nodeset N ic N store N write N] ]
2025-11-19 14:00:59 +01:00
return [ list " a n a l y s i s $ n a m e t r a n [ p a r e n t h e s i z e $ a r g s ] " " " ]
2025-09-23 10:19:06 +02:00
}
proc format_analysis_hb_spectre { name } {
2025-09-23 14:12:07 +02:00
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] ]
2025-11-19 14:00:59 +01:00
return [ list " a n a l y s i s $ n a m e h b [ p a r e n t h e s i z e $ a r g s ] " " " ]
2025-09-23 10:19:06 +02:00
}
proc format_postprocess_spectre { name } {
2025-09-23 14:12:07 +02:00
set tool [ format_args $name [ list tool NV] ]
set file [ format_args $name [ list file NV] ]
2025-09-24 13:16:44 +02:00
return [ list " p o s t p r o c e s s ( $ t o o l , $ f i l e ) " " " ]
2025-09-23 10:19:06 +02:00
}
2025-09-23 14:12:07 +02:00
#
# Netlister for Ngspice
#
2025-09-24 13:16:44 +02:00
# Wrap analysis
proc wrap_analysis_spice { cmds postcmd} {
set txt " "
if { [ string length $postcmd ] > 0 } {
append txt " d e s t r o y a l l \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 $ p o s t c m d "
}
return $txt
}
2025-09-23 14:12:07 +02:00
# Wrap in control block
proc wrap_control_spice { cmds } {
2025-09-24 13:16:44 +02:00
set control [ join $cmds " \n \n " ]
return [ join [ list " * * * * b e g i n u s e r a r c h i t e c t u r e c o d e " " . c o n t r o l " " s e t f i l e t y p e = b i n a r y " " " " $ c o n t r o l " " . e n d c " " * * * * e n d u s e r a r c h i t e c t u r e c o d e " ] " \n " ]
2025-09-23 14:12:07 +02:00
}
# 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 " n e t l i s t _ c o m m a n d _ a n a l y s i s _ a c " } {
set decoctlin true
} elseif { $antype eq " n e t l i s t _ c o m m a n d _ a n a l y s i s _ n o i s e " } {
set decoctlin true
} elseif { $antype eq " n e t l i s t _ c o m m a n d _ a n a l y s i s _ o p " } {
# For swept op rename analysis to dc
set decoctlin false
set anstr " d c "
} else {
set decoctlin false
}
set sweep [ xschem getprop instance $name sweep ]
set sweeplist { }
format_sweep_spice $decoctlin $name sweeplist typesdict
2025-09-24 13:16:44 +02:00
# Limit sweep dimension for analyses
if { [ string match " n e t l i s t _ c o m m a n d _ a n a l y s i s _ * " $antype ] } {
if { $antype eq " n e t l i s t _ c o m m a n d _ a n a l y s i s _ o p " } {
if { [ llength $sweeplist ] > 2 } {
error " s w e e p d i m e n s i o n c a n b e a t m o s t 2 "
}
} elseif { $antype eq " n e t l i s t _ c o m m a n d _ a n a l y s i s _ d c 1 d " } {
if { [ llength $sweeplist ] > 1 } {
error " s w e e p d i m e n s i o n c a n b e a t m o s t 2 "
}
} else {
if { [ llength $sweeplist ] > 0 } {
error " s w e e p i s n o t s u p o r t e d "
}
}
}
2025-09-23 14:12:07 +02:00
# Do we have any sweeps
if { [ llength $sweeplist ] > 0 } {
# Yes, join sweeps
set sweeps [ join $sweeplist " " ]
return " $ a n s t r $ s w e e p s "
} else {
return " $ a n s t r "
}
}
# 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 " n e t l i s t _ m o d i f i e r _ s w e e p " ) } {
# Sweep has tag property
try {
lappend swl [ format_single_sweep_spice $decoctlin $sweep ]
2025-09-24 13:16:44 +02:00
} on error msg {
2025-09-23 14:12:07 +02:00
# Stop traversing chain on error
2025-09-24 13:16:44 +02:00
error " $ s w e e p : $ m s g "
2025-09-23 14:12:07 +02:00
}
# Recursion into parent sweep
format_sweep_spice $decoctlin $sweep swl typesdict
}
}
}
# Fomat a single sweep
proc format_single_sweep_spice { decoctlin sweep} {
return " [ f o r m a t _ s w e e p _ s p i c e _ p a r a m s $ s w e e p ] [ f o r m a t _ s w e e p _ s p i c e _ r a n g e $ d e c o c t l i n $ s w e e p ] "
}
# 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] ]
}
}
2025-09-24 13:16:44 +02:00
# Each formatter returns a list with two elements
# - analysis
# - rawfile write script / post-command script
2025-09-23 14:12:07 +02:00
proc format_verbatim_spice { name } {
2025-09-24 13:16:44 +02:00
return [ list [ format_verbatim_spectre $name ] " " ]
2025-09-23 14:12:07 +02:00
}
proc format_analysis_op_spice { name } {
2025-09-24 13:16:44 +02:00
return [ list " o p " " w r i t e $ n a m e . r a w " ]
2025-09-23 14:12:07 +02:00
}
proc format_analysis_dc1d_spice { name } {
# 1D sweep formatting
set swp [ format_single_sweep_spice false $name ]
2025-09-24 13:16:44 +02:00
return [ list " d c $ s w p " " w r i t e $ n a m e . r a w " ]
2025-09-23 14:12:07 +02:00
}
proc format_analysis_dcinc_spice { name } {
2025-09-24 13:16:44 +02:00
error " d c i n c i s n o t s u p p o r t e d b y N g s p i c e "
2025-09-23 14:12:07 +02:00
}
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 ( $ o u t p ) "
} else {
return " v ( $ o u t p , $ o u t n ) "
}
}
proc format_analysis_dcxf_spice { name } {
set output " [ f o r m a t _ s i g n a l _ o u t p u t _ s p i c e $ n a m e ] "
2025-09-24 13:16:44 +02:00
return [ list " t f $ o u t p u t [ f o r m a t _ a r g s $ n a m e [ l i s t i n U N V ] ] " " w r i t e $ n a m e . r a w " ]
2025-09-23 14:12:07 +02:00
}
proc format_analysis_ac_spice { name } {
set swp " [ f o r m a t _ s w e e p _ s p i c e _ r a n g e t r u e $ n a m e ] "
2025-09-24 13:16:44 +02:00
return [ list " a c $ s w p " " w r i t e $ n a m e . r a w " ]
2025-09-23 14:12:07 +02:00
}
proc format_analysis_acxf_spice { name } {
2025-09-24 13:16:44 +02:00
error " a c x f i s n o t s u p p o r t e d b y N g s p i c e "
2025-09-23 14:12:07 +02:00
}
proc format_analysis_noise_spice { name } {
set output " [ f o r m a t _ s i g n a l _ o u t p u t _ s p i c e $ n a m e ] "
2025-09-24 13:16:44 +02:00
set swp " [ f o r m a t _ s w e e p _ s p i c e _ r a n g e t r u e $ n a m e ] "
set writer " w r i t e $ n a m e - i n t e g r a t e d . r a w \n s e t p l o t p r e v i o u s \n w r i t e $ n a m e . r a w "
return [ list " n o i s e $ o u t p u t [ f o r m a t _ a r g s $ n a m e [ l i s t i n U N V ] ] $ s w p [ f o r m a t _ a r g s $ n a m e [ l i s t p t s s u m N V ] ] " " $ w r i t e r " ]
2025-09-23 14:12:07 +02:00
}
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 " u i c " } {
append args " u i c "
}
2025-09-24 13:16:44 +02:00
return [ list " t r a n $ a r g s " " w r i t e $ n a m e . r a w " ]
2025-09-23 14:12:07 +02:00
}
proc format_analysis_hb_spice { name } {
2025-09-24 13:16:44 +02:00
error " h b i s n o t s u p p o r t e d b y N g s p i c e "
2025-09-23 14:12:07 +02:00
}
proc format_postprocess_spice { name } {
global tcl_platform
set tool [ format_args $name [ list tool NV] ]
2025-09-24 13:16:44 +02:00
if { ! [ string match " \" * \" " $tool ] } {
2025-09-23 14:12:07 +02:00
# Not quoted, check if it is PYTHON (VACASK variable for autodetected Python)
if { $tool eq " P Y T H O N " } {
if { $tcl_platform ( platform ) eq " w i n d o w s " } {
set tool " p y t h o n . e x e "
} else {
set tool " p y t h o n 3 "
}
}
}
2025-09-24 13:16:44 +02:00
# Keep quotes around tool and file
2025-09-23 14:12:07 +02:00
set file [ format_args $name [ list file NV] ]
2025-09-24 13:16:44 +02:00
return [ list " s h e l l $ t o o l $ f i l e " " " ]
2025-09-23 14:12:07 +02:00
}
2025-09-23 10:19:06 +02:00
}
2025-09-24 13:16:44 +02:00