在 Verilog/SystemVerilog 中,(* clock_buffer_type="NONE" *) 是 Xilinx Vivado 工具链 使用的属性语法,用于控制时钟缓冲器的插入。
一、语法和作用
(* clock_buffer_type = "NONE" *)
input clk_signal;
(* clock_buffer_type = "NONE" *)
wire slow_clock;
二、主要功能
1. 禁止自动插入时钟缓冲器
-
告诉综合工具不要为标记的信号自动插入时钟缓冲器(BUFG、BUFR等)
-
保持信号作为普通逻辑信号处理
2. 应用场景
module clock_management(
input clk_100m,
input clk_enable,
output reg data_out
);
// 正常的全局时钟
input clk_100m;
// 禁止时钟缓冲 - 可能是一个门控时钟或低频时钟
(* clock_buffer_type = "NONE" *)
wire gated_clock;
assign gated_clock = clk_100m & clk_enable;
always @(posedge gated_clock) begin
data_out <= ~data_out;
end
endmodule
三、典型使用情况
1. 门控时钟
module power_saving_design(
input clk,
input enable,
output [7:0] count
);
(* clock_buffer_type = "NONE" *)
wire gated_clk;
reg [7:0] counter;
assign gated_clk = clk & enable;
always @(posedge gated_clk) begin
if (enable)
counter <= counter + 1;
end
assign count = counter;
endmodule
2. 分频后的低频时钟
module low_freq_clock(
input clk_100m,
output reg slow_signal
);
(* clock_buffer_type = "NONE" *)
wire clk_1m;
reg [6:0] div_counter;
assign clk_1m = div_counter[6]; // 约 1.56MHz
always @(posedge clk_100m) begin
div_counter <= div_counter + 1;
end
always @(posedge clk_1m) begin
slow_signal <= ~slow_signal;
end
endmodule
3. 时钟选择逻辑
module clock_mux(
input clk_a,
input clk_b,
input select,
output reg data_out
);
(* clock_buffer_type = "NONE" *)
wire selected_clock;
// 时钟选择器 - 需要手动处理时钟域交叉
assign selected_clock = select ? clk_a : clk_b;
always @(posedge selected_clock) begin
data_out <= ~data_out;
end
endmodule
四、为什么使用这个属性?
1. 资源优化
-
全局时钟缓冲器(BUFG)数量有限
-
避免浪费宝贵的全局时钟资源
2. 特殊时钟需求
-
门控时钟用于低功耗设计
-
动态时钟切换
-
分频时钟用于低速模块
3. 时序约束控制
// 对非全局时钟信号创建生成的时钟约束
(* clock_buffer_type = "NONE" *)
wire divided_clk;
// 在 XDC 文件中可以这样约束:
// create_generated_clock -divide_by 8 -source [get_ports clk] \
// [get_nets divided_clk]
五、注意事项
⚠️ 重要警告
// 危险示例 - 可能导致时序问题
module risky_design(
input clk,
input [7:0] data_in,
output [7:0] data_out
);
(* clock_buffer_type = "NONE" *)
wire risky_clock;
// 使用组合逻辑生成时钟 - 可能产生毛刺
assign risky_clock = (data_in > 100) ? clk : 0;
always @(posedge risky_clock) begin // 危险!
data_out <= data_in;
end
endmodule
六、最佳实践
-
仅用于低频时钟(< 50MHz)
-
避免使用组合逻辑生成时钟
-
添加适当的时序约束
-
进行充分的时序分析
七、相关属性
// 其他时钟相关属性
(* clock_buffer_type = "BUFG" *) // 强制使用 BUFG
(* clock_buffer_type = "BUFH" *) // 使用水平时钟缓冲器
(* clock_signal = "yes" *) // 明确声明时钟信号
(* keep = "true" *) // 防止信号被优化
这个属性在时钟管理设计中非常重要,但需要谨慎使用,确保不会引入时序问题。