复杂交通灯设计与完美实现Word格式.docx
- 文档编号:19478132
- 上传时间:2023-01-06
- 格式:DOCX
- 页数:24
- 大小:504.61KB
复杂交通灯设计与完美实现Word格式.docx
《复杂交通灯设计与完美实现Word格式.docx》由会员分享,可在线阅读,更多相关《复杂交通灯设计与完美实现Word格式.docx(24页珍藏版)》请在冰豆网上搜索。
首先是控制黄灯闪烁。
由于控制模块只是控制三个灯的亮与不亮,在此模块中首先是相当于产生一个分频时钟y_flicker(周期1s),然后是控制黄灯的闪烁,控制模块light_select只是控制了三个灯亮与不亮(三位二进制,高电平有效),最后显示灯的亮或者闪还用三位二进制表示(colour),控制时直接把light_select的最高位和最低位直接赋给colour的最高位和最低位(分别控制绿灯和红灯的亮),中间位当分频时钟y_flicker为高且输入light_select为高时,输出colour才为高(黄灯亮),别的情况colour中间位都为低(黄灯灭),至此可以完美实现黄灯的闪烁了(1s内亮0.5s灭0.5s),也就可以实现要求的各个灯的亮或者闪烁。
然后就是七段译码的过程。
采用了3—8译码器的设计原理,将倒计时时间译码,输出到LED晶体管,显示最终倒计时时间。
LED中二极管对应的顺序编号如图1所示,并且是低电平有效。
写出所有数字对应的字型码,就可以知道数字的控制电平。
由于只有两位数字,考虑到成本以及复杂性,可不用扫描,直接用两个译码器就可以了。
图1七段数码管显示字段的示意图
2.总体设计框图及详细说明
程序总体设计框图如图2所示。
图2程序总体设计框图
下面将对所做的系统框图进行详尽说明:
首先,输入的50MHz的系统时钟和全局控制端reset,输出为个位数字的七段译码,十位数字七段译码以及各个灯最后状态。
然后由于系统时钟频率很大,第一要进行分频,使其成为1Hz的时钟信号,第二利用分频后的时钟信号对电路进行控制,开始先对状态跳转进行控制,正如1问所述,用case语句控制三灯亮与灭,紧跟着进行倒计时的过程,第三输出个位和十位上的数即可,要显示倒计时是很容易实现的,直接用两个七段译码即可。
最后要控制黄灯的闪烁,还是要先产生分频时钟,作为控制端,控制模块各灯亮与灭作为输入,即可产生黄灯闪烁的效果。
另外,作为全局控制端,reset信号是清零用的,在有时钟信号的地方就有reset。
3.时序说明
假设在0时刻,加上系统时钟,首先要进行reset清零,这时在控制模块的计数器会清零,三个灯都是灭的状态,控制状态跳转的使能端enable等于0,等待着清零结束,开始工作;
七段译码也不会显示。
在reset变低之后,系统开始正常工作。
首先是分频时钟开始工作,在计数器达到第一个25000000之前,分频时钟都是低电位,到25000000的时候分频时钟的第一个上升沿来临,此时状态控制开始运转,先工作的是绿灯,它会经过从59到0的倒计时过程,同时译码模块也开始工作,颜色控制colour是100,表征绿灯的点亮,经七段译码,这个倒计时数字也会同步显示出来。
经过60s(也就是经过60*50M个系统时钟上升沿之后)绿灯亮的时间到,会自动转到黄灯状态,黄灯是9到0的倒计时过程,译码的显示跟绿灯一样,只是黄灯的亮会加一个1Hz的时钟控制端,1秒内只有半秒,黄灯是亮的,从9秒到8.5秒之间黄灯是亮的,然后8.5到8是灭的,如此继续下去,知道10秒结束。
又经过10s(70*50M个系统时钟上升沿),状态转移到红灯,然后显示及七段译码过程与绿灯相似。
至此一个周期已经完成,接下来就是循环执行以上步骤的过程,直到有reset清零端打断其正常工作。
主要的时序是在三个灯不同状态之间跳转,这也是本程序的关键,他们之间的转换关系如图3所示。
图3时序状态转化图
4.模块设计框图、相关时序
本程序分为三个模块,顶层模块、控制模块、译码模块,各模块的设计框图以及相关时序说明如下:
顶层模块框图如图4所示。
如图4顶层模块框图
输入:
sysclk_50MHz全局时钟信号,50MHz
Reset全局复位端,高电平有效
输出:
color最终各灯状态(包括亮与闪)
led_ctrl_1s个位七段译码
led_ctrl_10s十位七段译码
时序说明:
加上时钟信号之后,首先用reset清零,然后控制模块会分频产生分频时钟,根据分频时钟的高与低,会控制各个状态之间的跳转,译码模块会同步通过数码管来显示倒计时数,并且会根据译码模块黄灯闪亮控制端来输出各灯的具体状态。
控制模块框图如图5所示。
图5控制模块框图
dout_1s倒计时个位上数字
dout_10s倒计时十位上数字
light_select各个灯状态light_select(只是控制亮与灭,不管黄灯闪烁)
首先还是加上系统时钟之后,用reset清零,则计数器清零、所有灯都不亮。
但reset为1之后模块开始工作,首先是计数器开始计数,随之分频时钟会根据计数器的变化而周期变化,绿灯会先亮60秒,之后黄灯也会亮(闪烁在译码模块实现)10秒,然后就是红灯亮60秒,以后就是循环以上步骤的过程,同时在循环过程中,倒计数的数会同步输出,各灯亮与灭状态也会同步输出。
译码模块框图如图6所示:
图6译码模块框图
输入端口:
sysclk_50MHz全局时钟信号,50MHz
reset全局复位端,高电平有效
din_1s显示器个位数据,由控制模块输入
din_10s显示器十位数据,由控制模块输入
light_sel选择那盏灯亮,由控制模块的输入
输出端口:
colour最终显示哪盏灯亮,可与硬件相连
led_data_1s显示器个位数据的译码
led_data_10s显示器十位数据的译码
此模块接受(系统时钟)sysclk_50MHz和(全局复位)reset的控制,均为上升沿触发,当reset为高电平时,电路复位,重新开始工作。
当reset为低电平时,电路正常工作。
时钟上升沿触发,对[3:
0]din_1s(显示器个位数据)进行译码,输出到[6:
0]led_data_1s(显示器个位数据的译码),;
对[3:
0]din_10s(显示器十位数据)进行译码,输出到[6:
0]led_data_10s(显示器十位数据的译码)。
这两个译码输出端口最终连接到硬件上去,实现7段LED数码管的显示。
时钟上升沿触发,对哪个灯亮进行译码输出,light_sel[2]将高电平传入到colour[2]中,红灯开始亮,light_sel[0]将高电平传入到colour[0]中,绿灯开始亮。
黄灯的闪烁在顶层模块说明。
5.系统结构和模块划分,关键子模块之间的接口实现定义。
系统划分为三个模块,顶层模块、控制模块、译码模块,各个模块的相关功能已经在
(1)中详细说明,这里详述子模块接口实现,控制模块里有三个输出,即倒计时时间的十位dout_10s,个位dout_1s,控制灯的亮与灭light_select,这三个都是作为译码模块的输入的,十位和个位直接在译码模块里直接使用,用七段译码,用于显示,灯的亮与灭light_select,最高位和最低位(分别控制绿灯和红灯)直接输出,中间位(控制黄灯)要再加上一个时钟信号,使其闪烁。
6.测试平台设计
在modelsim里进行仿真,testbench的书写很简单,从顶层模块来看,只有两个输入和三个输出,即输入系统时钟,控制清零端,输出个位的七段译码,十位的七段译码以及灯的颜色和状态。
具体实现代码如下:
`timescale1ns/1ns//clk周期应该20ns
moduletraffic_tb;
regsysclk_50MHz;
regreset;
wire[2:
0]color;
//最后控制绿黄红三灯
wire[6:
0]led_ctrl_1s;
//个位七段译码
wire[6:
0]led_ctrl_10s;
//十位七段译码
initial
begin
reset=1;
#1reset=0;
end
always
#1sysclk_50MHz=0;
//这里把系统时钟调为2ns
#1sysclk_50MHz=1;
traffic_lightU_traffic(//实例化
.sysclk_50MHz(sysclk_50MHz),
.reset(reset),
.color(color),
.led_ctrl_1s(led_ctrl_1s),
.led_ctrl_10s(led_ctrl_10s)
);
endmodule
四、实验结果与数据处理
1.Modelsim仿真结果,波形图,代码覆盖率图等
首先要说明的是,由于系统时钟频率很大,运行起来很慢,并且时钟频率的大小与最后结果的正确与否关系并不是很大,于是我们在仿真的时候,把时钟周期调为了较小的2ns。
由于结果很多很长,不可能一一列举,我们在此选择了几个有代表性的的点给予展示。
首先来看看图7,正如上前面所说,我们的输入输出一共有5个但是一些中间的输出的显示能让我们更好的理解,为了更好的理解仿真结果,我们将截图的左边一列的信号从上到下的解释说明列在表1中。
表1仿真结果信号解释说明
信号
解释
备注
sysclk_50MHz
系统时钟,50MHz
为了方便,这里取2ns
color
最终三灯状态
包括绿红灯亮,黄灯闪烁
light_selected
控制模块灯亮的标志
只控制亮与不亮,不闪
led_ctrl_1s
倒计时个位七段译码
系统时钟
led_ctrl_10s
倒计时十位七段译码
系统输出
dout_1s
倒计时个位上的数字
控制模块的输出
dout_10s
倒计时十位上的数字
y_flicker
黄灯闪烁控制端
高电平有效
图7展示的是绿灯倒计时的某一瞬间,竖线所在的位置是56s,这时候color和light_selected是100,表示此时绿灯亮,而led_ctrl_1s是0010000,对照译码表可以发现它显示的数字6,led_ctrl_10s是0010100,对照译码表可以发现它显示的数字5,十位和个位合起来就是数字56,正好与dout_10s(5)和dout_1s(6)结果相对应。
图7modelsim仿真结果关键点展示(绿灯)
图8展示的黄灯倒计时的某一瞬间,竖线显示的地方,此时color和light_selected都是010,表示此时是黄灯在亮,倒计时十位(dout_10s)和和个位(dout_1s)合起来是08,而七段译码led_ctrl_10s是0001000,对照译码表可以发现它显示的数字0,led_ctrl_1s是0000000,对照译码表可以发现它显示的数字8,也与输出结果吻合,最后一个y_flicker为1,也表示此时黄灯可以亮。
图8modelsim仿真结果关键点展示(黄灯)
图9也是展示的黄灯在倒计时08s时结果,与图8不同的是在color和y_flicker,图9的light_selected也是010,表示此时输入信号时黄灯在亮,然而闪烁控制端y_flicker为0,表示此时输出的黄灯应该是灭的,实际上通过图8和图9对比可以发现,它实现了黄灯闪烁的功能(08s的前半秒黄灯是亮的,后半秒是灭的)。
图9modelsim仿真结果关键点展示(黄灯)
图10展示的是红灯倒计时的某一刻,此时color和light_selected是100,表示此时红灯亮,而七段译码结果合起来是37,正好与下面的十位和个位输出结果一致。
图10modelsim仿真结果关键点展示(红灯)
以上四幅图虽然少,但却不失代表性,可以证明我们程序的正确性。
图11是用modelsim做出来的代码覆盖率图,可见代码覆盖率已经很高了,但是并没有达到100%,可见程序仍有可以改进和提高的地方。
图11modelsim代码覆盖率图
程序设计源代码如下:
//********************************************************************
//顶层模块,只做例化,不做逻辑设计
moduletraffic_light(
sysclk_50MHz,//全局时钟,50MHz
reset,//全局控制端
color,//控制绿黄红三灯亮或者闪烁
led_ctrl_1s,//个位七段译码
led_ctrl_10s//十位七段译码
);
inputsysclk_50MHz;
inputreset;
output[2:
output[6:
output[6:
wire[3:
0]dataout_1s;
//个位输出,连接控制和译码模块
wire[3:
0]dataout_10s;
//十位输出,连接控制和译码模块
wire[2:
0]light_selccted;
//三灯亮否,连接控制和译码模块
light_ctrlU_light_ctrl(//控制模块例化
.dout_1s(dataout_1s),//控制模块输出个位上的数
.dout_10s(dataout_10s),//控制模块输出个位十的数
.light_select(light_selccted)
);
//控制模块输出灯的亮与灭
decodeU_decode(//译码模块例化
.sysclk_50MHz(sysclk_50MHz),
.reset(reset),
.din_1s(dataout_1s),//译码模块个位输出做输入
.din_10s(dataout_10s),//译码模块十位输出做输入
.light_sel(light_selccted),//译码模块灯亮与否做输入
.colour(color),//输出,灯的亮和闪
.led_data_1s(led_ctrl_1s),//个位七段译码
.led_data_10s(led_ctrl_10s)//十位七段译码
);
//控制模块,主要是控制灯的时序变化,以及倒计时
modulelight_ctrl(
sysclk_50MHz,//全局时钟
reset,//全局控制端
dout_1s,//个位的数字
dout_10s,//十位的数字
light_select//只是控制三灯亮与灭
output[3:
0]dout_1s;
0]dout_10s;
output[2:
0]light_select;
reg[2:
reg[1:
0]light_status;
//状态控制,用于三灯跳转
regsub_clk_1Hz;
//分频后的1Hz的时钟
reg[24:
0]counter;
//计数器,用于产生1Hz时钟
regenable;
//使能端,控制灯跳转
reg[7:
0]light_long;
//灯亮的时间
parameterg_long=8'
h59;
//绿灯亮时间,BCD码表示
parametery_long=8'
h09;
//黄灯闪亮时间,BCD码表示
parameterr_long=8'
//红灯亮时间,BCD码表示
//用于产生分频时钟
always@(posedgesysclk_50MHzorposedgereset)
begin
if(reset)
sub_clk_1Hz<
=0;
counter<
=5'
d0;
end
else
if(counter==25'
d25000000-1)//0.5s后翻转
begin
counter<
=25'
sub_clk_1Hz<
=~sub_clk_1Hz;
=counter+1;
end
//控制状态跳转,倒计时
always@(posedgesub_clk_1Hzorposedgereset)
if(reset)//有清零,灯都灭
begin
light_select<
=3'
b000;
light_status<
=2'
enable<
if(enable==0)//使能端为0则执行
enable<
=1;
//使能端变1,下面只执行一次
case(light_status)//控制状态跳转
0:
begin
light_long<
=g_long;
//绿灯亮的时间60s
light_select<
b100;
//控制绿灯亮
light_status<
d1;
//交给下一个状态
1:
=y_long;
//黄灯亮的时间10s
b010;
//控制黄灯亮
d2;
2:
light_long<
=r_long;
//红灯亮的时间60s
b001;
//控制红灯亮
defaultlight_select<
endcase
if(light_long==0)//一个灯倒计时完,使能端变0
enable<
else
if(light_long[3:
0]==0)//如果个位为0
begin
light_long[3:
0]<
=4'
d9;
//则个位重新赋值9
light_long[7:
4]<
=light_long[7:
4]-1;
end//且十位减1
else//否则个位值减1
light_long[3:
=light_long[3:
0]-1;
assigndout_1s=light_long[3:
0];
//倒计时低四位就是输出个位
assigndout_10s=light_long[7:
4];
//倒计时高四位就是输出十位
//译码模块,主要是控制黄灯闪烁,绿红灯亮以及倒计时的显示
moduledecode(
din_1s,//个位上输入,是控制模块的输出
din_10s,//个位上输入,是控制模块的输出
light_sel,//灯亮的输入,是控制模块的输出
colour,//最终灯展示出来的效果
led_data_1s,//
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 复杂 交通灯 设计 完美 实现
![提示](https://static.bdocx.com/images/bang_tan.gif)