origen_testers 0.45.3 → 0.48.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/config/application.rb +1 -0
- data/config/version.rb +2 -2
- data/lib/origen_testers.rb +1 -0
- data/lib/origen_testers/atp/flow.rb +4 -0
- data/lib/origen_testers/charz.rb +421 -0
- data/lib/origen_testers/charz/profile.rb +120 -0
- data/lib/origen_testers/charz/routine.rb +38 -0
- data/lib/origen_testers/charz/routines/search_routine.rb +42 -0
- data/lib/origen_testers/charz/routines/shmoo_routine.rb +62 -0
- data/lib/origen_testers/charz/session.rb +100 -0
- data/lib/origen_testers/igxl_based_tester/base.rb +14 -0
- data/lib/origen_testers/origen_ext/generator/flow.rb +1 -0
- data/lib/origen_testers/smartest_based_tester/base/flow.rb +1 -1
- data/lib/origen_testers/smartest_based_tester/base/limits_file.rb +7 -3
- data/lib/origen_testers/smartest_based_tester/base/pattern_master.rb +2 -2
- data/lib/origen_testers/smartest_based_tester/base/test_method.rb +7 -1
- data/lib/origen_testers/smartest_based_tester/base/test_methods/base_tml.rb +18 -7
- data/lib/origen_testers/smartest_based_tester/base/test_methods/dc_tml.rb +1 -1
- data/lib/origen_testers/smartest_based_tester/base/variables_file.rb +16 -12
- data/lib/origen_testers/smartest_based_tester/v93k/templates/vars.tf.erb +10 -6
- data/lib/origen_testers/test/interface.rb +80 -0
- data/pattern/tester_overlay_no_start.rb +41 -0
- data/program/charz.rb +48 -0
- data/program/prb1.rb +1 -1
- data/templates/origen_guides/pattern/ultraflex.md.erb +20 -0
- data/templates/origen_guides/program/charz.md.erb +221 -0
- 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
|
-
|
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
|
-
|
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
|
-
|
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',
|
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
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
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
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
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
|
7
|
-
%
|
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
|
-
%
|
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
|
19
|
-
%
|
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
|
-
%
|
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
|
data/program/charz.rb
ADDED
@@ -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
|
data/program/prb1.rb
CHANGED
@@ -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
|