文章来源:FPGA入门到精通
建议8:采用复位树降低扇出
解释:全局复位信号往往需要驱动成千上万个触发器,扇出过大导致信号延迟增加、时序违例。
复位树通过多级缓冲将全局复位转化为局部复位。
复位树实现示例:
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
module reset_tree (
input clk,
input global_rst_n,
output reg local_rst_n
);
// 第一级:同步并展宽
reg rst_sync1, rst_sync2;
always @(posedge clk or negedge global_rst_n) begin
if (!global_rst_n) begin
rst_sync1 <= 1'b0;
rst_sync2 <= 1'b0;
end else begin
rst_sync1 <= 1'b1;
rst_sync2 <= rst_sync1;
end
end
// 第二级:局部缓冲(实际工程中实例化多个副本)
local_reset_buffer u_buf1 (.clk(clk), .rst_in(rst_sync2), .rst_out(local_rst_n));
endmodule
建议9:移除仅用于上电复位的信号
解释:FPGA上电后,所有触发器默认处于确定状态(Xilinx默认为0)。
如果复位信号仅仅是为了保证上电初始值,完全可以移除,节省资源。
可以移除复位的示例:
ounter(lineounter(lineounter(lineounter(lineounter(line
// 不需要复位:上电后默认q=0,且业务逻辑不依赖外部复位
always @(posedge clk) begin
if (ce)
q <= d; // 没有复位逻辑
end
必须保留复位的场景:
. 状态机需要在特定条件下回到初始状态
. 计数器需要在运行时清零
. 接口协议需要明确的复位行为
建议10:按复位需求分离进程
解释:将需要复位的信号和不需要复位的信号写在不同的 always 块中,避免混合描述带来的冗余控制集。
正确分离示例:
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
module separate_reset (
input clk,
input rst,
input ce,
input [7:0] d_ctrl,
input [7:0] d_data,
output reg [7:0] ctrl_reg,
output reg [7:0] data_reg
);
// 进程1:需要复位的控制寄存器
always @(posedge clk) begin
if (rst)
ctrl_reg <= 8'b0;
else if (ce)
ctrl_reg <= d_ctrl;
end
// 进程2:不需要复位的数据寄存器
always @(posedge clk) begin
if (ce)
data_reg <= d_data; // 数据通路不加复位
end
endmodule
全文总结
至此,FPGA触发器使用的十条核心建议已全部解析完毕。我们在三篇文章中依次梳理了:

在实际工程中,遵循这些建议不仅能让您的代码更加规范,更能在布局布线阶段显著降低时序收敛难度,提升FPGA资源利用率。