origen_testers 0.18.0 → 0.19.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/config/boot.rb +2 -1
- data/config/version.rb +1 -1
- data/lib/origen_testers/flow.rb +5 -0
- data/lib/origen_testers/generator.rb +1 -1
- data/lib/origen_testers/pattern_compilers/job.rb +3 -3
- data/lib/origen_testers/smartest_based_tester/base.rb +70 -1
- data/lib/origen_testers/smartest_based_tester/base/flow.rb +118 -13
- data/lib/origen_testers/smartest_based_tester/base/limits_file.rb +216 -0
- data/lib/origen_testers/smartest_based_tester/base/pattern_master.rb +9 -1
- data/lib/origen_testers/smartest_based_tester/base/processors/extract_bin_names.rb +64 -0
- data/lib/origen_testers/smartest_based_tester/base/test_method.rb +1 -4
- data/lib/origen_testers/smartest_based_tester/base/test_methods/limits.rb +11 -0
- data/lib/origen_testers/smartest_based_tester/base/test_suite.rb +8 -1
- data/lib/origen_testers/smartest_based_tester/v93k/limits_file.rb +10 -0
- data/lib/origen_testers/smartest_based_tester/v93k/templates/limits.csv.erb +3 -0
- data/lib/origen_testers/smartest_based_tester/v93k/templates/template.aiv.erb +17 -2
- data/lib/origen_testers/smartest_based_tester/v93k/templates/template.tf.erb +2 -0
- data/lib/origen_testers/test/dut.rb +34 -13
- data/program/test.rb +14 -9
- metadata +7 -5
- data/lib/origen_testers/smartest_based_tester/base/processors/extract_set_variables.rb +0 -22
- data/lib/origen_testers/test/dut3.rb +0 -244
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d0f9e7b0562c602396e9cb070d57050486a854df
|
4
|
+
data.tar.gz: fbde57d2fa40beae37c0443261339bb2f8c187d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f58d90428732f2046cf98e8b0c175531fd1a150eb86c8771beb3e766b2ec2de483f7cd7f72d8b1d74d78edcf6c9ece7fe9a587f5945b38cb8be88e793c915e07
|
7
|
+
data.tar.gz: c87af16d5020f20bdae4abcc3b6227e21f2c33d87c5e9f2d156e9d452f53840153ff1ceb1043586a0d257ebe27c30ca29f02c37ee64853e1cddbca89a7c61c48
|
data/config/boot.rb
CHANGED
@@ -5,7 +5,8 @@ require "origen_testers"
|
|
5
5
|
require "origen_testers/test/dut.rb"
|
6
6
|
require "origen_testers/test/block.rb"
|
7
7
|
require "origen_testers/test/dut2.rb"
|
8
|
-
|
8
|
+
# NOTE: Before adding new duts-- consider adding option to DUT class
|
9
|
+
# so we don't reduce overall code coverage-- thx, mgmt
|
9
10
|
require "origen_testers/test/nvm.rb"
|
10
11
|
|
11
12
|
require "origen_testers/test/interface"
|
data/config/version.rb
CHANGED
data/lib/origen_testers/flow.rb
CHANGED
@@ -48,6 +48,11 @@ module OrigenTesters
|
|
48
48
|
@lines
|
49
49
|
end
|
50
50
|
|
51
|
+
def test(obj, options = {})
|
52
|
+
obj.extract_atp_attributes(options) if obj.respond_to?(:extract_atp_attributes)
|
53
|
+
super(obj, options)
|
54
|
+
end
|
55
|
+
|
51
56
|
# @api private
|
52
57
|
def self.ht_comments
|
53
58
|
unless @ht_comments.is_a? Hash
|
@@ -151,7 +151,6 @@ module OrigenTesters
|
|
151
151
|
end
|
152
152
|
|
153
153
|
def write_to_file(options = {})
|
154
|
-
c = caller[0]
|
155
154
|
unless output_inhibited?
|
156
155
|
if defined? self.class::TEMPLATE || Origen.tester.is_a?(OrigenTesters::Doc)
|
157
156
|
write_from_template(options)
|
@@ -274,6 +273,7 @@ module OrigenTesters
|
|
274
273
|
def new(*args, &block) # :nodoc:
|
275
274
|
options = (args.last && args.last.is_a?(Hash)) ? args.last : {}
|
276
275
|
x = allocate
|
276
|
+
x.filename = options[:filename] if options[:filename]
|
277
277
|
x.send(:initialize, *args, &block)
|
278
278
|
Origen.interface.sheet_generators << x unless options[:manually_register]
|
279
279
|
x
|
@@ -22,13 +22,13 @@ module OrigenTesters
|
|
22
22
|
# Pinmap file (IGXL-Based)
|
23
23
|
attr_accessor :pinmap_workbook
|
24
24
|
|
25
|
-
#
|
25
|
+
# Pin Config file (Smartest-Based)
|
26
26
|
attr_accessor :pinconfig
|
27
27
|
|
28
|
-
#
|
28
|
+
# Pattern input dir (Smartest-Based)
|
29
29
|
attr_accessor :avc_dir
|
30
30
|
|
31
|
-
#
|
31
|
+
# Pattern output dir (Smartest-Based)
|
32
32
|
attr_accessor :binl_dir
|
33
33
|
|
34
34
|
# Pattern count - should be 1 for IGXL; number of AVC files listed in AIV file for Smartest
|
@@ -24,7 +24,44 @@ module OrigenTesters
|
|
24
24
|
alias_method :min_repeat_count, :min_repeat_loop
|
25
25
|
alias_method :min_repeat_count=, :min_repeat_loop=
|
26
26
|
|
27
|
+
# permit option to generate multiport type patterns
|
28
|
+
# and use multiport type code
|
29
|
+
attr_accessor :multiport
|
30
|
+
alias_method :multi_port, :multiport
|
31
|
+
alias_method :multi_port=, :multiport=
|
32
|
+
attr_accessor :multiport_prefix # multiport burst name prefix
|
33
|
+
attr_accessor :multiport_postfix # multiport burst name postfix
|
34
|
+
|
35
|
+
# When set to true, all test flows will be generated with a corresponding testtable limits
|
36
|
+
# file, rather than having the limits attached inline to the test suites
|
37
|
+
attr_accessor :create_limits_file
|
38
|
+
|
39
|
+
# Returns an array of strings that indicate which test modes will be included in limits files,
|
40
|
+
# by default returns an empty array.
|
41
|
+
# If no test modes have been specified then the limits file will simply be generated with no
|
42
|
+
# test modes.
|
43
|
+
attr_reader :limitfile_test_modes
|
44
|
+
alias_method :limitsfile_test_modes, :limitfile_test_modes
|
45
|
+
|
46
|
+
# When set to true, tests which are marked with continue: true will be forced to pass in
|
47
|
+
# generated test program flows. Flow branching based on the test result will be handled via
|
48
|
+
# some other means to give the same flow if the test 'fails', however the test will always
|
49
|
+
# appear as if it passed for data logging purposes.
|
50
|
+
#
|
51
|
+
# Testers which do not implement this option will ignore it.
|
52
|
+
attr_accessor :force_pass_on_continue
|
53
|
+
|
54
|
+
# When set to true, tests will be set to delayed binning by default (overon = on) unless
|
55
|
+
# delayed: false is supplied when defining the test
|
56
|
+
attr_accessor :delayed_binning
|
57
|
+
|
27
58
|
def initialize(options = {})
|
59
|
+
options = {
|
60
|
+
# whether to use multiport bursts or not, if so this indicates the name of the port to use
|
61
|
+
multiport: false,
|
62
|
+
multiport_prefix: false,
|
63
|
+
multiport_postfix: false
|
64
|
+
}.merge(options)
|
28
65
|
@max_repeat_loop = 65_535
|
29
66
|
@min_repeat_loop = 33
|
30
67
|
@pat_extension = 'avc'
|
@@ -35,7 +72,10 @@ module OrigenTesters
|
|
35
72
|
@comment_char = '#'
|
36
73
|
@level_period = true
|
37
74
|
@inline_comments = true
|
38
|
-
@
|
75
|
+
@multiport = options[:multiport]
|
76
|
+
@multiport_prefix = options[:multiport_prefix]
|
77
|
+
@multiport_postfix = options[:multiport_postfix]
|
78
|
+
@overlay_style = :subroutine # default to use subroutine for overlay
|
39
79
|
@capture_style = :hram # default to use hram for capture
|
40
80
|
@overlay_subr = nil
|
41
81
|
|
@@ -47,6 +87,35 @@ module OrigenTesters
|
|
47
87
|
else
|
48
88
|
@unique_test_names = :signature
|
49
89
|
end
|
90
|
+
if options.key?(:create_limits_file)
|
91
|
+
@create_limits_file = options[:create_limits_file]
|
92
|
+
else
|
93
|
+
@create_limits_file = false
|
94
|
+
end
|
95
|
+
self.limitfile_test_modes = options[:limitfile_test_modes] || options[:limitsfile_test_modes]
|
96
|
+
self.force_pass_on_continue = options[:force_pass_on_continue]
|
97
|
+
self.delayed_binning = options[:delayed_binning]
|
98
|
+
end
|
99
|
+
|
100
|
+
# Set the test mode(s) that you want to see in the limits files, supply an array of mode names
|
101
|
+
# to set multiple.
|
102
|
+
def limitfile_test_modes=(val)
|
103
|
+
@limitfile_test_modes = Array(val).map(&:to_s)
|
104
|
+
end
|
105
|
+
alias_method :limitsfile_test_modes, :limitfile_test_modes=
|
106
|
+
|
107
|
+
# return the multiport burst name
|
108
|
+
# provide the name you want to obtain multiport for
|
109
|
+
def multiport_name(patt_name)
|
110
|
+
name = "#{patt_name}"
|
111
|
+
if @multiport
|
112
|
+
name = "#{@multiport_prefix}_#{name}" if @multiport_prefix
|
113
|
+
name = "#{name}_#{@multiport_postfix}" if @multiport_postfix
|
114
|
+
unless @multiport_prefix || @multiport_postfix
|
115
|
+
name = "#{@multiport}_#{name}"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
name
|
50
119
|
end
|
51
120
|
|
52
121
|
# Set to :enabled to have all top-level flow modules wrapped by an enable flow variable
|
@@ -43,6 +43,8 @@ module OrigenTesters
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def at_flow_end
|
46
|
+
# Take whatever the test modes are set to at the end of the flow as what we go with
|
47
|
+
@test_modes = tester.limitfile_test_modes
|
46
48
|
end
|
47
49
|
|
48
50
|
def flow_header
|
@@ -86,14 +88,24 @@ module OrigenTesters
|
|
86
88
|
|
87
89
|
def finalize(options = {})
|
88
90
|
super
|
89
|
-
test_suites.finalize
|
90
|
-
test_methods.finalize
|
91
91
|
@indent = add_flow_enable ? 2 : 1
|
92
92
|
@lines = []
|
93
|
+
@open_test_methods = []
|
93
94
|
@stack = { on_fail: [], on_pass: [] }
|
94
|
-
ast = atp.ast(unique_id: sig, optimization: :smt
|
95
|
+
ast = atp.ast(unique_id: sig, optimization: :smt,
|
96
|
+
implement_continue: !tester.force_pass_on_continue,
|
97
|
+
optimize_flags_when_continue: !tester.force_pass_on_continue
|
98
|
+
)
|
95
99
|
@set_runtime_variables = ast.set_flags
|
96
100
|
process(ast)
|
101
|
+
test_suites.finalize
|
102
|
+
test_methods.finalize
|
103
|
+
render_limits_file(ast) if tester.create_limits_file
|
104
|
+
end
|
105
|
+
|
106
|
+
def render_limits_file(ast)
|
107
|
+
m = platform::LimitsFile.new(self, ast, manually_register: true, filename: "#{name}_limits", test_modes: @test_modes)
|
108
|
+
m.write_to_file unless m.empty?
|
97
109
|
end
|
98
110
|
|
99
111
|
def line(str)
|
@@ -109,28 +121,61 @@ module OrigenTesters
|
|
109
121
|
# end
|
110
122
|
|
111
123
|
def on_test(node)
|
112
|
-
|
113
|
-
|
124
|
+
test_suite = node.find(:object).to_a[0]
|
125
|
+
if test_suite.is_a?(String)
|
126
|
+
name = test_suite
|
127
|
+
else
|
128
|
+
name = test_suite.name
|
129
|
+
test_method = test_suite.test_method
|
130
|
+
if test_method.respond_to?(:test_name) && test_method.test_name == '' &&
|
131
|
+
n = node.find(:name)
|
132
|
+
test_method.test_name = n.value
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
114
136
|
if node.children.any? { |n| t = n.try(:type); t == :on_fail || t == :on_pass } ||
|
115
137
|
!stack[:on_pass].empty? || !stack[:on_fail].empty?
|
116
138
|
line "run_and_branch(#{name})"
|
117
139
|
process_all(node.to_a.reject { |n| t = n.try(:type); t == :on_fail || t == :on_pass })
|
140
|
+
on_pass = node.find(:on_pass)
|
141
|
+
on_fail = node.find(:on_fail)
|
142
|
+
|
143
|
+
if on_fail && on_fail.find(:continue) && tester.force_pass_on_continue
|
144
|
+
if test_method.respond_to?(:force_pass)
|
145
|
+
test_method.force_pass = 1
|
146
|
+
else
|
147
|
+
Origen.log.error 'Force pass on continue has been enabled, but the test method does not have a force_pass attribute!'
|
148
|
+
Origen.log.error " #{node.source}"
|
149
|
+
exit 1
|
150
|
+
end
|
151
|
+
@open_test_methods << test_method
|
152
|
+
else
|
153
|
+
if test_method.respond_to?(:force_pass)
|
154
|
+
test_method.force_pass = 0
|
155
|
+
end
|
156
|
+
@open_test_methods << nil
|
157
|
+
end
|
158
|
+
|
118
159
|
line 'then'
|
119
160
|
line '{'
|
120
161
|
@indent += 1
|
121
|
-
|
122
|
-
|
123
|
-
|
162
|
+
pass_branch do
|
163
|
+
process_all(on_pass) if on_pass
|
164
|
+
stack[:on_pass].each { |n| process_all(n) }
|
165
|
+
end
|
124
166
|
@indent -= 1
|
125
167
|
line '}'
|
126
168
|
line 'else'
|
127
169
|
line '{'
|
128
170
|
@indent += 1
|
129
|
-
|
130
|
-
|
131
|
-
|
171
|
+
fail_branch do
|
172
|
+
process_all(on_fail) if on_fail
|
173
|
+
stack[:on_fail].each { |n| process_all(n) }
|
174
|
+
end
|
132
175
|
@indent -= 1
|
133
176
|
line '}'
|
177
|
+
|
178
|
+
@open_test_methods.pop
|
134
179
|
else
|
135
180
|
line "run(#{name});"
|
136
181
|
end
|
@@ -228,7 +273,39 @@ module OrigenTesters
|
|
228
273
|
def on_set_flag(node)
|
229
274
|
flag = generate_flag_name(node.value)
|
230
275
|
runtime_control_variables << flag
|
231
|
-
|
276
|
+
if @open_test_methods.last
|
277
|
+
if pass_branch?
|
278
|
+
if @open_test_methods.last.respond_to?(:on_pass_flag)
|
279
|
+
if @open_test_methods.last.on_pass_flag == ''
|
280
|
+
@open_test_methods.last.on_pass_flag = flag
|
281
|
+
else
|
282
|
+
Origen.log.error "The test method cannot set #{flag} on passing, because it already sets: #{@open_test_methods.last.on_pass_flag}"
|
283
|
+
Origen.log.error " #{node.source}"
|
284
|
+
exit 1
|
285
|
+
end
|
286
|
+
else
|
287
|
+
Origen.log.error 'Force pass on continue has been requested, but the test method does not have an :on_pass_flag attribute:'
|
288
|
+
Origen.log.error " #{node.source}"
|
289
|
+
exit 1
|
290
|
+
end
|
291
|
+
else
|
292
|
+
if @open_test_methods.last.respond_to?(:on_fail_flag)
|
293
|
+
if @open_test_methods.last.on_fail_flag == ''
|
294
|
+
@open_test_methods.last.on_fail_flag = flag
|
295
|
+
else
|
296
|
+
Origen.log.error "The test method cannot set #{flag} on failing, because it already sets: #{@open_test_methods.last.on_fail_flag}"
|
297
|
+
Origen.log.error " #{node.source}"
|
298
|
+
exit 1
|
299
|
+
end
|
300
|
+
else
|
301
|
+
Origen.log.error 'Force pass on continue has been requested, but the test method does not have an :on_fail_flag attribute:'
|
302
|
+
Origen.log.error " #{node.source}"
|
303
|
+
exit 1
|
304
|
+
end
|
305
|
+
end
|
306
|
+
else
|
307
|
+
line "@#{flag} = 1;"
|
308
|
+
end
|
232
309
|
end
|
233
310
|
|
234
311
|
def on_group(node)
|
@@ -257,7 +334,11 @@ module OrigenTesters
|
|
257
334
|
if node.to_a[0] == 'pass'
|
258
335
|
line "stop_bin \"#{sbin}\", \"\", , good, noreprobe, green, #{bin}, over_on;"
|
259
336
|
else
|
260
|
-
|
337
|
+
if tester.create_limits_file
|
338
|
+
line 'multi_bin;'
|
339
|
+
else
|
340
|
+
line "stop_bin \"#{sbin}\", \"#{sdesc}\", , bad, noreprobe, red, #{bin}, over_on;"
|
341
|
+
end
|
261
342
|
end
|
262
343
|
end
|
263
344
|
|
@@ -282,6 +363,30 @@ module OrigenTesters
|
|
282
363
|
|
283
364
|
private
|
284
365
|
|
366
|
+
def pass_branch
|
367
|
+
open_branch_types << :pass
|
368
|
+
yield
|
369
|
+
open_branch_types.pop
|
370
|
+
end
|
371
|
+
|
372
|
+
def fail_branch
|
373
|
+
open_branch_types << :fail
|
374
|
+
yield
|
375
|
+
open_branch_types.pop
|
376
|
+
end
|
377
|
+
|
378
|
+
def pass_branch?
|
379
|
+
open_branch_types.last == :pass
|
380
|
+
end
|
381
|
+
|
382
|
+
def fail_branch?
|
383
|
+
open_branch_types.last == :fail
|
384
|
+
end
|
385
|
+
|
386
|
+
def open_branch_types
|
387
|
+
@open_branch_types ||= []
|
388
|
+
end
|
389
|
+
|
285
390
|
def generate_flag_name(flag)
|
286
391
|
case flag[0]
|
287
392
|
when '$'
|
@@ -0,0 +1,216 @@
|
|
1
|
+
require 'origen_testers/smartest_based_tester/base/processors/extract_bin_names'
|
2
|
+
module OrigenTesters
|
3
|
+
module SmartestBasedTester
|
4
|
+
class Base
|
5
|
+
class LimitsFile < ATP::Formatter
|
6
|
+
include OrigenTesters::Generator
|
7
|
+
|
8
|
+
attr_reader :ast, :flow, :test_modes, :flowname, :bin_names
|
9
|
+
|
10
|
+
def initialize(flow, ast, options = {})
|
11
|
+
@flow = flow
|
12
|
+
@ast = ast
|
13
|
+
@flowname = flow.filename.sub(/\..*/, '') # Base off the filename since it will include any prefix
|
14
|
+
@used_test_numbers = {}
|
15
|
+
@bin_names = Processors::ExtractBinNames.new.run(ast)
|
16
|
+
@test_modes = Array(options[:test_modes])
|
17
|
+
@empty = true
|
18
|
+
l = '"Suite name","Pins","Test name","Test number"'
|
19
|
+
if test_modes.empty?
|
20
|
+
l += ',"Lsl","Lsl_typ","Usl_typ","Usl","Units","Bin_s_num","Bin_s_name","Bin_h_num","Bin_h_name","Bin_type","Bin_reprobe","Bin_overon","Test_remarks"'
|
21
|
+
lines << l
|
22
|
+
else
|
23
|
+
l += (',"Lsl","Lsl_typ","Usl_typ","Usl","Units"' * test_modes.size) + ',"Bin_s_num","Bin_s_name","Bin_h_num","Bin_h_name","Bin_type","Bin_reprobe","Bin_overon","Test_remarks"'
|
24
|
+
lines << l
|
25
|
+
l = '"Test mode",,,'
|
26
|
+
test_modes.each do |mode|
|
27
|
+
l += ",\"#{mode}\",\"#{mode}\",\"#{mode}\",\"#{mode}\",\"#{mode}\""
|
28
|
+
end
|
29
|
+
l += ',,,,,,,,'
|
30
|
+
lines << l
|
31
|
+
end
|
32
|
+
process(ast)
|
33
|
+
end
|
34
|
+
|
35
|
+
def lines
|
36
|
+
@lines ||= []
|
37
|
+
end
|
38
|
+
|
39
|
+
def subdirectory
|
40
|
+
'testtable/limits'
|
41
|
+
end
|
42
|
+
|
43
|
+
def on_test(node)
|
44
|
+
o = {}
|
45
|
+
o[:suite_name] = extract_test_suite_name(node, o)
|
46
|
+
|
47
|
+
lines << line(extract_line_options(node, o))
|
48
|
+
|
49
|
+
node.find_all(:sub_test).each do |sub_test|
|
50
|
+
lines << line(extract_line_options(sub_test, o.dup))
|
51
|
+
end
|
52
|
+
|
53
|
+
process_all(node.children)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns true if the AST provided when initializing this limits table generator did not
|
57
|
+
# contain any tests, i.e. the resultant limits file is empty
|
58
|
+
def empty?
|
59
|
+
@empty
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def extract_line_options(node, o)
|
65
|
+
o[:test_name] = extract_test_name(node, o)
|
66
|
+
o[:test_number] = extract_test_number(node, o)
|
67
|
+
o[:limits] = extract_limits(node, o)
|
68
|
+
if on_fail = node.find(:on_fail)
|
69
|
+
if set_result = on_fail.find(:set_result)
|
70
|
+
if bin = set_result.find(:bin)
|
71
|
+
o[:bin_h_num] = bin.to_a[0] || o[:bin_h_num]
|
72
|
+
o[:bin_h_name] = bin_names[:hard][bin.to_a[0]][:name]
|
73
|
+
end
|
74
|
+
if sbin = set_result.find(:softbin)
|
75
|
+
o[:bin_s_num] = sbin.to_a[0] || o[:bin_s_num]
|
76
|
+
o[:bin_s_name] = bin_names[:soft][sbin.to_a[0]][:name]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
delayed = on_fail.find(:delayed)
|
80
|
+
if delayed && !delayed.to_a[0]
|
81
|
+
o[:bin_overon] = 'no'
|
82
|
+
elsif (delayed && delayed.to_a[0]) || tester.delayed_binning
|
83
|
+
o[:bin_overon] = 'on'
|
84
|
+
else
|
85
|
+
o[:bin_overon] = 'no'
|
86
|
+
end
|
87
|
+
end
|
88
|
+
o
|
89
|
+
end
|
90
|
+
|
91
|
+
def extract_limits(node, o)
|
92
|
+
modes = test_modes
|
93
|
+
lims = {}
|
94
|
+
(modes + [nil]).each do |mode|
|
95
|
+
lims[mode] = {}
|
96
|
+
if node.find(:nolimits)
|
97
|
+
lims[mode][:lsl] = nil
|
98
|
+
lims[mode][:lsl_typ] = 'NA'
|
99
|
+
lims[mode][:usl] = nil
|
100
|
+
lims[mode][:usl_typ] = 'NA'
|
101
|
+
else
|
102
|
+
limits = node.find_all(:limit)
|
103
|
+
if limits.empty?
|
104
|
+
# Assume it is a functional test in this case
|
105
|
+
lims[mode][:lsl] = 0
|
106
|
+
lims[mode][:lsl_typ] = 'GE'
|
107
|
+
lims[mode][:usl] = 0
|
108
|
+
lims[mode][:usl_typ] = 'LE'
|
109
|
+
else
|
110
|
+
limits.find_all { |l| l.to_a[3].to_s == mode.to_s }.each do |limit|
|
111
|
+
limit = limit.to_a
|
112
|
+
if limit[1] =~ /^G/i
|
113
|
+
lims[mode][:lsl] = limit[0]
|
114
|
+
lims[mode][:lsl_typ] = limit[0] ? limit[1].to_s.upcase : nil
|
115
|
+
lims[mode][:lsl_typ] = 'GE' if lims[mode][:lsl_typ] == 'GTE'
|
116
|
+
else
|
117
|
+
lims[mode][:usl] = limit[0]
|
118
|
+
lims[mode][:usl_typ] = limit[0] ? limit[1].to_s.upcase : nil
|
119
|
+
lims[mode][:usl_typ] = 'LE' if lims[mode][:usl_typ] == 'LTE'
|
120
|
+
end
|
121
|
+
lims[mode][:units] = limit[2]
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
lims
|
127
|
+
end
|
128
|
+
|
129
|
+
def extract_test_number(node, o)
|
130
|
+
number = (node.find(:number) || []).to_a[0]
|
131
|
+
if number
|
132
|
+
if n1 = @used_test_numbers[number]
|
133
|
+
if n1.has_source? && node.has_source?
|
134
|
+
Origen.log.error "Test number #{number} has been assigned more than once in limits file #{filename} (flow: #{flowname}):"
|
135
|
+
Origen.log.error " #{n1.source}"
|
136
|
+
Origen.log.error " #{node.source}"
|
137
|
+
exit 1
|
138
|
+
else
|
139
|
+
fail "Test number #{number} cannot be assigned to #{o[:suite_name]} in limits file #{filename} (flow: #{flowname}), since it has already be used for #{@used_test_numbers[number]}!"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
@used_test_numbers[number] = node
|
143
|
+
number
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def extract_test_suite_name(node, o)
|
148
|
+
test_obj = node.find(:object).to_a[0]
|
149
|
+
test_obj.respond_to?(:name) ? test_obj.name : test_obj if test_obj
|
150
|
+
end
|
151
|
+
|
152
|
+
def extract_test_name(node, o)
|
153
|
+
(node.find(:name) || []).to_a[0] || extract_test_suite_name(node, o) || o[:suite_name]
|
154
|
+
end
|
155
|
+
|
156
|
+
def line(options)
|
157
|
+
@empty = false
|
158
|
+
# "Suite name"
|
159
|
+
l = "\"#{options[:suite_name]}\""
|
160
|
+
# "Pins"
|
161
|
+
l << f(options[:pins])
|
162
|
+
# "Test name"
|
163
|
+
l << f(options[:test_name])
|
164
|
+
# "Test number"
|
165
|
+
l << f(options[:test_number])
|
166
|
+
if test_modes.empty?
|
167
|
+
# "Lsl"
|
168
|
+
l << f((options[:limits][nil] || {})[:lsl])
|
169
|
+
# "Lsl_typ"
|
170
|
+
l << f((options[:limits][nil] || {})[:lsl_typ])
|
171
|
+
# "Usl_typ"
|
172
|
+
l << f((options[:limits][nil] || {})[:usl_typ])
|
173
|
+
# "Usl"
|
174
|
+
l << f((options[:limits][nil] || {})[:usl])
|
175
|
+
# "Units"
|
176
|
+
l << f((options[:limits][nil] || {})[:units])
|
177
|
+
else
|
178
|
+
test_modes.each do |mode|
|
179
|
+
# "Lsl"
|
180
|
+
l << f((options[:limits][mode] || options[:limits][nil] || {})[:lsl])
|
181
|
+
# "Lsl_typ"
|
182
|
+
l << f((options[:limits][mode] || options[:limits][nil] || {})[:lsl_typ])
|
183
|
+
# "Usl_typ"
|
184
|
+
l << f((options[:limits][mode] || options[:limits][nil] || {})[:usl_typ])
|
185
|
+
# "Usl"
|
186
|
+
l << f((options[:limits][mode] || options[:limits][nil] || {})[:usl])
|
187
|
+
# "Units"
|
188
|
+
l << f((options[:limits][mode] || options[:limits][nil] || {})[:units])
|
189
|
+
end
|
190
|
+
end
|
191
|
+
# "Bin_s_num"
|
192
|
+
l << f(options[:bin_s_num])
|
193
|
+
# "Bin_s_name"
|
194
|
+
l << f(options[:bin_s_name])
|
195
|
+
# "Bin_h_num"
|
196
|
+
l << f(options[:bin_h_num])
|
197
|
+
# "Bin_h_name"
|
198
|
+
l << f(options[:bin_h_name])
|
199
|
+
# "Bin_type"
|
200
|
+
l << f(options[:bin_type])
|
201
|
+
# "Bin_reprobe"
|
202
|
+
l << f(options[:bin_reprobe])
|
203
|
+
# "Bin_overon"
|
204
|
+
l << f(options[:bin_overon])
|
205
|
+
# "Test_remarks"
|
206
|
+
l << f(options[:test_remarks])
|
207
|
+
l
|
208
|
+
end
|
209
|
+
|
210
|
+
def f(value)
|
211
|
+
",\"#{value}\""
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
@@ -41,11 +41,19 @@ module OrigenTesters
|
|
41
41
|
# end
|
42
42
|
|
43
43
|
def patterns
|
44
|
-
(references[:subroutine][:all] + references[:subroutine][:ate] +
|
44
|
+
return_arr = (references[:subroutine][:all] + references[:subroutine][:ate] +
|
45
45
|
references[:main][:all] + references[:main][:ate]).map do |p|
|
46
46
|
p = p.strip
|
47
47
|
p += '.binl.gz' unless p =~ /binl.gz$/
|
48
48
|
end.uniq
|
49
|
+
if $tester.multiport
|
50
|
+
return_arr += (references[:main][:all] + references[:main][:ate]).map do |p|
|
51
|
+
p = p.strip
|
52
|
+
p = $tester.multiport_name(p)
|
53
|
+
p += '.binl.gz' unless p =~ /.binl.gz$/
|
54
|
+
end.uniq
|
55
|
+
end
|
56
|
+
return_arr
|
49
57
|
end
|
50
58
|
|
51
59
|
def references
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module OrigenTesters
|
2
|
+
module SmartestBasedTester
|
3
|
+
class Base
|
4
|
+
module Processors
|
5
|
+
class ExtractBinNames < ATP::Processor
|
6
|
+
def run(node, options = {})
|
7
|
+
@bin_names = { soft: {}, hard: {} }
|
8
|
+
process(node)
|
9
|
+
@bin_names
|
10
|
+
end
|
11
|
+
|
12
|
+
def on_bin_descriptions(node)
|
13
|
+
node.children.each do |n|
|
14
|
+
number, name = *n
|
15
|
+
record number, name, type: n.type
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def on_test(node)
|
20
|
+
if on_fail = node.find(:on_fail)
|
21
|
+
if set_result = on_fail.find(:set_result)
|
22
|
+
if bin = set_result.find(:bin)
|
23
|
+
if bin.to_a[1]
|
24
|
+
record(*bin.to_a, supplied: true, type: :hard)
|
25
|
+
else
|
26
|
+
record(*bin.to_a, default_name(node), type: :hard)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
if sbin = set_result.find(:softbin)
|
30
|
+
if sbin.to_a[1]
|
31
|
+
record(*sbin.to_a, supplied: true, type: :soft)
|
32
|
+
else
|
33
|
+
record(*sbin.to_a, default_name(node), type: :soft)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
process_all(node.children)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def default_name(node)
|
44
|
+
test_obj = node.find(:object).to_a[0]
|
45
|
+
suite_name = test_obj.respond_to?(:name) ? test_obj.name : test_obj
|
46
|
+
test_name = (node.find(:name) || []).to_a[0] || suite_name
|
47
|
+
if suite_name == test_name
|
48
|
+
suite_name
|
49
|
+
else
|
50
|
+
"#{suite_name}_#{test_name}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def record(number, name, options)
|
55
|
+
table = @bin_names[options[:type]]
|
56
|
+
if !table[number] || (options[:supplied] && !table[number][:supplied])
|
57
|
+
table[number] = { name: name, supplied: options[:supplied] }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -15,6 +15,7 @@ module OrigenTesters
|
|
15
15
|
attr_reader :parameters
|
16
16
|
attr_accessor :class_name
|
17
17
|
attr_accessor :abs_class_name
|
18
|
+
attr_reader :limits
|
18
19
|
attr_accessor :limits_id
|
19
20
|
|
20
21
|
def initialize(options)
|
@@ -22,10 +23,6 @@ module OrigenTesters
|
|
22
23
|
@library = options[:library]
|
23
24
|
@class_name = options[:methods].delete(:class_name)
|
24
25
|
@parameters = {}
|
25
|
-
# Add limits by default
|
26
|
-
define_singleton_method('limits') do
|
27
|
-
@limits
|
28
|
-
end
|
29
26
|
@limits_id = options[:methods].delete(:limits_id)
|
30
27
|
@limits = TestMethods::Limits.new(self)
|
31
28
|
# Add any methods
|
@@ -52,6 +52,17 @@ module OrigenTesters
|
|
52
52
|
self.hi_limit = val
|
53
53
|
end
|
54
54
|
|
55
|
+
def to_atp_attributes
|
56
|
+
r = []
|
57
|
+
if lo_limit
|
58
|
+
r << { value: lo_limit, rule: 'LE', units: unit }
|
59
|
+
end
|
60
|
+
if hi_limit
|
61
|
+
r << { value: hi_limit, rule: 'GE', units: unit }
|
62
|
+
end
|
63
|
+
r
|
64
|
+
end
|
65
|
+
|
55
66
|
private
|
56
67
|
|
57
68
|
def test_name
|
@@ -130,6 +130,9 @@ module OrigenTesters
|
|
130
130
|
end
|
131
131
|
|
132
132
|
def lines
|
133
|
+
if pattern
|
134
|
+
burst = $tester.multiport ? "#{$tester.multiport_name(pattern)}" : "#{pattern}"
|
135
|
+
end
|
133
136
|
l = []
|
134
137
|
l << " comment = \"#{comment}\";" if comment
|
135
138
|
l << " ffc_on_fail = #{wrap_if_string(log_first)};" if log_first
|
@@ -139,7 +142,7 @@ module OrigenTesters
|
|
139
142
|
l << " override_lev_equ_set = #{wrap_if_string(level_equation)};" if level_equation
|
140
143
|
l << " override_lev_spec_set = #{wrap_if_string(level_spec)};" if level_spec
|
141
144
|
l << " override_levset = #{wrap_if_string(level_set)};" if level_set
|
142
|
-
l << " override_seqlbl = #{wrap_if_string(
|
145
|
+
l << " override_seqlbl = #{wrap_if_string(burst)};" if pattern
|
143
146
|
l << " override_test_number = #{test_number};" if test_number
|
144
147
|
l << " override_testf = #{test_method.id};" if test_method
|
145
148
|
l << " override_tim_equ_set = #{wrap_if_string(timing_equation)};" if timing_equation
|
@@ -171,6 +174,10 @@ module OrigenTesters
|
|
171
174
|
meta || {}
|
172
175
|
end
|
173
176
|
|
177
|
+
def extract_atp_attributes(options)
|
178
|
+
options[:limits] ||= limits.to_atp_attributes
|
179
|
+
end
|
180
|
+
|
174
181
|
private
|
175
182
|
|
176
183
|
def flags
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module OrigenTesters
|
2
|
+
module SmartestBasedTester
|
3
|
+
class V93K
|
4
|
+
require 'origen_testers/smartest_based_tester/base/limits_file'
|
5
|
+
class LimitsFile < Base::LimitsFile
|
6
|
+
TEMPLATE = "#{Origen.root!}/lib/origen_testers/smartest_based_tester/v93k/templates/limits.csv.erb"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -8,10 +8,25 @@ single_binary_pattern_dir ./BINL/
|
|
8
8
|
|
9
9
|
AI_V2B_OPTIONS -ALT -c <%= $dut.name.to_s.upcase %>.vbc -k -z PS800
|
10
10
|
|
11
|
+
% if $tester.multiport
|
12
|
+
PATTERNS name tmf_file port v2b_options
|
13
|
+
% port = !!$tester.multiport ? " #{$tester.multiport}" : ''
|
14
|
+
% else
|
11
15
|
PATTERNS name tmf_file v2b_options
|
16
|
+
% end
|
12
17
|
% subroutines.each do |pattern|
|
13
|
-
<%= pattern %> <%= $dut.name.to_s.upcase %>.tmf -s
|
18
|
+
<%= pattern %> <%= $dut.name.to_s.upcase %>.tmf<%= port %> -s
|
14
19
|
% end
|
15
20
|
% patterns.each do |pattern|
|
16
|
-
<%= pattern %> <%= $dut.name.to_s.upcase %>.tmf
|
21
|
+
<%= pattern %> <%= $dut.name.to_s.upcase %>.tmf<%= port %>
|
17
22
|
% end
|
23
|
+
%#-
|
24
|
+
% if $tester.multiport
|
25
|
+
% patterns.each do |pattern|
|
26
|
+
|
27
|
+
MULTI_PORT_BURST "<%= "#{$tester.multiport_name(pattern)}" %>"
|
28
|
+
PORTS <%= $tester.multiport %>
|
29
|
+
SEQ_GRPS grp1
|
30
|
+
<%= pattern %>
|
31
|
+
% end
|
32
|
+
% end
|
@@ -124,6 +124,7 @@ end
|
|
124
124
|
-----------------------------------------------------------------
|
125
125
|
testmethodlimits
|
126
126
|
|
127
|
+
% unless tester.create_limits_file
|
127
128
|
% if program
|
128
129
|
% program.testmethodlimits.each do |id, parameters|
|
129
130
|
<%= id %>:
|
@@ -139,6 +140,7 @@ testmethodlimits
|
|
139
140
|
% end
|
140
141
|
% end
|
141
142
|
% end
|
143
|
+
% end
|
142
144
|
|
143
145
|
end
|
144
146
|
-----------------------------------------------------------------
|
@@ -16,10 +16,26 @@ module OrigenTesters
|
|
16
16
|
include OrigenJTAG
|
17
17
|
|
18
18
|
def initialize(options = {})
|
19
|
+
options = {
|
20
|
+
test_generic_overlay_capture: false
|
21
|
+
}.merge(options)
|
22
|
+
|
23
|
+
@test_options = {
|
24
|
+
test_generic_overlay_capture: options[:test_generic_overlay_capture]
|
25
|
+
}
|
26
|
+
|
19
27
|
add_pin :tclk
|
20
28
|
add_pin :tdi
|
21
29
|
add_pin :tdo
|
22
30
|
add_pin :tms
|
31
|
+
if @test_options[:test_generic_overlay_capture]
|
32
|
+
# approved patts for this test type do not use these
|
33
|
+
add_pin :pa0
|
34
|
+
add_pin :pa1
|
35
|
+
add_pin :pa2
|
36
|
+
add_pin_group :pa, :pa2, :pa1, :pa0
|
37
|
+
add_pin_alias :tdi_a, :tdi
|
38
|
+
end
|
23
39
|
# add_pin_group :jtag, :tdi, :tdo, :tms
|
24
40
|
add_power_pin_group :vdd1
|
25
41
|
add_power_pin_group :vdd2
|
@@ -32,23 +48,28 @@ module OrigenTesters
|
|
32
48
|
reg.bits 1, :done
|
33
49
|
reg.bits 0, :enable
|
34
50
|
end
|
35
|
-
@
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
51
|
+
unless @test_options[:test_generic_overlay_capture]
|
52
|
+
# approved patts for this test type do not use these
|
53
|
+
@hv_supply_pin = 'VDDHV'
|
54
|
+
@lv_supply_pin = 'VDDLV'
|
55
|
+
@digsrc_pins = [:tdi, :tms]
|
56
|
+
@digsrc_settings = { digsrc_mode: :parallel, digsrc_bit_order: :msb }
|
57
|
+
@digcap_pins = :tdo
|
58
|
+
@digcap_settings = { digcap_format: :twos_complement }
|
59
|
+
end
|
41
60
|
@blocks = [Block.new(0, self), Block.new(1, self), Block.new(2, self)]
|
42
61
|
end
|
43
62
|
|
44
63
|
def on_create
|
45
|
-
|
46
|
-
tester.
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
64
|
+
unless @test_options[:test_generic_overlay_capture]
|
65
|
+
if tester && tester.uflex?
|
66
|
+
tester.assign_dc_instr_pins([hv_supply_pin, lv_supply_pin])
|
67
|
+
tester.assign_digsrc_pins(digsrc_pins)
|
68
|
+
tester.apply_digsrc_settings(digsrc_settings)
|
69
|
+
tester.assign_digcap_pins(digcap_pins)
|
70
|
+
tester.apply_digcap_settings(digcap_settings)
|
71
|
+
tester.memory_test_en = true
|
72
|
+
end
|
52
73
|
end
|
53
74
|
end
|
54
75
|
|
data/program/test.rb
CHANGED
@@ -10,16 +10,21 @@ Flow.create interface: 'OrigenTesters::Test::Interface' do
|
|
10
10
|
|
11
11
|
# para 'charge_pump', :high_voltage => true, :lo_limit => 5, :hi_limit => 6
|
12
12
|
|
13
|
+
if tester.v93k? && tester.create_limits_file
|
14
|
+
func :program_ckbd, :number => 1000, :bin => 100, :soft_bin => 1100
|
15
|
+
end
|
13
16
|
meas :read_pump, tnum: 1050, bin: 119, soft_bin: 2, lo_limit: 35, number: 40000
|
14
|
-
meas :read_pump, tnum:
|
15
|
-
meas :read_pump, tnum:
|
16
|
-
meas :read_pump, tnum:
|
17
|
-
meas :read_pump, tnum:
|
18
|
-
meas :read_pump, tnum:
|
19
|
-
meas :read_pump, tnum:
|
20
|
-
|
21
|
-
|
22
|
-
|
17
|
+
meas :read_pump, tnum: 1060, bin: 119, soft_bin: 2, hi_limit: 45, number: 40010
|
18
|
+
meas :read_pump, tnum: 1070, bin: 119, soft_bin: 2, hi_limit: 45, lo_limit: 35, number: 40020
|
19
|
+
meas :read_pump, tnum: 1080, bin: 119, soft_bin: 2, hi_limit: 45, lo_limit: 35, number: 40030
|
20
|
+
meas :read_pump, tnum: 1090, bin: 119, soft_bin: 2, hi_limit: 45.mV, lo_limit: 35.mV, number: 40040
|
21
|
+
meas :read_pump, tnum: 1100, bin: 119, soft_bin: 2, hi_limit: 45.mV, lo_limit: 35.mV, continue: true, number: 40050
|
22
|
+
meas :read_pump, tnum: 1110, bin: 119, soft_bin: 2, hi_limit: 2000, lo_limit: 0.01, continue: true, number: 40060
|
23
|
+
unless tester.v93k? && tester.create_limits_file
|
24
|
+
meas :read_pump, tnum: 1120, bin: 119, soft_bin: 2, hi_limit: "_some_spec", lo_limit: 0.01, continue: true, number: 40070
|
25
|
+
meas :read_pump, tnum: 1130, bin: 119, soft_bin: 2, hi_limit: [1, 2], number: 40080
|
26
|
+
meas :read_pump, tnum: 1140, bin: 119, soft_bin: 2, lo_limit: [1.uA, 2.uA, 3.uA], hi_limit: [4.uA,5.uA], units: "A", defer_limits: true, number: 40090
|
27
|
+
end
|
23
28
|
|
24
29
|
if tester.uflex?
|
25
30
|
log "Test of ultraflex render API"
|
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.19.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: 2018-
|
11
|
+
date: 2018-05-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: origen
|
@@ -254,9 +254,10 @@ files:
|
|
254
254
|
- lib/origen_testers/smartest_based_tester/base.rb
|
255
255
|
- lib/origen_testers/smartest_based_tester/base/flow.rb
|
256
256
|
- lib/origen_testers/smartest_based_tester/base/generator.rb
|
257
|
+
- lib/origen_testers/smartest_based_tester/base/limits_file.rb
|
257
258
|
- lib/origen_testers/smartest_based_tester/base/pattern_compiler.rb
|
258
259
|
- lib/origen_testers/smartest_based_tester/base/pattern_master.rb
|
259
|
-
- lib/origen_testers/smartest_based_tester/base/processors/
|
260
|
+
- lib/origen_testers/smartest_based_tester/base/processors/extract_bin_names.rb
|
260
261
|
- lib/origen_testers/smartest_based_tester/base/test_method.rb
|
261
262
|
- lib/origen_testers/smartest_based_tester/base/test_methods.rb
|
262
263
|
- lib/origen_testers/smartest_based_tester/base/test_methods/ac_tml.rb
|
@@ -273,8 +274,10 @@ files:
|
|
273
274
|
- lib/origen_testers/smartest_based_tester/v93k/builder/pattern_master.rb
|
274
275
|
- lib/origen_testers/smartest_based_tester/v93k/flow.rb
|
275
276
|
- lib/origen_testers/smartest_based_tester/v93k/generator.rb
|
277
|
+
- lib/origen_testers/smartest_based_tester/v93k/limits_file.rb
|
276
278
|
- lib/origen_testers/smartest_based_tester/v93k/pattern_compiler.rb
|
277
279
|
- lib/origen_testers/smartest_based_tester/v93k/pattern_master.rb
|
280
|
+
- lib/origen_testers/smartest_based_tester/v93k/templates/limits.csv.erb
|
278
281
|
- lib/origen_testers/smartest_based_tester/v93k/templates/template.aiv.erb
|
279
282
|
- lib/origen_testers/smartest_based_tester/v93k/templates/template.pmfl.erb
|
280
283
|
- lib/origen_testers/smartest_based_tester/v93k/templates/template.tf.erb
|
@@ -289,7 +292,6 @@ files:
|
|
289
292
|
- lib/origen_testers/test/custom_test_interface.rb
|
290
293
|
- lib/origen_testers/test/dut.rb
|
291
294
|
- lib/origen_testers/test/dut2.rb
|
292
|
-
- lib/origen_testers/test/dut3.rb
|
293
295
|
- lib/origen_testers/test/interface.rb
|
294
296
|
- lib/origen_testers/test/nvm.rb
|
295
297
|
- lib/origen_testers/timing.rb
|
@@ -362,7 +364,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
362
364
|
version: '0'
|
363
365
|
requirements: []
|
364
366
|
rubyforge_project:
|
365
|
-
rubygems_version: 2.6.
|
367
|
+
rubygems_version: 2.6.7
|
366
368
|
signing_key:
|
367
369
|
specification_version: 4
|
368
370
|
summary: This plugin provides Origen tester models to drive ATE type testers like
|
@@ -1,22 +0,0 @@
|
|
1
|
-
module OrigenTesters
|
2
|
-
module SmartestBasedTester
|
3
|
-
class Base
|
4
|
-
module Processors
|
5
|
-
# Extracts all runtime variables which are set within the given flow, returning
|
6
|
-
# them in an array
|
7
|
-
class ExtractSetVariables < ATP::Processor
|
8
|
-
def run(nodes)
|
9
|
-
@results = []
|
10
|
-
process_all(nodes)
|
11
|
-
@results.uniq
|
12
|
-
end
|
13
|
-
|
14
|
-
def on_set_flag(node)
|
15
|
-
flag = node.value
|
16
|
-
@results << flag
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,244 +0,0 @@
|
|
1
|
-
module OrigenTesters
|
2
|
-
module Test
|
3
|
-
class DUT3
|
4
|
-
# Simple DUT using Nexus interface
|
5
|
-
|
6
|
-
attr_accessor :blocks
|
7
|
-
attr_accessor :hv_supply_pin
|
8
|
-
attr_accessor :lv_supply_pin
|
9
|
-
attr_accessor :digsrc_pins
|
10
|
-
attr_accessor :digcap_pins
|
11
|
-
attr_accessor :digsrc_settings
|
12
|
-
attr_accessor :digcap_settings
|
13
|
-
|
14
|
-
include OrigenARMDebug
|
15
|
-
include Origen::TopLevel
|
16
|
-
include OrigenJTAG
|
17
|
-
|
18
|
-
def initialize(options = {})
|
19
|
-
add_pin :tclk
|
20
|
-
add_pin :tdi
|
21
|
-
add_pin :tdo
|
22
|
-
add_pin :tms
|
23
|
-
add_pin :pa0
|
24
|
-
add_pin :pa1
|
25
|
-
add_pin :pa2
|
26
|
-
add_pin_group :pa, :pa2, :pa1, :pa0
|
27
|
-
add_pin_alias :tdi_a, :tdi
|
28
|
-
# add_pin_group :jtag, :tdi, :tdo, :tms
|
29
|
-
add_power_pin_group :vdd1
|
30
|
-
add_power_pin_group :vdd2
|
31
|
-
add_virtual_pin :virtual1, type: :virtual_pin
|
32
|
-
add_virtual_pin :virtual2, type: :ate_ch
|
33
|
-
|
34
|
-
reg :testme32, 0x007a do |reg|
|
35
|
-
reg.bits 31..16, :portB
|
36
|
-
reg.bits 15..8, :portA
|
37
|
-
reg.bits 1, :done
|
38
|
-
reg.bits 0, :enable
|
39
|
-
end
|
40
|
-
@blocks = [Block.new(0, self), Block.new(1, self), Block.new(2, self)]
|
41
|
-
end
|
42
|
-
|
43
|
-
def startup(options)
|
44
|
-
$tester.set_timeset('tp0', 60)
|
45
|
-
end
|
46
|
-
|
47
|
-
def write_register(reg, options = {})
|
48
|
-
arm_debug.write_register(reg, options)
|
49
|
-
end
|
50
|
-
|
51
|
-
def read_register(reg, options = {})
|
52
|
-
arm_debug.write_register(reg, options)
|
53
|
-
end
|
54
|
-
|
55
|
-
def execute(options = {})
|
56
|
-
options = { define: false, # whether to define subr or call it
|
57
|
-
name: 'executefunc1',
|
58
|
-
onemodsub: false # whether to expects subr to be in single module
|
59
|
-
}.merge(options)
|
60
|
-
|
61
|
-
if options[:define]
|
62
|
-
# define subroutine
|
63
|
-
$tester.start_subroutine(options[:name], onemodsub: options[:onemodsub])
|
64
|
-
$tester.cycle
|
65
|
-
$tester.end_subroutine(onemodsub: options[:onemodsub])
|
66
|
-
$tester.cycle unless options[:onemodsub]
|
67
|
-
else
|
68
|
-
# call subroutine
|
69
|
-
$tester.cycle
|
70
|
-
$tester.call_subroutine(options[:name])
|
71
|
-
$tester.cycle
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
# Match loop functionality
|
76
|
-
def match(options = {})
|
77
|
-
options = { type: :match_pin, # whether to match DONE bit in register or match pin
|
78
|
-
# :match_done
|
79
|
-
# :match_2pins
|
80
|
-
delay_in_us: 5, # match loop delay
|
81
|
-
define: false, # whether to define subr or call it
|
82
|
-
subr_name: false, # default use match type as subr name
|
83
|
-
}.merge(options)
|
84
|
-
|
85
|
-
subr_name = options[:subr_name] ? options[:subr_name] : options[:type].to_s
|
86
|
-
|
87
|
-
if options[:define]
|
88
|
-
$tester.start_subroutine(subr_name)
|
89
|
-
$tester.cycle
|
90
|
-
if options[:type] == :match_done
|
91
|
-
|
92
|
-
# Match DONE bit in register
|
93
|
-
$tester.wait(match: true,
|
94
|
-
time_in_us: options[:delay_in_us],
|
95
|
-
global_loops: true,
|
96
|
-
check_for_fails: true,
|
97
|
-
force_fail_on_timeout: true,
|
98
|
-
clr_fail_post_match: true,
|
99
|
-
manual_stop: true) do
|
100
|
-
# Match on reading done bit
|
101
|
-
reg(:testme32).bits(:done).write(1)
|
102
|
-
reg(:testme32).bits(:done).read!
|
103
|
-
end
|
104
|
-
elsif options[:type] == :match_pin
|
105
|
-
# Match on TDO pin state
|
106
|
-
$tester.wait(match: true,
|
107
|
-
pin: pin(:tdo),
|
108
|
-
state: :high,
|
109
|
-
time_in_us: options[:delay_in_us],
|
110
|
-
global_loops: true,
|
111
|
-
check_for_fails: true,
|
112
|
-
force_fail_on_timeout: true,
|
113
|
-
clr_fail_post_match: true,
|
114
|
-
manual_stop: true)
|
115
|
-
elsif options[:type] == :match_2pins
|
116
|
-
# Match on TDO pin state
|
117
|
-
$tester.wait(match: true,
|
118
|
-
pin: pin(:tdo),
|
119
|
-
state: :high,
|
120
|
-
pin2: pin(:tms),
|
121
|
-
state2: :high,
|
122
|
-
time_in_us: options[:delay_in_us],
|
123
|
-
global_loops: true,
|
124
|
-
check_for_fails: true,
|
125
|
-
force_fail_on_timeout: true,
|
126
|
-
clr_fail_post_match: true,
|
127
|
-
manual_stop: true)
|
128
|
-
elsif options[:type] == :multiple_entries
|
129
|
-
# Match on TDO pin state, with multiple subr entry points
|
130
|
-
$tester.wait(match: true,
|
131
|
-
pin: pin(:tdo),
|
132
|
-
state: :high,
|
133
|
-
time_in_us: options[:delay_in_us],
|
134
|
-
global_loops: true,
|
135
|
-
multiple_entries: true,
|
136
|
-
check_for_fails: true,
|
137
|
-
force_fail_on_timeout: true,
|
138
|
-
clr_fail_post_match: true,
|
139
|
-
manual_stop: true)
|
140
|
-
end
|
141
|
-
$tester.cycle
|
142
|
-
$tester.end_subroutine
|
143
|
-
$tester.cycle
|
144
|
-
else
|
145
|
-
# call subroutine
|
146
|
-
$tester.cycle
|
147
|
-
$tester.call_subroutine(subr_name)
|
148
|
-
$tester.cycle
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
def handshake(options = {})
|
153
|
-
options = {
|
154
|
-
define: false, # whether to define subr or call it
|
155
|
-
}.merge(options)
|
156
|
-
|
157
|
-
if options[:define]
|
158
|
-
$tester.start_subroutine('handshake')
|
159
|
-
$tester.handshake(readcode: 100)
|
160
|
-
$tester.cycle
|
161
|
-
$tester.cycle
|
162
|
-
$tester.cycle
|
163
|
-
$tester.end_subroutine
|
164
|
-
else
|
165
|
-
$tester.cycle
|
166
|
-
$tester.call_subroutine('handshake')
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
def digsrc_overlay(options = {})
|
171
|
-
options = { define: false, # whether to define subr or call it
|
172
|
-
subr_name: false, # default use match type as subr name
|
173
|
-
digsrc_pins: @digsrc_pins, # defaults to what's defined in $dut
|
174
|
-
overlay_reg: nil, # defaults to testme32 register
|
175
|
-
overlay_cycle_num: 32, # Only needed if overlay_reg is NOT nil, this specificies how many clk cycles to overlay.
|
176
|
-
}.merge(options)
|
177
|
-
if options[:define]
|
178
|
-
$tester.start_subroutine(options[:subr_name]) # Start subroutine
|
179
|
-
digsrc_pins = $tester.assign_digsrc_pins(options[:digsrc_pins])
|
180
|
-
$tester.digsrc_start(digsrc_pins, dssc_mode: :single)
|
181
|
-
original_pin_states = {}
|
182
|
-
digsrc_pins.each do |pin|
|
183
|
-
original_pin_states.merge!(pin => pin(pin).data)
|
184
|
-
pin(pin).drive_mem
|
185
|
-
end
|
186
|
-
if options[:overlay_reg].nil?
|
187
|
-
options[:overlay_cycle_num].times do
|
188
|
-
$tester.digsrc_send(digsrc_pins)
|
189
|
-
$tester.cycle
|
190
|
-
end
|
191
|
-
else
|
192
|
-
$tester.dont_compress = true
|
193
|
-
options[:overlay_reg].size.times do
|
194
|
-
$tester.digsrc_send(digsrc_pins)
|
195
|
-
$tester.cycle
|
196
|
-
end
|
197
|
-
end
|
198
|
-
original_pin_states.each do |pin, state|
|
199
|
-
pin(pin).drive(state)
|
200
|
-
end
|
201
|
-
$tester.digsrc_stop(digsrc_pins)
|
202
|
-
$tester.cycle
|
203
|
-
$tester.end_subroutine # end subroutine
|
204
|
-
else
|
205
|
-
$tester.cycle
|
206
|
-
$tester.call_subroutine(options[:subr_name])
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
def memory_test(options = {})
|
211
|
-
options = {
|
212
|
-
}.merge(options)
|
213
|
-
|
214
|
-
$tester.memory_test(inc_counter_x: true, gen_vector: true)
|
215
|
-
|
216
|
-
$tester.memory_test(inc_counter_y: true, gen_vector: true)
|
217
|
-
|
218
|
-
$tester.memory_test(init_counter_x: true)
|
219
|
-
|
220
|
-
$tester.memory_test(inc_counter_x: true, init_counter_y: true)
|
221
|
-
|
222
|
-
$tester.memory_test(inc_counter_y: true, capture_vector: true)
|
223
|
-
|
224
|
-
$tester.memory_test(pin: pin(:tdo), pin_data: :expect)
|
225
|
-
end
|
226
|
-
|
227
|
-
def freq_count(options = {})
|
228
|
-
options = {
|
229
|
-
}.merge(options)
|
230
|
-
|
231
|
-
$tester.freq_count($dut.pin(:tdo), readcode: 73)
|
232
|
-
end
|
233
|
-
|
234
|
-
# dummy flag to check for a particular design bug for this DUT
|
235
|
-
def has_margin0_bug?
|
236
|
-
false
|
237
|
-
end
|
238
|
-
|
239
|
-
def find_block_by_id(id)
|
240
|
-
@blocks.find { |block| block.id == id }
|
241
|
-
end
|
242
|
-
end
|
243
|
-
end
|
244
|
-
end
|