This case study illustrates the use of control charts in analyzing a lithography process.
One of the assumptions in using classical Shewhart SPC charts is that the only source of variation is from part to part (or within subgroup variation). This is the case for most continuous processing situations. However, many of today’s processing situations have different sources of variation.
The semiconductor industry is one of the areas where the processing creates multiple sources of variation.
In semiconductor processing, the basic experimental unit is a silicon wafer. Operations are performed on the wafer, but individual wafers can be grouped multiple ways.
In the diffusion area, up to 150 wafers are processed in one time in a diffusion tube.
In the etch area, single wafers are processed individually.
In the lithography area, the light exposure is done on sub-areas of the wafer.
There are many times during the production of a computer chip where the experimental unit varies and thus there are different sources of variation in this batch processing environment.
The following is a case study of a lithography process. Five sites are measured on each wafer, three wafers are measured in a cassette (typically a grouping of 24 - 25 wafers) and thirty cassettes of wafers are used in the study. The width of a line is the measurement under study. There are two line width variables. The first is the original data and the second has been cleaned up somewhat. This case study uses the raw data. The entire data table is 450 rows long with six columns.
http://www.itl.nist.gov/div898/handbook/pmc/section6/pmc61.htm.
## Attach necessary libraries.
library(nlme)
library(ape)
library(Hmisc)
## Loading required package: lattice
## Loading required package: survival
## Loading required package: Formula
## Loading required package: ggplot2
##
## Attaching package: 'Hmisc'
## The following object is masked from 'package:ape':
##
## zoom
## The following objects are masked from 'package:base':
##
## format.pval, round.POSIXt, trunc.POSIXt, units
m = read.table("D:/Users/FXC/RStudio/Day3/data1.txt",skip=4)
cassette = as.factor(m[,1])
wafer = as.factor(m[,2])
site = as.factor(m[,3])
raw = m[,4]
order = m[,5]
par(mfrow=c(2,2))
plot(raw,ylab="Raw Line Width",type="l")
plot(Lag(raw,1),raw,ylab="Raw Line Width",xlab="lag(Raw Line Width)")
hist(raw,main="",xlab="Raw Line Width")
qqnorm(raw,main="")
par(mfrow=c(1,1))
plot(raw,ylab="Raw Line Width",xlab="Sequence",type="l")
## Compute summary statistics.
ybar = round(mean(raw),5)
std = round(sd(raw),5)
n = round(length(raw),0)
stderr = round(std/sqrt(n),5)
v = round(var(raw),5)
# Compute the five-number summary.
# min, lower hinge, Median, upper hinge, max
z = fivenum(raw)
lhinge = round(z[2],5)
uhinge = round(z[4],5)
rany = round((max(raw)-min(raw)),5)
iqry = round(IQR(raw),5)
z = acf(raw,plot=FALSE)
ac = round(z$acf[2],5)
Statistics = c(n,ybar,std,stderr,v,rany,lhinge,uhinge,iqry,ac)
names(Statistics)= c("Number of Observations ", "Mean", "Std. Dev.",
"Std. Dev. of Mean", "Variance", "Range",
"Lower Hinge", "Upper Hinge", "Inter-Quartile Range",
"Autocorrelation")
data.frame(Statistics)
## Statistics
## Number of Observations 446.00000
## Mean 2.53270
## Std. Dev. 0.69566
## Std. Dev. of Mean 0.03294
## Variance 0.48395
## Range 4.42212
## Lower Hinge 2.04567
## Upper Hinge 2.97195
## Inter-Quartile Range 0.92346
## Autocorrelation 0.60931
##> Statistics
##> Number of Observations 450.00000
##> Mean 2.53228
##> Std. Dev. 0.69376
##> Std. Dev. of Mean 0.03270
##> Variance 0.48130
##> Range 4.42212
##> Lower Hinge 2.04814
##> Upper Hinge 2.97195
##> Inter-Quartile Range 0.91928
##> Autocorrelation 0.60726
plot(m[,1], raw, xlab="Cassette", ylab="Raw Line Width")
boxplot(raw ~ cassette, xlab="Cassette", ylab="Raw Line Width")
plot(m[,2], raw, xlab="Wafer", ylab="Raw Line Width", xlim=c(0,4),
xaxt="n")
axis(1,at=c(0:4),labels=c("","1","2","3",""))
boxplot(raw ~ wafer, xlab="Wafer", ylab="Raw Line Width")
# Width vs Site
Save site as a numeric variable. The numbers 1-5 in nsite correspond to levels: Bot Cen Lef Rgt Top.
nsite = as.numeric(site)
plot(nsite, raw, xlab="Site", ylab="Raw Line Width", xaxt="n")
axis(1,at=c(1:5),labels=c("Bottom","Center","Left","Right","Top"))
boxplot(raw ~ site, xlab="Site", ylab="Raw Line Width", xaxt="n")
axis(1,at=c(1:5),labels=c("Bottom","Center","Left","Right","Top"))
Restructure data so that factors are in a single column. Save re-coded version of the factor levels for DEX mean plot.
tempxc = round(m[,1]/6,2) + 1
dm1 = cbind(raw,tempxc)
tempxc = m[,2] + 8
dm2 = cbind(raw,tempxc)
tempxc = nsite + 13
dm3 = cbind(raw,tempxc)
dm4 = rbind(dm1,dm2,dm3)
n = length(raw)
varind = c(rep("Cassette",n),rep("Wafer",n),rep("Site",n))
varind = as.factor(varind)
df = data.frame(dm4,varind)
q = aggregate(x=df$raw,by=list(df$varind,df$tempxc),FUN="mean")
plot(q$Group.2, q$x, ylab="Raw Line Width", xlab="Factors",
pch=19, xaxt="n", ylim=c(1,5))
xpos = c(3.5,10,16)
xlabel = c("Cassette","Wafer","Site")
axis(side=1,at=xpos,labels=xlabel)
abline(h=mean(raw))
q = aggregate(x=df$raw,by=list(df$varind,df$tempxc),FUN="sd")
plot(q$Group.2, q$x, ylab="Raw Line Width", xlab="Factors",
pch=19, xaxt="n", ylim=c(.4,.8))
xpos = c(3.5,10,16)
xlabel = c("Cassette","Wafer","Site")
axis(side=1,at=xpos,labels=xlabel)
abline(h=sd(raw))
raw.mr = abs(raw - Lag(raw))
raw.ma = (raw + Lag(raw))/2
center = mean(raw.ma[2:length(raw)])
mn.mr = mean(raw.mr[2:length(raw)])
d2 = 1.128
lcl = center - 3*mn.mr/d2
ucl = center + 3*mn.mr/d2
plot(raw.ma, ylim=c(1,5), type="l", ylab="Moving average of line width")
abline(h=center)
abline(h=lcl)
abline(h=ucl)
mtext(side=4,at=ucl,"UCL")
mtext(side=4,at=lcl,"LCL")
mtext(side=4,at=center,"Center")
lcl = mn.mr - 3*mn.mr/d2
ucl = mn.mr + 3*mn.mr/d2
plot(raw.mr, type="l", ylab="Moving range of line width")
abline(h=mn.mr)
abline(h=ucl)
abline(h=max(0,lcl))
mtext(side=4,at=ucl,"UCL")
mtext(side=4,at=max(0,lcl),"LCL")
mtext(side=4,at=mn.mr,"Center")
Compute averages and standard deviations for each cassette and wafer.
qmn = aggregate(x=raw,by=list(wafer,cassette),FUN="mean")
qsd = aggregate(x=raw,by=list(wafer,cassette),FUN="sd")
center = mean(qmn$x)
sbar = mean(qsd$x)
n = 5
c4 = 4*(n-1)/(4*n-3)
A3 = 3/(c4*sqrt(n))
ucl = center + A3*sbar
lcl = center - A3*sbar
plot(qmn$x, type="o", pch=16, ylab="Mean of line width", xlab="Wafer")
abline(h=center)
abline(h=ucl)
abline(h=lcl)
mtext(side=4,at=ucl,"UCL")
mtext(side=4,at=lcl,"LCL")
mtext(side=4,at=center,"Center")
## Compute center line and upper control limit and generate chart.
ucl = sbar + 3*(sbar/c4)*sqrt(1-c4**2)
plot(qsd$x, type="o", pch=16, ylim=c(.1,.9), ylab="SD of line width",
xlab="Wafer")
abline(h=sbar)
abline(h=ucl)
mtext(side=4,at=ucl,"UCL")
mtext(side=4,at=sbar,"Center")
qmn = aggregate(x=raw,by=list(cassette),FUN="mean")
qsd = aggregate(x=raw,by=list(cassette),FUN="sd")
center = mean(qmn$x)
sbar = mean(qsd$x)
n = 15
c4 = 4*(n-1)/(4*n-3)
A3 = 3/(c4*sqrt(n))
ucl = center + A3*sbar
lcl = center - A3*sbar
plot(qmn$x, type="o", pch=16, ylab="Mean of line width", xlab="Cassette",
ylim=c(1.5,4.5))
abline(h=center)
abline(h=ucl)
abline(h=lcl)
mtext(side=4,at=ucl,"UCL")
mtext(side=4,at=lcl,"LCL")
mtext(side=4,at=center,"Center")
# Generate SD control chart (cassettes).
ucl = sbar + 3*(sbar/c4)*sqrt(1-c4**2)
lcl = sbar - 3*(sbar/c4)*sqrt(1-c4**2)
plot(qsd$x, type="o", pch=16, ylab="SD of line width", ylim=c(.1,.9),
xlab="Cassette")
abline(h=sbar)
abline(h=ucl)
abline(h=lcl)
mtext(side=4,at=ucl,"UCL")
mtext(side=4,at=lcl,"LCL")
mtext(side=4,at=sbar,"Center")
df = data.frame(raw,cassette,wafer)
z = lme(raw ~ 1, random=~1|cassette/wafer, data=df)
varcomp(z)
## cassette wafer Within
## 0.26586829 0.04999157 0.17514438
## attr(,"class")
## [1] "varcomp"
##> cassette wafer Within
##> 0.26452145 0.04997089 0.17549617
##> attr(,"class")
##> [1] "varcomp"
## The "Within" component represents site variation.
aov(raw ~ cassette + wafer/cassette - wafer)
## Call:
## aov(formula = raw ~ cassette + wafer/cassette - wafer)
##
## Terms:
## cassette cassette:wafer Residuals
## Sum of Squares 127.64442 25.27768 62.43470
## Deg. of Freedom 29 60 356
##
## Residual standard error: 0.418782
## Estimated effects may be unbalanced
##> Call:
##> aov(formula = raw ~ cassette + wafer/cassette - wafer)
##> Terms:
##> cassette cassette:wafer Residuals
##> Sum of Squares 127.40293 25.52089 63.17865
##> Deg. of Freedom 29 60 360
##> Residual standard error: 0.4189227
##> Estimated effects may be unbalanced
qmn = aggregate(x=raw,by=list(cassette),FUN="mean")
qsd = aggregate(x=raw,by=list(cassette),FUN="sd")
ql = aggregate(x=raw,by=list(cassette),FUN="length")
center = mean(qmn$x)
sbar = mean(qsd$x)
n = ql$x[1]
c4 = 4*(n-1)/(4*n-3)
A3 = 3/(c4*sqrt(n))
ucl = center + A3*sbar
lcl = center - A3*sbar
sdybar = sd(qmn$x)
ll = center - 3*sdybar
ul = center + 3*sdybar
plot(qmn$x, type="o", pch=16, ylim=c(0,5),
ylab="Mean of Line Width", xlab="Cassette")
abline(h=center)
abline(h=ucl)
abline(h=lcl)
abline(h=ll)
abline(h=ul)
mtext(side=4,at=ucl,"UCL")
mtext(side=4,at=lcl,"LCL")
mtext(side=4,at=ll,"Lot-to-Lot")
mtext(side=4,at=ul,"Lot-to-Lot")