zoukankan      html  css  js  c++  java
  • 简单三段式状态机实验3-Sequence Detect(序列检测)

    1、序列检测器的逻辑功能描述:序列检测指的就是将一个指定的序列从数字码流中识别出来。本例中,我们将设计一个"10010”序列的检测器。设x_in为数字码流输入,z_out为检出标记输出,高电平表示“发现指定序列”,低电平表示“没有发现指定序列”。

    2、本次试验的data stream是 18'b11_0010_0100_0010_0101,通过循环来给x_in进行赋值。其中还要考虑到重叠现象。

    3、重点是状态图的描绘,仅有当状态机跳到E状态时,z_out才置1,说明发现了指定序列。其实这个试验关键是怎么来描绘该状态机。第一次看到夏宇闻书上该例子时,脑子里马上想到头一个问题,就是他是如何画出该状态机的,这个过程没有讲,很纳闷,那会是刚看Verilog,很多不懂,于是就放下这个问题,只阅读了代码。然而此次去看该例子时,我只看了题目和他的状态机,代码就不用看了,觉得书上画的状态机有点啰嗦,就没仔细看,干脆自己画一个 ,画该状态机其实也很简单,先把所有状态全都列出来,先单向的把IDLE->A->B->C->D->E跳变条件写上,比如IDLE到A,是当输入x_in为1时才会调到A,这个很好确认的吧,然后在仔细针对每个状态为其它条件时该如何跳,比如B是在x_in为1时是到C的,那么就得好好考虑x_in为0时,状态该跳到哪儿,就这样一步一步的仔细推敲,完整的状态机很快就完成

    4、代码实现:

    sequence_detect.v

     1 module sequence_detect(
     2                         //input
     3                         clk,
     4                         rst_n,
     5                         x_in,
     6                         
     7                         //ouput
     8                         z_out
     9                         );
    10 /****************************************/
    11 input clk;
    12 input rst_n;
    13 input x_in;
    14 output z_out;
    15 /****************************************/
    16 parameter IDLE = 3'd0;
    17 parameter A    = 3'd1;
    18 parameter B    = 3'd2;
    19 parameter C    = 3'd3;
    20 parameter D    = 3'd4;
    21 parameter E    = 3'd5;
    22 /****************************************/
    23 reg [2:0] crt_state,nxt_state;
    24 always @(posedge clk or negedge rst_n)
    25 begin
    26     if(!rst_n)
    27         crt_state <= IDLE;
    28     else
    29         crt_state <= nxt_state;
    30 end
    31 /****************************************/
    32 always @(*)
    33 begin
    34     case(crt_state)
    35         IDLE: if(x_in) nxt_state = A;
    36               else nxt_state = IDLE;
    37               
    38         A   : if(!x_in) nxt_state = B;
    39               else nxt_state = A;
    40               
    41         B   : if(!x_in) nxt_state = C;
    42               else nxt_state = A;
    43               
    44         C   : if(x_in) nxt_state = D;
    45               else nxt_state = IDLE;
    46         
    47         D   : if(!x_in) nxt_state = E;
    48               else nxt_state = A;
    49         
    50         E   : if(!x_in) nxt_state = C;
    51               else nxt_state = A;
    52         
    53         default: nxt_state = IDLE;
    54     endcase
    55 end
    56 /****************************************/
    57 reg z_out_temp;
    58 always @(posedge clk or negedge rst_n)
    59 begin
    60     if(!rst_n)
    61         z_out_temp <= 1'b0;
    62     else case(nxt_state)
    63             IDLE   : z_out_temp <= 1'b0;
    64             A      : z_out_temp <= 1'b0;
    65             B      : z_out_temp <= 1'b0;
    66             C      : z_out_temp <= 1'b0;
    67             D      : z_out_temp <= 1'b0;
    68             E      : z_out_temp <= 1'b1;
    69             default: z_out_temp <= 1'b0;
    70         endcase
    71 end
    72 /****************************************/
    73 assign z_out = z_out_temp;
    74 /****************************************/
    75 endmodule

    sequence_detect_top.v

     1 `timescale 1ns / 10ps
     2 module sequence_detect_top;
     3 reg clk;
     4 reg rst_n;
     5 reg [17:0] data;
     6 wire x_in;
     7 wire z_out;
     8 /***********************************************************/
     9 initial
    10 begin
    11     clk = 1'b0;
    12     rst_n = 1'b0;
    13     #100;
    14     rst_n = 1'b1;
    15 end
    16 /***********************************************************/
    17 always #10 clk = ~clk;
    18 /***********************************************************/
    19 always @(posedge clk or negedge rst_n)
    20 begin
    21     if(!rst_n)
    22         data <= 18'b11_0010_0100_0010_0101;
    23     else
    24         data <= {data[16:0],data[17]};
    25 end
    26 /***********************************************************/
    27 assign x_in = data[17];
    28 /***********************************************************/
    29 sequence_detect  sequence_detect_inst(
    30                                         //input
    31                                         .clk(clk),
    32                                         .rst_n(rst_n),
    33                                         .x_in(x_in),
    34                                        
    35                                         //ouput
    36                                         .z_out(z_out)
    37                                      );
    38 /***********************************************************/
    39 endmodule

    5、仿真波形:

    仅当crt_state在E状态(5)时,z_out置1。通过波形可以看到,输出是正确的。

  • 相关阅读:
    SQL 数据库 复制 与订阅 实现数据同步
    SQL 2008配置管理工具服务显示 远程过程调用失败0x800706be
    SQL2005中使用identity_insert向自动增量字段中写入内
    【树莓派】【转载】基于树莓派,制作家庭媒体中心+下载机
    Linux 按时间批量删除文件(删除N天前文件)
    【树莓派】为树莓派配置或扩展swap分区
    开源硬件相关平台
    【树莓派】树莓派上刷android系统
    【树莓派】树莓派上面安装配置teamviewer
    【树莓派】使用xdrp远程登录树莓派的图形界面
  • 原文地址:https://www.cnblogs.com/wen2376/p/3461798.html
Copyright © 2011-2022 走看看