| name | rtl-p4s-unit-test-policy |
| description | Internal reference: rtl p4s unit test policy (agent-loaded; do not invoke). |
| user-invocable | false |
Tier 2 Unit Test Policy
Coding Convention Requirements
Testbenches MUST follow project conventions:
- Port connections:
i_ prefix for inputs, o_ prefix for outputs, io_ for bidirectional
- Clock:
clk (single domain) or {domain}_clk (multiple, e.g., sys_clk) — NOT clk_i
- Reset:
rst_n (single domain) or {domain}_rst_n (multiple, e.g., sys_rst_n) — NOT rst_ni
- Use
logic only (NOT reg/wire)
- DUT instance:
u_ prefix (e.g., u_dut)
- Testbench filename:
tb_{module}.sv
Execution Policy
- testbench-dev writes SV testbenches per module (parallel), targeting uarch features
- Reference model comparison: Mode A (DPI-C) or Mode B (file compare) — auto-selected
- func-verifier runs simulations via run_sim.sh and reports results
- Failing tests trigger waveform analysis before reporting
- Gate: all unit tests pass AND reference comparison has zero mismatches
Reference Comparison Modes
| Mode | Condition | Method |
|---|
| A: DPI-C | refc/build/lib{module}_ref.so exists | SV TB calls ref functions via DPI-C, cycle-level comparison |
| B: File | DPI-C unavailable | RTL sim → output file, ref binary → output file, diff comparison |
DPI-C setup:
cd refc && mkdir -p build
gcc -std=c11 -shared -fPIC -o build/lib{module}_ref.so src/{module}_ref.c
Result JSON Schema
Each feature entry supports an optional ac_ids field for acceptance criteria traceability:
ac_ids: array of AC IDs covered by this test (e.g., ["REQ-U-012.AC-1", "REQ-U-012.AC-2"])
- When the requirement has
acceptance_criteria (structured object array with ac_id fields) in
iron-requirements.json, ac_ids MUST be populated for each covered criterion.
- When
acceptance_criteria is absent or an empty array [], ac_ids may be omitted (backward compatible).
{
"module": "{module}",
"tier": 2,
"ref_mode": "A_DPI" | "B_FILE",
"features": [
{"name": "fsm_idle_to_active", "status": "PASS", "req_ids": ["REQ-U-003"], "ac_ids": ["REQ-U-003.AC-1"]},
{"name": "pipeline_latency_3cyc", "status": "PASS", "req_ids": ["REQ-U-007"], "ac_ids": ["REQ-U-007.AC-1",
| |
Tier Transition Rules
- Tier 1 PASS (rtl-p4-implement Wave 4) → Tier 2 eligible
- Tier 2 PASS (this skill) → Tier 3 eligible (rtl-p5s-func-verify)
- Tier 2 FAIL → fix at rtl-p4s-bugfix, re-run Tier 2
Escalation & Stop Conditions
- Module fails unit test and waveform analysis cannot identify root cause → escalate to rtl-architect
- Simulator not available → report to user, suggest installation or Docker EDA image
- Testbench uses wrong naming convention → testbench-dev must rewrite before simulation
- Reference model not available → escalate to user; build ref model first (Absolute Rule 2)
- Reference mismatches persist after RTL fix → escalate to ref-model-dev for model review
Advanced
- Waveform dump: use
ifdef guards for portability (FSDB_DUMP, SHM_DUMP, VCD_DUMP). No dump by default for fast regression. Enable per-run via +define+FSDB_DUMP etc.
- Randomize input sequences with
$urandom for broader coverage
- Use
always_ff, always_comb in testbench helper modules (never always @*)
Minimum Coverage Targets (Tier 2)
These are intentionally lower than P5 targets (90%/80%/70%) to keep Tier 2 fast while ensuring meaningful depth:
Structural coverage:
- FSM state coverage >= 50%
- Line coverage >= 60%
Functional coverage (Tier 2):
Gate-enforced (hard):
- At least one covergroup per module (
covergroups_defined >= 1 in results JSON)
Recommended guidance (not gate-enforced — P5 coverage-analyst verifies these):
- Each FSM should have a covergroup with explicit bins for all states defined in uarch spec
- Each valid/ready interface should have cross-coverage: {valid, ready} x {data = 0, mid, max}
- Bins should be derived from uarch feature list
- Functional coverage bins do NOT have a numeric threshold at Tier 2 — the goal is bin existence and hit, not closure (P5 handles closure)
Traceability:
- Each feature test tagged with REQ-U-* IDs from
docs/phase-3-uarch/iron-requirements.json
Mandatory Error Injection (Tier 2)
Every Tier 2 unit test MUST include at minimum these error injection scenarios
where the module interface supports them:
| Category | Condition | Mandatory Test |
|---|
| Reset recovery | All modules | Assert rst_n=0 during active operation → verify FSM returns to reset state, no residual data |
| Backpressure stress | Modules with valid/ready interface | Hold ready low ≥16 cycles during valid=1 → verify data integrity preserved |
| Boundary arithmetic | Modules with datapath operations | Input at min/max boundary values → verify no overflow/underflow corruption |
Applicability: If a module lacks the interface for a category (e.g., no valid/ready),
that category is N/A. At least ONE error injection test must be present per module.
Gate: unit_results.json features array must contain at least one entry with
name containing "error_" or "err_" or "reset_" or "backpressure_" or "overflow_" prefix.
Absence of any error injection test → WARNING (advisory at Tier 2, enforced at Tier 3).
Final Checklist