Files
mxpic_EDA/backend/gds_builder.py
T

85 lines
2.7 KiB
Python

# -----------------------------------------------------------------------------
# Description: Backend integration wrapper for required mxpic_router project GDS generation.
# Inside functions: build_project_gds, _build_with_mxpic_router, _load_project_cells
# Developer : Qin Yue @ 2026
# Organization : OptiHK Limited
# -----------------------------------------------------------------------------
import os
from dataclasses import dataclass, field
from typing import Dict, List
import yaml
from router_dependency import require_router_stack
@dataclass
class BuildResult:
"""Container for GDS build output paths, status details, and engine metadata."""
output_path: str
engine: str
cells_built: List[str] = field(default_factory=list)
warnings: List[str] = field(default_factory=list)
def build_project_gds(
project_dir: str,
output_path: str,
pdk_public_root: str,
technology_manifest_path: str = None,
prefer_full_gds: bool = False,
) -> BuildResult:
"""Build a hierarchical project GDS from saved cell YAML files with mxpic_router."""
cells = _load_project_cells(project_dir)
if not cells:
raise ValueError("No saved cell YAML files found for this project")
return _build_with_mxpic_router(
project_dir,
output_path,
pdk_public_root,
technology_manifest_path,
prefer_full_gds,
)
def _build_with_mxpic_router(
project_dir: str,
output_path: str,
pdk_root: str,
technology_manifest_path: str,
prefer_full_gds: bool,
) -> BuildResult:
"""Delegate project GDS generation to the required external mxpic_router package."""
require_router_stack()
from mxpic_router import build_project_gds as build_routed_project_gds
result = build_routed_project_gds(
project_dir=project_dir,
output_path=output_path,
pdk_root=pdk_root,
technology_manifest_path=technology_manifest_path,
prefer_full_gds=prefer_full_gds,
)
return BuildResult(
output_path=result.get("output_path", output_path),
engine=result.get("engine", "mxpic_router"),
cells_built=result.get("cells_built", []),
warnings=result.get("warnings", []),
)
def _load_project_cells(project_dir: str) -> Dict[str, dict]:
"""Load saved cell YAML documents from a project directory."""
cells = {}
for filename in sorted(os.listdir(project_dir)):
if not filename.lower().endswith((".yml", ".yaml")):
continue
path = os.path.join(project_dir, filename)
with open(path, "r", encoding="utf-8") as file:
data = yaml.safe_load(file) or {}
cell_name = str(data.get("name") or os.path.splitext(filename)[0])
cells[cell_name] = data
return cells