You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3564 lines
130 KiB

8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
  1. ####################################################################################
  2. #
  3. # write_project_tcl.tcl (write a Vivado project tcl script for re-creating project)
  4. #
  5. # Script created on 02/08/2013 by Raj Klair (Xilinx, Inc.)
  6. #
  7. # 2014.2 - v2.0 (rev 4)
  8. # * do not return value from main proc
  9. # * fixed bug with relative file path calculation (break from loop while comparing
  10. # directory elements of file paths for file to make relative to o/p script dir)
  11. # 2014.1 - v2.0 (rev 3)
  12. # * make source file paths relative to script output directory
  13. #
  14. # 2013.4 -
  15. # 2013.3 -
  16. # 2013.2 - v1.0 (rev 2)
  17. # * no change
  18. #
  19. # 2013.1 - v1.0 (rev 1)
  20. # * initial version
  21. #
  22. ####################################################################################
  23. #
  24. # Modified version to better support revision control.
  25. # Can be called as write_project_tcl_git from the tcl console in Vivado.
  26. #
  27. # Differences:
  28. #
  29. # 1. The project directory is now relative to the scripts location.
  30. # Project directory was relative to the tcl console current directory.
  31. #
  32. # 2. When recreating a project, the generated files will be put in a "work_dir" directory
  33. # under the top directory. If "work_dir" exists already, it will be rewritten.
  34. #
  35. # 3. After recreating a project, the tcl console will change directory to the project directory.
  36. #
  37. # 4. No mention to the creation time of the project script, so that it is not different
  38. # every time it is generated.
  39. #
  40. # 5. Remove warning when local sources are detected.
  41. #
  42. ####################################################################################
  43. package require Vivado 1.2014.1
  44. namespace eval ::custom_projutils {
  45. namespace export write_project_tcl_git
  46. }
  47. namespace eval ::custom_projutils {
  48. proc write_project_tcl_git {args} {
  49. # Summary: Export Tcl script for re-creating the current project
  50. # Argument Usage:
  51. # [-paths_relative_to <arg> = Script output directory path]: Override the reference directory variable for source file relative paths
  52. # [-origin_dir_override <arg>]: Set 'origin_dir' directory variable to the specified value (Default is value specified with the -paths_relative_to switch)
  53. # [-target_proj_dir <arg> = Current project directory path]: Directory where the project needs to be restored
  54. # [-force]: Overwrite existing tcl script file
  55. # [-all_properties]: Write all properties (default & non-default) for the project object(s)
  56. # [-no_copy_sources]: Do not import sources even if they were local in the original project
  57. # [-no_ip_version]: Flag to not include the IP version as part of the IP VLNV in create_bd_cell commands.
  58. # [-absolute_path]: Make all file paths absolute wrt the original project directory
  59. # [-dump_project_info]: Write object values
  60. # [-use_bd_files ]: Use BD sources directly instead of writing out procs to create them
  61. # [-internal]: Print basic header information in the generated tcl script
  62. # [-validate]: Runs a validate script before recreating the project. To test if the files and paths refrenced in the tcl file exists or not.
  63. # [-quiet]: Execute the command quietly, returning no messages from the command.
  64. # file: Name of the tcl script file to generate
  65. # Return Value:
  66. # true (0) if success, false (1) otherwise
  67. # Categories: xilinxtclstore, projutils
  68. # reset global variables
  69. variable a_global_vars
  70. reset_global_vars
  71. # process options
  72. for {set i 0} {$i < [llength $args]} {incr i} {
  73. set option [string trim [lindex $args $i]]
  74. switch -regexp -- $option {
  75. "-paths_relative_to" {
  76. incr i;
  77. if { [regexp {^-} [lindex $args $i]] } {
  78. send_msg_id Vivado-projutils-021 ERROR "Missing value for the $option option.\
  79. Please provide a valid path/directory name immediately following '$option'"
  80. return
  81. }
  82. set a_global_vars(s_relative_to) [file normalize [lindex $args $i]]
  83. }
  84. "-target_proj_dir" {
  85. incr i;
  86. if { [regexp {^-} [lindex $args $i]] } {
  87. send_msg_id Vivado-projutils-021 ERROR "Missing value for the $option option.\
  88. Please provide a valid path/directory name immediately following '$option'"
  89. return
  90. }
  91. set a_global_vars(s_target_proj_dir) [lindex $args $i]
  92. }
  93. "-origin_dir_override" { incr i;set a_global_vars(s_origin_dir_override) [lindex $args $i] }
  94. "-force" { set a_global_vars(b_arg_force) 1 }
  95. "-all_properties" { set a_global_vars(b_arg_all_props) 1 }
  96. "-no_copy_sources" { set a_global_vars(b_arg_no_copy_srcs) 1 }
  97. "-no_ip_version" { set a_global_vars(b_arg_no_ip_version) 1 }
  98. "-absolute_path" { set a_global_vars(b_absolute_path) 1 }
  99. "-dump_project_info" { set a_global_vars(b_arg_dump_proj_info) 1 }
  100. "-use_bd_files" { set a_global_vars(b_arg_use_bd_files) 1 }
  101. "-internal" { set a_global_vars(b_internal) 1 }
  102. "-validate" { set a_global_vars(b_validate) 1 }
  103. "-quiet" { set a_global_vars(b_arg_quiet) 1}
  104. default {
  105. # is incorrect switch specified?
  106. if { [regexp {^-} $option] } {
  107. send_msg_id Vivado-projutils-001 ERROR "Unknown option '$option', please type 'write_project_tcl -help' for usage info.\n"
  108. return
  109. }
  110. set a_global_vars(script_file) $option
  111. }
  112. }
  113. }
  114. #read properties to exclude
  115. read_props_to_exclude
  116. # suppress all messages if -quiet flag is provided
  117. if { $a_global_vars(b_arg_quiet) } {
  118. suppress_messages
  119. }
  120. # script file is a must
  121. if { [lsearch {"" ".tcl"} [file tail $a_global_vars(script_file)]] != -1 } {
  122. if { $a_global_vars(b_arg_quiet) } {
  123. reset_msg_setting
  124. }
  125. send_msg_id Vivado-projutils-002 ERROR "Missing value for option 'file', please type 'write_project_tcl -help' for usage info.\n"
  126. return
  127. }
  128. # should not be a directory
  129. if { [file isdirectory $a_global_vars(script_file)] } {
  130. if { $a_global_vars(b_arg_quiet) } {
  131. reset_msg_setting
  132. }
  133. send_msg_id Vivado-projutils-003 ERROR "The specified filename is a directory ($a_global_vars(script_file)), please type 'write_project_tcl -help' for usage info.\n"
  134. return
  135. }
  136. # check extension
  137. if { [file extension $a_global_vars(script_file)] != ".tcl" } {
  138. set a_global_vars(script_file) $a_global_vars(script_file).tcl
  139. }
  140. set a_global_vars(script_file) [file normalize $a_global_vars(script_file)]
  141. # error if file directory path does not exist
  142. set file_path [file dirname $a_global_vars(script_file)]
  143. if { ! [file exists $file_path] } {
  144. set script_filename [file tail $a_global_vars(script_file)]
  145. if { $a_global_vars(b_arg_quiet) } {
  146. reset_msg_setting
  147. }
  148. send_msg_id Vivado-projutils-013 ERROR "Directory in which file ${script_filename} is to be written does not exist \[$a_global_vars(script_file)\]\n"
  149. return
  150. }
  151. # recommend -force if file exists
  152. if { [file exists $a_global_vars(script_file)] && !$a_global_vars(b_arg_force) } {
  153. if { $a_global_vars(b_arg_quiet) } {
  154. reset_msg_setting
  155. }
  156. send_msg_id Vivado-projutils-004 ERROR "Tcl Script '$a_global_vars(script_file)' already exist. Use -force option to overwrite.\n"
  157. return
  158. }
  159. if { [get_files -quiet *.bd] eq "" } { set a_global_vars(b_arg_use_bd_files) 1 }
  160. # set script file directory path
  161. set a_global_vars(s_path_to_script_dir) [file normalize $file_path]
  162. # now write
  163. if {[write_project_tcl_script]} {
  164. if { $a_global_vars(b_arg_quiet) } {
  165. reset_msg_setting
  166. }
  167. return
  168. }
  169. }
  170. }
  171. namespace eval ::custom_projutils {
  172. #
  173. # write_project_tcl tcl script argument & file handle vars
  174. #
  175. variable a_global_vars
  176. variable l_script_data [list]
  177. variable l_local_files [list]
  178. variable l_remote_files [list]
  179. variable l_bd_wrapper [list]
  180. variable l_validate_repo_paths [list]
  181. variable l_bc_filesets [list]
  182. variable b_project_board_set 0
  183. # set file types to filter
  184. variable l_filetype_filter [list]
  185. # Setup filter for non-user-settable filetypes
  186. set l_filetype_filter [list "ip" "ipx" "embedded design sources" "elf" "coefficient files" "configuration files" \
  187. "block diagrams" "block designs" "dsp design sources" "text" \
  188. "design checkpoint" "waveform configuration file" "csv"]
  189. # ip file extension types
  190. variable l_valid_ip_extns [list]
  191. set l_valid_ip_extns [list ".xci" ".bd" ".slx"]
  192. # set fileset types
  193. variable a_fileset_types
  194. set a_fileset_types {
  195. {{DesignSrcs} {srcset}}
  196. {{BlockSrcs} {blockset}}
  197. {{Constrs} {constrset}}
  198. {{SimulationSrcs} {simset}}
  199. {{Utils} {utilset}}
  200. }
  201. proc reset_global_vars {} {
  202. # Summary: initializes global namespace vars
  203. # This helper command is used to reset the variables used in the script.
  204. # Argument Usage:
  205. # none
  206. # Return Value:
  207. # None
  208. variable a_global_vars
  209. set a_global_vars(s_relative_to) {.}
  210. set a_global_vars(s_path_to_script_dir) ""
  211. set a_global_vars(s_origin_dir_override) ""
  212. set a_global_vars(s_target_proj_dir) ""
  213. set a_global_vars(b_arg_force) 0
  214. set a_global_vars(b_arg_no_copy_srcs) 0
  215. set a_global_vars(b_arg_no_ip_version) 0
  216. set a_global_vars(b_absolute_path) 0
  217. set a_global_vars(b_internal) 0
  218. set a_global_vars(b_validate) 0
  219. set a_global_vars(b_arg_all_props) 0
  220. set a_global_vars(b_arg_dump_proj_info) 0
  221. set a_global_vars(b_local_sources) 0
  222. set a_global_vars(curr_time) [clock format [clock seconds]]
  223. set a_global_vars(fh) 0
  224. set a_global_vars(dp_fh) 0
  225. set a_global_vars(def_val_fh) 0
  226. set a_global_vars(script_file) ""
  227. set a_global_vars(b_arg_quiet) 0
  228. if { [get_param project.enableMergedProjTcl] } {
  229. set a_global_vars(b_arg_use_bd_files) 0
  230. } else {
  231. set a_global_vars(b_arg_use_bd_files) 1
  232. }
  233. set a_global_vars(excludePropDict) [dict create]
  234. set l_script_data [list]
  235. set l_local_files [list]
  236. set l_remote_files [list]
  237. set l_bd_wrapper [list]
  238. set l_validate_repo_paths [list]
  239. set l_bc_filesets [list]
  240. }
  241. proc write_project_tcl_script {} {
  242. # Summary: write project script
  243. # This helper command is used to script help.
  244. # Argument Usage:
  245. # none
  246. # Return Value:
  247. # true (0) if success, false (1) otherwise
  248. variable a_global_vars
  249. variable l_script_data
  250. variable l_remote_files
  251. variable l_local_files
  252. variable temp_dir
  253. variable temp_offset 1
  254. variable clean_temp
  255. variable l_open_bds [list]
  256. variable l_added_bds
  257. variable a_os
  258. variable l_bc_filesets
  259. variable l_validate_repo_paths
  260. set l_script_data [list]
  261. set l_local_files [list]
  262. set l_remote_files [list]
  263. set l_bc_filesets [list]
  264. set l_open_bds [list]
  265. set l_added_bds [list]
  266. set l_validate_repo_paths [list]
  267. # Create temp directory (if required) for BD procs
  268. set temp_dir [ file join [file dirname $a_global_vars(script_file)] .Xiltemp ]
  269. set clean_temp 1
  270. if { [file isdirectory $temp_dir] || $a_global_vars(b_arg_use_bd_files) } {
  271. set clean_temp 0
  272. } else {
  273. file mkdir $temp_dir
  274. }
  275. # Get OS
  276. if { [is_win_os] } {
  277. set a_os "win"
  278. } else {
  279. set a_os ""
  280. }
  281. # get the project name
  282. set tcl_obj [current_project]
  283. set proj_name [file tail [get_property name $tcl_obj]]
  284. set proj_dir [get_property directory $tcl_obj]
  285. set part_name [get_property part $tcl_obj]
  286. # output file script handle
  287. set file $a_global_vars(script_file)
  288. if {[catch {open $file w} a_global_vars(fh)]} {
  289. if { $a_global_vars(b_arg_quiet) } {
  290. reset_msg_setting
  291. }
  292. send_msg_id Vivado-projutils-005 ERROR "failed to open file for write ($file)\n"
  293. return 1
  294. }
  295. # dump project in canonical form
  296. if { $a_global_vars(b_arg_dump_proj_info) } {
  297. set dump_file [file normalize [file join $a_global_vars(s_path_to_script_dir) ${proj_name}_dump.txt]]
  298. if {[catch {open $dump_file w} a_global_vars(dp_fh)]} {
  299. if { $a_global_vars(b_arg_quiet) } {
  300. reset_msg_setting
  301. }
  302. send_msg_id Vivado-projutils-006 ERROR "failed to open file for write ($dump_file)\n"
  303. return 1
  304. }
  305. # default value output file script handle
  306. set def_val_file [file normalize [file join $a_global_vars(s_path_to_script_dir) ${proj_name}_def_val.txt]]
  307. if {[catch {open $def_val_file w} a_global_vars(def_val_fh)]} {
  308. if { $a_global_vars(b_arg_quiet) } {
  309. reset_msg_setting
  310. }
  311. send_msg_id Vivado-projutils-007 ERROR "failed to open file for write ($file)\n"
  312. return 1
  313. }
  314. }
  315. # explicitly update the compile order for current source/simset, if following conditions are met
  316. if { {All} == [get_property source_mgmt_mode [current_project]] &&
  317. {0} == [get_property is_readonly [current_project]] &&
  318. {RTL} == [get_property design_mode [current_fileset]] } {
  319. # re-parse source fileset compile order for the current top
  320. if {[llength [get_files -quiet -compile_order sources -used_in synthesis]] > 1} {
  321. update_compile_order -fileset [current_fileset] -quiet
  322. }
  323. # re-parse simlulation fileset compile order for the current top
  324. if {[llength [get_files -quiet -compile_order sources -used_in simulation]] > 1} {
  325. update_compile_order -fileset [current_fileset -simset] -quiet
  326. }
  327. }
  328. # writer helpers
  329. wr_create_project $proj_dir $proj_name $part_name
  330. wr_project_properties $proj_dir $proj_name
  331. wr_filesets $proj_dir $proj_name
  332. wr_prflow $proj_dir $proj_name
  333. if { !$a_global_vars(b_arg_use_bd_files) } {
  334. wr_bd
  335. wr_bd_bc_specific
  336. } else {
  337. wr_bd_create_wrapper
  338. }
  339. # write BC and RM filesets to handle extra files(ELF, XDC) added
  340. if { [llength $l_bc_filesets] > 0 } {
  341. write_specified_fileset $proj_dir $proj_name $l_bc_filesets 0
  342. }
  343. wr_bc_managed_rm_files $proj_dir $proj_name
  344. wr_prConf $proj_dir $proj_name
  345. wr_runs $proj_dir $proj_name
  346. wr_proj_info $proj_name
  347. #write dashboards
  348. wr_dashboards $proj_dir $proj_name
  349. # write header
  350. write_header $proj_dir $proj_name $file
  351. # write validate script
  352. set l_validate_script [wr_validate_files]
  353. foreach line $l_validate_script {
  354. puts $a_global_vars(fh) $line
  355. }
  356. # write script data
  357. foreach line $l_script_data {
  358. puts $a_global_vars(fh) $line
  359. }
  360. close $a_global_vars(fh)
  361. if { $a_global_vars(b_arg_dump_proj_info) } {
  362. close $a_global_vars(def_val_fh)
  363. close $a_global_vars(dp_fh)
  364. }
  365. set script_filename [file tail $file]
  366. set out_dir [file dirname [file normalize $file]]
  367. if { !$a_global_vars(b_arg_quiet) } {
  368. send_msg_id Vivado-projutils-008 INFO "Tcl script '$script_filename' generated in output directory '$out_dir'\n\n"
  369. if { $a_global_vars(b_absolute_path) } {
  370. send_msg_id Vivado-projutils-016 INFO "Please note that the -absolute_path switch was specified, hence the project source files will be referenced using\n\
  371. absolute path only, in the generated script. As such, the generated script will only work in the same filesystem where those absolute paths are accessible."
  372. } else {
  373. if { "." != $a_global_vars(s_relative_to) } {
  374. if { {} == $a_global_vars(s_origin_dir_override) } {
  375. send_msg_id Vivado-projutils-017 INFO "Please note that the -paths_relative_to switch was specified, hence the project source files will be referenced\n\
  376. wrt the path that was specified with this switch. The 'origin_dir' variable is set to this path in the generated script."
  377. } else {
  378. send_msg_id Vivado-projutils-017 INFO "Please note that the -paths_relative_to switch was specified, hence the project source files will be referenced wrt the\n\
  379. path that was specified with this switch. The 'origin_dir' variable is set to '$a_global_vars(s_origin_dir_override)' in the generated script."
  380. }
  381. } else {
  382. send_msg_id Vivado-projutils-015 INFO "The file paths for the project source files were set relative to the location of the generated script.\n"
  383. }
  384. }
  385. }
  386. if { $a_global_vars(b_arg_quiet) } {
  387. reset_msg_setting
  388. }
  389. reset_global_vars
  390. return 0
  391. }
  392. proc wr_validate_files {} {
  393. variable a_global_vars
  394. set l_script_validate [list]
  395. variable l_validate_repo_paths
  396. variable l_local_files
  397. variable l_remote_files
  398. lappend l_script_validate "# Check file required for this script exists"
  399. lappend l_script_validate "proc checkRequiredFiles \{ origin_dir\} \{"
  400. lappend l_script_validate " set status true"
  401. if {[llength $l_local_files]>0} {
  402. lappend l_script_validate " set files \[list \\"
  403. foreach file $l_local_files {
  404. lappend l_script_validate " $file \\"
  405. }
  406. lappend l_script_validate " \]"
  407. lappend l_script_validate " foreach ifile \$files \{"
  408. lappend l_script_validate " if \{ !\[file isfile \$ifile\] \} \{"
  409. lappend l_script_validate " puts \" Could not find local file \$ifile \""
  410. lappend l_script_validate " set status false"
  411. lappend l_script_validate " \}"
  412. lappend l_script_validate " \}"
  413. lappend l_script_validate ""
  414. }
  415. if {[llength $l_remote_files]>0} {
  416. lappend l_script_validate " set files \[list \\"
  417. foreach file $l_remote_files {
  418. set file_no_quotes [string trim $file "\""]
  419. set rel_file_path \"\$\{origin_dir\}/$file_no_quotes\"
  420. lappend l_script_validate " $rel_file_path \\"
  421. }
  422. lappend l_script_validate " \]"
  423. lappend l_script_validate " foreach ifile \$files \{"
  424. lappend l_script_validate " if \{ !\[file isfile \$ifile\] \} \{"
  425. lappend l_script_validate " puts \" Could not find remote file \$ifile \""
  426. lappend l_script_validate " set status false"
  427. lappend l_script_validate " \}"
  428. lappend l_script_validate " \}"
  429. lappend l_script_validate ""
  430. }
  431. if {[llength $l_validate_repo_paths]>0} {
  432. lappend l_script_validate " set paths \[list \\"
  433. foreach path $l_validate_repo_paths {
  434. lappend l_script_validate " $path \\"
  435. }
  436. lappend l_script_validate " \]"
  437. lappend l_script_validate " foreach ipath \$paths \{"
  438. lappend l_script_validate " if \{ !\[file isdirectory \$ipath\] \} \{"
  439. lappend l_script_validate " puts \" Could not access \$ipath \""
  440. lappend l_script_validate " set status false"
  441. lappend l_script_validate " \}"
  442. lappend l_script_validate " \}"
  443. lappend l_script_validate ""
  444. }
  445. lappend l_script_validate " return \$status"
  446. lappend l_script_validate "\}"
  447. return $l_script_validate
  448. }
  449. proc wr_create_project { proj_dir name part_name } {
  450. # Summary: write create project command
  451. # This helper command is used to script help.
  452. # Argument Usage:
  453. # proj_dir: project directory path
  454. # name: project name
  455. # Return Value:
  456. # none
  457. variable a_global_vars
  458. variable l_script_data
  459. lappend l_script_data "# Set the reference directory for source file relative paths (by default the value is script directory path)"
  460. lappend l_script_data "set origin_dir \[file dirname \[info script\]\]"
  461. lappend l_script_data ""
  462. set var_name "origin_dir_loc"
  463. lappend l_script_data "# Use origin directory path location variable, if specified in the tcl shell"
  464. lappend l_script_data "if \{ \[info exists ::$var_name\] \} \{"
  465. lappend l_script_data " set origin_dir \$::$var_name"
  466. lappend l_script_data "\}"
  467. lappend l_script_data ""
  468. set var_name "user_project_name"
  469. lappend l_script_data "# Set the project name\nset _xil_proj_name_ \"$name\"\n"
  470. lappend l_script_data "# Use project name variable, if specified in the tcl shell"
  471. lappend l_script_data "if \{ \[info exists ::$var_name\] \} \{"
  472. lappend l_script_data " set _xil_proj_name_ \$::$var_name"
  473. lappend l_script_data "\}\n"
  474. lappend l_script_data "variable script_file"
  475. lappend l_script_data "set script_file \"[file tail $a_global_vars(script_file)]\"\n"
  476. lappend l_script_data "# Help information for this script"
  477. lappend l_script_data "proc print_help \{\} \{"
  478. lappend l_script_data " variable script_file"
  479. lappend l_script_data " puts \"\\nDescription:\""
  480. lappend l_script_data " puts \"Recreate a Vivado project from this script. The created project will be\""
  481. lappend l_script_data " puts \"functionally equivalent to the original project for which this script was\""
  482. lappend l_script_data " puts \"generated. The script contains commands for creating a project, filesets,\""
  483. lappend l_script_data " puts \"runs, adding/importing sources and setting properties on various objects.\\n\""
  484. lappend l_script_data " puts \"Syntax:\""
  485. lappend l_script_data " puts \"\$script_file\""
  486. lappend l_script_data " puts \"\$script_file -tclargs \\\[--origin_dir <path>\\\]\""
  487. lappend l_script_data " puts \"\$script_file -tclargs \\\[--project_name <name>\\\]\""
  488. lappend l_script_data " puts \"\$script_file -tclargs \\\[--help\\\]\\n\""
  489. lappend l_script_data " puts \"Usage:\""
  490. lappend l_script_data " puts \"Name Description\""
  491. lappend l_script_data " puts \"-------------------------------------------------------------------------\""
  492. if { {} == $a_global_vars(s_origin_dir_override) } {
  493. lappend l_script_data " puts \"\\\[--origin_dir <path>\\\] Determine source file paths wrt this path. Default\""
  494. lappend l_script_data " puts \" origin_dir path value is \\\".\\\", otherwise, the value\""
  495. lappend l_script_data " puts \" that was set with the \\\"-paths_relative_to\\\" switch\""
  496. lappend l_script_data " puts \" when this script was generated.\\n\""
  497. } else {
  498. lappend l_script_data " puts \"\\\[--origin_dir <path>\\\] Determine source file paths wrt this path. Default\""
  499. lappend l_script_data " puts \" origin_dir path value is \\\".\\\", otherwise, the value\""
  500. lappend l_script_data " puts \" that was set with the \\\"-origin_dir_override\\\" switch\""
  501. lappend l_script_data " puts \" when this script was generated.\\n\""
  502. }
  503. lappend l_script_data " puts \"\\\[--project_name <name>\\\] Create project with the specified name. Default\""
  504. lappend l_script_data " puts \" name is the name of the project from where this\""
  505. lappend l_script_data " puts \" script was generated.\\n\""
  506. lappend l_script_data " puts \"\\\[--help\\\] Print help information for this script\""
  507. lappend l_script_data " puts \"-------------------------------------------------------------------------\\n\""
  508. lappend l_script_data " exit 0"
  509. lappend l_script_data "\}\n"
  510. lappend l_script_data "if \{ \$::argc > 0 \} \{"
  511. lappend l_script_data " for \{set i 0\} \{\$i < \$::argc\} \{incr i\} \{"
  512. lappend l_script_data " set option \[string trim \[lindex \$::argv \$i\]\]"
  513. lappend l_script_data " switch -regexp -- \$option \{"
  514. lappend l_script_data " \"--origin_dir\" \{ incr i; set origin_dir \[lindex \$::argv \$i\] \}"
  515. lappend l_script_data " \"--project_name\" \{ incr i; set _xil_proj_name_ \[lindex \$::argv \$i\] \}"
  516. lappend l_script_data " \"--help\" \{ print_help \}"
  517. lappend l_script_data " default \{"
  518. lappend l_script_data " if \{ \[regexp \{^-\} \$option\] \} \{"
  519. lappend l_script_data " puts \"ERROR: Unknown option '\$option' specified, please type '\$script_file -tclargs --help' for usage info.\\n\""
  520. lappend l_script_data " return 1"
  521. lappend l_script_data " \}"
  522. lappend l_script_data " \}"
  523. lappend l_script_data " \}"
  524. lappend l_script_data " \}"
  525. lappend l_script_data "\}\n"
  526. lappend l_script_data "# Set the directory path for the original project from where this script was exported"
  527. if { $a_global_vars(b_absolute_path) || [need_abs_path $proj_dir] } {
  528. lappend l_script_data "set orig_proj_dir \"$proj_dir\""
  529. } else {
  530. set rel_file_path "[get_relative_file_path_for_source $proj_dir [get_script_execution_dir]]"
  531. set path "\[file normalize \"\$origin_dir/$rel_file_path\"\]"
  532. lappend l_script_data "set orig_proj_dir \"$path\""
  533. }
  534. lappend l_script_data ""
  535. # Validate
  536. lappend l_script_data "# Check for paths and files needed for project creation"
  537. lappend l_script_data "set validate_required $a_global_vars(b_validate)"
  538. lappend l_script_data "if \{ \$validate_required \} \{"
  539. lappend l_script_data " if \{ \[checkRequiredFiles \$origin_dir\] \} \{"
  540. lappend l_script_data " puts \"Tcl file \$script_file is valid. All files required for project creation is accesable. \""
  541. lappend l_script_data " \} else \{"
  542. lappend l_script_data " puts \"Tcl file \$script_file is not valid. Not all files required for project creation is accesable. \""
  543. lappend l_script_data " return"
  544. lappend l_script_data " \}"
  545. lappend l_script_data "\}"
  546. lappend l_script_data ""
  547. # create project
  548. lappend l_script_data "# Create project"
  549. set tcl_cmd ""
  550. # set target project directory path if specified. If not, create project dir in current dir.
  551. set target_dir $a_global_vars(s_target_proj_dir)
  552. if { {} == $target_dir } {
  553. set tcl_cmd "create_project \$\{_xil_proj_name_\} \$origin_dir/work_dir -part $part_name -quiet -force"
  554. } else {
  555. # is specified target proj dir == current dir?
  556. set cwd [file normalize [string map {\\ /} [pwd]]]
  557. set dir [file normalize [string map {\\ /} $target_dir]]
  558. if { [string equal $cwd $dir] } {
  559. set tcl_cmd "create_project \$\{_xil_proj_name_\} -part $part_name"
  560. } else {
  561. set tcl_cmd "create_project \$\{_xil_proj_name_\} \"$target_dir\" -part $part_name"
  562. }
  563. }
  564. if { [get_property managed_ip [current_project]] } {
  565. set tcl_cmd "$tcl_cmd -ip"
  566. }
  567. lappend l_script_data $tcl_cmd
  568. if { $a_global_vars(b_arg_dump_proj_info) } {
  569. puts $a_global_vars(dp_fh) "project_name=\$\{_xil_proj_name_\}"
  570. }
  571. lappend l_script_data ""
  572. lappend l_script_data "# Set the directory path for the new project"
  573. lappend l_script_data "set proj_dir \[get_property directory \[current_project\]\]"
  574. lappend l_script_data ""
  575. }
  576. proc wr_project_properties { proj_dir proj_name } {
  577. # Summary: write project properties
  578. # This helper command is used to script help.
  579. # Argument Usage:
  580. # proj_name: project name
  581. # Return Value:
  582. # None
  583. variable l_script_data
  584. variable b_project_board_set
  585. # write project properties
  586. set tcl_obj [current_project]
  587. set get_what "get_projects"
  588. lappend l_script_data "# Set project properties"
  589. lappend l_script_data "set obj \[current_project\]"
  590. # is project "board_part" set already?
  591. if { [string length [get_property "board_part" $tcl_obj]] > 0 } {
  592. set b_project_board_set 1
  593. }
  594. write_props $proj_dir $proj_name $get_what $tcl_obj "project"
  595. }
  596. proc write_bd_as_proc { bd_file } {
  597. # Summary: writes out BD creation steps as a proc
  598. # Argument: BD file
  599. # Return Value: None
  600. variable a_global_vars
  601. variable l_added_bds
  602. variable l_bd_proc_calls
  603. variable l_script_data
  604. variable temp_offset
  605. variable l_open_bds
  606. variable temp_dir
  607. variable bd_prop_steps
  608. set bd_file [list "$bd_file"]
  609. if { [lsearch $l_added_bds $bd_file] != -1 } { return }
  610. set to_close 1
  611. # Add sources referenced in the BD
  612. add_references $bd_file
  613. # Open BD in stealth mode, if not already open
  614. set bd_filename [file tail $bd_file]
  615. if { [lsearch $l_open_bds $bd_filename] != -1 } {
  616. set to_close 0
  617. } else {
  618. open_bd_design -stealth [ get_files $bd_file ]
  619. }
  620. current_bd_design [get_bd_designs [file rootname $bd_filename]]
  621. # write the BD as a proc to a temp file
  622. while { [file exists [file join $temp_dir "temp_$temp_offset.tcl"]] } {
  623. incr temp_offset
  624. }
  625. set temp_bd_file [file join $temp_dir "temp_$temp_offset.tcl"]
  626. if { $a_global_vars(b_arg_no_ip_version) } {
  627. write_bd_tcl -no_project_wrapper -no_ip_version -make_local -include_layout $temp_bd_file
  628. } else {
  629. write_bd_tcl -no_project_wrapper -make_local -include_layout $temp_bd_file
  630. }
  631. # Set non default properties for the BD
  632. wr_bd_properties $bd_file
  633. # Close BD if opened in stealth mode
  634. if {$to_close == 1 } {
  635. close_bd_design [get_bd_designs [file rootname $bd_filename]]
  636. }
  637. # Get proc call
  638. if {[catch {open $temp_bd_file r} fp]} {
  639. if { $a_global_vars(b_arg_quiet) } {
  640. reset_msg_setting
  641. }
  642. send_msg_id Vivado-projutils-020 ERROR "failed to write out proc for $bd_file \n"
  643. return 1
  644. }
  645. # TODO no need to read whole file, just second line will do
  646. set file_data [read $fp ]
  647. set split_proc [split $file_data]
  648. set proc_index 7
  649. set str [lindex $split_proc $proc_index]
  650. close $fp
  651. # Add the BD proc, call to the proc and BD property steps
  652. if { [string equal [lindex $split_proc [expr {$proc_index-1}] ] "proc"]
  653. && [regexp {^cr_bd_.*} $str]
  654. } then {
  655. append str " \"\""
  656. lappend l_script_data "\n"
  657. lappend l_script_data $file_data
  658. lappend l_added_bds $bd_file
  659. lappend l_script_data $str
  660. lappend l_script_data $bd_prop_steps
  661. }
  662. # delete temp file
  663. file delete $temp_bd_file
  664. incr temp_offset
  665. }
  666. proc wr_bd_properties { file } {
  667. # Summary: writes non default BD properties
  668. # Argument: the .BD file
  669. # Return Value: none
  670. variable bd_prop_steps
  671. variable a_global_vars
  672. set bd_prop_steps ""
  673. set bd_name [get_property FILE_NAME [current_bd_design]]
  674. set bd_props [list_property [ get_files $file ] ]
  675. set read_only_props [rdi::get_attr_specs -object [get_files $file] -filter {is_readonly}]
  676. foreach prop $bd_props {
  677. if { [lsearch $read_only_props $prop] != -1
  678. || [string equal -nocase $prop "file_type" ]
  679. } then { continue }
  680. set def_val [list_property_value -default $prop [ get_files $file ] ]
  681. set cur_val [get_property $prop [get_files $file ] ]
  682. set def_val \"$def_val\"
  683. set cur_val \"$cur_val\"
  684. if { $a_global_vars(b_arg_all_props) } {
  685. append bd_prop_steps "set_property $prop $cur_val \[get_files $bd_name \] \n"
  686. } else {
  687. if { $def_val ne $cur_val } {
  688. append bd_prop_steps "set_property $prop $cur_val \[get_files $bd_name \] \n"
  689. }
  690. }
  691. }
  692. }
  693. proc add_references { sub_design } {
  694. # Summary: Looks for sources referenced in the block design and adds them
  695. # Argument: sub_design file
  696. # Return Value: None
  697. variable l_script_data
  698. variable l_added_bds
  699. # Getting references, if any
  700. set refs [ get_files -quiet -references -of_objects [ get_files $sub_design ] ]
  701. foreach file $refs {
  702. if { [file extension $file ] ==".bd" } {
  703. if { [lsearch $l_added_bds $file] != -1 } { continue }
  704. # Write out referred bd as a proc
  705. write_bd_as_proc $file
  706. } else {
  707. # Skip adding file if it's already part of the project
  708. lappend l_script_data "if { \[get_files [file tail $file]\] == \"\" } {"
  709. lappend l_script_data " import_files -quiet -fileset [current_fileset -srcset] $file\n}"
  710. }
  711. }
  712. }
  713. proc wr_bd_create_wrapper {} {
  714. # Get all BD files in the design
  715. set bd_files [get_files -norecurse *.bd -filter "IS_BLOCK_CONTAINER_MANAGED == 0"]
  716. foreach bd_file $bd_files {
  717. # Add wrapper creation
  718. set bd_filename [file tail $bd_file]
  719. lappend l_script_data "\n# Create wrapper file for $bd_filename"
  720. lappend l_script_data "make_wrapper -files \[get_files $bd_filename\] -import -top\n"
  721. }
  722. }
  723. proc wr_bd {} {
  724. # Summary: write procs to create BD's
  725. # Return Value: None
  726. variable a_global_vars
  727. variable l_script_data
  728. variable l_added_bds
  729. variable l_bd_proc_calls
  730. variable l_open_bds [list]
  731. variable temp_dir
  732. variable clean_temp
  733. # String that will hold commands to set BD properties
  734. variable bd_prop_steps "\n# Setting BD properties \n"
  735. # Get already opened BD designs
  736. set open_bd_names [get_bd_designs]
  737. foreach bd_name $open_bd_names {
  738. lappend l_open_bds [get_property FILE_NAME [get_bd_designs $bd_name]]
  739. }
  740. # Get all BD files in the design
  741. set bd_files [get_files -norecurse *.bd -filter "IS_BLOCK_CONTAINER_MANAGED == 0"]
  742. lappend l_script_data "\n# Adding sources referenced in BDs, if not already added"
  743. foreach bd_file $bd_files {
  744. # Making sure BD is not locked
  745. set is_locked [get_property IS_LOCKED [get_files [list "$bd_file"] ] ]
  746. if { $is_locked == 1 } {
  747. close $a_global_vars(fh)
  748. file delete $a_global_vars(script_file)
  749. if { $a_global_vars(b_arg_quiet) } {
  750. reset_msg_setting
  751. }
  752. send_msg_id Vivado-projutils-018 ERROR "Project tcl cannot be written as the design contains one or more \
  753. locked/out-of-date design(s). Please run report_ip_status and update the design.\n"
  754. return 1
  755. }
  756. # Write out bd as a proc
  757. write_bd_as_proc $bd_file
  758. # Add wrapper creation
  759. set bd_filename [file tail $bd_file]
  760. lappend l_script_data "\n# Create wrapper file for $bd_filename"
  761. lappend l_script_data "make_wrapper -files \[get_files $bd_filename\] -import -top\n"
  762. }
  763. # Delete temp directory
  764. if { $clean_temp == 1} {
  765. file delete -force $temp_dir
  766. }
  767. wr_bd_wrapper
  768. }
  769. proc wr_bd_bc_specific {} {
  770. # Summary: write generate_target for the top level BD that contains Block Containers
  771. # Return Value: None
  772. variable l_bc_filesets
  773. variable l_script_data
  774. set bd_files [get_files -norecurse *.bd -filter "IS_BLOCK_CONTAINER_MANAGED == 0"]
  775. set bc_filesets_size [llength $l_bc_filesets]
  776. foreach bd_file $bd_files {
  777. set refs [ get_files -quiet -references -of_objects [ get_files $bd_file ] ]
  778. # If BD has references and project has BC filesets, then
  779. # we are assuming it as it is top level BD with BCs
  780. # TODO - Need to check whether this assumption works for all cases
  781. set delivered_targets [lsearch [get_property delivered_targets [get_files $bd_file] ] Synthesis]
  782. set stale_targets [lsearch [get_property stale_targets [get_files $bd_file] ] Synthesis]
  783. set is_generated [expr {$delivered_targets != -1 && $stale_targets == -1}]
  784. if { [llength $refs] != 0 && $is_generated == 1 && $bc_filesets_size != 0} {
  785. set filename [file tail $bd_file]
  786. lappend l_script_data "generate_target all \[get_files $filename\]\n"
  787. }
  788. }
  789. }
  790. proc wr_bd_wrapper {} {
  791. variable l_script_data
  792. variable l_bd_wrapper
  793. if {[llength $l_bd_wrapper]>0} {
  794. lappend l_script_data "#call make_wrapper to create wrapper files"
  795. foreach fileset_designame_wrappername $l_bd_wrapper {
  796. set fs_name [lindex $fileset_designame_wrappername 0]
  797. set design [lindex $fileset_designame_wrappername 1]
  798. set wrapper_name [lindex $fileset_designame_wrappername 2]
  799. lappend l_script_data "if \{ \[get_property IS_LOCKED \[ get_files -norecurse $design.bd\] \] == 1 \} \{"
  800. lappend l_script_data " import_files -fileset $fs_name $wrapper_name"
  801. lappend l_script_data "\} else \{"
  802. lappend l_script_data " set wrapper_path \[make_wrapper -fileset $fs_name -files \[ get_files -norecurse $design.bd] -top\]"
  803. lappend l_script_data " add_files -norecurse -fileset $fs_name \$wrapper_path"
  804. lappend l_script_data "\}"
  805. lappend l_script_data ""
  806. }
  807. lappend l_script_data ""
  808. }
  809. }
  810. proc wr_filesets { proj_dir proj_name } {
  811. # Summary: write fileset object properties
  812. # This helper command is used to script help.
  813. # Argument Usage:
  814. # proj_name: project name
  815. # Return Value:
  816. # None
  817. variable a_fileset_types
  818. # write fileset data
  819. foreach {fs_data} $a_fileset_types {
  820. set filesets [get_filesets -filter FILESET_TYPE==[lindex $fs_data 0]]
  821. write_specified_fileset $proj_dir $proj_name $filesets 1
  822. }
  823. }
  824. proc write_specified_fileset { proj_dir proj_name filesets ignore_bc } {
  825. # Summary: write fileset properties and sources
  826. # This helper command is used to script help.
  827. # Argument Usage:
  828. # proj_name: project name
  829. # filesets: list of filesets
  830. # Return Value:
  831. # None
  832. variable a_global_vars
  833. variable l_script_data
  834. variable a_fileset_types
  835. variable l_bc_filesets
  836. variable l_validate_repo_paths
  837. # write filesets
  838. set type "file"
  839. foreach tcl_obj $filesets {
  840. # Is this a IP block fileset for a proxy IP that is owned by another composite file?
  841. # If so, we don't want to write it out as an independent file. The parent will take care of it.
  842. if { [is_proxy_ip_fileset $tcl_obj] } {
  843. continue
  844. }
  845. # Is this a Block Container managed block fileset?
  846. # If so, we don't need to create block fileset, it will be auto created
  847. if { $ignore_bc == 1 && [is_bc_managed_fileset $tcl_obj] == true } {
  848. lappend l_bc_filesets $tcl_obj
  849. continue
  850. }
  851. set fs_type [get_property fileset_type [get_filesets $tcl_obj]]
  852. # is this a IP block fileset? if yes, do not create block fileset, but create for a pure HDL based fileset (no IP's)
  853. if { [is_ip_fileset $tcl_obj] || [is_bc_managed_fileset $tcl_obj] } {
  854. # do not create block fileset
  855. } elseif { [string equal $tcl_obj "utils_1"] } {
  856. # do not create utils fileset
  857. } else {
  858. lappend l_script_data "# Create '$tcl_obj' fileset (if not found)"
  859. lappend l_script_data "if \{\[string equal \[get_filesets -quiet $tcl_obj\] \"\"\]\} \{"
  860. set fs_sw_type [get_fileset_type_switch $fs_type]
  861. lappend l_script_data " create_fileset $fs_sw_type $tcl_obj"
  862. lappend l_script_data "\}\n"
  863. }
  864. set get_what_fs "get_filesets"
  865. # set IP REPO PATHS (if any) for filesets of type "DesignSrcs" or "BlockSrcs"
  866. if { (({DesignSrcs} == $fs_type) || ({BlockSrcs} == $fs_type)) } {
  867. # If BlockSet contains only one IP, then this indicates the case of OOC1
  868. # This means that we should not write these properties, they are read-only
  869. set blockset_is_ooc1 false
  870. if { {BlockSrcs} == $fs_type } {
  871. set current_fs_files [get_files -quiet -of_objects [get_filesets $tcl_obj] -norecurse]
  872. if { [llength $current_fs_files] == 1 } {
  873. set only_file_in_fs [lindex $current_fs_files 0]
  874. set file_type [get_property FILE_TYPE $only_file_in_fs]
  875. set blockset_is_ooc1 [expr {$file_type == {IP}} ? true : false]
  876. }
  877. }
  878. if { $blockset_is_ooc1} {
  879. # We do not write properties for OOC1
  880. } elseif { ({RTL} == [get_property design_mode [get_filesets $tcl_obj]]) } {
  881. set repo_paths [get_ip_repo_paths $tcl_obj]
  882. if { [llength $repo_paths] > 0 } {
  883. lappend l_script_data "# Set IP repository paths"
  884. lappend l_script_data "set obj \[get_filesets $tcl_obj\]"
  885. set path_list [list]
  886. foreach path $repo_paths {
  887. if { $a_global_vars(b_absolute_path) || [need_abs_path $path] } {
  888. lappend path_list $path
  889. if { [lsearch $l_validate_repo_paths $path] == -1 } {
  890. lappend l_validate_repo_paths $path
  891. }
  892. } else {
  893. set rel_file_path "[get_relative_file_path_for_source $path [get_script_execution_dir]]"
  894. # Filter out IP repositories outside of the project directory
  895. if { [string first .. $rel_file_path] == 0 } { continue }
  896. set path "\[file normalize \"\$origin_dir/$rel_file_path\"\]"
  897. lappend path_list $path
  898. if { [lsearch $l_validate_repo_paths $path] == -1 } {
  899. lappend l_validate_repo_paths $path
  900. }
  901. }
  902. }
  903. set repo_path_str [join $path_list " "]
  904. lappend l_script_data "if \{ \$obj != \{\} \} \{"
  905. lappend l_script_data "set_property \"ip_repo_paths\" \"${repo_path_str}\" \$obj"
  906. lappend l_script_data ""
  907. lappend l_script_data "# Rebuild user ip_repo's index before adding any source files"
  908. lappend l_script_data "update_ip_catalog -rebuild"
  909. lappend l_script_data "\}"
  910. lappend l_script_data ""
  911. }
  912. }
  913. }
  914. # is this a IP block fileset? if yes, then set the current srcset object (IP's will be added to current source fileset)
  915. if { [is_ip_fileset $tcl_obj] } {
  916. set srcset [current_fileset -srcset]
  917. lappend l_script_data "# Set '$srcset' fileset object"
  918. lappend l_script_data "set obj \[$get_what_fs $srcset\]"
  919. } else {
  920. lappend l_script_data "# Set '$tcl_obj' fileset object"
  921. lappend l_script_data "set obj \[$get_what_fs $tcl_obj\]"
  922. }
  923. if { {Constrs} == $fs_type } {
  924. lappend l_script_data ""
  925. write_constrs $proj_dir $proj_name $tcl_obj $type
  926. } else {
  927. write_files $proj_dir $proj_name $tcl_obj $type
  928. }
  929. # is this a IP block fileset? if yes, do not write block fileset properties (block fileset doesnot exist in new project)
  930. if { [is_ip_fileset $tcl_obj] } {
  931. # do not write ip fileset properties
  932. } else {
  933. lappend l_script_data "# Set '$tcl_obj' fileset properties"
  934. lappend l_script_data "set obj \[$get_what_fs $tcl_obj\]"
  935. write_props $proj_dir $proj_name $get_what_fs $tcl_obj "fileset"
  936. }
  937. }
  938. }
  939. proc wr_runs { proj_dir proj_name } {
  940. # Summary: write runs and properties
  941. # This helper command is used to script help.
  942. # Argument Usage:
  943. # proj_name: project name
  944. # Return Value:
  945. # None
  946. variable l_script_data
  947. # write runs (synthesis, Implementation)
  948. set runs [get_runs -filter {IS_SYNTHESIS == 1}]
  949. write_specified_run $proj_dir $proj_name $runs
  950. if { {RTL} == [get_property design_mode [current_fileset]] } {
  951. lappend l_script_data "# set the current synth run"
  952. lappend l_script_data "current_run -synthesis \[get_runs [current_run -synthesis]\]\n"
  953. }
  954. set runs [get_runs -filter {IS_IMPLEMENTATION == 1}]
  955. write_specified_run $proj_dir $proj_name $runs
  956. lappend l_script_data "# set the current impl run"
  957. lappend l_script_data "current_run -implementation \[get_runs [current_run -implementation]\]"
  958. lappend l_script_data ""
  959. lappend l_script_data "# Change current directory to project folder"
  960. lappend l_script_data "cd \[file dirname \[info script\]\]"
  961. }
  962. proc wr_proj_info { proj_name } {
  963. # Summary: write generated project status message
  964. # This helper command is used to script help.
  965. # Argument Usage:
  966. # proj_name: project name
  967. # Return Value:
  968. # None
  969. variable l_script_data
  970. lappend l_script_data "\nputs \"INFO: Project created:\${_xil_proj_name_}\""
  971. }
  972. proc write_header { proj_dir proj_name file } {
  973. # Summary: write script header
  974. # This helper command is used to script help.
  975. # Argument Usage:
  976. # Return Value:
  977. # None
  978. variable a_global_vars
  979. variable l_local_files
  980. variable l_remote_files
  981. set version_txt [split [version] "\n"]
  982. set version [lindex $version_txt 0]
  983. set copyright [lindex $version_txt 2]
  984. set product [lindex [split $version " "] 0]
  985. set version_id [join [lrange $version 1 end] " "]
  986. set tcl_file [file tail $file]
  987. puts $a_global_vars(fh) "#*****************************************************************************************"
  988. puts $a_global_vars(fh) "# $product (TM) $version_id"
  989. puts $a_global_vars(fh) "#\n# $tcl_file: Tcl script for re-creating project '$proj_name'\n#"
  990. puts $a_global_vars(fh) "# $copyright"
  991. puts $a_global_vars(fh) "#\n# This file contains the $product Tcl commands for re-creating the project to the state*"
  992. puts $a_global_vars(fh) "# when this script was generated. In order to re-create the project, please source this"
  993. puts $a_global_vars(fh) "# file in the $product Tcl Shell."
  994. puts $a_global_vars(fh) "#"
  995. puts $a_global_vars(fh) "# * Note that the runs in the created project will be configured the same way as the"
  996. puts $a_global_vars(fh) "# original project, however they will not be launched automatically. To regenerate the"
  997. puts $a_global_vars(fh) "# run results please launch the synthesis/implementation runs as needed.\n#"
  998. puts $a_global_vars(fh) "#*****************************************************************************************"
  999. }
  1000. proc print_local_file_msg { msg_type } {
  1001. # Summary: print warning on finding local sources
  1002. # This helper command is used to script help.
  1003. # Argument Usage:
  1004. # Return Value:
  1005. # None
  1006. puts ""
  1007. if { [string equal $msg_type "warning"] } {
  1008. send_msg_id Vivado-projutils-010 WARNING "Found source(s) that were local or imported into the project. If this project is being source controlled, then\n\
  1009. please ensure that the project source(s) are also part of this source controlled data. The list of these local source(s) can be found in the generated script\n\
  1010. under the header section."
  1011. } else {
  1012. send_msg_id Vivado-projutils-011 INFO "If this project is being source controlled, then please ensure that the project source(s) are also part of this source\n\
  1013. controlled data. The list of these local source(s) can be found in the generated script under the header section."
  1014. }
  1015. puts ""
  1016. }
  1017. proc get_ip_repo_paths { tcl_obj } {
  1018. # Summary:
  1019. # Iterate over the fileset properties and get the ip_repo_paths (if set)
  1020. # Argument Usage:
  1021. # tcl_obj : fileset
  1022. # Return Value:
  1023. # List of repo paths
  1024. set repo_path_list [list]
  1025. foreach path [get_property ip_repo_paths [get_filesets $tcl_obj]] {
  1026. lappend repo_path_list $path
  1027. }
  1028. return $repo_path_list
  1029. }
  1030. proc filter { prop val { file {} } } {
  1031. # Summary: filter special properties
  1032. # This helper command is used to script help.
  1033. # Argument Usage:
  1034. # Return Value:
  1035. # true (1) if found, false (1) otherwise
  1036. variable l_filetype_filter
  1037. variable l_valid_ip_extns
  1038. set prop [string toupper $prop]
  1039. if { [expr { $prop == "BOARD" } || \
  1040. { $prop == "IS_HD" } || \
  1041. { $prop == "IS_PARTIAL_RECONFIG" } || \
  1042. { $prop == "ADD_STEP" }]} {
  1043. return 1
  1044. }
  1045. if { [string equal type "project"] } {
  1046. if { [expr { $prop == "DIRECTORY" }] } {
  1047. return 1
  1048. }
  1049. }
  1050. # error reported if file_type is set
  1051. # e.g ERROR: [Vivado 12-563] The file type 'IP' is not user settable.
  1052. set val [string tolower $val]
  1053. if { [string equal $prop "FILE_TYPE"] } {
  1054. if { [lsearch $l_filetype_filter $val] != -1 } {
  1055. return 1
  1056. }
  1057. }
  1058. # filter readonly is_managed property for ip
  1059. if { [string equal $prop "IS_MANAGED"] } {
  1060. if { [lsearch -exact $l_valid_ip_extns [string tolower [file extension $file]]] >= 0 } {
  1061. return 1
  1062. }
  1063. }
  1064. # filter ip_repo_paths (ip_repo_paths is set before adding sources)
  1065. if { [string equal -nocase $prop {ip_repo_paths}] } {
  1066. return 1
  1067. }
  1068. # filter sim_types
  1069. if { ([string equal -nocase $prop {allowed_sim_models}]) } {
  1070. return 1
  1071. }
  1072. return 0
  1073. }
  1074. proc is_local_to_project { file } {
  1075. # Summary: check if file is local to the project directory structure
  1076. # This helper command is used to script help.
  1077. # Argument Usage:
  1078. # Return Value:
  1079. # true (1), if file is local to the project (inside project directory structure)
  1080. # false (0), if file is outside the project directory structure
  1081. # Remove quotes for proper normalize output
  1082. set file [string trim $file "\""]
  1083. set dir [get_property directory [current_project]]
  1084. set proj_comps [split [string trim [file normalize [string map {\\ /} $dir]]] "/"]
  1085. set file_comps [split [string trim [file normalize [string map {\\ /} $file]]] "/"]
  1086. set is_local 1
  1087. for {set i 1} {$i < [llength $proj_comps]} {incr i} {
  1088. if { [lindex $proj_comps $i] != [lindex $file_comps $i] } {
  1089. set is_local 0;break
  1090. }
  1091. }
  1092. return $is_local
  1093. }
  1094. proc is_ip_readonly_prop { name } {
  1095. # Summary: Return true if dealing with following IP properties that are not settable for an IP in read-only state
  1096. # Argument Usage:
  1097. # name: property name
  1098. # Return Value:
  1099. # true if success, false otherwise
  1100. if { [regexp -nocase {synth_checkpoint_mode} $name] ||
  1101. [regexp -nocase {is_locked} $name] ||
  1102. [regexp -nocase {generate_synth_checkpoint} $name] } {
  1103. return true
  1104. }
  1105. return false
  1106. }
  1107. proc write_properties { prop_info_list get_what tcl_obj {delim "#"} } {
  1108. # Summary: write object properties
  1109. # This helper command is used to script help.
  1110. # Argument Usage:
  1111. # Return Value:
  1112. # None
  1113. variable a_global_vars
  1114. variable l_script_data
  1115. if {[llength $prop_info_list] > 0} {
  1116. set b_add_closing_brace 0
  1117. foreach x $prop_info_list {
  1118. set elem [split $x $delim]
  1119. set name [lindex $elem 0]
  1120. set value [lindex $elem 1]
  1121. if { ([is_ip_readonly_prop $name]) && ([string equal $get_what "get_files"]) } {
  1122. set cmd_str "if \{ !\[get_property \"is_locked\" \$file_obj\] \} \{"
  1123. lappend l_script_data "$cmd_str"
  1124. set cmd_str " set_property -name \"$name\" -value \"$value\" -objects"
  1125. set b_add_closing_brace 1
  1126. } else {
  1127. set cmd_str "set_property -name \"$name\" -value \"$value\" -objects"
  1128. }
  1129. if { [string equal $get_what "get_files"] } {
  1130. lappend l_script_data "$cmd_str \$file_obj"
  1131. if { $b_add_closing_brace } {
  1132. lappend l_script_data "\}"
  1133. set b_add_closing_brace 0
  1134. }
  1135. } else {
  1136. # comment "is_readonly" project property
  1137. if { [string equal $get_what "get_projects"] && [string equal "$name" "is_readonly"] } {
  1138. if { ! $a_global_vars(b_arg_all_props) && !$a_global_vars(b_arg_quiet) } {
  1139. send_msg_id Vivado-projutils-012 INFO "The current project is in 'read_only' state. The generated script will create a writable project."
  1140. }
  1141. continue
  1142. }
  1143. lappend l_script_data "$cmd_str \$obj"
  1144. }
  1145. }
  1146. }
  1147. lappend l_script_data ""
  1148. }
  1149. proc align_project_properties { prop proj_name proj_file_path } {
  1150. # Summary:
  1151. # Argument Usage:
  1152. # Return Value:
  1153. variable a_global_vars
  1154. set dir_suffix {}
  1155. if { {} == $prop } {
  1156. return $proj_file_path
  1157. }
  1158. # align project properties to have project name variable
  1159. if {[string equal -nocase $prop "ip_output_repo"] ||
  1160. [string equal -nocase $prop "sim.ipstatic.compiled_library_dir"] } {
  1161. set dir_suffix "cache"
  1162. } else {
  1163. if {[string equal -nocase $prop "sim.central_dir"] ||
  1164. [string equal -nocase $prop "ip.user_files_dir"] ||
  1165. [string equal -nocase $prop "sim.ipstatic.source_dir"] } {
  1166. set dir_suffix "ip_user_files"
  1167. }}
  1168. # skip other properties
  1169. if { {} == $dir_suffix } {
  1170. return $proj_file_path
  1171. }
  1172. set match_str "${proj_name}/${proj_name}.${dir_suffix}"
  1173. set proj_file_path [string map {\\ /} $proj_file_path]
  1174. if { [regexp $match_str $proj_file_path] } {
  1175. set proj_file_path [regsub -all "${proj_name}" $proj_file_path "\$\{_xil_proj_name_\}"]
  1176. } else {
  1177. set match_str "${proj_name}.${dir_suffix}"
  1178. set proj_file_path [regsub "${proj_name}\.${dir_suffix}" $proj_file_path "\$\{_xil_proj_name_\}\.${dir_suffix}"]
  1179. }
  1180. return $proj_file_path
  1181. }
  1182. proc write_props { proj_dir proj_name get_what tcl_obj type {delim "#"}} {
  1183. # Summary: write first class object properties
  1184. # This helper command is used to script help.
  1185. # Argument Usage:
  1186. # Return Value:
  1187. # none
  1188. variable a_global_vars
  1189. variable l_script_data
  1190. variable b_project_board_set
  1191. if {[string equal $type "project"]} {
  1192. # escape empty spaces in project name
  1193. set tcl_obj [ list "$tcl_obj"]
  1194. }
  1195. if { [string first " " $get_what 0] != -1 } {
  1196. # For cases where get_what is multiple workds like "get_dashboard_gadgets -of_object..."
  1197. set current_obj [ eval $get_what $tcl_obj]
  1198. } else {
  1199. set current_obj [$get_what $tcl_obj]
  1200. }
  1201. if { $current_obj == "" } { return }
  1202. set obj_name [get_property name $current_obj]
  1203. set read_only_props [rdi::get_attr_specs -class [get_property class $current_obj] -filter {is_readonly}]
  1204. set prop_info_list [list]
  1205. set properties [list_property $current_obj]
  1206. #move board_part_repo_pats property before board_part CR:1072610
  1207. set idx [lsearch $properties "BOARD_PART_REPO_PATHS"]
  1208. if {$idx ne -1} {
  1209. set properties [lreplace $properties $idx $idx]
  1210. set properties [linsert $properties 0 "BOARD_PART_REPO_PATHS"]
  1211. }
  1212. foreach prop $properties {
  1213. if { [is_deprecated_property $prop] } { continue }
  1214. # is property excluded from being written into the script file
  1215. if { [is_excluded_property $current_obj $prop] } { continue }
  1216. # skip read-only properties
  1217. if { [lsearch $read_only_props $prop] != -1 } { continue }
  1218. if { ([string equal $type "gadget"]) && ([string equal -nocase $prop "type"]) } {
  1219. continue
  1220. }
  1221. # To handle the work-around solution of CR-988588 set board_part to base_board_part value then set board_connections
  1222. if { ([ string equal $type "project" ]) && ([ string equal [ string tolower $prop ] "board_connections" ]) } {
  1223. continue
  1224. }
  1225. if { ([ string equal $type "project" ]) && $b_project_board_set && ([ string equal [ string tolower $prop ] "board_part" ]) } {
  1226. set board_part_val [get_property $prop $current_obj]
  1227. set base_board_part_val [get_property base_board_part $current_obj]
  1228. set board_connections_val [get_property board_connections $current_obj]
  1229. if { $base_board_part_val != "" && $base_board_part_val != $board_part_val } {
  1230. set prop_entry "[string tolower $prop]$delim$base_board_part_val"
  1231. lappend prop_info_list $prop_entry
  1232. set prop_entry "board_connections$delim$board_connections_val"
  1233. lappend prop_info_list $prop_entry
  1234. continue
  1235. }
  1236. }
  1237. # skip writing PR-Configuration, attached right after creation of impl run
  1238. if { ([get_property pr_flow [current_project]] == 1) && [string equal $type "run"] } {
  1239. set isImplRun [get_property is_implementation $current_obj]
  1240. if { ($isImplRun == 1) && [string equal -nocase $prop "pr_configuration"] } {
  1241. continue
  1242. }
  1243. }
  1244. set prop_type "unknown"
  1245. if { [string equal $type "run"] } {
  1246. # skip steps.<step_name>.reports dynamic read only property (to be populated by creation of reports)
  1247. if { [regexp -nocase "STEPS\..*\.REPORTS" $prop] || [string equal -nocase "REPORT_STRATEGY" $prop] } {
  1248. continue;
  1249. }
  1250. if { [regexp "STEPS" $prop] } {
  1251. # skip step properties
  1252. } else {
  1253. set attr_names [rdi::get_attr_specs -class [get_property class [get_runs $tcl_obj] ]]
  1254. if { [lsearch $attr_names $prop] != -1 } {
  1255. set prop_type [get_property type [lindex $attr_names [lsearch $attr_names $prop]]]
  1256. }
  1257. }
  1258. } else {
  1259. set attr_spec [rdi::get_attr_specs -quiet $prop -object $current_obj]
  1260. if { {} == $attr_spec } {
  1261. set prop_lower [string tolower $prop]
  1262. set attr_spec [rdi::get_attr_specs -quiet $prop_lower -object $current_obj]
  1263. }
  1264. set prop_type [get_property type $attr_spec]
  1265. }
  1266. set def_val [list_property_value -default $prop $current_obj]
  1267. set dump_prop_name [string tolower ${obj_name}_${type}_$prop]
  1268. set cur_val [get_property $prop $current_obj]
  1269. # filter special properties
  1270. if { [filter $prop $cur_val] } { continue }
  1271. # do not set "runs" or "project" part, if "board_part" is set
  1272. if { ([string equal $type "project"] || [string equal $type "run"]) &&
  1273. [string equal -nocase $prop "part"] &&
  1274. $b_project_board_set } {
  1275. continue
  1276. }
  1277. # do not set "fileset" target_part, if "board_part" is set
  1278. if { [string equal $type "fileset"] &&
  1279. [string equal -nocase $prop "target_part"] &&
  1280. $b_project_board_set } {
  1281. continue
  1282. }
  1283. # do not set default_rm for partitionDef initially as RM is not created at time of creation of pdef
  1284. if { [string equal $type "partitionDef"] &&
  1285. [string equal -nocase $prop "default_rm"] } {
  1286. continue
  1287. }
  1288. # re-align values
  1289. set cur_val [get_target_bool_val $def_val $cur_val]
  1290. set abs_proj_file_path [get_property $prop $current_obj]
  1291. set path_match [string match $proj_dir* $abs_proj_file_path]
  1292. if { ($path_match == 1) && ($a_global_vars(b_absolute_path) != 1) && ![need_abs_path $abs_proj_file_path] } {
  1293. # changing the absolute path to relative
  1294. set abs_path_length [string length $proj_dir]
  1295. set proj_file_path [string replace $abs_proj_file_path 0 $abs_path_length "\$proj_dir/"]
  1296. set proj_file_path [align_project_properties $prop $proj_name $proj_file_path]
  1297. set prop_entry "[string tolower $prop]$delim$proj_file_path"
  1298. } else {
  1299. set abs_proj_file_path [align_project_properties $prop $proj_name $abs_proj_file_path]
  1300. set prop_entry "[string tolower $prop]$delim$abs_proj_file_path"
  1301. }
  1302. # handle the board_part_repo_paths property
  1303. if {[string equal -nocase $prop "board_part_repo_paths"]} {
  1304. set board_repo_paths [list]
  1305. set board_repo_paths [get_property $prop $current_obj]
  1306. if { [llength $board_repo_paths] > 0 } {
  1307. set board_paths [list]
  1308. foreach path $board_repo_paths {
  1309. if { $a_global_vars(b_absolute_path) || [need_abs_path $path] } {
  1310. lappend board_paths $path
  1311. } else {
  1312. set board_part_path [get_relative_file_path_for_source $path [get_script_execution_dir]]
  1313. # Limit board repo to those inside the project folder
  1314. if { [string first .. $board_part_path] == -1 } {
  1315. lappend board_paths "\[file normalize \"\$origin_dir/$board_part_path\"\]"
  1316. }
  1317. }
  1318. }
  1319. # Only set property if there is something in the list
  1320. if { [llength $board_paths] > 0 } {
  1321. set prop_entry "[string tolower $prop]$delim[join $board_paths " "]"
  1322. # Else, skip
  1323. } else {
  1324. continue
  1325. }
  1326. }
  1327. }
  1328. # re-align include dir path wrt origin dir
  1329. if { [string equal -nocase $prop "include_dirs"] } {
  1330. if { [llength $abs_proj_file_path] > 0 } {
  1331. if { !$a_global_vars(b_absolute_path) } {
  1332. set incl_paths $abs_proj_file_path
  1333. set rel_paths [list]
  1334. foreach path $incl_paths {
  1335. if { ![need_abs_path $path] } {
  1336. lappend rel_paths "\[file normalize \"\$origin_dir/[get_relative_file_path_for_source $path [get_script_execution_dir]]\"\]"
  1337. }
  1338. }
  1339. set prop_entry "[string tolower $prop]$delim[join $rel_paths " "]"
  1340. }
  1341. }
  1342. }
  1343. # fix paths wrt the original project dir
  1344. if {([string equal -nocase $prop "top_file"]) && ($cur_val != "") } {
  1345. set file $cur_val
  1346. set srcs_dir "${proj_name}.srcs"
  1347. set file_dirs [split [string trim [file normalize [string map {\\ /} $file]]] "/"]
  1348. set src_file [join [lrange $file_dirs [lsearch -exact $file_dirs "$srcs_dir"] end] "/"]
  1349. if { [is_local_to_project $file] || [need_abs_path $file]} {
  1350. set proj_file_path "\$proj_dir/$src_file"
  1351. } else {
  1352. set proj_file_path "[get_relative_file_path_for_source $src_file [get_script_execution_dir]]"
  1353. }
  1354. set prop_entry "[string tolower $prop]$delim$proj_file_path"
  1355. } elseif {([string equal -nocase $prop "target_constrs_file"] ||
  1356. [string equal -nocase $prop "target_ucf"]) &&
  1357. ($cur_val != "") } {
  1358. set file $cur_val
  1359. set fs_name $tcl_obj
  1360. set path_dirs [split [string trim [file normalize [string map {\\ /} $file]]] "/"]
  1361. set src_file [join [lrange $path_dirs [lsearch -exact $path_dirs "$fs_name"] end] "/"]
  1362. set file_object [lindex [get_files -quiet -of_objects [get_filesets $fs_name] [list $file]] 0]
  1363. set file_props [list_property $file_object]
  1364. if { [lsearch $file_props "IMPORTED_FROM"] != -1 } {
  1365. if { $a_global_vars(b_arg_no_copy_srcs) } {
  1366. set proj_file_path "\$orig_proj_dir/${proj_name}.srcs/$src_file"
  1367. } else {
  1368. set proj_file_path "\$proj_dir/\$\{_xil_proj_name_\}.srcs/$src_file"
  1369. }
  1370. } else {
  1371. # is file new inside project?
  1372. if { [is_local_to_project $file] } {
  1373. set path_dirs [split [string trim [file normalize [string map {\\ /} $file]]] "/"]
  1374. set local_constrs_file [join [lrange $path_dirs end-1 end] "/"]
  1375. set local_constrs_file [string trimleft $local_constrs_file "/"]
  1376. set local_constrs_file [string trimleft $local_constrs_file "\\"]
  1377. set file $local_constrs_file
  1378. set proj_file_path "\[get_files *$local_constrs_file\]"
  1379. } else {
  1380. if { $a_global_vars(b_absolute_path) || [need_abs_path $file] } {
  1381. set proj_file_path "$file"
  1382. } else {
  1383. set file_no_quotes [string trim $file "\""]
  1384. set rel_file_path [get_relative_file_path_for_source $file_no_quotes [get_script_execution_dir]]
  1385. set proj_file_path "\[file normalize \"\$origin_dir/$rel_file_path\"\]"
  1386. }
  1387. }
  1388. }
  1389. set prop_entry "[string tolower $prop]$delim$proj_file_path"
  1390. }
  1391. # re-align compiled_library_dir
  1392. if { [string equal -nocase $prop "compxlib.compiled_library_dir"] ||
  1393. [string equal -nocase $prop "compxlib.modelsim_compiled_library_dir"] ||
  1394. [string equal -nocase $prop "compxlib.questa_compiled_library_dir"] ||
  1395. [string equal -nocase $prop "compxlib.ies_compiled_library_dir"] ||
  1396. [string equal -nocase $prop "compxlib.vcs_compiled_library_dir"] ||
  1397. [string equal -nocase $prop "compxlib.riviera_compiled_library_dir"] ||
  1398. [string equal -nocase $prop "compxlib.activehdl_compiled_library_dir"] } {
  1399. set compile_lib_dir_path $cur_val
  1400. set cache_dir "${proj_name}.cache"
  1401. set path_dirs [split [string trim [file normalize [string map {\\ /} $cur_val]]] "/"]
  1402. if {[lsearch -exact $path_dirs "$cache_dir"] > 0} {
  1403. set dir_path [join [lrange $path_dirs [lsearch -exact $path_dirs "$cache_dir"] end] "/"]
  1404. set compile_lib_dir_path "\$proj_dir/$dir_path"
  1405. set compile_lib_dir_path [regsub $cache_dir $compile_lib_dir_path "\$\{_xil_proj_name_\}\.cache"]
  1406. }
  1407. set prop_entry "[string tolower $prop]$delim$compile_lib_dir_path"
  1408. }
  1409. # process run step tcl pre/post properties
  1410. if { [string equal $type "run"] } {
  1411. if { [regexp "STEPS" $prop] } {
  1412. if { [regexp "TCL.PRE" $prop] || [regexp "TCL.POST" $prop] } {
  1413. if { ($cur_val != "") } {
  1414. set file $cur_val
  1415. set srcs_dir "${proj_name}.srcs"
  1416. set file_dirs [split [string trim [file normalize [string map {\\ /} $file]]] "/"]
  1417. set src_file [join [lrange $file_dirs [lsearch -exact $file_dirs "$srcs_dir"] end] "/"]
  1418. set tcl_file_path {}
  1419. if { [is_local_to_project $file] } {
  1420. set tcl_file_path "\$proj_dir/$src_file"
  1421. } else {
  1422. if { $a_global_vars(b_absolute_path)|| [need_abs_path $file] } {
  1423. set tcl_file_path "$file"
  1424. } else {
  1425. set rel_file_path "[get_relative_file_path_for_source $src_file [get_script_execution_dir]]"
  1426. set tcl_file_path "\[file normalize \"\$origin_dir/$rel_file_path\"\]"
  1427. }
  1428. }
  1429. set prop_entry "[string tolower $prop]$delim$tcl_file_path"
  1430. }
  1431. }
  1432. }
  1433. }
  1434. if { $a_global_vars(b_arg_all_props) } {
  1435. lappend prop_info_list $prop_entry
  1436. } else {
  1437. if { $def_val != $cur_val } {
  1438. lappend prop_info_list $prop_entry
  1439. }
  1440. }
  1441. if { $a_global_vars(b_arg_dump_proj_info) } {
  1442. if { ([string equal -nocase $prop "top_file"] ||
  1443. [string equal -nocase $prop "target_constrs_file"] ||
  1444. [string equal -nocase $prop "target_ucf"] ) && [string equal $type "fileset"] } {
  1445. # fix path
  1446. set file $cur_val
  1447. set srcs_dir "${proj_name}.srcs"
  1448. set file_dirs [split [string trim [file normalize [string map {\\ /} $file]]] "/"]
  1449. set src_file [join [lrange $file_dirs [lsearch -exact $file_dirs "$srcs_dir"] end] "/"]
  1450. set cur_val "\$PSRCDIR/$src_file"
  1451. }
  1452. puts $a_global_vars(def_val_fh) "$prop:($prop_type) DEFAULT_VALUE ($def_val)==CURRENT_VALUE ($cur_val)"
  1453. puts $a_global_vars(dp_fh) "${dump_prop_name}=$cur_val"
  1454. }
  1455. }
  1456. if { {fileset} == $type } {
  1457. set fs_type [get_property fileset_type [get_filesets $tcl_obj]]
  1458. if { {SimulationSrcs} == $fs_type } {
  1459. if { ![get_property is_readonly [current_project]] } {
  1460. add_simulator_props $get_what $tcl_obj prop_info_list
  1461. }
  1462. }
  1463. }
  1464. # write properties now
  1465. write_properties $prop_info_list $get_what $tcl_obj $delim
  1466. }
  1467. proc add_simulator_props { get_what tcl_obj prop_info_list_arg } {
  1468. # Summary: write file and file properties
  1469. # This helper command is used to script help.
  1470. # Argument Usage:
  1471. # Return Value:
  1472. # none
  1473. upvar $prop_info_list_arg prop_info_list
  1474. set target_simulator [get_property target_simulator [current_project]]
  1475. set simulators [get_simulators]
  1476. foreach simulator [get_simulators] {
  1477. if { $target_simulator == $simulator } { continue }
  1478. set_property target_simulator $simulator [current_project]
  1479. set prefix [string tolower [lindex [split $simulator {.}] 0]]
  1480. write_simulator_props $prefix $get_what $tcl_obj prop_info_list
  1481. }
  1482. set_property target_simulator $target_simulator [current_project]
  1483. }
  1484. proc write_simulator_props { prefix get_what tcl_obj prop_info_list_arg } {
  1485. # Summary: write non-default simulator properties
  1486. # Argument Usage:
  1487. # Return Value:
  1488. # none
  1489. upvar $prop_info_list_arg prop_info_list
  1490. variable a_global_vars
  1491. variable l_script_data
  1492. set read_only_props [rdi::get_attr_specs -class [get_property class $tcl_obj] -filter {is_readonly}]
  1493. foreach prop [list_property [$get_what $tcl_obj]] {
  1494. if { [lsearch $read_only_props $prop] != -1 } { continue }
  1495. if { [is_deprecated_property $prop] } { continue }
  1496. set sim_prefix [string tolower [lindex [split $prop {.}] 0]]
  1497. if { $prefix != $sim_prefix } { continue }
  1498. set attr_spec [rdi::get_attr_specs -quiet $prop -object [$get_what $tcl_obj]]
  1499. if { {} == $attr_spec } {
  1500. set prop_lower [string tolower $prop]
  1501. set attr_spec [rdi::get_attr_specs -quiet $prop_lower -object [$get_what $tcl_obj]]
  1502. }
  1503. set prop_type [get_property type $attr_spec]
  1504. set def_val [list_property_value -default $prop $tcl_obj]
  1505. set cur_val [get_property $prop $tcl_obj]
  1506. set cur_val [get_target_bool_val $def_val $cur_val]
  1507. set prop_entry "[string tolower $prop]#[get_property $prop [$get_what $tcl_obj]]"
  1508. if { $def_val != $cur_val } {
  1509. lappend prop_info_list $prop_entry
  1510. }
  1511. }
  1512. }
  1513. proc is_deprecated_property { property } {
  1514. # Summary: filter old properties
  1515. # Argument Usage:
  1516. # Return Value:
  1517. set property [string tolower $property]
  1518. if { [string equal $property "board"] ||
  1519. [string equal $property "verilog_dir"] ||
  1520. [string equal $property "compxlib.compiled_library_dir"] ||
  1521. [string equal $property "runtime"] ||
  1522. [string equal $property "unit_under_test"] ||
  1523. [string equal $property "xelab.snapshot"] ||
  1524. [string equal $property "xelab.debug_level"] ||
  1525. [string equal $property "xelab.relax"] ||
  1526. [string equal $property "xelab.mt_level"] ||
  1527. [string equal $property "xelab.load_glbl"] ||
  1528. [string equal $property "xelab.rangecheck"] ||
  1529. [string equal $property "xelab.sdf_delay"] ||
  1530. [string equal $property "xelab.unifast"] ||
  1531. [string equal $property "xelab.nosort"] ||
  1532. [string equal $property "xelab.more_options"] ||
  1533. [string equal $property "xsim.view"] ||
  1534. [string equal $property "xsim.wdb"] ||
  1535. [string equal $property "xsim.saif"] ||
  1536. [string equal $property "xsim.tclbatch"] ||
  1537. [string equal $property "xsim.more_options"] ||
  1538. [string equal $property "modelsim.custom_do"] ||
  1539. [string equal $property "modelsim.custom_udo"] ||
  1540. [string equal $property "modelsim.vhdl_syntax"] ||
  1541. [string equal $property "modelsim.use_explicit_decl"] ||
  1542. [string equal $property "modelsim.log_all_signals"] ||
  1543. [string equal $property "modelsim.sdf_delay"] ||
  1544. [string equal $property "modelsim.saif"] ||
  1545. [string equal $property "modelsim.incremental"] ||
  1546. [string equal $property "modelsim.unifast"] ||
  1547. [string equal $property "modelsim.64bit"] ||
  1548. [string equal $property "modelsim.vsim_more_options"] ||
  1549. [string equal $property "modelsim.vlog_more_options"] ||
  1550. [string equal $property "modelsim.vcom_more_options"] ||
  1551. [string equal $property "xsim.simulate.uut"] ||
  1552. [string equal $property "modelsim.simulate.uut"] ||
  1553. [string equal $property "questa.simulate.uut"] ||
  1554. [string equal $property "ies.simulate.uut"] ||
  1555. [string equal $property "vcs.simulate.uut"] ||
  1556. [string equal $property "platform.xocc_link_xp_switches_default"] ||
  1557. [string equal $property "platform.xocc_compile_xp_switches_default"] ||
  1558. [string equal $property "dsa"] ||
  1559. [regexp {dsa\..*} $property ] } {
  1560. return true
  1561. }
  1562. return false
  1563. }
  1564. proc read_props_to_exclude {} {
  1565. # Summary: read properties that need to be excluded from writing into the script file generated by write_project_tcl command.
  1566. # Argument Usage:
  1567. # Return Value:
  1568. # none
  1569. variable a_global_vars
  1570. set objPropList [get_param project.wpt.excludeProperties -quiet]
  1571. foreach objPropEle $objPropList {
  1572. set objPropSplits [split $objPropEle ":"]
  1573. if { [llength $objPropSplits] == 2 } {
  1574. dict lappend a_global_vars(excludePropDict) [lindex $objPropSplits 0] [lindex $objPropSplits 1]
  1575. }
  1576. }
  1577. }
  1578. #This is a short term fix to address the need of exluding properties of certain object from getting written into the script file
  1579. #In this fix to execlude a property for an object comparison is done based on string representation of the tcl object.
  1580. #There is a chance that there are two Tcl objects with same string representaion in that case it all comes down to property name.
  1581. #If property name is also same then, then it could produce undefined results.
  1582. #This fix takes an assumption that object_string_rep:property is unique in the list.
  1583. proc is_excluded_property { obj property } {
  1584. # Summary: To determine if a property of an object is excluded from writing into the script file or not.
  1585. # Argument Usage:
  1586. # Return Value:
  1587. # none
  1588. variable a_global_vars
  1589. foreach _obj [dict keys $a_global_vars(excludePropDict)] {
  1590. if { $_obj == $obj } {
  1591. set _property [dict get $a_global_vars(excludePropDict) $_obj]
  1592. if { [lsearch -nocase $_property $property] != -1 } {
  1593. return true
  1594. }
  1595. }
  1596. }
  1597. return false
  1598. }
  1599. proc getBdforMangedWrapper { fs_name wraperfile proj_name path_dirs } {
  1600. variable a_global_vars
  1601. set srcs_index [lsearch -exact $path_dirs "$proj_name.srcs"]
  1602. if { $srcs_index == -1} {
  1603. #check for .gen directory
  1604. set srcs_index [lsearch -exact $path_dirs "$proj_name.gen"]
  1605. }
  1606. set src_file [join [lrange $path_dirs $srcs_index+1 end] "/"]
  1607. set wrapperName [file tail $wraperfile]
  1608. set wrapperNameNoExtension [file rootname $wrapperName]
  1609. set designName [string range $wrapperNameNoExtension 0 [expr {[string last "_wrapper" $wrapperNameNoExtension] - 1}]]
  1610. if { $designName == "" } {
  1611. #Not a wrapper file
  1612. return
  1613. }
  1614. set manged_file_path "$fs_name/bd/$designName/hdl/$wrapperName"
  1615. set manged_file_path [string trim $manged_file_path "\""]
  1616. if { $src_file != $manged_file_path || [get_files $designName.bd] == "" } {
  1617. #Wrapper file is not managed by project
  1618. return
  1619. }
  1620. return [list $designName $wrapperName]
  1621. }
  1622. proc write_files { proj_dir proj_name tcl_obj type } {
  1623. # Summary: write file and file properties
  1624. # This helper command is used to script help.
  1625. # Argument Usage:
  1626. # Return Value:
  1627. # none
  1628. variable a_global_vars
  1629. variable l_script_data
  1630. variable l_bd_wrapper
  1631. set l_local_file_list [list]
  1632. set l_remote_file_list [list]
  1633. # return if empty fileset
  1634. if {[llength [get_files -quiet -of_objects [get_filesets $tcl_obj]]] == 0 } {
  1635. lappend l_script_data "# Empty (no sources present)\n"
  1636. return
  1637. }
  1638. set fs_name [get_filesets $tcl_obj]
  1639. set make_wrapper_list [list]
  1640. set import_coln [list]
  1641. set add_file_coln [list]
  1642. # Create BD wrapper file names (without extensions) to be skipped later
  1643. set bd_wrapper_names {}
  1644. foreach bd_file [get_files *.bd] { lappend bd_wrapper_names [file rootname [file tail $bd_file]]_wrapper }
  1645. set bc_managed_fs_filter "IS_BLOCK_CONTAINER_MANAGED == 0"
  1646. foreach file [get_files -quiet -norecurse -of_objects [get_filesets $tcl_obj] -filter $bc_managed_fs_filter] {
  1647. if { [file extension $file] == ".xcix" } { continue }
  1648. # Skip direct import/add of BD files if -use_bd_files is not provided
  1649. if { [file extension $file] == ".bd" && !$a_global_vars(b_arg_use_bd_files) } { continue }
  1650. # Skip generated BD file wrappers
  1651. if { [lsearch -exact $bd_wrapper_names [file rootname [file tail $file]]] != -1 } { continue }
  1652. set path_dirs [split [string trim [file normalize [string map {\\ /} $file]]] "/"]
  1653. set srcs_index [lsearch -exact $path_dirs "$proj_name.srcs"]
  1654. set src_file [join [lrange $path_dirs $srcs_index+1 end] "/"]
  1655. # fetch first object
  1656. set file_object [lindex [get_files -quiet -of_objects [get_filesets $fs_name] [list $file]] 0]
  1657. set file_props [list_property $file_object]
  1658. if { [lsearch $file_props "IMPORTED_FROM"] != -1 } {
  1659. # import files
  1660. set imported_path [get_property "imported_from" $file]
  1661. set rel_file_path [get_relative_file_path_for_source $file [get_script_execution_dir]]
  1662. set proj_file_path "\$\{origin_dir\}/$rel_file_path"
  1663. set file "\"[file normalize $proj_dir/${proj_name}.srcs/$src_file]\""
  1664. if { $a_global_vars(b_arg_no_copy_srcs) } {
  1665. # add to the local collection
  1666. lappend l_remote_file_list $file
  1667. if { $a_global_vars(b_absolute_path) || [need_abs_path $file] } {
  1668. lappend add_file_coln "$file"
  1669. } else {
  1670. lappend add_file_coln "\[file normalize \"$proj_file_path\"\]"
  1671. }
  1672. } else {
  1673. # add to the import collection
  1674. lappend l_local_file_list $file
  1675. if { $a_global_vars(b_absolute_path) || [need_abs_path $file] } {
  1676. lappend import_coln "$file"
  1677. } else {
  1678. lappend import_coln "\[file normalize \"$proj_file_path\"\]"
  1679. }
  1680. }
  1681. } else {
  1682. set file "\"$file\""
  1683. set designName ""
  1684. set wrapperName ""
  1685. set bd_file ""
  1686. set design_wrapperName [getBdforMangedWrapper $fs_name $file $proj_name $path_dirs]
  1687. if { [llength $design_wrapperName] == 2} {
  1688. set designName [lindex $design_wrapperName 0]
  1689. set wrapperName [lindex $design_wrapperName 1]
  1690. }
  1691. if { $designName != "" } {
  1692. set wrapper_file ""
  1693. # add to the import collection
  1694. if { $a_global_vars(b_absolute_path)|| [need_abs_path $file] } {
  1695. set wrapper_file $file
  1696. } else {
  1697. set file_no_quotes [string trim $file "\""]
  1698. set org_file_path "\$\{origin_dir\}/[get_relative_file_path_for_source $file_no_quotes [get_script_execution_dir]]"
  1699. set wrapper_file "\[file normalize \"$org_file_path\" \]"
  1700. }
  1701. # this is a wrapper file
  1702. if { $a_global_vars(b_arg_use_bd_files) } {
  1703. set pair_fileset_designame [list]
  1704. lappend pair_fileset_designame $wrapper_file
  1705. lappend pair_fileset_designame $designName
  1706. lappend make_wrapper_list $pair_fileset_designame
  1707. } else {
  1708. set fileset_designame_wrappername [list]
  1709. lappend fileset_designame_wrappername $fs_name
  1710. lappend fileset_designame_wrappername $designName
  1711. lappend fileset_designame_wrappername $wrapper_file
  1712. lappend l_bd_wrapper $fileset_designame_wrappername
  1713. }
  1714. } elseif { [is_local_to_project $file] } {
  1715. # is local? add to local project, add to collection and then import this collection by default unless -no_copy_sources is specified
  1716. if { $a_global_vars(b_arg_dump_proj_info) } {
  1717. set src_file "\$PSRCDIR/$src_file"
  1718. }
  1719. # add to the import collection
  1720. if { $a_global_vars(b_absolute_path)|| [need_abs_path $file] } {
  1721. lappend import_coln $file
  1722. } else {
  1723. set file_no_quotes [string trim $file "\""]
  1724. set org_file_path "\$\{origin_dir\}/[get_relative_file_path_for_source $file_no_quotes [get_script_execution_dir]]"
  1725. lappend import_coln "\[file normalize \"$org_file_path\" \]"
  1726. }
  1727. lappend l_local_file_list $file
  1728. } else {
  1729. if {$a_global_vars(b_absolute_path) || [need_abs_path $file] } {
  1730. lappend add_file_coln [string trim $file "\""]
  1731. } else {
  1732. set file_no_quotes [string trim $file "\""]
  1733. set org_file_path "\$\{origin_dir\}/[get_relative_file_path_for_source $file_no_quotes [get_script_execution_dir]]"
  1734. lappend add_file_coln "\[file normalize \"$org_file_path\"\]"
  1735. }
  1736. set file_no_quotes [string trim $file "\""]
  1737. set rel_file_path \"[get_relative_file_path_for_source $file_no_quotes [get_script_execution_dir]]\"
  1738. lappend l_remote_file_list $rel_file_path
  1739. }
  1740. }
  1741. }
  1742. # set flag that local sources were found and print warning at the end
  1743. if { (!$a_global_vars(b_local_sources)) && ([llength l_local_file_list] > 0) } {
  1744. set a_global_vars(b_local_sources) 1
  1745. }
  1746. if {[llength $add_file_coln]>0} {
  1747. lappend l_script_data "set files \[list \\"
  1748. foreach file $add_file_coln {
  1749. lappend l_script_data " $file \\"
  1750. }
  1751. lappend l_script_data "\]"
  1752. lappend l_script_data "add_files -norecurse -fileset \$obj \$files"
  1753. lappend l_script_data ""
  1754. }
  1755. # now import local files if -no_copy_sources is not specified
  1756. if { [llength $import_coln] > 0 } {
  1757. if { ! $a_global_vars(b_arg_no_copy_srcs)} {
  1758. lappend l_script_data "# Import local files from the original project"
  1759. lappend l_script_data "set files \[list \\"
  1760. foreach ifile $import_coln {
  1761. lappend l_script_data " $ifile\\"
  1762. }
  1763. lappend l_script_data "\]"
  1764. # is this a IP block fileset? if yes, import files into current source fileset
  1765. if { [is_ip_fileset $tcl_obj] } {
  1766. lappend l_script_data "set imported_files \[import_files -fileset [current_fileset -srcset] \$files\]"
  1767. } else {
  1768. lappend l_script_data "set imported_files \[import_files -fileset $tcl_obj \$files\]"
  1769. }
  1770. } else {
  1771. lappend l_script_data "# Add local files from the original project (-no_copy_sources specified)"
  1772. lappend l_script_data "set files \[list \\"
  1773. foreach ifile $import_coln {
  1774. lappend l_script_data " $ifile\\"
  1775. }
  1776. lappend l_script_data "\]"
  1777. # is this a IP block fileset? if yes, add files into current source fileset
  1778. if { [is_ip_fileset $tcl_obj] } {
  1779. lappend l_script_data "set added_files \[add_files -fileset [current_fileset -srcset] \$files\]"
  1780. } else {
  1781. lappend l_script_data "set added_files \[add_files -fileset $tcl_obj \$files\]"
  1782. }
  1783. }
  1784. lappend l_script_data ""
  1785. }
  1786. if {[llength $make_wrapper_list]>0} {
  1787. lappend l_script_data "#call make_wrapper to create wrapper files"
  1788. foreach pair_fileset_designame $make_wrapper_list {
  1789. set wrapper_name [lindex $pair_fileset_designame 0]
  1790. set design [lindex $pair_fileset_designame 1]
  1791. lappend l_script_data "if \{ \[get_property IS_LOCKED \[ get_files -norecurse $design.bd\] \] == 1 \} \{"
  1792. lappend l_script_data " import_files -fileset $tcl_obj $wrapper_name"
  1793. lappend l_script_data "\} else \{"
  1794. lappend l_script_data " set wrapper_path \[make_wrapper -fileset $fs_name -files \[ get_files -norecurse $design.bd\] -top\]"
  1795. lappend l_script_data " add_files -norecurse -fileset $fs_name \$wrapper_path"
  1796. lappend l_script_data "\}"
  1797. lappend l_script_data ""
  1798. }
  1799. lappend l_script_data ""
  1800. }
  1801. # write fileset file properties for remote files (added sources)
  1802. write_fileset_file_properties $tcl_obj $fs_name $proj_dir $l_remote_file_list "remote"
  1803. # write fileset file properties for local files (imported sources)
  1804. write_fileset_file_properties $tcl_obj $fs_name $proj_dir $l_local_file_list "local"
  1805. }
  1806. proc write_constrs { proj_dir proj_name tcl_obj type } {
  1807. # Summary: write constrs fileset files and properties
  1808. # Argument Usage:
  1809. # Return Value:
  1810. # none
  1811. variable a_global_vars
  1812. variable l_script_data
  1813. set fs_name [get_filesets $tcl_obj]
  1814. # return if empty fileset
  1815. if {[llength [get_files -quiet -of_objects [get_filesets $tcl_obj]]] == 0 } {
  1816. lappend l_script_data "# Empty (no sources present)\n"
  1817. return
  1818. }
  1819. foreach file [get_files -quiet -norecurse -of_objects [get_filesets $tcl_obj]] {
  1820. lappend l_script_data "# Add/Import constrs file and set constrs file properties"
  1821. set constrs_file {}
  1822. set file_category {}
  1823. set path_dirs [split [string trim [file normalize [string map {\\ /} $file]]] "/"]
  1824. set begin [lsearch -exact $path_dirs "$proj_name.srcs"]
  1825. set src_file [join [lrange $path_dirs $begin+1 end] "/"]
  1826. set file_object [lindex [get_files -quiet -of_objects [get_filesets $fs_name] [list $file]] 0]
  1827. set file_props [list_property $file_object]
  1828. # constrs sources imported?
  1829. if { [lsearch $file_props "IMPORTED_FROM"] != -1 } {
  1830. set imported_path [get_property "imported_from" $file]
  1831. set rel_file_path [get_relative_file_path_for_source $file [get_script_execution_dir]]
  1832. set proj_file_path \$\{origin_dir\}/$rel_file_path
  1833. set file "\"[file normalize $proj_dir/${proj_name}.srcs/$src_file]\""
  1834. # donot copy imported constrs in new project? set it as remote file in new project.
  1835. if { $a_global_vars(b_arg_no_copy_srcs) } {
  1836. set constrs_file $file
  1837. set file_category "remote"
  1838. if { $a_global_vars(b_absolute_path) || [need_abs_path $imported_path] } {
  1839. add_constrs_file "$file"
  1840. } else {
  1841. set str "\"\[file normalize $proj_file_path\]\""
  1842. add_constrs_file $str
  1843. }
  1844. } else {
  1845. # copy imported constrs in new project. Set it as local file in new project.
  1846. set constrs_file $file
  1847. set file_category "local"
  1848. if { $a_global_vars(b_absolute_path) || [need_abs_path $file] } {
  1849. import_constrs_file $tcl_obj "$file"
  1850. } else {
  1851. set str "\"\[file normalize $proj_file_path\]\""
  1852. import_constrs_file $tcl_obj $str
  1853. }
  1854. }
  1855. } else {
  1856. # constrs sources were added, so check if these are local or added from remote location
  1857. set file "\"$file\""
  1858. set constrs_file $file
  1859. # is added constrs local to the project? import it in the new project and set it as local in the new project
  1860. if { [is_local_to_project $file] } {
  1861. # file is added from within project, so set it as local in the new project
  1862. set file_category "local"
  1863. if { $a_global_vars(b_arg_dump_proj_info) } {
  1864. set src_file "\$PSRCDIR/$src_file"
  1865. }
  1866. set file_no_quotes [string trim $file "\""]
  1867. set org_file_path "\$origin_dir/[get_relative_file_path_for_source $file_no_quotes [get_script_execution_dir]]"
  1868. set str "\"\[file normalize \"$org_file_path\"\]\""
  1869. if { $a_global_vars(b_arg_no_copy_srcs)} {
  1870. add_constrs_file "$str"
  1871. } else {
  1872. import_constrs_file $tcl_obj $str
  1873. }
  1874. } else {
  1875. # file is added from remote location, so set it as remote in the new project
  1876. set file_category "remote"
  1877. # find relative file path of the added constrs if no_copy in the new project
  1878. if { $a_global_vars(b_arg_no_copy_srcs) && (!$a_global_vars(b_absolute_path))&& ![need_abs_path $file] } {
  1879. set file_no_quotes [string trim $file "\""]
  1880. set rel_file_path [get_relative_file_path_for_source $file_no_quotes [get_script_execution_dir]]
  1881. set file_1 "\"\[file normalize \"\$origin_dir/$rel_file_path\"\]\""
  1882. add_constrs_file "$file_1"
  1883. } else {
  1884. add_constrs_file "$file"
  1885. }
  1886. }
  1887. # set flag that local sources were found and print warning at the end
  1888. if { !$a_global_vars(b_local_sources) } {
  1889. set a_global_vars(b_local_sources) 1
  1890. }
  1891. }
  1892. write_constrs_fileset_file_properties $tcl_obj $fs_name $proj_dir $constrs_file $file_category
  1893. }
  1894. }
  1895. proc add_constrs_file { file_str } {
  1896. # Summary: add constrs file
  1897. # This helper command is used to script help.
  1898. # Argument Usage:
  1899. # Return Value:
  1900. # none
  1901. variable a_global_vars
  1902. variable l_script_data
  1903. if { $a_global_vars(b_absolute_path) || [need_abs_path $file_str]} {
  1904. lappend l_script_data "set file $file_str"
  1905. } else {
  1906. if { $a_global_vars(b_arg_no_copy_srcs) } {
  1907. lappend l_script_data "set file $file_str"
  1908. } else {
  1909. set file_no_quotes [string trim $file_str "\""]
  1910. set rel_file_path [get_relative_file_path_for_source $file_no_quotes [get_script_execution_dir]]
  1911. lappend l_script_data "set file \"\[file normalize \"\$origin_dir/$rel_file_path\"\]\""
  1912. }
  1913. }
  1914. lappend l_script_data "set file_added \[add_files -norecurse -fileset \$obj \[list \$file\]\]"
  1915. }
  1916. proc import_constrs_file { tcl_obj file_str } {
  1917. # Summary: import constrs file
  1918. # This helper command is used to script help.
  1919. # Argument Usage:
  1920. # Return Value:
  1921. # none
  1922. variable a_global_vars
  1923. variable l_script_data
  1924. # now import local files if -no_copy_sources is not specified
  1925. if { ! $a_global_vars(b_arg_no_copy_srcs)} {
  1926. lappend l_script_data "set file $file_str"
  1927. lappend l_script_data "set file_imported \[import_files -fileset $tcl_obj \[list \$file\]\]"
  1928. }
  1929. }
  1930. proc write_constrs_fileset_file_properties { tcl_obj fs_name proj_dir file file_category } {
  1931. # Summary: write constrs fileset file properties
  1932. # This helper command is used to script help.
  1933. # Argument Usage:
  1934. # Return Value:
  1935. # none
  1936. variable a_global_vars
  1937. variable l_script_data
  1938. variable l_local_files
  1939. variable l_remote_files
  1940. set file_prop_count 0
  1941. # collect local/remote files for the header section
  1942. if { [string equal $file_category "local"] } {
  1943. lappend l_local_files $file
  1944. } elseif { [string equal $file_category "remote"] } {
  1945. set file_no_quotes [string trim $file "\""]
  1946. set rel_file_path \"[get_relative_file_path_for_source $file_no_quotes [get_script_execution_dir]]\"
  1947. lappend l_remote_files $rel_file_path
  1948. }
  1949. set file [string trim $file "\""]
  1950. # fix file path for local files
  1951. if { [string equal $file_category "local"] } {
  1952. set path_dirs [split [string trim [file normalize [string map {\\ /} $file]]] "/"]
  1953. set src_file [join [lrange $path_dirs end-1 end] "/"]
  1954. set src_file [string trimleft $src_file "/"]
  1955. set src_file [string trimleft $src_file "\\"]
  1956. set file $src_file
  1957. }
  1958. set file_object ""
  1959. if { [string equal $file_category "local"] } {
  1960. set file_object [lindex [get_files -quiet -of_objects [get_filesets $fs_name] [list "*$file"]] 0]
  1961. } elseif { [string equal $file_category "remote"] } {
  1962. set file_object [lindex [get_files -quiet -of_objects [get_filesets $fs_name] [list $file]] 0]
  1963. }
  1964. # get the constrs file properties
  1965. set file_props [list_property $file_object]
  1966. set prop_info_list [list]
  1967. set prop_count 0
  1968. foreach file_prop $file_props {
  1969. set is_readonly [get_property is_readonly [rdi::get_attr_specs $file_prop -object $file_object]]
  1970. if { [string equal $is_readonly "1"] } {
  1971. continue
  1972. }
  1973. set prop_type [get_property type [rdi::get_attr_specs $file_prop -object $file_object]]
  1974. set def_val [list_property_value -default $file_prop $file_object]
  1975. set cur_val [get_property $file_prop $file_object]
  1976. # filter special properties
  1977. if { [filter $file_prop $cur_val $file] } { continue }
  1978. # re-align values
  1979. set cur_val [get_target_bool_val $def_val $cur_val]
  1980. set dump_prop_name [string tolower ${fs_name}_file_${file_prop}]
  1981. set prop_entry ""
  1982. if { [string equal $file_category "local"] } {
  1983. set prop_entry "[string tolower $file_prop]#[get_property $file_prop $file_object]"
  1984. } elseif { [string equal $file_category "remote"] } {
  1985. set prop_value_entry [get_property $file_prop $file_object]
  1986. set prop_entry "[string tolower $file_prop]#$prop_value_entry"
  1987. }
  1988. # include all properties?
  1989. if { $a_global_vars(b_arg_all_props) } {
  1990. lappend prop_info_list $prop_entry
  1991. incr prop_count
  1992. } else {
  1993. # include only non-default (default behavior)
  1994. if { $def_val != $cur_val } {
  1995. lappend prop_info_list $prop_entry
  1996. incr prop_count
  1997. }
  1998. }
  1999. if { $a_global_vars(b_arg_dump_proj_info) } {
  2000. puts $a_global_vars(def_val_fh) "[file tail $file]=$file_prop ($prop_type) :DEFAULT_VALUE ($def_val)==CURRENT_VALUE ($cur_val)"
  2001. puts $a_global_vars(dp_fh) "$dump_prop_name=$cur_val"
  2002. }
  2003. }
  2004. # write properties now
  2005. if { $prop_count>0 } {
  2006. if { {remote} == $file_category } {
  2007. if { $a_global_vars(b_absolute_path) || [need_abs_path $file]} {
  2008. lappend l_script_data "set file \"$file\""
  2009. } else {
  2010. lappend l_script_data "set file \"\$origin_dir/[get_relative_file_path_for_source $file [get_script_execution_dir]]\""
  2011. lappend l_script_data "set file \[file normalize \$file\]"
  2012. }
  2013. } else {
  2014. lappend l_script_data "set file \"$file\""
  2015. }
  2016. lappend l_script_data "set file_obj \[get_files -of_objects \[get_filesets $tcl_obj\] \[list \"*\$file\"\]\]"
  2017. set get_what "get_files"
  2018. write_properties $prop_info_list $get_what $tcl_obj
  2019. incr file_prop_count
  2020. }
  2021. if { $file_prop_count == 0 } {
  2022. lappend l_script_data "# None"
  2023. }
  2024. }
  2025. proc write_specified_run { proj_dir proj_name runs } {
  2026. # Summary: write the specified run information
  2027. # This helper command is used to script help.
  2028. # Argument Usage:
  2029. # Return Value:
  2030. # none
  2031. variable a_global_vars
  2032. variable l_script_data
  2033. set get_what "get_runs"
  2034. foreach tcl_obj $runs {
  2035. # is block fileset based run that contains IP? donot create OOC run
  2036. if { [is_ip_run $tcl_obj] } {
  2037. continue
  2038. }
  2039. # fetch run attributes
  2040. set part [get_property part [$get_what $tcl_obj]]
  2041. set parent_run [get_property parent [$get_what $tcl_obj]]
  2042. set src_set [get_property srcset [$get_what $tcl_obj]]
  2043. set constrs_set [get_property constrset [$get_what $tcl_obj]]
  2044. set strategy [get_property strategy [$get_what $tcl_obj]]
  2045. set parent_run_str ""
  2046. if { $parent_run != "" } {
  2047. set parent_run_str " -parent_run $parent_run"
  2048. }
  2049. set fileset_type [get_property fileset_type [get_property srcset [$get_what $tcl_obj]]]
  2050. set isImplRun [get_property is_implementation [$get_what $tcl_obj]]
  2051. set isPRProject [get_property pr_flow [current_project]]
  2052. set def_flow_type_val [list_property_value -default flow [$get_what $tcl_obj]]
  2053. set cur_flow_type_val [get_property flow [$get_what $tcl_obj]]
  2054. set def_strat_type_val [list_property_value -default strategy [$get_what $tcl_obj]]
  2055. set cur_strat_type_val [get_property strategy [$get_what $tcl_obj]]
  2056. set isChildImplRun 0
  2057. if { $isPRProject == 1 && $isImplRun == 1 && $parent_run != "" } {
  2058. set isChildImplRun [get_property is_implementation [$get_what $parent_run]]
  2059. if { $isChildImplRun == 1 } {
  2060. set prConfig [get_property pr_configuration [get_runs $tcl_obj]]
  2061. if { [get_pr_configurations $prConfig] == "" } {
  2062. # review this change. Either skip this run creation or flag error while sourcing script...???
  2063. continue
  2064. }
  2065. }
  2066. }
  2067. set cmd_str " create_run -name $tcl_obj -part $part -flow {$cur_flow_type_val} -strategy \"$cur_strat_type_val\""
  2068. set retVal [get_param project.enableReportConfiguration]
  2069. set report_strategy ""
  2070. if { $retVal == 1 } {
  2071. set cmd_str " $cmd_str -report_strategy {No Reports}"
  2072. set report_strategy [get_property report_strategy $tcl_obj]
  2073. }
  2074. if { $isChildImplRun == 1 } {
  2075. set cmd_str " $cmd_str -pr_config $prConfig"
  2076. }
  2077. lappend l_script_data "# Create '$tcl_obj' run (if not found)"
  2078. lappend l_script_data "if \{\[string equal \[get_runs -quiet $tcl_obj\] \"\"\]\} \{"
  2079. lappend l_script_data "$cmd_str -constrset $constrs_set$parent_run_str"
  2080. lappend l_script_data "\} else \{"
  2081. lappend l_script_data " set_property strategy \"$cur_strat_type_val\" \[get_runs $tcl_obj\]"
  2082. lappend l_script_data " set_property flow \"$cur_flow_type_val\" \[get_runs $tcl_obj\]"
  2083. lappend l_script_data "\}"
  2084. if { ($isImplRun == 1) && ($isPRProject == 1 && $isChildImplRun == 0) && ({DesignSrcs} == $fileset_type) } {
  2085. set prConfig [get_property pr_configuration [get_runs $tcl_obj]]
  2086. if { [get_pr_configurations $prConfig] != "" } {
  2087. lappend l_script_data "set_property pr_configuration $prConfig \[get_runs $tcl_obj\]"
  2088. }
  2089. }
  2090. write_report_strategy $tcl_obj $report_strategy
  2091. lappend l_script_data "set obj \[$get_what $tcl_obj\]"
  2092. write_props $proj_dir $proj_name $get_what $tcl_obj "run"
  2093. }
  2094. }
  2095. proc get_fileset_type_switch { fileset_type } {
  2096. # Summary: Return the fileset type switch for a given fileset
  2097. # Argument Usage:
  2098. # Return Value:
  2099. # Fileset type switch name
  2100. variable a_fileset_types
  2101. set fs_switch ""
  2102. foreach {fs_data} $a_fileset_types {
  2103. set fs_type [lindex $fs_data 0]
  2104. if { [string equal -nocase $fileset_type $fs_type] } {
  2105. set fs_switch [lindex $fs_data 1]
  2106. set fs_switch "-$fs_switch"
  2107. break
  2108. }
  2109. }
  2110. return $fs_switch
  2111. }
  2112. proc get_target_bool_val { def_val cur_val } {
  2113. # Summary: Resolve current boolean property value wrt its default value
  2114. # Argument Usage:
  2115. # Return Value:
  2116. # Resolved boolean value
  2117. set target_val $cur_val
  2118. if { [string equal $def_val "false"] && [string equal $cur_val "0"] } { set target_val "false" } \
  2119. elseif { [string equal $def_val "true"] && [string equal $cur_val "1"] } { set target_val "true" } \
  2120. elseif { [string equal $def_val "false"] && [string equal $cur_val "1"] } { set target_val "true" } \
  2121. elseif { [string equal $def_val "true"] && [string equal $cur_val "0"] } { set target_val "false" } \
  2122. elseif { [string equal $def_val "{}"] && [string equal $cur_val ""] } { set target_val "{}" }
  2123. return $target_val
  2124. }
  2125. proc write_fileset_file_properties { tcl_obj fs_name proj_dir l_file_list file_category } {
  2126. # Summary:
  2127. # Write fileset file properties for local and remote files
  2128. # Argument Usage:
  2129. # tcl_obj: object to inspect
  2130. # fs_name: fileset name
  2131. # l_file_list: list of files (local or remote)
  2132. # file_category: file catwgory (local or remote)
  2133. # Return Value:
  2134. # none
  2135. variable a_global_vars
  2136. variable l_script_data
  2137. variable l_local_files
  2138. variable l_remote_files
  2139. # is this a IP block fileset? if yes, set current source fileset
  2140. if { [is_ip_fileset $tcl_obj] } {
  2141. lappend l_script_data "# Set '[current_fileset -srcset]' fileset file properties for $file_category files"
  2142. } else {
  2143. lappend l_script_data "# Set '$tcl_obj' fileset file properties for $file_category files"
  2144. }
  2145. set file_prop_count 0
  2146. # collect local/remote files
  2147. foreach file $l_file_list {
  2148. if { [string equal $file_category "local"] } {
  2149. lappend l_local_files $file
  2150. } elseif { [string equal $file_category "remote"] } {
  2151. lappend l_remote_files $file
  2152. } else {}
  2153. }
  2154. foreach file $l_file_list {
  2155. set file [string trim $file "\""]
  2156. # fix file path for local files
  2157. if { [string equal $file_category "local"] } {
  2158. set path_dirs [split [string trim [file normalize [string map {\\ /} $file]]] "/"]
  2159. set src_file [join [lrange $path_dirs end-1 end] "/"]
  2160. set src_file [string trimleft $src_file "/"]
  2161. set src_file [string trimleft $src_file "\\"]
  2162. set file $src_file
  2163. }
  2164. set file_object ""
  2165. if { [string equal $file_category "local"] } {
  2166. set file_object [lindex [get_files -quiet -of_objects [get_filesets $fs_name] [list "*$file"]] 0]
  2167. } elseif { [string equal $file_category "remote"] } {
  2168. set file_object [lindex [get_files -quiet -of_objects [get_filesets $fs_name] [list $file]] 0]
  2169. }
  2170. set file_props [list_property $file_object]
  2171. set prop_info_list [list]
  2172. set prop_count 0
  2173. foreach file_prop $file_props {
  2174. set is_readonly [get_property is_readonly [rdi::get_attr_specs $file_prop -object $file_object]]
  2175. if { [string equal $is_readonly "1"] } {
  2176. continue
  2177. }
  2178. # Fix for CR-939211
  2179. if { ([file extension $file] == ".bd") && ([string equal -nocase $file_prop "generate_synth_checkpoint"] || [string equal -nocase $file_prop "synth_checkpoint_mode"]) } {
  2180. continue
  2181. }
  2182. set prop_type [get_property type [rdi::get_attr_specs $file_prop -object $file_object]]
  2183. set def_val [list_property_value -default $file_prop $file_object]
  2184. set cur_val [get_property $file_prop $file_object]
  2185. # filter special properties
  2186. if { [filter $file_prop $cur_val $file] } { continue }
  2187. # re-align values
  2188. set cur_val [get_target_bool_val $def_val $cur_val]
  2189. set dump_prop_name [string tolower ${fs_name}_file_${file_prop}]
  2190. set prop_entry ""
  2191. if { [string equal $file_category "local"] } {
  2192. set prop_entry "[string tolower $file_prop]#[get_property $file_prop $file_object]"
  2193. } elseif { [string equal $file_category "remote"] } {
  2194. set prop_value_entry [get_property $file_prop $file_object]
  2195. set prop_entry "[string tolower $file_prop]#$prop_value_entry"
  2196. } else {}
  2197. if { $a_global_vars(b_arg_all_props) } {
  2198. lappend prop_info_list $prop_entry
  2199. incr prop_count
  2200. } else {
  2201. if { $def_val != $cur_val } {
  2202. lappend prop_info_list $prop_entry
  2203. incr prop_count
  2204. }
  2205. }
  2206. if { $a_global_vars(b_arg_dump_proj_info) } {
  2207. puts $a_global_vars(def_val_fh) "[file tail $file]=$file_prop ($prop_type) :DEFAULT_VALUE ($def_val)==CURRENT_VALUE ($cur_val)"
  2208. puts $a_global_vars(dp_fh) "$dump_prop_name=$cur_val"
  2209. }
  2210. }
  2211. # write properties now
  2212. if { $prop_count>0 } {
  2213. if { {remote} == $file_category } {
  2214. if { $a_global_vars(b_absolute_path) || [need_abs_path $file]} {
  2215. lappend l_script_data "set file \"$file\""
  2216. } else {
  2217. lappend l_script_data "set file \"\$origin_dir/[get_relative_file_path_for_source $file [get_script_execution_dir]]\""
  2218. lappend l_script_data "set file \[file normalize \$file\]"
  2219. }
  2220. } else {
  2221. lappend l_script_data "set file \"$file\""
  2222. }
  2223. # is this a IP block fileset? if yes, get files from current source fileset
  2224. if { [is_ip_fileset $tcl_obj] } {
  2225. lappend l_script_data "set file_obj \[get_files -of_objects \[get_filesets [current_fileset -srcset]\] \[list \"*\$file\"\]\]"
  2226. } else {
  2227. lappend l_script_data "set file_obj \[get_files -of_objects \[get_filesets $tcl_obj\] \[list \"*\$file\"\]\]"
  2228. }
  2229. set get_what "get_files"
  2230. write_properties $prop_info_list $get_what $tcl_obj
  2231. incr file_prop_count
  2232. }
  2233. }
  2234. if { $file_prop_count == 0 } {
  2235. lappend l_script_data "# None"
  2236. }
  2237. lappend l_script_data ""
  2238. }
  2239. proc get_script_execution_dir { } {
  2240. # Summary: Return script directory path from where the script will be executed
  2241. # Argument Usage:
  2242. # none
  2243. # Return Value:
  2244. # Path to the script direc
  2245. variable a_global_vars
  2246. # default: return script directory path
  2247. set scr_exe_dir $a_global_vars(s_path_to_script_dir)
  2248. # is -path_to_relative specified and the path exists? return this dir
  2249. set rel_to_dir $a_global_vars(s_relative_to)
  2250. if { ("." != $rel_to_dir) } {
  2251. set rel_to_dir [file normalize $rel_to_dir]
  2252. if { [file exists $rel_to_dir] } {
  2253. set scr_exe_dir $rel_to_dir
  2254. }
  2255. }
  2256. return $scr_exe_dir
  2257. }
  2258. # TODO: This is the same as xcs_get_relative_file_path for simulators, see common/utils.tcl
  2259. # Remember to add the 'source .../common/utils.tcl' in the write_project_tcl proc to load the common file
  2260. proc get_relative_file_path_for_source { file_path_to_convert relative_to } {
  2261. # Summary: Get the relative path wrt to path specified
  2262. # Argument Usage:
  2263. # file_path_to_convert: input file to make relative to specfied path
  2264. # Return Value:
  2265. # Relative path wrt the path specified
  2266. variable a_xport_sim_vars
  2267. # make sure we are dealing with a valid relative_to directory. If regular file or is not a directory, get directory
  2268. if { [file isfile $relative_to] || ![file isdirectory $relative_to] } {
  2269. set relative_to [file dirname $relative_to]
  2270. }
  2271. set cwd [file normalize [pwd]]
  2272. if { [file pathtype $file_path_to_convert] eq "relative" } {
  2273. # is relative_to path same as cwd?, just return this path, no further processing required
  2274. if { [string equal $relative_to $cwd] } {
  2275. return $file_path_to_convert
  2276. }
  2277. # the specified path is "relative" but something else, so make it absolute wrt current working dir
  2278. set file_path_to_convert [file join $cwd $file_path_to_convert]
  2279. }
  2280. # is relative_to "relative"? convert to absolute as well wrt cwd
  2281. if { [file pathtype $relative_to] eq "relative" } {
  2282. set relative_to [file join $cwd $relative_to]
  2283. }
  2284. # normalize
  2285. set file_path_to_convert [file normalize $file_path_to_convert]
  2286. set relative_to [file normalize $relative_to]
  2287. set file_path $file_path_to_convert
  2288. set file_comps [file split $file_path]
  2289. set relative_to_comps [file split $relative_to]
  2290. set found_match false
  2291. set index 0
  2292. set fc_comps_len [llength $file_comps]
  2293. set rt_comps_len [llength $relative_to_comps]
  2294. # compare each dir element of file_to_convert and relative_to, set the flag and
  2295. # get the final index till these sub-dirs matched. Break if limit reaches.
  2296. while { [lindex $file_comps $index] == [lindex $relative_to_comps $index] } {
  2297. if { !$found_match } { set found_match true }
  2298. incr index
  2299. if { ($index == $fc_comps_len) || ($index == $rt_comps_len) } {
  2300. break;
  2301. }
  2302. }
  2303. # any common dirs found? convert path to relative
  2304. if { $found_match } {
  2305. set parent_dir_path ""
  2306. set rel_index $index
  2307. # keep traversing the relative_to dirs and build "../" levels
  2308. while { [lindex $relative_to_comps $rel_index] != "" } {
  2309. set parent_dir_path "../$parent_dir_path"
  2310. incr rel_index
  2311. }
  2312. #
  2313. # at this point we have parent_dir_path setup with exact number of sub-dirs to go up
  2314. #
  2315. # now build up part of path which is relative to matched part
  2316. set rel_path ""
  2317. set rel_index $index
  2318. while { [lindex $file_comps $rel_index] != "" } {
  2319. set comps [lindex $file_comps $rel_index]
  2320. if { $rel_path == "" } {
  2321. # first dir
  2322. set rel_path $comps
  2323. } else {
  2324. # append remaining dirs
  2325. set rel_path "${rel_path}/$comps"
  2326. }
  2327. incr rel_index
  2328. }
  2329. # prepend parent dirs, this is the complete resolved path now
  2330. set resolved_path "${parent_dir_path}${rel_path}"
  2331. return $resolved_path
  2332. }
  2333. # no common dirs found, just return the normalized path
  2334. return $file_path
  2335. }
  2336. proc is_ip_fileset { fileset } {
  2337. # Summary: Find IP's if any from the specified fileset and return true if 'generate_synth_checkpoint' is set to 1
  2338. # Argument Usage:
  2339. # fileset: fileset name
  2340. # Return Value:
  2341. # true (1) if success, false (0) otherwise
  2342. # make sure fileset is block fileset type
  2343. set isPRFlow [get_property pr_flow [current_project]]
  2344. set isRMFileset 0
  2345. if { $isPRFlow == 1 } {
  2346. set allReconfigModules [get_reconfig_modules]
  2347. foreach reconfigmodule $allReconfigModules {
  2348. set rmFileset [get_filesets -of_objects [get_reconfig_modules $reconfigmodule]]
  2349. if { [string equal $rmFileset $fileset] } {
  2350. set isRMFileset 1
  2351. break
  2352. }
  2353. }
  2354. }
  2355. if { $isRMFileset == 1 } {
  2356. return false
  2357. }
  2358. if { [is_bc_managed_fileset $fileset] } {
  2359. return false
  2360. }
  2361. if { {BlockSrcs} != [get_property fileset_type [get_filesets $fileset]] } {
  2362. return false
  2363. }
  2364. set ip_filter "FILE_TYPE == \"IP\" || FILE_TYPE==\"Block Designs\""
  2365. set ips [get_files -all -quiet -of_objects [get_filesets $fileset] -filter $ip_filter]
  2366. set b_found false
  2367. foreach ip $ips {
  2368. if { [get_property generate_synth_checkpoint [lindex [get_files -quiet -all [list "$ip"]] 0]] } {
  2369. set b_found true
  2370. break
  2371. }
  2372. }
  2373. if { $b_found } {
  2374. return true
  2375. }
  2376. return false
  2377. }
  2378. proc is_bc_managed_fileset { fileset } {
  2379. # Summary: Determine if the fileset is managed by Block Container
  2380. # Argument Usage:
  2381. # fileset: fileset name
  2382. # Return Value:
  2383. # true (1) if the fileset contains a BD that is managed by Block Container, false (0) otherwise
  2384. # make sure fileset is block fileset type
  2385. if { {BlockSrcs} != [get_property fileset_type [get_filesets $fileset]] } {
  2386. return false
  2387. }
  2388. set bc_managed_fs_filter "IS_BLOCK_CONTAINER_MANAGED == 1"
  2389. if {[llength [get_files -norecurse -quiet -of_objects [get_filesets $fileset] -filter $bc_managed_fs_filter]] == 1} {
  2390. return true
  2391. }
  2392. return false
  2393. }
  2394. proc is_proxy_ip_fileset { fileset } {
  2395. # Summary: Determine if the fileset is an OOC run for a proxy IP that has a parent composite
  2396. # Argument Usage:
  2397. # fileset: fileset name
  2398. # Return Value:
  2399. # true (1) if the fileset contains an IP at its root with a parent composite, false (0) otherwise
  2400. # make sure fileset is block fileset type
  2401. if { {BlockSrcs} != [get_property fileset_type [get_filesets $fileset]] } {
  2402. return false
  2403. }
  2404. set ip_with_parent_filter "FILE_TYPE == IP && PARENT_COMPOSITE_FILE != \"\""
  2405. if {[llength [get_files -norecurse -quiet -of_objects [get_filesets $fileset] -filter $ip_with_parent_filter]] == 1} {
  2406. return true
  2407. }
  2408. return false
  2409. }
  2410. proc is_ip_run { run } {
  2411. # Summary: Find IP's if any from the fileset linked with the block fileset run
  2412. # Argument Usage:
  2413. # run: run name
  2414. # Return Value:
  2415. # true (1) if success, false (0) otherwise
  2416. set fileset [get_property srcset [get_runs $run]]
  2417. return [is_ip_fileset $fileset]
  2418. }
  2419. proc is_win_os {} {
  2420. # Summary: Determine if OS is Windows
  2421. # Return Value:
  2422. # true (1) if windows, false (0) otherwise
  2423. set os [lindex $::tcl_platform(os) 0]
  2424. set plat [lindex $::tcl_platform(platform) 0]
  2425. if { [string compare -nocase -length 3 $os "win"] == 0 ||
  2426. [string compare -nocase -length 3 $plat "win"] == 0 } {
  2427. return true
  2428. } else { return false }
  2429. }
  2430. proc need_abs_path { src } {
  2431. # Summary: Determine if src provided is in a different network mount than execution directory
  2432. # Argument Usage:
  2433. # src: source file to check
  2434. # Return Value:
  2435. # true (1) if src is in a different drive than script execution directory, false (0) otherwise
  2436. variable a_os
  2437. if { $a_os eq "win" } {
  2438. set src_path [file normalize [string trim $src "\""]]
  2439. set ref_path [file normalize [get_script_execution_dir]]
  2440. if { [string compare -nocase -length 2 $src_path $ref_path] != 0 } {
  2441. return true;
  2442. }
  2443. }
  2444. return false
  2445. }
  2446. proc wr_dashboards { proj_dir proj_name } {
  2447. # Summary: write dashboards and properties
  2448. # This helper command is used to script help.
  2449. # Argument Usage:
  2450. # proj_name: project name
  2451. # Return Value:
  2452. # None
  2453. # get current dash board
  2454. # get all dash boards
  2455. # For each dash boards
  2456. # create dash board
  2457. write_specified_dashboard $proj_dir $proj_name
  2458. }
  2459. proc write_specified_gadget { proj_dir proj_name gadget } {
  2460. # Summary: write the specified gadget
  2461. # This helper command is used to script help.
  2462. # Argument Usage:
  2463. # Return Value:
  2464. # none
  2465. variable l_script_data
  2466. set gadgetName [get_property name [get_dashboard_gadgets [list "$gadget"]]]
  2467. set gadgetType [get_property type [get_dashboard_gadgets [list "$gadget"]]]
  2468. set cmd_str "create_dashboard_gadget -name {$gadgetName} -type $gadgetType"
  2469. lappend l_script_data "# Create '$gadgetName' gadget (if not found)"
  2470. lappend l_script_data "if \{\[string equal \[get_dashboard_gadgets \[ list \"$gadget\" \] \] \"\"\]\} \{"
  2471. lappend l_script_data "$cmd_str"
  2472. lappend l_script_data "\}"
  2473. lappend l_script_data "set obj \[get_dashboard_gadgets \[ list \"$gadget\" \] \]"
  2474. set tcl_obj [get_dashboard_gadgets [list "$gadget"] ]
  2475. set get_what "get_dashboard_gadgets "
  2476. write_props $proj_dir $proj_name $get_what $tcl_obj "gadget" "$"
  2477. }
  2478. proc write_specified_dashboard { proj_dir proj_name } {
  2479. # Summary: write the specified dashboard
  2480. # This helper command is used to script help.
  2481. # Argument Usage:
  2482. # Return Value:
  2483. # none
  2484. variable l_script_data
  2485. #Create map of gadgets wrt to their position, so that gadget position can be restored.
  2486. set gadgetPositionMap [dict create]
  2487. ##get gadgets of this dashboard
  2488. set gadgets [get_dashboard_gadgets ]
  2489. foreach gd $gadgets {
  2490. write_specified_gadget $proj_dir $proj_name $gd
  2491. set gadgetCol [get_property COL [get_dashboard_gadgets [list "$gd"]]]
  2492. set gadgetRow [get_property ROW [get_dashboard_gadgets [list "$gd"]]]
  2493. dict set gadgetPositionMap $gadgetCol $gadgetRow $gd
  2494. }
  2495. #if current dashboard is "default_dashboard"
  2496. #check if the above "gadgets" variable has all the default_gadgets, if any default gadget is not there in "gadgets" variable, it means user has deleted those gadgets but as part of create_project, all the default gadgets are created. So we have to delete the gadgets which user has deleted.
  2497. set default_gadgets {"drc_1" "methodology_1" "power_1" "timing_1" "utilization_1" "utilization_2"}
  2498. foreach dgd $default_gadgets {
  2499. #if dgd is not in gadgets, then delete dgd
  2500. if {$dgd ni $gadgets } {
  2501. lappend l_script_data "# Delete the gadget '$dgd' "
  2502. lappend l_script_data "if \{\[string equal \[get_dashboard_gadgets \[ list \"$dgd\" \] \] \"$dgd\"\]\} \{"
  2503. set cmd_str "delete_dashboard_gadgets -gadgets $dgd"
  2504. lappend l_script_data "$cmd_str"
  2505. lappend l_script_data "\}"
  2506. }
  2507. }
  2508. foreach col [lsort [dict keys $gadgetPositionMap]] {
  2509. set rowDict [dict get $gadgetPositionMap $col]
  2510. foreach row [lsort [dict keys $rowDict]] {
  2511. set gadgetName [dict get $rowDict $row]
  2512. set cmd_str "move_dashboard_gadget -name {$gadgetName} -row $row -col $col"
  2513. lappend l_script_data "$cmd_str"
  2514. }
  2515. }
  2516. }
  2517. proc wr_bc_managed_rm_files { proj_dir proj_name } {
  2518. # Summary: write bc managed reconfig module files
  2519. # This helper command is used to script help.
  2520. # Argument Usage:
  2521. # proj_name: project name
  2522. # Return Value:
  2523. if { [get_property pr_flow [current_project]] == 0 } {
  2524. return
  2525. }
  2526. set partitionDefs [get_partition_defs -filter "IS_BLOCK_CONTAINER_MANAGED == 1"]
  2527. if { [llength $partitionDefs] == 0 } {
  2528. return
  2529. }
  2530. set reconfigModules [get_reconfig_modules -of_objects $partitionDefs]
  2531. foreach rm $reconfigModules {
  2532. write_reconfigmodule_files $proj_dir $proj_name $rm
  2533. }
  2534. }
  2535. proc wr_prflow { proj_dir proj_name } {
  2536. # Summary: write partial reconfiguration and properties
  2537. # This helper command is used to script help.
  2538. # Argument Usage:
  2539. # proj_name: project name
  2540. # Return Value:
  2541. # None
  2542. if { [get_property pr_flow [current_project]] == 0 } {
  2543. return
  2544. }
  2545. # write below properties only if it's a pr project
  2546. wr_pdefs $proj_dir $proj_name
  2547. wr_reconfigModules $proj_dir $proj_name
  2548. #wr_prConf $proj_dir $proj_name
  2549. }
  2550. proc wr_pdefs { proj_dir proj_name } {
  2551. # Summary: write partial reconfiguration and properties
  2552. # This helper command is used to script help.
  2553. # Argument Usage:
  2554. # proj_name: project name
  2555. # Return Value:
  2556. # None
  2557. # write pDef i.e. create partition def
  2558. set partitionDefs [get_partition_defs -filter "IS_BLOCK_CONTAINER_MANAGED == 0"]
  2559. foreach partitionDef $partitionDefs {
  2560. write_specified_partition_definition $proj_dir $proj_name $partitionDef
  2561. }
  2562. }
  2563. proc write_specified_partition_definition { proj_dir proj_name pDef } {
  2564. # Summary: write the specified partition definition
  2565. # This helper command is used to script help.
  2566. # Argument Usage:
  2567. # Return Value:
  2568. # none
  2569. variable l_script_data
  2570. set get_what "get_partition_defs"
  2571. set pdefName [get_property name [$get_what $pDef]]
  2572. set moduleName [get_property module_name [$get_what $pDef]]
  2573. set pdef_library [get_property library [$get_what $pDef]]
  2574. set default_library [get_property default_lib [current_project]]
  2575. set cmd_str "create_partition_def -name $pdefName -module $moduleName"
  2576. if { ($pdef_library != "") && (![string equal $pdef_library $default_library]) } {
  2577. set cmd_str "$cmd_str -library $pdef_library"
  2578. }
  2579. lappend l_script_data "# Create '$pdefName' partition definition"
  2580. lappend l_script_data "$cmd_str"
  2581. lappend l_script_data "set obj \[$get_what $pDef\]"
  2582. write_props $proj_dir $proj_name $get_what $pDef "partitionDef"
  2583. }
  2584. proc wr_reconfigModules { proj_dir proj_name } {
  2585. # Summary: write reconfiguration modules for RPs
  2586. # This helper command is used to script help.
  2587. # Argument Usage:
  2588. # proj_name: project name
  2589. # Return Value:
  2590. # None
  2591. # Ignore Block Container managed PartionDefs/RMs
  2592. set partitionDefs [get_partition_defs -filter "IS_BLOCK_CONTAINER_MANAGED == 0"]
  2593. if { [llength $partitionDefs] == 0 } {
  2594. return
  2595. }
  2596. # write reconfigurations modules
  2597. set reconfigModules [get_reconfig_modules -of_objects $partitionDefs]
  2598. variable a_global_vars
  2599. # associate a bd with rm to be used with write_specified_reconfig_module
  2600. set bd_rm_map [dict create]
  2601. foreach rm $reconfigModules {
  2602. set rm_bds [get_files -norecurse -quiet -of_objects [get_reconfig_modules $rm] *.bd]
  2603. foreach rm_bd1 $rm_bds {
  2604. dict set bd_rm_map $rm_bd1 $rm
  2605. }
  2606. }
  2607. set done_bds [list]
  2608. foreach rm $reconfigModules {
  2609. set rm_bds [get_files -norecurse -quiet -of_objects [get_reconfig_modules $rm] *.bd]
  2610. # get the dependent bd for a rm and process it first, this is required for 2RP support
  2611. set rm_bd_dep [lindex [get_files -references -quiet -of_objects [get_reconfig_modules $rm] *.bd] 0]
  2612. if {[llength $rm_bd_dep] == 1} {
  2613. if {$rm_bd ni $done_bds} {
  2614. if { !$a_global_vars(b_arg_use_bd_files) } {
  2615. write_bd_as_proc $rm_bd_dep
  2616. }
  2617. set rm1 [dict get $bd_rm_map $rm_bd_dep]
  2618. write_specified_reconfig_module $proj_dir $proj_name $rm1
  2619. lappend done_bds $rm_bd_dep
  2620. }
  2621. }
  2622. foreach rm_bd $rm_bds {
  2623. # process bd only if it has not already been processed
  2624. if {$rm_bd ni $done_bds} {
  2625. if { !$a_global_vars(b_arg_use_bd_files) } {
  2626. write_bd_as_proc $rm_bd
  2627. }
  2628. set rm1 [dict get $bd_rm_map $rm_bd]
  2629. write_specified_reconfig_module $proj_dir $proj_name $rm1
  2630. lappend done_bds $rm_bd
  2631. }
  2632. }
  2633. # when no RM BDs are present
  2634. if {[llength $rm_bds] == 0} {
  2635. write_specified_reconfig_module $proj_dir $proj_name $rm
  2636. }
  2637. }
  2638. }
  2639. proc write_specified_reconfig_module { proj_dir proj_name reconfModule } {
  2640. # Summary: write the specified partial reconfiguration module information
  2641. # This helper command is used to script help.
  2642. # Argument Usage:
  2643. # Return Value:
  2644. # none
  2645. variable l_script_data
  2646. set get_what "get_reconfig_modules"
  2647. # fetch all the run attritubes and properties of passed reconfig modules
  2648. set name [get_property name [$get_what $reconfModule]]
  2649. set partitionDefName [get_property partition_def [$get_what $reconfModule]]
  2650. set isGateLevelSet [get_property is_gate_level [$get_what $reconfModule]]
  2651. lappend l_script_data "# Create '$reconfModule' reconfigurable module"
  2652. lappend l_script_data "set partitionDef \[get_partition_defs $partitionDefName\]"
  2653. if { $isGateLevelSet } {
  2654. set moduleName [get_property module_name [$get_what $reconfModule]]
  2655. if { $moduleName == "" } {
  2656. return
  2657. }
  2658. lappend l_script_data "create_reconfig_module -name $name -top $moduleName -partition_def \$partitionDef -gate_level"
  2659. } else {
  2660. lappend l_script_data "create_reconfig_module -name $name -partition_def \$partitionDef"
  2661. }
  2662. # write default_rm property for pDef if RM and its corresponding property for pDef->defaultRM is same
  2663. set defaultRM_for_pDef [get_property default_rm [get_partition_def $partitionDefName]]
  2664. if { [string equal $reconfModule $defaultRM_for_pDef] } {
  2665. lappend l_script_data "set_property default_rm $reconfModule \$partitionDef"
  2666. }
  2667. lappend l_script_data "set obj \[$get_what $reconfModule\]"
  2668. write_props $proj_dir $proj_name $get_what $reconfModule "reconfigModule"
  2669. write_reconfigmodule_files $proj_dir $proj_name $reconfModule
  2670. }
  2671. proc wr_prConf {proj_dir proj_name} {
  2672. # Summary: write reconfiguration modules for RPs
  2673. # This helper command is used to script help.
  2674. # Argument Usage:
  2675. # proj_name: project name
  2676. # Return Value:
  2677. # None
  2678. if { [get_property pr_flow [current_project]] == 0 } {
  2679. return
  2680. }
  2681. # write pr configurations
  2682. set prConfigurations [get_pr_configurations]
  2683. foreach prConfig $prConfigurations {
  2684. write_specified_prConfiguration $proj_dir $proj_name $prConfig
  2685. }
  2686. }
  2687. proc write_specified_prConfiguration { proj_dir proj_name prConfig } {
  2688. # Summary: write the specified pr reconfiguration
  2689. # This helper command is used to script help.
  2690. # Argument Usage:
  2691. # Return Value:
  2692. # none
  2693. variable l_script_data
  2694. set get_what "get_pr_configurations"
  2695. # fetch pr config properties
  2696. set name [get_property name [$get_what $prConfig]]
  2697. set configObj [$get_what $prConfig]
  2698. set partition [get_property "partition_cell_rms" $configObj]
  2699. set greyBoxCell [get_property "greybox_cells" $configObj]
  2700. variable options
  2701. if {$partition ne ""} {
  2702. set options "-partitions \[list $partition \]"
  2703. }
  2704. if {$greyBoxCell ne ""} {
  2705. set options "$options -greyboxes \[list $greyBoxCell \]"
  2706. }
  2707. lappend l_script_data "# Create '$prConfig' pr configurations"
  2708. lappend l_script_data "create_pr_configuration -name $name $options"
  2709. lappend l_script_data "set obj \[$get_what $prConfig\]"
  2710. write_props $proj_dir $proj_name $get_what $prConfig "prConfiguration"
  2711. }
  2712. proc write_reconfigmodule_files { proj_dir proj_name reconfigModule } {
  2713. # Summary: write file and file properties
  2714. # This helper command is used to script help.
  2715. # Argument Usage:
  2716. # Return Value:
  2717. # none
  2718. variable a_global_vars
  2719. variable l_script_data
  2720. set l_local_file_list [list]
  2721. set l_remote_file_list [list]
  2722. # return if empty fileset
  2723. set bc_managed_fs_filter "IS_BLOCK_CONTAINER_MANAGED == 0"
  2724. set files [get_files -quiet -norecurse -of_objects [get_filesets -of_objects $reconfigModule] -filter $bc_managed_fs_filter]
  2725. if {[llength $files] == 0 } {
  2726. lappend l_script_data "# Empty (no sources present)\n"
  2727. return
  2728. }
  2729. set fileset [get_filesets -of_objects $reconfigModule]
  2730. set fs_name [get_property name $fileset]
  2731. set import_coln [list]
  2732. set add_file_coln [list]
  2733. set bd_list [list]
  2734. foreach file $files {
  2735. if { [file extension $file ] ==".bd" && !$a_global_vars(b_arg_use_bd_files)} {
  2736. lappend bd_list $file
  2737. continue
  2738. }
  2739. set path_dirs [split [string trim [file normalize [string map {\\ /} $file]]] "/"]
  2740. set begin [lsearch -exact $path_dirs "$proj_name.srcs"]
  2741. set src_file [join [lrange $path_dirs $begin+1 end] "/"]
  2742. # fetch first object
  2743. set file_object [lindex [get_files -quiet -norecurse -of_objects [get_filesets -of_objects $reconfigModule] [list $file]] 0]
  2744. set file_props [list_property $file_object]
  2745. if { [lsearch $file_props "IMPORTED_FROM"] != -1 } {
  2746. # import files
  2747. set imported_path [get_property "imported_from" $file]
  2748. set rel_file_path [get_relative_file_path_for_source $file [get_script_execution_dir]]
  2749. set proj_file_path "\$origin_dir/$rel_file_path"
  2750. set file "\"[file normalize $proj_dir/${proj_name}.srcs/$src_file]\""
  2751. if { $a_global_vars(b_arg_no_copy_srcs) } {
  2752. # add to the local collection
  2753. lappend l_remote_file_list $file
  2754. if { $a_global_vars(b_absolute_path) || [need_abs_path $file]} {
  2755. lappend add_file_coln "$file"
  2756. } else {
  2757. lappend add_file_coln "\"\[file normalize \"$proj_file_path\"\]\""
  2758. }
  2759. } else {
  2760. # add to the import collection
  2761. lappend l_local_file_list $file
  2762. if { $a_global_vars(b_absolute_path) || [need_abs_path $file]} {
  2763. lappend import_coln "$file"
  2764. } else {
  2765. lappend import_coln "\"\[file normalize \"$proj_file_path\"\]\""
  2766. }
  2767. }
  2768. } else {
  2769. set file "\"$file\""
  2770. # is local? add to local project, add to collection and then import this collection by default unless -no_copy_sources is specified
  2771. if { [is_local_to_project $file] } {
  2772. if { $a_global_vars(b_arg_dump_proj_info) } {
  2773. set src_file "\$PSRCDIR/$src_file"
  2774. }
  2775. # add to the import collection
  2776. set file_no_quotes [string trim $file "\""]
  2777. set org_file_path "\$origin_dir/[get_relative_file_path_for_source $file_no_quotes [get_script_execution_dir]]"
  2778. lappend import_coln "\"\[file normalize \"$org_file_path\"\]\""
  2779. lappend l_local_file_list $file
  2780. } else {
  2781. lappend l_remote_file_list $file
  2782. }
  2783. # add file to collection
  2784. if { $a_global_vars(b_arg_no_copy_srcs) && (!$a_global_vars(b_absolute_path)) && ![need_abs_path $file]} {
  2785. set file_no_quotes [string trim $file "\""]
  2786. set rel_file_path [get_relative_file_path_for_source $file_no_quotes [get_script_execution_dir]]
  2787. set file1 "\"\[file normalize \"\$origin_dir/$rel_file_path\"\]\""
  2788. lappend add_file_coln "$file1"
  2789. } else {
  2790. lappend add_file_coln "$file"
  2791. }
  2792. }
  2793. }
  2794. if {[llength $bd_list] > 0 } {
  2795. foreach bd_file $bd_list {
  2796. set filename [file tail $bd_file]
  2797. lappend l_script_data " move_files \[ get_files $filename \] -of_objects \[get_reconfig_modules $reconfigModule\]"
  2798. }
  2799. }
  2800. if {[llength $add_file_coln]>0} {
  2801. lappend l_script_data "set files \[list \\"
  2802. foreach file $add_file_coln {
  2803. if { $a_global_vars(b_absolute_path) || [need_abs_path $file]} {
  2804. lappend l_script_data " $file\\"
  2805. } else {
  2806. if { $a_global_vars(b_arg_no_copy_srcs) } {
  2807. lappend l_script_data " $file\\"
  2808. } else {
  2809. set file_no_quotes [string trim $file "\""]
  2810. set rel_file_path [get_relative_file_path_for_source $file_no_quotes [get_script_execution_dir]]
  2811. lappend l_script_data " \"\[file normalize \"\$origin_dir/$rel_file_path\"\]\"\\"
  2812. }
  2813. }
  2814. }
  2815. lappend l_script_data "\]"
  2816. lappend l_script_data "add_files -norecurse -of_objects \[get_reconfig_modules $reconfigModule\] \$files"
  2817. lappend l_script_data ""
  2818. }
  2819. # now import local files if -no_copy_sources is not specified
  2820. if { ! $a_global_vars(b_arg_no_copy_srcs)} {
  2821. if { [llength $import_coln] > 0 } {
  2822. lappend l_script_data "# Import local files from the original project"
  2823. lappend l_script_data "set files \[list \\"
  2824. foreach ifile $import_coln {
  2825. lappend l_script_data " $ifile\\"
  2826. }
  2827. lappend l_script_data "\]"
  2828. lappend l_script_data "import_files -of_objects \[get_reconfig_modules $reconfigModule\] \$files"
  2829. lappend l_script_data ""
  2830. }
  2831. }
  2832. # write fileset file properties for remote files (added sources)
  2833. write_reconfigmodule_file_properties $reconfigModule $fs_name $proj_dir $l_remote_file_list "remote"
  2834. # write fileset file properties for local files (imported sources)
  2835. write_reconfigmodule_file_properties $reconfigModule $fs_name $proj_dir $l_local_file_list "local"
  2836. # move sub-design files (XCI/BD) of reconfig modules from sources fileset to reconfig-module (RM) fileset
  2837. add_reconfigmodule_subdesign_files $reconfigModule
  2838. }
  2839. proc add_reconfigmodule_subdesign_files { reconfigModule } {
  2840. # Summary:
  2841. # Argument Usage:
  2842. # Return Value:
  2843. variable l_script_data
  2844. foreach rmSubdesignFileset [get_property subdesign_filesets $reconfigModule] {
  2845. foreach fileObj [get_files -quiet -norecurse -of_objects [get_filesets $rmSubdesignFileset]] {
  2846. set path_dirs [split [string trim [file normalize [string map {\\ /} $fileObj ]]] "/"]
  2847. set path [join [lrange $path_dirs end-1 end] "/"]
  2848. set path [string trimleft $path "/"]
  2849. lappend l_script_data "move_files -of_objects \$obj \[get_files *$path\]"
  2850. lappend l_script_data ""
  2851. }
  2852. }
  2853. }
  2854. proc write_reconfigmodule_file_properties { reconfigModule fs_name proj_dir l_file_list file_category } {
  2855. # Summary:
  2856. # Write fileset file properties for local and remote files
  2857. # Argument Usage:
  2858. # reconfigModule : object to inspect
  2859. # fs_name: fileset name
  2860. # l_file_list: list of files (local or remote)
  2861. # file_category: file catwgory (local or remote)
  2862. # Return Value:
  2863. # none
  2864. variable a_global_vars
  2865. variable l_script_data
  2866. variable l_local_files
  2867. variable l_remote_files
  2868. set l_local_files [list]
  2869. set l_remote_files [list]
  2870. set tcl_obj [get_filesets -of_objects $reconfigModule]
  2871. lappend l_script_data "# Set '$reconfigModule' fileset file properties for $file_category files"
  2872. set file_prop_count 0
  2873. # collect local/remote files
  2874. foreach file $l_file_list {
  2875. if { [string equal $file_category "local"] } {
  2876. lappend l_local_files $file
  2877. } elseif { [string equal $file_category "remote"] } {
  2878. lappend l_remote_files $file
  2879. } else {}
  2880. }
  2881. foreach file $l_file_list {
  2882. set file [string trim $file "\""]
  2883. # fix file path for local files
  2884. if { [string equal $file_category "local"] } {
  2885. set path_dirs [split [string trim [file normalize [string map {\\ /} $file]]] "/"]
  2886. set src_file [join [lrange $path_dirs end-1 end] "/"]
  2887. set src_file [string trimleft $src_file "/"]
  2888. set src_file [string trimleft $src_file "\\"]
  2889. set file $src_file
  2890. }
  2891. set file_object ""
  2892. if { [string equal $file_category "local"] } {
  2893. set file_object [lindex [get_files -quiet -norecurse -of_objects [get_filesets -of_objects $reconfigModule] [list "*$file"]] 0]
  2894. } elseif { [string equal $file_category "remote"] } {
  2895. set file_object [lindex [get_files -quiet -norecurse -of_objects [get_filesets -of_objects $reconfigModule] [list $file]] 0]
  2896. }
  2897. set file_props [list_property $file_object]
  2898. set prop_info_list [list]
  2899. set prop_count 0
  2900. foreach file_prop $file_props {
  2901. set is_readonly [get_property is_readonly [rdi::get_attr_specs $file_prop -object $file_object]]
  2902. if { [string equal $is_readonly "1"] } {
  2903. continue
  2904. }
  2905. set prop_type [get_property type [rdi::get_attr_specs $file_prop -object $file_object]]
  2906. set def_val [list_property_value -default $file_prop $file_object]
  2907. set cur_val [get_property $file_prop $file_object]
  2908. # filter special properties
  2909. if { [filter $file_prop $cur_val $file] } { continue }
  2910. # re-align values
  2911. set cur_val [get_target_bool_val $def_val $cur_val]
  2912. set dump_prop_name [string tolower ${fs_name}_file_${file_prop}]
  2913. set prop_entry ""
  2914. if { [string equal $file_category "local"] } {
  2915. set prop_entry "[string tolower $file_prop]#[get_property $file_prop $file_object]"
  2916. } elseif { [string equal $file_category "remote"] } {
  2917. set prop_value_entry [get_property $file_prop $file_object]
  2918. set prop_entry "[string tolower $file_prop]#$prop_value_entry"
  2919. } else {}
  2920. if { $a_global_vars(b_arg_all_props) } {
  2921. lappend prop_info_list $prop_entry
  2922. incr prop_count
  2923. } else {
  2924. if { $def_val != $cur_val } {
  2925. lappend prop_info_list $prop_entry
  2926. incr prop_count
  2927. }
  2928. }
  2929. if { $a_global_vars(b_arg_dump_proj_info) } {
  2930. puts $a_global_vars(def_val_fh) "[file tail $file]=$file_prop ($prop_type) :DEFAULT_VALUE ($def_val)==CURRENT_VALUE ($cur_val)"
  2931. puts $a_global_vars(dp_fh) "$dump_prop_name=$cur_val"
  2932. }
  2933. }
  2934. # write properties now
  2935. if { $prop_count>0 } {
  2936. if { {remote} == $file_category } {
  2937. if { $a_global_vars(b_absolute_path) || [need_abs_path $file]} {
  2938. lappend l_script_data "set file \"$file\""
  2939. } else {
  2940. lappend l_script_data "set file \"\$origin_dir/[get_relative_file_path_for_source $file [get_script_execution_dir]]\""
  2941. lappend l_script_data "set file \[file normalize \$file\]"
  2942. }
  2943. } else {
  2944. lappend l_script_data "set file \"$file\""
  2945. }
  2946. lappend l_script_data "set obj \[get_files -of_objects \[get_reconfig_modules $reconfigModule\] \[list \"*\$file\"\]\]"
  2947. set get_what "get_files -of_objects "
  2948. write_properties $prop_info_list $get_what $tcl_obj
  2949. incr file_prop_count
  2950. }
  2951. }
  2952. if { $file_prop_count == 0 } {
  2953. lappend l_script_data "# None"
  2954. }
  2955. lappend l_script_data ""
  2956. }
  2957. proc write_report_strategy { run report_strategy } {
  2958. # Summary:
  2959. # create report one by one as per its configuration.
  2960. # Argument Usage:
  2961. # run FCO:
  2962. # Return Value: none
  2963. set retVal [get_param project.enableReportConfiguration]
  2964. if { $retVal == 0 } {
  2965. return
  2966. }
  2967. set reports [get_report_configs -of_objects [get_runs $run]]
  2968. if { [llength $reports] == 0 } {
  2969. return
  2970. }
  2971. variable l_script_data
  2972. lappend l_script_data "set obj \[get_runs $run\]"
  2973. lappend l_script_data "set_property set_report_strategy_name 1 \$obj"
  2974. lappend l_script_data "set_property report_strategy {$report_strategy} \$obj"
  2975. lappend l_script_data "set_property set_report_strategy_name 0 \$obj"
  2976. foreach report $reports {
  2977. set report_name [get_property name $report]
  2978. set report_spec [get_property report_type $report]
  2979. set step [get_property run_step $report]
  2980. lappend l_script_data "# Create '$report' report (if not found)"
  2981. lappend l_script_data "if \{ \[ string equal \[get_report_configs -of_objects \[get_runs $run\] $report\] \"\" \] \} \{"
  2982. lappend l_script_data " create_report_config -report_name $report_name -report_type $report_spec -steps $step -runs $run"
  2983. lappend l_script_data "\}"
  2984. lappend l_script_data "set obj \[get_report_configs -of_objects \[get_runs $run\] $report\]"
  2985. lappend l_script_data "if { \$obj != \"\" } {"
  2986. write_report_props $report
  2987. lappend l_script_data "}"
  2988. }
  2989. }
  2990. proc write_report_props { report } {
  2991. # Summary:
  2992. # iterate over all report options and send all non default values to -->set_property <property> <curr_value> [report FCO]
  2993. # Argument Usage:
  2994. # report FCO:
  2995. # Return Value: none
  2996. variable l_script_data
  2997. variable a_global_vars
  2998. set obj_name [get_property name $report]
  2999. set read_only_props [rdi::get_attr_specs -class [get_property class $report] -filter {is_readonly}]
  3000. set prop_info_list [list]
  3001. set properties [list_property $report]
  3002. foreach prop $properties {
  3003. if { [string equal -nocase $prop "OPTIONS.pb"] || [string equal -nocase $prop "OPTIONS.rpx"] } {
  3004. #skipping read_only property
  3005. continue
  3006. }
  3007. if { [lsearch $read_only_props $prop] != -1 } { continue }
  3008. set def_val [list_property_value -default $prop $report]
  3009. set cur_val [get_property $prop $report]
  3010. # filter special properties
  3011. if { [filter $prop $cur_val] } { continue }
  3012. set cur_val [get_target_bool_val $def_val $cur_val]
  3013. set prop_entry "[string tolower $prop]#[get_property $prop $report]"
  3014. if { $a_global_vars(b_arg_all_props) } {
  3015. lappend prop_info_list $prop_entry
  3016. } elseif { $def_val != $cur_val } {
  3017. lappend prop_info_list $prop_entry
  3018. }
  3019. }
  3020. write_properties $prop_info_list "get_report_configs" $report
  3021. }
  3022. proc suppress_messages {} {
  3023. variable levels_to_suppress
  3024. set levels_to_suppress { {STATUS} {INFO} {WARNING} {CRITICAL WARNING} }
  3025. set msg_rules [split [ debug::get_msg_control_rules -as_tcl ] \n]
  3026. foreach line $msg_rules {
  3027. set idx_suppress [lsearch $line "-suppress"]
  3028. if { $idx_suppress >= 0 } {
  3029. set idx_severity [lsearch $line "-severity"]
  3030. if { $idx_suppress == $idx_severity + 2 } {
  3031. set lvl_idx [ lsearch $levels_to_suppress [lindex $line $idx_suppress-1 ] ]
  3032. if { $lvl_idx >= 0 } {
  3033. set levels_to_suppress [ lreplace $levels_to_suppress $lvl_idx $lvl_idx]
  3034. }
  3035. }
  3036. }
  3037. }
  3038. foreach level $levels_to_suppress {
  3039. set_msg_config -quiet -suppress -severity $level
  3040. }
  3041. }
  3042. proc reset_msg_setting {} {
  3043. variable levels_to_suppress
  3044. foreach level $levels_to_suppress {
  3045. reset_msg_config -quiet -suppress -severity $level
  3046. }
  3047. }
  3048. }