7、部分重构设计流程:Vivado PR设计流程、约束文件编写、综合与实现策略
好,咱们今天聊点实在的。部分重构(Partial Reconfiguration,简称PR)这个技术,说白了就是让FPGA在运行的时候,只换掉一部分逻辑,其他部分照常干活。听起来很酷对吧?但真正上手做,你会发现坑不少。我最早接触PR是在一个通信项目里,板子已经装到机箱里了,想升级算法又不能断电……嗯,那时候我就知道,PR这东西,流程不对,后面全是泪。
7.1 Vivado PR设计流程:三步走
Vivado的PR流程,我习惯把它拆成三个阶段。你按这个节奏走,基本不会乱。
7.1.1 第一步:规划与准备
这一步最容易被忽略。很多人上来就写代码,结果后面发现管脚冲突、资源不够,回头改设计,那叫一个痛苦。
- 确定重构区域:哪些模块需要动态换?哪些是固定的?我个人建议,把频繁升级的算法模块、协议处理模块划为可重构区。
- 划分物理区域:在芯片上圈出一块矩形区域,作为PR Region。注意,这个区域必须是连续的、对齐的时钟区域(Clock Region)。
- 创建PR设计:顶层模块里,把可重构模块实例化成一个黑盒(Black Box)。Vivado会帮你生成一个“空壳子”。
create_pblock 命令,精确到SLICE级别。这样后面综合实现时,Vivado不会乱放逻辑。
7.1.2 第二步:综合与实现
这一步是PR流程的核心。Vivado会做两遍综合:一遍是静态逻辑(Static Logic),一遍是每个可重构模块的“变体”(Reconfigurable Module Variant)。
- 综合静态设计:把顶层和固定模块综合成网表。
- 综合每个变体:比如你有三个版本的算法模块,每个都要单独综合。
- 布局布线:先布静态逻辑,再布每个变体。注意,变体只能放在你划好的PR Region里。
ASYNC_REG 约束标记。嗯,从那以后就没出过问题。
7.1.3 第三步:生成比特流
Vivado会生成两种比特流:
- 全比特流:包含静态逻辑和初始的可重构模块。第一次加载用这个。
- 部分比特流:只包含可重构模块的差异部分。运行时加载这个,就能换模块。
生成完成后,你会得到一堆 .bit 和 .partial.bit 文件。记得用 write_bitstream 命令加上 -cell 选项,指定哪个模块生成部分比特流。
7.2 约束文件编写:别让时序飞了
PR的约束,比普通设计多了一层。你想想看,同一个物理区域,要跑不同的逻辑,时序约束必须覆盖所有变体。
7.2.1 物理约束
用 pblock 约束来定义PR Region。我一般这么写:
create_pblock pblock_pr_region
add_cells_to_pblock [get_cells {u_pr_module}] pblock_pr_region
resize_pblock pblock_pr_region -add {SLICE_X36Y100:SLICE_X55Y149}
这里 u_pr_module 是顶层里那个黑盒实例的名字。坐标范围你得查芯片手册,别瞎填。
7.2.2 时序约束
PR的时序约束,核心是“静态逻辑的时序必须覆盖所有变体”。我习惯的做法是:
- 对静态逻辑的时钟,用
create_clock正常约束。 - 对可重构模块的输入输出路径,用
set_input_delay和set_output_delay约束,并且把-max和-min都设上。 - 用
set_clock_groups把不同变体的时钟分开,避免Vivado乱分析。
7.3 综合与实现策略:让工具听话
Vivado的综合和实现策略,在PR设计里需要特别调教。默认策略往往不够好。
7.3.1 综合策略
我推荐用 Vivado Synthesis Defaults 作为基础,然后做两处修改:
- 开启PR模式:在综合设置里,把
-pr_mode设为reconfigurable。这样Vivado会保留可重构模块的层次结构,不会把逻辑优化到静态区。 - 关闭跨模块优化:用
-flatten_hierarchy none。你想想看,如果Vivado把可重构模块和静态逻辑合并优化了,那后面怎么单独换模块?
7.3.2 实现策略
实现阶段,我习惯用 Performance_ExplorePR 策略。这个策略会尝试多种布局布线方案,找到最优解。但注意,它跑得比较慢。如果项目时间紧,可以用 Congestion_SpreadLogic_high 来缓解布线拥塞。
另外,有个参数叫 pr_flow,在实现时一定要设为 true。否则Vivado不会生成部分比特流。
report_utilization,看看可重构区域的资源占用。如果LUT或BRAM超过80%,我会调整区域大小或优化代码。因为PR模块的布线资源是固定的,太挤了容易时序违例。
7.4 知识体系总览
下面这张图,是我自己总结的PR设计流程。你照着这个框架走,基本不会漏步骤。
7.5 常见问题与对策
最后,我列几个PR设计里容易踩的坑,都是真金白银换来的教训。
| 问题 | 原因 | 对策 |
|---|---|---|
| 部分比特流加载失败 | PR Region的边界与静态逻辑有未约束的路径 | 用 set_property PR_MODE RECONFIGURABLE 强制约束 |
| 时序违例 | 不同变体的路径延迟差异大 | 所有变体共用同一套时序约束,以最严为准 |
| 资源利用率过高 | PR Region太小,或逻辑太密集 | 扩大区域,或拆分模块 |
| 重构时系统崩溃 | 重构过程中,静态逻辑访问了正在重构的模块 | 在顶层加握手信号,重构期间禁止访问 |
好了,关于Vivado PR设计流程、约束和策略,今天就聊到这儿。你回去可以拿一个简单的LED闪烁模块练练手,先跑通流程,再慢慢加复杂度。记住,PR这东西,纸上谈兵没用,动手做一遍比看十遍文档都管用。
公众号:蓝海资料掘金营,微信deep3321