105 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			105 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| # modelsim_poll.tcl — robust, logged, per-request protocol
 | |
| 
 | |
| # === CONFIG: set to your absolute shared folder ===
 | |
| set shared_dir "/home/brice/Code/modelsim_wave_ext/test/tmp"
 | |
| 
 | |
| # === Derived paths ===
 | |
| set commands_file [file join $shared_dir "modelsim_commands.txt"]
 | |
| 
 | |
| # Minimal logger
 | |
| proc elog {msg} {
 | |
|     puts "[clock format [clock seconds] -format {%H:%M:%S}] [info nameofexecutable]: $msg"
 | |
| }
 | |
| 
 | |
| # Return lines: "<module> /test/...", one per INSTANCE (not unique by module)
 | |
| proc extract_modules_from_find {} {
 | |
|     set result [find instances -r /*]
 | |
| 
 | |
|     elog $result
 | |
| 
 | |
|     return $result
 | |
| }
 | |
| 
 | |
| proc getTimeAtPercent {percent} {
 | |
|     lassign [wave zoom range] start end
 | |
|     lassign $start sVal sUnit
 | |
|     lassign $end   eVal eUnit
 | |
|     # (Usually sUnit == eUnit; if not, convert eVal to sUnit as needed.)
 | |
|     set t [expr {$sVal + ($eVal - $sVal) * $percent / 100.0}]
 | |
|     return "$t $sUnit"
 | |
| }
 | |
| 
 | |
| proc zoomAtPercent {percent {factor 1.1}} {
 | |
|     set time [getTimeAtPercent $percent]
 | |
|     lassign [wave zoom range] start end
 | |
|     lassign $start sVal sUnit
 | |
|     lassign $end   eVal eUnit
 | |
|     set new [expr {$eVal + 1}]
 | |
|     wave seetime "${new}${eUnit}" -at 0
 | |
|     wave seetime $time -at 50
 | |
|     wave zoom in $factor
 | |
|     lassign [wave zoom range] start end
 | |
|     lassign $start sVal sUnit
 | |
|     lassign $end   eVal eUnit
 | |
|     set new [expr {$eVal + 1}]
 | |
|     wave seetime "${new}${eUnit}" -at 0
 | |
|     wave seetime $time -at $percent
 | |
| }
 | |
| 
 | |
| proc handle_command {payload} {
 | |
|     if {[regexp {^get_module_tree\s+(.+)$} $payload -> top]} {
 | |
|         return [extract_modules_from_find]
 | |
|     } elseif {[regexp {^zoom_in_at\s+(.+)$} $payload -> percent]} {
 | |
|         return [zoomAtPercent $percent]
 | |
|     } elseif {[regexp {^zoom_out_at\s+(.+)$} $payload -> percent]} {
 | |
|         return [zoomAtPercent $percent 0.9]
 | |
|     } else {
 | |
|         if {[catch {eval $payload} out]} { return "ERROR: $out" }
 | |
|         return $out
 | |
|     }
 | |
| }
 | |
| 
 | |
| proc poll_commands {} {
 | |
|     global commands_file
 | |
|     if {[file exists $commands_file]} {
 | |
|         set fid [open $commands_file r]
 | |
|         # Handle both \n and \r\n
 | |
|         set content [string map {\r ""} [read $fid]]
 | |
|         close $fid
 | |
|         file delete -force $commands_file
 | |
| 
 | |
|         foreach raw [split $content "\n"] {
 | |
|             set line [string trim $raw]
 | |
|             if {$line eq ""} { continue }
 | |
| 
 | |
|             # Expect: <id>|<result_path>|<payload>
 | |
|             if {![regexp {^(\S+)\|(\S+)\|(.*)$} $line -> id result_path payload]} {
 | |
|                 elog "WARN: bad command line: $line"
 | |
|                 continue
 | |
|             }
 | |
| 
 | |
|             elog "CMD id=$id -> $payload"
 | |
|             set out [handle_command $payload]
 | |
| 
 | |
|             # Ensure directory exists
 | |
|             set dir [file dirname $result_path]
 | |
|             if {![file isdirectory $dir]} {
 | |
|                 catch { file mkdir $dir }
 | |
|             }
 | |
| 
 | |
|             if {[catch { set rf [open $result_path w] } err]} {
 | |
|                 elog "ERROR: cannot open result file '$result_path': $err"
 | |
|                 continue
 | |
|             }
 | |
|             puts $rf $out
 | |
|             close $rf
 | |
|             elog "WROTE result -> $result_path (len=[string length $out])"
 | |
|         }
 | |
|     }
 | |
|     after 200 poll_commands
 | |
| }
 | |
| 
 | |
| # Start
 | |
| elog "Poller starting. shared_dir=$shared_dir  pwd=[pwd]"
 | |
| poll_commands
 |