origen_testers 0.47.0 → 0.48.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
- SHA256:
3
- metadata.gz: df7294cf891812cfb78d98b161891a459391abb07841eb66d14929185385df22
4
- data.tar.gz: 2d0bfcc2c6862a2f10abc60136dbba9099f6f1ae0deeecb099b4700d34d95121
2
+ SHA1:
3
+ metadata.gz: aab714d801c978890bf63dcf475ccf275b87b54e
4
+ data.tar.gz: 37d3ef0d30281f9e467ba8475957aacebdb2959a
5
5
  SHA512:
6
- metadata.gz: c42eacdbe39b6eb35eddf8dcbeb08e49eab49bca4425c20f2c0474c8b5f977fdbeec9ed5b799001f7b8b7f5e6e87fc3293e3ac9c0ecc7012bc8eea8b7d86183b
7
- data.tar.gz: f17d9f4f1c7bdb90e58a0f2e6791e406bbf5b80b8ec8b5986a0e2e49e3e5d4145167c81a39773e560fbb8c8392a5b2dbbcf88efc52940e77301c6b4341a88a3a
6
+ metadata.gz: b2abd50fe57675fa06d61afe99ca4930a36bdfeaf172b8f166c40e0af190cf57b90a5e01ce366471a5aec5dd3a9be7957c09bb089c9922bdf07891f12226a9d6
7
+ data.tar.gz: b53c79a3dbc31a29fd74a984b4dc5111c245032d093d099a66195c08404f7d12980dd1f33d2f454ec4df1759a72c775aeb612c578dcfe4155af12f3cbe9d8b54
@@ -31,6 +31,7 @@ class OrigenTestersApplication < Origen::Application
31
31
  section.page :interface, heading: "Creating an Interface"
32
32
  section.page :resources, heading: "Additional Resources"
33
33
  section.page :code, heading: "Dynamic Custom Code"
34
+ section.page :charz, heading: "Characterization API"
34
35
  section.page :j750, heading: "J750 API"
35
36
  section.page :v93k, heading: "V93K Common API"
36
37
  section.page :v93ksmt7, heading: "V93K SMT7 API"
@@ -1,6 +1,6 @@
1
1
  module OrigenTesters
2
2
  MAJOR = 0
3
- MINOR = 47
3
+ MINOR = 48
4
4
  BUGFIX = 0
5
5
  DEV = nil
6
6
  VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
@@ -24,6 +24,7 @@ module OrigenTesters
24
24
  autoload :NoInterface, 'origen_testers/no_interface'
25
25
  autoload :MemoryStyle, 'origen_testers/memory_style'
26
26
  autoload :ATP, 'origen_testers/atp'
27
+ autoload :Charz, 'origen_testers/charz'
27
28
 
28
29
  # not yet autoload :Time, 'origen_testers/time'
29
30
 
@@ -0,0 +1,421 @@
1
+ Dir.glob("#{File.dirname(__FILE__)}/charz/**/*.rb").sort.each do |file|
2
+ require file
3
+ end
4
+ module OrigenTesters
5
+ module Charz
6
+ # @!attribute charz_stack
7
+ # @return [Array] FILO queue of charz session defining data
8
+ # @!attribute charz_routines
9
+ # @return [Hash] user defined charz routines
10
+ # @!attribute charz_profiles
11
+ # @return [Hash] user defined charz profiles
12
+ # @!attribute charz_session
13
+ # @return [Session] current charz session, based on data in the top of the charz_stack
14
+ # @!attribute eof_charz_tests
15
+ # @return [Array] charz tests to be added at the end of the flow
16
+ # @!attribute skip_group_eof_charz_tests
17
+ # @return [Boolean] whether or not to wrap eof charz tests in a group
18
+ # @!attribute eof_charz_tests_group_name
19
+ # @return [String, Symbol] group name to be used to for eof charz tests
20
+ attr_accessor :charz_stack, :charz_routines, :charz_profiles, :charz_session, :eof_charz_tests, :skip_group_eof_charz_tests, :eof_charz_tests_group_name
21
+
22
+ def charz_stack
23
+ @charz_stack ||= []
24
+ end
25
+
26
+ def charz_profiles
27
+ @charz_profiles ||= {}
28
+ end
29
+
30
+ def charz_routines
31
+ @charz_routines ||= {}
32
+ end
33
+
34
+ def charz_session
35
+ @charz_session ||= Session.new
36
+ end
37
+
38
+ def eof_charz_tests
39
+ @eof_charz_tests ||= []
40
+ end
41
+
42
+ # Add a new charz routine to @charz_routines
43
+ # A charz routine is a object that contains all the necessary info specific to a characterization test
44
+ # Its intended to be used in combination with an existing point test (regular non charz test) to create
45
+ # a characterization version of the point test
46
+ #
47
+ # @example create a 1d search routine that searches vdd, from 900mv to 300mv, resolution of 5mv
48
+ # add_charz_routine :my_routine, type: search do |rt|
49
+ # rt.start = 900.mv
50
+ # rt.stop = 300.mv
51
+ # rt.res = 5.mv
52
+ # rt.spec = 'vdd'
53
+ # end
54
+ #
55
+ # @param [Symbol] id charz_routine id, will be the key value in the @charz_routines hash. Must not have been previously used
56
+ # @param [Hash] options charz_routine options
57
+ # @option options [Symbol] :type :search or :'1d' will create a SearchRoutine, :shmoo or :'2d' will create a ShmooRoutine, nil will create a Routine
58
+ def add_charz_routine(id, options = {}, &block)
59
+ if charz_routines.ids.include?(id)
60
+ Origen.log.error("Cannot create charz routine '#{id}', it already exists!")
61
+ fail
62
+ end
63
+ case options[:type]
64
+ when :search, :'1d'
65
+ charz_routines[id] = SearchRoutine.new(id, options, &block)
66
+ when :shmoo, :'2d'
67
+ charz_routines[id] = ShmooRoutine.new(id, options, &block)
68
+ else
69
+ charz_routines[id] = Routine.new(id, options, &block)
70
+ end
71
+ end
72
+
73
+ # Add a new charz profile to @charz_profiles
74
+ # A charz profile is a collection of one or more charz routines, as well as flow control and placement data for
75
+ # the charz tests generated by those routines
76
+ #
77
+ # @example create a profile containing 2 routines, end of flow placement, whose tests are only ran if the parent fails
78
+ # add_charz_profile :my_profile do |prof|
79
+ # prof.routines = [:my_routine1, :my_routine2]
80
+ # prof.placement = :eof
81
+ # prof.on_result = :on_fail
82
+ # end
83
+ #
84
+ # @param [Symbol] id charz_profile id, will be the key value in the @charz_profiles hash. Must not have been previously used
85
+ # @param [Hash] options charz_profile options
86
+ def add_charz_profile(id, options = {}, &block)
87
+ if charz_profiles.ids.include?(id)
88
+ Origen.log.error("Cannot create charz profile '#{id}', it already exists!")
89
+ fail
90
+ end
91
+ charz_profiles[id] = Profile.new(id, options.merge(defined_routines: charz_routines.ids), &block)
92
+ end
93
+
94
+ # Queries the current charz session to see if its active, indicating point tests should be generating charz tests
95
+ def charz_active?
96
+ charz_session.active
97
+ end
98
+
99
+ # Queries the current charz session to see if point tests should skip generation, only adding the resulting charz test
100
+ def charz_only?
101
+ charz_active? && charz_session.charz_only
102
+ end
103
+
104
+ # Pauses the current charz session, preventing point tests from generating charz tests even if the session is valid
105
+ def charz_pause
106
+ charz_session.pause
107
+ end
108
+
109
+ # Resumes the current charz session. If the session isn't valid (ie charz_resume before setting up the session) then nothing will happen
110
+ def charz_resume
111
+ charz_session.resume
112
+ end
113
+
114
+ # Removes the current session generating data off the charz stack
115
+ # If charz data is still on the stack afterward, the session will update to reflect the new data
116
+ # if not, the session will become inactive
117
+ def charz_off
118
+ charz_stack.pop
119
+ if charz_stack.empty?
120
+ update_charz_session(nil)
121
+ else
122
+ update_charz_session(*charz_stack.last)
123
+ end
124
+ end
125
+
126
+ # Pushes a charz object (either a profile or a routine) onto the stack, along with any optional updates to modify the current session
127
+ # Once pushed, the charz_session will attempt to update itself with the new data, failing if the resulting session is invalid
128
+ #
129
+ # If a block is passed, yield the block of tests to enable charz for those tests, then disable charz with a charz_off call
130
+ #
131
+ # @param [Symbol] charz_id either a routine or profile id. Method fails if the id can't be found in @charz_routines or @charz_profiles
132
+ # @param [Hash] options charz_on options
133
+ # @option options [Symbol] :type (:profile) whether the charz_id refers to a charz profile or routine
134
+ def charz_on(charz_id, options = {})
135
+ options = {
136
+ type: :profile
137
+ }.merge(options)
138
+ case options[:type]
139
+ when :profile
140
+ charz_obj = charz_profiles[charz_id]
141
+ when :routine
142
+ if charz_id.is_a?(Array)
143
+ charz_obj = charz_routines[charz_id.first]
144
+ options[:routines] = charz_id
145
+ else
146
+ charz_obj = charz_routines[charz_id]
147
+ options[:routines] = [charz_id]
148
+ end
149
+ else
150
+ Origen.log.error "Unknown charz object type #{options[:type]}, valid types: :profile, :routine"
151
+ fail
152
+ end
153
+ if charz_obj.nil?
154
+ Origen.log.error "No #{options[:type]} found for charz_id: #{charz_id}"
155
+ fail
156
+ end
157
+ charz_stack.push([charz_obj, options])
158
+ unless update_charz_session(*charz_stack.last)
159
+ Origen.log.error 'charz_on failed to create a valid charz session'
160
+ fail
161
+ end
162
+ if block_given?
163
+ yield
164
+ charz_off
165
+ end
166
+ end
167
+
168
+ # An optional helper method to automatically assign an id to tests that will be generating charz tests that depend on the result of the parent test
169
+ # @param [Hash] options the options for a test before its created and added to the flow
170
+ # @param [TestInstance, #name] instance <Optional> the test instance whose name is stored in .name, alternatively pass the name in the options hash under :parent_test_name
171
+ def set_conditional_charz_id(*args)
172
+ case args.size
173
+ when 1
174
+ options = args[0]
175
+ parent_test_name = options[:parent_test_name]
176
+ when 2
177
+ instance = args[0]
178
+ options = args[1]
179
+ parent_test_name = instance.name
180
+ else
181
+ Origen.log.error 'Too many arguments passed to set_conditional_charz_id. Pass either (test_instance, options), or just (options)'
182
+ fail
183
+ end
184
+ unless options[:id]
185
+ if charz_active?
186
+ if charz_session.on_result
187
+ options[:id] = "#{parent_test_name}_charz_#{charz_session.name}".to_sym
188
+ end
189
+ end
190
+ end
191
+ end
192
+
193
+ # Called after the relevant point test has been inserted into the flow
194
+ # Takes the options used to build the previous point test as well as insert_charz_test specific options to then
195
+ # drill down to the point of the flow where the charz test would go, at which point control is handed back to the user's
196
+ # interface to handle creating and inserting the test
197
+ #
198
+ # By default, this method will handle:
199
+ # - the placement of the test (inline aka right after the point test, end of flow, or other)
200
+ # - wrapping the created charz tests in a group (skippable, group name defaults to <point test name> charz <session name>)
201
+ # - conditionally executing the charz tests based on if the point test passed or failed (see set_conditional_charz_id)
202
+ # - conditionally executing some/all charz tests based on a mix of enables and flags
203
+ #
204
+ # After the above is determined, the user regains control on a per-routine (if multiple routines) basis to then process generating the charz test
205
+ def insert_charz_tests(options, &block)
206
+ if charz_active?
207
+ if options[:id]
208
+ # two purposes:
209
+ # 1) prevent all charz tests inadverntently using the same ID as their parent
210
+ # 2) used in on_result behavior
211
+ current_id = options.delete(:id)
212
+ options[:last_test_id] ||= current_id
213
+ end
214
+ case charz_session.placement
215
+ when :inline
216
+ create_charz_group(options, &block)
217
+ when :eof
218
+ # collect the current session and options into a proc, stored in eof_charz_tests to be called later
219
+ current_session = charz_session.clone
220
+ eof_charz_tests << proc do
221
+ @charz_session = current_session
222
+ create_charz_group(options, &block)
223
+ end
224
+ else
225
+ # inline is the default behavior, and eof (end of flow) has built in support.
226
+ if respond_to?(:"create_#{charz_session.placement}_charz_tests")
227
+ send(:"create_#{charz_session.placement}_charz_tests", options, &block)
228
+ elsif respond_to?(:"insert_#{charz_session.placement}_charz_tests")
229
+ send(:"insert_#{charz_session.placement}_charz_tests", options, &block)
230
+ else
231
+ Origen.log.error "No handling specified for #{charz_session.placement} placement charz tests"
232
+ fail
233
+ end
234
+ end
235
+ end
236
+ end
237
+
238
+ # called automatically right after a top_level shutdown, generates end of flow charz tests
239
+ # user should not have to reference this call explicitly
240
+ def generate_eof_charz_tests
241
+ unless eof_charz_tests.empty?
242
+ if skip_group_eof_charz_tests
243
+ eof_charz_tests.map(&:call)
244
+ else
245
+ group_name = eof_charz_tests_group_name || 'End of Flow Charz Tests'
246
+ group group_name do
247
+ eof_charz_tests.map(&:call)
248
+ end
249
+ end
250
+ end
251
+ end
252
+
253
+ private
254
+
255
+ # called by charz_on, updates the current session, and passes the available routines in for validity checks
256
+ def update_charz_session(charz_obj, options = {})
257
+ charz_session.update(charz_obj, options.merge(defined_routines: charz_routines.ids))
258
+ end
259
+
260
+ # called by insert_charz_tests
261
+ #
262
+ # if insert_charz_tests was called with the skip group option, then skip to processing the sessions on_result functionality
263
+ # otherwise, on_result processing occurs within the created group
264
+ #
265
+ # group name defaults to <point test name> charz <session name>, but can be set by the user by passing :group_name in the options
266
+ def create_charz_group(options, &block)
267
+ if options[:skip_group]
268
+ process_on_result(options, &block)
269
+ else
270
+ group_name = options[:group_name] || "#{options[:parent_test_name]} charz #{charz_session.name}"
271
+ group group_name.to_sym do
272
+ process_on_result(options, &block)
273
+ end
274
+ end
275
+ end
276
+
277
+ # called by create_charz_group
278
+ #
279
+ # Handles the case where the session indicates these charz tests' execution depend on the point test's result
280
+ # Requires that the id of the point test has been passed to use this functionality. Otherwise, make sure that
281
+ # charz_session.on_result == nil
282
+ #
283
+ # on_fail and on_pass results are built-in, but if the user has a different check to make, it can be handled
284
+ # by defining the method process_<custom result>_charz_tests
285
+ #
286
+ # @see set_conditional_charz_id
287
+ def process_on_result(options, &block)
288
+ if charz_session.on_result
289
+ case charz_session.on_result
290
+ when :on_fail, :fail, :failed
291
+ last_test_id = options[:last_test_id] || @last_test_id
292
+ if_failed last_test_id do
293
+ process_gates(options, &block)
294
+ end
295
+ when :on_pass, :pass, :passed
296
+ last_test_id = options[:last_test_id] || @last_test_id
297
+ if_passed last_test_id do
298
+ process_gates(options, &block)
299
+ end
300
+ else
301
+ if respond_to?(:"process_#{charz_session.placement}_charz_tests")
302
+ send(:"process_#{charz_session.on_result}_charz_tests", options, &block)
303
+ else
304
+ Origen.log.error "No handling specified for result #{charz_session.on_result} charz tests"
305
+ fail
306
+ end
307
+ end
308
+ else
309
+ process_gates(options, &block)
310
+ end
311
+ end
312
+
313
+ # called by process_on_result
314
+ #
315
+ # Handles the case where charz_session.enables or charz_session.flags have been set
316
+ # referring to enables and flags both as gates, gates can wrap all routines in a session if they're in the form of an
317
+ # array, symbol, or a string (think of the normal use case of if_enable or if_flag)
318
+ #
319
+ # If the gate is a Hash, then that means different routines are getting different gate wrappers.
320
+ # Also if a routine is not indicated in the values of the gate, then that means that routine should not be gated at all
321
+ #
322
+ # This is the final method of handling the insert_charz_test usecases, where the block thats been passed around is finally called
323
+ # the user's provided block is passed the current routine (one at a time) to then take its info to generate a charz test
324
+ def process_gates(options, &block)
325
+ if options[:skip_gates] || !(charz_session.enables || charz_session.flags)
326
+ charz_session.routines.each do |routine|
327
+ block.call(options.merge(current_routine: routine))
328
+ end
329
+ else
330
+ if charz_session.enables && charz_session.flags
331
+ if charz_session.enables.is_a?(Hash) && !charz_session.flags.is_a?(Hash)
332
+ # wrap all tests in flags, wrap specific tests in enables
333
+ if_flag charz_session.flags do
334
+ insert_hash_gates(options, charz_session.enables, :if_enable, &block)
335
+ end
336
+ elsif !charz_session.enables.is_a?(Hash) && charz_session.flags.is_a?(Hash)
337
+ # wrap all tests in enables, wrap specific tests in flags
338
+ if_enable charz_session.enables do
339
+ insert_hash_gates(options, charz_session.flags, :if_flag, &block)
340
+ end
341
+ elsif charz_session.enables.is_a?(Hash) && charz_session.flags.is_a?(Hash)
342
+ # first insert the tests that are not tied to an enable or flag gate
343
+ ungated_routines = charz_session.routines - (charz_session.enables.values.flatten | charz_session.flags.values.flatten)
344
+ ungated_routines.each do |routine|
345
+ block.call(options.merge(current_routine: routine))
346
+ end
347
+ # wrap tests in an enable gate, flag gate, or both
348
+ gated_routines = charz_session.routines - ungated_routines
349
+ gated_routines.each do |routine|
350
+ enable = charz_session.enables.find { |gates, routines| routines.include?(routine) }&.first
351
+ flag = charz_session.flags.find { |gates, routines| routines.include?(routine) }&.first
352
+ if enable && flag
353
+ if_enable enable do
354
+ if_flag flag do
355
+ # wrap test in both enable and flag gate
356
+ block.call(options.merge(current_routine: routine))
357
+ end
358
+ end
359
+ elsif enable
360
+ if_enable enable do
361
+ # enable only
362
+ block.call(options.merge(current_routine: routine))
363
+ end
364
+ elsif flag
365
+ if_flag flag do
366
+ # flag only
367
+ block.call(options.merge(current_routine: routine))
368
+ end
369
+ end
370
+ end
371
+ else
372
+ # both enable and flag is set, and both apply to all routines in session
373
+ if_enable charz_session.enables do
374
+ if_flag charz_session.flags do
375
+ charz_session.routines.each do |routine|
376
+ block.call(options.merge(current_routine: routine))
377
+ end
378
+ end
379
+ end
380
+ end
381
+ else
382
+ # only enables or flags is set, not both
383
+ if charz_session.enables
384
+ gates = charz_session.enables
385
+ gate_method = :if_enable
386
+ elsif charz_session.flags
387
+ gates = charz_session.flags
388
+ gate_method = :if_flag
389
+ end
390
+ if gates.is_a?(Hash)
391
+ # wrap some tests in specific gates
392
+ insert_hash_gates(options, gates, gate_method, &block)
393
+ else
394
+ # wrap all tests in the indicated gates
395
+ send(gate_method, gates) do
396
+ charz_session.routines.each do |routine|
397
+ block.call(options.merge(current_routine: routine))
398
+ end
399
+ end
400
+ end
401
+ end
402
+ end
403
+ end
404
+
405
+ # helper method for the process gates method above
406
+ # handles wrapping routines in specific gates, and passing ungated routines back to the user
407
+ def insert_hash_gates(options, gate_hash, gate_method, &block)
408
+ ungated_routines = charz_session.routines - gate_hash.values.flatten
409
+ ungated_routines.each do |routine|
410
+ block.call(options.merge(current_routine: routine))
411
+ end
412
+ gate_hash.each do |gate, gated_routines|
413
+ send(gate_method, gate) do
414
+ gated_routines.each do |routine|
415
+ block.call(options.merge(current_routine: routine))
416
+ end
417
+ end
418
+ end
419
+ end
420
+ end
421
+ end
@@ -0,0 +1,120 @@
1
+ module OrigenTesters
2
+ module Charz
3
+ # A Charz Profile
4
+ # Used to store characterization routines as well as flow control, conditional execution, and test placement meta data
5
+ class Profile
6
+ # @!attribute id
7
+ # @return [Symbol] the id of the current profile, used as a key in OrigenTesters::Charz#charz_profiles hash
8
+ # @!attribute name
9
+ # @return [Symbol] the value used (if the user decides) to generate the name of the created charz test. defaults to the value of @id
10
+ # @!attribute placement
11
+ # @return [Symbol] placement of the to be created charz tests, defaults to inline, accepts :eof as well. Other placements can be used as well if @valid_placements is altered
12
+ # @!attribute on_result
13
+ # @return [Symbol] indicates if the resulting charz tests are depending on the point tests result, valid values include :on_fail, and :on_pass
14
+ # @!attribute enables
15
+ # @return [Symbol, String, Array, Hash] enable gates to be wrapped around the resulting charz tests
16
+ # @!attribute flags
17
+ # @return [Symbol, String, Array, Hash] flag gates to be wrapped around the resulting charz tests
18
+ # @!attribute routines
19
+ # @return [Array] list of charz routines to be called under this profile
20
+ # @!attribute charz_only
21
+ # @return [Boolean] indicates if the point tests should or shouldn't be added to the flow
22
+ attr_accessor :id, :name, :placement, :on_result, :enables, :flags, :routines, :charz_only
23
+
24
+ def initialize(id, options, &block)
25
+ @id = id
26
+ @id = @id.symbolize unless id.is_a? Symbol
27
+ options.each { |k, v| instance_variable_set("@#{k}", v) }
28
+ (block.arity < 1 ? (instance_eval(&block)) : block.call(self)) if block_given?
29
+ @name ||= id
30
+ @placement ||= :inline
31
+ @defined_routines = options.delete(:defined_routines)
32
+ attrs_ok?
33
+ end
34
+
35
+ def attrs_ok?
36
+ return if @quality_check == false
37
+
38
+ unknown_routines = @routines - @defined_routines
39
+ unless unknown_routines.empty?
40
+ Origen.log.error "Profile #{id}: unknown routines: #{unknown_routines}"
41
+ fail
42
+ end
43
+
44
+ @valid_placements ||= [:inline, :eof]
45
+ unless @valid_placements.include? @placement
46
+ Origen.log.error "Profile #{id}: invalid placement value, must be one of: #{@valid_placements}"
47
+ fail
48
+ end
49
+
50
+ if @on_result
51
+ @valid_on_results ||= [:on_fail, :fail, :failed, :on_pass, :pass, :passed]
52
+ unless @valid_on_results.include?(@on_result)
53
+ Origen.log.error "Profile #{id}: invalid on_result value, must be one of: #{@valid_on_results}"
54
+ fail
55
+ end
56
+ end
57
+
58
+ if @charz_only && @on_result
59
+ Origen.log.error "Profile #{id}: @charz_only is set, but @on_result (#{@on_result}) requires the parent test to exist in the flow"
60
+ fail
61
+ end
62
+
63
+ unless @gate_checks == false
64
+ gate_check(@enables, :enables) if @enables
65
+ gate_check(@flags, :flags) if @flags
66
+ end
67
+ end
68
+
69
+ def gate_check(gates, gate_type)
70
+ case gates
71
+ when Symbol, String
72
+ return
73
+ when Array
74
+ unknown_gates = gates.reject { |gate| [String, Symbol].include? gate.class }
75
+ if unknown_gates.empty?
76
+ return
77
+ else
78
+ Origen.log.error "Profile #{id}: Unknown #{gate_type} type(s) in #{gate_type} array."
79
+ Origen.log.error "Arrays must contain Strings and/or Symbols, but #{unknown_gates.map(&:class).uniq } were found in #{gates}"
80
+ fail
81
+ end
82
+ when Hash
83
+ gates.each do |gate, gated_routines|
84
+ if gate.is_a? Hash
85
+ Origen.log.error "Profile #{id}: #{gate_type} Hash keys cannot be of type Hash, but only Symbol, String, or Array"
86
+ fail
87
+ end
88
+ gate_check(gate, gate_type)
89
+ gated_routines = [gated_routines] unless gated_routines.is_a? Array
90
+ unknown_routines = gated_routines - @defined_routines
91
+ unless unknown_routines.empty?
92
+ Origen.log.error "Profile #{id}: unknown routines found in @#{gate_type}[#{gate.is_a?(Symbol) ? ':' : ''}#{gate}]: #{unknown_routines}"
93
+ fail
94
+ end
95
+ end
96
+ else
97
+ Origen.log.error "Profile #{id}: Unknown #{gate_type} type: #{gates.class}. #{gate_type} must be of type Symbol, String, Array, or Hash"
98
+ fail
99
+ end
100
+ end
101
+
102
+ def method_missing(m, *args, &block)
103
+ ivar = "@#{m.to_s.gsub('=', '')}"
104
+ ivar_sym = ":#{ivar}"
105
+ if m.to_s =~ /=$/
106
+ define_singleton_method(m) do |val|
107
+ instance_variable_set(ivar, val)
108
+ end
109
+ elsif instance_variables.include? ivar_sym
110
+ instance_variable_get(ivar)
111
+ else
112
+ define_singleton_method(m) do
113
+ instance_variable_get(ivar)
114
+ end
115
+ end
116
+ send(m, *args, &block)
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,38 @@
1
+ module OrigenTesters
2
+ module Charz
3
+ # A Generic charz routine
4
+ # Used to store characterization test specific meta data, values of which are used by the user to determine test parameter values
5
+ class Routine
6
+ # @!attribute id
7
+ # @return [Symbol] charz routine symbol, used as a key in OrigenTesters::Charz#charz_routines
8
+ # @!attribute name
9
+ # @return [Symbol] the value used (if the user decides) to generate the name of the created charz test. defaults to the value of @id
10
+ attr_accessor :id, :name
11
+
12
+ def initialize(id, options = {}, &block)
13
+ @id = id
14
+ @id = @id.symbolize unless id.is_a? Symbol
15
+ options.each { |k, v| instance_variable_set("@#{k}", v) }
16
+ (block.arity < 1 ? (instance_eval(&block)) : block.call(self)) if block_given?
17
+ @name ||= @id
18
+ end
19
+
20
+ def method_missing(m, *args, &block)
21
+ ivar = "@#{m.to_s.gsub('=', '')}"
22
+ ivar_sym = ":#{ivar}"
23
+ if m.to_s =~ /=$/
24
+ define_singleton_method(m) do |val|
25
+ instance_variable_set(ivar, val)
26
+ end
27
+ elsif instance_variables.include? ivar_sym
28
+ instance_variable_get(ivar)
29
+ else
30
+ define_singleton_method(m) do
31
+ instance_variable_get(ivar)
32
+ end
33
+ end
34
+ send(m, *args, &block)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,42 @@
1
+ module OrigenTesters
2
+ module Charz
3
+ # a 1D search routine
4
+ class SearchRoutine < Routine
5
+ # @!attribute start
6
+ # @return [Numeric] search start value
7
+ # @!attribute stop
8
+ # @return [Numeric] search stop value
9
+ # @!attribute res
10
+ # @return [Numeric] search resolution
11
+ # @!attribute spec
12
+ # @return [Numeric] spec parameter to be searched
13
+ attr_accessor :start, :stop, :res, :spec
14
+
15
+ # Runs the same initialization as Routine
16
+ # performs some rudimentary quality checks, which can be disabled by setting @quality_check = false
17
+ def initialize(id, options = {}, &block)
18
+ super
19
+ attrs_ok?
20
+ end
21
+
22
+ def attrs_ok?
23
+ return if @quality_check == false
24
+
25
+ @required_attrs ||= [:start, :stop, :res, :spec]
26
+ attrs = @required_attrs.map { |attr| instance_variable_get("@#{attr}") }
27
+ if attrs.compact.size != @required_attrs.size
28
+ Origen.log.error "SearchRoutine #{@id}: unspecified attributes, each of #{@required_attrs} must have a value"
29
+ fail
30
+ end
31
+
32
+ return if @attr_value_check == false
33
+ if [@start, @stop, @res].all? { |attr| attr.is_a? Numeric }
34
+ unless @res <= (@start - @stop).abs
35
+ Origen.log.error "SearchRoutine #{@id}: Search resolution (#{@res}) is larger than the search range: #{(@start - @stop).abs}"
36
+ fail
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,62 @@
1
+ module OrigenTesters
2
+ module Charz
3
+ # A 2D search or "Shmoo" routine
4
+ class ShmooRoutine < Routine
5
+ # @!attribute x_start
6
+ # @return [Numeric] the starting search value for the x dimension's spec search
7
+ # @!attribute x_stop
8
+ # @return [Numeric] the stopping search value for the x dimension's spec search
9
+ # @!attribute x_res
10
+ # @return the search resolution value for the x dimension's spec search
11
+ # @!attribute x_spec
12
+ # @return [Symbol, String] the spec parameter of interest for the x dimension
13
+ attr_accessor :x_start, :x_stop, :x_res, :x_spec
14
+ # @!attribute y_start
15
+ # @return [Numeric] the starting search value for the x dimension's spec search
16
+ # @!attribute y_stop
17
+ # @return [Numeric] the stopping search value for the x dimension's spec search
18
+ # @!attribute y_res
19
+ # @return the search resolution value for the x dimension's spec search
20
+ # @!attribute y_spec
21
+ # @return [Symbol, String] the spec parameter of interest for the x dimension
22
+ attr_accessor :y_start, :y_stop, :y_res, :y_spec
23
+
24
+ def initialize(id, options = {}, &block)
25
+ super
26
+ attrs_ok?
27
+ end
28
+
29
+ def attrs_ok?
30
+ return if @quality_check == false
31
+
32
+ @required_attrs ||= [:x_start, :x_stop, :x_res, :x_spec, :y_start, :y_stop, :y_res, :y_spec]
33
+ attrs = @required_attrs.map { |attr| instance_variable_get("@#{attr}") }
34
+ if attrs.compact.size != @required_attrs.size
35
+ Origen.log.error "ShmooRoutine #{@id}: unspecified attributes, each of #{@required_attrs} must have a value"
36
+ fail
37
+ end
38
+
39
+ return if @attr_value_check == false
40
+
41
+ # not sure if I want this check, if so need to scope out if step count is common
42
+
43
+ # if [@x_start, @x_stop, @x_res].all? { |attr| attr.is_a? Numeric }
44
+ # unless @x_res <= (@x_start - @x_stop).abs
45
+ # Origen.log.error "ShmooRoutine #{@id}: Search x_resolution (#{@x_res} is larger than the search x_range (#{@x_start - @x_stop).abs})"
46
+ # fail
47
+ # end
48
+ # end
49
+ # if [@y_start, @y_stop, @y_res].all? { |attr| attr.is_a? Numeric }
50
+ # unless @y_res <= (@y_start - @y_stop).abs
51
+ # Origen.log.error "ShmooRoutine #{@id}: Search y_resolution (#{@y_res} is larger than the search y_range (#{@y_start - @y_stop).abs})"
52
+ # fail
53
+ # end
54
+ # end
55
+ unless @x_spec != @y_spec
56
+ Origen.log.error "ShmooRoutine #{@id}: Search x_spec is identical to y_spec"
57
+ fail
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,100 @@
1
+ module OrigenTesters
2
+ module Charz
3
+ # A charz session
4
+ # contains the final combination of charz object (routines/profiles) and user options to determine how and what charz tests should be created
5
+ # the session should be checked in your interface to determine the current status and can be queried to make charz generation decisions
6
+ class Session < Profile
7
+ # @!attribute defaults
8
+ # @return [Hash] list of values to instantiate the inherited attributes from Profile with if not altered by the session update
9
+ attr_accessor :defaults
10
+
11
+ def initialize(options = {})
12
+ @id = :current_charz_session
13
+ @active = false
14
+ @valid = false
15
+ if options[:defaults]
16
+ @defaults = options[:defaults]
17
+ else
18
+ @defaults = {
19
+ placement: :inline,
20
+ on_result: nil,
21
+ enables: nil,
22
+ flags: nil,
23
+ name: 'charz',
24
+ charz_only: false
25
+ }
26
+ end
27
+ end
28
+
29
+ # Pauses the current session's activity while maintaining everthing else about the sessions state
30
+ def pause
31
+ @active = false
32
+ end
33
+
34
+ # Resume activity, if the session is valid
35
+ def resume
36
+ if @valid
37
+ @active = true
38
+ end
39
+ end
40
+
41
+ # Takes a Routine or Profile, and queries it to setup the session's attributes
42
+ # the attributes values can be set from 3 different sources, in order of priority (first is most important):
43
+ # - options
44
+ # - charz object
45
+ # - defaults
46
+ #
47
+ # If the resulting session is invalid, @valid will turn false. Otherwise, the session becomes active
48
+ def update(charz_obj, options)
49
+ @valid = false
50
+ if charz_obj.nil?
51
+ @active = false
52
+ @valid = false
53
+ return @valid
54
+ end
55
+ @defined_routines = options.delete(:defined_routines)
56
+ assign_by_priority(:placement, charz_obj, options)
57
+ assign_by_priority(:on_result, charz_obj, options)
58
+ assign_by_priority(:enables, charz_obj, options)
59
+ assign_by_priority(:flags, charz_obj, options)
60
+ assign_by_priority(:routines, charz_obj, options)
61
+ assign_by_priority(:name, charz_obj, options)
62
+ assign_by_priority(:charz_only, charz_obj, options)
63
+ attrs_ok?
64
+ massage_gates
65
+ @active = true
66
+ @valid = true
67
+ end
68
+
69
+ private
70
+
71
+ # convert hash gates to set convert their routines to type array if not already
72
+ def massage_gates
73
+ if @enables.is_a?(Hash)
74
+ @enables = {}.tap do |new_h|
75
+ @enables.each { |gates, routines| new_h[gates] = [routines].flatten }
76
+ end
77
+ end
78
+ if @flags.is_a?(Hash)
79
+ @flags = {}.tap do |new_h|
80
+ @flags.each { |gates, routines| new_h[gates] = [routines].flatten }
81
+ end
82
+ end
83
+ end
84
+
85
+ # see initialize
86
+ def assign_by_priority(ivar, charz_obj, options)
87
+ if options.keys.include?(ivar)
88
+ instance_variable_set("@#{ivar}", options[ivar])
89
+ elsif charz_obj.send(ivar)
90
+ instance_variable_set("@#{ivar}", charz_obj.send(ivar))
91
+ elsif @defaults.keys.include?(ivar)
92
+ instance_variable_set("@#{ivar}", @defaults[ivar])
93
+ else
94
+ Origen.log.error "Charz Session: No value could be determined for #{ivar}"
95
+ fail
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -138,6 +138,7 @@ module Origen
138
138
  end
139
139
  Origen.interface.startup(options) if Origen.interface.respond_to?(:startup)
140
140
  interface.instance_eval(&block)
141
+ Origen.interface.generate_eof_charz_tests if Origen.interface.respond_to?(:generate_eof_charz_tests)
141
142
  Origen.interface.shutdown(options) if Origen.interface.respond_to?(:shutdown)
142
143
  interface.at_flow_end if interface.respond_to?(:at_flow_end)
143
144
  Origen.app.listeners_for(:on_flow_end).each do |listener|
@@ -2,6 +2,7 @@ module OrigenTesters
2
2
  module Test
3
3
  class Interface
4
4
  include OrigenTesters::ProgramGenerators
5
+ include OrigenTesters::Charz
5
6
 
6
7
  attr_accessor :include_additional_prb2_test
7
8
  attr_reader :environment
@@ -10,6 +11,45 @@ module OrigenTesters
10
11
  # desired to configure your interface
11
12
  def initialize(options = {})
12
13
  @environment = options[:environment]
14
+ add_charz
15
+ end
16
+
17
+ def add_charz
18
+ add_charz_routine :routine1 do |routine|
19
+ routine.name = '_cz__rt1'
20
+ end
21
+ add_charz_routine :routine2 do |routine|
22
+ routine.name = '_cz__rt2'
23
+ end
24
+ add_charz_routine :routine3 do |routine|
25
+ routine.name = '_cz__rt3'
26
+ end
27
+ add_charz_routine :routine4 do |routine|
28
+ routine.name = '_cz__rt4'
29
+ end
30
+ add_charz_routine :routine5 do |routine|
31
+ routine.name = '_cz__rt5'
32
+ end
33
+ add_charz_routine :routine6 do |routine|
34
+ routine.name = '_cz__rt6'
35
+ end
36
+ add_charz_profile :cz do |profile|
37
+ profile.routines = [:routine3]
38
+ end
39
+ add_charz_profile :cz_only do |profile|
40
+ profile.charz_only = true
41
+ profile.routines = [:routine1]
42
+ end
43
+ add_charz_profile :simple_gates do |profile|
44
+ profile.flags = :my_flag
45
+ profile.enables = :my_enable
46
+ profile.routines = [:routine1]
47
+ end
48
+ add_charz_profile :complex_gates do |profile|
49
+ profile.flags = { ['$MyFlag1'] => [:routine1, :routine2], ['$MyFlag2'] => [:routine3], '$MyFlag3' => :routine4 }
50
+ profile.enables = { ['$MyEnable1'] => [:routine1], ['$MyEnable2'] => [:routine2, :routine3], '$MyEnable3' => :routine5 }
51
+ profile.routines = [:routine1, :routine2, :routine3, :routine4, :routine5, :routine6]
52
+ end
13
53
  end
14
54
 
15
55
  # Test that the block form of flow control methods like this can
@@ -86,6 +126,46 @@ module OrigenTesters
86
126
  end
87
127
  end
88
128
 
129
+ def func_with_charz(name, options = {})
130
+ options = {
131
+ duration: :static
132
+ }.merge(options)
133
+
134
+ if tester.v93k?
135
+ if tester.smt7?
136
+ tm = test_methods.ac_tml.ac_test.functional_test
137
+ ts = test_suites.run(name, options)
138
+ ts.test_method = tm
139
+ ts.pattern = 'charz_example'
140
+
141
+ test_level_charz = false
142
+ if options[:charz]
143
+ charz_on(*options[:charz])
144
+ test_level_charz = true
145
+ end
146
+
147
+ unless charz_only? && !options[:charz_test]
148
+ options[:parent_test_name] = name
149
+ set_conditional_charz_id(options)
150
+ flow.test ts, options
151
+ end
152
+
153
+ unless options[:charz_test]
154
+ insert_charz_tests(options.merge(parent_test_name: name, charz_test: true)) do |options|
155
+ charz_name = :"#{name}_#{charz_routines[options[:current_routine]].name}"
156
+ func_with_charz(charz_name, options)
157
+ end
158
+ end
159
+
160
+ charz_off if test_level_charz
161
+ else
162
+ fail 'Only SMT7 is Implemented for Charz'
163
+ end
164
+ else
165
+ fail "Tester #{tester.name} Not Yet Implemented for Charz"
166
+ end
167
+ end
168
+
89
169
  def func_with_comment(name, options = {})
90
170
  if tester.v93k?
91
171
  options = {
@@ -0,0 +1,48 @@
1
+ # An instance of the interface is
2
+ # passed in here, iterators and other
3
+ # argument passing will be supported
4
+ # similar to Pattern.create.
5
+ Flow.create interface: 'OrigenTesters::Test::Interface' do
6
+ flow.flow_description = '' if tester.v93k?
7
+
8
+ if tester.v93k? && tester.smt7?
9
+ charz_on :complex_gates, { on_result: :fail }
10
+ func_with_charz :func_complex_gates_on_fail
11
+ charz_off
12
+
13
+ charz_on :complex_gates, { enables: :my_enable }
14
+ func_with_charz :func_complex_flag_simple_enable
15
+ charz_off
16
+
17
+ charz_on :complex_gates, { flags: :my_flag } do
18
+ func_with_charz :func_complex_enable_simple_flag
19
+ end
20
+
21
+ charz_on :cz_only, { placement: :eof }
22
+ func_with_charz :func_charz_only
23
+ charz_off
24
+
25
+ func_with_charz :func_test_level_routine, charz: [:routine1, { type: :routine }]
26
+
27
+ charz_on :cz
28
+ func_with_charz :func_skip_group, skip_group: true
29
+ charz_pause
30
+ func_with_charz :func_pause_charz
31
+ charz_resume
32
+ func_with_charz :func_resume_charz
33
+ charz_off
34
+
35
+ charz_on :simple_gates, { on_result: :pass } do
36
+ func_with_charz :func_simple_gates_on_pass
37
+ end
38
+
39
+ charz_on :simple_gates, { enables: nil }
40
+ func_with_charz :func_simple_flags
41
+ charz_off
42
+
43
+ charz_on :simple_gates, { flags: nil }
44
+ func_with_charz :func_simple_enables
45
+ charz_off
46
+ end
47
+
48
+ end
@@ -0,0 +1,221 @@
1
+ % render "layouts/guides.html" do
2
+
3
+ Be sure to read and understand the guide to
4
+ [Creating an Interface](<%= path "guides/program/interface" %>) before
5
+ reading this guide.
6
+ This guide covers aspects of the Characterization (charz) API.
7
+
8
+ Currently, the charz API has only been proven out for V93K SMT7, but isn't inherently designed around working only for that environment.
9
+
10
+ The Charz API is enabled by including the Charz module in your interface:
11
+
12
+ ~~~ruby
13
+ # app/lib/my_app/interface.rb
14
+ module MyApp
15
+ class Interface
16
+ include OrigenTesters::ProgramGenerators
17
+ include OrigenTesters::Charz
18
+ ~~~
19
+
20
+ Note this guide assumes the audience is familiar with interface creation and custom test methods, and will not go into detail explaining those topics.
21
+
22
+ ## Overview
23
+
24
+ The Characterization API allows a flow to add characterization to existing production tests with little additional overhead.
25
+
26
+ First specify charz routines to set charz test options, then create a profile with flow creation meta for the resulting tests.
27
+ Afterwards, the `charz_on` method can be called in the flow to activate charz profiles, which is explained below.
28
+
29
+ ### Charz Routines
30
+
31
+ Charz routines contain relevant charz data thats specific to a charz test to be created. Created routines are stored in the `@charz_routines` attribute.
32
+ The data stored within a routine will be used in combination with the options used to make a production test to make a charz variant of the production test.
33
+
34
+ The interface adds charz routines by calling the `add_charz_routine` method:
35
+
36
+ ~~~ruby
37
+ add_charz_routine :vmin do |routine|
38
+ routine.name = 'cz_vmin_vdd'
39
+ routine.start = 1.0.V
40
+ routine.stop = 0.5.V
41
+ routine.res = 5.mV
42
+ routine.spec = 'VDD'
43
+ end
44
+ ~~~
45
+
46
+ ### Charz Profiles
47
+
48
+ Charz profiles contain a collection of routines, as well as test creation meta data related to test placement, production test result dependence, and conditional execution.
49
+
50
+ The interface adds charz profiles by calling the `add_charz_profile` method. To create a profile that contains previously defined vmin and vmax search routines, whose resulting searches
51
+ only run if the production test failed, and sets the vmax search routine to only run if the 'VmaxEnable' variable is set:
52
+
53
+ ~~~ruby
54
+ add_charz_profile :fail_searches do |profile|
55
+ profile.name = 'fail_searches'
56
+ profile.on_result = :on_fail
57
+ profile.routines = [:vmin, :vmax]
58
+ profile.enables = { ['$VmaxEnable'] => [:vmax] }
59
+ end
60
+ ~~~
61
+
62
+ ### Charz Session
63
+
64
+ The charz session (stored in your interfaces `@charz_session` attribute) monitors the current state of characterization at a given point in flow generation.
65
+
66
+ The API provides some key methods for querying that state during generation, such as:
67
+
68
+ * `charz_active?` : indicates if applicable productions tests should be generating charz tests as well
69
+ * `charz_only?` : indicates if the production tests should be added to the flow or not, only generating the resulting charz test
70
+
71
+ ## Interface Considerations
72
+
73
+ A couple of enhancements will need to be added to your interface to take advantage of the API in addition to adding `include OrigenTesters::Charz` as shown above.
74
+ The charz routines and profiles will need to be added, and your flow methods will need to be updated to know what to do when a charz session is active.
75
+
76
+ ### Adding charz routines and profiles
77
+
78
+ As long as the desired routines and profiles exist in the interface's @charz_routines and @charz_profiles hashes, the rest of the API will work as expected.
79
+ One option is to add them during the interface initialization:
80
+
81
+ ~~~ruby
82
+ # app/lib/my_app/interface.rb
83
+ module MyApp
84
+ class Interface
85
+ include OrigenTesters::ProgramGenerators
86
+ include OrigenTesters::Charz
87
+
88
+ def add_charz
89
+ add_charz_routine :my_routine do |routine|
90
+ routine.name = 'cz_vmin_vdd'
91
+ routine.start = 1.0.V
92
+ routine.stop = 0.5.V
93
+ routine.res = 5.mV
94
+ routine.spec = 'VDD'
95
+ end
96
+ add_charz_profile :my_profile do |profile|
97
+ profile.name = 'vmin_search'
98
+ profile.routines = [:vmin]
99
+ end
100
+ end
101
+
102
+ def initialize(options = {})
103
+ add_charz
104
+ end
105
+ ~~~
106
+
107
+ ### Configuring Existing Flow Methods
108
+
109
+ Now that your interface has defined some routines and profiles, the flow methods needs to be updated to work with an active charz session.
110
+
111
+ Lets take a simplistic example functional flow method defined in `MyApp::Interface`:
112
+
113
+ ~~~ruby
114
+ # V93K SMT7 example
115
+ def func(name, options = {})
116
+ tm = test_methods.ac_tml.ac_test.functional_test
117
+ ts = test_suites.run(name, options)
118
+ ts.test_method = tm
119
+ ts.pattern = 'example'
120
+ flow.test ts, options
121
+ end
122
+ ~~~
123
+
124
+ And now we'll add the ability for this flow method to generate a charz test as well:
125
+
126
+ ~~~ruby
127
+ # V93K SMT7 example
128
+ def func(name, options = {})
129
+ if options[:routine]
130
+ tm = test_methods.ac_tml.ac_test.spec_search
131
+ else
132
+ tm = test_methods.ac_tml.ac_test.functional_test
133
+ end
134
+ ts = test_suites.run(name, options)
135
+ ts.test_method = tm
136
+ ts.pattern = 'example'
137
+
138
+ if options[:routine]
139
+ ts.spec = options[:routine].spec
140
+ ts.min = options[:routine].stop
141
+ ts.max = options[:routine].start
142
+ ts.resolution = options[:routine].res
143
+ end
144
+
145
+ flow.test ts, options
146
+
147
+ unless options[:charz_test]
148
+ insert_charz_tests(options.merge(parent_test_name: name, charz_test: true)) do |options|
149
+ charz_name = :"#{name}_#{charz_routines[options[:current_routine]].name}"
150
+ options[:routine] = charz_routines[options[:current_routine]]
151
+ func(charz_name, options)
152
+ end
153
+ end
154
+ end
155
+ ~~~
156
+
157
+ ### #insert_charz_tests
158
+
159
+ The `insert_charz_tests` method handles everything regarding adding the charz test into the flow except determining the actual name and parameters of the test, which is
160
+ done by the local interface in the block passed to the `insert_charz_tests` method. This method handles:
161
+
162
+ * querying the charz session
163
+ * test placement
164
+ * charz test grouping
165
+ * production test result dependency
166
+ * gate processing (enables, flags)
167
+
168
+ The block that gets passed is yielded the latest options (with id removed if passed for the production test, so it doesn't get re-used for charz tests).
169
+ Routines in the current session are yielded one at a time, with their id being returned in `options[:current_routine]`.
170
+
171
+ #### Company Plugin Oppurtunity
172
+
173
+ If your company is already using a plugin to distribute the definitions of these flow methods, this is a good oppurtunity to add charz variants of those methods
174
+ that take routine as an input. This can really streamline the process, for example if you combine the charz flow methods plugin with a central flow entry point method called by
175
+ all flow methods, then the implementation becomes:
176
+
177
+ ~~~ruby
178
+ def add_to_flow(ts, options = {})
179
+ flow.test ts, options
180
+
181
+ unless options[:charz_test]
182
+ insert_charz_tests(options.merge(parent_test_name: name, charz_test: true)) do |options|
183
+ insert_current_charz_test(options)
184
+ end
185
+ end
186
+ end
187
+ ~~~
188
+
189
+ Where insert_current_charz_test is a method defined in the company charz flow method plugin.
190
+
191
+ ### Flow Usage Examples
192
+
193
+ Now that the interface has charz routines and profiles, lets look at how to use the API within the flow itself:
194
+
195
+ ~~~ruby
196
+ Flow.create(interface: 'MyApp:Interface') do
197
+
198
+ # regular non charz test
199
+ func :my_test1
200
+
201
+ # create charz test variants of my_test2 following the production
202
+ # version of my_test2 using the routines in :my_profile
203
+ charz_on :my_profile do
204
+ func :my_test2
205
+ end
206
+
207
+ # conditional charz enablement
208
+ # besides dut.enable_charz? check, identical to above
209
+ charz_on :my_profile if dut.enable_charz?
210
+ func :my_test3
211
+ charz_off if dut.enable_charz?
212
+
213
+ # override session values at the flow level
214
+ charz_on :my_profile, placement: :eof do
215
+ func :my_test4
216
+ end
217
+
218
+ end
219
+ ~~~
220
+
221
+ % 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.47.0
4
+ version: 0.48.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: 2020-08-05 00:00:00.000000000 Z
11
+ date: 2020-08-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: origen
@@ -16,14 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.44.0
19
+ version: 0.57.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.44.0
26
+ version: 0.57.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: simplecov
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.17'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.17'
41
+ - !ruby/object:Gem::Dependency
42
+ name: simplecov-html
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.10.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.10.0
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: require_all
29
57
  requirement: !ruby/object:Gem::Requirement
@@ -175,6 +203,12 @@ files:
175
203
  - lib/origen_testers/atp_deprecation.rb
176
204
  - lib/origen_testers/basic_test_setups.rb
177
205
  - lib/origen_testers/callback_handlers.rb
206
+ - lib/origen_testers/charz.rb
207
+ - lib/origen_testers/charz/profile.rb
208
+ - lib/origen_testers/charz/routine.rb
209
+ - lib/origen_testers/charz/routines/search_routine.rb
210
+ - lib/origen_testers/charz/routines/shmoo_routine.rb
211
+ - lib/origen_testers/charz/session.rb
178
212
  - lib/origen_testers/command_based_tester.rb
179
213
  - lib/origen_testers/decompiler.rb
180
214
  - lib/origen_testers/decompiler/decompiler_api.rb
@@ -474,6 +508,7 @@ files:
474
508
  - program/_erase_vfy.rb
475
509
  - program/_iv_resources.rb
476
510
  - program/basic_interface.rb
511
+ - program/charz.rb
477
512
  - program/components/_deep_nested.rb
478
513
  - program/components/_prb1_main.rb
479
514
  - program/components/_prb2_main.rb
@@ -509,6 +544,7 @@ files:
509
544
  - templates/origen_guides/pattern/timing.md.erb
510
545
  - templates/origen_guides/pattern/ultraflex.md.erb
511
546
  - templates/origen_guides/pattern/v93k.md.erb
547
+ - templates/origen_guides/program/charz.md.erb
512
548
  - templates/origen_guides/program/code.md.erb
513
549
  - templates/origen_guides/program/custom.md.erb
514
550
  - templates/origen_guides/program/doc.md.erb
@@ -549,7 +585,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
549
585
  version: '0'
550
586
  requirements: []
551
587
  rubyforge_project:
552
- rubygems_version: 2.7.6
588
+ rubygems_version: 2.6.14.4
553
589
  signing_key:
554
590
  specification_version: 4
555
591
  summary: This plugin provides Origen tester models to drive ATE type testers like