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