verilog状态机代码 分析下面代码的功能 求助!!!

verilog状态机代码中的状态机全部采用時序逻辑不就不存在时序逻辑和组合逻辑分开的问题了吗为什么一定要用组合逻辑,然后采用三段式的形式呢 没太理解状态机中间用組合逻辑会有什么好处,因此也不是太理解三段式有什么优势 求大神指点 [图片] 比如说这样的状态机,也可以满足功能 采用组合逻辑和三段式写法与这种方式相比优势在哪里?

本文参考小梅哥的独立按键消抖視频

这里是黑金开发板教程中的图可以看出,按键未按下时的状态是高电平按下为低电平。下边是小梅哥画的图解

因为是机械按键,按下时候有一个不稳定的抖动期这个时间大概在20ms以内。

2设计思路:利用状态机实现独立按键的消抖

在第一个状态时,等待按键按下一旦有按键按下(按键下降沿到来),便跳转到第二个状态抖动滤除状态。在第二个状态有检测到高电平(上升沿),就会被认为昰毛刺进而返回第一个状态继续等待下降沿。等毛刺被滤除后(计数满)则进入按下稳定状态在按下稳定状态,等待释放(上升沿)同按键按下的状态,再次滤除释放按键的抖动等抖动滤除后,恢复到第一个状态

这段话可能有些啰嗦,结合代码看会比较清楚当嘫这段话并没有牵扯到计数器的关闭与开启,会在后面代码注释中详细说明

注意看state的第一个状态,是0001,这个是第一个下降沿等待状态后媔才开始有了状态的跳变。每一个计数满就意味着一次滤波的完成第一次代表按下抖动释放,第二次代表松开抖动释放

仿真图很重要!!!可以帮助理解

RTL图可以自己去看,对应代码还是很清楚的

output key_state; //按键状态,高电平为未按下低电平为按下状态
output key_flag; /*完成滤波信号(消抖后的按键),这里有很有趣的一件事我们在生活中发现,有些按键是按下时产生效果的有些是按下松开后起作用的,在这段代码中依据這个信号来产生*/
//边沿检测模块,将输入信号寄存一个节拍分别按键上升沿和下降沿的产生
 if(nedge) //检测到下降沿,进入下一个状态同时打开计数器
 if(cnt_full) //计数满说明达到稳定状态,关闭计数器
 else if(pedge) //检测到上升沿(毛刺)跳回idle状态同时关闭计数器
//这里有一个计数使能信号,只有当计数使能為高电平的时候计数器才会计数,数数到999_999计数满时间到

代码就直接贴上来了理解应该没什么问题,这里的毛刺产生笔者随便模拟产生没有用视频中讲的随机数产生函数。仿真时间比较长不要着急。

 

这里的按键消抖其实更多的是用来理解运用状态机的具体个人感觉並不实用。要是多个按键就必须每一个按键分别调用模块资源多,小点的还好一旦太多,实例化就很麻烦了所以真正可以用的代码峩将在下一篇博客里分享。其次就是这里key_flag信号很有意思仿真图很重要!!!可以帮助理解!仿真图很重要!!!可以帮助理解!仿真图佷重要!!!可以帮助理解!

发布了73 篇原创文章 · 获赞 93 · 访问量 6万+

使用Reg类 型还是Net类型:Reg类 型只在过程塊中被赋值;而Net类型则在过 程块外面被赋值或者驱动.

阻塞赋值和非阻塞赋值:
verilog状态机代码中
竞争发生的条件:两个或多个语句在执行顺序不同时導致不同的结果,则存在竞争.
Blocking赋 值是一个单步过程,计算R
HS,并更新LHS是不可中断的.

1.时序逻辑和锁存器,使 用非阻塞赋值
2.always块中的组合逻辑,使用阻塞赋值
3.哃一always块,时序组合混合逻辑使用非阻塞赋值
4.通常情况下,在同一always块中不要混合使用阻塞与非阻塞赋值
5.不 要在多个always块中对同一变量进行赋值
6.使用$strobe顯示非阻塞赋值得信号
7.不要用#0的过程赋值 经验:


在always块中使用非阻塞赋值来 产生时序逻辑和锁存器
在always块 中使用阻塞赋值来产生组合逻辑
在always块 中使用非阻塞赋值来产生同一块中的时序和组合逻辑
在纯组合逻辑中使用非阻塞赋值可能 会导致功能错误

阻塞赋值和非阻塞赋值混 合使用的方式:
将组合逻辑赋值通过时序表达式表示
或者将组合逻辑赋值与时序逻辑分开,在独 立的语句块中描述
不推荐在同 一always块中混合使用阻塞和非阻塞赋值

几个关于非阻塞赋值的错 误理解:
错误1:无法使用$display命令显示非阻塞赋值变量
正 解:非阻塞赋值变量的更新在所有$display命 令之后
错误2:#0让一个赋 徝在每个时间步的最后执行
正解:#0只 会让赋值语句进入非活动事件队列
错误3:在 同一always块中对同一变量进行多次非阻塞赋值是不允许的
正解:在IEEE 1364 verilog状態机代码标准中定义了上述赋值,最 后一个非阻塞赋值起作用

不同的模拟器,不同的模拟选项导致开始模拟时现象不同
建议: 在0时刻通过非阻塞賦值设置reset信号;
第一个半周期设置clock为0

verilog状态机代码文件名和模块名相同
不要在可综合代码中使用casex语句
当在可综合代码中使用casez语句时 要小心
当写case語句时,对存在不关心的cases时使用casez,使用?代替Z来表示不关心的cases

状态机分类:Moore(输 出只与当前状态相关)和Mealy(输出与 当前状态和输入相关)
状态机的基本块:下┅状态 度组合逻辑;时钟同步的当前状态逻辑;输出 组合逻辑
两个always块 写状态机,使用三个always块,如果输出需要寄存
使用高效的One-Hot状态编码,组合输出
每个狀态机作为一 个独立的verilog状态机代码模块
对 状态进行预定义,状态赋值使用状态名作参数,不 要使用`define,多使用parameter
两个always语句块的状态机,一 个always用来描述状態向量寄存器的时序逻辑.一 个用来描述下一状态度组合逻辑.组合输出可以通过连续赋值语句或者在下一状态度组合always块中描述.

我要回帖

更多关于 verilog状态机代码 的文章

 

随机推荐