origen_testers 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/config/application.rb +140 -0
- data/config/commands.rb +73 -0
- data/config/development.rb +12 -0
- data/config/environment.rb +1 -0
- data/config/shared_commands.rb +47 -0
- data/config/users.rb +18 -0
- data/config/version.rb +8 -0
- data/lib/commands/build.rb +69 -0
- data/lib/origen_testers.rb +23 -0
- data/lib/origen_testers/api.rb +258 -0
- data/lib/origen_testers/basic_test_setups.rb +105 -0
- data/lib/origen_testers/callback_handlers.rb +58 -0
- data/lib/origen_testers/generator.rb +279 -0
- data/lib/origen_testers/generator/flow_control_api.rb +611 -0
- data/lib/origen_testers/generator/identity_map.rb +23 -0
- data/lib/origen_testers/generator/placeholder.rb +11 -0
- data/lib/origen_testers/generator/test_numberer.rb +23 -0
- data/lib/origen_testers/igxl_based_tester.rb +12 -0
- data/lib/origen_testers/igxl_based_tester/base.rb +641 -0
- data/lib/origen_testers/igxl_based_tester/base/flow.rb +171 -0
- data/lib/origen_testers/igxl_based_tester/base/flow_line.rb +322 -0
- data/lib/origen_testers/igxl_based_tester/base/generator.rb +217 -0
- data/lib/origen_testers/igxl_based_tester/base/patgroup.rb +109 -0
- data/lib/origen_testers/igxl_based_tester/base/patgroups.rb +38 -0
- data/lib/origen_testers/igxl_based_tester/base/patset.rb +68 -0
- data/lib/origen_testers/igxl_based_tester/base/patset_pattern.rb +56 -0
- data/lib/origen_testers/igxl_based_tester/base/patsets.rb +38 -0
- data/lib/origen_testers/igxl_based_tester/base/patsubr.rb +68 -0
- data/lib/origen_testers/igxl_based_tester/base/patsubr_pattern.rb +56 -0
- data/lib/origen_testers/igxl_based_tester/base/patsubrs.rb +38 -0
- data/lib/origen_testers/igxl_based_tester/base/test_instance.rb +326 -0
- data/lib/origen_testers/igxl_based_tester/base/test_instance_group.rb +58 -0
- data/lib/origen_testers/igxl_based_tester/base/test_instances.rb +179 -0
- data/lib/origen_testers/igxl_based_tester/files.rb +43 -0
- data/lib/origen_testers/igxl_based_tester/j750.rb +248 -0
- data/lib/origen_testers/igxl_based_tester/j750/flow.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/j750/flow_line.rb +19 -0
- data/lib/origen_testers/igxl_based_tester/j750/generator.rb +19 -0
- data/lib/origen_testers/igxl_based_tester/j750/patgroup.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750/patgroups.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/j750/patset.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750/patset_pattern.rb +18 -0
- data/lib/origen_testers/igxl_based_tester/j750/patsets.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/j750/patsubr.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750/patsubr_pattern.rb +18 -0
- data/lib/origen_testers/igxl_based_tester/j750/patsubrs.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/j750/templates/flow.txt.erb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750/templates/instances.txt.erb +16 -0
- data/lib/origen_testers/igxl_based_tester/j750/templates/patgroups.txt.erb +8 -0
- data/lib/origen_testers/igxl_based_tester/j750/templates/patsets.txt.erb +10 -0
- data/lib/origen_testers/igxl_based_tester/j750/templates/patsubrs.txt.erb +10 -0
- data/lib/origen_testers/igxl_based_tester/j750/test_instance.rb +547 -0
- data/lib/origen_testers/igxl_based_tester/j750/test_instance_group.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750/test_instances.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt.rb +34 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/flow.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/flow_line.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/generator.rb +19 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patgroup.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patgroups.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patset.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patset_pattern.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patsets.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patsubr.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patsubr_pattern.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patsubrs.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/test_instance.rb +515 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/test_instance_group.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/test_instances.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/parser.rb +102 -0
- data/lib/origen_testers/igxl_based_tester/parser/ac_spec.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/parser/ac_specs.rb +0 -0
- data/lib/origen_testers/igxl_based_tester/parser/dc_spec.rb +33 -0
- data/lib/origen_testers/igxl_based_tester/parser/dc_specs.rb +48 -0
- data/lib/origen_testers/igxl_based_tester/parser/descriptions.rb +339 -0
- data/lib/origen_testers/igxl_based_tester/parser/flow.rb +109 -0
- data/lib/origen_testers/igxl_based_tester/parser/flow_line.rb +203 -0
- data/lib/origen_testers/igxl_based_tester/parser/flows.rb +21 -0
- data/lib/origen_testers/igxl_based_tester/parser/pattern_set.rb +92 -0
- data/lib/origen_testers/igxl_based_tester/parser/pattern_sets.rb +31 -0
- data/lib/origen_testers/igxl_based_tester/parser/test_instance.rb +341 -0
- data/lib/origen_testers/igxl_based_tester/parser/test_instances.rb +24 -0
- data/lib/origen_testers/igxl_based_tester/parser/timeset.rb +13 -0
- data/lib/origen_testers/igxl_based_tester/parser/timesets.rb +0 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex.rb +477 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/flow.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/flow_line.rb +19 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/generator.rb +19 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patgroup.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patgroups.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patset.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patset_pattern.rb +18 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patsets.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patsubr.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patsubr_pattern.rb +18 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patsubrs.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/templates/flow.txt.erb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/templates/instances.txt.erb +16 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/templates/patgroups.txt.erb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/templates/patsets.txt.erb +10 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/templates/patsubrs.txt.erb +10 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/test_instance.rb +270 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/test_instance_group.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/test_instances.rb +10 -0
- data/lib/origen_testers/interface.rb +183 -0
- data/lib/origen_testers/parser.rb +22 -0
- data/lib/origen_testers/parser/description_lookup.rb +62 -0
- data/lib/origen_testers/parser/searchable_array.rb +30 -0
- data/lib/origen_testers/parser/searchable_hash.rb +30 -0
- data/lib/origen_testers/pattern_compilers.rb +116 -0
- data/lib/origen_testers/pattern_compilers/assembler.rb +88 -0
- data/lib/origen_testers/pattern_compilers/job.rb +96 -0
- data/lib/origen_testers/pattern_compilers/ultraflex_pattern_compiler.rb +599 -0
- data/lib/origen_testers/program_generators.rb +55 -0
- data/lib/origen_testers/smartest_based_tester.rb +8 -0
- data/lib/origen_testers/smartest_based_tester/base.rb +411 -0
- data/lib/origen_testers/smartest_based_tester/base/flow.rb +188 -0
- data/lib/origen_testers/smartest_based_tester/base/flow_node.rb +476 -0
- data/lib/origen_testers/smartest_based_tester/base/generator.rb +123 -0
- data/lib/origen_testers/smartest_based_tester/base/pattern_compiler.rb +23 -0
- data/lib/origen_testers/smartest_based_tester/base/pattern_master.rb +47 -0
- data/lib/origen_testers/smartest_based_tester/base/test_method.rb +143 -0
- data/lib/origen_testers/smartest_based_tester/base/test_methods.rb +73 -0
- data/lib/origen_testers/smartest_based_tester/base/test_methods/ac_tml.rb +33 -0
- data/lib/origen_testers/smartest_based_tester/base/test_methods/base_tml.rb +38 -0
- data/lib/origen_testers/smartest_based_tester/base/test_methods/custom_tml.rb +19 -0
- data/lib/origen_testers/smartest_based_tester/base/test_methods/dc_tml.rb +147 -0
- data/lib/origen_testers/smartest_based_tester/base/test_methods/limits.rb +43 -0
- data/lib/origen_testers/smartest_based_tester/base/test_suite.rb +166 -0
- data/lib/origen_testers/smartest_based_tester/base/test_suites.rb +58 -0
- data/lib/origen_testers/smartest_based_tester/v93k.rb +8 -0
- data/lib/origen_testers/smartest_based_tester/v93k/builder.rb +89 -0
- data/lib/origen_testers/smartest_based_tester/v93k/builder/flow.rb +169 -0
- data/lib/origen_testers/smartest_based_tester/v93k/builder/pattern_master.rb +54 -0
- data/lib/origen_testers/smartest_based_tester/v93k/flow.rb +10 -0
- data/lib/origen_testers/smartest_based_tester/v93k/flow_node.rb +9 -0
- data/lib/origen_testers/smartest_based_tester/v93k/generator.rb +19 -0
- data/lib/origen_testers/smartest_based_tester/v93k/pattern_compiler.rb +10 -0
- data/lib/origen_testers/smartest_based_tester/v93k/pattern_master.rb +10 -0
- data/lib/origen_testers/smartest_based_tester/v93k/templates/template.aiv.erb +17 -0
- data/lib/origen_testers/smartest_based_tester/v93k/templates/template.flow.erb +201 -0
- data/lib/origen_testers/smartest_based_tester/v93k/templates/template.pmfl.erb +13 -0
- data/lib/origen_testers/smartest_based_tester/v93k/test_method.rb +9 -0
- data/lib/origen_testers/smartest_based_tester/v93k/test_methods.rb +9 -0
- data/lib/origen_testers/smartest_based_tester/v93k/test_suite.rb +9 -0
- data/lib/origen_testers/smartest_based_tester/v93k/test_suites.rb +9 -0
- data/lib/origen_testers/test/basic_interface.rb +17 -0
- data/lib/origen_testers/test/block.rb +21 -0
- data/lib/origen_testers/test/dut.rb +184 -0
- data/lib/origen_testers/test/dut2.rb +76 -0
- data/lib/origen_testers/test/j750_base_interface.rb +119 -0
- data/lib/origen_testers/test/j750_hpt_interface.rb +8 -0
- data/lib/origen_testers/test/j750_interface.rb +8 -0
- data/lib/origen_testers/test/nvm.rb +94 -0
- data/lib/origen_testers/test/ultraflex_interface.rb +110 -0
- data/lib/origen_testers/test/v93k_interface.rb +115 -0
- data/lib/origen_testers/timing.rb +362 -0
- data/lib/origen_testers/vector.rb +203 -0
- data/lib/origen_testers/vector_based_tester.rb +42 -0
- data/lib/origen_testers/vector_generator.rb +623 -0
- data/lib/origen_testers/vector_pipeline.rb +288 -0
- data/pattern/dc_instr.rb +7 -0
- data/pattern/delay.rb +7 -0
- data/pattern/mem_test.rb +8 -0
- data/pattern/multi_vector.rb +117 -0
- data/pattern/multi_vector_plus1.rb +125 -0
- data/pattern/nvm/j750/add_late_pins.rb +3 -0
- data/pattern/nvm/j750/iterator_postfix_test_x_bx.rb +8 -0
- data/pattern/nvm/j750/iterator_test_x_bx.rb +8 -0
- data/pattern/nvm/j750/j750_halt.rb +159 -0
- data/pattern/nvm/j750/j750_workout.rb +202 -0
- data/pattern/nvm/j750/timing.rb +73 -0
- data/pattern/nvm/v93k/v93k_workout.rb +136 -0
- data/pattern/read_write_reg.rb +58 -0
- data/pattern/reset.rb +4 -0
- data/pattern/subroutines.rb +38 -0
- data/program/_additional_erase.rb +7 -0
- data/program/_efa_resources.rb +7 -0
- data/program/_erase.rb +25 -0
- data/program/_erase_vfy.rb +5 -0
- data/program/_iv_resources.rb +10 -0
- data/program/basic_interface.rb +5 -0
- data/program/components/_prb2_main.rb +6 -0
- data/program/flow_control.rb +164 -0
- data/program/prb1.rb +226 -0
- data/program/prb1_resources.rb +28 -0
- data/program/prb2.rb +40 -0
- data/program/test.rb +20 -0
- data/templates/example.txt.erb +53 -0
- data/templates/j750/_vt_flow.txt.erb +8 -0
- data/templates/j750/_vt_instances.txt.erb +4 -0
- data/templates/j750/program_sheet.txt.erb +9 -0
- data/templates/manifest/v93k.yaml.erb +22 -0
- data/templates/web/index.md.erb +51 -0
- data/templates/web/layouts/_basic.html.erb +15 -0
- data/templates/web/partials/_navbar.html.erb +22 -0
- data/templates/web/release_notes.md.erb +5 -0
- metadata +332 -0
@@ -0,0 +1,88 @@
|
|
1
|
+
module OrigenTesters
|
2
|
+
module PatternCompilers
|
3
|
+
class UltraFlexPatternCompiler
|
4
|
+
private
|
5
|
+
|
6
|
+
# Check the file extension of a file, return status can be 'atp', 'list', or nil
|
7
|
+
def check_file_ext(file)
|
8
|
+
status = nil
|
9
|
+
ext = file.extname
|
10
|
+
name = file.basename
|
11
|
+
if ext == '.atp'
|
12
|
+
status = 'atp'
|
13
|
+
elsif ext == '.gz'
|
14
|
+
# Ensure we have a .atp.gz
|
15
|
+
sub_ext = name.to_s.split('.')[-2]
|
16
|
+
if sub_ext == 'atp'
|
17
|
+
status = 'atp'
|
18
|
+
end
|
19
|
+
elsif ext == '.list'
|
20
|
+
status = 'list'
|
21
|
+
end
|
22
|
+
status
|
23
|
+
end
|
24
|
+
|
25
|
+
# Parse a pattern list file recursively until all .atp or .atp.gz files are found
|
26
|
+
def parse_list(path, files)
|
27
|
+
list_name = path.basename
|
28
|
+
dir = path.dirname
|
29
|
+
line_number = 0
|
30
|
+
path.open('r') do |f|
|
31
|
+
while (line = f.gets)
|
32
|
+
line_number += 1
|
33
|
+
# Strip the leading and trailing whitespace for sloppy typers
|
34
|
+
line.strip!
|
35
|
+
# Skip a blank line
|
36
|
+
next if line.match(/^\s+$/)
|
37
|
+
# Check if the pattern or list exists
|
38
|
+
line_path = Pathname.new("#{dir}/#{line}")
|
39
|
+
unless line_path.file?
|
40
|
+
# puts "Skipping #{line_path.to_s} at line ##{line_number} in file #{path.to_s} because it is not a file"
|
41
|
+
next
|
42
|
+
end
|
43
|
+
# Process the file
|
44
|
+
process_file(line_path, files)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Processes a file looking for a valid .atp or .list
|
50
|
+
def process_file(file, files)
|
51
|
+
# puts "processing file #{file.to_s}"
|
52
|
+
case check_file_ext(file)
|
53
|
+
when 'atp'
|
54
|
+
files << file unless files.include?(file)
|
55
|
+
when 'list'
|
56
|
+
parse_list(file, files)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Processes a diretcory looking for files in '.' or recursively
|
61
|
+
def process_directory(dir, files, rec)
|
62
|
+
dir.children(true).each do |f|
|
63
|
+
# ignore sub-directories
|
64
|
+
if f.directory?
|
65
|
+
if rec == false
|
66
|
+
next
|
67
|
+
else
|
68
|
+
process_directory(f.expand_path, files, rec)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
process_file(f.expand_path, files)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Deletes the pattern compiler log files
|
76
|
+
def clean_output
|
77
|
+
@jobs.each do |job|
|
78
|
+
logfile = Pathname.new("#{job.pattern.dirname}/#{job.pattern.basename.to_s.chomp(job.pattern.extname)}.log")
|
79
|
+
logfile.cleanpath
|
80
|
+
if logfile.file?
|
81
|
+
# puts "Deleting log file #{logfile}"
|
82
|
+
logfile.delete
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module OrigenTesters
|
2
|
+
module PatternCompilers
|
3
|
+
class Job
|
4
|
+
# Pattern to be compiled, is Pathname class. Will use full path
|
5
|
+
attr_accessor :pattern
|
6
|
+
|
7
|
+
# Type of pattern as designated by the LinuxPatternCompiler
|
8
|
+
attr_accessor :id
|
9
|
+
|
10
|
+
# Where the job is to be executed, either locally ('local') or on Linux Server Farm ('lsf')
|
11
|
+
attr_accessor :location
|
12
|
+
|
13
|
+
# Controls whether the compiler log files are kept: true/false
|
14
|
+
attr_accessor :clean
|
15
|
+
|
16
|
+
# Controls whether the compiler STDOUT is displayed
|
17
|
+
attr_accessor :verbose
|
18
|
+
|
19
|
+
# Output directory for the .PAT file
|
20
|
+
attr_accessor :output_directory
|
21
|
+
|
22
|
+
# Pinmap file
|
23
|
+
attr_accessor :pinmap_workbook
|
24
|
+
|
25
|
+
# Compiler options where only the opt has to be passed as '-opt'
|
26
|
+
attr_accessor :compiler_options
|
27
|
+
|
28
|
+
# Compiler options where an opt and an arg have to be passed '-opt:arg'
|
29
|
+
attr_accessor :compiler_options_with_args
|
30
|
+
|
31
|
+
# linux compiler full path
|
32
|
+
attr_reader :compiler
|
33
|
+
|
34
|
+
def initialize(pattern, options_with_args, options)
|
35
|
+
@pattern = pattern
|
36
|
+
@compiler = options_with_args.delete(:compiler)
|
37
|
+
@id = options_with_args.delete(:id)
|
38
|
+
@location = options_with_args.delete(:location)
|
39
|
+
@clean = options_with_args.delete(:clean)
|
40
|
+
@verbose = options_with_args.delete(:verbose)
|
41
|
+
@output_directory = options_with_args.delete(:output_directory)
|
42
|
+
@pinmap_workbook = options_with_args.delete(:pinmap_workbook)
|
43
|
+
@compiler_options_with_args = options_with_args.delete_if { |k, v| v.nil? } # Whatever's left has to be valid compiler options
|
44
|
+
@compiler_options = options.delete_if { |k, v| v == false }
|
45
|
+
end
|
46
|
+
|
47
|
+
def name
|
48
|
+
@pattern.basename
|
49
|
+
end
|
50
|
+
|
51
|
+
def cmd
|
52
|
+
cmd = ''
|
53
|
+
cmd = "#{@compiler} -pinmap_workbook:#{@pinmap_workbook} -output:#{@output_directory}/#{@pattern.basename.to_s.split('.').first}.PAT #{@pattern} "
|
54
|
+
# add in any remaining compiler options
|
55
|
+
compiler_options.each_key { |k| cmd += "-#{k} " }
|
56
|
+
compiler_options_with_args.each_pair { |k, v| cmd += "-#{k}:#{v} " }
|
57
|
+
if @verbose
|
58
|
+
cmd += ';'
|
59
|
+
else
|
60
|
+
cmd += '2>&1 > /dev/null;'
|
61
|
+
end
|
62
|
+
# If the job is to be run on the LSF add in the clean .log and mv the files if necessary
|
63
|
+
if @location == 'lsf'
|
64
|
+
cmd += clean_lsf if @clean == true
|
65
|
+
end
|
66
|
+
cmd
|
67
|
+
end
|
68
|
+
|
69
|
+
def ready?
|
70
|
+
ready = true
|
71
|
+
ready && @output_directory.directory? &&
|
72
|
+
@pattern.file? && @pinmap_workbook.file? &&
|
73
|
+
[true, false].include?(@clean) &&
|
74
|
+
[:local, :lsf].include?(@location)
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def orig_dir
|
80
|
+
@pattern.dirname
|
81
|
+
end
|
82
|
+
|
83
|
+
# Generates the LSF commands to delete the pattern compiler log files
|
84
|
+
def clean_lsf
|
85
|
+
cmd = ''
|
86
|
+
logfile = Pathname.new("#{@pattern.dirname}/#{@pattern.basename.to_s.split('.').first}.log")
|
87
|
+
logfile.cleanpath
|
88
|
+
logfile.cleanpath
|
89
|
+
if @clean == true
|
90
|
+
cmd += "rm #{logfile}; "
|
91
|
+
end
|
92
|
+
cmd
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,599 @@
|
|
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
|