状态机
这些天一直跟状态机打交道,所以来说一下状态机,说的不对的地方希望大家多多指正。状态机就是状态转移图。举个最简单的例子。人有三个状态健康,感冒,康复中。触发的条件有淋雨(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条评论)
登录后参与讨论