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
相关产品推荐
相关产品推荐

