FPGA设计优化及方案改进

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FPGA设计优化及方案改进相关的知识,希望对你有一定的参考价值。

参考技术A

FPGA设计优化及方案改进

  在FPGA设计中,必须首先明确HDL源代码编写非常重要;不同综合工具包含的综合子集不同致使有些HDL语句在某些综合工具中不能综合;同一逻辑功能可用不同HDL语句进行描述,但占用资源却可能差别很大。同时应当深刻理解并发性是硬件描述语言与普通高级语言的根本区别,因而设计硬件电路不能受传统顺序执行思维的束缚。

  此外,我们应当清楚速度优化与面积优化在FPGA设计中占有重要地位。对于大多数数字系统设计而言,速度常常是第一要求,但FPGA结构特性、综合工具性能、系统电路构成、PCB制版情况及HDL代码表述都会对工作速度产生重要影响。我们通过在电路结构设计中采用设计、寄存器配平、关键路径法可以进行速度优化。

  (1)流水线设计

  流水线(Pipelining)技术在速度优化中相当流行,它能显著提高系统设计的运行速度上限,在现代微、数字信号处理器、MCU、高速数字系统设计中都离不开流水线技术。图4与图5是流水线设计的\'典型图示,其中图4未使用流水线设计,图5采用了2级流水线设计,在设计中将延时较大的组合逻辑块切割成两块延时大致相等的组合逻辑块,并在这两个逻辑块中插入了触发器,即满足以下关系式:Ta=T1+T2,T1≈T2。通过分析可知,图4中Fmax≈1/Ta;图5中流水线第1级最高工作频率Fmax1≈1/T1,流水线第2级最高工作频率Fmax2≈1/T2≈1/T1,总设计最高频率为Fmax≈Fmax1≈Fmax2≈1/T1,因此图5设计速度较图4提升了近一倍。

  (2)寄存器配平(Register Balancing)

  寄存器配平是通过配平寄存器之间的组合延时逻辑块来实现速度优化,两个组合逻辑块延时差别过大,导致设计总体工作频率Fmax取决于T1,即最大的延时模块,从而使设计整体性能受限。通过对图7设计进行改进,将延时较大的组合逻辑1的部分逻辑转移到组合逻辑2中,成为图8结构,以减小延时T1,使t1≈t2,且满足T1+T2=t1+t2。寄存器配平后的图8结构中Fmax≈1/t1>1/T1,从而提高了设计速度。

  (3)关键路径法

  关键路径是指设计中从输入到输出经过的延时最长的逻辑路径,优化关键路径是提高设计工作速度的有效方法。图9中Td1>Td2,Td1>Td3,关键路径为延时Td1的模块,由于从输入到输出的延时取决于延时最长路径,而与其他延时较小的路径无关,因此减少Td1则能改善输入到输出的总延时。

  在优化设计过程中关键路径法可反复使用,直到不可能减少关键路径延时为止。许多EDA开发工具都提供时序分析器可以帮助找到延时最长的关键路径,以便设计者改进设计。对于结构固定的设计,关键路径法是进行速度优化的首选方法,可与其他方法配合使用。

  在FPGA设计中,面积优化实质上就是资源利用优化,面积优化有多种实现方法,诸如资源共享、逻辑优化、串行化,其中资源共享使用较多,下面举例说明。

  在利用FPGA设计数字系统时经常遇到同一模块需要反复被调用,例如多位乘法器、快速进位加法器等算术模块,它们占用芯片资源很多,使系统成本及器件功耗大幅上升,因而使用资源共享技术能够显著优化资源。图10和图11是资源共享的一个典型实例,由图可见使用资源共享技术节省了一个多位乘法器,从而达到减少资源消耗、优化面积的目的。

;

FPGA006 优化设计FPGA全局时钟管理模块

  • 1.rst_n--异步复位设计
 1 `timescale 1ns/1ns
 2 module FPGA_temp
 3 (
 4     input            clk,
 5     input            rst_n,
 6     
 7     input            a,
 8     output reg        b
 9 );
10 always@(posedge clk or negedge rst_n)
11 begin
12     if(!rst_n)
13         b <= 0;
14     else 
15         b <= a;
16 end
17 endmodule 

技术分享

没有对复位信号进行处理,当异步复位信号到来时,马上进行复位

优点:设计简单,节省资源。

缺点:容易使寄存器出现亚稳态问题;复位信号容易受到毛刺的影响

 

 

  • 2.rst_n--同步复位设计
 1 `timescale 1ns/1ns
 2 module FPGA_temp
 3 (
 4     input            clk,
 5     input            rst_n,
 6     
 7     input            a,
 8     output reg        b
 9 );
10 always@(posedge clk )
11 begin
12     if(!rst_n)
13         b <= 0;
14     else 
15         b <= a;
16 end
17 endmodule

技术分享

rst_n作为外部信号去采样(而非时钟信号)不再作为D触发器的复位端口,这样不存在

竞争--冒险问题,因为全部都是clk说了算(rst_n由全局时钟clk采样)

优点:降低亚稳态的出现概率;系统成了100%同步时序;因为只在时钟有效沿到来时才有效,所以可以滤除高于时钟频率的毛刺。

缺点:复位信号的有效时长必须大于时钟周期,才能真正的被系统识别并完成复位任务,还要考虑clk skew 、组合逻辑路径延时、复位延时等因素;消耗较多的组合逻辑资源。

 

 

  • 3.异步rst_n信号的同步化设计
 1 `timescale 1ns/1ns
 2 module FPGA_temp
 3 (
 4     input            clk,
 5     input            rst_n,
 6     
 7     input            a,
 8     output reg    b
 9 );
10 //------------------------------------------------------------------
11 reg         sys_rst_n;
12 always@(posedge clk)
13 begin
14     if(!rst_n)
15         sys_rst_n <= 0;
16     else 
17         sys_rst_n <= rst_n;
18 End
19 //---------------------------------------------------------
20 always@(posedge clk or negedge sys_rst_n)
21 begin
22     if(!sys_rst_n)
23         b <= 0;
24     else 
25         b <= a;
26 end
27 endmodule

技术分享

异步信号的同步化,同步化后的复位信号sys_rst_n作为D触发器的复位信号。

D触发器有异步复位专用的端口,采用异步复位端口无须额外增加器件资源消耗。

我们希望处理外部复位信号rst_n,以实现直接或间接控制D触发器的复位端口,这样充分利用了D触发器,同时减少了组合逻辑电路的消耗。因此,可以在将rst_n作为使能时钟的基础上,人为的生成另一个同步化后的“同步复位信号”。这需要我们用D触发器打一拍,然后直接提供给剩下的时序电路使用。

首先:第一个D触发器将rst_n打了一拍(通过DFFrst_n同步到clk上去),这一过程将rst_n信号同步到了clk时钟域;接着输出的sys_rst_n信号直接作为第二个D触发器的复位信号。 这样设计只用了一个D触发器便实现了异步复位信号的同步化,同时减少了组合逻辑的使用。

“异步复位,同步释放”

(1)“异步复位”: D触发器的复位端口,它是异步的(但在设计中已经同步了异步复位信号,所以这只是某种意义上的‘异步复位’)

(2)“同步释放” : 我们设计了同步逻辑电路,外部复位信号不会在出现释放时与clk信号竞争,整个系统将与全局时钟clk信号同步。

 

 

  • 4.PLL的全局时钟管理模块设计
 1 `timescale 1 ns / 1 ns
 2 module system_ctrl
 3 (
 4     //global clock
 5     input                clk,
 6     input                rst_n,
 7 
 8     //synced signal
 9     output                 clk_ref,    //clock output    
10     output                 sys_rst_n    //system reset
11 );
12 //----------------------------------------------
13 //rst_n sync, only controlled by the main clk
14 reg     rst_nr1, rst_nr2;
15 always @(posedge clk)
16 begin
17     if(!rst_n)
18         begin
19         rst_nr1 <= 1b0;
20         rst_nr2 <= 1b0;
21         end
22     else
23         begin
24         rst_nr1 <= 1b1;
25         rst_nr2 <= rst_nr1;
26         end
27 end
28 //----------------------------------
29 //component instantiation for system_delay
30 wire    delay_done;    //system init delay has done
31 system_init_delay
32 #(
33     .SYS_DELAY_TOP    (24d2500000)
34 //    .SYS_DELAY_TOP    (24‘d256)    //Just for test
35 )
36 u_system_init_delay
37 (
38     //global clock
39     .clk        (clk),
40     .rst_n        (1b1),            //It dont depend on rst_n when power up
41     //system interface
42     .delay_done    (delay_done)
43 );
44 assign    clk_ref = clk;
45 assign    sys_rst_n = rst_nr2 & delay_done;    //active High
46 Endmodule

技术分享

输入clkrst_n,封装输出clk_ref,并同步sys_rst_n

为了信号的最优化,通过两个D触发器来连续同步异步复位信号(通过寄存器多次触发能达到一定的滤波效果)。这种方式在异步信号的同步及边沿信号的采样中经常用到

 

 

  • 5.系统延时设计
 1 复位启动延时电路实现如下:
 2 //---------------------------------------------------------------------------------------------//code
 3 `timescale 1 ns / 1 ns
 4 module system_init_delay
 5 #(
 6     parameter    SYS_DELAY_TOP = 24d2500000    //50ms system init delay
 7 )
 8 (
 9     //global clock
10     input    clk,        //50MHz
11     input    rst_n,
12     
13     //system interface
14     output    delay_done
15 );
16 //------------------------------------------
17 //Delay 50ms for steady state when power on
18 reg    [23:0] delay_cnt = 24d0;
19 always@(posedge clk or negedge rst_n)
20 begin
21     if(!rst_n)
22         delay_cnt <= 0;
23     else if(delay_cnt < SYS_DELAY_TOP - 1b1)
24         delay_cnt <= delay_cnt + 1b1;
25     else
26         delay_cnt <= SYS_DELAY_TOP - 1b1;
27 end
28 assign    delay_done = (delay_cnt == SYS_DELAY_TOP - 1b1)? 1b1 : 1b0;
29 Endmodule

技术分享

?电源芯片转换需要一定时间

‚FPGA启动到稳定需要一定时间

ƒ外围电路IC的启动需要一定时间

 

 

  • 仿真代码
 1 `timescale 1ns/1ns
 2 module System_Ctrl_TB;
 3 //----------------------//clk generate module
 4 reg               clk;
 5 reg                   rst_n;
 6 localparam        period = 20;
 7 
 8 initial
 9 begin
10     clk = 0;
11     forever #(period/2)
12     clk = ~clk;
13 end 
14 task task_reset;
15 begin
16     rst_n = 0;
17     repeat(2)@(posedge clk)
18     rst_n = 1;
19 end
20 endtask
21 //---------------------------------------------------------
22 wire clk_ref;
23 wire sys_rst_n;
24 system_ctrl    u_system_ctrl
25 (
26     .clk            (clk),            //50MHz
27     .rst_n            (rst_n),        //global reset
28 
29     .clk_ref        (clk_ref),        //clock output    
30     .sys_rst_n        (sys_rst_n)        //system reset
31 );
32 //------------------------------------------------------------------------
33 task task_sysinit;
34 begin
35 
36 end
37 endtask
38 //--------------------------------------------------------------
39 initial
40 begin
41     task_sysinit;
42     task_reset;
43     
44     rst_n = 0;
45     #896;
46     rst_n = 1;
47     #1911;
48     rst_n = 0;
49     #853;
50     rst_n = 1;
51     #2099;
52     rst_n = 0;
53     #136;
54     rst_n = 1;
55 end 
56 endmodule

技术分享

Delay_done无效时,sys_rst_n均为低电平

 

 

 技术分享

技术分享

Delay_done有效时,sys_rst_nrst_n变化(打了两排拍)

 

 

仿真时遇到的错误(卡了好几个小时):

本该是:else if (delay_cnt < SYS_DELAY_TOP - 1‘b1)

写成了:else if (delay_done < SYS_DELAY_TOP - 1‘b1)

 

 

以上是关于FPGA设计优化及方案改进的主要内容,如果未能解决你的问题,请参考以下文章

FPGA006 优化设计FPGA全局时钟管理模块

FPGA006_2 优化设计FPGA全局时钟管理模块什么是PLL?

fpga的优点与缺点

学习FPGA有必要写SDRAM控制器吗?

求一个fpga高速信号采集设计方案

基于 ARM + FPGA 的 EtherCAT 主站设计及实现