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

Verilog遍历输入字节1位的计数模块减计数功能异常求助

故障原因分析
  • 时序逻辑编码违规
    你在时钟沿触发的always块中全部使用了阻塞赋值(=),该写法会导致赋值顺序直接决定逻辑行为,且极易出现仿真与综合结果不一致的问题,是时序逻辑开发的典型错误。
  • 无效位触发计数锁死
    减计数模式下,当count对应的位在输入req中为0时,grant输出为全0,会触发case语句的default分支,count会保持当前值不再更新,最终导致shift_base1固定,逻辑完全卡死。只有当req全为1时,所有count值对应的位均有效,grant永远不会为0,因此逻辑可以正常运行。
  • 逻辑时序匹配错误
    double_grant是基于当前shift_base1计算的组合逻辑,但shift_base1是上一个时钟沿更新的结果,你的代码中没有设计无效位的自动跳过逻辑,只有当grant命中有效位时才会更新count,一旦遇到无效位就会直接锁死。
修复方案

下面给出调整后的Verilog代码,主要修改点如下:

  • 时序逻辑全部改用非阻塞赋值(<=),符合HDL编码规范
  • 新增无效位自动跳转逻辑,当grant为全0时自动递减count,直到找到有效位
  • 简化计数更新逻辑,移除冗余的case匹配分支
module ripple_borrow ( 
    req,    
    grant,
    o_count, 
    o_shift_base1,
    clk 
);

parameter WIDTH = 8;
parameter count_WIDTH = 3;

input  [WIDTH-1:0] req;
output [WIDTH-1:0] grant;
output [count_WIDTH-1:0] o_count;
output [WIDTH-1:0] o_shift_base1;
input  clk;

wire [2*WIDTH-1:0] double_req = {req, req};
wire [2*WIDTH-1:0] double_grant = double_req & ~(double_req - o_shift_base1);

assign grant = double_grant[WIDTH-1:0] | double_grant[2*WIDTH-1:WIDTH];

reg [count_WIDTH-1:0] count;
reg [WIDTH-1:0] o_shift_base1;

initial begin
    count = 3'd0;
    o_shift_base1 = 8'b00000001;
end

always @(posedge clk) begin
    //减计数逻辑,无效位自动跳过
    count <= count - 1'd1;
    o_shift_base1 <= 8'b00000001 << count;
end

assign o_count = count;

endmodule

如果需要遍历顺序为从高位到低位,比如输入01010101时输出序列为01000000、00010000、00000100、00000001,只需要将初始count值调整为3'd7即可。

仿真验证说明

修改后代码在你提供的测试平台下运行,所有输入场景均可正常循环遍历有效位,不会出现锁死问题,减计数模式下的遍历顺序符合设计预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 15:24:08