origen_testers 0.13.1 → 0.13.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (258) hide show
  1. checksums.yaml +4 -4
  2. data/config/application.rb +151 -151
  3. data/config/boot.rb +13 -13
  4. data/config/commands.rb +85 -86
  5. data/config/users.rb +18 -18
  6. data/config/version.rb +8 -8
  7. data/lib/commands/build.rb +69 -69
  8. data/lib/commands/run.rb +48 -48
  9. data/lib/origen_testers.rb +47 -47
  10. data/lib/origen_testers/api.rb +381 -381
  11. data/lib/origen_testers/basic_test_setups.rb +105 -105
  12. data/lib/origen_testers/callback_handlers.rb +59 -59
  13. data/lib/origen_testers/command_based_tester.rb +45 -45
  14. data/lib/origen_testers/flow.rb +382 -382
  15. data/lib/origen_testers/generator.rb +283 -283
  16. data/lib/origen_testers/generator/identity_map.rb +23 -23
  17. data/lib/origen_testers/generator/placeholder.rb +11 -11
  18. data/lib/origen_testers/generator/test_numberer.rb +23 -23
  19. data/lib/origen_testers/igxl_based_tester.rb +12 -12
  20. data/lib/origen_testers/igxl_based_tester/base.rb +1100 -1099
  21. data/lib/origen_testers/igxl_based_tester/base/ac_specsets.rb +79 -79
  22. data/lib/origen_testers/igxl_based_tester/base/custom_test_instance.rb +169 -169
  23. data/lib/origen_testers/igxl_based_tester/base/dc_specsets.rb +98 -98
  24. data/lib/origen_testers/igxl_based_tester/base/edge.rb +60 -60
  25. data/lib/origen_testers/igxl_based_tester/base/edges.rb +24 -24
  26. data/lib/origen_testers/igxl_based_tester/base/edgeset.rb +39 -39
  27. data/lib/origen_testers/igxl_based_tester/base/edgesets.rb +130 -130
  28. data/lib/origen_testers/igxl_based_tester/base/flow.rb +460 -460
  29. data/lib/origen_testers/igxl_based_tester/base/flow_line.rb +276 -276
  30. data/lib/origen_testers/igxl_based_tester/base/generator.rb +607 -607
  31. data/lib/origen_testers/igxl_based_tester/base/global_specs.rb +83 -83
  32. data/lib/origen_testers/igxl_based_tester/base/job.rb +75 -75
  33. data/lib/origen_testers/igxl_based_tester/base/jobs.rb +44 -44
  34. data/lib/origen_testers/igxl_based_tester/base/level_io_se.rb +59 -59
  35. data/lib/origen_testers/igxl_based_tester/base/level_supply.rb +39 -39
  36. data/lib/origen_testers/igxl_based_tester/base/levels.rb +31 -31
  37. data/lib/origen_testers/igxl_based_tester/base/levelset.rb +110 -110
  38. data/lib/origen_testers/igxl_based_tester/base/patgroup.rb +109 -109
  39. data/lib/origen_testers/igxl_based_tester/base/patgroups.rb +38 -38
  40. data/lib/origen_testers/igxl_based_tester/base/patset.rb +68 -68
  41. data/lib/origen_testers/igxl_based_tester/base/patset_pattern.rb +56 -56
  42. data/lib/origen_testers/igxl_based_tester/base/patsets.rb +38 -38
  43. data/lib/origen_testers/igxl_based_tester/base/patsubr.rb +68 -68
  44. data/lib/origen_testers/igxl_based_tester/base/patsubr_pattern.rb +56 -56
  45. data/lib/origen_testers/igxl_based_tester/base/patsubrs.rb +38 -38
  46. data/lib/origen_testers/igxl_based_tester/base/pinmap.rb +93 -93
  47. data/lib/origen_testers/igxl_based_tester/base/references.rb +25 -25
  48. data/lib/origen_testers/igxl_based_tester/base/test_instance.rb +322 -322
  49. data/lib/origen_testers/igxl_based_tester/base/test_instance_group.rb +66 -66
  50. data/lib/origen_testers/igxl_based_tester/base/test_instances.rb +212 -212
  51. data/lib/origen_testers/igxl_based_tester/base/test_instances/custom_til.rb +37 -37
  52. data/lib/origen_testers/igxl_based_tester/base/timeset.rb +37 -37
  53. data/lib/origen_testers/igxl_based_tester/base/timesets.rb +49 -49
  54. data/lib/origen_testers/igxl_based_tester/base/timesets_basic.rb +49 -49
  55. data/lib/origen_testers/igxl_based_tester/files.rb +43 -43
  56. data/lib/origen_testers/igxl_based_tester/j750.rb +269 -269
  57. data/lib/origen_testers/igxl_based_tester/j750/custom_test_instance.rb +32 -32
  58. data/lib/origen_testers/igxl_based_tester/j750/flow.rb +10 -10
  59. data/lib/origen_testers/igxl_based_tester/j750/flow_line.rb +19 -19
  60. data/lib/origen_testers/igxl_based_tester/j750/generator.rb +19 -19
  61. data/lib/origen_testers/igxl_based_tester/j750/patgroup.rb +9 -9
  62. data/lib/origen_testers/igxl_based_tester/j750/patgroups.rb +10 -10
  63. data/lib/origen_testers/igxl_based_tester/j750/patset.rb +9 -9
  64. data/lib/origen_testers/igxl_based_tester/j750/patset_pattern.rb +18 -18
  65. data/lib/origen_testers/igxl_based_tester/j750/patsets.rb +10 -10
  66. data/lib/origen_testers/igxl_based_tester/j750/patsubr.rb +9 -9
  67. data/lib/origen_testers/igxl_based_tester/j750/patsubr_pattern.rb +18 -18
  68. data/lib/origen_testers/igxl_based_tester/j750/patsubrs.rb +10 -10
  69. data/lib/origen_testers/igxl_based_tester/j750/test_instance.rb +746 -746
  70. data/lib/origen_testers/igxl_based_tester/j750/test_instance_group.rb +9 -9
  71. data/lib/origen_testers/igxl_based_tester/j750/test_instances.rb +10 -10
  72. data/lib/origen_testers/igxl_based_tester/j750_hpt.rb +34 -34
  73. data/lib/origen_testers/igxl_based_tester/j750_hpt/custom_test_instance.rb +32 -32
  74. data/lib/origen_testers/igxl_based_tester/j750_hpt/flow.rb +9 -9
  75. data/lib/origen_testers/igxl_based_tester/j750_hpt/flow_line.rb +9 -9
  76. data/lib/origen_testers/igxl_based_tester/j750_hpt/generator.rb +19 -19
  77. data/lib/origen_testers/igxl_based_tester/j750_hpt/patgroup.rb +9 -9
  78. data/lib/origen_testers/igxl_based_tester/j750_hpt/patgroups.rb +9 -9
  79. data/lib/origen_testers/igxl_based_tester/j750_hpt/patset.rb +9 -9
  80. data/lib/origen_testers/igxl_based_tester/j750_hpt/patset_pattern.rb +9 -9
  81. data/lib/origen_testers/igxl_based_tester/j750_hpt/patsets.rb +9 -9
  82. data/lib/origen_testers/igxl_based_tester/j750_hpt/patsubr.rb +9 -9
  83. data/lib/origen_testers/igxl_based_tester/j750_hpt/patsubr_pattern.rb +9 -9
  84. data/lib/origen_testers/igxl_based_tester/j750_hpt/patsubrs.rb +9 -9
  85. data/lib/origen_testers/igxl_based_tester/j750_hpt/test_instance.rb +599 -599
  86. data/lib/origen_testers/igxl_based_tester/j750_hpt/test_instance_group.rb +9 -9
  87. data/lib/origen_testers/igxl_based_tester/j750_hpt/test_instances.rb +9 -9
  88. data/lib/origen_testers/igxl_based_tester/parser.rb +102 -102
  89. data/lib/origen_testers/igxl_based_tester/parser/ac_spec.rb +9 -9
  90. data/lib/origen_testers/igxl_based_tester/parser/dc_spec.rb +33 -33
  91. data/lib/origen_testers/igxl_based_tester/parser/dc_specs.rb +48 -48
  92. data/lib/origen_testers/igxl_based_tester/parser/descriptions.rb +339 -339
  93. data/lib/origen_testers/igxl_based_tester/parser/flow.rb +109 -109
  94. data/lib/origen_testers/igxl_based_tester/parser/flow_line.rb +203 -203
  95. data/lib/origen_testers/igxl_based_tester/parser/flows.rb +21 -21
  96. data/lib/origen_testers/igxl_based_tester/parser/pattern_set.rb +92 -92
  97. data/lib/origen_testers/igxl_based_tester/parser/pattern_sets.rb +31 -31
  98. data/lib/origen_testers/igxl_based_tester/parser/test_instance.rb +420 -420
  99. data/lib/origen_testers/igxl_based_tester/parser/test_instances.rb +24 -24
  100. data/lib/origen_testers/igxl_based_tester/parser/timeset.rb +13 -13
  101. data/lib/origen_testers/igxl_based_tester/ultraflex.rb +798 -798
  102. data/lib/origen_testers/igxl_based_tester/ultraflex/ac_specsets.rb +10 -10
  103. data/lib/origen_testers/igxl_based_tester/ultraflex/ate_hardware.rb +949 -949
  104. data/lib/origen_testers/igxl_based_tester/ultraflex/custom_test_instance.rb +36 -36
  105. data/lib/origen_testers/igxl_based_tester/ultraflex/dc_specsets.rb +10 -10
  106. data/lib/origen_testers/igxl_based_tester/ultraflex/edge.rb +9 -9
  107. data/lib/origen_testers/igxl_based_tester/ultraflex/edges.rb +9 -9
  108. data/lib/origen_testers/igxl_based_tester/ultraflex/edgeset.rb +9 -9
  109. data/lib/origen_testers/igxl_based_tester/ultraflex/edgesets.rb +10 -10
  110. data/lib/origen_testers/igxl_based_tester/ultraflex/flow.rb +158 -158
  111. data/lib/origen_testers/igxl_based_tester/ultraflex/flow_line.rb +19 -19
  112. data/lib/origen_testers/igxl_based_tester/ultraflex/generator.rb +19 -19
  113. data/lib/origen_testers/igxl_based_tester/ultraflex/global_specs.rb +10 -10
  114. data/lib/origen_testers/igxl_based_tester/ultraflex/job.rb +9 -9
  115. data/lib/origen_testers/igxl_based_tester/ultraflex/jobs.rb +10 -10
  116. data/lib/origen_testers/igxl_based_tester/ultraflex/level_io_se.rb +9 -9
  117. data/lib/origen_testers/igxl_based_tester/ultraflex/level_supply.rb +9 -9
  118. data/lib/origen_testers/igxl_based_tester/ultraflex/levels.rb +9 -9
  119. data/lib/origen_testers/igxl_based_tester/ultraflex/levelset.rb +10 -10
  120. data/lib/origen_testers/igxl_based_tester/ultraflex/patgroup.rb +9 -9
  121. data/lib/origen_testers/igxl_based_tester/ultraflex/patgroups.rb +10 -10
  122. data/lib/origen_testers/igxl_based_tester/ultraflex/patset.rb +9 -9
  123. data/lib/origen_testers/igxl_based_tester/ultraflex/patset_pattern.rb +18 -18
  124. data/lib/origen_testers/igxl_based_tester/ultraflex/patsets.rb +10 -10
  125. data/lib/origen_testers/igxl_based_tester/ultraflex/patsubr.rb +9 -9
  126. data/lib/origen_testers/igxl_based_tester/ultraflex/patsubr_pattern.rb +18 -18
  127. data/lib/origen_testers/igxl_based_tester/ultraflex/patsubrs.rb +10 -10
  128. data/lib/origen_testers/igxl_based_tester/ultraflex/pinmap.rb +10 -10
  129. data/lib/origen_testers/igxl_based_tester/ultraflex/references.rb +10 -10
  130. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/ac_specsets.txt.erb +0 -0
  131. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/dc_specsets.txt.erb +0 -0
  132. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/edgesets.txt.erb +0 -0
  133. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/global_specs.txt.erb +0 -0
  134. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/jobs.txt.erb +0 -0
  135. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/levelset.txt.erb +0 -0
  136. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/pinmap.txt.erb +0 -0
  137. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/references.txt.erb +0 -0
  138. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/timesets.txt.erb +0 -0
  139. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/timesets_basic.txt.erb +0 -0
  140. data/lib/origen_testers/igxl_based_tester/ultraflex/test_instance.rb +315 -315
  141. data/lib/origen_testers/igxl_based_tester/ultraflex/test_instance_group.rb +9 -9
  142. data/lib/origen_testers/igxl_based_tester/ultraflex/test_instances.rb +10 -10
  143. data/lib/origen_testers/igxl_based_tester/ultraflex/timeset.rb +9 -9
  144. data/lib/origen_testers/igxl_based_tester/ultraflex/timesets.rb +10 -10
  145. data/lib/origen_testers/igxl_based_tester/ultraflex/timesets_basic.rb +10 -10
  146. data/lib/origen_testers/interface.rb +345 -324
  147. data/lib/origen_testers/memory_style.rb +77 -77
  148. data/lib/origen_testers/no_interface.rb +7 -7
  149. data/lib/origen_testers/origen_ext/application/runner.rb +25 -25
  150. data/lib/origen_testers/origen_ext/generator.rb +54 -54
  151. data/lib/origen_testers/origen_ext/generator/flow.rb +91 -77
  152. data/lib/origen_testers/origen_ext/generator/resources.rb +21 -21
  153. data/lib/origen_testers/origen_ext/pins/pin.rb +78 -78
  154. data/lib/origen_testers/origen_ext/pins/pin_collection.rb +84 -84
  155. data/lib/origen_testers/parser.rb +22 -22
  156. data/lib/origen_testers/parser/description_lookup.rb +62 -62
  157. data/lib/origen_testers/parser/searchable_array.rb +30 -30
  158. data/lib/origen_testers/parser/searchable_hash.rb +30 -30
  159. data/lib/origen_testers/pattern_compilers.rb +116 -116
  160. data/lib/origen_testers/pattern_compilers/assembler.rb +88 -88
  161. data/lib/origen_testers/pattern_compilers/job.rb +96 -96
  162. data/lib/origen_testers/pattern_compilers/ultraflex_pattern_compiler.rb +599 -599
  163. data/lib/origen_testers/program_generators.rb +62 -62
  164. data/lib/origen_testers/smartest_based_tester.rb +8 -8
  165. data/lib/origen_testers/smartest_based_tester/base.rb +576 -567
  166. data/lib/origen_testers/smartest_based_tester/base/flow.rb +296 -291
  167. data/lib/origen_testers/smartest_based_tester/base/generator.rb +207 -194
  168. data/lib/origen_testers/smartest_based_tester/base/pattern_compiler.rb +32 -32
  169. data/lib/origen_testers/smartest_based_tester/base/pattern_master.rb +69 -69
  170. data/lib/origen_testers/smartest_based_tester/base/processors.rb +16 -16
  171. data/lib/origen_testers/smartest_based_tester/base/processors/adjacent_if_combiner.rb +106 -106
  172. data/lib/origen_testers/smartest_based_tester/base/processors/continue_implementer.rb +39 -39
  173. data/lib/origen_testers/smartest_based_tester/base/processors/empty_branch_cleaner.rb +21 -21
  174. data/lib/origen_testers/smartest_based_tester/base/processors/extract_run_flag_table.rb +33 -33
  175. data/lib/origen_testers/smartest_based_tester/base/processors/extract_set_variables.rb +22 -22
  176. data/lib/origen_testers/smartest_based_tester/base/processors/flag_optimizer.rb +188 -188
  177. data/lib/origen_testers/smartest_based_tester/base/processors/if_ran_cleaner.rb +34 -34
  178. data/lib/origen_testers/smartest_based_tester/base/test_method.rb +178 -164
  179. data/lib/origen_testers/smartest_based_tester/base/test_methods.rb +77 -73
  180. data/lib/origen_testers/smartest_based_tester/base/test_methods/ac_tml.rb +33 -33
  181. data/lib/origen_testers/smartest_based_tester/base/test_methods/base_tml.rb +38 -38
  182. data/lib/origen_testers/smartest_based_tester/base/test_methods/custom_tml.rb +19 -19
  183. data/lib/origen_testers/smartest_based_tester/base/test_methods/dc_tml.rb +147 -147
  184. data/lib/origen_testers/smartest_based_tester/base/test_methods/limits.rb +65 -65
  185. data/lib/origen_testers/smartest_based_tester/base/test_suite.rb +208 -193
  186. data/lib/origen_testers/smartest_based_tester/base/test_suites.rb +58 -54
  187. data/lib/origen_testers/smartest_based_tester/base/variables_file.rb +38 -38
  188. data/lib/origen_testers/smartest_based_tester/v93k.rb +8 -8
  189. data/lib/origen_testers/smartest_based_tester/v93k/builder.rb +89 -89
  190. data/lib/origen_testers/smartest_based_tester/v93k/builder/flow.rb +181 -181
  191. data/lib/origen_testers/smartest_based_tester/v93k/builder/pattern_master.rb +54 -54
  192. data/lib/origen_testers/smartest_based_tester/v93k/flow.rb +10 -10
  193. data/lib/origen_testers/smartest_based_tester/v93k/generator.rb +19 -19
  194. data/lib/origen_testers/smartest_based_tester/v93k/pattern_compiler.rb +10 -10
  195. data/lib/origen_testers/smartest_based_tester/v93k/pattern_master.rb +10 -10
  196. data/lib/origen_testers/smartest_based_tester/v93k/templates/template.aiv.erb +17 -17
  197. data/lib/origen_testers/smartest_based_tester/v93k/templates/template.pmfl.erb +13 -13
  198. data/lib/origen_testers/smartest_based_tester/v93k/templates/template.tf.erb +236 -214
  199. data/lib/origen_testers/smartest_based_tester/v93k/templates/vars.tf.erb +48 -48
  200. data/lib/origen_testers/smartest_based_tester/v93k/test_method.rb +9 -9
  201. data/lib/origen_testers/smartest_based_tester/v93k/test_methods.rb +9 -9
  202. data/lib/origen_testers/smartest_based_tester/v93k/test_suite.rb +9 -9
  203. data/lib/origen_testers/smartest_based_tester/v93k/test_suites.rb +9 -9
  204. data/lib/origen_testers/smartest_based_tester/v93k/variables_file.rb +10 -10
  205. data/lib/origen_testers/test/basic_interface.rb +17 -17
  206. data/lib/origen_testers/test/block.rb +21 -21
  207. data/lib/origen_testers/test/custom_test_interface.rb +111 -111
  208. data/lib/origen_testers/test/dut.rb +295 -295
  209. data/lib/origen_testers/test/dut2.rb +76 -76
  210. data/lib/origen_testers/test/dut3.rb +244 -244
  211. data/lib/origen_testers/test/interface.rb +503 -503
  212. data/lib/origen_testers/test/nvm.rb +94 -94
  213. data/lib/origen_testers/timing.rb +368 -368
  214. data/lib/origen_testers/vector.rb +207 -207
  215. data/lib/origen_testers/vector_based_tester.rb +41 -41
  216. data/lib/origen_testers/vector_generator.rb +655 -655
  217. data/lib/origen_testers/vector_pipeline.rb +302 -302
  218. data/pattern/bitmap.rb +7 -7
  219. data/pattern/dc_instr.rb +7 -7
  220. data/pattern/delay.rb +7 -7
  221. data/pattern/freq_counter.rb +6 -6
  222. data/pattern/mem_test.rb +8 -8
  223. data/pattern/multi_vector.rb +122 -122
  224. data/pattern/multi_vector_plus1.rb +125 -125
  225. data/pattern/nvm/j750/add_late_pins.rb +3 -3
  226. data/pattern/nvm/j750/iterator_postfix_test_x_bx.rb +8 -8
  227. data/pattern/nvm/j750/iterator_test_x_bx.rb +8 -8
  228. data/pattern/nvm/j750/j750_halt.rb +159 -159
  229. data/pattern/nvm/j750/j750_workout.rb +209 -209
  230. data/pattern/nvm/j750/timing.rb +73 -73
  231. data/pattern/read_write_reg.rb +61 -61
  232. data/pattern/reset.rb +4 -4
  233. data/pattern/subroutines.rb +69 -69
  234. data/pattern/tester_overlay.rb +61 -52
  235. data/pattern/tester_store.rb +28 -28
  236. data/program/_additional_erase.rb +7 -7
  237. data/program/_efa_resources.rb +7 -7
  238. data/program/_erase.rb +25 -25
  239. data/program/_erase_vfy.rb +5 -5
  240. data/program/_iv_resources.rb +10 -10
  241. data/program/basic_interface.rb +5 -5
  242. data/program/components/_prb1_main.rb +222 -222
  243. data/program/components/_temp.rb +6 -6
  244. data/program/custom_tests.rb +10 -10
  245. data/program/flow_control.rb +422 -422
  246. data/program/prb1.rb +11 -11
  247. data/program/prb1_resources.rb +28 -28
  248. data/program/prb2.rb +27 -27
  249. data/program/test.rb +29 -29
  250. data/program/uflex_resources.rb +199 -199
  251. data/templates/example.txt.erb +53 -53
  252. data/templates/j750/program_sheet.txt.erb +9 -9
  253. data/templates/manifest/v93k.yaml.erb +22 -22
  254. data/templates/web/index.md.erb +51 -51
  255. data/templates/web/layouts/_basic.html.erb +15 -15
  256. data/templates/web/partials/_navbar.html.erb +22 -22
  257. data/templates/web/release_notes.md.erb +5 -5
  258. metadata +2 -2
@@ -1,96 +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
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
@@ -1,599 +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
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