origen_testers 0.45.3 → 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.
Files changed (28) hide show
  1. checksums.yaml +5 -5
  2. data/config/application.rb +1 -0
  3. data/config/version.rb +2 -2
  4. data/lib/origen_testers.rb +1 -0
  5. data/lib/origen_testers/atp/flow.rb +4 -0
  6. data/lib/origen_testers/charz.rb +421 -0
  7. data/lib/origen_testers/charz/profile.rb +120 -0
  8. data/lib/origen_testers/charz/routine.rb +38 -0
  9. data/lib/origen_testers/charz/routines/search_routine.rb +42 -0
  10. data/lib/origen_testers/charz/routines/shmoo_routine.rb +62 -0
  11. data/lib/origen_testers/charz/session.rb +100 -0
  12. data/lib/origen_testers/igxl_based_tester/base.rb +14 -0
  13. data/lib/origen_testers/origen_ext/generator/flow.rb +1 -0
  14. data/lib/origen_testers/smartest_based_tester/base/flow.rb +1 -1
  15. data/lib/origen_testers/smartest_based_tester/base/limits_file.rb +7 -3
  16. data/lib/origen_testers/smartest_based_tester/base/pattern_master.rb +2 -2
  17. data/lib/origen_testers/smartest_based_tester/base/test_method.rb +7 -1
  18. data/lib/origen_testers/smartest_based_tester/base/test_methods/base_tml.rb +18 -7
  19. data/lib/origen_testers/smartest_based_tester/base/test_methods/dc_tml.rb +1 -1
  20. data/lib/origen_testers/smartest_based_tester/base/variables_file.rb +16 -12
  21. data/lib/origen_testers/smartest_based_tester/v93k/templates/vars.tf.erb +10 -6
  22. data/lib/origen_testers/test/interface.rb +80 -0
  23. data/pattern/tester_overlay_no_start.rb +41 -0
  24. data/program/charz.rb +48 -0
  25. data/program/prb1.rb +1 -1
  26. data/templates/origen_guides/pattern/ultraflex.md.erb +20 -0
  27. data/templates/origen_guides/program/charz.md.erb +221 -0
  28. metadata +43 -5
@@ -85,7 +85,13 @@ module OrigenTesters
85
85
  end
86
86
  # Finally set any initial values that have been supplied
87
87
  options[:attrs].each do |k, v|
88
- send("#{k}=", v) if respond_to?("#{k}=")
88
+ accessor = "#{k}="
89
+ if respond_to?(accessor)
90
+ send(accessor, v)
91
+ else
92
+ accessor = "#{k.to_s.underscore}="
93
+ send(accessor, v) if respond_to?(accessor)
94
+ end
89
95
  end
90
96
  end
91
97
 
@@ -13,14 +13,14 @@ module OrigenTesters
13
13
 
14
14
  def method_missing(method, *args, &block)
15
15
  if definitions[method]
16
- m = platform::TestMethod.new methods: definitions[method].dup,
17
- attrs: (args.first || {}),
18
- type: method,
19
- library: self
20
- test_methods.add(m)
21
- m
16
+ instantiate_test_method(method, args)
22
17
  else
23
- super
18
+ method = method.to_s.underscore.to_sym
19
+ if definitions[method]
20
+ instantiate_test_method(method, args)
21
+ else
22
+ super
23
+ end
24
24
  end
25
25
  end
26
26
 
@@ -31,6 +31,17 @@ module OrigenTesters
31
31
  def definitions
32
32
  @definitions || self.class::TEST_METHODS
33
33
  end
34
+
35
+ private
36
+
37
+ def instantiate_test_method(method, args)
38
+ m = platform::TestMethod.new methods: definitions[method].dup,
39
+ attrs: (args.first || {}),
40
+ type: method,
41
+ library: self
42
+ test_methods.add(m)
43
+ m
44
+ end
34
45
  end
35
46
  end
36
47
  end
@@ -9,7 +9,7 @@ module OrigenTesters
9
9
  test_current: [:current, 10.uA],
10
10
  settling_time: [:time, 1.ms],
11
11
  measurement_mode: [:string, 'PPMUpar', %w(PPMUpar ProgLoad)],
12
- polarity: [:string, 'SPOL', ['SPOL' 'BPOL']],
12
+ polarity: [:string, 'SPOL', %w(SPOL BPOL)],
13
13
  precharge_to_zero_vol: [:string, 'ON', %w(ON OFF)],
14
14
  test_name: [:string, 'passVolt_mv'],
15
15
  output: [:string, 'None', %w(None ReportUI ShowFailOnly)]
@@ -6,13 +6,13 @@ module OrigenTesters
6
6
  include OrigenTesters::Generator
7
7
 
8
8
  attr_reader :variables
9
- attr_accessor :filename, :id
9
+ attr_accessor :filename, :id, :subdirectory
10
10
 
11
11
  def initialize(options = {})
12
12
  end
13
13
 
14
14
  def subdirectory
15
- 'testflow/mfh.testflow.setup'
15
+ @subdirectory ||= 'testflow/mfh.testflow.setup'
16
16
  end
17
17
 
18
18
  def add_variables(vars)
@@ -35,21 +35,25 @@ module OrigenTesters
35
35
 
36
36
  # What SMT7 calls a flag
37
37
  def flags
38
- (variables[:all][:referenced_enables] + variables[:all][:set_enables]).uniq.sort do |x, y|
39
- x = x[0] if x.is_a?(Array)
40
- y = y[0] if y.is_a?(Array)
41
- # Need to use strings for the comparison as some flags can be a string and some a symbol
42
- x.to_s <=> y.to_s
38
+ if variables
39
+ (variables[:all][:referenced_enables] + variables[:all][:set_enables]).uniq.sort do |x, y|
40
+ x = x[0] if x.is_a?(Array)
41
+ y = y[0] if y.is_a?(Array)
42
+ # Need to use strings for the comparison as some flags can be a string and some a symbol
43
+ x.to_s <=> y.to_s
44
+ end
43
45
  end
44
46
  end
45
47
 
46
48
  # What SMT7 calls a declaration
47
49
  def declarations
48
- (variables[:all][:jobs] + variables[:all][:referenced_flags] + variables[:all][:set_flags]).uniq.sort do |x, y|
49
- x = x[0] if x.is_a?(Array)
50
- y = y[0] if y.is_a?(Array)
51
- # Need to use strings for the comparison as some declarations can be a string and some a symbol
52
- x.to_s <=> y.to_s
50
+ if variables
51
+ (variables[:all][:jobs] + variables[:all][:referenced_flags] + variables[:all][:set_flags]).uniq.sort do |x, y|
52
+ x = x[0] if x.is_a?(Array)
53
+ y = y[0] if y.is_a?(Array)
54
+ # Need to use strings for the comparison as some declarations can be a string and some a symbol
55
+ x.to_s <=> y.to_s
56
+ end
53
57
  end
54
58
  end
55
59
 
@@ -3,11 +3,13 @@ language_revision = 1;
3
3
 
4
4
  declarations
5
5
 
6
- % declarations.each do |var|
7
- % if var.is_a?(Array)
6
+ % if declarations
7
+ % declarations.each do |var|
8
+ % if var.is_a?(Array)
8
9
  @<%= var[0].to_s %> = <%= var[1].is_a?(String) || var[1].is_a?(Symbol) ? "\"#{var[1]}\"" : var[1] %>;
9
- % else
10
+ % else
10
11
  @<%= var.to_s %> = 0;
12
+ % end
11
13
  % end
12
14
  % end
13
15
 
@@ -15,11 +17,13 @@ end
15
17
  -----------------------------------------------------------------
16
18
  flags
17
19
 
18
- % flags.each do |var|
19
- % if var.is_a?(Array)
20
+ % if flags
21
+ % flags.each do |var|
22
+ % if var.is_a?(Array)
20
23
  user <%= var[0].to_s %> = <%= var[1].is_a?(String) || var[1].is_a?(Symbol) ? "\"#{var[1]}\"" : var[1] %>;
21
- % else
24
+ % else
22
25
  user <%= var.to_s %> = 0;
26
+ % end
23
27
  % end
24
28
  % end
25
29
 
@@ -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,41 @@
1
+ Pattern.create(name: "test_overlay_no_start") do
2
+ tester.overlay_style = :digsrc
3
+ # increase coverage by changing tdi dig src settings
4
+ tester.source_memory :digsrc do |mem|
5
+ mem.pin :tdi, size: 32
6
+ end
7
+ cc 'should get a repeat count added to this vector for digsrc start minimum distance'
8
+ tester.cycle
9
+
10
+ dut.pin(:tclk).drive(1)
11
+ dut.pin(:tdi).drive(1)
12
+ dut.pin(:tdo).assert(1)
13
+ dut.pin(:tms).drive(1)
14
+
15
+ cc 'should get a repeat 5 vector'
16
+ tester.cycle repeat: 5
17
+
18
+ tester.digsrc_skip_start :tdi_a if tester.ultraflex?
19
+ tester.digsrc_skip_start :pa if tester.ultraflex?
20
+
21
+ cc 'should get a send microcode and 1 cycle with D'
22
+ tester.cycle overlay: {overlay_str: 'dummy_str', pins: dut.pin(:tdi_a)}
23
+ cc 'should get a cycle with D and no send'
24
+ tester.cycle overlay: {overlay_str: 'dummy_str', pins: dut.pin(:tdi_a), change_data: false}
25
+ cc 'regular cycle with no D or send'
26
+ tester.cycle
27
+
28
+ cc 'cycle with 001 on pa'
29
+ dut.pin(:pa).drive!(1)
30
+ cc 'send microcode followed by DDD on pa'
31
+ dut.pin(:pa).drive(0)
32
+ tester.cycle overlay: {overlay_str: "dummy_str", pins: dut.pin(:pa)}
33
+ cc 'cycle with 001 on pa'
34
+ dut.pin(:pa).drive!(1)
35
+ cc 'send microcode, DDD on pa with repeat 5 (will send 5 sets of data)'
36
+ dut.pin(:pa).drive(0)
37
+ tester.cycle repeat: 5, overlay: {overlay_str: "dummy_str", pins: dut.pin(:pa)}
38
+ cc 'cycle with 001 on pa'
39
+ dut.pin(:pa).drive!(1)
40
+
41
+ end
@@ -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
@@ -13,7 +13,7 @@ Flow.create interface: 'OrigenTesters::Test::Interface', flow_description: 'Prob
13
13
  import 'test' # import top-level test.rb directly, note that Flow.create options of sub-flow will be ignored!
14
14
 
15
15
  # Test that a reference to a deeply nested test works (mainly for SMT8)
16
- test :on_deep_1, if_failed: :deep_test
16
+ test :on_deep_1, if_failed: :deep_test, test_text: "some_custom_text"
17
17
 
18
18
  pass 1, description: "Good die!", softbin: 1
19
19
  end
@@ -7,4 +7,24 @@ automatically to any supported platform.
7
7
  There are no significant APIs in this category currently, therefore refer to the
8
8
  [Common Pattern API](<%= path "guides/pattern/common" %>) which can fully target the UltraFLEX.
9
9
 
10
+ ### DigSrc
11
+
12
+ UltraFlex supports <code>:digsrc</code> as a <code>tester.overlay_style</code> set like this:
13
+
14
+ ~~~ruby
15
+ tester.overlay_style = :digsrc
16
+ ~~~
17
+
18
+ By default Origen will automatically place the digsrc start opcode at the beginning of the resulting pattern
19
+ when <code>:digsrc</code> overlay is used. In some cases (like when the pattern is used in a pattern set that has already started
20
+ the instrument in a previous pattern, or possibly in svm_patterns) this behavior is undesirable.
21
+
22
+ The insertion of this start opcode can be disabled by placing the following code **before** any overlay operations
23
+ for a given pin.
24
+
25
+ ~~~ruby
26
+ tester.digsrc_skip_start :pin_or_group_name if tester.ultraflex?
27
+ # Overlay operations can happen after this point
28
+ ~~~
29
+
10
30
  % 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