打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
序列检测器

功能描述:

序列检测器就是将一个指定序列从数字码流中识别出来。本例中将设计一个“10010”序列的检测器。设X为数字码流的输入,Z为检测出标记输出,高电平表示发现指定的序列10010.考虑码流为110010010000100101....则,如表有:

用FSM实现

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
moduleseqdet
(
   inputwirex,
   inputwireclk,
   inputwirerst,
   outputwirez
);
  
reg[2:0] state;
  
localparam  IDLE = 3'd0,
            A    = 3'd1,
            B    = 3'd2,
            C    = 3'd3,
            D    = 3'd4,
            E    = 3'd5,
            F    = 3'd6,
            G    = 3'd7;
  
assignz = (state == D && x==0)?1'b1:1'b0;//状态为D时又收到输入0,表明10010已经收到,输出为1
  
always@ (posedgeclk,negedgerst)
   if(!rst)
      begin
          state <= IDLE;
      end
   else
      casex(state)
          IDLE:
             if(x==1)
                state <= A;  //状态A记住第一位正确高电平1来过
             else
                state <= IDLE;
          A:
             if(x==0)
                state <= B;  //状态B记住第二位正确低电平0来过
             else
                state <= A;
          B:
             if(x==0)
                state <= C;  //状态C记住第三位正确低电平0来过
             else
                state <= F; //输入高电平,不符合要求,F记住只有1位对过
          C:
             if(x==1)
                state <= D;  //状态D记住第四位正确高电平1来过
             else
                state <= G;  //输入低电平,不符合要求,G记住没有1为曾经对过
          D:
             if(x==0)
                state <= E;  //状态E记住第五位正确低电平0来过
             else
                state <= A; 
          E:
             if(x==0)
                state <= C; //用状态记住100正确来过
             else
                state <= A;
          F:
             if(x==1)
                state <= A;
             else
                state <= B;
          G:
             if(x==1)
                state <= F;
             else
                state <= B;
        default:
                state <=IDLE;
      endcase
  
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
`timescale1ns/1ns
moduleseqdet_tb;
localparamT =20;
regclk,rst;
reg[23:0] data;
wirez,x;
  
assignx = data[23];
  
initial
begin
    clk =0;
    rst =1;
    #2 rst =0;
    #30 rst =1;
    data =20'b1100_1001_0000_1001_0100;
    #(T*1000) $stop;
end
  
always#T clk = ~clk;
  
always@ (posedgeclk)
   #2 data = {data[22:0],data[23]};
     
seqdet U1
(
   .x(x),
   .z(z),
   .clk(clk),
   .rst(rst)
);
  
endmodule

用移位寄存器实现检测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
moduleseqdet
(
   inputwirex,
   inputwireclk,
   inputwirerst,
   outputwirez,
   outputreg[4:0] q
);
  
//reg [4:0] q;
  
assignz = (q == 5'b10010) ? 1'b1:1'b0;
  
always@ (posedgeclk,negedgerst)
   if(!rst)
      q <= 5'd0;
   else
      q <= {q[3:0],x};
  
endmodule

RTL级视图:

测试文件:

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
`timescale1ns/1ns
moduleseqdet_tb;
localparamT =20;
regclk,rst;
reg[23:0] data;
wirez,x;
wire[4:0] q;
  
assignx = data[23];
  
initial
begin
    clk =0;
    rst =1;
    #2 rst =0;
    #30 rst =1;
    data =20'b1100_1001_0000_1001_0100;
    #(T*1000) $stop;
end
  
always#T clk = ~clk;
  
always@ (posedgeclk)
   #2 data = {data[22:0],data[23]};
     
seqdet U1
(
   .x(x),
   .z(z),
   .clk(clk),
   .q(q),
   .rst(rst)
);
  
endmodule

仿真结果:

NOTE:

由于移位寄存器的赋值是在always块中,故而相对实际延迟了一个clk.

由上面的方针结果可知,输出z相对x晚了一个时钟周期,因为由于移位寄存器的赋值是在always块中,故而相对实际延迟了一个clk.

代码修改如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
moduleseqdet
(
   inputwirex,
   inputwireclk,
   inputwirerst,
   outputwirez,
   outputreg[4:0] q
);
  
wire[4:0] q_next;
  
assignq_next ={q[3:0],x};
assignz = (q_next== 5'b10010) ? 1'b1:1'b0;
  
always@ (posedgeclk,negedgerst)
   if(!rst)
      q <= 5'd0;
   else
      q <= q_next;
  
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
moduleseqdet
(
   inputwirex,
   inputwireclk,
   inputwirerst_n,
   outputwirez
);
//用verilog设计一个 10010 序列的检测器
reg[4:0] cs,ns;
localparam[4:0]    IDLE    =5'd0,
                          A     =5'd1,
                          B     =5'd2,
                          C     =5'd3,
                          D     =5'd4,
                          E     =5'd5;
//状态转移
always@ (posedgeclk,negedgerst_n)
    if(!rst_n)
        cs  <= IDLE;
    else
        cs <= ns;
//组合逻辑,产生下一状态译码逻辑
always@ (*)
begin
    ns = 5'bx;
    case(cs)
        IDLE:
            begin
                if(x==1)
                    ns = A;
                else
                    ns = IDLE;
            end
        A:
            begin
                if(x==0)
                    ns = B;
                else
                    ns = A;
            end
        B:
            begin
                if(x==0)
                    ns = C;
                else
                    ns = A;
            end
        C:
            begin
                if(x==1)
                    ns = D;
                else
                    ns = IDLE;
            end
        D:
            begin
                if(x==0)
                    ns = E;
                else
                    ns = A;
            end
        E:
            begin
                if(x==0)
                    ns = C;
                else
                    ns = A;
            end
        default:
            ns = IDLE;
    endcase
end
//状态寄存输出
/*
always @ (posedge clk,negedge rst_n)
begin
    if(!rst_n)
        z <= 1'b0;
    else
        begin
        case(ns)
            IDLE,A,B,C,D:   z <= 1'b0;
            E               :   z <= 1'b1;
            default:    z <= 1'b0;
        endcase
        end
end
*/
  
//状态为D时又收到输入0,表明10010已经收到,输出为1  
//assign z = (cs == D && x==0)?1'b1:1'b0;
assignz = (ns==E);
  
endmodule

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
【FPGA系列】五分钟教会你设计一个流水灯
Verilog 及Xilinx_FPGA入门(一)
异步与同步清零Verilog hdl表达程序
一天一个设计实例-静态随机存储器 SRAM 的 Verilog HDL/VHDL语言描述
零基础学FPGA(八)浅谈状态机
【精品博文】串口接收模块电路设计
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服