origen_testers 0.51.4 → 0.52.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 +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
|
|