基于tcl脚本构建Xilinx Vivado工程
为了便于工程管理,将svn文件压缩到最小,通过tcl脚本实现对工程的管理,方便远程客户端工程的使用。
1 工程目录
工程目录如下
my_fpga_project/
├── build.tcl # 主构建入口脚本
├── create_project.tcl # 工程创建脚本
├── ip_manager.tcl # IP管理模块
├── bd_manager.tcl # Block Design管理模块
├── src/
│ ├── hdl/
│ │ ├── top.v
│ │ ├── module1.v
│ │ └── module2.v
│ ├── xdc/
│ │ ├── timing.xdc
│ │ └── physical.xdc
│ └── sim/
│ └── testbench.v
├── ip/
│ ├── clk_wiz_0/
│ │ ├── clk_wiz_0.tcl
│ │ └── clk_wiz_0.xci
│ ├── blk_mem_gen_0/
│ │ ├── blk_mem_gen_0.tcl
│ │ └── blk_mem_gen_0.xci
│ └── axi_uartlite_0/
│ ├── axi_uartlite_0.tcl
│ └── axi_uartlite_0.xci
├── bd/
│ ├── system_bd.tcl # Block Design重建脚本
│ └── system_bd.bd # Block Design文件(可选)
├── output/
│ └── bitstream/
└── temp/ # 临时目录(完全忽略)
2 IP生成脚本
现行流程
我们现在的流程是:
先有IP,然后生成重建脚本;
在新环境中,我们是通过重建脚本来创建IP。
# 完整的IP脚本和文件生成函数
proc generate_all_ip_scripts {{ip_dir "./ip"}} {set ip_list [get_ips]if {[llength $ip_list] == 0} {puts "WARNING: No IPs found in the current project."return 0}puts "=================================================================="puts "Generating scripts and files for [llength $ip_list] IP cores"puts "=================================================================="set success_count 0set warning_count 0set error_count 0# 安全地打印IP列表puts -nonewline "IP List: "foreach ip $ip_list {#puts -nonewline "[get_property NAME $ip] "}#puts ""foreach ip $ip_list {set ip_name [get_property NAME $ip]set specific_ip_dir "$ip_dir/$ip_name"puts "Processing IP: $ip_name"# 创建IP目录if {![file exists $specific_ip_dir]} {file mkdir $specific_ip_dir# puts "Created directory: $specific_ip_dir"}# 生成重建脚本set script_result [generate_ip_script $ip $specific_ip_dir]# 复制.xci文件set xci_result [copy_xci_file $ip $specific_ip_dir]# 复制其他相关文件# set additional_result [copy_ip_additional_files $ip $specific_ip_dir] # 统计结果if {$script_result && $xci_result} {incr success_countputs "SUCCESS: Completed processing for $ip_name"} else {if {!$script_result} {incr error_count} else {incr warning_count}puts "WARNING: Some operations failed for $ip_name"}# 空行分隔 puts "" }# 输出总结报告puts "=================================================================="puts "GENERATION SUMMARY"puts "=================================================================="puts "Total IPs processed: [llength $ip_list]"puts "Successfully completed: $success_count"puts "With warnings: $warning_count"puts "With errors: $error_count"if {$error_count == 0} {puts "All IP scripts and files have been generated successfully!"return 1} else {puts "Some IPs had errors during generation. Please check the logs above."return 0}
}# 生成单个IP的重建脚本
proc generate_ip_script {ip ip_dir} {set ip_name [get_property NAME $ip]set script_path "$ip_dir/$ip_name.tcl"# 使用更精确的错误捕获set result [catch {write_ip_tcl $ip -force $script_path} error_msg options]# 检查文件是否生成(无论是否有警告)if {[file exists $script_path]} {puts "Generated script: $script_path"if {$result != 0} {# 有警告但文件生成了puts "Note: Generation completed with warnings: $error_msg"}return 1} else {# 文件未生成,真正的失败puts "ERROR: Failed to generate script for $ip_name: $error_msg"return 0}
}# 复制.xci文件
proc copy_xci_file {ip ip_dir} {# 获取项目目录set project_dir [get_property DIRECTORY [current_project]]set ip_name [get_property NAME $ip]# 尝试多种方式查找.xci文件set xci_found 0# 方法1: 尝试直接获取属性# if {!$xci_found} {# if {[catch {# set xci_file [get_property FILE_NAME $ip]# if {[file exists $xci_file]} {# set xci_target "$ip_dir/[file tail $xci_file]"# file copy -force $xci_file $xci_target# puts " Copied .xci file (method 1): $xci_target"# set xci_found 1# }# } error_msg]} {# puts " Method 1 failed: $error_msg"# }# }# 方法2: 在项目目录中搜索if {!$xci_found} {# 安全地构建搜索模式set search_patterns [list]lappend search_patterns "$project_dir/${ip_name}.xci"lappend search_patterns "$project_dir/*.srcs/*/ip/*/${ip_name}.xci"lappend search_patterns "$project_dir/*.gen/*/ip/*/${ip_name}.xci"# 安全地打印搜索模式puts -nonewline "Search patterns: "foreach pattern $search_patterns {puts -nonewline "$pattern "}puts ""foreach pattern $search_patterns {# 修复:使用 catch 来避免 glob 错误if {[catch {set files [glob -nocomplain -- $pattern]foreach file $files {if {[file exists $file]} {set xci_target "$ip_dir/[file tail $file]"puts "xci_target: $xci_target"puts "file: $file"file copy -force $file $xci_targetputs "Copied .xci file: $xci_target"set xci_found 1break}}} error_msg]} {puts "WARNING: Error searching with pattern $pattern: $error_msg"}if {$xci_found} { break }}}if {!$xci_found} {puts "WARNING: Could not locate .xci file for $ip_name"return 0} return 1
}# 复制IP的其他相关文件
# proc copy_ip_additional_files {ip ip_dir} {
# set ip_name [get_property NAME $ip]
# set ip_file_dir [file dirname [get_property FILE_NAME $ip]]
# set copied_files 0
#
# # 定义需要复制的文件类型
# set file_patterns {
# "*.coe"
# "*.mif"
# "*.dat"
# "*.mem"
# "*.hex"
# "*.edif"
# "*.ngc"
# }
#
# foreach pattern $file_patterns {
# set files [glob -nocomplain "$ip_file_dir/$pattern"]
# foreach file $files {
# set target_file "$ip_dir/[file tail $file]"
# if {[catch {
# file copy -force $file $target_file
# puts " Copied additional file: [file tail $file]"
# incr copied_files
# } error_msg]} {
# puts " WARNING: Failed to copy [file tail $file]: $error_msg"
# }
# }
# }
#
# if {$copied_files > 0} {
# puts " Copied $copied_files additional files for $ip_name"
# }
#
# return 1
# }# 主执行部分
if {[info script] eq $argv0} {# 如果直接运行此脚本set root_dir [file normalize "."]set ip_dir "$root_dir/ip"# 确保IP目录存在if {![file exists $ip_dir]} {file mkdir $ip_dirputs "Created main IP directory: $ip_dir"}# 生成所有IP脚本和文件generate_all_ip_scripts $ip_dir
}
在Vivado Tcl控制台中执行
source generate_ip_scripts.tcl
generate_all_ip_scripts "./ip"
生成ip所需要的tcl脚本。
运行日志
generate_all_ip_scripts "./ip"
==================================================================
Generating scripts and files for 3 IP cores
==================================================================
IP List: Processing IP: pll24
Generated script: ./ip/pll24/pll24.tcl
Search patterns: K:/2025Niu/NewUSBCore_ForA7/pll24.xci K:/2025Niu/NewUSBCore_ForA7/*.srcs/*/ip/*/pll24.xci K:/2025Niu/NewUSBCore_ForA7/*.gen/*/ip/*/pll24.xci
xci_target: ./ip/pll24/pll24.xci
file: K:/2025Niu/NewUSBCore_ForA7/BF_System.srcs/sources_1/ip/pll24/pll24.xci
Copied .xci file: ./ip/pll24/pll24.xci
SUCCESS: Completed processing for pll24Processing IP: pll48
Generated script: ./ip/pll48/pll48.tcl
Search patterns: K:/2025Niu/NewUSBCore_ForA7/pll48.xci K:/2025Niu/NewUSBCore_ForA7/*.srcs/*/ip/*/pll48.xci K:/2025Niu/NewUSBCore_ForA7/*.gen/*/ip/*/pll48.xci
xci_target: ./ip/pll48/pll48.xci
file: K:/2025Niu/NewUSBCore_ForA7/BF_System.srcs/sources_1/ip/pll48/pll48.xci
Copied .xci file: ./ip/pll48/pll48.xci
SUCCESS: Completed processing for pll48Processing IP: scan_tbl
Generated script: ./ip/scan_tbl/scan_tbl.tcl
Search patterns: K:/2025Niu/NewUSBCore_ForA7/scan_tbl.xci K:/2025Niu/NewUSBCore_ForA7/*.srcs/*/ip/*/scan_tbl.xci K:/2025Niu/NewUSBCore_ForA7/*.gen/*/ip/*/scan_tbl.xci
xci_target: ./ip/scan_tbl/scan_tbl.xci
file: K:/2025Niu/NewUSBCore_ForA7/BF_System.srcs/sources_1/ip/scan_tbl/scan_tbl.xci
Copied .xci file: ./ip/scan_tbl/scan_tbl.xci
SUCCESS: Completed processing for scan_tbl==================================================================
GENERATION SUMMARY
==================================================================
Total IPs processed: 3
Successfully completed: 3
With warnings: 0
With errors: 0
All IP scripts and files have been generated successfully!
1
3 工程生成
脚本
# 完整工程创建和IP管理脚本
# 目标器件: xc7a100tcsg324-2# 工程配置参数
set project_name "NewUSBCore_ForA7"
set device_part "xc7a100tcsg324-2"
set ip_dir "./ip"
set hdl_dir "./src/hdl"
set constraints_dir "./src/xdc"
set output_dir "./output"
set top_module_file "vissonicap"
set_property top vissonicap [current_fileset]
# 创建工程目录结构
proc create_project_structure {} {global ip_dir hdl_dir constraints_dir output_dirset dirs [list $ip_dir $hdl_dir $constraints_dir $output_dir]foreach dir $dirs {if {![file exists $dir]} {file mkdir $dirputs "Created directory: $dir"}}
}# 创建新工程
proc create_new_project {project_name device_part} {puts "=================================================================="puts "Creating new project: $project_name"puts "Target device: $device_part"puts "=================================================================="# 关闭当前工程(如果有)if {[get_projects -quiet] ne ""} {close_project}# 创建新工程create_project $project_name . -part $device_part -force# 设置工程属性set_property target_language Verilog [current_project]set_property simulator_language Mixed [current_project]set_property default_lib work [current_project]puts "Project created successfully"return 1
}# 添加HDL文件
proc add_hdl_files {{hdl_dir "./hdl"}} {puts "=================================================================="puts "Adding HDL files from: $hdl_dir"puts "=================================================================="if {![file exists $hdl_dir]} {puts "WARNING: HDL directory '$hdl_dir' does not exist."return 0}# 查找Verilog文件set v_files [glob -nocomplain -directory $hdl_dir "*.v"]set sv_files [glob -nocomplain -directory $hdl_dir "*.sv"]set vhd_files [glob -nocomplain -directory $hdl_dir "*.vhd"]set all_files [concat $v_files $sv_files $vhd_files]if {[llength $all_files] == 0} {puts "WARNING: No HDL files found in $hdl_dir"return 0}# 添加文件到工程add_files -norecurse $all_filesupdate_compile_order -fileset sources_1puts "Added [llength $all_files] HDL files:"foreach file $all_files {puts " [file tail $file]"}# 设置顶层模块(自动检测) set_top_module_improved $all_files# 手动配置顶层模块# puts " Top File = $top_module_file" # set_property top $top_module_file [current_fileset] return 1
}# 改进的顶层模块设置 - 修复版本
proc set_top_module_improved {all_files} {puts "=================================================================="puts "Setting Top Module"puts "=================================================================="# 优先查找包含项目名称或明显顶层标识的文件set top_module_candidates [list]foreach file $all_files {set file_name [file tail $file]set module_name [file rootname $file_name]puts "Checking file: $file_name, module: $module_name"# 优先级1: 包含项目名称的文件if {[string match "*vissonicap*" [string tolower $module_name]]} {lappend top_module_candidates [list $module_name $file 10]puts " -> High priority candidate: $module_name (contains 'vissonicap')"continue}# 优先级2: 包含"top"的文件if {[string match "*top*" [string tolower $module_name]]} {lappend top_module_candidates [list $module_name $file 5]puts " -> Medium priority candidate: $module_name (contains 'top')"continue}# 优先级3: 其他文件lappend top_module_candidates [list $module_name $file 1]puts " -> Low priority candidate: $module_name"}# 按优先级排序set top_module_candidates [lsort -integer -decreasing -index 2 $top_module_candidates]if {[llength $top_module_candidates] == 0} {puts "ERROR: No candidate modules found"return 0}# 选择最高优先级的模块set best_candidate [lindex $top_module_candidates 0]set top_module_name [lindex $best_candidate 0]set top_module_file [lindex $best_candidate 1]set top_module_priority [lindex $best_candidate 2]puts "Selected top module: $top_module_name (priority: $top_module_priority)"puts "From file: [file tail $top_module_file]"# 设置顶层模块set_property top $top_module_name [current_fileset]puts "Successfully set top module to: $top_module_name"return 1
}# 手动设置顶层模块(如果自动检测失败)
proc set_top_module_manual {module_name} {puts "=================================================================="puts "Manually Setting Top Module to: $module_name"puts "=================================================================="# 检查模块是否存在set files [get_files -compile_order sources -used_in synthesis]set module_found 0foreach file $files {set file_module [file rootname [file tail $file]]if {[string equal $file_module $module_name]} {set module_found 1break}}if {!$module_found} {puts "ERROR: Module '$module_name' not found in project files"return 0}# 设置顶层模块set_property top $module_name [current_fileset]puts "Successfully set top module to: $module_name"return 1
}# 添加约束文件
proc add_constraint_files {{constraints_dir "./constraints"}} {puts "=================================================================="puts "Adding constraint files from: $constraints_dir"puts "=================================================================="if {![file exists $constraints_dir]} {puts "WARNING: Constraints directory '$constraints_dir' does not exist."return 0}# 查找约束文件set xdc_files [glob -nocomplain -directory $constraints_dir "*.xdc"]if {[llength $xdc_files] == 0} {puts "WARNING: No constraint files (.xdc) found in $constraints_dir"return 0}# 添加约束文件add_files -fileset constrs_1 -norecurse $xdc_filesputs "Added [llength $xdc_files] constraint files:"foreach file $xdc_files {puts " [file tail $file]"}return 1
}# 重建单个IP - 修复版本
proc rebuild_single_ip {script_path ip_name ip_dir {force_refresh 0}} {# 检查脚本文件是否存在if {![file exists $script_path]} {puts " ERROR: Script file does not exist: $script_path"return 0}# 检查IP目录是否存在if {![file exists $ip_dir]} {puts " ERROR: IP directory does not exist: $ip_dir"return 0}set ip_exists [get_ips -quiet $ip_name]if {$ip_exists ne "" && !$force_refresh} {puts " IP $ip_name already exists in project. Skipping."return 1}if {$ip_exists ne "" && $force_refresh} {puts " Removing existing IP: $ip_name"delete_ips $ip_name}puts " Rebuilding IP from script: $script_path"set result [catch {# 保存当前目录set original_dir [pwd]# 切换到IP目录(使用绝对路径)set target_dir [file normalize $ip_dir]puts " Changing to directory: $target_dir"if {[file exists $target_dir] && [file isdirectory $target_dir]} {cd $target_dir# 执行重建脚本set script_file [file tail $script_path]puts " Executing script: $script_file"source $script_file# 返回原目录cd $original_dir} else {puts " ERROR: Target directory does not exist or is not a directory: $target_dir"return 0}} error_msg]if {$result != 0} {puts " ERROR: Failed to rebuild IP $ip_name: $error_msg"return 0}# 验证IP是否成功创建set rebuilt_ip [get_ips -quiet $ip_name]if {$rebuilt_ip eq ""} {puts " ERROR: IP $ip_name was not created after running script"return 0}puts " IP $ip_name created successfully"# 生成IP输出产品puts " Generating IP output products for $ip_name"set generate_result [catch {generate_target all $rebuilt_ip} generate_error]if {$generate_result != 0} {puts " WARNING: IP generation completed with warnings: $generate_error"# 这不算完全失败,所以仍然返回成功} else {puts " IP output products generated successfully"}return 1
}# 自动重建所有IP
proc rebuild_all_ips {{ip_dir "./ip"} {force_refresh 0}} {puts "=================================================================="puts "Rebuilding IPs from directory: $ip_dir"puts "=================================================================="set ip_dir [file normalize $ip_dir]if {![file exists $ip_dir]} {puts "WARNING: IP directory '$ip_dir' does not exist."return 0}set ip_scripts [find_ip_scripts $ip_dir]if {[llength $ip_scripts] == 0} {puts "WARNING: No IP script files (.tcl) found in $ip_dir"return 0}puts "Found [llength $ip_scripts] IP scripts to process"set success_count 0set error_count 0foreach script_info $ip_scripts {set script_path [dict get $script_info script_path]set ip_name [dict get $script_info ip_name]set ip_dir [dict get $script_info ip_dir]puts "Processing IP: $ip_name"puts " Script: $script_path"set result [rebuild_single_ip $script_path $ip_name $ip_dir $force_refresh]if {$result} {puts "SUCCESS: Rebuilt IP $ip_name"incr success_count} else {puts "ERROR: Failed to rebuild IP $ip_name"incr error_count}puts ""}puts "IP Rebuild Summary:"puts " Successfully rebuilt: $success_count"puts " Failed: $error_count"return [expr {$error_count == 0}]
}# 查找IP脚本文件 - 修复版本
proc find_ip_scripts {ip_dir} {set ip_scripts [list]# 使用安全的目录查找方式if {[catch {set subdirs [glob -nocomplain -type d -directory $ip_dir "*"]} error_msg]} {puts "ERROR: Failed to search IP directory: $error_msg"return $ip_scripts}foreach subdir $subdirs {set dir_name [file tail $subdir]# 在每个子目录中查找.tcl文件if {[catch {set tcl_files [glob -nocomplain -type f -directory $subdir "*.tcl"]} error_msg]} {puts "WARNING: Failed to search directory $subdir: $error_msg"continue}foreach tcl_file $tcl_files {set file_name [file tail $tcl_file]set file_stem [file rootname $file_name]# 检查是否与目录名匹配if {$file_stem eq $dir_name} {set script_info [dict create]dict set script_info script_path $tcl_filedict set script_info ip_name $dir_namedict set script_info ip_dir $subdirlappend ip_scripts $script_infoputs "Found IP script: $dir_name -> $tcl_file"}}}return $ip_scripts
}# 运行综合
proc run_synthesis {} {puts "=================================================================="puts "Running Synthesis"puts "=================================================================="# 检查是否有设计源文件set source_files [get_files -compile_order sources -used_in synthesis]if {[llength $source_files] == 0} {puts "ERROR: No source files found for synthesis"return 0}# 检查顶层模块是否设置set top_module [get_property top [current_fileset]]if {$top_module eq ""} {puts "ERROR: No top module set for synthesis"return 0}puts "Synthesis top module: $top_module"reset_run synth_1launch_runs synth_1 -jobs 4wait_on_run synth_1set synth_status [get_property STATUS [get_runs synth_1]]if {$synth_status eq "synth_design Complete!"} {puts "Synthesis completed successfully"return 1} else {puts "ERROR: Synthesis failed with status: $synth_status"# 获取详细错误信息if {[catch {open_run synth_1} error_msg]} {puts "Detailed error: $error_msg"}return 0}
}# 运行实现
proc run_implementation {} {puts "=================================================================="puts "Running Implementation"puts "=================================================================="# 检查综合是否完成set synth_run [get_runs synth_1]set synth_status [get_property STATUS $synth_run]if {$synth_status ne "synth_design Complete!"} {puts "ERROR: Synthesis must be completed before implementation"puts "Current synthesis status: $synth_status"return 0}reset_run impl_1launch_runs impl_1 -jobs 4wait_on_run impl_1set impl_status [get_property STATUS [get_runs impl_1]]if {$impl_status eq "route_design Complete!"} {puts "Implementation completed successfully"return 1} else {puts "ERROR: Implementation failed with status: $impl_status"return 0}
}# 生成位流文件
proc generate_bitstream {{output_dir "./output"}} {puts "=================================================================="puts "Generating Bitstream"puts "=================================================================="set output_dir [file normalize $output_dir]if {![file exists $output_dir]} {file mkdir $output_dirputs "Created output directory: $output_dir"}# 检查实现是否完成set impl_run [get_runs impl_1]set impl_status [get_property STATUS $impl_run]if {$impl_status ne "route_design Complete!"} {puts "ERROR: Implementation must be completed before generating bitstream"puts "Current implementation status: $impl_status"return 0}# 打开实现设计if {[catch {open_run impl_1} error_msg]} {puts "ERROR: Failed to open implementation run: $error_msg"return 0}# 获取项目名称作为位流文件名set project_name [get_property NAME [current_project]]set bitstream_file "$output_dir/${project_name}.bit"# 写位流文件puts "Writing bitstream to: $bitstream_file"if {[catch {write_bitstream -force $bitstream_file} error_msg]} {puts "ERROR: Failed to generate bitstream: $error_msg"return 0}if {[file exists $bitstream_file]} {puts "Bitstream generated successfully: $bitstream_file"# 同时生成调试文件set debug_file "$output_dir/${project_name}.ltx"if {[catch {write_debug_probes -force $debug_file} error_msg]} {puts "WARNING: Failed to generate debug probes: $error_msg"} else {puts "Debug probes generated: $debug_file"}# 复制到位流到项目根目录(可选)file copy -force $bitstream_file "./${project_name}.bit"puts "Bitstream also copied to: ./${project_name}.bit"return 1} else {puts "ERROR: Bitstream file was not created"return 0}
}# 生成IP脚本(从原始脚本复制过来的函数)
proc generate_ip_script {ip ip_dir} {set ip_name [get_property NAME $ip]set script_path "$ip_dir/$ip_name.tcl"set result [catch {write_ip_tcl $ip -force $script_path} error_msg]if {[file exists $script_path]} {puts "Generated script: $script_path"if {$result != 0} {puts "Note: Generation completed with warnings: $error_msg"}return 1} else {puts "ERROR: Failed to generate script for $ip_name: $error_msg"return 0}
}# 复制XCI文件(从原始脚本复制过来的函数)
proc copy_xci_file {ip ip_dir} {set project_dir [get_property DIRECTORY [current_project]]set ip_name [get_property NAME $ip]set xci_found 0set search_patterns [list \"$project_dir/${ip_name}.xci" \"$project_dir/*.srcs/*/ip/*/${ip_name}.xci" \"$project_dir/*.gen/*/ip/*/${ip_name}.xci" \]foreach pattern $search_patterns {if {[catch {set files [glob -nocomplain -- $pattern]foreach file $files {if {[file exists $file]} {set xci_target "$ip_dir/[file tail $file]"file copy -force $file $xci_targetputs "Copied .xci file: $xci_target"set xci_found 1break}}} error_msg]} {puts "WARNING: Error searching with pattern $pattern: $error_msg"}if {$xci_found} { break }}if {!$xci_found} {puts "WARNING: Could not locate .xci file for $ip_name"return 0} return 1
}# 完整工程创建流程 - 修复版本
proc create_complete_project {} {global project_name device_part ip_dir hdl_dir constraints_dir output_dirputs "================================================================"puts "Starting Complete Project Creation"puts "================================================================"# 1. 创建目录结构create_project_structure# 2. 创建新工程if {![create_new_project $project_name $device_part]} {return 0}# 3. 添加HDL文件if {![add_hdl_files $hdl_dir]} {puts "ERROR: Failed to add HDL files"return 0}# 4. 添加约束文件if {![add_constraint_files $constraints_dir]} {puts "WARNING: No constraint files added, but continuing..."}# 5. 重建所有IPif {![rebuild_all_ips $ip_dir 1]} {puts "WARNING: Some IPs failed to rebuild, but continuing..."}# 6. 更新编译顺序update_compile_order -fileset sources_1# 7. 运行综合if {![run_synthesis]} {puts "ERROR: Synthesis failed, stopping..."return 0}# 8. 运行实现if {![run_implementation]} {puts "ERROR: Implementation failed, stopping..."return 0}# 9. 生成位流if {![generate_bitstream $output_dir]} {puts "ERROR: Bitstream generation failed"return 0}puts "================================================================"puts "Project Creation Completed Successfully!"puts "================================================================"puts "Project: $project_name"puts "Device: $device_part"puts "Bitstream: $output_dir/${project_name}.bit"return 1
}# 调试函数:检查工程状态
proc check_project_status {} {puts "=================================================================="puts "Project Status Check"puts "=================================================================="if {[get_projects -quiet] eq ""} {puts "No project is currently open"return 0}set project_name [get_property NAME [current_project]]puts "Current project: $project_name"# 检查源文件set source_files [get_files -compile_order sources -used_in synthesis]puts "Source files: [llength $source_files]"foreach file $source_files {puts " - [file tail $file]"}# 检查约束文件set constraint_files [get_files -fileset constrs_1]puts "Constraint files: [llength $constraint_files]"# 检查IPset ips [get_ips]puts "IP cores: [llength $ips]"# 检查顶层模块set top_module [get_property top [current_fileset]]puts "Top module: $top_module"# 检查运行状态set synth_run [get_runs -quiet synth_1]if {$synth_run ne ""} {set synth_status [get_property STATUS $synth_run]puts "Synthesis status: $synth_status"}set impl_run [get_runs -quiet impl_1]if {$impl_run ne ""} {set impl_status [get_property STATUS $impl_run]puts "Implementation status: $impl_status"}return 1
}# 主执行部分
if {[info script] eq $argv0} {# 解析命令行参数set action "complete"for {set i 0} {$i < [llength $argv]} {incr i} {set arg [lindex $argv $i]switch -exact -- $arg {"-create" {set action "create"}"-synthesis" {set action "synthesis"}"-implementation" {set action "implementation"}"-bitstream" {set action "bitstream"}"-ips" {set action "ips"}"-status" {set action "status"}"-set_top" {incr iset top_module [lindex $argv $i]set_top_module_manual $top_modulereturn 1}"-help" {puts "Usage:"puts " -create : Create complete project (default)"puts " -synthesis : Run synthesis only"puts " -implementation: Run implementation only"puts " -bitstream : Generate bitstream only"puts " -ips : Rebuild IPs only"puts " -status : Check project status"puts " -set_top <module> : Manually set top module"puts " -help : Show this help"return 0}}}# 执行相应操作switch $action {"create" {create_complete_project}"synthesis" {run_synthesis}"implementation" {run_implementation}"bitstream" {generate_bitstream}"ips" {rebuild_all_ips}"status" {check_project_status}default {create_complete_project}}
}puts "Project management utilities loaded successfully."
puts "Available commands:"
puts " create_complete_project - Create complete project with all steps"
puts " rebuild_all_ips - Rebuild all IP cores"
puts " run_synthesis - Run synthesis"
puts " run_implementation - Run implementation"
puts " generate_bitstream - Generate bitstream file"
puts " check_project_status - Check current project status"
puts " set_top_module_manual <module> - Manually set top module"
通过tcl脚本自动实现工程建立,生成位流和原工程一样,符合预期。