origen_testers 0.43.0 → 0.44.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bcd28a31ae733240fb79442791a52b0289cb60767ab4ca3420958a5c5451cb29
4
- data.tar.gz: 208ed25a437e3df788b0305f88fbcd967ffa563fd68a7508d5b055f7c3380395
3
+ metadata.gz: dee8846aa21d987c842939ca190021953c4a869c93475352095da56aea0e0c8e
4
+ data.tar.gz: bfeb41a71144f612912a09f8cc2c3d1f4e5a9165aff1a0391bd0b9d12e85633a
5
5
  SHA512:
6
- metadata.gz: c36b5d4a30d947489f3ed2d165c867249df0235b3d5d797bd3eaf5b2f232cbf0c6d4d33b1425ab6fd061d65eac4fd8803355af6e0b317a96b5f98335438845f2
7
- data.tar.gz: 4af3ae57d4c893138271ac876bc7968def1bc4df416764481a264594af38213264f8f818fbdf40204f3b4b54441158ce05d1233245b1872124b2801495af0587
6
+ metadata.gz: 83eb0028c6054bfe4897de617da651902e6d2c838edbe55b7bb651e2a9be0c6559f0576b604a173e78137454246633f9428fd138644b119ff68f475ead4e50e0
7
+ data.tar.gz: aa6ea68ad27361ce36ae06476c0db801c0d342862e43a6265ae089762e19b19d380311bbac787fffba722928db71861a4e219d129bd6f94b354c7ed95b097abd
@@ -1,6 +1,6 @@
1
1
  module OrigenTesters
2
2
  MAJOR = 0
3
- MINOR = 43
3
+ MINOR = 44
4
4
  BUGFIX = 0
5
5
  DEV = nil
6
6
  VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
@@ -262,6 +262,10 @@ module OrigenTesters::ATP
262
262
  extract_meta!(options) do
263
263
  apply_conditions(options) do
264
264
  children = [n1(:name, name)]
265
+ children << n1(:bypass, options[:bypass]) if options[:bypass]
266
+ if options[:comment] || options[:description] || options[:desc]
267
+ children << n1(:comment, options[:comment] || options[:description] || options[:desc])
268
+ end
265
269
  children << id(options[:id]) if options[:id]
266
270
  children << on_fail(options[:on_fail]) if options[:on_fail]
267
271
  children << on_pass(options[:on_pass]) if options[:on_pass]
@@ -53,14 +53,28 @@ module OrigenTesters::ATP
53
53
  end
54
54
 
55
55
  def on_group(node)
56
- name, *nodes = *node
56
+ array_for_update = []
57
+ if node.find(:bypass) && node.find(:comment)
58
+ name, bypass, comment, *nodes = *node
59
+ array_for_update = [name, bypass, comment]
60
+ elsif node.find(:bypass)
61
+ name, bypass, *nodes = *node
62
+ array_for_update = [name, bypass]
63
+ elsif node.find(:comment)
64
+ name, comment, *nodes = *node
65
+ array_for_update = [name, comment]
66
+ else
67
+ name, *nodes = *node
68
+ array_for_update = [name]
69
+ end
70
+
57
71
  if conditions_to_remove.any? { |c| node.type == c.type && c.to_a == [name] }
58
- conditions_to_remove << node.updated(nil, [name])
72
+ conditions_to_remove << node.updated(nil, array_for_update)
59
73
  result = node.updated(:inline, optimize(process_all(nodes)))
60
74
  conditions_to_remove.pop
61
75
  else
62
- conditions_to_remove << node.updated(nil, [name])
63
- result = node.updated(nil, [name] + optimize(process_all(nodes)))
76
+ conditions_to_remove << node.updated(nil, [name, bypass, comment])
77
+ result = node.updated(nil, array_for_update + optimize(process_all(nodes)))
64
78
  conditions_to_remove.pop
65
79
  end
66
80
  result
@@ -18,7 +18,7 @@ module OrigenTesters
18
18
  # Returns an array containing all runtime variables which get set by the flow
19
19
  attr_reader :set_runtime_variables
20
20
 
21
- attr_accessor :add_flow_enable, :flow_name, :flow_description
21
+ attr_accessor :add_flow_enable, :flow_name, :flow_bypass, :flow_description
22
22
 
23
23
  def self.generate_flag_name(flag)
24
24
  case flag[0]
@@ -83,6 +83,10 @@ module OrigenTesters
83
83
  end
84
84
  end
85
85
 
86
+ def flow_bypass
87
+ @flow_bypass || false
88
+ end
89
+
86
90
  def flow_description
87
91
  @flow_description || ''
88
92
  end
@@ -586,12 +590,18 @@ module OrigenTesters
586
590
  stack[:on_fail].pop if on_fail
587
591
  stack[:on_pass].pop if on_pass
588
592
  @indent -= 1
593
+ bypass = node.find(:bypass).try(:value) || flow_bypass
594
+ comment = node.find(:comment).try(:value) || ''
589
595
  if smt8?
590
596
  line '// *******************************************************'
591
597
  line "// /GROUP - #{group_name}"
592
598
  line '// *******************************************************'
593
599
  else
594
- line "}, open,\"#{group_name}\", \"\""
600
+ if bypass
601
+ line "}, groupbypass, open,\"#{group_name}\", \"\""
602
+ else
603
+ line "}, open,\"#{group_name}\", \"\""
604
+ end
595
605
  end
596
606
  end
597
607
 
@@ -27,6 +27,7 @@ module OrigenTesters
27
27
  self.unique_test_names = options[:unique_test_names]
28
28
  end
29
29
  flow.flow_name = options[:flow_name]
30
+ flow.flow_bypass = options[:flow_bypass].nil? ? false : options[:flow_bypass]
30
31
  flow.flow_description = options[:flow_description] || OrigenTesters::Flow.flow_comments.join(' ')
31
32
  end
32
33
  end
@@ -174,13 +174,13 @@ Flow.create interface: 'OrigenTesters::Test::Interface', flow_name: "Flow Contro
174
174
  func :gt3, bin: 90, if_failed: :gt_grp2, number: 50730
175
175
 
176
176
  log "Test that nested groups work"
177
- group "level1" do
177
+ group "level1" , comment: "Level 1 Group" do
178
178
  func :lev1_test1, bin: 5, number: 50740
179
179
  func :lev1_test2, bin: 5, number: 50750
180
180
  func :lev1_test3, id: :l1t3, bin: 10, number: 50760
181
181
  func :lev1_test4, if_failed: :l1t3, bin: 12, number: 50770
182
182
  func :lev1_test5, id: :l1t5, bin: 12, number: 50780
183
- group "level2" do
183
+ group "level2" , bypass: true do
184
184
  func :lev2_test1, bin: 5, number: 50790
185
185
  func :lev2_test2, bin: 5, number: 50800
186
186
  func :lev2_test3, id: :l2t3, bin: 10, number: 50810
@@ -1,6 +1,6 @@
1
1
  # An example of creating an entire test program from
2
2
  # a single source file
3
- Flow.create interface: 'OrigenTesters::Test::Interface', environment: :probe do
3
+ Flow.create interface: 'OrigenTesters::Test::Interface', flow_bypass: true, environment: :probe do
4
4
 
5
5
  # Test that this can be overridden from the target at flow-level
6
6
  self.add_flow_enable = :enabled
@@ -306,4 +306,37 @@ end
306
306
  In all cases the `$` will be removed from the final flag name that appears in the test program.
307
307
 
308
308
 
309
+
310
+ #### Adding the V93K bypass option:
311
+
312
+ Add the flow bypass option:
313
+
314
+ ~~~ruby
315
+ Flow.create interface: 'My::Interface', flow_bypass: true do
316
+ test :test1
317
+ end
318
+
319
+ Flow.create interface: 'My::Interface' do
320
+ flow.flow_bypass = true
321
+ test :test1
322
+ end
323
+ ~~~
324
+
325
+ Add group bypass option:
326
+
327
+ ~~~ruby
328
+ group :my_group, bypass: true do
329
+ test :test1
330
+ end
331
+ ~~~
332
+
333
+ Add group comment/description options;
334
+
335
+ ~~~ruby
336
+ group :my_other_group, comment: "This is the other group" do
337
+ test :test1
338
+ end
339
+ ~~~
340
+
341
+
309
342
  % end
@@ -0,0 +1,309 @@
1
+ % render "layouts/guides.html" do
2
+
3
+ The runtime flow control of a test program is an area that can be particularly messy:
4
+
5
+ * Need to deal with different and often obscure vendor APIs
6
+ * It can be very hard to decipher both the intention and the actual behavior
7
+ during code reviews
8
+ * It is easy to make mistakes
9
+ * Mistakes can be costly - there have been many customer quality
10
+ incidents in the past from missed test caused by errors in flow control
11
+
12
+ To deal with these problems Origen provides a simple and intuitive API
13
+ to describe runtime flow logic:
14
+
15
+ * Generates legal and battle-tested code
16
+ * Takes care of cross-platform implementation
17
+ * Makes flow control easy to review
18
+ * Covers over gaps or weaknesses in the vendor APIs
19
+
20
+ Conditional tests fall into two categories:
21
+
22
+ * Those that will run based on the flow execution environment. For example based on
23
+ the job selected at runtime or on some enable flag that can be set by the user at
24
+ runtime.
25
+ * Those that will only run based on the outcome of another test - i.e. execute a given
26
+ test based on whether a previous test passed, failed or ran at all.
27
+
28
+ #### Execution Based on the Runtime Environment
29
+
30
+ The following methods are available to describe these cases:
31
+
32
+ * **if_enable / unless_enable** - Run the test if a flow runtime option is/is not enabled at runtime
33
+ * **if_job / unless_job** - Run based on the current job (P1, FR, QC, etc)
34
+
35
+ Here are some examples of how to apply these methods to single tests:
36
+
37
+ ~~~ruby
38
+ # Run this test to characterize the vreg, only if the 'vreg_cz' flag has been enabled
39
+ para :vreg_meas, softbin: 107, cz: true, if_enable: "vreg_cz"
40
+ # Apply HVST to the vreg module, unless the 'skip_hvst' flag has been enabled
41
+ func :vreg_hvst, softbin: 101, hv: 10.V, vdd: :max, unless_enable: "skip_hvst"
42
+ # Run this test only at cold
43
+ para :vreg_meas, softbin: 105, lo: 1.12, hi: 1.34V, if_job: "FC"
44
+ ~~~
45
+
46
+ The use of `if/unless_enable` will make use of flow enable words on Teradyne platforms and user
47
+ flow variables on Advantest.
48
+ The `if/unless_job` control will make use of the job column on Teradyne platforms and a user
49
+ flow variable named `@JOB` on Advantest.
50
+
51
+ Both of these controls support a block form, which allows it to be applied to a group of test
52
+ and, in the case of enable words, it also provides a way to implement AND and OR logic:
53
+
54
+ ~~~ruby
55
+ # OR - Run these tests if either word is set
56
+ if_enable [:word1, :word2] do
57
+ func: :test1
58
+ func: :test2
59
+ end
60
+
61
+ # AND - Run these tests if both words are set
62
+ if_enable :word1 do
63
+ if_enable :word2 do
64
+ func: :test1
65
+ func: :test2
66
+ end
67
+ end
68
+ ~~~
69
+
70
+
71
+ #### Execution Based on Relational Expressions
72
+
73
+ The following methods are available to describe these cases:
74
+
75
+ * **whenever** - Run the test(s) if the relational expression evaluates to TRUE
76
+ * **whenever_all** - Run the test(s) if ALL of the relational expressions evaluate to TRUE
77
+ * **whenever_any** - Run the test(s) if ANY of the relational expressions evaluate to TRUE
78
+
79
+ The following relational operators are available for use with the above methods:
80
+
81
+ * **eq** - equal to
82
+ * **ne** - not equal to
83
+ * **gt** - greater than
84
+ * **ge** - greater than or equal to
85
+ * **lt** - less than
86
+ * **le** - less than or equal to
87
+
88
+ Here are some examples of how to apply these methods:
89
+
90
+ ~~~ruby
91
+ # Run these tests if VAR1 is greater than 2
92
+ whenever gt(:var1, 2) do
93
+ func: :test1
94
+ func: :test2
95
+ end
96
+
97
+ # Run these tests if VAR1 is greater than 2 AND VAR2 is less than VAR3
98
+ whenever_all gt(:var1, 2), lt(:var2, :var3) do
99
+ func: :test1
100
+ func: :test2
101
+ end
102
+
103
+ # Run these tests if VAR1 is greater than 2 OR VAR2 is less than VAR3
104
+ whenever_any gt(:var1, 2), lt(:var2, :var3) do
105
+ func: :test1
106
+ func: :test2
107
+ end
108
+ ~~~
109
+
110
+ Additionally, these variables can be set in the flow using the **set** method as shown in here:
111
+
112
+ ~~~ruby
113
+ # Set the VAR1 = 1
114
+ set :var1, 1
115
+ set :var2, 'OFF'
116
+ set :var3, 3.14
117
+
118
+ # Update VAR1 value based on some runtime condition
119
+ if_enable :some_other_variable do
120
+ set :var1, 3
121
+ end
122
+
123
+ # Run these tests if VAR1 is greater than 2
124
+ whenever gt(:var1, 2) do
125
+ func: :test1
126
+ func: :test2
127
+ end
128
+ ~~~
129
+
130
+ #### Execution Based on a Previous Test
131
+
132
+ The following methods are available to describe these cases:
133
+
134
+ * **if_ran / unless_ran** - Run only if a previous test did or did not run
135
+ * **if_failed (unless_passed)** - Run only if a previous test failed
136
+ * **if_passed (unless_failed)** - Run only if a previous test passed
137
+
138
+ All of these methods require you to provide the ID of the previous test on which
139
+ the conditional execution will depend.
140
+ This ID must be assigned by you in the flow line of the previous test by adding
141
+ an `:id` key, like this:
142
+
143
+ ~~~ruby
144
+ para :vreg_meas, softbin: 105, lo: 1.12, hi: 1.34, id: :vreg_meas_1
145
+ ~~~
146
+
147
+ The ID can be any value you like as long as it is unique, Origen will raise an error
148
+ if any duplicate IDs are encountered.
149
+
150
+ On the dependent tests the API is similar to the previous examples except the ID
151
+ of the previous test is given in place of the enable flag or job name.
152
+ Here are some examples:
153
+
154
+ ~~~ruby
155
+ para :vreg_meas, softbin: 105, lo: 1.12, hi: 1.34, id: :vreg_meas_1
156
+ # Automatically characterize the vreg if the measurement fails
157
+ para :vreg_meas, softbin: 107, cz: true, if_failed: :vreg_meas_1
158
+ # Then bin out
159
+ bin 3, softbin: 105, if_failed: :vreg_meas_1
160
+ # Check if the HVST has already been run on this device
161
+ func :rd_vreg_hvst_passcode, softbin: 50, vdd: :nom, id: :vreg_hvst_done
162
+ # If not run it
163
+ func :vreg_hvst, softbin: 101, hv: 10.V, vdd: :max, unless_passed: :vreg_hvst_done
164
+ # And program the flag for next time
165
+ func :pgm_vreg_hvst_passcode, softbin: 51, vdd: :nom, unless_passed: :vreg_hvst_done
166
+ ~~~
167
+
168
+ Origen automatically takes care of setting up all of the tests in the relationship:
169
+
170
+ * The parent tests in the relationship are automatically set to continue on fail
171
+ * Flag(s) will be set to indicate whether the parent test passed or failed
172
+ * Conditional execution flags are set on all dependent tests
173
+
174
+ AND and OR conditions can be created by using `if_any/all_failed/passed`
175
+ variations as follows:
176
+
177
+ ~~~ruby
178
+ func :test1, id: :t1
179
+ func :test2, id: :t2
180
+
181
+ # OR logic - This test will run if either of the referenced tests fail
182
+ func :test3, if_any_failed: [:t1, :t2]
183
+
184
+ # AND logic - This test will only run if both of the referenced tests fail
185
+ func :test4, if_all_passed: [:t1, :t2]
186
+
187
+ # Block forms are available as with all condition APIs
188
+ if_any_passed [:t1, :t2] do
189
+ #...
190
+ end
191
+ ~~~
192
+
193
+ #### References to External Tests
194
+
195
+ It is possible to generate conditional relationships between tests that span across
196
+ different flow modules, in that case the test ID must be appended with `:extern_`.
197
+ This will indicate to Origen that the reference is external and
198
+ will prevent an error being raised for the ID not being found within the current flow.
199
+
200
+ Here is an example:
201
+
202
+ ~~~ruby
203
+ # program/flow_1.rb
204
+ Flow.create do
205
+ # This ID can only be referenced within this flow
206
+ func :test1, id: :t1
207
+ # This ID can be referenced outside of this flow
208
+ func :test2 id: :extern_t2
209
+ end
210
+
211
+ # program/flow_2.rb
212
+ Flow.create do
213
+ # This will generate an undefined ID error
214
+ func :test3, if_failed: :t1
215
+ # But this will work, since the ID's name indicates that it is an intentional external reference
216
+ func :test4, if_failed: :extern_t2
217
+ end
218
+ ~~~
219
+
220
+ #### Applying Conditions to Sub-Flows
221
+
222
+ All of the flow control methods have a block form which will apply the
223
+ condition to all tests within the block.
224
+
225
+ A very useful pattern is to split your code into small re-usable snippets
226
+ and then wrap the import with these flow control methods to apply conditional
227
+ execution.
228
+ For example, here the 'FH' job requirement will be applied to all tests
229
+ imported from the vreg component:
230
+
231
+ ~~~ruby
232
+ # Only run the vreg tests at hot
233
+ if_job "FH" do
234
+ import "components/vreg"
235
+ end
236
+ ~~~
237
+
238
+ #### Conditions Applied to Groups
239
+
240
+ Groups can also be used to implement AND/OR logic, here is an example of how you
241
+ might implement a speed binning flow:
242
+
243
+ ~~~ruby
244
+ group "200Mhz", id: :spec200 do
245
+ func :test1_200
246
+ func :test2_200
247
+ end
248
+
249
+ # Bin out to bin 1 if passed at 200 Mhz, here if_passed will apply to all tests in the group
250
+ pass 1, if_passed: :spec200
251
+
252
+ group "100Mhz", id: :spec100 do
253
+ func :test1_100
254
+ func :test2_100
255
+ end
256
+
257
+ # Bin out to bin 2 if passed at 100 Mhz, here if_passed will apply to all tests in the group
258
+ pass 2, if_passed: :spec100
259
+
260
+ # Otherwise we have failed
261
+ bin 3
262
+ ~~~
263
+
264
+ #### Manually Setting and Referencing Flags
265
+
266
+ It may be sometimes be necessary to react on a flag that is controlled by a 3rd party and
267
+ which will be passed into an Origen-based test block, or to set a flag which a 3rd
268
+ party test block will later reference.
269
+
270
+ An API exists to manually set and react to flags in these situations:
271
+
272
+ ~~~ruby
273
+ log "Example of manual flag setting upon pass or fail"
274
+ test :test1, on_pass: { set_flag: :my_pass_flag }, on_fail: { set_flag: :my_fail_flag }, continue: true
275
+
276
+ # Execute only if the above pass flag was set
277
+ test :test2, if_flag: :my_pass_flag
278
+
279
+ # Execute only if the above pass flag was not set
280
+ unless_flag :my_pass_flag do
281
+ test :test3
282
+ end
283
+ ~~~
284
+
285
+ Note that flag names will usually be forced to uppercase, this is to institute a convention that
286
+ flags/flow variables are always uppercased in order to avoid any test program bugs from
287
+ incorrectly referencing a given flag due to case sensitivity.
288
+
289
+ However, if you need to reference a flag from a 3rd party test module that does not follow this
290
+ convention, then a literal flag can be supplied by prefixing it with `$` as shown below:
291
+
292
+ ~~~ruby
293
+ test :test1, on_fail: { set_flag: :$My_Mixed_Flag }, continue: true
294
+ test :test2, if_flag: "$My_Mixed_Flag"
295
+ unless_flag "$My_Mixed_Flag" do
296
+ test :test3
297
+ end
298
+
299
+ test :extra_test, if_enable: :$MCEn_extras
300
+ unless_enable "$MCEn_test" do
301
+ test :test1
302
+ test :test2
303
+ end
304
+ ~~~
305
+
306
+ In all cases the `$` will be removed from the final flag name that appears in the test program.
307
+
308
+
309
+ % end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: origen_testers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.43.0
4
+ version: 0.44.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen McGinty
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-11 00:00:00.000000000 Z
11
+ date: 2019-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: origen
@@ -510,6 +510,7 @@ files:
510
510
  - templates/origen_guides/program/custom.md.erb
511
511
  - templates/origen_guides/program/doc.md.erb
512
512
  - templates/origen_guides/program/flowapi.md.erb
513
+ - templates/origen_guides/program/flowapi.md.erb~
513
514
  - templates/origen_guides/program/flows.md.erb
514
515
  - templates/origen_guides/program/generating.md.erb
515
516
  - templates/origen_guides/program/interface.md.erb
@@ -545,8 +546,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
545
546
  - !ruby/object:Gem::Version
546
547
  version: '0'
547
548
  requirements: []
548
- rubyforge_project:
549
- rubygems_version: 2.7.7
549
+ rubygems_version: 3.0.1
550
550
  signing_key:
551
551
  specification_version: 4
552
552
  summary: This plugin provides Origen tester models to drive ATE type testers like