#!/usr/bin/env python3 """ ChipVerifyAI - Main Gradio Application for Hugging Face Spaces Complete web interface for intelligent chip design verification """ import os import sys import json import pandas as pd import numpy as np import gradio as gr import plotly.graph_objects as go import plotly.express as px from datetime import datetime import warnings import traceback from typing import Dict, List, Any, Optional, Tuple import tempfile import zipfile from pathlib import Path # Import our custom modules from models.ml_models import ChipMLPipeline from models.llm_models import ChipLLMPipeline from data.dataset_collector import DatasetCollector from data.preprocessor import DataPreprocessor from utils.verification_parser import RTLParser from utils.visualizations import create_risk_dashboard, create_coverage_plot from utils.metrics import calculate_verification_metrics # Configure warnings warnings.filterwarnings('ignore') # Global configuration CONFIG = { "app_name": "ChipVerifyAI", "version": "1.0.0", "description": "Intelligent Chip Design Verification with ML + LLM", "max_file_size": 50 * 1024 * 1024, # 50MB "supported_formats": { "rtl": [".v", ".sv", ".vhd"], "docs": [".txt", ".md", ".pdf", ".docx"], "data": [".csv", ".json", ".xml", ".yaml"], "logs": [".log", ".txt"] } } class ChipVerifyAIApp: """Main application class for ChipVerifyAI""" def __init__(self): self.ml_pipeline = None self.llm_pipeline = None self.dataset_collector = None self.preprocessor = None self.rtl_parser = None self.is_initialized = False print("๐Ÿ”ง Initializing ChipVerifyAI Application...") def initialize_app(self) -> str: """Initialize all components of the application""" try: if self.is_initialized: return "โœ… Application already initialized!" print("๐Ÿš€ Starting application initialization...") # Initialize components self.ml_pipeline = ChipMLPipeline() self.llm_pipeline = ChipLLMPipeline() self.dataset_collector = DatasetCollector() self.preprocessor = DataPreprocessor() self.rtl_parser = RTLParser() # Load or train models if not self._load_pretrained_models(): print("๐Ÿ“Š No pretrained models found, initializing with demo models...") self._initialize_demo_models() self.is_initialized = True return "โœ… ChipVerifyAI initialized successfully! Ready for verification tasks." except Exception as e: error_msg = f"โŒ Initialization failed: {str(e)}" print(error_msg) traceback.print_exc() return error_msg def _load_pretrained_models(self) -> bool: """Try to load pretrained models""" try: models_dir = Path("models/trained_models") if models_dir.exists() and any(models_dir.iterdir()): self.ml_pipeline.load_models(str(models_dir)) self.llm_pipeline.load_model(str(models_dir / "llm_model")) print("โœ… Loaded pretrained models") return True return False except Exception as e: print(f"โš ๏ธ Could not load pretrained models: {e}") return False def _initialize_demo_models(self): """Initialize demo models for demonstration""" # Create synthetic data for demo demo_data = self.dataset_collector.create_synthetic_dataset(n_samples=1000) # Train ML models self.ml_pipeline.train_models(demo_data) # Initialize LLM with base model self.llm_pipeline.initialize_base_model() print("โœ… Demo models initialized") def analyze_rtl_design( self, rtl_files: List[Any], design_description: str, complexity_estimate: float, target_frequency: float, power_budget: float ) -> Tuple[str, Any, Any]: """Analyze RTL design files and provide comprehensive assessment""" if not self.is_initialized: init_msg = self.initialize_app() if "failed" in init_msg.lower(): return init_msg, None, None try: analysis_results = { "timestamp": datetime.now().isoformat(), "design_description": design_description, "files_analyzed": len(rtl_files) if rtl_files else 0, "complexity_estimate": complexity_estimate, "target_frequency_mhz": target_frequency, "power_budget_mw": power_budget } # Parse RTL files if provided rtl_features = {} if rtl_files: rtl_features = self._parse_rtl_files(rtl_files) analysis_results.update(rtl_features) else: # Use estimates if no files provided rtl_features = self._estimate_rtl_features( design_description, complexity_estimate ) analysis_results.update(rtl_features) # ML Analysis - Bug Prediction ml_results = self.ml_pipeline.predict_bugs(rtl_features) analysis_results["ml_analysis"] = ml_results # Risk Assessment risk_score = self._calculate_risk_score(rtl_features, ml_results) analysis_results["risk_score"] = risk_score # Generate recommendations recommendations = self._generate_recommendations(analysis_results) analysis_results["recommendations"] = recommendations # Create visualizations risk_plot = create_risk_dashboard(analysis_results) metrics_plot = self._create_metrics_plot(analysis_results) # Format report report = self._format_analysis_report(analysis_results) return report, risk_plot, metrics_plot except Exception as e: error_msg = f"โŒ Analysis failed: {str(e)}" print(error_msg) traceback.print_exc() return error_msg, None, None def generate_testbench( self, design_description: str, testbench_type: str, coverage_targets: str, protocol_type: str ) -> str: """Generate SystemVerilog testbench using LLM""" if not self.is_initialized: init_msg = self.initialize_app() if "failed" in init_msg.lower(): return init_msg try: # Prepare generation parameters generation_params = { "description": design_description, "testbench_type": testbench_type, "coverage_targets": coverage_targets, "protocol": protocol_type, "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S") } # Generate testbench using LLM generated_testbench = self.llm_pipeline.generate_testbench(generation_params) # Add header and metadata header = f"""//============================================================================== // ChipVerifyAI Generated Testbench // Generated: {generation_params['timestamp']} // Description: {design_description} // Type: {testbench_type} // Protocol: {protocol_type} // Coverage Targets: {coverage_targets} //============================================================================== """ full_testbench = header + generated_testbench return full_testbench except Exception as e: error_msg = f"โŒ Testbench generation failed: {str(e)}" print(error_msg) traceback.print_exc() return error_msg def batch_verification_analysis( self, project_files: Any, analysis_config: str ) -> Tuple[str, Any]: """Perform batch analysis on multiple design files""" if not self.is_initialized: init_msg = self.initialize_app() if "failed" in init_msg.lower(): return init_msg, None try: if not project_files: return "โŒ No project files provided", None # Parse configuration try: config = json.loads(analysis_config) if analysis_config else {} except: config = {} # Process files batch_results = [] # Extract files from zip if needed extracted_files = self._extract_project_files(project_files) for file_info in extracted_files: file_analysis = self._analyze_single_file(file_info, config) batch_results.append(file_analysis) # Aggregate results summary = self._create_batch_summary(batch_results) # Create batch visualization batch_plot = self._create_batch_visualization(batch_results) # Format batch report report = self._format_batch_report(summary, batch_results) return report, batch_plot except Exception as e: error_msg = f"โŒ Batch analysis failed: {str(e)}" print(error_msg) traceback.print_exc() return error_msg, None def _parse_rtl_files(self, rtl_files: List[Any]) -> Dict[str, Any]: """Parse RTL files to extract features""" features = { "total_files": len(rtl_files), "total_lines": 0, "module_count": 0, "signal_count": 0, "always_blocks": 0, "complexity_score": 0.0, "has_memory": False, "has_fsm": False, "file_types": [] } try: for file_obj in rtl_files: if hasattr(file_obj, 'name') and hasattr(file_obj, 'read'): content = file_obj.read() if isinstance(content, bytes): content = content.decode('utf-8', errors='ignore') file_features = self.rtl_parser.parse_rtl_content(content) features = self._merge_features(features, file_features) features["file_types"].append(file_obj.name.split('.')[-1]) except Exception as e: print(f"Warning: RTL parsing failed: {e}") # Return default features if parsing fails return features def _estimate_rtl_features(self, description: str, complexity: float) -> Dict[str, Any]: """Estimate RTL features from description and complexity""" # Simple heuristic-based estimation base_lines = int(1000 * complexity) return { "total_lines": base_lines, "module_count": max(1, int(complexity * 3)), "signal_count": base_lines // 10, "always_blocks": base_lines // 20, "complexity_score": complexity, "has_memory": "memory" in description.lower() or "ram" in description.lower(), "has_fsm": "state" in description.lower() or "fsm" in description.lower(), "estimated": True } def _calculate_risk_score(self, rtl_features: Dict, ml_results: Dict) -> float: """Calculate overall risk score""" complexity_risk = min(1.0, rtl_features.get("complexity_score", 0) / 10) ml_risk = ml_results.get("bug_probability", 0) if isinstance(ml_results, dict) else 0 size_risk = min(1.0, rtl_features.get("total_lines", 0) / 20000) return (complexity_risk + ml_risk + size_risk) / 3 def _generate_recommendations(self, analysis: Dict) -> List[str]: """Generate verification recommendations based on analysis""" recommendations = [] risk_score = analysis.get("risk_score", 0) if risk_score > 0.7: recommendations.extend([ "๐Ÿ”ด HIGH RISK: Implement comprehensive verification strategy", "๐Ÿ“‹ Use formal verification methods for critical paths", "๐Ÿงช Increase test coverage targets to >95%", "๐Ÿ‘ฅ Conduct thorough design reviews" ]) elif risk_score > 0.4: recommendations.extend([ "๐ŸŸก MEDIUM RISK: Standard verification practices recommended", "๐Ÿ“Š Monitor coverage metrics closely", "๐Ÿ” Focus on corner case testing" ]) else: recommendations.extend([ "๐ŸŸข LOW RISK: Maintain current verification practices", "๐Ÿ“ˆ Continue monitoring design metrics" ]) # Add specific recommendations based on features if analysis.get("has_memory"): recommendations.append("๐Ÿง  Memory interface detected - verify CDC and coherency") if analysis.get("has_fsm"): recommendations.append("๐Ÿ”„ State machine detected - verify all transitions") return recommendations def _create_metrics_plot(self, analysis: Dict) -> go.Figure: """Create metrics visualization""" metrics = { 'Risk Score': analysis.get('risk_score', 0), 'Complexity': min(1.0, analysis.get('complexity_estimate', 0) / 10), 'Size Factor': min(1.0, analysis.get('total_lines', 0) / 10000), 'ML Confidence': analysis.get('ml_analysis', {}).get('confidence', 0) } fig = go.Figure(data=go.Scatterpolar( r=list(metrics.values()), theta=list(metrics.keys()), fill='toself', name='Design Metrics' )) fig.update_layout( polar=dict( radialaxis=dict( visible=True, range=[0, 1] ) ), showlegend=True, title="Design Metrics Radar Chart" ) return fig def _format_analysis_report(self, analysis: Dict) -> str: """Format comprehensive analysis report""" report = f""" # ๐Ÿ” ChipVerifyAI Analysis Report ## ๐Ÿ“Š Design Overview - **Description**: {analysis.get('design_description', 'N/A')} - **Files Analyzed**: {analysis.get('files_analyzed', 0)} - **Total Lines of Code**: {analysis.get('total_lines', 0):,} - **Complexity Score**: {analysis.get('complexity_score', 0):.2f}/10 - **Analysis Time**: {analysis.get('timestamp', 'N/A')} ## ๐ŸŽฏ Risk Assessment - **Overall Risk Score**: {analysis.get('risk_score', 0):.1%} - **Risk Level**: {'๐Ÿ”ด HIGH' if analysis.get('risk_score', 0) > 0.7 else '๐ŸŸก MEDIUM' if analysis.get('risk_score', 0) > 0.4 else '๐ŸŸข LOW'} ## ๐Ÿค– ML Analysis Results """ ml_results = analysis.get('ml_analysis', {}) if isinstance(ml_results, dict): report += f""" - **Bug Probability**: {ml_results.get('bug_probability', 0):.1%} - **Confidence**: {ml_results.get('confidence', 0):.1%} - **Model Used**: {ml_results.get('model_type', 'Random Forest')} """ report += f""" ## ๐Ÿ“‹ Recommendations """ for rec in analysis.get('recommendations', []): report += f"- {rec}\n" report += f""" ## ๐Ÿ“ˆ Design Characteristics - **Module Count**: {analysis.get('module_count', 0)} - **Signal Count**: {analysis.get('signal_count', 0)} - **Always Blocks**: {analysis.get('always_blocks', 0)} - **Has Memory Interface**: {'Yes' if analysis.get('has_memory') else 'No'} - **Has State Machine**: {'Yes' if analysis.get('has_fsm') else 'No'} ## ๐ŸŽฏ Verification Strategy Based on the analysis results, we recommend: 1. **Priority**: {'High' if analysis.get('risk_score', 0) > 0.7 else 'Medium' if analysis.get('risk_score', 0) > 0.4 else 'Standard'} 2. **Coverage Target**: {'95%+' if analysis.get('risk_score', 0) > 0.7 else '90%+' if analysis.get('risk_score', 0) > 0.4 else '85%+'} 3. **Verification Methods**: {'Formal + Simulation' if analysis.get('risk_score', 0) > 0.7 else 'Simulation + Assertions' if analysis.get('risk_score', 0) > 0.4 else 'Standard Simulation'} --- *Report generated by ChipVerifyAI v{CONFIG['version']}* """ return report def _merge_features(self, base_features: Dict, new_features: Dict) -> Dict: """Merge RTL features from multiple files""" merged = base_features.copy() for key, value in new_features.items(): if key in merged and isinstance(value, (int, float)): merged[key] += value elif key not in merged: merged[key] = value return merged def _extract_project_files(self, project_files: Any) -> List[Dict]: """Extract files from uploaded project archive""" extracted = [] # Implementation for extracting ZIP/TAR files # This would handle project file uploads return extracted def _analyze_single_file(self, file_info: Dict, config: Dict) -> Dict: """Analyze a single file in batch mode""" # Implementation for single file analysis return {"filename": file_info.get("name", "unknown"), "status": "analyzed"} def _create_batch_summary(self, results: List[Dict]) -> Dict: """Create summary from batch results""" return { "total_files": len(results), "analyzed_files": len([r for r in results if r.get("status") == "analyzed"]), "total_risk": sum(r.get("risk_score", 0) for r in results) / len(results) if results else 0 } def _create_batch_visualization(self, results: List[Dict]) -> go.Figure: """Create visualization for batch results""" fig = go.Figure() fig.add_trace(go.Bar( x=[f"File {i+1}" for i in range(len(results))], y=[r.get("risk_score", 0) for r in results], name="Risk Scores" )) fig.update_layout(title="Batch Analysis Results") return fig def _format_batch_report(self, summary: Dict, results: List[Dict]) -> str: """Format batch analysis report""" return f""" # ๐Ÿ“ฆ Batch Analysis Report ## Summary - **Total Files**: {summary.get('total_files', 0)} - **Analyzed**: {summary.get('analyzed_files', 0)} - **Average Risk**: {summary.get('total_risk', 0):.1%} ## Individual Results """ # Initialize the application app = ChipVerifyAIApp() def create_gradio_interface(): """Create and configure the Gradio interface""" # Custom CSS for better styling css = """ .gradio-container { max-width: 1200px !important; margin: auto !important; } .main-header { text-align: center; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; border-radius: 10px; margin-bottom: 20px; } .tab-content { padding: 20px; } .warning-box { background-color: #fff3cd; border: 1px solid #ffeaa7; border-radius: 5px; padding: 15px; margin: 10px 0; } .success-box { background-color: #d4edda; border: 1px solid #c3e6cb; border-radius: 5px; padding: 15px; margin: 10px 0; } """ with gr.Blocks( title=f"{CONFIG['app_name']} - {CONFIG['description']}", theme=gr.themes.Soft(), css=css ) as interface: # Main header gr.HTML(f"""

๐Ÿ”ฌ {CONFIG['app_name']}

{CONFIG['description']}

Version {CONFIG['version']} | Automating 70% of chip verification effort with AI

""") # Initialization section with gr.Row(): with gr.Column(scale=2): init_button = gr.Button("๐Ÿš€ Initialize ChipVerifyAI", variant="primary", size="lg") with gr.Column(scale=3): init_status = gr.Textbox( label="Initialization Status", value="Click 'Initialize ChipVerifyAI' to start the application", interactive=False, lines=2 ) init_button.click(app.initialize_app, outputs=init_status) # Main application tabs with gr.Tabs(): # RTL Analysis Tab with gr.Tab("๐Ÿ” RTL Design Analysis"): gr.HTML("""
๐Ÿ“ Instructions: Upload your RTL files (.v, .sv, .vhd) or provide design details for AI-powered verification analysis.
""") with gr.Row(): with gr.Column(scale=1): rtl_files = gr.Files( label="RTL Design Files", file_count="multiple", file_types=[".v", ".sv", ".vhd", ".txt"], height=150 ) design_desc = gr.Textbox( label="Design Description", placeholder="e.g., 32-bit RISC-V processor with 5-stage pipeline, L1 cache, and AHB interface", lines=4 ) with gr.Row(): complexity_est = gr.Slider( minimum=1, maximum=10, value=5, step=0.5, label="Complexity Estimate (1-10)" ) target_freq = gr.Number( label="Target Frequency (MHz)", value=100, minimum=1 ) power_budget = gr.Number( label="Power Budget (mW)", value=100, minimum=1 ) analyze_button = gr.Button("๐Ÿ” Analyze Design", variant="primary") with gr.Column(scale=1): gr.Markdown("### ๐Ÿ’ก Analysis Tips") gr.Markdown(""" - **Upload RTL files** for detailed analysis - **Provide description** even without files - **Set complexity** based on design size - **Specify targets** for better recommendations ### ๐ŸŽฏ What You'll Get - **Bug probability prediction** - **Risk assessment dashboard** - **Verification recommendations** - **Interactive metrics visualization** """) # Analysis results with gr.Row(): with gr.Column(scale=2): analysis_report = gr.Markdown(label="๐Ÿ“Š Analysis Report") with gr.Column(scale=1): risk_dashboard = gr.Plot(label="๐ŸŽฏ Risk Dashboard") metrics_radar = gr.Plot(label="๐Ÿ“ˆ Design Metrics") analyze_button.click( app.analyze_rtl_design, inputs=[rtl_files, design_desc, complexity_est, target_freq, power_budget], outputs=[analysis_report, risk_dashboard, metrics_radar] ) # Testbench Generation Tab with gr.Tab("โšก Testbench Generation"): gr.HTML("""
๐Ÿค– AI-Powered Generation: Describe your design and get professional SystemVerilog testbenches with UVM methodology.
""") with gr.Row(): with gr.Column(): tb_design_desc = gr.Textbox( label="Design Description for Testbench", placeholder="e.g., UART transmitter with configurable baud rate, 8N1 format, FIFO buffer", lines=4 ) with gr.Row(): tb_type = gr.Dropdown( choices=[ "UVM Testbench", "Basic SystemVerilog Testbench", "Assertion-Based Testbench", "Coverage-Driven Testbench", "Constrained Random Testbench" ], value="UVM Testbench", label="Testbench Type" ) protocol_type = gr.Dropdown( choices=[ "Custom Protocol", "UART", "SPI", "I2C", "AHB", "AXI4", "PCIe", "Ethernet" ], value="Custom Protocol", label="Protocol Type" ) coverage_targets = gr.Textbox( label="Coverage Targets", value="Functional: 95%, Line: 100%, Branch: 95%", lines=2 ) generate_tb_button = gr.Button("โšก Generate Testbench", variant="primary") with gr.Column(): gr.Markdown("### ๐Ÿ› ๏ธ Generation Features") gr.Markdown(""" - **Professional UVM structure** - **Comprehensive assertions** - **Coverage models included** - **Protocol-specific drivers** - **Configurable parameters** - **Industry best practices** ### ๐Ÿ“‹ Supported Protocols - Standard interfaces (UART, SPI, I2C) - Advanced buses (AHB, AXI4) - High-speed (PCIe, Ethernet) - Custom protocol support """) # Generated testbench output generated_testbench = gr.Code( label="๐Ÿ”ง Generated SystemVerilog Testbench", language="systemverilog", lines=25 ) generate_tb_button.click( app.generate_testbench, inputs=[tb_design_desc, tb_type, coverage_targets, protocol_type], outputs=generated_testbench ) # Batch Analysis Tab with gr.Tab("๐Ÿ“ฆ Batch Project Analysis"): gr.HTML("""
๐Ÿ—๏ธ Project-Level Analysis: Upload entire project folders (ZIP) for comprehensive multi-file verification analysis.
""") with gr.Row(): with gr.Column(): project_upload = gr.File( label="Project Files (ZIP/TAR)", file_types=[".zip", ".tar", ".tar.gz"], height=100 ) analysis_config = gr.TextArea( label="Analysis Configuration (JSON)", value='{"coverage_threshold": 90, "complexity_limit": 8, "enable_formal": true}', lines=6 ) batch_analyze_button = gr.Button("๐Ÿ“Š Analyze Project", variant="primary") with gr.Column(): gr.Markdown("### ๐Ÿ“ Project Analysis Features") gr.Markdown(""" - **Multi-file processing** - **Dependency analysis** - **Cross-module verification** - **Hierarchical risk assessment** - **Batch testbench generation** - **Comprehensive reporting** ### โš™๏ธ Configuration Options ```json { "coverage_threshold": 90, "complexity_limit": 8, "enable_formal": true, "protocols": ["uart", "spi"], "generate_testbenches": true } ``` """) # Batch results with gr.Row(): batch_report = gr.Markdown(label="๐Ÿ“‹ Batch Analysis Report") batch_visualization = gr.Plot(label="๐Ÿ“Š Project Overview") batch_analyze_button.click( app.batch_verification_analysis, inputs=[project_upload, analysis_config], outputs=[batch_report, batch_visualization] ) # Footer with information gr.HTML("""

๐Ÿ”ฌ ChipVerifyAI - Revolutionizing Chip Verification

Supported Formats: Verilog (.v), SystemVerilog (.sv), VHDL (.vhd), Documentation (.txt, .md, .pdf)

ML Models: Random Forest, XGBoost, Neural Networks for bug prediction and risk assessment

LLM Generation: Fine-tuned transformers for professional testbench and assertion generation

Open Source: Built for the VLSI community | Research Foundation: AUTG + ChatCPU methodologies

""") return interface # Launch the application if __name__ == "__main__": print(f"๐Ÿš€ Starting {CONFIG['app_name']} v{CONFIG['version']}") # Create and launch the interface demo = create_gradio_interface() # Launch with appropriate settings for Hugging Face Spaces demo.launch( server_name="0.0.0.0", server_port=7860, share=True, show_error=True, show_tips=True, enable_queue=True, max_threads=10 )