目录

一、设计要求

二、模块总和

三、模块设计

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:

总结

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

文章来源

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: