名称:交通灯控制系统设计Verilog代码VIVADO仿真
软件:VIVADO
语言:Verilog
代码功能:
交通灯控制系统
要求设计一个交通灯控制系统。信号灯分为红黄绿三种。道路分为东西方向和南北方向。为便于描述,本文将东西方向称为干路,南北方向称为支路。红灯停绿灯行,黄灯时是预备时间,也要停止。
要求:
1:干路绿灯时间20秒,黄灯时间5秒,红灯时间25秒。
2:支路绿灯时间20秒,红灯时间25秒,黄灯时间5秒。
FPGA代码Verilog/VHDL代码资源下载:www.hdlcode.com
设计文档:
一、系统设计
设计系统功能模块如下所示:
系统分为分频模块、红绿灯控制模块、倒计时控制模块、数码管显示模块四个子模块,然后通过顶层模块将这四个模块连接起来。
分频模块用于将系统时钟50MHz分频为1Hz,1Hz对应1秒,可用于后续的倒计时控制。
红绿灯控制模块用于实现主路支路的红绿灯切换控制,即控制红绿灯按干路绿灯时间20秒,黄灯时间5秒,红灯时间25秒。支路绿灯时间20秒,红灯时间25秒。黄灯时间5秒的规律变化。该模块使用状态机控制,状态图如下:
状态分为复位状态,主路绿灯状态,主路黄灯状态,支路绿灯状态,支路黄灯状态。当按下复位复位按键时状态机进入复位状态,然后自动进入主路绿灯状态,在该状态下,主路绿灯亮,支路红灯亮。经过20秒后,进入主路黄灯状态,在该状态下,主路黄灯亮,支路红灯亮。经过5秒后,进入支路绿灯状态,在该状态下,主路红灯亮,支路绿灯亮。经过20秒后,进入支路黄灯状态,在该状态下,主路红灯亮,支路黄灯亮。经过5秒后,进入主路绿灯状态,在该状态下,主路绿灯亮,支路红灯亮。
倒计时控制模块用于根据红黄绿灯的状态和总时间计算倒计时,例如干路绿灯时间是20秒,在干路绿灯亮时,开始计数,计数时钟用分频模块输出的1Hz信号,即可以计数0~19,然后再用总时间20减去计数值,就能得到倒计时数。其他灯的倒计时同理。然后在绿灯亮时,只显示绿灯的倒计时,在红灯亮时,只显示红灯的倒计时,在黄灯亮时,只显示黄灯的倒计时。
数码管显示模块用于将倒计数显示在数码管上,即需要实现数码管译码功能,将倒计时值译码为数码管显示值。
二、功能模块设计分析
分频模块框图如下所示:
分频模块框图
模块中输入信号为clk,为系统时钟50MHZ,输出信号为clk_out,为1Hz的信号。
红绿灯控制模块框图如下所示:
输入clk_1Hz为分频模块输出的1Hz时钟,输入main_green_time、main_yellow_time、branch_green_time、branch_yellow_time分别表示主路绿灯时间(8’h37为十六进制,对应十进制的55)、主路黄灯时间、支路绿灯时间、支路黄灯时间。
输出main_red、main_green、main_yellow分别表示主路红、绿、黄灯。branch_red、branch_green、branch_yellow分别表示支路红、绿、黄灯。输出main_green_BCD、main_yellow_BCD、main_red_BCD分别表示主路绿灯正计数、主路黄灯正计数、主路红灯正计数。branch_green_BCD、branch_yellow_BCD、branch_red_BCD分别表示支路绿灯正计数、支路黄灯正计数、支路红灯正计数。
倒计时控制模块框图如下所示:
输入clk为系统时钟50MHz,输入main_red、main_green、main_yellow分别表示主路红、绿、黄灯。branch_red、branch_green、branch_yellow分别表示支路红、绿、黄灯。输入main_green_time、main_yellow_time、branch_green_time、branch_yellow_time分别表示主路绿灯时间、主路黄灯时间、支路绿灯时间、支路黄灯时间。输入main_green_BCD、main_yellow_BCD、main_red_BCD分别表示主路绿灯正计数、主路黄灯正计数、主路红灯正计数。branch_green_BCD、branch_yellow_BCD、branch_red_BCD分别表示支路绿灯正计数、支路黄灯正计数、支路红灯正计数。
输出main_data_out表示主路倒计时数据显示值,branch_data_out表示支路倒计时数据显示。
数码管显示模块框图如下所示:
输入clk为系统时钟50MHz,输入main_data表示主路倒计时数据显示值,branch_data表示支路倒计时数据显示。输出为数码管的位选和段选信号。
系统顶层模块将上述四个模块连接起来,如下图所示:
顶层端口输入为50MHz时钟,输出main_red、main_green、main_yellow分别表示主路红、绿、黄灯。branch_red、branch_green、branch_yellow分别表示支路红、绿、黄灯。输出为数码管的位选和段选信号。
三、仿真分析
代码设计完成后,经过编译综合,成功后可以编写TB文件进行仿真验证,TB文件验证的原理是模拟产生代码的输入信号,将输入信号加载到代码中观察输出信号是否满足设计要求。设计的TB文件如下所示:
TB文件中模拟了系统输入信号50MHz,然后通过仿真图观察各个模块的信号是否满足设计要求。
分频模块仿真图如下:
图中输入clk为50MHz信号,输出clk_out信号正确分频为1Hz,模块功能验证正确。
交通灯控制模块仿真图如下:
局部放大后
图中clk_1Hz为1秒时钟频率,输入main_green_time、main_yellow_time、branch_green_time、branch_yellow_time分别表示主路绿灯时间(20 秒)、主路黄灯时间(5秒)、支路绿灯时间(20秒)、支路黄灯时间(5秒)。
输出main_red、main_green、main_yellow分别表示主路红、绿、黄灯。branch_red、branch_green、branch_yellow分别表示支路红、绿、黄灯。输出main_green_BCD、main_yellow_BCD、main_red_BCD分别表示主路绿灯正计数、主路黄灯正计数、主路红灯正计数。branch_green_BCD、branch_yellow_BCD、branch_red_BCD分别表示支路绿灯正计数、支路黄灯正计数、支路红灯正计数。图中可以看到主路主路红绿灯切换正确,时长正确。因此交通灯控制模块功能验证正确。
倒计时控制模块仿真图如下:
输入clk为系统时钟50MHz,输入main_red、main_green、main_yellow分别表示主路红、绿、黄灯。branch_red、branch_green、branch_yellow分别表示支路红、绿、黄灯。输入main_green_time、main_yellow_time、branch_green_time、branch_yellow_time分别表示主路绿灯时间、主路黄灯时间、支路绿灯时间、支路黄灯时间。输入main_green_BCD、main_yellow_BCD、main_red_BCD分别表示主路绿灯正计数、主路黄灯正计数、主路红灯正计数。branch_green_BCD、branch_yellow_BCD、branch_red_BCD分别表示支路绿灯正计数、支路黄灯正计数、支路红灯正计数。
输出main_data_out表示主路倒计时数据显示值,branch_data_out表示支路倒计时数据显示。观察图中main_data_out信号和branch_data_out信号,可以清楚看到倒计时计数正确,对应的红绿灯也正确。因此倒计时控制模块功能验证正确。
数码管显示模块仿真图如下:
输入main_data表示主路倒计时数据显示值,branch_data表示支路倒计时数据显示。输出branch_data_one为支路倒计时个位,branch_data_ten为支路倒计时十位,输出main_data_one为主路倒计时个位,main_data_ten为主路倒计时十位。顶层模块仿真图为:
顶层端口输入为50MHz时钟,输出main_red、main_green、main_yellow分别表示主路红、绿、黄灯。branch_red、branch_green、branch_yellow分别表示支路红、绿、黄灯。可以清楚看到倒计时计数正确,对应的红绿灯也正确。
四、结论与体会
本文设计的交通灯控制系统采用自顶向下的设计方法,系统采用模块化设计,并对每个模块进行了单独仿真,仿真验证正确,最终整体仿真功能也正确。本设计可以在代码中灵活修改红绿灯时间,具有适应性好的优点。当然本系统也有改进的空间,比如后续可以改为按键控制修改红绿灯时间。
参考文献
[1] 袁玉卓等.FPGA自学笔记-设计与验证[M].北京:北京航空航天大学出版社
[2] 王振红. FPGA电子系统设计项目实践[M]. 北京:清华大学出版社
[3] 南志贤等. 基于Quartus Prime的FPGA/CPLD数字系统设计实例[M]. 北京:电子工业出版社
[4] 姜书艳等. 数字设计FPGA应用[M]. 北京:科学出版社
[5] 赵艳华等.实例讲解:基于Quartus II的FPGACPLD数字系统设计快速入门[M].北京:电子工业出版社
[6] 张晋荣等. FPGA实战训练精粹[M]. 北京:清华大学出版社
部分代码展示:
/* 红->绿?绿->黄?黄->红 1、红--计时main_red_times------------------------绿--计时main_green_times---main_yellow_times黄灯---------------红 2、绿--计时branch_green_times---branch_yellow_times黄灯--------------------红--计时branch_reg_times-------------------绿 */ //东西为支路 //南北为主路 module?traffic_light( input?clk,//100Mhz input?en, //led?1亮0灭 output?main_red,//主路灯 output?main_green,//主路灯 output?main_yellow,//主路灯 output?branch_red,//支路灯 output?branch_green,//支路灯 output?branch_yellow,//支路灯 output?[3:0]?weixuan,//数码管位选 output?[7:0]?duanxian//数码管段选 ); ?wire?clk_1Hz; ?wire?[7:0]?main_green_BCD; ?wire?[7:0]?main_yellow_BCD; ?wire?[7:0]?main_red_BCD; ?wire?[7:0]?branch_green_BCD; ?wire?[7:0]?branch_yellow_BCD; ?wire?[7:0]?branch_red_BCD; ?wire?[7:0]?main_data_out; ?wire?[7:0]?branch_data_out; ? wire?main_red_led;//主路灯 wire?main_green_led;//主路灯 wire?main_yellow_led;//主路灯 wire?branch_red_led;//支路灯 wire?branch_green_led;//支路灯 wire?branch_yellow_led;//支路灯 //led?0亮1灭 assign?main_red=main_red_led;//主路灯 assign?main_green=main_green_led;//主路灯 assign?main_yellow=main_yellow_led?;//主路灯 assign?branch_red=branch_red_led;//支路灯 assign?branch_green=branch_green_led;//支路灯 assign?branch_yellow=branch_yellow_led?;//支路灯? //分频模块 div?div100 ( .?clk(clk), .?clk_out(clk_1Hz) ); //定义路口个灯持续时间,修改此处时间 //主路绿灯+主路黄灯=支路红灯时间 //支路绿灯+支路黄灯=主路红灯时间 wire?[7:0]main_green_time; wire?[7:0]main_yellow_time; wire?[7:0]branch_green_time; wire?[7:0]branch_yellow_time;
点击链接获取代码文件:http://www.hdlcode.com/index.php?m=home&c=View&a=index&aid=1102