文章来源:FPGA入门到精通
FPGA工具层面的设置只是临时缓解拥塞的手段,而代码层面的优化是从根源上减少互连需求,彻底解决拥塞问题,同时不会牺牲设计的性能。
这里分享一些代码优化方法。
优先优化高扇出信号(解决长线拥塞最有效)
高扇出信号(单个信号驱动大量负载)是引发长线拥塞的最常见原因,这类信号会消耗大量的全局布线资源,是拥塞的重灾区。
常见的高扇出信号:
全局复位、全局使能、时钟使能、配置信号等,这类信号的扇出通常会达到数千甚至上万。
代码优化方法:
1、拆分复制高扇出信号
手动逻辑复制不要用单个全局信号驱动所有模块,将其复制为多个本地信号,分别驱动不同的子模块,降低单个信号的扇出。
// 错误示例:单个全局复位驱动所有模块
always @(posedge clk or posedge rst) begin
if(rst) begin ... end // 所有模块的复位都用这个rst,扇出过万
end
// 正确示例:拆分复位信号,每个子模块用本地复位
reg rst_a, rst_b, rst_c;
always @(posedge clk or posedge global_rst) begin
if(global_rst) begin
rst_a <= 1'b1;
rst_b <= 1'b1;
rst_c <= 1'b1;
end else begin
rst_a <= 1'b0;
rst_b <= 1'b0;
rst_c <= 1'b0;
end
end
// 每个子模块用自己的rst,单个信号的扇出降到几千
2、对高扇出信号插入流水线打拍
对高扇出信号插入一级 / 两级寄存器,拆分扇出,工具会自动将这些寄存器分散布局,减少单个信号的布线压力。
// 对高扇出的使能信号打拍,拆分扇出
reg en_p1, en_p2;
always @(posedge clk) begin
en_p1 <= high_fanout_en;
en_p2 <= en_p1;
end
// 后半段的逻辑用en_p2,前半段用en_p1,拆分负载
3、模块内部避免全局复位,改用局部复位
全局复位是最常见的高扇出信号,尽量避免使用全局复位,改用模块内的局部复位,或者仅对关键模块使用复位,减少复位信号的扇出。