我是一名FPGA设计领域的新手,有太多的不足和缺陷,需要花时间去一个一个地攻破他们。唯有这样,也许在未来的某一天,我就成功了。
这几天,我在搞设计时发现了几种可以减少设计资源的技巧,现在把它们拿出来与大家分享,希望对大家在设计时有一定的帮助。*^_^*下面综合的器件以Xilinx公司的Spartan6系列的xc6slx45-2fgg484为例。
一、加法计数器
这里以20000进制的加法计数器为例进行讲解。
<1>通过判断计数器cnt是否小于19999,若小于19999则每个时钟加1,否则赋值为0,实现电路如程序清单1所示:
程序清单1
/********************************Copyright************************************
** 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
**
**
**----------------------------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
**
**
**---------------------------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
**
**
**---------------------------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>总结:一般情况下,将一个大的计数器适当分解为小的计数器可以减少资源的消耗。









QQ好友和群
QQ空间
腾讯微博
腾讯朋友
收藏
淘帖
顶
踩
