FPGA 序列检测器(上篇)—— 使用摩尔状态机实现

前几天参加了一场面试,选择题净是关于实际开发的关键知识,对于没有项目经验的我而言,完全不知所云。在看不到成功的希望的同时,最后的序列检测本应该是手到擒拿,结果以翻车结束。这里吃一堑长一智,避免下次出现类似的悲剧。

题目是检测序列 11001,使用三段时状态机:

这里约定以下信号,

  1. 时钟                    clk
  2. 复位(低电平有效)            rst_n
  3. 数据输入                    dat_in
  4. 检测结果输出(检测到了就置位)    check
  5. 启动信号                    go

这里约定使用摩尔状态机,米里机的在下一章:

检测方式,遇到这样包含重复序列的信号的话就直接忽略后面的序列(xxxx110011001xxx)

首先是检测表(姑且就这么叫吧),数学上叫二叉树、二叉表,但是我呢,比较任性。

Start

                                                             

0

1

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

00

01

10

11

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

000

001

010

011

100

101

110

111

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

0000

0001

0010

0011

0100

0101

0110

0111

1000

1001

1010

1011

1100

1101

1110

1111

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

00000

00001

00010

00011

00100

00101

00110

00111

01000

01001

01010

01011

01100

01101

01110

01111

10000

10001

10010

10011

10100

10101

10110

10111

11000

11001

11010

11011

11100

11101

11110

11111

这个表很重要,它展示了信息分类的结果,每一步都只有两个选择,在表中红色的表示正确的序列,黄色的表示还可以继续检测的序列,而黑色的表示必须回到开始的序列。

在这个表中,存在很多判断结构,比如第四行第八列的值为 111,它包含两个正确的 11,状态机应该回到上一步。

这里约定状态

    Start:    初始状态,go 信号置位,进入状态 S0

    S0:    有零个正确值 ,

    S1:    有一个正确值 11

    S2:    有两个正确值 11

    S3:    有三个正确值 110

    S4:    有四个正确值 1100

    S5:    有五个正确值 11001

状态转移图如下:

状态机的输出就比较简单了,摩尔机的输出只与现态有关:

仅仅状态 S5 的时候输出 1,其他情况输出 0。

Word 写文件多好,面试非要用笔,本来期望答案写的像小学语文作业,结果弄的像医生的处方一样。

开始经典的三段式状态机:

代码如下:

仿真结果如下:

    

时序报告:

可以看到,这个三段式状态机大概能跑 730MHz,似乎速度还不错。

较高的速度也拜良好的编码习惯所赐。

下一章描述米里状态机。毕竟知识也需要经常温习,避免忘记。

原文地址:https://www.cnblogs.com/SummerSunnyDay/p/14470970.html