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

VCS仿真中为何部分变量允许多驱动而其他变量报错?

Why pass_val works but rollover_n triggers a driver conflict in VCS?

Great question! Let's break down why you're seeing this confusing discrepancy between pass_val and rollover_n in your Verilog code when simulating with VCS.

Core Verilog Rule to Remember

First, let's get the basics straight: logic-type variables cannot be driven by multiple independent procedural blocks (separate always blocks). Variables hold a single value at any time, so having two distinct blocks trying to set their value creates an ambiguous conflict—there's no built-in rule for which assignment takes precedence. This is exactly what the "illegal combination of procedural drivers" error is flagging.

Why pass_val didn't trigger the error (for now)

Looking at your code, the assignment to pass_val in the second always block (@(pass_val,compare,rollover_n)) is conditional: it only sets pass_val = 0 when pass_val > compare. When this condition isn't met, the block doesn't touch pass_val at all.

Some simulators like VCS might be lenient here if they can't definitively prove that both blocks will ever drive pass_val simultaneously. However, this is not valid synthesizable Verilog, and you're lucky it didn't break—you could easily hit race conditions or unexpected behavior in more complex scenarios. The always_comb block unconditionally sets pass_val every time it runs, while the second block only modifies it in one branch; the simulator might not flag this immediately, but it's a ticking time bomb.

Why rollover_n throws the error

Unlike pass_val, rollover_n has unambiguous conflicting drivers:

  • In the always_comb block: every code path assigns a value to rollover_n (either 1 or 0 via the if/else statement—assuming seqnum_rollover_n was a typo for rollover_n).
  • In the second always block: whenever rollover_n is high, the block sets it to 0. Even if the condition isn't met, the block has the potential to drive rollover_n, creating a clear conflict with the always_comb block's continuous assignments.

VCS's compiler correctly catches this definite conflict—two separate procedural blocks both can drive rollover_n, which violates Verilog's variable driving rules.

How to fix this

You need to refactor your code so each variable is driven by only one procedural block. Here are practical approaches:

  • Merge logic into a single block: Combine the bit-slicing/comparison logic and arbitration logic into one always_comb block. This eliminates conflicting drivers entirely, as all assignments to pass_val and rollover_n live in the same block.
  • Restructure driver responsibilities: Instead of having the arbitration block modify rollover_n, have it set a control signal (like clear_rollover) that the always_comb block uses to update rollover_n. This keeps all assignments to rollover_n within the always_comb block.
  • Use wire-type with continuous assignment (if needed): If you must keep separate blocks, change rollover_n to a wire and use a continuous assignment with priority (e.g., assign rollover_n = arbitration_clear ? 0 : (pass_val == 0 && |enable) ? 1 : 0;). This resolves the conflict by explicitly defining which driver takes precedence.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:57:22