-
Notifications
You must be signed in to change notification settings - Fork 3
/
Yield by Radius.jsl
137 lines (118 loc) · 4.1 KB
/
Yield by Radius.jsl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Attempts to fill in a data table of Yield by Radius
//
// Datatable needs to have the following two columns:
// "Result" and "Radius". The script
// create or update LSL, USL, Pass, TotalDieWithinRadius,
// TotalDiePassWithinRadius, and YieldWithinRadius columns
dt1 = Current Data Table();
// Edit these to update the specs.
lslValue = 9;
uslValue = 12.7;
// First, lets check if the columns already exist
colNameList = dt1 << Get Column Names(string);
newCols = {"LSL", "USL", "Pass", "TotalDieWithinRadius",
"TotalDiePassWithinRadius", "YieldWithinRadius"};
/*
If (!contains(colNameList, newCol),
// Create it
dt1 << New Column(newCol, numeric, continuous);
);
*/
For ( i = 1, i <= Length(newCols), i++,
If (!contains(colNameList, newCols[i]),
// Create it
dt1 << New Column(newCols[i], numeric, continuous);
);
);
// Now all of the columns should exist, so we can add 'formulas' for
// the upper and lower spec limits.
// TODO: Change to just setting entire column?
lslCol = Column( "LSL" );
lslCol << Set Formula(lslValue);
lslCol << Eval Formula;
uslCol = Column( "USL" );
uslCol << Set Formula(uslValue);
uslCol << Eval Formula;
// Now update the Pass column
passCol = Column( "Pass" );
passCol << Set Formula(:LSL <= :Rdson <= :USL);
passCol << Eval Formula;
// Next, we need to determine how many die are within a given radius.
// At this point, the script gets a bit specialized - The user needs
// to determine what Columns make up the primary key.
//
// Example: My Reedholm Rdson MSA data
// The Lot_ID, Test_Name, and Wafer_Name columns make up a PK for a
// single wafer.
//
// TODO: Change to user prompt to select PK columns.
//
// For now, I only expect to work on the MSA data so I know the cols.
//
// Take a summary of the data, grouped by PKs and Radius. We also
// find the sum of passing die for each unique radius. This will
// be used later.
// Note that the order is intentional.
dt2 = dt1 << Summary(
Group( :Test_Name, :Lot_ID, :Wafer_Name, :Radius ),
Sum( :Pass )
);
// Next, create a column which Accumulates how many die are within
// each radius.
// Formula is so that the TotalDieWithinRadius resets on each wafer,
// lot, or test change
totalDieWithinRadiusCol = dt2 << New Column( "TotalDieWithinRadius" );
totalDieWithinRadiusCol << Set Formula(
If(
// If: first Row in Table
Row() == 1,
// Then reset accumulate
:N Rows[Row(),Empty()],
// Else If: wafer, Lot, or Test Changed
:Test_Name[Row()] != :Test_Name[Row() - 1]
| :Lot_ID[Row()] != :Lot_ID[Row() - 1]
| :Wafer_Name[Row()] != :Wafer_Name[Row() - 1],
// Then reset accumulate
:N Rows[Row()],
// Else: accumulate
:N Rows[Row()] + :TotalDieWithinRadius[Row() - 1])
);
totalDieWithinRadiusCol << Eval Formula;
// Now create the TotalDiePassWithinRadius column. Pretty much the
// same as the other column, but uses Sum(Pass) instead.
totalDiePassWithinRadiusCol = dt2 << New Column( "TotalDiePassWithinRadius" );
totalDiePassWithinRadiusCol << Set Formula(
If(
// If: first Row in Table
Row() == 1,
// Then reset accumulate
:Name("Sum(Pass)")[Row(),Empty()],
// Else If: wafer, Lot, or Test Changed
:Test_Name[Row()] != :Test_Name[Row() - 1]
| :Lot_ID[Row()] != :Lot_ID[Row() - 1]
| :Wafer_Name[Row()] != :Wafer_Name[Row() - 1],
// Then reset accumulate
::Name("Sum(Pass)")[Row()],
// Else: accumulate
::Name("Sum(Pass)")[Row()] + :TotalDiePassWithinRadius[Row() - 1])
);
totalDiePassWithinRadiusCol << Eval Formula;
// Lastly, create the YieldWithinRadius column.
yieldWithinRadiusCol = dt2 << New Column( "YieldWithinRadius" );
yieldWithinRadiusCol << Set Formula(
(:TotalDiePassWithinRadius / :TotalDieWithinRadius) * 100
);
yieldWithinRadiusCol << Eval Formula;
// Now that our Summary table is done, let's update the main table
// with the results.
dt2Name = dt2 << Get Name();
dt1 << Update(
With( dt2 ),
Match Columns(
:Lot_ID = :Lot_ID,
:Wafer_Name = :Wafer_Name,
:Test_Name = :Test_Name,
:Radius = :Radius
),
Add Columns from Update table( None )
)