One RTL design, different verification questions
Take one asynchronous FIFO and ask it four different questions. Does it behave? Are its clock and reset crossings safe? What did the test exercise? And would a planted bug get caught?
Same RTL, four engines, four answers. They do not agree, and that is the point.
A single simulation that ends in PASS is the most over-trusted line in hardware verification. It tells you that under the stimulus that ran, the checks that existed were not violated. It does not tell you the crossings are safe, the coverage means anything, or that a different class of bug is not sitting one clock domain away.
The way to see that is not an argument, it is a design. Here is one WIOWIZ block, wz_async_fifo, a dual-clock asynchronous FIFO with Gray-coded read and write pointers crossed through two-flop synchronizers, concurrent SVA that it never overflows or underflows, and a self-checking scoreboard on the read side. We run it, unchanged, through four WIOWIZ engines and read what each one returns.
Question 1: Does it behave? (FSimX)
The simulation engine answers a narrow question: under this stimulus, did the design do what the test expected. We stream 512 words across the two clock domains and let the scoreboard and the two assertions check every one.
$ fsxrun wz_async_fifo.sv tb_wz_async_fifo.sv -top tb_wz_async_fifo -vcd dump.vcd [FIFO] streamed 512 words across two clock domains, errors=0 WZ_ASYNC_FIFO_PASS - 512 words crossed in order, no loss/corruption Result: PASS Checks: 1237 passed, 0 failed Assertions: 1237 passed, 0 failed Warnings: 0 Errors: 0 Peak memory: 32 MB Waveform: dump.vcd (256.6 KB, 72 signals)
FSimX 0.5.399, from the run. The design carries two concurrent SVA assertions (no overflow, no underflow); FSimX evaluates them on every clock edge, and the 1237 counts are those passing evaluations plus the scoreboard checks, none failing.
Clean. If PASS were the end of verification, we would ship. It is the beginning.
Question 2: Are the crossings safe? (Truti)
The same RTL, handed to the CDC/RDC engine, is not asked to run anything. It is asked whether the structure of every clock and reset crossing is safe. It reads a different answer.

Truti signoff report on wz_async_fifo. SIGNOFF: DIRTY, 8 must-fix crossings, with the clock/reset domain matrix and the reset-deassertion diagram.
Verdict DIRTY. Eight must-fix findings, and note how they arise: with no constraints file, Truti treats every top-level input as its own abstract asynchronous domain, marked ABSTRACT_ASYNC in the domain table, and reports pessimistically rather than assuming the inputs are already synchronous. It also, separately, recognized 100 proven two-flop synchronizers inside the design, shown, never silently dropped. The reset side is its own family: RDC_ASYNC_DEASSERT, an asynchronous reset that can deassert into the destination clock domain without a reset synchronizer, a crossing simulation never looked at.
Simulation said pass. The structural audit says the reset deassertions and the unconstrained inputs are not proven safe. Both are correct. They are answering different questions.
Question 3: What did the test exercise? (Coverage)
Coverage answers a third question: of everything this design can do, how much our stimulus touched. The number matters far less than what the tool admits it did not measure.

Asesha metrics center, from the run. Toggle at 28.02%, and the banner states plainly that seven of eight metric families are ABSENT (not 0%).
Toggle coverage is 28.02% on this short run. The line that matters is the warning above it: feed provides 1/8 standard metric types; ABSENT (not 0%): line/statement, block, branch, expression, fsm, assertion, covergroup. A family the run did not collect is carried as not-applicable, never scored as a false zero. The per-bin table shows each untoggled bit as MISS with an UNKNOWN formal state, so you can see exactly what was not exercised.
Question 4: Would a planted bug get caught? (and by what)
The FIFO ships with a built-in negative control. Define WZ_FIFO_BUG and the write address is corrupted so words are lost and reordered. We re-run the same testbench.
$ fsxrun wz_async_fifo.sv tb_wz_async_fifo.sv -top tb_wz_async_fifo -D WZ_FIFO_BUG [FIFO] MISMATCH #0: got 0x00000001 expected 0x00000000 [FIFO] MISMATCH #1: got 0x00000000 expected 0x00000001 [FIFO] streamed 512 words across two clock domains, errors=512 WZ_ASYNC_FIFO_FAIL - 512 ordering/data errors *I,FSX-S1006: 2 concurrent SVA assertion(s) lowered and EVALUATED every clock edge
Same testbench, bug enabled. The failure is loud and unmistakable.
The bug is caught, 512 errors. But look at what caught it. The two SVA assertions still evaluated every clock edge, and they did not fire, because the corruption is a data and ordering error, not an overflow or underflow. The scoreboard caught it. Different checks catch different bugs: the assertions guard one property, the scoreboard guards another, and a design with only one of them would have shipped this.
One design, four answers, no faked pass
Put the four questions side by side, from the same unchanged RTL:
| Question | Engine | Answer |
|---|---|---|
| Does it behave under this stimulus? | FSimX | PASS · 1237 checks |
| Are the clock/reset crossings safe? | Truti | DIRTY · 8 must-fix |
| What did the test exercise? | Asesha | 28.02% toggle · 7/8 families absent |
| Would a planted bug be caught? | FSimX scoreboard | FAIL · 512 errors (assertions silent) |
One design, four engines, four answers that do not agree because they are not the same question.
The unifying thread is not that the engines disagree. It is that none of them faked an answer. Truti reported DIRTY under a pessimistic input policy rather than a comfortable clean. Coverage reported the seven families it did not measure as absent, not as zero. The assertions that did not catch the data bug stayed silent rather than claiming credit. A verification result is only worth as much as the question behind it, and reading these four together is what turns a green checkmark back into engineering.