状态机fsm_有限状态机

以序列检测器为例讲解有限状态机的编写

  一、根据信号产生方法不同,分为米里型和摩尔型

da9313e38f6872bfb501d87ccfd03599.png

米里型

ce09bacc1c96d1de524a8ba4bdaa5e9c.png

摩尔型

  米里型的输出不仅与当前状态有关,也随输入信号的变化立即变化,而摩尔型的输出只随时钟边沿变化。

  二、状态机的编写过程:

1. 画状态转移图(找准输入,当前状态下某一输入所导致的状态转移,每一个状态的组合逻辑输出)

2. 对多余状态的处理(不可能出现的状态),全部转移到可能出现的状态,注意复位信号

3. 写测试代码

  三、状态机编码:

  最好选用格雷码和one-hot码

  格雷码选用原因:格雷码表示的相邻的两个数字之间跳转时只有一位发生变化。提高电路的稳定性,减少毛刺的产生和减少功耗

   格雷码组成规律:随数字增长,每个数第一位为0110循环,第二位为00111100循环,第三位为0000111111110000增长,以此类推。

d4b815efe06cc59fa71dbb4085062e13.png

  One-hot码组成规律:有n个状态就用n位二进制表示,所有位中只有一位为1,其他为0。例如四个状态:s0=0001,s1=0010,s2=0100,s3=1000。

  One-hot码选用原因:没有组合逻辑,电路速度非常快,可靠性高,从组成规律可以看出其实就是移位寄存器。

  格雷码与二进制码的转换

 (1)二进制码转换成格雷码

  从最右边第一位开始,依次将每一位与左邻一位异或(XOR),作为对应格雷码该位的值,最左边一位不变。

 (2)格雷码转换成二进制码

  从左边第二位起,将每位与左边一位解码后的值异或(XOR),作为该位解码后的值(最左边一位依然不变)。

  四、序列检测器:检测序列10110

  1、序列检测10110,最重要的问题是为什么我们选择8个状态,当数据进入序列检测器的时候,只要有一个数字破坏了10110这一序列的顺序(比如我们检测到101,结果下一个是0,不是1,我们就要重新开始)我们就要重新开始测,基于这一思想,假设状态数的位数是M,则2^M>待检测序列的数>

2^(M-1)。

   2、状态编码利用格雷码和one hot 编码,状态机相邻状态只有一个比特位有变化,减少电路中毛刺的产生。

  3、状态机编写(单过程描述方式),注意状态的跳转以及各个状态所对应的组合逻辑的输出,最后就是多余状态的处理

a5303af6de95b3096a42ac1e59cb57c3.png

状态转移图

 1module seqdetector(clk,clr,met,rst);
2 parameter s0= 3'b000,//表示初始状态
3           s1= 3'b001,//捕捉到数据1'b1 
4           s2= 3'b011,//捕捉到数据2'b10 
5           s3= 3'b010,//捕捉到数据3'b101 
6           s4= 3'b110,//捕捉到数据4'b1011 
7           s5= 3'b111,//捕捉到数据5'b10110 
8           s6= 3'b101,//多余状态
9           s7= 3'b100;//多余状态
10           //格雷码编码
11 input clk,clr,rst;
12 output met;
13 reg met;
14 reg[2:0] state;
15 always @(posedge clk,posedge rst)//异步复位,同步复位则为:always @(posedge clk)
16 begin
17     if(rst==1'b1) begin state=s0; end18     else19     begin20         case(state)21         s0: if(clr) begin state<=s1; met=1'b0;  end//state<=s1表示下一状态为s1
22             else begin state<=s0; met=1'b0;  end//met=1'b0表示在此状态下,23                                                 //状态机组合逻辑应该输出1'b0
24         s1: if(clr) begin state<=s1; met=1'b0;  end
25             else begin state<=s2; met=1'b0;  end
26
27         s2: if(clr) begin state<=s3; met=1'b0;  end
28             else begin state<=s0; met=1'b0;  end
29
30         s3: if(clr) begin state<=s4; met=1'b0;  end
31             else begin state<=s0; met=1'b0;  end
32
33         s4: if(clr) begin state<=s1; met=1'b0;  end
34             else begin state<=s5; met=1'b0;  end
35
36         s5: if(clr) begin state<=s1; met=1'b1;  end
37             else begin state<=s0; met=1'b1;  end
38          /*39         s6: if(clr) begin state<=s1; met=1'b0;  end40             else begin state<=s0; met=1'b0;  end4142         s7: if(clr) begin state<=s1; met=1'b0;  end43             else begin state<=s0; met=1'b0;  end         44          */
45          default:if(clr) begin state<=s1; met=1'b0;  end
46             else begin state<=s0; met=1'b0;  end//上面注释部分可与default部分相互替换
47            //若检测到序列不满足10110,则根据接收到的状态跳转到s0和s1,
48            //接收到0则跳转到s0,接收到1则跳转到s1。
49
50         endcase
51     end
52
53
54 end
55
56
57
58endmodule

代码

 1`timescale 1ns/1ps
2module seqdetector_tb;
3 reg clk_t,rst_t,clr_t;
4 wire met_t;
5 seqdetector sd(.clk(clk_t),
6             .clr(clr_t),
7             .met(met_t),
8             .rst(rst_t));
9   initial
10   begin
11       clk_t=1'b0;rst_t=1'b0;
12       #1;clr_t=1'b0;
13       #3;rst_t=1'b1;
14       #3;rst_t=1'b0;//记得复位信号要回到0,否则状态机一直被复位
15       #1000;$stop;
16   end
17       always #5 clk_t=~clk_t;
18       always #10 clr_t={$random} %2;//随机产生0和1的序列
19endmodule

测试代码

bee974c414a6c106fa6d0c460f42bab6.png

仿真结果

f88ba207ceed2508c6ee53a47d67c988.png

  来看看组合逻辑输出为1的细节部分

细节一

6e18fd8b68d93bf1428b425fcf3f9f27.png

细节二

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值