Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • Part 0 · What Debugging Is6
  • Part 1 · Reproduce8
  • Part 2 · Observe9
  • Part 3 · Localise10
  • Part 4 · Hypothesise and Test6
  • Part 5 · Bug Classes16
  • Part 6 · Debug by Stage9
    • RTL Simulation
    • Formal Counterexamples as Traces
    • Gate-Level Simulation
    • Equivalence Failures
    • Emulation and FPGA Prototyping
    • The First Failing Test on Silicon
    • Silicon vs Simulation Correlation
    • Marginal and Environmental Failures
    • Moving the Failure to the Cheapest Stage
  • Part 7 · Hangs and Deadlocks7
  • Part 8 · Intermittent Failures7
  • Part 9 · Fix, Prove, Prevent7
  • Part 10 · Case Studies12
  • Part 11 · Debug as a Team5
  • Part 12 · Interview Prep5
Loading lesson

‹Part 6 · Debug by Stage
  1. Topics
  2. The Art of Hardware Debug
  3. Part 6 · Debug by Stage
  4. Silicon vs Simulation Correlation

Part 6 · Debug by Stage · Principal (P)

Silicon vs Simulation Correlation

When silicon and simulation disagree, neither is right by default. Match the inputs first, compare at the finest grain both can give, cross with a second die, and know each model's blind spots. A real bench runs one test on the RTL and on two modelled dies and walks the comparisons in order.

On this page

    Why this matters

    When silicon and simulation disagree, teams argue about which one is real while the actual difference, usually a setting or a version, sits unexamined. Correlating inputs first and comparing at the finest common grain settles in hours what the argument leaves open for weeks.

    After this lesson you can: separate a silicon-simulation disagreement into inputs, model and die, align the inputs from a register dump, find the first differing window from signatures, and decide which source to believe for which question.

    Note

    Level: Principal (P) · Debug-loop step: Observe, Localise

    Before this: The First Failing Test on Silicon, Differential Debugging

    Two teams, two answers

    The first dies run the stream-signature test. Each 64-word window of the stream is folded into a 32-bit signature, a MISR, which software reads at the end. Simulation of the same test gives eight signatures. Silicon gives eight different ones. The RTL team says simulation is the reference and the silicon is broken; the lab says silicon is what the customer gets and the model is wrong.

    Both cannot be right, and both may be wrong. Which do you believe, and how do you find out?

    What people usually do, and why it fails

    Each side defends its instrument. The RTL team reruns the simulation, gets the same answer, and calls that proof. The lab runs the test on the same die again, gets the same answer, and calls that proof. Neither repeat adds information, because each repeats its own inputs. Then the debate moves to a single bit of evidence, the final signature matches or it does not, which cannot say where the two runs parted.

    The question is not which instrument is real. Both are. Simulation says what the RTL does with the bench's inputs. Silicon says what one die did with the lab's inputs. The specification says what should happen. A disagreement lives in a difference between those: the inputs, the model, or the die.

    The method: inputs, grain, dies, blind spots

    1. Align the inputs first. Configuration after boot, firmware version, clock frequencies and their ratio, reset sequence, test version, the netlist or RTL version behind the simulation. Read the chip's registers through the debug port and set the simulation up from that dump, rather than from what the bench assumes.

    2. Compare at the finest grain both sides can give. Per-window signatures, counters, a trace of one interface. The first window that differs is silicon's first wrong cycle, and everything before it is cleared.

    3. Change the die before you change the design. A difference on every die is the design or the model. A difference on one die is that die: a defect, or a margin problem if it moves with voltage, frequency or temperature (marginal failures).

    4. Know each model's blind spots. Simulation can disagree with silicon and be the one that is wrong (the table below). Silicon can mislead too: a bad socket, a marginal supply, a test program that differs from the simulated one.

    5. Decide what each source is trusted for. Silicon is the truth about what this die did. Simulation, once correlated, is the truth about what the RTL specifies for those inputs. The specification decides which of them is the bug.

    Where simulation can be the wrong one

    What silicon does instead

    An unknown (X) or an uninitialised flip-flop

    a definite 0 or 1, different per die and per power-up

    A two-state simulator starting flops at 0

    random power-up values; a bug that needs a nonzero value appears only on silicon

    Zero-delay logic

    real path delays, setup and hold, droop

    Behavioural models of memories, PLLs, analogue or hard IP

    the real block, with behaviour the model left out

    The RTL, after an engineering change made in the netlist

    the changed netlist

    Differential debugging shows the first two rows on dbglab: the same seed gives X in one simulator, a pass in another and a random wrong value with random start-up values.

    The picture

    A decision flow: if the inputs differ, set the simulation up from the chip's register dump; then find the first differing window; if a second die differs the same way, suspect the design or the model; if not, check whether it moves with voltage, frequency or temperature (margin) or not (a defect on that die).
    Correlating silicon and simulation: inputs first, then the first differing window, then a second die, then margin or defect.

    On the debug loop this is Observe and Localise across two instruments: the comparison is the observation, and the first differing window is the localisation.

    Do it: one test, the RTL and two dies

    The bench runs one test, 512 random words in eight windows, through four copies of the signature block. sim is the RTL as the bench sets it up. die_a and die_b are models of two silicon dies: both run boot code that sets a configuration bit, and die A also has a modelled physical defect, a bit that flips on certain words, which no simulation of the RTL can contain. sim_si is the RTL set up from die A's register dump. The bench prints the comparisons in the order the method makes them.

    sig_engine.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    `timescale 1ns/1ps
    // sig_engine: folds a stream of words into a 32-bit signature (a MISR), one signature per window
    // of 64 words, restarted at each window, so each window can be compared on its own. A config
    // register, CFG.swap (reset value 0), byte-swaps each word first.
    // FLAW = 1 is a model of a physical defect on one die (for example a coupling fault): when a word's
    // top byte is FF, bit 13 of the next signature flips. The RTL has FLAW = 0; no simulation of the
    // RTL can show it.
    module sig_engine #(parameter bit FLAW = 0) (
      input  logic        clk, rst_n,
      input  logic        cfg_we, cfg_swap,             // config write port (software or boot code)
      input  logic        in_valid,
      input  logic [31:0] in_data,
      output logic        swap_q,                       // config readback (the debug port reads it)
      output logic        win_valid,                    // a window's signature is ready
      output logic [31:0] win_sig
    );
      logic [31:0] sig, w, nxt;
      logic [5:0]  cnt;
      assign w   = swap_q ? {in_data[7:0], in_data[15:8], in_data[23:16], in_data[31:24]} : in_data;
      assign nxt = ({sig[30:0], sig[31] ^ sig[21] ^ sig[1] ^ sig[0]} ^ w)
                 ^ ((FLAW && in_data[31:24] == 8'hFF) ? 32'h0000_2000 : 32'h0);
      always_ff @(posedge clk or negedge rst_n)
        if (!rst_n) begin swap_q <= 1'b0; sig <= '0; cnt <= '0; win_valid <= 1'b0; win_sig <= '0; end
        else begin
          if (cfg_we) swap_q <= cfg_swap;
          win_valid <= 1'b0;
          if (in_valid) begin
            cnt <= cnt + 6'd1;
            if (cnt == 6'd63) begin win_sig <= nxt; win_valid <= 1'b1; sig <= '0; end
            else sig <= nxt;
          end
        end
    endmodule
    

    Steps 1 and 2: everything differs, so check the inputs

    Terminal
    $ iverilog -g2012 -o c.vvp corr_tb.sv
    $ vvp -n c.vvp
    step 1: simulation against die A, same test
      window  sim       die A
      0       2b03e740  7102b0ae  DIFFERENT
      1       c9eb1a70  6c06bc36  DIFFERENT
      2       463494a0  176feeea  DIFFERENT
      3       bb6e0530  90e6bb70  DIFFERENT
      4       bd9364d1  306686d5  DIFFERENT
      5       ea7a1708  32289b39  DIFFERENT
      6       e9c17833  8806cd87  DIFFERENT
      7       dbffc3cf  11cf7efb  DIFFERENT
    step 2: config readback through the debug port: sim CFG.swap=0, die A CFG.swap=1

    All eight windows differ, from window 0. A difference that starts at the first observation and never stops is the signature of different inputs or setup, not of a bug that happens during the test. So before reading a single signature, read the configuration: die A has CFG.swap = 1, written by its boot code, and the simulation left it at its reset value of 0. The bench never ran the boot code.

    Steps 3 and 4: the same setup, then a second die

    Terminal
    step 3: simulation set up from die A's register dump, against die A
      window  sim_si    die A
      0       7102b0ae  7102b0ae  same
      1       6c06bc36  6c06bc36  same
      2       176feeea  176feeea  same
      3       90a6bb71  90e6bb70  DIFFERENT
      4       e6bd49e9  306686d5  DIFFERENT
      5       32289b39  32289b39  same
      6       bed01648  8806cd87  DIFFERENT
      7       11ce7efb  11cf7efb  DIFFERENT
    step 4: the same against die B
      window  sim_si    die B
      0       7102b0ae  7102b0ae  same
      1       6c06bc36  6c06bc36  same
      2       176feeea  176feeea  same
      3       90a6bb71  90a6bb71  same
      4       e6bd49e9  e6bd49e9  same
      5       32289b39  32289b39  same
      6       bed01648  bed01648  same
      7       11ce7efb  11ce7efb  same
    • Step 3. With the simulation set up from die A's dump, windows 0, 1, 2 and 5 match exactly: the setup explained them completely. Windows 3, 4, 6 and 7 still differ, and the first is window 3: words 192 to 255.

    • Step 4. Die B, same boot code, matches the simulation in every window. So the RTL and its simulation agree with one die for this test, and the difference belongs to die A.

    Step 5: what the differing windows share

    Terminal
    step 5: words with top byte FF in each window of the captured input: 0 0 0 1 1 0 1 1
    summary: sim vs A 8 of 8 windows differ; sim_si vs A 4 (windows 3 4 6 7); sim_si vs B 0
    PASS: the setup explained every difference but 4 windows; those differ only on die A

    Windows 3, 4, 6 and 7 each contain a word whose top byte is FF, and the matching windows contain none. The bench can print this because it knows the defect model; in a lab you find such a feature by running the differing windows' words as short tests and halving them, the bisection in stimulus of silicon. A pattern-dependent difference on one die, absent on another, is a failure-analysis case with the pattern named, or a margin question if it moves with voltage and temperature.

    What the evidence says

    Which to believe was never the question. For what die A did, believe die A: its signatures repeat and they are the customer's result. For what the design should do with these inputs, believe the simulation, now that its inputs match and a second die agrees with it. Every window differed because of the bench; the four that still differ without it belong to one die. Nobody needed to change the RTL, and nobody needed to argue.

    Traps

    "The simulation is golden"

    A simulation is golden only for what it models. A two-state simulator that starts every flip-flop at 0 will pass a design that reads an unreset register, and silicon, starting at random values, will fail it, differently on every power-up. When silicon fails and simulation passes, check the model's blind spots before the silicon.

    Correlating against the wrong version

    An engineering change made in the netlist after the RTL froze, a test program edited for the tester, or a boot ROM built from a newer branch all give "silicon disagrees with simulation" with no bug in either. Put the version of every input in the comparison, as a replay record does for a simulation.

    Common pitfall

    One signature at the end. A single end-of-test signature says same or different, one bit. Plan windowed signatures, counters and readable configuration into the design so that correlation has a grain finer than the whole test (observability by design).

    Why this matters

    Principal lens. Correlation is a deliverable, not a reaction. Before tape-out, decide which tests form the correlation suite, what each must match exactly (signatures, cycle counts within a stated band, counters), how the chip's configuration is read back, and how the same test source runs in simulation, on the emulator and on silicon. Run the suite on the first die, on every new lot and after every netlist change.

    Give the suite an owner and the result a status. A programme that knows on the first day that silicon matches simulation on a hundred tests can treat the next disagreement as information; a programme that never correlated will spend the first month arguing about which instrument to trust.

    Interview

    Asked: "A test passes in simulation and fails on silicon. The RTL team says the silicon is bad. How do you settle it?"

    Weak answer: Silicon is what ships, so I would assume the simulation model is wrong and look for what the testbench misses, or rerun the test on the chip several times to be sure.

    Strong answer: Neither is right by default; the difference is in the inputs, the model or the die. First I make the inputs the same: I read the chip's configuration and versions and set the simulation up from that, because a boot setting or a firmware difference is the commonest cause. Then I compare at the finest grain both give, windowed signatures or counters, to find the first point where they part. Then I run a second die: if it matches simulation, the problem is that die, a defect or margin, which I check with a shmoo; if every die differs, it is the design or a gap in the model, such as X handling, initial values, timing or a behavioural model, and the specification decides which is the bug.

    Follow-ups: (1) What would make you believe the simulation is the wrong one? (2) What would you build into the design to make this faster next time?

    Check yourself After you set the simulation up from the chip's register dump, every die still differs from simulation in every window, starting at window 0. What do you check next?

    A difference from the first observation on every die is still an input or a model difference, not a bug during the test. Check what the register dump does not cover: the clock ratio, the reset sequence, the stimulus source (is the test program on the tester the one that was simulated?), and the version of the netlist behind the simulation. Then compare something simpler than the signature, such as the first few words of a trace, to see whether the inputs or the block's output differ first.

    Check yourself Silicon fails a test on some dies and not others, with a different wrong value after each power-up. Simulation passes in a two-state simulator. What is the likely class, and how would you show it in simulation?

    A value that changes with every power-up and every die points at state that is never initialised before it is read. A two-state simulator that starts flip-flops at 0 hides it. Rerun with unknown or random initial values, X in a four-state simulator or random start-up values in a two-state one; a failure that appears only then confirms the class, and the unreset registers read before being written are the suspects.

    Remember

    • A disagreement has three possible homes: different inputs, a model that cannot show the effect, or this die. Rule out inputs first; they are the commonest.

    • Compare at the finest grain both sides can give: per-window signatures or counters, not one pass or fail at the end.

    • One die differing is a die. Every die differing is the design or the model. Change the die before you change the design.

    Rule of thumb: never compare outputs until the inputs are shown to be the same, and never call silicon wrong from one die.

    How this was checked

    corr_tb.sv as shown, 2026-10-18: iverilog -g2012 -o c.vvp corr_tb.sv, vvp -n c.vvp (Icarus Verilog 13.0): steps 1 to 5 as shown and PASS; sim against die A, 8 of 8 windows differ; after the register dump, 4 (windows 3, 4, 6 and 7); against die B, 0. verilator --binary --timing --assert -Wno-fatal --top-module corr_tb (Verilator 5.048) prints the same lines.

    Limits: both dies are models written for this page. Die A's defect is a modelled bit flip on words whose top byte is FF; die B is the RTL. The boot code is two lines of the bench. No chip, tester or debug port was used. Step 5 counts the trigger words because the bench knows the model; in a lab that feature has to be found, for example by running the differing windows' words as short tests.

    Keep going

    • Interview: run a mock interview on this topic

    Related topics

    • Part 6 · Debug by Stage

    • Bring-up: ATE vs bench correlation

    • Bring-up: debug interfaces and observability

    • Differential debugging

    Previous

    62 / 107

    Next: Marginal and Environmental Failures

    Up next

    Up nextMarginal and Environmental Failures

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • RTL Simulation
    • Formal Counterexamples as Traces
    • Gate-Level Simulation