29 source $tcl_path/utils/hdl_parser.tcl
31 proc PrintOrWrite {output_file msg} {
32 if {$output_file ne ""} {
33 puts $output_file $msg
39 proc _create_hier_meta {} {
40 set hier_meta [dict create]
41 dict set hier_meta all_modules {}
42 dict set hier_meta proj_files {}
43 dict set hier_meta parsed_files_cache {}
47 proc _compute_file_checksum {file_path} {
48 if {![
file exists $file_path]} {
52 if {[
catch {
package require md5 2.0.7} result]} {
54 if {[
catch {
exec md5sum $file_path} output]} {
57 return [
lindex $output 0]
59 return [
string tolower [md5::md5 -hex -file $file_path]]
64 proc is_known_library {hier_meta_ref lib_name} {
65 upvar 1 $hier_meta_ref hier_meta
66 return [dict exists $hier_meta libraries known_libs $lib_name]
69 proc is_ignored_module {module_key ignore_patterns} {
70 foreach pattern $ignore_patterns {
71 if {[
string match $pattern $module_key]} {
78 proc _create_proj_file_info {file_path library properties} {
79 set file_info [dict create]
80 dict set file_info file_path $file_path
81 dict set file_info library $library
82 dict set file_info properties $properties
83 dict set file_info ext [
file extension $file_path]
87 proc file_info_path {file_info} {
return [dict get $file_info file_path]}
88 proc file_info_library {file_info} {
return [dict get $file_info library]}
89 proc file_info_properties {file_info} {
return [dict get $file_info properties]}
90 proc file_info_ext {file_info} {
return [dict get $file_info ext]}
92 proc _store_module {hier_meta_ref mod_name mod_library mod_type file_path references_list props} {
93 upvar 1 $hier_meta_ref hier_meta
95 set key "${mod_library}.${mod_type}.${mod_name}"
97 dict set mod name $mod_name
98 dict set mod library $mod_library
99 dict set mod type $mod_type
100 dict set mod file_path $file_path
101 dict set mod references $references_list
102 dict set mod properties $props
103 dict set mod color "white"
105 dict set hier_meta all_modules $key $mod
108 proc _hier_parse_hdl {hier_meta_ref file_info} {
109 upvar 1 $hier_meta_ref hier_meta
112 if {[
string first "top_control" $file_info] != -1} {
117 if {[
string first "top_l0mdt" $file_info] != -1} {
123 if {![
file exists $f]} {
return}
127 set ext [
string tolower [
file extension $f]]
129 Msg Debug "Parsing $f"
130 set discovered_modules [list]
132 foreach node $hdl_constructs {
138 set node_type [dict get $node type]
139 set node_name [dict get $node name]
141 set references [list]
142 set sv_include_files [list]
143 foreach component [dict get $node components_declared] {
144 lappend references "unknown.component.[dict get $component name]"
147 foreach inst [dict get $node instantiations] {
148 if { [dict get $inst type] == "component_inst"} {
149 lappend references "unknown.component.[dict get $inst mod_name]"
150 }
elseif { [dict get $inst type] == "entity_inst"} {
151 set split_name [
split [dict get $inst mod_name] "."]
152 lappend references "[
lindex $split_name 0].component.[
lindex $split_name 1]"
153 }
elseif { [dict get $inst type] == "sv_import"} {
154 lappend references "unknown.sv_package.[dict get $inst mod_name]"
155 }
elseif { [dict get $inst type] == "sv_include"} {
156 lappend sv_include_files [dict get $inst mod_name]
157 }
elseif { [dict get $inst type] == "vhdl_pkg_inst"} {
158 set split_name [
split [dict get $inst mod_name] "."]
159 lappend references "[
lindex $split_name 0].vhdl_package.[
lindex $split_name 1]"
163 foreach lib [dict get $node libraries] {
164 foreach use [dict get $lib uses] {
165 set split_name [
split $use "."]
166 lappend references "[
lindex $split_name 0].vhdl_package.[
lindex $split_name 1]"
170 set references [lsort -unique $references]
171 dict set node references $references
172 dict set node sv_includes $sv_include_files
174 set mod_properties [dict create]
175 if {$ext eq ".v" || $ext eq ".vh" || $ext eq ".sv" || $ext eq ".svh" ||
176 [lsearch -exact $file_properties "SystemVerilog"] != -1} {
177 if {$ext eq ".sv" || $ext eq ".svh" ||
178 [lsearch -exact $file_properties "SystemVerilog"] != -1} {
179 dict set mod_properties filetype "SystemVerilog"
181 dict set mod_properties filetype "Verilog"
183 }
elseif {$ext eq ".vhd" || $ext eq ".vhdl"} {
184 set knownYears {93 2008 2019}
186 foreach y $knownYears {
187 if {[lsearch -exact $file_properties $y] != -1} {
192 dict set mod_properties filetype "VHDL$year"
195 dict set node properties $mod_properties
196 dict set node library $library
197 dict set node color "white"
199 if {$node_type == "vhdl_architecture"} {
200 set key "${library}.${node_type}.[dict get $node entity].${node_name}"
202 set key "${library}.${node_type}.${node_name}"
205 dict set hier_meta all_modules $key $node
206 lappend discovered_modules $key
208 return $discovered_modules
211 proc _hier_parse_ip {hier_meta_ref file_info {include_gen_prods 0}} {
212 upvar 1 $hier_meta_ref hier_meta
215 if {![
file exists $f]} {
return}
218 set name [
file rootname [
file tail $f]]
219 set mod_properties [dict create]
220 dict set mod_properties filetype "XCI"
223 if {[
catch {open $f r} fid]} {
224 Msg Warning "Warning: Could not open XCI file: $f"
226 set content [read $fid]
229 if {[regexp {"OUTPUTDIR":\s*\[\s*\{\s*"value":\s*"([^"]+)"} $content -> dir_value]} {
230 set output_dir $dir_value
234 set xci_dir [
file dirname $f]
235 set resolved_output_dir [
file normalize [
file join $xci_dir $output_dir]]
239 set dirs_to_scan [list [list $resolved_output_dir 0]]
241 if { $include_gen_prods == 1} {
242 while {[
llength $dirs_to_scan] > 0} {
243 set current [
lindex $dirs_to_scan 0]
244 set dirs_to_scan [
lrange $dirs_to_scan 1 end]
245 set current_dir [
lindex $current 0]
246 set current_depth [
lindex $current 1]
248 if {$current_depth >= 5} { continue}
249 if {![
file isdirectory $current_dir]} { continue}
251 set entries [glob -nocomplain -directory $current_dir *]
252 foreach entry $entries {
253 if {[
file isfile $entry]} {
254 set ext [
string tolower [
file extension $entry]]
255 if {$ext eq ".vhd" || $ext eq ".v" || $ext eq ".sv"} {
256 lappend hdl_files $entry
258 }
elseif {[
file isdirectory $entry]} {
259 set dir_name [
file tail $entry]
261 if {$dir_name ne "synth"} {
262 lappend dirs_to_scan [list $entry [
expr {$current_depth + 1}]]
272 foreach hdl_file $hdl_files {
273 set ext [
string tolower [
file extension $hdl_file]]
277 if {$file_checksum ne "" && [dict exists $hier_meta parsed_files_cache $file_checksum]} {
278 Msg Debug "Reusing previously parsed modules for $hdl_file"
279 set discovered_modules [dict get $hier_meta parsed_files_cache $file_checksum]
280 set all_subs [
concat $all_subs $discovered_modules]
287 set discovered_modules [list]
289 if {$ext eq ".vhd" || $ext eq ".vhdl" || $ext eq ".v" || $ext eq ".sv"} {
293 if {$file_checksum ne ""} {
294 dict set hier_meta parsed_files_cache $file_checksum $discovered_modules
297 set all_subs [
concat $all_subs $discovered_modules]
300 set all_subs [lsort -unique $all_subs]
302 if {[
llength $all_subs] == 0} {
305 _store_module hier_meta $name $library "component" $f $all_subs $mod_properties
307 _store_module hier_meta $name $library "xci" $f $all_subs $mod_properties
314 proc _hier_parse_file {hier_meta_ref file_info {include_gen_prods 0}} {
315 upvar 1 $hier_meta_ref hier_meta
318 if {$ext eq ".vhd" || $ext eq ".vhdl" || $ext eq ".v" || $ext eq ".sv" ||
319 $ext eq ".vh" || $ext eq ".svh"} {
321 }
elseif {$ext eq ".xci"} {
323 }
elseif {$ext eq ".bd"} {
332 proc _hier_submodule_append {hier_meta_ref parent_key sub_key} {
333 upvar 1 $hier_meta_ref hier_meta
335 if {[dict exists $hier_meta all_modules $parent_key]} {
336 set mod [dict get $hier_meta all_modules $parent_key]
337 dict lappend mod references $sub_key
338 dict set hier_meta all_modules $parent_key $mod
343 proc _reference_resolver {hier_meta_ref} {
344 upvar 1 $hier_meta_ref hier_meta
346 set package_bodies [ dict filter [dict get $hier_meta all_modules] script {k v} {expr {[dict get $v type] eq "vhdl_package_body"}}]
347 set architectures [ dict filter [dict get $hier_meta all_modules] script {k v} {expr {[dict get $v type] eq "vhdl_architecture"}}]
349 dict for {package_body body_info} $package_bodies {
350 set entity_key [split $package_body "."]
351 set entity_key "[lindex $entity_key 0].vhdl_package.[lindex $entity_key 2]"
352 if {[dict exists [dict get $hier_meta all_modules] $entity_key]} {
353 _hier_submodule_append hier_meta $entity_key $package_body
358 dict for {architecture arch_info} $architectures {
359 # if {[string first "top_l0mdt" $architecture] != -1} {
364 # if {[string first "top_control" $architecture] != -1} {
369 set entity_key [split $architecture "."]
370 set entity_key "[lindex $entity_key 0].vhdl_entity.[lindex $entity_key 2]"
371 if {[dict exists [dict get $hier_meta all_modules] $entity_key]} {
372 _hier_submodule_append hier_meta $entity_key $architecture
379 set resolution_list [list]
381 dict for {mod_key mod} [dict get $hier_meta all_modules] {
382 set references_data [dict get $mod references]
383 set new_references [list]
384 set mod_lib [dict get $mod library]
386 if { [string first "top_control" $mod_key] != -1 } {
390 foreach ref $references_data {
391 # puts "Processing ref: $ref in mod: $mod_key"
392 set parts [split $ref "."]
393 set library [lindex $parts 0]
394 set type [lindex $parts 1]
395 set name [lindex $parts 2]
399 set resolved_mod_name ""
401 if {$library == "unknown" && $type == "sv_package"} {
402 set pattern ".*\\.sv_package\\.$name\$"
403 set matches [dict filter [dict get $hier_meta all_modules] \
404 script {k v} {expr {[regexp $pattern $k]}}]
405 if {[dict size $matches] == 0} {
406 lappend new_references $ref
407 Msg Debug "No sv_package match found for $ref in $mod_key"
409 dict for {k v} $matches {
410 lappend new_references $k
411 Msg Debug "Mod: $mod_key resolved $ref to $k"
418 if { ($library != "unknown" && $library != "work" && $type != "component") || ($library == "unknown" && $type != "component") } {
419 # puts "Keeping reference as-is: $ref"
420 lappend new_references $ref
425 if { $library != "unknown"} {
432 set pattern "${ref_lib}\\.(vhdl_entity|verilog_module)\\.$name\$"
433 set matches [dict filter [dict get $hier_meta all_modules] script {k v} {expr {[regexp $pattern $k]}}]
434 if {[dict size $matches] == 0} {
435 set pattern ".*\\.(vhdl_entity|verilog_module)\\.$name\$"
436 set matches [dict filter [dict get $hier_meta all_modules] script {k v} {expr {[regexp $pattern $k]}}]
437 if {[dict size $matches] > 1} {
438 Msg Warning "Ambiguous component reference '$name' in '$mod_key': multiple libraries match, picking first found"
442 if {[dict size $matches] == 0} {
443 lappend new_references $ref
444 Msg Debug "No match found for $ref in $mod_key"
446 dict for {k v} $matches {
447 lappend new_references $k
448 Msg Debug "Mod: $mod_key resolved $ref to $k"
454 dict set hier_meta all_modules $mod_key references $new_references
460 dict for {mod_key mod} [dict get $hier_meta all_modules] {
461 if {![dict exists $mod sv_includes]} { continue }
462 set sv_includes [dict get $mod sv_includes]
463 if {[llength $sv_includes] == 0} { continue }
465 set new_refs [dict get $mod references]
466 foreach include_file $sv_includes {
467 dict for {proj_file _} [dict get $hier_meta proj_files] {
468 if {[file tail $proj_file] ne $include_file} { continue }
469 dict for {k m} [dict get $hier_meta all_modules] {
470 if {[dict get $m file_path] eq $proj_file &&
471 [lsearch -exact $new_refs $k] == -1} {
474 Msg Debug "Mod: $mod_key include-depends on $k (via $include_file)"
479 dict set hier_meta all_modules $mod_key references $new_refs
482 return [dict create total $total_resolved resolutions $resolution_list]
485 proc dfs_sort {hier_meta_ref top_module} {
486 upvar 1 $hier_meta_ref hier_meta
489 proc _dfs_visit {hier_meta_ref node sorted_ref bad_nodes_ref} {
490 upvar 1 $hier_meta_ref hier_meta
491 upvar 1 $sorted_ref sorted
492 upvar 1 $bad_nodes_ref bad_nodes
494 if {![dict exists $hier_meta all_modules $node]} {
498 set mod [dict get $hier_meta all_modules $node]
499 set color [dict get $mod color]
501 if {$color eq "gray"} {
502 Msg Warning "Warning: Circular dependency detected at $node"
503 if {[lsearch -exact $bad_nodes $node] == -1} {
504 lappend bad_nodes $node
509 if {$color eq "black"} {
513 dict set mod color "gray"
514 dict set hier_meta all_modules $node $mod
517 set references [dict get $mod references]
518 foreach child $references {
522 set mod [dict get $hier_meta all_modules $node]
523 dict set mod color "black"
524 dict set hier_meta all_modules $node $mod
532 _dfs_visit hier_meta $top_module sorted bad_nodes
534 if {[
llength $bad_nodes] > 0} {
535 return [dict create success 0 sorted {} cycles 1 bad_nodes $bad_nodes]
538 return [dict create success 1 sorted $sorted cycles 0 bad_nodes {}]
542 proc _debug_string_hier_meta {hier_meta_ref {indent 0}} {
543 upvar 1 $hier_meta_ref hier_meta
545 set ind [
string repeat " " $indent]
546 set s "${ind}=== ALL MODULES ==="
547 dict for {key mod} [dict get $hier_meta all_modules] {
548 append s "\n${ind}$key:"
549 dict for {field value} $mod {
550 append s "\n${ind} $field: $value"
555 append s "\n${ind}=== PROJECT FILES ==="
556 dict for {file finfo} [dict get $hier_meta proj_files] {
557 append s "\n${ind}$file:"
558 dict for {field value} $finfo {
559 append s "\n${ind} $field: $value"
568 proc Hierarchy {listProperties listLibraries repo_path {output_path ""} \
569 {compile_order 0} {light ""} {top_module_override ""} {ignore_opt_list ""} {include_ieee 0} {include_gen_prods 0} {quiet 0}} {
574 set ignore_list [list]
576 if {$include_ieee == 0} {
577 lappend ignore_list "ieee.*.*"
578 lappend ignore_list "std.*.*"
581 foreach pat [
split $ignore_opt_list ","] {
582 set pat [
string trim $pat]
584 if {![regexp {^[\w*]+\.[\w*]+\.[\w*]+$} $pat]} {
585 Msg Warning "Warning: ignore pattern '$pat' does not match expected format <lib>.<type>.<name> (wildcards * allowed), ignoring"
587 lappend ignore_list $pat
592 if {$top_module_override ne ""} {
593 set top_module $top_module_override
594 Msg Warning "Using specified top module: $top_module"
597 dict for {lib files} $listLibraries {
598 set lib [file rootname $lib]
602 if {[dict exists $listProperties $f]} {
604 set fprops [dict get $listProperties $f]
605 if {$top_module eq ""} {
606 set top [lindex [regexp -inline {\ytop\s*=\s*(.+?)\y.*} $fprops] 1]
608 set ext [file extension $f]
609 if {$ext eq ".vhd" || $ext eq ".vhdl"} {
610 set top_module "${lib}.vhdl_entity.${top}"
611 } elseif { $ext eq ".v" || $ext eq ".sv"} {
612 set top_module "${lib}.verilog_module.${top}"
614 set top_module "${lib}.component.${top}"
621 dict set hier_meta proj_files $f [_create_proj_file_info $f $lib $props]
625 if {$top_module_override eq ""} {
626 Msg Info "Top module from properties: $top_module"
630 dict for {file file_info} [dict get $hier_meta proj_files] {
631 _hier_parse_file hier_meta $file_info $include_gen_prods
634 set parse_us [
lindex $t_parse 0]
635 set parse_ms [
expr {$parse_us / 1000.0}]
637 Msg Info "Completed initial parsing in $parse_ms ms"
639 set t_resolve [
time {
640 set resolve_result [_reference_resolver hier_meta]
642 set resolve_us [
lindex $t_resolve 0]
643 set resolve_ms [
expr {$resolve_us / 1000.0}]
645 set total [dict get $resolve_result total]
646 set resolutions [dict get $resolve_result resolutions]
647 Msg Info "Completed reference resolution: $total references resolved in $resolve_ms ms"
650 if {$output_path != ""} {
651 set output_file [open $repo_path/$output_path "w"]
658 set sorted_modules [
dfs_sort hier_meta $top_module]
659 set bad_nodes [dict get $sorted_modules bad_nodes]
663 if {$compile_order} {
664 set compile_order_dict [
print_compile_order hier_meta [dict get $sorted_modules sorted] $output_file $quiet]
665 if {$output_path != ""} {
668 return $compile_order_dict
670 set p [
print_hierarchy hier_meta $top_module $output_file $ignore_list $bad_nodes $light]
671 PrintOrWrite $output_file "\n\n=====Packages in project:====="
672 dict for {lib pkg_list} $p {
673 if {[llength $pkg_list] == 0} {
676 PrintOrWrite $output_file "Library: $lib"
677 foreach pkg_entry $pkg_list {
678 PrintOrWrite $output_file " Package: $pkg_entry"
683 if {$output_path != ""} {
688 proc print_compile_order {hier_meta_ref sorted_list {output_file ""} {quiet 0}} {
689 upvar 1 $hier_meta_ref hier_meta
699 set seen [dict create]
701 foreach mod_key $sorted_list {
702 set mod [dict get $hier_meta all_modules $mod_key]
703 set file_path [dict get $mod file_path]
704 set library [dict get $mod library]
705 set pair "${file_path}\t${library}"
707 if {$file_path eq "" || [dict exists $seen $pair]} {
710 dict set seen $pair 1
711 lappend result $file_path $library
714 dict for {file file_info} [dict get $hier_meta proj_files] {
715 set library [file_info_library $file_info]
716 set pair "${file}\t${library}"
717 if {[dict exists $seen $pair]} {
720 dict set seen $pair 1
721 lappend result $file $library
725 foreach {file lib} $result {
733 proc print_hierarchy {hier_meta_ref module {output_file ""} {ignore_list ""} \
734 {bad_nodes ""} {light 0} {indent 0} {stack_ref ""} {last_properties_ref ""} {is_last 1}} {
735 upvar 1 $hier_meta_ref hier_meta
743 if {$stack_ref eq ""} {
745 set last_properties [list]
747 upvar 1 $stack_ref stack
748 upvar 1 $last_properties_ref last_properties
752 if {![dict exists $hier_meta all_modules $module]} {
753 set parts [
split $module "."]
754 set lib [
lindex $parts 0]
755 set type [
lindex $parts 1]
756 set name [
lindex $parts 2]
761 set mod [dict get $hier_meta all_modules $module]
763 set name [dict get $mod name]
764 set type [dict get $mod type]
765 set lib [dict get $mod library]
766 set file_path [dict get $mod file_path]
771 if {$type eq "vhdl_entity" && $module_exists} {
772 set references [dict get $mod references]
774 foreach ref $references {
775 if {[
string match "${lib}.vhdl_architecture.${name}.*" $ref]} {
776 lappend arch_refs $ref
779 if {[
llength $arch_refs] == 1} {
780 set arch_key [
lindex $arch_refs 0]
781 if {[dict exists $hier_meta all_modules $arch_key]} {
782 set arch_mod [dict get $hier_meta all_modules $arch_key]
783 set arch_file_path [dict get $arch_mod file_path]
784 if {$arch_file_path eq $file_path} {
785 set p [
print_hierarchy hier_meta $arch_key $output_file $ignore_list $bad_nodes $light $indent stack last_properties $is_last]
786 set package_dict [
MergeDict $p $package_dict]
795 if {[lsearch -exact $stack $module] != -1} {
796 if {[lsearch -exact $bad_nodes $module] != -1} {
802 lappend stack $module
806 for {
set i 0} {$i < [
llength $last_properties]} {
incr i} {
807 if {[
lindex $last_properties $i]} {
808 append indent_str " "
810 append indent_str "│ "
827 set path_str " - ${file_path}"
830 if {$type == "vhdl_architecture"} {
831 set name "[dict get $mod entity].$name"
835 if {[
string first "vhdl_package" $type] == -1} {
836 if {!$module_exists} {
837 set msg "${indent_str}${connector}${lib}.${name} (${type})"
838 }
elseif {$is_circular} {
839 set msg "${indent_str}${connector}${lib}.${name} (${type})${path_str} \[WARNING: circular reference detected\]"
841 set msg "${indent_str}${connector}${lib}.${name} (${type})${path_str}"
844 if {[
DictGet $package_dict "$lib"] == ""} {
845 dict set package_dict "$lib" [list]
847 set package_list [
DictGet $package_dict "$lib"]
848 if {![
IsInList $package_list "${name} ${path_str}"] } {
849 lappend package_list "${name} ${path_str}"
850 dict set package_dict "$lib" $package_list
857 if {$is_circular || !$module_exists} {
861 set references [dict get $mod references]
862 set all_subs [lsort -unique $references]
865 set filtered_subs [list]
866 foreach sub $all_subs {
868 lappend filtered_subs $sub
872 set num_subs [
llength $filtered_subs]
874 foreach sub $filtered_subs {
876 set is_last_child [
expr {$sub_idx == $num_subs}]
878 lappend last_properties $is_last
879 set p [
print_hierarchy hier_meta $sub $output_file $ignore_list $bad_nodes $light [
expr {$indent + 1}] stack last_properties $is_last_child]
880 set package_dict [
MergeDict $p $package_dict]
881 set last_properties [
lrange $last_properties 0 end-1]
884 set stack [
lrange $stack 0 end-1]
890 proc get_rtl_refs {node {name ""}} {
891 set out [dict create]
893 if {$name ne "" && ![
catch {dict get $node reference_info} refinfo]} {
895 catch {
set rt [dict get $refinfo ref_type]}
896 catch {
set rn [dict get $refinfo ref_name]}
897 if {[
string equal $rt "hdl"] && $rn ne ""} {
898 dict set out $name $rn
902 if {![
catch {dict get $node components} comps]} {
903 dict for {cname cnode} $comps {
904 set childMap [get_rtl_refs $cnode $cname]
905 set out [dict merge $out $childMap]
909 dict for {k v} $node {
910 if {$k eq "components" || $k eq "reference_info"} {continue}
911 if {[catch {dict size $v}]} {continue}
912 set childMap [get_rtl_refs $v $k]
913 set out [dict merge $out $childMap]
919 proc _hier_parse_bd {hier_meta_ref file_info} {
920 upvar 1 $hier_meta_ref hier_meta
924 if {![
file exists $f]} {
return}
929 set name [
file rootname [
file tail $f]]
930 set mod_properties [dict create]
931 dict set mod_properties filetype "BD"
933 set bd_file [open $f r]
934 set bd_json [read $bd_file]
936 set bd_design $bd_json
938 set lines [
split $bd_design "\n"]
939 set filtered_lines {}
940 foreach line $lines {
941 if {[
string first "\\" $line] == -1} {
942 lappend filtered_lines $line
945 set bd_design [
join $filtered_lines "\n"]
947 regsub -all {":\s*\{} $bd_design " \{" bd_design
948 regsub -all {:\s*("(?:[^"\\]|\\.)*")} $bd_design { {\1}} bd_design
949 regsub -all {"} $bd_design {} bd_design
950 regsub -all {,} $bd_design {} bd_design
951 regsub -all {:\s* \{} $bd_design {\{} bd_design
952 regsub -all {\[} $bd_design "\{" bd_design
953 regsub -all {\]} $bd_design "\}" bd_design
955 set bd_design [
string range $bd_design 1 end-1]
957 if {[
catch {dict size $bd_design} err]} {
958 Msg Warning "Warning: malformed bd_design in $f, skipping"
962 set bd_design [
lindex $bd_design 1]
964 set unknown_modules {}
966 if {[lsearch -exact $unknown_modules $v] == -1} {
967 lappend unknown_modules "unknown.component.$v"
970 _store_module hier_meta $name $library component $f $unknown_modules $mod_properties