集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 346|回复: 0

mealy状态机的输出不仅与当前状态值有关,而且与当前输入有关。 moore状态机的输出...

[复制链接]
dameihuaxia 发表于 2022-7-22 15:10:27 | 显示全部楼层 |阅读模式
mealy状态机的输出不仅与当前状态值有关,而且与当前输入有关。
moore状态机的输出仅与当前状态值有关,而与此时的输入无关

下面通过序列检测“1101”从右到左不重叠检测来详细说明这两种状态机的区别:
先规定一下状态机的状态转移图的表示,每个状态之间都有一个指向的箭头,表示跳转的过程,箭头上有标注的一组数据,斜杠(/)左边表达的是状态的输入,斜杠(/)右边表达的是状态的输出。

所以绘制状态转移图需要知道以下三个要素:
(1)输入:根据输入可以确定是否需要进行状态转移以及输出,是影响状态机系统执行过程的重要驱动力。
(2)输出:根据当前时刻的状态以及输出,是状态机系统最终要执行的动作。
(3)状态:根据输入和上一个状态决定当前时刻所处的状态,是状态机系统执行的一个稳定过。

根据这些抽象出的要素我们就可以绘制状态转移图了,首先我们根据分析的状态数先画出5个状态,如下图所示,每个状态我们取一个状态名(题目中有要求用S0, S1, S2, …标识):接收的到值为0的状态我们取名为S0,该状态也成为初始状态;
接收的到值为1的状态我们取名为S1;
接收的到值为10的状态我们取名为S2;
接收的到值为101的状态我们取名为S3;
接收的到值为1011的状态我们取名为S4。

从第一个S0状态开始分析,从初始状态开始进行跳转。如下图所示,在S0状态下有两种跳转情况:一种情况是输入为0,没有任何有用的序列值,状态继续维持在S0;另一种情况是输入为1,序列值变为1,状态跳转到S1。
接着分析S1状态跳转的情况。如下图所示,在S1状态下同样有两种跳转情况:一种情况是输入为0,序列值变为10,状态跳转到S2;另一种情况是输入为1,序列值变为11,状态还是继续维持在S1,相当于是之前输入的1被抛弃,新输入的1进入序列的检测。
继续分析S2状态跳转的情况。如下图所示,在S2状态下同样有两种跳转情况:一种情况是输入为0,此时序列变为100,所有的值都没用了,状态跳转到初始状态S0;另一种情况是输入为1,序列变为101,状态跳转到S2。
下面该分析S3状态跳转的情况了。如下图所示,在S3状态下依然也有两种跳转情况:一种情况是输入为0,此时序列变为1010,状态回到S2,相当于是之前输入的10被抛弃,新组合成的10进入序列的检测;另一种情况是输入为1,即在S3状态下的输入为1,此时的序列为1011,已经满足了我们题目中的序列检测的要求了,可以有输出了。

S4状态的存在是区分Moore和Mealy状态机的关键
按照上面5种状态的状态转移图来继续分析,S3状态下的第二种情况时虽然满足了1011的序列,但是我们先不输出,而是跳转到S4状态,再继续分析S4状态的跳转情况。如下图所示,在S4状态下依然也有两种跳转情况:一种情况是输入为0,序列变为10110,输出1表示检测到了1011序列,同时状态跳转到S0;另一种情况是输入为1,序列变为10111,也会输出1表示检测到了1011序列,但状态会跳转到S1,因为最后输入的1还可以进行下一次1011序列的检测。
如果最后的输出只和当前状态有关而与输入无关则称为moore型状态机:上图所表达的状态转移图就是moore型的,因为在S4状态下无论输入是0还是1都已经检测到了1011序列,都会有输出,显然和输入时无关的。
如果最后的输出不仅和当前状态有关还和输入有关则称为mealy状态机:上图所表达的状态转移图就是mealy型的

moore型状态机的RTL功能代码如下所示:

module moore_fsm(
        input sclk,
        input rst_n,
        input data_in,
        output reg data_out
);


//--------define parameter and interdace signals-----
parameter S0 = 5'b0_0001;
parameter S1 = 5'b0_0010;
parameter S2 = 5'b0_0100;
parameter S3 = 5'b0_1000;
parameter S4 = 5'b1_0000;


reg [4:0] current_state;
reg [4:0] next_state;

//---------main code---------------
//the first FSM
always @ (posedge sclk or negedge rst_n) begin
        if(!rst_n)
                current_state <= S0;
        else
                current_state <= next_state;
end

//the second FSM
always @ (*) begin
        case(current_state)
                S0 : if(data_in==1'b1)
                                        next_state <= S1;
                         else
                                        next_state <= S0;
                S1 : if(data_in==1'b0)
                                        next_state <= S2;
                         else
                                        next_state <= S1;
                S2 : if(data_in==1'b1)
                                        next_state <= S3;
                         else
                                        next_state <= S0;
                S3 : if(data_in==1'b1)
                                        next_state <= S4;
                         else
                                        next_state <= S2;
                S4 : if(data_in==1'b1)
                                        next_state <= S1;
                         else
                                        next_state <= S0;
                default : next_state <= S0;
        endcase
end

//the third FSM
always @ (posedge sclk or negedge rst_n) begin
        if(!rst_n)
                data_out <= 1'b0;
        else if(next_state==S4)
                data_out <= 1'b1;
        else
                data_out <= 1'b0;
end
endmodule



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67


mealy型状态机的RTL功能代码如下所示:

module  moore_fsm(
     input  wire   sys_clk    ,   //系统时钟50MHz
     input  wire   sys_rst_n  ,   //全局复位
     input   wire  data_in    ,   //外部输入的序列   
     output  reg   data_out      //检测到1011序列后的输出信号
);

//只有4种状态,使用独热码
parameter S0 =4'b0001;
parameter S1 =4'b0010;
parameter S2 =4'b0100;
parameter S3 =4'b1000;


reg [3:0] current_state;
reg [3:0] next_state;


always @ (posedge sys_clk or negedge sys_rst_n) begin
        if(!sys_rst_n)
                current_state <= S0;
        else
                current_state <= next_state;
end
always@(*) begin
     case(current_state)              
         S0      :   if(data_in ==1'b1)
                         next_state <= S1;
                     else
                         next_state <= S0;
        
         S1      :   if(data_in ==1'b0)
                         next_state <= S2;
                     else
                         next_state <= S1;
        
         S2      :   if(data_in ==1'b1)
                         next_state <= S3;
                     else
                         next_state <= S0;
        
         S3      :   if(data_in ==1'b1)
                         next_state <= S0;
                     else
                         next_state <= S2;
        
         default:     next_state <= S0;
    endcase

end

always@(posedge sys_clk  or negedge sys_rst_n) begin
     if(sys_rst_n ==   1'b0)
         data_out <=1'b0;
     else   if(current_state == S3 && data_in ==1'b1)
         data_out <=1'b1;
     else  
         data_out <=1'b0;
end
/*
reg[3:0] state;

//第一段状态机,描述当前状态state如何根据输入跳转到下一状态
always@(posedge sys_clk  or negedge sys_rst_n)   
     if(sys_rst_n ==   1'b0)
         state <= S0;
     else   case(state)              
                 S0      :   if(data_in ==1'b1)
                                 state <= S1;
                             else
                                 state <= S0;
               
                 S1      :   if(data_in ==1'b0)
                                 state <= S2;
                             else
                                 state <= S1;
               
                 S2      :   if(data_in ==1'b1)
                                 state <= S3;
                             else
                                 state <= S0;
               
                 S3      :   if(data_in ==1'b1)
                                 state <= S0;
                             else
                                 state <= S2;
               
                 default:     state <= S0;
             endcase

//第二段状态机,描述当前状态state和输入如何影响输出
always@(posedge sys_clk  or negedge sys_rst_n)   
     if(sys_rst_n ==   1'b0)
         data_out <=1'b0;
     else   if(state == S3 && data_in ==1'b1)
         data_out <=1'b1;
     else  
         data_out <=1'b0;
*/      
endmodule


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101





————————————————
版权声明:本文为CSDN博主「day day learn」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43727437/article/details/104654195
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|集成电路技术分享 ( 京ICP备20003123号-1 )

GMT+8, 2024-5-18 15:03 , Processed in 0.061457 second(s), 20 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表