My omnium-gatherom of scripts and source code.
1##########################################################################
2# Parsing of command line flags #
3##########################################################################
4
5proc flagVal {flag default} {
6 global argv
7 foreach t $argv {
8 if {[string match "-$flag*" $t]} {return [string range $t 2 end]}
9 }
10 return $default
11}
12
13proc findFlag {flag} {
14 global argv
15 foreach t $argv {
16 if {[string match "-$flag" $t]} {return 1}
17 }
18 return 0
19}
20
21##########################################################################
22# Register File Implementation. Shown as array of 8 columns #
23##########################################################################
24
25
26# Font used to display register contents
27set fontSize [expr 10 * [flagVal "f" 12]]
28set codeFontSize [expr 10 * [flagVal "c" 10]]
29set labFontSize [expr 10 * [flagVal "l" 10]]
30set bigFontSize [expr 10 * [flagVal "b" 16]]
31set dpyFont "*-courier-medium-r-normal--*-$fontSize-*-*-*-*-*-*"
32set labFont "*-helvetica-medium-r-normal--*-$labFontSize-*-*-*-*-*-*"
33set bigLabFont "*-helvetica-bold-r-normal--*-$bigFontSize-*-*-*-*-*-*"
34set codeFont "*-courier-medium-r-normal--*-$codeFontSize-*-*-*-*-*-*"
35# Background Color of normal register
36set normalBg white
37# Background Color of highlighted register
38set specialBg LightSkyBlue
39
40# Height of titles separating major sections of control panel
41set sectionHeight 2
42
43
44# How many rows of code do I display
45set codeRowCount [flagVal "r" 50]
46
47# Keep track of previous highlighted register
48set lastId -1
49proc setReg {id val highlight} {
50 global lastId normalBg specialBg
51 if {$lastId >= 0} {
52 .r.reg$lastId config -bg $normalBg
53 set lastId -1
54 }
55 if {$id < 0 || $id >= 15} {
56 error "Invalid Register ($id)"
57 }
58 .r.reg$id config -text [format %16x $val]
59 if {$highlight} {
60 uplevel .r.reg$id config -bg $specialBg
61 set lastId $id
62 }
63}
64
65# Clear all registers
66proc clearReg {} {
67 global lastId normalBg
68 if {$lastId >= 0} {
69 .r.reg$lastId config -bg $normalBg
70 set lastId -1
71 }
72 for {set i 0} {$i < 8} {incr i 1} {
73 .r.reg$i config -text ""
74 }
75}
76
77# Set all 3 condition codes
78proc setCC {zv cv ov} {
79 .cc.cc0 config -text [format %d $zv]
80 .cc.cc1 config -text [format %d $cv]
81 .cc.cc2 config -text [format %d $ov]
82}
83
84
85### Create display for misc. state
86frame .flags
87pack .flags -in . -side bottom
88
89##############################################################################
90# Status Display #
91##############################################################################
92
93set simStat "AOK"
94# Line to display simulation status
95frame .stat
96pack .stat -in .flags -side left
97label .stat.statlab -width 7 -text "Stat" -height $sectionHeight -font $bigLabFont
98label .stat.statdpy -width 3 -font $dpyFont -relief ridge -bg white -textvariable simStat
99label .stat.fill -width 6 -text ""
100pack .stat.statlab .stat.statdpy .stat.fill -in .stat -side left
101##############################################################################
102# Condition Code Display #
103##############################################################################
104# Create Window for condition codes
105frame .cc
106pack .cc -in .flags -side right
107
108label .cc.lab -text "Condition Codes" -height $sectionHeight -font $bigLabFont
109pack .cc.lab -in .cc -side left
110
111
112set ccnames [list "Z" "S" "O"]
113
114# Create Row of CC Labels
115for {set i 0} {$i < 3} {incr i 1} {
116 label .cc.lab$i -width 1 -font $dpyFont -text [lindex $ccnames $i]
117 pack .cc.lab$i -in .cc -side left
118 label .cc.cc$i -width 1 -font $dpyFont -relief ridge -bg $normalBg
119 pack .cc.cc$i -in .cc -side left
120}
121
122##############################################################################
123# Register Display #
124##############################################################################
125
126
127# Create Window for registers
128frame .r
129pack .r -in . -side bottom
130# Following give separate window for register file
131# toplevel .r
132# wm title .r "Register File" -height $sectionHeight -font $bigLabFont
133label .r.lab -text "Register File" -font $bigLabFont -height $sectionHeight
134pack .r.lab -in .r -side top
135# Set up top row control panel (disabled)
136# frame .r.cntl
137# pack .r.cntl -fill x -in .r
138# label .r.labreg -text "Register" -width 10
139# entry .r.regid -width 3 -relief sunken -textvariable regId -font $dpyFont
140# label .r.labval -text "Value" -width 10
141# entry .r.regval -width 8 -relief sunken -textvariable regVal -font $dpyFont
142# button .r.doset -text "Set" -command {setReg $regId $regVal 1} -width 6
143# button .r.c -text "Clear" -command clearReg -width 6
144# pack .r.labreg .r.regid .r.labval .r.regval .r.doset .r.c -in .r.cntl -side left
145
146set regnames [list "%rax" "%rcx" "%rdx" "%rbx" "%rsp" "%rbp" "%rsi" "%rdi" "%r8 " "%r9 " "%r10" "%r11" "%r12" "%r13" "%r14" ""]
147
148# Create rows of register labels and displays
149for {set j 0} {$j < 3} {incr j 1} {
150 frame .r.labels$j
151 pack .r.labels$j -side top -in .r
152
153 for {set c 0} {$c < 5} {incr c 1} {
154 set i [expr $j * 5 + $c]
155 label .r.lab$i -width 16 -font $dpyFont -text [lindex $regnames $i]
156 pack .r.lab$i -in .r.labels$j -side left
157 }
158
159 # Create Row of Register Entries
160 frame .r.row$j
161 pack .r.row$j -side top -in .r
162
163 # Create 5 registers
164 for {set c 0} {$c < 5} {incr c 1} {
165 set i [expr $j * 5 + $c]
166 if {$i == 15} {
167 label .r.reg$i -width 16 -font $dpyFont -text ""
168 } else {
169 label .r.reg$i -width 16 -font $dpyFont -relief ridge \
170 -bg $normalBg
171 }
172 pack .r.reg$i -in .r.row$j -side left
173 }
174
175}
176
177##############################################################################
178# Main Control Panel #
179##############################################################################
180#
181# Set the simulator name (defined in simname in ssim.c)
182# as the title of the main window
183#
184wm title . $simname
185#wm title . "Y86-64 Simulator"
186
187# Control Panel for simulator
188set cntlBW 11
189frame .cntl
190pack .cntl
191button .cntl.quit -width $cntlBW -text Quit -command exit
192button .cntl.run -width $cntlBW -text Go -command simGo
193button .cntl.stop -width $cntlBW -text Stop -command simStop
194button .cntl.step -width $cntlBW -text Step -command simStep
195button .cntl.reset -width $cntlBW -text Reset -command simResetAll
196pack .cntl.quit .cntl.run .cntl.stop .cntl.step .cntl.reset -in .cntl -side left
197# Simulation speed control
198scale .spd -label {Simulator Speed (10*log Hz)} -from -10 -to 30 -length 10c \
199 -orient horizontal -command setSpeed
200pack .spd
201
202# Simulation mode
203set simMode forward
204
205# frame .md
206# pack .md
207# radiobutton .md.wedged -text Wedged -variable simMode \
208# -value wedged -width 10 -command {setSimMode wedged}
209# radiobutton .md.stall -text Stall -variable simMode \
210# -value stall -width 10 -command {setSimMode stall}
211# radiobutton .md.forward -text Forward -variable simMode \
212# -value forward -width 10 -command {setSimMode forward}
213# pack .md.wedged .md.stall .md.forward -in .md -side left
214
215# simDelay defines #milliseconds for each cycle of simulator
216# Initial value is 1000ms
217set simDelay 1000
218# Set delay based on rate expressed in log(Hz)
219proc setSpeed {rate} {
220 global simDelay
221 set simDelay [expr round(1000 / pow(10,$rate/10.0))]
222}
223
224# Global variables controlling simulator execution
225# Should simulator be running now?
226set simGoOK 0
227
228proc simStop {} {
229 global simGoOK
230 set simGoOK 0
231}
232
233proc simStep {} {
234 global simStat
235 set simStat [simRun 1]
236}
237
238proc simGo {} {
239 global simGoOK simDelay simStat
240 set simGoOK 1
241 # Disable the Go and Step buttons
242 # Enable the Stop button
243 while {$simGoOK} {
244 # run the simulator 1 cycle
245 after $simDelay
246 set simStat [simRun 1]
247 if {$simStat != "AOK" && $simStat != "BUB"} {set simGoOK 0}
248 update
249 }
250 # Disable the Stop button
251 # Enable the Go and Step buttons
252}
253
254##############################################################################
255# Processor State display #
256##############################################################################
257
258# Overall width of pipe register display
259set procWidth 60
260set procHeight 1
261set labWidth 8
262
263# Add labeled display to window
264proc addDisp {win width name} {
265 global dpyFont labFont
266 set lname [string tolower $name]
267 frame $win.$lname
268 pack $win.$lname -in $win -side left
269 label $win.$lname.t -text $name -font $labFont
270 label $win.$lname.c -width $width -font $dpyFont -bg white -relief ridge
271 pack $win.$lname.t $win.$lname.c -in $win.$lname -side top
272 return [list $win.$lname.c]
273}
274
275# Set text in display row
276proc setDisp {wins txts} {
277 for {set i 0} {$i < [llength $wins] && $i < [llength $txts]} {incr i} {
278 set win [lindex $wins $i]
279 set txt [lindex $txts $i]
280 $win config -text $txt
281 }
282}
283
284frame .p -width $procWidth
285pack .p -in . -side bottom
286label .p.lab -text "Processor State" -height $sectionHeight -font $bigLabFont
287pack .p.lab -in .p -side top
288label .p.mem -text "Memory Stage" -height $procHeight -font $bigLabFont -width $procWidth -bg NavyBlue -fg White
289label .p.ex -text "Execute Stage" -height $procHeight -font $bigLabFont -width $procWidth -bg NavyBlue -fg White
290label .p.id -text "Decode Stage" -height $procHeight -font $bigLabFont -width $procWidth -bg NavyBlue -fg White
291label .p.if -text "Fetch Stage" -height $procHeight -font $bigLabFont -width $procWidth -bg NavyBlue -fg White
292label .p.pcc -text "PC Stage" -height $procHeight -font $bigLabFont -width $procWidth -bg NavyBlue -fg White
293# Mem
294frame .p.m
295# Execute
296frame .p.e
297# Decode
298frame .p.d
299# Fetch
300frame .p.f
301# PC
302frame .p.pc
303# Prev
304frame .p.prev
305pack .p.m .p.mem .p.e .p.ex .p.d .p.id .p.f .p.if .p.pc .p.pcc .p.prev -in .p -side top -anchor w -expand 1
306
307# Take list of lists, and transpose nesting
308# Assumes all lists are of same length
309proc ltranspose {inlist} {
310 set result {}
311 for {set i 0} {$i < [llength [lindex $inlist 0]]} {incr i} {
312 set nlist {}
313 for {set j 0} {$j < [llength $inlist]} {incr j} {
314 set ele [lindex [lindex $inlist $j] $i]
315 set nlist [concat $nlist [list $ele]]
316 }
317 set result [concat $result [list $nlist]]
318 }
319 return $result
320}
321
322# Fields in PREV display
323# Total size = 57
324set pwins(PREV) [ltranspose \
325 [list [addDisp .p.prev 3 pCnd] \
326 [addDisp .p.prev 6 pInstr] \
327 [addDisp .p.prev 16 pValC] \
328 [addDisp .p.prev 16 pValM] \
329 [addDisp .p.prev 16 pValP]]]
330
331
332# Fields in PC display
333# Total size = 16
334set pwins(PC) [ltranspose [list [addDisp .p.pc 16 PC]]]
335
336# Fetch display
337# Total size = 6+4+4+16+16 = 46
338set pwins(F) [ltranspose \
339 [list [addDisp .p.f 6 Instr] \
340 [addDisp .p.f 4 rA]\
341 [addDisp .p.f 4 rB] \
342 [addDisp .p.f 16 valC] \
343 [addDisp .p.f 16 valP]]]
344
345# Decode Display
346# Total size = 16+16+4+4+4+4 = 48
347set pwins(D) [ltranspose \
348 [list [addDisp .p.d 16 valA] \
349 [addDisp .p.d 16 valB] \
350 [addDisp .p.d 4 dstE] \
351 [addDisp .p.d 4 dstM] \
352 [addDisp .p.d 4 srcA] \
353 [addDisp .p.d 4 srcB]]]
354
355# Execute Display
356# Total size = 3+16 = 19
357set pwins(E) [ltranspose \
358 [list [addDisp .p.e 3 Cnd] \
359 [addDisp .p.e 16 valE]]]
360
361# Memory Display
362# Total size = 16
363set pwins(M) [ltranspose \
364 [list [addDisp .p.m 16 valM]]]
365
366# update status line for specified proc register
367proc updateStage {name txts} {
368 set Name [string toupper $name]
369 global pwins
370 set wins [lindex $pwins($Name) 0]
371 setDisp $wins $txts
372}
373
374##########################################################################
375# Instruction Display #
376##########################################################################
377
378toplevel .c
379wm title .c "Program Code"
380frame .c.cntl
381pack .c.cntl -in .c -side top -anchor w
382label .c.filelab -width 10 -text "File"
383entry .c.filename -width 20 -relief sunken -textvariable codeFile \
384 -font $dpyFont -bg white
385button .c.loadbutton -width $cntlBW -command {loadCode $codeFile} -text Load
386pack .c.filelab .c.filename .c.loadbutton -in .c.cntl -side left
387
388proc clearCode {} {
389 simLabel {} {}
390 destroy .c.t
391 destroy .c.tr
392}
393
394proc createCode {} {
395 # Create Code Structure
396 frame .c.t
397 pack .c.t -in .c -side top -anchor w
398 frame .c.tr
399 pack .c.tr -in .c.t -side top -anchor nw
400}
401
402proc loadCode {file} {
403 # Kill old code window
404 clearCode
405 # Create new one
406 createCode
407 simCode $file
408 simResetAll
409}
410
411# Start with initial code window, even though it will be destroyed.
412createCode
413
414# Add a line of code to the display
415proc addCodeLine {line addr op text} {
416 global codeRowCount
417 # Create new line in display
418 global codeFont
419 frame .c.tr.$addr
420 pack .c.tr.$addr -in .c.tr -side top -anchor w
421 label .c.tr.$addr.a -width 6 -text [format "0x%x" $addr] -font $codeFont
422 label .c.tr.$addr.i -width 20 -text $op -font $codeFont
423 label .c.tr.$addr.s -width 2 -text "" -font $codeFont -bg white
424 label .c.tr.$addr.t -text $text -font $codeFont
425 pack .c.tr.$addr.a .c.tr.$addr.i .c.tr.$addr.s \
426 .c.tr.$addr.t -in .c.tr.$addr -side left
427}
428
429# Keep track of which instructions have stage labels
430
431set oldAddr {}
432
433proc simLabel {addrs labs} {
434 global oldAddr
435 set newAddr {}
436 # Clear away any old labels
437 foreach a $oldAddr {
438 .c.tr.$a.s config -text ""
439 }
440 for {set i 0} {$i < [llength $addrs]} {incr i} {
441 set a [lindex $addrs $i]
442 set t [lindex $labs $i]
443 if {[winfo exists .c.tr.$a]} {
444 .c.tr.$a.s config -text $t
445 set newAddr [concat $newAddr $a]
446 }
447 }
448 set oldAddr $newAddr
449}
450
451proc simResetAll {} {
452 global simStat
453 set simStat "AOK"
454 simReset
455 simLabel {} {}
456 clearMem
457}
458
459###############################################################################
460# Memory Display #
461###############################################################################
462toplevel .m
463wm title .m "Memory Contents"
464frame .m.t
465pack .m.t -in .m -side top -anchor w
466
467label .m.t.lab -width 6 -font $dpyFont -text " "
468pack .m.t.lab -in .m.t -side left
469for {set i 0} {$i < 16} {incr i 8} {
470 label .m.t.a$i -width 16 -font $dpyFont -text [format " 0x---%x" [expr $i % 16]]
471 pack .m.t.a$i -in .m.t -side left
472}
473
474
475# Keep track of range of addresses currently displayed
476set minAddr 0
477set memCnt 0
478set haveMem 0
479
480proc createMem {nminAddr nmemCnt} {
481 global minAddr memCnt haveMem codeFont dpyFont normalBg
482 set minAddr $nminAddr
483 set memCnt $nmemCnt
484
485 if { $haveMem } { destroy .m.e }
486
487 # Create Memory Structure
488 frame .m.e
489 set haveMem 1
490 pack .m.e -in .m -side top -anchor w
491 # Now fill it with values
492 for {set i 0} {$i < $memCnt} {incr i 16} {
493 set addr [expr $minAddr + $i]
494
495 frame .m.e.r$i
496 pack .m.e.r$i -side bottom -in .m.e
497 label .m.e.r$i.lab -width 6 -font $dpyFont -text [format "0x%.3x-" [expr $addr / 16]]
498 pack .m.e.r$i.lab -in .m.e.r$i -side left
499
500 for {set j 0} {$j < 16} {incr j 8} {
501 set a [expr $addr + $j]
502 label .m.e.v$a -width 16 -font $dpyFont -relief ridge \
503 -bg $normalBg
504 pack .m.e.v$a -in .m.e.r$i -side left
505 }
506 }
507}
508
509proc setMem {Addr Val} {
510 global minAddr memCnt
511 if {$Addr < $minAddr || $Addr > [expr $minAddr + $memCnt]} {
512 error "Memory address $Addr out of range"
513 }
514 .m.e.v$Addr config -text [format %16x $Val]
515}
516
517proc clearMem {} {
518 destroy .m.e
519 createMem 0 0
520}
521
522
523
524###############################################################################
525# Command Line Initialization #
526###############################################################################
527
528# Get code file name from input
529
530# Find file with specified extension
531proc findFile {tlist ext} {
532 foreach t $tlist {
533 if {[string match "*.$ext" $t]} {return $t}
534 }
535 return ""
536}
537
538
539set codeFile [findFile $argv yo]
540if {$codeFile != ""} { loadCode $codeFile}