基于FPGA的序列检测器设计(状态机)

1. 项目介绍

       序列检测器是一种能够检测输入的一串二进制代码的电路,当该二进制代码与事先设定的码组一致时,检测电路输出高电平,否则输出低电平。序列检测器多用于通信系统中对同步码的检测,或者是对所需信号的提取,这在数字通信领域中有着广泛的运用,如下图所示101序列检测器(可重叠)。

2. 设计要求

     采用状态机设计一个“1010110”序列检测器,其功能是检测到一个7位的二进制序列“1010110”,输出一个时钟周期的高脉冲,其他情况下为0。当遇到“…………1010110_10110……………..”时,后面的一个也认为满足检测要求。

3.  设计分析

       序列检测器检测的关键在于正确码的收到必须是连续的,这就要求检测器必须记住前一次的正确码及正确序列,直到在连续的检测中所收到的每一位码都与预置数的对应码相同。在检测过程中,任何一位不相同都将回到初始状态重新开始检测。

(1)系统架构图

系统端口及其意义

  • clk:系统时钟,50MHz;
  • rst_n: 系统复位信号,低电平有效;
  • idata: 串行输入信号
  • flag:当检测到 “1010110”,输出一个时钟周期的高脉冲,其他时刻为0;

(2)状态划分

       本系统采用状态机进行设计,将“1010110”序列检测过程划分为7个状态:

  • S0:        未检测到有效信号的状态;
  • S1:        检测到“1”信号;
  • S2:        检测到“10”信号;
  • S3:        检测到“101”信号;
  • S4:        检测到“1010”信号;
  • S5:         检测到“10101”信号;
  • S6:         检测到“101011”信号;

 

         这里当遇到“…………1010110_10110……………..”时,后面的一个也认为满足检测要求,前面出现的信号可重复使用,会出现一个时钟周期的高电平。

4. 设计实现

 1 module sequence1010110(
 2     input        wire                clk,
 3     input     wire                rst_n,
 4     input     wire                 idata,
 5     
 6     output     reg                flag
 7 );
 8 
 9     localparam             S0  = 7'b000_0001;
10     localparam             S1  = 7'b000_0010;
11     localparam             S2  = 7'b000_0100;
12     localparam             S3  = 7'b000_1000;
13     localparam             S4  = 7'b001_0000;
14     localparam             S5  = 7'b010_0000;
15     localparam             S6  = 7'b100_0000;
16     
17     reg             [6:0]        c_state;
18     reg             [6:0]        n_state;
19     
20     always@(posedge clk or negedge rst_n)begin
21         if(rst_n == 1'b0)
22             c_state <= S0;
23         else
24             c_state <= n_state;    
25     end
26     
27     always@(*)begin
28         case(c_state)
29             S0    : begin
30                     if(idata == 1'b1)
31                         n_state = S1;
32                     else
33                         n_state = S0;
34             end
35             
36             S1: begin
37                     if(idata == 1'b1)
38                         n_state = S1;
39                     else
40                         n_state = S2;
41             end
42             
43             S2: begin
44                     if(idata == 1'b1)
45                         n_state = S3;
46                     else
47                         n_state = S0;
48             end
49             
50             S3: begin
51                     if(idata == 1'b1)
52                         n_state = S1;
53                     else
54                         n_state = S4;
55             end
56             
57             S4: begin
58                     if(idata == 1'b1)
59                         n_state = S5;
60                     else
61                         n_state = S0;
62             end
63             
64             S5: begin
65                     if(idata == 1'b1)
66                         n_state = S6;
67                     else
68                         n_state = S4;
69             end
70             
71             S6: begin
72                     if(idata == 1'b1)
73                         n_state = S1;
74                     else
75                         n_state = S2;
76             end
77             
78             default : n_state = S0;
79         endcase
80     end
81     
82     always@(posedge clk or negedge rst_n)begin
83         if(rst_n == 1'b0)
84             flag <= 1'b0;
85         else
86             if((c_state == S6)&&(idata == 1'b0))
87                 flag <= 1'b1;
88             else
89                 flag <= 1'b0;
90     
91     end
92 
93 endmodule 

5. 仿真验证

 1 `timescale 1ns/1ps
 2 
 3 module sequence1010110_tb();
 4 
 5     reg                            clk;
 6     reg                            rst_n;
 7     reg                             idata;
 8     
 9     wire                            flag;
10     
11     reg             [15:0]        ascii_state;
12     wire             [6:0]            tb_state;
13     
14     assign tb_state = sequence1010110_inst.c_state;
15     
16     always@(*)begin
17         case(tb_state)
18             7'b000_0001    :    ascii_state = "S0";
19             7'b000_0010    :    ascii_state = "S1";
20             7'b000_0100    :    ascii_state = "S2";
21             7'b000_1000    :    ascii_state = "S3";
22             7'b001_0000    :    ascii_state = "S4";
23             7'b010_0000    :    ascii_state = "S5";
24             7'b100_0000    :    ascii_state = "S6";
25             default        :  ascii_state = "NO";
26         endcase
27     end
28 
29     sequence1010110 sequence1010110_inst(
30         .clk                    (clk),
31         .rst_n                (rst_n),
32         .idata                (idata),
33         
34         .flag                    (flag)
35     );
36 
37     initial clk = 1'b0;
38     always #10 clk = ~clk;
39     
40     initial begin
41         rst_n = 1'b0; idata = 1'b0;
42         #101;
43         rst_n = 1'b1;
44         #50;
45         repeat(100)begin
46             @(posedge clk); #2;
47             idata = {$random}%2;
48         end
49         
50         @(posedge clk); #2; idata = 1'b1;
51         @(posedge clk); #2; idata = 1'b0;
52         @(posedge clk); #2; idata = 1'b1;
53         @(posedge clk); #2; idata = 1'b0;
54         @(posedge clk); #2; idata = 1'b1;
55         @(posedge clk); #2; idata = 1'b1;
56         @(posedge clk); #2; idata = 1'b0;
57         @(posedge clk); #2; idata = 1'b1;
58         @(posedge clk); #2; idata = 1'b0;
59         @(posedge clk); #2; idata = 1'b1;
60         @(posedge clk); #2; idata = 1'b1;
61         @(posedge clk); #2; idata = 1'b0;
62         @(posedge clk); #2; idata = 1'b1;
63         @(posedge clk); #2; idata = 1'b1;
64         
65         #200; $stop;
66     end 
67     
68 endmodule 

6. 参考资料

(1)陪您一起学习FPGA-郝旭帅团队_哔哩哔哩_bilibili

posted @ 2021-08-06 22:41  豌豆茶  阅读(2492)  评论(0编辑  收藏  举报