目录
一、设计要求
二、模块总和
三、模块设计
1.顶层模块
2.分频模块
3.计数模块
4.状态机模块
5.倒计时模块
6.数码显示模块
7.约束代码
四、引脚分配
五、板上测试
总结
一、设计要求
1.利用 NEXYS4 DDR 开发板设计一款交通灯控制系统,能够显示红、黄、绿灯;
2.交通灯控制系统具有秒表倒计时功能;
3.我通过修改led六个分别表示主干道红绿黄和支干道红绿黄
4.信号灯设计时间
主干道绿灯,支干道红灯 30s
主干道红灯,支干道黄灯 5s
主干道红灯,支干道绿灯 30s
主干道黄灯,支干道红灯 5s
二、模块总和
三、模块设计
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]}]
四、引脚分配
五、板上测试
S0:
S1:
S2:
S3:
文章来源:https://www.toymoban.com/news/detail-517951.html
总结
进行顶层模块时钟分配的时候,千万不能分配错,不然容易导致时间不一致导致数码显示错误;除了计数70s模块使用1s分频时钟,其余模块都是使用的原时钟信号,数码显示模块内部进行使用了1ms时钟使能,利用视觉暂留,进行数码管的动态扫描。文章来源地址https://www.toymoban.com/news/detail-517951.html
到了这里,关于Verilog设计交通信号灯的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!