三段式
- 1.什么是有限状态机
- 2.Mealy 状态机
- 2.Moore FSM
- 3.Mealy 和 Moore的区别
- 4.Encoding 风格
-
- 设计原则
- 5. 一段式状态机
- 6. 二段式状态机
-
- 控制current state 写法
- 控制 state写法
- 控制current state 和output
- 7.三段式状态机
- 总结
-
- Extra
1.什么是有限状态机 如果一个系统在有限数字的内部状态下转换,就可以用有限状态机来描述这个系统。网上比较经典的例子就是校验固定序列 100010这种。 状态机一般有两种书写方式分别是Mealy状态机和Moore状态机。
2.Mealy 状态机
文章图片
Mealy状态机的输出是由当前状态和当前输入一起决定的。
2.Moore FSM
文章图片
Moore状态机的输出只与当前状态相关。
3.Mealy 和 Moore的区别
- 如上述已经说过的Mealy是由当前输入和当前状态state确定的所以Mealy是一种“asynchronousmachine”,而Moore是只有当前状态决定的所以它是一种“synchronous machine”。
- Mealy需要的状态比Moore少
- Moore状态机适合于不太在于毛刺(glitches)的情况。
- Mealy状态机适合于无毛刺 无延时的情况,但是对于Mealy的异步设计需要注意,所以Mealy相对于Moore的设计会更复杂。
- Binary : 状态由binary格式表示(000,001,010…)
- Gray :状态由格雷码风格表示(000,001,011…)
- One Hot : 只有1个bit是high,reset是low(0001,0010,0100…)
- One Cold : 只有1个bit是low,reset是high(1110,1101,1011…)
文章图片
5. 一段式状态机
module top_module(
input clk,
input areset,// Asynchronous reset to state B
input in,
output out);
//parameter A=0, B=1;
reg state, next_state;
always @(posedge clk, posedge areset) begin// This is a sequential always block
if(areset) begin
state <= B;
out <= 1;
end
else begin
case(state)
A:
if (in) begin
state <= A;
out <= 0;
end
else begin
state <= B;
out <= 1;
end
end
B:
if (in) begin
state <= B;
out <= 1;
end
else begin
state <= A;
out <= 0;
end
endcase
end
end// Output logic
// assign out = (state == ...);
endmodule
上述是一种Mealy的写法 输出是由 in和当前状态共同决定的所以这种写法state和output会同时到达。
文章图片
module top_module(
input clk,
input areset,// Asynchronous reset to state B
input in,
output out);
//parameter A=0, B=1;
reg state, next_state;
always @(posedge clk, posedge areset) begin// This is a sequential always block
if(areset) begin
state <= B;
out <= 1;
end
else begin
case(state)
A: begin out <= 0;
if (in) begin
state <= A;
end
else begin
state <= B;
end
end
B: begin out <= 1;
if (in) begin
state <= B;
end
else begin
state <= A;
end
end
endcase
end
end// Output logic
// assign out = (state == ...);
endmodule
上述这种写法是Moore写法区别是在case语句中 out是放在if判断中还是放在if判断外。 判断写法也可以写成 一下这种形式
state <= in ? A : B;
文章图片
6. 二段式状态机 控制current state 写法
module top_module(
input clk,
input areset,// Asynchronous reset to state B
input in,
output reg out);
//
parameter A=1'b0, B=1'b1;
reg current_state, next_state;
always@(posedge clk or posedge areset)begin
if(areset)begin
current_state <= B;
end
else begin
current_state <= next_state;
end
end
always@(*)begin
case(current_state)
B:begin
if(in == 1'b1)begin
next_state = B;
end
else begin
next_state = A;
end
end
A:begin
if(in == 1'b1)begin
next_state = A;
end
else begin
next_state = B;
end
end
endcase
end//combinational logic way
always@(*)begin
if(current_state == B)begin
out = 1'b1;
end
else begin
out = 1'b0;
end
end
上述还是一种Moore的二段式写法但是这次的输出out不会延后一个时钟,是因为next_state 是由组合逻辑电路产生的这样输出只会慢next_state一个时钟。 这种写法属于控制current_state
文章图片
如果用VHDL写的话,实际上输出是会慢state 1个 delta delay的。
文章图片
控制 state写法
module top_module(
input clk,
input areset,// Asynchronous reset to state B
input in,
output reg out);
//
parameter A=1'b0, B=1'b1;
reg state;
always@(posedge clk or posedge areset)begin
if(areset)begin
state <= B;
end
else begin
case (state)
A : if(in) begin
state <= A;
end
else begin
state <= B;
end
B : if (in) begin
state <= B;
end
else begin
state <= A;
end
end
end
//combinational logic way
always@(*)begin
if(state == B)begin
out = 1'b1;
end
else begin
out = 1'b0;
end
end
这种写法的在VHDL中依然有 output value 实际上依然有one delta delay的延时。
控制current state 和output
module top_module(
input clk,
input areset,// Asynchronous reset to state B
input in,
output reg out);
//
parameter A=1'b0, B=1'b1;
reg current_state, next_state;
always@(posedge clk or posedge areset)begin
if(areset)begin
current_state <= B;
end
else begin
current_state <= next_state;
case(state)
A : out <= 0;
B : out <= 1;
endcase
end
end
always@(*)begin
case(current_state)
B:begin
if(in == 1'b1)begin
next_state = B;
end
else begin
next_state = A;
end
end
A:begin
if(in == 1'b1)begin
next_state = A;
end
else begin
next_state = B;
end
end
endcase
end
这种写法会消除one delta delay 。 因为这样能够确保state和output都是从register输出的,这样就不用管downstream(后面要接的电路)的情况,也没有了one delta delay了。 这种写法也相当于大家经常看到的普遍的二段式加上寄存器输出。
7.三段式状态机 Moore:
module adder(
clk,rst,q_out,key
)
input clk,rst,key;
out q_out;
localparamS1 = 0, S2 = 1, S3 = 2;
reg[1:0] state, next_state;
always @(posedge clk or posedge rst)
begin
if(rst)
state <= S1;
else
state <= next_state;
endalways @(key or state)
begin
case(state)
S1 : if(key)
next_state = S2;
else
next_state = S1;
S2 : if(key)
next_state = S3;
else
next_state = S2;
S3 : if(key)
next_state = S1;
else
next_state = S2;
default:
next_state = 2'bxx;
endcase
endalways @(posedge clk or posedge rst)
begin
if(rst)
q_out <= 0 ;
else
case(next_state)
S1 : q_out <= 0;
S2 : q_out <= 1;
S3 : q_out <= 0;
default : q_out <= 1'bx;
endcase
end
endmodule
总结 三段式使用3个always块,第一个采用同步时序电路用来描述状态转移state->next_state,第二个用组合逻辑实现转换数值传递条件,最后再输出再增加一级触发器来实现时序逻辑输出,这样做的好处是:
- 有效除去因为组合逻辑输出产生的毛刺,利于时序计算和约束,利于布局布线实现高性能设计。
- 对于输出为总线模式的输出信号,容易使总线对齐,从而减少总线数据偏移,减少接收端数据采样出错的概率。
文中提到的delta delay 的问题可能就是VHDL与Verilog最本质的区别。
其实三段式和二段式的主要区别就是,在组合逻辑的时候要不要在使用register输出output,像我二段式中时序同时控制current state 和输出这种形式其实本质和三段式没有区别。所以还是要理解电路的时序问题再看采用怎样的代码。
Extra 【verilog|verilog中一文搞懂有限状态机(FSM)Mealy和Moore状态机(及一段式,二段式,三段式)】在Xilin官网上有讨论提出,可能很多人喜欢用一段式,这样是最简单的。至于原因大家可以自己去瞅瞅,因为看过一遍之后,没能记下来所以不想在这个小细节上纠结。
https://forums.xilinx.com/t5/Synthesis/FSM-coding-1-vs-2-vs-3-process-style-which-one-is-preferred/td-p/746476
大家感兴趣可以参考 Verilog flaw这篇文章
https://insights.sigasi.com/opinion/jan/verilogs-major-flaw/
还有这一篇对VHDL如何写三种模式的状态机的方法,我使用的图是这个网站的,我相当于把VHDL翻译成Verilog,仿真之后也是符合我说的现象的。
https://vhdlwhiz.com/n-process-state-machine/
http://blog.sina.com.cn/s/blog_6f0eeb330101djzu.html
推荐阅读
- 设计|FSM有限状态机(三段式)-Verilog实现
- HDLBits|HDLBits练习-有限状态机FSM
- 行为树|BT9(各种调试工具介绍)
- App更新之dialog数字进度条
- Verilog|IIC总线协议Verilog实现
- 【2】FPGA设计与调试方法|FPGA状态机(一段式、二段式、三段式)、摩尔型(Moore)和米勒型(Mealy)
- 【3】简单的接口与外设|FPGA实现IIC协议(二)----IIC总线的FPGA实现(单次读写驱动)
- 任务定时|SpringBoot整合Quartz定时任务持久化到数据库的开发。超详细,可用
- 随笔|数字电路分秒电子钟