您现在的位置是:首页 >其他 >08 FPGA—计数器与分频器的应用网站首页其他

08 FPGA—计数器与分频器的应用

咖啡0糖 2024-06-14 17:19:13
简介08 FPGA—计数器与分频器的应用

1. 理论

       时序逻辑电路中最基本的单元—寄存器,我们可以使用寄存器来做计数器。基本上关于时间的设计都离不开计数器。

     计数器在数字系统中主要是对脉冲的个数进行计数,以实现测量、计数控制的功能,同时兼有分频功能。计数器一般都是从 0 开始计数,计数到我们需要的值或者计数满溢出后清零,并可以进行不断的循环, 3 位数的十进制计数器最大可以计数到 999, 4 位数的最大可以计数到 9999; 3 位数的二进制计数器最大可以计数到 111(7), 4 位数的最大可以计数到 1111(15)。

    分频器:一般开发板上面只有一个晶振,即只有一种频率的时钟。要想获得其他频率的时钟有pll  ip和写代码实现。pll后面会讲。

计数器

2.实操

    实验目标:使小灯闪烁10次,闪烁频率为一秒。

2.1  模块框图 

2.2 波形设计

2.3 编写rtl代码

`timescale  1ns/1ns

 module  ledflash10
#(
    parameter CNT_MAX =  25'd24_999_999             
	                                                
)
(
input    wire    sys_clk,
input    wire    sys_rst_n,

output   reg    led_out     
);

reg       [24:0]         cnt; 
reg       [4:0]          led_flag;
reg                      cnt_flag;                           
 
//cnt:定时0.5s    
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 0)
	    cnt <= 0;
    else if ((cnt == CNT_MAX)  ||  (led_flag > 19))
	    cnt <= 0;
	else 
	    cnt <= cnt + 1'b1;                          

//cnt_flag:标记cnt是否计满0.5s   	
always@(posedge sys_clk or negedge sys_rst_n)		
    if(sys_rst_n == 0)
	   cnt_flag <= 0;  
    else if (cnt == CNT_MAX - 25'b1)
	   cnt_flag <= 1;
    else 
       cnt_flag <= 0;	
                     	  
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 0)
	    led_flag <= 0;
    else if(cnt_flag == 1 )
		led_flag <= led_flag + 1'b1; 
	
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 0)
	    led_out <= 0;
    else if((cnt_flag == 1)  &&  (led_flag  <  5'd20  ))
		led_out <= ~led_out;   
		
	
endmodule   

3. 分频器

       使用 parmaeter 参数化的方法做成通用的任意分频模块,方便以后的调用。

`timescale  1ns/1ns

module  divider
#(
    parameter   CNT_MAX = 3'd6  //六分频计数器
)
(
    input   wire    sys_clk     ,   
    input   wire    sys_rst_n   ,   

    output  reg      clk_flag       
);

reg     [3:0]   cnt;               

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt <= 1'b0;
    else    if(cnt == CNT_MAX )
        cnt <= 1'b0;
    else
        cnt <= cnt + 1'b1;
//clk_flag  
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        clk_flag <= 1'b0;
    else    if(cnt == CNT_MAX-1)
        clk_flag <= 1'b1;
	else    
	    clk_flag <= 1'b0;
   

endmodule

       这里不使用图一的分频的思想,而采用图二倍频的思想。一是因为实现奇分频更方便,二是因为分频的方式产生的 clk_out 信号并没有连接到全局时钟网络上,在高速系统会出现问题。
 

 图一

  图二

 说明:

       本人使用的是野火家Xilinx Spartan6系列开发板及配套教程,以上内容如有疑惑或错误欢迎评论区指出,或者移步B站观看野火家视频教程。

开发软件:ise14.7     仿真:modelsim 10.5 

如需上述资料私信或留下邮箱。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。