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

HDLBits边缘检测:两种Verilog实现为何行为存在差异?

Verilog边缘检测:两种写法的行为差异解析

我在HDLBits上进行Verilog边缘检测练习时,对if ({d_last, in} == 2'b01)与pedge <= in & ~d_last这两种写法的行为差异感到困惑——二者看起来都是对比当前与前一周期的信号,为什么我的代码会报出输出固定电平的警告?

我的代码

module top_module (
    input clk,
    input [7:0] in,
    output [7:0] pedge
);
    
    reg [7:0] d_last;   
            
    always @(posedge clk) begin
        d_last <= in;           
        if ({d_last, in} == 2'b01)
            pedge <= 1;
        else
            pedge <= 0;
    end

endmodule

警告信息

Warning (13024): Output pins are stuck at VCC or GND
该警告表示输出引脚始终固定为高电平(VCC)或低电平(GND)。若输出引脚不应为常量,这可能意味着存在bug,例如赋值语句导致值始终不变(如assign a = x & ~x;)。

官方解决方案

module top_module(
    input clk,
    input [7:0] in,
    output reg [7:0] pedge);
    
    reg [7:0] d_last;   
            
    always @(posedge clk) begin
        d_last <= in;           // 记录前一周期的输入状态
        pedge <= in & ~d_last;  // 当输入从0变为1时,检测到上升沿
    end
    
endmodule

差异原因解析

1. 位宽匹配错误

你的代码中,{d_last, in}是将两个8位信号拼接成16位宽的信号,然后和2位的2'b01做比较。Verilog中不同位宽的信号比较时,会将短位宽的信号零扩展到长位宽的长度,也就是2'b01会被扩展为16'b0000000000000001。这意味着只有当d_last的8位全为0,且in只有最低位为1、其余7位全为0时,条件才会成立——这种场景几乎不会出现,导致pedge绝大多数时候被赋值为0,综合器因此判定输出固定为低电平,抛出警告。

另外,你给8位的pedge赋值为1,会被自动扩展为8'b00000001,这也不符合需求:我们需要对in的每一位单独检测上升沿,而不是只把最低位置1。

2. 逻辑粒度错误

官方代码的in & ~d_last是对每一位单独进行上升沿检测:对于in的每一位,当当前周期为1、前一周期为0时,对应位输出1,否则输出0,完美实现了8位信号的逐位上升沿检测。

而你的代码用拼接后的整体信号做判断,本质是把两个8位信号当成一个16位信号来处理,完全误解了逐位检测的需求,逻辑上从根就错了。

3. 输出类型声明遗漏

你的代码中pedge是output [7:0]类型,但在always块中赋值,Verilog要求这类输出必须声明为reg类型(如官方代码中的output reg [7:0] pedge),否则会引发隐含的类型不匹配问题,也可能加剧综合器的误判。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 01:35:12