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