pyoptics.litho.metrics

Image quality metrics for lithography.

Threshold (constant threshold resist) model: a positive resist exposed with the dose D (relative to the dose-to-clear of the open frame) is removed where D*I >= threshold, I the image normalized to the open frame. A dark feature (line on a clear field mask) remains where D*I < threshold, a bright feature (contact hole, trench) is opened where D*I >= threshold. Its CD is the distance of the two contour crossings around the feature center.

Metrics:

  • contrast(): Michelson contrast,

  • image_log_slope(), nils(): (normalized) image log slope at an edge,

  • feature_edges(), threshold_cd(): printed edges and CD,

  • nils_at_threshold(): NILS at the printed edges,

  • dose_to_size(): dose that prints a target CD,

  • fem_cd(): focus-exposure matrix of CDs (Bossung curves),

  • process_window(), el_dof(): in-spec doses per focus, exposure latitude vs. depth of focus,

  • best_focus(): vertex of CD through focus,

  • gaussian_blur(): a simple resist diffusion model.

The functions work on 1D cuts u, I with u increasing and finely sampled (linear interpolation between samples).

References

C. Mack, “Fundamental Principles of Optical Lithography: The Science of Microfabrication”, Wiley (2007).

J. W. Bossung, “Projection printing characterization”, Proc. SPIE 100, 80 (1977).

    1. Levinson, “Principles of Lithography”, 4th ed., SPIE Press (2019).

Functions

best_focus

Best focus: the vertex of a parabola fitted to a quantity through focus, e.g. CD (the vertex of a Bossung curve) or NILS.

dof_at_el

Largest depth of focus with a minimum exposure latitude.

dose_to_size

Dose that puts the printed edges at center -+ cd_target/2.

el_dof

Exposure latitude vs. depth of focus.

feature_edges

Printed edges of the feature at center.

fem_cd

Focus-exposure matrix.

gaussian_blur

Blur an image with a Gaussian of standard deviation sigma (a simple model of acid diffusion in the resist).

image_log_slope

Image log slope |d ln(I)/dx| at an edge.

nils_at_threshold

NILS at the printed edges, cd*|d ln(I)/du| averaged over both edges.

process_window

Range of doses that print within cd_target*(1 -+ tolerance) for each focus.

threshold_cd

Printed CD of the feature at center for a threshold.

pyoptics.litho.metrics.contrast(I)[source]

Michelson contrast (I_max - I_min)/(I_max + I_min) of an image.

pyoptics.litho.metrics.nils(x, I, x_edge, linewidth)[source]

Normalized image log slope NILS = linewidth*|d ln(I)/dx| at x_edge.

Parameters:
x, Iarrays

Sampled image (x increasing, finely sampled).

x_edgenumber

Position of the nominal edge of the feature.

linewidthnumber

Nominal width of the feature.

Returns:
NILSnumber
pyoptics.litho.metrics.image_log_slope(x, I, x_edge)[source]

Image log slope |d ln(I)/dx| at an edge.

Parameters:
x, Iarrays

Cut through the image.

x_edgenumber

Position of the edge.

Returns:
ilsnumber
pyoptics.litho.metrics.feature_edges(u, I, threshold, center=0.0, bright=False)[source]

Printed edges of the feature at center.

Parameters:
u, Iarrays

Cut through the feature (u increasing).

thresholdnumber

Contour level (dose already applied to I).

centernumber, optional

Position of the feature center.

brightbool, optional

True for a bright feature (prints where I >= threshold).

Returns:
left, rightnumbers

Edge positions; nan if the feature does not print (the center is not inside the feature region) or the region reaches the end of the cut.

pyoptics.litho.metrics.threshold_cd(u, I, threshold, center=0.0, bright=False)[source]

Printed CD of the feature at center for a threshold.

Parameters:
u, Iarrays

Cut through the feature (u increasing).

thresholdnumber

Contour level (dose already applied to I).

centernumber, optional

Position of the feature center.

brightbool, optional

True for a bright feature (prints where I >= threshold).

Returns:
cdnumber

nan if the feature does not print.

pyoptics.litho.metrics.nils_at_threshold(u, I, threshold, center=0.0, bright=False, cd=None)[source]

NILS at the printed edges, cd*|d ln(I)/du| averaged over both edges.

Parameters:
u, Iarrays

Cut through the feature (u increasing).

thresholdnumber

Contour level (dose already applied to I).

centernumber, optional

Position of the feature center.

brightbool, optional

True for a bright feature.

cdnumber, optional

Width used for the normalization; default: the printed CD.

Returns:
nilsnumber

nan if the feature does not print.

pyoptics.litho.metrics.dose_to_size(u, I, cd_target, threshold=0.3, center=0.0)[source]

Dose that puts the printed edges at center -+ cd_target/2.

D = threshold/I_edge with the mean intensity I_edge of both edges.

Parameters:
u, Iarrays

Cut through the feature (u increasing).

cd_targetnumber

Target CD.

thresholdnumber, optional

Printing threshold.

centernumber, optional

Position of the feature center.

Returns:
dosenumber
pyoptics.litho.metrics.fem_cd(u, images, doses, threshold=0.3, center=0.0, bright=False)[source]

Focus-exposure matrix.

Parameters:
uarray

Cut positions.

imagessequence of arrays

Cuts I(u) for each focus.

dosesarray
threshold, center, bright

As for threshold_cd().

Returns:
cdarray

Shape (len(doses), len(images)); nan where the feature does not print.

pyoptics.litho.metrics.process_window(foci, doses, cd, cd_target, tolerance=0.1, n_fine=2001)[source]

Range of doses that print within cd_target*(1 -+ tolerance) for each focus.

Parameters:
foci, dosesarrays

Axes of the focus-exposure matrix (doses increasing).

cdarray

Shape (len(doses), len(foci)), e.g. from fem_cd().

cd_targetnumber
tolerancenumber, optional

Relative CD tolerance (default 10 %).

n_fineint, optional

Dose samples for the interpolation.

Returns:
dose_low, dose_higharrays of shape (len(foci),)

Smallest and largest in-spec dose (the contiguous in-spec interval closest to the center of the dose range); nan where none.

pyoptics.litho.metrics.el_dof(foci, dose_low, dose_high)[source]

Exposure latitude vs. depth of focus.

For every focus window [f_i, f_j], the common dose range is [max(low), min(high)]; its exposure latitude is (high - low)/((high + low)/2).

Parameters:
fociarray

Foci (increasing).

dose_low, dose_higharrays

In-spec dose range per focus, e.g. from process_window().

Returns:
dof, elarrays

Depth of focus (window widths, increasing) and the largest exposure latitude (relative, e.g. 0.1 = 10 %) of any window of that width.

pyoptics.litho.metrics.dof_at_el(dof, el, el_min)[source]

Largest depth of focus with a minimum exposure latitude.

Parameters:
dof, elarrays

From el_dof().

el_minnumber

Required exposure latitude (relative).

Returns:
doffloat

0 if no window reaches el_min.

pyoptics.litho.metrics.gaussian_blur(I, dx, sigma, dy=None)[source]

Blur an image with a Gaussian of standard deviation sigma (a simple model of acid diffusion in the resist). The image is taken as periodic (sample whole periods, e.g. with utils.grid1d()).

Parameters:
Iarray

1D or 2D (Ny, Nx) image.

dx, dynumbers

Grid spacings (dy defaults to dx).

sigmanumber

Diffusion length.