VIVADO 按键消抖

VIVADO下的按键消抖实验

实验内容

在黑金AX7050开发板上实现按键消抖,通过按键实现对led 的控制。实验本身比较基础,最近在重新整理FPGA相关知识,买了块黑金的开发板,也希望能学到更多东西,第一篇就从按键的消抖开始,后期会不定期更新一些自己对其他实验原理的一些感悟,为一年多以后找工作打好基础。

实验环境

windows 10 64 位
vivado (vicado 2019.1)
黑金AX7050 开发板

实验原理

通过FPGA计时的方法,当检测到按键输入有变化的时候,计数器清零,否则计数器加一,这样的话我可以认为在一段时间内计数器累加,说明按键稳定了一段时间,这样的话我们可以认为这样的按键是消除了抖动后的按键值。
VIVADO 按键消抖

消抖部分代码

`timescale 1 ns / 100 ps
module  ax_debounce 
(
input       clk, 
input       rst, 
input       button_in,
output reg  button_posedge,
output reg  button_negedge,
output reg  button_out
);
 ---------------- internal constants --------------
parameter N = 32 ;           // debounce timer bitwidth
parameter FREQ = 50;         //model clock :Mhz
parameter MAX_TIME = 20;     //ms
localparam TIMER_MAX_VAL =   MAX_TIME * 1000 * FREQ;
---------------- internal variables ---------------
reg  [N-1 : 0]  q_reg;      // timing regs
reg  [N-1 : 0]  q_next;
reg DFF1, DFF2;             // input flip-flops
wire q_add;                 // control flags
wire q_reset;
reg button_out_d0;
 ------------------------------------------------------

contenious assignment for counter control
assign q_reset = (DFF1  ^ DFF2);          // xor input flip flops to look for level chage to reset counter
assign q_add = ~(q_reg == TIMER_MAX_VAL); // add to counter when q_reg msb is equal to 0
    
 combo counter to manage q_next 
always @ ( q_reset, q_add, q_reg)
begin
    case( {q_reset , q_add})
        2'b00 :
                q_next <= q_reg;
        2'b01 :
                q_next <= q_reg + 1;
        default :
                q_next <= { N {1'b0} };
    endcase     
end

 Flip flop inputs and q_reg update
always @ ( posedge clk or posedge rst)
begin
    if(rst == 1'b1)
    begin
        DFF1 <= 1'b0;
        DFF2 <= 1'b0;
        q_reg <= { N {1'b0} };
    end
    else
    begin
        DFF1 <= button_in;
        DFF2 <= DFF1;
        q_reg <= q_next;
    end
end

 counter control
always @ ( posedge clk or posedge rst)
begin
	if(rst == 1'b1)
		button_out <= 1'b1;
    else if(q_reg == TIMER_MAX_VAL)
        button_out <= DFF2;
    else
        button_out <= button_out;
end

always @ ( posedge clk or posedge rst)
begin
	if(rst == 1'b1)
	begin
		button_out_d0 <= 1'b1;
		button_posedge <= 1'b0;
		button_negedge <= 1'b0;
	end
	else
	begin
		button_out_d0 <= button_out;
		button_posedge <= ~button_out_d0 & button_out;
		button_negedge <= button_out_d0 & ~button_out;
	end	
end
endmodule


代码中q_reset的表示使用了异或运算,用来表示前后两个锁存的寄存器是否正确,如果前后两级寄存器的值一致,表示当前锁存的键值没有变化,此时当计数器累加到我们设定的可以输出的值,表示锁存的按键值可以稳定输出。

计数部分代码(稳定时间设定10ms)

module count_m10
(
input          clk,
input          rst_n,
input          en,    //Counter enable
input          clr,   //Counter synchronous reset   
output reg[3:0]data,  //counter value
output reg     t      // carry enable signal
);
always@(posedge clk or negedge rst_n) 
begin
    if(rst_n==0)
    begin
        data <= 4'd0;
        t <= 1'd0;
    end
    else if(clr)
    begin
        data <= 4'd0;
        t <= 1'd0;      
    end
    else if(en)
    begin
        if(data==4'd9)
        begin
            t<= 1'b1;    //Counter to 9 to generate carry
            data <= 4'd0;//Counter to 9 reset
        end
        else
        begin
            t <= 1'b0;
            data <= data + 4'd1;
        end
    end
    else
        t <= 1'b0;
end

endmodule






TOP顶层文件

module key_debounce
(
input       sys_clk,       //system clock 50Mhz on board
input        rst_n,        //reset ,low active
input        key,          //user key on board
output [3:0] led           //user leds on board
);
wire        button_negedge; //Key falling edge
/*************************************************************************
Only one pulse is generated when a key is pressed to meet requirements
****************************************************************************/
ax_debounce ax_debounce_m0
(
.clk             (sys_clk       ),
.rst             (~rst_n        ),
.button_in       (key           ),
.button_posedge  (              ),
.button_negedge  (button_negedge),
.button_out      (              )
);

wire[3:0]   count;
wire        t0;
/*************************************************************************
Decimal counts when button_negedge changes
****************************************************************************/
count_m10 count10_m0
(
.clk             (sys_clk       ),
.rst_n           (rst_n         ),
.en              (button_negedge),
.clr             (1'b0          ),
.data            (count         ),
.t               (t0            )
);
assign led = ~count;
endmodule 




上一篇:FPGA(八)---按键消抖


下一篇:verilog之时序逻辑电路(附代码)