|
CocoTB Framework · Verification Infrastructure for RTL Testing GitHub · Documentation Index · MIT License |
Shared Components Overview¶
Everything in this directory exists because every protocol family needed it. Packets, field configs, randomization, statistics, memory modeling, signal mapping — the protocol BFMs (GAXI, FIFO, APB, AXI4) are built on top of these pieces, and none of it knows which protocol it's serving. When you find yourself reaching for the same helper in two different testbenches, this is where it belongs.
Architecture Overview¶
The shared components sit between the protocol layers and cocotb itself:
graph TB
subgraph Proto["Protocol Layers"]
GAXI[GAXI]
FIFO[FIFO]
APB[APB]
AXI4[AXI4]
end
subgraph Shared["Shared Components"]
Packet[Packet Management]
Random[Randomization & Config]
Stats[Statistics & Monitoring]
Memory[Memory Model]
Signal[Signal Mapping]
Utils[Utilities & Debug]
end
subgraph Core["CocoTB Core"]
CocoTB[CocoTB Framework]
end
Proto --> Shared
Shared --> Core
Component Categories¶
Packet Management & Data Handling¶
The core data structures and the fast paths that move field values in and out of them:
- packet.py: Thread-safe generic packet class with field caching
- packet_factory.py: Factory pattern for packet creation and management
- field_config.py: Rich field configuration with validation and encoding
- data_strategies.py: High-performance data collection/driving with signal caching
Key Features: - Protocol-agnostic packet handling - Automatic field validation and masking - Thread-safe operations for parallel testing - Caching where the hot loops are - FIFO packing/unpacking support
Randomization & Configuration¶
Directed and constrained-random stimulus, from simple weighted bins to field dependencies:
- flex_randomizer.py: Multi-mode randomization engine (constrained, sequence, custom)
- flex_config_gen.py: Helper for creating weighted randomization profiles
- randomization_config.py: High-level randomization configuration framework
Key Features: - Constrained random with weighted bins - Sequence-based deterministic patterns - Custom generator functions - Object bin support (non-numeric values) - Dependency management between fields - Pre-defined timing profiles
Statistics & Monitoring¶
The numbers that tell you what the test actually did:
- master_statistics.py: Statistics for master/slave components (latency, throughput, errors)
- monitor_statistics.py: Basic monitor statistics (transactions, violations)
Key Features: - Real-time performance metrics - Moving window averages - Error categorization and tracking - Protocol violation detection - Reporting you can paste into a bug ticket
Memory & Storage¶
The memory model your slave BFMs and scoreboards talk to:
- memory_model.py: NumPy-based memory with access tracking and region management
Key Features: - NumPy backend for bulk operations - Per-address access tracking - Named region management - Boundary checking and validation - Coverage analysis - Detailed memory dumps
Protocol Support¶
Signal discovery and error injection — the infrastructure the protocol BFMs stand on:
- signal_mapping_helper.py: Automatic signal discovery and mapping for GAXI/FIFO
- protocol_error_handler.py: Generic error injection for testing error handling
Key Features: - Pattern-based signal discovery - Manual signal mapping override - Prefix handling for cocotb compatibility - Error region and transaction management - Protocol violation simulation
Utilities & Debug¶
The small tools that save debug time:
- debug_object.py: Object inspection and detailed logging utilities
Design Principles¶
1. Protocol Agnostic¶
Nothing in the shared layer knows which protocol it's serving. GAXI, FIFO, APB, AXI4 — the same packet, randomizer, and memory model work for all of them unmodified.
2. Performance Optimized¶
The optimizations live where the cycles are:
- Thread-safe caching for parallel testing
- NumPy backend for memory operations
- Pre-computed field validation rules
- Cached signal references in the per-cycle loops
3. Flexible Configuration¶
- Real configuration classes with validation, not bare dicts
- Multiple randomization modes
- Configurable statistics collection
- Field encoding and formatting hooks
4. Comprehensive Error Handling¶
- Error messages with caller context, not bare exceptions
- Graceful degradation for optional features
- Validation that tells you what's wrong and usually how to fix it
5. Rich Debugging Support¶
- Logging at multiple levels
- Object inspection utilities
- Performance statistics and cache hit rates
- Rich table formatting for configuration display
Integration Patterns¶
Typical Component Usage Flow¶
# 1. Configure fields
field_config = FieldConfig()
field_config.add_field(FieldDefinition("addr", 32, format="hex"))
field_config.add_field(FieldDefinition("data", 32, format="hex"))
# 2. Create packet factory
factory = PacketFactory(MyPacket, field_config)
# 3. Set up randomization
randomizer = FlexRandomizer({
'addr': ([(0x1000, 0x2000)], [1.0]),
'data': ([(0, 0xFFFF)], [1.0])
})
# 4. Create memory model
memory = MemoryModel(num_lines=256, bytes_per_line=4, log=log)
# 5. Set up statistics
stats = MasterStatistics()
# 6. Resolve signals (automatic or manual)
resolver = SignalResolver('gaxi_master', dut, bus, log, 'MyMaster')
resolver.apply_to_component(component)
Cross-Component Integration¶
The pieces are designed to fit together, and the seams are deliberate:
- Packets get their structure from FieldConfig and are built by PacketFactory
- Randomization components fill Packet fields with generated values
- Statistics components count what Masters/Slaves/Monitors do
- MemoryModel consumes Packets for transaction-based read/write
- SignalResolver bridges CocoTB signals to component attributes — the exact handles that data_strategies then caches
Performance Characteristics¶
Thread Safety¶
- Caching uses RLock throughout, so components are safe in parallel test environments
- Statistics collection is atomic and consistent
Memory Efficiency¶
- Field caching avoids repeated per-access computation
- NumPy backend for large memory operations
- Cached signal references instead of repeated lookups
- Moving-window statistics so history doesn't grow without bound
Performance Gains¶
Measured against the naive implementations they replaced:
- 40% faster data collection through cached signal references
- 30% faster data driving through cached driving functions
- No per-cycle hasattr()/getattr() calls
- Pre-computed field validation rules
Testing & Validation¶
The shared components validate their own inputs:
- Field validation with specific error messages
- Signal mapping validation with detailed diagnostics
- Memory boundary checking with overflow protection
- Randomization constraint validation with type checking
- Thread-safe cache verification for parallel testing
Future Extensions¶
The architecture leaves room to grow:
- New protocol support through signal mapping patterns
- Additional randomization modes in FlexRandomizer
- Custom metrics in the statistics classes
- Extended memory model features (compression, persistence)
- Additional debugging and profiling utilities
Getting Started¶
Where to start depends on what you're building:
- For Packet Handling: Start with
field_config.pyandpacket.py - For Randomization: Begin with
flex_randomizer.pyandflex_config_gen.py - For Memory Testing: Use
memory_model.pywith your protocol components - For Signal Mapping: Start with
signal_mapping_helper.pyfor automatic discovery - For Statistics: Integrate
master_statistics.pyormonitor_statistics.py
Each component's page has the full API, examples, and the gotchas worth knowing before you wire it into a testbench.