git:20260711.0e18132 to git:20260713.5e3a14d

19 added, 0 removed. Audit A to A.

---
name: testbench-gen
description: "Generate a PROFESSIONAL, high-coverage testbench for a design directly from its Phase-1 L-docs — the Phase-2 'Simulation' step (canonical flow Step 4). Use whenever a design needs functional verification: derive the interface (L1/L9), clock/reset (L8/L9), a reference model, a scoreboard, functional coverage, and assertions, then run cocotb. Program-first: the deterministic generator `professional_tb_gen.py` (MCP `eda_professional_tb`) does the derivation; this skill is the judgment layer for filling a non-closed-form reference model and reviewing coverage. Triggers on: 'write a testbench', 'generate testbench', 'verify this design', 'functional verification', 'coverage', '幫我寫 testbench', '產生 testbench', after Phase-2 RTL is authored and before Phase-3."
---
# testbench-gen — deterministic professional testbench generation
The canonical flow's **Step 4 (Simulation)** derives a professional, high-coverage
testbench from the Phase-1 layers — never a hand-waved skeleton. The load-bearing
work is a PROGRAM: `programs/professional_tb_gen.py` (exposed as MCP tool
`eda_professional_tb`). This skill is the judgment layer around it.
## What the program does (program-first)
`professional_tb_gen.py <project>` reads the project's `phase1/generated_docs/L*.json`
and emits, under `phase2/stage1/sim_professional/<top>/`:
- `tb_<top>.py` — a **cocotb** testbench: clock/reset from L8/L9, a reference
model, a SCOREBOARD, functional coverage (cocotb-coverage covergroups), and a
directed-corner + constrained-random stimulus loop.
- `<top>_coverage_model.json` (an **L28** coverage model), `<top>_assertions.sva`
(an **L29** assertion set), a cocotb `Makefile`, and `verification_plan.json`.
It **combines open-source** frameworks rather than re-inventing them: **cocotb**
(TB base) + **cocotb-coverage** (functional coverage + constrained-random) +
**Verilator/Icarus** (sim) + an **SVA bind** for Verilator/SymbiYosys. Add
`cocotb-coverage` to the runtime (see mcp-eda/INSTALL_GUIDE.md).
## The reference-model strategy — 3 tiers (honest, never a vacuous pass)
1. **Closed-form** (arithmetic primitives `c = a OP b`): reuses
`arith_oracle_tb_gen.compute_golden` — the single source of truth.
2. **Bounded-latency streaming scoreboard** (serial datapaths — one parallel
operand + a 1-bit serial operand + a 1-bit serial result, e.g. a bit-serial
multiplier): the scoreboard AUTO-DERIVES the output `(latency, bit_order)`
from a calibration vector, then checks every vector against the closed-form
reference. **This closes the serial-datapath DEFER** that `arith_oracle_tb_gen`
punts on entirely (proven: spm bit-serial multiplier, 208/208 vs
`(x*y) mod 2^N`, `order=lsb latency=1` auto-derived).
3. **Reference hook** (classes with no closed form — CPU/SoC/DSP): the generated
TB emits a clearly-marked `reference_model` hook that **`TestSkip`s until
filled** — NEVER a silent vacuous pass. The judgment layer (this skill /
spec-to-refmodel) fills it from L10 vectors or a spec-derived model, with the
program-vs-AI cross-check (dual-track convergence).
## When YOU (the judgment layer) act
- **Fill a Tier-3 reference model**: read the L-docs (L2 function, L3 protocol,
L10 vectors) and author the Python reference the hook needs — then re-run so
the scoreboard is real. This is the only place an LLM is needed; the interface,
clock/reset, coverage bins, and (for Tier-1/2) the reference are all derived by
the program.
- **Review coverage**: after a run, read `coverage_<top>.xml` + the L28 model;
if functional bins are unhit, add directed vectors or tighten the
constrained-random constraints. Loop until the closure policy (functional bins
100% + code coverage targets) is met.
- **Formalise assertions**: the L29 SVA carries reset→known-state + protocol
handshake properties deterministically; L16 must/shall prose is emitted as
`TODO(spec-to-assertion)` stubs for you to formalise (never fabricated as a
passing SVA).
## Capture
Any recovery here (a new reference-model pattern, a new coverage-derivation rule,
a streaming-alignment case) is captured per `benchmark-enhancement-capture`:
program-first into `professional_tb_gen.py` (a deterministic derivation rule) so
the next design gets it automatically — and, if the gap is in a forked sim tool
(Verilator/Icarus/cocotb), as a **Bucket-T** forked-tool item.
## Gaps to grow into (from the 2026-07-11 verification research)
- Fill the currently-empty **L22 verification plan** fields (coverage_goals /
formal_properties / regression_matrix) and wire them to L28/L29.
- Add **L30 stimulus/constraints** (constrained-random weights, sequences).
- Widen code coverage to FSM-transition / expression / condition (Verilator
`--coverage-user`) and gate sign-off on it.
- pyuvm structural env + riscv-dv for CPU-class constrained-random.
+ ## Compliance gate (mandatory)
+
+ After producing your output, save it to a file and run:
+
+ ```bash
+ python3 plugins/vibe-ic/_shared/skill_compliance_check.py \
+ --requirements plugins/vibe-ic/skills/testbench-gen/compliance.yaml \
+ <your_output_file>
+ ```
+
+ Exit 0 = PASS, exit 1 = FAIL with specific missing elements listed.
+ `compliance.yaml` in the corresponding skill directory enumerates
+ every required element of your output: section headers, metadata fields,
+ handoff lines, tool invocations.
+
+ **Your task is not complete until the audit returns PASS.** Missing
+ elements are the single largest source of skill-execution non-determinism
+ across different agents.
+