UVM RAL · Chapter 10 · RAL Coverage
Register & Field Coverage
With built-in coverage enabled, this page explains what it actually measures at register and field level and what a 100 percent number does and does not tell you. The built-in models measure access and structural coverage, not functional correctness. Register-bit coverage says each bit was written and read, field-value coverage says the field took some spread of values, and address coverage says each address was accessed. The crucial nuance is that this is touched, not verified. A full built-in score means every bit was exercised and values were seen, not that the field's behaviour or the specific critical values and cross combinations were checked. You learn the touched-versus-verified gap and the bug of signing off a field on a coverage number that never required the value a real defect was hiding behind.
Foundation12 min readUVM RALcoverageREG_BITSFIELD_VALStouched vs verified
Chapter 10 · Section 10.2 · RAL Coverage
1. Why Should I Learn This?
Built-in register/field coverage is easy to read and easy to misread: a 100% number feels like 'this register is done,' but it only certifies that bits were touched and values seen, not that the field's behaviour or its critical values and crosses were verified. Knowing exactly what the built-in models measure — and the gap between touched and verified — is what stops you from signing off a field on a coverage number that never required the value a real bug was hiding behind.
Learning to interpret built-in register/field coverage correctly — as structural reach, not functional verification — is what makes the enabling of 10.1 meaningful and motivates the user-defined coverage of 10.3. It is the difference between coverage that reassures and coverage that misleads.
2. Industry Story — 100% covered, and still broken
A team enables built-in coverage, runs their regression, and a control field reports 100% UVM_CVR_FIELD_VALS coverage. 'Field fully covered,' they conclude, and sign it off. The field is a mode selector, and one of its encodings is a reserved/illegal value the hardware is supposed to reject.
The built-in field-value coverage was 100% because the field had taken a spread of values across the regression — enough to fill the automatic bins. But the automatic bins never required the specific reserved encoding to be driven, so the test that would have checked 'does the hardware correctly reject the illegal mode?' never ran, and a bug in that rejection path escaped — while the field showed 100% covered. The coverage number was true (the field was heavily exercised) but misread (100% touched was taken to mean fully verified), and the specific functional value that mattered fell in the gap. It surfaced in silicon as a hang when software accidentally wrote the reserved mode. The post-mortem lesson: built-in field-value coverage measures that a field took some values, not that it took the specific critical values (reserved encodings, boundary modes) or crosses that matter — so 100% built-in coverage means touched, not verified; the critical values that hide bugs must be required explicitly by user-defined coverage (10.3), never assumed from a full built-in number.
3. Concept — built-in coverage measures reach, not behaviour
The built-in register/field models measure access/structural coverage — that stimulus reached the register space — which is real but limited:
UVM_CVR_REG_BITS— bits touched. Did each register bit take 0 and 1 through the bus (written and read)? It certifies reach of every bit, not that the bit's function is correct.UVM_CVR_FIELD_VALS— values seen. What values did the field take? The automatic bins track that the field spanned some values — not that it took the specific functional values (a reserved encoding, a boundary mode) whose meaning matters, nor that those values were crossed with other fields.UVM_CVR_ADDR_MAP— addresses accessed. Was each address hit? Reach of the map, not correctness of what lives there.- The gap: touched vs verified. 100% built-in coverage means every bit was touched and a spread of values was seen — it does not mean the field's behaviour was checked, or that the critical value/cross was exercised. Those require user-defined coverage (10.3).
Here is the gap made concrete: a field's automatic value bins can be full while the functionally-critical values go unrequired:
100% built-in field coverage = values SEEN, not critical values VERIFIED
covergroup4. Mental Model — built-in coverage is a 'did we visit' map, not a 'did it work' checklist
5. Working Example — reading built-in coverage, then requiring what matters
Query built-in register/field coverage for reach, and recognize where user-defined coverage must require the critical values:
// Built-in coverage (enabled per 10.1) gives REACH: was every bit touched, did the field span values?
real bits_cov = reg_model.ctrl.get_coverage(UVM_CVR_REG_BITS); // did we touch every ctrl bit?
real field_cov = reg_model.ctrl.get_coverage(UVM_CVR_FIELD_VALS); // did the field span SOME values?
`uvm_info("COV", $sformatf("ctrl bits=%.1f%% field_vals=%.1f%% (REACH, not behaviour)", bits_cov, field_cov), UVM_LOW)
// 100% here means TOUCHED/SEEN — it does NOT assert the reserved mode was driven or a cross was hit.// The critical values the built-in bins do NOT require must be required EXPLICITLY (user-defined, 10.3):
covergroup mode_cg with function sample(bit [2:0] mode, bit dma_on);
cp_mode: coverpoint mode {
bins normal[] = {[0:5]};
bins boundary = {6};
bins reserved = {7}; // the illegal encoding the hardware must reject — REQUIRED here
}
cp_cross: cross cp_mode, dma_on; // the mode x other-field combination that actually matters
endgroup
// This REQUIRES the reserved value and the cross — closing the touched-vs-verified gap the built-in bins leave.// Interpreting a sign-off: built-in 100% + the user-defined critical bins hit = a defensible 'covered'.
// Built-in 100% ALONE = 'reached', not 'verified' — do not sign off a field on the built-in number alone.Built-in coverage confirms reach (bits touched, values seen); the user-defined covergroup requires the reserved encoding and the cross that the automatic bins never demanded — which is what a full-coverage sign-off actually needs. The next section is the bug of stopping at the built-in 100%.
6. Debugging Session — 100% built-in coverage that missed the value that mattered
A field reports 100% built-in field-value coverage but a reserved encoding was never required, so the bug behind it escaped — built-in 100% is touched, not verified
TOUCHED, NOT VERIFIED// Sign off a mode field on built-in field-value coverage alone:
if (reg_model.ctrl.mode.get_coverage(UVM_CVR_FIELD_VALS) == 100.0)
`uvm_info("COV", "mode field FULLY COVERED — done", UVM_LOW); // BUG: 100% built-in = touched, not verified
// The field took a spread of values (filling the auto bins), but the RESERVED encoding (must be rejected)
// was never REQUIRED -> the test that checks illegal-mode rejection never ran -> bug escapes at 100%.Built-in field-value coverage reads 100% and the field is signed off as 'fully covered.' Yet a real bug — the hardware fails to reject the reserved/illegal mode encoding — escapes, because the specific reserved value was never driven and its rejection never checked. The coverage number gave false confidence: it was genuinely 100% (the field was heavily exercised) but was misread as 'verified.' The escape surfaces later (in silicon, a hang when software writes the reserved mode), with the confusing property that the field had 100% coverage — so coverage 'passed' while a bug behind an unrequired value shipped.
UVM_CVR_FIELD_VALS with its automatic bins measures that the field took some spread of values — enough to fill the auto bins — which it did, so it correctly reported 100%. But the automatic bins do not require the specific functionally-critical values: the reserved/illegal encoding that must be rejected, boundary modes, or values that only matter when crossed with another field. So 100% built-in coverage certified that the field was touched across a range (reach), not that the particular value hiding the bug was exercised or that its behaviour was verified. The sign-off treated a reach metric as a verification metric — the touched-vs-verified gap — and the reserved value fell squarely in that gap: never required by the built-in bins, so never driven, so its (broken) rejection path never tested, all while the number read 100%. Nothing about the coverage was wrong; it was misinterpreted — built-in field coverage cannot, by construction, require the critical values, so a full built-in number simply does not carry the meaning 'fully verified.'
Do not sign off a field on built-in coverage alone. Add user-defined coverage (10.3) that explicitly requires the functionally-critical values and crosses — a coverpoint with an explicit reserved bin for the illegal encoding, boundary bins, and a cross with the other fields that matter — so those must be hit for coverage to close, and pair it with the checks (does the hardware reject the reserved mode?) that verify behaviour. Sign off on built-in reach 100% AND the user-defined critical bins hit AND the behavioural checks passing. The rule the bug teaches: built-in register/field coverage measures reach — bits touched, values seen — so 100% means touched, not verified; the specific critical values (reserved encodings, boundary modes) and crosses that hide bugs are not required by the automatic bins and must be required explicitly by user-defined coverage. A field is 'covered' when the values that matter were required and its behaviour checked — never on a built-in number that only proves the field was reached.
7. Common Mistakes
- Reading 100% built-in coverage as 'verified.' It means bits touched and values seen (reach) — not behaviour checked or critical values exercised.
- Signing off a field on
UVM_CVR_FIELD_VALSalone. The automatic bins do not require reserved encodings, boundary modes, or crosses — those need user-defined coverage (10.3). - Assuming a spread of values covers the critical value. Some values filling the auto bins does not include the specific value that matters — require it explicitly.
- Ignoring cross combinations. A value that only matters when crossed with another field is invisible to per-field built-in bins — model the cross (10.3).
- Confusing coverage with checking. Coverage says a value was exercised; a check says the behaviour was correct — you need both.
8. Industry Best Practices
- Interpret built-in reg/field coverage as reach. Bits touched, values seen, addresses accessed — a real measure of stimulus reach, not of verification.
- Require critical values and crosses explicitly. Reserved encodings, boundary modes, and cross combinations belong in user-defined coverage (10.3), not assumed from built-in bins.
- Sign off on reach AND required-critical-values AND checks. Built-in 100% is necessary context, not a sufficient sign-off.
- Pair coverage with checking. Exercising a value (coverage) is not verifying its behaviour (a check) — ensure both exist for critical values.
- Name the functionally-loaded values per field. Identify which encodings/modes carry meaning and make them required coverage goals.
9. Interview / Review Questions
10. Key Takeaways
- Built-in register/field coverage measures access/structural reach:
UVM_CVR_REG_BITS(each bit touched — took 0 and 1),UVM_CVR_FIELD_VALS(the field took some values),UVM_CVR_ADDR_MAP(each address accessed). - 100% built-in coverage means touched, not verified — it does not assert the field's behaviour was checked, nor that the specific critical values or crosses that matter were exercised.
- The automatic field-value bins require only that a field took some spread of values — not the reserved/illegal encodings, boundary modes, or cross combinations that carry functional meaning.
- The signature bug is signing off a field on built-in 100% while a reserved encoding (or a cross) was never required, so the bug behind it escapes at 100% coverage.
- Built-in coverage is a reach layer; the critical values and crosses must be required explicitly by user-defined coverage (10.3) and paired with checks — sign off on reach AND required-critical-values AND passing checks, never the built-in number alone.