状态机:
状态机是逻辑设计里面重要的内容,许多公司的硬件和逻辑工程师面试中,状态机设计几乎是必选题目。所以本次以状态机为话题进行重点讨论,以及如何写好状态机。
状态机全称是有限状态机(Finite State Machine、FSM),是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。
本篇博客对相关概念以及使用状态机实现特定字符串的检测,并通过程序具体理解一段式、两段式以及三段式状态机的区别以及优缺点。
~~ ~~
~~ ~~
1. 状态机基础概念:
状态机分摩尔(Moore)型有限状态机与米利(Mealy)型有限状态机。
Moore 有限状态机输出只与当前状态有关,与输入信号的当前值无关。在时钟脉冲的有效边沿作用后的有限个门延后,输出达到稳定值。从时序上看,Moore 状态机属于同步输出状态机。Moore 有限状态机最重要的特点就是将输入与输出信号隔离开来。
Mealy 状态机的输出是现态和所有输入的函数,随输入变化而随时发生变化。从时序上看,Mealy 状态机属于异步输出状态机,它不依赖于时钟。
基本的概念我相信大家都知道,这里我们着重来讲一段式,两段式和三段式状态机。
一段式状态机:
将整个状态机写到 1 个 always 模块里面,在该模块中即描述状态转移,又描述状态的输入和输出,这种写法一般被称为一段式 FSM 描述方法;
两段式状态机:
还有一种写法是将用 2 个always 模块,其中一个 always 模块采用同步时序描述状态转移;另一个模块采用组合逻辑判断状态转移条件,描述状态转移规律,这种写法被称为两段式 FSM 描述方法;
三段式状态机:
还有一种写法是在两段式描述方法基础上发展出来的,这种写法使用 3 个 always 模块,一个 always模块采用同步时序描述状态转移;第二个采用组合逻辑判断状态转移条件,描述状态转移规律;第三个 always 模块使用同步时序电路描述每个状态的输出。
写法。
~~ ~~
~~ ~~
2. 三种写法状态机之间的比较
例子:(这里引用了小梅哥FPGA的例子,也强烈建议小梅哥FPGA,适合FPGA学习)
实现对字符串HELLO 的检测,其状态转移图,如下图所示:
一段式和两段式状态机的程序相对简单,这里只放三段式状态机的程序(三段式相对于一段式和两段式状态机较优):
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
c_state <= H;
else
c_state <= n_state;
end
always@(*) begin
case(c_state)
H:begin
if(data == "H")
n_state = e;
else
n_state = H;
end
e:begin
if(data == "e")
n_state = l1;
else
n_state = H;
end
l1:begin
if(data == "l")
n_state = l2;
else
n_state = H;
end
l2:begin
if(data == "l")
n_state = o;
else
n_state = H;
end
o:begin
if(data == "o")begin
n_state = H;
end
else begin
n_state = H;
end
end
default:n_state = H;
endcase
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
led <= 1'b0;
else begin
if(n_state == o)
led <= 1'b1;
else
led <= 1'b0;
end
end
以及RTL视图:
那么实现这个字符串检测的功能,利用三种不同写法的状态机各有什么优缺点呢,先分别看一下三种状态机的状态描述结构图,相信你可以直观地看出区别。
1.一段式状态机状态描述结构图:
2.两段式状态机状态描述结构图:
3.三段式状态机状态描述结构图:
总结来说:
两段式之所以比一段式编码合理,就在于两段式编码将同步时序和组合逻辑分别放到不同的 always 程序块中实现。这样做的好处不仅仅是便于阅读、理解、维护,更重要的是利于综合器优化代码,利于用户添加合适的时序约束条件,利于布局布线器实现设计。
三段式与两段式相比,关键在于根据状态转移规律,在上一状态根据输入条件判断出当前状态的输出,从而在不插入额外时钟节拍的前提下,实现了寄存器输出。
这里只是简单介绍了一下状态机,方便大家共同学习,,,如果感兴趣的可以添加QQ进一步相互交流QQ:2859340499.