介绍:按键的物理结构导致了会有抖动现象的出现,判断按键是否真正按下,需要把抖动的部分滤波。根据经验可知,抖动一般在20ms内,所以常规的消抖方法是从变化沿出现时刻开始,延时20ms后判断按键的状态。这种方法适用范围不广,因为精度不高(如下图,会判断出错)。

本次设计通过状态机的设计提高了按键消抖的性能,具体思路如图:

学习:

  ①testbench文件不会综合成电路,所以可以适用较多的高级语句。

  ②学会看IEEE手册,里面有很完整的语法讲解。想查看某个语句的语法,可以直接 Ctrl+F 搜关键字 ,找的比较快

新语法:

  ①random function:产生一个随机数

    rand = $random(seed) 则rand为一个随机数,seed一般为1,2等,不影响结果,可以直接省略为 rand = $random 。

    rand = $random % range 则rand为在 - range  ~  +range-1  内的随机数 。%是取余运算

    rand = {$random } % range 则rand为在  0  ~  +range-1  内的随机数 。{}是取绝对值运算。

  ② repeat 重复,循环

    repeat(n)重复n次,下面跟begin-end语句,重复n次begin-end 。

   

代码实现:

module buttopn_debounde(
clk,
tx,
reset,
bd_tx
);
input tx ;
input clk ;
input reset ;
output reg bd_tx ; reg [1:0]edge_detect_regist;
always@(posedge clk or negedge reset)//输入信号的移位寄存器
begin
if (!reset)
edge_detect_regist <= 2'd0 ;
else
begin
edge_detect_regist[0] <= tx ;
edge_detect_regist[1] <= edge_detect_regist[0] ;
//等效于 edge_detect_regist <={ edge_detect_regist[0] , tx }
end
end wire neg_edge , pos_edge ;
assign neg_edge = ( edge_detect_regist == 2'b10 ) ? 1 : 0 ;//下降沿
assign pos_edge = ( edge_detect_regist == 2'b01 ) ? 1 : 0 ;//上升沿 parameter delay = 20000000 / 20 ;//抖动20ms reg [3:0]state ;
reg [19:0]counter1 ;
always@(posedge clk or negedge reset)
begin
if (!reset)
state <= 4'd0 ;//空闲态
else if ( ( neg_edge ) && ( state == 4'd0 ) )
state <= 4'd1 ;//按下消抖态
else if ( ( state == 4'd1 ) && (( delay - 1) > counter1 ) && ( pos_edge ) )
state <= 4'd0 ;//空闲态
else if ( ( state == 4'd1 ) && (( delay - 1) <= counter1 ) )
state <= 4'd2 ;//按下态
else if ( ( pos_edge ) && ( state == 4'd2 ) )
state <= 4'd3 ;//释放消抖态
else if ( ( state == 4'd3 ) && (( delay - 1) > counter1 ) && ( neg_edge ) )
state <= 4'd2 ;//按下态
else if ( ( state == 4'd3 ) && (( delay - 1) <= counter1 ) )
state <= 4'd0 ;//空闲态
end always@(posedge clk or negedge reset)
begin
if (!reset)
counter1 <= 5'd0 ;
else if ( ( neg_edge ) || ( pos_edge ) )
counter1 <= 5'd0 ;
else if ( ( state == 4'd1 ) && (! neg_edge ) && (! pos_edge ) )
counter1 <= counter1 + 1'd1 ;
else if ( ( state == 4'd3 ) && (! neg_edge ) && (! pos_edge ) )
counter1 <= counter1 + 1'd1 ;
end always@(posedge clk or negedge reset)
begin
if (!reset)
bd_tx <= 1'd1 ;//空闲态
else
case(state)
0:bd_tx <= 1'd1 ;
1:bd_tx <= 1'd1 ;
2:bd_tx <= 1'd0 ;
3:bd_tx <= 1'd0 ;
endcase
end reg pre_sign ;
always@(posedge clk or negedge reset)
begin
if (!reset)
pre_sign <= 1'd1 ;//空闲态
else if( ( state == 4'd1 ) && (( delay - 1) <= counter1 ) )
pre_sign <= 1'd0 ;
else if ( state == 4'd2 )
pre_sign <= 1'd1 ;
end reg release_sign ;
always@(posedge clk or negedge reset)
begin
if (!reset)
release_sign <= 1'd0 ;//空闲态
else if( ( state == 4'd3 ) && (( delay - 1) <= counter1 ) )
release_sign <= 1'd1 ;
else if ( state == 4'd0 )
release_sign <= 1'd0 ;
end endmodule
`timescale 1ns / 1ns
module button_debounce_tb(
); reg clk ;
reg tx ;
reg reset ;
wire bd_tx ; buttopn_debounde
#(
.delay(100)
)
buttopn_debounde_sim(
clk,
tx,
reset,
bd_tx
); initial clk = 1 ;
always #10 clk = ! clk ;
initial
begin
reset = 1'd0 ;
tx = 1'd1 ;
#201 ;
reset = 1'd1 ;
#200 ;
tx = 1'd0 ;#500 ;
tx = 1'd1 ;#400 ;
tx = 1'd0 ;#200 ;
tx = 1'd1 ;#100 ;
tx = 1'd0 ;#2100;
#2000 ;
tx = 1'd1 ;#100 ;
tx = 1'd0 ;#200 ;
tx = 1'd1 ;#1900;
tx = 1'd0 ;#200 ;
tx = 1'd1 ;#2000;
#2000;
$stop;
end
endmodule
`timescale 1ns / 1ns
module button_debounce_tb_optimization(
); reg clk ;
reg tx ;
reg reset ;
wire bd_tx ; buttopn_debounde
#(
.delay(100)
)
buttopn_debounde_sim1(
clk,
tx,
reset,
bd_tx
); initial clk = 1 ;
always #10 clk = ! clk ;
initial
begin
reset = 1'd0 ;
tx = 1'd1 ;
#200 ;
reset = 1'd1 ;
#2000 ;
press_generator(1) ;
#1000;
press_generator(1) ;
#10000;
press_generator(1) ;
#10000;
$stop;
end reg [31:0]rand ;
task press_generator;
input reg seeds;
begin
tx = 1 ;
# 200 ;
tx = ! tx ; //0 repeat(6)
begin
rand = {$random(seeds)} % ( 2000 );
# rand ;
tx = ! tx ;
end #10000; repeat(5)
begin
tx = ! tx ;
rand = {$random(seeds)} % ( 2000 );
# rand ;
end
#10000;
end
endtask
endmodule

强化版按键消抖Verilog实现的更多相关文章

  1. 按键消抖-----verilog

    实际系统中常用的按键大部分都是轻触式按键,如下图所示.该按键内部由一个弹簧片和两个固定触点组成,当弹簧片被按下,则两个固定触点接通,按键闭合.弹簧片松开,两个触点断开,按键也就断开了.根据这种按键的机 ...

  2. 按键消抖VERILOG实现

    对于消抖,有很多种写法.今天分享一下我的写法. 基本思路: 1. 看图                     图1                                           ...

  3. Verilog HDL那些事_建模篇笔记(实验三:按键消抖)

    实验三:按键消抖 首先将按键消抖功能分成了两个模块,电平检查模块和10ms延迟模块.电平检测模块用来检测按键信号的变化(是否被按下),10ms延迟模块用来稳定电平检查模块的输入,进而稳定按键信号,防止 ...

  4. 【代码】verilog之:按键消抖

    此模块完美运行 /*-------------------------------------------------------------------------------------- -- ...

  5. 09A-独立按键消抖实验01——小梅哥FPGA设计思想与验证方法视频教程配套文档

    芯航线--普利斯队长精心奉献   实验目的: 1.复习状态机的设计思想并以此为基础实现按键消抖 2.单bit异步信号同步化以及边沿检测 3.在激励文件中学会使用随机数发生函数$random 4.仿真模 ...

  6. FPGA学习笔记(八)—— 状态机设计实例之独立按键消抖

    ###### [该随笔中部分内容转载自小梅哥] ######### 独立按键消抖自古以来在单片机和FPGA中都是个不可避免的问题,首先,解释一下什么叫做按键抖动,如图,按键在按下和松开的那个瞬间存在大 ...

  7. 09B-独立按键消抖实验02——小梅哥FPGA设计思想与验证方法视频教程配套文档

    芯航线--普利斯队长精心奉献   实验目的: 1.复习按键的设计 2.用模块化设计的方式实现每次按下按键0,4个LED显示状态以二进制加法格式加1,每次按下按键1,4个LED显示状态以二进制加法格式减 ...

  8. 基于FPGA的数字秒表(数码管显示模块和按键消抖)实现

    本文主要是学习按键消抖和数码管动态显示,秒表显示什么的,个人认为,拿FPGA做秒表真是嫌钱多. 感谢 感谢学校和至芯科技,笔者专业最近去北京至芯科技培训交流了一周.老师的经验还是可以的,优化了自己的代 ...

  9. 按键消抖——task任务和仿真平台搭建

    一.按键抖动原理 按键抖动原理:按键存在一个反作用弹簧,因此当按下或者松开时均会产生额外的物理抖动,物理抖动会产生电平的抖动. 消抖方法:一般情况下,抖动的总时间会持续20ms以内,按下按键后,等20 ...

随机推荐

  1. Erdos-Renyi随机图的生成方式及其特性

    1 随机图生成简介 1.1 \(G_{np}\)和\(G_{nm}\) 以下是我学习<CS224W:Machine Learning With Graphs>[1]中随机图生成部分的笔记, ...

  2. 云厂商 RDS MySQL 怎么选

    1. 摘要 为了让大家更好的了解各云厂商在RDS MySQL数据库功能上的差异,也为给准备上云的同学做个参考,本文将对阿里云.腾讯云.华为云和AWS 的 RDS MySQL数据库进行对比说明. 从一个 ...

  3. 自增特性,外键,级联更新与级联删除,表间关系,SELECT用法,GROUP BY

    自增特性 自动增长的作用: 问题:为数据表设置主键约束后,每次插入记录时,如果插入的值已经存在,会插入失败. 如何解决:为主键生成自动增长的值. 自动增长的语法: 字段名 数据类型 AUTO_INCR ...

  4. 用Docker打包Python运行环境

    虽然Docker作为部署环境打包镜像的工具,和我的科研并没有直接的关系.但我觉得在项目中运用Docker来打包环境依赖也可以大大提高工作效率,于是准备专门学习一下Docker. 1. Docker基础 ...

  5. 宽字符输出中文,Devc++解决方法

    有群友问类似问题,然后我编译了一下试试: #include <stdio.h> #include <wchar.h> #include <locale.h> int ...

  6. Sentinel介绍与使用 收藏起来

    点赞再看,养成习惯,微信搜索[牧小农]关注我获取更多资讯,风里雨里,小农等你,很高兴能够成为你的朋友. 项目源码地址:公众号回复 sentinel,即可免费获取源码 前言 在家休息的的时候,突然小勇打 ...

  7. SeataAT模式原理

    Seata架构 Seata将分布式事务理解为一个全局事务,它由若干个分支事务组成,一个分支事务就是一个满足ACID的本地事务. Seata架构中有三个角色: TC (Transaction Coord ...

  8. c# 简单的滑动图片验证

    普通的验证码对用户使用体验不友好,出现了滑动图片验证的验证方式,用户只要按住滑块完成图片的拼接即可通过验证(这是最简单的方式,滑动轨迹,数据分析,滑行速度 什么的暂没考虑) 主要的实现思路: 1.先从 ...

  9. Netty是什么,Netty为什么速度这么快,线程模型分析

    哈喽!大家好,我是小奇,一位热爱分享的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 书接上回,现在下着大雨看来是去 ...

  10. 12.MYSQL基础-常见函数

    4. 常见函数 一.字符函数 概念 类似于Java的方法,将一组逻辑语句封装在方法中,对外暴露方法名 优点 隐藏了实现细节 提高代码的重用性 调用 select 函数名(实参列表) [ from 表] ...