0% found this document useful (0 votes)
34 views

Launch Emulator

Uploaded by

Srinivasan
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
34 views

Launch Emulator

Uploaded by

Srinivasan
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 30

###############################################################################

# (c) Copyright 2012-2017 Xilinx, Inc. All rights reserved.


#
# This file contains confidential and proprietary information
# of Xilinx, Inc. and is protected under U.S. and
# international copyright and other intellectual property
# laws.
#
# DISCLAIMER
# This disclaimer is not a license and does not grant any
# rights to the materials distributed herewith. Except as
# otherwise provided in a valid license issued to you by
# Xilinx, and to the maximum extent permitted by applicable
# law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
# WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
# AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
# BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
# INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
# (2) Xilinx shall not be liable (whether in contract or tort,
# including negligence, or under any other theory of
# liability) for any loss or damage of any kind or nature
# related to, arising under or in connection with these
# materials, including for any direct, or any indirect,
# special, incidental, or consequential loss or damage
# (including loss of data, profits, goodwill, or any type of
# loss or damage suffered as a result of any action brought
# by a third party) even if such damage or loss was
# reasonably foreseeable or Xilinx had been advised of the
# possibility of the same.
#
# CRITICAL APPLICATIONS
# Xilinx products are not designed or intended to be fail-
# safe, or for use in any application requiring fail-safe
# performance, such as life-support or safety devices or
# systems, Class III medical devices, nuclear facilities,
# applications related to the deployment of airbags, or any
# other applications that could lead to death, personal
# injury, or severe property or environmental damage
# (individually and collectively, "Critical
# Applications"). Customer assumes the sole risk and
# liability of any use of Xilinx products in Critical
# Applications, subject only to applicable laws and
# regulations governing limitations on product liability.
#
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
# PART OF THIS FILE AT ALL TIMES.
###############################################################################
package require inifile
package require json

# Set XILINX_XD if not set


if {![info exists ::env(XILINX_XD)]} {
set VITIS_EMULATOR_SCRIPT [info script]
#set ::env(XILINX_XD) [file normalize [file join [file dirname
$VITIS_EMULATOR_SCRIPT] ..]]
set ::env(XILINX_XD) [file normalize [file join [file dirname
$VITIS_EMULATOR_SCRIPT] .. .. ..]]
} else {
MSG_INFO "Using user-defined path for XILINX_XD environment variable
$::env(XILINX_XD)"
}

if {$::tcl_platform(os) == "Linux"} {
set script_ext "sh"
set xsim_redir ">/dev/null"
} else {
set script_ext "bat"
set xsim_redir ">NUL"
}

source [file join $::env(XILINX_XD) data emulation scripts common_procs.tcl]


######################################################################
# Command line parsing

set qemu_args ""


set pmc_args ""
set qemu_args_cmdline ""
set pmc_args_cmdline ""
set pl_sim_args ""
set target_emu ""
set bootBHFilePath ""
set zynq7000_unixsock_name "abc"
set pl_script ""
set runtime "ocl"
set pl_sim_script ""
set pl_sim_dir ""
set device_family ""
set qimage ""
set qimage_low ""
set qimage_high ""
set sdimage ""
set ospi_img ""
set qemu_args_file ""
set pmc_args_file ""
set pl_sim_args_file ""
set config_file ""
set graphic_xsim ""
set graphic_qemu ""
set target ""
set host ""
set gdb_port ""
set pid_file ""
set timeout ""
set nobuild ""
set norun ""
set killpid ""
set run_sim_in_gdb ""
set print_qemu_version ""
set no_reboot ""
set envdict [dict create]
set plsimdict [dict create]
set pl_sim_dir_specified ""
set interactive ""
set sim_log_path ""
set verbose ""
set log_dir ""
set plKernelDbg "wdb"
set enable_prep_target 0
set enable_tcp_sockets 0
set noc_ddr_shared_mem_specified 0
set pids_to_kill ""
set kill_pid_file ""
set xtlm_aximm_logging 0
set xtlm_axis_logging 0
set machine_path_socket_path 1
set ddr_sharing_size ""
set sharing_size ""
set enable_debug_full 0
set wcfg_file ""
set pkg_temp_dir ""
set platform_name ""
set noc_memory_config_file ""
set qemu_hw_dtb ""
set pmc_hw_dtb ""
set qemu_v4 0
for {set i 0} {$i < $argc} {incr i} {
set arg [lindex $argv $i]

if {[string equal $arg "-pl-sim-dir"]} {


incr i
set pl_sim_dir_specified 1
set pl_sim_dir [lindex $argv $i]
} elseif {[string equal $arg "-device-family"]} {
incr i
set device_family [lindex $argv $i]
} elseif {[string equal $arg "-t"]} {
incr i
set target_emu [lindex $argv $i]
} elseif {[string equal $arg "-target"]} {
incr i
set target_emu [lindex $argv $i]
} elseif {[string equal $arg "-pl-sim-script"]} {
incr i
set pl_sim_script [lindex $argv $i]
} elseif {[string equal $arg "-image"]} {
incr i
set qimage [lindex $argv $i]
} elseif {[string equal $arg "-qspi-image"]} {
incr i
set qimage [lindex $argv $i]
} elseif {[string equal $arg "-qspi-low-image"]} {
incr i
set qimage_low [lindex $argv $i]
} elseif {[string equal $arg "-qspi-high-image"]} {
incr i
set qimage_high [lindex $argv $i]
} elseif {[string equal $arg "-ospi-image"]} {
incr i
set ospi_img [lindex $argv $i]
} elseif {[string equal $arg "-sd-card-image"]} {
incr i
set sdimage [lindex $argv $i]
} elseif {[string equal $arg "-qemu-args-file"]} {
incr i
set qemu_args_file [lindex $argv $i]
} elseif {[string equal $arg "-pmc-args-file"]} {
incr i
set pmc_args_file [lindex $argv $i]
} elseif {[string equal $arg "-pl-sim-args-file"]} {
incr i
set pl_sim_args_file [lindex $argv $i]
} elseif {[string equal $arg "-qemu-args"]} {
incr i
append qemu_args_cmdline [lindex $argv $i]
} elseif {[string equal $arg "-pl-sim-args"]} {
incr i
#append pl_sim_args [lindex $argv $i]
set pl_sim_args_name [lindex $argv $i]
set sim_option ""
if {[string first "=" $pl_sim_args_name] != -1} {
set name_value [split $pl_sim_args_name "="]
if { [llength $name_value] == 2 } {
set name [lindex $name_value 0 ]
set value [lindex $name_value 1 ]
set sim_option $name
dict set plsimdict $name $value
puts "INFO: \[LAUNCH_EMULATOR\] Setting simulator option $name to $value"
} else {
puts "WARNING: \[LAUNCH_EMULATOR\] multiple \"=\" found in pl-sim-args
option.( Ignoring $pl_sim_args_name )"
}
} else {
append pl_sim_args " $sim_option"
puts "INFO: \[LAUNCH_EMULATOR\] Setting simulator option $sim_option.Please
ensure it is a valid option"
#puts "WARNING: \[LAUNCH_EMULATOR\] \"=\" not found in add_env option.
( Ignoring $env_name_value )"
}
} elseif {[string equal $arg "-pmc-args"]} {
incr i
append pmc_args_cmdline [lindex $argv $i]
} elseif {[string equal $arg "-config-file"]} {
incr i
set config_file [lindex $argv $i]
} elseif {[string equal $arg "-user-pre-sim-script"]} {
incr i
set envName "USER_PRE_SIM_SCRIPT"
set envVal [lindex $argv $i]
dict set envdict $envName $envVal
} elseif {[string equal $arg "-user-post-sim-script"]} {
incr i
set envName "USER_POST_SIM_SCRIPT"
set envVal [lindex $argv $i]
dict set envdict $envName $envVal
} elseif {[string equal $arg "-xtlm-aximm-log"]} {
set xtlm_aximm_logging 1
} elseif {[string equal $arg "-xtlm-axis-log"]} {
set xtlm_axis_logging 1
} elseif {[string equal $arg "-vivado"]} {
incr i
set vivado_loc [lindex $argv $i]
set ::env(VIVADO_LOC) $vivado_loc
} elseif {[string equal $arg "-add-env"]} {
incr i
set env_name_value [lindex $argv $i]
if {[string first "=" $env_name_value] != -1} {
set name_value [split $env_name_value "="]
if { [llength $name_value] == 2 } {
set name [lindex $name_value 0 ]
set value [lindex $name_value 1 ]
dict set envdict $name $value
} else {
puts "WARNING: \[LAUNCH_EMULATOR\] multiple \"=\" found in add_env option.(
Ignoring $env_name_value )"
}
} else {
puts "WARNING: \[LAUNCH_EMULATOR\] \"=\" not found in add_env option.
( Ignoring $env_name_value )"
}
} elseif { [string equal $arg "-emu-data"] } {
incr i
set envName "AIE_SHIM_SOL_PATH"
set envVal [lindex $argv $i]
dict set envdict $envName $envVal
} elseif { [string equal $arg "-boot-bh"] } {
incr i
set bootBHFilePath [lindex $argv $i]
} elseif { [string equal $arg "-aie-shim-sol-path"] } {
incr i
set envName "AIE_SHIM_SOL_PATH"
set envVal [lindex $argv $i]
dict set envdict $envName $envVal
} elseif { [string equal $arg "-aie-sim-options"] } {
incr i
set envName "AIESIM_OPTIONS"
set envVal [lindex $argv $i]
dict set envdict $envName $envVal
} elseif { [string equal $arg "-aie-sim-config"] } {
incr i
set envName "AIESIM_CONFIG"
set envVal [lindex $argv $i]
dict set envdict $envName $envVal
} elseif { [string equal $arg "-noc-ddr-shared-mem"] } {
puts "WARNING : \[LAUNCH_EMULATOR\] -noc-ddr-shared-mem switch is deprecated .
Ignoring DDR Memory Sharing. NOT setting NOCSIM_DRAM_FILE."
#set noc_ddr_shared_mem_specified 1
incr i
#set envName "NOCSIM_DRAM_FILE"
#set envVal [lindex $argv $i]
#dict set envdict $envName $envVal
} elseif { [string equal $arg "-aie-device-file-path"] } {
incr i
set envName "JSON_DEVICE_FILE_PATH"
set envVal [lindex $argv $i]
dict set envdict $envName $envVal
} elseif { [string equal $arg "-xtlm-log-state"] } {
incr i
set envName "XTLM_LOG_STATE"
set envVal [lindex $argv $i]
dict set envdict $envName $envVal
} elseif {[string equal $arg "-graphic-xsim"]} {
set graphic_xsim 1
} elseif {[string equal $arg "-g"]} {
set graphic_xsim 1
} elseif {[string equal $arg "-graphic-qemu"]} {
set graphic_qemu 1
} elseif {[string equal $arg "-forward-port"]} {
incr i
set target [lindex $argv $i]
incr i
set host [lindex $argv $i]
} elseif {[string equal $arg "-runtime"]} {
incr i
set runtime [lindex $argv $i]
} elseif {[string equal $arg "-gdb-port"]} {
incr i
set gdb_port [lindex $argv $i]
} elseif {[string equal $arg "-pid-file"]} {
incr i
set pid_file [lindex $argv $i]
} elseif {[string equal $arg "-no-reboot"]} {
set no_reboot 1
} elseif {[string equal $arg "-timeout"]} {
incr i
set timeout [lindex $argv $i]
} elseif {[string equal $arg "-kill"]} {
incr i
set killpid [lindex $argv $i]
} elseif {[string equal $arg "-help"] || [string equal $arg "--help"]} {
usage
exit 0
} elseif {[string equal $arg "-nobuild"]} {
set nobuild 1
} elseif {[string equal $arg "-norun"]} {
set norun 1
} elseif {[string equal $arg "-run-sim-in-gdb"]} {
set run_sim_in_gdb 1
} elseif {[string equal $arg "-interactive"]} {
set interactive 1
} elseif {[string equal $arg "-verbose"]} {
set verbose 1
} elseif {[string equal $arg "-enable-debug"]} {
set interactive 1
} elseif {[string equal $arg "-sim-gui"]} {
set graphic_xsim 1
} elseif {[string equal $arg "-print-qemu-version"]} {
set print_qemu_version 1
} elseif {[string equal $arg "-ps-only"]} {
set target_emu "sw_emu"
} elseif {[string equal $arg "-pl-kernel-dbg"]} {
incr i
set plKernelDbg [lindex $argv $i]
} elseif { [string equal $arg "-kill-pid-file"] } {
incr i
set kill_pid_file [lindex $argv $i]
} elseif {[string equal $arg "-enable-prep-target"]} {
set enable_prep_target 1
} elseif {[string equal $arg "-enable-tcp-sockets"]} {
set enable_tcp_sockets 1
} elseif {[string equal $arg "-no-pl"]} {
set target_emu "sw_emu"
} elseif {[string equal $arg "-m"]} {
incr i
set ddr_sharing_size [lindex $argv $i]
} elseif {[string equal $arg "-machine-path-socket-path"]} {
set machine_path_socket_path 1
} elseif {[string equal $arg "-enable-debug-full"]} {
set enable_debug_full 1
set interactive 1
} elseif {[string equal $arg "-wcfg-file-path"]} {
incr i
set wcfg_file [lindex $argv $i]
} elseif {[string equal $arg "-platform-name"]} {
incr i
set platform_name [lindex $argv $i]
} elseif {[string equal $arg "-use-qemu-version-v4"]} {
set qemu_v4 1
} elseif {[string equal $arg "-noc-memory-config"]} {
incr i
set noc_memory_config_file [lindex $argv $i]
} elseif {[string equal $arg "-qemu-dtb"]} {
incr i
set qemu_hw_dtb [lindex $argv $i]
} elseif {[string equal $arg "-pmc-dtb"]} {
incr i
set pmc_hw_dtb [lindex $argv $i]
} else {
puts "CRITICAL_WARNING: \[LAUNCH_EMULATOR\] Unknown option $arg. Ignoring it"
}
}

puts "CRITICAL_WARNING: \[LAUNCH_EMULATOR\] DEPRECATED !! Using the old flow which


uses launch_emulator.tcl. Please use v++ -p to generate the script to launch new
launch_emulator.py "

if {$graphic_xsim == 1 && $interactive == 1} {


puts "INFO : \[LAUNCH_EMULATOR\] Both Graphic simulator and XTERM modes are
enabled.Giving preference to Graphic simulator."
set interactive 0
}

if {[info exists ::env(USER_PRE_SIM_SCRIPT)] && $wcfg_file ne ""} {


puts "WARNING : \[LAUNCH_EMULATOR\] Both -user-pre-sim-script and -wcfg-file-path
are provided. Either one of the option is accepted. Giving predence for -wcfg-file-
path"
}

if {$wcfg_file ne ""} {
if {[file exists $wcfg_file]} {
set wcfg_cmd_str "open_wave_config $wcfg_file"

set pre_sim_script "pre_sim_script.tcl"


set out [open $pre_sim_script w]
puts $out "$wcfg_cmd_str"
close $out

set pre_sim_script_file_path [file join [pwd] $pre_sim_script]

set envName "USER_PRE_SIM_SCRIPT"


set envVal $pre_sim_script_file_path
dict set envdict $envName $envVal
} else {
puts "WARNING : Invalid WCFG file path provided. Please provide the valid WCFG
file to get the Custom Signals viewed in the waveform"
}
}

if {$noc_ddr_shared_mem_specified && [file exists $noc_memory_config_file ]} {


puts "ERROR : -noc-ddr-shared-mem and -noc-memory-config switch cannot be used at
the same time. Cannot set two inter-related ENV Varibles “NOCSIM_DRAM_FILE” and
“NOCSIM_MULTI_DRAM_FILE” at the same time ."
}

set envName "ENABLE_XTLM_AXIMM_LOG"


dict set envdict $envName $xtlm_aximm_logging

set envName "ENABLE_XTLM_AXIS_LOG"


dict set envdict $envName $xtlm_axis_logging

foreach { key value } $plsimdict {


append pl_sim_args " $key"
append pl_sim_args " \"$value\""
}

if {$::tcl_platform(os) != "Linux"} {
# only for linux, unix sockets, windows uses tcp sockets
set machine_path_socket_path 1
set enable_tcp_sockets 1
}

# ##################### kill the process if pid is given ###########


# if kill is called, the first thing you want to do is kill the process and
underlying subprocesses.
# Info like deviceFamily is not needed and need not be intialised
# dont move this piece of code down or to helper files
if {[info exists killpid] && $killpid != ""} {
puts "INFO: \[LAUNCH_EMULATOR\] Killing process $killpid"
kill_group $killpid $verbose
exit 0
}

# ##################### kill the process if pid file is given ###########


# if kill is called, the first thing you want to do is kill the process and
underlying subprocesses.
# Info like deviceFamily is not needed and need not be intialised
# dont move to helper files
if {[info exists kill_pid_file] && $kill_pid_file != ""} {
if { ![isAbsolute $kill_pid_file] } {
set kill_pid_file [file join [pwd] $kill_pid_file]
}

if {![file exists $kill_pid_file]} {


puts "ERROR: \[LAUNCH_EMULATOR\] $kill_pid_file file doesnt exist."
exit 1;
}

puts "INFO: \[LAUNCH_EMULATOR\] Killing process in file $kill_pid_file"


set fp [open $kill_pid_file r]
set data [join [split [read $fp] "\n"]]
foreach line $data {
kill_group $line $verbose
if {![pid_exists $line]} {
puts "Successfully killed launch_emulator process"
}
}

close $fp
exit 0
}
# ##################### set device family ###########
set cpu_type ""
if {$enable_prep_target == 1} {
set cpu_type [setCpuType $device_family]
} else {
if {![info exists device_family] || $device_family == ""} {

########### needed to determine cpu_type ############################


set vimage_packages [file join $::env(XILINX_XD) scripts vimage]
lappend auto_path $vimage_packages
package require vimage::utils

set xml_file [file join [pwd] _vimage emulation emulation.xml]


if {[file exists $xml_file]} {
puts "WARNING : \[LAUNCH_EMULATOR\] Device Family option is not
provided.Setting -device-family from cpu_type mentioned in emulation.xml.It is
suggested to explicitly mention the Device Family using -device-family option.
Valid Device Families are 7series / Ultrascale / Versal"

set xpath "xd:emulation/xd:target/@xd:cpuType"


set cpu_type [::vimage::utils::xpath_get_value $xml_file $xpath]
if {$cpu_type != "cortex-a9" && $cpu_type != "cortex-a53" && $cpu_type !=
"x86"} {
puts "ERROR : \[LAUNCH_EMULATOR\] Un-identified cpu_type mentioned in
emulation.xml. Please provide a valid cpu_type.Valid values are cortex-a9 / cortex-
a53 / x86"
exit 1;
}
} else {
puts "ERROR : \[LAUNCH_EMULATOR\] Device Family option is not
provided.Emulation.xml also doesn't exist.Please provide a valid Device Family like
7series / Ultrascale / Versal"
exit 1;
}
#####################################################################

#exit 1
} else {
set cpu_type [setCpuType $device_family]
}
}

if {$device_family != "versal" && $ddr_sharing_size != ""} {


puts "INFO : \[LAUNCH_EMULATOR\] DDR Memory Sharing option -m is only allowed for
VERSAL."
set ddr_sharing_size ""
}

if {$ddr_sharing_size != ""} {
puts "WARNING : \[LAUNCH_EMULATOR\] DDR Memory Sharing option -m is deprecated.
Ignoring -m option used."
set ddr_sharing_size ""
}

if {[file exists $noc_memory_config_file ]} {


set envName "NOCSIM_MULTI_DRAM_FILE"
set ::env($envName) $noc_memory_config_file
} elseif {$cpu_type == "x86" && $noc_ddr_shared_mem_specified != 1} {
# setting NOC DDR file name automatically (CR 1016562)
set envName "NOCSIM_DRAM_FILE"
set envVal "qemu-memory-_ddr@0x00000000"
set ::env($envName) $envVal
}

# #################### pre processing#######################


set pmc_port ""
set pl_port ""

source [file join $::env(XILINX_XD) data emulation scripts pre_processing.tcl]

#pre_process_options pl_sim_dir device_family target_emu pl_sim_script qimage


sdimage qemu_args_file pmc_args_file pl_sim_args_file qemu_args_cmdline pl_sim_args
pmc_args_cmdline config_file envdict graphic_xsim graphic_qemu target host runtime
gdb_port pid_file no_reboot timeout nobuild norun run_sim_in_gdb print_qemu_version
target_emu
pre_process_options $verbose $pl_sim_dir $device_family $cpu_type $target_emu
$pl_sim_script $qimage $qimage_low $qimage_high $sdimage $ospi_img $qemu_args_file
$pmc_args_file $pl_sim_args_file $qemu_args_cmdline $pl_sim_args $pmc_args_cmdline
$config_file $envdict $graphic_xsim $graphic_qemu $target $host $runtime $gdb_port
$pid_file $no_reboot $timeout $nobuild $norun $run_sim_in_gdb $print_qemu_version

set sim_name [get_simulator_name $pl_sim_dir]

# for versal, noc ddr sharing more than 2 GB, create noc shared files txt.CR-
1064064
#if {$device_family == "versal"} {
# if {[info exists ddr_sharing_size] && $ddr_sharing_size != ""} {
# set sharing_size_arr [split $ddr_sharing_size "G"]
# set sharing_size [lindex $sharing_size_arr 0]
# if {$sharing_size <= 2} {
# puts "\[LAUNCH_EMULATOR\] INFO:Sharing less than or equal to 2G DDR Memory.
Using default NOCSIM_DRAM_FILE"
# }
# if {$sharing_size > 34} {
# puts "\[LAUNCH_EMULATOR\] INFO:Only 34G DDR Memory can be shared using NOC
SIM CONFIG files. Setting shared value to 34G though $sharing_size G is mentioned."
# set sharing_size 34
# }
# if {$sharing_size > 2 && $target_emu == "hw_emu"} {
# create_ddr_memory_files $pl_sim_dir $sharing_size
# }
# }
#}

set socket_file [get_socket_file $pl_sim_dir $cpu_type $runtime $::tcl_platform(os)


$machine_path_socket_path]

######################################################################
# QEMU script and arguments
# create start_qemu.sh
set qemu_cmd [get_qemu_cmd $cpu_type $::tcl_platform(os) $verbose $qemu_v4]
set pmc_cmd [get_pmc_cmd $cpu_type $::tcl_platform(os) $verbose $qemu_v4]

set emDir [file normalize [file join [pwd] emu_qemu_scripts]]


catch {file mkdir ${emDir}}

if {[info exists print_qemu_version] && $print_qemu_version != ""} {


puts "qemu version : [exec $qemu_cmd "--version" ]"
}

set qemu_script [get_qemu_script $cpu_type $script_ext $verbose


$enable_prep_target]
set pmc_script [get_pmc_script $cpu_type $script_ext $verbose $enable_prep_target]

# ########### read qemu args file ##############


if {![file exists $qemu_args_file]} {
puts "Could not find QEMU arguments file $qemu_args_file, ignoring"
} else {
if {$cpu_type == "cortex-a53" && [info exists target] && $target != ""} {
set fp [open $qemu_args_file r]
set file_data [read $fp]
set data [split $file_data "\n"]
#set data [join [split [read $fp] "\n"]]
set net_count 0
foreach line $data {
if {[string equal -length 1 $line "#"]} {
# it is a comment, if it starts with #, dont append the line to qemu_args.
continue
}
if {[string equal -length 1 $line "-"]} {
if {[string equal $line "-net"]} {
incr net_count 1
if { $net_count < 4 } {
append qemu_args " $line"
}
} else {
append qemu_args " $line"
}
if {[string equal $line "-hw-dtb"]} {
set qemuargs_hwdtb 1
}
} else {
if {$::tcl_platform(os) != "Linux" && $line == "/dev/null"} {
set line "null"
}
if { $net_count > 3 && ( $line == "nic" || $line == "user" ) } {
puts ""
} else {
append qemu_args " \"$line\""
}
}
}
close $fp
} else {
set fp [open $qemu_args_file r]
set file_data [read $fp]
set data [split $file_data "\n"]
foreach line $data {
if {[string equal -length 1 $line "#"]} {
# it is a comment, if it starts with #, dont append the line to qemu_args.
continue
}
if {[string equal -length 1 $line "-"]} {
append qemu_args " $line"
if {[string equal $line "-hw-dtb"]} {
set qemuargs_hwdtb 1
}
} else {
if {$::tcl_platform(os) != "Linux" && $line == "/dev/null"} {
set line "null"
}
append qemu_args " \"$line\""
}
}
close $fp
}
}
append qemu_args " $qemu_args_cmdline "

# ####################################################

set qemu_dtb [get_qemu_dtb $cpu_type $target_emu $verbose $qemu_v4]

if {$qemu_hw_dtb != "" && ![info exists qemuargs_hwdtb] } {


append qemu_args " -hw-dtb $qemu_hw_dtb "
}

if {![info exists qemuargs_hwdtb] && $qemu_hw_dtb == ""} {


append qemu_args " -hw-dtb $qemu_dtb "
}
set qemu_args [append_sd_card_img_to_qemu_args $cpu_type $sdimage $qemu_args
$qimage $ospi_img $qimage_low $qimage_high $target_emu]

if {[info exists target] && $target != "" && [info exists host] && $host != ""} {
append qemu_args " -net \"nic,netdev=net0\" -netdev \"user,id=net0,hostfwd=tcp::$
{target}-:${host}\""
#append qemu_args " -redir \"tcp:${target}::${host}\""
}

if {[info exists gdb_port] && $gdb_port != ""} {


append qemu_args " -gdb \"tcp:127.0.0.1:${gdb_port}\""
append qemu_args " -S"
}

if {[info exists no_reboot] && $no_reboot != ""} {


append qemu_args " -no-reboot"
}

# only for versal append ddr mem sharing


if {$device_family == "versal"} {
if {[info exists ddr_sharing_size] && $ddr_sharing_size != ""} {

set sharing_size_arr [split $ddr_sharing_size "G"]


set sharing_size [lindex $sharing_size_arr 0]

if {$sharing_size > 2} { #TODO: Need to check if this is still valid to set


when > 2G
append qemu_args " -m \"$ddr_sharing_size\""
}
}
}

if {![info exists graphic_qemu] || $graphic_qemu == ""} {


append qemu_args " -display \"none\""
}

set qemu_args [set_machine_path $cpu_type $qemu_args $target_emu]

#append qemu_args " -sync-quantum \"4000000\""

#to remove warning regarding audio driver


set ::env(QEMU_AUDIO_DRV) "none"

set qemu_args [set_socket_connection $cpu_type $qemu_args $target_emu $verbose


$enable_tcp_sockets $machine_path_socket_path]

#write_to_file $pl_sim_dir $qemu_script $::tcl_platform(os) $qemu_cmd $qemu_args


set fp [open $qemu_script w]
if {$::tcl_platform(os) == "Linux"} {
puts $fp "#!/bin/bash"
puts $fp "cd $pl_sim_dir"
puts $fp "\$QEMU_GDB_COMMAND $qemu_cmd $qemu_args"
} else {
puts $fp "@echo off"
puts $fp "cd $pl_sim_dir"
puts $fp "\%QEMU_GDB_COMMAND\% $qemu_cmd $qemu_args"
puts $fp "@echo on"
}
close $fp
exec chmod u+x $qemu_script

######################################################################
######################################################################
# PMC script and arguments
# create start_pmu.sh

if {$cpu_type == "cortex-a9"} {
# There is no microblaze in zynq 7000. No need to generate start_pmu.sh
} else {
set pmcargs_microblaze_set 0
if {$cpu_type == "cortex-a53"} {
# zynq mp
set pmc_dtb ""
if {[info exists ::env(QEMU_DTB_PATH)] } {
set pmc_dtb [file join $::env(QEMU_DTB_PATH) zynqmp-pmu.dtb]
} else {
if {$qemu_v4 != 1} {
if {$::tcl_platform(os) == "Linux"} {
set pmc_dtb [file join $::env(XILINX_XD) data emulation dtbs zynqmp
zynqmp-pmu.dtb]
} else {
set pmc_dtb [file join $::env(XILINX_XD) data emulation dtbs zynqmp
dtb_qemu_win zynqmp-pmu.dtb]
}
} else {
set pmc_dtb [file join $::env(XILINX_XD) data emulation dtbs zynqmp
dtb_qemuv4_2 zynqmp-pmu.dtb]
}
}
puts "pmc_dtb $pmc_dtb"
append pmc_args " -hw-dtb $pmc_dtb "
set pmc_rom [file join $::env(XILINX_XD) data emulation dtbs zynqmp
pmu_rom_qemu_sha3.elf]
append pmc_args " -kernel $pmc_rom "
if {$enable_tcp_sockets} {
append pmc_args " -chardev \"socket,id=pmu-apu-
rp,host=127.0.0.1,port=$pmc_port\""
} else {
if {$machine_path_socket_path eq 1} {
append pmc_args " -chardev \"socket,path=./qemu-rport-_pmu@0,id=pmu-apu-
rp\""
} else {
append pmc_args " -chardev \"socket,path=/tmp/$::env(VIMAGE_PID)/qemu-
rport-_pmu@0,id=pmu-apu-rp\""
}
}
} else {
# VERSAL
set pmc_dtb ""
if {[info exists ::env(QEMU_DTB_PATH)] } {
set pmc_dtb [file join $::env(QEMU_DTB_PATH) board-versal-pmc-virt.dtb]
} else {
if {$qemu_v4 != 1} {
if {$pmc_hw_dtb != ""} {
set pmc_dtb $pmc_hw_dtb
} else {
set pmc_dtb [file join $::env(XILINX_XD) data emulation dtbs versal
$target_emu board-versal-pmc-virt.dtb]
}
} else {
set pmc_dtb [file join $::env(XILINX_XD) data emulation dtbs versal
dtb_qemuv4_2 board-versal-pmc-virt.dtb]
}
}

append pmc_args " -machine-path \".\""


if {$enable_tcp_sockets} {
append pmc_args " -chardev \"socket,id=ps-pmc-
rp,host=127.0.0.1,port=$pmc_port\""
} else {
if {$machine_path_socket_path eq 1} {
append pmc_args " -chardev \"socket,path=./qemu-rport-_pmc@0,id=ps-pmc-
rp\""
} else {
append pmc_args " -chardev \"socket,path=/tmp/$::env(VIMAGE_PID)/qemu-
rport-_pmc@0,id=ps-pmc-rp\""
}
}
}

if {![file exists $pmc_args_file]} {


puts "Could not find pmc arguments file, ignoring"
} else {
set fp [open $pmc_args_file r]
set file_data [read $fp]
set data [split $file_data "\n"]
foreach line $data {
if {[string equal -length 1 $line "#"]} {
# it is a comment, if it starts with #, dont append the line to
pmc/pmu_args
continue
}
if {[string equal -length 1 $line "-"]} {
if { $pmcargs_microblaze_set eq 1 && $bootBHFilePath ne ""} {
# append pmc_args " -
device \"loader,file=$bootBHFilePath,addr=0xf201e000,force-raw\" "
set pmcargs_microblaze_set 0
}
append pmc_args " $line"
if {[string equal $line "-M"]} {
set pmcargs_microblaze_set 1
}
if {[string equal $line "-hw-dtb"]} {
set pmcargs_hwdtb 1
}
} else {
if {$::tcl_platform(os) != "Linux" && $line == "/dev/null"} {
set line "null"
}
append pmc_args " \"$line\""
}
}
}

if {![info exists pmcargs_hwdtb]} {


append pmc_args " -hw-dtb \"$pmc_dtb\" "
}

append pmc_args " $pmc_args_cmdline "


close $fp

set fp [open $pmc_script w]


if {$::tcl_platform(os) == "Linux"} {
puts $fp "#!/bin/bash"
puts $fp "cd $pl_sim_dir"
puts $fp "\$QEMU_GDB_COMMAND $pmc_cmd $pmc_args"
} else {
puts $fp "@echo off"
puts $fp "cd $pl_sim_dir"
puts $fp "\%QEMU_GDB_COMMAND\% $pmc_cmd $pmc_args"
puts $fp "@echo on"
}
close $fp
exec chmod u+x $pmc_script
}
######################################################################
######################################################################
# XSIM script and arguments
# create a script to run PL simulation.
if { ![info exists pl_sim_script] || $pl_sim_script == ""} {
if { [info exists pl_sim_args_file ] && $pl_sim_args_file != ""} {
set fp [open $pl_sim_args_file r]
set data [join [split [read $fp] "\n"]]
foreach line $data {
if {[string equal -length 1 $line "-"]} {
append pl_sim_args " $line"
} else {
if {$::tcl_platform(os) != "Linux" && $line == "/dev/null"} {
set line "null"
}
append pl_sim_args " \"$line\""
}
}
close $fp
}

set xsim_script ""


set protoinst_file ""
set wcfg_file ""

if {$cpu_type == "cortex-a9" || $cpu_type == "cortex-a53"} {


if {$enable_prep_target == 1} {
set xsim_script [file join $pl_sim_dir simulate.$script_ext]
set sim_log_path [file join $pl_sim_dir simulate.log]
set protoinst_file [file join $pl_sim_dir dr_behav.protoinst]
set wcfg_file [file join $pl_sim_dir dr_behav.wcfg]
} else {
if {$runtime == "c++"} {
# v++ takes care of creating start_simulation.sh in _vimage/emulation
folder
set sim_file [file join $pl_sim_dir start_simulation.$script_ext]
set in [open $sim_file r]
while {[gets $fh line] != -1} {
set first [lindex [split [string trimleft $line]] 0]
if {$first == "cd"} {
set sim_log_dir [lindex [split [string trimleft $line]] 1]
set sim_log_path [file join $sim_log_dir simulate.log]
#puts "----sim_log_dir1 $sim_log_dir"
#puts "----sim_log_path1 $sim_log_path"
break
}
}
close $in
} else {
set sim_log_dir [create_start_simulation_script $pl_sim_dir_specified
$pl_sim_script $pl_sim_dir $graphic_xsim $plKernelDbg]
set sim_log_path [file join $sim_log_dir simulate.log]
#puts "----sim_log_dir $sim_log_dir"
#puts "----sim_log_path $sim_log_path"
}
set xsim_script [file join $pl_sim_dir start_simulation.$script_ext]
}
} else {
set xsim_script [file join $pl_sim_dir simulate.$script_ext]
set sim_log_path [file join $pl_sim_dir simulate.log]
#puts "----sim_log_path2 $sim_log_path"
}

if {$target_emu == "sw_emu"} {
# no need of xsim_script for sw_emu as there is no PL to simulate.It is PS only
deisgn.
} else {
if {![file exists $xsim_script]} {
puts "ERROR: \[LAUNCH_EMULATOR\] Missing expected simulation script:
$xsim_script"
exit 1
}
}

if {[info exists run_sim_in_gdb] && $run_sim_in_gdb != ""} {


if { [writeNewSimulateScript $pl_sim_dir] } {
puts "INFO: \[LAUNCH_EMULATOR\] launching simulator in gdb"
set xsim_script [file join $pl_sim_dir simulate_gdb.$script_ext]
set sim_log_path [file join $pl_sim_dir simulate.log]
#puts "----sim_log_path3 $sim_log_path"
set xsim_redir ""
}
}

if {[info exists graphic_xsim] && $graphic_xsim != ""} {


createRun1nsTclScript $pl_sim_dir
if {$sim_name == "xsim"} {
append pl_sim_args " -g"
if {$protoinst_file != ""} {
append pl_sim_args " --protoinst $protoinst_file"
}
if {$wcfg_file != ""} {
set ::env(VITIS_WAVEFORM) $wcfg_file
}
} elseif {$sim_name == "questa"} {
writeNewSimulateScriptForQuesta $pl_sim_dir 1
} elseif {$sim_name == "xcelium"} {
writeNewSimulateScriptForXcelium $pl_sim_dir 1
} else {
writeNewSimulateScriptForVCS $pl_sim_dir 1
}
if { [info exists ::env(VITIS_LAUNCH_WAVEFORM_BATCH) ] } {
unset ::env(VITIS_LAUNCH_WAVEFORM_BATCH)
}
set ::env(VITIS_LAUNCH_WAVEFORM_GUI) 1
} else {
if {$sim_name == "xsim"} {
append pl_sim_args " -R"
if {$wcfg_file != ""} {
set ::env(VITIS_WAVEFORM) $wcfg_file
}
if {$protoinst_file != ""} {
append pl_sim_args " --protoinst $protoinst_file"
}
} else {
}
if { [info exists ::env(VITIS_LAUNCH_WAVEFORM_GUI) ] } {
unset ::env(VITIS_LAUNCH_WAVEFORM_GUI)
}
set ::env(VITIS_LAUNCH_WAVEFORM_BATCH) 1
}
} else {
# Vivado user
#set xsim_script $pl_sim_script
set sim_log_dir [create_start_simulation_script $pl_sim_dir_specified
$pl_sim_script $pl_sim_dir $graphic_xsim]
set sim_log_path [file join $sim_log_dir simulate.log]
#puts "----sim_log_dir2 $sim_log_dir"
#puts "----sim_log_path4 $sim_log_path"
set xsim_script [file join $pl_sim_dir start_simulation.$script_ext]
}

##resize of sd_card.img to nearest power of 2###


##With the recent QEMU upgrade, sd_card size should be power of 2###
##resizing the sd_card using qemu_img utility and this is used by the###
##non-acceleration test cases (SDK flow) ###

######################################################################
######################################################################
# SD card image ######################################################

set sd_card_img_path ""

if {$cpu_type == "cortex-a9" || $cpu_type == "cortex-a53"} {


#puts "pwd [pwd]"
if {![info exists nobuild] || $nobuild == ""} {
if {![info exists sdimage] || $sdimage == ""} {
set save_dir [pwd]
cd [file join [pwd] _vimage emulation]
if {[file exists sd_card]} {
delete_directory sd_card
}
if {[file exists sd_card.img]} {
delete_file sd_card.img
}
catch {file mkdir sd_card}
# Copy files specified in manifest
set fp [open sd_card.manifest r]
set data [join [split [read $fp] "\n"]]
foreach line $data {
catch {file copy -force $line sd_card}
}
#if OCL flow copy the driver to the sd_card
if {$runtime == "ocl"} {
catch {file mkdir [file join "sd_card" "data" ]}
catch {file mkdir [file join "sd_card" "data" "emulation" ]}
file copy -force [file join $env(XILINX_VITIS) "data" "emulation" "unified"
] [file join "sd_card" "data" "emulation" "unified" ]
}
close $fp
set sd_card_size 500000
set sd_card_img_path [file join [pwd] sd_card.img]
exec mkfatimg [file join [pwd] sd_card] [file join [pwd] sd_card.img]
$sd_card_size > mkfatimg.log
cd $save_dir
} else {
if {[info exists sdimage] && [file isdirectory $sdimage]} {
set save_dir [pwd]
cd $sdimage
if {[file exists sd_card]} {
delete_directory sd_card
}
if {[file exists sd_card.img]} {
delete_file sd_card.img
}
catch {file mkdir sd_card}

# Copy files specified in manifest


set fp [open sd_card.manifest r]
set data [join [split [read $fp] "\n"]]
foreach line $data {
file copy -force $line sd_card
}
#if OCL flow copy the driver to the sd_card
if {$runtime == "ocl"} {
catch{file mkdir [file join "sd_card" "data" ]}
catch{file mkdir [file join "sd_card" "data" "emulation" ]}
file copy -force [file join $env(XILINX_VITIS) "data" "emulation"
"unified" ] [file join "sd_card" "data" "emulation" "unified" ]
}
close $fp
set sd_card_size 500000
set sd_card_img_path [file join [pwd] sd_card.img]
exec mkfatimg [file join [pwd] sd_card] [file join [pwd] sd_card.img]
$sd_card_size > mkfatimg.log
cd $save_dir
} else {
set sd_card_img_path $sdimage
#puts "picking sd_card image file from path specified.Not recreating the
sd_Card image"
}
}
}
} else {
set sd_card_img_path $sdimage
}
if {$sd_card_img_path != ""} {
set SDCARD_FILESIZE [expr [file size $sd_card_img_path]]
#puts "file size in string : [file size $sd_card_img_path] size in int :
$SDCARD_FILESIZE"
set logresult [expr log($SDCARD_FILESIZE)/log(2)]
#puts "logresult $logresult"
set roundresult [expr {ceil($logresult)}]
#puts "roundresult $roundresult"
set rounded_size [expr {ceil(pow(2, $roundresult))}]
#puts "rounded_size $rounded_size"
if {[info exists ::env(QEMU_BIN_PATH)] } {
if {$::tcl_platform(os) != "Linux"} {
set qemu_resize_cmd [file join $::env(QEMU_BIN_PATH) qemu-img.exe]
} else {
set qemu_resize_cmd [file join $::env(QEMU_BIN_PATH) qemu-img]
}
#puts "qemu_resize_cmd $qemu_resize_cmd"
#[exec $qemu_resize_cmd resize $sd_card_img_path $rounded_size]
if [catch "exec -ignorestderr $qemu_resize_cmd resize -f raw $sd_card_img_path
$rounded_size" ret opt] {
set return [lindex [dict get $opt -errorcode] end]
puts "qemu_img: $return"
}
puts "resized sd card image"
} else {
if {$::tcl_platform(os) != "Linux"} {
set qemu_arch [file join $::env(XILINX_XD) data emulation qemu_win qemu]
set qemu_resize_cmd [file join $qemu_arch qemu-img.exe]
} else {
set qemu_arch [file join $::env(XILINX_XD) data emulation qemu qemu sysroots
x86_64-petalinux-linux usr bin]
set qemu_resize_cmd [file join $qemu_arch qemu-img]
}
#puts "qemu_resize_cmd $qemu_resize_cmd"
if [catch "exec -ignorestderr $qemu_resize_cmd resize -f raw $sd_card_img_path
$rounded_size" ret opt] {
set return [lindex [dict get $opt -errorcode] end]
puts "qemu_img: $return"
}
puts "resized sd card image"
}
}
######################################################################
# Execution helper functions

proc run_qemu {interactive qemu_script port dont_check process_name cpu_type


enable_tcp_sockets target} {
set log_name $target
append log_name "_"
append log_name $process_name
if {$::tcl_platform(os) == "Linux"} {
# On linux use setsid so the whole process tree can get killed later
if {[info exists interactive] && $interactive== 1} {
set qemu_pid [exec xterm -hold -e $qemu_script <@stdin >@stdout &]
} else {
catch {set qemu_pids [exec setsid $qemu_script <@stdin >@stdout | tee
$log_name.log &]} msg
puts "Qemu_pids $qemu_pids"
lappend pids_to_kill $qemu_pids
split $qemu_pids
set qemu_pid [lindex $qemu_pids 0]
#puts "---Qemu_pid $qemu_pid"
}
} else {
if {[info exists interactive] && $interactive== 1} {
catch {set qemu_pid [exec xterm -hold -e $qemu_script <@stdin >@stdout &]}
msg
} else {
catch {set qemu_pids [exec $qemu_script <@stdin >@stdout | tee $log_name.log
& ]} msg
puts "Qemu_pids $qemu_pids"
lappend pids_to_kill $qemu_pids
split $qemu_pids
set qemu_pid [lindex $qemu_pids 0]
#puts "---Qemu_pid $qemu_pid"
}
}

set emulation_live 0
if {$enable_tcp_sockets == 1 || $cpu_type == "cortex-a9"} {
while {($emulation_live == 0)} {
after 1000
puts -nonewline "."
flush stdout
if {[port_open $port] || $dont_check } {
set emulation_live 1
puts "."
}
if {![pid_exists $qemu_pid] && !$dont_check } {
puts " Failed to start $qemu_script. Aborting!"
puts "ERROR: \[LAUNCH_EMULATOR\] launch_emulator exited because of an issue
in launching QEMU"
exit 1
}
}
}
return $qemu_pid
}

# #####################################################################

# # running the script


if {![info exists norun] || $norun == ""} {
if {$::tcl_platform(os) == "Linux"} {
#Linux
if {$cpu_type == "x86" || $cpu_type == "cortex-a53"} {
# Zynq Mp or Versal
puts "Starting QEMU"
puts " - Press <Ctrl-a h> for help "
puts -nonewline "Waiting for QEMU to start. "
if {[info exists verbose] && $verbose== 1} {
puts "INFO: Running qemu script $qemu_script on port $pmc_port"
}
set log_dir [pwd]
puts "qemu_port $pmc_port"
set qemu_pid [run_qemu $interactive $qemu_script $pmc_port false "ps"
$cpu_type $enable_tcp_sockets $target_emu]
after 3000
puts "QEMU started. qemu_pid=$qemu_pid."
puts -nonewline "Waiting for PMU to start. "
set pmc_pid ""
if {$target_emu eq "sw_emu"} {
# run only pmc emulation, no need to run pl emulation #hence no need to check
for port while running pmc
# for linux, enable pllauncher, with cosim dtb

# We donot want to see a seperate shell for pmu even when interactive mode
is enabled.Henec explicitly setting interactive to 0

set pmc_pid [run_qemu $enable_debug_full $pmc_script $pl_port true "pmu"


$cpu_type $enable_tcp_sockets $target_emu]
after 3000
puts "PMC started. pmc_pid=$pmc_pid"
set machine_path $pl_sim_dir
set emulation_mode "batch"
set pl_script [file join $machine_path "pl_script.$script_ext"];
if {[info exists graphic_xsim] && $graphic_xsim != ""} {
set emulation_mode "gui"
}
run_pllauncher $emulation_mode $machine_path $pl_script $verbose
if {[info exists interactive] && $interactive== 1} {
set pl_pid [exec xterm -hold -e $pl_script $xsim_redir <@stdin >@stdout
&]
} else {
set pl_pid [exec setsid $pl_script $xsim_redir &]
}
if {[info exists pid_file] && $pid_file != ""} {
set fp [open $pid_file w]
puts $fp "[group_pid $pl_pid]"
close $fp
}

# set device_script [file join $machine_path "device_script.


$script_ext"];
# run_devicelauncher $machine_path $device_script
# if {[info exists interactive] && $interactive== 1} {
# set device_pid [exec xterm -hold -e $device_script $xsim_redir <@stdin
>@stdout &]
# } else {
# set device_pid [exec setsid $device_script $xsim_redir &]
# }
# if {[info exists pid_file] && $pid_file != ""} {
# set fp [open $pid_file w]
# puts $fp "[group_pid $device_pid]"
# close $fp
# }

if {[info exists pid_file] && $pid_file != ""} {


write_to_pidFile $pid_file $qemu_pid
}
} else {
# HW_EMU # run pmc emulation, and pl emulation
# # We donot want to see a seperate shell for pmu even when interactive
mode is enabled.Henec explicitly setting interactive to 0
after 1500
set pmc_pid [run_qemu $enable_debug_full $pmc_script $pl_port false "pmu"
$cpu_type $enable_tcp_sockets $target_emu]

puts "PMC started. pmc_pid=$pmc_pid"


after 1500
cd $pl_sim_dir
if {[info exists verbose] && $verbose== 1} {
puts "INFO: Running simulation script $xsim_script with args
$pl_sim_args"
}

if {[info exists interactive] && $interactive== 1} {


set pl_pid [exec xterm -hold -e $xsim_script $pl_sim_args $xsim_redir
<@stdin >@stdout &]
} else {
set pl_pid [eval exec $xsim_script $pl_sim_args $xsim_redir &]
}

puts "Simulation Started. pl_pid=$pl_pid"


if {[info exists pid_file] && $pid_file != ""} {
write_to_pidFile $pid_file $pl_pid
}
}
} else {
# Zynq 7000
delete_file $socket_file
if {$target_emu eq "hw_emu"} {
# for zynq 7000, hw_emu , always enable PL simulation first else, it will
give qemu warning
puts "HW EMU Starting PL simulation"
if {[info exists verbose] && $verbose== 1} {
puts "INFO: Running simulation script $xsim_script with args
$pl_sim_args"
}
set log_dir [pwd]
cd $pl_sim_dir
if {[info exists interactive] && $interactive== 1} {
set pl_pid [exec xterm -hold -e $xsim_script $pl_sim_args $xsim_redir &]
} else {
set pl_pid [exec setsid $xsim_script $pl_sim_args $xsim_redir &]
}

#set pl_pid [exec setsid $xsim_script $pl_sim_args $xsim_redir &]


puts "Simulation Started. pl_pid=$pl_pid"
after 3000
puts -nonewline "Waiting for PL simulation to start"
set emulation_live 0
while {$emulation_live == 0} {
after 1000
puts -nonewline "."
flush stdout
if {[file exists $socket_file]} {
set emulation_live 1
puts " PL simulation started!"
}
if {![pid_exists $pl_pid]} {
puts " PL simulation failed to start. Aborting!"
exit 1
}
}
if {[info exists pid_file] && $pid_file != ""} {
write_to_pidFile $pid_file $pl_pid
}
puts "Starting QEMU"
puts " - Press <Ctrl-a h> for help "
if {[info exists verbose] && $verbose== 1} {
puts "Command: $qemu_cmd $qemu_args"
puts "INFO: Running qemu script $qemu_script on port $pmc_port"
}

if {[info exists interactive] && $interactive== 1} {


catch {set qemu_pid [exec xterm -hold -e $qemu_script <@stdin >@stdout
&]} msg
} else {
catch {set qemu_pid [exec setsid $qemu_script <@stdin >@stdout | tee
hw_emu_ps.log &]} msg
}

puts "QEMU started. qemu_pid=$qemu_pid"


if {$target_emu eq "sw_emu"} {
if {[info exists pid_file] && $pid_file != ""} {
write_to_pidFile $pid_file $qemu_pid
}
}
} else {
#SW_EMU # for zynq 7000, sw_emu , we can launch qemu first
#puts "pl_port $pl_port"
puts "Starting QEMU"
puts " - Press <Ctrl-a h> for help "
if {[info exists verbose] && $verbose== 1} {
puts "Command: $qemu_cmd $qemu_args"
puts "INFO: Running qemu script $qemu_script on port $pmc_port"
}
set log_dir [pwd]
if {[info exists interactive] && $interactive== 1} {
catch {set qemu_pid [exec xterm -hold -e $qemu_script <@stdin >@stdout
&]} msg
} else {
catch {set qemu_pid [exec setsid $qemu_script <@stdin >@stdout | tee
hw_emu_ps.log &]} msg
}

puts "QEMU started. qemu_pid=$qemu_pid"


#puts "pl_port $pl_port"
puts -nonewline "Waiting for QEMU to start"
set emulation_live 0

while {($emulation_live == 0)} {


after 1000
puts -nonewline "."
flush stdout
if {[port_open $pl_port]} {
set emulation_live 1
puts " QEMU started!"
}
if {![pid_exists $qemu_pid]} {
puts " QEMU failed to start. Aborting!"
exit 1
}
}
if {[info exists pid_file] && $pid_file != ""} {
write_to_pidFile $pid_file $qemu_pid
}
after 3000
#puts "SW_EMU Starting PL simulation"
set machine_path $pl_sim_dir
set emulation_mode "batch"
if {[info exists graphic_xsim] && $graphic_xsim != ""} {
set emulation_mode "gui"
}
set pl_script [file join $machine_path "pl_script.$script_ext"];
run_pllauncher $emulation_mode $machine_path $pl_script $verbose
if {[info exists interactive] && $interactive== 1} {
set pl_pid [exec xterm -hold -e $pl_script $xsim_redir &]
} else {
set pl_pid [exec setsid $pl_script $xsim_redir &]
}
}

if {[info exists pid_file] && $pid_file != ""} {


write_to_pidFile $pid_file $pl_pid
}

if {[info exists pid_file] && $pid_file != ""} {


write_to_pidFile $pid_file $qemu_pid
}
}
} else {
# Windows
if {$cpu_type == "x86" || $cpu_type == "cortex-a53"} {
# Zynq Mp or Versal
puts "Starting QEMU"
puts " - Press <Ctrl-a h> for help "
puts -nonewline "Waiting for QEMU to start. "
if {[info exists verbose] && $verbose== 1} {
puts "INFO: Running qemu script $qemu_script on port $pmc_port"
}
set log_dir [pwd]
set qemu_pid [run_qemu $interactive $qemu_script $pmc_port false "ps"
$cpu_type $enable_tcp_sockets $target_emu]

puts "QEMU started. qemu_pid=$qemu_pid."


puts -nonewline "Waiting for PMU to start. "
set pmc_pid ""
if {$target_emu eq "sw_emu"} {
# Windows# pllauncher was never tested for windows.Hence using non-cosim
dtb for windows.
# # We donot want to see a seperate shell for pmu even when interactive
mode is enabled.Henec explicitly setting interactive to 0
set pmc_pid [run_qemu $enable_debug_full $pmc_script $pl_port true "pmu"
$cpu_type $enable_tcp_sockets $target_emu]
puts "PMC started. pmc_pid=$pmc_pid"
if {[info exists pid_file] && $pid_file != ""} {
write_to_pidFile $pid_file $qemu_pid
}
} else {
# We donot want to see a seperate shell for pmu even when interactive mode
is enabled.Henec explicitly setting interactive to 0
set pmc_pid [run_qemu $enable_debug_full $pmc_script $pl_port false "pmu"
$cpu_type $enable_tcp_sockets $target_emu]
puts "PMC started. pmc_pid=$pmc_pid"
cd $pl_sim_dir
if {[info exists verbose] && $verbose== 1} {
puts "INFO: Running simulation script $xsim_script with args
$pl_sim_args"
}

if {[info exists interactive] && $interactive== 1} {


set pl_pid [eval exec xterm -hold -e $xsim_script $pl_sim_args
$xsim_redir &]
} else {
set pl_pid [eval exec $xsim_script $pl_sim_args $xsim_redir &]
}
puts "Simulation Started. pl_pid=$pl_pid"
if {[info exists pid_file] && $pid_file != ""} {
write_to_pidFile $pid_file $pl_pid
}
}
} else {
#Zynq 70000
puts "Starting QEMU"
puts " - Press <Ctrl-a h> for help "
set log_dir [pwd]
set qemu_pid [run_qemu $interactive $qemu_script $pl_port false "ps"
$cpu_type $enable_tcp_sockets $target_emu]
puts "QEMU started. qemu_pid=$qemu_pid"
if {$target_emu eq "hw_emu"} {
puts "Starting PL simulation"
#puts "Command: $xsim_script $xsim_args"
if {[info exists verbose] && $verbose== 1} {
puts "INFO: Running simulation script $xsim_script with args
$pl_sim_args"
}

if {[info exists interactive] && $interactive== 1} {


set pl_pid [eval exec xterm -hold -e $xsim_script $pl_sim_args
$xsim_redir &]
} else {
set pl_pid [eval exec $xsim_script $pl_sim_args $xsim_redir &]
}
#puts "XSIM Started. pl_pid=$pl_pid"
if {[info exists pid_file] && $pid_file != ""} {
write_to_pidFile $pid_file $pl_pid
}
} else {
if {[info exists pid_file] && $pid_file != ""} {
write_to_pidFile $pid_file $qemu_pid
}
}
}
}

# Timeout handling
set done 0
if {[info exists timeout] && $timeout != ""} {
after [expr $timeout * 1000] set done 1
}

# Enter event loop


while {!$done} {
update
if {![pid_exists $qemu_pid]} {
#set time [clock format $systemTime -format %H:%M:%S]
set systemTime [clock seconds]
puts "\[LAUNCH_EMULATOR\] INFO: [clock format $systemTime -format %H:%M:%S] :
PS-QEMU exited"
#puts "\[LAUNCH_EMULATOR\] INFO: Forcefully killing other process like
PMU/PMC and XSIM"
break
}
if {$cpu_type == "x86" || $cpu_type == "cortex-a53"} {
# PMU / PMC exists only for zynqMP and verbose
if {![pid_exists $pmc_pid]} {
set systemTime [clock seconds]
puts "\[LAUNCH_EMULATOR\] INFO: [clock format $systemTime -format %H:%M:%S]
: PMU/PMC-QEMU exited"
#puts "\[LAUNCH_EMULATOR\] INFO: Forcefully killing other process like QEMU
and XSIM"
break
}
}
if {$target_emu eq "hw_emu" || $::tcl_platform(os) == "Linux"} {
if {![pid_exists $pl_pid]} {
if {$target_emu eq "hw_emu"} {
set systemTime [clock seconds]
puts "\[LAUNCH_EMULATOR\] INFO: [clock format $systemTime -format %H:%M:
%S] : Simulation exited"
#puts "\[LAUNCH_EMULATOR\] INFO: Force fully killing other process like
QEMU and PMU/PMC"
} else {
set systemTime [clock seconds]
puts "\[LAUNCH_EMULATOR\] INFO: [clock format $systemTime -format %H:%M:
%S] : PLLauncher exited"
#puts "\[LAUNCH_EMULATOR\] INFO: Force fully killing QEMU and PMU/PMC"
}
break
}
}
}

if {$done} {
puts "\[LAUNCH_EMULATOR\] Emulation timeout reached!"
}

# Cleanup
#Adding 2 second delay, because XSIM is taking some time to quit after qemu quits.
#If this dalay is not added , during cleanup, we are trying to kill xsim process
using the PID present..
#When we are checking for xsim pid, it exists.But, by the time we give kill
command, it gets killed , and kill command cannot find xsim pid. and we are seeing
terminate issues because of this.

after 2000

if {[pid_exists $qemu_pid]} {
if {$done} {
set systemTime [clock seconds]
puts "\[LAUNCH_EMULATOR\] INFO: [clock format $systemTime -format %H:%M:%S] :
Trying to kill PS-QEMU forcefully because timeout is reached"
}
if {!$done} {
set systemTime [clock seconds]
puts "\[LAUNCH_EMULATOR\] INFO: [clock format $systemTime -format %H:%M:%S] :
Trying to kill PS-QEMU forcefully"
}
kill_process $qemu_pid $verbose
if {![pid_exists $qemu_pid]} {
set systemTime [clock seconds]
puts "\[LAUNCH_EMULATOR\] INFO: [clock format $systemTime -format %H:%M:%S] :
PS-QEMU exited by force"
}
} else {
set systemTime [clock seconds]
puts "\[LAUNCH_EMULATOR\] INFO: [clock format $systemTime -format %H:%M:%S] :
PS-QEMU exited"
}

if {$cpu_type == "x86" || $cpu_type == "cortex-a53"} {


# PMU / PMC exists only for zynqMP and verbose
if {[pid_exists $pmc_pid]} {
if {$done} {
set systemTime [clock seconds]
puts "\[LAUNCH_EMULATOR\] INFO: [clock format $systemTime -format %H:%M:%S]
: Trying to kill PMU/PMC-QEMU forcefully because timeout is reached"
}
if {!$done} {
set systemTime [clock seconds]
puts "\[LAUNCH_EMULATOR\] INFO: [clock format $systemTime -format %H:%M:%S]
: Trying to kill PMU/PMC-QEMU forcefully"
}
kill_process $pmc_pid $verbose
if {![pid_exists $pmc_pid]} {
set systemTime [clock seconds]
puts "\[LAUNCH_EMULATOR\] INFO: [clock format $systemTime -format %H:%M:%S]
: PMU/PMC-QEMU exited by force"
}
} else {
set systemTime [clock seconds]
puts "\[LAUNCH_EMULATOR\] INFO: [clock format $systemTime -format %H:%M:%S] :
PMU/PMC-QEMU exited"
}
}

if {[pid_exists $pl_pid]} {
if {$done && $target_emu == "hw_emu"} {
set systemTime [clock seconds]
puts "\[LAUNCH_EMULATOR\] INFO: [clock format $systemTime -format %H:%M:%S] :
Trying to kill simulation forcefully because timeout is reached"
}
if {!$done && $target_emu == "hw_emu"} {
set systemTime [clock seconds]
puts "\[LAUNCH_EMULATOR\] INFO: [clock format $systemTime -format %H:%M:%S] :
Trying to kill simulation forcefully because QEMU exited"
}
if {$done && $target_emu == "sw_emu"} {
set systemTime [clock seconds]
puts "\[LAUNCH_EMULATOR\] INFO: [clock format $systemTime -format %H:%M:%S] :
Trying to kill PLLauncher forcefully because timeout is reached"
}
if {!$done && $target_emu == "sw_emu"} {
set systemTime [clock seconds]
puts "\[LAUNCH_EMULATOR\] INFO: [clock format $systemTime -format %H:%M:%S] :
Trying to kill PLLauncher forcefully because QEMU exited"
}

kill_process $pl_pid $verbose


after 2000

if {![pid_exists $pl_pid]} {
if {$target_emu == "hw_emu"} {
set systemTime [clock seconds]
puts "\[LAUNCH_EMULATOR\] INFO: [clock format $systemTime -format %H:%M:%S]
: Simulation exited by force"
} else {
set systemTime [clock seconds]
puts "\[LAUNCH_EMULATOR\] INFO: [clock format $systemTime -format %H:%M:%S]
: PLLauncher exited by force"
}
}
} else {
if {$target_emu == "hw_emu" } {
set systemTime [clock seconds]
puts "\[LAUNCH_EMULATOR\] INFO: [clock format $systemTime -format %H:%M:%S] :
Simulation exited"
} else {
set systemTime [clock seconds]
puts "\[LAUNCH_EMULATOR\] INFO: [clock format $systemTime -format %H:%M:
%S] : PLLauncher exited"
}
}
foreach pid_to_kill $pids_to_kill {
if {[pid_exists $pid_to_kill]} {
puts "\[LAUNCH_EMULATOR\] INFO: killing $pid_to_kill"
kill_process $pid_to_kill $verbose
if {![pid_exists $pid_to_kill]} {
puts "\[LAUNCH_EMULATOR\] INFO: killed $pid_to_kill"
}
}
}

# Copy simulation.log , xsc.log to log_dir, i,e location from where


launch_emulator is run
# Moving hw_emu_pmu.log to pl_sim_dir
if {$target_emu eq "hw_emu"} {
set xsc_log_pat [file normalize [file join $sim_log_path ..]]
set xsc_log_path [file join $xsc_log_pat xsc.log]
if {[file exists $xsc_log_path]} {
file copy -force $xsc_log_path $log_dir
dump_log_into_console "xsc.log" $xsc_log_path
}
if {[file exists $sim_log_path]} {
file copy -force $sim_log_path $log_dir
dump_log_into_console "simulate.log" $sim_log_path
}
}

#set pmu_path $log_dir


set pmu_file_path $target_emu
append pmu_file_path "_pmu.log"
set pmu_path [file normalize [file join $log_dir $pmu_file_path]]
#puts "pmu_path $pmu_path"
#puts "pl-sim_dir $pl_sim_dir"
if {[file exists $pmu_path]} {
file rename -force $pmu_path $pl_sim_dir
dump_log_into_console $pmu_file_path $pmu_path
}

#set ps_file_path $target_emu


#append ps_file_path "_ps.log"
#set ps_path [file normalize [file join $log_dir $ps_file_path]]
#if {[file exists $ps_path]} {
# dump_log_into_console $ps_file_path $ps_path
#}
puts "Please refer PS /simulate logs at $log_dir for more details."

post_operations $pl_sim_dir $log_dir $platform_name $envdict

puts "DONE!"
puts "INFO: Emulation ran successfully"
exit 0
}

You might also like