FPGA设计优化及方案改进
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FPGA设计优化及方案改进相关的知识,希望对你有一定的参考价值。
参考技术AFPGA设计优化及方案改进
在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打了一拍(通过DFF将rst_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 <= 1‘b0; 20 rst_nr2 <= 1‘b0; 21 end 22 else 23 begin 24 rst_nr1 <= 1‘b1; 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 (24‘d2500000) 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 (1‘b1), //It don‘t 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
输入clk和rst_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 = 24‘d2500000 //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 = 24‘d0; 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 - 1‘b1) 24 delay_cnt <= delay_cnt + 1‘b1; 25 else 26 delay_cnt <= SYS_DELAY_TOP - 1‘b1; 27 end 28 assign delay_done = (delay_cnt == SYS_DELAY_TOP - 1‘b1)? 1‘b1 : 1‘b0; 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_n随rst_n变化(打了两排拍)
仿真时遇到的错误(卡了好几个小时):
本该是:else if (delay_cnt < SYS_DELAY_TOP - 1‘b1)
写成了:else if (delay_done < SYS_DELAY_TOP - 1‘b1)
以上是关于FPGA设计优化及方案改进的主要内容,如果未能解决你的问题,请参考以下文章