Kern-Pipeline: ✅ FERTIG & VALIDIERT
SimulationConfig + CLI einstellbarfull_chem Resist-Parameter in SimulationConfig exposen# NEU in SimulationConfig:
# Dill ABC exposure
dill_A: float = 0.05 # Absorptionskoeffizient [µm⁻¹]
dill_B: float = 0.0 # Bleich-Koeffizient
dill_C: float = 0.05 # Photosäure-Generierung (Default 0.1)
dill_Q: float = 1.0 # Quantenausbeute (NEU, war hardcoded 1.0)
# PEB (ADI)
peb_D: float = 5.0 # Diffusion [nm²/s]
peb_k: float = 0.3 # Reaktionsrate [1/s]
peb_t_bake: float = 60.0 # Backzeit [s]
peb_sigma_diff: float = 5.0 # Analytischer PEB Diffusions-Sigma [nm]
# Mack Development
mack_R_max: float = 100.0
mack_R_min: float = 0.1
mack_n: float = 5.0
mack_M_th: float = 0.5
_cd_via_full_chem diese Config-Parameter nutzen (statt Hardcodes)dose_to_acid(C=dill_C, Q=dill_Q, ...)reaction_diffusion_adi(..., D=peb_D, k=peb_k, n_steps=...)MackModel(R_max=..., R_min=..., n=..., M_th=...)full_chem Parametereuv simulate --resist-model=full_chem --dill-C=0.1 --dill-Q=0.5 --peb-k=0.2 --peb-t=90 --mack-Rmax=200 ...
full_chem vs. aerial_threshold Konsistenztest_reference_nils.py ergänzenstochastic.py Funktionen in Pipeline einbinden# In run_simulation() nach aerial Image:
if cfg.enable_stochastic:
aerial = add_photon_shot_noise(aerial, dose=cfg.dose_mj_cm2, ...)
# oder: aerial = add_resist_stochastics(aerial, ...)
enable_stochastic: bool = False
photons_per_nm2: float = 1e4 # für Shot-Noise
ler_sigma_nm: float = 1.0 # Line Edge Roughness
lwr_sigma_nm: float = 1.5 # Line Width Roughness
euv simulate --stochastic --photons=1e4 --ler=1.2
SimulationResultler_nm: float = 0.0
lwr_nm: float = 0.0
cd_distribution: List[float] = [] # bei Monte-Carlo runs
process-window CLI erweitern--output-csv für Excel-Import--output-plot für PNG (Heatmap CD über Dose×Fokus)--tolerance=±10% einstellbar--target-cd Default aus ConfigSimulationResult um Process-Window Metriken erweiterndepth_of_focus_nm: float = 0.0
exposure_latitude_pct: float = 0.0
meef: float = 0.0 # Mask Error Enhancement Factor
# MEFF = (ΔCD_wafer / CD_wafer) / (ΔCD_mask / CD_mask)
# ≈ d(CD)/d(mask_CD) * (mask_CD / wafer_CD)
# Numerisch über zwei Simulationen mit leicht variiertem mask_CD
mask3d/rcwa.py in Pipeline einbindenabsorber_height, absorber_taper, undercut, multilayer_roughnessuse_rcwa: bool = False
mask_absorber_taper_deg: float = 0.0
mask_undercut_nm: float = 0.0
mask_sidewall_roughness_nm: float = 0.0
use_rcwa=False (analytisch) vs. use_rcwa=True mit dünnem Absorber → Diff < 1%high_na.py Module nutzenhigh_na_mode: bool = False
na_x: float = 0.55
na_y: float = 0.55 * 0.5 # Anamorphose 4x/8x
polarisation: str = "unpolarized" # "TE", "TM", "unpolarized"
zernike_coeffs: List[float] = [] # [Z4, Z5, Z6, ...] Wellenfront-Fehler
euv simulate --high-na --na-x=0.55 --na-y=0.275 --polarisation=TE --zernike="0,0,0.02,0,0"
| Notebook | Thema |
|———-|——-|
| 01_aerial_image.ipynb | Hopkins vs. Abbe, TCC, Kohärenz, SE-Blur |
| 02_nils_cd.ipynb | NILS Definition, Messung, CD-Abhängigkeit |
| 03_resist_chain.ipynb | Dill ABC, PEB, Mack, Dosis-Latitude |
| 04_process_window.ipynb | Bossung, DoF, EL, MEFF |
| 05_stochastics.ipynb | Photon Shot Noise, LER, LWR |
| 06_mask3d.ipynb | RCWA, Mask-3D-Effekte, Best Focus Shift |
pytest auf Ubuntu (CPU) + macOS (ARM)pytest --cov Coverage-Reportpyproject.toml version bumpgit tag v1.1.0pip publish automation| Phase | Aufwand | Dauer (1 Person) | Abhängigkeiten |
|---|---|---|---|
| 1: Resist Config | ~2 Tage | 1 Woche | — |
| 2: Stöckastik | ~3 Tage | 1 Woche | Phase 1 |
| 3: Process Window | ~2 Tage | 3 Tage | — |
| 4: RCWA Integration | ~5 Tage | 2 Wochen | Mask3D Modul stabil |
| 5: High-NA | ~5 Tage | 2 Wochen | High-NA Modul stabil |
| 6: Lehre-Notebooks | ~5 Tage | 1-2 Wochen | Alle Phasen |
| 7: CI/CD | ~2 Tage | 3 Tage | — |
Gesamt: ~24 Tage ≈ 5 Wochen für “Feature-Complete v1.2”
full_chem nutzbar & reproduzierbar