origen_testers 0.5.7 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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?