目录
一、六位流水灯
代码实现分为三阶段:
-
复位阶段: 当
rst_n
为低电平时,模块复位。计数器cnt_1s
清零。LED 状态led
初始化为6'b000001
(第一个 LED 亮,其余灭)。 -
正常运行阶段: 当
rst_n
为高电平时,模块开始工作:LED 状态向左循环移位一次。当计数器达到TIME_1s - 1
时:end_cnt_1s
信号变为1
,触发 LED 状态更新。计数器清零。计数器cnt_1s
在每个时钟上升沿加 1。 -
**循环流水灯效果:**LED 状态每 1 秒更新一次,依次向左移动,形成流水灯效果。
具体代码如下:
module led (
input clk, // 时钟信号
input rst_n, // 复位信号(低电平有效)
output reg[5:0] led // 6位LED输出
);
parameter TIME_1s = 50_000_000; // 1秒的时间常数(假设时钟频率为25MHz)
reg [30-1:0] cnt_1s ; // 30位宽的计数器
wire add_cnt_1s , end_cnt_1s ; // 计数器使能信号和结束信号
// 计数器逻辑
always @(posedge clk or negedge rst_n)
if (!rst_n)
cnt_1s <= 30'b0; // 复位时计数器清零
else if (add_cnt_1s )
if (end_cnt_1s )
cnt_1s <=30'b0; // 计数器达到1秒时清零
else
cnt_1s <= cnt_1s +1'd1; // 计数器加1
else
cnt_1s <= cnt_1s ; // 保持计数器值
assign add_cnt_1s = 1'b1; // 计数器始终使能
assign end_cnt_1s = add_cnt_1s && (TIME_1s-1 == cnt_1s ); // 计数器达到1秒时结束信号为1
// LED控制逻辑
always @(posedge clk or negedge rst_n)
if(!rst_n)
led <= 6'b000001; // 复位时第一个LED亮,其余灭
else if(end_cnt_1s)
led <= {led[4:0], led[5]}; // 每1秒LED向左循环移位一次
else
led <= led; // 保持LED状态
endmodule
实现效果如下:
6位流水灯
二、按键控制流水灯
按键按下时流水灯停止移动,再次按下时恢复移动。
-
按键输入信号
key
:按键按下时为低电平(0
),松开时为高电平(1
)。 -
暂停状态寄存器
pause
:用于控制流水灯的移动。当pause
为1
时,流水灯停止移动;当pause
为0
时,流水灯继续移动。 -
按键处理逻辑 :在时钟上升沿检测按键状态,如果按键按下(
key
为低电平),则切换pause
的状态。 -
LED控制逻辑 :在
end_cnt_1s
为1
且pause
为0
时,流水灯才会移动。module led (
input clk, // 时钟信号
input rst_n, // 复位信号(低电平有效)
input key, // 按键信号(按下为低电平)
output reg[5:0] led // 6位LED输出
);parameter TIME_1s = 50_000_000; // 1秒的时间常数(假设时钟频率为25MHz) reg [30-1:0] cnt_1s ; // 30位宽的计数器 wire add_cnt_1s , end_cnt_1s ; // 计数器使能信号和结束信号 reg pause; // 暂停状态寄存器 // 计数器逻辑 always @(posedge clk or negedge rst_n) if (!rst_n) cnt_1s <= 30'b0; // 复位时计数器清零 else if (add_cnt_1s ) if (end_cnt_1s ) cnt_1s <=30'b0; // 计数器达到1秒时清零 else cnt_1s <= cnt_1s +1'd1; // 计数器加1 else cnt_1s <= cnt_1s ; // 保持计数器值 assign add_cnt_1s = 1'b1; // 计数器始终使能 assign end_cnt_1s = add_cnt_1s && (TIME_1s-1 == cnt_1s ); // 计数器达到1秒时结束信号为1 // 按键处理逻辑 always @(posedge clk or negedge rst_n) if (!rst_n) pause <= 1'b0; // 复位时暂停状态为0(流水灯移动) else if (!key) // 按键按下(低电平有效) pause <= ~pause; // 切换暂停状态 // LED控制逻辑 always @(posedge clk or negedge rst_n) if(!rst_n) led <= 6'b000001; // 复位时第一个LED亮,其余灭 else if(end_cnt_1s && !pause) // 只有在不暂停时才会移动LED led <= {led[4:0], led[5]}; // 每1秒LED向左循环移位一次 else led <= led; // 保持LED状态
endmodule
实现效果如下:
按键控制流水灯
总结
从简单的流水灯入手,开始逐步对verilog语言有更深入的了解。