当前位置: 首页 > article >正文

vivado2020.2 工程导出为tcl并rebuild(二)

这篇文档承接vivado2020.2 工程导出为tcl并rebuild一在上一篇文档中遗留一个问题就是重建后的工程中有import文件夹下面的内容为大家提供另一个解决方案。前期准备检查工程经过实验如果工程中有增量编译的文件比如.srcs/utils_1/imports/synth_1/xxxx.dcp且这个文件在工程中有这个文件处理方法如下手动从项目中删掉但是不要从路径中删掉否则后面修改了tcl文件之后会报错然后将综合和实现过程中的自动增量编译关掉不勾选图中的配置。生成了tcl之后手动删掉.dcp相关的部分后面rebuild工程之后将dcp相关的代码删掉然后生成工程后手动添加dcp文件有一个点需要注意一下就是tcl中可能有类似下面的代码可能需要把value改为0这个没试过。参考前一篇文章从vivado中生成一个用于rebuild的tcl文件将tcl文件复制到一个新的文件夹下将附件中的文件复制到新的文件夹下执行步骤执行convert_tcl.bat。执行rebuild.bat。新的工程就创建好了。代码附件convert_tcl.batecho off REM Vivado TCL 脚本转换工具 - Windows 批处理包装器 REM 双击运行自动转换当前目录下的 vivado_project.tcl REM 命令行使用convert_tcl.bat [参数] echo echo Vivado TCL 脚本转换工具 echo echo. REM 检查是否提供了参数 if not [%1][] goto :use_params REM 没有参数使用默认文件 set TARGET_FILEvivado_project.tcl goto :process :use_params REM 使用提供的参数 set TARGET_FILE%* :process echo 正在处理文件%TARGET_FILE% echo. REM 检查 Python 是否可用 where python nul 21 if %errorlevel% equ 0 ( set PYTHON_CMDpython ) else ( where py nul 21 if %errorlevel% equ 0 ( set PYTHON_CMDpy ) else ( echo [错误] 未找到 Python请先安装 Python 3.6 pause exit /b 1 ) ) echo [信息] 使用 Python 命令: %PYTHON_CMD% echo. REM 获取脚本所在目录 set SCRIPT_DIR%~dp0 set CONVERT_SCRIPT%SCRIPT_DIR%convert_import_to_add.py REM 检查转换脚本是否存在 if not exist %CONVERT_SCRIPT% ( echo [错误] 找不到转换脚本: %CONVERT_SCRIPT% pause exit /b 1 ) REM 执行转换 %PYTHON_CMD% %CONVERT_SCRIPT% %TARGET_FILE% echo. echo echo 转换完成 echo pauseconvert_import_to_add.py#!/usr/bin/env python3 # -*- coding: utf-8 -*- Vivado TCL 脚本转换工具将 import_files 转换为 add_files -norecurse 功能说明 1. 批量替换所有 import_files 命令为 add_files -norecurse 2. 删除相关的赋值语句set imported_files , set file_imported 3. 保留文件路径和参数不变 4. 支持递归处理目录或单个文件 5. 自动备份原始文件 使用方法 python convert_import_to_add.py tcl_file_or_directory [options] 选项 --backup-dir DIR 指定备份目录默认在原文件同目录创建 backup_时间戳 --recursive 递归处理目录下的所有 .tcl 文件 --dry-run 仅显示将要执行的修改不实际修改文件 --verbose 显示详细的处理信息 示例 python convert_import_to_add.py vivado_project.tcl python convert_import_to_add.py ./scripts --recursive python convert_import_to_add.py vivado_project.tcl --dry-run --verbose import os import re import sys import shutil import argparse from datetime import datetime from pathlib import Path from typing import List, Tuple class TCLConverter: Vivado TCL 脚本转换器 def __init__(self, verbose: bool False): self.verbose verbose self.stats { total_files: 0, converted_files: 0, total_replacements: 0, patterns_found: { batch_import: 0, single_import: 0, quiet_import: 0, plain_import: 0, } } def log(self, message: str, level: str INFO): 打印日志信息 if level DEBUG and not self.verbose: return prefix { INFO: [INFO], SUCCESS: [OK], WARNING: [WARN], ERROR: [ERROR], DEBUG: [DEBUG] }.get(level, ) print(f{prefix} {message}) def convert_content(self, content: str) - Tuple[str, int]: 转换 TCL 内容 replacement_count 0 # 模式 1: set imported_files [import_files -fileset name $files] pattern1 rset\simported_files\s\[import_files\s(-fileset\s\w)\s\$files\] replacement1 radd_files \1 -norecurse $files matches1 len(re.findall(pattern1, content)) if matches1 0: content re.sub(pattern1, replacement1, content) replacement_count matches1 self.stats[patterns_found][batch_import] matches1 self.log(f发现 {matches1} 处批量导入模式, DEBUG) # 模式 2: set file_imported [import_files -fileset name [list $file]] pattern2 rset\sfile_imported\s\[import_files\s(-fileset\s\w)\s\[list\s\$file\]\] replacement2 radd_files \1 -norecurse [list $file] matches2 len(re.findall(pattern2, content)) if matches2 0: content re.sub(pattern2, replacement2, content) replacement_count matches2 self.stats[patterns_found][single_import] matches2 self.log(f发现 {matches2} 处单文件导入模式, DEBUG) # 模式 3: import_files -quiet -fileset name path pattern3 rimport_files\s(-quiet\s-fileset\s\w)\s(.?)(?:\n|$) def replace_quiet(match): nonlocal replacement_count replacement_count 1 self.stats[patterns_found][quiet_import] 1 return fadd_files {match.group(1)} -norecurse {match.group(2).strip()}\n matches3 len(re.findall(pattern3, content)) if matches3 0: content re.sub(pattern3, replace_quiet, content) self.log(f发现 {matches3} 处静默导入模式, DEBUG) # 模式 4: 其他未匹配的 import_files 用法 pattern4 r(?![#\w])import_files\s remaining_matches len(re.findall(pattern4, content)) if remaining_matches 0: self.stats[patterns_found][plain_import] remaining_matches self.log(f警告: 发现 {remaining_matches} 处未处理的 import_files 用法请手动检查, WARNING) return content, replacement_count def convert_file(self, file_path: Path, backup_dir: Path None, dry_run: bool False) - bool: 转换单个 TCL 文件 try: self.log(f处理文件: {file_path}, DEBUG) with open(file_path, r, encodingutf-8) as f: original_content f.read() if import_files not in original_content: self.log(f跳过: {file_path.name} (无 import_files), INFO) return True converted_content, replacement_count self.convert_content(original_content) if replacement_count 0: self.log(f跳过: {file_path.name} (无需转换), INFO) return True self.stats[total_replacements] replacement_count self.log(f找到 {replacement_count} 处需要替换的内容, INFO) if dry_run: self.log(f[DRY RUN] 将修改: {file_path.name}, INFO) return True if backup_dir: backup_path backup_dir / file_path.name shutil.copy2(file_path, backup_path) self.log(f已备份: {backup_path}, DEBUG) # 写入无 BOM 的 UTF-8 文件 with open(file_path, w, encodingutf-8, newline) as f: f.write(converted_content) self.stats[converted_files] 1 self.log(f成功转换: {file_path.name} ({replacement_count} 处修改), SUCCESS) return True except Exception as e: self.log(f处理失败 {file_path.name}: {str(e)}, ERROR) return False def process(self, target_path: Path, recursive: bool False, backup_dir: Path None, dry_run: bool False) - dict: 处理文件或目录 self.log( * 60, INFO) self.log(Vivado TCL 脚本转换工具, INFO) self.log( * 60, INFO) self.log(f目标: {target_path}, INFO) self.log(f模式: {递归 if recursive else 单文件}, INFO) self.log(f模拟运行: {是 if dry_run else 否}, INFO) self.log(- * 60, INFO) if not dry_run and not backup_dir: timestamp datetime.now().strftime(%Y%m%d_%H%M%S) if target_path.is_file(): backup_dir target_path.parent / fbackup_{timestamp} else: backup_dir target_path / fbackup_{timestamp} backup_dir.mkdir(parentsTrue, exist_okTrue) self.log(f备份目录: {backup_dir}, INFO) tcl_files [] if target_path.is_file(): if target_path.suffix.lower() .tcl: tcl_files.append(target_path) else: self.log(f错误: {target_path} 不是 .tcl 文件, ERROR) return self.stats elif target_path.is_dir(): if recursive: tcl_files list(target_path.rglob(*.tcl)) else: tcl_files list(target_path.glob(*.tcl)) if not tcl_files: self.log(未找到任何 .tcl 文件, WARNING) return self.stats self.stats[total_files] len(tcl_files) self.log(f找到 {len(tcl_files)} 个 TCL 文件, INFO) self.log(- * 60, INFO) for file_path in tcl_files: self.convert_file(file_path, backup_dir, dry_run) self.print_summary() return self.stats def print_summary(self): 打印转换统计摘要 print(\n * 60) print(转换统计摘要) print( * 60) print(f总文件数: {self.stats[total_files]}) print(f成功转换: {self.stats[converted_files]}) print(f总替换数: {self.stats[total_replacements]}) print(\n替换模式分布:) for pattern, count in self.stats[patterns_found].items(): if count 0: pattern_names { batch_import: 批量导入 (set imported_files), single_import: 单文件导入 (set file_imported), quiet_import: 静默导入 (import_files -quiet), plain_import: 其他未匹配模式 } print(f - {pattern_names.get(pattern, pattern)}: {count}) if self.stats[patterns_found][plain_import] 0: print(\n警告: 存在未自动处理的 import_files 用法请手动检查) print( * 60) def main(): 主函数 parser argparse.ArgumentParser( descriptionVivado TCL 脚本转换工具将 import_files 转换为 add_files -norecurse, formatter_classargparse.RawDescriptionHelpFormatter ) parser.add_argument(target, typestr, help目标 TCL 文件或目录路径) parser.add_argument(--recursive, -r, actionstore_true, help递归处理目录下的所有 .tcl 文件) parser.add_argument(--backup-dir, -b, typestr, defaultNone, help指定备份目录) parser.add_argument(--dry-run, -n, actionstore_true, help仅显示将要执行的修改不实际修改文件) parser.add_argument(--verbose, -v, actionstore_true, help显示详细的处理信息) args parser.parse_args() target_path Path(args.target) if not target_path.exists(): print(f错误: 路径不存在: {target_path}) sys.exit(1) converter TCLConverter(verboseargs.verbose) backup_dir Path(args.backup_dir) if args.backup_dir else None stats converter.process( target_pathtarget_path, recursiveargs.recursive, backup_dirbackup_dir, dry_runargs.dry_run ) if stats[converted_files] 0: sys.exit(0) elif stats[total_files] 0: sys.exit(1) else: sys.exit(0) if __name__ __main__: main()rebuild.batCALL D:\Xilinx\Vivado\2020.2\bin\vivado.bat -mode batch -source vivado_project.tcl PAUSE

相关文章:

vivado2020.2 工程导出为tcl并rebuild(二)

这篇文档承接vivado2020.2 工程导出为tcl并rebuild(一)在上一篇文档中,遗留一个问题,就是重建后的工程中有import文件夹,下面的内容为大家提供另一个解决方案。前期准备检查工程,经过实验,如果工…...

忍者像素绘卷惊艳效果:云端画坊UI交互+物理反馈+像素质感全流程演示

忍者像素绘卷惊艳效果:云端画坊UI交互物理反馈像素质感全流程演示 1. 像素艺术新纪元:忍者绘卷效果总览 忍者像素绘卷是基于Z-Image-Turbo深度优化的图像生成工作站,它将传统忍者文化与16-Bit复古游戏美学完美融合。这款工具最引人注目的特…...

Qwen2.5-14B-Instruct镜像免配置:像素剧本圣殿Helm Chart一键部署K8s集群

Qwen2.5-14B-Instruct镜像免配置:像素剧本圣殿Helm Chart一键部署K8s集群 1. 产品概述 像素剧本圣殿(Pixel Script Temple)是一款基于Qwen2.5-14B-Instruct深度微调的专业剧本创作工具。它将顶尖的AI推理能力与8-Bit复古美学完美融合&#…...

给Python异步代码加上类型提示(Type Hints)

为Python异步代码添加类型提示:提升健壮性与可维护性 在Python生态中,异步编程(asyncio)已成为处理高并发场景的核心工具,但动态类型的特性使得代码在复杂项目中容易变得难以维护。通过引入类型提示(Type …...

51万行核心代码一夜“开源”,信仰崩塌:“我不想用Ai了”

点击“开发者技术前线”,选择“星标”让一部分开发者看到未来来源丨开发者技术前线Claude Code 51万行核心代码一夜“开源”,以“AI安全”为信仰的 Anthropic 因一个 .map 文件翻车。随后官方立马修复了这个问题。但一场人为失误引发的连锁反应&#xff…...

从上传到导出:清音听真1.7B语音识别完整操作流程详解

从上传到导出:清音听真1.7B语音识别完整操作流程详解 1. 认识清音听真1.7B语音识别系统 语音识别技术已经发展到了一个令人惊喜的阶段。想象一下,你刚参加完一场重要的会议,录音里混杂着各种背景噪音和多人发言,传统工具要么识别…...

名包名表回收门店有哪些

在奢侈品市场日益繁荣的当下,名包名表回收需求也日益增长。不少人都想了解有哪些名包名表回收门店,下面为大家详细介绍。市场常见回收门店类型市场上的名包名表回收门店主要有连锁门店和个体小店。连锁门店通常具有统一的品牌形象和服务标准,…...

富集分析结果太杂乱?3个ggplot2技巧让你的气泡图秒变高颜值SCI配图

富集分析结果太杂乱?3个ggplot2技巧让你的气泡图秒变高颜值SCI配图 科研论文中的图表质量直接影响审稿人对研究成果的第一印象。对于生物信息学分析而言,富集分析(如GO、KEGG、GSEA)的结果可视化尤为关键——它不仅需要准确传达数…...

ARINC 429协议解析:航空电子数据总线的核心原理与应用

1. ARINC 429协议概述:航空电子系统的神经脉络在波音747的驾驶舱内,当飞行员调整飞行高度时,这个指令会通过一组特殊的双绞线以100kbps的速度传输到飞行控制计算机——这背后正是ARINC 429在发挥作用。作为现代航空电子系统的"普通话&qu…...

Python调试神器:Pdb命令速查手册

Pdb 调试命令速查表 基础命令 查看代码 l # 显示当前位置附近的代码(11行) ll # 显示当前函数的完整代码 w # 显示调用栈(where) list 10, 20 # 显示第10-20行…...

时序抖动:概念、测量与系统设计优化

1. 时序抖动的基础概念与影响机制在数字系统设计中,时序抖动(Jitter)是指时钟信号边沿相对于理想位置的偏差。这种看似微小的偏差会对系统性能产生深远影响,特别是在高速数据传输和精密信号处理领域。想象一下交响乐团的指挥手势出…...

Unity中Dropdown与TMP_Dropdown的OnValueChange事件优化:解决单选项点击无响应问题

1. 问题背景:Dropdown单选项点击无响应的尴尬 最近在做一个Unity项目时,遇到了一个让人抓狂的问题:当Dropdown下拉框只有一个选项时,无论怎么点击都不会触发OnValueChange事件。这简直就像按电梯按钮没反应一样让人烦躁。想象一下…...

解决‘找不到.so文件’:GCC动态链接库编译成功后运行报错的三种终极解决方案

解决‘找不到.so文件’:GCC动态链接库编译成功后运行报错的终极指南 当你满心欢喜地用gcc -fPIC -shared编译好动态库,再用gcc main.c -L. -lxxx生成可执行文件,却在运行时遭遇"error while loading shared libraries: libxxx.so: canno…...

【全网首家】Claude Opus 4.7 vs Opus 4.6 实测对比:7 项测试跑完后,我发现升级最值的是 coding 和 debug

Claude Opus 4.7 vs Opus 4.6 实测对比:7 项测试跑完后,我发现升级最值的是 coding 和 debug 通过 Crazyrouter AI API 网关,对 Claude Opus 4.7 和 Opus 4.6 做了 7 组真实场景测试。不是只看发布文案,也不是只看官方说法&#x…...

python python-semantic-release

# 关于Python Semantic Release的一些个人看法 平时做项目,版本号管理是个挺麻烦的事情。一开始可能觉得简单,手动改改__version__就行,但随着项目规模变大、协作的人变多,这个问题就复杂起来了。什么时候该升主版本号&#xff1f…...

python commitizen

# 关于Python Commitizen,你可能需要知道这些 在团队协作开发中,代码提交信息的质量常常被忽视,却直接影响项目的可维护性。杂乱无章的提交信息就像没有标签的档案柜,时间一长,谁都说不清某个改动究竟为何发生。Python…...

python pre-commit-hooks

## 关于Python pre-commit hooks,一些实际工作中的思考 在团队协作开发Python项目时,经常会遇到这样的场景:有人提交了代码,但忘记格式化,或者引入了语法错误,或者提交了调试用的print语句。这些问题虽然不…...

Java物联网项目源码 | TCP IP、HTTP、MQTT通讯协议 | 实时监控、报警信息、...

Java物联网项目源码使用技术:JAVA [ springmvc / spring / mybatis ] 、Mysql 、Html 、Jquery 、css协议和优势:TCP/IP、HTTP、MQTT 通讯协议。系统包括:后台服务,传感器解析服务、web展示;目前web系统支持功能&#…...

MedGemma Medical Vision Lab效果展示:病理切片WSI低倍镜下肿瘤区域与淋巴细胞浸润密度文本评估

MedGemma Medical Vision Lab效果展示:病理切片WSI低倍镜下肿瘤区域与淋巴细胞浸润密度文本评估 1. 引言:当AI遇见病理切片分析 病理切片分析是医学诊断中的重要环节,但传统的人工分析方式存在效率低、主观性强等挑战。今天我们要展示的Med…...

跨平台Gitea数据迁移实战指南

1. 为什么需要跨平台Gitea数据迁移 最近在帮朋友处理一个Gitea服务器迁移的项目时,遇到了一个棘手的问题:他们原来的Gitea服务运行在Windows服务器上,现在需要迁移到Ubuntu系统。这让我意识到,很多团队在基础设施升级或架构调整时…...

保姆级避坑指南:Ubuntu 20.04 LTS源码编译Qt 5.15.2全流程

1. 为什么选择源码编译Qt 5.15.2? 在Ubuntu 20.04 LTS上安装Qt通常有两种方式:通过apt安装预编译版本,或者从源码编译安装。源码编译虽然步骤繁琐,但能带来三个关键优势:版本可控(官方仓库的Qt版本往往较旧…...

OpenClaw部署与调用本地部署的大模型

记录一下这个部署过程:不想调云端API,毕竟花钱买Token还是有点肉疼,所以打算在本地部一个大模型。有一台放在内网机房的服务器,用来做大模型的宿主机。有了大模型之后,需要找个终端来运行 OpenClaw 框架,所…...

golang如何实现用户积分系统_golang用户积分系统实现总结

积分系统需用数据库原子更新或Redis原子命令操作,强制记录含幂等ID的完整流水,查询分场景选DB直查或带TTL的Redis缓存,扣减前校验余额与状态,逆向冲正依赖流水source和幂等ID。积分增减必须用原子操作,别直接读-改-写并…...

SQL处理大规模分组聚合的内存限制_调整服务器配置

MySQL分组聚合OOM时应调大tmp_table_size和max_heap_table_size而非sort_buffer_size;PostgreSQL需按并发和操作数合理设work_mem;ClickHouse需联动max_threads配置max_bytes_before_external_group_by。MySQL分组聚合OOM时,sort_buffer_size…...

从BUUCTF一道RSA难题看e与φ不互素问题的AMM算法实战解析

1. 当RSA遇上特殊条件:e与φ(n)不互素问题 第一次遇到RSA题目时,很多CTF选手都会觉得"这不就是白给题吗?"——毕竟只要知道p和q,按照标准流程计算私钥d就能解密。但现实往往给我们当头一棒:当公钥指数e与欧拉…...

从“完全或无”到IND-CCA2:公钥加密安全模型的演进与实战解析

1. 公钥加密安全模型的演进之路 我第一次接触公钥加密安全模型时,完全被各种缩写搞晕了。直到在实际项目中踩过几次坑,才真正理解这些安全等级的重要性。想象一下,你给朋友寄了个带锁的箱子,从"完全或无"到IND-CCA2&…...

Fastjson的AutoType:从‘得力助手’到‘安全噩梦’,我们该如何用SafeMode优雅收场?

Fastjson的AutoType:从‘得力助手’到‘安全噩梦’,我们该如何用SafeMode优雅收场? 在Java生态中,Fastjson以其卓越的性能和简洁的API长期占据JSON处理库的榜首。但近年来,这个明星库却因为一个名为AutoType的特性频频…...

别再死磕命令行!用eNSP+USG6000V零基础搞定防火墙Web管理界面(附虚拟网卡配置避坑指南)

零基础玩转防火墙:eNSPUSG6000V图形化管理全攻略 第一次接触防火墙配置时,命令行界面总让人望而生畏。作为网络安全领域的敲门砖,图形化管理界面(Web UI)无疑是新手更友好的选择。本文将带你用华为eNSP模拟器和USG600…...

免费在线UML绘图神器:3分钟学会用代码生成专业图表

免费在线UML绘图神器:3分钟学会用代码生成专业图表 【免费下载链接】plantuml-editor PlantUML online demo client 项目地址: https://gitcode.com/gh_mirrors/pl/plantuml-editor 还在为复杂的UML绘图工具而头疼吗?PlantUML Editor是一款革命性…...

5分钟掌握PlantUML Editor:专业级代码驱动UML绘图工具实战指南

5分钟掌握PlantUML Editor:专业级代码驱动UML绘图工具实战指南 【免费下载链接】plantuml-editor PlantUML online demo client 项目地址: https://gitcode.com/gh_mirrors/pl/plantuml-editor 还在为绘制复杂的UML图表而烦恼吗?传统的拖拽式绘图…...