6.实验6:状态机
Part I :简单的序列检测状态机
实现一个FSM用于识别2中指定的输入序列:4个1或4个0。输入信号为w,输出为z。当连续4个时钟w=1或0时,z=1;否则,z=0.序列允许重合,比如连续5个时钟w=1,在第4,5个时钟z=1。图7.1描述了w和z的关系。
图7.1 w和z的关系
状态图如图7.2所示。用9个触发器,状态编码用独热码,实现本FSM。
表7.1 独热码编码 图7.2 状态图
在DE2-115上按以下步骤实现设计:
1. 为FSM项目创建一个新的Quartus II项目。选定目标芯片。
2. 例化9个触发器。只用assign语句。注意,独热码便于检查逻辑表达式。使用开关SW0作为FSM的同步复位(低有效)。SW1作为w的输入,按键KEY0作为clock输入。LEDG0作为输出z,状态输出到LEDR8到LEDR0.
3. 分配引脚,编译。
4. 仿真。
5.仿真正确后,下载验证。
Part 1代码:
1 LIBRARY ieee;
2
3 USE ieee.std_logic_1164.all;
4
5 ENTITY part1 IS
6
7 PORT (
8
9 KEY : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
10
11 SW : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
12
13 LEDG : OUT STD_LOGIC_VECTOR(0 DOWNTO 0);
14
15 LEDR : OUT STD_LOGIC_VECTOR(8 DOWNTO 0)
16
17 );
18
19 END part1;
20
21 ARCHITECTURE Behavior OF part1 IS
22
23 -- Declare intermediate signals for referenced outputs
24
25 SIGNAL LEDG_x : STD_LOGIC_VECTOR(0 DOWNTO 0);
26
27 SIGNAL LEDR_x : STD_LOGIC_VECTOR(8 DOWNTO 0);
28
29 component sequence_detector
30
31 PORT (
32
33 w : IN STD_LOGIC;
34
35 clk : IN STD_LOGIC;
36
37 rst_n : IN STD_LOGIC;
38
39 z : OUT STD_LOGIC;
40
41 state : OUT STD_LOGIC_VECTOR(8 DOWNTO 0)
42
43 );
44
45 END component;
46
47 BEGIN
48
49 -- Drive referenced outputs
50
51 LEDG <= LEDG_x;
52
53 LEDR <= LEDR_x;
54
55 u0 : sequence_detector
56
57 PORT MAP (
58
59 w => SW(1), --序列检测器的输入信号
60
61 clk => KEY(0), --时钟
62
63 rst_n => SW(0), --复位
64
65 z => LEDG_x(0), --序列检测器的输出信号
66
67 state => LEDR_x --FSM的状态,编码方式为独热码
68
69 );
70
71 END Behavior;
72
73 LIBRARY ieee;
74
75 USE ieee.std_logic_1164.all;
76
77 --序列检测器,能识别连续输入的4个1或0
78
79 --风格一,直接用逻辑表达式来实现
80
81 ENTITY sequence_detector IS
82
83 PORT (
84
85 w : IN STD_LOGIC;
86
87 clk : IN STD_LOGIC;
88
89 rst_n : IN STD_LOGIC;
90
91 z : OUT STD_LOGIC;
92
93 state : OUT STD_LOGIC_VECTOR(8 DOWNTO 0)
94
95 );
96
97 END sequence_detector;
98
99 ARCHITECTURE Behavior OF sequence_detector IS
100
101 SIGNAL D : STD_LOGIC_VECTOR(8 DOWNTO 0); --9个触发器的输入/出
102
103 SIGNAL Q : STD_LOGIC_VECTOR(8 DOWNTO 0);
104
105 component ff
106
107 PORT (
108
109 d : IN STD_LOGIC;
110
111 clk : IN STD_LOGIC;
112
113 rst_n : IN STD_LOGIC;
114
115 set_n : IN STD_LOGIC;
116
117 q : OUT STD_LOGIC
118
119 );
120
121 END component;
122
123 BEGIN --用9个触发器构成状态机
124
125 D(0) <= '0'; --初始状态A
126
127 da : ff
128
129 PORT MAP (
130
131 d => D(0),
132
133 clk => clk,
134
135 rst_n => '1',
136
137 set_n => rst_n,
138
139 q => Q(0)
140
141 );
142
143 D(1) <= (Q(0) OR Q(5) OR Q(6) OR Q(7) OR Q(8)) AND NOT(w); --状态b
144
145 db : ff
146
147 PORT MAP (
148
149 d => D(1),
150
151 clk => clk,
152
153 rst_n => rst_n,
154
155 set_n => '1',
156
157 q => Q(1)
158
159 );
160
161 D(2) <= Q(1) AND NOT(w); --状态c
162
163 dc : ff
164
165 PORT MAP (
166
167 d => D(2),
168
169 clk => clk,
170
171 rst_n => rst_n,
172
173 set_n => '1',
174
175 q => Q(2)
176
177 );
178
179 D(3) <= Q(2) AND NOT(w); --状态d
180
181 dd : ff
182
183 PORT MAP (
184
185 d => D(3),
186
187 clk => clk,
188
189 rst_n => rst_n,
190
191 set_n => '1',
192
193 q => Q(3)
194
195 );
196
197 D(4) <= (Q(3) OR Q(4)) AND NOT(w); --状态e
198
199 de : ff
200
201 PORT MAP (
202
203 d => D(4),
204
205 clk => clk,
206
207 rst_n => rst_n,
208
209 set_n => '1',
210
211 q => Q(4)
212
213 );
214
215 D(5) <= (Q(0) OR Q(1) OR Q(2) OR Q(3) OR Q(4)) AND w; --状态f
216
217 df : ff
218
219 PORT MAP (
220
221 d => D(5),
222
223 clk => clk,
224
225 rst_n => rst_n,
226
227 set_n => '1',
228
229 q => Q(5)
230
231 );
232
233 D(6) <= Q(5) AND w; --状态g
234
235 dg : ff
236
237 PORT MAP (
238
239 d => D(6),
240
241 clk => clk,
242
243 rst_n => rst_n,
244
245 set_n => '1',
246
247 q => Q(6)
248
249 );
250
251 D(7) <= Q(6) AND w; --状态h
252
253 dh : ff
254
255 PORT MAP (
256
257 d => D(7),
258
259 clk => clk,
260
261 rst_n => rst_n,
262
263 set_n => '1',
264
265 q => Q(7)
266
267 );
268
269 D(8) <= (Q(7) OR Q(8)) AND w;--状态i
270
271 di : ff
272
273 PORT MAP (
274
275 d => D(8),
276
277 clk => clk,
278
279 rst_n => rst_n,
280
281 set_n => '1',
282
283 q => Q(8)
284
285 );
286
287 z <= Q(4) OR Q(8);
288
289 state <= Q;
290
291 END Behavior;
292
293 LIBRARY ieee;
294
295 USE ieee.std_logic_1164.all; --具有同步复位和置位功能的dff
296
297 ENTITY ff IS
298
299 PORT (
300
301 d : IN STD_LOGIC;
302
303 clk : IN STD_LOGIC;
304
305 rst_n : IN STD_LOGIC;
306
307 set_n : IN STD_LOGIC;
308
309 q : OUT STD_LOGIC
310
311 );
312
313 END ff;
314
315 ARCHITECTURE Behavior OF ff IS
316
317 BEGIN
318
319 PROCESS (clk)
320
321 BEGIN
322
323 IF (clk'EVENT AND clk = '1') THEN
324
325 IF ((NOT(rst_n)) = '1') THEN
326
327 q <= '0';
328
329 ELSIF ((NOT(set_n)) = '1') THEN
330
331 q <= '1';
332
333 ELSE
334
335 q <= d;
336
337 END IF;
338
339 END IF;
340
341 END PROCESS;
342
343 END Behavior;
Part II :另一种风格的状态机
用赋值和case语句代替手工推导的逻辑表达式,来实现part1中的状态机。
按以下步骤实现电路:
1. 为FSM创建一个新工程。指定目标芯片。
2. 引脚功能:SW0—复位、SW1—w输入、KEY0—clock、LEDG0—z、:LEDR3-0—状态。
3. 编译之前,必须设定综合工具以指定的状态编码实现FSM。选择Assignments > Setting > Analysis and Synthsis 将State Machine Processing 设为User-encoded。
4. 打开RTL Viewer工具查看Quartus II生成的电路。双击电路图中表示状态机的方框图,查看状态图。要查看状态编码,可在编译报告里选择Analysis and Synthesis > State M:achines.
5. 仿真。
6. 下载测试。
7. 修改,在第3步,选择Assignments > Settings > Analysis and Synthesis > State Machine Processing > One-Hot。重新编译,查看区别。
Part 2代码:
1 LIBRARY ieee;
2
3 USE ieee.std_logic_1164.all;
4
5 ENTITY lab7_part2 IS
6
7 PORT ( clk, w, rst: in std_logic; z: out std_logic);
8
9 END lab7_part2;
10
11 ARCHITECTURE Behavior OF lab7_part2 IS
12
13 TYPE State_type IS (A, B, C, D, E, F, G, H, I);
14
15 SIGNAL present_state, next_state : State_type;
16
17 BEGIN
18
19 PROCESS (w, present_state)
20
21 BEGIN
22
23 case present_state IS
24
25 WHEN A => z<='0';
26
27 IF (w = '0') THEN next_state <= B;
28
29 ELSE next_state <= F;
30
31 END IF;
32
33 WHEN B => z<='0';
34
35 IF (w = '0') THEN next_state <= C;
36
37 ELSE next_state <= F;
38
39 END IF;
40
41 WHEN C => z<='0';
42
43 IF (w = '0') THEN next_state <= D;
44
45 ELSE next_state <= F;
46
47 END IF;
48
49 WHEN D => z<='0';
50
51 IF (w = '0') THEN next_state <= E;
52
53 ELSE next_state <= F;
54
55 END IF;
56
57 WHEN E => z<='1';
58
59 IF (w = '0') THEN next_state <= E;
60
61 ELSE next_state <= F;
62
63 END IF;
64
65 WHEN F => z<='0';
66
67 IF (w = '0') THEN next_state <= B;
68
69 ELSE next_state <= G;
70
71 END IF;
72
73 WHEN G => z<='0';
74
75 IF (w = '0') THEN next_state <= B;
76
77 ELSE next_state <= H;
78
79 END IF;
80
81 WHEN H => z<='0';
82
83 IF (w = '0') THEN next_state <= B;
84
85 ELSE next_state <= I;
86
87 END IF;
88
89 WHEN I => z<='1';
90
91 IF (w = '0') THEN next_state <= B;
92
93 ELSE next_state <= I;
94
95 END IF;
96
97 END CASE;
98
99 END PROCESS;
100
101 PROCESS (clk,rst)
102
103 BEGIN
104
105 if rst = '1' then
106
107 present_state <= A;
108
109 elsif rising_edge(clk) then
110
111 present_state <= next_state;
112
113 end if;
114
115 END PROCESS;
116
117 END Behavior;