📄 router.tcl
字号:
## 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. ####### router.tcl -- provides support for examining interconnect traffic###### Dan Teodosiu, Sep. 1996####==================================================================# Symbolic displaying of message types# Initialize message name tablefor {set i 0} {$i < 128} {incr i} { set message_name($i) "-" }set message_name(0) "WB"set message_name(2) "NAK_CLEAR_GET"set message_name(3) "UPGRADE_DELAYED"set message_name(4) "INVAL_DELAYED"set message_name(5) "FORWARD_ACK"set message_name(6) "GET"set message_name(7) "GETX"set message_name(8) "UPGRADE_ACK_DELAYED"set message_name(9) "GET_FROM_IO"set message_name(10) "NAK"set message_name(11) "GETX_FROM_IO"set message_name(12) "PUTX_FROM_IO"set message_name(13) "PUT"set message_name(14) "PUT_FROM_IO"set message_name(15) "PUTX_ACKS_DONE"set message_name(16) "SWS_READ"set message_name(17) "ACKS_DONE"set message_name(18) "REPLACE"set message_name(19) "NOP"set message_name(20) "SWB"set message_name(21) "IO_FORWARD_ACK<0>"set message_name(22) "PREF"set message_name(23) "IO_GETX<0>"set message_name(24) "UNC_READ"set message_name(25) "UNC_WRITE"set message_name(26) "IO_NAK<0>"set message_name(27) "IO_GETX_FROM_IO<0>"set message_name(28) "IO_PUTX_FROM_IO<0>"set message_name(29) "UNC_WRITE_NAK"set message_name(30) "UNC_PUT"set message_name(31) "IO_PUTX<0>"set message_name(32) "UNC_ACKS_DONE"set message_name(33) "UNC_WB"set message_name(34) "NAK_CLEAR_OTHER"set message_name(37) "MC_DATA_NAK"set message_name(38) "MC_ACK"set message_name(40) "MC_SEND_GETX_NAK"set message_name(41) "MC_RECV_GETX"set message_name(42) "MC_RECV_GETX_NAK"set message_name(43) "MC_SEND_PUTX"set message_name(44) "MC_RECV_PUTX"set message_name(45) "MC_RH_REQ"set message_name(46) "MC_RH_ACK"set message_name(47) "PUTX"set message_name(48) "MC_RH_NAK"set message_name(50) "MC_INVAL_ACK"set message_name(51) "UNC_READ_FROM_IO"set message_name(52) "MC_DATA_FAST"set message_name(53) "MC_GO_FAST"set message_name(54) "BUSERR"set message_name(55) "FWALL_WRITE_TO_SWQ"set message_name(56) "PIO_WRITE"set message_name(57) "PIO_READ"set message_name(59) "MC_SEND_GETX"set message_name(60) "MC_INVAL"set message_name(61) "BZ_RH_NAK"set message_name(62) "MC_RECV_IO_GETX"set message_name(64) "SWS_WRITE"set message_name(67) "UPGRADE_EAGER"set message_name(68) "INVAL_EAGER"set message_name(70) "RETRACT"set message_name(71) "GETX_EAGER"set message_name(72) "UPGRADE_ACK_EAGER"set message_name(75) "MC_SEND_IO_GETX"set message_name(76) "MC_REQ"set message_name(77) "BZ_RH_REQ"set message_name(78) "BZ_RH_ACK"set message_name(81) "SIPS_REQUEST"set message_name(82) "SIPS_REQUEST_ACK"set message_name(83) "SIPS_REQUEST_NAK"set message_name(84) "SIPS_REPLY_ACK"set message_name(85) "IO_FORWARD_ACK<1>"set message_name(86) "RETRACT_NAK"set message_name(87) "IO_GETX<1>"set message_name(88) "PUT_SEQ"set message_name(89) "PUT_IDENT"set message_name(90) "IO_NAK<1>"set message_name(91) "IO_GETX_FROM_IO<1>"set message_name(92) "IO_PUTX_FROM_IO<1>"set message_name(93) "SIPS_REPLY"set message_name(95) "IO_PUTX<1>"set message_name(103) "FWALL_WRITE_ACK"set message_name(105) "FWALL_WRITE_RETRY"set message_name(106) "LOCK_TOKEN_REQUEST"set message_name(107) "LOCK_TOKEN_GRANT"set message_name(108) "SIPS_REPLY_NAK"set message_name(138) "UNC_NAK"set message_name(149) "IO_FORWARD_ACK<2>"set message_name(151) "IO_GETX<2>"set message_name(154) "IO_NAK<2>"set message_name(155) "IO_GETX_FROM_IO<2>"set message_name(156) "IO_PUTX_FROM_IO<2>"set message_name(159) "IO_PUTX<2>"set message_name(182) "UNC_BUSERR"set message_name(192) "MC_COLLECT_GET"set message_name(193) "MC_COLLECT_IO_GET"set message_name(194) "MC_COLLECT_PUT"set message_name(195) "MC_COLLECT_NAK"set message_name(213) "IO_FORWARD_ACK<3>"set message_name(215) "IO_GETX<3>"set message_name(218) "IO_NAK<3>"set message_name(219) "IO_GETX_FROM_IO<3>"set message_name(220) "IO_PUTX_FROM_IO<3>"set message_name(223) "IO_PUTX<3>"proc messageType {type} { global message_name set n $message_name([expr $type]) if {$n == "-"} { return [hex $type] } else { return $n }}# Initialize vector name tablefor {set i 0} {$i < 256} {incr i} { set vector_name([hex $i]) "-" }set vector_name(0xf0) "MAGIC_RECOVER"set vector_name(0xf1) "MAGIC_REQUEST"set vector_name(0xf2) "MAGIC_REPLY"set vector_name(0x61) "ROUTER_READ_REQ"set vector_name(0x62) "ROUTER_WRITE_REQ"set vector_name(0xe9) "ROUTER_READ_REP"set vector_name(0xea) "ROUTER_WRITE_REP"# ... and many more I didn't care to init here...proc vectorType {type} { global vector_name set n $vector_name([hex $type]) if {$n == "-"} { return [hex $type] } else { return "$n" }}#==================================================================# Message beautification.# printMessage returns a better-looking string containing the message# representation.# Works for both regular messages and vector packets.#proc printMessage {msg} { set src [expr ([lindex $msg 1] >> 21) & 0x7ff] set dest [expr ([lindex $msg 2] >> 14) & 0x1ff] set dir [expr ([lindex $msg 2] >> 10) & 0xf] set cmd [expr ([lindex $msg 3] >> 22) & 0xff] set a [format "0x%06x%08x" [expr [lindex $msg 3] & 0x3fffff] [lindex $msg 4]] if {[lindex $msg 0] == "VP"} { ### Vector packet set t [vectorType $cmd] set d [format "0x%08x%08x" [lindex $msg 6] [lindex $msg 7]] set r [format "0x%08x%08x" [lindex $msg 8] [lindex $msg 9]] return "VP $t s:$src d:$dest p:$dir a:$a r:$r $d" } elseif {[lindex $msg 0] == "PKT"} { ### Regular packet set t [messageType $cmd] set d "" set dlen [llength $msg] for {set i 6} {$i < $dlen} {incr i 2} { set dw [format "0x%08x%08x" [lindex $msg $i] [lindex $msg [expr $i + 1]]] set d "$d$dw " } return "PKT $t s:$src d:$dest p:$dir a:$a $d" } else { ### Whooops return "BAD PACKET\n" }}#==================================================================# Router annotations# These annotations fire whenever a new pkt arrives at a routerannotation type router numfor {set i 0} {$i < $PARAM(CPU.Count)} {incr i} { annotation set router $i { newPacket }}# Note: this contortion necessary because we cannot change router watch# status before SimOS is entered.set simosEntaered 0for {set i 0} {$i < $PARAM(CPU.Count)} {incr i} { set watchRouter($i) 0 }annotation set simos enter { set simosEntaered 1 if {$CPU == 0} { # only do once for {set i 0} {$i < $PARAM(CPU.Count)} {incr i} { if {$watchRouter($i) != 0} { router watch $i on } } }} #==================================================================# New packet has arrived -- what now?# illegible? yeah, but man, sooo efficient...proc newPacket {} { global router_ann_routerNum router_ann_portNum router_ann_lane set pn [expr [router queuelen $router_ann_routerNum $router_ann_portNum $router_ann_lane] - 1] set p [router packet $router_ann_routerNum $router_ann_portNum $router_ann_lane $pn] if [catch {packetAction $router_ann_routerNum $router_ann_portNum $router_ann_lane $pn "$p"} status] { if {[lindex $status 0] != "invalid"} { log "ROUTER: $status\n" } defaultPacketAction $router_ann_routerNum $router_ann_portNum $router_ann_lane $pn "$p" }}proc defaultPacketAction {routerNum portNum lane n pkt} { set prettyPkt [printMessage $pkt] log "+++ new packet r:$routerNum p:$portNum l:$lane pn:$n\n" log " $prettyPkt\n"}#==================================================================# Various utilities for determining interconnect configproc numPorts {rn} { return [llength [router connections $rn]]}proc magicPort {rn} { set cx [router connections $rn] return [lsearch $cx M]}proc connectedRouter {rn pn} { set rp [lindex [router connections $rn] $pn] if {$rp == "M"} { return "M" } else { return [lindex $rp 0] }}proc connectedPort {rn pn} { return [lindex [lindex [router connections $rn] $pn] 1]}#==================================================================# Utilities for setting / clearing router watchproc routerWatch {r on} { global watchRouter simosEntaered set oldwatch $watchRouter($r) if {$on == "on" && $oldwatch == 0} { if {$simosEntaered != 0} { router watch $r on } set watchRouter($r) 1 } elseif {$on == "off" && $oldwatch != 0} { if {$simosEntaered != 0} { router watch $r off } set watchRouter($r) 0 } else { console "bad parameter to routerWatch: $on\n" exit }}proc routerWatchAll {on} { global PARAM for {set i 0} {$i < $PARAM(CPU.Count)} {incr i} { routerWatch $i $on }}#==================================================================console " ROUTER package loaded\n"annotation set simos enter { if {$CPU == 0} { console "\n INTERCONNECT TOPOLOGY:\n" for {set i 0} {$i < $PARAM(CPU.Count)} {incr i} { console " $i " for {set j 0} {$j < [numPorts $i]} {incr j} { set cr [connectedRouter $i $j] set cp [connectedPort $i $j] if {$cr == "M"} { console "$j:M " } elseif {$cr == ""} { console "$j:- " } else { console "$j:($cr.$cp) " } } console "\n" } console "\n" }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -