Close Menu
VLSI Web
  • Home
    • About Us
    • Contact Us
    • Privacy Policy
  • Digital Design
    • Digital Circuits
    • Verilog
    • VHDL
    • System Verilog
    • UVM
  • VLSI Roles
    • RTL Design
    • Design Verification
    • Physical Design
    • DFT
    • STA
  • Interviews
  • Informative
  • VLSI Forge
Instagram LinkedIn WhatsApp Telegram
Instagram LinkedIn WhatsApp Telegram
VLSI Web
  • Home
    • About Us
    • Contact Us
    • Privacy Policy
  • Digital Design
    • Digital Circuits
    • Verilog
    • VHDL
    • System Verilog
    • UVM
  • VLSI Roles
    • RTL Design
    • Design Verification
    • Physical Design
    • DFT
    • STA
  • Interviews
  • Informative
  • VLSI Forge
VLSI Web
System Verilog

Functional Coverage in SystemVerilog: Covergroups, Bins and Crosses

Raju GorlaBy Raju Gorla13 July 2026Updated:11 October 2026No Comments4 Mins Read
Functional coverage in SystemVerilog
Share
Facebook Twitter LinkedIn Email Telegram WhatsApp

The short answer: Functional coverage measures which features and scenarios from the spec your tests have actually exercised. In SystemVerilog you write covergroups with coverpoints, bins (explicit, automatic, ranges, transitions, illegal and ignore bins) and crosses, and sample them at the right moments; cover properties capture temporal scenarios. Together with code coverage, it tells you when verification is done, and which constraints or tests to add when it isn’t.

Random tests are only useful if you know what they hit. Functional coverage is how you find out. In this post I show how to write coverage that answers real questions, and how to use it to close verification. It combines my older posts on assertions and functional coverage and on coverage analysis.

For assertions themselves, see SystemVerilog assertions.

  1. Coverage closure
  2. Code coverage vs functional coverage
  3. A covergroup, step by step
  4. Transition and sequence coverage
  5. Where and when to sample
  6. Closing coverage

Table of Contents

  • Part 1: Coverage closure
  • Part 2: Code coverage vs functional coverage
  • Part 3: A covergroup, step by step
  • Part 4: Transition and sequence coverage
  • Part 5: Where and when to sample
  • Part 6: Closing coverage
  • FAQ
    • What is the difference between code coverage and functional coverage?
    • What are illegal_bins and ignore_bins?
    • Where should I sample covergroups?
    • Is 100% functional coverage enough?

Part 1: Coverage closure

The coverage closure loop: plan, model, run, analyse, close
Coverage is a loop, not a number you check once.

Part 2: Code coverage vs functional coverage

Code coverage Functional coverage
Written by The simulator, automatically You, from the verification plan
Measures Lines, branches, conditions, toggles, FSM states Features, values, combinations, sequences
Tells you Which RTL was executed Which spec scenarios were tested
Misses Missing features and unchecked results Code you didn’t think to cover

You need both. 100% code coverage with poor functional coverage means untested features; full functional coverage with low code coverage means dead code or a weak plan.

Part 3: A covergroup, step by step

covergroup txn_cg with function sample(bus_txn t);
  cp_kind: coverpoint t.kind;                   // one bin per enum value

  cp_len: coverpoint t.len {
    bins one      = {1};
    bins small    = {[2:7]};
    bins medium   = {[8:15]};
    bins max      = {16};
    illegal_bins zero = {0};                     // error if ever seen
  }

  cp_addr: coverpoint t.addr[15:12] {
    bins region[] = {[0:15]};                    // 16 bins, one per 4 KB region
  }

  x_kind_len: cross cp_kind, cp_len {
    ignore_bins idle_long = binsof(cp_kind) intersect {IDLE} &&
                            !binsof(cp_len.one);
  }
endgroup

txn_cg cg = new();
// in the monitor, after a transaction completes:
cg.sample(t);

Part 4: Transition and sequence coverage

cp_state: coverpoint state {
  bins start   = (IDLE => RUN);
  bins restart = (DONE => IDLE => RUN);
  bins long_run = (RUN [*4:8]);          // stays in RUN 4 to 8 samples
}

c_b2b: cover property (@(posedge clk) push ##1 push ##1 push);

Part 5: Where and when to sample

  • Sample in the monitor, on completed transactions, not on the stimulus you intended to send. Coverage must reflect what really happened on the DUT’s pins.
  • For internal states, sample on a clock with an explicit event: covergroup fsm_cg @(posedge clk iff !rst);.
  • Don’t sample during reset.

Part 6: Closing coverage

  • Merge coverage from all seeds and tests, then look at the holes, not the percentage.
  • For each hole, ask: is it unreachable (exclude it with a reason), not stimulated (adjust constraints) or a real gap (write a directed test)?
  • Watch for crosses that explode into thousands of bins; only cross what matters.
  • Review exclusions with the designer; an excluded bin is a claim that the scenario can’t happen.

Practise this on VLSI Forge

I built VLSI Forge so you can write RTL in your browser, run it on a real simulator and check every signal in the waveform. Free, nothing to install.

Design Verification problems · Daily challenge

Previous in my SystemVerilog series: SystemVerilog assertions. Next: Testbench architecture.

FAQ

What is the difference between code coverage and functional coverage?

Code coverage is collected automatically and shows which RTL was exercised. Functional coverage is written by you and shows which spec features and scenarios were tested.

What are illegal_bins and ignore_bins?

illegal_bins report an error if the value occurs; ignore_bins remove values from coverage because they don’t matter or can’t occur.

Where should I sample covergroups?

Usually in the monitor, on transactions observed at the DUT interface, so coverage reflects what really happened.

Is 100% functional coverage enough?

Only if the coverage model is good and every check passes. Coverage measures stimulus, not correctness, so it must be paired with checkers.

Assertion-based verification Design verification Functional Coverage Metrics HDL programming System Verilog
Share. Facebook Twitter LinkedIn Email Telegram WhatsApp
Previous ArticleSystemVerilog Assertions (SVA) with Examples
Next Article SystemVerilog Testbench Architecture: A Self-Checking Testbench Without UVM
Raju Gorla
  • Website

Related Posts

Verilog

Blocking vs Non-Blocking Assignments in Verilog (with Waveforms)

25 July 2026
System Verilog

Design Patterns in SystemVerilog Testbenches: Factory, Callbacks and More

16 July 2026
System Verilog

DPI in SystemVerilog: Calling C from Your Testbench (and Back)

15 July 2026
Add A Comment
Leave A Reply Cancel Reply

Topics
  • Digital Circuits
  • Informative
  • Interview Questions
  • Physical Design
  • RTL Design
  • STA
  • System Verilog
  • UVM
  • Verilog
Instagram LinkedIn WhatsApp Telegram
  • About
  • Contact
  • Privacy Policy
  • VLSI Forge
  • Courses
  • Feedback
© 2026 VLSI Web

Type above and press Enter to search. Press Esc to cancel.