状态机-阶段1 练习3

题目:

 

画出状态图:

 

dout 输出条件:

注意:在S3状态时,已收到了1.5元,所以不管后面收到1元还是0.5元都跳回S0,并找零钱(0元或0.5元),所以不需要在单独设立一个状态 S4(2元)。

 代码:

  1 //售货机
  2 module state_test(
  3                     clk,
  4                     rst_n,
  5                     din_vld,
  6                     din,
  7                     dout
  8 );
  9 
 10 parameter    S0 = 0;
 11 parameter    S1 = 1;
 12 parameter    S2 = 2;
 13 parameter    S3 = 3;
 14 
 15 input         clk        ;
 16 input         rst_n    ;
 17 input        din_vld ;
 18 input         din        ;
 19 output        dout    ;
 20     
 21 reg            dout    ;
 22 reg [3-1:0]    state_c    ;
 23 reg [3-1:0]    state_n    ;
 24 
 25 wire        S02S1_start;
 26 wire        S02S2_start;
 27 wire        S12S2_start;
 28 wire        S12S3_start;
 29 wire        S22S0_start;
 30 wire        S22S3_start;
 31 wire        S32S0_start;
 32 
 33 
 34 //第一段,状态跳转
 35 always @(posedge clk or negedge rst_n)begin
 36     if(!rst_n)begin
 37         state_c <= S0;
 38     end
 39     else begin
 40         state_c <= state_n;
 41     end
 42 end
 43 
 44 //第二段:组合逻辑always模块,描述状态转移条件判断
 45 always @(*)begin
 46     case(state_c)
 47         S0:begin
 48             if(S02S1_start)begin
 49                 state_n = S1;
 50             end
 51             else if(S02S2_start) begin
 52                 state_n = S2;
 53             end
 54             else begin
 55                 state_n = state_c;
 56             end
 57         end
 58         
 59         S1:begin
 60             if(S12S2_start)begin
 61                 state_n = S2;
 62             end
 63             else if(S12S3_start)begin
 64                 state_n = S3;
 65             end
 66             else begin
 67                 state_n = state_c;
 68             end
 69         end
 70         
 71         S2:begin
 72             if(S22S3_start)begin
 73                 state_n = S3;
 74             end
 75             else if(S22S0_start)begin
 76                 state_n = S0;
 77             end
 78             else begin
 79                 state_n = state_c;
 80             end
 81         end
 82         
 83         S3:begin
 84             if(S32S0_start)begin
 85                 state_n = S0;
 86             end
 87             else begin
 88                 state_n = state_c;
 89             end
 90         end
 91         
 92         default:begin
 93             state_n = S0;
 94         end
 95     endcase
 96 end
 97 
 98 //第三段:设计转移条件
 99 assign S02S1_start = state_c == S0 && din_vld && din == 0;
100 assign S02S2_start = state_c == S0 && din_vld && din == 1;
101 
102 assign S12S2_start = state_c == S1 && din_vld && din == 0;
103 assign S12S3_start = state_c == S1 && din_vld && din == 1;
104 
105 assign S22S0_start = state_c == S2 && din_vld && din == 1;
106 assign S22S3_start = state_c == S2 && din_vld && din == 0;
107 
108 assign S32S0_start = state_c == S3 && din_vld && (din == 0 || din == 1);
109 
110 
111 //第四段,设计输出
112 always @(posedge clk or negedge rst_n)begin
113     if(!rst_n)begin
114         dout <= 0; 
115     end
116     else if(state_c == S3 && din_vld == 1 && din == 1)begin
117         dout <= 1;
118     end
119     else begin //if(din_vld == 1 && (state_c == S3 && din == 0) || (state_c == S2 && din == 1))begin
120         dout <= 0;
121     end
122 end
123 
124 endmodule

测试代码:

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

仿真波形:

 

Quartus 综合出来的状态图:

 

转移条件:

 

posted @ 2022-03-25 09:05  MyBooks  阅读(43)  评论(0)    收藏  举报