问题:
Place 30-174 Unroutable Placement! The following clock source components are placed too far from each other. These clocks drive common load instances. This requires them to be placed in a relative way such that both clocks can drive the common load instances. Please refer to the clocking user guide for more details on which clock regions these clock sources can drive.
dvi_clk_bufg_dvi0 (BUFR.O) is provisionally placed by clockplacer on BUFR_X0Y16
dvi_clk_bufg_dvi1 (BUFR.O) is provisionally placed by clockplacer on BUFR_X0Y22
dvi_inst/dvi_clk_INST_0_i_3 (LUT6.I3) cannot be placed
dvi_inst/dvi_clk_INST_0_i_3 (LUT6.I2) cannot be placed
分析:
BUFR 是区域时钟缓冲器,只能驱动它所在同一个时钟区域内的逻辑。X0Y16 和 X0Y22 分属不同时钟区域,它们的驱动范围不重叠,没有一个物理位置能同时被这两个 BUFR 覆盖。
代码中为什么会出现这种情况呢?
是因为代码中有一段时钟选择逻辑,用组合逻辑/LUT 将多个 BUFR 输出做 MUX:
// 类似这样的写法导致了问题:
assign clk_594m = sel ? bufr_clk0 : bufr_clk1; // LUT实现 → 多BUFR驱动同一LUT
综合工具把这个 MUX 映射到了一个 LUT6,导致该 LUT 的两个输入分别来自不同区域的 BUFR,核心问题是 BUFR 区域限制 + LUT 多时钟驱动导致不可布线。
解决方法:
可以尝试以下三种解决方法:
解决1:将BUFR改为BUFG(BUFG资源少的不建议)
1.BUFR
可将时钟信号驱动至时钟区域内的专用时钟网络,独立于全局时钟树。与BUFIO组件不同,BUFR组件可驱动时钟区域内I/O逻辑和逻辑资源(如CLB、块RAM等)。它们可通过IBUF、BUFMRCE、MMCM或本地互连的输出驱动,并能根据时钟输入产生分频时钟输出 。分频值为1到8之间的整数。****BUFR组件非常适合需要时钟域交叉或串并转换的源同步时钟应用。****若在多个时钟区域内需要本地时钟,BUFMRCE可驱动相邻时钟区域的m个BUFR组件,从而进一步扩展时钟覆盖能力。
|------|-----------|-------|--------------------------------------------------------------------------------------------------------------------------|
| port | direction | width | function |
| CE | INPUT | 1 | 时钟使能端口。该引脚不能在"BYPASS"模式下使用。当BUFR_DIVIDE设置为"BYPASS"或未使用时,将其连接到vcc。 |
| CLR | INPUT | 1 | 分频时钟输出的异步清零功能。当该引脚处于高电平有效状态时,将复位用于生成分频时钟输出的计数器,并使输出信号处于低电平有效状态。该引脚不可用于"BYPASS"模式。若BUFR_DIVIDE设置为"BYPASS"或未使用时,应将其连接至接地端。 |
| I | INPUT | 1 | 时钟输入端口。该端口是 BUFR 的时钟源端口,可由 IBUF 、BUFMRCE、 MMCM 或本地互连驱动。 |
| O | OUTPUT | 1 | 时钟输出端口。 |
|-------------|--------|--------------------------------------------------|-----------|--------------------------------------------|
| atttribute | type | Allowed_values | default | description |
| BUFR_DIVIDE | STRING | "BYPASS", "1", "2", "3", "4", "5", "6", "7", "8" | "BYPASS" | 指定输出时钟是否为输入时钟的分频版本 |
| SIM_DEVICE | STRING | "7SERIES" | "7SERIES" | 若要实现正确的仿真行为,当目标为7系列设备时,必须将此属性设置为"7SERIES"。 |
verilog例化
// BUFR: Regional Clock Buffer for I/O and Logic Resources within a Clock Region
// 7 Series
// Xilinx HDL Language Template, version 2018.3
BUFR #(
.BUFR_DIVIDE("BYPASS"), // Values: "BYPASS, 1, 2, 3, 4, 5, 6, 7, 8"
.SIM_DEVICE("7SERIES") // Must be set to "7SERIES"
)
BUFR_inst (
.O(O), // 1-bit output: Clock output port
.CE(CE), // 1-bit input: Active high, clock enable (Divided modes only)
.CLR(CLR), // 1-bit input: Active high, asynchronous clear (Divided modes only)
.I(I) // 1-bit input: Clock buffer input driven by an IBUF, MMCM or local interconnect
);
2.BUFG
该设计元件是一个高扇出缓冲器,用于将信号连接到全局 布线 资源,以实现信号的低偏斜 。BUFG通常用于时钟网,以及其他高扇出网,如设置/复位和时钟使能。
verilog例化
// BUFG: Global Clock Simple Buffer
// 7 Series
// Xilinx HDL Language Template, version 2018.3
BUFG BUFG_inst (
.O(O), // 1-bit output: Clock output
.I(I) // 1-bit input: Clock input
);
解决2:用BUFGMUX 做时钟选择,不用 LUT
解决3:在BUFR之前做好选择
在这里博主是先将多个时钟进行BUFR处理后再进行多选一处理出现的问题,那么可以先做多选一处理,然后再BUFR,就可以解决上面出现的问题。