origen_testers 0.31.0 → 0.40.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/config/application.rb +3 -1
  3. data/config/shared_commands.rb +4 -0
  4. data/config/version.rb +1 -1
  5. data/lib/origen_testers/api.rb +8 -0
  6. data/lib/origen_testers/atp/flow.rb +30 -9
  7. data/lib/origen_testers/flow.rb +36 -2
  8. data/lib/origen_testers/generator.rb +44 -5
  9. data/lib/origen_testers/interface.rb +22 -2
  10. data/lib/origen_testers/origen_ext/generator.rb +4 -3
  11. data/lib/origen_testers/origen_ext/generator/flow.rb +99 -5
  12. data/lib/origen_testers/program_generators.rb +5 -1
  13. data/lib/origen_testers/smartest_based_tester.rb +1 -0
  14. data/lib/origen_testers/smartest_based_tester/base.rb +177 -114
  15. data/lib/origen_testers/smartest_based_tester/base/flow.rb +329 -127
  16. data/lib/origen_testers/smartest_based_tester/base/generator.rb +25 -7
  17. data/lib/origen_testers/smartest_based_tester/base/limits_file.rb +186 -60
  18. data/lib/origen_testers/smartest_based_tester/base/pattern_compiler.rb +4 -0
  19. data/lib/origen_testers/smartest_based_tester/base/pattern_master.rb +4 -0
  20. data/lib/origen_testers/smartest_based_tester/base/processors/extract_bin_names.rb +5 -1
  21. data/lib/origen_testers/smartest_based_tester/base/processors/extract_flow_vars.rb +108 -0
  22. data/lib/origen_testers/smartest_based_tester/base/test_method.rb +8 -3
  23. data/lib/origen_testers/smartest_based_tester/base/test_suite.rb +9 -108
  24. data/lib/origen_testers/smartest_based_tester/base/test_suites.rb +17 -7
  25. data/lib/origen_testers/smartest_based_tester/base/variables_file.rb +29 -7
  26. data/lib/origen_testers/smartest_based_tester/smt7.rb +59 -0
  27. data/lib/origen_testers/smartest_based_tester/smt8.rb +218 -0
  28. data/lib/origen_testers/smartest_based_tester/v93k/flow.rb +32 -0
  29. data/lib/origen_testers/smartest_based_tester/v93k/templates/vars.tf.erb +2 -2
  30. data/lib/origen_testers/smartest_based_tester/v93k/test_suite.rb +109 -0
  31. data/lib/origen_testers/smartest_based_tester/v93k_smt8.rb +8 -0
  32. data/lib/origen_testers/smartest_based_tester/v93k_smt8/flow.rb +234 -0
  33. data/lib/origen_testers/smartest_based_tester/v93k_smt8/generator.rb +48 -0
  34. data/lib/origen_testers/smartest_based_tester/v93k_smt8/limits_file.rb +14 -0
  35. data/lib/origen_testers/smartest_based_tester/v93k_smt8/limits_workbook.rb +148 -0
  36. data/lib/origen_testers/smartest_based_tester/v93k_smt8/templates/limits.csv.erb +3 -0
  37. data/lib/origen_testers/smartest_based_tester/v93k_smt8/templates/template.flow.erb +41 -0
  38. data/lib/origen_testers/smartest_based_tester/v93k_smt8/test_suite.rb +66 -0
  39. data/lib/origen_testers/stil_based_tester/base.rb +4 -0
  40. data/lib/origen_testers/test/interface.rb +16 -2
  41. data/lib/origen_testers/vector_generator.rb +9 -4
  42. data/lib/origen_testers/vector_pipeline.rb +1 -1
  43. data/pattern/nvm/v93k/v93k_workout.rb +7 -0
  44. data/program/_erase_vfy.rb +2 -1
  45. data/program/components/_deep_nested.rb +3 -0
  46. data/program/components/_prb1_main.rb +1 -1
  47. data/program/components/_prb2_main.rb +6 -2
  48. data/program/flow_control.rb +3 -3
  49. data/program/prb1.rb +4 -0
  50. data/program/prb2.rb +7 -3
  51. data/templates/origen_guides/pattern/v93k.md.erb +24 -0
  52. data/templates/origen_guides/program/v93k.md.erb +6 -148
  53. data/templates/origen_guides/program/v93ksmt7.md.erb +165 -0
  54. data/templates/origen_guides/program/v93ksmt8.md.erb +112 -0
  55. metadata +30 -3
  56. data/lib/origen_testers/smartest_based_tester/base/test_methods/smart_calc_tml.rb +0 -23
@@ -4,6 +4,38 @@ 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/templates/template.tf.erb"
7
+
8
+ def flow_header
9
+ h = [' {']
10
+ if add_flow_enable
11
+ h << " if @#{flow_enable_var_name} == 1 then"
12
+ h << ' {'
13
+ i = ' '
14
+ else
15
+ i = ''
16
+ end
17
+ if set_runtime_variables.size > 0
18
+ h << i + ' {'
19
+ set_runtime_variables.each do |var|
20
+ h << i + " @#{generate_flag_name(var.to_s)} = -1;"
21
+ end
22
+ h << i + ' }, open,"Init Flow Control Vars", ""'
23
+ end
24
+ h
25
+ end
26
+
27
+ def flow_footer
28
+ f = []
29
+ if add_flow_enable
30
+ f << ' }'
31
+ f << ' else'
32
+ f << ' {'
33
+ f << ' }'
34
+ end
35
+ f << ''
36
+ f << " }, open,\"#{flow_name}\",\"#{flow_description}\""
37
+ f
38
+ end
7
39
  end
8
40
  end
9
41
  end
@@ -3,7 +3,7 @@ language_revision = 1;
3
3
 
4
4
  declarations
5
5
 
6
- % clean_runtime_control_variables.each do |var|
6
+ % declarations.each do |var|
7
7
  % if var.is_a?(Array)
8
8
  @<%= var[0].to_s %> = <%= var[1].is_a?(String) || var[1].is_a?(Symbol) ? "\"#{var[1]}\"" : var[1] %>;
9
9
  % else
@@ -15,7 +15,7 @@ end
15
15
  -----------------------------------------------------------------
16
16
  flags
17
17
 
18
- % clean_flow_control_variables.each do |var|
18
+ % flags.each do |var|
19
19
  % if var.is_a?(Array)
20
20
  user <%= var[0].to_s %> = <%= var[1].is_a?(String) || var[1].is_a?(Symbol) ? "\"#{var[1]}\"" : var[1] %>;
21
21
  % else
@@ -3,6 +3,115 @@ module OrigenTesters
3
3
  class V93K
4
4
  require 'origen_testers/smartest_based_tester/base/test_suite'
5
5
  class TestSuite < Base::TestSuite
6
+ ATTRS =
7
+ %w(name
8
+ comment
9
+
10
+ timing_equation timing_spec timing_set
11
+ level_equation level_spec level_set
12
+ analog_set
13
+ pattern
14
+ context
15
+ test_type
16
+ test_method
17
+
18
+ test_number
19
+ test_level
20
+
21
+ bypass
22
+ set_pass
23
+ set_fail
24
+ hold
25
+ hold_on_fail
26
+ output_on_pass
27
+ output_on_fail
28
+ pass_value
29
+ fail_value
30
+ per_pin_on_pass
31
+ per_pin_on_fail
32
+ log_mixed_signal_waveform
33
+ fail_per_label
34
+ ffc_enable
35
+ log_first
36
+ ffv_enable
37
+ frg_enable
38
+ hardware_dsp_disable
39
+ )
40
+
41
+ ALIASES = {
42
+ tim_equ_set: :timing_equation,
43
+ tim_spec_set: :timing_spec,
44
+ timset: :timing_set,
45
+ timeset: :timing_set,
46
+ time_set: :timing_set,
47
+ lev_equ_set: :level_equation,
48
+ lev_spec_set: :level_spec,
49
+ levset: :level_set,
50
+ levels: :level_set,
51
+ pin_levels: :level_set,
52
+ anaset: :analog_set,
53
+ test_num: :test_number,
54
+ test_function: :test_method,
55
+ value_on_pass: :pass_value,
56
+ value_on_fail: :fail_value,
57
+ seqlbl: :pattern,
58
+ mx_waves_enable: :log_mixed_signal_waveform,
59
+ hw_dsp_disable: :hardware_dsp_disable,
60
+ ffc_on_fail: :log_first
61
+ }
62
+
63
+ DEFAULTS = {
64
+ output_on_pass: true,
65
+ output_on_fail: true,
66
+ pass_value: true,
67
+ fail_value: true,
68
+ per_pin_on_pass: true,
69
+ per_pin_on_fail: true
70
+ }
71
+
72
+ # Generate accessors for all attributes and their aliases
73
+ ATTRS.each do |attr|
74
+ if attr == 'name' || attr == 'pattern'
75
+ attr_reader attr.to_sym
76
+ else
77
+ attr_accessor attr.to_sym
78
+ end
79
+ end
80
+
81
+ # Define the aliases
82
+ ALIASES.each do |_alias, val|
83
+ define_method("#{_alias}=") do |v|
84
+ send("#{val}=", v)
85
+ end
86
+ define_method("#{_alias}") do
87
+ send(val)
88
+ end
89
+ end
90
+
91
+ def lines
92
+ if pattern
93
+ burst = $tester.multiport ? "#{$tester.multiport_name(pattern)}" : "#{pattern}"
94
+ end
95
+ l = []
96
+ l << " comment = \"#{comment}\";" if comment
97
+ l << " ffc_on_fail = #{wrap_if_string(log_first)};" if log_first
98
+ l << " local_flags = #{flags};"
99
+ l << ' override = 1;'
100
+ l << " override_anaset = #{wrap_if_string(analog_set)};" if analog_set
101
+ l << " override_lev_equ_set = #{wrap_if_string(level_equation)};" if level_equation
102
+ l << " override_lev_spec_set = #{wrap_if_string(level_spec)};" if level_spec
103
+ l << " override_levset = #{wrap_if_string(level_set)};" if level_set
104
+ l << " override_seqlbl = #{wrap_if_string(burst)};" if pattern
105
+ l << " override_test_number = #{test_number};" if test_number
106
+ l << " override_testf = #{test_method.id};" if test_method
107
+ l << " override_tim_equ_set = #{wrap_if_string(timing_equation)};" if timing_equation
108
+ l << " override_tim_spec_set = #{wrap_if_string(timing_spec)};" if timing_spec
109
+ l << " override_timset = #{wrap_if_string(timing_set)};" if timing_set
110
+ l << ' site_control = "parallel:";'
111
+ l << ' site_match = 2;'
112
+ l << " test_level = #{test_level};" if test_level
113
+ l
114
+ end
6
115
  end
7
116
  end
8
117
  end
@@ -0,0 +1,8 @@
1
+ module OrigenTesters
2
+ module SmartestBasedTester
3
+ class V93K_SMT8 < Base
4
+ require 'origen_testers/smartest_based_tester/v93k_smt8/generator.rb'
5
+ end
6
+ end
7
+ V93K_SMT8 = SmartestBasedTester::V93K_SMT8
8
+ end
@@ -0,0 +1,234 @@
1
+ module OrigenTesters
2
+ module SmartestBasedTester
3
+ class V93K_SMT8
4
+ require 'origen_testers/smartest_based_tester/base/flow'
5
+ class Flow < Base::Flow
6
+ TEMPLATE = "#{Origen.root!}/lib/origen_testers/smartest_based_tester/v93k_smt8/templates/template.flow.erb"
7
+
8
+ def on_test(node)
9
+ test_suite = node.find(:object).to_a[0]
10
+ if test_suite.is_a?(String)
11
+ name = test_suite
12
+ else
13
+ name = test_suite.name
14
+ test_method = test_suite.test_method
15
+ if test_method.respond_to?(:test_name) && test_method.test_name == '' &&
16
+ n = node.find(:name)
17
+ test_method.test_name = n.value
18
+ end
19
+ end
20
+
21
+ if node.children.any? { |n| t = n.try(:type); t == :on_fail || t == :on_pass } ||
22
+ !stack[:on_pass].empty? || !stack[:on_fail].empty?
23
+ line "#{name}.execute();"
24
+ @open_test_names << name
25
+ @post_test_lines << []
26
+ process_all(node.to_a.reject { |n| t = n.try(:type); t == :on_fail || t == :on_pass })
27
+ on_pass = node.find(:on_pass)
28
+ on_fail = node.find(:on_fail)
29
+
30
+ if on_fail && on_fail.find(:continue) && tester.force_pass_on_continue
31
+ if test_method.respond_to?(:force_pass)
32
+ test_method.force_pass = 1
33
+ else
34
+ Origen.log.error 'Force pass on continue has been enabled, but the test method does not have a force_pass attribute!'
35
+ Origen.log.error " #{node.source}"
36
+ exit 1
37
+ end
38
+ @open_test_methods << test_method
39
+ else
40
+ if test_method.respond_to?(:force_pass)
41
+ test_method.force_pass = 0
42
+ end
43
+ @open_test_methods << nil
44
+ end
45
+
46
+ pass_lines = capture_lines do
47
+ @indent += 1
48
+ pass_branch do
49
+ process_all(on_pass) if on_pass
50
+ stack[:on_pass].each { |n| process_all(n) }
51
+ end
52
+ @indent -= 1
53
+ end
54
+
55
+ fail_lines = capture_lines do
56
+ @indent += 1
57
+ fail_branch do
58
+ process_all(on_fail) if on_fail
59
+ stack[:on_fail].each { |n| process_all(n) }
60
+ end
61
+ @indent -= 1
62
+ end
63
+
64
+ if !pass_lines.empty? && fail_lines.empty?
65
+ line "if (#{name}.pass) {"
66
+ pass_lines.each { |l| line l, already_indented: true }
67
+ line '}'
68
+
69
+ elsif pass_lines.empty? && !fail_lines.empty?
70
+ line "if (!#{name}.pass) {"
71
+ fail_lines.each { |l| line l, already_indented: true }
72
+ line '}'
73
+
74
+ elsif !pass_lines.empty? && !fail_lines.empty?
75
+ line "if (#{name}.pass) {"
76
+ pass_lines.each { |l| line l, already_indented: true }
77
+ line '} else {'
78
+ fail_lines.each { |l| line l, already_indented: true }
79
+ line '}'
80
+
81
+ end
82
+
83
+ @open_test_methods.pop
84
+ @open_test_names.pop
85
+ @post_test_lines.pop.each { |l| line(l) }
86
+ else
87
+ line "#{name}.execute();"
88
+ end
89
+ end
90
+
91
+ def on_sub_flow(node)
92
+ sub_flow = sub_flow_from(node)
93
+ @sub_flows ||= {}
94
+ path = Pathname.new(node.find(:path).value)
95
+ name = path.basename('.*').to_s
96
+ @sub_flows[name] = "#{path.dirname}.#{name}".gsub(/(\/|\\)/, '.')
97
+ # Pass down all input variables before executing
98
+ sub_flow.input_variables.each do |var|
99
+ var = var[0] if var.is_a?(Array)
100
+ line "#{name}.#{var} = #{var};"
101
+ end
102
+ line "#{name}.execute();"
103
+ # And then retrieve all common output variables
104
+ (output_variables & sub_flow.output_variables).sort.each do |var|
105
+ var = var[0] if var.is_a?(Array)
106
+ line "#{var} = #{name}.#{var};"
107
+ end
108
+ if on_pass = node.find(:on_pass)
109
+ pass_lines = capture_lines do
110
+ @indent += 1
111
+ pass_branch do
112
+ process_all(on_pass) if on_pass
113
+ end
114
+ @indent -= 1
115
+ end
116
+ on_pass = nil if pass_lines.empty?
117
+ end
118
+
119
+ if on_fail = node.find(:on_fail)
120
+ fail_lines = capture_lines do
121
+ @indent += 1
122
+ fail_branch do
123
+ process_all(on_fail) if on_fail
124
+ end
125
+ @indent -= 1
126
+ end
127
+ on_fail = nil if fail_lines.empty?
128
+ end
129
+
130
+ if on_pass && !on_fail
131
+ line "if (#{name}.pass) {"
132
+ pass_lines.each { |l| line l, already_indented: true }
133
+ line '}'
134
+
135
+ elsif !on_pass && on_fail
136
+ line "if (!#{name}.pass) {"
137
+ fail_lines.each { |l| line l, already_indented: true }
138
+ line '}'
139
+
140
+ elsif on_pass && on_fail
141
+ line "if (#{name}.pass) {"
142
+ pass_lines.each { |l| line l, already_indented: true }
143
+ line '} else {'
144
+ fail_lines.each { |l| line l, already_indented: true }
145
+ line '}'
146
+ end
147
+ end
148
+
149
+ def sub_flows
150
+ @sub_flows || {}
151
+ end
152
+
153
+ # Variables which should be defined as an input to the current flow
154
+ def input_variables
155
+ vars = flow_variables
156
+ # Jobs and enables flow into a sub-flow
157
+ (vars[:all][:jobs] + vars[:all][:referenced_enables] + vars[:all][:set_enables] +
158
+ # As do any flags which are referenced by it but which are not set within it
159
+ (vars[:all][:referenced_flags] - vars[:all][:set_flags])).uniq.sort do |x, y|
160
+ x = x[0] if x.is_a?(Array)
161
+ y = y[0] if y.is_a?(Array)
162
+ x <=> y
163
+ end
164
+ end
165
+
166
+ # Variables which should be defined as an output of the current flow
167
+ def output_variables
168
+ vars = flow_variables
169
+ # Flags that are set by this flow flow out of it
170
+ (vars[:this_flow][:set_flags] +
171
+ # As do any flags set by its children which are marked as external
172
+ vars[:all][:set_flags_extern] +
173
+ # And any flags which are set by a child and referenced in this flow
174
+ (vars[:this_flow][:referenced_flags] & vars[:sub_flows][:set_flags]) +
175
+ # And also intermediate flags, those are flags which are set by a child and referenced
176
+ # by a parent of the current flow
177
+ intermediate_variables).uniq.sort do |x, y|
178
+ x = x[0] if x.is_a?(Array)
179
+ y = y[0] if y.is_a?(Array)
180
+ x <=> y
181
+ end
182
+ end
183
+
184
+ # Output variables which are not directly referenced by this flow, but which are referenced by a parent
185
+ # flow and set by the given child flow and therefore must pass through the current flow.
186
+ # By calling this method with no argument it will consider variables set by any child flow, alternatively
187
+ # pass in the variables for the child flow in question and only that will be considered.
188
+ def intermediate_variables(*sub_flows)
189
+ set_flags = []
190
+ all_sub_flows.each { |f| set_flags += f.flow_variables[:all][:set_flags] }
191
+ if set_flags.empty?
192
+ []
193
+ else
194
+ upstream_referenced_flags = []
195
+ p = parent
196
+ while p
197
+ upstream_referenced_flags += p.flow_variables[:this_flow][:referenced_flags]
198
+ p = p.parent
199
+ end
200
+ upstream_referenced_flags.uniq
201
+ set_flags & upstream_referenced_flags
202
+ end
203
+ end
204
+
205
+ def flow_header
206
+ h = []
207
+ if add_flow_enable && top_level?
208
+ h << " if (#{flow_enable_var_name} == 1) {"
209
+ i = ' '
210
+ else
211
+ i = ' '
212
+ end
213
+ flow_variables[:this_flow][:set_flags].each do |var|
214
+ if var.is_a?(Array)
215
+ h << i + "#{var[0]} = #{var[1].is_a?(String) || var[1].is_a?(Symbol) ? '"' + var[1].to_s + '"' : var[1]};"
216
+ else
217
+ h << i + "#{var} = -1;"
218
+ end
219
+ end
220
+ h << '' unless flow_variables[:this_flow][:set_flags].empty?
221
+ h
222
+ end
223
+
224
+ def flow_footer
225
+ f = []
226
+ if add_flow_enable && top_level?
227
+ f << ' }'
228
+ end
229
+ f
230
+ end
231
+ end
232
+ end
233
+ end
234
+ end
@@ -0,0 +1,48 @@
1
+ module OrigenTesters
2
+ module SmartestBasedTester
3
+ class V93K_SMT8
4
+ # Include this module in an interface class to make it a V93K interface and to give
5
+ # access to the V93K SMT8 program generator API
6
+ module Generator
7
+ extend ActiveSupport::Concern
8
+
9
+ require_all "#{Origen.root!}/lib/origen_testers/smartest_based_tester/v93k_smt8"
10
+ require 'origen_testers/smartest_based_tester/base/generator'
11
+
12
+ included do
13
+ include Base::Generator
14
+ PLATFORM = V93K_SMT8
15
+ end
16
+
17
+ # Sub flows are generated in a forked process for SMT8, however any updates made to interface
18
+ # instance variables by the sub-flow will be applied to the interface of the master process.
19
+ # This is what the user would expect to happen and keeps them largely unaware of the fact that
20
+ # the sub-flow is actually being generated by a forked process.
21
+ # However, to do this it is necessary to marshal the value of the instance variables and
22
+ # some (rich) Ruby objects cannot be marshaled. This parameter allows applications to selectively
23
+ # mark such variables as not to be returned from the forked process, skipping the marshal
24
+ # operation but also meaning that any changes made to the variable by the sub-flow will not
25
+ # be visible to the top-level flow.
26
+ #
27
+ # If the application actually needs updates to that variable made during a sub-flow to
28
+ # be available to the top-level flow, then they will need to work around it in another
29
+ # way on a case by case basis.
30
+ #
31
+ # # In the application's interface
32
+ # sub_flow_no_return_vars << :@my_problem_var
33
+ def sub_flow_no_return_vars
34
+ @sub_flow_no_return_vars ||= []
35
+ end
36
+
37
+ # See sub_flow_no_return_vars
38
+ def sub_flow_no_return_vars=(val)
39
+ @sub_flow_no_return_vars = val
40
+ end
41
+
42
+ def limits_workbook
43
+ @@limits_workbook ||= LimitsWorkbook.new(manually_register: true)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end