origen_testers 0.47.0 → 0.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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