5. Coverage Closure and Progress Tracking Workflow
This workflow analyzes VCS coverage reports, identifies code and functional coverage gaps, acts on human decisions by either building missing coverage models or adding test-plan entries, maintains the verification progress JSON file, plots the coverage trend over time, and produces the formal verification report when a round wraps up.
Coverage and Progress Data Flow
Skills in Detail
1. uvm-coverage-closure — Coverage Closure Analysis
What it does: analyzes VCS coverage reports such as
urgReport, identifies holes in functional coverage and code coverage (line, cond, toggle, branch, FSM), and emits a per-round gap analysis report containing two human-decision tables:Decision table What you write in it Where the decision goes Suspected dead code 豁免(waive) /需补激励(needs stimulus)Rows marked needs stimulus become [coverage-driven]entries intestplan.mdCoverage-model build decision 补建(build it) /暂不补建(not for now)Rows marked build it go into a build list and are handed to uvm-env-coverage-addThe second table answers a different question: were the coverage models that should exist ever written? That is not the same as "which bins does an existing model still miss". Functional coverage can read 100% while an entire feature has no sampling points at all, and such a percentage must not be read as "functional verification completeness". Categories marked not for now are listed again in the next round's report with the earlier decision pre-filled, so they never quietly drop out of sight.
This skill writes no coverage-model code and runs no simulation — it produces the report and the test-plan entries, nothing else.
Usage:
/uvm-coverage-closure <WORK_DIR> <TESTPLAN_MD> <RTL_DIR> [--spec <spec.md>] [--extra-points <file>]
1b. uvm-env-coverage-add — Incremental Coverage-Model Build
- What it does: reads the coverage-model build list from the previous step together with the coverage-goal fields in
testplan.md, and adds covergroups to an existing environment. It edits exactly one file,{ip}_coverage.sv, and touches no other environment file. After writing, it verifies by compiling withCOV=1and fixes until the build passes (at most 3 rounds; otherwise it restores from the backup). - How it differs from
uvm-env-impl:uvm-env-implbuilds an environment from scratch and rewrites driver / monitor / scoreboard along with it. Incremental work on a mature environment must go through this skill instead. - What it does not do: nothing beyond compiling — no simulation, no coverage merge.
- Usage:
/uvm-env-coverage-add <WORK_DIR> <TESTPLAN_MD> <RTL_DIR> [--from-report <report>] [--categories "A,B"] [--spec <path>] [--max-groups N]
A new covergroup requires a full rerun
Covergroups are sampled during simulation: simv.vdb holds the coverage structure (the bins), while each tc_*.vdb holds only hit data. Changing a covergroup definition changes the structure, so you must recompile and rerun every test case — rerunning only the new ones has no effect. Functional coverage will drop noticeably afterwards because the denominator grew; that is expected.
2. uvm-progress-tracker — Verification Progress JSON
- What it does: maintains the verification progress JSON file.
initmode — creates a new progress file with the current time as the starting point.appendmode — appends one stage entry recordingstart_time(when the stage began),finish_time(when it ended), andduration(how long that stage itself took, in minutes). With--rpt-dirit first runsmake mergeand then reads every coverage metric back from the URG report.
- Usage:
/uvm-progress-tracker [<NAME>] [<COVERAGE>] [--file <PATH>] [--start-time <ts>] [--rpt-dir <PATH>]
duration is not cumulative
Earlier files used time_min, which meant minutes elapsed from the start of the run to the end of that stage — a 9-minute document review and a 52-hour simulation looked alike in the file, and you had to subtract by hand to recover either one. Each stage now records its own duration. While both formats are in circulation, decide once for the whole file: if any stage carries duration, read the entire file as per-stage durations; otherwise time_min keeps its cumulative meaning. Guessing stage by stage makes the time axis run backwards.
3. uvm-progress-chart — Progress Trend Chart
- What it does: renders a "verification progress (time vs. coverage)" line chart from staged progress data in JSON, redrawing the full chart each time and emitting both a
.drawiofile and a.pngimage. - Usage:
/uvm-progress-chart <INPUT_JSON> <OUTPUT_DIR> [<BASENAME>]
4. uvm-report-gen — Formal Verification Report
- What it does: when a verification round wraps up, it gathers facts scattered across the project into a Word report fit for delivery.
collect_facts.pyfirst collects verifiable figures from the coverage report, regression status, DUT defect ledger, test plan, RTL, SVA, and simulation logs; the report is then written as Markdown against an outline and rendered to a styled.docx, with placeholder boxes where screenshots belong. - Why not hand-roll
python-docx: the data sources are scattered and each one carries a definitional trap — DUT scope vs. the report front page's global scope, assertion source statements vs. bind instances, and aregression_status.mdthat records snap judgments and is never back-filled. Miss one and a wrong number reaches the reader. - Two hard rules:
- Never resolve a conflict silently — when two sources disagree, both go into the "data reconciliation" section, stating which one was used and why;
- Never overwrite a report that already has screenshots pasted in — writing is refused when the target docx contains embedded images (once a placeholder becomes a real screenshot, regenerating would wipe it out along with any other manual edits). Use
--forceif you genuinely mean to.
- Defects come from
dut_defect_ledger.mdonly — never inferred from regression status. - Usage:
/uvm-report-gen <WORK_DIR> <OUTPUT_DOCX> [--rpt-dir <rpt>] [--testplan <md>] [--ledger <md>] [--spec <md>] [--rtl-dir <dir>] [--kb <md>] [--progress <json>] [--outline <md>]
4b. uvm-report-gen-qmd — Multi-Format Report (Quarto)
How it relates to the previous skill: fact collection and authoring are identical — the same
collect_facts.py, the same outline, kept from drifting bycheck-script-copies.mjs. The two diverge only at the rendering layer.uvm-report-genuvm-report-gen-qmdRenderer python-docx, drawn by handQuarto (Pandoc underneath) Output .docxonly.docx+.html(+.pdf)TOC / page numbers Hand-written static list, no page numbers One line of YAML, generated Table / figure numbering None Automatic, with @tbl-x/@fig-xcross-referencesScreenshots Placeholder boxes, pasted into the docx by hand afterwards Image files in the project, assembled at render time Dependency python-docx(a pip wheel)The Quarto binary (~150MB, per platform) Which to use: delivering only a docx, or targeting a machine that cannot install Quarto →
uvm-report-gen. Need several formats → this skill.The intermediate
.qmdis left on disk and rendering is a separatequarto rendercommand, so a site without Quarto can fall back to another renderer without untangling a pipeline.Usage:
/uvm-report-gen-qmd <WORK_DIR> <OUTPUT_DIR> [--formats docx,html] [--assets-dir <dir>] [--reference-docx <docx>] [--rpt-dir <rpt>] [--testplan <md>] [--ledger <md>] …
The Word TOC is a field, not text
The table of contents Quarto writes into a docx is a TOC field instruction with an empty result; Word fills it in only when the field is updated. The skill's finalize_docx.py sets <w:updateFields w:val="true"/> so Word and WPS offer to update on open.
But soffice --headless --convert-to pdf does not evaluate that field (measured, not assumed) — a PDF made straight from the docx has a blank contents page, and it looks finished. For a PDF, either open and update the document in Word/WPS first and save as PDF, or let Quarto produce the PDF directly (that path's TOC is real body text, but it needs a LaTeX/typst engine with usable Chinese fonts).
