tksimos.tcl
29.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
#!/usr/bin/wish -f
#!/powderkeg/pk1/bosch/blt2.1/bltwish -f
#
# Copyright (C) 1996-1998 by the Board of Trustees
# of Leland Stanford Junior University.
#
# This file is part of the SimOS distribution.
# See LICENSE file for terms of the license.
#
wm title . TkSimOS
set visualPort 1865
set hostname localhost
set hostlist { }
set varUpdatePeriod 0
set chartsUpdatePeriod 0
foreach s { main stream local } { set sock($s) "" }
set varUpdateCB 0
set chartsUpdateCB 0
set charts_bg lightsteelblue
set charts_fg black
set chartEntries 60
set localHost [exec hostname]
set localSock 1066
set modelist { kernel sync ROOT idle total }
set formatlist { dec hex str "flt" "flt.1" }
set simos_vars {}
set derived_vars {}
set vcnt 0
proc dec {val} { format "%u" $val }
proc hex {val} { format "0x%x" $val }
proc str {val} { return $val }
proc pct {val} { format "%5.1f%%" $val }
proc flt {val} { format "%f" $val }
proc flt.1 {val} { format "%.1f" $val }
proc err msg {
# puts $msg
tk_dialog .dlog "TkSimOS Error" $msg "" 0 OK
}
proc connected {} {
global sock
return [expr {$sock(main) != ""}]
}
proc simosConnect {} {
global sock hostname visualPort
global localHost localSock
global varUpdatePeriod
# Set up main connection
if [catch {set sock(main) [socket $hostname $visualPort]} msg] {
err "Connect failed: $msg"
return -1
}
catch {destroy .hostset}
fconfigure $sock(main) -buffering none
catch {connectHook}
mainWindow
# Set up stream connection
catch { close $sock(stream) }
while {$sock(local) == ""} {
if [catch {
set sock(local) [socket -server streamConnect $localSock]
}] {
err "Failed to setup server socket"
incr localSock
}
}
if [catch {simosQuery [list "VISUALstream $localHost $localSock"]} msg] {
err "Connect failed: $msg"
return -1
}
if {$varUpdatePeriod > 0} varPeriodicUpdate
}
proc streamConnect {s h p} {
global sock
set sock(stream) $s
fconfigure $sock(stream) -buffering line
fconfigure $sock(stream) -blocking 0
streamParse
}
proc simosDisconnect {} {
global sock chartsUpdateCB varUpdateCB
catch {close $sock(main)}
catch {close $sock(stream)}
catch {set sock(main) ""}
catch {set sock(stream) ""}
catch {destroy .vt}
catch {destroy .vc}
catch {destroy .charts}
catch {destroy .debug}
catch {destroy .modesp}
catch {after cancel $chartsUpdateCB}
catch {after cancel $varUpdateCB}
chartsCleanup
mainWindow
}
proc simosQuery {querylist} {
global sock
if ![connected] return {}
foreach query $querylist {
if [catch {puts $sock(main) $query} msg] {
# Could not transmit request to SimOS -- it probably terminated
err "SimOS request failed:\n$msg"
simosDisconnect
return ""
}
}
set replylist {}
foreach query $querylist {
if [catch {set len [read $sock(main) 8]} msg] {
err "SimOS request failed:\n$msg"
simosDisconnect
return ""
}
# need next two lines to remove trailing chars of junk
# that cause the ensuing read to fail
set reallen 0
scan $len "%s" reallen
if [catch {set ret [read $sock(main) [expr $reallen]]} msg] {
err "SimOS request failed:\n$msg"
simosDisconnect
return ""
}
lappend replylist $ret
}
return $replylist
}
proc streamRead {} {
global sock
fconfigure $sock(stream) -blocking 0
if [catch {set len [read $sock(stream) 8]} msg] {
err "SimOS stream read failed:\n$msg"
simosDisconnect
return ""
}
# need next two lines to remove trailing chars of junk
# that cause the ensuing read to fail
set reallen 0
scan $len "%s" reallen
if {[fblocked $sock(stream)] || $reallen==0} {
error "Stream empty"
}
# Once header is received, always use blocking to ensure the
# entire data packet is received
fconfigure $sock(stream) -blocking 1
if [catch {set ret [read $sock(stream) [expr $reallen]]} msg] {
err "SimOS stream read failed:\n$msg"
simosDisconnect
return ""
}
return $ret
}
proc varDisplay v {
global var_value var_format var_chart formatlist
global var_widget vcnt
if ![info exists var_value($v)] {
if [catch {varAdd $v} msg] { err $msg; return }
}
if ![winfo exists .vt] return
if ![info exists var_widget($v)] {
set var_widget($v) var_$vcnt; incr vcnt
}
if [winfo exists .vt.$var_widget($v)] return;
frame .vt.$var_widget($v) -relief groove -bd 2
label .vt.$var_widget($v).name -text $v -width 45
label .vt.$var_widget($v).value -width 15 -textvariable var_value($v)
menubutton .vt.$var_widget($v).format -textvariable var_format($v) \
-fg blue -menu .vt.$var_widget($v).format.menu -width 4
menu .vt.$var_widget($v).format.menu
foreach f $formatlist {
.vt.$var_widget($v).format.menu add command -label $f \
-command "varFormat $v $f"
}
button .vt.$var_widget($v).hide -text "Hide" -command "varHide $v"
button .vt.$var_widget($v).chart -text "Chart" -command "varChartToggle $v"
pack .vt.$var_widget($v) -before .vt.control
pack .vt.$var_widget($v).name .vt.$var_widget($v).value \
.vt.$var_widget($v).format .vt.$var_widget($v).hide \
.vt.$var_widget($v).chart -side left -fill x
}
proc varTableCreate {} {
global var_widget
toplevel .vt
wm title .vt "TkSimOS Variable Table"
frame .vt.control -relief groove -bd 4
pack .vt.control -fill x
frame .vt.control.newVar
label .vt.control.newVar.label -text "Display Variable:"
entry .vt.control.newVar.entry -width 45 -relief sunken
bind .vt.control.newVar.entry <Return> {
if [catch {varAdd [%W get]} msg] {
err $msg
} else {
varDisplay [%W get]
# varUpdate
}
%W delete 0 end
}
pack .vt.control.newVar
pack .vt.control.newVar.label .vt.control.newVar.entry -side left -fill x
frame .vt.control.update
label .vt.control.update.label1 -text "Update every"
entry .vt.control.update.period -width 5 -relief sunken \
-textvariable varUpdatePeriod
bind .vt.control.update.period <Return> {
catch {after cancel $varUpdateCB}
after [expr [%W get] * 1000] varPeriodicUpdate
}
label .vt.control.update.label2 -text "seconds"
pack .vt.control.update
pack .vt.control.update.label1 .vt.control.update.period \
.vt.control.update.label2 -side left
frame .vt.control.buttons
button .vt.control.buttons.updateNow -text "Update All" \
-command varUpdate
button .vt.control.buttons.deleteAll -text "Hide All" \
-command varTableHide
button .vt.control.buttons.close -text "Close" -command varTableClose
pack .vt.control.buttons
pack .vt.control.buttons.updateNow .vt.control.buttons.deleteAll \
.vt.control.buttons.close -side left -fill x
foreach v [array names var_widget] {
varDisplay $v
}
varChartCreate
catch {varTableHook}
varUpdate
}
proc var {v {type total}} {
global var_value var_last
if ![info exists var_value($v)] {
varAdd $v
}
if {$type == "periodic"} {
if [catch {set val [expr $var_value($v) - $var_last($v)]}] {
set val ""
}
return $val
} else {
return $var_value($v)
}
}
proc varFormat {v {f ""}} {
global var_format var_value
if {$f != ""} {
set var_format($v) $f
}
if [info exists var_value($v)] {
set val $var_value($v)
if [catch {set var_value($v) [$var_format($v) $val]}] {
set var_format($v) "str"
set var_value($v) $val
}
}
}
proc varAdd {v {format "str"}} {
global var_format var_value var_last var_eval
global simos_vars derived_vars
set var_format($v) $format
set var_value($v) ""
set var_last($v) 0
if [info exists var_eval($v)] {
lappend derived_vars $v
} else {
lappend simos_vars $v
}
}
proc varHide {v} {
global var_widget var_value var_eval var_chart
catch {destroy .vt.$var_widget($v)}
catch {unset var_widget($v)}
catch {destroy .vc.$var_widget($v)}
catch {unset var_chart($v)}
}
proc varDelete {v} {
global var_widget var_format var_value var_eval var_chart
global simos_vars derived_vars
varHide $v
catch {unset var_value($v)}
catch {unset var_format($v)}
catch {unset var_eval($v)}
set i [lsearch $simos_vars $v]
if {$i >= 0} {
set simos_vars [lreplace $simos_vars $i $i]
}
set i [lsearch $derived_vars $v]
if {$i >= 0} {
set simos_vars [lreplace $derived_vars $i $i]
}
}
proc varDefine {v calc} {
global var_eval
set var_eval($v) $calc
if [catch {varAdd $v} msg] { err $msg }
}
proc varUpdate {} {
global var_value var_eval var_format var_chart var_widget var_last
global simos_vars derived_vars
set query {}
set dlist {}
foreach v $simos_vars {
lappend query "set $v"
}
if {[llength $query] > 0} {
set rlist [simosQuery $query]
# First set the values of all SimOS-defined variables
foreach v $simos_vars val $rlist {
set var_last($v) $var_value($v)
if {$val == "can't read \"$v\": no such variable"} {
lappend dlist $v
} else {
set var_value($v) $val
varFormat $v
}
}
if {[llength $dlist] == 1} {
varDelete $dlist
err "Undefined variable $dlist"
} elseif {[llength $dlist] > 1} {
foreach d $dlist {
varDelete $d
}
err "Undefined variables:\n $dlist"
}
}
# Next compute the values of the derived variables
foreach v $derived_vars {
set var_last($v) $var_value($v)
if [catch {set val [uplevel \#0 $var_eval($v)]} msg] {
set val "<undefined>"
}
set var_value($v) $val
varFormat $v
}
# Finally, update chart information for charted variables
if [winfo exists .vc] {
foreach v [array names var_chart] {
lappend var_chart($v) $var_value($v)
stripChartUpdate .vc.$var_widget($v) $var_chart($v)
}
}
}
proc varPeriodicUpdate {} {
global varUpdatePeriod varUpdateCB pauseSimulation
if ![connected] return
if {$varUpdatePeriod > 0} {
if !$pauseSimulation varUpdate
set varUpdateCB \
[after [expr $varUpdatePeriod * 1000] varPeriodicUpdate]
}
}
proc varTableHide {} {
global var_widget
foreach v [array names var_widget] {
varHide $v
}
}
proc varChartToggle {v} {
global var_chart var_value var_widget
if [winfo exists .vc.$var_widget($v)] {
destroy .vc.$var_widget($v)
unset var_chart($v)
} else {
set var_chart($v) {}
stripChartCreate .vc.$var_widget($v) $v
}
}
proc varChartCreate {} {
toplevel .vc
wm title .vc "TkSimOS Variable Chart"
label .vc.label -text "Variable Charts"
pack .vc.label
}
proc varTableClose {} {
global var_chart
destroy .vt
catch {destroy .vc}
foreach v [array names var_chart] {
unset var_chart($v)
}
}
proc doCheckpoint {} {
if {[simosQuery "doCheckpoint"] != OK} {
err "SimOS reported checkpoint failure"
}
}
proc simosExit {} {
global sock
if [catch {puts $sock(main) "simosExit"} msg] {
err "Checkpoint failed: $msg"
}
simosDisconnect
}
proc hostSet host {
global sock hostname visualPort
if [connected] {
err "Can't change host: already connected to $hostname:$visualPort"
return
}
if {$host == ""} {
set name ""
toplevel .hostset
wm title .hostset "TkSimOS: New host"
label .hostset.label -text Hostname:
entry .hostset.name -width 25 -relief sunken -textvariable name
pack .hostset.label .hostset.name -side left
focus .hostset.name
bind .hostset.name <Return> {
lappend hostlist $name
hostSet $name
destroy .hostset
hostMenu .host
}
} else {
set hostname $host
}
}
proc hostMenu {w} {
global hostname hostlist
catch {destroy $w}
frame $w
menubutton $w.name -textvariable hostname -menu $w.name.menu -fg blue
menu $w.name.menu
foreach h $hostlist {
$w.name.menu add command -label $h -command "hostSet $h"
}
$w.name.menu add command -label "new host..." -command {hostSet ""}
label $w.label -text "Connect to: "
entry $w.port -width 5 -relief sunken -textvariable visualPort
pack $w
pack $w.label $w.name $w.port -side left -fill x
}
proc mainWindow {} {
global hostlist hostname visualPort
global pauseSimulation getModes
if [connected] {
catch {destroy .host}
label .host -text "Connected to $hostname:$visualPort" -fg red
pack .host -fill x -ipady 5
catch {destroy .pause}
set pauseSimulation \
[simosQuery [list "set PauseSimulation"]]
checkbutton .pause -text "Pause Simulation" -variable pauseSimulation \
-command {simosQuery [list "set PauseSimulation $pauseSimulation"]}
pack .pause
set getModes 0
checkbutton .modesp -text "Retrieve Modes Data" -variable getModes
pack .modesp
catch {destroy .comm}
frame .comm
button .comm.vt -text "Variable table" -command {
varTableCreate
}
button .comm.charts -text "Stripcharts" \
-command { chartsCreate }
button .comm.debug -text "FlashLite debug" \
-command { debugWindow }
button .comm.cpt -text "Checkpoint" \
-command doCheckpoint
button .comm.kill -text "Exit SimOS" \
-command simosExit
button .comm.disconnect -text "Disconnect from SimOS" \
-command simosDisconnect
button .comm.exit -text "Exit TkSimOS" \
-command exit
pack .comm -fill x
pack .comm.vt .comm.charts .comm.debug .comm.cpt .comm.kill \
.comm.disconnect .comm.exit -fill x
} else {
catch {destroy .pause}
catch {destroy .comm}
frame .comm
button .comm.connect -text "Connect to SimOS" -command simosConnect
button .comm.exit -text "Exit TkSimOS" -command exit
pack .comm -fill x
pack .comm.connect .comm.exit -fill x
hostMenu .host
}
}
proc bucket {mf} {
global bucket_diff
return $bucket_diff($mf)
}
proc chartsSetup {} {
global charts_bg charts_fg
if {[simosQuery [list {log [timing fields]}]] != "OK"} {
err "Error in reading data stream"
error "Can't read data stream"
}
catch {destroy .charts}
toplevel .charts -background $charts_bg
wm title .charts "TkSimOS Stripcharts"
frame .charts.control -relief groove -bd 4 -bg $charts_bg
pack .charts.control -fill x
frame .charts.control.update -bg $charts_bg
label .charts.control.update.label1 -text "Update every" \
-fg $charts_fg -bg $charts_bg
entry .charts.control.update.period -width 5 -relief sunken \
-textvariable chartsUpdatePeriod -fg $charts_fg -bg $charts_bg
bind .charts.control.update.period <Return> {
catch {after cancel $chartsUpdateCB}
set chartsUpdateCB [after [expr [%W get] * 1000] chartsUpdate]
}
label .charts.control.update.label2 -text "seconds" \
-fg $charts_fg -bg $charts_bg
pack .charts.control.update
pack .charts.control.update.label1 .charts.control.update.period \
.charts.control.update.label2 -side left
button .charts.control.close -text "Close All" -command "chartsCleanup" \
-fg $charts_fg -bg $charts_bg
pack .charts.control.close
}
proc chartsCleanup {} {
global chartsUpdateCB bucket_field bucket_prev bucket_total
global chart_stats chart_normed
catch {after cancel chartsUpdateCB}
catch {destroy .charts}
catch {unset bucket_field}
catch {unset bucket_prev}
catch {unset bucket_diff}
catch {unset bucket_total}
catch {unset chart_stats}
catch {unset chart_normed}
}
proc streamParse {} {
global sock
if {$sock(stream) == ""} return
while 1 {
if [catch {set buf [streamRead]} msg] {
if {$msg != "Stream empty"} {
err "streamParse: $msg"
} else {
after 1000 streamParse
}
return
} else {
# puts "STREAM: $buf"
if {[lindex $buf 0] == "TIMING:"} {
modesParse $buf
} else {
catch {streamParseHook $buf}
}
}
}
}
proc modesParse {buf} {
global bucket_field bucket_prev bucket_total bucket_diff modelist
foreach line [split $buf "\n"] {
if {[lindex $line 1] == "SR_FIELDS"} {
set bucket_field $line
foreach f [lrange $bucket_field 4 end] {
foreach m $modelist {
set bucket_diff($m,$f) 0
set bucket_total($m,$f) 0
set bucket_prev($m,$f) 0
}
}
} elseif [regexp [concat {^TIMING: tree (.*) depth ([0-9]*) } \
{name (.*) parent (.*) n ([0-9]*)$}] \
$line match tree depth name parent n] {
} elseif {[lindex $line 1] == "SR_BUCKET"} {
if ![info exists bucket_field] return
set m [lindex $line 2]
if {[lsearch $modelist $m] == -1} continue
for {set i 4} {$i < [llength $line]} {incr i} {
set f [lindex $bucket_field $i]
incr bucket_total($m,$f) [lindex $line $i]
}
} elseif {$line == "TIMING: tree modes END"} {
foreach mf [array names bucket_total] {
set bucket_diff($mf) [expr $bucket_total($mf) - $bucket_prev($mf)]
set bucket_prev($mf) $bucket_total($mf)
set bucket_total($mf) 0
}
}
}
}
proc chartsUpdate {} {
global sock bucket_field chart_fields chartsUpdatePeriod chartsUpdateCB
global getModes pauseSimulation
if ![connected] return
if !$pauseSimulation {
if {$getModes && [info exists bucket_field]} {
simosQuery [list {log [timing dump modes]}]
}
foreach chart [array names chart_fields] {
chartUpdate $chart
chartRedraw $chart
}
}
set chartsUpdateCB [after [expr $chartsUpdatePeriod * 1000] chartsUpdate]
}
proc chartUpdate {chart} {
global chart_fields chart_eval chart_stats chart_normed
set total 0
foreach field $chart_fields($chart) {
if ![catch {set val [eval $chart_eval($chart,$field)]}] {
lappend chart_stats($chart,$field) $val
set total [expr $total + $val]
}
}
foreach field $chart_fields($chart) {
if {$total > 0} {
lappend chart_normed($chart,$field) \
[expr 1.0 * [lindex $chart_stats($chart,$field) end] / $total]
} else {
lappend chart_normed($chart,$field) 0.0
}
}
}
proc chartRedraw {chart} {
global modeLast modeTotal
global chart_fields chart_norm chart_stats chart_normed
set w .charts.chart_$chart
if ![winfo exists $w] return;
foreach field $chart_fields($chart) {
if $chart_norm($chart) {
set modeTotal($chart,$field) ""
set modeLast($chart,$field) \
[pct [expr [lindex $chart_normed($chart,$field) end]*100]]
} else {
set modeTotal($chart,$field) ""
set modeLast($chart,$field) \
[lindex $chart_stats($chart,$field) end]
}
if $chart_norm($chart) {
stackedChartUpdate $w.chart $field $chart_normed($chart,$field)
} else {
stackedChartUpdate $w.chart $field $chart_stats($chart,$field)
}
}
}
proc chartsClose {chart} {
global chart_fields chart_eval chart_norm
global chart_stats chart_normed chart_colors
destroy .charts.chart_$chart
foreach field $chart_fields($chart) {
unset chart_eval($chart,$field)
unset chart_stats($chart,$field)
unset chart_normed($chart,$field)
}
unset chart_fields($chart)
unset chart_colors($chart)
unset chart_norm($chart)
# Cleanup charts data if all charts windows are closed
if {[array size chart_fields] == 0} chartsCleanup
}
proc chartDefine {name fields} {
global chart_fields chart_eval chart_colors chart_stats
set chart_fields($name) ""
set chart_norm($name) 0
foreach fdef $fields {
set field [lindex $fdef 0]
lappend chart_fields($name) $field
set chart_stats($name,$field) {}
set chart_eval($name,$field) [lindex $fdef 1]
if {[llength $fdef] > 2} {
lappend chart_colors($name) [lindex $fdef 2]
} else {
lappend chart_colors($name) "black"
}
}
}
proc chartConfigure {name config} {
global chart_config
set w .charts.chart_$name.chart
if [winfo exists $w] {
$w $config
} else {
lappend chart_config($w) $config
}
}
proc chartsCreate {} {
global modeLast modeTotal
global charts_fg charts_bg
global chart_fields chart_eval chart_colors chart_norm
if [winfo exists .charts] return
if [catch chartsSetup] return
foreach chart [array names chart_fields] {
set w .charts.chart_$chart
frame $w -relief groove -bd 2 -bg $charts_bg
pack $w -before .charts.control
frame $w.ctl -bg $charts_bg
label $w.ctl.name -text $chart -width 25 -fg $charts_fg -bg $charts_bg
checkbutton $w.ctl.norm -text "Normalize" \
-variable chart_norm($chart) -command "chartRedraw $chart" \
-fg $charts_fg -bg $charts_bg
button $w.ctl.close -text "Close" -command "chartsClose $chart" \
-fg $charts_fg -bg $charts_bg
pack $w.ctl
pack $w.ctl.norm $w.ctl.name $w.ctl.close -side left
frame $w.table -bg $charts_bg
frame $w.table.title -bg $charts_bg
label $w.table.title.label -width 20 -text "Mode" \
-fg $charts_fg -bg $charts_bg
label $w.table.title.recent -width 12 -text "Last Period" \
-fg $charts_fg -bg $charts_bg
pack $w.table.title
pack $w.table.title.label $w.table.title.recent -side left
foreach f $chart_fields($chart) c $chart_colors($chart) {
frame $w.table.f_$f -bg $charts_bg
label $w.table.f_$f.label -width 20 -text $f -fg $c -bg $charts_bg
label $w.table.f_$f.recent -width 12 -fg $c -bg $charts_bg \
-textvariable modeLast($chart,$f)
pack $w.table.f_$f -after $w.table.title
pack $w.table.f_$f.label $w.table.f_$f.recent -side left
}
stackedChartCreate $w.chart $chart_fields($chart) $chart_colors($chart)
pack $w.table $w.chart -side left
}
chartsUpdate
}
proc stackedChartCreate {w elts colors} {
global chartEntries charts_bg
global chart_config
barchart $w -title "" -bg $charts_bg
$w legend configure -mapped 0
$w configure -height 180 -width 320 -barwidth 1 -barmode stacked
$w yaxis configure -min 0 -mapped 0
$w xaxis configure -min -0.5 -max [expr $chartEntries - 0.5] -mapped 0
foreach elt $elts color $colors {
$w element create $elt -xdata {} -ydata {} \
-fg $color -relief flat -borderwidth 0
}
if [info exists chart_config($w)] {
foreach config $chart_config($w) {
eval $w $config
}
}
}
proc stackedChartUpdate {w elt ylist} {
global xlist chartEntries
set count [llength $ylist]
if {$count < $chartEntries} {
$w element configure $elt \
-xdata [lrange $xlist 0 [expr $count - 2]] \
-ydata [lrange $ylist 1 end]
} else {
$w element configure $elt \
-xdata $xlist \
-ydata [lrange $ylist [expr $count - $chartEntries] end]
}
}
proc tickFormat {w value} {
return [format "%10s" $value]
}
proc stripChartCreate {chart title} {
global xlist chartEntries
uplevel barchart $chart -title $title
$chart configure -height 100 -width 460 -barwidth 1.25
$chart legend configure -mapped 0
$chart yaxis configure -min 0 -title "" -showticks 1 -command tickFormat
$chart xaxis configure -min -0.5 -max [expr $chartEntries - 0.5] -mapped 0
$chart element create strip -xdata {} -ydata {} \
-relief flat -borderwidth 0
pack $chart
}
proc stripChartUpdate {chart ylist} {
global xlist chartEntries
set count [llength $ylist]
if {$count < $chartEntries} {
$chart element configure strip \
-xdata [lrange $xlist 0 [expr $count - 2]] \
-ydata [lrange $ylist 1 end]
} else {
$chart element configure strip \
-xdata $xlist \
-ydata [lrange $ylist [expr $count - $chartEntries] end]
}
}
set debugOptions "TiXhe"
proc debugUpdate {node flag} {
global DEBUG
simosQuery [list "set DEBUG($node,$flag) [set DEBUG($node,$flag)]"]
}
proc debugUpdateAll {flag value} {
global DEBUG
set query {}
set numCpus [simosQuery [list {set PARAM(CPU.Count)}]]
for {set i 0} {$i <= $numCpus} {incr i} {
set DEBUG($i,$flag) $value
lappend query "set DEBUG($i,$flag) $value"
}
set ret [simosQuery $query]
}
set debugHelp ""
set debugInfo(a) { "DPsim annotations" }
set debugInfo(b) { "Buffer tracing" }
set debugInfo(c) { "Context tracing" }
set debugInfo(d) { "Directory thread tracing" }
set debugInfo(e) { "Emulator tracing" }
set debugInfo(f) { "Fault tracing" }
set debugInfo(h) { "Handler tracing" }
set debugInfo(i) { "Initialization sequence" }
set debugInfo(l) { "Latency output" }
set debugInfo(m) { "Memory system tracing" }
set debugInfo(n) { "Network thread tracing" }
set debugInfo(p) { "Processor thread tracing" }
set debugInfo(s) { "Scache thread tracing" }
set debugInfo(u) { "printf1 output from emulated handlers" }
set debugInfo(v) { "Virtual address translation tracing" }
set debugInfo(w) { "Watchdog thread tracing" }
set debugInfo(x) { "Enable protocol FLDEBUGTIME() output, DPsim call/return" }
set debugInfo(z) { "Misc or temporary" }
set debugInfo(A) { "Data handling debug statements" }
set debugInfo(B) { "SysADBus arbitration debugging" }
set debugInfo(C) { "Message passing cache coherence interaction" }
set debugInfo(D) { "Directory data cache tracing" }
set debugInfo(E) { "Show details of every handler-generated sEnd" }
set debugInfo(F) { "FlashPoint debugging" }
set debugInfo(G) { "Accelerated write gather debugging" }
set debugInfo(H) { "Handler timing dump" }
set debugInfo(I) { "InBox internal tracing" }
set debugInfo(J) { "IO thread tracing" }
set debugInfo(K) { "Vector pacKet tracing" }
set debugInfo(M) { "Message passing protocol debugging" }
set debugInfo(O) { "OutBox internal tracing" }
set debugInfo(P) { "Internal protocol tracing" }
set debugInfo(Q) { "Queue histogram debugging" }
set debugInfo(S) { "Software queue debugging" }
set debugInfo(T) { "Prints simulation time every DebugInterval ticks" }
set debugInfo(V) { "Verilog-FlashLite debugging output" }
set debugInfo(W) { "Wait-for-PI-reply debugging" }
set debugInfo(X) { "Enable statistics output" }
set debugInfo(Y) { "Report MD$ and MI$ misses (not hits)" }
set debugInfo(Z) { "Message passing timing debug output" }
set debugInfo(1) { "Message passing timing debugs required for calcperf.pl" }
set debugInfo(\() { "Jumptable activity trace" }
proc debugWindow {} {
global DEBUG debugOptions debugInfo debugHelp
toplevel .debug
wm title .debug "TkSimOS: FlashLite Debug Settings"
set numCpus [simosQuery [list {set PARAM(CPU.Count)}]]
# Get starting values of debug flags from SimOS
set debugQuery {}
set debugVars {}
for {set i 0} {$i <= $numCpus} {incr i} {
foreach j [split $debugOptions {}] {
set var "DEBUG($i,$j)"
lappend debugVars $var
lappend debugQuery "set $var"
}
}
set debugFlags [simosQuery $debugQuery]
foreach v $debugVars f $debugFlags {
set $v $f
}
for {set i 0} {$i <= $numCpus} {incr i} {
frame .debug.node_$i -relief groove -bd 2
if {$i == $numCpus} {
label .debug.node_$i.label -text "System" -width 20
} else {
label .debug.node_$i.label -text "Node $i" -width 20
}
pack .debug.node_$i.label -side left
foreach j [split $debugOptions {}] {
checkbutton .debug.node_$i.flag_$j -text $j \
-variable DEBUG($i,$j) -command "debugUpdate $i $j"
bind .debug.node_$i.flag_$j <Enter> "set debugHelp $debugInfo($j)"
bind .debug.node_$i.flag_$j <Leave> "set debugHelp {}"
bind .debug.node_$i.flag_$j <2> "debugUpdateAll $j 1"
bind .debug.node_$i.flag_$j <3> "debugUpdateAll $j 0"
pack .debug.node_$i.flag_$j -side left
}
pack .debug.node_$i
}
label .debug.help -textvariable debugHelp
pack .debug.help
}
if [file exists $env(HOME)/.tksimosrc] {
source $env(HOME)/.tksimosrc
}
if [file exists ./init.tksimos] {
source ./init.tksimos
}
if {$argc > 0} {
foreach f $argv {
source $f
}
}
set xlist {}
for {set i 0} {$i < $chartEntries} {incr i} {
lappend xlist $i
}
mainWindow