OpenCores
URL https://opencores.org/ocsvn/mips_enhanced/mips_enhanced/trunk

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [software/] [logan/] [logan.tcl] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
#!/usr/bin/wish
2
 
3
############################################
4
# On-chip Logic Analyzer GUI               #
5
#                                          #
6
# File:   logan.tcl                        #
7
# Author: Kristoffer Carlsson              #
8
############################################
9
 
10
 
11
# Sets the flag ready when any data is ready to be read from variable data
12
proc get_data {fd} {
13
 
14
    global data ready
15
 
16
    if [eof $fd] {
17
        catch {close $fd}
18
        return
19
    }
20
    set data [read $fd]
21
    set ready 1
22
}
23
 
24
# Calculates the RSP checksum
25
proc calc_checksum {data} {
26
    set sum 0
27
    for {set k 0} {$k < [string length $data]} {incr k} {
28
        binary scan [string index $data $k] c dd
29
        set sum [expr $dd + $sum]
30
    }
31
    set sum [expr $sum % 256]
32
    return [format %.2x $sum]
33
}
34
 
35
# Hex encodes a string
36
proc str2hex {str} {
37
    for {set k 0} {$k < [string length $str]} {incr k} {
38
        binary scan [string index $str $k] c dd
39
        append hex [format %.2x $dd ]
40
    }
41
    return $hex
42
}
43
 
44
# Decodes a hex encoded string
45
proc hex2str {hex} {
46
    for {set k 1} {$k < [string length $hex]} {incr k 2} {
47
        scan "0x[string range $hex $k [expr $k+1]]" %x byte
48
        append str [format %c $byte]
49
    }
50
    return $str
51
}
52
 
53
# Converts the integer <x> to a string with <bits> number of bits
54
proc toBin {x  bits} {
55
    set bitstr ""
56
    for {set i 0} {$i < $bits} {incr i} {
57
        set bitstr "[expr ($x >> $i)&1]$bitstr"
58
    }
59
    return $bitstr
60
}
61
 
62
# Converts a string of bits to string with the hexadecimal value
63
proc binToHex {bitstr} {
64
    global nibbleToHex
65
 
66
    set hexstr ""
67
 
68
    set len [string length $bitstr]
69
 
70
    if {[expr $len % 4 != 0]} {
71
        # zero pad so that the bitstr is a multiple of 4. Needed for nibbleToHex
72
        for {set i 0} {$i < [expr 4-($len % 4)]} {incr i} {
73
            set bitstr "0$bitstr"
74
        }
75
    }
76
 
77
    for {set i 0} {$i < [string length $bitstr]} {incr i 4} {
78
        set bits [string range $bitstr $i [expr $i+3]]
79
        set hex $nibbleToHex($bits)
80
        append hexstr $hex
81
    }
82
    return $hexstr
83
}
84
 
85
# Parses the data from the RSP packet
86
proc parse_packet {data format} {
87
 
88
    set output ""
89
 
90
    if {$data == "-"} {
91
        return "-";
92
    }
93
    while {[regexp -nocase -all {\$([A-Za-z0-9]*)\#([A-Za-z0-9]{2})(.*)} $data -> val check data] == 1} {
94
        if {[calc_checksum $val] == $check}  {
95
            append output $val
96
 
97
        } else {
98
            return "-1"
99
        }
100
    }
101
    return $output
102
}
103
 
104
# Reads any memory address from GRMON
105
proc read_mem {addr len s} {
106
 
107
    global data ready
108
 
109
    set cmd "m$addr,$len"
110
    rsp_cmd $cmd $s
111
 
112
   while {1} {
113
       vwait ready
114
       set ready 0
115
       if {$data == "+"} {
116
           continue
117
       } elseif {$data == "-"} {
118
           puts "Checksum error in receiver. Resending .. "
119
           rsp_cmd $rspcmd $s
120
       } else {
121
           set val [parse_packet $data "int"]
122
 
123
           if {$val == -1} {
124
               puts "Checksum error"
125
               puts $s "-"
126
           } else {
127
               puts $s "+"
128
               return [format %u "0x$val"]
129
               break
130
           }
131
       }
132
   }
133
}
134
 
135
# Sends any GRMON command
136
proc remote_cmd {cmd s} {
137
 
138
    global data ready
139
 
140
    set rspcmd "qRcmd,"
141
    append rspcmd [str2hex $cmd]
142
    rsp_cmd $rspcmd $s
143
 
144
    while {1} {
145
        vwait ready
146
        set ready 0
147
        if {$data == "+"} {
148
            continue
149
        } elseif {$data == "-"} {
150
            puts "Checksum error in receiver. Resending .. "
151
            rsp_cmd $rspcmd $s
152
        } else {
153
            # packet received
154
            set val [parse_packet $data "int"]
155
            if {$val == -1} {
156
                puts "Checksum error"
157
                puts $s "-"
158
            } else {
159
                if {$val == "OK"} {
160
                    puts $s "+"
161
                    break
162
                } else {
163
                    puts $s "+"
164
                }
165
            }
166
        }
167
    }
168
}
169
 
170
# Gets the logan base address
171
proc read_addr {s} {
172
 
173
    global data ready
174
 
175
    set addr "-1"
176
 
177
    set rspcmd "qRcmd,"
178
    append rspcmd [str2hex "la"]
179
    rsp_cmd $rspcmd $s
180
 
181
    while {1} {
182
        vwait ready
183
        set ready 0
184
        if {$data == "+"} {
185
            continue
186
        } elseif {$data == "-"} {
187
            puts "Checksum error in receiver. Resending .. "
188
            rsp_cmd $rspcmd $s
189
        } else {
190
            # packet received
191
            set val [parse_packet $data "int"]
192
            if {$val == -1} {
193
                puts "Checksum error"
194
                puts $s "-"
195
            } else {
196
                set output [hex2str $val]
197
                if { [regexp -nocase -all {[ |\t]*(0x[0-9A-Za-z]+)} $output -> match] == 1 } {
198
                    set addr $match
199
                }
200
                if {$val == "OK"} {
201
                    puts $s "+"
202
                    break
203
                } else {
204
                    puts $s "+"
205
                }
206
            }
207
        }
208
    }
209
    return $addr
210
}
211
 
212
# Send a GDB RSP command
213
proc rsp_cmd {cmd s} {
214
    append rspcmd "\$" $cmd "#"  [calc_checksum $cmd]
215
    puts $s $rspcmd
216
    flush $s
217
}
218
 
219
 
220
# Reads status word
221
proc read_status {addr} {
222
    global s usereg usequal armed trigged dbits depth trigl
223
 
224
    set status [read_mem "$addr" 4 $s]
225
 
226
    set usereg  [expr ($status & 0x80000000) ? "yes" : "no" ]
227
    set usequal [expr ($status & 0x40000000) ? "yes" : "no" ]
228
    set armed   [expr ($status & 0x20000000) ? "yes" : "no" ]
229
    set trigged [expr ($status & 0x10000000) ? "yes" : "no" ]
230
    set dbits   [expr ($status & 0x0ff00000) >> 20]
231
    set depth   [expr (($status & 0x000fffc0) >> 6)+1]
232
    set trigl   [expr ($status & 0x0000003f)]
233
}
234
 
235
# Reads the LOGAN setup file
236
proc read_config {filename} {
237
 
238
    global dbits
239
 
240
    set fd [open $filename r]
241
 
242
    set bits 0
243
 
244
    while {[gets $fd line] >= 0} {
245
        if {[regexp -nocase -all {^[ |\t]*([^ |\t]+)[ |\t]+([0-9]+)}  $line -> name size] == 1} {
246
            lappend signals $name $size
247
            set bits [expr $bits+$size]
248
            if {$bits == $dbits} {
249
                break
250
            }
251
        }
252
    }
253
    return $signals
254
}
255
 
256
 
257
# Send the patterns/masks to GRMON
258
proc download_conf {trigl siglist mcarr eqarr} {
259
 
260
    global s
261
    upvar $mcarr mc
262
    upvar $eqarr eq
263
 
264
    for {set tl 0} {$tl < $trigl} {incr tl} {
265
        upvar #0  "pm.$tl" pm
266
        set i 1
267
        set totpat ""
268
        set totmask ""
269
        foreach {pat mask} $pm {
270
            set size [lindex $siglist $i]
271
            append totpat [toBin $pat $size]
272
            append totmask [toBin $mask $size]
273
            incr i 2
274
        }
275
        set cmdstr "la pm $tl 0x[binToHex $totpat] 0x[binToHex $totmask]"
276
        remote_cmd $cmdstr $s
277
        set cmdstr "la trigctrl $tl $mc($tl) [expr $eq($tl) == "yes" ? 1:0]"
278
        remote_cmd $cmdstr $s
279
    }
280
}
281
 
282
# Load configuration from file
283
proc load_conf { } {
284
 
285
    global s sigs trigl cur_tl dbits mc eq tcount dcount qualbit qualval
286
 
287
    set file [tk_getOpenFile]
288
    if {$file == ""} { return }
289
    set fd [open $file "r"]
290
 
291
    set tl [gets $fd]
292
    set db [gets $fd]
293
 
294
    if {$tl != $trigl || $db != $dbits} {
295
        tk_messageBox -message \
296
            "Configuration file does not match current hardware.\nConfiguration not loaded."\
297
            -type ok -icon error
298
        return
299
    }
300
 
301
    set bits 0
302
    while {[gets $fd line] >= 0} {
303
        if {[regexp -nocase -all {^[ |\t]*([^ |\t]+)[ |\t]+([0-9]+)}  $line -> name size] == 1} {
304
            lappend sigs $name $size
305
            set bits [expr $bits+$size]
306
            if {$bits == $dbits} {
307
                break
308
            }
309
        }
310
    }
311
    if {$bits != $dbits} {
312
        tk_messageBox -message "Signal sizes don't match dbits" -type ok -icon error
313
        return
314
    }
315
 
316
    set tcount [gets $fd]
317
    set dcount [gets $fd]
318
    set qualbit [gets $fd]
319
    set qualval [gets $fd]
320
 
321
    remote_cmd "la count $tcount" $s
322
    remote_cmd "la div $dcount" $s
323
    remote_cmd "la qual $qualbit $qualval" $s
324
 
325
    for {set i 0} {$i < $tl} {incr i} {
326
        upvar pm.$i pm
327
        set pm [split [gets $fd] " "]
328
    }
329
 
330
    array set mc [split [gets $fd] " "]
331
    array set eq [split [gets $fd] " "]
332
 
333
    download_conf $trigl $sigs mc eq
334
 
335
    updatePMentry pm.$cur_tl $cur_tl
336
    .t.tl.mc.entry delete 0 end
337
    .t.tl.eq.entry delete 0 end
338
    .t.tl.mc.entry insert 0 $mc($cur_tl)
339
    .t.tl.eq.entry insert 0 $eq($cur_tl)
340
 
341
    close $fd
342
}
343
 
344
# Save configuration to file
345
proc save_conf { } {
346
    global sigs trigl dbits mc eq tcount dcount qualbit qualval
347
 
348
    set file [tk_getSaveFile]
349
    if {$file == ""} { return }
350
    set fd [open $file "w+"]
351
    set nr [expr [llength $sigs]/2]
352
 
353
    puts $fd "$trigl\n$dbits"
354
 
355
    foreach {sig size} $sigs {
356
        puts $fd "$sig\t$size"
357
    }
358
 
359
    puts $fd "$tcount\n$dcount\n$qualbit\n$qualval"
360
 
361
    for {set i 0} {$i < $trigl} {incr i} {
362
        upvar pm.$i pm
363
        puts $fd $pm
364
    }
365
    puts $fd [array get mc]
366
    puts $fd [array get eq]
367
 
368
    flush $fd
369
    close $fd
370
}
371
 
372
 
373
# Updates the pattern and mask entry
374
proc updatePMentry {pml sel} {
375
 
376
    upvar #0 $pml pm
377
 
378
    .t.tl.pm.cfg.pattern delete 0 end
379
    .t.tl.pm.cfg.mask delete 0 end
380
    set i [.t.tl.pm.slist.list curselection]
381
    if {$i == ""} {
382
        .t.tl.pm.slist.list selection set $sel
383
        set i $sel
384
    }
385
    set i [expr 2*$i]
386
    .t.tl.pm.cfg.pattern insert 0 [lindex $pm $i]
387
    .t.tl.pm.cfg.mask insert 0 [lindex $pm [expr 1 + $i]]
388
}
389
 
390
# Saves the pattern and mask entry
391
proc savePMentry {pml sel} {
392
 
393
    upvar $pml pm
394
 
395
    set i [.t.tl.pm.slist.list curselection]
396
    if {$i == ""} {
397
        .t.tl.pm.slist.list selection set $sel
398
        set i $sel
399
    }
400
    set i [expr 2*$i]
401
 
402
    set pm [lreplace $pm $i $i [.t.tl.pm.cfg.pattern get]]
403
    set pm [lreplace $pm [expr $i+1] [expr $i+1] [.t.tl.pm.cfg.mask get]]
404
 
405
}
406
 
407
# Called by trace when changing tl, saves and updates the entry boxes
408
proc changeTL {var index op} {
409
    upvar $var newtl
410
    global cur_tl selsig
411
    global pm.$cur_tl mc eq
412
    savePMentry pm.$cur_tl $selsig
413
    set mc($cur_tl) [.t.tl.mc.entry get]
414
    set eq($cur_tl) [.t.tl.eq.entry get]
415
    set cur_tl $newtl
416
    .t.tl.mc.entry delete 0 end
417
    .t.tl.mc.entry insert 0 $mc($cur_tl)
418
    .t.tl.eq.entry delete 0 end
419
    .t.tl.eq.entry insert 0 $eq($cur_tl)
420
    updatePMentry pm.$cur_tl $cur_tl
421
}
422
 
423
proc OptionMenu {name label width var init l} {
424
    global $var
425
    frame $name
426
    label $name.label -text $label -width $width -anchor w
427
    pack $name.label -side left
428
    set optname [eval tk_optionMenu $name.menu $var $init]
429
    pack $name.menu -side right
430
    $optname delete 0
431
    set j [llength $l]
432
    for {set i 0} {$i < $j} {incr i} {
433
        set e [lindex $l $i]
434
        $optname insert $i radiobutton -label $e -variable $var
435
    }
436
    return $name
437
}
438
 
439
 
440
proc SettingEntry {name label width command args} {
441
    frame $name
442
    label $name.label -text $label -width $width -anchor w
443
    eval {entry $name.entry -relief sunken} $args
444
    pack $name.label -side left
445
    pack $name.entry -side right -fill x -expand true
446
    bind $name.entry <Return> $command
447
    return $name.entry
448
}
449
 
450
proc StatusMessage {name label value width args} {
451
    frame $name
452
    label $name.label -text $label -width $width -anchor w
453
    eval {label $name.val -text $value -width 6} $args -anchor w
454
    pack $name.label -side left
455
    pack $name.val -side right
456
    return $name
457
}
458
 
459
 
460
 
461
#########################################################
462
# Main code starts here                                 #
463
#########################################################
464
 
465
# init 
466
 
467
if { [catch {set s [socket localhost 2222]}] != 0 } {
468
    puts "\nError connecting to localhost : 2222\nPut GRMON in GDB mode.\n"
469
    exit
470
} else {
471
    fconfigure $s -blocking 0 -buffering none
472
    fileevent $s readable {get_data $s}
473
    set conn 1
474
}
475
 
476
set data 0
477
set ready 0
478
set cur_tl 0
479
set selsig 0
480
 
481
for {set i 0} {$i < 16} {incr i} {
482
    set index [toBin $i 4]
483
    set nibbleToHex($index) [format %.1x $i]
484
}
485
 
486
vwait ready
487
 
488
set addr [read_addr $s]
489
 
490
if {$addr == "-1"} {
491
    puts "\n No logic analyzer found! Exiting ...\n"
492
    exit
493
}
494
 
495
set tcount_addr [format %x [expr $addr + 0x0C]]
496
set dcount_addr [format %x [expr $addr + 0x10]]
497
set qual_addr   [format %x [expr $addr + 0x14]]
498
set addr [format %x $addr]
499
 
500
read_status $addr
501
 
502
set tcount [read_mem $tcount_addr 4 $s]
503
set dcount [read_mem $dcount_addr 4 $s]
504
set qual   [read_mem $qual_addr 4 $s]
505
 
506
set qualbit [expr $qual & 0xFF]
507
set qualval [expr ($qual & 256)>>8]
508
 
509
set sigs [read_config "setup.logan"]
510
 
511
# set up the pattern/mask, mc and eq lists
512
for {set i 0} {$i < $trigl} {incr i} {
513
    set mc($i) 0
514
    set eq($i) "yes"
515
    lappend tl $i
516
    for {set j 0} {$j < [llength $sigs]} {incr j} {
517
        lappend pm.$i 0
518
    }
519
}
520
 
521
# Create widgets and configure bindings
522
 
523
# top level frame and menubar
524
wm title . "Logic Analyzer GUI - connected"
525
frame .menubar
526
pack .menubar -fill x
527
 
528
menubutton .menubar.file -text File -menu .menubar.file.m
529
pack .menubar.file -side left
530
 
531
set m [menu .menubar.file.m]
532
$m add command -label "Load conf" -command {load_conf}
533
$m add command -label "Save conf" -command {save_conf}
534
$m add command -label "Detach" -command {
535
    if {$conn == 1} {
536
        rsp_cmd "D" $s
537
        vwait ready
538
        puts $s "+"
539
        close $s
540
        set conn 0
541
        wm title . "Logic Analyzer GUI - disconnected"
542
    }
543
}
544
$m add command -label "Reconnect" -command {
545
    if {$conn == 0} {
546
        set s [socket localhost 2222]
547
        fconfigure $s -blocking 0 -buffering none
548
        fileevent $s readable {get_data $s}
549
        set conn 1
550
        wm title . "Logic Analyzer GUI - connected"
551
    }
552
}
553
$m add command -label "Exit" -command {
554
    if {$conn == 1} {
555
        rsp_cmd "D" $s
556
        vwait ready
557
        puts $s "+"
558
    }
559
    exit
560
}
561
 
562
 
563
frame .t -width 800 -height 450
564
 
565
 
566
# .t.tl frame contains all trigger level specific config
567
frame .t.tl -relief ridge -bd 1 -width 500 -height 450
568
pack .t.tl  -side left -padx 15 -pady 15 -ipadx 5 -ipady 5
569
 
570
OptionMenu .t.tl.trigl "Config for trigl level: " 25 new_tl 0 $tl
571
trace variable new_tl w changeTL
572
 
573
pack .t.tl.trigl -pady 10
574
 
575
# .t.tl.pm contains the signal listbox and p/m entry
576
frame .t.tl.pm
577
pack .t.tl.pm
578
 
579
set sl [frame .t.tl.pm.slist]
580
listbox $sl.list -yscrollcommand {$sl.scroll set} -setgrid true -background white
581
$sl.list selection set 0
582
scrollbar $sl.scroll -orient vertical -command {$sl.list yview}
583
pack $sl.scroll -side right -fill y
584
pack $sl.list -side left
585
pack $sl -padx 10 -pady 10 -side left
586
 
587
foreach {signal size} $sigs {
588
    $sl.list insert end  "$signal ($size bits)"
589
 
590
}
591
 
592
bind $sl.list <ButtonRelease-1> {updatePMentry pm.$cur_tl $selsig}
593
bind $sl.list <ButtonPress-1> {savePMentry pm.$cur_tl $selsig}
594
bind $sl.list <Key-Tab> {
595
    set newsig [$sl.list curselection]
596
    if {$newsig != ""} {
597
        set selsig $newsig
598
    }
599
}
600
bind $sl.list <Leave> {
601
    set newsig [$sl.list curselection]
602
    if {$newsig != ""} {
603
        set selsig $newsig
604
    }
605
}
606
 
607
# cfg frame contains the p/m entry boxes
608
set cfg [frame .t.tl.pm.cfg]
609
label $cfg.plab -text "Pattern:" -width 8 -anchor w
610
entry $cfg.pattern
611
$cfg.pattern insert 0 0
612
label $cfg.mlab -text "Mask:" -width 8 -anchor w
613
entry $cfg.mask
614
$cfg.mask insert 0 0
615
 
616
pack $cfg -side right -pady 10 -anchor nw
617
pack $cfg.plab $cfg.pattern $cfg.mlab $cfg.mask -padx 10 -anchor w
618
 
619
SettingEntry .t.tl.mc "Match counter: " 15 {}
620
SettingEntry .t.tl.eq "Trig on equal: " 15 {}
621
.t.tl.mc.entry insert 0 0
622
.t.tl.eq.entry insert 0 "yes"
623
bind .t.tl.eq.entry <ButtonPress-1> {
624
    if {[.t.tl.eq.entry get] == "yes"} {
625
        set new "no"
626
    } else {
627
        set new "yes"
628
    }
629
    .t.tl.eq.entry del 0 end
630
    .t.tl.eq.entry insert 0 $new
631
}
632
 
633
pack .t.tl.mc .t.tl.eq -side top -padx 10 -pady 10
634
 
635
button .t.tl.down -text "Download conf" -command {
636
    savePMentry pm.$cur_tl $selsig
637
    set mc($cur_tl) [.t.tl.mc.entry get]
638
    set eq($cur_tl) [.t.tl.eq.entry get]
639
    download_conf $trigl $sigs mc eq
640
}
641
pack .t.tl.down -padx 10 -pady 20
642
 
643
# status & settings
644
frame .t.s -width 200 -height 450
645
 
646
button .t.s.stat -text "Update status" -command {read_status $addr}
647
set d [frame .t.s.statd -relief ridge -bd 1]
648
 
649
StatusMessage $d.width "Width: "  $dbits 15 -textvar dbits
650
StatusMessage $d.depth "Depth: "  $depth 15 -textvar depth
651
StatusMessage $d.trigl "Trigl: "  $trigl 15 -textvar trigl
652
StatusMessage $d.usereg "Usereg: "  $usereg 15 -textvar usereg
653
StatusMessage $d.usequal "Qualifier: "  $usereg 15 -textvar usequal
654
StatusMessage $d.armed "Armed: "  $armed 15 -textvar armed
655
StatusMessage $d.trigged "Trigged: "  $trigged 15 -textvar trigged
656
 
657
pack .t.s.stat
658
pack $d.width $d.depth $d.trigl $d.usereg $d.usequal $d.armed $d.trigged -anchor w
659
pack .t.s.statd -padx 10 -pady 10 -expand 1 -fill x
660
 
661
set d [frame .t.s.setd -relief ridge -bd 1]
662
 
663
SettingEntry $d.tcount "Trig count: " 15 {remote_cmd "la count [$d.tcount.entry get]" $s} -textvar tcount
664
SettingEntry $d.dcount "Sample divisor: " 15 {remote_cmd "la div [$d.dcount.entry get]" $s} -textvar dcount
665
SettingEntry $d.qb "Qualifier bit: " 15 {remote_cmd "la qual [$d.qb.entry get] [$d.qv.entry get]" $s} -textvar qualbit
666
SettingEntry $d.qv "Qualifier val: " 15 {remote_cmd "la qual [$d.qb.entry get] [$d.qv.entry get]" $s} -textvar qualval
667
 
668
pack $d.tcount $d.dcount $d.qb $d.qv
669
pack .t.s.setd -padx 10 -pady 10 -expand 1 -fill x
670
 
671
set b [frame .t.s.b]
672
pack $b -padx 10 -pady 10
673
 
674
button $b.arm -text Arm -width 15  -command {remote_cmd "la arm" $s}
675
button $b.reset -text Reset -width 15 -command {remote_cmd "la reset" $s}
676
button $b.dump -text Dump -width 15 -command {remote_cmd "la dump" $s}
677
button $b.wave -text GTKWave -width 15 -command {exec "gtkwave" "log.vcd"}
678
 
679
grid $b.arm $b.reset
680
grid $b.dump $b.wave
681
 
682
SettingEntry .t.s.cmd "GRMON command: " 17 {remote_cmd [.t.s.cmd.entry get] $s} -bg white
683
pack .t.s.cmd
684
 
685
pack .t.s -side right -padx 15 -pady 15 -expand 1 -fill x
686
 
687
pack .t -expand 1 -fill both

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.