FPGA实现无极可调分频器(常规分频方法实现)
硬件工具:黑金AX301
1.实现效果:
**两个按键(key1选择数码管位数,key2选择数字0-9)可以控制6位数码管的输入数字(0-999999),且该数字即为输出的频率,并且该频率可在一个LED灯上表示。
效果
RTL视图:
2.代码部分:
按键扫描模块:
消抖设计方法为,做一个用于计数20ms的计数器,当检测到按键按下时,计数器开始计数,如果在计数期间按键状态改变,则判定为时抖动,计数器清零并重新计数。若计数器计满,则计数器清零并判定按键为按下,产生一个按键按下的标志位。
module key_filter
#(
parameter CNT_MAX = 20'd999_999 //计数器计数最大值
)
(
input wire sys_clk , //系统时钟50Mhz
input wire sys_rst_n , //全局复位
input wire key_in , //按键输入信号
output reg key_flag //key_flag为1时表示消抖后检测到按键被按下
//key_flag为0时表示没有检测到按键被按下
);
//********************************************************************//
//****************** Parameter and Internal Signal *******************//
//********************************************************************//
//reg define
reg [19:0] cnt_20ms ; //计数器
//********************************************************************//
//***************************** Main Code ****************************//
//********************************************************************//
//cnt_20ms:如果时钟的上升沿检测到外部按键输入的值为低电平时,计数器开始计数
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_20ms <= 20'b0;
else if(key_in == 1'b1)
cnt_20ms <= 20'b0;
else if(cnt_20ms == CNT_MAX && key_in == 1'b0)
cnt_20ms <= cnt_20ms;
else
cnt_20ms <= cnt_20ms + 1'b1;
//key_flag:当计数满20ms后产生按键有效标志位
//且key_flag在999_999时拉高,维持一个时钟的高电平
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
key_flag <= 1'b0;
else if(cnt_20ms == CNT_MAX - 1'b1)
key_flag <= 1'b1;
else
key_flag <= 1'b0;
endmodule
时钟分频输出模块:
通过对系统时钟(50MHz)分频的方法可以实现由按键控制输出频率为0-50MHz的信号,详见代码部分。
module clk_test
#(
parameter CNT_MAX = 25'd24_999_999 //计数最大值(0.5s)
)
(
input clk ,
input rst_n ,
input key1 , //按键1信号
input key2 , //按键2信号
output reg clk_out , //可调时钟输出
output reg [24:0] n , //用