Verilog 消抖电路 方案2

说明:假定按键的默认状态为0,被按下后为1;

按键抖动时长小于20ms,也即使用20ms的消抖时间;

以仿真的1us代替实际1ms。

源代码:

module debounce(

    input wire clk, nrst,

    input wire key_in,

    output reg key_out

    );

    localparam TIME_20MS = 1_000;

    reg key_cnt;

    reg [20:0] cnt;

    always @(posedge clk or negedge nrst) begin

        if(nrst == 0)

            key_cnt <= 0;

        else if(cnt == TIME_20MS - 1)

            key_cnt <= 0;

        else if(key_cnt == 0 && key_out != key_in)

            key_cnt <= 1;

    end



    always @(posedge clk or negedge nrst) begin

        if(nrst == 0)

            cnt <= 0;

        else if(key_cnt) begin

            if(key_out == key_in)

                cnt <= 0;

            else

                cnt <= cnt + 1'b1;

        end

        else

            cnt <= 0;

    end

     

     always @(posedge clk or negedge nrst) begin

            if(nrst == 0)

                key_out <= 0;

            else if(cnt == TIME_20MS - 1)

                key_out <= key_in;

     end

endmodule

测试代码:

// 按键消抖测试电路



// 时间单位

`timescale 1ns/10ps



// module

module  test_debounce;



    // time period parameter

    localparam T = 20;



    // variable

    reg clk, nrst;

    reg key_in;

    wire key_out;



    // instantiate

    debounce uut(

        .clk    (clk    ),

        .nrst   (nrst   ),

        .key_in (key_in ),

        .key_out(key_out)

    );



    // clock

    initial begin

        clk = 1;

        forever #(T/2) clk = ~clk;

    end



    // reset

    initial begin

        nrst = 1;

        @(negedge clk) nrst = 0;

        @(negedge clk) nrst = 1;

    end



    // key_in

    initial begin

        // initial value

        key_in = 0;

        

        // wait reset

        repeat(3) @(negedge clk);

        

        // no bounce

        // key down

        key_in = 1;



        // last 60ms

        repeat(3000) @(negedge clk);



        // key up

        key_in = 0;



        // wait 50ms

        repeat(2500) @(negedge clk);



        // down 5ms, up 15ms

        // key down, bounce 5ms

        repeat(251) @(negedge clk) key_in = ~key_in;



        // last 60ms

        repeat(3000) @(negedge clk);



        // key up, bounce 15ms

        repeat(751) @(negedge clk) key_in = ~key_in;



        // wait 50ms

        repeat(2500) @(negedge clk);



        // down 19ms, up 19ms

        // key down, bounce 19ms

        repeat(951) @(negedge clk) key_in = ~key_in;



        // last 60ms

        repeat(3000) @(negedge clk);



        // key up, bounce 19ms

        repeat(951) @(negedge clk) key_in = ~key_in;



        // wait 50ms

        repeat(2500) @(negedge clk);

        

        // additional, this situation shoud not ever happen

        // down 25ms, up 25ms

        // key down, bounce 25ms

        repeat(1251) @(negedge clk) key_in = ~key_in;



        // last 60ms

        repeat(3000) @(negedge clk);



        // key up, bounce 25ms

        repeat(1251) @(negedge clk) key_in = ~key_in;



        // wait 50ms

        repeat(2500) @(negedge clk);



        // stop

        $stop;

    end

endmodule

仿真结果:

 

时钟周期T=20000ps=20ns(1us代替实际1ms)

搬运工 侵删

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值