origen_testers 0.14.0 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/config/shared_commands.rb +11 -19
- data/config/version.rb +1 -1
- data/lib/origen_testers.rb +2 -0
- data/lib/origen_testers/callback_handlers.rb +7 -25
- data/lib/origen_testers/origen_ext/generator.rb +1 -1
- data/lib/origen_testers/pattern_compilers.rb +120 -66
- data/lib/origen_testers/pattern_compilers/assembler.rb +7 -3
- data/lib/origen_testers/pattern_compilers/base.rb +266 -0
- data/lib/origen_testers/pattern_compilers/igxl_based.rb +348 -0
- data/lib/origen_testers/pattern_compilers/j750.rb +80 -0
- data/lib/origen_testers/pattern_compilers/job.rb +49 -9
- data/lib/origen_testers/pattern_compilers/runner.rb +40 -0
- data/lib/origen_testers/pattern_compilers/templates/template.aiv.erb +31 -0
- data/lib/origen_testers/pattern_compilers/ultraflex.rb +92 -0
- data/lib/origen_testers/pattern_compilers/v93k.rb +455 -0
- data/lib/origen_testers/pattern_compilers/v93k/digcap.rb +107 -0
- data/lib/origen_testers/pattern_compilers/v93k/multiport.rb +80 -0
- metadata +14 -6
- data/lib/origen_testers/pattern_compilers/ultraflex_pattern_compiler.rb +0 -599
@@ -0,0 +1,348 @@
|
|
1
|
+
module OrigenTesters
|
2
|
+
module PatternCompilers
|
3
|
+
class IGXLBasedPatternCompiler < BasePatternCompiler
|
4
|
+
def initialize(id, options = {})
|
5
|
+
super
|
6
|
+
|
7
|
+
# The following are pattern compiler options that are common between all IGXL platforms, these
|
8
|
+
# are added onto the base options. Specifc IGXL platforms can add on additional options
|
9
|
+
# in their respective initialize methods.
|
10
|
+
@user_options = {}.merge(@user_options)
|
11
|
+
|
12
|
+
@job_options = {
|
13
|
+
pinmap_workbook: dut.pinmap, # required: will default to $dut.pinmap
|
14
|
+
}.merge(@job_options)
|
15
|
+
|
16
|
+
# These are compiler options that are common to both the UltraFLEX and J750 compilers
|
17
|
+
# Set all of these compiler options that don't have args to true/flase. if true then send compiler '-opt'
|
18
|
+
@compiler_options = {
|
19
|
+
comments: false, # preserves comments in pattern binary
|
20
|
+
cpp: false, # runs C++ preprocessor on pattern file
|
21
|
+
debug: false, # generate intermediate file(s) to simplify debug ( application dependent )
|
22
|
+
import_all_undefineds: false, # automatically import all undefined symbols. the key is mis-spelled but correct!
|
23
|
+
suppress_log: false, # disables output to main log file
|
24
|
+
template: false, # generate setup template
|
25
|
+
timestamp: false, # enable log timestamp
|
26
|
+
}.merge(@compiler_options)
|
27
|
+
|
28
|
+
# These are compiler options that are common to both the UltraFLEX and J750 compilers
|
29
|
+
@compiler_options_with_args = {
|
30
|
+
define: nil, # Define macro values to be passed to C-preprocessor
|
31
|
+
digital_inst: nil, # Name of digital instrument
|
32
|
+
logfile: nil, # Messages go to <filename> instead of <infile> log
|
33
|
+
opcode_mode: nil, # Patgen opcode mode, specific to digital instrument
|
34
|
+
output: nil, # Name of output file
|
35
|
+
pinmap_sheet: nil, # Name of workbook containing pinmap
|
36
|
+
# pinmap_workbook: nil, # Name of sheet in workbook which contains pinmap (moved to @job_options)
|
37
|
+
setup: nil, # path to setup file
|
38
|
+
}.merge(@compiler_options_with_args)
|
39
|
+
end
|
40
|
+
|
41
|
+
def verify_pinmap_is_specified
|
42
|
+
if @job_options[:pinmap_workbook].nil?
|
43
|
+
# Check if the app has dut.pinmap defined
|
44
|
+
if dut.pinmap && File.exist?(dut.pinmap)
|
45
|
+
@job_options[:pinmap_workbook] = dut.pinmap
|
46
|
+
else
|
47
|
+
fail 'Pinmap is not defined! Pass as an option or set $dut.pinmap.'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
@job_options[:pinmap_workbook] = convert_to_pathname(@job_options[:pinmap_workbook])
|
51
|
+
fail 'Pinmap is not a file!' unless @job_options[:pinmap_workbook].file?
|
52
|
+
end
|
53
|
+
|
54
|
+
# Return the compiler instance pinmap
|
55
|
+
def pinmap
|
56
|
+
@job_options[:pinmap_workbook]
|
57
|
+
end
|
58
|
+
|
59
|
+
# Executes the compiler for each job in the queue
|
60
|
+
def run(list = nil, options = {})
|
61
|
+
# Check if there was a pattern list passed as an argument
|
62
|
+
# If so, then compile the patterns inside it.
|
63
|
+
# Otherwise compile the jobs in the queue
|
64
|
+
if list.nil?
|
65
|
+
if empty?
|
66
|
+
empty_msg
|
67
|
+
return
|
68
|
+
end
|
69
|
+
@jobs.each do |job|
|
70
|
+
fail "Error: compiler #{job.id} not ready for pattern #{job.name}" unless job.ready?
|
71
|
+
if job.location == :lsf
|
72
|
+
Origen.app.lsf.submit(ATPC_SETUP + '; ' + job.cmd)
|
73
|
+
else
|
74
|
+
Origen.profile "Linux pattern compiler compiles pattern #{job.pattern}" do
|
75
|
+
system job.cmd
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
if @job_options[:location] == :local
|
80
|
+
if @job_options[:clean] == true
|
81
|
+
puts 'Log file :clean option set to true, deleting log files'
|
82
|
+
clean_output
|
83
|
+
end
|
84
|
+
end
|
85
|
+
# Clear @jobs
|
86
|
+
clear
|
87
|
+
else
|
88
|
+
list = convert_to_pathname(list)
|
89
|
+
fail "Error: pattern list #{list} does not exist, exiting..." unless list.file?
|
90
|
+
File.open(list, 'r') do |file|
|
91
|
+
while (line = file.gets)
|
92
|
+
current_job_options = @job_options.merge(@compiler_options_with_args)
|
93
|
+
current_job_options.update_common(options)
|
94
|
+
# puts "current job options is #{current_job_options}"
|
95
|
+
compiler_opts = {}
|
96
|
+
line.strip!
|
97
|
+
pattern = line.match(/^(\S+)\s+(.*)/).captures[0]
|
98
|
+
unless File.file? pattern
|
99
|
+
puts "Warning: Pattern #{pattern} does not exist, skipping..."
|
100
|
+
next
|
101
|
+
end
|
102
|
+
pattern = convert_to_pathname(pattern)
|
103
|
+
line.match(/^\S+\s+(.*)/).captures[0].split(/\s+/).each do |e|
|
104
|
+
opt, arg = e.split(':')
|
105
|
+
opt.gsub!('-', '')
|
106
|
+
if arg.nil?
|
107
|
+
compiler_opts[opt.to_sym] = true
|
108
|
+
else
|
109
|
+
# Check for some specific options
|
110
|
+
case opt
|
111
|
+
when 'pinmap_workbook'
|
112
|
+
current_job_options[opt.to_sym] = Pathname.new(arg)
|
113
|
+
when 'output'
|
114
|
+
dot_pat = Pathname.new(arg)
|
115
|
+
current_job_options[:output_directory] = dot_pat.dirname
|
116
|
+
else
|
117
|
+
current_job_options[opt.to_sym] = arg
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
@jobs << Job.new(pattern, current_job_options, compiler_opts)
|
122
|
+
inspect_jobs
|
123
|
+
end
|
124
|
+
end
|
125
|
+
run
|
126
|
+
# Clear @jobs
|
127
|
+
clear
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# Finds the patterns and creates a compiler job for each one found.
|
132
|
+
# Handles singles files (.atp, .atp.gz, or .list) and directories (recursively or flat)
|
133
|
+
def find_jobs(path = @path)
|
134
|
+
fail 'Pattern path is set to nil, pass in a valid file (.atp or .atp.gz) or a valid directory' if path.nil?
|
135
|
+
@path = Pathname.new(path)
|
136
|
+
fail 'Pattern path does not exist, pass in a valid file (.atp or .atp.gz) or a valid directory' unless @path.exist?
|
137
|
+
@path = @path.expand_path
|
138
|
+
# Set the reference directory for pattern sub-dir mirroring
|
139
|
+
set_reference_directory
|
140
|
+
Origen.profile 'Linux pattern compiler finds patterns' do
|
141
|
+
# Check if the path is a file or a directory
|
142
|
+
if @path.directory?
|
143
|
+
# Get all of the patterns inside this dir or inside this directory recursively
|
144
|
+
process_directory(@path, @files, @user_options[:recursive])
|
145
|
+
elsif @path.file? # Found a file so no searching is necessary
|
146
|
+
process_file(@path, @files)
|
147
|
+
else # Didn't find a directory or a file so user must want a search for this arg string * NOT SUPPORTED YET
|
148
|
+
fail 'Error: Did not find a file or directory to compile, exiting...'
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
Origen.profile 'Linux pattern compiler creates jobs' do
|
153
|
+
@files.each do |f|
|
154
|
+
rel_dir = Pathname.new("#{f.dirname.to_s[@user_options[:reference_directory].to_s.size..-1]}")
|
155
|
+
if @job_options[:output_directory].nil?
|
156
|
+
# job output dir not specified, create a unique (hash) based on path/compiler_name
|
157
|
+
s = Digest::MD5.new
|
158
|
+
s << @user_options[:reference_directory].to_s
|
159
|
+
s << @id.to_s
|
160
|
+
out = "#{@user_options[:reference_directory]}/job_#{@id}_#{s.to_s[0..6].upcase}#{rel_dir}"
|
161
|
+
output_dir = Pathname.new(out)
|
162
|
+
else
|
163
|
+
output_dir = Pathname.new("#{@job_options[:output_directory]}#{rel_dir}")
|
164
|
+
end
|
165
|
+
unless output_dir.directory?
|
166
|
+
puts "Output directory #{output_dir} for pattern #{f.basename} does not exist, creating it..."
|
167
|
+
FileUtils.mkdir_p(output_dir)
|
168
|
+
end
|
169
|
+
current_job_options = @job_options.merge(@compiler_options_with_args)
|
170
|
+
current_job_options[:output_directory] = output_dir
|
171
|
+
@jobs << Job.new(f, current_job_options, @compiler_options)
|
172
|
+
current_job_options = {}
|
173
|
+
end
|
174
|
+
end
|
175
|
+
@files = []
|
176
|
+
if empty?
|
177
|
+
empty_msg
|
178
|
+
else
|
179
|
+
inspect_jobs
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
# Output all of the jobs into a pattern list so it can be compiled later
|
184
|
+
# Must be executed after the 'find_jobs' method and before the 'run' method
|
185
|
+
# or @jobs will be empty
|
186
|
+
def to_list(options = {})
|
187
|
+
options = {
|
188
|
+
name: @id,
|
189
|
+
output_directory: Dir.pwd,
|
190
|
+
expand: true,
|
191
|
+
force: false
|
192
|
+
}.update_common(options)
|
193
|
+
list = "#{options[:output_directory]}/#{options[:name]}.list"
|
194
|
+
list = convert_to_pathname(list)
|
195
|
+
if empty?
|
196
|
+
empty_msg
|
197
|
+
return
|
198
|
+
end
|
199
|
+
if list.file?
|
200
|
+
if options[:force] == true
|
201
|
+
puts "Pattern list file #{list} already exists, deleting it..."
|
202
|
+
list.delete
|
203
|
+
else
|
204
|
+
fail "Pattern list file #{list} already exists, exiting..."
|
205
|
+
end
|
206
|
+
end
|
207
|
+
File.open(list, 'w') do |patlist|
|
208
|
+
@jobs.each do |job|
|
209
|
+
if options[:expand] == true
|
210
|
+
pinmap = job.pinmap_workbook
|
211
|
+
dot_pat_name = "#{job.output_directory}/#{job.pattern.basename.to_s.split('.').first}.PAT"
|
212
|
+
dot_atp_name = job.pattern
|
213
|
+
else
|
214
|
+
pinmap = job.pinmap_workbook.basename
|
215
|
+
dot_pat_name = "#{job.pattern.basename.to_s.split('.').first}.PAT"
|
216
|
+
dot_atp_name = job.pattern.basename
|
217
|
+
end
|
218
|
+
patlist.print("#{dot_atp_name} -pinmap_workbook:#{pinmap} -output:#{dot_pat_name}")
|
219
|
+
job.compiler_options.each_key { |k| patlist.print(" -#{k}") }
|
220
|
+
job.compiler_options_with_args.each_pair { |k, v| patlist.print(" -#{k}:#{v}") }
|
221
|
+
patlist.puts('')
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
# alias_method :find, :find_jobs
|
227
|
+
#
|
228
|
+
# Output the compiler jobs in the queue to the console
|
229
|
+
def inspect_jobs(index = nil)
|
230
|
+
return empty_msg if empty?
|
231
|
+
desc = []
|
232
|
+
puts "\n"
|
233
|
+
@jobs.each_with_index do |j, i|
|
234
|
+
unless index.nil?
|
235
|
+
next unless i == index
|
236
|
+
end
|
237
|
+
desc << '| Job: ' + "#{i + 1} ".rjust(8) + '|' + 'Pattern:'.rjust(18) + " #{j.pattern.basename}".ljust(120) + '|'
|
238
|
+
desc << '| |' + 'Compiler ID:'.rjust(18) + " #{j.id} ".ljust(120) + '|'
|
239
|
+
desc << '| |' + 'Pinmap:'.rjust(18) + " #{j.pinmap_workbook} ".ljust(120) + '|'
|
240
|
+
desc << '| |' + '.atp directory:'.rjust(18) + " #{j.pattern.dirname} ".ljust(120) + '|'
|
241
|
+
desc << '| |' + '.pat directory:'.rjust(18) + " #{j.output_directory} ".ljust(120) + '|'
|
242
|
+
desc << '| |' + 'LSF:'.rjust(18) + " #{j.location == :lsf ? true : false} ".ljust(120) + '|'
|
243
|
+
desc << '| |' + 'Delete log files:'.rjust(18) + " #{j.clean} ".ljust(120) + '|'
|
244
|
+
desc << '| |' + 'Verbose:'.rjust(18) + " #{j.verbose} ".ljust(120) + '|'
|
245
|
+
fragment = '| |' + 'Compiler args:'.rjust(18)
|
246
|
+
overflow_fragment = '| |' + ' '.rjust(18)
|
247
|
+
compiler_args = []
|
248
|
+
compiler_fragment = ''
|
249
|
+
j.compiler_options.each_key do |k|
|
250
|
+
if compiler_fragment.size + " -#{k}".size >= 120
|
251
|
+
compiler_args << compiler_fragment
|
252
|
+
compiler_fragment = nil
|
253
|
+
end
|
254
|
+
compiler_fragment += " -#{k}"
|
255
|
+
end
|
256
|
+
compiler_args << compiler_fragment unless compiler_fragment.nil?
|
257
|
+
compiler_fragment = ''
|
258
|
+
j.compiler_options_with_args.each_pair do |k, v|
|
259
|
+
if compiler_fragment.size + " -#{k}:#{v}".size >= 120
|
260
|
+
compiler_args << compiler_fragment
|
261
|
+
compiler_fragment = nil
|
262
|
+
end
|
263
|
+
compiler_fragment += " -#{k}:#{v}"
|
264
|
+
end
|
265
|
+
compiler_args << compiler_fragment unless compiler_fragment.nil?
|
266
|
+
if compiler_args.join.length <= 120
|
267
|
+
desc << fragment + "#{compiler_args.join}".ljust(120) + '|'
|
268
|
+
else
|
269
|
+
# Need to cycle through compiler args and build a fragment <= 100 characters
|
270
|
+
# and print it. Keep going until the remaining args is <= 100 and print again
|
271
|
+
char_cnt = 0
|
272
|
+
line_cnt = 0
|
273
|
+
args = []
|
274
|
+
compiler_args = compiler_args.join.strip.split(/\s+/)
|
275
|
+
until compiler_args.empty?
|
276
|
+
args = compiler_args.select { |e| (char_cnt += e.length + 1) < 120 }
|
277
|
+
# remove the args that fit on the first line
|
278
|
+
compiler_args -= args
|
279
|
+
if line_cnt == 0
|
280
|
+
desc << fragment + " #{args.join(' ')}".ljust(120) + '|'
|
281
|
+
else
|
282
|
+
desc << overflow_fragment + " #{args.join(' ')}".ljust(120) + '|'
|
283
|
+
end
|
284
|
+
args = []
|
285
|
+
line_cnt += 1
|
286
|
+
char_cnt = 0
|
287
|
+
end
|
288
|
+
end
|
289
|
+
desc << '-' * desc.first.size
|
290
|
+
end
|
291
|
+
puts desc.flatten.join("\n")
|
292
|
+
end
|
293
|
+
# For future checks on incorrect or incompatible arguments to compiler options
|
294
|
+
def options_ok?
|
295
|
+
end
|
296
|
+
|
297
|
+
def ready?
|
298
|
+
ready = true
|
299
|
+
paths_contain_data = true
|
300
|
+
ready &= paths_contain_data
|
301
|
+
ready &= !@job_options[:output_directory].nil?
|
302
|
+
ready &= !@user_options[:reference_directory].nil?
|
303
|
+
ready &= !@path.nil?
|
304
|
+
ready &= !@job_options[:pinmap_workbook].nil?
|
305
|
+
ready &= @job_options[:output_directory].directory?
|
306
|
+
ready &= @user_options[:reference_directory].directory?
|
307
|
+
ready &= @path.exist?
|
308
|
+
ready &= @job_options[:pinmap_workbook].file?
|
309
|
+
ready &= [true, false].include?(@job_options[:clean])
|
310
|
+
ready &= [:local, :lsf].include?(@job_options[:location])
|
311
|
+
ready &= File.exist?(@job_options[:compiler])
|
312
|
+
ready
|
313
|
+
end
|
314
|
+
|
315
|
+
def bad_options
|
316
|
+
bad = []
|
317
|
+
options = {
|
318
|
+
output_directory: @job_options[:output_directory],
|
319
|
+
reference_directory: @user_options[:reference_directory],
|
320
|
+
path: @path,
|
321
|
+
pinmap_workbook: @job_options[:pinmap_workbook],
|
322
|
+
clean: @job_options[:clean],
|
323
|
+
location: @job_options[:location],
|
324
|
+
compiler: @job_options[:compiler]
|
325
|
+
}
|
326
|
+
options.each do |k, v|
|
327
|
+
bad << k if v.nil?
|
328
|
+
if v.is_a? String # compiler
|
329
|
+
v = Pathname.new(v)
|
330
|
+
bad << k unless v.file?
|
331
|
+
elsif v.is_a? Symbol # clean
|
332
|
+
bad << k unless [:local, :lsf].include? v
|
333
|
+
elsif v.is_a? Pathname
|
334
|
+
if k.match(/directory/)
|
335
|
+
bad << k unless v.directory?
|
336
|
+
elsif k == :path
|
337
|
+
bad << k unless v.exist?
|
338
|
+
else # pinmap
|
339
|
+
bad << k unless v.file?
|
340
|
+
end
|
341
|
+
end
|
342
|
+
end
|
343
|
+
bad
|
344
|
+
end
|
345
|
+
alias_method :bad_opts, :bad_options
|
346
|
+
end
|
347
|
+
end
|
348
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module OrigenTesters
|
2
|
+
module PatternCompilers
|
3
|
+
class J750PatternCompiler < IGXLBasedPatternCompiler
|
4
|
+
# Linux compiler executable path
|
5
|
+
def self.linux_compiler
|
6
|
+
Origen.site_config.origen_testers[:j750_linux_pattern_compiler]
|
7
|
+
end
|
8
|
+
|
9
|
+
# Windows compiler executable path
|
10
|
+
def self.windows_compiler
|
11
|
+
Origen.site_config.origen_testers[:j750_windows_pattern_compiler]
|
12
|
+
end
|
13
|
+
|
14
|
+
# Pre-compile environment setup if necessary
|
15
|
+
def self.atpc_setup
|
16
|
+
Origen.site_config.origen_testers[:j750_atpc_setup]
|
17
|
+
end
|
18
|
+
|
19
|
+
# Resolves to correct compiler based on operating system
|
20
|
+
def self.compiler
|
21
|
+
Origen.running_on_windows? ? windows_compiler : linux_compiler
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.compiler_cmd
|
25
|
+
Pathname.new(compiler).absolute? ? compiler : eval('"' + compiler + '"')
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.compiler_options
|
29
|
+
"#{compiler_cmd} -help"
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.compiler_version
|
33
|
+
"#{compiler_cmd} -version"
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize(id, options = {})
|
37
|
+
super
|
38
|
+
|
39
|
+
@user_options = {}.merge(@user_options)
|
40
|
+
|
41
|
+
@job_options = {
|
42
|
+
tester: :j750,
|
43
|
+
compiler: self.class.compiler, # required
|
44
|
+
}.merge(@job_options)
|
45
|
+
|
46
|
+
# These are compiler options that are specific to J750 compiler (builds on options from IGXL-Based)
|
47
|
+
# Set all of these compiler options that don't have args to true/flase. if true then send compiler '-opt'
|
48
|
+
@compiler_options = {
|
49
|
+
compress: false, # Compress the compiled output file.
|
50
|
+
extended: false, # Compiles the pattern for extended mode.
|
51
|
+
scan_parallel: false, # Expands scan vectors into parallel SVM/LVM vectors.
|
52
|
+
svm_only: false, # Compile all vectors in the file for SVM.
|
53
|
+
svm_subr_only: false, # Only SVM subroutines in file being used.
|
54
|
+
}.merge(@compiler_options)
|
55
|
+
|
56
|
+
# These are compiler options that are specific to J750 compiler (builds on options from IGXL-Based)
|
57
|
+
@compiler_options_with_args = {
|
58
|
+
i: nil, # Includes paths to be passed to C++ preprocessor.
|
59
|
+
lvm_size: nil, # Number of LVM vectors to allow in a single pattern.
|
60
|
+
max_errors: nil, # Number of errors that will cause compilation of the pattern file to be aborted.
|
61
|
+
min_period: nil, # Minimum period, in seconds, that will be used during a pattern burst.
|
62
|
+
}.merge(@compiler_options_with_args)
|
63
|
+
|
64
|
+
update_common_options(options) # Update common options with default (see BasePatternCompiler)
|
65
|
+
verify_pinmap_is_specified # verify pinmap specified correctly - IGXL specific
|
66
|
+
clean_and_verify_options # Standard cleaning and verifying (see BasePatternCompiler)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Executes the compiler for each job in the queue
|
70
|
+
def run(list = nil, options = {})
|
71
|
+
fail "Error: the tester #{Origen.tester} is not an J750 tester,exiting..." unless is_j750?
|
72
|
+
msg = "Error: application #{Origen.app.name} is running on Windows, "
|
73
|
+
msg += 'to run the pattern compiler you must be on a Linux machine'
|
74
|
+
fail msg if Origen.running_on_windows?
|
75
|
+
|
76
|
+
super
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -19,9 +19,27 @@ module OrigenTesters
|
|
19
19
|
# Output directory for the .PAT file
|
20
20
|
attr_accessor :output_directory
|
21
21
|
|
22
|
-
# Pinmap file
|
22
|
+
# Pinmap file (IGXL-Based)
|
23
23
|
attr_accessor :pinmap_workbook
|
24
24
|
|
25
|
+
# Pinmap file (Smartest-Based)
|
26
|
+
attr_accessor :pinconfig
|
27
|
+
|
28
|
+
# Pinmap file (Smartest-Based)
|
29
|
+
attr_accessor :avc_dir
|
30
|
+
|
31
|
+
# Pinmap file (Smartest-Based)
|
32
|
+
attr_accessor :binl_dir
|
33
|
+
|
34
|
+
# Pattern count - should be 1 for IGXL; number of AVC files listed in AIV file for Smartest
|
35
|
+
attr_accessor :count
|
36
|
+
|
37
|
+
# tmf file (Smartest-Based)
|
38
|
+
attr_accessor :tmf
|
39
|
+
|
40
|
+
# aiv2b options (Smartest-Based)
|
41
|
+
attr_accessor :aiv2b_opts
|
42
|
+
|
25
43
|
# Compiler options where only the opt has to be passed as '-opt'
|
26
44
|
attr_accessor :compiler_options
|
27
45
|
|
@@ -33,6 +51,7 @@ module OrigenTesters
|
|
33
51
|
|
34
52
|
def initialize(pattern, options_with_args, options)
|
35
53
|
@pattern = pattern
|
54
|
+
@tester = options_with_args.delete(:tester)
|
36
55
|
@compiler = options_with_args.delete(:compiler)
|
37
56
|
@id = options_with_args.delete(:id)
|
38
57
|
@location = options_with_args.delete(:location)
|
@@ -40,6 +59,12 @@ module OrigenTesters
|
|
40
59
|
@verbose = options_with_args.delete(:verbose)
|
41
60
|
@output_directory = options_with_args.delete(:output_directory)
|
42
61
|
@pinmap_workbook = options_with_args.delete(:pinmap_workbook)
|
62
|
+
@pinconfig = options_with_args.delete(:pinconfig)
|
63
|
+
@avc_dir = options_with_args.delete(:avc_dir)
|
64
|
+
@binl_dir = options_with_args.delete(:binl_dir)
|
65
|
+
@count = options_with_args.delete(:count) || 1
|
66
|
+
@tmf = options_with_args.delete(:tmf)
|
67
|
+
@aiv2b_opts = options_with_args.delete(:aiv2b_opts)
|
43
68
|
@compiler_options_with_args = options_with_args.delete_if { |k, v| v.nil? } # Whatever's left has to be valid compiler options
|
44
69
|
@compiler_options = options.delete_if { |k, v| v == false }
|
45
70
|
end
|
@@ -50,10 +75,17 @@ module OrigenTesters
|
|
50
75
|
|
51
76
|
def cmd
|
52
77
|
cmd = ''
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
78
|
+
case @tester
|
79
|
+
when :v93k
|
80
|
+
cmd = "#{resolve_compiler_location} #{@pattern} "
|
81
|
+
when :ultraflex, :j750
|
82
|
+
cmd = "#{resolve_compiler_location} -pinmap_workbook:#{@pinmap_workbook} -output:#{@output_directory}/#{@pattern.basename.to_s.split('.').first}.PAT #{@pattern} "
|
83
|
+
# add in any remaining compiler options
|
84
|
+
compiler_options.each_key { |k| cmd += "-#{k} " }
|
85
|
+
compiler_options_with_args.each_pair { |k, v| cmd += "-#{k}:#{v} " }
|
86
|
+
else
|
87
|
+
fail 'Unsupported tester'
|
88
|
+
end
|
57
89
|
if @verbose
|
58
90
|
cmd += ';'
|
59
91
|
else
|
@@ -66,12 +98,20 @@ module OrigenTesters
|
|
66
98
|
cmd
|
67
99
|
end
|
68
100
|
|
101
|
+
def resolve_compiler_location
|
102
|
+
Pathname.new(@compiler).absolute? ? @compiler : eval('"' + @compiler + '"')
|
103
|
+
end
|
104
|
+
|
69
105
|
def ready?
|
70
106
|
ready = true
|
71
|
-
ready
|
72
|
-
|
73
|
-
|
74
|
-
|
107
|
+
ready &= @output_directory.directory?
|
108
|
+
ready &= @pattern.file?
|
109
|
+
ready &= @pinmap_workbook.file? if @tester == :ultraflex || @tester == :j750
|
110
|
+
ready &= @pinconfig.file? if @tester == :v93k
|
111
|
+
ready &= @tmf.file? if @tester == :v93k
|
112
|
+
ready &= [true, false].include?(@clean)
|
113
|
+
ready &= [:local, :lsf].include?(@location)
|
114
|
+
ready
|
75
115
|
end
|
76
116
|
|
77
117
|
private
|