具体要求:
1.东南西北四个方向分别有4个交通灯,led_east[2:0],led_south[2:0],led_west[2:0],led_north[2:0].
2.复位时,所有方向都是绿灯亮.
3.复位后,每个方向都按绿灯>黄灯>红灯的顺序依次变亮,其中,东面的灯变换的间隔时间为1s,西面间隔为2s,南面的间隔为3s,北面的间隔为4s。
固定参数:
clk:系统时钟为50mhz。也就是说1s为50_000_000个脉冲。2s就为100_000_000个脉冲.
rst_n: 复位信号。
cnt1-4:计数器,分别记1到4秒。
time_1-4s: 1s到4s。
具体代码:
其中,初始led[2:0] = 3'b100. led[2]=绿灯,led[1]=黄灯,led[0]=红灯。 1为亮,0为灭。
module liushuideng(
input clk,
input rst_n,
output [2:0] dout_east,
output [2:0] dout_south,
output [2:0] dout_west,
output [2:0] dout_north,
output [2:0] yimiao,
output [2:0] liangmiao,
output [2:0] sanmiao,
output [2:0] simiao
);
reg [2:0] led_east ;
reg [2:0] led_south ;
reg [2:0] led_west ;
reg [2:0] led_north ;
parameter t1 = 50_000_000 - 1;
parameter t2 = 100_000_000 - 1;
parameter t3 = 150_000_000 - 1;
parameter t4 = 200_000_000 - 1;
reg [2:0] time_1s;
reg [2:0] time_2s;
reg [2:0] time_3s;
reg [2:0] time_4s;
reg [25:0] cnt1;
reg [26:0] cnt2;
reg [27:0] cnt3;
reg [27:0] cnt4;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt1 <= 0;
else if (cnt1 == t1)
cnt1 <= 0;
else
cnt1 <= cnt1 + 1;
end
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt2 <= 0;
else if (cnt2 == t2)
cnt2 <= 0;
else
cnt2 <= cnt2 + 1;
end
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt3 <= 0;
else if (cnt3 == t3)
cnt3 <= 0;
else
cnt3 <= cnt3 + 1;
end
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt4 <= 0;
else if (cnt4 == t4)
cnt4 <= 0;
else
cnt4 <= cnt4 + 1;
end
always @ (posedge clk or negedge rst_n)begin
if (!rst_n)
time_1s <= 0;
else if (cnt1 == t1)
time_1s = time_1s + 1;
else if(time_1s == 1)
time_1s <= 0;
end
always @ (posedge clk or negedge rst_n)begin
if (!rst_n)
time_2s <= 0;
else if (cnt2 == t2)
time_2s = time_2s + 1;
else if(time_2s == 1)
time_2s <= 0;
end
always @ (posedge clk or negedge rst_n)begin
if (!rst_n)
time_3s <= 0;
else if (cnt3 == t3)
time_3s = time_3s + 1;
else if(time_3s == 1)
time_3s <= 0;
end
always @ (posedge clk or negedge rst_n)begin
if (!rst_n)
time_4s <= 0;
else if (cnt4 == t4)
time_4s = time_4s + 1;
else if(time_4s == 1)
time_4s <= 0;
end
always @(negedge clk or negedge rst_n) begin
if (!rst_n) begin
led_east <= 3'b100;
end
else if(time_1s == 1)
led_east <= {led_east[0],led_east[2:1]};
else begin
led_east <= led_east;
end
end
assign dout_east = led_east;
always @(negedge clk or negedge rst_n) begin
if (!rst_n)
led_west <= 3'b100;
else if(time_2s == 1)
led_west <= {led_west[0],led_west[2:1]};
else
led_west <= led_west;
end
assign dout_west = led_west;
always @(negedge clk or negedge rst_n) begin
if (!rst_n)
led_south <= 3'b100;
else if(time_3s == 1)
led_south <= {led_south[0],led_south[2:1]};
else
led_south <= led_south;
end
assign dout_south = led_south;
always @(negedge clk or negedge rst_n) begin
if (!rst_n)
led_north <= 3'b100;
else if(time_4s == 1)
led_north <= {led_north[0],led_north[2:1]};
else
led_north <= led_north;
end
assign dout_north = led_north;
assign yimiao = time_1s;
assign liangmiao = time_2s;
assign sanmiao = time_3s;
assign simiao = time_4s;
endmodule
仿真模块:
module jiaotongdeng_m();
reg clk ;
reg rst_n ;
wire [2:0] dout_east ;
wire [2:0] dout_south ;
wire [2:0] dout_west ;
wire [2:0] dout_north ;
wire [2:0] yimiao;
wire [2:0] liangmiao;
wire [2:0] sanmiao;
wire [2:0] simiao;
initial begin
clk = 0;
rst_n = 0;
#200
rst_n = 1;
end
always #10 clk = ~clk;
liushuideng liushuideng_u(
.clk (clk) ,
.rst_n (rst_n) ,
.dout_east (dout_east) ,
.dout_west (dout_west) ,
.dout_south (dout_south) ,
.dout_north (dout_north),
.yimiao (yimiao),
.liangmiao (liangmiao),
.sanmiao (sanmiao),
.simiao (simiao)
);
endmodule
仿真结果:
运用的仿真软件为vivado.2019版本。为了方便仿真,我设置t1=10-1个,意思是10个脉冲为1s,1个时钟周期为20ns,那么此时的1s为200ns。就是1s=200ns,那么从仿真结果来看,东边的灯每过200ns,也就是1s,变换一次,西边的则是每过400ns,也就是2s,变换一次。剩下的南边和北边也是如此。
作为一个刚刚接触fpga的小白,有很多的不足,如有错误,或者更好的办法,请大家指正,感谢!!!