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.
@@ -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 << " measurement.pattern = setupRef(#{tester.package_namespace}.patterns.#{pattern});"
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 << " measurement.specification = setupRef(#{tester.package_namespace}.specs.#{specification});"
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
- l << " #{name} = #{wrap_if_string(test_method.format(param[0]))};"
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
- microcode " Period '#{w[:period]}ns';"
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
- (wave ? wave.evaluated_events : []).each do |t, v|
153
- line << "'#{t}ns' "
154
- if v == 0
155
- line << 'D'
156
- elsif v == 1
157
- line << 'U'
158
- else
159
- line << 'D/U'
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
- (wave ? wave.evaluated_events : []).each_with_index do |tv, i|
170
- t, v = *tv
171
- if i == 0 && t != 0
172
- line << "'0ns' X; "
173
- end
174
- line << "'#{t}ns' "
175
- if v == 0
176
- line << 'L'
177
- elsif v == 0
178
- line << 'H'
179
- else
180
- line << 'L/H/X'
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?
@@ -9,5 +9,8 @@ Flow.create interface: 'OrigenTesters::Test::CustomTestInterface', flow_descript
9
9
 
10
10
  if tester.v93k?
11
11
  custom_b :test4, number: 30040
12
+ if tester.smt8?
13
+ custom_hash :test5, number: 30050
14
+ end
12
15
  end
13
16
  end
@@ -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? && !tester.smt8?
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
- log "Tests of flow loop, non-default test number increment"
364
- loop from: 0, to: 5, var: '$LOOP_VARIABLE', test_num_inc: 2 do
365
- func :test_myloop3, number: 56200
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
- loop from: 0, to: 9, step: 2, var: '$LOOP_VARIABLE1'do
375
- loop from: 1, to: 10, step: 1, var: '$LOOP_VARIABLE2' do
376
- loop from: 1, to: 5, step: 1, var: '$LOOP_VARIABLE3' do
377
- func :test_myloop5, number: 56400
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