我是靠谱客的博主 欣慰往事,这篇文章主要介绍FPGA编程,verilog实现简易电梯控制系统,某大学数电实验课设,现在分享给大家,希望可以做个参考。

开发环境:Vivado 2020.1

使用编程语言:Verilog

开发板芯片:xc7a35tftg256-1(具体开发板型号未知,不同版本的开发板可能某些元件的引脚电平会不同,可能需要根据自己手上的开发板版本做一些修改)

项目基本介绍:

1、实现2层楼的简易电梯控制系统。

2、电梯有4个按键。

        1楼外只有向上按键(KEY0)

        2楼外只有向下按键(KEY1)

        电梯内还有2个按键分别为:

        1楼按键(KEY2)

        2楼按键(KEY3)

        所有楼层外和电梯内的按键产生的信号作为给电梯的运行请求信号。

   

3、电梯有4个指示灯(LED0、 LED1 、 LED2 、 LED3)。

         LED0: 按下KEY0键,若电梯不在1楼,则LED0亮。

         LED1: 按下KEY1键,若电梯不在2楼,则LED1亮。

         LED2: 电梯在2楼,按KEY2键, 则LED2亮,电梯到1楼后LED2灭。

         LED3: 电梯在1楼,按KEY3键, 则LED3亮,电梯到2楼后LED3灭。

4、有2个数码管,分别显示当前运行状态及楼层。

        (1)1个数码管显示当前运行状态,电梯有三个运行状态:待机、 上行、下行。 待机:电梯停在1楼或2楼且无请求信号时均为待机状态。 上行状态:电梯停在1楼,有KEY1或KEY3被按下,进入上行状态。 下行状态:电梯停在2楼,有KEY0或KEY2被按下,进入下行状态。

        (2)1个数码管显示所在楼层,显示1或2;每一层楼之间的运行时 间间隔为4秒。

5、有2个拨码开关。

        (1)复位开关。向下拨动后,电梯复位回到1楼。

        (2)启动开关。向上拨动后,按键有效,电梯正常工作。

具体要求:

 附加功能:

       作者只完成了附加功能的第一和第二个,其他的有兴趣可以自己添加。对于复位功能,最开始的时候只以为是整个程序的复位,没有考虑是要像正常地从2楼到1楼,这里只完成了所有状态的复位,即拨下复位拨码开关直接显示为一楼待机状态,而不会经过四秒后再到一楼。后来框架搭好了之后又不便于更改这样的功能了(主要是我懒)。而且期末了还挺忙的,后期如果有时间的话考虑将所有的附加功能都加上去并且把复位也给改了。 

       接下来简单地介绍一下思路:有四个按键,我就给四个按键分别分配了一个四秒的计时器,当某一个按键被按下后,计时器就会开始工作,这时对应的状态位会被置位,比如在一楼按下上行按键后,对应按键的led灯会被点亮,电梯进入上行状态,四秒计时结束后楼层状态翻转(注意这里只有两层楼,其实可以只用一位的状态位来表示楼层,但我选择了用两个位来分别表示,它们分别是lou1和lou2----lou1 = 1,lou2 = 0在一楼;lou1 = 0,lou2 = 1在二楼,楼层状态改变就是这两个状态位翻转)电梯重新进入待机状态。

      当然对于计时器其实还有很多的细节没有说,主要是解决按键之间的冲突和配合。具体代码如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
module count_4( input en, //使能位 input clk, input wait1, //两个等待位,检测是否处于冲突状态 input wait2, output reg flag =0, //led灯使能信号 output reg key_d, //按键延迟信号 output reg status = 0 //计数状态输出:为1计数、为0不计数 ); //等待位,如果该计时器被用于上行计时,那么如果处于下行状态时,计时器就会等待下行状态结束再开始计时 //这里的两个等待位分别对应了两个下行计数器的状态输出位---status reg flag2 = 1; always@(posedge clk) begin if(wait1 | wait2) flag2 <= 0; else flag2 <= 1; end //使能位上升沿来临,计数器使能信号置位为1 //作用是记住按键被按下的状态 reg flag1 = 1; always@(posedge clk) begin if(en == 1) flag <= 1; else if (flag1 == 0) flag <= 0; end //当使能位为1且不处于冲突状态时计时器开始计时,并将输出状态位置位为1 always@(posedge clk) begin if(flag & flag2) status <= 1 ; else if (flag1 == 0) status <= 0; end //在开始计时的时候获得一个冲激信号 //这个信号被用来模拟按键被按下的动作 reg [31:0] temp1 =0; reg impluse = 0; always@(posedge clk) begin if(status == 0) begin temp1 <= 0; impluse <= 0; end else if(temp1 < 10) begin temp1 <= temp1 +1; impluse <= 1; end else begin temp1 <= temp1+1; impluse <= 0; end end //key_d = key_delay,是处于冲突状态时有按键被按下的延时信号,即冲突状态结束后模拟一次按键被按下的动作 always@(posedge clk) begin if(impluse) key_d = 1; else key_d = 0; end //获得1hz的信号,用来计时 reg [31:0] temp =0; reg clk_1hz = 0; always@(posedge clk) begin if(status == 0) begin temp <= 0; clk_1hz <= 0; end else if(temp == 49999999) begin temp <= 0; clk_1hz <= 1; end else begin temp <= temp +1; clk_1hz <= 0; end end //开始计时 //计时完成后,计时器状态位复位,使能信号复位,等待下一次按键被按下 reg [1:0] count = 0; always@(posedge clk_1hz or negedge status) begin if(status == 0) begin count <=0; flag1 <= 1; end else if(count == 3 ) begin count <= 0; flag1 <= 0; end else begin count <= count + 1; flag1 <= 1; end end endmodule

 这里详细说一下key_d这个信号,因为在要求里面有说在下行状态时如果按下上行按键,那么电梯会在到达1楼后继续进入上行状态直到到达2楼后再结束运行。因为在顶层代码中我用到了按键按下的信号、楼层状态以及运行状态这几个信号用来做逻辑判断,以此来改变某些状态。但是在刚刚说的那种情况下,当下行状态结束后如果没有按下上行按键那么电梯也是不会上行的,原因是上行按键是在下行状态被按下的,此时顶层的逻辑判断会判定其无效。为了解决这个问题而又不对顶层模块进行大改,我就在计时器中添加了key_d这个延迟信号,它的作用是当下行状态结束的一瞬间就模拟一次上行按键被按下的动作,以此来获得上行命令,达到所说的要求。而两个wait信号是用来判定是否在冲突状态的,如果在冲突状态就等该冲突状态结束后再开始计时,同时key_d这个信号会模拟一次对于按键被按下的动作。flag这个信号是用来控制按键对应的led灯的,只要按键被按下这个flag就会被置位为1,led灯会再根据其他的一些信号来判断是否要亮(这里的led灯特指按键对应的灯,而非流水灯)。en信号就是使能信号,最开始就是按键被按下的信号,但是会导致led灯的亮灭出现一些问题(比如按下上行key1后再按下上行key3那么led1就会熄灭),所以我又用其他的一些信号将其与按键被按下的信号做了一些逻辑上的与或操作来解决这个问题。计时器大概就是这样了,更加具体的可以看代码,关键部分都有注释。

       剩下的就是一些数码管的动态显示、bcd译码器以及按键消抖的代码,这些东西其实很简单,网上有大把现成的代码可以用,这里就附上我的代码:

按键消抖:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
module ajxd( input clk, input [3:0] btn_in, output [3:0] btn_out, input rst_n ); reg clk_20ms = 0; reg [31:0] temp = 0; always@(posedge clk) begin if(rst_n == 0) begin temp <= 0; clk_20ms <= 0; end else if(temp == 999999) begin temp <= 0; clk_20ms <= 1; end else if(temp < 999999) begin clk_20ms <= 0; temp <= temp+1; end end reg [3:0] btn0; reg [3:0] btn1; reg [3:0] btn2; initial begin btn0=0; btn1=0; btn2=0; end always@(posedge clk_20ms) begin btn0<=btn_in; btn1<=btn0; btn2<=btn1; end assign btn_out=((btn0&btn1)&(~btn2) | (btn0&btn1&btn2) | ((~btn0)&btn1&btn2)); endmodule

数码管动态显示:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
module seg_scan( input clk, input [6:0] data_seg0, input [6:0] data_seg1, output reg [7:0] data_seg, output reg [5:0] data_dig ); parameter clk_freq=50000000;//50Mhz parameter scan_freq=200;//200hz parameter scan_cont=clk_freq/scan_freq/2-1; reg [31:0] time_cont = 0; reg temp = 0; always@(posedge clk) begin if(time_cont<scan_cont) time_cont = time_cont+1; else begin time_cont <= 0; temp <= ~temp; end end always@(posedge clk) begin case(temp) 0: begin data_seg<={1'b0,data_seg0}; data_dig<=6'b111110; end 1: begin data_seg<={1'b0,data_seg1}; data_dig<=6'b111101; end endcase end /* 2: begin data_seg<={1'b0,data_seg2}; data_dig<=6'b111011; end 3: begin data_seg<={1'b0,data_seg3}; data_dig<=6'b110111; end 4: begin data_seg<={1'b0,data_seg4}; data_dig<=6'b101111; end 5: begin data_seg<={1'b0,data_seg5}; data_dig<=6'b011111; end */ endmodule

 最后的模块结构如下:

 再附上顶层模块代码:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
module top( input clk, input rst_n, input start, input [3:0] key, output reg [4:0] state_led = 0, output reg buzzer = 1, output reg [3:0] led =0, output [3:0] row, output [7:0] data_seg, output [5:0] data_dig ); //-------------------------------------------------------------------------------------------------- //按键相关 assign row = 4'b1110; //只需要用到最下面一行,不需要按建行扫描 //按键消抖 wire [3:0] key_xd; ajxd u2 ( .clk (clk), .btn_in ( key), .rst_n (rst_n), .btn_out (key_xd) ); //定义四个按键信号,代表按下按键并消抖之后的信号 wire key0,key1,key2,key3; //按键按下时定义为高电平 assign key0 = ~(key_xd[0]|row[0]); assign key1 = ~(key_xd[1]|row[0]); assign key2 = ~(key_xd[2]|row[0]); assign key3 = ~(key_xd[3]|row[0]); //-------------------------------------------------------------------------------------------------- /* 每一个按键都对应了一个四秒的计时器, 该计时器检测到按键上升沿信号后开始计时, 计时状态位——status: 1 = 计时中 ; 0 = 计时完成 */ //四个状态位,分别代表了key0下行,key1上行,key2下行,key3上行状态 wire status_dow0; wire status_up1; wire status_dow2; wire status_up3; /* 四个按键信号延迟位 key_delay_x x=0,1,2,3 为了完成“在上行状态时按下KEY0或KEY2下行,电梯到达2楼后立刻下行”这一要求 在计时器中添加了一个按键被按下后的延迟按键信号输出 其功能为: 若处于上行状态中,按下KEY0或KEY2,那么KEY0或KEY2对应的计时器会被触发,但由于 还处于上行状态,无法开启下行状态。于是将等待上行状态完成后模拟一次KEY0或KEY2被 按下的信号。相当于在上行状态结束的一瞬间再按下了KEY0或KEY2一次,以此来达到期望的效果。 在下行状态按下上行按键也同理 */ wire key_d0; wire key_d1; wire key_d2; wire key_d3; /* 用来记录四个按键是否被按下的信号,其主要作用是点亮按键对应的led灯 当按键被按下对应的flag就会置位为1,后面会用到该信号来点亮按键对应的 led灯 */ wire flag0; wire flag1; wire flag2; wire flag3; //定义两个楼层 reg lou1,lou2; //定义5个状态---上行(key1)、上行(key3)、下行(key0)、下行(key2)、待机 reg state_up1,state_up3,state_dow0,state_dow2,state_wait; /* 例化计时器模块 */ count_4 dow_count0 ( .clk (clk), .en (key0&(lou2|(~state_wait))&(~led[2])), .flag (flag0), .key_d (key_d0), .wait1 (status_up1), .wait2 (status_up3), .status (status_dow0) ); count_4 up_count1 ( .clk (clk), .en (key1&(lou1|(~state_wait))&(~led[3])), .flag (flag1), .key_d (key_d1), .wait1 (status_dow0), .wait2 (status_dow2), .status (status_up1) ); count_4 dow_count2 ( .clk (clk), .en (key2&(lou2|(~state_wait))&(~led[0])), .flag (flag2), .key_d (key_d2), .wait1 (status_up1), .wait2 (status_up3), .status (status_dow2) ); count_4 up_count3 ( .clk (clk), .en (key3&(lou1|(~state_wait))&(~led[1])), .flag (flag3), .key_d (key_d3), .wait1 (status_dow0), .wait2 (status_dow2), .status (status_up3) ); //-------------------------------------------------------------------------------------------------- /* 楼层及电梯状态判断 */ //定义5个状态---上行(key1)、上行(key3)、下行(key0)、下行(key2)、待机 //reg state_up1,state_up3,state_dow0,state_dow2,state_wait; //定义两个楼层 //reg lou1,lou2; //ps:本来这几个状态位是定义在这的,但是前面用到了这几个状态位,所以将这几个状态位定义在了前面,这里是做提示用 //初始状态:电梯停在一楼,待机状态 initial begin lou1 = 1; lou2 = 0; state_up1 = 0; state_up3 = 0; state_dow0 = 0; state_dow2 = 0; state_wait = 1; end /* 使用计时器状态和楼层状态以及按键被按下的信号做逻辑判断 以此来改变楼层状态位和上下行状态位以及待机状态位 */ always@(posedge clk) begin if(rst_n == 0) //复位,所有状态皆回到初始值 begin lou1 = 1; lou2 = 0; state_up1 = 0; state_up3 = 0; state_dow0 = 0; state_dow2 = 0; state_wait = 1; end else if (start == 1) //启动 begin if(lou1&(~lou2)&(key_d1|key_d3)) //电梯不处于上行状态且电梯在一楼、KEY1或KEY3被按下,则电梯进入上行状态,跳出待机状态 begin if(status_up1 == 1) begin state_up1 <= 1; state_wait <= 0; end else if (status_up3 == 1) begin state_up3 <= 1; state_wait <= 0; end end else begin if((status_up1 == 0)&(state_up1 == 1)) //上行状态保持4秒后,status_up1/3置位、上行状态结束、进入待机状态、楼层状态翻转 begin state_up1 <= 0; state_wait <= 1; lou1 <= ~lou1; lou2 <= ~lou2; end else if((status_up3 == 0)&(state_up3 == 1)) begin state_up3 <= 0; state_wait <= 1; lou1 <= ~lou1; lou2 <= ~lou2; end end if(lou2&(~lou1)&(key_d0|key_d2)) //电梯不处于下行状态且电梯在二楼、KEY2或KEY0被按下,则电梯进入下行状态,跳出待机状态 begin if(status_dow0 == 1) begin state_dow0 <= 1; state_wait <= 0; end else if (status_dow2 == 1) begin state_dow2 <= 1; state_wait <= 0; end end else begin if((status_dow0 == 0)&(state_dow0 == 1)) //下行状态保持4秒后,status_dow0/2置位、下行状态结束、进入待机状态、楼层状态翻转 begin state_dow0 <= 0; state_wait <= 1; lou1 <= ~lou1; lou2 <= ~lou2; end else if((status_dow2 == 0)&(state_dow2 == 1)) begin state_dow2 <= 0; state_wait <= 1; lou1 <= ~lou1; lou2 <= ~lou2; end end end end //-------------------------------------------------------------------------------------------------- /* 点亮LED灯 */ always@(posedge clk ) begin if(rst_n == 1'b0) //reset begin led <= 0; end else if(start == 1) //start begin led[0] <= (status_dow0&(~status_dow2)&(lou2&(~lou1)))|((state_up1|state_up3)&flag0); led[1] <= (status_up1&(~status_up3)&(lou1&(~lou2)))|((state_dow0|state_dow2)&flag1); led[2] <= (status_dow2&(~status_dow0)&(lou2&(~lou1)))|((state_up1|state_up3)&flag2); led[3] <= (status_up3&(~status_up1)&(lou1&(~lou2)))|((state_dow0|state_dow2)&flag3); end end //-------------------------------------------------------------------------------------------------- /* 这里使用的是共阴极数码管,若为共阳极数码管则只需要改动数码管相关的一些代码 调用数码管动态显示模块控制数码管的显示 用两个七段(八段)数码管,一个显示楼层数字,一个显示上行、下行、待机状态。 上行用数码管a亮其他灭表示;待机用数码管g亮其他灭表示;下行用数码管d亮其他灭表示。 */ reg [6:0] data_seg0; //运行状态显示 reg [6:0] data_seg1; //当前楼层显示 seg_scan scan ( .clk (clk), .data_seg0 (data_seg1), .data_seg1 (data_seg0), .data_seg (data_seg), .data_dig (data_dig) ); //定义一个数码管状态变量,方便用数码管显示状态 wire [6:0] status_seg ; assign status_seg = {lou1,lou2,state_up1,state_up3,state_dow0,state_dow2,state_wait}; always@(posedge clk) begin case(status_seg) 7'b1000001: //1楼待机 begin data_seg0 <= 7'b1000000; data_seg1 <= 7'b0000110; end 7'b1010000: //1楼上行——status_up1——KEY1被按下 begin data_seg0 <= 7'b0000001; data_seg1 <= 7'b0000110; end 7'b1001000: //1楼上行——status_up3——KEY3被按下 begin data_seg0 <= 7'b0000001; data_seg1 <= 7'b0000110; end 7'b0100001: //2楼待机 begin data_seg0 <= 7'b1000000; data_seg1 <= 7'b1011011; end 7'b0100100: //2楼下行——status_dow0——KEY0被按下 begin data_seg0 <= 7'b0001000; data_seg1 <= 7'b1011011; end 7'b0100010: //2楼下行——status_dow2——KEY2被按下 begin data_seg0 <= 7'b0001000; data_seg1 <= 7'b1011011; end default: //其他情况,显示E,待机 begin data_seg0 <= 7'b1000000; data_seg1 <= 7'b1111001; end endcase end //-------------------------------------------------------------------------------------------------- //附加功能:蜂鸣器 //这里采用无源蜂鸣器,需要输入一定频率的方波信号 //输入信号频率决定了蜂鸣器发出的声音频率,这里采用500hz的方波信号 //获得1khz的信号 reg [31:0] temp =0; reg clk_1khz = 0; always@(posedge clk) begin if(temp == 49999) begin temp <= 0; clk_1khz <= 1; end else begin temp <= temp +1; clk_1khz <= 0; end end reg lou1_dly; reg turn = 0; reg [15:0] cnt = 0; //这是一个检测信号翻转的模块,采用了非阻塞赋值 //检测楼层状态是否翻转,若翻转则turn = 1并开始计时,计时完成后turn = 0 always@(posedge clk) begin lou1_dly <= lou1; if(lou1 != lou1_dly) turn <= 1; else if(cnt == 100) turn <= 0; end parameter cnt_max = 100; always@(posedge clk_1khz) begin if(turn == 1) begin if(cnt == cnt_max) cnt <= 0; else cnt <= cnt + 1; end else cnt <= 0; end //当turn = 1时向蜂鸣器输入1khz的信号,蜂鸣器响0.1s,这里蜂鸣器响的时间由上面的cnt计数器决定 //t = cnt_max / 1000 单位s //作为蜂鸣器的输入信号buzzer的频率其实为500hz //也可以将clk_1hz信号直接赋给buzzer,令其为1khz,这种办法其实更好, //可以节约一个寄存器资源,也让buzzer和1khz的时钟频率相同, //但在这里两个都无所谓,只是频率不同而已,看自己的需要更改即可 always@(posedge clk_1khz) begin if(turn == 1) buzzer <= ~buzzer; else if(turn == 0) buzzer <= 0; end //-------------------------------------------------------------------------------------------------- //附加功能:流水灯,上行状态将LED11---LED7从左到右每隔一秒依次点亮; // 下行状态将LED11---LED7从右到左每隔一秒依次点亮 //定义两个状态位控制流水灯的状态 wire state_up;//用来控制上行流水灯 wire state_dow;//用来控制下行流水灯 //为了防止预期以外的情况出现,这里采用了楼层和按键对应的led灯来共同控制流水灯的状态 assign state_up = (led[1]|led[3])&(lou1&(~lou2)); assign state_dow = (led[0]|led[2])&(lou2&(~lou1)); /* 获得1.05hz的信号(总共5个灯,每隔一秒亮一个, 但是最后一个灯在4秒末结束时才亮,这时电梯都已经结束了当前状态了 所以最后效果其实是只能看见4个灯亮,这里将计数器的时钟改为1.05hz左右, 即每隔大概9.5s左右点亮一个灯,这样最后一个灯就可以被点亮0.2s左右) */ reg [31:0] temp1 =0; reg clk_1hz = 0; always@(posedge clk or negedge state_up or negedge state_dow) begin if(~(state_up|state_dow)) begin temp1 <= 0; clk_1hz <= 0; end else if(state_up | state_dow) begin if(temp1 == 47619046) begin temp1 <= 0; clk_1hz <= 1; end else begin temp1 <= temp1 +1; clk_1hz <= 0; end end else temp1 <= 0; end //计数器 reg [3:0] cnt1 = 0; always@(posedge clk_1hz or negedge state_up or negedge state_dow) begin if(~(state_up|state_dow)) begin cnt1 <= 0; end else if(state_up | state_dow) begin if(cnt1 == 5) cnt1 <= 0; else cnt1 <= cnt1 + 1; end else cnt1 <= 0; end always@(posedge clk ) begin if(state_up) begin case(cnt1) 0 :state_led <= 5'b10000; 1 :state_led <= 5'b11000; 2 :state_led <= 5'b11100; 3 :state_led <= 5'b11110; 4 :state_led <= 5'b11111; default:state_led <= 5'b00000; endcase end else if(state_dow) begin case(cnt1) 0 :state_led <= 5'b00001; 1 :state_led <= 5'b00011; 2 :state_led <= 5'b00111; 3 :state_led <= 5'b01111; 4 :state_led <= 5'b11111; default:state_led <= 5'b00000; endcase end else state_led <= 5'b00000; end endmodule

约束文件:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets start_IBUF] set_property IOSTANDARD LVCMOS33 [get_ports {data_dig[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_dig[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_dig[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_dig[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_dig[4]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_dig[5]}] set_property PACKAGE_PIN G12 [get_ports {data_dig[0]}] set_property PACKAGE_PIN H13 [get_ports {data_dig[1]}] set_property PACKAGE_PIN M12 [get_ports {data_dig[2]}] set_property PACKAGE_PIN N13 [get_ports {data_dig[3]}] set_property PACKAGE_PIN N14 [get_ports {data_dig[4]}] set_property PACKAGE_PIN N11 [get_ports {data_dig[5]}] set_property PACKAGE_PIN T10 [get_ports {key[3]}] set_property PACKAGE_PIN R11 [get_ports {key[2]}] set_property PACKAGE_PIN T12 [get_ports {key[1]}] set_property PACKAGE_PIN R12 [get_ports {key[0]}] set_property PACKAGE_PIN T5 [get_ports {led[3]}] set_property PACKAGE_PIN R7 [get_ports {led[2]}] set_property PACKAGE_PIN R8 [get_ports {led[1]}] set_property PACKAGE_PIN P9 [get_ports {led[0]}] set_property PACKAGE_PIN R10 [get_ports {row[3]}] set_property PACKAGE_PIN P10 [get_ports {row[2]}] set_property PACKAGE_PIN M6 [get_ports {row[1]}] set_property PACKAGE_PIN K3 [get_ports {row[0]}] set_property PACKAGE_PIN D4 [get_ports clk] set_property PACKAGE_PIN F3 [get_ports rst_n] set_property PACKAGE_PIN T9 [get_ports start] set_property IOSTANDARD LVCMOS33 [get_ports clk] set_property IOSTANDARD LVCMOS33 [get_ports rst_n] set_property IOSTANDARD LVCMOS33 [get_ports start] set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[7]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[6]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[5]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[4]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {key[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {key[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {key[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {key[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {row[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {row[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {row[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {row[0]}] set_property PACKAGE_PIN L13 [get_ports {data_seg[7]}] set_property PACKAGE_PIN M14 [get_ports {data_seg[6]}] set_property PACKAGE_PIN P13 [get_ports {data_seg[5]}] set_property PACKAGE_PIN K12 [get_ports {data_seg[4]}] set_property PACKAGE_PIN K13 [get_ports {data_seg[3]}] set_property PACKAGE_PIN L14 [get_ports {data_seg[2]}] set_property PACKAGE_PIN N12 [get_ports {data_seg[1]}] set_property PACKAGE_PIN P11 [get_ports {data_seg[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[7]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[6]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[5]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[4]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[0]}] set_property PACKAGE_PIN L2 [get_ports buzzer] set_property IOSTANDARD LVCMOS33 [get_ports buzzer] set_property IOSTANDARD LVCMOS33 [get_ports {state_led[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {state_led[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {state_led[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {state_led[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {state_led[4]}] set_property PACKAGE_PIN T2 [get_ports {state_led[0]}] set_property PACKAGE_PIN R1 [get_ports {state_led[1]}] set_property PACKAGE_PIN G5 [get_ports {state_led[2]}] set_property PACKAGE_PIN H3 [get_ports {state_led[3]}] set_property PACKAGE_PIN E3 [get_ports {state_led[4]}]

最后就到这里了,有什么问题欢迎讨论,如果有更好的想法也可以在评论区分享一下。

最后

以上就是欣慰往事最近收集整理的关于FPGA编程,verilog实现简易电梯控制系统,某大学数电实验课设的全部内容,更多相关FPGA编程内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(64)

评论列表共有 0 条评论

立即
投稿
返回
顶部