状态机-阶段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 综合出来的状态图:

 

转移条件:

 

posted @ 2022-03-23 09:26  MyBooks  阅读(127)  评论(0)    收藏  举报