verilog:按键消抖模块(数字钟)

  在设计FPGA时只要用到了按键那么就需要使用按键消抖模块,目的就是为了消除按键的抖动。关于按键的抖动不再多说,直接给出设计的模块。

module keyboard_module(
    input i_clk_5MHz,
    input i_rstn, //复位
    input i_key1, i_key2, i_key3, //三个按键  在本次实验中三个按键要实现的功能为功能切换、校时+1、确定ok。
    output reg [2:0] kb_status //{i_key3, i_key2, i_key1} , 1 = on
);

    reg [2:0] kb_d1;
    reg [4:0] keep_cnt[2:0];
    reg [12:0] clk_cnt;

    always@(posedge i_clk_5MHz) begin
        if(~i_rstn) begin
            kb_d1 <= 0;
            keep_cnt[2] <= 0;
            keep_cnt[1] <= 0;
            keep_cnt[0] <= 0;
            clk_cnt <= 0;
        end
        else if(clk_cnt < 13'd5000) begin
            clk_cnt <= clk_cnt+1;
        end
        else begin//a?T:F表示当a为逻辑1时则输出T如果a为逻辑0时则输出F
            clk_cnt <= 0;//本代码段实现的是按键防抖的目的
            kb_d1 <= {i_key3, i_key2, i_key1};
            keep_cnt[2] <= ~(kb_d1[2]==i_key3)  ? 0 :
                           (keep_cnt[2]==5'd20) ? 5'd20 : keep_cnt[2]+1;  //表示在5000×20个时钟内达到稳定的效果
            keep_cnt[1] <= ~(kb_d1[1]==i_key2)  ? 0 :
                           (keep_cnt[1]==5'd20) ? 5'd20 : keep_cnt[1]+1;
            keep_cnt[0] <= ~(kb_d1[0]==i_key1)  ? 0 :
                           (keep_cnt[0]==5'd20) ? 5'd20 : keep_cnt[0]+1;
            kb_status[2] <= (keep_cnt[2]==5'd20)? kb_d1[2] : kb_status[2];
            kb_status[1] <= (keep_cnt[1]==5'd20)? kb_d1[1] : kb_status[1];
            kb_status[0] <= (keep_cnt[0]==5'd20)? kb_d1[0] : kb_status[0];
        end
    end

endmodule

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我来为您解答。 首先,我们需要定义电子秒表的功能,即实现计时、暂停、复位和显示功能。然后,我们可以将其分解为以下模块: 1. 顶层模块:包含时钟模块按键消抖模块、计数模块和译码显示模块,用于控制电子秒表的整体功能。 2. 时钟模块:用于提供基本的时钟信号,通常使用晶体振荡器或者RC振荡器实现。 3. 按键消抖模块:用于消除按键的抖动,确保按键信号的正确性和稳定性。 4. 计数模块:用于实现计时功能,包括计时、暂停和复位功能。 5. 译码显示模块:用于将计数模块输出的数字转换成7段LED数字管的显示格式。 接下来,我们可以使用Verilog语言进行设计。 首先,定义顶层模块的输入和输出: ```verilog module stopwatch( input clk, // 时钟信号 input rst, // 复位信号 input start_stop, // 开始/停止信号 input reset, // 复位信号 output [3:0] digit0, // 数字0 output [3:0] digit1, // 数字1 output [3:0] digit2, // 数字2 output [3:0] digit3 // 数字3 ); ``` 然后,实例化时钟模块按键消抖模块: ```verilog wire clk_10ms; // 10ms时钟信号 wire start_stop_debounced;// 消抖后的开始/停止信号 wire reset_debounced; // 消抖后的复位信号 clk_divider clk_divider_inst( .clk(clk), // 输入时钟信号 .rst(rst), // 复位信号 .clk_10ms(clk_10ms) // 10ms时钟信号 ); debouncer debouncer_inst( .clk(clk), // 输入时钟信号 .rst(rst), // 复位信号 .input(start_stop), // 开始/停止信号 .debounced_output(start_stop_debounced)// 消抖后的开始/停止信号 ); debouncer debouncer_inst2( .clk(clk), // 输入时钟信号 .rst(rst), // 复位信号 .input(reset), // 复位信号 .debounced_output(reset_debounced) // 消抖后的复位信号 ); ``` 接着,实例化计数模块和译码显示模块: ```verilog wire [23:0] counter; // 计数器输出 wire [3:0] digit0_raw; // 显示数字0 wire [3:0] digit1_raw; // 显示数字1 wire [3:0] digit2_raw; // 显示数字2 wire [3:0] digit3_raw; // 显示数字3 counter_10ms counter_inst( .clk(clk_10ms), // 输入10ms时钟信号 .rst(reset_debounced), // 复位信号 .start_stop(start_stop_debounced),// 开始/停止信号 .counter(counter) // 计数器输出 ); decoder decoder_inst( .input(counter), // 输入计数器输出 .digit0_raw(digit0_raw), // 显示数字0 .digit1_raw(digit1_raw), // 显示数字1 .digit2_raw(digit2_raw), // 显示数字2 .digit3_raw(digit3_raw) // 显示数字3 ); ``` 最后,将译码显示模块的输出连接到顶层模块的输出: ```verilog assign digit0 = digit0_raw; assign digit1 = digit1_raw; assign digit2 = digit2_raw; assign digit3 = digit3_raw; ``` 到此,电子秒表的设计就完成了。需要注意的是,这只是一个简单的示例,实际应用中还需要考虑更多的细节和可能出现的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值