This code was contributed by [charleshsiao] on 2014-04-01 ..
formatting is tidied up, now we just need some explanatory context :-).
[HJG] So... executing sed and awk means this needs to be run on a unix-system.
Using sed plus awk separately is... well, strange. (awk could do both steps of the processing)
Doing that inside tcl, which has perfectly good string-operations, is... well, stranger. (tcl could do it alone) <
>
Reading a bunch of files means we need to know the contents of theses files to get this program running.
FS_NVM_V2.lib - no idea...
This code is for semiconductor device model tunning. We can do its tunning if no money to buying modeling tool.
We maybe can get model card from tsmc/UMC... like this form.
===
+ u0 = 0.012
+ ua = ...
+ ub = ...
+ dsub = ...
+ drout = ...
+ pvag = ...
+ cdsc = ...
+ cdscb = ...
+ cdscd = ...
===
When doing curve fitting, we need do sp runset writing in advance. Maybe named vd-id.sp and need hspice tool.
so, judge.tcl would looks like:
===
exec hspice vd-id.sp > OUT
foreach ip {46 47 48 49 50 51 52} {
set line [exec sed -n "${ip}p" OUT]
if [regexp {^\s*[0-9]} $line x] break
}; #dynamic check which lines are our needing data
exec cat OUT | sed -n "${line},[expr $line+55]p" | awk \{print $2} > gc
...
===
======
set run 1
proc base {file array} {
global $array
array set $array {}; set ww 1
set hand [open $file r]
set yy [read $hand]
foreach j $yy {
array set $array "$ww $j"
incr ww
}
incr ww -1
close $hand
set sum 0
for {set w 1} {$w<=$ww} {incr w} {set sum [expr $sum+[set ${array}($w)]*[set ${array}($w)]]}
set ${array}(sum) $sum
}
foreach {rr} {ga gb da db dat dbt dyt dzt} {
base $rr $rr
}
proc comp {a b} {
global $a $b
if {[llength [array get $a]]!=[llength [array get $b]]} return
set num [llength [array names $a]]
incr num -1
set dsum 0
for {set i 1} {$i<=$num} {incr i} {
set dsum [expr $dsum+([set ${a}($i)]-[set ${b}($i)])*([set ${a}($i)]-[set ${b}($i)])]
}
return "[expr sqrt($dsum/$num)/sqrt([set ${a}(sum)]/$num)]"
}
#puts [comp ga gc]
proc rms {} {
foreach rr {gc gd dd de dd2 de2 dw2 dx2} {global $rr; base $rr $rr}
return [expr 1.0*[comp ga gc]]
return [expr ([comp ga gc]+[comp gb gd])*0.5]
#return [expr ([comp ga gc]+[comp gb gd]+[comp da dd]+[comp db de])*0.25]
#return [expr ([comp ga gc]+[comp gb gd]+[comp da dd]+[comp db de]+[comp dat dd2]+[comp dbt de2]+[comp dyt dw2]+[comp dzt dx2])*0.125]
}
proc altr {l c inter} {
global run
set vsat [exec sed -n ${l}p l55sp_v151_FS_NVM_V2.lib | awk "{print \$[set c]}"]
#set vsat [exec sed -n 763p l55sp_v151.lib | awk "{print \$4}"]
set line [exec sed -n ${l}p l55sp_v151_FS_NVM_V2.lib]
#set line [exec sed -n 763p l55sp_v151.lib]
exec tclsh judge.tcl &
exec tclsh judge2.tcl &
after 4000
#puts [rms]
#puts "[comp ga gc]+[comp gb gd]+[comp da dd]+[comp db de]+[comp dat dd2]+[comp dbt de2]+[comp dyt dw2]+[comp dzt dx2]"
set now [rms]
set last 1000
set plus [expr $vsat+$inter]
set minus [expr $vsat-$inter]
set line [lreplace $line [expr $c-1] [expr $c-1] $plus]
exec sed -i "${l}c $line" l55sp_v151_FS_NVM_V2.lib
exec tclsh judge.tcl &
exec tclsh judge2.tcl &
after 4000
set plus [rms]
set line [lreplace $line [expr $c-1] [expr $c-1] $minus]
exec sed -i "${l}c $line" l55sp_v151_FS_NVM_V2.lib
exec tclsh judge.tcl &
exec tclsh judge2.tcl &
after 4000
set minus [rms]
if {$minus<$now} {set dir -1} elseif {$plus<$now} {set dir 1} else {
global var brms; set var "temp best!!"; set brms "$now"
set line [lreplace $line [expr $c-1] [expr $c-1] $vsat]
exec sed -i "${l}c $line" l55sp_v151_FS_NVM_V2.lib
return
}
#puts $dir
while {$last>=$now && $run==1} {
set last $now
set vsat [expr $vsat+$inter*$dir]
set line [lreplace $line [expr $c-1] [expr $c-1] $vsat]
exec sed -i "${l}c $line" l55sp_v151_FS_NVM_V2.lib
exec tclsh judge.tcl &
exec tclsh judge2.tcl &
after 4000
set now [rms]
puts $vsat
puts $now
}
set vsat [expr $vsat-$inter*$dir]
set line [lreplace $line [expr $c-1] [expr $c-1] $vsat]
exec sed -i "${l}c $line" l55sp_v151_FS_NVM_V2.lib
exec tclsh judge.tcl &
exec tclsh judge2.tcl &
after 4000
set now [rms]
global var brms
set var $vsat
set brms $now
}
bind . {set run 0}
#altr 214 4 0.0001
label .a -text "item default value:" -width 50
label .b -textvariable va -fg blue
label .aa -text "now value:"
label .bb -textvariable varl -fg red
label .c -textvariable item -fg red
#button .a -text [exec sed -n 214p default.lib | awk "{print \$4}"] -command {}
#button .b -text U0 -command {altr 214 4 0.0001}
#button .c -text UA -command {altr 215 4 0.1e-9}
#button .d -text UB -command {altr 216 4 0.1e-18}
menu .m
. configure -menu .m
.m add command -label U0 -command {set l 214; set c 4; set varl [exec sed -n ${l}p l55sp_v151_FS_NVM_V2.lib | awk "{print \$[set c]}"]; set item U0; set va [exec sed -n ${l}p default.lib | awk "{print \$[set c]}"]; set brms ""; set var ""; set int [exp $va]}
.m add command -label UA -command {set l 215; set c 4; set varl [exec sed -n ${l}p l55sp_v151_FS_NVM_V2.lib | awk "{print \$[set c]}"]; set item UA; set va [exec sed -n ${l}p default.lib | awk "{print \$[set c]}"]; set brms ""; set var ""; set int [exp $va]}
.m add command -label UB -command {set l 216; set c 4; set varl [exec sed -n ${l}p l55sp_v151_FS_NVM_V2.lib | awk "{print \$[set c]}"]; set item UB; set va [exec sed -n ${l}p default.lib | awk "{print \$[set c]}"]; set brms ""; set var ""; set int [exp $va]}
.m add command -label DSUB -command {set l 217; set c 4; set item DSUB; foreach {varl va int} [settle $l $c] break; set brms ""; set var ""}
.m add command -label DROUT -command {set l 218; set c 4; set item DROUT; foreach {varl va int} [settle $l $c] break; set brms ""; set var ""}
.m add command -label PVAG -command {set l 219; set c 4; set item PVAG; foreach {varl va int} [settle $l $c] break; set brms ""; set var ""}
.m add command -label CDSC -command {set l 220; set c 4; set item CDSC; foreach {varl va int} [settle $l $c] break; set brms ""; set var ""}
.m add command -label CDSCB -command {set l 221; set c 4; set item CDSCB; foreach {varl va int} [settle $l $c] break; set brms ""; set var ""}
.m add command -label CDSCD -command {set l 222; set c 4; set item CDSCD; foreach {varl va int} [settle $l $c] break; set brms ""; set var ""}
entry .cc -textvariable int
button .d -text RUN -command {if {$int!=""} {altr $l $c $int}}
label .e -text "temp the best arg-rms"
entry .f -textvariable brms
label .g -text "temp the fittest value"
entry .i -textvariable var
#button .e -text minv -command {altr 752 7 1}
pack .a .b .aa .bb .c .cc .d .e .f .g .i
proc exp val {
#if {$val>0} {set op 1} else {set op 0}
if {[expr log10(abs($val))]>=0} {set pw 1} else {set pw 0}
if $pw {set new "1e[expr int(log10(abs($val)))-2]"} else {set new "1e[expr int(log10(abs($val)))-3]"}
#if $op {return $new} else {return [expr -$new]}
return $new
}
proc settle {l c} {
set varl [exec sed -n ${l}p l55sp_v151_FS_NVM_V2.lib | awk "{print \$[set c]}"]
set va [exec sed -n ${l}p default.lib | awk "{print \$[set c]}"]
set int [exp $va]
return "$varl $va $int"
}
======
<> Engineering