Hog Hog2025.2-3
check_list_files.tcl
Go to the documentation of this file.
1 #!/usr/bin/env tclsh
2 # Copyright 2018-2025 The University of Birmingham
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 # @file
17 # Check if the content of list files matches the project. It can also be used to update the list files.
18 
19 #parsing command options
20 if {[catch {package require cmdline} ERROR]} {
21  puts "$ERROR\n If you are running this script on tclsh, you can fix this by installing 'tcllib'"
22  return
23 }
24 
25 set hog_path [file normalize "[file dirname [info script]]/.."]
26 set repo_path [file normalize "$hog_path/../.."]
27 source $hog_path/hog.tcl
28 
29 if {[IsISE]} {
30  set tcl_path [file normalize "[file dirname [info script]]"]
31  source $tcl_path/cmdline.tcl
32 }
33 set parameters {
34  {project.arg "" "Project name. If not set gets current project"}
35  {outDir.arg "" "Name of output dir containing log files."}
36  {log.arg "1" "Logs errors/warnings to outFile."}
37  {recreate "If set, it will create List Files from the project configuration"}
38  {recreate_conf "If set, it will create the project hog.conf file."}
39  {recreate_sim "If set, it will create the simulation list files."}
40  {force "Force the overwriting of List Files. To be used together with \"-recreate\""}
41  {pedantic "Script fails in case of mismatch"}
42  {ext_path.arg "" "Sets the absolute path for the external libraries."}
43 }
44 
45 
46 set usage "Checks if the list and conf files matches the project ones. It can also be used to update the list and conf files. \nUSAGE: $::argv0 \[Options\]"
47 
48 
49 if {[catch {array set options [cmdline::getoptions ::argv $parameters $usage]}]} {
50  Msg Info [cmdline::usage $parameters $usage]
51  exit 1
52 }
53 
54 set ext_path $options(ext_path)
55 
56 set ListErrorCnt 0
57 set ListSimErrorCnt 0
58 set ConfErrorCnt 0
59 set SrcListErrorCnt 0
60 set SimListErrorCnt 0
61 set SimConfErrorCnt 0
62 set ConListErrorCnt 0
63 set TotErrorCnt 0
64 set SIM_PROPS [list "dofile" \
65  "wavefile" \
66  "topsim" \
67  "runtime"]
68 
69 if {![string equal $options(project) ""]} {
70  set project $options(project)
71  set group_name [file dirname $project]
72  set project_name [file tail $project]
73  Msg Info "Opening project $project_name..."
74 
75  if {[IsVivado]} {
76  file mkdir "$repo_path/Projects/$project/$project_name.gen/sources_1"
77  open_project "$repo_path/Projects/$project/$project_name.xpr"
78  set proj_file [get_property DIRECTORY [current_project]]
79  set proj_dir [file normalize $proj_file]
80  set group_name [GetGroupName $proj_dir $repo_path]
81  } elseif {[IsSynplify]} {
82  set proj_file $repo_path/Projects/$project/$project_name.prjx
83  } elseif {[IsDiamond]} {
84  set proj_file $repo_path/Projects/$project/$project_name.ldf
85  }
86 } else {
87  if {[IsVivado]} {
88  set project_name [get_projects [current_project]]
89  set proj_file [get_property DIRECTORY [current_project]]
90  set proj_dir [file normalize $proj_file]
91  } elseif {[IsSynplify]} {
92  set proj_dir [file normalize [file dirname "[project_data -dir]/../.."]]
93  set proj_name [file tail $proj_dir]
94  set proj_file $proj_dir/$proj_name.prjx
95  } elseif {[IsDiamond]} {
96  set proj_dir [pwd]
97  set proj_name [file tail $proj_dir]
98  set proj_file $proj_dir/$proj_name.ldf
99  }
100 
101  set group_name [GetGroupName $proj_dir $repo_path]
102 }
103 
104 
105 if {$options(outDir) != ""} {
106  set outFile $options(outDir)/diff_list_and_conf.txt
107  set outSimFile $options(outDir)/diff_sim_list_and_conf.txt
108  if {[file exists $outFile]} {
109  file delete $outFile
110  }
111 
112  if {[file exists $outSimFile]} {
113  file delete $outSimFile
114  }
115 
116  if {!$options(log)} {
117  set outFile ""
118  set outSimFile ""
119  }
120 } else {
121  set outFile ""
122  set outSimFile ""
123 }
124 
125 
126 if {[file exists $repo_path/Top/$group_name/$project_name] && [file isdirectory $repo_path/Top/$group_name/$project_name] && $options(force) == 0} {
127  set DirName Top_new/$group_name/$project_name
128 } else {
129  set DirName Top/$group_name/$project_name
130 }
131 
132 if {$options(recreate_sim) == 1 && [IsVivado]} {
133  Msg Info "Checking $project_name simulation list files..."
134  # Get project simulation libraries and properties from list files
135  lassign [GetHogFiles -ext_path "$ext_path" \
136  -list_files ".sim" "$repo_path/Top/$group_name/$project_name/list/" $repo_path]\
137  listSimLibraries listSimProperties listSimSets
138  # Get project libraries and properties from Vivado
139  lassign [GetProjectFiles $proj_file] prjLibraries prjProperties prjSimLibraries prjConstraints prjSrcSets prjSimSets prjConSets
140  Msg Info "Retrieved project files..."
141 
142  set extrasimFiles [ReadExtraFileList "$repo_path/Projects/$group_name/$project_name/.hog/extrasim.files"]
143 
144  # Removing duplicates from listSimLibraries listSimProperties prjSimLibraries
145  set listSimLibraries [RemoveDuplicates $listSimLibraries]
146  set listSimProperties [RemoveDuplicates $listSimProperties]
147  set prjSimLibraries [RemoveDuplicates $prjSimLibraries]
148 
149  Msg Debug "Project Sim Libraries"
150  Msg Debug $prjSimLibraries
151  Msg Debug "Sim List Libraries"
152  Msg Debug $listSimLibraries
153  Msg Debug "Project SimSets"
154  Msg Debug $prjSimSets
155  Msg Debug "List SimSets"
156  Msg Debug $listSimSets
157  Msg Debug "Sim List File Properties"
158  Msg Debug $listSimProperties
159 
160  lassign [CompareLibDicts $prjSimLibraries $listSimLibraries $prjSimSets $listSimSets \
161  $prjProperties $listSimProperties "Warning" $outSimFile $extrasimFiles] \
162  SimListErrorCnt extrasimFiles prjSimLibraries prjProperties
163 
164  foreach {k v} $extrasimFiles {
165  MsgAndLog "Simulation file $k was found in .hog/extrasim.files but not in project." "Warning" $outFile
166  incr SimListErrorCnt
167  }
168 }
169 
170 if {$options(recreate_conf) == 0 || $options(recreate) == 1} {
171  Msg Info "Checking $project_name list files..."
172 
173  # Get project libraries and properties from list files
174  lassign [GetHogFiles -ext_path "$ext_path" \
175  -list_files ".src,.ext" "$repo_path/Top/$group_name/$project_name/list/" $repo_path]\
176  listLibraries listProperties listSrcSets
177  # Get project constraints and properties from list files
178  lassign [GetHogFiles -ext_path "$ext_path" \
179  -list_files ".con" "$repo_path/Top/$group_name/$project_name/list/" $repo_path] \
180  listConstraints listConProperties listConSets
181 
182  # Get files generated at creation time
183  set extraFiles [ReadExtraFileList "$repo_path/Projects/$group_name/$project_name/.hog/extra.files"]
184  set extraConstraints [ReadExtraFileList "$repo_path/Projects/$group_name/$project_name/.hog/extracon.files"]
185 
186  # Get project libraries and properties from Vivado
187  lassign [GetProjectFiles $proj_file] prjLibraries prjProperties prjSimLibraries prjConstraints prjSrcSets prjSimSets prjConSets
188  Msg Info "Retrieved project files..."
189 
190  # Removing duplicates from listlibraries listProperties
191  set listLibraries [RemoveDuplicates $listLibraries]
192  set listProperties [RemoveDuplicates $listProperties]
193  set listConstraints [RemoveDuplicates $listConstraints]
194  set prjLibraries [RemoveDuplicates $prjLibraries]
195  set prjConstraints [RemoveDuplicates $prjConstraints]
196  set prjProperties [RemoveDuplicates $prjProperties]
197 
198  #################################################################
199  ##### START COMPARISON OF FILES IN PROJECT AND LIST FILES ######
200  #################################################################
201  Msg Debug "Project Libraries"
202  Msg Debug $prjLibraries
203  Msg Debug "Source List Libraries"
204  Msg Debug $listLibraries
205  Msg Debug "Project Filesets"
206  Msg Debug $prjSrcSets
207  Msg Debug "List Filesets"
208  Msg Debug $listSrcSets
209  Msg Debug "Project File Properties"
210  Msg Debug $prjProperties
211  Msg Debug "List File Properties"
212  Msg Debug $listProperties
213  Msg Debug "Project Constraints"
214  Msg Debug $prjConstraints
215  Msg Debug "List Constraints"
216  Msg Debug $listConstraints
217  Msg Debug "Project ConSets"
218  Msg Debug $prjConSets
219  Msg Debug "List ConSets"
220  Msg Debug $listConSets
221  Msg Debug "List Constraint Properties"
222  Msg Debug $listConProperties
223 
224  lassign [CompareLibDicts $prjLibraries $listLibraries \
225  $prjSrcSets $listSrcSets \
226  $prjProperties $listProperties "CriticalWarning" $outFile $extraFiles] \
227  SrcListErrorCnt extraFiles prjLibraries prjProperties
228  lassign [CompareLibDicts $prjConstraints $listConstraints \
229  $prjConSets $listConSets \
230  $prjProperties $listConProperties "CriticalWarning" $outFile $extraConstraints] \
231  ConListErrorCnt extraConstraints prjConstraints prjProperties
232 
233  # Check if any files remained in extraFiles
234  foreach {k v} $extraFiles {
235  MsgAndLog "$k was found in .hog/extra.files but not in project." "CriticalWarning" $outFile
236  incr SrcListErrorCnt
237  }
238 
239  foreach {k v} $extraConstraints {
240  MsgAndLog "Constraint file $k was found in .hog/extracon.files but not in project." "CriticalWarning" $outFile
241  incr SrcListErrorCnt
242  }
243 
244  if {$SrcListErrorCnt == 0} {
245  Msg Info "Design List Files matches project. Nothing to do."
246  }
247 
248  if {$ConListErrorCnt == 0} {
249  Msg Info "Constraint List Files matches project. Nothing to do."
250  }
251 
252  # Recreating src list files
253  if {$options(recreate) == 1 && ($SrcListErrorCnt > 0 || $ConListErrorCnt > 0)} {
254  set listpath "$repo_path/$DirName/list/"
255  Msg Info "Updating list files in $listpath"
256  # Create the list path, if it does not exist yet
257  file mkdir $listpath
258  if {$SrcListErrorCnt > 0} {
259  # Delete existing .src list files
260  if {$options(force) == 1} {
261  foreach F [glob -nocomplain "$listpath/*.src" "$listpath/*.ext"] {
262  file delete $F
263  }
264  }
265  WriteListFiles $prjLibraries $prjProperties $listpath $repo_path $ext_path
266  }
267 
268  if {$ConListErrorCnt > 0} {
269  # Delete existing .con list files
270  if {$options(force) == 1} {
271  foreach F [glob -nocomplain "$listpath/*.con"] {
272  file delete $F
273  }
274  }
275  WriteListFiles $prjConstraints $prjProperties $listpath $repo_path
276  }
277  }
278 }
279 
280 if {[IsXilinx]} {
281  set conf_file "$repo_path/Top/$group_name/$project_name/hog.conf"
282  # checking project settings
283  if {$options(recreate) == 0 || $options(recreate_conf) == 1} {
284  #creating 4 dicts:
285  # - hogConfDict: hog.conf properties (if exists)
286  # - defaultConfDict: default properties
287  # - projConfDict: current project properties
288  # - newConfDict: "new" hog.conf
289 
290  # Get project libraries and properties from Vivado
291  lassign [GetProjectFiles] prjLibraries prjProperties
292  ##nagelfar ignore
293  set prjSrcDict [DictGet $prjLibraries SRC]
294 
295 
296  set hogConfDict [dict create]
297  set defaultConfDict [dict create]
298  set projConfDict [dict create]
299  set newConfDict [dict create]
300 
301  #filling hogConfDict
302  if {[file exists $conf_file]} {
303  set hogConfDict [ReadConf $conf_file]
304 
305  #convert hog.conf dict keys to uppercase
306  foreach key [list main synth_1 impl_1 generics] {
307  set runDict [DictGet $hogConfDict $key]
308  foreach runDictKey [dict keys $runDict] {
309  #do not convert paths
310  if {[string first $repo_path [DictGet $runDict $runDictKey]] != -1} {
311  continue
312  }
313  dict set runDict [string toupper $runDictKey] [DictGet $runDict $runDictKey]
314  dict unset runDict [string tolower $runDictKey]
315  }
316  dict set hogConfDict $key $runDict
317  }
318  } elseif {$options(recreate_conf) == 0} {
319  Msg Warning "$repo_path/Top/$group_name/$project_name/hog.conf not found. Skipping properties check"
320  }
321 
322 
323  # filling newConfDict with existing hog.conf properties apart from main synth_1 impl_1 and generics
324  foreach key [dict keys $hogConfDict] {
325  if {$key != "main" && $key != "synth_1" && $key != "impl_1" && $key != "generics"} {
326  dict set newConfDict $key [DictGet $hogConfDict $key]
327  }
328  }
329 
330  # list of properties that must not be checked/written
331  set PROP_BAN_LIST [list DEFAULT_LIB \
332  AUTO_RQS.DIRECTORY \
333  AUTO_INCREMENTAL_CHECKPOINT.DIRECTORY \
334  AUTO_INCREMENTAL_CHECKPOINT \
335  COMPXLIB.MODELSIM_COMPILED_LIBRARY_DIR \
336  COMPXLIB.QUESTA_COMPILED_LIBRARY_DIR \
337  COMPXLIB.RIVIERA_COMPILED_LIBRARY_DIR \
338  COMPXLIB.ACTIVEHDL_COMPILED_LIBRARY_DIR \
339  COMPXLIB.IES_COMPILED_LIBRARY_DIR \
340  COMPXLIB.VCS_COMPILED_LIBRARY_DIR \
341  ENABLE_RESOURCE_ESTIMATION \
342  INCREMENTAL_CHECKPOINT \
343  IP_CACHE_PERMISSIONS \
344  IP.USER_FILES_DIR \
345  NEEDS_REFRESH \
346  PART \
347  REPORT_STRATEGY \
348  SIM.IP.AUTO_EXPORT_SCRIPTS \
349  SIM.IPSTATIC.SOURCE_DIR \
350  STEPS.WRITE_DEVICE_IMAGE.ARGS.READBACK_FILE \
351  STEPS.WRITE_DEVICE_IMAGE.ARGS.VERBOSE \
352  STEPS.WRITE_BITSTREAM.ARGS.READBACK_FILE \
353  STEPS.WRITE_BITSTREAM.ARGS.VERBOSE \
354  STEPS.SYNTH_DESIGN.TCL.PRE \
355  STEPS.SYNTH_DESIGN.TCL.POST \
356  STEPS.WRITE_BITSTREAM.TCL.PRE \
357  STEPS.WRITE_BITSTREAM.TCL.POST \
358  STEPS.WRITE_DEVICE_IMAGE.TCL.PRE \
359  STEPS.WRITE_DEVICE_IMAGE.TCL.POST \
360  STEPS.INIT_DESIGN.TCL.POST \
361  STEPS.ROUTE_DESIGN.TCL.POST \
362  XPM_LIBRARIES]
363 
364  set SIM_BAN_LIST [list HBS.CONFIGURE_DESIGN_FOR_HIER_ACCESS \
365  RUNTIME \
366  SIM_WRAPPER_TOP]
367 
368  set HOG_GENERICS [list GLOBAL_DATE \
369  GLOBAL_TIME \
370  FLAVOUR]
371 
372  #filling defaultConfDict and projConfDict
373  foreach proj_run [list [current_project] [get_runs synth_1] [get_runs impl_1] [current_fileset]] {
374  #creating dictionary for each $run
375  set projRunDict [dict create]
376  set defaultRunDict [dict create]
377  #selecting only READ/WRITE properties
378  set run_props [list]
379  foreach propReport [split "[report_property -return_string -all $proj_run]" "\n"] {
380  if {[string equal "[lindex $propReport 2]" "false"]} {
381  lappend run_props [lindex $propReport 0]
382  }
383  }
384  # Append BOARD_PART_REPO_PATHS since it is not in given by report_property...
385  if {$proj_run == [current_project]} {
386  lappend run_props "BOARD_PART_REPO_PATHS"
387  }
388 
389  foreach prop $run_props {
390  #ignoring properties in $PROP_BAN_LIST
391  if {$prop in $PROP_BAN_LIST} {
392  set tmp 0
393  #Msg Info "Skipping property $prop"
394  } elseif {"$proj_run" == "[current_fileset]"} {
395  # For current fileset extract only generics
396  if {$prop == "GENERIC"} {
397  foreach generic [get_property $prop [current_fileset]] {
398  set generic_prop_value [split $generic {=}]
399  if {[llength $generic_prop_value] == 2} {
400  if {[string toupper [lindex $generic_prop_value 0]] in $HOG_GENERICS} {
401  continue
402  }
403  dict set projRunDict [string toupper [lindex $generic_prop_value 0]] [lindex $generic_prop_value 1]
404  dict set defaultRunDict [string toupper $prop] ""
405  }
406  }
407  }
408  } else {
409  #Project values
410  # setting only relative paths
411  if {[string first $repo_path [get_property $prop $proj_run]] != -1} {
412  set prop_val ""
413  foreach p [get_property $prop $proj_run] {
414  set prop_val "$prop_val[Relative $repo_path $p] "
415  }
416  dict set projRunDict [string toupper $prop] [string trim $prop_val]
417  } elseif {[string first $ext_path [get_property $prop $proj_run]] != -1} {
418  set prop_val ""
419  foreach p [get_property $prop $proj_run] {
420  set prop_val "$prop_val[Relative $ext_path $p] "
421  }
422  dict set projRunDict [string toupper $prop] [string trim $prop_val]
423  } else {
424  dict set projRunDict [string toupper $prop] [get_property $prop $proj_run]
425  }
426 
427  # default values
428  dict set defaultRunDict [string toupper $prop] [list_property_value -default $prop $proj_run]
429  }
430  }
431  if {"$proj_run" == "[current_project]"} {
432  dict set projRunDict "PART" [get_property PART $proj_run]
433  dict set projConfDict main $projRunDict
434  dict set defaultConfDict main $defaultRunDict
435  } elseif {"$proj_run" == "[current_fileset]"} {
436  dict set projConfDict generics $projRunDict
437  dict set defaultConfDict generics $defaultRunDict
438  } else {
439  dict set projConfDict $proj_run $projRunDict
440  dict set defaultConfDict $proj_run $defaultRunDict
441  }
442  }
443 
444  #adding default properties set by default by Hog or after project creation
445  set defMainDict [dict create TARGET_LANGUAGE VHDL SIMULATOR_LANGUAGE MIXED]
446  dict set defMainDict IP_OUTPUT_REPO "[Relative $repo_path $proj_dir]/${project_name}.cache/ip"
447  dict set defaultConfDict main [dict merge [DictGet $defaultConfDict main] $defMainDict]
448 
449  #comparing projConfDict, defaultConfDict and hogConfDict
450  set hasStrategy 0
451 
452  foreach proj_run [list main synth_1 impl_1 generics] {
453  set projRunDict [DictGet $projConfDict $proj_run]
454  set hogConfRunDict [DictGet $hogConfDict $proj_run]
455  set defaultRunDict [DictGet $defaultConfDict $proj_run]
456  set newRunDict [dict create]
457 
458  set strategy_str "STRATEGY strategy Strategy"
459  foreach s $strategy_str {
460  if {[dict exists $hogConfRunDict $s]} {
461  set hasStrategy 1
462  }
463  }
464 
465  if {$hasStrategy == 1 && $options(recreate_conf) == 0} {
466  Msg Warning "A strategy for run $proj_run has been defined inside hog.conf. \
467  This prevents Hog to compare the project properties. \
468  Please regenerate your hog.conf file using the dedicated Hog button."
469  }
470 
471  foreach settings [dict keys $projRunDict] {
472  set currset [DictGet $projRunDict $settings]
473  set hogset [DictGet $hogConfRunDict $settings]
474  set defset [DictGet $defaultRunDict $settings]
475 
476  # Remove quotes from vivado properties
477  regsub -all {\"} $currset "" currset
478 
479  if {[string toupper $currset] != [string toupper $hogset] && ([string toupper $currset] != [string toupper $defset] || $hogset != "")} {
480  if {[string first "DEFAULT" [string toupper $currset]] != -1 && $hogset == ""} {
481  continue
482  }
483  if {[string tolower $hogset] == "true" && $currset == 1} {
484  continue
485  }
486  if {[string tolower $hogset] == "false" && $currset == 0} {
487  continue
488  }
489  if {[regexp {\_VER$} [string toupper $settings]] || [regexp {\_SHA$} [string toupper $settings]]} {
490  continue
491  }
492 
493  if {[string toupper $settings] != "STRATEGY"} {
494  dict set newRunDict $settings $currset
495  if {$options(recreate_conf) == 1} {
496  incr ConfErrorCnt
497  Msg Info "$proj_run setting $settings has been changed from \"$hogset\" in hog.conf to \"$currset\" in project."
498  } elseif {[file exists $repo_path/Top/$group_name/$project_name/hog.conf] && $hasStrategy == 0} {
499  MsgAndLog "Project $proj_run setting $settings value \"$currset\" does not match hog.conf \"$hogset\"." "CriticalWarning" $outFile
500  incr ConfErrorCnt
501  }
502  }
503  } elseif {[string toupper $currset] == [string toupper $hogset] && [string toupper $hogset] != "" && [string toupper $settings] != "STRATEGY"} {
504  dict set newRunDict $settings $currset
505  }
506  }
507  dict set newConfDict $proj_run $newRunDict
508 
509  #if anything remains into hogConfDict it means that something is wrong
510  foreach settings [dict keys $hogConfRunDict] {
511  if {[dict exists $projRunDict [string toupper $settings]] == 0} {
512  if {$settings in $PROP_BAN_LIST} {
513  Msg Warning "In hog.conf section $proj_run the following property is defined: \"$settings\". \
514  This property is ignored and will not be rewritten when automatically recreating hog.conf (i.e. pressing Hog button)."
515  continue
516  }
517  incr ConfErrorCnt
518  if {$options(recreate_conf) == 0} {
519  MsgAndLog "hog.conf property $settings is not a valid Vivado property." "CriticalWarning" $outFile
520  } else {
521  Msg Info "found property $settings in old hog.conf. This is not a valid Vivado property and will be deleted."
522  }
523  }
524  }
525  }
526 
527  #check if the version in the she-bang is the same as the IDE version, otherwise incr ConfErrorCnt
528  set actual_version [GetIDEVersion]
529  if {[file exists $conf_file]} {
530  lassign [GetIDEFromConf $conf_file] ide conf_version
531  if {$actual_version != $conf_version} {
532  MsgAndLog "The version specified in the first line of hog.conf is wrong or no version was specified. \
533  If you want to run this project with $ide $actual_version, the first line of hog.conf should be: \#$ide $actual_version" "CriticalWarning" $outFile
534  incr ConfErrorCnt
535  }
536  }
537 
538 
539  if {$ConfErrorCnt == 0 && [file exists $conf_file] == 1} {
540  Msg Info "$conf_file matches project. Nothing to do"
541  }
542 
543  # recreating hog.conf
544  if {$options(recreate_conf) == 1 && ($ConfErrorCnt > 0 || [file exists $conf_file] == 0 || $hasStrategy == 1)} {
545  Msg Info "Updating configuration file $repo_path/$DirName/hog.conf."
546  # writing configuration file
547  set confFile $repo_path/$DirName/hog.conf
548  set version [GetIDEVersion]
549  WriteConf $confFile $newConfDict "vivado $version"
550  }
551  }
552 
553  set sim_conf "$repo_path/Top/$group_name/$project_name/sim.conf"
554  # Checking simulation settings
555  if {$options(recreate) == 0 || $options(recreate_sim) == 1} {
556  #creating 4 dicts:
557  # - simConfDict: sim.conf properties (if exists)
558  # - defaultConfDict: default properties
559  # - projConfDict: current project properties
560  # - newConfDict: "new" sim.conf
561  set simConfDict [dict create]
562  set defaultConfDict [dict create]
563  set projConfDict [dict create]
564  set newSimConfDict [dict create]
565 
566  # Get SimSets from list files or sim.conf
567  set dict_list_simsets [GetSimSets $group_name/$project_name $repo_path]
568  set dict_proj_simsets [dict create]
569  # filling defaultConfDict and projConfDict
570  foreach simset [get_filesets] {
571  if {[get_property FILESET_TYPE $simset] != "SimulationSrcs"} {
572  continue
573  }
574  #creating dictionary for each simset
575  set projSimDict [dict create]
576  set defaultSimDict [dict create]
577  set simset_error 0
578  #selecting only READ/WRITE properties
579  set sim_props [list]
580  foreach propReport [split "[report_property -return_string -all [get_filesets $simset]]" "\n"] {
581  if {[string equal "[lindex $propReport 2]" "false"]} {
582  lappend sim_props [lindex $propReport 0]
583  }
584  }
585 
586  foreach prop $sim_props {
587  if {$prop in $SIM_BAN_LIST} {
588  continue
589  }
590 
591  #Project values
592  # setting only relative paths
593  if {[string first $repo_path [get_property $prop $simset]] != -1} {
594  dict set projSimDict [string toupper $prop] [Relative $repo_path [get_property $prop $simset]]
595  } elseif {[string first $ext_path [get_property $prop $simset]] != -1} {
596  dict set projSimDict [string toupper $prop] [Relative $ext_path [get_property $prop $simset]]
597  } else {
598  dict set projSimDict [string toupper $prop] [get_property $prop $simset]
599  }
600 
601  # default values
602  dict set defaultSimDict [string toupper $prop] [list_property_value -default $prop $simset]
603  dict set projConfDict $simset $projSimDict
604  dict set defaultConfDict $simset $defaultSimDict
605  }
606 
607  set hog_simset [DictGet $dict_list_simsets $simset]
608  set list_props [DictGet $hog_simset "properties"]
609  set list_generics [DictGet $hog_simset "generics"]
610  set list_hog_section [DictGet $hog_simset "hog"]
611  set list_simulator [DictGet $hog_simset "simulator"]
612 
613  set newSimDict [dict create]
614  set newGenericsDict [dict create]
615  set projSimDict [DictGet $projConfDict $simset]
616  set defaultRunDict [DictGet $defaultConfDict $simset]
617 
618  foreach setting [dict keys $projSimDict] {
619  set currset [DictGet $projSimDict $setting]
620  set hogset [DictGet $list_props $setting]
621  set defset [DictGet $defaultRunDict $setting]
622 
623  if {[string toupper $setting] == "GENERIC"} {
624  # Check the generics section of the sim.conf
625  foreach gen_set $currset {
626  set generic_and_value [split $gen_set =]
627  set generic [string toupper [lindex $generic_and_value 0]]
628  set gen_value [lindex $generic_and_value 1]
629  set generichogset [DictGet $list_generics $generic]
630 
631  # Remove quotes from vivado properties
632  regsub -all {\"} $gen_value "" gen_value
633  dict set newGenericsDict $generic $gen_value
634  if {$gen_value != $generichogset} {
635  if {$options(recreate_sim) == 1} {
636  incr simset_error
637  Msg Info "$simset generics setting $generic has been changed from \"$generichogset\" in sim.conf to \"$gen_value\" in project."
638  } elseif {[file exists $sim_conf]} {
639  MsgAndLog "Simset $simset setting $generic value \"$gen_value\" does not match sim.conf \"$generichogset\"." "Warning" $outSimFile
640  incr simset_error
641  }
642  }
643  }
644  continue
645  }
646 
647  if {[string toupper $currset] != [string toupper $hogset] && [string toupper $currset] != [string toupper $defset]} {
648  if {[string first "DEFAULT" [string toupper $currset]] != -1 && $hogset == ""} {
649  continue
650  }
651  if {[string tolower $hogset] == "true" && $currset == 1} {
652  continue
653  }
654  if {[string tolower $hogset] == "false" && $currset == 0} {
655  continue
656  }
657 
658  if {[regexp {^[^\.]*\.[^\.]*$} $setting]} {
659  continue
660  }
661 
662  dict set newSimDict $setting $currset
663  if {$options(recreate_sim) == 1} {
664  incr simset_error
665  Msg Info "Simulation property $setting of simset $simset has been changed from \"$hogset\" in sim.conf/$simset.sim to \"$currset\" in project."
666  } else {
667  MsgAndLog "Simulation property $setting value \"$currset\" does not match configuration in sim.conf/$simset.sim \"$hogset\"." "Warning" $outSimFile
668  incr simset_error
669  }
670  } elseif {[string toupper $currset] == [string toupper $hogset] && [string toupper $hogset] != ""} {
671  dict set newSimDict $setting $currset
672  }
673  # Check if this is the active simulation set
674  if {$simset == [current_fileset -simset]} {
675  dict set newSimDict "ACTIVE" "1"
676  }
677  }
678  dict set newSimConfDict "properties" $newSimDict
679  dict set newSimConfDict "generics" $newGenericsDict
680  dict set newSimConfDict "hog" $list_hog_section
681 
682  #if anything remains into hogConfDict it means that something is wrong
683  foreach setting [dict keys $list_props] {
684  set hogset [DictGet $list_props $setting]
685  if {$setting == "ACTIVE"} {
686  if {$hogset == "1" && $simset != [current_fileset -simset]} {
687  incr simset_error
688  if {$options(recreate_sim) == 0} {
689  MsgAndLog "Simulation set $simset is set as active, but the actual active one in the project is [current_fileset -simset]" "Warning" $outSimFile
690  } else {
691  Msg Info "Simulation set $simset was set as active in old sim.conf. I will set [current_fileset -simset] as active in the file instead."
692  }
693  }
694  continue
695  }
696 
697  # ignore settings for other simulators
698  set other_sim_prop 0
699  foreach simulator [GetSimulators] {
700  if {[string toupper $simulator] != [string toupper [get_property target_simulator [current_project]]]} {
701  if {[string first [string toupper $simulator] [string toupper $setting]] == 0} {
702  set other_sim_prop 1
703  break
704  }
705  }
706  }
707 
708  if {$other_sim_prop == 1} {
709  continue
710  }
711 
712  if {[dict exists $projSimDict [string toupper $setting]] == 0 && [dict exists $projSimDict $setting] == 0} {
713  incr simset_error
714  if {$options(recreate_sim) == 0} {
715  MsgAndLog "Property $setting is not a valid Vivado property. Please check your sim.conf or $simset.sim file" "Warning" $outSimFile
716  } else {
717  Msg Info "Found property $setting in your sim.conf or $simset.sim file. This is not a valid Vivado property and will be deleted."
718  }
719  }
720  }
721  if {$simset_error == 0} {
722  Msg Info "Simulation properties for $simset are up-to-date. Nothing to do"
723  } else {
724  Msg Warning "Simulation properties for simset $simset have been changed."
725  }
726 
727  # Updating .sim files
728  if {$options(recreate_sim) == 1 && ($simset_error > 0 || $SimListErrorCnt > 0 || [file exists $sim_conf])} {
729  Msg Info "Updating configuration in $simset.sim"
730  # Remove sim.conf if it exists
731  if {[file exists $sim_conf]} {
732  Msg Info "Removing old sim.conf file $sim_conf, properties will be written in $simset.sim file instead."
733  file delete $sim_conf
734  }
735  set listpath "$repo_path/$DirName/list/"
736  file mkdir $listpath
737  #writing configuration file
738  set confFile $repo_path/$DirName/list/$simset.sim
739  set version [GetIDEVersion]
740  WriteConf $confFile $newSimConfDict "Simulator $list_simulator"
741  Msg Info "Adding \[files\] section to $simset.sim list file"
742  WriteSimListFile $simset $prjSimLibraries $prjProperties $prjSimSets $listpath $repo_path $options(force)
743  }
744  set SimConfErrorCnt [expr {$SimConfErrorCnt + $simset_error}]
745  }
746  }
747 }
748 
749 
750 #closing project if a new one was opened
751 if {![string equal $options(project) ""]} {
752  if {[IsVivado]} {
753  close_project
754  }
755 }
756 
757 
758 set TotErrorCnt [expr {$ConfErrorCnt + $SrcListErrorCnt + $ConListErrorCnt}]
759 
760 if {$options(recreate_conf) == 0 && $options(recreate) == 0} {
761  if {$options(pedantic) == 1 && $TotErrorCnt > 0} {
762  Msg Error "Number of errors: $TotErrorCnt. (Design List files = [expr $SrcListErrorCnt + $ConListErrorCnt], hog.conf = $ConfErrorCnt)."
763  } elseif {$TotErrorCnt > 0} {
764  Msg CriticalWarning "Number of errors: $TotErrorCnt (Design List files = [expr $SrcListErrorCnt + $ConListErrorCnt], hog.conf = $ConfErrorCnt)."
765  } else {
766  Msg Info "Design List files and hog.conf match project. All ok!"
767  }
768 
769  if {$SimListErrorCnt > 0 || $SimListErrorCnt > 0} {
770  Msg Warning "Number of mismatch in simulation list files = $SimListErrorCnt"
771  } else {
772  Msg Info "Simulation list files match project. All ok!"
773  }
774 
775  if {$SimConfErrorCnt > 0} {
776  Msg Warning "Number of mismatch in simulation properties = $SimConfErrorCnt"
777  } else {
778  Msg Info "Simulation config files match project. All ok!"
779  }
780 }
781 
782 
783 Msg Info "All done."
784 
785 return $TotErrorCnt