My omnium-gatherom of scripts and source code.
at main 540 lines 16 kB view raw
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}