origen_testers 0.52.15 → 0.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/config/version.rb +2 -2
  3. data/lib/commands/build.rb +2 -2
  4. data/lib/commands/convert.rb +1 -1
  5. data/lib/commands/run.rb +2 -2
  6. data/lib/origen_testers/api.rb +3 -0
  7. data/lib/origen_testers/atp/ast/node.rb +1 -2
  8. data/lib/origen_testers/atp/flow.rb +36 -24
  9. data/lib/origen_testers/atp/flow_api.rb +1 -0
  10. data/lib/origen_testers/atp/parser.rb +6 -4
  11. data/lib/origen_testers/atp/processor.rb +1 -0
  12. data/lib/origen_testers/atp/processors/on_pass_fail_remover.rb +1 -0
  13. data/lib/origen_testers/atp/processors/relationship.rb +2 -4
  14. data/lib/origen_testers/atp/runner.rb +1 -0
  15. data/lib/origen_testers/callback_handlers.rb +1 -0
  16. data/lib/origen_testers/charz/profile.rb +7 -7
  17. data/lib/origen_testers/charz/routines/search_routine.rb +1 -0
  18. data/lib/origen_testers/charz/session.rb +1 -1
  19. data/lib/origen_testers/charz.rb +14 -10
  20. data/lib/origen_testers/command_based_tester.rb +1 -2
  21. data/lib/origen_testers/decompiler/nodes.rb +1 -1
  22. data/lib/origen_testers/decompiler/pattern/enumerable_ext.rb +1 -1
  23. data/lib/origen_testers/decompiler/pattern/splitter.rb +0 -2
  24. data/lib/origen_testers/decompiler/pattern.rb +2 -1
  25. data/lib/origen_testers/flow.rb +25 -24
  26. data/lib/origen_testers/generator/identity_map.rb +1 -1
  27. data/lib/origen_testers/generator/test_numberer.rb +1 -3
  28. data/lib/origen_testers/generator.rb +4 -2
  29. data/lib/origen_testers/igxl_based_tester/base/ac_specsets.rb +1 -1
  30. data/lib/origen_testers/igxl_based_tester/base/custom_test_instance.rb +1 -1
  31. data/lib/origen_testers/igxl_based_tester/base/dc_specsets.rb +1 -1
  32. data/lib/origen_testers/igxl_based_tester/base/edgesets.rb +1 -1
  33. data/lib/origen_testers/igxl_based_tester/base/flow_line.rb +11 -17
  34. data/lib/origen_testers/igxl_based_tester/base/generator.rb +17 -2
  35. data/lib/origen_testers/igxl_based_tester/base/global_specs.rb +1 -1
  36. data/lib/origen_testers/igxl_based_tester/base/job.rb +16 -16
  37. data/lib/origen_testers/igxl_based_tester/base/level_io_se.rb +2 -2
  38. data/lib/origen_testers/igxl_based_tester/base/levelset.rb +2 -5
  39. data/lib/origen_testers/igxl_based_tester/base/patgroup.rb +1 -3
  40. data/lib/origen_testers/igxl_based_tester/base/patset.rb +0 -1
  41. data/lib/origen_testers/igxl_based_tester/base/patsubr.rb +0 -1
  42. data/lib/origen_testers/igxl_based_tester/base/test_instance.rb +13 -14
  43. data/lib/origen_testers/igxl_based_tester/base/test_instance_group.rb +2 -2
  44. data/lib/origen_testers/igxl_based_tester/base/timesets.rb +1 -1
  45. data/lib/origen_testers/igxl_based_tester/base/timesets_basic.rb +1 -1
  46. data/lib/origen_testers/igxl_based_tester/base.rb +16 -19
  47. data/lib/origen_testers/igxl_based_tester/decompiler/atp.rb +12 -20
  48. data/lib/origen_testers/igxl_based_tester/j750/flow_line.rb +1 -2
  49. data/lib/origen_testers/igxl_based_tester/j750/patset_pattern.rb +1 -2
  50. data/lib/origen_testers/igxl_based_tester/j750/patsubr_pattern.rb +1 -2
  51. data/lib/origen_testers/igxl_based_tester/j750/test_instance.rb +7 -8
  52. data/lib/origen_testers/igxl_based_tester/j750.rb +3 -2
  53. data/lib/origen_testers/igxl_based_tester/j750_hpt/test_instance.rb +5 -6
  54. data/lib/origen_testers/igxl_based_tester/j750_hpt.rb +1 -1
  55. data/lib/origen_testers/igxl_based_tester/parser/descriptions.rb +18 -20
  56. data/lib/origen_testers/igxl_based_tester/parser/test_instance.rb +2 -2
  57. data/lib/origen_testers/igxl_based_tester/parser.rb +12 -12
  58. data/lib/origen_testers/igxl_based_tester/ultraflex/ate_hardware.rb +55 -55
  59. data/lib/origen_testers/igxl_based_tester/ultraflex/flow_line.rb +1 -2
  60. data/lib/origen_testers/igxl_based_tester/ultraflex/patsubr_pattern.rb +1 -2
  61. data/lib/origen_testers/igxl_based_tester/ultraflex/test_instance.rb +9 -10
  62. data/lib/origen_testers/igxl_based_tester/ultraflex.rb +12 -14
  63. data/lib/origen_testers/igxl_based_tester.rb +1 -1
  64. data/lib/origen_testers/interface.rb +8 -8
  65. data/lib/origen_testers/labview_based_tester/pxie6570.rb +2 -0
  66. data/lib/origen_testers/labview_based_tester.rb +2 -2
  67. data/lib/origen_testers/origen_ext/pins/pin.rb +6 -5
  68. data/lib/origen_testers/origen_ext/pins/pin_collection.rb +6 -6
  69. data/lib/origen_testers/parser/searchable_array.rb +2 -2
  70. data/lib/origen_testers/parser/searchable_hash.rb +2 -2
  71. data/lib/origen_testers/parser.rb +1 -1
  72. data/lib/origen_testers/pattern_compilers/assembler.rb +3 -1
  73. data/lib/origen_testers/pattern_compilers/base.rb +5 -4
  74. data/lib/origen_testers/pattern_compilers/igxl_based.rb +9 -3
  75. data/lib/origen_testers/pattern_compilers/j750.rb +4 -3
  76. data/lib/origen_testers/pattern_compilers/ultraflex.rb +4 -3
  77. data/lib/origen_testers/pattern_compilers/v93k.rb +28 -31
  78. data/lib/origen_testers/pattern_compilers.rb +1 -0
  79. data/lib/origen_testers/program_generators.rb +6 -0
  80. data/lib/origen_testers/smartest_based_tester/base/flow.rb +37 -26
  81. data/lib/origen_testers/smartest_based_tester/base/generator.rb +2 -0
  82. data/lib/origen_testers/smartest_based_tester/base/limits_file.rb +2 -2
  83. data/lib/origen_testers/smartest_based_tester/base/pattern_master.rb +3 -3
  84. data/lib/origen_testers/smartest_based_tester/base/processors/extract_flow_vars.rb +1 -1
  85. data/lib/origen_testers/smartest_based_tester/base/test_method.rb +62 -25
  86. data/lib/origen_testers/smartest_based_tester/base/test_methods/base_tml.rb +18 -4
  87. data/lib/origen_testers/smartest_based_tester/base/test_methods/dc_tml.rb +1 -1
  88. data/lib/origen_testers/smartest_based_tester/base/test_methods/limits.rb +1 -1
  89. data/lib/origen_testers/smartest_based_tester/base/variables_file.rb +1 -1
  90. data/lib/origen_testers/smartest_based_tester/base.rb +11 -13
  91. data/lib/origen_testers/smartest_based_tester/decompiler/avc.rb +5 -10
  92. data/lib/origen_testers/smartest_based_tester/decompiler/nodes.rb +1 -1
  93. data/lib/origen_testers/smartest_based_tester/decompiler.rb +1 -0
  94. data/lib/origen_testers/smartest_based_tester/smt8.rb +5 -6
  95. data/lib/origen_testers/smartest_based_tester/v93k/test_suite.rb +1 -2
  96. data/lib/origen_testers/smartest_based_tester/v93k.rb +1 -1
  97. data/lib/origen_testers/smartest_based_tester/v93k_smt8/shmoo_test.rb +3 -2
  98. data/lib/origen_testers/smartest_based_tester/v93k_smt8/test_suite.rb +30 -26
  99. data/lib/origen_testers/smartest_based_tester/v93k_smt8.rb +1 -1
  100. data/lib/origen_testers/stil_based_tester/base.rb +6 -7
  101. data/lib/origen_testers/test/custom_test_interface.rb +7 -7
  102. data/lib/origen_testers/test/dut.rb +23 -22
  103. data/lib/origen_testers/test/interface.rb +9 -7
  104. data/lib/origen_testers/test/nvm.rb +3 -3
  105. data/lib/origen_testers/timing/timeset.rb +0 -2
  106. data/lib/origen_testers/timing/timing_api.rb +2 -3
  107. data/lib/origen_testers/vector.rb +6 -5
  108. data/lib/origen_testers/vector_generator.rb +9 -3
  109. data/lib/origen_testers.rb +1 -1
  110. metadata +6 -18
@@ -54,20 +54,18 @@ module OrigenTesters
54
54
  avc_dir: nil,
55
55
  binl_dir: nil,
56
56
  multiport: nil, # Optional hash for multiport settings: port_bursts, port_in_focus, prefix, postfix
57
- digcap: nil, # Optional hash for digcap settings: pins, vps, nrf, char
57
+ digcap: nil # Optional hash for digcap settings: pins, vps, nrf, char
58
58
  }.merge(@user_options)
59
59
 
60
60
  @job_options = {
61
61
  tester: :v93k,
62
- compiler: self.class.compiler, # required
62
+ compiler: self.class.compiler # required
63
63
  }.merge(@job_options)
64
64
 
65
- @compiler_options = {
66
-
67
- }.merge(@compiler_options)
65
+ @compiler_options = {}.merge(@compiler_options)
68
66
 
69
67
  @compiler_options_with_args = {
70
- aiv2b_opts: nil
68
+ aiv2b_opts: nil
71
69
  }.merge(@compiler_options_with_args)
72
70
 
73
71
  @avc_files = []
@@ -149,6 +147,7 @@ module OrigenTesters
149
147
  # Assumes .aiv file and all workspace collateral has been built up
150
148
  aiv = convert_to_pathname(aiv)
151
149
  fail 'File does not exist! Please specify existing aiv file.' unless aiv.file?
150
+
152
151
  current_job_options = @job_options.merge(@compiler_options_with_args)
153
152
  current_job_options = current_job_options.merge(extract_job_options_from_aiv(aiv))
154
153
  current_job_options = current_job_options.merge(options)
@@ -163,6 +162,7 @@ module OrigenTesters
163
162
  # Output the compiler jobs in the queue to the console
164
163
  def inspect_jobs(index = nil)
165
164
  return empty_msg if empty?
165
+
166
166
  desc = []
167
167
  puts "\n"
168
168
  @jobs.each_with_index do |j, i|
@@ -195,8 +195,10 @@ module OrigenTesters
195
195
  # First-level verification: file/directory was given and exists
196
196
  msg = 'Pass in a valid file (.avc, .avc.gz, .list) or a valid directory'
197
197
  fail "Pattern path is set to nil! #{msg}" if p.nil?
198
+
198
199
  path = Pathname.new(p)
199
200
  fail "Pattern path does not exist! #{msg}" unless path.exist?
201
+
200
202
  path = path.expand_path
201
203
 
202
204
  # Set the reference directory for pattern sub-dir mirroring
@@ -257,7 +259,7 @@ module OrigenTesters
257
259
 
258
260
  # Move AVC files into job space (through pre-processor)
259
261
  @files.each do |file|
260
- contents = File.open(file, 'rb') { |f| f.read }
262
+ contents = File.open(file, 'rb', &:read)
261
263
  new_contents = preprocess_avc(contents)
262
264
  new_avc_file = Pathname.new("#{job_avc_dir}/#{Pathname.new(file).basename}").cleanpath
263
265
  File.open(new_avc_file, 'w') { |f| f.write(new_contents.force_encoding('UTF-8')) }
@@ -315,6 +317,7 @@ module OrigenTesters
315
317
  factor = 1
316
318
  contents.each_line do |line|
317
319
  next if line.match(/^\s*\#/)
320
+
318
321
  if line.match(/^\s*SQPG\s+LBGN\s+(\d+)\s*;/)
319
322
  factor = Regexp.last_match(1).to_i
320
323
  end
@@ -325,42 +328,36 @@ module OrigenTesters
325
328
  end
326
329
 
327
330
  def avc_dir
328
- @avc_dir ||= begin
329
- if @user_options[:avc_dir]
330
- clean_path(@user_options[:avc_dir].to_s)
331
- else
332
- Pathname.new('./AVC') # default value
333
- end
334
- end
331
+ @avc_dir ||= if @user_options[:avc_dir]
332
+ clean_path(@user_options[:avc_dir].to_s)
333
+ else
334
+ Pathname.new('./AVC') # default value
335
+ end
335
336
  end
336
337
 
337
338
  def binl_dir
338
- @binl_dir ||= begin
339
- if @user_options[:binl_dir]
340
- clean_path(@user_options[:binl_dir].to_s)
341
- else
342
- Pathname.new('./BINL') # default value
343
- end
344
- end
339
+ @binl_dir ||= if @user_options[:binl_dir]
340
+ clean_path(@user_options[:binl_dir].to_s)
341
+ else
342
+ Pathname.new('./BINL') # default value
343
+ end
345
344
  end
346
345
 
347
346
  def tmp_dir
348
- @tmp_dir ||= begin
349
- if @user_options[:tmp_dir]
350
- clean_path(@user_options[:tmp_dir].to_s)
351
- else
352
- Pathname.new('./tmp') # default value
353
- end
354
- end
347
+ @tmp_dir ||= if @user_options[:tmp_dir]
348
+ clean_path(@user_options[:tmp_dir].to_s)
349
+ else
350
+ Pathname.new('./tmp') # default value
351
+ end
355
352
  end
356
353
 
357
354
  # Given path string, return Pathname object with cleaned up path
358
355
  def clean_path(path_str)
359
356
  path = Pathname.new(path_str).cleanpath
360
357
  if path.absolute?
361
- return path
358
+ path
362
359
  else
363
- return Pathname.new("./#{path}")
360
+ Pathname.new("./#{path}")
364
361
  end
365
362
  end
366
363
 
@@ -408,7 +405,7 @@ module OrigenTesters
408
405
 
409
406
  def extract_job_options_from_aiv(file)
410
407
  options = {}
411
- contents = File.open(file, 'rb') { |f| f.read }
408
+ contents = File.open(file, 'rb', &:read)
412
409
  count = 0
413
410
  counting = false
414
411
  contents.each_line do |line|
@@ -104,6 +104,7 @@ module OrigenTesters
104
104
  if p.nil?
105
105
  fail "No tester platform defined, supply one of the following as an argument: #{PLATFORMS.keys.sort.join(', ')}"
106
106
  end
107
+
107
108
  p = p.to_sym
108
109
  @pattern_compilers[p].keys
109
110
  end
@@ -1,4 +1,10 @@
1
1
  require 'active_support/concern'
2
+ # Ensure the OrigenTesters namespace and its autoloads (Interface, J750, V93K,
3
+ # etc.) are registered. This file can be loaded directly (e.g. when a plugin
4
+ # interface does `include OrigenTesters::ProgramGenerators` before origen_testers
5
+ # has been fully required), in which case `include Interface` / the PLATFORMS
6
+ # constants below would otherwise raise an uninitialized-constant error.
7
+ require 'origen_testers'
2
8
  module OrigenTesters
3
9
  # Include this module to create an interface that supports multiple tester
4
10
  # types.
@@ -33,7 +33,15 @@ module OrigenTesters
33
33
  tester.smt8?
34
34
  end
35
35
 
36
- def var_filename
36
+ def qualified_name
37
+ @qualified_name ||= if parent
38
+ "#{parent.qualified_name}.#{name}"
39
+ else
40
+ name.to_s
41
+ end
42
+ end
43
+
44
+ def var_filename # rubocop:disable Lint/DuplicateMethods
37
45
  @var_filename || 'global'
38
46
  end
39
47
 
@@ -41,24 +49,22 @@ module OrigenTesters
41
49
  @var_filename = new_var_filename
42
50
  end
43
51
 
44
- def subdirectory
45
- @subdirectory ||= begin
46
- if smt8?
47
- parents = []
48
- f = parent
49
- while f
50
- parents.unshift(File.basename(f.filename, '.*').to_s.downcase)
51
- f = f.parent
52
- end
53
- if Origen.interface.respond_to?(:insertion) && tester.insertion_in_the_flow_path
54
- File.join tester.package_namespace, Origen.interface.insertion.to_s, 'flows', *parents
55
- else
56
- File.join tester.package_namespace, 'flows', *parents
57
- end
58
- else
59
- 'testflow/mfh.testflow.group'
60
- end
61
- end
52
+ def subdirectory # rubocop:disable Lint/DuplicateMethods
53
+ @subdirectory ||= if smt8?
54
+ parents = []
55
+ f = parent
56
+ while f
57
+ parents.unshift(File.basename(f.filename, '.*').to_s.downcase)
58
+ f = f.parent
59
+ end
60
+ if Origen.interface.respond_to?(:insertion) && tester.insertion_in_the_flow_path
61
+ File.join tester.package_namespace, Origen.interface.insertion.to_s, 'flows', *parents
62
+ else
63
+ File.join tester.package_namespace, 'flows', *parents
64
+ end
65
+ else
66
+ 'testflow/mfh.testflow.group'
67
+ end
62
68
  end
63
69
 
64
70
  def filename
@@ -79,7 +85,7 @@ module OrigenTesters
79
85
  end
80
86
  end
81
87
 
82
- def flow_name(filename = nil)
88
+ def flow_name(filename = nil) # rubocop:disable Lint/DuplicateMethods
83
89
  @flow_name_ = @flow_name unless smt8?
84
90
  @flow_name_ ||= begin
85
91
  flow_name = (filename || self.filename).sub(/\..*/, '').upcase
@@ -91,11 +97,11 @@ module OrigenTesters
91
97
  end
92
98
  end
93
99
 
94
- def flow_bypass
100
+ def flow_bypass # rubocop:disable Lint/DuplicateMethods
95
101
  @flow_bypass || false
96
102
  end
97
103
 
98
- def flow_description
104
+ def flow_description # rubocop:disable Lint/DuplicateMethods
99
105
  @flow_description || ''
100
106
  end
101
107
 
@@ -153,9 +159,8 @@ module OrigenTesters
153
159
  @ast ||= begin
154
160
  unique_id = smt8? ? nil : sig
155
161
  atp.ast(unique_id: unique_id, optimization: :smt,
156
- implement_continue: !tester.force_pass_on_continue,
157
- optimize_flags_when_continue: !tester.force_pass_on_continue
158
- )
162
+ implement_continue: !tester.force_pass_on_continue,
163
+ optimize_flags_when_continue: !tester.force_pass_on_continue)
159
164
  end
160
165
  end
161
166
 
@@ -188,6 +193,7 @@ module OrigenTesters
188
193
  def finalize(options = {})
189
194
  if smt8?
190
195
  return unless top_level? || options[:called_by_top_level]
196
+
191
197
  super
192
198
  # Refresh the ast before finalized gets set to true
193
199
  # If ast gets called by the user the finalized flag will lock it to the incorrect value
@@ -206,6 +212,7 @@ module OrigenTesters
206
212
  unless sub_flow
207
213
  fail "Something went wrong, couldn't find the sub-flow object for path #{path}"
208
214
  end
215
+
209
216
  # on_fail and on_pass nodes are removed because they will be rendered by the sub-flow's parent
210
217
  sub_flow.instance_variable_set(:@ast, sub_flow_ast.remove(:on_fail, :on_pass).updated(:flow))
211
218
  sub_flow.instance_variable_set(:@finalized, true) # To stop the AST being regenerated
@@ -509,6 +516,7 @@ module OrigenTesters
509
516
  if smt8? && !(step == -1 || step == 1)
510
517
  fail 'SMT8 does not support steps other than -1 or 1.'
511
518
  end
519
+
512
520
  if step.is_a?(String) || step.is_a?(Symbol)
513
521
  step = generate_flag_name(step)
514
522
  if tester.smt7?
@@ -520,6 +528,7 @@ module OrigenTesters
520
528
  else
521
529
  var = generate_flag_name(node.to_a[3])
522
530
  end
531
+
523
532
  test_num_inc = node.to_a[4]
524
533
  unless smt8?
525
534
  var = "@#{var}"
@@ -560,6 +569,7 @@ module OrigenTesters
560
569
 
561
570
  def generate_expr_string(node, options = {})
562
571
  return node unless node.respond_to?(:type)
572
+
563
573
  case node.type
564
574
  when :eq, :ne, :gt, :ge, :lt, :le
565
575
  result = "#{generate_expr_term(node.to_a[0])} " # operand 1
@@ -572,7 +582,8 @@ module OrigenTesters
572
582
  end
573
583
 
574
584
  def generate_expr_term(val)
575
- return val if val.is_a?(Fixnum) || val.is_a?(Integer) || val.is_a?(Float)
585
+ return val if val.is_a?(Integer) || val.is_a?(Float)
586
+
576
587
  case val[0]
577
588
  when '$'
578
589
  if smt8?
@@ -83,9 +83,11 @@ module OrigenTesters
83
83
  # Returns the current flow object (Origen.interface.flow)
84
84
  def flow(id = Origen.file_handler.current_file.basename('.rb').to_s)
85
85
  return @current_flow if @current_flow
86
+
86
87
  id = id.to_s.sub(/_resources?/, '')
87
88
  filename = id.split('.').last
88
89
  return flow_sheets[id] if flow_sheets[id] # will return flow if already existing
90
+
89
91
  p = platform::Flow.new
90
92
  p.inhibit_output if Origen.interface.resources_mode?
91
93
  if id == Origen.file_handler.current_file.basename('.rb').to_s && Origen.interface.try(:use_flow_name_for_top_level)
@@ -36,7 +36,7 @@ module OrigenTesters
36
36
  l += ',default,default'
37
37
  else
38
38
  test_modes.each { |mode| l += ",#{mode}" }
39
- test_modes.each { |mode| l += ",#{mode}" }
39
+ test_modes.each { |mode| l += ",#{mode}" } # rubocop:disable Style/CombinableLoops
40
40
  end
41
41
  lines << l
42
42
 
@@ -282,7 +282,7 @@ module OrigenTesters
282
282
  # "Low Limit"
283
283
  l << f((options[:limits][mode] || options[:limits][nil] || {})[:lsl] || 'na')
284
284
  end
285
- test_modes.each do |mode|
285
+ test_modes.each do |mode| # rubocop:disable Style/CombinableLoops
286
286
  # "High Limit"
287
287
  l << f((options[:limits][mode] || options[:limits][nil] || {})[:usl] || 'na')
288
288
  end
@@ -13,15 +13,15 @@ module OrigenTesters
13
13
  @paths = {}
14
14
  end
15
15
 
16
- def filename
16
+ def filename # rubocop:disable Lint/DuplicateMethods
17
17
  @filename || flow.filename.sub('.tf', '.pmfl')
18
18
  end
19
19
 
20
- def subdirectory
20
+ def subdirectory # rubocop:disable Lint/DuplicateMethods
21
21
  @subdirectory ||= 'vectors'
22
22
  end
23
23
 
24
- def paths
24
+ def paths # rubocop:disable Lint/DuplicateMethods
25
25
  { '../vectors' => patterns }
26
26
  end
27
27
 
@@ -1,4 +1,4 @@
1
- require 'set'
1
+ require 'set' # rubocop:disable Lint/RedundantRequireStatement -- needed for Ruby 2.6
2
2
  module OrigenTesters
3
3
  module SmartestBasedTester
4
4
  class Base
@@ -4,6 +4,22 @@ module OrigenTesters
4
4
  class TestMethod
5
5
  FORMAT_TYPES = [:current, :voltage, :time, :frequency, :string, :integer, :double, :boolean, :class, :list_strings, :list_classes]
6
6
 
7
+ def self.parameter_sort_keys
8
+ @@parameter_sort_keys ||= {}
9
+ end
10
+
11
+ def self.installed_dynamic_methods
12
+ @installed_dynamic_methods ||= {}
13
+ end
14
+
15
+ def self.underscored_parameter_names
16
+ @@underscored_parameter_names ||= {}
17
+ end
18
+
19
+ def self.underscore_parameter_name(name)
20
+ underscored_parameter_names[name] ||= name.underscore
21
+ end
22
+
7
23
  # Returns the object representing the test method library that the
8
24
  # given test method is defined in
9
25
  attr_reader :library
@@ -38,8 +54,11 @@ module OrigenTesters
38
54
  unless method_name == :finalize
39
55
  var_name = "@#{method_name}".gsub(/=|\?/, '_')
40
56
  instance_variable_set(var_name, function)
41
- define_singleton_method method_name do |*args|
42
- instance_variable_get(var_name).call(self, *args)
57
+ unless self.class.installed_dynamic_methods[method_name]
58
+ self.class.send(:define_method, method_name) do |*args|
59
+ instance_variable_get(var_name).call(self, *args)
60
+ end
61
+ self.class.installed_dynamic_methods[method_name] = true
43
62
  end
44
63
  end
45
64
  end
@@ -54,19 +73,28 @@ module OrigenTesters
54
73
  allowed = type_default[2]
55
74
  @parameters[attr] = type
56
75
  aliases = [clean_attr]
57
- aliases << clean_attr.underscore if clean_attr.underscore != clean_attr
76
+ underscored_attr = self.class.underscore_parameter_name(clean_attr)
77
+ aliases << underscored_attr if underscored_attr != clean_attr
58
78
  aliases.each do |alias_|
59
- define_singleton_method("#{alias_}=") do |v|
60
- v = v.to_s if v.is_a?(Symbol)
61
- if allowed
62
- unless allowed.include?(v)
63
- fail "Cannot set #{alias_} to #{v}, valid values are: #{allowed.join(', ')}"
79
+ setter = :"#{alias_}="
80
+ unless self.class.installed_dynamic_methods[setter]
81
+ self.class.send(:define_method, setter) do |v|
82
+ v = v.to_s if v.is_a?(Symbol)
83
+ if allowed
84
+ unless allowed.include?(v)
85
+ fail "Cannot set #{alias_} to #{v}, valid values are: #{allowed.join(', ')}"
86
+ end
64
87
  end
88
+ instance_variable_set("@#{clean_attr}", v)
65
89
  end
66
- instance_variable_set("@#{clean_attr}", v)
90
+ self.class.installed_dynamic_methods[setter] = true
67
91
  end
68
- define_singleton_method(alias_) do
69
- instance_variable_get("@#{clean_attr}")
92
+ alias_name = alias_.to_sym
93
+ unless self.class.installed_dynamic_methods[alias_name]
94
+ self.class.send(:define_method, alias_name) do
95
+ instance_variable_get("@#{clean_attr}")
96
+ end
97
+ self.class.installed_dynamic_methods[alias_name] = true
70
98
  end
71
99
  end
72
100
  send("#{clean_attr}=", default)
@@ -75,11 +103,19 @@ module OrigenTesters
75
103
  if options[:methods][:aliases]
76
104
  options[:methods][:aliases].each do |alias_, attr|
77
105
  clean_attr = clean_attr_name(attr)
78
- define_singleton_method("#{alias_}=") do |v|
79
- send("#{clean_attr}=", v)
106
+ setter = :"#{alias_}="
107
+ unless self.class.installed_dynamic_methods[setter]
108
+ self.class.send(:define_method, setter) do |v|
109
+ send("#{clean_attr}=", v)
110
+ end
111
+ self.class.installed_dynamic_methods[setter] = true
80
112
  end
81
- define_singleton_method(alias_) do
82
- send(clean_attr)
113
+ alias_name = alias_.to_sym
114
+ unless self.class.installed_dynamic_methods[alias_name]
115
+ self.class.send(:define_method, alias_name) do
116
+ send(clean_attr)
117
+ end
118
+ self.class.installed_dynamic_methods[alias_name] = true
83
119
  end
84
120
  end
85
121
  end
@@ -89,7 +125,7 @@ module OrigenTesters
89
125
  if respond_to?(accessor)
90
126
  send(accessor, v)
91
127
  else
92
- accessor = "#{k.to_s.underscore}="
128
+ accessor = "#{self.class.underscore_parameter_name(k.to_s)}="
93
129
  send(accessor, v) if respond_to?(accessor)
94
130
  end
95
131
  end
@@ -122,6 +158,7 @@ module OrigenTesters
122
158
 
123
159
  def handle_val_type(val, type, attr)
124
160
  return val if val == '' && !tester.smt8?
161
+
125
162
  case type
126
163
  when :current, 'CURR'
127
164
  "#{val}[A]"
@@ -155,11 +192,13 @@ module OrigenTesters
155
192
  unless val.is_a?(Array)
156
193
  fail "#{val} is not an Array. List_strings must have Array values"
157
194
  end
195
+
158
196
  "##{val}"
159
197
  when :list_classes
160
198
  unless val.is_a?(Array)
161
199
  fail "#{val} is not an Array. List_classes must have Array values"
162
200
  end
201
+
163
202
  "##{val.to_s.gsub('"', '')}"
164
203
  else
165
204
  fail "Unknown type for attribute #{attr}: #{type}"
@@ -189,15 +228,13 @@ module OrigenTesters
189
228
 
190
229
  def sorted_parameters
191
230
  @parameters.sort_by do |name|
192
- if name.is_a?(String)
193
- name
194
- else
195
- if name.to_s[0] == '_'
196
- name.to_s.camelize(:upper)
197
- else
198
- name.to_s.camelize(:lower)
199
- end
200
- end
231
+ self.class.parameter_sort_keys[name] ||= if name.is_a?(String)
232
+ name
233
+ elsif name.to_s[0] == '_'
234
+ name.to_s.camelize(:upper)
235
+ else
236
+ name.to_s.camelize(:lower)
237
+ end
201
238
  end
202
239
  end
203
240
 
@@ -4,6 +4,10 @@ module OrigenTesters
4
4
  class TestMethods
5
5
  # Base class of all test method libraries
6
6
  class BaseTml
7
+ def self.test_method_classes
8
+ @test_method_classes ||= {}
9
+ end
10
+
7
11
  # Returns the test_methods object for the current flow
8
12
  attr_reader :test_methods
9
13
 
@@ -35,10 +39,20 @@ module OrigenTesters
35
39
  private
36
40
 
37
41
  def instantiate_test_method(method, args)
38
- m = platform::TestMethod.new methods: definitions[method].dup,
39
- attrs: (args.first || {}),
40
- type: method,
41
- library: self
42
+ definition = definitions[method]
43
+ base_class = platform::TestMethod
44
+ cache_key = [base_class, definition.object_id]
45
+ klass = BaseTml.test_method_classes[cache_key] ||= begin
46
+ generated_class = Class.new(base_class)
47
+ # Retain the definition so its object ID cannot be recycled while
48
+ # this generated class remains cached.
49
+ generated_class.instance_variable_set(:@test_method_definition, definition)
50
+ generated_class
51
+ end
52
+ m = klass.new methods: definition.dup,
53
+ attrs: (args.first || {}),
54
+ type: method,
55
+ library: self
42
56
  test_methods.add(m)
43
57
  m
44
58
  end
@@ -94,7 +94,7 @@ module OrigenTesters
94
94
  output_dc: {
95
95
  class_name: 'OutputDC',
96
96
  pinlist: [:string, ''],
97
- mode: [:string, 'PROGRAMLOAD', %w(PROGRAMLOAD, PPMU SPMU PPMUTERM SPMUTERM)],
97
+ mode: [:string, 'PROGRAMLOAD', %w(PROGRAMLOAD PPMU SPMU PPMUTERM SPMUTERM)],
98
98
  measure_level: [:string, 'BOTH', %(BOTH LOW HIGH)],
99
99
  force_current_low: [:current, 0],
100
100
  force_current_high: [:current, 0],
@@ -19,7 +19,7 @@ module OrigenTesters
19
19
  @render = true
20
20
  end
21
21
 
22
- def unit=(val)
22
+ def unit=(val) # rubocop:disable Lint/DuplicateMethods
23
23
  case val.to_s.downcase
24
24
  when 'v', 'volts'
25
25
  @unit = 'V'
@@ -11,7 +11,7 @@ module OrigenTesters
11
11
  def initialize(options = {})
12
12
  end
13
13
 
14
- def subdirectory
14
+ def subdirectory # rubocop:disable Lint/DuplicateMethods
15
15
  @subdirectory ||= 'testflow/mfh.testflow.setup'
16
16
  end
17
17
 
@@ -206,12 +206,13 @@ module OrigenTesters
206
206
  def seq_path
207
207
  @seq_path || 'specs'
208
208
  end
209
+
209
210
  # Set the test mode(s) that you want to see in the limits files, supply an array of mode names
210
211
  # to set multiple.
211
212
  def limitfile_test_modes=(val)
212
213
  @limitfile_test_modes = Array(val).map(&:to_s)
213
214
  end
214
- alias_method :limitsfile_test_modes, :limitfile_test_modes=
215
+ alias_method :limitsfile_test_modes, :limitfile_test_modes= # rubocop:disable Lint/DuplicateMethods
215
216
 
216
217
  # return the multiport burst name
217
218
  # provide the name you want to obtain multiport for
@@ -286,7 +287,7 @@ module OrigenTesters
286
287
  super(options)
287
288
  end
288
289
 
289
- unless options_overlay.nil?
290
+ unless options_overlay.nil? # rubocop:disable Lint/EmptyConditionalBody, Lint/RedundantCopDisableDirective
290
291
  # stage = :body if ovly_style == :subroutine # always set stage back to body in case subr overlay was selected
291
292
  end
292
293
  end
@@ -368,12 +369,12 @@ module OrigenTesters
368
369
  # other platforms, such as the J750, is required.
369
370
  def store(*pins)
370
371
  options = pins.last.is_a?(Hash) ? pins.pop : {}
371
- options = { offset: 0
372
- }.merge(options)
372
+ options = { offset: 0 }.merge(options)
373
373
  pins = pins.flatten.compact
374
374
  if pins.empty?
375
375
  fail 'For the V93K you must supply the pins to store/capture'
376
376
  end
377
+
377
378
  pins.each do |pin|
378
379
  pin.restore_state do
379
380
  pin.capture
@@ -395,12 +396,12 @@ module OrigenTesters
395
396
  # $tester.cycle # This is the vector that will be captured
396
397
  def store_next_cycle(*pins)
397
398
  options = pins.last.is_a?(Hash) ? pins.pop : {}
398
- options = {
399
- }.merge(options)
399
+ options = {}.merge(options)
400
400
  pins = pins.flatten.compact
401
401
  if pins.empty?
402
402
  fail 'For the V93K you must supply the pins to store/capture'
403
403
  end
404
+
404
405
  pins.each { |pin| pin.save; pin.capture }
405
406
  # Register this clean up function to be run after the next vector
406
407
  # is generated, cool or what!
@@ -470,8 +471,7 @@ module OrigenTesters
470
471
  # ==== Examples
471
472
  # $tester.handshake # Pass control to the tester for a measurement
472
473
  def handshake(options = {})
473
- options = {
474
- }.merge(options)
474
+ options = {}.merge(options)
475
475
  ::Pattern.split(options)
476
476
  end
477
477
 
@@ -480,8 +480,7 @@ module OrigenTesters
480
480
  # ==== Examples
481
481
  # $tester.freq_count($top.pin(:d_out)) # Freq measure on pin "d_out"
482
482
  def freq_count(_pin, options = {})
483
- options = {
484
- }.merge(options)
483
+ options = {}.merge(options)
485
484
  ::Pattern.split(options)
486
485
  end
487
486
 
@@ -706,8 +705,7 @@ module OrigenTesters
706
705
 
707
706
  # An internal method called by Origen to create the pattern header
708
707
  def pattern_header(options = {})
709
- options = {
710
- }.merge(options)
708
+ options = {}.merge(options)
711
709
  pin_list = ordered_pins.map do |p|
712
710
  if Origen.app.pin_pattern_order.include?(p.id)
713
711
  # specified name overrides pin name
@@ -738,7 +736,7 @@ module OrigenTesters
738
736
  # An internal method called by Origen to generate the pattern footer
739
737
  def pattern_footer(options = {})
740
738
  options = {
741
- end_in_ka: false
739
+ end_in_ka: false
742
740
  }.merge(options)
743
741
  if options[:end_in_ka]
744
742
  Origen.log.warning '93K keep alive not yet implemented!'