FSM

来源:互联网 发布:淘宝怎么设置打折价格 编辑:程序博客网 时间:2024/06/06 03:32

http://www.eefocus.com/liuyuxue/blog/13-11/300257_00bea.html
这位博主写得十分全面啊。以下摘录部分

关于二段与三段

Coding Style
状态机一般有三种写法,他们在速度、面积、代码可维护性等各个方面互有优劣。

一段式:只有一个always block,把所有的逻辑(输入、输出、状态)都在一个always block中实现;这种写法看起来很简洁,但是不利于维护。如果状态复杂一些就很容易出错。不推荐这种方法,但是在简单的状态机可以使用。

二段式:有两个always block,把时序逻辑和组合逻辑分隔开来。时序逻辑里进行当前状态和下一状态的切换,组合逻辑实现各个输入、输出以及状态判断。这种写法不仅便于阅读、理解、维护,而且利于综合器优化代码,利于用户添加合适的时序约束条件,利于布局布线器实现设计。在两段式描述中,当前状态的输出用组合逻辑实现,可能存在竞争和冒险,产生毛刺。则要求对状态机的输出用寄存器打一拍,但很多情况不允许插入寄存器节拍,此时使用三段式描述。其优势在于能够根据状态转移规律,在上一状态根据输入条件判断出当前状态的输出,从而不需要额外插入时钟节拍。

三段式:有三个always block,一个时序逻辑采用同步时序的方式描述状态转移,一个采用组合逻辑的方式判断状态转移条件、描述状态转移规律,第三个模块使用同步时序的方式描述每个状态的输出。代码容易维护,时序逻辑的输出解决了两段式组合逻辑的毛刺问题,但是从资源消耗的角度上看,三段式的资源消耗多一些,且输出比另外两种会延时一个时钟周期。
三段式模板:见原文

个人体会

区别其实即在于对组合逻辑和时序逻辑的处理上。
对于组合逻辑,有两输入同时反响跳变的时候就会出现出现竞争冒险。(为了消除毛刺,会在输出加一级寄存器?回头出文讲解)
对于时序逻辑,会增加一些寄存器,从而导致面积增大,输出时间变长(但是从更加长远的角度来看,当然这是提速的行为)

关于FSM always块中对于初始和default状态的赋值

有两个作用:第一,仿真的时候可以很好的考察FSM的完备性,如果不完备,则进入任意状态,仿真的时候可以很快发现;第二,实现时综合器对x的处理时“don’t care”,即任何没有定义的状态寄存器向量(CS)都会被忽略,综合器为其生成的电路最简洁,同时满足要求。

个人体会

通常对于下一状态的赋值有三种方式:1,全部设置为不定态;2,设置为预先规定的初始状态;3,设置为某一有效状态。(看起来二、三是一样的啊)。显然基于综合器和仿真的考虑,X态肯定是更好啦。
Question?如果不用默认状态(也就是把这句话给去掉啊)会怎么样呢?

default 状态的设置

设置“default: NS = ‘bx”与实际硬件电路相一致。如果将缺省状态设置为某一确定的状态(例如:设置”default: NS = S1”,行不行呢?尽管综合器产生的逻辑和设置“default:state=’bx”时相同,但是状态机的Verilog HDL模型综合前和综合后的仿真结果会不一致。因为启动仿真器时,状态机所有的输入都不确定,因此立即进入default状态。如果通过设置将状态变量设为S1,但是实际硬件电路的状态机在通电之后,进入的状态是不确定的,很可能不是S1的状态,这样就会产生不必要的冲突。因此,还是设置“default: NS = ‘bx”与实际硬件电路相一致。

状态机中状态变量初始化赋值:如果所有的状态都使用到了,可以使用x,它可以让综合器删除不必要的译码电路,使生成的电路简洁,并与设计要求一致,另外调试的时候很方便;如果状态没有使用完,有多余的状态,则不能使用x,应该设置为IDLE或者0。这样做能使状态机若偶然进入多余状态后仍能在下一时钟跳变沿时返回正常工作状态,否则会引起死锁。

待补充部分(关于编码类型、消除glitch)

always @ (posedge clk or negedge rst_n) //异步复位
if(!rst_n)
current_state <= IDLE;
else
current_state <= next_state; //注意,使用的是非阻塞赋值

//第二个进程,组合逻辑always模块,描述状态转移条件判断
always @ (current_state) //电平触发
begin
next_state = IDLE; //要初始化,使得系统复位后能进入正确的状态
case(current_state)
S1: if(…)
next_state = S2; //阻塞赋值

endcase
end

//第三个进程,同步时序always模块,格式化描述次态寄存器输出
always @ (posedge clk or negedge rst_n)
…//初始化
case(next_state)
S1:
out1 <= 1’b1; //注意是非阻塞逻辑
S2:
out2 <= 1’b1;
default:… //default的作用是免除综合工具综合出锁存器
endcase
end

原创粉丝点击