origen_testers 0.51.4 → 0.52.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/config/commands.rb +1 -1
- data/config/version.rb +2 -2
- data/lib/origen_testers/atp/flow.rb +39 -0
- data/lib/origen_testers/atp/flow_api.rb +2 -2
- data/lib/origen_testers/smartest_based_tester/base/flow.rb +61 -17
- data/lib/origen_testers/smartest_based_tester/base/generator.rb +5 -1
- data/lib/origen_testers/smartest_based_tester/base/processors/extract_flow_vars.rb +18 -1
- data/lib/origen_testers/smartest_based_tester/base/test_method.rb +25 -3
- data/lib/origen_testers/smartest_based_tester/base/variables_file.rb +1 -1
- data/lib/origen_testers/smartest_based_tester/base.rb +28 -4
- data/lib/origen_testers/smartest_based_tester/v93k_smt8/flow.rb +69 -5
- data/lib/origen_testers/smartest_based_tester/v93k_smt8/limits_workbook.rb +28 -26
- data/lib/origen_testers/smartest_based_tester/v93k_smt8/templates/template.flow.erb +3 -0
- data/lib/origen_testers/smartest_based_tester/v93k_smt8/test_suite.rb +111 -4
- data/lib/origen_testers/stil_based_tester/base.rb +77 -24
- data/lib/origen_testers/test/custom_test_interface.rb +36 -2
- data/lib/origen_testers/test/interface.rb +123 -0
- data/program/components/_prb1_main.rb +9 -0
- data/program/custom_tests.rb +3 -0
- data/program/flow_control.rb +37 -8
- data/templates/origen_guides/pattern/stil.md.erb +17 -0
- data/templates/origen_guides/program/flowapi.md.erb +26 -1
- data/templates/origen_guides/program/v93k.md.erb +14 -0
- data/templates/origen_guides/program/v93ksmt8.md.erb +25 -0
- metadata +3 -3
@@ -7,11 +7,19 @@ module OrigenTesters
|
|
7
7
|
%w(
|
8
8
|
name
|
9
9
|
comment
|
10
|
+
bypass
|
10
11
|
|
11
12
|
test_method
|
12
13
|
|
13
14
|
pattern
|
14
15
|
specification
|
16
|
+
seq
|
17
|
+
burst
|
18
|
+
|
19
|
+
spec_namespace
|
20
|
+
spec_path
|
21
|
+
seq_namespace
|
22
|
+
seq_path
|
15
23
|
)
|
16
24
|
|
17
25
|
ALIASES = {
|
@@ -22,6 +30,7 @@ module OrigenTesters
|
|
22
30
|
DEFAULTS = {
|
23
31
|
}
|
24
32
|
|
33
|
+
NO_STRING_TYPES = [:list_strings, :list_classes, :class]
|
25
34
|
# Generate accessors for all attributes and their aliases
|
26
35
|
ATTRS.each do |attr|
|
27
36
|
if attr == 'name' || attr == 'pattern'
|
@@ -42,24 +51,122 @@ module OrigenTesters
|
|
42
51
|
end
|
43
52
|
|
44
53
|
def lines
|
54
|
+
# Initialize path setting
|
55
|
+
# prefix = test method library prefix expectations
|
56
|
+
# self.spec_namespace = instance override from the tester specification namespace
|
57
|
+
# self.seq_namespace = instance override from the tester sequence namespace
|
58
|
+
# self.spec_path = instance override from the tester specification path
|
59
|
+
# self.seq_path = instance override from the tester sequence path
|
60
|
+
if Origen.interface.respond_to? :custom_smt8_prefix
|
61
|
+
prefix = Origen.interface.custom_smt8_prefix
|
62
|
+
else
|
63
|
+
prefix = 'measurement.'
|
64
|
+
end
|
65
|
+
spec_namespace = self.spec_namespace || tester.package_namespace
|
66
|
+
spec_path = self.spec_path || tester.spec_path
|
67
|
+
seq_namespace = self.seq_namespace || tester.package_namespace
|
68
|
+
seq_path = self.seq_path || tester.seq_path
|
45
69
|
l = []
|
46
|
-
l << "suite #{name} calls #{test_method.klass} {"
|
70
|
+
l << "suite #{name} calls #{test_method.klass[0].downcase + test_method.klass[1..-1]} {"
|
47
71
|
if pattern && !pattern.to_s.empty?
|
48
|
-
l << "
|
72
|
+
l << " #{prefix}pattern = setupRef(#{seq_namespace}.patterns.#{pattern});"
|
73
|
+
end
|
74
|
+
if seq && !seq.to_s.empty?
|
75
|
+
l << " #{prefix}operatingSequence = setupRef(#{seq_namespace}.#{seq_path}.#{seq});"
|
76
|
+
end
|
77
|
+
if burst && !burst.to_s.empty?
|
78
|
+
l << " #{prefix}operatingSequence = setupRef(#{seq_namespace}.#{seq_path}.#{burst});"
|
49
79
|
end
|
50
80
|
if specification && !specification.to_s.empty?
|
51
|
-
l << "
|
81
|
+
l << " #{prefix}specification = setupRef(#{spec_namespace}.#{spec_path}.#{specification});"
|
82
|
+
end
|
83
|
+
if bypass
|
84
|
+
l << ' bypass = true;'
|
52
85
|
end
|
53
86
|
test_method.sorted_parameters.each do |param|
|
54
87
|
name = param[0]
|
55
88
|
unless name.is_a?(String)
|
56
89
|
name = name.to_s[0] == '_' ? name.to_s.camelize(:upper) : name.to_s.camelize(:lower)
|
57
90
|
end
|
58
|
-
|
91
|
+
if [true, false].include? test_method.format(param[0])
|
92
|
+
l << " #{name} = #{wrap_if_string(test_method.format(param[0]))};"
|
93
|
+
elsif NO_STRING_TYPES.include?(param.last) && test_method.format(param[0]).is_a?(String) && !test_method.format(param[0]).empty?
|
94
|
+
l << " #{name} = #{test_method.format(param[0])};"
|
95
|
+
elsif test_method.format(param[0]).is_a?(String) && !test_method.format(param[0]).empty?
|
96
|
+
l << " #{name} = #{wrap_if_string(test_method.format(param[0]))};"
|
97
|
+
elsif param.last.is_a? Hash
|
98
|
+
if !test_method.format(name).nil? && !test_method.format(name).is_a?(Hash)
|
99
|
+
fail "#{name} parameter structure requires a Hash but value provided is #{test_method.format(name).class}"
|
100
|
+
elsif test_method.format(name).nil? && tester.print_all_params
|
101
|
+
l = add_nested_params(l, name, 'param0', {}, param.last, 1)
|
102
|
+
elsif test_method.format(name).nil?
|
103
|
+
# Do nothing
|
104
|
+
else
|
105
|
+
test_method.format(name).each do |key, meta_hash|
|
106
|
+
l = add_nested_params(l, name, key, meta_hash, param.last, 1)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
59
110
|
end
|
60
111
|
l << '}'
|
61
112
|
l
|
62
113
|
end
|
114
|
+
|
115
|
+
# rubocop:disable Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters.
|
116
|
+
def add_nested_params(l, name, key, value_hash, nested_params, nested_loop_count)
|
117
|
+
nested_params_accepted_keys = []
|
118
|
+
skip_keys = []
|
119
|
+
unless value_hash.nil?
|
120
|
+
unless value_hash.is_a?(Hash)
|
121
|
+
fail "Provided value to nested params was not a Hash. Instead the value was #{value_hash.class}"
|
122
|
+
end
|
123
|
+
dynamic_spacing = ' ' * (4 * nested_loop_count)
|
124
|
+
l << "#{dynamic_spacing}#{name}[#{key}] = {" unless name.nil?
|
125
|
+
nested_params.each do |nested_param|
|
126
|
+
# Guarentee hash is using all symbol keys
|
127
|
+
# Since we cannot guarentee ruby version is greater than 2.5, we have to use an older syntax to
|
128
|
+
value_hash = value_hash.inject({}) { |memo, (k, v)| memo[k.to_sym] = v; memo }
|
129
|
+
nested_key = nested_param.first.to_sym
|
130
|
+
nested_key_underscore = nested_key.to_s.underscore.to_sym
|
131
|
+
nested_params_accepted_keys << nested_key
|
132
|
+
nested_params_accepted_keys << nested_key_underscore
|
133
|
+
# We cannot create nested member functions with aliases
|
134
|
+
# Requirement for hash parameter passing is to pass one of the key types and not both
|
135
|
+
if value_hash.keys.include?(nested_key) &&
|
136
|
+
value_hash.keys.include?(nested_key_underscore) && nested_key != nested_key_underscore
|
137
|
+
fail 'You are using a hash based test method and provided both the parameter name and alias name.'
|
138
|
+
end
|
139
|
+
nested_key = nested_key_underscore if value_hash.keys.include?(nested_key_underscore)
|
140
|
+
if nested_param.last.first.is_a?(Hash) && value_hash[nested_key].is_a?(Hash)
|
141
|
+
value_hash[nested_key].each do |inner_key, inner_meta_hash|
|
142
|
+
l = add_nested_params(l, nested_param.first, inner_key, value_hash.dig(nested_key, inner_key), nested_param.last.first, nested_loop_count + 1)
|
143
|
+
skip_keys << nested_key
|
144
|
+
end
|
145
|
+
elsif nested_param.last.first.is_a?(Hash) && tester.print_all_params
|
146
|
+
l = add_nested_params(l, nested_param.first, 'param0', {}, nested_param.last.first, nested_loop_count + 1)
|
147
|
+
end
|
148
|
+
type = nested_param.last.first
|
149
|
+
if NO_STRING_TYPES.include?(nested_param.last.first) && value_hash[nested_key] && !skip_keys.include?(nested_key)
|
150
|
+
l << " #{dynamic_spacing}#{nested_param.first} = #{test_method.handle_val_type(value_hash[nested_key], type, nested_param.first)};"
|
151
|
+
elsif value_hash[nested_key] && !skip_keys.include?(nested_key)
|
152
|
+
l << " #{dynamic_spacing}#{nested_param.first} = #{wrap_if_string(test_method.handle_val_type(value_hash[nested_key], type, nested_param.first))};"
|
153
|
+
elsif NO_STRING_TYPES.include?(nested_param.last.first) && !nested_param.last.last.is_a?(Hash) && tester.print_all_params && !skip_keys.include?(nested_key)
|
154
|
+
l << " #{dynamic_spacing}#{nested_param.first} = #{test_method.handle_val_type(nested_param.last.last, type, nested_param.first)};"
|
155
|
+
elsif !nested_param.last.last.is_a?(Hash) && tester.print_all_params && !skip_keys.include?(nested_key)
|
156
|
+
l << " #{dynamic_spacing}#{nested_param.first} = #{wrap_if_string(test_method.handle_val_type(nested_param.last.last, type, nested_param.first))};"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
l << "#{dynamic_spacing}};" unless name.nil?
|
160
|
+
# Sanity check there are not overpassed parameters
|
161
|
+
value_hash.keys.each do |nested_key|
|
162
|
+
unless nested_params_accepted_keys.include?(nested_key.to_sym)
|
163
|
+
fail "You provided a parameter \'#{nested_key}\' that was not an accepted parameter to the hash parameter \'#{name}\'"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
l
|
168
|
+
end
|
169
|
+
# rubocop:enable Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters.
|
63
170
|
end
|
64
171
|
end
|
65
172
|
end
|
@@ -15,6 +15,7 @@ module OrigenTesters
|
|
15
15
|
@min_repeat_loop = 2
|
16
16
|
@pat_extension = 'stil'
|
17
17
|
@compress = true
|
18
|
+
@use_timing_equations = options[:use_timing_equations]
|
18
19
|
|
19
20
|
# @support_repeat_previous = true
|
20
21
|
@match_entries = 10
|
@@ -93,12 +94,29 @@ module OrigenTesters
|
|
93
94
|
output_group_definition(flattened_ordered_pins, "#{ordered_pins_name || 'ALL'}")
|
94
95
|
microcode '}'
|
95
96
|
|
97
|
+
# output the period category specs
|
98
|
+
if @use_timing_equations
|
99
|
+
microcode ''
|
100
|
+
microcode 'Spec {'
|
101
|
+
microcode " Category c_#{@pattern_name} {"
|
102
|
+
(@wavesets || []).each_with_index do |w, i|
|
103
|
+
microcode " period_#{w[:name]} = '#{w[:period]}ns';"
|
104
|
+
end
|
105
|
+
microcode ' }'
|
106
|
+
microcode '}'
|
107
|
+
end
|
108
|
+
|
96
109
|
microcode ''
|
97
110
|
microcode "Timing t_#{@pattern_name} {"
|
98
111
|
(@wavesets || []).each_with_index do |w, i|
|
99
112
|
microcode '' if i != 0
|
100
113
|
microcode " WaveformTable Waveset#{i + 1} {"
|
101
|
-
|
114
|
+
period_var = "period_#{w[:name]}"
|
115
|
+
if @use_timing_equations
|
116
|
+
microcode " Period '#{period_var}';"
|
117
|
+
else
|
118
|
+
microcode " Period '#{w[:period]}ns';"
|
119
|
+
end
|
102
120
|
microcode ' Waveforms {'
|
103
121
|
w[:lines].each do |line|
|
104
122
|
microcode " #{line}"
|
@@ -115,6 +133,7 @@ module OrigenTesters
|
|
115
133
|
|
116
134
|
microcode ''
|
117
135
|
microcode "PatternExec e_#{@pattern_name} {"
|
136
|
+
microcode " Category c_#{@pattern_name};" if @use_timing_equations
|
118
137
|
microcode " Timing t_#{@pattern_name};"
|
119
138
|
microcode " PatternBurst b_#{@pattern_name};"
|
120
139
|
microcode '}'
|
@@ -131,6 +150,27 @@ module OrigenTesters
|
|
131
150
|
end
|
132
151
|
|
133
152
|
def set_timeset(t, period_in_ns = nil)
|
153
|
+
# check for period size override from the app if performing convert command
|
154
|
+
if Origen.current_command == 'convert'
|
155
|
+
listeners = Origen.listeners_for(:convert_command_set_period_in_ns)
|
156
|
+
if listeners.empty?
|
157
|
+
unless @call_back_message_displayed
|
158
|
+
Origen.log.warn 'STIL output is generated using "origen convert" with no timeset period callback method defined. Default period size will be used.'
|
159
|
+
Origen.log.info 'stil tester implements a callback for setting the timeset period size when converting a pattern to stil format'
|
160
|
+
Origen.log.info 'to use the callback feature add the following define to your app in config/application.rb'
|
161
|
+
Origen.log.info ' def convert_command_set_period_in_ns(timeset_name)'
|
162
|
+
Origen.log.info ' return 25 if timeset_name == "timeset0"'
|
163
|
+
Origen.log.info ' return 30 if timeset_name == "timeset1"'
|
164
|
+
Origen.log.info ' 40'
|
165
|
+
Origen.log.info ' end'
|
166
|
+
@call_back_message_displayed = true
|
167
|
+
end
|
168
|
+
else
|
169
|
+
listeners.each do |listener|
|
170
|
+
period_in_ns = listener.convert_command_set_period_in_ns(t)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
134
174
|
super
|
135
175
|
if pattern_only
|
136
176
|
# Why does D10 not include this?
|
@@ -140,25 +180,32 @@ module OrigenTesters
|
|
140
180
|
wave_number = nil
|
141
181
|
@wavesets.each_with_index do |w, i|
|
142
182
|
if w[:name] == timeset.name && w[:period] = timeset.period_in_ns
|
143
|
-
wave_number = i
|
183
|
+
wave_number = i + 1 # bug fix wave numbers are 1 more than their index #
|
144
184
|
end
|
145
185
|
end
|
146
186
|
unless wave_number
|
147
187
|
lines = []
|
188
|
+
period_var = "period_#{timeset.name}"
|
148
189
|
flattened_ordered_pins.each do |pin|
|
149
190
|
if pin.direction == :input || pin.direction == :io
|
150
191
|
line = "#{pin.name} { 01 { "
|
151
192
|
wave = pin.drive_wave if tester.timeset.dut_timeset
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
193
|
+
if wave
|
194
|
+
(@use_timing_equations ? wave.events : wave.evaluated_events).each do |t, v|
|
195
|
+
if @use_timing_equations
|
196
|
+
line << "'#{t.to_s.gsub('period', period_var)}' "
|
197
|
+
else
|
198
|
+
line << "'#{t}ns' "
|
199
|
+
end
|
200
|
+
if v == 0
|
201
|
+
line << 'D'
|
202
|
+
elsif v == 1
|
203
|
+
line << 'U'
|
204
|
+
else
|
205
|
+
line << 'D/U'
|
206
|
+
end
|
207
|
+
line << '; '
|
160
208
|
end
|
161
|
-
line << '; '
|
162
209
|
end
|
163
210
|
line << '}}'
|
164
211
|
lines << line
|
@@ -166,20 +213,26 @@ module OrigenTesters
|
|
166
213
|
if pin.direction == :output || pin.direction == :io
|
167
214
|
line = "#{pin.name} { LHX { "
|
168
215
|
wave = pin.compare_wave if tester.timeset.dut_timeset
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
216
|
+
if wave
|
217
|
+
(@use_timing_equations ? wave.events : wave.evaluated_events).each_with_index do |tv, i|
|
218
|
+
t, v = *tv
|
219
|
+
if i == 0 && t != 0
|
220
|
+
line << "'0ns' X; "
|
221
|
+
end
|
222
|
+
if @use_timing_equations
|
223
|
+
line << "'#{t.to_s.gsub('period', period_var)}' "
|
224
|
+
else
|
225
|
+
line << "'#{t}ns' "
|
226
|
+
end
|
227
|
+
if v == 0
|
228
|
+
line << 'L'
|
229
|
+
elsif v == 0
|
230
|
+
line << 'H'
|
231
|
+
else
|
232
|
+
line << 'L/H/X'
|
233
|
+
end
|
234
|
+
line << '; '
|
181
235
|
end
|
182
|
-
line << '; '
|
183
236
|
end
|
184
237
|
line << '}}'
|
185
238
|
lines << line
|
@@ -33,11 +33,23 @@ module OrigenTesters
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
+
def custom_hash(name, options = {})
|
37
|
+
name = "custom_hash_#{name}".to_sym
|
38
|
+
if tester.v93k? && tester.smt8?
|
39
|
+
ti = test_methods.my_tml.test_hash
|
40
|
+
ti.my_arg_hash = {
|
41
|
+
my_param_name: {
|
42
|
+
my_arg2: 1
|
43
|
+
}
|
44
|
+
}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
36
48
|
private
|
37
49
|
|
38
50
|
def add_custom_tml
|
39
51
|
add_tml :my_tml,
|
40
|
-
test_a:
|
52
|
+
test_a: {
|
41
53
|
# Parameters can be defined with an underscored symbol as the name, this can be used
|
42
54
|
# if the C++ implementation follows the standard V93K convention of calling the attribute
|
43
55
|
# the camel cased version, starting with a lower-cased letter, i.e. 'testerState' in this
|
@@ -79,10 +91,32 @@ module OrigenTesters
|
|
79
91
|
end
|
80
92
|
}
|
81
93
|
},
|
82
|
-
test_b:
|
94
|
+
test_b: {
|
83
95
|
render_limits_in_tf: false,
|
84
96
|
my_arg0: [:string, ''],
|
85
97
|
my_arg1: [:string, 'b_default_value']
|
98
|
+
},
|
99
|
+
test_hash: {
|
100
|
+
# Parameters can be defined with an underscored symbol as the name, this can be used
|
101
|
+
# if the C++ implementation follows the standard V93K convention of calling the attribute
|
102
|
+
# the camel cased version, starting with a lower-cased letter, i.e. 'testerState' in this
|
103
|
+
# first example.
|
104
|
+
# The attribute definition has two required parameters, the type and the default value.
|
105
|
+
# The type can be :string, :current, :voltage, :time, :frequency, or :integer
|
106
|
+
# An optional 3rd parameter can be supplied to give an array of allowed values. If supplied,
|
107
|
+
# Origen will raise an error upon an attempt to set it to an unlisted value.
|
108
|
+
tester_state: [:string, 'CONNECTED', %w(CONNECTED UNCHANGED)],
|
109
|
+
test_name: [:string, 'Functional'],
|
110
|
+
my_list_string: [:list_strings, %w(E1 E2)],
|
111
|
+
my_list_class: [:list_classes, %w(E1 E2)],
|
112
|
+
my_arg_hash: [{
|
113
|
+
my_arg0: [:string, ''],
|
114
|
+
my_arg1: [:string, 'a_default_value'],
|
115
|
+
my_arg2: [:integer, 0],
|
116
|
+
my_arg2: [:list_strings, %w(E1 E2)],
|
117
|
+
my_arg3: [:list_classes, %w(E1 E2)]
|
118
|
+
}]
|
119
|
+
# Define any methods you want the test method to have
|
86
120
|
}
|
87
121
|
end
|
88
122
|
|
@@ -12,6 +12,67 @@ module OrigenTesters
|
|
12
12
|
def initialize(options = {})
|
13
13
|
@environment = options[:environment]
|
14
14
|
add_charz
|
15
|
+
add_my_tml if tester.v93k?
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_my_tml
|
19
|
+
add_tml :my_hash_tml,
|
20
|
+
class_name: 'MyTmlHashNamespace',
|
21
|
+
|
22
|
+
# Here is a test definition.
|
23
|
+
# The identifier should be lower-cased and underscored, in-keeping with Ruby naming conventions.
|
24
|
+
# By default the class name will be the camel-cased version of this identifier, so 'myTest' in
|
25
|
+
# this case.
|
26
|
+
my_hash_test: {
|
27
|
+
# [OPTIONAL] The C++ test method class name can be overridden from the default like this:
|
28
|
+
class_name: 'MyHashExampleClass',
|
29
|
+
# [OPTIONAL] If the test method does not require a definition in the testmethodlimits section
|
30
|
+
# of the .tf file, you can suppress like this:
|
31
|
+
# render_limits_in_file: false,
|
32
|
+
# Parameters can be defined with an underscored symbol as the name, this can be used
|
33
|
+
# if the C++ implementation follows the standard V93K convention of calling the attribute
|
34
|
+
# the camel cased version, starting with a lower-cased letter, i.e. 'testerState' in this
|
35
|
+
# first example.
|
36
|
+
# The attribute definition has two required parameters, the type and the default value.
|
37
|
+
# The type can be :string, :current, :voltage, :time, :frequency, integer, :double or :boolean
|
38
|
+
pin_list: [:string, ''],
|
39
|
+
samples: [:integer, 1],
|
40
|
+
precharge_voltage: [:voltage, 0],
|
41
|
+
settling_time: [:time, 0],
|
42
|
+
# An optional parameter that sets the limits name in the 'testmethodlimits' section
|
43
|
+
# of the generated .tf file. Defaults to 'Functional' if not provided.
|
44
|
+
test_name: [:string, 'HashExample'],
|
45
|
+
# An optional 3rd parameter can be supplied to provide an array of allowed values. If supplied,
|
46
|
+
# Origen will raise an error upon an attempt to set it to an unlisted value.
|
47
|
+
tester_state: [:string, 'CONNECTED', %w(CONNECTED UNCHANGED DISCONNECTED)],
|
48
|
+
force_mode: [:string, 'VOLT', %w(VOLT CURR)],
|
49
|
+
# The name of another parameter can be supplied as the type argument, meaning that the type
|
50
|
+
# here will be either :current or :voltage depending on the value of :force_mode
|
51
|
+
# force_value: [:force_mode, 3800.mV],
|
52
|
+
# In cases where the C++ library has deviated from standard attribute naming conventions
|
53
|
+
# (camel-cased with lower cased first character), the absolute attribute name can be given
|
54
|
+
# as a string.
|
55
|
+
# The Origen accessor for these will be the underscored version, with '.' characters
|
56
|
+
# converted to underscores e.g. tm.an_unusual_name
|
57
|
+
'hashParameter': [{ param_name0: [:string, 'NO'], param_name1: [:integer, 0] }],
|
58
|
+
'hashParameter2': [{ param_name0: [:string, 'NO'], param_name1: [:integer, 0] }],
|
59
|
+
'nestedHashParameter': [{
|
60
|
+
param_name0: [:string, ''],
|
61
|
+
param_list_strings: [:list_strings, %w(E1 E2)],
|
62
|
+
param_list_classes: [:list_classes, %w(E1 E2)],
|
63
|
+
param_name1: [{
|
64
|
+
param_name0: [:integer, 0],
|
65
|
+
param_list_strings: [:list_strings, %w(E1 E2)],
|
66
|
+
param_list_classes: [:list_classes, %w(E1 E2)]
|
67
|
+
}]
|
68
|
+
}],
|
69
|
+
'nestedHashParameter2': [{
|
70
|
+
param_name0: [:string, ''],
|
71
|
+
param_name1: [{
|
72
|
+
param_name0: [:integer, 0]
|
73
|
+
}]
|
74
|
+
}]
|
75
|
+
}
|
15
76
|
end
|
16
77
|
|
17
78
|
def add_charz
|
@@ -218,6 +279,68 @@ module OrigenTesters
|
|
218
279
|
end
|
219
280
|
end
|
220
281
|
|
282
|
+
def my_hash_test(name, options = {})
|
283
|
+
number = options[:number]
|
284
|
+
|
285
|
+
if tester.v93k? && tester.smt8?
|
286
|
+
block_loop(name, options) do |block, i|
|
287
|
+
options[:number] = number + i if number && i
|
288
|
+
tm = test_methods.my_hash_tml.my_hash_test
|
289
|
+
tm.hashParameter = {
|
290
|
+
param1: {}
|
291
|
+
}
|
292
|
+
tm.nestedHashParameter = {
|
293
|
+
my_param_name0: {
|
294
|
+
param_name0: 'hello',
|
295
|
+
param_name1: {
|
296
|
+
my_param_name1: {
|
297
|
+
param_name0: 1
|
298
|
+
},
|
299
|
+
my_param_name2: {
|
300
|
+
param_name0: 2
|
301
|
+
},
|
302
|
+
my_param_name3: {
|
303
|
+
param_name0: 3
|
304
|
+
}
|
305
|
+
}
|
306
|
+
}
|
307
|
+
}
|
308
|
+
tm.nestedHashParameter2 = {
|
309
|
+
my_param_name4: {
|
310
|
+
param_name0: 'goodbye'
|
311
|
+
},
|
312
|
+
my_param_name5: {
|
313
|
+
param_name0: 'goodbye forever'
|
314
|
+
}
|
315
|
+
}
|
316
|
+
ts = test_suites.run(name, options)
|
317
|
+
ts.test_method = tm
|
318
|
+
ts.spec = options.delete(:pin_levels) if options[:pin_levels]
|
319
|
+
ts.spec ||= 'specs.Nominal'
|
320
|
+
flow.test ts, options
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
def my_override_spec_test(name, options = {})
|
326
|
+
number = options[:number]
|
327
|
+
|
328
|
+
if tester.v93k? && tester.smt8?
|
329
|
+
tm = test_methods.ac_tml.ac_test.functional_test
|
330
|
+
ts = test_suites.run(name, options)
|
331
|
+
ts.test_method = tm
|
332
|
+
ts.spec = options.delete(:pin_levels) if options[:pin_levels]
|
333
|
+
ts.spec ||= 'specs.Nominal'
|
334
|
+
ts.pattern = 'pat1'
|
335
|
+
ts.burst = 'sequence1'
|
336
|
+
ts.spec_path = 'myCustomSpecPath'
|
337
|
+
ts.seq_path = 'myCustomSeqPath'
|
338
|
+
ts.spec_namespace = 'myCustomSpecNamespace'
|
339
|
+
ts.seq_namespace = 'myCustomSeqNamespace'
|
340
|
+
flow.test ts, options
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
221
344
|
def block_loop(name, options)
|
222
345
|
if options[:by_block]
|
223
346
|
if tester.j750? || tester.uflex?
|
@@ -1,4 +1,10 @@
|
|
1
1
|
Flow.create do |options|
|
2
|
+
if tester.smt8?
|
3
|
+
my_hash_test :hash_example, number: 8000
|
4
|
+
my_override_spec_test :spec_override_example, number: 8010
|
5
|
+
add_auxiliary_flow :POWERDOWN, path: 'testflow.POWERDOWN'
|
6
|
+
end
|
7
|
+
|
2
8
|
# Instantiate tests via the
|
3
9
|
# interface
|
4
10
|
func 'program_ckbd', tname: 'PGM_CKBD', tnum: 1000, bin: 100, soft_bin: 1100
|
@@ -240,6 +246,9 @@ Flow.create do |options|
|
|
240
246
|
log 'Passing test flags works as expected'
|
241
247
|
func :test_with_no_flags, bypass: false, output_on_pass: false, output_on_fail: false, value_on_pass: false, value_on_fail: false, per_pin_on_pass: false, per_pin_on_fail: false, number: 6020
|
242
248
|
func :test_with_flags, bypass: true, output_on_pass: true, output_on_fail: true, value_on_pass: true, value_on_fail: true, per_pin_on_pass: true, per_pin_on_fail: true, number: 6030
|
249
|
+
elsif tester.smt8?
|
250
|
+
func :test_with_no_flags, bypass: false, number: 6020
|
251
|
+
func :test_with_flags, bypass: true, number: 6030
|
243
252
|
end
|
244
253
|
|
245
254
|
if tester.smt7?
|
data/program/custom_tests.rb
CHANGED
data/program/flow_control.rb
CHANGED
@@ -319,6 +319,18 @@ Flow.create interface: 'OrigenTesters::Test::Interface', flow_name: "Flow Contro
|
|
319
319
|
set_flag '$global'
|
320
320
|
end
|
321
321
|
|
322
|
+
log 'Test unset_flag functionality'
|
323
|
+
set_flag '$my_unset_flag'
|
324
|
+
unset_flag '$my_unset_flag'
|
325
|
+
|
326
|
+
log 'Test add_flag functionality'
|
327
|
+
add_flag :my_uncalled_flag
|
328
|
+
|
329
|
+
log 'Test inout variables'
|
330
|
+
add_flag :MY_INOUT_ADD_FLAG
|
331
|
+
if_flag '$MY_INOUT_ADD_FLAG' do
|
332
|
+
end
|
333
|
+
|
322
334
|
if tester.v93k?
|
323
335
|
log "This should retain the set-run-flag in the else conditional"
|
324
336
|
func :test22, id: :at22, number: 51480
|
@@ -349,7 +361,7 @@ Flow.create interface: 'OrigenTesters::Test::Interface', flow_name: "Flow Contro
|
|
349
361
|
func :test36, on_fail: { render: 'multi_bin;' }, if_flag: :my_flag, number: 51570
|
350
362
|
end
|
351
363
|
|
352
|
-
if tester.v93k?
|
364
|
+
if tester.v93k?
|
353
365
|
log "Tests of flow loop"
|
354
366
|
loop from: 0, to: 5, step: 1, var: '$LOOP_VARIABLE' do
|
355
367
|
func :test_myloop, number: 56000
|
@@ -360,9 +372,11 @@ Flow.create interface: 'OrigenTesters::Test::Interface', flow_name: "Flow Contro
|
|
360
372
|
func :test_myloop2, number: 5610
|
361
373
|
end
|
362
374
|
|
363
|
-
|
364
|
-
|
365
|
-
|
375
|
+
if tester.smt7?
|
376
|
+
log "Tests of flow loop, non-default test number increment"
|
377
|
+
loop from: 0, to: 5, var: '$LOOP_VARIABLE', test_num_inc: 2 do
|
378
|
+
func :test_myloop3, number: 56200
|
379
|
+
end
|
366
380
|
end
|
367
381
|
|
368
382
|
log "Tests of decrementing loop"
|
@@ -371,14 +385,29 @@ Flow.create interface: 'OrigenTesters::Test::Interface', flow_name: "Flow Contro
|
|
371
385
|
end
|
372
386
|
|
373
387
|
log "Tests of nested flow loop, depth 3"
|
374
|
-
|
375
|
-
loop from:
|
376
|
-
loop from: 1, to:
|
377
|
-
|
388
|
+
if tester.smt7?
|
389
|
+
loop from: 0, to: 9, step: 2, var: '$LOOP_VARIABLE1'do
|
390
|
+
loop from: 1, to: 10, step: 1, var: '$LOOP_VARIABLE2' do
|
391
|
+
loop from: 1, to: 5, step: 1, var: '$LOOP_VARIABLE3' do
|
392
|
+
func :test_myloop5, number: 56400
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
396
|
+
else
|
397
|
+
loop from: 0, to: 9, step: 1, var: '$LOOP_VARIABLE1'do
|
398
|
+
loop from: 1, to: 10, step: 1, var: '$LOOP_VARIABLE2' do
|
399
|
+
loop from: 1, to: 5, step: 1, var: '$LOOP_VARIABLE3' do
|
400
|
+
func :test_myloop5, number: 56400
|
401
|
+
end
|
378
402
|
end
|
379
403
|
end
|
380
404
|
end
|
381
405
|
|
406
|
+
log "Tests of variable loop"
|
407
|
+
loop from: '$TEST_VAR', to: 1, step: -1, var: '$LOOP_VARIABLE' do
|
408
|
+
func :test_myloop6, number: 56500
|
409
|
+
end
|
410
|
+
|
382
411
|
# Test of skipping variable name not yet ready
|
383
412
|
end
|
384
413
|
|
@@ -17,6 +17,23 @@ If the timeset waveforms used by the pattern are
|
|
17
17
|
[fully defined within your Origen application](<%= path "guides/pattern/timing/#Defining_Timesets" %>)
|
18
18
|
then that information will also be represented within the generated STIL pattern.
|
19
19
|
|
20
|
+
Optionally the defined timing can be represented in equation form by setting up your environment as follows:
|
21
|
+
|
22
|
+
~~~ruby
|
23
|
+
OrigenTesters::STIL.new use_timing_equations: true
|
24
|
+
~~~
|
25
|
+
|
26
|
+
If your application is used to convert patterns from another format into STIL format you can add
|
27
|
+
a callback function to config/application.rb to set appropriate period sizes as follows:
|
28
|
+
|
29
|
+
~~~ruby
|
30
|
+
def convert_command_set_period_in_ns(timeset_name)
|
31
|
+
return 25 if timeset_name == "timeset0"
|
32
|
+
return 30 if timeset_name == "timeset1"
|
33
|
+
40
|
34
|
+
end
|
35
|
+
~~~
|
36
|
+
|
20
37
|
A pattern containing a `Pattern { }` block only - i.e. only vectors and without the `Signals { }`,
|
21
38
|
`Timing { }` and other frontmatter blocks - can be generated by setting up your environment as follows:
|
22
39
|
|