‘10010’序列检测器的两种实现方法(有限状态机、移位寄存器)

文章来源:FPGA技术联盟

1、序列检测器?

序列检测器指的就是将一个指定的序列(以‘10010’为例)从数字码流中识别出来,是一个经典的数字电路实例。通常的序列检测方法有2种:有限状态机法(FSM);移位寄存器法。

       序列检测还分为重复检测和非重复检测。假设在输入码流“10010010”中进行重复检测,则会在检测到第一个“10010”和第二个“10010”后分别拉高输出表示成功检测;若非重复检测则只在检测到第一个“10010”拉高输出。

      接下来就几种情况分别进行说明并提供代码、仿真及仿真结果说明。

2、有限状态机法

      FSM(有限状态机)又可分为两种,根据状态机的输出是否与输入条件相关,可将状态机分为两大类,即摩尔(Moore)型状态机和米勒(Mealy) 型状态机。可参考FPGA状态机(一段式、二段式、三段式)、摩尔型(Moore)和米勒型(Mealy)

• Moore 状态机:组合逻辑的输出只取决于当前状态,而与输入状态无关。

• Mealy 状态机:输出不仅取决于当前状态,还取决于输入状态。

2.1、Moore 状态机

        先将状态转移图贴出:

1.png

• IDLE:初始状态,对输入的码流进行检测,若为1则跳转到状态A,则为0保留在该状态

• A:  对输入的码流进行检测,若为0则跳转到状态B(10),则为1保留在该状态

• B:  对输入的码流进行检测,若为0则跳转到状态C(100),则为1则跳转到状态A(101)

• C:  对输入的码流进行检测,若为1则跳转到状态D(1001),则为0则跳转到状态IDLE(1000)

• D:  对输入的码流进行检测,若为0则跳转到状态E(10010),则为1则跳转到状态A(10011)

• E:  此时已经成功检测到了序列”10010“,可以拉高输出。

   • 重复检测:然后对输入的码流进行检测,若为0则跳转到状态C(100_100,后面的100可视为新的一轮检测),则为1则跳转到状态A(10010_1)

   • 非重复检测:然后对输入的码流进行检测,若为0则跳转到状态IDLE(10010_0,后面的100不可视为新的一轮检测),则为1则跳转到状态A(10010_1)

2.1.1、Verilog 代码

      根据状态转移图可编写Verilog代码如下:需要注意的是,将是否进行重复检测设为了参数REPEAT,1--重复检测;0--非重复检测,提供程序复用性。

2.JPG

2.1.2、testbench

      在测试代码我们分别例化两个检测模块,一个用来检测重复输出,另一个用来检测非重复输出。

3.png

2.1.3、仿真结果

        仿真结果如下:

4.JPG

   可以看到重复检测的结果比非重复检测的结果还是多一些的,接下来选取几个典型的局部:

5.JPG

  上图中,成功检测到序列”10010“,因为后续输入不满足条件,所以不存在重复检测。检测到序列 ”10010“后系统进入状态E,在状态E拉高输出表示一次成功的检测,由于输出采用时序逻辑,输出会延迟一个时钟周期,所以总体看来,Moore状态机的输出要落后序列 ”10010“1个时钟周期。

        重复检测的结果如下:

6.JPG

 上图中,输入码流为”10010_010“,在重复检测模式中,后面的10010又组成了一次成功的序列输入,所以一共输出两次成功检测标志;而非重复检测标志则只输出一次成功检测标志。

2.2、Mealy 状态机

       Mealy 状态机的输出不仅取决于当前状态,还取决于输入状态。所以在检测到序列”1001“后,若下一个输入为0则会拉高输出;若下一个输入为1则无输出。据此可以画出状态转移图如下:

7.JPG

•  IDLE:初始状态,对输入的码流进行检测,若为1则跳转到状态A,则为0保留在该状态

•  A:对输入的码流进行检测,若为0则跳转到状态B(10),则为1保留在该状态

•  B:对输入的码流进行检测,若为0则跳转到状态C(100),则为1则跳转到状态A(101)

•  C:对输入的码流进行检测,若为1则跳转到状态D(1001),则为0则跳转到状态IDLE(1000)

•  D:对输入的码流进行检测,则为1则跳转到状态A(10011);若为0则成功检测到了序列”10010“,可以拉高输出。

重复检测:则跳转到状态E(100_10,后面的10可视为新的一轮检测)

非重复检测:则跳转到状态IDLE(10010_,开始新的一轮检测)

2.2.1、Verilog代码

       根据状态转移图可编写Verilog代码如下:需要注意的是,将是否进行重复检测设为了参数REPEAT,1--重复检测;0--非重复检测,提供程序复用性。

8.JPG

2.2.2、testbench

      在测试代码我们分别例化两个检测模块,一个用来检测重复输出,另一个用来检测非重复输出。

9.JPG

2.2.3、仿真结果

       仿真结果如下:

10.JPG

   可以看到重复检测的结果比非重复检测的结果还是多一些的,接下来选取几个典型的局部图:

11.JPG

 在检测到后1001后,接下来的输入为0构成10010所以立即输出成功检测标志。

        重复检测的结果如下:

12.JPG

 上图中,输入码流为”10010_010“,在重复检测模式中,后面的10010又组成了一次成功的序列输入,所以一共输出两次成功检测标志;而非重复检测标志则只输出一次成功检测标志。

3、移位寄存器法

3.1、说明

       移位寄存器法比较简单粗暴,直接使用一个5位的寄存器寄存每一个码流,并在下一个时钟周期对其移位,再与需要的结果(10010)进行对比,根据对比结果输出检测结果。

     非重复检测:最少都是码流”10010——10010“,那么两次成功输出会间隔最少5个时钟。所以我们可以设计一个计数器,当成功检测时将其清零,其他时候递加1。

     实际上重复检测的时候直接输出即可,而非重复检测则需要根据计数器的值进行判断。每次成功输出时需要判断此时计数器的值,若非重复检测则计数器的值应大于等于4(0-4共5个时钟)。

3.2、Verilog代码

      将是否进行重复检测设为了参数REPEAT,1--重复检测;0--非重复检测,编写Verilog代码如下:

13.JPG

3.3、 testbench

      在测试代码我们分别例化两个检测模块,一个用来检测重复输出,另一个用来检测非重复输出。基本和FSM的tb文件一致。

3.4、仿真结果

       仿真结果见下图:

14.JPG

  方框内都是进行了重复检测的部分,由于重复检测的逻辑比较简单,所以我们只截取重复部分的非重复检测的典型图:

15.JPG