Verilog 按键消抖模块

遇到的问题:第一边沿检测以及对key_flag和key_state的作用了解耗费了我很多时间,经过不断的分析后还是找出了错误在解决问题的过程中让我也对层次化设计FPGA更加了解,同时对阻塞赋值和非阻塞赋值也有了更深刻的了解,熟悉了定时器的设计与应用感悟:FPGA是个大坑啊,进去了就出不来了,哈哈哈!       希望自己在接下来的路上越搓越勇
设计代码:
/**NAME: Rayone*DATE: 2019/5/21*FUNC: key filter*/
module key_filter(Clk,Rst_n,key_in,key_flag,key_state);
//端口定义input Clk;input Rst_n;input key_in;output reg key_flag; //滤波后如果检测确实按下了将其置1output reg key_state;//按键在空闲稳定状态下为1 在按下稳定状态为0//key_filter模块设计
//——>利用两级D触发器降低亚稳态发生的可能reg key_in_tmpa,key_in_tmpb;always@(posedge Clk or negedge Rst_n)if(!Rst_n)beginkey_in_tmpa <= 1'b0;key_in_tmpb <= 1'b0;endelse beginkey_in_tmpa <= key_in;key_in_tmpb <= key_in_tmpa;end//——>捕获key_in变化信号wire pedge,nedge;//key_in的上升沿和下降沿reg key_in_a,key_in_b;always@(posedge Clk or negedge Rst_n)if(!Rst_n)beginkey_in_a <= 1'b0;key_in_b <= 1'b0;endelse beginkey_in_a <= key_in_tmpb;//key_in_tmpb是key_in经过二级D触发器处理后的,这里是非阻塞赋值//key_in_a在给key_in_b赋值的同时也给key_in_b赋值,处于时时更新的key_in_b <= key_in_a;end//now :key_in_a   ago :key_in_bassign pedge = ((!key_in_b) & key_in_a); //key_in上升沿信号到来assign nedge = ( key_in_b & (!key_in_a));//key_in下降沿信号到来//前期设计已经准备好了,接下来就是状态机的设计localparam  //one-hot codeIDLE     = 4'b0001,FILTER0 = 4'b0010,DOWN    = 4'b0100,FILTER1 = 4'b1000;//用一个状态寄存器保存状态reg [3:0]state;//设计定时器reg [19:0]cnt;        //——>需要一个计数寄存器,因为只用计数20ms,所以一个20位的寄存器已经足够了reg en_cnt;        //——>计数器开始计数使能信号reg cnt_full_flag;//——>计数器加满标志//状态机设计always@(posedge Clk or negedge Rst_n)if(!Rst_n)beginstate <= IDLE;en_cnt <= 1'b0;key_flag <= 1'b0;key_state <= 1'b1;endelse begin case(state)IDLE:beginkey_flag <= 1'b0;if(nedge)begin//如果检测到下降沿state <= FILTER0;//进入按下抖动滤波状态en_cnt <= 1'b1;  //使能计数(此时需要计时20ms,前面我们没有设计计数器,于是我们在最后设计一个计数器哦)endelse state <= IDLE;end   FILTER0:beginif(cnt_full_flag)beginstate <= DOWN;en_cnt <= 1'b0;key_flag <= 1'b1; //标志按键此时确实按下key_state <= 1'b0;//此时按键处于按下稳定状态endelse if(pedge)beginen_cnt <= 1'b0;state <= IDLE;   endelse state <= FILTER0;   endDOWN:beginkey_flag <= 1'b0;if(pedge)beginen_cnt <= 1'b1;state <= FILTER1;end   elsestate <= DOWN;endFILTER1:beginif(cnt_full_flag == 1'b1)beginstate <= IDLE;       //计数满标志成功计数en_cnt <= 1'b0; //关闭计数
//                      key_flag <= 1'b1;  //标志按键此时确实释放key_state <= 1'b1;//空闲稳定状态下为1endelse if(nedge)beginen_cnt <= 1'b0;state <= DOWN;  endelse state <= FILTER1;   enddefault:begin state <= IDLE; en_cnt <= 1'b0;        key_flag <= 1'b0;key_state <= 1'b1;endendcaseend//计数器加1操作 always@(posedge Clk or negedge Rst_n)if(!Rst_n)begincnt <= 20'd0;endelse if(en_cnt)cnt <= cnt + 1'b1;else cnt <= 20'd0;//产生计数20ms满信号 cnt_full_flag always@(posedge Clk or negedge Rst_n)if(!Rst_n)cnt_full_flag <= 1'b0;else if(cnt == 999_999)cnt_full_flag <= 1'b1;else cnt_full_flag <= 1'b0;endmodule

按键的状态图:

仿真波形图:

可以看到:当检测到按键按下时key_flag置1表示按键已经按下,key_state用于判断按下后是否处于稳定状态,如果要将该模块运用于其他模块就可以通过检测这两个信号状态来进行使用
module led_ctrl(Clk,Rst_n,key_flag0,key_flag1,key_state0,key_state1,led);input Clk;input Rst_n;input key_flag0,key_flag1;input key_state0,key_state1;output [3:0]led;reg [3:0]led_r;always@(posedge Clk or negedge Rst_n)if(!Rst_n)led_r <= 4'b0000;else if(key_flag0 && !key_state0)led_r <= led_r + 1'b1;else if(key_flag1 && !key_state1)led_r <= led_r - 1'b1;elseled_r <= led_r;assign led = ~led_r;endmodule
这里就是通过检测key_flag(按键是否按下)和key_state(是否处于稳定状态)来使4个led表示的二进制数的加1和减1操作

Verilog中的按键消抖相关推荐

  1. Verilog功能模块 —— 按键消抖

    一. 什么是按键消抖 按键消抖_百度百科 (baidu.com) 按键消抖通常的按键所用开关为机械弹性开关,当机械触点断开.闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断 ...

  2. Verilog实现独立按键消抖(状态机)

    本文参考小梅哥的独立按键消抖视频 1,实验原理: 这里是黑金开发板教程中的图,可以看出,按键未按下时的状态是高电平,按下为低电平.下边是小梅哥画的图解. 因为是机械按键,按下时候有一个不稳定的抖动期, ...

  3. FPGA学习-Verilog实现独立按键消抖

    文章目录 前言 一.独立按键消抖原理 二.按键消抖程序实现(Verilog) 1.按键触发判断 2.计数器模块实现 3.按键状态更新 4.按键控制led亮灭 三.仿真测试文件编写 四.编译结果 前言 ...

  4. 可编程逻辑器件之按键消抖实验

    一.实验目标 能够熟练的进行可编程逻辑器件开发,能够通过具体工程需求进行需求分析.模块划分.代码编写.功能仿真.综合分析.板级验证,能够独立正确的进行实验操作,培养学生的工程实践研究能力和动手实践能力 ...

  5. ARM(I.MX6ULL) EPIT定时器中断实验、定时器按键消抖

    参考:Linux之ARM (I.MX6ULL) EPIT定时器详解 作者:一只青木呀 发布时间: 2020-09-20 10:03:37 网址:https://blog.csdn.net/weixin ...

  6. Verilog中按键消抖检测的实现

    Verilog按键消抖是FPGA学习时的一个入门教程,为避免眼高手低,还是再次分析与记录一下.此处着重介绍按键消抖的基本原理,对按键消抖与检测的关键技术进行分析,并进行功能仿真. 一.按键消抖基本原理 ...

  7. 【Verilog HDL 训练】第 09 天(按键消抖)

    5月7日 按键防抖 1. 用verilog实现按键抖动消除电路,抖动小于15ms,输入时钟12MHz. 在编写Verilog代码之前,先分析下一些前提问题,首先是几个按键(1个,多个),我们以1个和三 ...

  8. 基于verilog按键消抖设计

    关于键盘的基础知识,我就以下面的一点资料带过,因为这个实在是再基础不过的东西了.然后我引两篇我自己的博文,都是关于按键消抖的,代码也正是同目录下project里的.这两篇博文都是ednchina的博客 ...

  9. Verilog实现4位按键消抖,分别控制一个LED

    Verilog实现4位按键消抖,分别控制一个LED 代码思路(完整代码在后) 完整代码 参考:(主要是第一篇,第二篇不严谨) <按键消抖与LED控制>实验的个人思考与总结 Verilog实 ...

  10. verilog基础-状态机之FPGA独立按键消抖设计与验证(熟练testbench的写法)

    独立按键消抖设计与验证 本实验主要是为了锻炼状态机的思维模式以及熟练掌握TB的写法 本节主要收获了:define的用法,另外就是,顶层的input在TB中是reg的真正含义,其实就是把激励当做寄存器来 ...

最新文章

  1. 外国人居留证办理手续
  2. CURL NDK 交叉编译
  3. Java虚拟机:class类文件结构
  4. 配置IISExpress允许外部访问
  5. RocketMQ入门
  6. 前端学习(3015):vue+element今日头条管理--自定义验证规则
  7. Tensorflow官方文档学习理解 (四)-深入MNIST
  8. css基础--滤镜特效
  9. 小伙子自学C++编程简单DIY,即让你拥有一个屏幕画笔,非常实用!
  10. 你会用JSON.stringify()?
  11. [ PyQt入门教程 ] Qt Designer工具的使用
  12. CSS基础(P45-P65)
  13. .net的过去、现在和未来
  14. 前端水印生成方案(网页水印+图片水印)
  15. 宇视网络视频录像机如何修改宇视摄像机网络地址
  16. 苹果x计算机怎么恢复,苹果手机怎样找回备忘录,电脑小白数据恢复全攻略
  17. 区块链游戏,不懂你别玩!
  18. jsPlumb使用小技巧
  19. java.lang.IllegalStateException: 由于没有提供multi-part配置,无法处理parts
  20. 三角函数专题【高阶辅导】

热门文章

  1. OSChina 周五乱弹 ——我们测算过无数代码却依旧算不准没钱的这一生
  2. mac电脑网游加速器哪个好用?网易uu网游加速器分享
  3. UniAPP支付宝H5支付
  4. 35 个非主流数据库
  5. 一篇文章,带你详细了解华为认证体系证书(1)
  6. PLC实训 — PLC的27条基本逻辑指令
  7. 用两个栈实现一个队列【C语言】
  8. ES6新语法-day02
  9. 【业务安全01】业务安全基础及测试流程
  10. zip命令 – 压缩文件