|
本帖最后由 fpgaw 于 2010-11-18 16:21 编辑
近年来,数字电路越来越复杂,我们的程序也越来越复杂,在中大型设计中,状态机的使用也越来越频繁,我们要如何编写一个让人容易读懂的状态机就是眼前最重要的事情。下面我们先来回顾一下状态机的分类。状态机共分为两大类一类是Moore状态机,一类是Mealy状态机。这两类状态机的区别主要是Moore的输出值只取决与当前状态,而Mealy状态机不仅与当前状态有关,还和输入值有关。如何区分是Moore还是Mealy型状态机,主要是看程序中状态转移的always语句中的条件转移变量。例如:
input a,clk; input a,clk;
output dout; output dout;
reg dout; reg dout;
parameter st0=1,st1=1,st2=2,st3=3;(编码方式,下面再讲) parameter st0=1,st1=1,st2=2,st3=3; (编码方式,下面再讲)
reg [1:0] state; reg [1:0] state;
[email=always@(negedge]always@(negedge[/email] clk) [email=always@(negedge]always@(negedge[/email] clk)
case(state)------------(case中只有状态,没有输入a,所以他是Moore状态机) case(state or a)------------(case既有有状态,也有输入a,所以他是Mealy状态机)
... ...
... ...
endcase endcase
endmodule endmodule
下面我在介绍一下我们在写状态机的时候用什么样的编码方式。状态机的编码方式主要有二进制编码,格雷编码和一位热码编码。下面我就对这三种编码分别做以介绍。一般二进制编码就是用 二进制来做编码,如000,001,010,111,等等。其实就是按照二进制的顺序进行编码,作为简单的编码,可以采用此编码方式,但是有一点要记住,再用此编码方式时,一定要做好毛刺处理的问题,因为当状态在发生变化的时候,编码也同时跟着发生变化,所以就会产生毛刺。产生毛刺的主要原因还是因为二进制码在变化时,最少有两位会同时发生变化,在时延上是不相等的。所以二进制码不能很好的剔除毛刺,同时会出现暂态过程,引起逻辑上的错误,从而造成程序跑飞。格雷编码其实就是变化的二进制编码,它主要要解决的问题就是去除毛刺,减少暂态过程。提高稳定性。例如:三位二进制码(000,001,010,011,100,101,110,111),变为格雷码(000,001,011,010,110,111,101,100)。在将二进制码变为格雷码时要记住变化时只能有一位变化,其他位保持不变。同时,要保证位数越高变化越慢。例如(000,001,101,111,011,010,110,100)在这个编码中最高位的变化速率是原来的两倍。在高速电路中这是一种不好的编码方式。最后我在讲讲一位热码编码。采用这种编码方式,相对于格雷码来说虽然增加了触发器,但是节省了组合电路。提高了电路的速度和可靠性。例如5位的热码编码(5'b00001,5'b00010,5'b00100,5'b01000,5'b10000;)。与格雷码一样都是一位进行变化,唯一不同的是,一位热码是不需要进行逻辑运算的。
最后我在讲讲整个状态机的编写如何让人很快的读懂。首先我们要知道自己的状态机一共有几部分组成,我在这里所指的几部分是说时序和组合逻辑。一般状态机都是由时序和组合逻辑两部分组成(只有一部分组成的在这里先不讲)。那么我们要怎么写才容易让人读懂呢?把状态机的时序部分作为第一部分,把状态机的组合逻辑作为第二部分。那么在第一部分里我们要做些什么工作呢?在第一部分里我们主要是用时序来控制状态机的同步描述,状态机的初始化。第二部分我们可以分为两个小步,第一步是进行状态机的状态转移,第二步是进行状态机的输出描述。其实第二部分也可以不分为两个小步,但是本人觉得分开后程序更清晰了。在第二部分中我们就可以选择是用Moore型还是Mealy型状态机了。
好了这次先讲这么多,有不对的地方请大家多多批评指正。在此新年之际祝大家新年快乐。<a href='http://www.caijiqi.net/cms/taker/luntan-caiji.jsp' target='_blank' title='论坛采集'><img alt='论坛采集' width='1' height='10' border='0' src='http://www.caijiqi.net/ad.gif'></a> |
|