IEEE1450 (STIL) Pattern Merging Introduction At least two technologies require a capability not present in IEEE1450. That capability is simultaneous pattern execution. Two technologies that need this support are heterogeneous multisite testing and multiple embedded core based testing in systems on chips (SoC’s.) This capability would also ease communication of scan-based and perhaps other types of patterns. Heterogeneous multisite testing is the simultaneous testing of two or more different devices on the same piece of automated test equipment (ATE.) An example of the value of this might be seen in the probe of a wafer created with a multi-device reticle. Multiple embedded core based testing is the simultaneous testing of two or more different embedded cores in an SoC. The value in this is reduction of test time and maximization of the use of ATE resources. This proposal will describe a construct used in a STIL pattern, that is, an extension to STIL that causes simultaneous execution of pattern data in prescribed and synchronized ways. This construct could affect a single pattern or two or more patterns and would have a cumulative effect. To be specific, this construct will permit the re-arranging of execution order of single patterns and the simultaneous and scheduled execution of multiple patterns in cases where the patterns share signal resources or not. Justification The simplest example of the value of this capability is found in how it will ease the communication of scan-based patterns. A scan pattern is composed of a “load” followed by one or more “capture” cycles, followed by an “unload” operation. In practice, however, scan patterns are overlapped such that the “unload” for one pattern executes simultaneously with the “load” for the following pattern. In practice, the scan data is nearly inextricably merged in the set of scan patterns making the extraction and reordering of scan patterns, that is to say the consideration of individual scan patterns, very difficult. A much more desirable approach to this would be to have the ability to describe the patterns individually and then have a construct which tells the STIL reader how to interpret and/or execute the patterns to simultaneously “unload” one pattern while “load”ing the following pattern. Two benefits are seen here. 1) The patterns are communicated in a more natural, human-readable form. 2) The patterns are more easily manipulated on an individual basis for the purposes of pattern re-ordering of selective pattern removal. Another example, is the simultaneous scheduling of core tests in an SoC. Today, if two cores were to be simultaneously executed using STIL as the pattern format, the pattern data would have to be joined inseparably. The patterns have to be considered at the boundary (pins) of the SoC and cannot be considered at the core level. CTL addresses the case of considering core patterns at the boundary of the core, but apparently not simultaneously, so the problem still exists. A means to address this is to express the patterns separately as if they were being executed independently and then have a construct describe how to simultaneously execute the patterns. This presupposes that no conflict exists in the simultaneous execution of the patterns such as control bits set to complementary states or protocols which interfere. A pattern compiler would have to check for such conditions. The final case is a simple extraction from the SoC case. If one thinks of a multisite loadboard or probecard as an SoC, then one could conceive that the sites might have different device types connected to the tester. All else is the same as with the SoC case except that conflicts are much less likely. These three compelling circumstances support the creation of this construct. There may well be more. Implementation The means to implement this is the use of labels in patterns, procedures and macros, combined with a new construct. The construct is a new keyword called “PatternMerge” which would be used in the “PatternBurst” block. The scope of the “PatternMerge” statement is limited to the patterns instantiated in the “PatList” statement in the “PatternBurst” block. The “PatternMerge” keyword would identify two or more discrete, named and labeled locations in patterns that would provide a common time origin for multiple patterns or multiple, locally referenced time origins for a single pattern. The “PatternMerge” statement may also be used in the pattern instantiation in the “PatList” block. In this case the scope of the “PatternMerge” statement is limited to the instantiated pattern. Supposing one pattern, it might be reasonable to ask for a mergence of the second and fifth cycle of a pattern and then the tenth and twelfth cycle of the same pattern. This infers that cycles 2 and 5, 3 and 6, and 4 and 7 would execute simultaneously followed by cycles 8 then 9, followed by cycles 10and 12, and 11 and 13 then continuing with cycle 14 with no further mergence. More graphically, if the original vector order was: 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 then with the above requested merges, the order would become 1,2&5,3&6,4&7,8,9,10&12,11&13,14,15. reducing the vector count of the pattern from 15 down to 10. Pattern Conflicts The pattern compiler must validate that merging the patterns like this must not create conflicts. I.E, if vector 2 of the prior example set pin “A” to 1 and vector 5 of the prior example set pin “A” to 0, then there would be an irresolvable conflict. However, if vector 2 set pin “A” to an X and vector 5 set pin “A” to a 0 there would be no conflict. An example of this in STIL would look like: PatternBurst PATTERN_A_UNMERGED { PatList { PATTERN_A { PatternMerge Vector2, Vector5; PatternMerge Vector10, Vector12; } } } Pattern PATTERN_A { V { a = Vector2: V { a = V { a = V { a = Vector5: V { a = V { a = V { a = V { a = V { a = Vector 10: V { a = V { a = Vector 12: V { a = V { a = V { a = V { a = } 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, X, X, X, 1, b b b b b b b b b b b b b b b = = = = = = = = = = = = = = = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, X, c c c c c c c c c c c c c c c = = = = = = = = = = = = = = = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, d d d d d d d d d d d d d d d = = = = = = = = = = = = = = = X X X X 1 1 1 X X X X 0 0 X X }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; Another way to state the PatternBurst block would be: PatternBurst PATTERN_A_UNMERGED { PatList { PATTERN_A } PatternMerge { Pattern_A.Vector2 Pattern_A.Vector5; } PatternMerge { Pattern_A.Vector10 Pattern_A.Vector12; } } This would execute the same way as the following (affected bits in bold): PatternBurst PATTERN_A_MERGED { PatList { PATTERN_A } } Pattern V { a V { a V { a V { a V { a V { a V { a V { a V { a V { a PATTERN_A { = 1, b = 1, = 1, b = 1, = 1, b = 1, = 1, b = 1, = 1, b = 1, = 1, b = 1, = 1, b = 1, = 1, b = 1, = X, b = 1, = 1, b = X, c c c c c c c c c c = = = = = = = = = = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, d d d d d d d d d d = = = = = = = = = = X 1 1 1 X X 0 0 X X }; }; }; }; }; }; }; }; }; }; // // // // // // // // // // A.1 A.2 A.5 A.3 A.6 A.4 A.7 A.8 A.9 A.10 A.12 A.11 A.13 A.14 A.15 } A brief example of merging two patterns: PatternBurst PATTERN_AB_UNMERGED { PatList { PATTERN_A PATTERN_B } PatternMerge { Pattern_A.Vector2, Pattern_A.Vector5; } PatternMerge { Pattern_A.Vector10, Pattern_A.Vector12; } PatternMerge { Pattern_A.Vector14, Pattern_B.Vector1; } } Pattern PATTERN_A { V { a = Vector2: V { a = V { a = V { a = Vector5: V { a = V { a = V { a = V { a = V { a = Vector10: V { a = V { a = Vector12: V { a = V { a = V { a = V { a = } 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, X, X, X, 1, b b b b b b b b b b b b b b b = = = = = = = = = = = = = = = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, X, c c c c c c c c c c c c c c c = = = = = = = = = = = = = = = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, d d d d d d d d d d d d d d d = = = = = = = = = = = = = = = X X X X 1 1 1 X X X X 0 0 X X }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; Pattern PATTERN_B { Vector1: V { a = 1, b = 1, c = 0, d = 1 }; V { a = 1, b = 1, c = 0, d = 0 }; } This would execute the same way as the following (affected bits in bold): PatternBurst PATTERN_AB_MERGED { PatList { PATTERN_A } } Pattern V { a V { a V { a V { a V { a V { a V { a V { a V { a V { a } PATTERN_A { = 1, b = 1, = 1, b = 1, = 1, b = 1, = 1, b = 1, = 1, b = 1, = 1, b = 1, = 1, b = 1, = 1, b = 1, = 1, b = 1, = 1, b = 1, c c c c c c c c c c = = = = = = = = = = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, d d d d d d d d d d = = = = = = = = = = X 1 1 1 X X 0 0 1 0 };// };// };// };// };// };// };// };// };// };// A.1 A.2 A.3 A.4 A.5 A.6 A.7 A.8 A.9 A.10 A.12 A.11 A.13 A.14 B.1 B.2 This final example would show a small scan example including merging into procedures: Procedures { "scan_pattern" { W "_default_WFT_"; "load": Shift { V { "_si"=####; "_so"=XXXX; "clk"=P; } } "forcePI": V { "_pi"=##############; "_po"=XXXXXXXX; } "measurePO": V { "_po"=########; } "pulse": V { "clk"=P; "_po"=XXXXXXXX; } "unload": Shift { V { "_si"=XXXX; "_so"=####; "clk"=P; } } } } MacroDefs { "test_setup" { W "_default_WFT_"; V { "clk"=0; } } } PatternBurst PatternBurst PATTERN_A_UNMERGED { PatList { PATTERN_A } PatternMerge { Pattern_A.pattern_1.unload Pattern_A.pattern_2.load } PatternMerge { Pattern_A.pattern_2.unload Pattern_A.pattern_3.load } } Pattern PATTERN_A { W "_default_WFT_"; "precondition all Signals": C { "_pi"=00000000000000; "_po"=XXXXXXXX; } Macro "test_setup"; pattern_1: Call "scan_pattern" { "si[0]"=11111011; "si[1]"=00000001; "si[2]"=01111011; "si[3]"=0000101; "_pi"=00111111110010; "_po"=LLLLLLLL; "so[0]"=LLHHLLHH; "so[1]"=LLHHLLHH; "so[2]"=LLHHLLHH; "so[3]"=LLHHLLH; } pattern_2: Call "scan_pattern" { "si[0]"=00110100; "si[1]"=01001010; "si[2]"=10110100; "si[3]"=0001011; "_pi"=00111101001111; "_po"=HLHLLHLL; "so[0]"=HHLLLLHH; "so[1]"=LLLLLLLH; "so[2]"=LLLLLLHL; "so[3]"=LHLLHLL; } pattern_3: Call "scan_pattern" { "si[0]"=11001101; "si[1]"=10111101; "si[2]"=01001110; "si[3]"=1101001; "_pi"=00100111100101; "_po"=HHHLHLHH; "so[0]"=LHLHHHLL; "so[1]"=LLHHLLHL; "so[2]"=LLLLHHLL; "so[3]"=LLLLLHH; } } Out of order execution Supposing in the prior example, one wanted to execute the patterns in a different order than they occur in the pattern, this is possible through out-of-order vector execution. For instance suppose the test engineer wanted to execute pattern 2, then 3, and then pattern 1. In this case, the “PatternBurst” would look like this: PatternBurst PatternBurst PATTERN_A_UNMERGED { PatList { PATTERN_A { Start pattern_2 } } PatternMerge { Pattern_A.pattern_2.unload Pattern_A.pattern_3.load } PatternMerge { Pattern_A.pattern_3.unload Pattern_A.pattern_1.load } } For cases of out-of-order execution where the first vector to be executed is not the first vector of a pattern, another pattern must provide the first vector location to reference against. At least one pattern in the burst must begin execution at its local time 0 for the merge operation to make sense in this case. Where no patterns are set to begin execution at their first vector, a reference or “scaffold” pattern must be provided. Such a pattern would only have labels to refer to and empty vectors to provide time references. This pattern would begin execution at its first vector and all other patterns would be merged against it. <example needed> Non Contiguous Execution: “Pattern Fill” “PatternMerge” between two patterns makes possible the case where segments of a pattern may be scheduled into non-contiguous blocks of time. This happens when the amount of vector data is insufficient to fill the time between merge points. In this case, and consistent with STIL’s “sticky data” the pattern would repeat the last data for each signal. Therefore, it is important to leave innocuous data on signals when this occurs. The standard will make no check for this case, however. Pattern Marking (standard for label names) It is further recommended that the labels used for reference be consistent with the structural label format for pattern marking being developed in IEEE P1450.6 (CTL). The combination of pattern merging and proper pattern marking provides a complete solution for describing structural tests in an SoC methodology.