|按键翻转 LED(无消抖)

按键翻转 LED(无消抖)

作者: 石志超更新于: 2026/2/27
module top (
    input        sys_clk,      // 50MHz 时钟
    input        sys_rst_n,    // 复位
    input        key_n,        // 1 个按键(低有效:按下 = 0)
    output [3:0] led           // 4 个 LED(低有效)
);

reg        key_prev;   // 上一拍的按键值
reg [3:0]  led_r;      // LED 状态寄存器

always @(posedge sys_clk or negedge sys_rst_n) begin
    if (!sys_rst_n) begin
        key_prev <= 1'b1;       // 复位:默认未按(高电平)
        led_r    <= 4'b0000;    // LED 全灭
    end else begin
        key_prev <= key_n;      // 记住「上一拍」的按键状态
        // 检测下降沿:上一拍高 + 这一拍低 = 按下瞬间
        if (key_prev && !key_n)
            led_r <= ~led_r;    // 翻转全部 LED
    end
end

assign led = ~led_r;  // 低有效取反

// ★ 试试快速按 — 你会发现 LED 有时不翻转、有时翻转两次
//   这就是「按键抖动」!一次按下产生了多个下降沿
//   下午会讲如何用消抖解决

endmodule
# 系统时钟 50MHz
set_property PACKAGE_PIN P15 [get_ports sys_clk]
set_property IOSTANDARD LVCMOS33 [get_ports sys_clk]
create_clock -period 20.000 -name sys_clk [get_ports sys_clk]

# 复位按键 KEY1(按下 = 0)
set_property PACKAGE_PIN E18 [get_ports sys_rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports sys_rst_n]

# ★ 新增:用户按键 KEY2(按下 = 0)
set_property PACKAGE_PIN E17 [get_ports key_n]
set_property IOSTANDARD LVCMOS33 [get_ports key_n]

# LED x4(输出 0 = 亮)
set_property PACKAGE_PIN F15 [get_ports {led[0]}]
set_property PACKAGE_PIN G14 [get_ports {led[1]}]
set_property PACKAGE_PIN E16 [get_ports {led[2]}]
set_property PACKAGE_PIN E15 [get_ports {led[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[*]}]