NAME

Physics::Electrodeposition - Model metal electrodeposition (electroplating) on semiconductor wafers.

SYNOPSIS

use Physics::Electrodeposition;

# Blanket, constant-current copper plating on a 300 mm wafer.
my $ecd = Physics::Electrodeposition->new(
    metal            => 'Copper',
    wafer_diameter   => 300,      # mm
    current_density  => 20,       # mA/cm^2
    target_thickness => 1.0,      # um  (module solves for time)
    efficiency       => 0.97,
    anode_type       => 'soluble',
);

print $ecd->report;               # full text report

my $h  = $ecd->film_thickness_um; # final thickness, um
my $P  = $ecd->power;             # cell power, W
my $mb = $ecd->mass_balance;      # hashref of species moles/grams

# Through-mask plating from a GDSII opening layer.
my $pillars = Physics::Electrodeposition->new(
    gdsii                 => 'reticle.gds',
    pattern_layer         => 10,       # layer containing plating openings
    pattern_datatype      => 0,        # optional datatype filter
    pattern_scope         => 'die',    # stepped reticle, not full wafer
    resist_thickness      => 50,       # um
    current_density       => 10,       # mA/cm^2 in the openings
    current_density_basis => 'active',
    target_thickness      => 40,       # um pillar height
    ion_conc              => 0.63,     # mol/L Cu2+
    boundary_layer        => 0.008,    # cm
);

printf "open %.1f%%, active j %.1f mA/cm2, time %.1f min\n",
    100 * $pillars->open_fraction,
    $pillars->j_active_mA,
    $pillars->process_time / 60;

DESCRIPTION

Physics::Electrodeposition implements a first-principles engineering model of constant-current (galvanostatic) electrodeposition of a metal onto a circular wafer cathode. It is parameterized for an acid copper-sulfate damascene bath by default but works for any metal/bath by overriding constructor arguments.

The model couples Faraday's law (mass and thickness), a lumped cell-voltage model (thermodynamic + activation + concentration overpotentials + ohmic drop + additive drop) for power, a diffusion-limited current density for transport, and geometry-based estimates of uniformity (Wagner number, seed terminal effect) and surface smoothness.

CONSTRUCTOR

new(%args)

Construct a simulation object. All inputs are named arguments. Defaults describe an acid copper-sulfate bath with a soluble copper anode on a 300 mm wafer; any metal, bath, tool, pattern, or recipe parameter may be overridden.

Metal and cathode-deposit inputs include metal, molar_mass (g/mol), valence, density (g/cm3), E0 (V vs SHE), and seed_resistivity (Ohm*cm). Bath inputs include ion_conc and acid_conc (mol/L), conductivity (S/cm), diffusivity (cm2/s), temperature (K), j0 (A/cm2), alpha, additive_drop (V), and additive_use (mL/kA*h). Tool inputs include wafer_diameter (mm), electrode_gap (cm), seed_thickness (nm), boundary_layer (cm), and anode_type, either soluble or inert.

Recipe inputs are current_density (mA/cm2), current_density_basis, time (s), target_thickness (um), and efficiency. If time is not given, process_time is solved from target_thickness. For patterned models, current_density_basis defaults to active (current density in openings); for blanket models it defaults to applied (current density over the wafer).

my $ni = Physics::Electrodeposition->new(
    metal           => 'Nickel',
    molar_mass      => 58.6934,
    valence         => 2,
    density         => 8.90,
    E0              => -0.257,
    ion_conc        => 0.90,
    conductivity    => 0.12,
    current_density => 5,
    time            => 20 * 60,
);

MODEL AND GEOMETRY ACCESSORS

open_fraction

Return the plated/open area fraction. Blanket simulations return 1.0. Patterned simulations return the GDSII opening area divided by the pattern field area.

printf "open area = %.2f%%\n", 100 * $model->open_fraction;
j_applied

Return the wafer-referenced current density in A/cm2. This drives total tool current, bulk electrolyte IR drop, and seed terminal-effect calculations.

my $tool_j = $model->j_applied;
j_active

Return the feature/opening-referenced current density in A/cm2. This drives Faraday growth, interfacial kinetics, and mass-transport checks. For a patterned run with current_density_basis = 'applied'>, this is the applied current density divided by open_fraction.

printf "surface j = %.3f A/cm2\n", $model->j_active;
j

Backward-compatible alias for j_applied.

j_applied_mA

Return j_applied in mA/cm2.

j_active_mA

Return j_active in mA/cm2.

printf "applied/active = %.2f / %.2f mA/cm2\n",
    $model->j_applied_mA, $model->j_active_mA;
wafer_area

Return circular wafer cathode area in cm2 from wafer_diameter.

wafer_radius

Return wafer radius in cm.

current

Return total cell current in amperes, j_applied * wafer_area.

active_area

Return plated area in cm2, open_fraction * wafer_area.

printf "wafer %.1f cm2, active %.1f cm2, current %.2f A\n",
    $model->wafer_area, $model->active_area, $model->current;
ion_conc_cgs

Return metal-ion concentration in mol/cm3, converted from constructor ion_conc in mol/L.

seed_sheet_resistance

Return seed-layer sheet resistance in Ohm/square from seed_resistivity and seed_thickness.

printf "Cu seed Rs = %.3f Ohm/sq\n", $model->seed_sheet_resistance;

GROWTH, TIME, CHARGE, AND MASS METHODS

deposition_rate

Return Faraday-law growth rate in cm/s at the active plating surface.

deposition_rate_um_min

Return the same growth rate in um/min.

process_time

Return plating time in seconds. If time was supplied to new, that value is returned. Otherwise the method solves the time required to reach target_thickness from deposition_rate.

film_thickness

Return final active-area film thickness in cm.

film_thickness_um

Return final active-area film thickness in um.

blanket_equivalent_thickness_um

For patterned runs, return the blanket film thickness that the same total charge would deposit if spread over the full wafer. This equals film_thickness_um * open_fraction. For blanket runs it equals the film thickness.

printf "rate %.3f um/min, time %.1f min, feature h %.2f um\n",
    $model->deposition_rate_um_min,
    $model->process_time / 60,
    $model->film_thickness_um;
printf "blanket-equivalent h %.3f um\n",
    $model->blanket_equivalent_thickness_um;
charge

Return total charge passed in coulombs.

moles_deposited

Return moles of metal deposited at the cathode, including current efficiency.

mass_deposited

Return grams of metal deposited.

mass_balance

Return a hash reference with run chemistry quantities. Keys include charge_C, amp_hours, metal_mol, metal_g, ion_consumed_mol, H2_evolved_mol, H2_evolved_L_STP, Hplus_consumed_cathode_mol, net_Hplus_change_mol, and additive_mL. Soluble-anode runs also include anode_metal_dissolved_mol, ion_replenished_mol, and net_ion_change_mol. Inert-anode runs set metal replenishment to zero and add O2_evolved_mol, O2_evolved_L_STP, and Hplus_generated_anode_mol.

my $mb = $model->mass_balance;
printf "Q %.0f C, metal %.4f g, additive %.3f mL\n",
    $model->charge, $model->mass_deposited, $mb->{additive_mL};
printf "net ion change %.6f mol\n", $mb->{net_ion_change_mol};

TRANSPORT, VOLTAGE, AND POWER METHODS

limiting_current_density

Return diffusion-limited active current density in A/cm2, n F D C / delta, using diffusivity, ion_conc, boundary_layer, and valence.

current_fraction_of_limit

Return j_active / limiting_current_density. Values below about 0.7 generally indicate transport margin; values near 1 indicate starvation, roughness, or powdery deposit risk.

die "too close to limiting current"
    if $model->current_fraction_of_limit > 0.8;
thermodynamic_voltage

Return reversible cell-voltage contribution in volts. A soluble symmetric metal anode returns approximately zero; an inert anode includes oxygen evolution relative to the metal reduction potential.

activation_overpotential

Return cathodic activation overpotential magnitude in volts from a Tafel form using j_active, j0, alpha, temperature, and valence.

concentration_overpotential

Return mass-transport concentration overpotential magnitude in volts from current_fraction_of_limit.

ohmic_drop

Return electrolyte IR drop in volts from j_applied, electrode_gap, and conductivity.

cell_voltage

Return total lumped cell voltage in volts: thermodynamic, cathodic activation, anodic activation, concentration, ohmic, and additive terms.

power

Return electrical power in watts, cell_voltage * current.

energy

Return total electrical energy in joules.

energy_Wh

Return total electrical energy in watt-hours.

specific_energy_kWh_kg

Return electrical energy intensity in kWh/kg of deposited metal.

printf "jlim %.1f mA/cm2, eta_act %.3f V, eta_conc %.3f V\n",
    1000 * $model->limiting_current_density,
    $model->activation_overpotential,
    $model->concentration_overpotential;
printf "cell %.2f V, %.1f W, %.3f Wh, %.2f kWh/kg\n",
    $model->cell_voltage, $model->power,
    $model->energy_Wh, $model->specific_energy_kWh_kg;

UNIFORMITY AND SURFACE QUALITY METHODS

polarization_resistance

Return charge-transfer areal resistance in Ohm*cm2, d eta_act / d j, at the active current density.

concentration_resistance

Return concentration-polarization areal resistance in Ohm*cm2, d eta_conc / d j, at the active current density.

electrolyte_areal_resistance

Return normal electrolyte areal resistance in Ohm*cm2, electrode_gap / conductivity.

series_areal_resistance

Return the sum of polarization, concentration, and electrolyte areal resistances. The terminal-effect metric compares lateral seed drop against this wafer-normal resistance.

wagner_number

Return the wafer-scale Wagner number. Larger values imply that kinetics help throw current uniformly; small values imply a primary/ohmic distribution that needs tool shaping.

terminal_effect_drop

Return estimated center-to-edge voltage drop in the seed layer in volts.

terminal_effect_ratio

Return dimensionless terminal-effect severity: lateral seed drop divided by the wafer-normal voltage scale.

nonuniformity_percent

Return estimated uncompensated within-wafer non-uniformity in percent (1 sigma).

roughness_nm

Return estimated RMS roughness in nm from film thickness, transport loading, and additive leveling.

smoothness_verdict

Return a qualitative string such as EXCELLENT, GOOD, MARGINAL, or ROUGH / powdery risk based mainly on the fraction of limiting current.

printf "Wa %.2f, seed drop %.3f V, terminal ratio %.2f\n",
    $model->wagner_number,
    $model->terminal_effect_drop,
    $model->terminal_effect_ratio;
printf "WIWNU %.1f%%, roughness %.1f nm: %s\n",
    $model->nonuniformity_percent,
    $model->roughness_nm,
    $model->smoothness_verdict;

PATTERN AND GDSII METHODS

has_pattern

Return true when the model has a Physics::Electrodeposition::Pattern object, either supplied directly with pattern or built from gdsii.

loading_nonuniformity

Return estimated within-die non-uniformity in percent from local pattern-density loading. It delegates to the Pattern object and uses loading_exponent.

isolated_to_dense_ratio

Return estimated height ratio of isolated openings to dense-array openings. Values above 1 mean isolated features plate taller.

pattern_radial_nonuniformity

Return radial density-driven within-wafer non-uniformity in percent for pattern_scope = 'wafer'>. For die-scope or blanket runs, returns zero.

feature_aspect_ratio

Return resist_thickness / minimum_CD. Returns zero when no pattern is present or resist_thickness is not set.

fill_risk_verdict

Return a qualitative through-mask filling warning based on aspect ratio and transport loading.

if ($model->has_pattern) {
    printf "loading %.1f%%, iso/dense %.2fx\n",
        $model->loading_nonuniformity,
        $model->isolated_to_dense_ratio;
    printf "radial NU %.1f%%, AR %.2f, risk: %s\n",
        $model->pattern_radial_nonuniformity,
        $model->feature_aspect_ratio,
        $model->fill_risk_verdict;
}

REPORTING

report

Return a formatted multi-section text report with narrative insight (adds a PHOTORESIST PATTERN section when a GDSII mask is supplied).

print $model->report;

PHOTORESIST PATTERNING (GDSII)

Pass gdsii => 'mask.gds' to import mask openings from a GDSII layout. The constructor creates a Physics::Electrodeposition::Pattern object by calling "new" in Physics::Electrodeposition::Pattern with the file path, optional pattern_layer, optional pattern_datatype, pattern_scope, and wafer_diameter. You may also construct a Pattern object yourself and pass it as pattern = $pat> when you want to reuse parsed geometry or inspect it before simulation.

use Physics::Electrodeposition;
use Physics::Electrodeposition::Pattern;

my $pat = Physics::Electrodeposition::Pattern->new(
    file     => 'bumps.gds',
    layer    => 10,
    datatype => 0,
    scope    => 'die',
    grid     => 16,
);

my $run = Physics::Electrodeposition->new(
    pattern               => $pat,
    pattern_layer         => 10,
    pattern_scope         => 'die',
    resist_thickness      => 45,
    current_density       => 8,
    current_density_basis => 'active',
    target_thickness      => 30,
);

print $run->report;

The GDSII reader is dependency-free and understands the subset needed for mask geometry extraction: units, structures, BOUNDARY and BOX elements, and SREF/AREF cell references. Referenced cells are flattened with their transforms, and returned polygon coordinates are converted to micrometres. The pattern layer is interpreted as plating openings in photoresist; the code sums those polygon areas and assumes the openings are non-overlapping. It does not perform Boolean union/overlap cleanup, resist-profile modeling, or a full 3-D field solve.

pattern_layer should identify the layout layer that represents open resist windows, not metal fill or keep-out layers. If it is omitted, all polygon layers are included. pattern_datatype further filters shapes on that layer. pattern_scope = 'die'> treats the GDSII bounding box as one reticle/die field that is stepped across the wafer and reports within-die loading. pattern_scope = 'wafer'> treats the GDSII as a full-wafer mask and enables radial pattern-density non-uniformity.

Current-density basis is important for patterned simulations. With current_density_basis = 'active'>, the recipe current density is already referenced to the open plating area, so total tool current decreases with open fraction. With current_density_basis = 'applied'>, the recipe current density is referenced to the full wafer, so the active in-opening current density increases as open fraction decreases.

my $applied_basis = Physics::Electrodeposition->new(
    gdsii                 => 'mask.gds',
    pattern_layer         => 10,
    current_density       => 20,       # mA/cm2 over the full wafer
    current_density_basis => 'applied',
    target_thickness      => 10,
);

printf "open %.3f, applied %.1f, active %.1f mA/cm2\n",
    $applied_basis->open_fraction,
    $applied_basis->j_applied_mA,
    $applied_basis->j_active_mA;

For self-contained tests or examples, simple GDSII files can be generated with "write_boundaries" in Physics::Electrodeposition::GDSII. Coordinates are in micrometres:

use Physics::Electrodeposition::GDSII;

Physics::Electrodeposition::GDSII->write_boundaries('openings.gds', [
    { layer => 10, datatype => 0,
      pts => [[0,0], [25,0], [25,25], [0,25]] },
    { layer => 10, datatype => 0,
      pts => [[75,0], [100,0], [100,25], [75,25]] },
]);

my $gds_run = Physics::Electrodeposition->new(
    gdsii                 => 'openings.gds',
    pattern_layer         => 10,
    pattern_datatype      => 0,
    resist_thickness      => 50,
    current_density       => 10,
    current_density_basis => 'active',
    target_thickness      => 40,
);

UNITS

Public convenience methods report engineering units (um, mA/cm^2, V, W). Internal calculations use cm, A/cm^2, mol/cm^3, s and g.

CAVEATS

The uniformity, roughness, loading and additive-consumption figures are calibrated engineering estimates, not a full 3-D primary/secondary/tertiary current distribution simulation. Use them for scoping and sensitivity studies.

AUTHOR

Generated for the Physics-Electrodeposition project.