origen_testers 0.14.0 → 0.15.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.
- 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
|