基于FPGA的交通信号灯实现 (verilog极简实现)

本文分享利用FPGA实现的交通信号灯,FPGA型号为野火征途Pro开发板,具体功能如下:

此项目旨在模拟东西和南北两路口交通信号灯,初始态两路口均为红灯亮,接着,东西路口绿灯亮,南北路口红灯亮,数码管同时显示15秒倒计时,当倒计时时间小于3秒,东西路口绿灯灭,黄灯开始闪烁。黄灯闪烁若干次,即当倒计时结束,东西路口红灯亮同时南北路口绿灯亮,数码管重新赋值15秒倒计时,同理当倒计时时间小于3秒,南北路口绿灯熄灭,黄灯闪烁,闪烁若干次至倒计时结束,不断重复上述操作。

[5:0]LED输出解释:6位数据从高到底依次表示东西路口的绿灯,黄灯和红灯,例如:输出100001即东西路口绿灯亮,红黄不亮,南北口红灯亮,绿黄不亮。

分频模块 div_2hz

首先设计需要秒为单位的倒计时,本文使用的开发板输出系统时钟为50Mhz,因此需要进行分频。为后续对黄灯闪烁的精确控制,1秒需要亮灭两个过程,所以设计2hz分频模块,即0.5秒为一个时钟周期。

module div_2hz(
		input sys_clk, //50Mhz系统时钟
		input sys_rst_n, //复位信号
		output reg clk_2hz //2hz分频输出信号
);

reg [24:0]num_2hz; //定义reg型信号存储当前计数值
parameter num1=12_499_999; //定义常量 后面计数器的最大值,即计0-12_499_999共计12_500_000个数

//12_500_000计数器  因为需要得到2hz频率,需要对50Mhz进行分频,同时输出时钟占空比50%,即计数最大值为分频数一半
always@(posedge sys_clk or negedge sys_rst_n)
	if(!sys_rst_n)
		num_2hz<=25'd0;
	else if(num_2hz==num1)
		num_2hz<=25'd0;
	else
		num_2hz<=num_2hz+1;
	
//当达到计数最大值,对输出信号进行反转,得到2hz时钟输出	
always@(posedge sys_clk or negedge sys_rst_n) 
	if(!sys_rst_n)
		clk_2hz<=1'b1;
	else if(num_2hz==num1)
		clk_2hz<=~clk_2hz;
	
endmodule

交通信号灯模块 tra_sign

本模块为项目的核心,利用状态机实现交通信号灯功能以及数码管倒计时的显示。模块输入为2hz分频时钟以及系统复位信号,输出为[5:0]LED信号以及倒计时时间信号。

定义五个状态s0-s4,s0代表初始复位态,此时默认交通信号灯全灭;

s1状态表示东西路口绿灯,南北路口红灯;

s2状态表示东西路口黄灯闪烁,南北路口红灯;

s3状态表示东西路口红灯,南北路口绿灯;

s4状态表示东西路口红灯,南北路口黄灯闪烁;

此模块难点在于倒计时时间与交通信号灯的同步,这里采用always@(*)的组合逻辑方法,具体原理详见下述解释

module tra_sign (
		input clk_2hz, //2hz分频时钟
		input sys_rst_n,
		output reg[5:0]led, //模拟交通灯的6位数据
		output [4:0]num2 //倒计时数据输出
);

reg [4:0]num1;
reg [2:0]state;

//定义5个状态
parameter s0=3'd0;
parameter s1=3'd1;
parameter s2=3'd2;
parameter s3=3'd3;
parameter s4=3'd4;

//时序逻辑:数据30-1不断地循环倒数,实质每倒数两次位1s
always@(posedge clk_2hz or negedge sys_rst_n)
	if(!sys_rst_n)
		num1<=5'd30;
	else if(num1==1)
		num1<=5'd30;
	else
		num1<=num1-1;

//组合逻辑:num2为倒计时时间,其赋值需要进行双重判断,首先num1不能为30,否则相当于上个30个数倒数结束,15秒倒计时结束,应当给num2倒计时时间重新赋值15。在num1不为30条件下进行取余判断,因为num1倒数两次才为1s,两条件均满足,将此时倒计时时间(num1/2)立即赋值num2
assign num2=(num1!=30)?((num1%2==0)?num1/2:num2):15;

//组合逻辑:每个状态下将交通信号灯信号[5:0]LED赋对应值
always@(*)
	if(!sys_rst_n)
		led<=6'b000_000;
	else if(state==s1)
		led<=6'b100_001;
	else if(state==s2) //s2状态黄灯需要闪烁,此时凸显出num1的作用,对其进行奇偶判断进行亮灭赋值
		if(num1%2==0)
			led<=6'b010_001;
		else
			led<=6'b000_001;
	else if(state==s3)
		led<=6'b001_100;
	else if(state==s4) //s4同上s2
		if(num1%2==0)
			led<=6'b001_010;
		else
			led<=6'b001_000;
		

//组合逻辑:5个状态转换条件的描述		
always@(*)
	if(!sys_rst_n)
		state<=s0;
	else case(state)
	s0:state<=s1; //s0复位态无条件转s1
	s1:
		if(num2<=3) //s1状态当倒计时小于等于3秒转移s2
			state<=s2;
		else 
			state<=state;
	s2:
		if(num2==15)  //若一轮倒计时结束,则状态转换
			state<=s3;
		else
			state<=state;
	s3:
		if(num2<=3) //s3状态当倒计时小于等于3秒转移s4
			state<=s4;
		else 
			state<=state;
	s4:
		if(num2==15) //若一轮倒计时结束,则状态转换
			state<=s1;
		else
			state<=state;
	default:state<=state;
	endcase
	
endmodule	

交通信号灯测试文件  tra_sign_tb

`timescale 1ns/1ns
module tra_sign_tb();

reg sys_rst_n;
reg clk_2hz;
wire [5:0]led;
wire [4:0]num2;

 initial begin
 clk_2hz = 1'b1;
 sys_rst_n <= 1'b0;
 #20
 sys_rst_n <= 1'b1;
 end
 
 always #10 clk_2hz = ~clk_2hz;

 
 tra_sign tra_sign_inst(
		.clk_2hz(clk_2hz),
		.sys_rst_n(sys_rst_n),
		.led(led),
		.num2(num2)
);
 endmodule

仿真结果:

仿真图中复位状态此时交通信号灯全灭,对应LED为000000,当复位结束时,num2从0111开始自减即15秒倒计时开始。此时为s1状态即LED输出100001,即东西口绿灯,南北口红灯

当倒计时时间小于等于3秒,即num2为0011开始,进入s2状态,此时东西口绿灯灭,黄灯进行闪烁,1s进行一个亮灭周期。LED输出010001和000001,当一轮倒计时结束,num2重新赋值15进行新一轮倒计时,进入s3状态,此时东西口红灯,南北口绿灯,LED输出001100

当倒计时再次小于等于3秒,此时南北口绿灯灭,黄灯进行1s亮灭周期闪烁,即前0.5s亮后0.5秒灭,当15秒倒计时再次结束,num2重新赋值,如此循环往复。

本文利用一个时序逻辑多个组合逻辑,避免了时序逻辑混乱造成的时钟沿对齐困难等问题,达到交通灯功状态转换以及同步倒计时功能。

至此借助modelsim模拟交通灯功能完毕,后面会将完整烧录程序分享。

如有表达不准确或错误处,多多谅解,后面会不断分享项目设计

本实验设计一个十字路口的交通灯控制器,分为东西和南北两个部分。每个部分有五盏灯,分别为左转灯、直行灯、右转灯、人行道灯及黄灯,另外还有一个倒计时器。左转灯、直行灯、右转灯、人行道灯亮表示允许通行,灯灭表示禁止通行;黄灯亮表示即将有信号灯的状态发生改变;倒计时显示了到下一状态的时间。 2.状态表(0表示灯灭,1表示灯亮) 时间度量 东西方向  南北方向 东西方向 南北方向 t/s ← ↑ → 行人 黄 ← ↑ → 行人 黄 倒计时/s 倒计时/s 0~13 0 1 1 0 0 0 0 0 0 0 13 45 13~15 0 1 1 0 1 0 0 0 0 0 2   15~28 0 1 0 1 0 0 0 0 0 0 13   28~30 0 1 0 1 1 0 0 0 0 0 2   30~43 1 0 0 0 0 0 0 0 0 0 13   43~45 1 0 0 0 1 0 0 0 0 0 2   45~58 0 0 0 0 0 0 1 1 0 0 45 13 58~60 0 0 0 0 0 0 1 1 0 1   2 60~73 0 0 0 0 0 0 1 0 1 0   13 73~75 0 0 0 0 0 0 1 0 1 1   2 75~88 0 0 0 0 0 1 0 0 0 0   13 88~90 0 0 0 0 0 1 0 0 0 1   2 3.状态图(低电平表示灯灭,高电平表示灯亮) 4.顶层设计图 如图所示,交通灯控制器主要分为三个模块,交通灯状态控制,交通灯显示和倒计时。交通灯状态控制模块:接受频率为1Hz的时钟信号,根据该信号进行处理,对交通灯显示和倒计时模块给出相应的状态编号(12个状态)。交通灯显示模块:通过相应的状态设置两组交通灯的亮灭。倒计时模块:通过相应的状态确定倒计时的基数及显示。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值