CPM UVM verification
UVM environment for the Configurable Packet Modifier (CPM): dual agents, RAL, SVA on interfaces, functional coverage, scoreboard, and reference model. Three DUT bugs found in verification, fixed in RTL v1.1; regression clean with spec v1.1.
DUT Overview
The Configurable Packet Modifier (CPM) is a hardware IP block that processes streaming packets with configurable transformations.
Operation Modes
Register Map
| Address | Name | Access | Fields | Description |
|---|---|---|---|---|
0x00 |
CTRL | RW | ENABLE[0], SOFT_RST[1] | Control register |
0x04 |
MODE | RW | MODE[1:0] | Processing mode (0-3) |
0x08 |
PARAMS | RW | MASK[15:0], ADD_CONST[31:16] | Mode parameters |
0x0C |
DROP_CFG | RW | DROP_EN[0], DROP_OPCODE[7:4] | Drop configuration |
0x10 |
STATUS | RO | BUSY[0] | Pipeline busy status |
0x14 |
COUNT_IN | RO | [31:0] | Input packet counter |
0x18 |
COUNT_OUT | RO | [31:0] | Output packet counter |
0x1C |
DROPPED_COUNT | RO | [31:0] | Dropped packet counter |
COUNT_OUT + DROPPED_COUNT == COUNT_IN
This invariant must always hold when the pipeline is stable (STATUS.BUSY = 0).
The verification environment checks this at end-of-test via RAL readback.
Specification Requirements
Mandatory requirements from the verification project specification. All must be implemented for closure.
Mandatory UVM Mechanisms
- CpmRegModel with all 8 registers
- CpmRegAdapter for bus conversion
- uvm_reg_predictor for auto-prediction
- uvm_reg_hw_reset_seq executed
- CpmConfigSeq for RAL-based configuration
- CpmTopVirtualSeq orchestrates complete flow
- 8-step flow: Reset, Configure, Traffic, Reconfigure, Stress, Drop, Readback, End
- Raises/drops objections at virtual sequence level
- CpmBaseTrafficSeq overridden by CpmCoverageTrafficSeq
- Applied in CpmMainTest.build_phase()
- Demonstrates polymorphism
- CpmPacketStatsCb with real purpose
- Tracks packet statistics (opcode count, payload range)
- Registered in CpmMainTest.connect_phase()
- MODE: 100% (all 4 modes)
- OPCODE: 100% (all 16 opcodes)
- MODE x OPCODE Cross: 100% (64 bins)
- Drop/Stall bins: 50% (hit at least once)
- p_input_stability - Input stable under stall
- p_output_stability - Output stable under stall
- p_bounded_liveness - Packet out within latency
- 4 cover properties - All hit
Coverage Plan
Functional and code coverage strategy to verify all DUT features are exercised.
Functional Coverage Strategy
The coverage model is implemented in CpmPacketCoverage.sv and CpmRegCoverage.sv using SystemVerilog covergroups.
| Coverpoint | Description | Target | Rationale |
|---|---|---|---|
| cp_mode | All 4 operation modes (PASS, XOR, ADD, ROT) | 100% | Each mode has unique transformation logic that must be verified |
| cp_opcode | All 16 opcode values (0x0-0xF) | 90% | Opcodes interact with drop mechanism; high coverage ensures corner cases |
| cp_mode_opcode | Cross coverage: MODE x OPCODE (64 bins) | 80% | Ensures all mode/opcode combinations are tested |
| cp_drop | Drop event occurrence (drop_hit, no_drop) | Hit once | Verify drop mechanism is exercised during testing |
| cp_stall | Backpressure/stall events (stall_hit, no_stall) | Hit once | Verify pipeline backpressure scenarios are tested |
Code Coverage Targets
Code coverage is collected on the DUT (cpm_rtl.sv) using QuestaSim's built-in coverage tools.
| Metric | Target | Description |
|---|---|---|
| Statements | 95% | Percentage of executable statements exercised |
| Branches | 90% | Percentage of if/else and case branches taken |
| Expressions | 90% | Boolean sub-expression coverage |
| Conditions | 80% | Individual condition outcomes in expressions |
| Toggles | 50% | Signal toggle activity (0→1 and 1→0) |
Register Coverage
Register coverage is collected in CpmRegCoverage.sv to ensure all register access patterns are exercised.
- Address coverage: All 8 register addresses accessed (CTRL, MODE, PARAMS, DROP_CFG, STATUS, COUNT_IN, COUNT_OUT, DROPPED_COUNT)
- Operation coverage: Both read and write operations performed
- Cross coverage: Address x Operation combinations
Assertions Plan
SystemVerilog Assertions (SVA) to verify protocol compliance and DUT behavior at the RTL level.
Assertions are implemented in CpmStreamIf.sv and monitor the streaming interface protocol.
All assertions are disabled during reset (disable iff (rst)) to avoid false failures.
Planned Assertions
| Assertion | Requirement | Description |
|---|---|---|
p_input_stability |
Spec 6.3 | When input is valid but not ready (stall condition), all input signals (ID, opcode, payload) must remain stable on the next clock cycle. This ensures the DUT properly handles backpressure from downstream. |
p_output_stability |
Spec 6.3 | When output is valid but not ready (output stall), all output signals must remain stable on the next clock cycle. This verifies the DUT holds output data during backpressure. |
p_bounded_liveness |
Spec 4.1-4.4 | When a packet is accepted at input and output is ready, a packet must exit within a bounded number of cycles (10 cycles to allow for pipeline latency). Disabled when packet is expected to be dropped. |
Planned Cover Properties
Cover properties ensure that important protocol scenarios are exercised during simulation:
| Cover Property | Purpose |
|---|---|
c_input_stall |
Verify that input stall events (in_valid high, in_ready low) occur during testing |
c_output_stall |
Verify that output stall events (out_valid high, out_ready low) occur during testing |
c_in_fire |
Verify that input handshakes (in_valid AND in_ready) complete successfully |
c_out_fire |
Verify that output handshakes (out_valid AND out_ready) complete successfully |
Verification Environment Architecture
Dual-agent UVM architecture with complete separation between packet processing and register configuration.
Testbench Top Module - Hardware Level
- Input stability
- Output stability
- Bounded liveness
- 4 Cover properties
- req, gnt
- addr, wdata, rdata
- write_en
v
UVM Environment (inside Test)
- Valid/Ready handshake
- Callback hooks (pre/post_drive)
- Dual ports: m_ap_input, m_ap_output
- Latency tracking
- Req/Gnt protocol
- Read/Write ops
- Transaction extraction
- m_ap → Predictor
- 4 operation modes
- Drop logic
- Expected queue
- ID+Opcode match
- MODE 100%
- OPCODE 100%
- Cross 100%
- Drop/Stall 50%
- Address 100%
- Operation 100%
- Cross 75%
- 8 Registers
- CpmRegAdapter
- uvm_reg_predictor
TLM Connections
| Source | Destination | Purpose |
|---|---|---|
PacketMonitor.m_ap_input |
Scoreboard.write_input() |
Send input packets for expected queue |
PacketMonitor.m_ap_output |
Scoreboard.write_output() |
Send output packets for comparison |
PacketMonitor.m_ap_input |
PacketCoverage.write() |
Collect functional coverage |
RegMonitor.m_ap |
uvm_reg_predictor.write() |
RAL prediction |
RegMonitor.m_ap |
RegCoverage.write() |
Register coverage |
UVM Component Hierarchy
Complete UVM component hierarchy showing the relationship between all verification components.
Component Tree
Note: Replace this auto-generated diagram with your original hand-drawn component tree diagram for the final presentation.
- CpmRefModel
- Expected queue
- write_input/output()
- m_packet_coverage
- m_reg_coverage
- m_reg_model (8 regs)
- m_reg_adapter
- m_predictor
Component Statistics
RAL Model
Register Abstraction Layer (RAL) implementation - mandatory requirement for systematic register verification.
Central register model containing all 8 CPM registers with proper field definitions.
| Register | Access | Fields |
|---|---|---|
| m_ctrl | RW | m_enable, m_soft_rst |
| m_mode | RW | m_op_mode |
| m_params | RW | m_mask, m_add_const |
| m_drop_cfg | RW | m_drop_en, m_drop_opcode |
| m_status | RO | m_busy |
| m_count_in | RO | m_count_in |
| m_count_out | RO | m_count_out |
| m_dropped_count | RO | m_dropped_count |
RAL Reset Sequence
CpmRalResetTest executes the built-in UVM reset verification sequence to confirm all register reset values match the specification.
This is a mandatory requirement per the verification deliverables document.
Sequence Library
Complete sequence library with virtual sequences orchestrating the test flow.
Virtual Sequence Flow
- Raises objection at start, drops at end
- Checks counter invariant via RAL when
STATUS.BUSY == 0 - Waits for pipeline drain before final checks
Sequence Types
- CpmTopVirtualSeq - Main test flow
- 8-step orchestration
- Raises/drops objections
- Counter invariant check
- CpmConfigSeq - Programs registers
- Sets MODE, MASK, ADD_CONST
- Configures DROP_EN, DROP_OPCODE
- Uses RAL API for all writes
- CpmBaseTrafficSeq - Random packets
- CpmStressSeq - Burst traffic
- CpmDropSeq - Target drop opcode
- CpmCoverageTrafficSeq - All 16 opcodes
Factory Override
The factory override mechanism allows dynamic substitution of sequence types at runtime.
In CpmMainTest.build_phase(), the base traffic sequence is overridden with a coverage-driven variant
(CpmCoverageTrafficSeq) to ensure all opcodes are exercised.
Callback Implementation
Mandatory callback mechanism implemented with real purpose: tracking packet statistics throughout simulation.
The callback mechanism allows external observers to hook into the packet driver's execution flow without modifying the driver itself.
This project implements CpmPacketStatsCb, a concrete callback that collects statistics during simulation.
Extends CpmBasePacketCb with real statistics tracking functionality:
- Opcode distribution: Count per opcode (0-15)
- Total packets: Number of packets driven
- Payload range: Min/max payload values
- Timing: First and last packet timestamps
Registration: Callback is registered in CpmMainTest.connect_phase() using the UVM callback API.
Verification Results Summary
Complete verification results demonstrating all closure criteria have been met with RTL v1.1.
Test Results
| Test | Packets | Matched | Dropped | Mismatched | Status |
|---|---|---|---|---|---|
| CpmSmokeTest | 10 | 10 | 0 | 0 | PASS |
| CpmMainTest | 505 | 485 | 20 | 0 | PASS |
| CpmRalResetTest | N/A | N/A | N/A | N/A | PASS |
Key Metrics
Functional Coverage Results
Code Coverage Results (DUT)
| Metric | Coverage | Target | Status |
|---|---|---|---|
| Statements | 100.00% | 95% | Exceeds |
| Branches | 95.55% | 90% | Exceeds |
| Expressions | 100.00% | 90% | Exceeds |
| Conditions | 88.88% | 80% | Exceeds |
| Toggles | 58.62% | 50% | Exceeds |
| Total DUT | 88.61% | 85% | Exceeds |
Assertion Results
SVA Assertion Status
| Assertion | Status |
|---|---|
p_input_stability |
PASS |
p_output_stability |
PASS |
p_bounded_liveness |
PASS |
Assertion Summary
Counter Invariant Verification
COUNT_IN (40) == COUNT_OUT (40) + DROPPED_COUNT (0)
Verified via RAL readback after waiting for STATUS.BUSY == 0.
RTL v1.1 fix confirmed: counters now correct under backpressure.
Closure Criteria Checklist
- All tests pass (no runtime hangs)
- Scoreboard reports 0 mismatches
- All 3 SVA assertions pass (0 violations)
- Functional coverage targets achieved
- RAL reset sequence passes cleanly
- Counter invariant verified via RAL
- UVM_ERROR count = 0
- All 4 operation modes verified
- Factory override demonstrated
- Callback with real purpose (CpmPacketStatsCb)
- Virtual sequence orchestrates complete flow
- All DUT bugs fixed in RTL v1.1
- Spec v1.1 compliance verified
- Documentation complete
Bug Tracking and Resolution
Complete history of discovered bugs, their root causes, and resolutions. All DUT bugs have been fixed in RTL v1.1.
DUT Bugs (All Fixed in RTL v1.1)
Issue: Counter incremented on out_valid instead of out_fire,
causing multiple counts per packet during backpressure.
Fix: Changed line 287 from if(out_valid) to if(out_fire)
Issue: Output signals changed while out_valid=1 and out_ready=0,
violating Spec Section 6.3 stability rules.
Fix: s0 slot only updates on out_fire
Issue: ROT_AMT hardcoded as localparam instead of configurable register.
Resolution: Spec v1.1 clarifies ROT_AMT is intentionally fixed at 4 bits (not a bug)
Testbench Bugs (All Closed)
| Bug ID | Title | Severity | Status | Resolution |
|---|---|---|---|---|
TB-001 |
Virtual Interface config_db Collision | Critical | Closed | Direct uvm_config_db::set for each interface type |
TB-002 |
Reset Wait Race Condition | High | Closed | Changed to clocked wait: do @(posedge clk) while (rst) |
TB-003 |
Zero-Time Loop in Monitor | High | Closed | Added clock edge before task calls |
TB-004 |
Reference Model Config Stale | Medium | Closed | Read config from RAL model in predict_output() |
TB-005 |
Scoreboard FIFO Ordering Assumption | Medium | Closed | Match by ID+OPCODE instead of FIFO order |
TB-006 |
RAL Model Not Built | Critical | Closed | Added m_reg_model.build() in CpmEnv |
Spec Ambiguities Status
| Issue | Status | Resolution |
|---|---|---|
| ROT_AMT value undefined | Resolved | Spec v1.1 confirms fixed at 4 bits |
| Counter invariant timing | Resolved | STATUS.BUSY defines when invariant holds |
| SOFT_RST scope | Resolved | "Clears counters and internal state" includes pipeline |
| Ordering contradiction | Open | Different latencies vs "no reordering" - needs clarification |
| Counter overflow behavior | Open | Standard wrap assumed (low priority) |
Repository file structure
Paths match the Git tree (verification/, cpm_design/). The bench contains 50 SystemVerilog files under verification/, plus RTL and scripts documented below.
RTL
| Path | Purpose |
|---|---|
cpm_design/cpm_rtl.sv |
CPM DUT |
Packages (verification/pkg/) — 11 files
| Path | Purpose |
|---|---|
verification/pkg/CpmParamsPkg.sv | Parameters, field widths, cpm_mode_e, map constants |
verification/pkg/CpmTransactionsPkg.sv | Packet and register transactions |
verification/pkg/CpmConfigPkg.sv | Env and agent configuration types |
verification/pkg/CpmRalPkg.sv | RAL package / includes |
verification/pkg/CpmPacketAgentPkg.sv | Packet agent compilation unit |
verification/pkg/CpmRegAgentPkg.sv | Register agent compilation unit |
verification/pkg/CpmCoveragePkg.sv | Functional coverage |
verification/pkg/CpmScoreboardPkg.sv | Scoreboard and reference model |
verification/pkg/CpmSequencesPkg.sv | Sequences |
verification/pkg/CpmTestsPkg.sv | Tests |
verification/pkg/CpmEnvPkg.sv | Top environment package |
Transactions — 2 files
| Path | Purpose |
|---|---|
verification/transactions/CpmPacketTxn.sv | Stream packet item |
verification/transactions/CpmRegTxn.sv | Register bus item |
Interfaces — 2 files
| Path | Purpose |
|---|---|
verification/interfaces/CpmStreamIf.sv | Stream valid/ready, SVA and cover properties |
verification/interfaces/CpmRegIf.sv | Register bus signals |
Configuration — 3 files
| Path | Purpose |
|---|---|
verification/config/CpmStreamAgentConfig.sv | Packet agent config |
verification/config/CpmRegAgentConfig.sv | Register agent config |
verification/config/CpmEnvConfig.sv | Environment config |
Packet agent — 4 files (verification/agent/packet/)
| Path | Purpose |
|---|---|
verification/agent/packet/CpmPacketDriver.sv | Valid/ready driver, callback hooks |
verification/agent/packet/CpmPacketMonitor.sv | Dual analysis ports (in/out) |
verification/agent/packet/CpmPacketSequencer.sv | Packet sequencer |
verification/agent/packet/CpmPacketAgent.sv | Agent |
Register agent — 4 files (verification/agent/reg/)
| Path | Purpose |
|---|---|
verification/agent/reg/CpmRegDriver.sv | Req/gnt protocol |
verification/agent/reg/CpmRegMonitor.sv | Bus observer for RAL / coverage |
verification/agent/reg/CpmRegSequencer.sv | Reg sequencer |
verification/agent/reg/CpmRegAgent.sv | Agent |
RAL — 3 files
| Path | Purpose |
|---|---|
verification/ral/CpmRegModel.sv | Eight registers (CTRL, MODE, PARAMS, DROP_CFG, STATUS, counters) |
verification/ral/CpmRegAdapter.sv | reg2bus / bus2reg |
verification/ral/CpmRegPredictor.sv | uvm_reg_predictor |
Sequences — 6 files
| Path | Purpose |
|---|---|
verification/sequences/virtual/CpmTopVirtualSeq.sv | Top virtual sequence (full flow) |
verification/sequences/ral/CpmConfigSeq.sv | RAL programming |
verification/sequences/packet/CpmBaseTrafficSeq.sv | Base random traffic |
verification/sequences/packet/CpmStressSeq.sv | Burst stress |
verification/sequences/packet/CpmDropSeq.sv | Drop-oriented stimulus |
verification/sequences/packet/CpmCoverageTrafficSeq.sv | Coverage / opcode sweep |
Scoreboard — 4 files
| Path | Purpose |
|---|---|
verification/scoreboard/CpmScoreboard.sv | Main scoreboard, queues, invariants |
verification/scoreboard/CpmRefModel.sv | Reference model (modes, drop, latency) |
verification/scoreboard/CpmScoreboardOutputImp.sv | Output analysis_imp |
verification/scoreboard/CpmScoreboardModeImp.sv | Mode side-band analysis_imp |
Coverage — 2 files
| Path | Purpose |
|---|---|
verification/coverage/CpmPacketCoverage.sv | Packet / mode / cross / stall / drop |
verification/coverage/CpmRegCoverage.sv | Register access coverage |
Callbacks — 3 files
| Path | Purpose |
|---|---|
verification/callbacks/CpmBasePacketCb.sv | Base packet callback; includes class CpmPacketStatsCb (same file, not a separate .sv) |
verification/callbacks/CpmBaseRegCb.sv | Base register callback |
verification/callbacks/CpmBaseMonitorCb.sv | Base monitor callback |
Tests — 4 files
| Path | Purpose |
|---|---|
verification/tests/CpmBaseTest.sv | Common test base |
verification/tests/CpmMainTest.sv | Primary test: virtual seq, factory override, stats callback |
verification/tests/CpmSmokeTest.sv | Smoke |
verification/tests/CpmRalResetTest.sv | RAL hardware reset |
Environment and testbench top
| Path | Purpose |
|---|---|
verification/env/CpmEnv.sv | Top UVM env: agents, scoreboard, coverage, RAL, TLM |
verification/tb_top.sv | DUT, interfaces, clocks, reset, run_test() |
Scripts (simulation)
| Path | Purpose |
|---|---|
scripts/Run/run.py | Test runner |
scripts/Run/compile.do | Questa compile |
scripts/Run/elaborate.do | Questa elaborate |
scripts/Run/assertion_report.do | Assertion report |
scripts/generate_coverage_report.py | Optional coverage HTML |
Canonical listing: docs/FILE_STRUCTURE.md (same content as this section).
Project Phases
The verification project was executed in 13 phases, each with specific deliverables.
verification/ tree (50 SystemVerilog files), package layering,
dual-agent architecture, RAL integration, and virtual sequence flow.
What's New in v1.1
Major updates since the initial release, including RTL bug fixes, new callback implementation, and spec clarifications.
- COUNT_OUT: Now increments on
out_fire - Output Stability: Signals stable during stall
- ROT_AMT: Fixed at 4 bits (per spec)
- Tracks packet statistics in real-time
- Counts packets per opcode (16 bins)
- Records min/max payload values
- Measures test duration
- ROT_AMT: Fixed at 4 bits
- STATUS.BUSY: Defines invariant timing
- SOFT_RST: Clears internal state
UVM_ERROR: 0 | SVA Violations: 0 | Mismatches: 0
All 505 packets processed correctly. Counter invariant verified via RAL. All 4 SVA assertions pass.