origen_testers 0.52.10 → 0.52.12

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: 2ad56d048270f5877bdd6da72571a2b4f04ad2fc045d33d61bc34f7aedd9fdf8
4
- data.tar.gz: 91032b7a9d74d80ccdf9c61e816abfd642d8b187bb5d18c79af6797f94b183e7
3
+ metadata.gz: 4607f1c380b66ebfbec0846cd3e5bcfcbfbb65d1ed94ba1239b088f1625372bf
4
+ data.tar.gz: 1f86cd54c83de4482f40f81b33775b8c216ffced71f77871fd009a94138299ae
5
5
  SHA512:
6
- metadata.gz: 1ef803cd8aea71320aaa9885f827b6a93dc79c7bb2d281e8bde083c75b0e6f3abe2db66c1829c4b65b15f4310494da19a7d3c0ae315ad4b5911df68940b3b454
7
- data.tar.gz: 8e8f3eee5a4740b8966b816359f471eb26958b3a090260bbf105121c1394f0eaab6a70e7537c605af0d7290a7f0912de0a035ceebb7df22a86dc6f701a826653
6
+ metadata.gz: 84308cebe5faddd92e75c410bba7954e90d0ac74ece08af1f4dcc9cf3204f6241286a57209139ae6fedeeecc0373edac6b6a140710c56ba62d274e551e67c070
7
+ data.tar.gz: a4c37216bf06b8206da9e819ff3d5239d57c28784e78942df087d3e0a5d657305b73e181d4b15def1ea174584e63ff19a262446c07a8500d2ebbddb89c2c3f0a
data/config/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module OrigenTesters
2
2
  MAJOR = 0
3
3
  MINOR = 52
4
- BUGFIX = 10
4
+ BUGFIX = 12
5
5
  DEV = nil
6
6
  VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
7
7
  end
@@ -259,6 +259,7 @@ module OrigenTesters::ATP
259
259
  nodes = [name]
260
260
  nodes << id(options[:id]) if options[:id]
261
261
  nodes << n1(:path, path.to_s)
262
+ nodes << n1(:bypass, true) if options[:bypass] == true
262
263
  nodes += children
263
264
  ast = ast.updated :sub_flow, nodes,
264
265
  file: options.delete(:source_file) || source_file,
@@ -24,6 +24,11 @@ module OrigenTesters
24
24
  def initialize(id, options, &block)
25
25
  @id = id
26
26
  @id = @id.symbolize unless id.is_a? Symbol
27
+ if Origen.interface_loaded? && Origen.interface.respond_to?(:default_valid_charz_placements)
28
+ @valid_placements = Origen.interface.default_valid_charz_placements
29
+ else
30
+ @valid_placements = [:inline, :eof]
31
+ end
27
32
  options.each { |k, v| instance_variable_set("@#{k}", v) }
28
33
  (block.arity < 1 ? (instance_eval(&block)) : block.call(self)) if block_given?
29
34
  @name ||= id
@@ -55,7 +60,6 @@ module OrigenTesters
55
60
  fail
56
61
  end
57
62
 
58
- @valid_placements ||= [:inline, :eof]
59
63
  unless @valid_placements.include? @placement
60
64
  Origen.log.error "Profile #{id}: invalid placement value, must be one of: #{@valid_placements}"
61
65
  fail
@@ -20,7 +20,11 @@ module OrigenTesters
20
20
  # @return [Boolean] whether or not to wrap eof charz tests in a group
21
21
  # @!attribute eof_charz_tests_group_name
22
22
  # @return [String, Symbol] group name to be used to for eof charz tests
23
- attr_accessor :charz_stack, :charz_routines, :charz_profiles, :charz_session, :charz_instance, :eof_charz_tests, :skip_group_eof_charz_tests, :eof_charz_tests_group_name
23
+ # @!attribute default_valid_charz_placements
24
+ # @return [Array<Symbol>] (:inline, :eof) list of charz placements used when verifying a new profile is valid
25
+ attr_accessor :charz_stack, :charz_routines, :charz_profiles, :charz_session, :charz_instance,
26
+ :eof_charz_tests, :skip_group_eof_charz_tests, :eof_charz_tests_group_name,
27
+ :default_valid_charz_placements
24
28
 
25
29
  def charz_stack
26
30
  @charz_stack ||= []
@@ -38,6 +42,10 @@ module OrigenTesters
38
42
  @charz_session ||= Session.new
39
43
  end
40
44
 
45
+ def default_valid_charz_placements
46
+ @default_valid_charz_placements ||= [:inline, :eof]
47
+ end
48
+
41
49
  # If there is a current instance present, that should always be used. However when running EOF charz,
42
50
  # the instance to be used is no longer set, so instead of referencing the session, use the one that we've
43
51
  # stored already
@@ -258,6 +258,12 @@ module OrigenTesters
258
258
  options = {
259
259
  name: nil
260
260
  }.merge(options)
261
+
262
+ if !options.key?(:disable_group_on_sub_flow) &&
263
+ Origen.interface.instance_variable_get(:@disable_group_on_sub_flow)
264
+ options[:disable_group_on_sub_flow] = true
265
+ end
266
+
261
267
  file = Pathname.new(file).absolute? ? file : "#{current_dir}/#{file}"
262
268
  file = Origen.file_handler.add_rb_to(file) # add .rb to filename if missing
263
269
  orig_file = "#{file}" # capture original filename possibly without pre-pended underscore
@@ -34,14 +34,21 @@ module Origen
34
34
  if OrigenTesters::Flow.flow_comments
35
35
  top = false
36
36
  name = options[:name] || Pathname.new(file).basename('.rb').to_s.sub(/^_/, '')
37
- # Generate imports as separate sub-flow files on this platform
38
- if tester.v93k? && tester.smt8?
39
- parent, sub_flow = *_sub_flow(name, options, &block)
40
- path = sub_flow.output_file.relative_path_from(Origen.file_handler.output_directory)
41
- parent.atp.sub_flow(sub_flow.atp.raw, path: path.to_s)
37
+ import_options = Origen.generator.option_pipeline.last || {}
38
+ if import_options[:disable_group_on_sub_flow] ||
39
+ # runtime options passed to the import call take priority over Flow.create static options
40
+ (import_options[:disable_group_on_sub_flow].nil? && options[:disable_group])
41
+ _create(options, &block)
42
42
  else
43
- Origen.interface.flow.group(name, description: flow_comments) do
44
- _create(options, &block)
43
+ # Generate imports as separate sub-flow files on this platform
44
+ if tester.v93k? && tester.smt8?
45
+ parent, sub_flow = *_sub_flow(name, options, &block)
46
+ path = sub_flow.output_file.relative_path_from(Origen.file_handler.output_directory)
47
+ parent.atp.sub_flow(sub_flow.atp.raw, path: path.to_s)
48
+ else
49
+ Origen.interface.flow.group(name, description: flow_comments) do
50
+ _create(options, &block)
51
+ end
45
52
  end
46
53
  end
47
54
  else
@@ -62,6 +69,7 @@ module Origen
62
69
 
63
70
  # @api private
64
71
  def _sub_flow(name, options, &block)
72
+ Origen.interface._on_sub_flow(name, options) if Origen.interface.respond_to?(:_on_sub_flow)
65
73
  @top_level_flow ||= Origen.interface.flow
66
74
  parent = Origen.interface.flow
67
75
  # If the parent flow already has a child flow of this name then we need to generate a
@@ -113,9 +121,9 @@ module Origen
113
121
  Origen.app.reload_target!
114
122
  Origen.tester.generating = :program
115
123
  end
116
- opts = Origen.generator.option_pipeline.pop || {}
124
+ options[:sub_flow_options] = Origen.generator.option_pipeline.pop || {}
117
125
  Origen.interface.startup(options) if Origen.interface.respond_to?(:startup)
118
- interface.instance_exec(opts, &block)
126
+ interface.instance_exec(options[:sub_flow_options], &block)
119
127
  Origen.interface.shutdown(options) if Origen.interface.respond_to?(:shutdown)
120
128
  if Origen.tester.doc?
121
129
  Origen.interface.flow.stop_section
@@ -491,22 +491,29 @@ module OrigenTesters
491
491
 
492
492
  def on_loop(node, options = {})
493
493
  start = node.to_a[0]
494
- if start.is_a?(String)
494
+ if start.is_a?(String) || start.is_a?(Symbol)
495
495
  start = generate_flag_name(start)
496
496
  unless smt8?
497
497
  start = "@#{start}"
498
498
  end
499
499
  end
500
500
  stop = node.to_a[1]
501
- if stop.is_a?(String) && smt8?
501
+ if stop.is_a?(String) || stop.is_a?(Symbol)
502
502
  stop = generate_flag_name(stop)
503
- elsif stop.is_a?(String)
504
- fail 'loops with \'stop\' defined as a variable cannot be supported in the defined environments.'
503
+ if tester.smt7?
504
+ stop = "@#{stop}"
505
+ end
505
506
  end
506
507
  step = node.to_a[2]
507
508
  if smt8? && !(step == -1 || step == 1)
508
509
  fail 'SMT8 does not support steps other than -1 or 1.'
509
510
  end
511
+ if step.is_a?(String) || step.is_a?(Symbol)
512
+ step = generate_flag_name(step)
513
+ if tester.smt7?
514
+ step = "@#{step}"
515
+ end
516
+ end
510
517
  if node.to_a[3].nil?
511
518
  fail 'You must supply a loop variable name!'
512
519
  else
@@ -518,7 +525,7 @@ module OrigenTesters
518
525
  end
519
526
  # num = (stop - start) / step + 1
520
527
  # Handle increment/decrement
521
- if step < 0
528
+ if step.is_a?(Numeric) && step < 0
522
529
  compare = '>'
523
530
  incdec = "- #{step * -1}"
524
531
  else
@@ -526,7 +533,10 @@ module OrigenTesters
526
533
  incdec = "+ #{step}"
527
534
  end
528
535
  if tester.smt7?
529
- line "for #{var} = #{start}; #{var} #{compare} #{stop + step} ; #{var} = #{var} #{incdec}; do"
536
+ unless stop.is_a?(String)
537
+ stop = "#{stop + step}"
538
+ end
539
+ line "for #{var} = #{start}; #{var} #{compare} #{stop} ; #{var} = #{var} #{incdec}; do"
530
540
  line "test_number_loop_increment = #{test_num_inc}"
531
541
  line '{'
532
542
  @indent += 1
@@ -56,6 +56,18 @@ module OrigenTesters
56
56
  end
57
57
  alias_method :on_unless_job, :on_if_job
58
58
 
59
+ def on_whenever(node)
60
+ flow_var, *nodes = *node
61
+ [flow_var].flatten.each do |f|
62
+ if [String, Symbol].include?(f.value.class)
63
+ add generate_flag_name(f.value.to_s), :referenced_flags
64
+ end
65
+ end
66
+ process_all(nodes)
67
+ end
68
+ alias_method :on_whenever_all, :on_whenever
69
+ alias_method :on_whenever_any, :on_whenever
70
+
59
71
  def on_if_flag(node)
60
72
  flag, *nodes = *node
61
73
  [flag].flatten.each do |f|
@@ -109,6 +121,17 @@ module OrigenTesters
109
121
  add flag, :set_enables
110
122
  end
111
123
 
124
+ def on_loop(node)
125
+ start, stop, step, loop_var, test_inc, *nodes = *node
126
+ [start, stop, step, loop_var].each do |type|
127
+ if [String, Symbol].include?(type.class) && tester.smt8?
128
+ add generate_flag_name(type), :referenced_flags
129
+ end
130
+ end
131
+
132
+ process_all(nodes)
133
+ end
134
+
112
135
  private
113
136
 
114
137
  def in_sub_flow?
@@ -95,9 +95,18 @@ module OrigenTesters
95
95
  sub_flow = sub_flow_from(node)
96
96
  @sub_flows ||= {}
97
97
  path = Pathname.new(node.find(:path).value)
98
+ bypass = false
99
+ if node.find(:bypass)
100
+ if node.find(:bypass).value.to_s.match(/true/)
101
+ bypass = true
102
+ end
103
+ end
98
104
  name = path.basename('.*').to_s
99
105
  path = Origen.interface.sub_flow_path_overwrite(path) if Origen.interface.respond_to? :sub_flow_path_overwrite
100
- @sub_flows[name] = "#{path.dirname}.#{name}".gsub(/(\/|\\)/, '.')
106
+ @sub_flows[name] = {
107
+ bypass: bypass,
108
+ path: "#{path.dirname}.#{name}".gsub(/(\/|\\)/, '.')
109
+ }
101
110
  # Pass down all input variables before executing
102
111
  if sub_flow.input_variables.size > 0 && tester.flow_variable_grouping
103
112
  line "// #{name} sub-flow input variables"
@@ -31,8 +31,12 @@ flow <%= flow_name %> {
31
31
  % auxiliary_flows.each do |name, path|
32
32
  flow <%= name %> calls <%= path %> {}
33
33
  % end
34
- % sub_flows.each do |name, path|
35
- flow <%= name %> calls <%= path %> { }
34
+ % sub_flows.each do |name, settings|
35
+ flow <%= name %> calls <%= settings[:path] %> {<%=" }" unless settings[:bypass]%>
36
+ % if settings[:bypass]
37
+ bypass = true;
38
+ }
39
+ % end
36
40
  % end
37
41
  }
38
42
 
@@ -165,6 +165,19 @@ module OrigenTesters
165
165
  l
166
166
  end
167
167
  # rubocop:enable Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters.
168
+
169
+ def wrap_if_string(value)
170
+ if value.is_a?(String)
171
+ if value =~ /setupRef(.*)/
172
+ # Do not wrap setupRef calls in quotes
173
+ return value
174
+ else
175
+ "\"#{value}\""
176
+ end
177
+ else
178
+ value
179
+ end
180
+ end
168
181
  end
169
182
  end
170
183
  end
@@ -60,6 +60,7 @@ module OrigenTesters
60
60
  param_name0: [:string, ''],
61
61
  param_list_strings: [:list_strings, %w(E1 E2)],
62
62
  param_list_classes: [:list_classes, %w(E1 E2)],
63
+ param_func_call: [:string, 'setupRef(FQN)'],
63
64
  'param_group.param0': [:string, ''],
64
65
  param_name1: [{
65
66
  param_name_int: [:integer, 0],
@@ -0,0 +1,5 @@
1
+ Flow.create do |options|
2
+
3
+ test :"#{options[:status]}_#{options[:type]}"
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ Flow.create(disable_group: true) do |options|
2
+
3
+ test :"#{options[:status]}_#{options[:type]}"
4
+
5
+ end
data/program/prb1.rb CHANGED
@@ -19,5 +19,10 @@ Flow.create interface: 'OrigenTesters::Test::Interface', flow_description: 'Prob
19
19
  # Test that a reference to a deeply nested test works (mainly for SMT8)
20
20
  test :on_deep_1, if_failed: :deep_test, test_text: "some_custom_text"
21
21
 
22
+ import 'components/default_group_import', type: 'import_option_disable', disable_group_on_sub_flow: true, status: :ungrouped
23
+ import 'components/default_no_group_import', type: 'flow_create_option_disable', status: :ungrouped
24
+ import 'components/default_no_group_import', type: 'flow_create_option_override', disable_group_on_sub_flow: false, status: :grouped
25
+
26
+
22
27
  pass 1, description: "Good die!", softbin: 1
23
28
  end
@@ -311,4 +311,87 @@ Flow.create(interface: 'MyApp:Interface') do
311
311
  end
312
312
  ~~~
313
313
 
314
+ #### Custom Placement Example
315
+
316
+ For an example of adding new placements lets say we want to insert a charz test if the parent
317
+ test fails, but not until after a later test in the flow "testB" has ran. To do so:
318
+
319
+ * The profile needs to know that this new placement is valid and then target it
320
+ * The charz tests themselves need a placement specific constructor method that collects the results for later use
321
+ * Lastly, a method for calling the collected constructors and inserting them into the flow
322
+
323
+ ##### Adding valid placements
324
+
325
+ To add new valid placements, you can do so either on a per-profile basis or across all profiles
326
+ for the current interface:
327
+
328
+ ~~~ruby
329
+ # Per-Profile
330
+ add_charz_profile :my_profile |p|
331
+ # ...
332
+ p.valid_placements = [:on_fail_after_testB]
333
+ p.placement = :on_fail_after_testB
334
+ end
335
+
336
+ # Across Interface via interface instance variable:
337
+ @default_valid_charz_placements = [:inline, :eof, :on_fail_after_testB]
338
+
339
+ add_charz_profile :my_profile |p|
340
+ # ...
341
+ p.placement = :on_fail_after_testB
342
+ end
343
+ ~~~
344
+
345
+ ##### Placement Constructor and Collection
346
+
347
+ So that the charz API knows how to handle this placement, it will expect a method to be defined
348
+ named as `create_<placement>_charz_tests(options, &block)`. This method will need to store the
349
+ current context in a manner that can be called later. To collect multiple tests, we'll use
350
+ an interface instance variable.
351
+
352
+ ~~~ruby
353
+ # collect the current instance and options into a proc,
354
+ # which will be stored in @on_fail_after_testB_charz_tests to be called later
355
+ def create_on_fail_after_testB_charz_tests(options, &block)
356
+ # we'll need to save the current charz instance as it is now as its used in the test creation
357
+ current_instance = charz_instance.clone
358
+
359
+ # Store the setup instructions in a proc to be called later
360
+ @on_fail_after_testB_charz_tests ||= []
361
+ @on_fail_after_testB_charz_tests << proc do
362
+ # these are existing methods in the charz API
363
+ set_charz_instance(current_instance)
364
+ create_charz_group(options, &block)
365
+ end
366
+ end
367
+ ~~~
368
+
369
+ ##### Inserting collected tests into the flow
370
+
371
+ Now all thats left is to define the generator to call the collected tests, then
372
+ we can apply our charz profile to the tests of interest and call the generator after testB
373
+ has ran.
374
+
375
+ ~~~ruby
376
+ # simple generator to call each collected proc
377
+ def generate_on_fail_after_testB_charz_tests
378
+ @on_fail_after_testB_charz_tests.map(&:call)
379
+ @on_fail_after_testB_charz_tests = [] # clear to prevent accidental repeats
380
+ end
381
+ ~~~
382
+
383
+ And then finally in the flow:
384
+
385
+ ~~~ruby
386
+ charz_on :my_profile do
387
+ func :test_i_want_to_charz1, id: :t1
388
+ func :test_i_want_to_charz2, id: :t2
389
+ end
390
+
391
+ # ...
392
+
393
+ func :testB
394
+ generate_on_fail_after_testB_charz_tests
395
+ ~~~
396
+
314
397
  % end
@@ -406,8 +406,6 @@ Decrementing loops, having `from:` value > `to:` value and using negative `step:
406
406
 
407
407
  ##### Loop Rules For Each Environment
408
408
 
409
- `SMT7` cannot support a variable stop location. Only the `from:` parameter is allowed to be a variable.
410
-
411
409
  `SMT8` cannot have a step other than -1 or 1. The limitations of the range flow restrict those steps.
412
410
  The `to:` parameter can be a flow variable just like `from:`.
413
411
 
@@ -110,6 +110,38 @@ end
110
110
 
111
111
  This same API may be used to implement similar features on other platforms in future, but for now only the V93K is implemented.
112
112
 
113
+ #### Grouping on sub-flows
114
+
115
+ By default, imported sub-flows are wrapped in a group named by the passed `:name` option if provided, otherwise the name of the file is used.
116
+
117
+ ~~~ruby
118
+ import 'my_sub_flow' # sub flow contains single test 'my_test'
119
+
120
+ # Results in the following output in the .tf file:
121
+ # {
122
+ # run(my_test);
123
+ # }, open,"my_sub_flow", ""
124
+ ~~~
125
+
126
+ To disable this behavior, you can either pass to your import call the option `disable_group_on_sub_flow: true`,
127
+ or set `disable_group: true` in your Flow.create() parameters:
128
+
129
+ ~~~ruby
130
+ # Pass option to import
131
+ import 'my_sub_flow', { disable_group_on_sub_flow: true }
132
+
133
+ # Or set in Flow.create() in _my_sub_flow.rb
134
+ Flow.create(disable_group: true) do
135
+ func :my_test
136
+ end
137
+
138
+ # Results in the following output in the .tf file:
139
+ # run(my_test);
140
+ ~~~
141
+
142
+ Note that the import option takes priority, so if `Flow.create(disable_group: true)`
143
+ is set but import is passed `disable_group_on_sub_flow: false` then a group will still be created.
144
+
113
145
  ### Test Name Uniqueness
114
146
 
115
147
  Test (suite) naming collisions can occur when importing multiple independent test flow modules into a
@@ -55,7 +55,11 @@ Contains the limits tables for all flows.
55
55
  A top-level test program flow file in Origen will generate a correspondingly named file in the `flows/` directory,
56
56
  where the name of the generated file is the upper-cased version of the source file name.
57
57
  If the flow imports sub-flows or contains groups, then those will be contained in a directory named after the
58
- lower-cased version of the flow name.
58
+ lower-cased version of the flow name. For sub-flow imports, this can be disabled by passing the option
59
+ `disable_sub_flow_on_group: true` to the import call, or by setting the disable_group option in your sub-flow:
60
+ `Flow.create(disable_group: true)`. Note that if both are provided, the import option value will take priority.
61
+ When the group is disabled this way, the content of the sub-flow will simply be inserted as if it was defined
62
+ in the calling flow instead of a sub flow.
59
63
 
60
64
  ##### limits/
61
65
 
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.52.10
4
+ version: 0.52.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen McGinty
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-03-20 00:00:00.000000000 Z
11
+ date: 2025-08-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: origen
@@ -542,6 +542,8 @@ files:
542
542
  - program/basic_interface.rb
543
543
  - program/charz.rb
544
544
  - program/components/_deep_nested.rb
545
+ - program/components/_default_group_import.rb
546
+ - program/components/_default_no_group_import.rb
545
547
  - program/components/_prb1_main.rb
546
548
  - program/components/_prb2_main.rb
547
549
  - program/components/_small.rb
@@ -618,7 +620,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
618
620
  - !ruby/object:Gem::Version
619
621
  version: '0'
620
622
  requirements: []
621
- rubygems_version: 3.1.6
623
+ rubygems_version: 3.2.3
622
624
  signing_key:
623
625
  specification_version: 4
624
626
  summary: This plugin provides Origen tester models to drive ATE type testers like