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.
@@ -0,0 +1,107 @@
1
+ module OrigenTesters
2
+ module PatternCompilers
3
+ class V93KPatternCompiler
4
+ module DigCapAPI
5
+ class DigCap
6
+ attr_accessor :owner, :pins, :vps, :nrf, :char
7
+
8
+ def initialize(owner, options)
9
+ @owner = owner
10
+ @pins = nil
11
+
12
+ if options && options[:pins] && options[:vps]
13
+ @pins = options[:pins] # required: pins to be captured
14
+ @vps = options[:vps] # required: vecotrs per sample
15
+ @nrf = options[:nrf] || 1 # optional: nr_frames (defaults to 1)
16
+ @char = options[:char] || 'C' # optional: vector character representing capture
17
+ elsif options
18
+ fail 'Must specifiy pins and vps for digcap setup!'
19
+ end
20
+ end
21
+
22
+ def render_aiv_lines
23
+ lines = []
24
+ lines << ''
25
+ lines << 'AI_DIGCAP_SETTINGS {'
26
+ lines << render_digcap_header
27
+ avc_files.each do |f|
28
+ if vec_per_frame[f.to_sym] > 0
29
+ lines << render_digcap_entry(f)
30
+ end
31
+ end
32
+ lines << '};'
33
+ lines
34
+ end
35
+
36
+ def capture_string
37
+ " #{char * num_pins} "
38
+ end
39
+
40
+ def num_pins
41
+ if pins.is_a? String
42
+ pins.split(' ').size
43
+ elsif pins.is_a? Symbol
44
+ dut.pins(pins).size
45
+ elsif pins.is_a? Array
46
+ fail 'Digcap Pins does not support array yet'
47
+ end
48
+ end
49
+
50
+ def enabled?
51
+ pins.nil? ? false : true
52
+ end
53
+
54
+ def empty?
55
+ vec_per_frame.each do |k, v|
56
+ return false if v > 0
57
+ end
58
+ true # digcap setup but no avc contain capture vectors
59
+ end
60
+
61
+ private
62
+
63
+ def render_digcap_header
64
+ line = 'variable'.ljust(max_filename_size + 4)
65
+ line += ' '
66
+ line += 'label'.ljust(max_filename_size)
67
+ line += ' '
68
+ line += 'vec_per_frame vec_per_sample nr_frames {pins};'
69
+ line
70
+ end
71
+
72
+ def render_digcap_entry(pattern)
73
+ line = "#{pattern}_var".ljust(max_filename_size + 4)
74
+ line += ' '
75
+ line += "#{pattern}".ljust(max_filename_size)
76
+ line += ' '
77
+ line += "#{vec_per_frame[pattern.to_sym]}".ljust(15)
78
+ line += "#{vps}".ljust(16)
79
+ line += "#{nrf}".ljust(11)
80
+ line += "{#{pins}};"
81
+ line
82
+ end
83
+
84
+ def avc_files
85
+ owner.avc_files
86
+ end
87
+
88
+ def max_filename_size
89
+ owner.max_avcfilename_size
90
+ end
91
+
92
+ def vec_per_frame
93
+ owner.vec_per_frame
94
+ end
95
+ end
96
+
97
+ def digcap
98
+ @digcap ||= DigCap.new(self, @user_options[:digcap])
99
+ end
100
+
101
+ def digcap?
102
+ digcap.enabled?
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,80 @@
1
+ module OrigenTesters
2
+ module PatternCompilers
3
+ class V93KPatternCompiler
4
+ module MultiportAPI
5
+ class Multiport
6
+ attr_accessor :port_in_focus, :port_bursts, :prefix, :postfix
7
+
8
+ def initialize(options)
9
+ @port_in_focus = nil
10
+
11
+ if options && options[:port_in_focus]
12
+ @port_in_focus = options[:port_in_focus]
13
+ @port_bursts = options[:port_bursts]
14
+ @prefix = options[:prefix].nil? ? '' : "#{options[:prefix]}_"
15
+ @postfix = options[:postfix].nil? ? '' : "_#{options[:postfix]}"
16
+ end
17
+ end
18
+
19
+ def render_aiv_lines(pattern)
20
+ mpb_entry = []
21
+ mpb_entry << ''
22
+ mpb_entry << render_mpb_header(pattern)
23
+ mpb_entry << render_mpb_port_line(pattern)
24
+ mpb_entry << render_mpb_burst_line(pattern)
25
+ mpb_entry
26
+ end
27
+
28
+ def enabled?
29
+ port_in_focus.nil? ? false : true
30
+ end
31
+
32
+ private
33
+
34
+ def render_mpb_header(pattern)
35
+ "MULTI_PORT_BURST #{prefix}#{pattern}#{postfix}"
36
+ end
37
+
38
+ def render_mpb_port_line(pattern)
39
+ line = 'PORTS '
40
+ line += port_in_focus.to_s
41
+ line += mpb_padding(port_in_focus.to_s, pattern, 0)
42
+ if port_bursts
43
+ port_bursts.each do |k, v|
44
+ line += k.to_s
45
+ line += mpb_padding(k.to_s, v.to_s, 0)
46
+ end
47
+ end
48
+ line
49
+ end
50
+
51
+ def render_mpb_burst_line(pattern)
52
+ line = ' '
53
+ line += pattern.to_s
54
+ line += mpb_padding(port_in_focus.to_s, pattern, 1)
55
+ if port_bursts
56
+ port_bursts.each do |k, v|
57
+ line += v.to_s
58
+ line += mpb_padding(k.to_s, v.to_s, 1)
59
+ end
60
+ end
61
+ line
62
+ end
63
+
64
+ def mpb_padding(str0, str1, index = 0)
65
+ width = str0.size > str1.size ? str0.size : str1.size
66
+ index == 0 ? ' ' * (width + 2 - str0.size) : ' ' * (width + 2 - str1.size)
67
+ end
68
+ end
69
+
70
+ def multiport
71
+ @multiport ||= Multiport.new(@user_options[:multiport])
72
+ end
73
+
74
+ def multiport?
75
+ multiport.enabled?
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
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.14.0
4
+ version: 0.15.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: 2017-11-20 00:00:00.000000000 Z
11
+ date: 2017-11-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: origen
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.7.40
19
+ version: 0.26.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.7.40
26
+ version: 0.26.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: require_all
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -233,8 +233,16 @@ files:
233
233
  - lib/origen_testers/parser/searchable_hash.rb
234
234
  - lib/origen_testers/pattern_compilers.rb
235
235
  - lib/origen_testers/pattern_compilers/assembler.rb
236
+ - lib/origen_testers/pattern_compilers/base.rb
237
+ - lib/origen_testers/pattern_compilers/igxl_based.rb
238
+ - lib/origen_testers/pattern_compilers/j750.rb
236
239
  - lib/origen_testers/pattern_compilers/job.rb
237
- - lib/origen_testers/pattern_compilers/ultraflex_pattern_compiler.rb
240
+ - lib/origen_testers/pattern_compilers/runner.rb
241
+ - lib/origen_testers/pattern_compilers/templates/template.aiv.erb
242
+ - lib/origen_testers/pattern_compilers/ultraflex.rb
243
+ - lib/origen_testers/pattern_compilers/v93k.rb
244
+ - lib/origen_testers/pattern_compilers/v93k/digcap.rb
245
+ - lib/origen_testers/pattern_compilers/v93k/multiport.rb
238
246
  - lib/origen_testers/program_generators.rb
239
247
  - lib/origen_testers/smartest_based_tester.rb
240
248
  - lib/origen_testers/smartest_based_tester/base.rb
@@ -348,7 +356,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
348
356
  version: 1.8.11
349
357
  requirements: []
350
358
  rubyforge_project:
351
- rubygems_version: 2.5.2
359
+ rubygems_version: 2.6.7
352
360
  signing_key:
353
361
  specification_version: 4
354
362
  summary: This plugin provides Origen tester models to drive ATE type testers like
@@ -1,599 +0,0 @@
1
- module OrigenTesters
2
- module PatternCompilers
3
- class UltraFlexPatternCompiler
4
- require 'pathname'
5
- require_relative 'assembler'
6
- require_relative 'job'
7
-
8
- # Linux compiler executable path
9
- LINUX_PATTERN_COMPILER = "#{Origen.root!}/bin/latest/bin/atpcompiler"
10
- # LINUX_PATTERN_COMPILER = "#{Origen.root!}/bin/latest/bin/atpcompiler"
11
-
12
- # Windows compiler executable path
13
- WINDOWS_PATTERN_COMPILER = "#{ENV['IGXLROOT']}/bin/apc.exe"
14
-
15
- # Linux compiler preamble
16
- ATPC_SETUP = "#{Origen.root!}/bin/latest/etc/atpcrc.csh"
17
-
18
- # ID will allow users to set default configurations for the compiler for unique pattern types
19
- attr_accessor :id
20
-
21
- # Compiler commands array
22
- attr_accessor :jobs
23
-
24
- def initialize(id, options = {})
25
- @id = id
26
- @id = @id.to_sym
27
-
28
- @user_options = {
29
- path: nil, # required: will be passed in or parsed from a .list file
30
- reference_directory: nil, # optional: will be set to @path or Origen.app.config.pattern_output_directory
31
- target: nil, # optional: allows user to temporarily set target and run compilation
32
- recursive: false # optional: controls whether to look for patterns in a directory recursively
33
- }
34
- @job_options = {
35
- compiler: running_on_windows? ? WINDOWS_PATTERN_COMPILER : LINUX_PATTERN_COMPILER, # required
36
- id: @id, # required
37
- pinmap_workbook: $dut.pinmap, # required: will default to $dut.pinmap
38
- location: :local, # optional: controls whether the commands go to the LSF or run locally
39
- clean: false, # optional: controls whether compiler log files are deleted after compilation
40
- output_directory: nil, # optional:
41
- verbose: false # optional: controls whether the compiler output gets put to STDOUT
42
- }
43
- @compiler_options = { # Set all of these compiler options that don't have args to true/flase. if true then send compiler '-opt'
44
- import_all_undefineds: false, # automatically import all undefined symbols. the key is mis-spelled but correct!
45
- cpp: false, # runs C++ preprocessor on pattern file
46
- comments: false, # saves comments in binary file for tools visibility. pass '-comments' if set to true
47
- # pass nothing if set to false
48
- nocompress: false, # do not compress pattern data blocks
49
- suppress_log: false, # disables output to main log file
50
- multiinst: false, # indicates more than one instrument is connected to a single pin
51
- lock: false, # prevents pattern from being reverse compiled or opened in PatternTool
52
- stdin: false, # Compile data from standard input. Do not use -cpp or specify any pattern file(s) when using this option.
53
- debug: false, # generate intermediate file(s) to simplify debug ( application dependent )
54
- template: false, # generate setup template
55
- timestamp: false, # enable log timestamp
56
- }
57
- @compiler_options_with_args = {
58
- output: nil, # Output filename, compiler defaults to <pattern name>.PAT
59
- pinmap_sheet: nil, # <sheetname>
60
- digital_inst: nil, # 'HSD4G', 'HSDM', or 'HSDMQ'
61
- opcode_mode: nil, # HSDM mode: 'single' | 'dual'. HSDMQ mode: 'single' | 'dual' | 'quad'
62
- pat_version: nil, # version of pattern file to compile
63
- scan_type: nil, # type of scan data
64
- max_errors: nil, # <n>, defaults to 200 on compiler side, valu eof 0 will never abort compilation
65
- logfile: nil, # <filename>, directs any compiler messages to <filename>. will default to output directory if nil
66
- define: nil, # defines values of macros passed to C++ preprocessor.
67
- # can only be defined once per pattern with space delimited list
68
- includes: nil, # include paths to be passed to C- preprocessor.
69
- post_processor: nil, # <pathname> customer's post-process executable.
70
- # need to pass 'post-processor' to compiler
71
- post_processor_args: nil, # <args> customer's post-process executable arguments
72
- # need to pass 'post-processor_args' to compiler
73
- cdl_cache: nil, # 'yes' | 'no', turns on/off CDL caching, default on compiler side is 'yes'
74
- init_pattern: nil, # <pattern>, uses the specified pattern module/file/set as an init patterns
75
- check_set_msb: nil, # 'yes' | 'no', turns on/off check the 'set' or 'set_infinite' opcode
76
- # is preceded by a 'set_msb' or 'set_msb_infinite' opcode. compiler default is 'yes'
77
- time_domain: nil, # <time domain>, specifies time domain for pins in patterns
78
- allow_mto_dash: nil, # Turn on/off support for channel data runtime repeat,i.e. vector dash in MTO patterns. Default value is "no".
79
- check_vm_min_size: nil, # Turns on/off the check on minimum size of a VM pattern. Default value is "yes".
80
- check_vm_mod_size: nil, # Turns on/off the check on a VM pattern module size. Default value is "yes".
81
- check_oob_size: nil, # Turns on/off the check on size of OOB regions. Yes means size must be modulo 10. Default value is "no".
82
- allow_mixed_1x2x: nil, # Turns on/off the support of mixed 1x/2x pin groups. Default value is "no".
83
- allow_differential: nil, # Turns on/off support for differential pins. Default value is "yes".
84
- allow_scan_in_srm: nil, # Allow/disallow scan vectors in SRM pattern modules. Default value is "no".
85
- vm_block_size: nil, # Specifies uncompressed size in bytes of a pattern data block
86
- setup: nil, # path to setup file
87
- }
88
-
89
- @user_options.update_common(options)
90
- @job_options.update_common(options)
91
- @compiler_options.update_common(options)
92
- @compiler_options_with_args.update_common(options)
93
-
94
- # Check to make sure @compiler_options and @compiler_options_with_args do not have any keys in common
95
- fail "Error: @compiler_options and @compiler_options_with_args share keys #{@compiler_options.intersections(@compiler_options_with_args)}. They should be mutually exclusive, exiting..." if @compiler_options.intersect? @compiler_options_with_args
96
-
97
- # Convert any path related options to Pathname object and expand the path
98
- unless @user_options[:path].nil?
99
- if @user_options[:path].is_a? Pathname
100
- @path = @user_options[:path]
101
- else
102
- @path = Pathname.new(@user_options[:path])
103
- end
104
- @path = @path.expand_path
105
- # path is set but output_directory is not so set output_directory to path
106
- @job_options[:output_directory] = @path if @job_options[:output_directory].nil?
107
- end
108
-
109
- set_reference_directory
110
-
111
- if @job_options[:output_directory].nil?
112
- fail 'Output directory is not set!'
113
- else
114
- @job_options[:output_directory] = convert_to_pathname(@job_options[:output_directory])
115
- # output_directory can not exist, will create for user
116
- unless @job_options[:output_directory].directory?
117
- puts "Output directory #{@job_options[:output_directory]} does not exist, creating it..."
118
- FileUtils.mkdir_p(@job_options[:output_directory])
119
- end
120
- end
121
-
122
- # Pinmap is required
123
- if @job_options[:pinmap_workbook].nil?
124
- # Check if the app has $dut.pinmap defined
125
- if File.exist? $dut.pinmap
126
- @job_options[:pinmap_workbook] = $dut.pinmap
127
- else
128
- fail 'Pinmap is not defined! Pass as an option or set $dut.pinmap.'
129
- end
130
- end
131
- @job_options[:pinmap_workbook] = convert_to_pathname(@job_options[:pinmap_workbook])
132
- fail 'Pinmap is not a file' unless @job_options[:pinmap_workbook].file?
133
-
134
- # Logfile is optional
135
- unless @compiler_options[:logfile].nil?
136
- @compiler_options[:logfile] = convert_to_pathname(@compiler_options[:logfile])
137
- fail 'Pinmap is not a file' unless @job_options[:pinmap_workbook].file?
138
- end
139
-
140
- # Check if the LSF is setup in the application
141
- if Origen.app.config.lsf.project.nil? || Origen.app.config.lsf.project.empty?
142
- puts 'LSF is not set at Origen.app.config.lsf.project, changing to local compilation'
143
- @job_options[:location] = :local
144
- end
145
-
146
- # Compiler jobs
147
- @jobs = []
148
-
149
- # .atp/.atp.gz files found
150
- @files = []
151
- end
152
-
153
- # Return the id/name of the compiler instance
154
- def name
155
- @id
156
- end
157
-
158
- # Return the compiler instance pinmap
159
- def pinmap
160
- @job_options[:pinmap_workbook]
161
- end
162
-
163
- # Allow users to search for a pattern in the job queue or default
164
- # to return all jobs
165
- def jobs(search = nil)
166
- found = false
167
- if search.nil?
168
- inspect_jobs
169
- found = true
170
- elsif search.is_a? String
171
- @jobs.each_with_index do |job, index|
172
- if job.pattern.to_s.match(search)
173
- inspect_jobs(index)
174
- found = true
175
- else
176
- puts "No match found for #{search}"
177
- end
178
- end
179
- elsif search.is_a? Regexp
180
- @jobs.each_with_index do |job, index|
181
- if search.match(job.pattern.to_s)
182
- inspect_jobs(index)
183
- found = true
184
- else
185
- puts "No match found for #{search}"
186
- end
187
- end
188
- elsif search.is_a? Integer
189
- if @jobs[search].nil?
190
- puts "The compiler queue does not contain a job at index #{search}"
191
- else
192
- inspect_jobs(search)
193
- found = true
194
- end
195
- else
196
- fail 'Search argument must be of type String, Regexp, or Integer'
197
- end
198
- found
199
- end
200
-
201
- # Finds the patterns and creates a compiler job for each one found.
202
- # Handles singles files (.atp, .atp.gz, or .list) and directories (recursively or flat)
203
- def find_jobs(path = @path)
204
- fail 'Pattern path is set to nil, pass in a valid file (.atp or .atp.gz) or a valid directory' if path.nil?
205
- @path = Pathname.new(path)
206
- fail 'Pattern path does not exist, pass in a valid file (.atp or .atp.gz) or a valid directory' unless @path.exist?
207
- @path = @path.expand_path
208
- # Set the reference directory for pattern sub-dir mirroring
209
- set_reference_directory
210
- Origen.profile 'Linux pattern compiler finds patterns' do
211
- # Check if the path is a file or a directory
212
- if @path.directory?
213
- # Get all of the patterns inside this dir or inside this directory recursively
214
- # Check if the recursive arg was passed
215
- if @user_options[:recursive] == true
216
- process_directory(@path, @files, true)
217
- else # Just grab the files found inside this directory
218
- process_directory(@path, @files, false)
219
- end
220
- elsif @path.file? # Found a file so no searching is necessary
221
- process_file(@path, @files)
222
- else # Didn't find a directory or a file so user must want a search for this arg string * NOT SUPPORTED YET
223
- fail 'Error: Did not find a file or directory to compile, exiting...'
224
- end
225
- end
226
-
227
- Origen.profile 'Linux pattern compiler creates jobs' do
228
- @files.each do |f|
229
- rel_dir = Pathname.new("#{f.dirname.to_s[@user_options[:reference_directory].to_s.size..-1]}")
230
- output_dir = Pathname.new("#{@job_options[:output_directory]}#{rel_dir}")
231
- unless output_dir.directory?
232
- puts "Output directory #{output_dir} for pattern #{f.basename} does not exist, creating it..."
233
- FileUtils.mkdir_p(output_dir)
234
- end
235
- current_job_options = @job_options.merge(@compiler_options_with_args)
236
- current_job_options[:output_directory] = output_dir
237
- @jobs << Job.new(f, current_job_options, @compiler_options)
238
- current_job_options = {}
239
- end
240
- end
241
- @files = []
242
- if empty?
243
- empty_msg
244
- else
245
- inspect_jobs
246
- end
247
- end
248
- alias_method :find, :find_jobs
249
-
250
- # Executes the compiler for each job in the queue
251
- def run(list = nil, options = {})
252
- fail "Error: the tester #{Origen.tester} is not an Ultrflex tester,exiting..." unless is_ultraflex?
253
- fail "Error: application #{Origen.app.name} is running on Windows, to run the pattern compiler you must be on a Linux machine" if running_on_windows?
254
-
255
- # Check if there was a pattern list passed as an argument
256
- # If so, then compile the patterns inside it.
257
- # Otherwise compile the jobs in the queue
258
- if list.nil?
259
- if empty?
260
- empty_msg
261
- return
262
- end
263
- @jobs.each do |job|
264
- fail "Error: compiler #{job.id} not ready for pattern #{job.name}" unless job.ready?
265
- if job.location == :lsf
266
- Origen.app.lsf.submit(ATPC_SETUP + '; ' + job.cmd)
267
- else
268
- Origen.profile "Linux pattern compiler compiles pattern #{job.pattern}" do
269
- system job.cmd
270
- end
271
- end
272
- end
273
- if @job_options[:location] == :local
274
- if @job_options[:clean] == true
275
- puts 'Log file :clean option set to true, deleting log files'
276
- clean_output
277
- end
278
- end
279
- # Clear @jobs
280
- clear
281
- else
282
- list = convert_to_pathname(list)
283
- fail "Error: pattern list #{list} does not exist, exiting..." unless list.file?
284
- File.open(list, 'r') do |file|
285
- while (line = file.gets)
286
- current_job_options = @job_options.merge(@compiler_options_with_args)
287
- current_job_options.update_common(options)
288
- # puts "current job options is #{current_job_options}"
289
- compiler_opts = {}
290
- line.strip!
291
- pattern = line.match(/^(\S+)\s+(.*)/).captures[0]
292
- unless File.file? pattern
293
- puts "Warning: Pattern #{pattern} does not exist, skipping..."
294
- next
295
- end
296
- pattern = convert_to_pathname(pattern)
297
- line.match(/^\S+\s+(.*)/).captures[0].split(/\s+/).each do |e|
298
- opt, arg = e.split(':')
299
- opt.gsub!('-', '')
300
- if arg.nil?
301
- compiler_opts[opt.to_sym] = true
302
- else
303
- # Check for some specific options
304
- case opt
305
- when 'pinmap_workbook'
306
- current_job_options[opt.to_sym] = Pathname.new(arg)
307
- when 'output'
308
- dot_pat = Pathname.new(arg)
309
- current_job_options[:output_directory] = dot_pat.dirname
310
- else
311
- current_job_options[opt.to_sym] = arg
312
- end
313
- end
314
- end
315
- @jobs << Job.new(pattern, current_job_options, compiler_opts)
316
- inspect_jobs
317
- end
318
- end
319
- run
320
- # Clear @jobs
321
- clear
322
- end
323
- end
324
-
325
- # Clear the job queue
326
- def clear
327
- @jobs = []
328
- @files = []
329
- end
330
-
331
- # Output all of the jobs into a pattern list so it can be compiled later
332
- # Must be executed after the 'find_jobs' method and before the 'run' method
333
- # or @jobs will be empty
334
- def to_list(options = {})
335
- options = {
336
- name: @id,
337
- output_directory: Dir.pwd,
338
- expand: true,
339
- force: false
340
- }.update_common(options)
341
- list = "#{options[:output_directory]}/#{options[:name]}.list"
342
- list = convert_to_pathname(list)
343
- if empty?
344
- empty_msg
345
- return
346
- end
347
- if list.file?
348
- if options[:force] == true
349
- puts "Pattern list file #{list} already exists, deleting it..."
350
- list.delete
351
- else
352
- fail "Pattern list file #{list} already exists, exiting..."
353
- end
354
- end
355
- File.open(list, 'w') do |patlist|
356
- @jobs.each do |job|
357
- if options[:expand] == true
358
- pinmap = job.pinmap_workbook
359
- dot_pat_name = "#{job.output_directory}/#{job.pattern.basename.to_s.split('.').first}.PAT"
360
- dot_atp_name = job.pattern
361
- else
362
- pinmap = job.pinmap_workbook.basename
363
- dot_pat_name = "#{job.pattern.basename.to_s.split('.').first}.PAT"
364
- dot_atp_name = job.pattern.basename
365
- end
366
- patlist.print("#{dot_atp_name} -pinmap_workbook:#{pinmap} -output:#{dot_pat_name}")
367
- job.compiler_options.each_key { |k| patlist.print(" -#{k}") }
368
- job.compiler_options_with_args.each_pair { |k, v| patlist.print(" -#{k}:#{v}") }
369
- patlist.puts('')
370
- end
371
- end
372
- end
373
-
374
- # For future checks on incorrect or incompatible arguments to compiler options
375
- def options_ok?
376
- end
377
-
378
- def ready?
379
- ready = true
380
- paths_contain_data = true
381
- # check for nil
382
- ready = paths_contain_data && !@job_options[:output_directory].nil? &&
383
- !@user_options[:reference_directory].nil? &&
384
- !@path.nil? &&
385
- !@job_options[:pinmap_workbook].nil?
386
- ready && @job_options[:output_directory].directory? &&
387
- @user_options[:reference_directory].directory? &&
388
- @path.exist? &&
389
- @job_options[:pinmap_workbook].file? &&
390
- [true, false].include?(@job_options[:clean]) &&
391
- [:local, :lsf].include?(@job_options[:location]) &&
392
- File.exist?(@job_options[:compiler])
393
- end
394
-
395
- def bad_options
396
- bad = []
397
- options = {
398
- output_directory: @job_options[:output_directory],
399
- reference_directory: @user_options[:reference_directory],
400
- path: @path,
401
- pinmap_workbook: @job_options[:pinmap_workbook],
402
- clean: @job_options[:clean],
403
- location: @job_options[:location],
404
- compiler: @job_options[:compiler]
405
- }
406
- options.each do |k, v|
407
- bad << k if v.nil?
408
- if v.is_a? String # compiler
409
- v = Pathname.new(v)
410
- bad << k unless v.file?
411
- elsif v.is_a? Symbol # clean
412
- bad << k unless [:local, :lsf].include? v
413
- elsif v.is_a? Pathname
414
- if k.match(/directory/)
415
- bad << k unless v.directory?
416
- elsif k == :path
417
- bad << k unless v.exist?
418
- else # pinmap
419
- bad << k unless v.file?
420
- end
421
- end
422
- end
423
- bad
424
- end
425
- alias_method :bad_opts, :bad_options
426
-
427
- # Output the compiler options to the console
428
- def inspect_options(verbose = nil)
429
- desc = []
430
- # Find the longest option argument string
431
- my_job_options = @job_options
432
- my_job_options.delete(:compiler)
433
- all_arguments = @user_options.values + my_job_options.values + @compiler_options.values + @compiler_options_with_args.values
434
- min_argument_padding = 'Argument'.length + 2
435
- argument_padding = all_arguments.max_by { |e| e.to_s.length }.to_s.length + 3
436
- argument_padding = min_argument_padding if argument_padding < min_argument_padding
437
- puts "\n"
438
- header = '| Option ' + '| Argument'.ljust(argument_padding) + '| Required |'
439
- desc << header
440
- desc << '-' * header.length
441
- [@user_options, my_job_options, @compiler_options, @compiler_options_with_args].each do |opt|
442
- opt.each_pair do |k, v|
443
- if k.match(/pinmap_workbook|path|id|directory|clean|location|recursive/i)
444
- req = 'true '
445
- else
446
- next if v.nil? || v == false
447
- req = 'false'
448
- end
449
- desc << "| #{k}".ljust(22) + "| #{v}".ljust(argument_padding) + "| #{req} |"
450
- end
451
- end
452
- puts desc
453
- end
454
-
455
- # Output the compiler jobs in the queue to the console
456
- def inspect_jobs(index = nil)
457
- return empty_msg if empty?
458
- desc = []
459
- puts "\n"
460
- @jobs.each_with_index do |j, i|
461
- unless index.nil?
462
- next unless i == index
463
- end
464
- desc << '| Job: ' + "#{i + 1} ".rjust(8) + '|' + 'Pattern:'.rjust(18) + " #{j.pattern.basename}".ljust(100) + '|'
465
- desc << '| |' + 'Compiler ID:'.rjust(18) + " #{j.id}".ljust(100) + '|'
466
- desc << '| |' + 'Pinmap:'.rjust(18) + " #{j.pinmap_workbook}".ljust(100) + '|'
467
- desc << '| |' + '.atp directory:'.rjust(18) + " #{j.pattern.dirname}".ljust(100) + '|'
468
- desc << '| |' + '.pat directory:'.rjust(18) + " #{j.output_directory}".ljust(100) + '|'
469
- desc << '| |' + 'LSF:'.rjust(18) + " #{j.location == :lsf ? true : false}".ljust(100) + '|'
470
- desc << '| |' + 'Delete log files:'.rjust(18) + " #{j.clean}".ljust(100) + '|'
471
- desc << '| |' + 'Verbose:'.rjust(18) + " #{j.verbose}".ljust(100) + '|'
472
- fragment = '| |' + 'Compiler args:'.rjust(18)
473
- overflow_fragment = '| |' + ' '.rjust(18)
474
- compiler_args = []
475
- compiler_fragment = ''
476
- j.compiler_options.each_key do |k|
477
- if compiler_fragment.size + " -#{k}".size >= 100
478
- compiler_args << compiler_fragment
479
- compiler_fragment = nil
480
- end
481
- compiler_fragment += " -#{k}"
482
- end
483
- compiler_args << compiler_fragment unless compiler_fragment.nil?
484
- compiler_fragment = ''
485
- j.compiler_options_with_args.each_pair do |k, v|
486
- if compiler_fragment.size + " -#{k}:#{v}".size >= 100
487
- compiler_args << compiler_fragment
488
- compiler_fragment = nil
489
- end
490
- compiler_fragment += " -#{k}:#{v}"
491
- end
492
- compiler_args << compiler_fragment unless compiler_fragment.nil?
493
- if compiler_args.join.length <= 100
494
- desc << fragment + "#{compiler_args.join}".ljust(100) + '|'
495
- else
496
- # Need to cycle through compiler args and build a fragment <= 100 characters
497
- # and print it. Keep going until the remaining args is <= 100 and print again
498
- char_cnt = 0
499
- line_cnt = 0
500
- args = []
501
- compiler_args = compiler_args.join.strip.split(/\s+/)
502
- until compiler_args.empty?
503
- args = compiler_args.select { |e| (char_cnt += e.length + 1) < 100 }
504
- # remove the args that fit on the first line
505
- compiler_args -= args
506
- if line_cnt == 0
507
- desc << fragment + " #{args.join(' ')}".ljust(100) + '|'
508
- else
509
- desc << overflow_fragment + " #{args.join(' ')}".ljust(100) + '|'
510
- end
511
- args = []
512
- line_cnt += 1
513
- char_cnt = 0
514
- end
515
- end
516
- desc << '-' * desc.first.size
517
- end
518
- puts desc.flatten.join("\n")
519
- end
520
-
521
- # Returns the number of jobs in the compiler
522
- def count
523
- @jobs.size
524
- end
525
-
526
- # Checks if the compiler queue is empty
527
- def empty?
528
- @jobs.empty?
529
- end
530
-
531
- private
532
-
533
- def running_on_windows?
534
- RUBY_PLATFORM == 'i386-mingw32'
535
- end
536
-
537
- def empty_msg
538
- puts "No compiler jobs created, check the compiler options\n" if self.empty?
539
- end
540
-
541
- def convert_to_pathname(opt)
542
- if opt.is_a? String
543
- opt = Pathname.new(opt)
544
- opt = opt.expand_path
545
- elsif opt.is_a? Pathname
546
- opt = opt.expand_path
547
- else
548
- fail "Option #{opt} is not a String, cannot convert to Pathname"
549
- end
550
- opt
551
- end
552
-
553
- def set_reference_directory
554
- if @user_options[:reference_directory].nil?
555
- # Nothing passed for reference directory so set it to Origen.app.config.pattern_output_directory if valid
556
- if File.directory? Origen.app.config.pattern_output_directory
557
- @user_options[:reference_directory] = Pathname.new(Origen.app.config.pattern_output_directory)
558
- elsif @path
559
- if @path.directory?
560
- @user_options[:reference_directory] = @path
561
- else
562
- @user_options[:reference_directory] = @path.dirname
563
- end
564
- end
565
- elsif File.directory?(@user_options[:reference_directory])
566
- @user_options[:reference_directory] = Pathname.new(@user_options[:reference_directory])
567
- else
568
- debug 'Reference directory not set, creating it...'
569
- @user_options[:reference_directory] = Pathname.new(@user_options[:reference_directory])
570
- FileUtils.mkdir_p(@user_options[:reference_directory])
571
- end
572
- @user_options[:reference_directory] = @user_options[:reference_directory].expand_path
573
- # reference_directory must be a subset of @path. if it is not then set to @path if @path exists
574
- unless @path.nil?
575
- if @path.directory?
576
- @user_options[:reference_directory] = @path unless @path.to_s.include? @user_options[:reference_directory].to_s
577
- elsif @path.file?
578
- @user_options[:reference_directory] = @path.dirname
579
- else
580
- debug "Path is set to #{@path} which is not a valid directory or file!"
581
- end
582
- end
583
- end
584
-
585
- # Check if the current tester is an Ultraflex
586
- def is_ultraflex?
587
- platform == :ultraflex ? true : false
588
- end
589
-
590
- def platform
591
- if $tester.nil?
592
- fail 'No tester instantiated, $tester is set to nil'
593
- else
594
- $tester.class.to_s.downcase.split('::').last.to_sym
595
- end
596
- end
597
- end
598
- end
599
- end