原创 状态机

2013-10-22 09:56 1295 12 12 分类: FPGA/CPLD 文集: Verilog

 

状态机

这些天一直跟状态机打交道,所以来说一下状态机,说的不对的地方希望大家多多指正。状态机就是状态转移图。举个最简单的例子。人有三个状态健康,感冒,康复中。触发的条件有淋雨(t1),吃药(t2),打针(t3),休息(t4)。所以状态机就是健康-(t3)->健康;健康-(t1)->感冒;感冒-(t3)->健康;感冒-(t2)->康复中;康复中-(t4)->健康,等等。就是这样状态在不同的条件下跳转到自己或不同状态的图。状态机简写为FSM(Finite State Machine),主要分为2大类:第一类,若输出只和状态有关而与输入无关,则称为Moore状态机;第二类,输出不仅和状态有关而且和输入有关系,则称为Mealy状态机。要特别注意的是,因为Mealy状态机和输入有关,输出会受到输入的干扰,所以可能会产生毛刺(Gitch)现象,使用时应当注意。这些都是百度上的解释,感兴趣的可以看一下,可以给我们一个初步的了解,在特权同学《深入浅出玩转FPGA》笔记五当中也有一些介绍。网上也会有很多的介绍让我们去了解。

这里说一下自己的感受,前面也提到状态机的分类,状态机简写为FSM(Finite State Machine),主要分为2大类:第一类,若输出只和状态有关而与输入无关,则称为Moore状态机;第二类,输出不仅和状态有关而且和输入有关系,则称为Mealy状态机。忘了在哪本书中看到过了,verilog hdl中有很多的方法来描述有限状态机,最常用的方法就是用always语句和case语句,状态机一般有三种不同的写法:一段式、二段式、三段式。

一段式:整个状态机写到一个always模块里面,既描述状态转移,又描述状态的输入和输出。一般格式是这样的:

reg [3:0] state;

always @ (posedge clk or negedge rst)

begin

if(!rst)

   begin

     cstate<=idle;

     “输出”<=0;

   end

else

begin

case(state)

.

.

.

default:…………

endcase

end

end

二段式:用两个always模块描述状态机,其中一个always模块采用同步时序描述状态转移,另一个模块采用组合逻辑判断状态转移条件,描述状态转移规律以及输出.一般格式是这样的:

reg [3:0] cstate;

reg [3:0] nstate;

always @ (posedge clk or negedge rst)

begin

if(!rst)

cstate<=idle;

else

cstate<=nstate;

end

always @ (cstate or 一系列的触发条件)

begin

case (cstate)

.

.

.

endcase

end

三段式:是在两个always模块描述方法基础上,使用三个always模块,一个always模块采用同步时钟描述状态转移,一个always模块采用组合逻辑判断状态转移条件,描述状态转移规律,另一个always模块描述状态输出(可以用组合电路输出,也可以时序电路输出)。一般格式是这样的:

reg [3:0] cstate;

reg [3:0] nstate;

always @ (posedge clk or negedge rst)

begin

if(!rst)

cstate<=idle;

else

cstate<=nstate;

end

 

always @ (cstate or一系列的出发条件)

begin

case(cstate)

.

.

.

endcase

end

 

always @ (posedge clk or negedge rst)

begin

if (!rst)

else

case(cstate)

.

.

.

endcase

end

总结一下,一段式状态机在一个always模块里,显得有点乱不利于维护、理解、阅读,当然如果是简单的状态机,还是可以使用。二段状态机虽然便于维护、理解、阅读,但是组合逻辑输出容易出现毛刺现象,不利于约束不利于综合器和布局布线器高性能的设计。三段状态机既利与维护有不会有毛刺现象的出现,但貌似资源消耗会多一点。

文章评论0条评论)

登录后参与讨论
我要评论
0
12
关闭 站长推荐上一条 /2 下一条