Verilog 14位计数器添加复位按钮后无法实现问题求助
14位计数器复位按钮失效问题分析与修复
问题场景
实现14位计数器时,已在顶层模块和计数器模块中添加button作为复位信号,UCF文件中绑定引脚NET "button" LOC = K18;,但综合时报错:button已定义但未使用,同时存在button_ibuf和button无负载的提示,且按钮复位功能未实现。计数器模块代码如下:
module counter_14bit( input wire counter_clk_signal, input wire switch, // enable / disable the counter input wire button, // reset the counter to 0 output reg [13:0] counter=0 // 14 bit counter value (0-16383) ); always@(posedge counter_clk_signal) begin if (switch == 0) begin counter <= counter; end // max 14-bit unsigned value is 16383 but my board has only 4 sseg displays so // limit counter to 9999 max if (switch == 1) begin if (button == 1) begin counter <= 0; // reset counter to 0 if button 1 is pressed end if (counter == 9999) begin // reset counter to 0 if counter is 9999 counter <= 0; end else begin counter <= counter+1; end end end endmodule
问题根源
- 逻辑优先级冲突:当
switch=1时,按钮复位和计数逻辑是两个独立的if语句。即使button=1时执行了counter<=0,后续判断会因为此时counter为0,进入else分支执行counter<=counter+1,直接覆盖复位操作。综合器识别到button未对输出产生有效影响,将其优化掉,引发未使用、无负载的报错。 - 冗余无效代码:
switch==0时的counter <= counter是无意义的赋值,寄存器默认会保持当前值,该代码可删除。
修复方案
调整always块内的逻辑顺序,用else if保证复位逻辑的最高优先级,避免被后续逻辑覆盖:
module counter_14bit( input wire counter_clk_signal, input wire switch, // enable / disable the counter input wire button, // reset the counter to 0 output reg [13:0] counter=0 // 14 bit counter value (0-16383) ); always@(posedge counter_clk_signal) begin if (switch == 0) begin // 计数器禁用时自动保持当前值,无需额外赋值 end else begin // switch == 1,启用计数器 if (button == 1) begin counter <= 0; // 优先处理按钮复位 end else if (counter == 9999) begin counter <= 0; // 其次处理计数溢出复位 end else begin counter <= counter + 1; // 正常计数 end end end endmodule
额外建议
实际硬件中按钮存在机械抖动,建议在顶层模块对button信号添加去抖电路(比如两级寄存器同步+计数滤波),避免误触发复位。
内容的提问来源于stack exchange,提问作者ctbram
相关产品推荐
相关产品推荐

