状态机-阶段1 练习4

 

 

注意:dout 在dout_vld有效时,其值有效,说明 dou_vld 和 dout 是在同一拍上

 

 状态机:

 

产生输出:

代码:

  1 module state_test(
  2                     clk,
  3                     rst_n,
  4                     din_vld,
  5                     din,
  6                     
  7                     dout_vld,
  8                     dout
  9 );
 10 
 11 parameter        S0 = 0;
 12 parameter        S1 = 1;
 13 parameter        S2 = 2;
 14 parameter        S3 = 3;
 15 parameter        S4 = 4;
 16 
 17 input            clk;
 18 input             rst_n;
 19 input            din_vld;
 20 input[2-1:0]    din;
 21 
 22 output            dout_vld;
 23 output[6-1:0]    dout;
 24 
 25 
 26 wire              S02S1_start;
 27 wire              S02S2_start;
 28 wire              S12S2_start;
 29 wire              S12S3_start;
 30 wire              S12S0_start;
 31 wire              S22S3_start;
 32 wire              S22S4_start;
 33 wire              S22S0_start;
 34 wire              S32S4_start;
 35 wire              S32S0_start;
 36 wire              S42S0_start;
 37 wire            vld0;
 38 wire            vld1;
 39 wire            vld2;
 40 wire            vld3;
 41 wire            vld4;
 42 
 43 
 44 reg                dout_vld;
 45 reg[6-1:0]        dout;
 46 
 47 reg[3-1:0]        state_c;
 48 reg[3-1:0]        state_n;
 49 
 50 //第一段,状态跳转
 51 always @(posedge clk or negedge rst_n)begin
 52     if(!rst_n)begin
 53         state_c <= S0;
 54     end
 55     else begin
 56         state_c <= state_n;
 57     end
 58 end
 59 
 60 //第二段,组合逻辑,罗列出状态转移条件
 61 always @(*)begin
 62     case(state_c)
 63         S0:begin
 64             if(S02S1_start)begin
 65                 state_n = S1;
 66             end
 67             else if(S02S2_start)begin
 68                 state_n = S2;
 69             end
 70             else begin
 71                 state_n = state_c;
 72             end
 73         end
 74         
 75         S1:begin
 76             if(S12S2_start)begin
 77                 state_n = S2;
 78             end
 79             else if(S12S3_start)begin
 80                 state_n = S3;
 81             end
 82             else if(S12S0_start)begin
 83                 state_n = S0;
 84             end
 85             else begin
 86                 state_n = state_c;
 87             end
 88         end
 89         
 90         S2:begin
 91             if(S22S3_start)begin
 92                 state_n = S3;
 93             end
 94             else if(S22S4_start)begin
 95                 state_n = S4;
 96             end
 97             else if(S22S0_start)begin
 98                 state_n = S0;
 99             end
100             else begin
101                 state_n = state_c;
102             end
103         end
104         
105         S3:begin
106             if(S32S4_start)begin
107                 state_n = S4;
108             end
109             else if(S32S0_start)begin
110                 state_n = S0;
111             end
112             else begin
113                 state_n = state_c;
114             end
115         end
116         
117         S4:begin
118             if(S42S0_start)begin
119                 state_n = S0;
120             end
121             else begin
122                 state_n = state_c;
123             end
124         end
125         
126         default:begin
127             state_n = S0;
128         end
129     endcase
130 end
131 
132 //第三段,设计条件
133 assign S02S1_start = state_c == S0 && din_vld && din == 0;
134 assign S02S2_start = state_c == S0 && din_vld && din == 1;
135 
136 assign S12S2_start = state_c == S1 && din_vld && din == 0;
137 assign S12S3_start = state_c == S1 && din_vld && din == 1;
138 assign S12S0_start = state_c == S1 && din_vld && din == 2;
139 
140 assign S22S3_start = state_c == S2 && din_vld && din == 0;
141 assign S22S4_start = state_c == S2 && din_vld && din == 1;
142 assign S22S0_start = state_c == S2 && din_vld && din == 2;
143 
144 assign S32S4_start = state_c == S3 && din_vld && din == 0;
145 assign S32S0_start = state_c == S3 && din_vld && (din == 1 || din == 2);
146 
147 assign S42S0_start = state_c == S4 && din_vld && (din == 0 || din == 1 || din == 2);
148 
149 
150 assign vld0 = state_c == S0 && din_vld && din == 2;
151 assign vld1 = state_c == S1 && din_vld && din == 2;
152 assign vld2 = state_c == S2 && din_vld && din == 2;
153 assign vld3 = state_c == S3 && din_vld && (din == 1 || din == 2); 
154 assign vld4 = state_c == S4 && din_vld && (din == 0  || din == 1 || din == 2); 
155 
156 //第四段,设计输出
157 always @(posedge clk or negedge rst_n)begin
158     if(!rst_n)begin
159         dout_vld <= 0;
160     end
161     else if(vld0 || vld1 || vld2 || vld3 || vld4)begin
162         dout_vld <= 1;
163     end
164     else begin
165         dout_vld <= 0;
166     end
167 end
168 
169 always @(posedge clk or negedge rst_n)begin
170     if(!rst_n)begin
171         dout <= 0;
172     end
173     else if(vld1  || (state_c == S4 && din_vld && din == 1))begin //这里所有判断跳进不能加上 && dout_vld ,dout 和 dout_vld 是在同一拍上有效
174         dout <= 5;
175     end
176     else if(vld2)begin
177         dout <= 10;
178     end
179     else if(state_c == S3 && din_vld && din == 2)begin
180         dout <= 15;
181     end
182     else if(state_c == S4 && din_vld && din == 2)begin
183         dout <= 20;
184     end
185     else begin
186         dout <= 0;
187     end
188 end
189 
190 endmodule

测试代码:

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

仿真波形:

 

 

quartus 状态图:

 

转移条件

 

 

 

posted @ 2022-03-29 10:43  MyBooks  阅读(49)  评论(0编辑  收藏  举报