You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Verilog中如何获取时钟计数器输出?DE0 FPGA计数点灯异常求助

DE0 FPGA按键计数点亮LED问题修复方案

错误原因

  • LED赋值逻辑错误:你定义的led是1位输出端口,count是8位寄存器,直接编写assign led = count时,Verilog会自动截取count的最低位赋值给led。count最低位每计数1次翻转一次,因此每2次计数就会完成一次亮灭周期,和你遇到的现象完全吻合。
  • 按键直接作为时钟的隐患:机械按键按下/松开时会产生数毫秒的抖动,直接接时钟端口会导致一次按键触发多个上升沿,计数结果不准;同时异步时钟输入还可能引入亚稳态,导致电路工作异常。
  • 初始化逻辑不规范:Verilog的initial块在绝大多数FPGA综合场景下不可靠,上电初始化建议依赖复位信号实现。

最小修改方案(仅解决8次触发逻辑,暂未处理按键消抖)

修改LED赋值语句,判断计数达到7(从0开始计数,共8次)时点亮LED即可,修改后代码如下:

module tima(output reg led, input reset, input clock);
reg [2:0]count; // 8次计数只需要3位寄存器足够,不需要8位

always @ (posedge clock, posedge reset) begin
    if(reset) begin
        count <= 0;
        led <= 0;
    end else begin
        count <= count + 1'd1;
        // 计数到7时点亮LED,否则熄灭,也可根据需求改为翻转LED
        led <= (count == 3'd7);
    end
end

endmodule

规范实现方案(添加按键消抖,适配DE0板载资源)

建议使用DE0的板载50MHz系统时钟作为全局时钟,将按键作为普通IO输入,添加消抖和上升沿检测逻辑,确保一次按键只触发一次计数:

module tima(
    output reg led,
    input reset,
    input sys_clk, // 接DE0板载50MHz时钟
    input key_in   // 接按键输入
);
reg [19:0] debounce_cnt; // 20位计数器实现约20ms消抖
reg key_stable;
reg key_stable_dly;
wire key_pulse;
reg [2:0] count;

// 按键消抖逻辑
always @(posedge sys_clk or posedge reset) begin
    if(reset) begin
        debounce_cnt <= 0;
        key_stable <= 1'b1; // 按键默认上拉为高电平
    end else begin
        if(key_in != key_stable) begin
            debounce_cnt <= debounce_cnt + 1'b1;
            if(debounce_cnt == 20'd999999) begin // 50MHz下计数1e6次为20ms
                key_stable <= key_in;
                debounce_cnt <= 0;
            end
        end else begin
            debounce_cnt <= 0;
        end
    end
end

// 按键边沿检测,生成计数脉冲
always @(posedge sys_clk or posedge reset) begin
    if(reset) begin
        key_stable_dly <= 1'b1;
    end else begin
        key_stable_dly <= key_stable;
    end
end
// 若按键按下为低电平,检测下降沿触发计数,需要高电平触发可修改为 ~key_stable_dly & key_stable
assign key_pulse = key_stable_dly & (~key_stable);

// 计数与LED控制逻辑
always @(posedge sys_clk or posedge reset) begin
    if(reset) begin
        count <= 3'd0;
        led <= 1'b0;
    end else begin
        if(key_pulse) begin
            count <= count + 1'd1;
            led <= (count == 3'd6); // 第8次按下时点亮LED
        end
    end
end

endmodule

内容的提问来源于stack exchange,提问作者josed2212

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 04:06:00