Files
mxpic_forge/scripts/export_technology_manifests.py
T

95 lines
2.9 KiB
Python

import argparse
import os
import shutil
from copy import deepcopy
from pathlib import Path
from typing import Any, Dict
import yaml
from mxpic.technologies.manifest_loader import TECHNOLOGIES_ROOT
SILTERRA_EOM1_MANIFEST = TECHNOLOGIES_ROOT / "silterra" / "EMO1_2ML_CU.yml"
def build_silterra_eom1_manifest() -> Dict[str, Any]:
"""Load the Silterra EOM1 manifest consumed by mxpic_EDA."""
return _build_export_manifest(SILTERRA_EOM1_MANIFEST)
def _build_export_manifest(manifest_path: Path) -> Dict[str, Any]:
with manifest_path.open("r", encoding="utf-8") as file:
manifest = yaml.safe_load(file) or {}
manifest = deepcopy(manifest)
manifest["layers"] = _export_layers(manifest.get("layers", {}))
return manifest
def _export_layers(layers: Dict[str, Any]) -> Dict[str, Any]:
exported = {}
for name, entry in layers.items():
exported_entry = dict(entry)
layer = exported_entry.pop("layer")
exported_entry["layer"] = int(layer[0])
exported_entry["datatype"] = int(layer[1])
exported[name] = exported_entry
return exported
def export_manifests(destination_root: str) -> None:
"""Export supported technology manifests into an EDA PDK root."""
for manifest_path in _manifest_paths():
_export_manifest(manifest_path, destination_root)
def _manifest_paths() -> list[Path]:
return sorted(
path
for path in TECHNOLOGIES_ROOT.glob("*/*.yml")
if path.is_file()
)
def _export_manifest(manifest_path: Path, destination_root: str) -> None:
manifest = _build_export_manifest(manifest_path)
technology_dir = Path(destination_root) / manifest["foundry"] / manifest["technology"]
technology_dir.mkdir(parents=True, exist_ok=True)
_copy_material_files(manifest, manifest_path.parent, technology_dir)
output_path = technology_dir / "technology.yml"
with output_path.open("w", encoding="utf-8") as file:
yaml.safe_dump(manifest, file, sort_keys=False, allow_unicode=True)
def _copy_material_files(manifest: Dict[str, Any], source_dir: Path, technology_dir: Path) -> None:
for material in manifest.get("materials", {}).values():
data_file = material.get("data_file")
if not data_file:
continue
source = source_dir / data_file
if not source.exists():
continue
target = technology_dir / data_file
target.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(source, target)
def main() -> None:
parser = argparse.ArgumentParser(description="Export mxpic technology manifests for mxpic_EDA.")
parser.add_argument(
"--dest",
default=os.path.abspath(os.path.join(os.getcwd(), "..", "mxpic_EDAX", "mxpic", "PDKs")),
help="Destination mxpic_EDA PDK root.",
)
args = parser.parse_args()
export_manifests(os.path.abspath(args.dest))
if __name__ == "__main__":
main()