【原创】降低设计资源的技巧(一)
0赞我是一名FPGA设计领域的新手,有太多的不足和缺陷,需要花时间去一个一个地攻破他们。唯有这样,也许在未来的某一天,我就成功了。
这几天,我在搞设计时发现了几种可以减少设计资源的技巧,现在把它们拿出来与大家分享,希望对大家在设计时有一定的帮助。*^_^*下面综合的器件以Xilinx公司的Spartan6系列的xc6slx45-2fgg484为例。
一、加法计数器
这里以20000进制的加法计数器为例进行讲解。
<1>通过判断计数器cnt是否小于19999,若小于19999则每个时钟加1,否则赋值为0,实现电路如程序清单1所示:
程序清单1
/********************************Copyright************************************ ** CrazyBird ** http://blog.chinaaet.com/crazybird ** **-----------------------------File Infomation-------------------------------- ** FileName : add_counter_1.v ** Author : CrazyBird ** Data : 2015-10-31 ** Version : v1.0 ** Description : 20000 decimal additive counter ** *****************************************************************************/ // synopsys translate_off `timescale 1 ns / 1 ps // synopsys translate_on module add_counter_1 #( parameter T_COUNT = 20000 ) ( input rst_n, input clk, output reg [14:0] cnt ); //----------------------------------------------- // 20000 decimal additive counter always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) cnt <= 15'd0; else if(cnt < T_COUNT-1'b1) cnt <= cnt + 1'b1; else cnt <= 15'd0; end endmodule //********************************End File***********************************
综合后资源消耗情况如图1所示:
图1 加法计数器在临界条件cnt<19999下的资源消耗情况
<2>通过判断计数器cnt是否等于19999,若等于19999则赋值为0,否则每个时钟加1,实现电路如程序清单2所示:
程序清单2
/********************************Copyright********************************** ** CrazyBird ** http://blog.chinaaet.com/crazybird ** **----------------------------File Infomation------------------------------- ** FileName : add_counter_2.v ** Author : CrazyBird ** Data : 2015-10-31 ** Version : v1.0 ** Description : 20000 decimal additive counter ** ***************************************************************************/ // synopsys translate_off `timescale 1 ns / 1 ps // synopsys translate_on module add_counter_2 #( parameter T_COUNT = 20000 ) ( input rst_n, input clk, output reg [14:0] cnt ); //----------------------------------------------- // 20000 decimal additive counter always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) cnt <= 15'd0; else if(cnt == T_COUNT) cnt <=15'd0; else cnt <= cnt + 1'b1; end endmodule //*******************************End File**********************************
综合后资源消耗情况如图2所示:
图2 加法计数器在临界条件cnt==19999下的资源消耗情况
<3>总结:一般情况下,加法计数器在临界条件cnt小于T_COUNT下综合消耗的资源要比在临界条件cnt等于T_COUNT下要少。
二、将大的计数器适当分解为小的计数器
这里以时钟为100MHz,每延时20ms产生一个时钟周期的使能信号即计数2000000次为例。
<1>用一个计数器实现,实现电路如程序清单3所示:
程序清单3
/*******************************Copyright********************************** ** CrazyBird ** http://blog.chinaaet.com/crazybird ** **---------------------------File Infomation------------------------------- ** FileName : large_counter.v ** Author : CrazyBird ** Data : 2015-10-31 ** Version : v1.0 ** Description : Large counter to achieve 2000000 count ** **************************************************************************/ // synopsys translate_off `timescale 1 ns / 1 ps // synopsys translate_on module large_counter #( parameter T_COUNT = 2000000 ) ( input rst_n, input clk, output cnt_done ); //----------------------------------------- // count 2000000 reg [20:0] cnt; always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) cnt <= 21'd0; else if(cnt < T_COUNT-1'b1) cnt <= cnt + 1'b1; else cnt <= 21'd0; end assign cnt_done = (cnt == T_COUNT-1'b1); endmodule //******************************End File***********************************
综合后资源消耗情况如图3所示:
图3 采用单个大的计数器消耗的资源情况
<2>用两个小的计数器实现,其中一个计数器cnt1计数2000,另一个计数器cnt2计数1000。每当cnt1完成一个周期的计数,cnt2加1(嘿嘿,注意了,这里还可以运用第一种设计技巧来帮助减少资源消耗),实现电路如程序清单4所示:
程序清单4
/*******************************Copyright********************************** ** CrazyBird ** http://blog.chinaaet.com/crazybird ** **---------------------------File Infomation------------------------------- ** FileName : small_counter.v ** Author : CrazyBird ** Data : 2015-10-31 ** Version : v1.0 ** Description : Small counter to achieve 2000000 count ** **************************************************************************/ // synopsys translate_off `timescale 1 ns / 1 ps // synopsys translate_on module small_counter #( parameter T_COUNT_1 = 2000, parameter T_COUNT_2 = 1000 ) ( input rst_n, input clk, output cnt_done ); //----------------------------------------- // count 2000 reg [10:0] cnt1; always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) cnt1 <= 11'd0; else if(cnt1 < T_COUNT_1-1'b1) cnt1 <= cnt1 + 1'b1; else cnt1 <= 11'd0; end wire cnt1_done = (cnt1 == T_COUNT_1-1'b1); // count 1000 reg [9:0] cnt2; always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) cnt2 <= 10'd0; else if(cnt2 < T_COUNT_2-1'b1) cnt2 <= cnt2 + 1'b1; else cnt2 <= 10'd0; end assign cnt_done = (cnt2 == T_COUNT_2-1'b1); endmodule //******************************End File************************************
综合后资源消耗情况如图4所示:
图4 适当分解为小的计数器消耗的资源情况
<3>总结:一般情况下,将一个大的计数器适当分解为小的计数器可以减少资源的消耗。