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