xschem/src/hspice_backannotate.tcl

141 lines
4.3 KiB
Tcl

#
# File: hspice_backannotate.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
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] {
set vnodes 1
}
if [regexp {\*\*\*\*.*voltage sources} $line] {
set vnodes 0
set vsources 1
}
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] == {+} && $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
}
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_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 instance $i voltage [get_voltage $net] fast} err]} {
puts "1 error : $err net: $net"
}
}
if { $type == "current_probe"} {
if {[catch {xschem setprop instance $i current [get_current $name] fast} 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 instance $i voltage [get_diff_voltage $netp $netm] fast} 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
#
#
}