CODEX revised with following function: 1. GDS building, 2. different user group with different authority.

This commit is contained in:
2026-05-28 20:35:49 +08:00
parent e6e9e13cf2
commit 1215bf978a
25 changed files with 439 additions and 196 deletions
+59 -2
View File
@@ -1,5 +1,6 @@
import math
import os
import sys
from dataclasses import dataclass, field
from typing import Dict, List
@@ -16,13 +17,34 @@ class BuildResult:
warnings: List[str] = field(default_factory=list)
def build_project_gds(project_dir: str, output_path: str, pdk_public_root: str) -> BuildResult:
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."""
cells = _load_project_cells(project_dir)
if not cells:
raise ValueError("No saved cell YAML files found for this project")
registry = PdkRegistry(pdk_public_root)
try:
return _build_with_mxpic_router(
project_dir,
output_path,
pdk_public_root,
technology_manifest_path,
prefer_full_gds,
)
except ImportError as router_error:
if _cells_have_links(cells):
raise RuntimeError(
"Routed Build GDS requires mxpic_router, nazca, and mxpic_forge when layout links are present. "
f"Router import failed: {router_error}"
) from router_error
registry = PdkRegistry(pdk_public_root, prefer_full_gds=prefer_full_gds)
os.makedirs(os.path.dirname(output_path), exist_ok=True)
try:
@@ -37,6 +59,33 @@ def build_project_gds(project_dir: str, output_path: str, pdk_public_root: str)
) from nazca_error
def _build_with_mxpic_router(
project_dir: str,
output_path: str,
pdk_root: str,
technology_manifest_path: str,
prefer_full_gds: bool,
) -> BuildResult:
router_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "mxpic_router"))
if os.path.isdir(router_root) and router_root not in sys.path:
sys.path.insert(0, router_root)
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]:
cells = {}
for filename in sorted(os.listdir(project_dir)):
@@ -56,6 +105,14 @@ def _ordered_cell_names(cells: Dict[str, dict]) -> List[str]:
return composites + projects
def _cells_have_links(cells: Dict[str, dict]) -> bool:
for data in cells.values():
for bundle in (data.get("bundles") or {}).values():
if bundle.get("links"):
return True
return False
def _build_with_gdstk(cells: Dict[str, dict], output_path: str, registry: PdkRegistry) -> BuildResult:
import gdstk