SystemVerilog同一模块多实例行为不一致问题排查咨询
问题成因
- 运算符优先级错误:Verilog中
===相等运算符的优先级高于按位与&,你写的EN & DSR === 1'b1实际运算顺序是EN & (DSR === 1'b1),和预期的(EN & DSR) === 1'b1逻辑完全不符,会直接导致条件判断错乱。同时此处应该使用逻辑与&&而非按位与&,避免多bit位操作时的意外行为。 - 组合逻辑生成非预期锁存器:这是一个电平敏感的组合逻辑always块,但
stepp和stepn没有在所有条件分支中被赋值:当EN为低电平、或者两个if条件都不满足时,两个信号都没有赋值,编译器会自动推断出锁存器来保留之前的输出值。如果之前stepn已经被置为高电平,后续没有对它的赋值操作时它会一直保持高,此时如果stepp被置高就会出现两个同时为高的异常。8个实例表现不一致是因为锁存器的初始状态、布局布线后时序延迟的微小差异都会影响锁存器的输出行为。 - 条件分支覆盖不全:代码只判断了
RSTDAC_B为0和1的情况,当信号出现X(未知态)、Z(高阻态)时没有对应处理,也可能引入不确定行为。
解决方法
- 修正运算符使用,增加括号明确运算顺序,把按位与
&替换为逻辑与&& - 在always块开头给两个输出信号设置默认值,确保所有分支都有赋值,避免锁存器推断
- 可选补全复位外的默认分支,仿真时更容易定位异常状态
修正后代码
always @ (RSTDAC_B or EN or DSR or DSR_B ) begin // 先赋默认值,避免锁存器 stepp = 1'b0; stepn = 1'b0; if (RSTDAC_B === 1'b0) begin stepp = 1'b0; stepn = 1'b0; end else if (RSTDAC_B === 1'b1) begin if ((EN && DSR) === 1'b1) begin stepn = 1'b1; end else if ((EN && DSR_B) === 1'b1) begin stepp = 1'b1; end end // 可选:ASIC设计可补全else分支处理X/Z态,仿真时更容易定位问题 // else begin // stepp = 1'bx; // stepn = 1'bx; // end end
如果该模块功能允许同步设计,建议改为时钟沿触发的时序逻辑,稳定性会更高,也能避免组合逻辑的竞争冒险问题。
内容的提问来源于stack exchange,提问作者user16818402
相关产品推荐
相关产品推荐

