程序简介:该模块实现经典的流水灯效果,8个LED以0.5秒间隔依次左移
module led_run(
Clk, // 输入时钟信号
Reset_n, // 低电平有效的复位信号
Led // 8位LED输出,控制LED灯状态
);
input Clk;
input Reset_n;
output reg [7:0] Led; // 寄存器类型输出,用于存储LED状态
reg [24:0] counter; // 25位计数器,用于时钟分频(最大计数值25_000_000)
// 计数器控制逻辑:每个时钟上升沿或复位下降沿触发
always@(posedge Clk or negedge Reset_n)
if(!Reset_n) // 复位信号有效时
counter <= 0; // 计数器清零
else if(counter == 24_999_999) // 达到预设计数值(0.5秒@50MHz)
counter <= 0; // 计数器归零,重新开始计数
else
counter <= counter + 1'b1; // 计数器递增
// LED状态控制逻辑:每个时钟上升沿或复位下降沿触发
always@(posedge Clk or negedge Reset_n)
if(!Reset_n) // 复位信号有效时
Led <= 8'b0000_0001; // 初始化LED状态(最右侧灯亮)
else if(counter == 25'd24_999_999) begin // 达到预设计数值时更新LED
if(Led == 8'b1000_0000) // 检测是否到达最左侧位置
Led <= 8'b0000_0001; // 循环复位至最右侧
else
Led <= Led << 1; // 未到达最左侧时左移一位
/* 备选循环移位方案(保留注释供参考):
Led <= {Led[6:0], Led[7]}; */
end
else // 未达到计数值时
Led <= Led; // 保持当前LED状态
endmodule
注释说明:
1. 模块接口
(1) Clk:系统时钟输入,典型值50MHz。
(2) Reset_n:低电平复位信号,0有效,1释放。
(3) Led:8位寄存器输出,每位直接驱动一个LED灯,Led灯默认为共阴极,也就是值为1时点亮。
2. 计数器设计
(1)位宽选择:25位计数器,reg [24:0]。
(2)定时计算:
当Clk=50MHz时,周期=20ns
计数值24,999,999对应0.5秒((24,999,999+1)*20ns = 500,000,000ns)
减少仿真时间:注释24_999用于仿真快速验证(缩减5000倍时间)
3. LED控制逻辑
(1) 复位状态:8'b0000_0001初始化最右侧LED点亮
(2)移位模式:
普通左移:Led << 1
边界检测:当最高位亮时(即8'b1000_0000)复位至最右侧
备选方案:循环移位`{Led[6:0], Led[7]}`可实现硬件环形移位(当前注释保留)