Skip to main content
Glama
NellyW8
by NellyW8

read_openlane_reports

Extract and analyze OpenLane report files for PPA metrics, timing, and routing quality. Specify a report category or retrieve all for comprehensive design results evaluation on the EDA Tools MCP Server.

Instructions

Read OpenLane report files for LLM analysis. Returns all reports or specific category for detailed analysis of PPA metrics, timing, routing quality, and other design results.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
project_idYesProject ID from OpenLane run
report_typeNoSpecific report category to read (synthesis, placement, routing, final, etc.). Leave empty to read all reports.

Implementation Reference

  • Core implementation of the 'read_openlane_reports' tool handler in the EDAServer class. Locates the latest OpenLane run directory, reads key report files (synthesis stats, timing reports, final summary), parses essential PPA metrics and design status flags, and returns a structured JSON object suitable for LLM analysis.
    async readOpenlaneReports(projectId: string, reportType?: string): Promise<string> { try { const project = this.projects.get(projectId); if (!project) { return JSON.stringify({ success: false, error: `Project ${projectId} not found.`, }, null, 2); } const runsDir = join(project.dir, "runs"); let latestRun = ""; try { const runs = await fs.readdir(runsDir); if (runs.length === 0) { return JSON.stringify({ success: false, error: "No OpenLane runs found. Run OpenLane flow first.", }, null, 2); } latestRun = runs.sort().reverse()[0]; } catch { return JSON.stringify({ success: false, error: "No runs directory found. Run OpenLane flow first.", }, null, 2); } const reportsDir = join(project.dir, "runs", latestRun, "reports"); const finalDir = join(project.dir, "runs", latestRun, "final"); // Simple results object const results: any = { project_id: projectId, run_id: latestRun, success: true, ppa_metrics: { power_mw: null, max_frequency_mhz: null, total_cells: null, logic_area_um2: null, timing_slack_ns: null }, design_status: { synthesis_complete: false, timing_clean: false, routing_complete: false }, reports: {} }; // Helper to safely read file const readFile = async (path: string) => { try { return await fs.readFile(path, 'utf8'); } catch { return null; } }; // Read synthesis report const synthReport = await readFile(join(reportsDir, "synthesis", "1-synthesis.stat.rpt")); if (synthReport) { results.design_status.synthesis_complete = true; results.reports.synthesis = synthReport.substring(0, 2000); const cellMatch = synthReport.match(/Number of cells:\s*(\d+)/); if (cellMatch) { results.ppa_metrics.total_cells = parseInt(cellMatch[1]); } } // Read timing report try { const routingDir = join(reportsDir, "routing"); const files = await fs.readdir(routingDir); for (const file of files) { if (file.includes('sta') || file.includes('timing')) { const timingReport = await readFile(join(routingDir, file)); if (timingReport) { results.reports.timing = timingReport.substring(0, 2000); const wnsMatch = timingReport.match(/WNS.*?(-?\d+\.?\d*)/i); if (wnsMatch) { const wns = parseFloat(wnsMatch[1]); results.ppa_metrics.timing_slack_ns = wns; results.design_status.timing_clean = wns >= 0; } break; } } } } catch { // Timing reports not available } // Read final summary if available const finalSummary = await readFile(join(finalDir, "final.summary.rpt")); if (finalSummary) { results.reports.final_summary = finalSummary.substring(0, 3000); results.design_status.routing_complete = true; } // Add analysis summary const issues = []; if (!results.design_status.synthesis_complete) issues.push("Synthesis incomplete"); if (!results.design_status.timing_clean) issues.push("Timing violations detected"); if (!results.design_status.routing_complete) issues.push("Routing incomplete"); results.summary = { status: issues.length === 0 ? "SUCCESS" : "ISSUES_FOUND", issues: issues, note: "PPA metrics and design status extracted from OpenLane reports" }; return JSON.stringify(results, null, 2); } catch (error: any) { return JSON.stringify({ success: false, error: error.message || String(error), }, null, 2); } }
  • src/index.ts:840-857 (registration)
    Registration of the 'read_openlane_reports' tool in the ListToolsRequest handler, including name, description, and input schema definition.
    name: "read_openlane_reports", description: "Read OpenLane report files for LLM analysis. Returns all reports or specific category for detailed analysis of PPA metrics, timing, routing quality, and other design results.", inputSchema: { type: "object", properties: { project_id: { type: "string", description: "Project ID from OpenLane run" }, report_type: { type: "string", description: "Specific report category to read (synthesis, placement, routing, final, etc.). Leave empty to read all reports.", default: "" }, }, required: ["project_id"], }, },
  • Input schema for the 'read_openlane_reports' tool, defining parameters project_id (required) and optional report_type.
    inputSchema: { type: "object", properties: { project_id: { type: "string", description: "Project ID from OpenLane run" }, report_type: { type: "string", description: "Specific report category to read (synthesis, placement, routing, final, etc.). Leave empty to read all reports.", default: "" }, }, required: ["project_id"], },
  • src/index.ts:929-939 (registration)
    Dispatch/registration case in the CallToolRequest handler that invokes the readOpenlaneReports method on edaServer instance.
    case "read_openlane_reports": { const projectId = validateRequiredString(args, "project_id", name); const reportType = getStringProperty(args, "report_type", ""); return { content: [{ type: "text", text: await edaServer.readOpenlaneReports(projectId, reportType || undefined), }], }; }

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/NellyW8/mcp-EDA'

If you have feedback or need assistance with the MCP directory API, please join our Discord server