1. Stochastic Metastability Injection
To meaningfully test metastability, we must inject it into simulation. Real metastability is random—we need to simulate it stochastically.
Approach 1: Random Clock Skew Injection
Introduce random phase offsets between clock domains:
// Stochastic clock skew injection for metastability testing
reg clk_a, clk_b;
real skew_ns;
initial begin
clk_a = 0;
forever #5 clk_a = ~clk_a; // 100 MHz
end
initial begin
clk_b = 0;
forever begin
// Random phase offset (0-10ns): shifts Clock B unpredictably
// relative to Clock A, hitting setup/hold violations
skew_ns = $urandom_range(0, 10);
#(5 - skew_ns/2) clk_b = ~clk_b;
#(5 + skew_ns/2) clk_b = ~clk_b;
end
end
// Random input changes relative to Clock B edge (stress setup/hold)
always @(*) begin
// 20% chance input toggles in metastable window
if ($urandom < 0.2 * 2^32) begin
async_input = ~async_input;
end
end
Approach 2: Metastable State Injection
Directly force FF output to intermediate voltage during setup/hold violation:
// Inject metastable state into FF1 during violation window
always @(posedge clk_b or negedge rst_b) begin
if (!rst_b) begin
ff1 <= 1'b0;
end else begin
// Detect setup/hold violation window
setup_violation = (async_in !== async_in_prev)
& ($time < SETUP_TIME);
hold_violation = (async_in !== async_in_prev)
& ($time < HOLD_TIME);
if (setup_violation || hold_violation) begin
// Inject metastable state: ~50% probability of 0 vs 1
if ($urandom < 2^31) begin
ff1 <= 1'b0; // May not fully settle
end else begin
ff1 <= 1'b1; // Or settle to 1
end
end else begin
ff1 <= async_in; // Normal capture
end
end
end
2. PVT Corner Simulation
What is PVT?
- P (Process): Fast vs. Slow transistor speed (manufacturing variations)
- V (Voltage): Supply voltage (1.8V, 1.65V, 1.95V, etc.)
- T (Temperature): Operating temperature (-40°C to 125°C)
Metastability is most likely at worst-case PVT: Slow process + High temperature + Low voltage.
Simulation Corners
| Corner | Process | Voltage | Temperature | Metastability Risk |
|---|---|---|---|---|
| SS (Slow-Slow) | Slow | Low | High | ❌ WORST (slowest resolution) |
| FF (Fast-Fast) | Fast | High | Low | ✓ Best (fastest resolution) |
| TT (Typical-Typical) | Typical | Nominal | Nominal | ~ Medium (average case) |
| SF (Slow-Fast) | Slow | High | Low | ~ Medium |
| FS (Fast-Slow) | Fast | Low | High | ~ Medium |
Critical insight: MTBF is worst at SS corner. If MTBF > 1 million years at SS, it's safe at all other corners.
3. Timing Stress Testing
Setup/Hold Window Testing
Intentionally violate setup/hold to stress-test synchronizers:
- Test 1: Input changes 0-50ps before clock edge (setup violation)
- Test 2: Input changes 0-50ps after clock edge (hold violation)
- Test 3: Rapid toggles every 100ps (maximizes violation probability)
- Test 4: Slow input changes relative to fast clock (minimum slack)
Expected result: Even under violation stress, FF2 output should be clean and metastability-free.
4. Clock Frequency Stress
Test CDC at extreme frequency combinations:
Frequency Stress Patterns
Pattern 1: Clock A >> Clock B - Clock A: 1 GHz - Clock B: 10 MHz (100x slower) - Test: Fast input changes, slow output sampling - Risk: Multiple input toggles before Clock B sees any change
Pattern 2: Clock B >> Clock A - Clock A: 10 MHz - Clock B: 1 GHz (100x faster) - Test: Slow input, fast output sampling - Risk: FF2 may capture metastable FF1 before resolution
Pattern 3: Asynchronous clocks (no common divisor) - Clock A: 100 MHz (period 10ns) - Clock B: 333 MHz (period 3ns) - Test: Phase relationship changes randomly - Risk: Worst-case metastability windows more likely
5. Dual-Clock FIFO Stress Testing
FIFO Fill/Empty Stress
- Burst fill: Write 256 entries continuously, then read slowly
- Burst read: Read continuously while writes are slow
- Alternating: Write 10, read 10, write 10, read 10, etc.
- Pointer wrap: Fill to 255 entries, then wrap to 0 and refill
Empty/Full Flag Testing
The flags are synchronized with dual-FF and 2-cycle latency. Test the edge cases:
- FIFO transitions from empty → not empty (read pointer moves)
- FIFO transitions from not full → full (write pointer approaches read pointer)
- Verify no transient glitches or metastable flag states
6. Data Integrity Testing
Pattern-Based Testing
Write specific patterns to FIFO and verify read integrity:
- Pattern 1: Alternating 1s and 0s (0xAAAA, 0x5555, etc.)
- Pattern 2: Walking 1s (0x0001, 0x0002, 0x0004, ... 0x8000)
- Pattern 3: Address-in-address test (entry 0 contains 0x00, entry 1 contains 0x01, etc.)
- Pattern 4: Random data with random interleaving
After each test, verify every word read matches what was written.
7. Common Testing Mistakes
- ❌ Mistake: Only testing synchronizers at nominal voltage/temperature (misses SS corner)
- ✓ Fix: Simulate at all PVT corners, prioritize SS worst-case
- ❌ Mistake: Not stressing setup/hold violations (doesn't exercise metastability detection)
- ✓ Fix: Deliberately inject violations during testing
- ❌ Mistake: Testing only at equal clock frequencies (misses real-world async cases)
- ✓ Fix: Test at extreme frequency ratios (100:1, 1:100, etc.)
- ❌ Mistake: Short simulation runs (metastability is rare, long runs catch problems)
- ✓ Fix: Run simulations for millions of clock cycles
8. Coverage Metrics for CDC
Standard Coverage
- Line coverage: 95%+ of CDC code executed
- Branch coverage: All if/else paths taken
- Toggle coverage: Every signal toggles at least once
CDC-Specific Coverage
- Metastable window coverage: Test inputs sampled during setup/hold violations
- Pointer wrap coverage: Pointers wrap from max value to 0
- Empty/full transitions: FIFO transitions between empty and not-empty, full and not-full
- Gray code all values: Test Gray synchronization with all 256 possible values
- Clock skew coverage: Phase relationship between clocks varies across test range
9. Automated Testing Framework
Professional teams use automated regression suites:
- Test suites: Parameterized tests for 2FF, Gray code, FIFO with multiple configurations
- Random seeds: Different seeds for each test run (explores different random sequences)
- PVT sweeps: Automatically run same tests across all PVT corners
- Coverage tracking: Accumulate coverage across all test runs
- Failure detection: Automated checks for data corruption, glitches, flag inconsistencies
10. Summary & Testing Checklist
- ✅ Inject stochastic metastability: Random skew, random violations
- ✅ Test all PVT corners: Priority on slow-slow worst case
- ✅ Stress setup/hold violations: Intentional timing violations
- ✅ Extreme frequency ratios: 100:1, 1:100, asynchronous clocks
- ✅ FIFO burst patterns: Fill, empty, wrap-around
- ✅ Data integrity: Pattern-based verification
- ✅ 95%+ code coverage
- ✅ CDC-specific coverage: Metastable window, pointer wrap, transitions
- ✅ Long simulation runs: Millions of clock cycles (rare bugs need time)
- ✅ Automated regression: All tests run on every design change
Next (Day 9): Reset synchronization and multi-domain coordination.