ITADN

opt_clean after proc changes simulation result for explicitly-driven output bit

#5941Openzhihaoxu1325 创建于 2026-06-08
pending-verification
Z
zhihaoxu1325commented
### Version Yosys 0.64+341 (git sha1 cc9692caa, GNU /bin/c++ 11.4.0) ### On which OS did this happen? Linux ### Reproduction Steps opt_clean incorrectly removes cells or wires that are still live in the output cone, causing a deterministic output bit flip. The reduced design has an explicitly-driven output out_data[0] whose value depends on a deep vector shift/mux/concat cone. After proc, the design contains multiple $dlatch and $adff cells produced from always_latch blocks where different conditions write different registers within the same block. opt_clean's unused-bit analysis appears to misjudge part of this cone as dead — likely because the liveness propagation fails to trace through chained shifts and part-selects — and removes 16 cells and 186 wires. This severs a path that ultimately feeds out_data[0], flipping it from the correct value 0 to 1 at cycle 13 under deterministic stimulus. The bug is isolated to opt_clean alone: applying only proc produces correct simulation, while proc; opt_clean produces the mismatch. The output is fully and explicitly driven (assign out_data = {191'b0, celloutsig_0_293z[0]}), so this is not an undriven-wire comparison artifact. No Yosys warnings are emitted during the failing run. Files in this directory: - `top.sv`: top module - `tb.sv`: deterministic comparison testbench Run: ```sh yosys -q -s yosys_script.ys perl -pe 's/module top\\b/module top_baseline/' baseline.v > baseline_sim.v perl -pe 's/module top\\b/module top_optimized/' optimized.v > optimized_sim.v iverilog -g2012 -o sim.out baseline_sim.v optimized_sim.v tb.sv vvp sim.out ``` ### Expected Behavior Expected: no deterministic 0/1 mismatch btw baseline_sim.v and optimized_sim.v. ### Actual Behavior Observed: ```text SIM_MISMATCH cycle=13 signal=out_data bit=0 gold=0 gate=1 ``` The top module explicitly drives the whole output: ```systemverilog assign out_data = {191'b0, celloutsig_0_293z[0]}; ``` The run without the optimization pass produces no mismatch. Adding only `opt_clean` changes `out_data[0]` from `0` to `1` at cycle 13. The `opt_clean` run reports no Yosys warnings, so this is not an undriven output comparison artifact. The relevant output cone is a vector mux/concat/part-select cone: ```systemverilog assign celloutsig_0_293z = celloutsig_0_24z[1] ? celloutsig_0_17z[17:5] : { celloutsig_0_70z[6:2], celloutsig_0_194z }; assign celloutsig_0_194z = celloutsig_0_17z[20:13] <<< celloutsig_0_115z[15:8]; ``` `proc` also creates several `$adff` registers and `$dlatch` cells from the reduced sequential logic. In the RTLIL dump, `opt_clean` removes 16 cells and 186 wires. Since `celloutsig_0_293z[0]` remains directly connected to `out_data[0]`, the likely failure mode is that `opt_clean`'s liveness/unused-bit analysis is treating part of this vector cone as unused even though it still contributes to the observed output bit. ## Verification Performed Using `top.sv`: - `proc` only: no mismatch - `proc; opt_clean; flatten; check`: mismatch at `out_data[0]` - `proc; opt_expr -full; opt_clean; flatten; check`: same mismatch - `proc; opt; flatten; check`: same mismatch [opt-clean.zip](https://github.com/user-attachments/files/28700998/opt-clean.zip)
1 条评论