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

  • Start Here6
  • SystemVerilog Language Foundations28
  • Object-Oriented SystemVerilog for Verification30
  • Constraint Randomization — Interview-Critical Deep Dive36
  • SystemVerilog Assertions — Interview-Critical Deep Dive40
  • Functional Coverage in SystemVerilog22
    • Covergroups & Coverpoints
    • Bins: Explicit, Auto, Illegal & Ignore
      • Auto Bins vs Explicit Bins
      • Transition Bins
      • Exclusions, Patterns & Filters
      • Bin Design Strategy
    • Cross Coverage
    • Coverage Options & Methods
    • Coverage Closure & Sign-Off
  • Testbench Architecture in SystemVerilog23
  • Advanced Language & Integration25
  • Senior & Interview Preparation21
  • Principal-Level Verification28
Loading lesson

‹Bins: Explicit, Auto, Illegal & Ignore
  1. Topics
  2. SystemVerilog
  3. Functional Coverage in SystemVerilog
  4. Bins: Explicit, Auto, Illegal & Ignore
  5. Transition Bins

Part 5 · Functional Coverage · Intermediate

Transition Bins

Transition bins prove paths were taken, with repetition and FSM recipes.

On this page

    Why this matters

    Every FSM state read 100% while the recovery path from ERR back to BUSY had never been taken. State bins count where the machine was, not how it moved.

    After this lesson you can: write transition bins for sequences of sampled values, with consecutive and goto repetition, and know where an assertion fits better.

    Covering sequences, not values

    Value bins prove a state was visited. Transition bins prove a path was taken: bins b = (A => B) hits when consecutive samples of the coverpoint were A then B.

    Consecutive means consecutive samples of the covergroup. Disciplined sampling at every relevant moment is what keeps that word honest.

    The listing below is not run in this course's checks: the open simulators do not count covergroups, so the lesson's bench counts it with the bins model.

    design.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // not-run: Verilator 5.048 ignores covergroups (COVERIGN) and Icarus 13 has none; the bins model counts it
    typedef enum logic [1:0] { IDLE, BUSY, DONE, ERR } st_e;
    
    covergroup cg_fsm @(posedge clk);
      cp_arc : coverpoint state iff (rst_n) {
        // single transitions (FSM arcs)
        bins idle_busy = (IDLE => BUSY);
        bins busy_done = (BUSY => DONE);
        bins done_idle = (DONE => IDLE);
        bins any_err   = (IDLE, BUSY, DONE => ERR);  // set → value
    
        // multi-step path: full happy loop in one bin
        bins happy_loop = (IDLE => BUSY => DONE => IDLE);
    
        // multiple transitions in one bin (either counts)
        bins recover = (ERR => IDLE), (ERR => BUSY);
      }
    endgroup
    Check yourself What sample stream covers happy_loop = (IDLE => BUSY => DONE => IDLE)?

    Four consecutive samples reading IDLE, BUSY, DONE, IDLE in that order.

    Repetition inside transitions

    A [N] repeats a value for exactly N consecutive samples, with [n:m] giving a range. A [->N] is the nonconsecutive goto: N occurrences with other values allowed in between.

    The listing below is not run in this course's checks: the open simulators do not count covergroups, so the lesson's bench counts it with the bins model.

    design.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // not-run: Verilator 5.048 ignores covergroups (COVERIGN) and Icarus 13 has none; the bins model counts it
    covergroup cg_seq @(posedge clk);
      cp_st : coverpoint state iff (rst_n) {
        // BUSY held exactly 3 cycles between IDLE and DONE:
        bins busy3      = (IDLE => BUSY [*3] => DONE);
    
        // BUSY held 2 to 4 cycles:
        bins busy_short = (IDLE => BUSY [*2:4] => DONE);
    
        // 2 non-consecutive ERR visits, then recovery to IDLE:
        bins flaky      = (ERR [->2] => IDLE);
      }
    endgroup

    Sample stream

    Bin

    Why it hits

    IDLE BUSY BUSY BUSY DONE IDLE

    (IDLE => BUSY [*3] => DONE)

    IDLE, then BUSY on three consecutive samples, then DONE

    ERR IDLE BUSY ERR IDLE

    (ERR [->2] => IDLE)

    Two ERRs with gaps allowed, and the sample after the second is IDLE

    Check yourself Samples read ERR, IDLE, BUSY, ERR, IDLE. Does flaky = (ERR [->2] => IDLE) hit?

    Yes. Two ERR occurrences arrive with gaps allowed, and the next sample is IDLE.

    Reading a sampled stream

    Watch the middle row, state. Encoded values are 0 IDLE, 1 BUSY, 2 DONE, with rst_n gating sampling through iff.

    • Slot 0: state is 0 (IDLE) and rst_n is 1. A path opens.

    • Slot 1: state is 1 (BUSY).

    • Slot 2: state is still 1.

    • Slot 3: state is still 1, the third consecutive BUSY.

    • Slot 4: state is 2 (DONE). The chain IDLE, BUSY x3, DONE is complete.

    • Slot 5: state is 0 (IDLE). A new path opens.

    • Slot 6: state is 1 (BUSY).

    • Slot 7: rst_n is 0, so iff skips this sample. What happens to the in-flight path is not fixed by the standard.

    The stream above is simulated stimulus. The busy3 hit at slot 4 follows from the transition rules.

    IEEE 1800 does not say whether a false iff aborts an in-flight transition or simply skips the sample. Many tools skip, so a sequence can be counted across a reset gap. To force an abort, fold reset into the expression, for example coverpoint (rst_n ? state : RESET_VAL), or use an SVA cover property.

    Check yourself Slot 7 is skipped by iff, then DONE arrives at the next accepted sample. Does busy3 hit?

    No, under either reading. If the skip aborts the path, the chain is gone. If the skip is ignored, only one BUSY (slot 6) precedes the DONE, not three.

    The SVA boundary

    The standard FSM recipe pairs one enum coverpoint for state occupancy with one transition coverpoint for every legal arc from the state diagram. Together they prove every state was reached and every designed edge was taken.

    Transition bins watch one coverpoint over consecutive samples. Multi-signal relations and elastic timing belong to cover property with SVA sequences.

    Rule of thumb: same variable with consecutive samples means transition bins, while multiple signals or elastic timing means SVA cover.

    Do not cross transition bins. Cross value bins instead, and select combinations with binsof.

    Testbench

    The bench counts both coverpoints from this lesson over the two sample streams in the table, using the model's transition bins: also() adds an alternative to a bin, as a comma does in bins recover = (ERR => IDLE), (ERR => BUSY);, and add_goto() stands for [->N].

    design.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
    // uses: covmodel
    // The FSM transition bins from this lesson, counted over the lesson's sample streams.
    typedef enum int {IDLE, BUSY, DONE, ERR} st_e;
    
    module tb_trans_bins;
      cm_point cp_arc = new("cp_arc"), cp_st = new("cp_st");
      initial begin
        cp_arc.add_trans("idle_busy", '{IDLE, BUSY});
        cp_arc.add_trans("busy_done", '{BUSY, DONE});
        cp_arc.add_trans("done_idle", '{DONE, IDLE});
        cp_arc.add_trans("any_err", '{IDLE, ERR}); cp_arc.also('{BUSY, ERR}); cp_arc.also('{DONE, ERR});   // (IDLE, BUSY, DONE => ERR)
        cp_arc.add_trans("happy_loop", '{IDLE, BUSY, DONE, IDLE});
        cp_arc.add_trans("recover", '{ERR, IDLE}); cp_arc.also('{ERR, BUSY});                                // (ERR => IDLE), (ERR => BUSY)
        cp_st.add_trans("busy3", '{IDLE, BUSY, BUSY, BUSY, DONE});                                           // (IDLE => BUSY [*3] => DONE)
        cp_st.add_trans("busy_short", '{IDLE, BUSY, BUSY, DONE});                                            // (IDLE => BUSY [*2:4] => DONE)
        cp_st.also('{IDLE, BUSY, BUSY, BUSY, DONE}); cp_st.also('{IDLE, BUSY, BUSY, BUSY, BUSY, DONE});
        cp_st.add_goto("flaky", ERR, 2, IDLE);                                                               // (ERR [->2] => IDLE)
        begin
          st_e s1[6] = '{IDLE, BUSY, BUSY, BUSY, DONE, IDLE};      // the lesson's first stream
          st_e s2[5] = '{ERR, IDLE, BUSY, ERR, IDLE};              // and its second
          foreach (s1[i]) begin cp_arc.sample(s1[i]); cp_st.sample(s1[i]); end
          foreach (s2[i]) begin cp_arc.sample(s2[i]); cp_st.sample(s2[i]); end
        end
        cp_arc.report(); cp_st.report();
        if (cp_st.bin_list[0].hits != 1 || cp_st.bin_list[1].hits != 1 || cp_st.bin_list[2].hits != 1) $fatal(1, "FAIL: repetition bins");
        if (cp_arc.bin_list[4].hits != 0 || cp_arc.bin_list[5].hits != 2) $fatal(1, "FAIL: arc bins");
        $display("PASS: busy3, busy_short and flaky each hit once; happy_loop never did, because BUSY always ran more than once before DONE");
        $finish;
      end
    endmodule
    Terminal
      coverpoint cp_arc: 83.33% (5 of 6 bins)  below goal 100
        idle_busy      2
        busy_done      1
        done_idle      1
        any_err        2
        happy_loop     0     <- hole
        recover        2
      coverpoint cp_st: 100.00% (3 of 3 bins)
        busy3          1
        busy_short     1
        flaky          1
    PASS: busy3, busy_short and flaky each hit once; happy_loop never did, because BUSY always ran more than once before DONE

    Common pitfall

    An iff guard that skips samples mid-sequence has tool-dependent effects on transition bins. A tool that skips the sample can count a path across a reset gap, a false hit. Map reset to an out-of-range value in the coverpoint expression when the gap must break the path.

    Interview

    Likely question: FSM coverage with transition bins or SVA cover. Answer with the single-variable versus multi-signal boundary, plus the sampling-discipline caveat.

    Check yourself The plan needs: req rises, then gnt within 3 cycles while abort stays low. Transition bins or SVA cover?

    SVA cover. Three signals with elastic timing sit outside single-variable consecutive sampling.

    Remember

    • (A => B) counts consecutive samples, not cycles.

    • [*N] repeats back to back; [->N] allows gaps.

    • Covering a path is not checking it: pair it with an assertion.

    Rule of thumb: cover the arcs the spec names, not just the states.

    How this was checked

    Counted with the course's bins model (rich/coverage/cov_model.sv, listed on the Coverage hub) on Verilator 5.048 (--binary --timing) on 2026-10-18; every bench printed the PASS line shown. Verilator 5.048 parses covergroups with a COVERIGN warning and ignores their bins, and Icarus 13 has none, so each covergroup listing is marked not run and its bench counts the same bins with the model.

    Over the lesson's two streams busy3, busy_short and flaky each hit once, and happy_loop never did, because BUSY always ran more than once before DONE.

    Related topics

    • Sampling and iff guards

    Previous

    146 / 259

    Next: Exclusions, Patterns & Filters

    Up next

    Up nextExclusions, Patterns & Filters

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Bin Design Strategy
    clkstate01201rst_n
    A sampled state stream that completes (IDLE=>BUSY[*3]=>DONE), then hits a sample that iff skips