-
Notifications
You must be signed in to change notification settings - Fork 2
structures
A structure is an extension of the _list _or string (str) data type. To create a structure, variables must be declared within a _list _or str variable. For example:
list S1F2 = { char mdln[5] = "Hyper", char rev[5] = "2.3.1" };
_
In this example, the structure variable, S1F2, has two member variables, mdln and rev, which can be accessed either by name or index. For example, the statements:
put ( str ( S1F2.mdln ) );
put ( str ( *S1F2[0] ) );
_
both produce "Hyper". Since the member variable, 'mdln', is the first element of the list variable, S1F2, accessing this member using a subscript value (and the dereference operator) is valid. Notice that both member variables are defined as char vectors. Thus, the str typecast is used to convert the char array to a more readable str format. We could permanently convert the two member variables to str by re-declaring them:
str S1F2.mdln;
str S1F2.rev;
_
The S1F2 structure variable could have been created in a more direct way:
char S1F2.mdln[5] = "Hyper";
char S1F2.rev[5] = "2.3.1";
_
Another way to create the S1F2 structure variable, although somewhat indirect, would be:
S1F2 = {};
char mdln[5] = "Hyper";
char rev[5] = "2.3.1";
append ( S1F2, mdln );
append ( S1F2, rev );
_
In the above example the variables mdln and rev are first defined as top-level variables and then inserted into S1F2 using the append method. (We could have also used the insert method.) After being appended to the S1F2 list variable they become member variables and are no longer available as top-level variables.
The ability to use either member variable names or the corresponding array indices provides flexible lookup features. For example, suppose you had a three-dimensional cube of data, the dimensions being wafer, site, and item. To print out the entire cube of data, a plausible set of statements could be:
for ( int waferIndex=0; waferIndex<numWafers; waferIndex++ )
for ( int siteIndex=0; siteIndex<numSites; siteIndex++ )
for ( int itemIndex=0; itemIndex<numItemss; itemIndex++ )
printDataValue ( waferIndex, siteIndex, itemIndex ) ;
_
where printDataValue() is a user-defined HS method that takes three index arguments and displays the desired data value.
If the data is contained in an one-dimensional vector variable declared as:
float dataValue[numWafers*numSites*numItems];
_
then the printDataValue() method could be defined as follows :
printDataValue ( int waferIndex, int siteIndex, int itemIndex)
{
put ( dataValue[(waferIndex*numSites*numItems)+(siteIndex*numItems)+(itemIndex)] );
}
_
In HS this is efficient enough; once the index is calculated the data access is fast because dataValue is a vector. However, this method of storing data does not allow for mixed data types, nor does it allow us to attach labels to the dimensions of the data.
Organizing the data in a structure is straight-forward. The first dimension of the structure is a list of wafers, as follows:
list dataValue = {
list WAFER_0 = {},
list WAFER_1 = {},
list WAFER_2 = {},
list WAFER_3 = {},
list WAFER_4 = {},
list WAFER_5 = {},
list WAFER_6 = {}
};
_
The second dimension, site, could be defined for each wafer as follows:
list dataValue.WAFER_0 = {
list TOP = {},
list CENTER = {},
list BOTTOM = {},
list LEFT = {},
list RIGHT = {}
};
_
Finally, the third dimension of the dataValue structure contains items for each of the sites. For example, the TOP site on WAFER_0 might be defined as follows:
dataValue.WAFER_0.TOP = {
float CD,
int DEPTH,
str LAYER
};
_
The remaining wafers and sites can be defined in a similar manner. Now we can access a data item as follows:
put ( dataValue[waferIndex][siteIndex][itemIndex] );
_
The structure of dataValue can be seen with:
put ( dataValue );
_
which prints:
'WAFER_0' 'WAFER_1' 'WAFER_2' 'WAFER_3' 'WAFER_4' 'WAFER_5' 'WAFER_6'
_
Thus, *dataValue[3], for example, is the same as dataValue.WAFER_3. If we print out the next level:
put ( dataValue.WAFER_3 ); /* or put ( *dataValue[3] ); */
_
it produces:
'TOP' 'CENTER' 'BOTTOM' 'LEFT' 'RIGHT'
_
So, dataValue[3][2] can be accessed in the following ways:
put ( dataValue.WAFER_3.BOTTOM );
put ( *( dataValue.WAFER_3[2] ) );
put ( dataValue[3].BOTTOM );
_
All produce:
'CD' 'DEPTH' 'LAYER'
_
Note the use of the asterisk in the second statement of the above example. This is required to dereference (i.e. refer to the value of) the element dataValue.WAFER_3[2]. Without the dereference operator we would have gotten the result, 'BOTTOM', since that is the third element of WAFER_3. See the section on References and Dereferencing for more information.
In this lowest level of the dataValue structure we defined three member items, a float, an int, and a str. The describe method can be used to examine this structure member as follows:
describe ( dataValue.WAFER_3.BOTTOM );
_
produces:
list 'BOTTOM' = {
float 'CD'[1] = {
0
},
int 'DEPTH'[1] = {
0
},
str 'LAYER' = {
}
;
_
Note that this description is a fully explicit declaration statement for the structure member, BOTTOM.
There are many ways to access a data value at the lowest level. For example, the DEPTH member of WAFER_3.BOTTOM can be accessed in the following ways:
dataValue.WAFER_3.BOTTOM.DEPTH
*(dataValue.WAFER_3.BOTTOM[1])
dataValue.WAFER_3[2].DEPTH
*((dataValue.WAFER_3[2])[1])
dataValue[3].BOTTOM.DEPTH
*(dataValue[3].BOTTOM[1])
dataValue[3][2].DEPTH
*(dataValue[3][2][1])
_
A clever and useful approach for defining and accessing structure members is accomplished by setting up str variables that contain the names of the member variables that you wish to reference. These, along with the dereference operator, can be used as follows:
str waferId = "WAFER_3";
str siteId = "BOTTOM";
str itemId = "DEPTH";
put ( dataValue.*waferId.*siteId.*itemId );
_
This prints the value of dataValue.WAFER_3.BOTTOM.DEPTH. Using this approach, you could define a method to add site data to each member of the dataValue array as follows:
inDATA ( str waferId, str siteId, float cdValue, int depth, str layer )
{
dataValue.*waferId.*siteId =
{ float CD = cdValue, int DEPTH = depth, str LAYER = layer };
}
_
In fact, the entire dataValue structure can be defined with just a few lines of code:
list dataValue = {};
str wafer = "WAFER_";
str site = { "TOP", "CENTER", "BOTTOM", "LEFT", "RIGHT" };
for ( int waferIndex = 0; waferIndex < 7; waferIndex++ ) {
str wafer_id = wafer + waferIndex;
list *wafer_id = {};
for ( int siteIndex = 0; siteIndex < 5; siteIndex++ ) {
str site_id = site[siteIndex];
list *site_id = { float CD, int DEPTH, str LAYER };
append ( *wafer_id, *site_id );
}
append ( dataValue, *wafer_id );
}
_