赞
踩
写在前面:以下仿真实验设计应用的是Xilinx Vivado。
题目要求应用Verilog语言设计一个红绿灯,规则为红灯亮15秒,然后黄灯亮3秒,然后绿灯亮12秒,然后红灯亮15秒,以这个规律往复下去,具体要求为展示相应的仿真结果(用波形图表示),并且结果用三个灯中哪个灯亮、倒计时和两个七段数码管(共阴共阳自选)显示数值(用波形图表示),最终提交整个工程文件以及波形图的分析。
首先,我们分析题目,主要要求就是一个简单的红绿灯设计以及用数码管显示数字并且循环,所以,我们先找到循环周期,既然是15s -> 12s -> 3s,我们可以将周期设置为30s(15s + 12s + 3s),然后第一个周期就是从14s开始倒退至0s,然后从12s开始倒退至0s,然后从2s开始倒退到0s,然后只要对应数字显示数字即可,这种分析思路读者日后在写其他的设计时候也可以应用。
在正式设计之前,我们需要知道输入输出是什么,从分析题目的结果来,看我们的输入除了时间(单位:s)找不到其他的输入了,输出即为我们需要验证的波形图,对于这一道题而言我们的输出即为三个灯,倒计时数字,以及倒计时数码管显示。
分析完输入输出之后,我们就要正式开始设计了,在时钟(clk)进行变化的时候(在这里我们设置上升沿触发),我们的timenum需要从0开始每次都自加1,我们首先先判断是否时间大于等于30s,如果是那么让timenum = 0,然后重新开始判断,废话不多说直接上代码:
if (timenum >= 30) timenum = 0; if (timenum < RedTime) begin RYG <= 3'b100; num <= RedTime - timenum - 1; end else if (timenum < GreenTime + RedTime) begin RYG <= 3'b001; num <= GreenTime + RedTime - timenum - 1; end else if (timenum < YellowTime + GreenTime + RedTime) begin RYG <= 3'b010; num <= YellowTime + GreenTime + RedTime - timenum - 1; end timenum = timenum + 5'd1;
以上代码中RYG用来表示三个灯,timenum用来记录次数,num用来倒计时,就这样第一个问题就设计完了。
接下来是段码的表示,我们只需要给断码赋值即可,但是这个时候问题来了,这一道题是最多也就到14s,我们暴力枚举就完全可以,万一你要设计红灯50s呢?这个时候再用枚举就不是很合适了,这时候我们可以通过分别对十位和各位进行单独赋值,我们应用两个case语句,进行段码的显示,到这里我们就要开始选数码管了,这里笔者选择共阴数码管进行设计,我们要开始进行漫长的计算0到9分别对应什么了,以下是笔者所计算,不一定全部正确,如果有错误,欢迎评论改正:
0: 7'b1111110;
1: 7'b0110000;
2: 7'b1101101;
3: 7'b1111001;
4: 7'b0110011;
5: 7'b1011011;
6: 7'b1011111;
7: 7'b1110000;
8: 7'b1111111;
9: 7'b1111011;
逻辑设计已经结束,之后就是测试代码的书写了,由于只有一个输入所以测试代码是比较好写的,如下:
`timescale 1ns / 1ps module sim_RYG(); reg clk; wire[2:0] RYG; wire[3:0] num; wire[13:0] NumericDisplay; RYG U1( .clk(clk), .RYG(RYG), .num(num), .NumericDisplay(NumericDisplay) ); initial clk = 0; always #5 clk = ~clk; endmodule
对于结果分析,笔者不多做解释,直接贴上仿真实验波形图,读者自行分析即可。
从上升沿触发开始有红灯变化为绿灯从绿灯变化为黄灯,再变化为红灯,形成循环
此设计笔者未贴出整个代码以及整个傻瓜式教程,是因为笔者认为这种东西只有自己实际的做一遍才算掌握,对于这一道类型的题目,如果还有问题的话,欢迎联系笔者QQ:2428425170,查看整个工程文件。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。