origen_testers 0.51.5 → 0.52.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a180bdac7bac206de7e54920fe663e70d1a2385d719a4a2ee134168856926142
4
- data.tar.gz: 1882b6db742cdcb8f4a05a2a5f2d14c8bf0edcbee5e2ad65cff473a4a0ebefb7
3
+ metadata.gz: eb1671039082e3f1856ec1facd0861776bf7ed44b07be01103028a21e20962cc
4
+ data.tar.gz: a9855748f37e09b0f80d86c42c111c3577eec987e49336ad43b772fb267c8a36
5
5
  SHA512:
6
- metadata.gz: 1dc6ab272a3770ee8351f0b1fad2d17cc41fa1a0abf5fe3df4f0d7caba4aea82551fe2719dae4bb676c2080af4c0327e12d2682afd288db50f5f9bbad44a392e
7
- data.tar.gz: 1be16fa7b79f24afeb21d59713c66134917922d19a4534e611bc9a153cdf10911e3a96c9a066928a30db3850ee26084dd9655065d388f5bcdf9102f00cef778c
6
+ metadata.gz: b647195f53446e14b390662d93ebe7207aba5f8a90af089cad0e5368f0ee9f8347db00c7440ea497509b6b565067ddebf8b4e0e4e3f47a3f4f1d50e6aa16784b
7
+ data.tar.gz: 2ec5f3ed1581bdaac66f115c8f0950e0e965d40c7b369da6b3b16d405c7cddfd337fa5f9b088c7bbb54ee3d51166b5904a43aca8c2a1055c12170bb7bd451c10
data/config/commands.rb CHANGED
@@ -200,7 +200,7 @@ when "examples", "test"
200
200
  puts
201
201
  puts "To approve any diffs in the reference.list files run the following command:"
202
202
  puts
203
- platforms = %w(j750 j750_literals j750_hpt ultraflex ultraflex_literals v93k v93k_multiport v93k_enable_flow v93k_disable_flow v93k_limits_file v93k_global v93k_smt8) # put here the various platforms used in examples/program_generator.rb
203
+ platforms = %w(j750 j750_literals j750_hpt ultraflex ultraflex_literals v93k v93k_multiport v93k_enable_flow v93k_disable_flow v93k_limits_file v93k_global v93k_smt8 v93k_flowgrouping) # put here the various platforms used in examples/program_generator.rb
204
204
  reflist_command = ''
205
205
  platforms.each do |platform|
206
206
  unless reflist_command == ''
data/config/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module OrigenTesters
2
2
  MAJOR = 0
3
- MINOR = 51
4
- BUGFIX = 5
3
+ MINOR = 52
4
+ BUGFIX = 1
5
5
  DEV = nil
6
6
  VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
7
7
  end
@@ -479,6 +479,21 @@ module OrigenTesters::ATP
479
479
  end
480
480
  end
481
481
 
482
+ def add_auxiliary_flow(name, options = {})
483
+ if tester.smt8?
484
+ if name.to_s != options[:path].split('.').last.to_s
485
+ fail "Auxiliary flow path does not end in '#{name}'. The path instead is '#{options[:path]}'. Please update the path to align with the provided name."
486
+ end
487
+ extract_meta!(options) do
488
+ apply_conditions(options) do
489
+ n2(:auxiliary_flow, n1(:name, name), n1(:path, options[:path]))
490
+ end
491
+ end
492
+ else
493
+ fail 'Auxiliary flow API is only usable in SMT8.'
494
+ end
495
+ end
496
+
482
497
  def bin(number, options = {})
483
498
  if number.is_a?(Hash)
484
499
  fail 'The bin number must be passed as the first argument'
@@ -547,6 +562,22 @@ module OrigenTesters::ATP
547
562
  end
548
563
  end
549
564
 
565
+ def unset_flag(flag, options = {})
566
+ extract_meta!(options) do
567
+ apply_conditions(options) do
568
+ unset_flag_node(flag)
569
+ end
570
+ end
571
+ end
572
+
573
+ def add_flag(flag, options = {})
574
+ extract_meta!(options) do
575
+ apply_conditions(options) do
576
+ add_flag_node(flag)
577
+ end
578
+ end
579
+ end
580
+
550
581
  def set(var, val, options = {})
551
582
  extract_meta!(options) do
552
583
  apply_conditions(options) do
@@ -938,6 +969,14 @@ module OrigenTesters::ATP
938
969
  n1(:set_flag, flag)
939
970
  end
940
971
 
972
+ def unset_flag_node(flag)
973
+ n1(:unset_flag, flag)
974
+ end
975
+
976
+ def add_flag_node(flag)
977
+ n1(:add_flag, flag)
978
+ end
979
+
941
980
  # Ensures the flow ast has a volatile node, then adds the
942
981
  # given flags to it
943
982
  def add_volatile_flags(node, flags)
@@ -8,8 +8,8 @@ module OrigenTesters::ATP
8
8
  @atp
9
9
  end
10
10
 
11
- ([:test, :bin, :pass, :continue, :cz, :log, :sub_test, :volatile, :add_global_flag, :set_flag, :set, :enable, :disable, :render,
12
- :context_changed?, :ids, :describe_bin, :describe_softbin, :describe_soft_bin, :loop] +
11
+ ([:test, :bin, :pass, :continue, :cz, :log, :sub_test, :volatile, :add_global_flag, :set_flag, :unset_flag, :add_flag, :set, :enable, :disable, :render,
12
+ :context_changed?, :ids, :describe_bin, :describe_softbin, :describe_soft_bin, :loop, :add_auxiliary_flow] +
13
13
  OrigenTesters::ATP::Flow::CONDITION_KEYS.keys + OrigenTesters::ATP::Flow::RELATIONAL_OPERATORS).each do |method|
14
14
  define_method method do |*args, &block|
15
15
  options = args.pop if args.last.is_a?(Hash)
@@ -50,7 +50,12 @@ module OrigenTesters
50
50
  parents.unshift(File.basename(f.filename, '.*').to_s.downcase)
51
51
  f = f.parent
52
52
  end
53
- File.join tester.package_namespace, 'flows', *parents
53
+ # need to variablize this for internal usage!!
54
+ if Origen.interface.respond_to?(:insertion)
55
+ File.join tester.package_namespace, Origen.interface.insertion.to_s, 'flows', *parents
56
+ else
57
+ File.join tester.package_namespace, 'flows', *parents
58
+ end
54
59
  else
55
60
  'testflow/mfh.testflow.group'
56
61
  end
@@ -447,17 +452,26 @@ module OrigenTesters
447
452
 
448
453
  def on_whenever(node)
449
454
  expressions, *nodes = *node
450
-
455
+ and_string = ' and '
456
+ or_string = ' or '
457
+ if smt8?
458
+ and_string = ' && '
459
+ or_string = ' || '
460
+ end
451
461
  case node.type
452
462
  when :whenever_all
453
- condition = expressions.map { |e| "#{generate_expr_string(e)}" }.join(' and ')
463
+ condition = expressions.map { |e| "#{generate_expr_string(e)}" }.join(and_string)
454
464
  when :whenever_any
455
- condition = expressions.map { |e| "#{generate_expr_string(e)}" }.join(' or ')
465
+ condition = expressions.map { |e| "#{generate_expr_string(e)}" }.join(or_string)
456
466
  else
457
467
  condition = expressions.map { |e| "#{generate_expr_string(e)}" }.join('ERROR')
458
468
  end
459
469
 
460
- line "if #{condition} then"
470
+ if smt8?
471
+ line "if (#{condition})"
472
+ else
473
+ line "if #{condition} then"
474
+ end
461
475
  line '{'
462
476
  @indent += 1
463
477
  process_all(node.children)
@@ -471,13 +485,23 @@ module OrigenTesters
471
485
  alias_method :on_whenever_all, :on_whenever
472
486
 
473
487
  def on_loop(node, options = {})
474
- # TODO: don't have the SMT8 way to do this yet
475
- if smt8?
476
- fail 'Flow loop control not yet supported for SMT8!'
477
- end
478
488
  start = node.to_a[0]
489
+ if start.is_a?(String)
490
+ start = generate_flag_name(start)
491
+ unless smt8?
492
+ start = "@#{start}"
493
+ end
494
+ end
479
495
  stop = node.to_a[1]
496
+ if stop.is_a?(String) && smt8?
497
+ stop = generate_flag_name(stop)
498
+ elsif stop.is_a?(String)
499
+ fail 'loops with \'stop\' defined as a variable cannot be supported in the defined environments.'
500
+ end
480
501
  step = node.to_a[2]
502
+ if smt8? && !(step == -1 || step == 1)
503
+ fail 'SMT8 does not support steps other than -1 or 1.'
504
+ end
481
505
  if node.to_a[3].nil?
482
506
  fail 'You must supply a loop variable name!'
483
507
  else
@@ -487,7 +511,7 @@ module OrigenTesters
487
511
  unless smt8?
488
512
  var = "@#{var}"
489
513
  end
490
- num = (stop - start) / step + 1
514
+ # num = (stop - start) / step + 1
491
515
  # Handle increment/decrement
492
516
  if step < 0
493
517
  compare = '>'
@@ -496,13 +520,24 @@ module OrigenTesters
496
520
  compare = '<'
497
521
  incdec = "+ #{step}"
498
522
  end
499
- line "for #{var} = #{start}; #{var} #{compare} #{stop + step} ; #{var} = #{var} #{incdec}; do"
500
- line "test_number_loop_increment = #{test_num_inc}"
501
- line '{'
502
- @indent += 1
503
- process_all(node.children)
504
- @indent -= 1
505
- line '}'
523
+ if tester.smt7?
524
+ line "for #{var} = #{start}; #{var} #{compare} #{stop + step} ; #{var} = #{var} #{incdec}; do"
525
+ line "test_number_loop_increment = #{test_num_inc}"
526
+ line '{'
527
+ @indent += 1
528
+ process_all(node.children)
529
+ @indent -= 1
530
+ line '}'
531
+ elsif smt8?
532
+ line "for (#{var} : #{start}..#{stop})"
533
+ line '{'
534
+ @indent += 1
535
+ process_all(node.children)
536
+ @indent -= 1
537
+ line '}'
538
+ else
539
+ fail 'Environment was not supported for flow loops.'
540
+ end
506
541
  end
507
542
 
508
543
  def generate_expr_string(node, options = {})
@@ -614,6 +649,15 @@ module OrigenTesters
614
649
  end
615
650
  end
616
651
 
652
+ def on_unset_flag(node)
653
+ flag = generate_flag_name(node.value)
654
+ if smt8?
655
+ line "#{flag} = 0;"
656
+ else
657
+ line "@#{flag} = 0;"
658
+ end
659
+ end
660
+
617
661
  # Note that for smt8?, this should never be hit anymore since groups are now generated as sub-flows
618
662
  def on_group(node)
619
663
  on_fail = node.children.find { |n| n.try(:type) == :on_fail }
@@ -88,7 +88,11 @@ module OrigenTesters
88
88
  return flow_sheets[id] if flow_sheets[id] # will return flow if already existing
89
89
  p = platform::Flow.new
90
90
  p.inhibit_output if Origen.interface.resources_mode?
91
- p.filename = filename
91
+ if id == Origen.file_handler.current_file.basename('.rb').to_s && Origen.interface.try(:use_flow_name_for_top_level)
92
+ p.filename = Origen.interface.flow_name
93
+ else
94
+ p.filename = filename
95
+ end
92
96
  p.test_suites ||= platform::TestSuites.new(p)
93
97
  p.test_methods ||= platform::TestMethods.new(p)
94
98
  flow_sheets[id] = p
@@ -7,7 +7,8 @@ module OrigenTesters
7
7
  # and their default values
8
8
  class ExtractFlowVars < ATP::Processor
9
9
  OWNERS = [:all, :this_flow, :sub_flows]
10
- CATEGORIES = [:jobs, :referenced_flags, :set_flags, :set_flags_extern,
10
+ CATEGORIES = [:jobs, :referenced_flags, :set_flags, :unset_flags, :add_flags,
11
+ :set_flags_extern, :unset_flags_extern, :add_flags_extern,
11
12
  :referenced_enables, :set_enables]
12
13
 
13
14
  def run(node, options = {})
@@ -72,6 +73,22 @@ module OrigenTesters
72
73
  end
73
74
  end
74
75
 
76
+ def on_unset_flag(node)
77
+ add generate_flag_name(node.value), :unset_flags
78
+ # Also separate flags which have been set and which should be externally visible
79
+ if !node.to_a.include?('auto_generated') || node.to_a.include?('extern')
80
+ add generate_flag_name(node.value), :unset_flags_extern
81
+ end
82
+ end
83
+
84
+ def on_add_flag(node)
85
+ add generate_flag_name(node.value), :add_flags
86
+ # Also separate flags which have been set and which should be externally visible
87
+ if !node.to_a.include?('auto_generated') || node.to_a.include?('extern')
88
+ add generate_flag_name(node.value), :add_flags_extern
89
+ end
90
+ end
91
+
75
92
  def on_if_enabled(node)
76
93
  flag, *nodes = *node
77
94
  [flag].flatten.each do |f|
@@ -2,7 +2,7 @@ module OrigenTesters
2
2
  module SmartestBasedTester
3
3
  class Base
4
4
  class TestMethod
5
- FORMAT_TYPES = [:current, :voltage, :time, :string, :integer, :double, :boolean]
5
+ FORMAT_TYPES = [:current, :voltage, :time, :string, :integer, :double, :boolean, :class, :list_strings, :list_classes]
6
6
 
7
7
  # Returns the object representing the test method library that the
8
8
  # given test method is defined in
@@ -107,10 +107,20 @@ module OrigenTesters
107
107
  type = send(name)
108
108
  elsif respond_to?(name.sub(/b$/, ''))
109
109
  type = inverse_of(send(name.sub(/b$/, '')))
110
+ elsif parameters[attr].is_a?(Hash) || parameters[attr.to_sym].is_a?(Hash)
111
+ type = :hash
110
112
  else
111
113
  fail "Unknown attribute type: #{parameters[attr]}"
112
114
  end
113
115
  end
116
+ if val.nil? && !tester.print_all_params
117
+ nil
118
+ else
119
+ handle_val_type(val, type, attr)
120
+ end
121
+ end
122
+
123
+ def handle_val_type(val, type, attr)
114
124
  case type
115
125
  when :current, 'CURR'
116
126
  "#{val}[A]"
@@ -126,9 +136,9 @@ module OrigenTesters
126
136
  val
127
137
  when :boolean
128
138
  # Check for valid values
129
- if [0, 1, true, false].include?(val)
139
+ if [0, 1, true, false, 'true', 'false'].include?(val)
130
140
  # Use true/false for smt8 and 0/1 for smt7
131
- if [1, true].include?(val)
141
+ if [1, true, 'true'].include?(val)
132
142
  tester.smt8? ? true : 1
133
143
  else
134
144
  tester.smt8? ? false : 0
@@ -136,6 +146,18 @@ module OrigenTesters
136
146
  else
137
147
  fail "Unknown boolean value for attribute #{attr}: #{val}"
138
148
  end
149
+ when :hash, :class
150
+ val
151
+ when :list_strings
152
+ unless val.is_a?(Array)
153
+ fail "#{val} is not an Array. List_strings must have Array values"
154
+ end
155
+ "##{val}"
156
+ when :list_classes
157
+ unless val.is_a?(Array)
158
+ fail "#{val} is not an Array. List_classes must have Array values"
159
+ end
160
+ "##{val.to_s.gsub('"', '')}"
139
161
  else
140
162
  fail "Unknown type for attribute #{attr}: #{type}"
141
163
  end
@@ -48,7 +48,7 @@ module OrigenTesters
48
48
  # What SMT7 calls a declaration
49
49
  def declarations
50
50
  if variables
51
- (variables[:all][:jobs] + variables[:all][:referenced_flags] + variables[:all][:set_flags]).uniq.sort do |x, y|
51
+ (variables[:all][:jobs] + variables[:all][:referenced_flags] + variables[:all][:set_flags] + variables[:all][:unset_flags] + variables[:all][:add_flags]).uniq.sort do |x, y|
52
52
  x = x[0] if x.is_a?(Array)
53
53
  y = y[0] if y.is_a?(Array)
54
54
  # Need to use strings for the comparison as some declarations can be a string and some a symbol
@@ -19,6 +19,9 @@ module OrigenTesters
19
19
  # flow, the default value is :signature
20
20
  attr_reader :unique_test_names
21
21
 
22
+ # use flow variable grouping or not
23
+ attr_accessor :flow_variable_grouping
24
+
22
25
  # Returns the SMT version, defaults to 7
23
26
  attr_reader :smt_version
24
27
 
@@ -66,6 +69,8 @@ module OrigenTesters
66
69
  # defaults to the application's namespace if not defined (SMT8 only)
67
70
  attr_writer :package_namespace
68
71
 
72
+ attr_writer :spec_path, :seq_path
73
+
69
74
  # When set to true, the bins and softbins sheets from the limits spreadsheet will
70
75
  # be written out to a standalone (spreadsheet) file instead (SMT8 only)
71
76
  attr_accessor :separate_bins_file
@@ -74,6 +79,10 @@ module OrigenTesters
74
79
  # format (SMT8 only)
75
80
  attr_accessor :zip_patterns
76
81
 
82
+ # When set to true (the default), parameters will be generated in the flow file regardless if the default is selected
83
+ # (SMT8 only)
84
+ attr_accessor :print_all_params
85
+
77
86
  def initialize(options = {})
78
87
  options = {
79
88
  # whether to use multiport bursts or not, if so this indicates the name of the port to use
@@ -104,6 +113,7 @@ module OrigenTesters
104
113
  if smt8?
105
114
  @pat_extension = 'pat'
106
115
  @program_comment_char = ['println', '//']
116
+ @print_all_params = options[:print_all_params].nil? ? true : options[:print_all_params]
107
117
  else
108
118
  @pat_extension = 'avc'
109
119
  @program_comment_char = ['print_dl', '//']
@@ -135,15 +145,20 @@ module OrigenTesters
135
145
  @unique_test_names = :signature
136
146
  end
137
147
  end
138
- if smt8?
139
- @create_limits_file = true
148
+ if options.key?(:create_limits_file)
149
+ @create_limits_file = options[:create_limits_file]
140
150
  else
141
- if options.key?(:create_limits_file)
142
- @create_limits_file = options[:create_limits_file]
151
+ if smt8?
152
+ @create_limits_file = true
143
153
  else
144
154
  @create_limits_file = false
145
155
  end
146
156
  end
157
+
158
+ if options.key?(:flow_variable_grouping)
159
+ @flow_variable_grouping = options[:flow_variable_grouping]
160
+ end
161
+
147
162
  if options[:literal_flags]
148
163
  @literal_flags = true
149
164
  end
@@ -152,6 +167,8 @@ module OrigenTesters
152
167
  end
153
168
 
154
169
  @package_namespace = options.delete(:package_namespace)
170
+ @spec_path = options.delete(:spec_path)
171
+ @seq_path = options.delete(:seq_path)
155
172
  self.limitfile_test_modes = options[:limitfile_test_modes] || options[:limitsfile_test_modes]
156
173
  self.force_pass_on_continue = options[:force_pass_on_continue]
157
174
  self.delayed_binning = options[:delayed_binning]
@@ -167,6 +184,13 @@ module OrigenTesters
167
184
  @package_namespace || Origen.app.namespace
168
185
  end
169
186
 
187
+ def spec_path
188
+ @spec_path || 'specs'
189
+ end
190
+
191
+ def seq_path
192
+ @seq_path || 'specs'
193
+ end
170
194
  # Set the test mode(s) that you want to see in the limits files, supply an array of mode names
171
195
  # to set multiple.
172
196
  def limitfile_test_modes=(val)
@@ -4,6 +4,7 @@ module OrigenTesters
4
4
  require 'origen_testers/smartest_based_tester/base/flow'
5
5
  class Flow < Base::Flow
6
6
  TEMPLATE = "#{Origen.root!}/lib/origen_testers/smartest_based_tester/v93k_smt8/templates/template.flow.erb"
7
+ IN_IDENTIFIER = '_AUTOIN'
7
8
 
8
9
  def on_test(node)
9
10
  test_suite = node.find(:object).to_a[0]
@@ -93,18 +94,44 @@ module OrigenTesters
93
94
  @sub_flows ||= {}
94
95
  path = Pathname.new(node.find(:path).value)
95
96
  name = path.basename('.*').to_s
97
+ path = Origen.interface.sub_flow_path_overwrite(path) if Origen.interface.respond_to? :sub_flow_path_overwrite
96
98
  @sub_flows[name] = "#{path.dirname}.#{name}".gsub(/(\/|\\)/, '.')
97
99
  # Pass down all input variables before executing
100
+ if sub_flow.input_variables.size > 0 && tester.flow_variable_grouping
101
+ line "// #{name} sub-flow input variables"
102
+ line '{'
103
+ @indent += 1
104
+ end
98
105
  sub_flow.input_variables.each do |var|
99
- var = var[0] if var.is_a?(Array)
100
- line "#{name}.#{var} = #{var};"
106
+ # Handle the inout variables
107
+ # Get the main value into the temporary input variable
108
+ if sub_flow.inout_variables.keys.include?(var)
109
+ var = var[0] if var.is_a?(Array)
110
+ line "#{name}.#{var} = #{sub_flow.inout_variables[var]};"
111
+ else
112
+ var = var[0] if var.is_a?(Array)
113
+ line "#{name}.#{var} = #{var};"
114
+ end
115
+ end
116
+ if sub_flow.input_variables.size > 0 && tester.flow_variable_grouping
117
+ @indent -= 1
118
+ line '}'
101
119
  end
102
120
  line "#{name}.execute();"
103
121
  # And then retrieve all common output variables
122
+ if (output_variables & sub_flow.output_variables).size > 0 && tester.flow_variable_grouping
123
+ line "// #{name} sub-flow output variables"
124
+ line '{'
125
+ @indent += 1
126
+ end
104
127
  (output_variables & sub_flow.output_variables).sort.each do |var|
105
128
  var = var[0] if var.is_a?(Array)
106
129
  line "#{var} = #{name}.#{var};"
107
130
  end
131
+ if (output_variables & sub_flow.output_variables).size > 0 && tester.flow_variable_grouping
132
+ @indent -= 1
133
+ line '}'
134
+ end
108
135
  if on_pass = node.find(:on_pass)
109
136
  pass_lines = capture_lines do
110
137
  @indent += 1
@@ -146,20 +173,48 @@ module OrigenTesters
146
173
  end
147
174
  end
148
175
 
176
+ def on_auxiliary_flow(node)
177
+ @auxiliary_flows ||= {}
178
+ path = node.find(:path).value
179
+ name = node.find(:name).value
180
+ @auxiliary_flows[name] = "#{path}"
181
+ line "#{name}.execute();"
182
+ end
183
+
149
184
  def sub_flows
150
185
  @sub_flows || {}
151
186
  end
152
187
 
188
+ def auxiliary_flows
189
+ @auxiliary_flows || {}
190
+ end
191
+
192
+ def inout_variables
193
+ @inout_variables || {}
194
+ end
195
+
153
196
  # Variables which should be defined as an input to the current flow
154
197
  def input_variables
155
198
  vars = flow_variables
156
199
  # Jobs and enables flow into a sub-flow
157
- (vars[:all][:jobs] + vars[:all][:referenced_enables] + vars[:all][:set_enables] +
200
+ in_var_array = (vars[:all][:jobs] + vars[:all][:referenced_enables] + vars[:all][:set_enables] +
158
201
  # As do any flags which are referenced by it but which are not set within it
159
- (vars[:all][:referenced_flags] - vars[:all][:set_flags])).uniq.sort do |x, y|
202
+ (vars[:all][:referenced_flags] - vars[:all][:set_flags] - vars[:all][:unset_flags])).uniq
203
+ identified_inout_variables = in_var_array.select { |e| output_variables.include?(e) }
204
+ result = in_var_array.reject { |e| output_variables.include?(e) }
205
+ @inout_variables = {}
206
+ # create inout variables with unique ids to reduce user conflicts
207
+ identified_inout_variables.each do |var|
208
+ unique_id = 0
209
+ var.each_byte { |n| unique_id += n }
210
+ identifier = IN_IDENTIFIER + "_#{unique_id.to_s[0..4]}"
211
+ @inout_variables[:"#{var}#{identifier}"] = var
212
+ end
213
+ result += @inout_variables.keys
214
+ result.uniq.sort do |x, y|
160
215
  x = x[0] if x.is_a?(Array)
161
216
  y = y[0] if y.is_a?(Array)
162
- x <=> y
217
+ x.to_s <=> y.to_s
163
218
  end
164
219
  end
165
220
 
@@ -170,6 +225,10 @@ module OrigenTesters
170
225
  (vars[:this_flow][:set_flags] +
171
226
  # As do any flags set by its children which are marked as external
172
227
  vars[:all][:set_flags_extern] +
228
+ # Other test methods are setting the flags
229
+ vars[:this_flow][:add_flags] +
230
+ # Other test methods are set in the children
231
+ vars[:all][:add_flags_extern] +
173
232
  # And any flags which are set by a child and referenced in this flow
174
233
  (vars[:this_flow][:referenced_flags] & vars[:sub_flows][:set_flags]) +
175
234
  # And also intermediate flags, those are flags which are set by a child and referenced
@@ -217,6 +276,11 @@ module OrigenTesters
217
276
  h << i + "#{var} = -1;"
218
277
  end
219
278
  end
279
+ # Handle the inout variables
280
+ # Use the original variable name and get the value out of the temporary input variable
281
+ inout_variables.each do |inout_var, orig_var|
282
+ h << i + "#{orig_var} = #{inout_var};"
283
+ end
220
284
  h << '' unless flow_variables[:this_flow][:set_flags].empty?
221
285
  h
222
286
  end
@@ -65,35 +65,37 @@ module OrigenTesters
65
65
  Origen.log.info "Writing... #{output_file}"
66
66
  spreadsheet = RODF::Spreadsheet.new
67
67
  Origen.interface.flow_sheets.each do |name, flow|
68
- if flow.limits_file
69
- limits_name = flow.limits_file.filename.sub('.csv', '')
70
- table = spreadsheet.table limits_name
71
- flow.limits_file.output_file.readlines.each_with_index do |line, i|
72
- # Need to fix the first row, SMT8 won't allow the Low/High limits cells not to be merged
73
- if i == 0
74
- row = table.row
75
- x = nil
76
- line.chomp.split(',').each do |word|
77
- if word == 'Low Limit'
78
- x = 0
79
- elsif word == 'High Limit'
80
- row.cell 'Low Limit', span: x + 1
81
- x = 0
82
- elsif word == 'Unit'
83
- row.cell 'High Limit', span: x + 1
84
- row.cell word
85
- x = nil
86
- elsif x
87
- x += 1
88
- else
68
+ if tester.create_limits_file
69
+ if flow.limits_file
70
+ limits_name = flow.limits_file.filename.sub('.csv', '')
71
+ table = spreadsheet.table limits_name
72
+ flow.limits_file.output_file.readlines.each_with_index do |line, i|
73
+ # Need to fix the first row, SMT8 won't allow the Low/High limits cells not to be merged
74
+ if i == 0
75
+ row = table.row
76
+ x = nil
77
+ line.chomp.split(',').each do |word|
78
+ if word == 'Low Limit'
79
+ x = 0
80
+ elsif word == 'High Limit'
81
+ row.cell 'Low Limit', span: x + 1
82
+ x = 0
83
+ elsif word == 'Unit'
84
+ row.cell 'High Limit', span: x + 1
85
+ row.cell word
86
+ x = nil
87
+ elsif x
88
+ x += 1
89
+ else
90
+ row.cell word
91
+ end
92
+ end
93
+ else
94
+ row = table.row
95
+ line.chomp.split(',').each do |word|
89
96
  row.cell word
90
97
  end
91
98
  end
92
- else
93
- row = table.row
94
- line.chomp.split(',').each do |word|
95
- row.cell word
96
- end
97
99
  end
98
100
  end
99
101
  end
@@ -21,6 +21,9 @@ flow <%= flow_name %> {
21
21
  <%= line %>
22
22
  % end
23
23
 
24
+ % end
25
+ % auxiliary_flows.each do |name, path|
26
+ flow <%= name %> calls <%= path %> {}
24
27
  % end
25
28
  % sub_flows.each do |name, path|
26
29
  flow <%= name %> calls <%= path %> { }
@@ -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,120 @@ 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 param.last.is_a? Hash
92
+ if !test_method.format(name).nil? && !test_method.format(name).is_a?(Hash)
93
+ fail "#{name} parameter structure requires a Hash but value provided is #{test_method.format(name).class}"
94
+ elsif test_method.format(name).nil? && tester.print_all_params
95
+ l = add_nested_params(l, name, 'param0', {}, param.last, 1)
96
+ elsif test_method.format(name).nil?
97
+ # Do nothing
98
+ else
99
+ test_method.format(name).each do |key, meta_hash|
100
+ l = add_nested_params(l, name, key, meta_hash, param.last, 1)
101
+ end
102
+ end
103
+ elsif NO_STRING_TYPES.include?(param.last) && test_method.format(param[0]).is_a?(String) && !test_method.format(param[0]).empty?
104
+ l << " #{name} = #{test_method.format(param[0])};"
105
+ else
106
+ l << " #{name} = #{wrap_if_string(test_method.format(param[0]))};"
107
+ end
59
108
  end
60
109
  l << '}'
61
110
  l
62
111
  end
112
+
113
+ # rubocop:disable Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters.
114
+ def add_nested_params(l, name, key, value_hash, nested_params, nested_loop_count)
115
+ nested_params_accepted_keys = []
116
+ skip_keys = []
117
+ unless value_hash.nil?
118
+ unless value_hash.is_a?(Hash)
119
+ fail "Provided value to nested params was not a Hash. Instead the value was #{value_hash.class}"
120
+ end
121
+ dynamic_spacing = ' ' * (4 * nested_loop_count)
122
+ l << "#{dynamic_spacing}#{name}[#{key}] = {" unless name.nil?
123
+ nested_params.each do |nested_param|
124
+ # Guarentee hash is using all symbol keys
125
+ # Since we cannot guarentee ruby version is greater than 2.5, we have to use an older syntax to
126
+ value_hash = value_hash.inject({}) { |memo, (k, v)| memo[k.to_sym] = v; memo }
127
+ nested_key = nested_param.first.to_sym
128
+ nested_key_underscore = nested_key.to_s.underscore.to_sym
129
+ nested_params_accepted_keys << nested_key
130
+ nested_params_accepted_keys << nested_key_underscore
131
+ # We cannot create nested member functions with aliases
132
+ # Requirement for hash parameter passing is to pass one of the key types and not both
133
+ if value_hash.keys.include?(nested_key) &&
134
+ value_hash.keys.include?(nested_key_underscore) && nested_key != nested_key_underscore
135
+ fail 'You are using a hash based test method and provided both the parameter name and alias name.'
136
+ end
137
+ nested_key = nested_key_underscore if value_hash.keys.include?(nested_key_underscore)
138
+ if nested_param.last.first.is_a?(Hash) && value_hash[nested_key].is_a?(Hash)
139
+ value_hash[nested_key].each do |inner_key, inner_meta_hash|
140
+ 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)
141
+ skip_keys << nested_key
142
+ end
143
+ elsif nested_param.last.first.is_a?(Hash) && tester.print_all_params
144
+ l = add_nested_params(l, nested_param.first, 'param0', {}, nested_param.last.first, nested_loop_count + 1)
145
+ end
146
+ type = nested_param.last.first
147
+ if NO_STRING_TYPES.include?(nested_param.last.first) && value_hash[nested_key] && !skip_keys.include?(nested_key)
148
+ l << " #{dynamic_spacing}#{nested_param.first} = #{test_method.handle_val_type(value_hash[nested_key], type, nested_param.first)};"
149
+ elsif value_hash[nested_key] && !skip_keys.include?(nested_key)
150
+ l << " #{dynamic_spacing}#{nested_param.first} = #{wrap_if_string(test_method.handle_val_type(value_hash[nested_key], type, nested_param.first))};"
151
+ 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)
152
+ l << " #{dynamic_spacing}#{nested_param.first} = #{test_method.handle_val_type(nested_param.last.last, type, nested_param.first)};"
153
+ elsif !nested_param.last.last.is_a?(Hash) && tester.print_all_params && !skip_keys.include?(nested_key)
154
+ l << " #{dynamic_spacing}#{nested_param.first} = #{wrap_if_string(test_method.handle_val_type(nested_param.last.last, type, nested_param.first))};"
155
+ end
156
+ end
157
+ l << "#{dynamic_spacing}};" unless name.nil?
158
+ # Sanity check there are not overpassed parameters
159
+ value_hash.keys.each do |nested_key|
160
+ unless nested_params_accepted_keys.include?(nested_key.to_sym)
161
+ fail "You provided a parameter \'#{nested_key}\' that was not an accepted parameter to the hash parameter \'#{name}\'"
162
+ end
163
+ end
164
+ end
165
+ l
166
+ end
167
+ # rubocop:enable Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters.
63
168
  end
64
169
  end
65
170
  end
@@ -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
 
@@ -280,6 +280,9 @@ test :test2, if_flag: :my_pass_flag
280
280
  unless_flag :my_pass_flag do
281
281
  test :test3
282
282
  end
283
+
284
+ log "Example of manually unsetting flag"
285
+ test :test4, on_pass: { unset_flag :my_custom_flag1 }
283
286
  ~~~
284
287
 
285
288
  Note that flag names will usually be forced to uppercase, this is to institute a convention that
@@ -303,6 +306,14 @@ unless_enable "$MCEn_test" do
303
306
  end
304
307
  ~~~
305
308
 
309
+ For custom environment libraries, there might be a need to reference a flag without using the native
310
+ flag API. `add_flag` will allow the flow and sub-flow to have access to the flag without adding to the flow.
311
+
312
+ ~~~ruby
313
+ log "Example of manually adding a flag to a flow without calling the flag"
314
+ add_flag :my_custom_flag2
315
+ ~~~
316
+
306
317
  In all cases the `$` will be removed from the final flag name that appears in the test program.
307
318
 
308
319
  Whenever you set a flag or automation initializes a variable, you can remove the variable from initialization flow by labeling as a global flag
@@ -352,7 +363,7 @@ end
352
363
  ~~~
353
364
 
354
365
 
355
- #### Flow Loops for V93k (SMT7 only)
366
+ #### Flow Loops for V93k
356
367
  Use flow loop control to permit re-running tests without using additional sequence labels.
357
368
 
358
369
  ~~~ruby
@@ -381,7 +392,21 @@ loop from: 0, to: 5, var: '$LOOP_VARIABLE', test_num_inc: 2 do
381
392
  end
382
393
  ~~~
383
394
 
395
+ You can also provide a variable starting point:
396
+ ~~~ruby
397
+ loop from: '$TEST_VARIABLE', to: 5, var: '$LOOP_VARIABLE' do
398
+ func :test_myloop6, number: 56600
399
+ end
400
+ ~~~
401
+
384
402
  Decrementing loops, having `from:` value > `to:` value and using negative `step:`, is also supported.
403
+
404
+ ##### Loop Rules For Each Environment
405
+
406
+ `SMT7` cannot support a variable stop location. Only the `from:` parameter is allowed to be a variable.
407
+
408
+ `SMT8` cannot have a step other than -1 or 1. The limitations of the range flow restrict those steps.
409
+ The `to:` parameter can be a flow variable just like `from:`.
385
410
 
386
411
 
387
412
 
@@ -74,6 +74,20 @@ or to assign a spec in SMT8:
74
74
  t.spec = 'my_spec_min'
75
75
  ~~~
76
76
 
77
+ The default namespace and folder paths are determined by your environment with `tester.package_namespace` and
78
+ `tester.spec_path`/`tester.seq_path` respectively. If you need to override these values for specific test suites
79
+ you have the following available:
80
+
81
+ ~~~ruby
82
+ # Overrides spec namespace and folder path
83
+ t.spec_namespace
84
+ t.spec_path
85
+ # Overrides sequence and pattern namespace
86
+ t.seq_namespace
87
+ # Overrides sequence folder path
88
+ t.seq_path
89
+ ~~~
90
+
77
91
  If the test method provides parameters, you can set them in the same way. As a convenience,
78
92
  Origen will automatically work out whether the reference is to a parameter of the test suite
79
93
  or of the test method, and will assign it accordingly.
@@ -103,10 +103,35 @@ flow Main {
103
103
  }
104
104
  ~~~
105
105
 
106
+ #### Auxiliary Flows
106
107
 
108
+ SMT8 utilizes auxiliary flows to perform recurring actions. `add_auxiliary_flow` API exists to symlink to a predefined auxiliary flow.
109
+ This API does not allow variables to be passed to or from the auxiliary flow since they are stand alone flows.
107
110
 
111
+ ~~~ruby
112
+ add_auxiliary_flow :POWERDOWN, 'testflow.POWERDOWN'
113
+ ~~~
114
+
115
+ ~~~java
116
+ flow Main {
117
+ setup {
118
+ flow POWERDOWN calls testflow.POWERDOWN {}
119
+ }
108
120
 
121
+ execute {
122
+ POWERDOWN.execute();
123
+ }
124
+ }
125
+ ~~~
109
126
 
127
+ #### Flow Variable Grouping
110
128
 
129
+ Sub-flow variable passing causes variables before and after the execution call to populate the flow.
130
+ If you wish to have a collapse-able block for the variables, you need to set the flow_variable_grouping variable to true.
131
+
132
+ ~~~
133
+ # add this line to your origen_site_config.yml
134
+ flow_variable_grouping: true
135
+ ~~~
111
136
 
112
137
  % end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: origen_testers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.51.5
4
+ version: 0.52.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen McGinty
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-11 00:00:00.000000000 Z
11
+ date: 2024-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: origen
@@ -601,7 +601,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
601
601
  - !ruby/object:Gem::Version
602
602
  version: '0'
603
603
  requirements: []
604
- rubygems_version: 3.1.6
604
+ rubygems_version: 3.2.3
605
605
  signing_key:
606
606
  specification_version: 4
607
607
  summary: This plugin provides Origen tester models to drive ATE type testers like