下面给你一份更 精准贴合“Vivado 进阶 – 19P 时钟资源网络与 CLOCK_DEDICATED_ROUTE 应用” 的完整技术讲解(工程师视角 + 实战可用)。
⭐ 为什么资料中常说“19P 的时钟资源网络问题”?
在 Vivado 的 placement(布局)阶段,会出现如下 Category:
[Place 19-xxxx] <clock-name> is not routed on a global clock resource
因此工程师口中常说 “19P” 或 “19 类报错/警告”。
19 系列报错均与时钟资源(Clocking Resources)直接相关。
1️⃣ Vivado 时钟资源网络基础(必须掌握)
Xilinx FPGA 内时钟资源分 4 层:
| 层级 | 资源 | 效果 |
|---|---|---|
| ① 全局层 | BUFG / BUFGCE / BUFGCTRL | 跨全芯片、延迟最低 |
| ② 区域层 | BUFH / BUFHCE | 单个 Clock Region |
| ③ 垂直 Spine | Vertical Clock Backbone | 多区域连通 |
| ④ 普通布线 | Fabric Routing | 不可用于时钟!(会触发 19P) |
⚠ 核心:时钟必须走专用网络(BUFG → Global Clock Network)。
2️⃣ 典型的“19P” 报错实例(你大概率见过)
🔥 报错示例 1:
[Place 19-329] The net <clk_x> is not routed on a global clock net.
🔥 报错示例 2:
[Place 30-574] CLOCK_DEDICATED_ROUTE required but not allowed
🔥 报错示例 3:
[Place 19-345] Clock <mmcm_clkout0> drives logic in multiple clock regions via fabric routing.
这些本质上都是:
时钟应走 专用时钟网络,但 Vivado 发现你走的是 普通布线 或 跨区不合法布线。
3️⃣ 为什么会出现 19P?
最常见 5 个原因如下:
✔ ① 时钟没有经过 BUFG(最常见)
例如:
assign clk2 = clk1;
Vivado 会把 clk2 看成普通信号。
触发 19-329 / CLOCK_DEDICATED_ROUTE 报错。
✔ ② BUFR / BUFH 区域时钟跨多个区域使用
例如你用 BUFR 生成一个时钟,但驱动了多个 Clock Region → 违规。
✔ ③ MMCM/PLL 的输出未连接到 BUFG
MMCM/PLL 的 O 输出没有用 BUFG 会直接触发 19P。
✔ ④ 时钟作为信号逻辑组合不合法使用
例如:
always @(posedge clk_in or posedge rst) // 合法
always @(posedge some_logic_signal) // 非法,会触发 19P
✔ ⑤ Pblock 限制导致时钟无法跨区路由
你把逻辑框在某个 Pblock 中,但时钟来源不在该区域,导致 Vivado 无法使用专用 Spine 结构。
4️⃣ CLOCK_DEDICATED_ROUTE 属性详解
Vivado 默认要求:
CLOCK_DEDICATED_ROUTE = TRUE
即:
✔ 使用全局时钟网络
✔ 不允许使用普通布线(fabric routing)
当你设置下面这条时:
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_test]
Vivado 会允许你走普通布线,但会警告你可能:
- 时钟抖动增大
- 延迟不可预测
- 难以闭合时序
⚠ 适合 低速逻辑测试,不适合正式产品。
5️⃣ 正确解决“19P”和 CLOCK_DEDICATED_ROUTE 的方法
⭐ 方法 1(推荐):把所有跨区域、高扇出时钟接 BUFG
推荐模板:
BUFG u_clk_bufg (
.I(clk_in),
.O(clk_sys)
);
⭐ 方法 2:对 MMCM/PLL 输出也必须上 BUFG
MMCME2_BASE u_mmcm (
...
.CLKOUT0 (clk_mmcm)
);
BUFG u_clk_bufg2 (
.I(clk_mmcm),
.O(clk_mmcm_bufg)
);
⭐ 方法 3:区域级时钟必须保持在单一 Clock Region
使用 BUFH:
BUFH u_bufh (
.I(clk_in),
.O(clk_region)
);
⭐ 方法 4:使用 Pblock 时要确保时钟 spine 可达
避免把时钟源和逻辑锁在不同的 CR。
⭐ 方法 5:低速工程可临时关闭(但不推荐)
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_internal]
用于:
- debug
- 低速 (<50 MHz)
- 结构验证
不用于正式 FPGA 产品。
6️⃣ 什么时候必须启用 CLOCK_DEDICATED_ROUTE?
| 场景 | 必须专用布线 |
|---|---|
| 系统主时钟 | ✔ |
| DDR 时钟 | ✔ |
| 千兆以太网 | ✔ |
| PCIe | ✔ |
| 多区域逻辑驱动 | ✔ |
| 时序要求 < 10ns | ✔ |
7️⃣ 什么时候可以允许 FALSE?
| 场景 | 可用 FALSE |
|---|---|
| 慢速逻辑(< 30MHz) | ✔ |
| 原型验证 | ✔ |
| 单区测试模块 | ✔ |
| 调试临时时钟 | ✔ |
8️⃣ 实战 Debug 流程(最实用)
你可以用以下命令查看是哪个时钟触发问题:
report_clock_networks
查看时钟是否使用 BUFG:
report_clocks
查看某个 net 被当作时钟进行分析:
get_nets -hier *clk*
定位违反时钟专线的网:
report_drc -name {CLOCK*}
📌 总结(最重要的 5 句话)
- Vivado 的 “19P” 错误 本质是时钟网络走错了。
- 高扇出/跨区时钟必须经过 BUFG。
- BUFR/BUFH 的区域时钟不能跨 Region 使用。
- CLOCK_DEDICATED_ROUTE=FALSE 虽能绕过,但不适用于高速和正式设计。
- Pblock 会影响时钟专用 routing,必须注意时钟 spine 的可达性。
发表回复