FPGA自学笔记——200704 按键消抖 状态机

小梅哥FPGA教程3.7——独立按键消抖设计与验证
本来今天想看模块设计加减计数器的,发现也要用到按键消抖的内容,所以最后还是学了按键消抖,这里对所学内容进行一个复盘

Part1 为什么消抖

按键在按下的过程中因为机械原因会产生抖动(弹簧震动),到达稳定态需要一定的时间(资料说一般是20ms),如果单纯靠按键信号的上升沿或下降沿判断则肯定存在误判,所以要进行一定的过滤去除按键抖动的影响
另外人按一个按键持续时间快一点应该也有100ms,所以不用想只要你够快电路就检测不到你按了按键
对应场景比如按键作为一个输入标志,控制LED亮灭,那么抖动会造成影响,而如果是按键复位这样的场景,则影响不大

Part2 消抖的硬软方法

硬件包括RS触发器(与非或者或非门,只是用于单刀双掷开关),RC电路配合施密特触发器(两脚或者四脚按键),555定时器组成的单稳态触发器

RS触发器是通过 1 1状态的保持功能实现消抖(抖动时R,S输入都是1 1),后面两种则是通过电容充放电需要时间才能改变电平来实现消抖

软件消抖看了下网上的资料,是进行两次确认,接收到第一个信号后延时一段时间,如果状态还是一样则认为按键已稳定

软硬消抖方法百度一下有很多,也不是今天学习的重点,额外了解就好了

Part3 FPGA消抖

这个案例的学习目标其实是复习状态机,学习task模块编写以及random随机函数的使用,顺带讲一下仿真模型的概念

实际消抖肯定是用软件消抖的思路,设置一个计时器通过延时做两次确认就好,这个案例里面每次抖动都会重启计数器,相当多余,所以开始学习的时候一度感到不合理,直到认识到这只是个为了应用状态机的案例就不纠结于这个问题了

整体模块内容包括:

  1. 按键按下和松开的上升沿判断和下降沿判断(边沿检测电路),使用两个串联同步寄存器和与门实现
  2. 计时器(计数器),20ms/20ns=10^6,要带一个使能端启动
  3. 状态机case块,四个状态IDLE,FILTER0,DOWN,FILTER1(四个状态也是分析后设定的,不纠结)

具体细节:
1.always块语句只对一个信号进行操作,总体上大家都是按照clk变化来并行的,分开写并不影响逻辑
2.paralocal的语法细节要注意(=和,)
3.通常将参数的定义都放在前面,避免modelsim仿真时报错
4.always里面进行了赋值的语句要定义为reg型
5.case里面的default差不多能按rst_n的条件书写
6.遇到了一个bug将resolve multiple constant drivers for net" ",这个是一个信号在多个地方(并行的进程中)被赋值了,实际上肯定不允许,所以双击对应的信号查找修改即可,简单讲一个信号只能在一个always块里赋值,多了就不行

Part4 testbench编写错误总结

1.rst_n通常都是开局置0,延时一段时间后重新置1,然后再执行后面的设计内容
2.random函数产生的是有符号的32位随机整数,想获得正的随机整数就使用{$random},语言就使用{$random}%b(取余运算),这样获得的随机数就在0~b-1之间了
3.task模块,语法倒没有什么太多要注意的
4.repeat函数
5.error loading design 报错则去检查setting-simulation-compile文件里面文件名设置是否正确,然后检查testbench文件里面的模块调用是否正确,这些编译的时候都不会报错,但是仿真会无法运行
6.modelsim波形自动分组快捷键ctrl+G(group)
注:markdown里面有些字符比如# $ *无法正常显示,只需要在前面加上转移符号\即可

Part5 仿真模型

1.相当于把testbench里面的一些操作提取出来进行封装,只给出一个接口,这样在不同的设计中有共性的操作部分就可以在仿真的时候方便的调用了
2.仿真前要在setting-simulation-compile的tb文件下加入model的文件
3.主要应用案例有SDRAM

你可能感兴趣的:(FPGA自学笔记——200704 按键消抖 状态机)