1. LED流水灯
任务目标
在FPGA开发板上驱动8个LED,实现依次点亮并循环流动的效果。核心是掌握计数器分频产生时序节拍,以及用移位寄存器或译码逻辑驱动多路输出。
硬件与依赖
- 开发板:任意主流FPGA开发板(如Altera Cyclone IV / Xilinx Artix-7)
- 时钟:板载50MHz有源晶振
- 输出:8个LED,低电平点亮(若为高电平点亮,反转代码中的赋值即可)
- 工具:Quartus II / Vivado / 开源链(Icarus Verilog + yosys)均可综合
核心代码
module led_water(
input clk, // 50MHz
input rst_n, // 低电平复位
output reg [7:0] led
);
// 计数器:50MHz / 2^24 ≈ 2.98Hz,即每个LED约亮0.336s
reg [23:0] cnt;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
cnt <= 24'd0;
else
cnt <= cnt + 1'b1;
end
// 取计数器最高3位作为LED译码输入
wire [2:0] sel = cnt[23:21];
always @(*) begin
case (sel)
3'd0: led = 8'b0000_0001;
3'd1: led = 8'b0000_0010;
3'd2: led = 8'b0000_0100;
3'd3: led = 8'b0000_1000;
3'd4: led = 8'b0001_0000;
3'd5: led = 8'b0010_0000;
3'd6: led = 8'b0100_0000;
3'd7: led = 8'b1000_0000;
default: led = 8'b0000_0001;
endcase
end
endmodule
运行与验证
- 引脚约束:将
clk绑定到板载50MHz时钟引脚,rst_n绑定到按键(按下为低电平),led[7:0]绑定到8个LED引脚。 - 综合烧录:在Quartus/Vivado中新建工程,添加上述代码,完成引脚分配后编译并下载到开发板。
- 功能仿真(可选):编写testbench,将
cnt位宽临时改为4位(reg [3:0] cnt),sel = cnt[3:1],仿真观察led是否按0000_0001 → 0000_0010 → … → 1000_0000循环变化。
通过判定标准:烧录后按下复位键释放,8个LED按顺序依次点亮并循环,每秒约3个LED完成一轮流动,无闪烁或跳变异常。
关键说明
- 计数器
cnt位宽决定流水速度:24位时约0.336秒切换一次;减小位宽可加快速度,增大位宽则变慢。 - 本设计采用组合逻辑译码方式,直观展示“计数器 → 译码 → 输出”的基本时序逻辑结构;若需更简洁的写法,也可改用移位寄存器实现。
- 若开发板LED为高电平点亮,将
case中每个赋值取反(如8'b1111_1110)即可。