origen_testers 0.51.5 → 0.52.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/config/commands.rb +1 -1
- data/config/version.rb +2 -2
- data/lib/origen_testers/atp/flow.rb +39 -0
- data/lib/origen_testers/atp/flow_api.rb +2 -2
- data/lib/origen_testers/smartest_based_tester/base/flow.rb +61 -17
- data/lib/origen_testers/smartest_based_tester/base/generator.rb +5 -1
- data/lib/origen_testers/smartest_based_tester/base/processors/extract_flow_vars.rb +18 -1
- data/lib/origen_testers/smartest_based_tester/base/test_method.rb +25 -3
- data/lib/origen_testers/smartest_based_tester/base/variables_file.rb +1 -1
- data/lib/origen_testers/smartest_based_tester/base.rb +28 -4
- data/lib/origen_testers/smartest_based_tester/v93k_smt8/flow.rb +69 -5
- data/lib/origen_testers/smartest_based_tester/v93k_smt8/limits_workbook.rb +28 -26
- data/lib/origen_testers/smartest_based_tester/v93k_smt8/templates/template.flow.erb +3 -0
- data/lib/origen_testers/smartest_based_tester/v93k_smt8/test_suite.rb +109 -4
- data/lib/origen_testers/test/custom_test_interface.rb +36 -2
- data/lib/origen_testers/test/interface.rb +123 -0
- data/program/components/_prb1_main.rb +9 -0
- data/program/custom_tests.rb +3 -0
- data/program/flow_control.rb +37 -8
- data/templates/origen_guides/program/flowapi.md.erb +26 -1
- data/templates/origen_guides/program/v93k.md.erb +14 -0
- data/templates/origen_guides/program/v93ksmt8.md.erb +25 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eb1671039082e3f1856ec1facd0861776bf7ed44b07be01103028a21e20962cc
|
4
|
+
data.tar.gz: a9855748f37e09b0f80d86c42c111c3577eec987e49336ad43b772fb267c8a36
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b647195f53446e14b390662d93ebe7207aba5f8a90af089cad0e5368f0ee9f8347db00c7440ea497509b6b565067ddebf8b4e0e4e3f47a3f4f1d50e6aa16784b
|
7
|
+
data.tar.gz: 2ec5f3ed1581bdaac66f115c8f0950e0e965d40c7b369da6b3b16d405c7cddfd337fa5f9b088c7bbb54ee3d51166b5904a43aca8c2a1055c12170bb7bd451c10
|
data/config/commands.rb
CHANGED
@@ -200,7 +200,7 @@ when "examples", "test"
|
|
200
200
|
puts
|
201
201
|
puts "To approve any diffs in the reference.list files run the following command:"
|
202
202
|
puts
|
203
|
-
platforms = %w(j750 j750_literals j750_hpt ultraflex ultraflex_literals v93k v93k_multiport v93k_enable_flow v93k_disable_flow v93k_limits_file v93k_global v93k_smt8) # put here the various platforms used in examples/program_generator.rb
|
203
|
+
platforms = %w(j750 j750_literals j750_hpt ultraflex ultraflex_literals v93k v93k_multiport v93k_enable_flow v93k_disable_flow v93k_limits_file v93k_global v93k_smt8 v93k_flowgrouping) # put here the various platforms used in examples/program_generator.rb
|
204
204
|
reflist_command = ''
|
205
205
|
platforms.each do |platform|
|
206
206
|
unless reflist_command == ''
|
data/config/version.rb
CHANGED
@@ -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
|
-
|
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(
|
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(
|
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
|
-
|
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
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
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
|
-
|
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, :
|
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
|
139
|
-
@create_limits_file =
|
148
|
+
if options.key?(:create_limits_file)
|
149
|
+
@create_limits_file = options[:create_limits_file]
|
140
150
|
else
|
141
|
-
if
|
142
|
-
@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
|
-
|
100
|
-
|
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
|
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
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
x
|
88
|
-
|
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
|
@@ -7,11 +7,19 @@ module OrigenTesters
|
|
7
7
|
%w(
|
8
8
|
name
|
9
9
|
comment
|
10
|
+
bypass
|
10
11
|
|
11
12
|
test_method
|
12
13
|
|
13
14
|
pattern
|
14
15
|
specification
|
16
|
+
seq
|
17
|
+
burst
|
18
|
+
|
19
|
+
spec_namespace
|
20
|
+
spec_path
|
21
|
+
seq_namespace
|
22
|
+
seq_path
|
15
23
|
)
|
16
24
|
|
17
25
|
ALIASES = {
|
@@ -22,6 +30,7 @@ module OrigenTesters
|
|
22
30
|
DEFAULTS = {
|
23
31
|
}
|
24
32
|
|
33
|
+
NO_STRING_TYPES = [:list_strings, :list_classes, :class]
|
25
34
|
# Generate accessors for all attributes and their aliases
|
26
35
|
ATTRS.each do |attr|
|
27
36
|
if attr == 'name' || attr == 'pattern'
|
@@ -42,24 +51,120 @@ module OrigenTesters
|
|
42
51
|
end
|
43
52
|
|
44
53
|
def lines
|
54
|
+
# Initialize path setting
|
55
|
+
# prefix = test method library prefix expectations
|
56
|
+
# self.spec_namespace = instance override from the tester specification namespace
|
57
|
+
# self.seq_namespace = instance override from the tester sequence namespace
|
58
|
+
# self.spec_path = instance override from the tester specification path
|
59
|
+
# self.seq_path = instance override from the tester sequence path
|
60
|
+
if Origen.interface.respond_to? :custom_smt8_prefix
|
61
|
+
prefix = Origen.interface.custom_smt8_prefix
|
62
|
+
else
|
63
|
+
prefix = 'measurement.'
|
64
|
+
end
|
65
|
+
spec_namespace = self.spec_namespace || tester.package_namespace
|
66
|
+
spec_path = self.spec_path || tester.spec_path
|
67
|
+
seq_namespace = self.seq_namespace || tester.package_namespace
|
68
|
+
seq_path = self.seq_path || tester.seq_path
|
45
69
|
l = []
|
46
|
-
l << "suite #{name} calls #{test_method.klass} {"
|
70
|
+
l << "suite #{name} calls #{test_method.klass[0].downcase + test_method.klass[1..-1]} {"
|
47
71
|
if pattern && !pattern.to_s.empty?
|
48
|
-
l << "
|
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 << "
|
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
|
-
|
91
|
+
if param.last.is_a? Hash
|
92
|
+
if !test_method.format(name).nil? && !test_method.format(name).is_a?(Hash)
|
93
|
+
fail "#{name} parameter structure requires a Hash but value provided is #{test_method.format(name).class}"
|
94
|
+
elsif test_method.format(name).nil? && tester.print_all_params
|
95
|
+
l = add_nested_params(l, name, 'param0', {}, param.last, 1)
|
96
|
+
elsif test_method.format(name).nil?
|
97
|
+
# Do nothing
|
98
|
+
else
|
99
|
+
test_method.format(name).each do |key, meta_hash|
|
100
|
+
l = add_nested_params(l, name, key, meta_hash, param.last, 1)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
elsif NO_STRING_TYPES.include?(param.last) && test_method.format(param[0]).is_a?(String) && !test_method.format(param[0]).empty?
|
104
|
+
l << " #{name} = #{test_method.format(param[0])};"
|
105
|
+
else
|
106
|
+
l << " #{name} = #{wrap_if_string(test_method.format(param[0]))};"
|
107
|
+
end
|
59
108
|
end
|
60
109
|
l << '}'
|
61
110
|
l
|
62
111
|
end
|
112
|
+
|
113
|
+
# rubocop:disable Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters.
|
114
|
+
def add_nested_params(l, name, key, value_hash, nested_params, nested_loop_count)
|
115
|
+
nested_params_accepted_keys = []
|
116
|
+
skip_keys = []
|
117
|
+
unless value_hash.nil?
|
118
|
+
unless value_hash.is_a?(Hash)
|
119
|
+
fail "Provided value to nested params was not a Hash. Instead the value was #{value_hash.class}"
|
120
|
+
end
|
121
|
+
dynamic_spacing = ' ' * (4 * nested_loop_count)
|
122
|
+
l << "#{dynamic_spacing}#{name}[#{key}] = {" unless name.nil?
|
123
|
+
nested_params.each do |nested_param|
|
124
|
+
# Guarentee hash is using all symbol keys
|
125
|
+
# Since we cannot guarentee ruby version is greater than 2.5, we have to use an older syntax to
|
126
|
+
value_hash = value_hash.inject({}) { |memo, (k, v)| memo[k.to_sym] = v; memo }
|
127
|
+
nested_key = nested_param.first.to_sym
|
128
|
+
nested_key_underscore = nested_key.to_s.underscore.to_sym
|
129
|
+
nested_params_accepted_keys << nested_key
|
130
|
+
nested_params_accepted_keys << nested_key_underscore
|
131
|
+
# We cannot create nested member functions with aliases
|
132
|
+
# Requirement for hash parameter passing is to pass one of the key types and not both
|
133
|
+
if value_hash.keys.include?(nested_key) &&
|
134
|
+
value_hash.keys.include?(nested_key_underscore) && nested_key != nested_key_underscore
|
135
|
+
fail 'You are using a hash based test method and provided both the parameter name and alias name.'
|
136
|
+
end
|
137
|
+
nested_key = nested_key_underscore if value_hash.keys.include?(nested_key_underscore)
|
138
|
+
if nested_param.last.first.is_a?(Hash) && value_hash[nested_key].is_a?(Hash)
|
139
|
+
value_hash[nested_key].each do |inner_key, inner_meta_hash|
|
140
|
+
l = add_nested_params(l, nested_param.first, inner_key, value_hash.dig(nested_key, inner_key), nested_param.last.first, nested_loop_count + 1)
|
141
|
+
skip_keys << nested_key
|
142
|
+
end
|
143
|
+
elsif nested_param.last.first.is_a?(Hash) && tester.print_all_params
|
144
|
+
l = add_nested_params(l, nested_param.first, 'param0', {}, nested_param.last.first, nested_loop_count + 1)
|
145
|
+
end
|
146
|
+
type = nested_param.last.first
|
147
|
+
if NO_STRING_TYPES.include?(nested_param.last.first) && value_hash[nested_key] && !skip_keys.include?(nested_key)
|
148
|
+
l << " #{dynamic_spacing}#{nested_param.first} = #{test_method.handle_val_type(value_hash[nested_key], type, nested_param.first)};"
|
149
|
+
elsif value_hash[nested_key] && !skip_keys.include?(nested_key)
|
150
|
+
l << " #{dynamic_spacing}#{nested_param.first} = #{wrap_if_string(test_method.handle_val_type(value_hash[nested_key], type, nested_param.first))};"
|
151
|
+
elsif NO_STRING_TYPES.include?(nested_param.last.first) && !nested_param.last.last.is_a?(Hash) && tester.print_all_params && !skip_keys.include?(nested_key)
|
152
|
+
l << " #{dynamic_spacing}#{nested_param.first} = #{test_method.handle_val_type(nested_param.last.last, type, nested_param.first)};"
|
153
|
+
elsif !nested_param.last.last.is_a?(Hash) && tester.print_all_params && !skip_keys.include?(nested_key)
|
154
|
+
l << " #{dynamic_spacing}#{nested_param.first} = #{wrap_if_string(test_method.handle_val_type(nested_param.last.last, type, nested_param.first))};"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
l << "#{dynamic_spacing}};" unless name.nil?
|
158
|
+
# Sanity check there are not overpassed parameters
|
159
|
+
value_hash.keys.each do |nested_key|
|
160
|
+
unless nested_params_accepted_keys.include?(nested_key.to_sym)
|
161
|
+
fail "You provided a parameter \'#{nested_key}\' that was not an accepted parameter to the hash parameter \'#{name}\'"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
l
|
166
|
+
end
|
167
|
+
# rubocop:enable Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters.
|
63
168
|
end
|
64
169
|
end
|
65
170
|
end
|
@@ -33,11 +33,23 @@ module OrigenTesters
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
+
def custom_hash(name, options = {})
|
37
|
+
name = "custom_hash_#{name}".to_sym
|
38
|
+
if tester.v93k? && tester.smt8?
|
39
|
+
ti = test_methods.my_tml.test_hash
|
40
|
+
ti.my_arg_hash = {
|
41
|
+
my_param_name: {
|
42
|
+
my_arg2: 1
|
43
|
+
}
|
44
|
+
}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
36
48
|
private
|
37
49
|
|
38
50
|
def add_custom_tml
|
39
51
|
add_tml :my_tml,
|
40
|
-
test_a:
|
52
|
+
test_a: {
|
41
53
|
# Parameters can be defined with an underscored symbol as the name, this can be used
|
42
54
|
# if the C++ implementation follows the standard V93K convention of calling the attribute
|
43
55
|
# the camel cased version, starting with a lower-cased letter, i.e. 'testerState' in this
|
@@ -79,10 +91,32 @@ module OrigenTesters
|
|
79
91
|
end
|
80
92
|
}
|
81
93
|
},
|
82
|
-
test_b:
|
94
|
+
test_b: {
|
83
95
|
render_limits_in_tf: false,
|
84
96
|
my_arg0: [:string, ''],
|
85
97
|
my_arg1: [:string, 'b_default_value']
|
98
|
+
},
|
99
|
+
test_hash: {
|
100
|
+
# Parameters can be defined with an underscored symbol as the name, this can be used
|
101
|
+
# if the C++ implementation follows the standard V93K convention of calling the attribute
|
102
|
+
# the camel cased version, starting with a lower-cased letter, i.e. 'testerState' in this
|
103
|
+
# first example.
|
104
|
+
# The attribute definition has two required parameters, the type and the default value.
|
105
|
+
# The type can be :string, :current, :voltage, :time, :frequency, or :integer
|
106
|
+
# An optional 3rd parameter can be supplied to give an array of allowed values. If supplied,
|
107
|
+
# Origen will raise an error upon an attempt to set it to an unlisted value.
|
108
|
+
tester_state: [:string, 'CONNECTED', %w(CONNECTED UNCHANGED)],
|
109
|
+
test_name: [:string, 'Functional'],
|
110
|
+
my_list_string: [:list_strings, %w(E1 E2)],
|
111
|
+
my_list_class: [:list_classes, %w(E1 E2)],
|
112
|
+
my_arg_hash: [{
|
113
|
+
my_arg0: [:string, ''],
|
114
|
+
my_arg1: [:string, 'a_default_value'],
|
115
|
+
my_arg2: [:integer, 0],
|
116
|
+
my_arg2: [:list_strings, %w(E1 E2)],
|
117
|
+
my_arg3: [:list_classes, %w(E1 E2)]
|
118
|
+
}]
|
119
|
+
# Define any methods you want the test method to have
|
86
120
|
}
|
87
121
|
end
|
88
122
|
|
@@ -12,6 +12,67 @@ module OrigenTesters
|
|
12
12
|
def initialize(options = {})
|
13
13
|
@environment = options[:environment]
|
14
14
|
add_charz
|
15
|
+
add_my_tml if tester.v93k?
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_my_tml
|
19
|
+
add_tml :my_hash_tml,
|
20
|
+
class_name: 'MyTmlHashNamespace',
|
21
|
+
|
22
|
+
# Here is a test definition.
|
23
|
+
# The identifier should be lower-cased and underscored, in-keeping with Ruby naming conventions.
|
24
|
+
# By default the class name will be the camel-cased version of this identifier, so 'myTest' in
|
25
|
+
# this case.
|
26
|
+
my_hash_test: {
|
27
|
+
# [OPTIONAL] The C++ test method class name can be overridden from the default like this:
|
28
|
+
class_name: 'MyHashExampleClass',
|
29
|
+
# [OPTIONAL] If the test method does not require a definition in the testmethodlimits section
|
30
|
+
# of the .tf file, you can suppress like this:
|
31
|
+
# render_limits_in_file: false,
|
32
|
+
# Parameters can be defined with an underscored symbol as the name, this can be used
|
33
|
+
# if the C++ implementation follows the standard V93K convention of calling the attribute
|
34
|
+
# the camel cased version, starting with a lower-cased letter, i.e. 'testerState' in this
|
35
|
+
# first example.
|
36
|
+
# The attribute definition has two required parameters, the type and the default value.
|
37
|
+
# The type can be :string, :current, :voltage, :time, :frequency, integer, :double or :boolean
|
38
|
+
pin_list: [:string, ''],
|
39
|
+
samples: [:integer, 1],
|
40
|
+
precharge_voltage: [:voltage, 0],
|
41
|
+
settling_time: [:time, 0],
|
42
|
+
# An optional parameter that sets the limits name in the 'testmethodlimits' section
|
43
|
+
# of the generated .tf file. Defaults to 'Functional' if not provided.
|
44
|
+
test_name: [:string, 'HashExample'],
|
45
|
+
# An optional 3rd parameter can be supplied to provide an array of allowed values. If supplied,
|
46
|
+
# Origen will raise an error upon an attempt to set it to an unlisted value.
|
47
|
+
tester_state: [:string, 'CONNECTED', %w(CONNECTED UNCHANGED DISCONNECTED)],
|
48
|
+
force_mode: [:string, 'VOLT', %w(VOLT CURR)],
|
49
|
+
# The name of another parameter can be supplied as the type argument, meaning that the type
|
50
|
+
# here will be either :current or :voltage depending on the value of :force_mode
|
51
|
+
# force_value: [:force_mode, 3800.mV],
|
52
|
+
# In cases where the C++ library has deviated from standard attribute naming conventions
|
53
|
+
# (camel-cased with lower cased first character), the absolute attribute name can be given
|
54
|
+
# as a string.
|
55
|
+
# The Origen accessor for these will be the underscored version, with '.' characters
|
56
|
+
# converted to underscores e.g. tm.an_unusual_name
|
57
|
+
'hashParameter': [{ param_name0: [:string, 'NO'], param_name1: [:integer, 0] }],
|
58
|
+
'hashParameter2': [{ param_name0: [:string, 'NO'], param_name1: [:integer, 0] }],
|
59
|
+
'nestedHashParameter': [{
|
60
|
+
param_name0: [:string, ''],
|
61
|
+
param_list_strings: [:list_strings, %w(E1 E2)],
|
62
|
+
param_list_classes: [:list_classes, %w(E1 E2)],
|
63
|
+
param_name1: [{
|
64
|
+
param_name0: [:integer, 0],
|
65
|
+
param_list_strings: [:list_strings, %w(E1 E2)],
|
66
|
+
param_list_classes: [:list_classes, %w(E1 E2)]
|
67
|
+
}]
|
68
|
+
}],
|
69
|
+
'nestedHashParameter2': [{
|
70
|
+
param_name0: [:string, ''],
|
71
|
+
param_name1: [{
|
72
|
+
param_name0: [:integer, 0]
|
73
|
+
}]
|
74
|
+
}]
|
75
|
+
}
|
15
76
|
end
|
16
77
|
|
17
78
|
def add_charz
|
@@ -218,6 +279,68 @@ module OrigenTesters
|
|
218
279
|
end
|
219
280
|
end
|
220
281
|
|
282
|
+
def my_hash_test(name, options = {})
|
283
|
+
number = options[:number]
|
284
|
+
|
285
|
+
if tester.v93k? && tester.smt8?
|
286
|
+
block_loop(name, options) do |block, i|
|
287
|
+
options[:number] = number + i if number && i
|
288
|
+
tm = test_methods.my_hash_tml.my_hash_test
|
289
|
+
tm.hashParameter = {
|
290
|
+
param1: {}
|
291
|
+
}
|
292
|
+
tm.nestedHashParameter = {
|
293
|
+
my_param_name0: {
|
294
|
+
param_name0: 'hello',
|
295
|
+
param_name1: {
|
296
|
+
my_param_name1: {
|
297
|
+
param_name0: 1
|
298
|
+
},
|
299
|
+
my_param_name2: {
|
300
|
+
param_name0: 2
|
301
|
+
},
|
302
|
+
my_param_name3: {
|
303
|
+
param_name0: 3
|
304
|
+
}
|
305
|
+
}
|
306
|
+
}
|
307
|
+
}
|
308
|
+
tm.nestedHashParameter2 = {
|
309
|
+
my_param_name4: {
|
310
|
+
param_name0: 'goodbye'
|
311
|
+
},
|
312
|
+
my_param_name5: {
|
313
|
+
param_name0: 'goodbye forever'
|
314
|
+
}
|
315
|
+
}
|
316
|
+
ts = test_suites.run(name, options)
|
317
|
+
ts.test_method = tm
|
318
|
+
ts.spec = options.delete(:pin_levels) if options[:pin_levels]
|
319
|
+
ts.spec ||= 'specs.Nominal'
|
320
|
+
flow.test ts, options
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
def my_override_spec_test(name, options = {})
|
326
|
+
number = options[:number]
|
327
|
+
|
328
|
+
if tester.v93k? && tester.smt8?
|
329
|
+
tm = test_methods.ac_tml.ac_test.functional_test
|
330
|
+
ts = test_suites.run(name, options)
|
331
|
+
ts.test_method = tm
|
332
|
+
ts.spec = options.delete(:pin_levels) if options[:pin_levels]
|
333
|
+
ts.spec ||= 'specs.Nominal'
|
334
|
+
ts.pattern = 'pat1'
|
335
|
+
ts.burst = 'sequence1'
|
336
|
+
ts.spec_path = 'myCustomSpecPath'
|
337
|
+
ts.seq_path = 'myCustomSeqPath'
|
338
|
+
ts.spec_namespace = 'myCustomSpecNamespace'
|
339
|
+
ts.seq_namespace = 'myCustomSeqNamespace'
|
340
|
+
flow.test ts, options
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
221
344
|
def block_loop(name, options)
|
222
345
|
if options[:by_block]
|
223
346
|
if tester.j750? || tester.uflex?
|
@@ -1,4 +1,10 @@
|
|
1
1
|
Flow.create do |options|
|
2
|
+
if tester.smt8?
|
3
|
+
my_hash_test :hash_example, number: 8000
|
4
|
+
my_override_spec_test :spec_override_example, number: 8010
|
5
|
+
add_auxiliary_flow :POWERDOWN, path: 'testflow.POWERDOWN'
|
6
|
+
end
|
7
|
+
|
2
8
|
# Instantiate tests via the
|
3
9
|
# interface
|
4
10
|
func 'program_ckbd', tname: 'PGM_CKBD', tnum: 1000, bin: 100, soft_bin: 1100
|
@@ -240,6 +246,9 @@ Flow.create do |options|
|
|
240
246
|
log 'Passing test flags works as expected'
|
241
247
|
func :test_with_no_flags, bypass: false, output_on_pass: false, output_on_fail: false, value_on_pass: false, value_on_fail: false, per_pin_on_pass: false, per_pin_on_fail: false, number: 6020
|
242
248
|
func :test_with_flags, bypass: true, output_on_pass: true, output_on_fail: true, value_on_pass: true, value_on_fail: true, per_pin_on_pass: true, per_pin_on_fail: true, number: 6030
|
249
|
+
elsif tester.smt8?
|
250
|
+
func :test_with_no_flags, bypass: false, number: 6020
|
251
|
+
func :test_with_flags, bypass: true, number: 6030
|
243
252
|
end
|
244
253
|
|
245
254
|
if tester.smt7?
|
data/program/custom_tests.rb
CHANGED
data/program/flow_control.rb
CHANGED
@@ -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?
|
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
|
-
|
364
|
-
|
365
|
-
|
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
|
-
|
375
|
-
loop from:
|
376
|
-
loop from: 1, to:
|
377
|
-
|
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
|
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.
|
4
|
+
version: 0.52.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen McGinty
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-04-
|
11
|
+
date: 2024-04-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: origen
|
@@ -601,7 +601,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
601
601
|
- !ruby/object:Gem::Version
|
602
602
|
version: '0'
|
603
603
|
requirements: []
|
604
|
-
rubygems_version: 3.
|
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
|