1. LED流水灯

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

运行与验证

  1. 引脚约束:将clk绑定到板载50MHz时钟引脚,rst_n绑定到按键(按下为低电平),led[7:0]绑定到8个LED引脚。
  2. 综合烧录:在Quartus/Vivado中新建工程,添加上述代码,完成引脚分配后编译并下载到开发板。
  3. 功能仿真(可选):编写testbench,将cnt位宽临时改为4位(reg [3:0] cnt),sel = cnt[3:1],仿真观察led是否按0000_0001 → 0000_0010 → … → 1000_0000循环变化。

通过判定标准:烧录后按下复位键释放,8个LED按顺序依次点亮并循环,每秒约3个LED完成一轮流动,无闪烁或跳变异常。

LED流水灯状态循环 LED0 LED1 LED2 LED3 LED4 LED5 LED6 LED7 计数器最高3位每递增1,点亮位置右移1位,循环周期 = 2³ × 分频周期

关键说明

  • 计数器cnt位宽决定流水速度:24位时约0.336秒切换一次;减小位宽可加快速度,增大位宽则变慢。
  • 本设计采用组合逻辑译码方式,直观展示“计数器 → 译码 → 输出”的基本时序逻辑结构;若需更简洁的写法,也可改用移位寄存器实现。
  • 若开发板LED为高电平点亮,将case中每个赋值取反(如8'b1111_1110)即可。