• 状态机阶段1 练习1


     题目:

     序列检测状态机图:

     

     注意:收到1001001时,只能算检测到一组

    初始状态是S0,若当din = 1 时,跳转到S1; 若 din = 0 时,不跳转,保持原状态;

    在S1状态时:若当din = 0 时,跳转到 S2 ; 若 din = 1 时,不跳转,保持原状态;

    在S2状态时:若当din = 0 时,跳转到 S3 ; 若 din = 1 时,跳转到S1;

    在S3状态时:din前面已经收到了100了,此时在S3状态时,若din 收到了1 ,就成功检测到了1001 序列,此时也要跳转到S0,便有后续重新检测下一轮序列;若din  = 0 时,跳转到S0,重新开始检测下一个序列。

    也就是说,当在S3状态时,不管din收到0还是1,都要跳转到S0,产生dout条件是 在S3状态且,din = 1。

    画状态时,先画出能够明确跳转到下一个状态和条件,然后再考虑不跳转或跳回原上一个状态等。

    代码:

      1 module state_test(
      2                     clk,
      3                     rst_n,
      4                     din,
      5                     dout
      6 );
      7 
      8 parameter     S0 = 3'b000;
      9 parameter     S1 = 3'b001;
     10 parameter     S2 = 3'b010;
     11 parameter     S3 = 3'b100;
     12 
     13 input         clk;
     14 input        rst_n;
     15 input        din;
     16 
     17 output        dout;
     18 
     19 reg         dout;
     20 
     21 wire        S02S1_start;
     22 wire        S12S2_start;
     23 wire        S22S3_start;
     24 wire        S22S1_start;
     25 wire        S32S0_start;
     26 
     27 reg[4-1:0]     state_c;
     28 reg[4-1:0]     state_n;
     29 
     30 //第一段,状态跳转
     31 always @(posedge clk or negedge rst_n)begin
     32     if(!rst_n)begin
     33         state_c <= S0;
     34     end
     35     else begin
     36         state_c <= state_n; //将下一个状态赋给当前状态
     37     end
     38 end
     39 
     40 //第二段:组合逻辑always模块,描述状态转移条件判断
     41 always @(*)begin
     42     case(state_c)
     43     
     44     S0:begin
     45         if(S02S1_start)begin
     46             state_n = S1;
     47         end
     48         else begin
     49             state_n = state_c;
     50         end
     51     end
     52     
     53     S1:begin
     54         if(S12S2_start)begin
     55             state_n = S2;
     56         end
     57         else begin
     58             state_n = state_c;
     59         end
     60     end
     61     
     62     S2:begin
     63         if(S22S3_start)begin
     64             state_n = S3;
     65         end
     66         else if(S22S1_start)begin
     67             state_n = S1;
     68         end
     69         else begin
     70             state_n = state_c;
     71         end
     72     end
     73     
     74     S3:begin
     75         if(S32S0_start)begin
     76             state_n = S0;
     77         end
     78         else begin
     79             state_n = state_c;
     80         end
     81     end
     82     
     83     default : begin
     84                 state_n = S0;
     85     end
     86     endcase
     87 end
     88 
     89 //第三段:设计转移条件
     90 assign S02S1_start = state_c == S0 && din == 1;
     91 assign S12S2_start = state_c == S1 && din == 0;
     92 assign S22S3_start = state_c == S2 && din == 0;
     93 assign S22S1_start = state_c == S2 && din == 1;
     94 assign S32S0_start = state_c == S3 && (din == 0 || din == 1); //注意优先级,需将后面的或运算符用括号括起来
     95 
     96 //第四段:同步时序always模块,格式化描述寄存器输出(可有多个输出)
     97 always @(posedge clk or negedge rst_n) begin
     98     if(!rst_n)begin
     99         dout <= 0;
    100     end
    101     else if(state_c == S3 && din == 1)begin // S32S0_star && din == 1
    102         dout <= 1;
    103     end
    104     else begin
    105         dout <= 0;
    106     end
    107 end
    108 
    109 endmodule 

    测试代码:

     1 module state_sim;
     2 
     3 reg     clk;
     4 reg     rst_n;
     5 reg     din;
     6 
     7 wire     dout;
     8 
     9 parameter    CLK_CYCLE = 10;
    10 
    11 initial begin
    12         clk = 0;
    13         forever begin
    14             #(CLK_CYCLE/2);
    15             clk = ~clk;
    16         end
    17 end
    18 
    19 initial begin
    20         rst_n = 0;
    21         #1;
    22         #(CLK_CYCLE*5);
    23         rst_n = 1;
    24 end
    25 
    26 initial begin
    27         #1;
    28         din = 0;
    29         #(CLK_CYCLE*10);
    30         din = 1;
    31         #(CLK_CYCLE);
    32         
    33         din = 0;
    34         #(CLK_CYCLE);
    35         
    36         din = 0;
    37         #(CLK_CYCLE);
    38         
    39         din = 1;
    40         #(CLK_CYCLE);
    41         
    42         din = 0;
    43         #(CLK_CYCLE);
    44         
    45         din = 0;
    46         #(CLK_CYCLE);
    47         
    48         din = 1;
    49         #(CLK_CYCLE);
    50         
    51         repeat(100)begin
    52             din = $urandom_range(0,1);
    53             #(CLK_CYCLE);
    54         end
    55 end
    56 
    57 state_test u1_inist(
    58                     .clk(clk),
    59                     .rst_n(rst_n),
    60                     .din(din),
    61                     .dout(dout)
    62                 );
    63 
    64 endmodule

    仿真波形:

    quartus 综合出来的状态图:

    转移条件:

  • 相关阅读:
    《面向对象》读书笔记4
    《面向对象》读书笔记3
    《面向对象》读书笔记2
    《面向对象》读书笔记1
    B树
    树的子结构
    最长公共子序列
    最长公共子串
    堆和堆排序
    位图的原理和简单实现
  • 原文地址:https://www.cnblogs.com/wen2376/p/16042945.html
Copyright © 2020-2023  润新知