Verilog设计交通信号灯

目录

一、设计要求

二、模块总和

三、模块设计

1.顶层模块

2.分频模块

3.计数模块

4.状态机模块

5.倒计时模块

6.数码显示模块

7.约束代码

四、引脚分配

五、板上测试

总结

一、设计要求

1.利用 NEXYS4 DDR 开发板设计一款交通灯控制系统,能够显示红、黄、绿灯;
2.交通灯控制系统具有秒表倒计时功能;

3.我通过修改led六个分别表示主干道红绿黄和支干道红绿黄

4.信号灯设计时间

主干道绿灯,支干道红灯 30s
主干道红灯,支干道黄灯 5s
主干道红灯,支干道绿灯 30s
主干道黄灯,支干道红灯 5s

二、模块总和

Verilog设计交通信号灯_第1张图片

三、模块设计

1.顶层模块

module top(
	input clk,
	input rst_n,
	output [7:0]sel,
	output [7:0]seg,
	output [5:0]led
	);
wire clk_1s;
wire [6:0]cnt;
wire [3:0]en1,en2;
 div div(
	.clk(clk),
	.rst_n(rst_n),
	.clk_1s(clk_1s)
    );
 counter counter(
	.clk(clk_1s),
	.rst_n(rst_n),
	.cnt(cnt)
    );
 vlg_traffic a1(
	.clk(clk),
	.rst_n(rst_n),
	.cnt(cnt),
	.led(led)
    );
 countdown countdown(
	.clk(clk),
	.rst_n(rst_n),
	.cnt(cnt),
	.en1(en1),
	.en2(en2) 
    );
 digital digital(
	.clk(clk),
	.rst_n(rst_n),
	.en1(en1),
	.en2(en2),
	.sel(sel),
	.seg(seg) 
);
endmodule

2.分频模块

module div(
	input clk,
	input rst_n,
	output  reg clk_1s//1s
    );

reg[29:0]count1;//计数1s
//1s计数
always @(posedge clk or negedge rst_n)
	if(!rst_n)
		count1 <= 1'b0;

	else if(count1 == 49999999)//计数器1完成0.5s计数
		count1 <= 1'b0;
	else
		count1 <= count1 + 1'b1;
//1s分频
always @(posedge clk or negedge rst_n)
	if(!rst_n)
		clk_1s <= 0;
	else if(count1 == 49999999)
		clk_1s <= ~clk_1s;//时钟100Mhz 完成1s分频
	else 
		clk_1s <= clk_1s;

	endmodule

3.计数模块

module counter(
	input clk,
	input rst_n,
	output reg [6:0]cnt//实现70s红绿黄灯
    );

always @(posedge clk or negedge rst_n)
	if(!rst_n)
		cnt <= 0;
	else if(cnt == 7'd70)
			cnt <= 0; 
    else 
		cnt <= cnt + 1;
endmodule

4.状态机模块

module vlg_traffic(
	input clk,
	input rst_n,
	input  [6:0]cnt,
	output reg [5:0]led//led[5]主干道黄灯 led[4]主干道红灯 led[3]主干道绿灯 
					   //led[2]支干道黄灯 led[1]支干道红灯 led[0]支干道绿灯
    );

reg [3:0]state;	

parameter s0 = 4'b00001;//s0:主干道绿灯,支干道红灯 30s 灯6'b001_010
parameter s1 = 4'b00010;//s1:主干道黄灯,支干道红灯 5s  灯6'b100_010
parameter s2 = 4'b00100;//s2:主干道红灯,支干道黄灯 5s  灯6'b010_100
parameter s3 = 4'b01000;//s3:主干道红灯,支干道绿灯 30s 灯6'b010_001

always @(posedge clk or negedge rst_n)
	if(!rst_n)
			state <= s0;
	else case(state)
		s0:begin
				if(cnt <= 7'd29)
					begin
						led <= 6'b001_010;
						state <= s0;
					end
				else 
					state <= s1;
			end
		s1:begin
				if((cnt > 7'd29)&&(cnt <= 7'd34))//用于板上显示从5s倒计时
					begin
						led <= 6'b100_010;
						state <= s1;
					end
				else 
					state <= s2;
			end 
			
		s2:begin
				if((cnt > 7'd34)&&(cnt <= 7'd39))
					begin
						led <= 6'b010_100;	
						state <= s2;
					end
				else 
						state <= s3;
			end
	   
		s3:begin 
				if((cnt > 7'd39)&&(cnt <= 7'd69))
					begin 
						led <= 6'b010_001;
						state <= s3;
					end	
				else
						state <= s0;

			end
		default:state <= s0;
		endcase
endmodule

5.倒计时模块

module countdown(
	input clk,
	input rst_n,
	input [6:0]cnt,
	output reg [3:0]en1,// 个位 最多为9 位宽为4
	output reg [3:0]en2 // 十位 最多为9 位宽为4 
    );

always @(posedge clk or negedge rst_n)
	if(!rst_n)
		begin
			en1 <= 0;
			en2 <= 0;
		end
	else if(cnt <= 7'd29)//用于板上从29s倒计时
		begin 
			en1 <= (29-cnt)%10;
			en2 <= ((29-cnt)-en1)/10; 
		end
	else if((cnt > 7'd29)&&(cnt <= 7'd34))//板上从4s倒计时
		begin 	
			en1 <= (34-cnt);
			en2 <= 0;
		end
	else if((cnt > 7'd34)&&(cnt <= 7'd39))//板上从4s倒计时
		begin 
			en1 <= (39-cnt);
			en2 <= 0;
		end
	else if((cnt > 7'd39)&&(cnt <= 7'd69))//板上从29s倒计时
		begin 
			en1 <= (69-cnt)%10;
			en2 <= ((69-cnt)-en1)/10;
		end
endmodule 

6.数码显示模块

module digital(
	input clk,
	input rst_n,
	input [3:0]en1,
	input [3:0]en2,
	output reg [7:0]sel,//片选信号
	output reg [7:0]seg //段选信号
);
//1ms计数器
	reg [16:0]cnt1;
	always @(posedge clk or negedge rst_n)
		if(!rst_n)
			cnt1 <= 0;
		else if(cnt1 == 99999)//1000000/10=100000
			cnt1 <= 0;
		else 
			cnt1 <= cnt1 + 1;
//1ms使能时钟控制信号	
	reg clk_1ms;
	always @(posedge clk or negedge rst_n)
		if(!rst_n)
			clk_1ms <= 0;
		else if(cnt1 == 99999)
			clk_1ms <= 1;
		else 
			clk_1ms <= 0;
//位选计数器
	reg [2:0]num_cnt;
	always @(posedge clk or negedge rst_n)
	if(!rst_n)
		num_cnt <= 0;
	else if(clk_1ms)
		num_cnt <= num_cnt + 1;
//板上位选信号	共阳极 低电平有效
	always @(posedge clk)
		case(num_cnt)
			0:sel <=8'b1111_1110;//个位
			1:sel <=8'b1111_1101;//十位
			2:sel <=8'b1111_1011;
			3:sel <=8'b1111_0111;
			4:sel <=8'b1110_1111;
			5:sel <=8'b1101_1111;
			6:sel <=8'b1011_1111;
			7:sel <=8'b0111_1111;
		endcase 
//数据分配	
	wire [31:0]data;
	assign data[3:0] = en1;
	assign data[7:4] = en2;
	assign data[11:8] = 0;
	assign data[15:12] = 0;
	assign data[19:16] = 0;
	assign data[23:20] = 0;
	assign data[27:24] = 0;
	assign data[31:28] = 0;
	
	reg [3:0]disp_tmp;
	always @(posedge clk)
		case(num_cnt)
			0:disp_tmp <= data[3:0];
			1:disp_tmp <= data[7:4];
			2:disp_tmp <= data[11:8];
			3:disp_tmp <= data[15:12];
			4:disp_tmp <= data[19:16];
			5:disp_tmp <= data[23:20];
			6:disp_tmp <= data[27:24];
			7:disp_tmp <= data[31:28];
		endcase 
		
//板上段选信号 共阳极 低电平有效	
	always @(posedge clk)
		case(disp_tmp)
			4'd0:seg <= 8'b1100_0000;
			4'd1:seg <= 8'b1111_1001;
			4'd2:seg <= 8'b1010_0100;
			4'd3:seg <= 8'b1011_0000;
			4'd4:seg <= 8'b1001_1001;
			4'd5:seg <= 8'b1001_0010;
	        4'd6:seg <= 8'b1000_0010;
			4'd7:seg <= 8'b1111_1000;
			4'd8:seg <= 8'b1000_0000;
			4'd9:seg <= 8'b1001_0000;
		endcase 
		
endmodule

7.约束代码

set_property IOSTANDARD LVCMOS33 [get_ports {led[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {sel[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {sel[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {sel[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {sel[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {sel[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {sel[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {sel[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {sel[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
set_property PACKAGE_PIN E3 [get_ports clk]
set_property PACKAGE_PIN C12 [get_ports rst_n]
set_property PACKAGE_PIN U13 [get_ports {sel[7]}]
set_property PACKAGE_PIN K2 [get_ports {sel[6]}]
set_property PACKAGE_PIN T14 [get_ports {sel[5]}]
set_property PACKAGE_PIN P14 [get_ports {sel[4]}]
set_property PACKAGE_PIN J14 [get_ports {sel[3]}]
set_property PACKAGE_PIN T9 [get_ports {sel[2]}]
set_property PACKAGE_PIN J18 [get_ports {sel[1]}]
set_property PACKAGE_PIN J17 [get_ports {sel[0]}]
set_property PACKAGE_PIN T10 [get_ports {seg[0]}]
set_property PACKAGE_PIN R10 [get_ports {seg[1]}]
set_property PACKAGE_PIN K16 [get_ports {seg[2]}]
set_property PACKAGE_PIN K13 [get_ports {seg[3]}]
set_property PACKAGE_PIN P15 [get_ports {seg[4]}]
set_property PACKAGE_PIN T11 [get_ports {seg[5]}]
set_property PACKAGE_PIN L18 [get_ports {seg[6]}]
set_property PACKAGE_PIN H15 [get_ports {seg[7]}]
set_property PACKAGE_PIN H17 [get_ports {led[0]}]
set_property PACKAGE_PIN K15 [get_ports {led[1]}]
set_property PACKAGE_PIN J13 [get_ports {led[2]}]
set_property PACKAGE_PIN N14 [get_ports {led[3]}]
set_property PACKAGE_PIN R18 [get_ports {led[4]}]
set_property PACKAGE_PIN V17 [get_ports {led[5]}]

四、引脚分配

Verilog设计交通信号灯_第2张图片

Verilog设计交通信号灯_第3张图片

Verilog设计交通信号灯_第4张图片

Verilog设计交通信号灯_第5张图片

五、板上测试

S0:

Verilog设计交通信号灯_第6张图片

S1:

Verilog设计交通信号灯_第7张图片

S2:

Verilog设计交通信号灯_第8张图片

S3:

Verilog设计交通信号灯_第9张图片

总结

进行顶层模块时钟分配的时候,千万不能分配错,不然容易导致时间不一致导致数码显示错误;除了计数70s模块使用1s分频时钟,其余模块都是使用的原时钟信号,数码显示模块内部进行使用了1ms时钟使能,利用视觉暂留,进行数码管的动态扫描。

你可能感兴趣的:(项目设计,开发语言,fpga开发,学习,课程设计,经验分享)