origen_testers 0.5.7 → 0.6.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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/config/shared_commands.rb +6 -0
  3. data/config/version.rb +2 -2
  4. data/lib/commands/run.rb +44 -0
  5. data/lib/origen_testers.rb +19 -1
  6. data/lib/origen_testers/flow.rb +382 -0
  7. data/lib/origen_testers/generator.rb +32 -29
  8. data/lib/origen_testers/igxl_based_tester/base/ac_specsets.rb +79 -0
  9. data/lib/origen_testers/igxl_based_tester/base/dc_specsets.rb +98 -0
  10. data/lib/origen_testers/igxl_based_tester/base/edge.rb +60 -0
  11. data/lib/origen_testers/igxl_based_tester/base/edges.rb +24 -0
  12. data/lib/origen_testers/igxl_based_tester/base/edgeset.rb +39 -0
  13. data/lib/origen_testers/igxl_based_tester/base/edgesets.rb +97 -0
  14. data/lib/origen_testers/igxl_based_tester/base/flow.rb +390 -115
  15. data/lib/origen_testers/igxl_based_tester/base/flow_line.rb +4 -54
  16. data/lib/origen_testers/igxl_based_tester/base/generator.rb +257 -11
  17. data/lib/origen_testers/igxl_based_tester/base/level_io_se.rb +59 -0
  18. data/lib/origen_testers/igxl_based_tester/base/level_supply.rb +39 -0
  19. data/lib/origen_testers/igxl_based_tester/base/levels.rb +31 -0
  20. data/lib/origen_testers/igxl_based_tester/base/levelset.rb +109 -0
  21. data/lib/origen_testers/igxl_based_tester/base/pinmap.rb +93 -0
  22. data/lib/origen_testers/igxl_based_tester/base/test_instance.rb +33 -1
  23. data/lib/origen_testers/igxl_based_tester/base/timeset.rb +37 -0
  24. data/lib/origen_testers/igxl_based_tester/base/timesets.rb +47 -0
  25. data/lib/origen_testers/igxl_based_tester/j750/templates/flow.txt.erb +2 -2
  26. data/lib/origen_testers/igxl_based_tester/ultraflex/ac_specsets.rb +10 -0
  27. data/lib/origen_testers/igxl_based_tester/ultraflex/custom_test_instance.rb +4 -0
  28. data/lib/origen_testers/igxl_based_tester/ultraflex/dc_specsets.rb +10 -0
  29. data/lib/origen_testers/igxl_based_tester/ultraflex/edge.rb +9 -0
  30. data/lib/origen_testers/igxl_based_tester/ultraflex/edges.rb +9 -0
  31. data/lib/origen_testers/igxl_based_tester/ultraflex/edgeset.rb +9 -0
  32. data/lib/origen_testers/igxl_based_tester/ultraflex/edgesets.rb +10 -0
  33. data/lib/origen_testers/igxl_based_tester/ultraflex/flow.rb +137 -0
  34. data/lib/origen_testers/igxl_based_tester/ultraflex/level_io_se.rb +9 -0
  35. data/lib/origen_testers/igxl_based_tester/ultraflex/level_supply.rb +9 -0
  36. data/lib/origen_testers/igxl_based_tester/ultraflex/levels.rb +9 -0
  37. data/lib/origen_testers/igxl_based_tester/ultraflex/levelset.rb +10 -0
  38. data/lib/origen_testers/igxl_based_tester/ultraflex/pinmap.rb +10 -0
  39. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/ac_specsets.txt.erb +58 -0
  40. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/dc_specsets.txt.erb +58 -0
  41. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/edgesets.txt.erb +95 -0
  42. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/flow.txt.erb +2 -2
  43. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/levelset.txt.erb +121 -0
  44. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/pinmap.txt.erb +24 -0
  45. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/timesets.txt.erb +137 -0
  46. data/lib/origen_testers/igxl_based_tester/ultraflex/test_instance.rb +4 -0
  47. data/lib/origen_testers/igxl_based_tester/ultraflex/timeset.rb +9 -0
  48. data/lib/origen_testers/igxl_based_tester/ultraflex/timesets.rb +10 -0
  49. data/lib/origen_testers/interface.rb +41 -6
  50. data/lib/origen_testers/no_interface.rb +7 -0
  51. data/lib/origen_testers/origen_ext/application/runner.rb +25 -0
  52. data/lib/origen_testers/origen_ext/generator.rb +37 -0
  53. data/lib/origen_testers/origen_ext/generator/flow.rb +70 -0
  54. data/lib/origen_testers/origen_ext/generator/resources.rb +21 -0
  55. data/lib/origen_testers/program_generators.rb +0 -1
  56. data/lib/origen_testers/smartest_based_tester/base/flow.rb +158 -134
  57. data/lib/origen_testers/smartest_based_tester/base/generator.rb +2 -3
  58. data/lib/origen_testers/smartest_based_tester/base/test_suite.rb +4 -0
  59. data/lib/origen_testers/smartest_based_tester/v93k/templates/template.flow.erb +5 -6
  60. data/lib/origen_testers/test/dut.rb +5 -0
  61. data/lib/origen_testers/test/j750_base_interface.rb +0 -3
  62. data/lib/origen_testers/test/ultraflex_interface.rb +230 -4
  63. data/lib/origen_testers/test/v93k_interface.rb +5 -23
  64. data/program/components/_temp.rb +6 -0
  65. data/program/flow_control.rb +190 -62
  66. data/program/prb1.rb +13 -50
  67. data/program/prb2.rb +0 -16
  68. data/program/test.rb +12 -3
  69. data/program/uflex_resources.rb +159 -0
  70. metadata +66 -16
  71. data/lib/origen_testers/doc.rb +0 -224
  72. data/lib/origen_testers/doc/generator.rb +0 -124
  73. data/lib/origen_testers/doc/generator/flow.rb +0 -69
  74. data/lib/origen_testers/doc/generator/flow_line.rb +0 -201
  75. data/lib/origen_testers/doc/generator/test.rb +0 -66
  76. data/lib/origen_testers/doc/generator/test_group.rb +0 -64
  77. data/lib/origen_testers/doc/generator/tests.rb +0 -45
  78. data/lib/origen_testers/doc/model.rb +0 -160
  79. data/lib/origen_testers/generator/flow_control_api.rb +0 -611
  80. data/lib/origen_testers/smartest_based_tester/base/flow_node.rb +0 -476
  81. data/lib/origen_testers/smartest_based_tester/v93k/flow_node.rb +0 -9
@@ -0,0 +1,70 @@
1
+ # This shim is temporary to help NXP transition to Origen from
2
+ # our original internal version (RGen)
3
+ if defined? RGen::ORIGENTRANSITION
4
+ require 'rgen/generator/flow'
5
+ else
6
+ require 'origen/generator/flow'
7
+ end
8
+ module Origen
9
+ class Generator
10
+ class Flow
11
+ alias_method :orig_create, :create
12
+
13
+ # Create a call stack of flows so that we can work out where the nodes
14
+ # of the ATP AST originated from
15
+ def create(options = {}, &block)
16
+ file, line = *caller[0].split(':')
17
+ OrigenTesters::Flow.callstack << file
18
+ flow_comments, comments = *_extract_comments(OrigenTesters::Flow.callstack.last, line.to_i)
19
+ OrigenTesters::Flow.comment_stack << comments
20
+ if OrigenTesters::Flow.flow_comments
21
+ top = false
22
+ name = options[:name] || Pathname.new(file).basename('.rb').to_s.sub(/^_/, '')
23
+ Origen.interface.flow.group(name, description: flow_comments) do
24
+ orig_create(options, &block)
25
+ end
26
+ else
27
+ OrigenTesters::Flow.flow_comments = flow_comments
28
+ if options.key?(:unique_ids)
29
+ OrigenTesters::Flow.unique_ids = options.delete(:unique_ids)
30
+ else
31
+ OrigenTesters::Flow.unique_ids = true
32
+ end
33
+ top = true
34
+ orig_create(options, &block)
35
+ end
36
+ OrigenTesters::Flow.callstack.pop
37
+ OrigenTesters::Flow.comment_stack.pop
38
+ OrigenTesters::Flow.flow_comments = nil if top
39
+ end
40
+
41
+ def _extract_comments(file, flow_line)
42
+ flow_comments = []
43
+ comments = {}
44
+ comment = nil
45
+ File.readlines(file).each_with_index do |line, i|
46
+ if comment
47
+ if line =~ /^\s*#-(.*)/
48
+ # Nothing, just ignore but keep the comment open
49
+ elsif line =~ /^\s*#(.*)/
50
+ comment << Regexp.last_match(1).strip
51
+ else
52
+ comment = nil
53
+ end
54
+ else
55
+ if line =~ /^\s*#[^-](.*)/
56
+ if i < flow_line
57
+ comment = flow_comments
58
+ else
59
+ comment = []
60
+ comments[i + 1] = comment
61
+ end
62
+ comment << Regexp.last_match(1).strip
63
+ end
64
+ end
65
+ end
66
+ [flow_comments, comments]
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,21 @@
1
+ # This shim is temporary to help NXP transition to Origen from
2
+ # our original internal version (RGen)
3
+ if defined? RGen::ORIGENTRANSITION
4
+ require 'rgen/generator/resources'
5
+ else
6
+ require 'origen/generator/resources'
7
+ end
8
+ module Origen
9
+ class Generator
10
+ class Resources
11
+ alias_method :orig_create, :create
12
+
13
+ # Patching to make resources_mode apply much earlier
14
+ def create(options = {}, &block)
15
+ OrigenTesters::Interface.with_resources_mode do
16
+ orig_create(options, &block)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -12,7 +12,6 @@ module OrigenTesters
12
12
 
13
13
  included do
14
14
  Origen.add_interface(self)
15
- include Generator::FlowControlAPI::Interface
16
15
  end
17
16
 
18
17
  module ClassMethods
@@ -1,11 +1,10 @@
1
1
  module OrigenTesters
2
2
  module SmartestBasedTester
3
3
  class Base
4
- class Flow
5
- include OrigenTesters::Generator
6
- include OrigenTesters::Generator::FlowControlAPI
4
+ class Flow < ATP::Formatter
5
+ include OrigenTesters::Flow
7
6
 
8
- attr_accessor :test_suites, :test_methods, :pattern_master
7
+ attr_accessor :test_suites, :test_methods, :pattern_master, :lines, :stack
9
8
 
10
9
  def subdirectory
11
10
  'testflow'
@@ -15,172 +14,197 @@ module OrigenTesters
15
14
  super.gsub('_flow', '')
16
15
  end
17
16
 
17
+ def hardware_bin_descriptions
18
+ @hardware_bin_descriptions ||= {}
19
+ end
20
+
21
+ def flow_control_variables
22
+ @flow_control_variables ||= []
23
+ end
24
+
25
+ def runtime_control_variables
26
+ @runtime_control_variables ||= []
27
+ end
28
+
18
29
  def finalize(options = {})
19
30
  super
20
- flow_control_variables.uniq!
21
- collection.each { |n| n.finalize if n.respond_to?(:finalize) }
22
31
  test_suites.finalize
23
32
  test_methods.finalize
33
+ @indent = 0
34
+ @lines = []
35
+ @stack = { on_fail: [], on_pass: [] }
36
+ process(model.ast)
37
+ flow_control_variables.uniq!
38
+ runtime_control_variables.uniq!
24
39
  end
25
40
 
26
- # Convenience method that will automatically generate a run and branch if a :bin
27
- # option is supplied. If no :bin option is present then it will generate a simple
28
- # run entry in the flow.
29
- def test(test_suite, options = {})
30
- sbin = options[:sbin] || options[:softbin] || options[:soft_bin]
31
- if (options[:bin] || sbin) && !options[:continue]
32
- node = run_and_branch(test_suite, options)
33
- options.delete(:id)
34
- # Only pass options to configure the bin, don't pass flow control options, those apply to the main
35
- # test only in this case
36
- bin = bad_bin(options[:bin], options.slice(*(FlowNode::ATTRS[:bad_bin].keys + FlowNode::ALIASES[:bad_bin].keys)))
37
- node.else_nodes << bin
38
- node
39
- else
40
- run(test_suite, options)
41
- end
41
+ def line(str)
42
+ @lines << (' ' * @indent * 2) + str
42
43
  end
43
44
 
44
- # This module contains methods that correspond to the test flow primitives available
45
- # in the palette window of the test flow editor
46
- module Palette
47
- def run(test_suite, options = {})
48
- add(:run, { test_suite: test_suite }.merge(options))
49
- end
50
- alias_method :run_test, :run
51
-
52
- def run_and_branch(test_suite, options = {})
53
- add(:run_and_branch, { test_suite: test_suite }.merge(options))
54
- end
55
-
56
- def good_bin(number, options = {})
57
- add(:good_bin, { bin: number }.merge(options))
58
- end
59
-
60
- def bad_bin(number, options = {})
61
- add(:bad_bin, { bin: number }.merge(options))
62
- end
63
-
64
- def multi_bin(number, options = {})
65
- fail 'V93K Flow#multi_bin method has not been implemented yet!'
66
- end
67
-
68
- def print(msg, options = {})
69
- add(:print, { value: msg }.merge(options))
45
+ def on_test(node)
46
+ name = node.find(:object).to_a[0]
47
+ name = name.name unless name.is_a?(String)
48
+ if node.children.any? { |n| t = n.try(:type); t == :on_fail || t == :on_pass }
49
+ line "run_and_branch(#{name})"
50
+ process_all(node.to_a.reject { |n| t = n.try(:type); t == :on_fail || t == :on_pass })
51
+ line 'then'
52
+ line '{'
53
+ @indent += 1
54
+ on_pass = node.children.find { |n| n.try(:type) == :on_pass }
55
+ if on_pass
56
+ process_all(on_pass)
57
+ stack[:on_pass].each { |n| process_all(n) }
58
+ end
59
+ @indent -= 1
60
+ line '}'
61
+ line 'else'
62
+ line '{'
63
+ @indent += 1
64
+ on_fail = node.children.find { |n| n.try(:type) == :on_fail }
65
+ if on_fail
66
+ with_continue(on_fail.children.any? { |n| n.try(:type) == :continue }) do
67
+ process_all(on_fail)
68
+ stack[:on_fail].each { |n| process_all(n) }
69
+ end
70
+ end
71
+ @indent -= 1
72
+ line '}'
73
+ else
74
+ line "run(#{name});"
70
75
  end
76
+ end
71
77
 
72
- def print_to_datalog(msg, options = {})
73
- add(:print_to_datalog, { value: msg }.merge(options))
74
- end
78
+ def on_job(node)
79
+ jobs, state, *nodes = *node
80
+ jobs = clean_job(jobs)
81
+ flow_control_variables << 'JOB'
82
+ condition = jobs.join(' or ')
83
+ line "if #{condition} then"
84
+ line '{'
85
+ @indent += 1
86
+ process_all(node) if state
87
+ @indent -= 1
88
+ line '}'
89
+ line 'else'
90
+ line '{'
91
+ @indent += 1
92
+ process_all(node) unless state
93
+ @indent -= 1
94
+ line '}'
95
+ end
75
96
 
76
- def assign_value(variable, value, options = {})
77
- add(:assign_value, { variable: variable, value: value }.merge(options))
78
- end
97
+ def on_condition_flag(node)
98
+ flag, state, *nodes = *node
99
+ if flag.is_a?(Array)
100
+ condition = flag.map { |f| "@#{f.upcase} == 1" }.join(' or ')
101
+ else
102
+ condition = "@#{flag.upcase} == 1"
103
+ end
104
+ line "if #{condition} then"
105
+ line '{'
106
+ @indent += 1
107
+ process_all(nodes) if state
108
+ @indent -= 1
109
+ line '}'
110
+ line 'else'
111
+ line '{'
112
+ @indent += 1
113
+ process_all(nodes) unless state
114
+ @indent -= 1
115
+ line '}'
116
+ end
79
117
 
80
- def if_then(condition, options = {})
81
- add(:if_then, { condition: condition }.merge(options))
118
+ def on_flow_flag(node)
119
+ flag, state, *nodes = *node
120
+ [flag].flatten.each do |f|
121
+ flow_control_variables << f.upcase
82
122
  end
123
+ on_condition_flag(node)
124
+ end
83
125
 
84
- def group(name, options = {})
85
- name = make_unique(:group, name)
86
- g = add(:group, { name: name }.merge(options))
87
- if block_given?
88
- open_groups << g
89
- yield g
90
- open_groups.pop
91
- end
92
- g
126
+ def on_run_flag(node)
127
+ flag, state, *nodes = *node
128
+ [flag].flatten.each do |f|
129
+ runtime_control_variables << f.upcase
93
130
  end
131
+ on_condition_flag(node)
94
132
  end
95
- include Palette
96
133
 
97
- # Convenience method to provide similar functionality to enabling a Teradyne flow word/variable
98
- def enable_flow_word(variable, options = {})
99
- assign_value(variable, 1, options)
134
+ def on_enable_flow_flag(node)
135
+ flag = node.value.upcase
136
+ flow_control_variables << flag
137
+ line "@#{flag} = 1;"
100
138
  end
101
139
 
102
- def skip(identifier = nil, options = {})
103
- identifier, options = nil, identifier if identifier.is_a?(Hash)
104
- open_skips << []
105
- yield
106
- nodes = open_skips.pop
107
- s = if_then(:skip, options)
108
- s.else_nodes = nodes
140
+ def on_disable_flow_flag(node)
141
+ flag = node.value.upcase
142
+ flow_control_variables << flag
143
+ line "@#{flag} = 0;"
109
144
  end
110
145
 
111
- def hardware_bin_descriptions
112
- @hardware_bin_descriptions ||= {}
146
+ def on_set_run_flag(node)
147
+ flag = node.value.upcase
148
+ runtime_control_variables << flag
149
+ line "@#{flag} = 1;"
113
150
  end
114
151
 
115
- def flow_control_variables
116
- @flow_control_variables ||= []
152
+ def on_group(node)
153
+ on_fail = node.children.find { |n| n.try(:type) == :on_fail }
154
+ on_pass = node.children.find { |n| n.try(:type) == :on_pass }
155
+ with_continue(on_fail && on_fail.children.any? { |n| n.try(:type) == :continue }) do
156
+ line '{'
157
+ @indent += 1
158
+ stack[:on_fail] << on_fail if on_fail
159
+ stack[:on_pass] << on_pass if on_pass
160
+ process_all(node.children - [on_fail, on_pass])
161
+ stack[:on_fail].pop if on_fail
162
+ stack[:on_pass].pop if on_pass
163
+ @indent -= 1
164
+ line "}, open,\"#{unique_group_name(node.find(:name).value)}\", \"\""
165
+ end
117
166
  end
118
167
 
119
- private
120
-
121
- def add(type, options = {})
122
- options = save_context(options) if [:run, :run_and_branch].include?(type)
123
-
124
- # Delete the ID if a test within a group with the same ID to avoid a duplicate ID
125
- # error.
126
- if options[:id]
127
- id = Origen.interface.filter_id(options[:id], options)
128
- options.delete(:id) if group_opened? && open_groups.any? { |g| g.id == id }
129
- end
130
- node = track_relationships(options) do |options|
131
- platform::FlowNode.create(self, type, options)
132
- end
133
- unless Origen.interface.resources_mode?
134
- if skip_opened?
135
- open_skips.last << node
136
- node.parent = open_skips.last
137
- else
138
- if group_opened?
139
- open_groups.last.nodes << node
140
- node.parent = open_groups.last.nodes
141
- else
142
- collection << node
143
- end
168
+ def on_set_result(node)
169
+ unless @continue
170
+ bin = node.find(:bin).try(:value)
171
+ sbin = node.find(:softbin).try(:value)
172
+ desc = node.find(:bin_description).try(:value)
173
+ if bin && desc
174
+ hardware_bin_descriptions[bin] ||= desc
144
175
  end
145
- end
146
- if node.test?
147
- node.test_suite = options[:test_suite]
148
- c = Origen.interface.consume_comments
149
- unless Origen.interface.resources_mode?
150
- Origen.interface.descriptions.add_for_test_usage(node.test_suite.name, Origen.interface.top_level_flow, c)
176
+ if node.to_a[0] == 'pass'
177
+ line "stop_bin \"#{sbin}\", \"\", , good, noreprobe, green, #{bin}, over_on;"
178
+ else
179
+ line "stop_bin \"#{sbin}\", \"fail\", , bad, noreprobe, red, #{bin}, over_on;"
151
180
  end
152
- else
153
- Origen.interface.discard_comments
154
181
  end
155
- node
156
- end
157
-
158
- def open_skips
159
- @open_skips ||= []
160
182
  end
161
183
 
162
- def skip_opened?
163
- open_skips.size > 0
184
+ def on_log(node)
185
+ line "print_dl(\"#{node.to_a[0]}\");"
164
186
  end
165
187
 
166
- def open_groups
167
- @open_groups ||= []
188
+ def unique_group_name(name)
189
+ @group_names ||= {}
190
+ if @group_names[name]
191
+ @group_names[name] += 1
192
+ "#{name}_#{@group_names[name]}"
193
+ else
194
+ @group_names[name] = 1
195
+ name
196
+ end
168
197
  end
169
198
 
170
- def group_opened?
171
- open_groups.size > 0
199
+ def clean_job(job)
200
+ [job].flatten.map { |j| "@JOB == \"#{j.to_s.upcase}\"" }
172
201
  end
173
202
 
174
- def make_unique(type, name, options = {})
175
- @uniques ||= {}
176
- t = @uniques[type] ||= {}
177
- t[name] ||= 0
178
- t[name] += 1
179
- if t[name] == 1
180
- name
181
- else
182
- "#{name}_#{t[name]}"
183
- end
203
+ def with_continue(value)
204
+ orig = @continue
205
+ @continue = true if value
206
+ yield
207
+ @continue = orig
184
208
  end
185
209
  end
186
210
  end
@@ -26,6 +26,7 @@ module OrigenTesters
26
26
 
27
27
  # @api private
28
28
  def at_flow_start
29
+ flow.at_flow_start
29
30
  end
30
31
 
31
32
  # @api private
@@ -40,9 +41,7 @@ module OrigenTesters
40
41
 
41
42
  def flow(filename = Origen.file_handler.current_file.basename('.rb').to_s)
42
43
  f = filename.to_sym
43
- if Origen.interface.resources_mode?
44
- f = f.to_s.sub(/_resources?/, '').to_sym
45
- end
44
+ f = f.to_s.sub(/_resources?/, '').to_sym
46
45
  return flow_sheets[f] if flow_sheets[f] # will return flow if already existing
47
46
  p = platform::Flow.new
48
47
  p.inhibit_output if Origen.interface.resources_mode?