origen_testers 0.51.5 → 0.52.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a180bdac7bac206de7e54920fe663e70d1a2385d719a4a2ee134168856926142
4
- data.tar.gz: 1882b6db742cdcb8f4a05a2a5f2d14c8bf0edcbee5e2ad65cff473a4a0ebefb7
3
+ metadata.gz: 806f6c174a2b26a0ead003ab2a26ad6874ab43ceaeb1f72b90183f0c549f0b0f
4
+ data.tar.gz: 997ca9d806de6b205cf98013f9260b5b44e2e0a82dda42b2aa98020a9a9c961c
5
5
  SHA512:
6
- metadata.gz: 1dc6ab272a3770ee8351f0b1fad2d17cc41fa1a0abf5fe3df4f0d7caba4aea82551fe2719dae4bb676c2080af4c0327e12d2682afd288db50f5f9bbad44a392e
7
- data.tar.gz: 1be16fa7b79f24afeb21d59713c66134917922d19a4534e611bc9a153cdf10911e3a96c9a066928a30db3850ee26084dd9655065d388f5bcdf9102f00cef778c
6
+ metadata.gz: 79ade702c6acb3876aa888ca66570afea165a48a52c08fb0d19f41707f0f02a6c32151d694fd4d4a4cbff45dd1b53c73ca27c5e2e56bd733a48975452a4f8f66
7
+ data.tar.gz: d84b6632197fb9305b4fb7032eecf5620a424fb292ab46c6b24376116f7701aff2dabeec31a11c5b18214285adbfab98fc38f739a720c62feb9494389c2ff2f3
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 = 0
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,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
@@ -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.0
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-25 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