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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
use crate::prog_gen::{
BinType, FlowCondition, FlowID, GroupType, Limit, LimitSelector, ParamValue, PatternGroupType,
ResourcesType, UniquenessOption,
};
use crate::prog_gen::supported_testers::SupportedTester;
use crate::prog_gen::advantest::smt8::processors::create_flow_data::FlowData;
#[derive(Clone, Debug, PartialEq, Serialize)]
pub enum PGM {
/// This will be ignored by all processors, so can be used to indicate the absence of a node
Nil,
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//// Common pat gen and prog gen nodes
//////////////////////////////////////////////////////////////////////////////////////////////////////////
TesterEq(Vec<SupportedTester>), // Child nodes should only be processed when targetting the given tester(s)
TesterNeq(Vec<SupportedTester>), // Child nodes should only be processed unless targetting the given tester(s)
//// Teradyne custom nodes
//// Advantest custom nodes
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//// Flow (prog gen) nodes
//////////////////////////////////////////////////////////////////////////////////////////////////////////
Flow(String),
SubFlow(String, Option<FlowID>),
/// Defines a new test, this must be done before attributes can be set via PGMSetAttr. Note that this doesn't
/// actually add it to the test flow, that must be done via a PGMTest node
/// ID, Name, Tester, Library Template
DefTest(usize, String, SupportedTester, String, String),
/// Defines a new test invocation, this must be done before attributes can be set via PGMSetAttr. Note that
/// this doesn't actually add it to the test flow, that must be done via a PGMTest node
/// ID, Name, Tester
DefTestInv(usize, String, SupportedTester),
/// Assign an existing test to an existing invocation
/// InvID TestID
AssignTestToInv(usize, usize),
/// Define a collection item underneath a test or another collection item
/// ItemID ParentID CollectionName InstanceID AllowMissing
DefTestCollectionItem(usize, usize, String, String, bool),
/// Set the attribute with the given name within the given test (ID), to the given value
SetAttr(usize, String, Option<ParamValue>, bool),
/// Set the limit of the given test or invocation, (test_id, inv_id, hi/lo, value). Note that either test_id
/// or inv_id must be present, but not both.
SetLimit(Option<usize>, Option<usize>, LimitSelector, Option<Limit>),
/// Execute a test (or invocation) from the flow
Test(usize, FlowID),
/// Execute a test (or invocation) from the flow, where the test is simply a string to be inserted
/// into the flow
/// Bin Softbin Number
TestStr(String, FlowID, Option<usize>, Option<usize>, Option<usize>),
/// Defines a new pattern group, also used to model IG-XL pattern sets
PatternGroup(usize, String, SupportedTester, Option<PatternGroupType>),
/// Push a pattern to the given pattern group ID
PushPattern(usize, String, Option<String>),
/// Render the given text directly to the flow
Render(String),
/// Add a log line to the flow
Log(String),
/// A FlowID will always be present when the group type is a flow group
Group(String, Option<SupportedTester>, GroupType, Option<FlowID>),
/// All children will be gated by the given condition (if_failed, if_enabled, etc.)
Condition(FlowCondition),
/// Execute a test (or invocation) from the flow with a CZ setup reference
Cz(usize, String, FlowID),
/// Bin (number, is_soft, type, description, priority)
DefBin(usize, bool, BinType, Option<String>, Option<usize>),
/// Bin out (hard, soft, type)
Bin(usize, Option<usize>, BinType),
/// Events to run if the test or group with the given ID failed
OnFailed(FlowID),
/// Events to run if the test or group with the given ID passed
OnPassed(FlowID),
/// Any tests contained within a Resources block will not be added to the flow, but will be added
/// to 'resource' sheets/files, e.g. the test instances sheet
Resources,
/// Volatile flag definition (a flag that can be changed state by tests)
Volatile(String),
/// Set the flag to the given state (name, state, autogenerated). Autogenerated should be set to differentiate
/// a flag operation that has been generated by Origen (to implement flow control logic) vs. once that has
/// been directly specified by the user
SetFlag(String, bool, bool),
SetDefaultFlagState(String, bool),
/// Continue in the event of a failure
Continue,
/// Delay binning in the event of a failure
Delayed,
Else,
Whenever, // Placeholder
WheneverAny, // Placeholder
WheneverAll, // Placeholder
/// Enable a flow switch
Enable(String),
/// Disable a flow switch
Disable(String),
ResourcesFilename(String, ResourcesType),
BypassSubFlows,
FlowDescription(String),
FlowNameOverride(String),
Namespace(String),
/// Apply the given uniqueness option to all contained test names, etc.
Uniqueness(UniquenessOption),
IGXLSetWaitFlags(usize, Vec<String>),
FlowData(FlowData),
/// A typed data variable declaration: (name, type_name, initial_value).
/// Used for declaring local or global variables in any tester format that supports them
/// (e.g. V93K SMT8 variable sheets), not to be confused with the flow-control flag
/// variables tracked in the Model.
Variable(String, String, Option<String>),
/// A step or node whose type is not specifically recognized by the current processor.
/// Carries the original type name and raw identifying data so it can be passed through
/// losslessly and reconstructed by an importer. (step_type_name, raw_data)
Unknown(String, String),
/// A source-level documentation comment. Does not execute at runtime.
/// Distinct from Log (which is a runtime output statement). Used to annotate
/// the generated flow source in formats that support inline comments/descriptions.
Comment(String),
/// A timed delay/wait step. Duration is a format-agnostic string
/// (e.g. "1s", "500ms", "1.5e-3"). Processors targeting testers with
/// timing support should emit the appropriate wait primitive; others should
/// pass it through unchanged.
Wait(String),
/// Variable assignment: (variable_name, value_expression).
/// Complements Variable (declaration) — assigns a new value to an existing
/// variable. The value_expression may be a literal or a tester-specific
/// expression string.
SetVariable(String, String),
/// Flow input/output parameter declaration: (name, type_name, default_value).
/// Distinct from Variable (local variable). Represents a named, typed parameter
/// of a SubFlow — analogous to a function argument. Used in formats with named
/// parameter declarations such as SMT7.
Parameter(String, String, Option<String>),
/// Multi-site synchronization barrier. Processors targeting testers that support
/// multi-site execution should emit the appropriate sync primitive (e.g. V93K
/// synchronization). Processors that don't understand this node should pass it
/// through unchanged.
Synchronize,
/// A labeled jump target. Formats that support labeled flow control use this to mark
/// a named jump destination. Complemented by Goto.
Label(String),
/// Jump to a labeled target. Formats that support labeled flow control use this to
/// redirect execution to the named label. Complemented by Label.
Goto(String),
/// Events to run if the test or group with the given ID produced a runtime error
/// or abort (not a test failure). Completes the result-handler triad alongside
/// OnPassed and OnFailed. Processors that don't handle this should pass it through.
OnError(FlowID),
/// An external procedure/subroutine call with positional arguments: (procedure_name, args).
/// Distinct from SubFlow (which is flow-graph-aware and tracked by the Model).
/// Used for calling external procedures, library routines, or user-defined subroutines
/// that are not part of the flow graph. Processors that don't handle this should pass
/// it through unchanged.
Call(String, Vec<String>),
/// A bounded iteration loop: (iteration_count, counter_variable_name).
/// `iteration_count` is None for condition-driven or infinite loops.
/// `counter_variable_name` is None if the loop counter is not exposed as a variable.
/// Child nodes form the loop body. Fills the gap left by the payload-less Whenever* placeholders
/// for formats with explicit loop constructs (e.g. SMT7 loops).
Loop(Option<u32>, Option<String>),
/// A structured result report entry: (category, message).
/// Distinct from Log (runtime stdout) and Comment (source annotation).
/// Produces structured output that becomes part of the test result record.
/// Used by formats like SMT8 result annotation steps.
Report(String, String),
/// A runtime assertion: (expression, failure_message).
/// If the expression evaluates to false at runtime, execution halts with an error
/// (not a test failure). Distinct from Test (which measures a DUT) and Condition
/// (which branches). Used for program-correctness checks and defensive assertions.
Assertion(String, String),
/// A named hook or callback invocation with positional arguments: (callback_name, args).
/// Used for formats where callbacks are first-class flow steps. Processors that don't
/// handle this should pass it through unchanged.
Callback(String, Vec<String>),
}
impl std::fmt::Display for PGM {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match &self {
_ => write!(f, "{}", format!("{:?}", self)),
}
}
}