0% found this document useful (0 votes)
56 views30 pages

Launch Emulator

Uploaded by

Srinivasan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
56 views30 pages

Launch Emulator

Uploaded by

Srinivasan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
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