基于FPGA的交通灯设计规范
一、功能描述:
本设计实现一个交通信号灯,具体功能如下:
1.异步信号复位,复位后1组为红灯亮2组为绿灯亮,数码管显示从24开始
依次递减计数
2.实现红黄绿灯的延时交替亮灭,分两组灯,1组红灯亮时,2组为黄灯,5
秒后,1组红灯亮,2组绿灯亮;25秒后,1组黄灯亮,2组红灯亮;5秒后,1组绿灯亮,2组红灯亮。
如此交替重复
3.计时时间25秒、5秒显示在数码管上。
分别为:从24依次递减到0,从4
依次递减到0
二、输入输出信号描述:
系统结构框图
顶层模块说明:
1、fenpin:将50MHz晶振转为1Hz作为时钟频率;
2、delay:计数延时;
3、state:指出状态转移顺序;
4、shuma:将计数延时用数码管输出显示。
设计说明:
设计分为分频、延时、状态机、数码管显示四个模块。
分频,将50MHz的系统时钟转为1Hz。
计数延时,让状态机能在合适的时间点进行状态切换。
状态机,完成状态间的切换,输出。
数码管显示,将延时模块的计时输出值转换为数码管输出显示。
状态机的输出状态信号标志flag=out[1]|out[4],即为:判断此时的两组输出是否有黄灯亮。
flag_data=flag,作为计数延时模块的输入,用状态信号标志flag_data和计数值cnt来共同控制计数模块是5秒还是25秒。
四、子模块描述:
4.1、fenpin:分频模块
1、功能描述
将实验板上的50MHz的石英晶振频率转为1Hz。
2、管脚描述
每当clock时钟上升沿来临时,内部寄存器sum从0递加,加至25000000时,对clk进行取反操作,则可得到频率为1Hz的clk时钟
4.2、delay:延时模块
1、功能描述
计数延时,让状态机能在合适的时间点进行状态切换。
用计数值和状态信号标志的与结果(cnt==0 && flag_data)来判断计数延时的初始值应为24还是4
4.3、state:状态机模块
1、功能描述
完成状态间的切换,输出。
状态信号标志flag=out[1]|out[4]。
即为检测当前是否有黄灯亮。
注:out[5:3]对应1组灯的:红黄绿
out[2:0]对应2组灯的:红黄绿
4.4、shuma:数码管显示模块
1、功能描述
将延时模块的计时输出值转换为数码管输出显示。
将m1对10取整接入数码管的十位,m2对10取余接入数码管的个位。
五、验证方案:
1、结果验证
将程序下载至实验板,观测其数码管计数显示和两组灯的亮灭变化。
2、复位验证
下载到实验板,让其运行一段时间,进行复位,观测变化。
3、仿真验证
六、实验截图:
图1:仿真综合
图2:管脚分配
七、源程序代码:
顶层模块:
module traffic_light(clock,rst,out,m1,m2);
input clock,rst;
output [5:0]out;
output[6:0]m1,m2;
wire [4:0] x;
wire y;
fenpin F(.clock(clock),.rst(rst),.clk(clk));
delay D(.clk(clk),.flag_data(y),.rst(rst),.cnt(x)); state S(.in(x),.rst(rst),.flag(y),.clk(clk),.out(out)); shuma M(.data(x),.rst(rst),.m1(m1),.m2(m2)); endmodule
分频模块:
module fenpin(clock,rst,clk);
input clock,rst;
output clk;
reg clk;
reg [25:0]sum;
always@(posedge clock or negedge rst)
begin
if(!rst)
begin
clk<='b0;
sum=0;
end
else if(sum==25000000)
begin
clk<=~clk;
sum<=0;
end
else sum<=sum+1;
end
endmodule
延时模块:
module delay(clk,flag_data,rst,cnt);
input clk,rst,flag_data;
output[4:0]cnt;
reg[4:0]cnt;
always@(posedge clk or negedge rst)
begin
if(!rst)cnt<='d24;
else if(cnt==0 && flag_data==0)cnt<='d4;
else if(cnt==0 && flag_data) cnt<='d24;
else cnt<=cnt-5'b1;
end
endmodule
状态机模块:
module state(clk,in,rst,flag,out);
input clk,rst;
input[4:0]in;
output [5:0]out;
output flag;
reg [5:0]out;
reg[3:0]state;
assign flag=out[1]|out[4];
parameter r1_g2or1_2_y=6'b100010,r1_y2og1_r2=6'b001100, g1_r2oy1_r2=6'b010100,y1_r2or1g2=6'b100001,
A='b0001,B='b0010,C='b0100,D='b1000;
always@(posedge clk or negedge rst)
begin
if(!rst)
begin
state<=A;
out<=y1_r2or1_g2;
end
else
begin
case(state)
A: begin
if(in==0 && flag==0)
begin
state<=B;
out<=r1_g2or1_2_y;
end
else
state<=A;
end
B: begin
if(in==0 && flag)
begin
state<=C;
out<=r1_y2og1_r2;
end
else
state<=B;
end
C: begin
if(in==0 && flag==0)
begin
state<=D;
out<=g1_r2oy1_r2;
end
else
state<=C;
end
D: begin
if(in==0 && flag)
begin
state<=A;
out<=y1_r2or1_g2;
end
else
state<=D;
end
default:state<=A;
endcase
end
end
endmodule
数码管显示模块:
module shuma(data,rst,m1,m2);
input rst;
input[4:0]data;
output[6:0]m1,m2;
reg[6:0]m1,m2;
reg[3:0]n1,n2;
reg[7:0]db[9:0];
parameter
db[0]=7'b1000000;db[1]=7'b1111001;db[2]=7'b0100100;db[3]=7'b0110000;db[4]=7'b0011001; db[5]=7'b0010010;db[6]=7'b0000010;db[7]=7'b1111000;db[8]=7'b0000000;db[9]=7'b0010000; always@(data)
begin
if(!rst)
begin
m1<=db[0];
m2<=db[0];
end
else
begin
n1<=data/'d10;
n2<=data%'d10;
m1<=db[n1];
m2<=db[n2];
end
end
endmodule。