#!/usr/bin/env python3 """ MTBF Calculator for CDC Synchronizers Based on Xilinx UG953 and Intel AN545 """ import math import sys def calculate_mtbf(t_meta, tau, T0, f_clk, f_data, num_stages=2): """ Calculate Mean Time Between Failures for synchronizer Args: t_meta: Resolution time (seconds) - window after clock edge tau: Metastability time constant (seconds) - typically 10-50 ps T0: Setup/hold violation window (seconds) - typically 1-10 ps f_clk: Clock frequency (Hz) f_data: Data toggle rate (Hz) num_stages: Number of flip-flop stages (2 or 3) Returns: MTBF in seconds """ # Base MTBF for single stage mtbf_base = math.exp(t_meta / tau) / (T0 * f_clk * f_data) # Each additional stage multiplies MTBF by exp(t/tau) if num_stages > 1: for _ in range(num_stages - 1): mtbf_base *= math.exp(t_meta / tau) return mtbf_base def mtbf_to_years(mtbf_seconds): """Convert MTBF from seconds to years""" seconds_per_year = 365.25 * 24 * 3600 return mtbf_seconds / seconds_per_year def print_analysis(params): """Print detailed MTBF analysis""" print("="*70) print("METASTABILITY ANALYSIS - DNA CORE CDC") print("="*70) print() print("Parameters:") print(f" Resolution time (t_meta): {params['t_meta']*1e9:.2f} ns") print(f" Time constant (tau): {params['tau']*1e12:.1f} ps") print(f" Violation window (T0): {params['T0']*1e12:.1f} ps") print(f" Clock frequency: {params['f_clk']/1e6:.1f} MHz") print(f" Data toggle rate: {params['f_data']/1e6:.1f} MHz") print(f" Synchronizer stages: {params['num_stages']}") print() mtbf_sec = calculate_mtbf(**params) mtbf_years = mtbf_to_years(mtbf_sec) print("Results:") print(f" MTBF: {mtbf_years:.2e} years") print() # Safety classification if mtbf_years > 1e15: safety = "AEROSPACE/SAFETY-CRITICAL" status = "āœ… EXCELLENT" elif mtbf_years > 1e12: safety = "INDUSTRIAL" status = "āœ… VERY GOOD" elif mtbf_years > 1e9: safety = "CONSUMER" status = "āœ… ACCEPTABLE" else: safety = "UNSAFE" status = "āŒ INSUFFICIENT" print(f" Classification: {safety}") print(f" Status: {status}") print() # Comparison universe_age = 1.38e10 # years print("Comparison:") print(f" Age of universe: {universe_age:.2e} years") print(f" MTBF / Age: {mtbf_years / universe_age:.2e}x") print() print("="*70) def dna_core_analysis(): """Analysis for DNA core @ 300 MHz with DMA @ 400 MHz""" # Typical UltraScale+ parameters params_2ff = { 't_meta': 1.0e-9, # 1 ns resolution time 'tau': 30e-12, # 30 ps time constant (7nm) 'T0': 10e-12, # 10 ps violation window 'f_clk': 300e6, # 300 MHz DNA clock 'f_data': 100e6, # 100 MHz average toggle 'num_stages': 2 # 2-FF synchronizer } params_3ff = params_2ff.copy() params_3ff['num_stages'] = 3 print("\n" + "="*70) print("DNA CORE CDC ANALYSIS") print("="*70 + "\n") print("Scenario 1: 2-FF Synchronizer (minimum safe)") print("-" * 70) print_analysis(params_2ff) print("\nScenario 2: 3-FF Synchronizer (recommended)") print("-" * 70) print_analysis(params_3ff) # High-frequency worst case params_worst = { 't_meta': 0.5e-9, # 0.5 ns resolution (tighter) 'tau': 20e-12, # 20 ps (worst process corner) 'T0': 15e-12, # 15 ps (worst case) 'f_clk': 400e6, # 400 MHz DMA clock 'f_data': 200e6, # 200 MHz worst-case toggle 'num_stages': 3 } print("\nScenario 3: Worst-Case (400 MHz, tight timing)") print("-" * 70) print_analysis(params_worst) def interactive_mode(): """Interactive MTBF calculator""" print("\n" + "="*70) print("INTERACTIVE MTBF CALCULATOR") print("="*70 + "\n") try: t_meta = float(input("Resolution time (ns): ")) * 1e-9 tau = float(input("Time constant tau (ps): ")) * 1e-12 T0 = float(input("Violation window T0 (ps): ")) * 1e-12 f_clk = float(input("Clock frequency (MHz): ")) * 1e6 f_data = float(input("Data toggle rate (MHz): ")) * 1e6 num_stages = int(input("Number of FF stages (2 or 3): ")) params = { 't_meta': t_meta, 'tau': tau, 'T0': T0, 'f_clk': f_clk, 'f_data': f_data, 'num_stages': num_stages } print() print_analysis(params) except (ValueError, KeyboardInterrupt): print("\nInvalid input or cancelled.") sys.exit(1) if __name__ == "__main__": if len(sys.argv) > 1 and sys.argv[1] == "-i": interactive_mode() else: dna_core_analysis() print("\nšŸ’” Tip: Run with -i flag for interactive mode") print(" python3 mtbf_calculator.py -i") print()