任务要求流水灯:驱动板上LED1 ~LED8按如下2个模式循环闪烁:
① 每个灯亮1s灭1s,从右至左依次闪烁,共8次
② 每个灯亮1s灭0.5s,从左至右间隔闪烁,共4次
求朋友们检查一下下面代码还有没有什么大的缺陷
`timescale 1ns / 1ns
module ledflow(
input sys_clk , //系统时钟
input sys_rst_n, //系统复位,低电平有效
output reg [7:0] led //8个LED灯
);
//reg define
reg [31:0] counter1, counter2;
reg [31:0] cnt;
reg led_control;
reg [7:0] led1,led2;
//*****************************************************
//** main code
//*****************************************************
//计数器counter1对系统时钟计数,计时2秒,对应状态1,1s左移1s灭
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
counter1 <= 32'd0;
else if(!led_control)//led_control==0为状态1
if (counter1 < 32'd200_000_000)//系统时钟100M,计数器计200M次即2s
counter1 <= counter1 + 1'b1;
else
counter1 <= 32'd0;
else
counter1 <= 32'd0; //状态2时,counter1置零不计数
end
//计数器counter2计数1.5秒,对应状态2,1s右移0.5s灭
always @ (posedge sys_clk or negedge sys_rst_n) begin
// begin your code here
if (!sys_rst_n)
counter2 <= 32'd0;
else if(led_control) begin // led_control==1为状态2
if (counter2 < 32'd150_000_000) // 系统时钟100M,计数器计150M次即1.5s
counter2 <= counter2 + 1'b1;
else
counter2 <= 32'd0;
end
else
counter2 <= 32'd0; // 状态1时,counter2置零不计数
// end your code here
end
//一轮用时:状态1每个灯用时2s,亮一轮8个灯即16s+状态2每个灯用时1.5s,间隔亮两轮4个灯即6s=22秒
always @ (posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)
cnt<=32'd0;
else if(cnt<32'd2200_000_000)
cnt<=cnt+1;
else
cnt<=0;
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
led_control <= 0;
// begin your code here
else begin
if (cnt >= 16 * 110_000_000) // 1-16s为状态1,即led_control=0
led_control <= 1; // 16s后进入状态2
if (cnt >= 22 * 110_000_000) // 17-22s为状态2,即led_control=1
led_control <= 0; // 22s后重新进入状态1
end
// end your code here
end
//移位寄存器led1,2s左移1次
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)
led1<=8'b00000001;
else if (!led_control) begin
if (counter1 == 32'd200_000_000)
led1 <= {led1[6:0], 1'b0}; //左移1位
else
led1 <= led1;
end
else led1 <= {led2[7], led2[7:1]};//状态2时led1就在led2基础上左移,状态转换时即可无缝衔接
end
//移位寄存器led2,1.5s右移2位
always @(posedge sys_clk or negedge sys_rst_n) begin
// begin your code here
if(!sys_rst_n)
led2 <= 8'b10000000;
else if (led_control) begin // 状态2时向右移动
if (counter2 == 32'd150_000_000)
led2 <= led2 >> 2; // 右移2位
else
led2 <= led2;
end
else
led2 <= led2; // 状态1时led2保持不变
// end your code here
end
//根据led_control给输出LED赋值
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
led <= 8'b00000001;
else case (led_control)
0 : begin // 进入状态1时
if (cnt >= 32'd0 && cnt < 16 * 110_000_000) // 1-16s为状态1,每个灯用时2s
led <= led1;
else if (cnt >= 16 * 110_000_000 && cnt < 22 * 110_000_000) // 17-22s为状态2,每个灯用时1.5s
led <= led2;
end
1 : begin // 进入状态2时
if (cnt >= 16 * 110_000_000 && cnt < 22 * 110_000_000) // 17-22s为状态2,每个灯用时1.5s
led <= led2;
else if (cnt >= 22 * 110_000_000 && cnt < 38 * 110_000_000) // 间隔亮两轮4个灯即6s
led <= led1;
end
default : led <= led;
endcase
end
endmodule