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