crazybird

【原创】降低设计资源的技巧(一)

0
阅读(2515)

    我是一名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所示:

加法计数器cnt小于1999

图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所示:

加法计数器cnt等于1999

图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>总结:一般情况下,将一个大的计数器适当分解为小的计数器可以减少资源的消耗。