状态机
1、状态机是许多数字系统的核心部件,是一类重要的时序逻辑电路。通常包括三个部分:一是下一个状态的逻辑电路,二是存储状态机当前状态的时序逻辑电路,三是输出组合逻辑电路。
2、根据状态机的输出信号是否与电路的输入有关分为Mealy型状态机和Moore型状态机。电路的输出信号不仅与电路当前状态有关,还与电路的输入有关,称为 Mealy 型状态机,而电路的输出仅仅与各触发器的状态,不受电路输入信号影响或无输入,称为
Moore 型状态机。
3、状态机的描述通常有三种方法,称为一段式状态机,二段式状态机和三段式状态机。状态机的描述通常包含以下四部分:
1)利用参数定义语句 parameter 描述状态机各个状态名称,即状态编码。状态编码通常有很多方法包含自然二进制编码,One-hot 编码,格雷编码码等;
2)用时序的 always 块描述状态触发器实现状态存储;
3)使用敏感表和 case 语句(也采用 if-else 等价语句)描述状态转换逻辑;
4)描述状态机的输出逻辑。
4、(1)一段式状态机
module detect_1( input clk_i, input rst_n_i, output out_o ); reg out_r; //状态声明和状态编码 reg [1:0] state; parameter [1:0] S0=2'b00; parameter [1:0] S1=2'b01; parameter [1:0] S2=2'b10; parameter [1:0] S3=2'b11; always@(posedge clk_i) begin if(!rst_n_i)begin state<=0; out_r<=1'b0; end else case(state) S0 : begin out_r<=1'b0; state<= S1; end S1 : begin out_r<=1'b1; state<= S2; end S2 : begin out_r<=1'b0; state<= S3; end S3 : begin out_r<=1'b1; end endcase end assign out_o=out_r; endmodule
一段式状态机是应该避免使用的,该写法仅仅适用于非常简单的状态机设计,不符合组
合逻辑与时序逻辑分开的原则,整个结构代码也不清晰,不利用维护和修改。
(2)两段式状态机
//状态声明和状态编码 reg [1:0] Current_state; reg [1:0] Next_state; parameter [1:0] S0=2'b00; parameter [1:0] S1=2'b01; parameter [1:0] S2=2'b10; parameter [1:0] S3=2'b11; //时序逻辑:描述状态转换 always@(posedge clk_i) begin if(!rst_n_i) Current_state<=0; else Current_state<=Next_state; end //组合逻辑:描述下一状态和输出 always@(*) begin out_r=1'b0; case(Current_state) S0 : begin out_r=1'b0; Next_state= S1; end S1 : begin out_r=1'b1; Next_state= S2; end S2 : begin out_r=1'b0; Next_state= S3; end S3 : begin out_r=1'b1; Next_state=Next_state; end endcase end assign out_o=out_r; endmodule
两段式状态机采用两个 always 模块实现状态机的功能,其中一个 always 采用同步时序逻辑描述状态转移,另一个 always 采用组合逻辑来判断状态条件转移。两段式状态机是推荐的状态机设计方法。
(3)三段式状态机
module detect_3( input clk_i, input rst_n_i, output out_o ); reg out_r; //状态声明和状态编码 reg [1:0] Current_state; reg [1:0] Next_state; parameter [1:0] S0=2'b00; parameter [1:0] S1=2'b01; parameter [1:0] S2=2'b10; parameter [1:0] S3=2'b11; //时序逻辑:描述状态转换 always@(posedge clk_i) begin if(!rst_n_i) Current_state<=0; else Current_state<=Next_state; end //组合逻辑:描述下一状态 always@(*) begin case(Current_state) S0: Next_state = S1; S1: Next_state = S2; S2: Next_state = S3; S3: begin Next_state = Next_state; end default : Next_state = S0; endcase end //输出逻辑:让输出 out,经过寄存器 out_r 锁存后输出,消除毛刺 always@(posedge clk_i) begin if(!rst_n_i) out_r<=1'b0; else begin case(Current_state) S0,S2: out_r<=1'b0; S1,S3: out_r<=1'b1; default : out_r<=out_r; endcase end end assign out_o=out_r;
三段式状态机在第一个 always 模块采用同步时序逻辑方式描述状态转移,第二个always 模块采用组合逻辑方式描述状态转移规律,第三个 always 描述电路的输出。通常让输出信号经过寄存器缓存之后再输出,消除电路毛刺。这种状态机也是比较推崇的,主要是由于维护方便,组合逻辑与时序逻辑完全独立。
版权声明:本文为CSDN博主「herryone123」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/kenjianqi1647/article/details/79144945