Moore型状态机和Mealy型状态机

  一、状态机的定义

    状态机就是能够根据控制信号按照预先设定的状态进行状态转移,是协调相关信号动作、完成特定动作的控制中心。状态机简写为 FSM (Finite  State  Machine),分为两类:

    1:输出只和当前状态有关而与输入无关,则称为摩尔(Moore)状态机;

    2:输出不仅和当前状态有关而且和输入有关,则称为米利(Mealy)状态机;

  二、两种状态机的区别

    1:在波形上区别:以一个序列检测器为例,检测到输入信号11时输出z为1,其他时候为0。用摩尔型FSM实现需要用到三个状态(A,B,C)。而用米利型FSM实现则需要两个状态(A,B)。摩尔型FSM输出函数的输入只由状态变量决定,要想输出z=1,必须C状态形成,即寄存器中的两个1都打进去后才可以。输出z=1会在下一个有效沿到来的时候被赋值。而米利型FSM输出函数是由输入和状态变量共同决定的。状态在B的时候如果输入为1,则直接以组合电路输出z=1不需要等到下个有效沿到来。从而也就不需要第三个状态C。

    2:摩尔状态机更安全:输出在时钟边沿变化(总是在一个周期后)。在Mealy机器中,输入更改可能会在逻辑完成后立即导致输出更改, 当两台机器互连时出现大问题 ,如果不小心,可能会发生异步反馈

    3:Mealy状态机对输入的反应更快在相同的周期内反应 - 不需要等待时钟。在Moore机器中,可能需要更多逻辑来将状态解码为输出 - 在时钟边沿之后更多的门延迟。并非所有时序电路都可以使Mealy模型实现。 一些时序电路只能作为摩尔机器实现。

  三、经典三段式状态机模板

 1 reg        [:]            current_state           ;
 2 reg        [:]            next_state               ;    
 3 
 4 wire        [:0]            IDLE                    ;
 5 wire        [:0]            S0                ;
 6 wire        [:0]            S1                ;
 7 wire        [:0]            S2                ;
 8 
 9 //=============================================================================
10 //****************************     State Machine    *******************************
11 //=============================================================================
12     
13 always @(posedge sclk or negedge s_rst_n) begin
14     if(!s_rst_n)
15         current_state <= IDLE;
16     else
17         current_state <= next_state;
18 end
19 
20 always @(*) begin
21     next_state = IDLE;
22     case(current_state)
23         IDLE:begin
24             if(idle2s0 == 1'b1)
25                 next_state = S0;
26             else
27                 next_state = current_state;
28         end
29         
30         S0:begin
31             if(s02s1 == 1'b1)
32                 next_state = S1;
33             else
34                 next_state =current_state;
35         end
36         
37         S1:begin
38             if(s12s2 == 1'b1)
39                 next_state = S2;
40             else
41                 next_state = current_state;
42         end
43         
44         S2:begin
45             if(s22idle == 1'b1)
46                 next_state = IDLE;
47             else
48                 next_state = current_state;
49         end
50         
51         default:begin
52             next_state = IDLE;
53         end
54     endcase
55 end
56 
57 assign        idle2s0        =    current_state == IDLE    && 
58 assign        s02s1        =    current_state == S0            && 
59 assign        s12s2        =    current_state == S1            && 
60 assign        s22idle        =    current_state == S2        && 
61 
62 always @(posedge sclk or negedge s_rst_n) begin
63     if(!s_rst_n) begin
64 
65     end
66     else begin
67         case(next_state)
68             
69     end
70 end    
View Code

  四、摩尔型状态机

  1、举例说明摩尔型状态机,非重叠检测 1101  1101

  (1)状态转移图

  (2)Moore代码

 1 // *********************************************************************************
 2 // Project Name : state_test
 3 // Email            : 
 4 // Create Time   : 2020/06/25 20:20
 5 // Module Name : state_test
 6 // editor        : qing
 7 // Version        : Rev1.0.0
 8 // Description     : 非重叠检测的Mooer状态机 1101
 9 // *********************************************************************************
10 
11 module state_test(
12     input                    sclk                ,
13     input                    s_rst_n            ,
14         
15     input                    din                ,
16     output    reg            dout
17 );
18 
19 //========================================================================
20 // =========== Define Parameter and Internal signals =========== 
21 //========================================================================/
22 
23 reg            [4:0]        current_state            ;
24 reg            [4:0]        next_state                ;    
25 
26 parameter   S0           =        5'b00001            ;
27 parameter   S1          =        5'b00010        ;
28 parameter   S2          =        5'b00100        ;
29 parameter   S3          =        5'b01000        ;
30 parameter   S4                  =              5'b10000            ;
31 
32 //=============================================================================
33 //****************************     Main Code    *******************************
34 //=============================================================================
35     
36 always @(posedge sclk or negedge s_rst_n) begin
37     if(!s_rst_n)
38         current_state <= S0;
39     else
40         current_state <= next_state;
41 end
42 
43 always @(*) begin
44     next_state = S0;
45     case(current_state)
46         S0:begin
47             if(din == 1'b1)  // 1
48                 next_state = S1;
49             else
50                 next_state = current_state;  // 0
51         end
52         
53         S1:begin
54             if(din == 1'b1)
55                 next_state = S2; // 11
56             else 
57                 next_state = S0; // 10
58         end
59         
60         S2:begin
61             if(din == 1'b0)  // 110
62                 next_state = S3;
63             else
64                 next_state = current_state; // 111
65         end
66         
67         S3:begin
68             if(din == 1'b1)
69                 next_state = S4;  // 1101
70             else
71                 next_state = S0;  // 1100
72         end
73 
74         S4:begin
75             if(din == 1'b1)  // 1101 1
76                 next_state = S1;
77             else
78                 next_state = S0; // 1101 0
79         end
80         
81         default:begin
82             next_state = S0;
83         end
84     endcase
85 end
86 
87 always @(posedge sclk or negedge s_rst_n) begin
88     if(!s_rst_n) begin
89         dout <= 0;
90     end
91     else if(current_state == S4)
92         dout <= 1;
93     else
94         dout <= 0;
95 end
96 endmodule
View Code

  testbench

 1 // *********************************************************************************
 2 // Project Name  : state_test
 3 // Email             : 
 4 // Create Time    : 2020/06/25 06:25
 5 // Module Name  : state_test_tb
 6 // editor         : qing
 7 // Version         : Rev1.0.0
 8 // *********************************************************************************
 9 
10 `timescale    1ns/1ps
11 module state_test_tb;
12     reg            sclk            ;
13     reg            s_rst_n        ;
14     reg            din            ;
15     wire                dout            ;
16 
17 state_test state_test_inst(
18     .sclk        (sclk        )        ,
19     .s_rst_n    (s_rst_n    )        ,
20     .din        (din        )        ,
21     .dout        (dout    )
22 );
23 
24 initial
25     sclk = 1'b0;
26     always #10  sclk = ~sclk;
27 
28 initial
29     begin
30         #1;
31         din = 0;
32         s_rst_n = 1'b0;
33         #21;
34         s_rst_n = 1'b1;
35 
36         #51;
37 
38         din = 1;
39         #20;
40         din = 0;
41         #20;
42         din = 1;
43         #20;
44         din = 1;
45         #20;
46         din = 0;
47         #20;
48         din = 1;
49         #20;
50         din = 0;
51         #30;
52 
53         din = 1;
54         #20;
55         din = 0;
56         #20;
57         din = 1;
58         #20;
59         din = 1;
60         #20;
61         din = 0;
62         #20;
63         din = 1;
64         #20;
65         din = 0;
66         #30;    
67     end
68     
69 endmodule
70  
View Code

  2、举例说明摩尔型状态机,重叠检测 1101001

  (1)状态转移图

  (2)Moore代码

 1 // *********************************************************************************
 2 // Project Name : state_test
 3 // Email             : 
 4 // Create Time   : 2020/06/25 20:20
 5 // Module Name : state_test
 6 // editor        : qing
 7 // Version        : Rev1.0.0
 8 // Description     : 重叠检测的Mooer状态机 1101
 9 // *********************************************************************************
10 
11 module state_test(
12     input                    sclk                ,
13     input                    s_rst_n            ,
14         
15     input                    din                ,
16     output    reg            dout
17 );
18 
19 //========================================================================
20 // =========== Define Parameter and Internal signals =========== 
21 //========================================================================/
22 
23 reg            [4:0]        current_state            ;
24 reg            [4:0]        next_state                ;    
25 
26 parameter   S0           =        5'b00001            ;
27 parameter   S1          =        5'b00010        ;
28 parameter   S2          =        5'b00100        ;
29 parameter   S3          =        5'b01000        ;
30 parameter   S4                   =             5'b10000            ;
31 
32 //=============================================================================
33 //****************************     Main Code    *******************************
34 //=============================================================================
35     
36 always @(posedge sclk or negedge s_rst_n) begin
37     if(!s_rst_n)
38         current_state <= S0;
39     else
40         current_state <= next_state;
41 end
42 
43 always @(*) begin
44     next_state = S0;
45     case(current_state)
46         S0:begin
47             if(din == 1'b1)  // 1
48                 next_state = S1;
49             else
50                 next_state = current_state;  // 0
51         end
52         
53         S1:begin
54             if(din == 1'b1)
55                 next_state = S2; // 11
56             else 
57                 next_state = S0; // 10
58         end
59         
60         S2:begin
61             if(din == 1'b0)  // 110
62                 next_state = S3;
63             else
64                 next_state = current_state; // 111
65         end
66         
67         S3:begin
68             if(din == 1'b1)
69                 next_state = S4;  // 1101
70             else
71                 next_state = S0;  // 1100
72         end
73 
74         S4:begin
75             if(din == 1'b1)  // 1101 1
76                 next_state = S2;
77             else
78                 next_state = S0; // 1101 0
79         end
80         
81         default:begin
82             next_state = S0;
83         end
84     endcase
85 end
86 
87 always @(posedge sclk or negedge s_rst_n) begin
88     if(!s_rst_n) begin
89         dout <= 0;
90     end
91     else if(current_state == S4)
92         dout <= 1;
93     else
94         dout <= 0;
95 end
96 endmodule
View Code

  testbench

 1 // *********************************************************************************
 2 // Project Name : state_test
 3 // Email        : 
 4 // Create Time  : 2020/06/25 06:25
 5 // Module Name  : state_test_tb
 6 // editor         : qing
 7 // Version         : Rev1.0.0
 8 // *********************************************************************************
 9 
10 `timescale    1ns/1ps
11 module state_test_tb;
12     reg            sclk            ;
13     reg            s_rst_n            ;
14     reg            din                ;
15     wire        dout            ;
16 
17 state_test state_test_inst(
18     .sclk        (sclk        )        ,
19     .s_rst_n    (s_rst_n    )        ,
20     .din        (din        )        ,
21     .dout        (dout        )
22 );
23 
24 initial
25     sclk = 1'b0;
26     always #10  sclk = ~sclk;
27 
28 initial
29     begin
30         #1;
31         din = 0;
32         s_rst_n = 1'b0;
33         #21;
34         s_rst_n = 1'b1;
35 
36         #51;
37 
38         din = 1;
39         #20;
40         din = 0;
41         #20;
42         din = 1;
43         #20;
44         din = 1;
45         #20;
46         din = 0;
47         #20;
48         din = 1;
49         #20;
50         din = 0;
51         #30;
52 
53         din = 1;
54         #20;
55         din = 0;
56         #20;
57         din = 1;
58         #20;
59         din = 1;
60         #20;
61         din = 0;
62         #20;
63         din = 1;
64         #20;
65         din = 0;
66         #30;    
67     end
68     
69 endmodule
View Code

  

  五、米利型状态机  1101序列检测

  1、状态转移图

   2、Mealy 代码

 1 // *********************************************************************************
 2 // Project Name : mealy_state
 3 // Email            : 
 4 // Create Time   : 2020/06/29 22:28
 5 // Module Name : 
 6 // editor        : Qing
 7 // Version        : Rev1.0.0
 8 // Description  : 米利型状态机 1101序列检测
 9 // *********************************************************************************
10 
11 module mealy_state(
12     input                sclk        ,
13     input                s_rst_n    ,
14 
15     input                din        ,
16     output    reg        dout
17     );
18 
19 //========================================================================
20 // =========== Define Parameter and Internal signals =========== 
21 //========================================================================/
22 
23 
24 reg            [3:0]            current_state    ;
25 reg            [3:0]            next_state        ;    
26 
27 parameter            IDLE        =    4'b0001    ;
28 parameter            S0        =    4'b0010    ;
29 parameter            S1        =    4'b0100    ;
30 parameter            S2        =    4'b1000    ;
31 
32 //=============================================================================
33 //****************************     State Machine    *******************************
34 //=============================================================================
35     
36 always @(posedge sclk or negedge s_rst_n) begin
37     if(!s_rst_n)
38         current_state <= IDLE;
39     else
40         current_state <= next_state;
41 end
42 
43 always @(*) begin
44     next_state = IDLE;
45     case(current_state)
46         IDLE:begin
47             if(din == 1'b1)
48                 next_state = S0;
49             else
50                 next_state = current_state;
51         end
52         
53         S0:begin
54             if(din == 1'b1)
55                 next_state = S1;
56             else 
57                 next_state = IDLE;
58         end
59         
60         S1:begin
61             if(din == 1'b0)
62                 next_state = S2;
63             else
64                 next_state = current_state;
65         end
66         
67         S2:begin
68             if(din == 1'b1)
69                 next_state = IDLE;
70             else 
71                 next_state = IDLE;
72         end
73         
74         default:begin
75             next_state = IDLE;
76         end
77     endcase
78 end
79 
80 always @(posedge sclk or negedge s_rst_n) begin
81     if(!s_rst_n) 
82         dout <= 1'b0;
83     else if(current_state == S2 && din == 1'b1)
84         dout <= 1'b1;
85     else
86         dout <= 1'b0;
87 end
88 
89 endmodule
View Code

   testbench:

 1 // *********************************************************************************
 2 // Project Name : mealy_state
 3 // Email        : 
 4 // Create Time  : 2020/06/29 23:06
 5 // Module Name  : mealy_state_tb
 6 // editor        : Qing
 7 // Version        : Rev1.0.0
 8 // *********************************************************************************
 9 
10 module mealy_state_tb;
11     reg            sclk        ;
12     reg            s_rst_n        ;
13     reg            din            ;
14     wire        dout        ;
15 
16 mealy_state mealy_state_inst(
17     .sclk        (sclk        ),
18     .s_rst_n    (s_rst_n    ),
19     .din        (din        ),
20     .dout        (dout        )
21     );
22 
23 initial
24     sclk = 1'b0;
25     always #10 sclk = ~sclk;
26 
27 initial
28     begin
29         #1;
30         din =1'b0;
31         s_rst_n = 1'b0;
32         #21;
33         s_rst_n = 1'b1;
34         #20;
35 
36         xulie;
37         #100;
38         xulie;
39         #100;
40         xulie;
41     end
42 
43 task xulie;
44     repeat(2)
45         begin
46             din = 1'b1;
47             #40;
48             din = 1'b0;
49             #20;
50             din = 1'b1;
51             #80;
52             din = 1'b1;
53             #30;
54             din = 1'b0;
55             #30;
56             din = 1'b1;
57             #100;
58         end
59 
60 endtask
61 
62 endmodule
View Code

  六、总结

  1、Moore状态机的输出是与时钟同步,Mealy状态机的输出是异步的,当输入发生变化时,输出就发生变化。

  2、Mealy状态机的输出比Moore状态机状态的输出提前一个周期;

  3、序列检测器可以用于检测一组或多组由二进制码组成的脉冲序列信号,当序列检测器连续收到一组串行二进制码后,如果这组码与检测器中预先设置的码相同,则输出 1 ,否则输出 0 。由于这种检测的关键在于正确码的接收是连续的,这就要求检测器必须记住前一次的正确码及正确序列,直到在连续检测中所收到的每一位码都与预置数的对应码相同。在检测过程中,任何一位不相等都将回到初始状态重新开始检测。

  七、参考

  1:《搭建你的数字积木数字电路与逻辑设计》(Verilog HDL & Vivado版);

  2:https://blog.csdn.net/CrazyUncle/article/details/88830654

  八、附录

  1:米利型状态机 检测 1001

 1 // *********************************************************************************
 2 // Project Name : mealy_state
 3 // Email        : 
 4 // Create Time  : 2020/06/30 09:35
 5 // Module Name  : 
 6 // editor        : Qing
 7 // Version        : Rev1.0.0
 8 // Description  : 米利型状态机 1001序列检测
 9 // *********************************************************************************
10 
11 module mealy_state(
12     input                sclk        ,
13     input                s_rst_n        ,
14 
15     input                din            ,
16     output    reg            dout
17     );
18 
19 //========================================================================
20 // =========== Define Parameter and Internal signals =========== 
21 //========================================================================/
22 
23 
24 reg            [3:0]            current_state    ;
25 reg            [3:0]            next_state        ;    
26 
27 parameter            IDLE        =    4'd0    ;
28 parameter            S0            =    4'd1    ;
29 parameter            S1            =    4'd2    ;
30 parameter            S2            =    4'd3    ;
31 
32 //=============================================================================
33 //****************************     State Machine    *******************************
34 //=============================================================================
35     
36 always @(posedge sclk or negedge s_rst_n) begin
37     if(!s_rst_n)
38         current_state <= IDLE;
39     else
40         current_state <= next_state;
41 end
42 
43 always @(*) begin
44     next_state = IDLE;
45     case(current_state)
46         IDLE:begin
47             if(din == 1'b1)
48                 next_state = S0;  // 1
49             else
50                 next_state = current_state;  // 0
51         end
52         
53         S0:begin
54             if(din == 1'b0)  // 10
55                 next_state = S1;
56             else 
57                 next_state = current_state; // 11
58         end
59         
60         S1:begin
61             if(din == 1'b0)
62                 next_state = S2; // 100
63             else
64                 next_state = S0; // 101
65         end
66         
67         S2:begin
68             if(din == 1'b1)
69                 next_state = S0;  // 1001
70             else 
71                 next_state = IDLE; // 1000
72 
73         end
74         
75         default:begin
76             next_state = IDLE;
77         end
78     endcase
79 end
80 
81 always @(posedge sclk or negedge s_rst_n) begin
82     if(!s_rst_n) 
83         dout <= 1'b0;
84     else if(current_state == S2 && din == 1'b1)
85         dout <= 1'b1;
86     else
87         dout <= 1'b0;
88 end
89 
90 endmodule
View Code

  testbench:

 1 // *********************************************************************************
 2 // Project Name : mealy_state
 3 // Email        : 
 4 // Create Time  : 2020/06/29 23:06
 5 // Module Name  : mealy_state_tb
 6 // editor        : Qing
 7 // Version        : Rev1.0.0
 8 // *********************************************************************************
 9 
10 module mealy_state_tb;
11     reg            sclk        ;
12     reg            s_rst_n        ;
13     reg            din            ;
14     wire        dout        ;
15 
16 mealy_state mealy_state_inst(
17     .sclk        (sclk        ),
18     .s_rst_n    (s_rst_n    ),
19     .din        (din        ),
20     .dout        (dout        )
21     );
22 
23 initial
24     sclk = 1'b0;
25     always #10 sclk = ~sclk;
26 
27 initial
28     begin
29         #1;
30         din =1'b0;
31         s_rst_n = 1'b0;
32         #21;
33         s_rst_n = 1'b1;
34         #20;
35 
36         xulie;
37         #100;
38         xulie;
39         #100;
40         xulie;
41     end
42 
43 task xulie;
44     repeat(2)
45         begin
46             din = 1'b1;
47             #40;
48             din = 1'b0;
49             #50;
50             din = 1'b1;
51             #50;
52             din = 1'b0;
53             #30;
54             din = 1'b1;
55             #100;
56         end
57 
58 endtask
59 
60 endmodule
View Code

   2:摩尔型状态机  无重叠检测 0110

  

   阅读不同的人写的代码,发现不同的描述方式都可以实现同一个功能,没有统一的解答过程,这让我感到迷惑。

   如有疏漏或不当之处,还望各位道友不吝指出~

  

  

  

原文地址:https://www.cnblogs.com/571328401-/p/13193815.html