origen_testers 0.9.9 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (254) hide show
  1. checksums.yaml +4 -4
  2. data/config/application.rb +151 -151
  3. data/config/boot.rb +13 -12
  4. data/config/commands.rb +86 -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 -46
  10. data/lib/origen_testers/api.rb +381 -292
  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 +1095 -929
  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 +446 -446
  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 -691
  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 +328 -328
  147. data/lib/origen_testers/memory_style.rb +77 -0
  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 +77 -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 +562 -492
  166. data/lib/origen_testers/smartest_based_tester/base/flow.rb +279 -279
  167. data/lib/origen_testers/smartest_based_tester/base/generator.rb +193 -193
  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 +13 -13
  171. data/lib/origen_testers/smartest_based_tester/base/processors/empty_branch_cleaner.rb +49 -49
  172. data/lib/origen_testers/smartest_based_tester/base/processors/extract_set_variables.rb +22 -22
  173. data/lib/origen_testers/smartest_based_tester/base/processors/flag_optimizer.rb +143 -143
  174. data/lib/origen_testers/smartest_based_tester/base/processors/if_ran_cleaner.rb +34 -34
  175. data/lib/origen_testers/smartest_based_tester/base/test_method.rb +164 -164
  176. data/lib/origen_testers/smartest_based_tester/base/test_methods.rb +73 -73
  177. data/lib/origen_testers/smartest_based_tester/base/test_methods/ac_tml.rb +33 -33
  178. data/lib/origen_testers/smartest_based_tester/base/test_methods/base_tml.rb +38 -38
  179. data/lib/origen_testers/smartest_based_tester/base/test_methods/custom_tml.rb +19 -19
  180. data/lib/origen_testers/smartest_based_tester/base/test_methods/dc_tml.rb +147 -147
  181. data/lib/origen_testers/smartest_based_tester/base/test_methods/limits.rb +65 -65
  182. data/lib/origen_testers/smartest_based_tester/base/test_suite.rb +193 -193
  183. data/lib/origen_testers/smartest_based_tester/base/test_suites.rb +54 -54
  184. data/lib/origen_testers/smartest_based_tester/base/variables_file.rb +38 -38
  185. data/lib/origen_testers/smartest_based_tester/v93k.rb +8 -8
  186. data/lib/origen_testers/smartest_based_tester/v93k/builder.rb +89 -89
  187. data/lib/origen_testers/smartest_based_tester/v93k/builder/flow.rb +181 -181
  188. data/lib/origen_testers/smartest_based_tester/v93k/builder/pattern_master.rb +54 -54
  189. data/lib/origen_testers/smartest_based_tester/v93k/flow.rb +10 -10
  190. data/lib/origen_testers/smartest_based_tester/v93k/generator.rb +19 -19
  191. data/lib/origen_testers/smartest_based_tester/v93k/pattern_compiler.rb +10 -10
  192. data/lib/origen_testers/smartest_based_tester/v93k/pattern_master.rb +10 -10
  193. data/lib/origen_testers/smartest_based_tester/v93k/templates/template.aiv.erb +17 -17
  194. data/lib/origen_testers/smartest_based_tester/v93k/templates/template.pmfl.erb +13 -13
  195. data/lib/origen_testers/smartest_based_tester/v93k/templates/template.tf.erb +214 -214
  196. data/lib/origen_testers/smartest_based_tester/v93k/templates/vars.tf.erb +48 -48
  197. data/lib/origen_testers/smartest_based_tester/v93k/test_method.rb +9 -9
  198. data/lib/origen_testers/smartest_based_tester/v93k/test_methods.rb +9 -9
  199. data/lib/origen_testers/smartest_based_tester/v93k/test_suite.rb +9 -9
  200. data/lib/origen_testers/smartest_based_tester/v93k/test_suites.rb +9 -9
  201. data/lib/origen_testers/smartest_based_tester/v93k/variables_file.rb +10 -10
  202. data/lib/origen_testers/test/basic_interface.rb +17 -17
  203. data/lib/origen_testers/test/block.rb +21 -21
  204. data/lib/origen_testers/test/custom_test_interface.rb +111 -111
  205. data/lib/origen_testers/test/dut.rb +295 -295
  206. data/lib/origen_testers/test/dut2.rb +76 -76
  207. data/lib/origen_testers/test/dut3.rb +244 -0
  208. data/lib/origen_testers/test/interface.rb +503 -503
  209. data/lib/origen_testers/test/nvm.rb +94 -94
  210. data/lib/origen_testers/timing.rb +362 -362
  211. data/lib/origen_testers/vector.rb +207 -207
  212. data/lib/origen_testers/vector_based_tester.rb +41 -41
  213. data/lib/origen_testers/vector_generator.rb +655 -655
  214. data/lib/origen_testers/vector_pipeline.rb +302 -302
  215. data/pattern/bitmap.rb +7 -7
  216. data/pattern/dc_instr.rb +7 -7
  217. data/pattern/delay.rb +7 -7
  218. data/pattern/freq_counter.rb +6 -6
  219. data/pattern/mem_test.rb +8 -8
  220. data/pattern/multi_vector.rb +122 -122
  221. data/pattern/multi_vector_plus1.rb +125 -125
  222. data/pattern/nvm/j750/add_late_pins.rb +3 -3
  223. data/pattern/nvm/j750/iterator_postfix_test_x_bx.rb +8 -8
  224. data/pattern/nvm/j750/iterator_test_x_bx.rb +8 -8
  225. data/pattern/nvm/j750/j750_halt.rb +159 -159
  226. data/pattern/nvm/j750/j750_workout.rb +209 -209
  227. data/pattern/nvm/j750/timing.rb +73 -73
  228. data/pattern/read_write_reg.rb +61 -61
  229. data/pattern/reset.rb +4 -4
  230. data/pattern/subroutines.rb +69 -69
  231. data/pattern/tester_overlay.rb +53 -0
  232. data/pattern/tester_store.rb +29 -0
  233. data/program/_additional_erase.rb +7 -7
  234. data/program/_efa_resources.rb +7 -7
  235. data/program/_erase.rb +25 -25
  236. data/program/_erase_vfy.rb +5 -5
  237. data/program/_iv_resources.rb +10 -10
  238. data/program/basic_interface.rb +5 -5
  239. data/program/components/_temp.rb +6 -6
  240. data/program/custom_tests.rb +10 -10
  241. data/program/flow_control.rb +321 -321
  242. data/program/prb1.rb +219 -219
  243. data/program/prb1_resources.rb +28 -28
  244. data/program/prb2.rb +27 -27
  245. data/program/test.rb +29 -29
  246. data/program/uflex_resources.rb +199 -199
  247. data/templates/example.txt.erb +53 -53
  248. data/templates/j750/program_sheet.txt.erb +9 -9
  249. data/templates/manifest/v93k.yaml.erb +22 -22
  250. data/templates/web/index.md.erb +51 -51
  251. data/templates/web/layouts/_basic.html.erb +15 -15
  252. data/templates/web/partials/_navbar.html.erb +22 -22
  253. data/templates/web/release_notes.md.erb +5 -5
  254. metadata +7 -3
@@ -1,23 +1,23 @@
1
- module OrigenTesters
2
- module Generator
3
- class IdentityMap
4
- def initialize
5
- @store = {}
6
- @versions = {}
7
- end
8
-
9
- def current_version_of(obj)
10
- map = map_for(obj)
11
- if map
12
- map[:replaced_by] || map[:instance]
13
- else
14
- obj
15
- end
16
- end
17
-
18
- def map_for(obj)
19
- @store[obj.object_id]
20
- end
21
- end
22
- end
23
- end
1
+ module OrigenTesters
2
+ module Generator
3
+ class IdentityMap
4
+ def initialize
5
+ @store = {}
6
+ @versions = {}
7
+ end
8
+
9
+ def current_version_of(obj)
10
+ map = map_for(obj)
11
+ if map
12
+ map[:replaced_by] || map[:instance]
13
+ else
14
+ obj
15
+ end
16
+ end
17
+
18
+ def map_for(obj)
19
+ @store[obj.object_id]
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,11 +1,11 @@
1
- module OrigenTesters
2
- module Generator
3
- class Placeholder
4
- attr_accessor :type, :file, :options, :id
5
-
6
- def initialize(type, file, options = {})
7
- @type, @file, @options = type, file, options
8
- end
9
- end
10
- end
11
- end
1
+ module OrigenTesters
2
+ module Generator
3
+ class Placeholder
4
+ attr_accessor :type, :file, :options, :id
5
+
6
+ def initialize(type, file, options = {})
7
+ @type, @file, @options = type, file, options
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,23 +1,23 @@
1
- module OrigenTesters
2
- module Generator
3
- class TestNumberer
4
- # Will return a test number for the given test.
5
- #
6
- # @param [Hash] options Options to customize the number generation
7
- # @option options [Integer] :bits (6) The number of bits in the DAC code
8
- # @option options [Float] :range (1.26) The range parameter, see code formula
9
- # @option options [Integer] :offset (0) The o
10
- def test_number_for(test_name, options = {})
11
- options = {
12
-
13
- }.merge(options)
14
- end
15
-
16
- private
17
-
18
- def store_file
19
- @store_file ||= Pathname.new "#{Origen.root}/.test_program/test_numbers"
20
- end
21
- end
22
- end
23
- end
1
+ module OrigenTesters
2
+ module Generator
3
+ class TestNumberer
4
+ # Will return a test number for the given test.
5
+ #
6
+ # @param [Hash] options Options to customize the number generation
7
+ # @option options [Integer] :bits (6) The number of bits in the DAC code
8
+ # @option options [Float] :range (1.26) The range parameter, see code formula
9
+ # @option options [Integer] :offset (0) The o
10
+ def test_number_for(test_name, options = {})
11
+ options = {
12
+
13
+ }.merge(options)
14
+ end
15
+
16
+ private
17
+
18
+ def store_file
19
+ @store_file ||= Pathname.new "#{Origen.root}/.test_program/test_numbers"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,12 +1,12 @@
1
- module OrigenTesters
2
- module IGXLBasedTester
3
- autoload :Base, 'origen_testers/igxl_based_tester/base.rb'
4
- autoload :J750, 'origen_testers/igxl_based_tester/j750.rb'
5
- autoload :J750_HPT, 'origen_testers/igxl_based_tester/j750_hpt.rb'
6
- autoload :UltraFLEX, 'origen_testers/igxl_based_tester/ultraflex.rb'
7
- end
8
- # Convenience/Legacy names without the IGXLBasedTester namespace
9
- autoload :J750, 'origen_testers/igxl_based_tester/j750.rb'
10
- autoload :J750_HPT, 'origen_testers/igxl_based_tester/j750_hpt.rb'
11
- autoload :UltraFLEX, 'origen_testers/igxl_based_tester/ultraflex.rb'
12
- end
1
+ module OrigenTesters
2
+ module IGXLBasedTester
3
+ autoload :Base, 'origen_testers/igxl_based_tester/base.rb'
4
+ autoload :J750, 'origen_testers/igxl_based_tester/j750.rb'
5
+ autoload :J750_HPT, 'origen_testers/igxl_based_tester/j750_hpt.rb'
6
+ autoload :UltraFLEX, 'origen_testers/igxl_based_tester/ultraflex.rb'
7
+ end
8
+ # Convenience/Legacy names without the IGXLBasedTester namespace
9
+ autoload :J750, 'origen_testers/igxl_based_tester/j750.rb'
10
+ autoload :J750_HPT, 'origen_testers/igxl_based_tester/j750_hpt.rb'
11
+ autoload :UltraFLEX, 'origen_testers/igxl_based_tester/ultraflex.rb'
12
+ end
@@ -1,929 +1,1095 @@
1
- module OrigenTesters
2
- module IGXLBasedTester
3
- # This is the base class of all IGXL-based testers
4
- class Base
5
- include VectorBasedTester
6
-
7
- attr_accessor :software_version
8
- attr_accessor :pattern_compiler_pinmap
9
- attr_accessor :memory_test_en
10
- attr_accessor :testerconfig
11
- attr_accessor :channelmap
12
- attr_accessor :default_channelmap
13
- attr_accessor :default_testerconfig
14
- attr_accessor :max_site
15
- # NOTE: DO NOT USE THIS CLASS DIRECTLY ONLY USED AS PARENT FOR
16
- # DESIRED TESTER CLASS
17
-
18
- # Returns a new IGXLBasedTester instance, normally there would only ever be one of these
19
- # assigned to the global variable such as $tester by your target.
20
- def initialize
21
- @unique_counter = 0
22
- @counter_lsb_bits = 0
23
- @counter_msb_bits = 0
24
- @max_repeat_loop = 65_535 # 16 bits
25
- @min_repeat_loop = 2
26
- @pat_extension = 'atp'
27
- @active_loads = true
28
- @pipeline_depth = 34
29
- @software_version = ''
30
- @compress = true
31
- @support_repeat_previous = true
32
- @match_entries = 10
33
- @name = ''
34
- @program_comment_char = ['logprint', "'"]
35
- @opcode_mode = :extended
36
- @flags = %w(cpuA cpuB cpuC cpuD)
37
- @microcode = {}
38
- @microcode[:enable] = 'enable'
39
- @microcode[:set_flag] = 'set_cpu'
40
- @microcode[:mask_vector] = 'ign ifc icc'
41
-
42
- @mask_vector = false # sticky option to mask all subsequent vectors
43
-
44
- @min_pattern_vectors = 0 # no minimum
45
-
46
- @memory_test_en = false # memory test enabled (for all patterns?)
47
-
48
- @testerconfig ||= {}
49
- @channelmap ||= {}
50
- end
51
-
52
- def igxl_based?
53
- true
54
- end
55
-
56
- def import_tester_config(testconfigname, fullconfigpath)
57
- # This function reads in CurrentConfig.txt file generated by IG-XL.
58
- # testconfigname example ==> "FT", "WT", "Production"
59
- # fullconfigpath example ==> "/product_folder/CurrentConfig.txt"
60
-
61
- puts "importing Testerconfig #{testconfigname}..."
62
- slotnum = Struct.new(:slot, :instrument, :idprom)
63
- @testerconfig[testconfigname] ||= {}
64
- current_config_file = Pathname.new(fullconfigpath)
65
- File.open(current_config_file, 'r').each_line do |line|
66
- if line =~ /^\d*.0/
67
- (slot, blank1, instrument, blank2, idprom) = line.split(/\t/)
68
- if (!slot.nil?) && (!instrument.nil?) && (!idprom.nil?)
69
- @testerconfig[testconfigname][slot.split('.').first.to_i] = slotnum.new(slot.split('.').first.to_i, instrument, idprom.chomp)
70
- end
71
- end
72
- end
73
-
74
- @default_testerconfig ||= testconfigname # Default TesterConfig gets set if it's not nil
75
- end
76
-
77
- def get_tester_instrument(testconfigname, slot)
78
- @testerconfig[testconfigname].each_with_index do |element, index|
79
- if slot.to_s == element[0].to_s
80
- return element[1][:instrument]
81
- end
82
- end
83
- nil # if no corresponding slot
84
- end
85
-
86
- def get_instrument_slots(testconfigname, instrument) # testconfigname example "WT", "FT", "Production"
87
- @slots = []
88
- @testerconfig[testconfigname].each_with_index do |element, index|
89
- if instrument.to_s == element[1][:instrument].to_s
90
- @slots << element[0].to_i
91
- end
92
- end
93
- @slots # if no corresponding slot
94
- end
95
-
96
- def import_chanmap(chanmapname, fullchanmappath)
97
- # This function reads IG-XL ChannelMap file
98
- # chanmapname example ==> "FT", "WT", "FTX2"
99
- # fullchanmappath example ==> "/product_folder/Chans_FT.txt"
100
-
101
- puts "importing ChannelMap #{fullchanmappath}..."
102
-
103
- chanassignment = Struct.new(:pinname, :site, :channel, :type, :packagepin)
104
- chanmap_file = Pathname.new(fullchanmappath)
105
- @channelmap[chanmapname] ||= {}
106
- File.open(chanmap_file, 'r').each_line.with_index do |line, index|
107
- if index == 0
108
- unless line =~ /DTChanMap/
109
- puts "#{fullchanmappath} is not a valid IG-XL ChannelMap!"
110
- break
111
- end
112
- end
113
- if index == 5
114
- siteloc = line.strip.split(/\t/).size - 1 # strip all white spaces and grab second to last
115
- @max_site_s = line.split(/\t/)[siteloc].strip.split(/\s/)[1]
116
- @max_site = @max_site_s.to_i
117
- (0..@max_site).each do |sitenum|
118
- @channelmap[chanmapname][sitenum] ||= {}
119
- end
120
- end
121
- if index > 5
122
- (blank1, pinname, packagepin, type) = line.split(/\t/)
123
- (0..@max_site).each do |sitenum|
124
- channel = line.split(/\t/)[4 + sitenum].to_s
125
- @channelmap[chanmapname][sitenum][pinname.downcase.intern] = chanassignment.new(pinname.downcase.intern, sitenum, channel.chomp, type.chomp, packagepin)
126
- end
127
- end
128
- end
129
- @default_channelmap ||= chanmapname # Default Channelmap gets set if it's not nil
130
- end
131
-
132
- def get_tester_channel(chanmapname, pinname, sitenum)
133
- if sitenum <= @max_site
134
- @testerchannel = @channelmap[chanmapname][sitenum][pinname].channel
135
- return @testerchannel
136
- else
137
- return nil
138
- end
139
- end
140
-
141
- # Check if a specific pin for a given channelmap for a given site number is using merged channel.
142
- # If yes, return x2 for Merged2, x4 for Merged4, etc. If no, return nil.
143
- def merged_channels(chanmapname, pinname, sitenum)
144
- if sitenum <= @max_site
145
- if @channelmap[chanmapname][sitenum][pinname].type.include?('Merged')
146
- @merged_channels = @channelmap[chanmapname][sitenum][pinname].type.split('Merged')[1]
147
- return 'x' + @merged_channels
148
- end
149
- else
150
- return nil
151
- end
152
- end
153
-
154
- # Check if a specific HexVS supply is HexVS+ variety, which has +/-2mV accuracy as opposed to
155
- # +/-7mV accuracy.
156
- # If the specific HexVS is HexVS+ variety, returns a "+" string, otherwise nil.
157
- def is_hexvs_plus(testconfigname, slot)
158
- if @testerconfig[testconfigname][slot][:instrument].to_s == 'HexVS'
159
- @productnum = @testerconfig[testconfigname][slot][:idprom].split(' ')[0]
160
- if (@productnum.include?('974-294-')) && (@productnum.split('-')[2].to_i >= 20)
161
- return '+'
162
- end
163
- end
164
- nil # if nothing matched
165
- end
166
-
167
- # Check if a specific VHDVS (UVS256) supply is High-Accuracy (HA) variety, which has +/-5mV+0.1%*SUPPLY accuracy as opposed to
168
- # +/-10mV+0.1%*SUPPLY accuracy.
169
- # If the specific VHDVS is of High-Accuracy variety, returns a "+" string, otherwise nil.
170
- def is_vhdvs_plus(testconfigname, slot)
171
- if @testerconfig[testconfigname][slot][:instrument].to_s == 'VHDVS'
172
- @productnum = @testerconfig[testconfigname][slot][:idprom].split(' ')[0]
173
- # binding.pry
174
- if (@productnum.include?('805-052-')) && (@productnum.split('-')[2].to_i >= 05)
175
- return '+'
176
- end
177
- end
178
- nil # if nothing matched
179
- end
180
- # Check if a specific VHDVS (UVS256) channel assignment is _HC variety (high-current)
181
- # If the specific VHDVS channel is _HC variety, returns a "_HC" string, otherwise nil.
182
- def is_vhdvs_hc(chanmapname, pinname, sitenum)
183
- if sitenum <= @max_site
184
- if @channelmap[chanmapname][sitenum][pinname].channel.downcase.include?('hc')
185
- return '_HC'
186
- end
187
- end
188
- nil # if nothing matched
189
- end
190
-
191
- def assign_dc_instr_pins(dc_pins)
192
- if !dc_pins.is_a?(Array)
193
- @dc_pins = [] << dc_pins
194
- else
195
- @dc_pins = dc_pins
196
- end
197
- end
198
-
199
- def assign_digsrc_pins(digsrc_pins)
200
- if !digsrc_pins.is_a?(Array)
201
- @digsrc_pins = [] << digsrc_pins
202
- else
203
- @digsrc_pins = digsrc_pins
204
- end
205
- end
206
-
207
- def assign_digcap_pins(digcap_pins)
208
- if !digcap_pins.is_a?(Array)
209
- @digcap_pins = [] << digcap_pins
210
- else
211
- @digcap_pins = digcap_pins
212
- end
213
- end
214
-
215
- def get_dc_instr_pins
216
- @dc_pins
217
- end
218
-
219
- def get_digsrc_pins
220
- @digsrc_pins
221
- end
222
-
223
- def get_digcap_pins
224
- @digcap_pins
225
- end
226
-
227
- def flows
228
- parser.flows
229
- end
230
-
231
- # Main accessor to all content parsed from existing test program sheets found in the
232
- # supplied directory or in Origen.config.test_program_output_directory
233
- def parser(prog_dir = Origen.config.test_program_output_directory)
234
- unless prog_dir
235
- fail 'You must supply the directory containing the test program sheets, or define it via Origen.config.test_program_output_directory'
236
- end
237
- @parser ||= IGXLBasedTester::Parser.new
238
- @parsed_dir ||= false
239
- if @parsed_dir != prog_dir
240
- @parser.parse(prog_dir)
241
- @parsed_dir = prog_dir
242
- end
243
- @parser
244
- end
245
-
246
- # Capture a vector to the tester HRAM.
247
- #
248
- # This method applies a store vector (stv) opcode to the previous vector, note that is does
249
- # not actually generate a new vector.
250
- #
251
- # Sometimes when generating vectors within a loop you may want to apply a stv opcode
252
- # retrospectively to a previous vector, passing in an offset option will allow you
253
- # to do this.
254
- #
255
- # On J750 the pins argument is ignored since the tester only supports whole vector capture.
256
- #
257
- # @example
258
- # $tester.cycle # This is the vector you want to capture
259
- # $tester.store # This applies the STV opcode
260
- #
261
- # $tester.cycle # This one gets stored
262
- # $tester.cycle
263
- # $tester.cycle
264
- # $tester.store(:offset => -2) # Just realized I need to capture that earlier vector
265
- def store(*pins)
266
- options = pins.last.is_a?(Hash) ? pins.pop : {}
267
- options = { offset: 0
268
- }.merge(options)
269
- update_vector microcode: 'stv', offset: options[:offset]
270
- last_vector(options[:offset]).contains_capture = true
271
- end
272
- alias_method :to_hram, :store
273
- alias_method :capture, :store
274
-
275
- # Capture the next vector generated to HRAM
276
- #
277
- # This method applies a store vector (stv) opcode to the next vector to be generated,
278
- # note that is does not actually generate a new vector.
279
- #
280
- # On J750 the pins argument is ignored since the tester only supports whole vector capture.
281
- #
282
- # @example
283
- # $tester.store_next_cycle
284
- # $tester.cycle # This is the vector that will be captured
285
- def store_next_cycle(*pins)
286
- options = pins.last.is_a?(Hash) ? pins.pop : {}
287
- options = {
288
- }.merge(options)
289
- preset_next_vector microcode: 'stv' do |vector|
290
- vector.contains_capture = true
291
- end
292
- end
293
- alias_method :store!, :store_next_cycle
294
-
295
- # @api private
296
- def remove_store_from_vector(vector)
297
- super
298
- vector.microcode = nil
299
- end
300
-
301
- # Call a subroutine.
302
- #
303
- # This method applies a call subroutine opcode to the previous vector, it does not
304
- # generate a new vector.
305
- #
306
- # Subroutines should always be called through this method as it ensures a running
307
- # log of called subroutines is maintained and which then gets output in the pattern
308
- # header to import the right dependencies.
309
- #
310
- # An offset option is available to make the call on earlier vectors.
311
- #
312
- # ==== Examples
313
- # $tester.call_subroutine("mysub")
314
- # $tester.call_subroutine("my_other_sub", :offset => -1)
315
- def call_subroutine(name, options = {})
316
- options = {
317
- offset: 0
318
- }.merge(options)
319
- called_subroutines << name.to_s.chomp unless called_subroutines.include?(name.to_s.chomp) || @inhibit_vectors
320
- update_vector microcode: "call #{name}", offset: options[:offset]
321
- end
322
-
323
- # Start a subroutine.
324
- #
325
- # Generates a global subroutine label. Global is used to adhere to the best practice of
326
- # containing all subroutines in dedicated patterns, e.g. global_subs.atp
327
- #
328
- # ==== Examples
329
- # $tester.start_subroutine("wait_for_done")
330
- # < generate your subroutine vectors here >
331
- # $tester.end_subroutine
332
- def start_subroutine(name, options = {})
333
- local_subroutines << name.to_s.chomp unless local_subroutines.include?(name.to_s.chomp) || @inhibit_vectors
334
- if $tester.ultraflex? && (name =~ /keep_?alive/ || options[:keep_alive])
335
- microcode "keepalive subr #{name}:"
336
- else
337
- microcode "global subr #{name}:"
338
- end
339
- end
340
-
341
- # End a subroutine.
342
- #
343
- # Generates a return opcode on the last vector.
344
- #
345
- # ==== Examples
346
- # $tester.start_subroutine("wait_for_done")
347
- # < generate your subroutine vectors here >
348
- # $tester.end_subroutine
349
- # cond: whether return is conditional on a flag (to permit to mix subrs together)
350
- def end_subroutine(cond = false, options = {})
351
- (cond, options) = false, cond if cond.is_a?(Hash)
352
- if cond
353
- update_vector microcode: 'if (flag) return'
354
- else
355
- update_vector microcode: 'return'
356
- end
357
- end
358
-
359
- # Do a frequency measure.
360
- #
361
- # Write the necessary micro code to do a frequency measure on the given pin,
362
- # optionally supply a read code to pass information to the tester.
363
- #
364
- # ==== Examples
365
- # $tester.freq_count($top.pin(:d_out)) # Freq measure on pin "d_out"
366
- # $tester.freq_count($top.pin(:d_out):readcode => 10)
367
- def freq_count(pin, options = {})
368
- options = { readcode: false
369
- }.merge(options)
370
-
371
- set_code(options[:readcode]) if options[:readcode]
372
- cycle(microcode: "#{@microcode[:set_flag]} (cpuA)")
373
- cycle(microcode: "#{@microcode[:set_flag]} (cpuA)")
374
- cycle(microcode: "#{@microcode[:set_flag]} (cpuB)")
375
- cycle(microcode: "#{@microcode[:set_flag]} (cpuC)")
376
- cycle(microcode: 'freq_loop_1:')
377
- cycle(microcode: 'if (cpuA) jump freq_loop_1')
378
- pin.drive_lo
379
- delay(2000)
380
- pin.dont_care
381
- cycle(microcode: "freq_loop_2: #{@microcode[:enable]} (#{@flags[1]})")
382
- cycle(microcode: 'if (flag) jump freq_loop_2')
383
- cycle(microcode: "#{@microcode[:enable]} (#{@flags[2]})")
384
- cycle(microcode: 'if (flag) jump freq_loop_1')
385
- end
386
-
387
- # * J750 Specific *
388
- #
389
- # Generates a single MTO opcode line for J750
390
- #
391
- # Codes implemented: xa load_preset, xa inc, ya load_preset, ya inc, stv_m0, stv_m1, stv_c<br>
392
- def memory_test(options = {})
393
- options = {
394
- gen_vector: true, # Default generate vector not just MTO opcode
395
- init_counter_x: false, # initialize counter X
396
- inc_counter_x: false, # increment counter X
397
- init_counter_y: false, # initialize counter X
398
- inc_counter_y: false, # increment counter X
399
- capture_vector: false, # capture vector to memory using all mem types
400
- capture_vector_mem0: false, # capture vector to memory type 0, here for J750 will be stv_m0
401
- capture_vector_mem1: false, # capture vector to memory type 1, here for J750 will be stv_m1
402
- capture_vector_mem2: false, # capture vector to memory type 2, here for J750 will be stv_c
403
- pin: false, # pin on which to drive or expect data, pass pin object here!
404
- pin_data: false, # pin data (:none, :drive, :expect)
405
- }.merge(options)
406
-
407
- mto_opcode = ''
408
-
409
- if options[:init_counter_x]
410
- mto_opcode += ' xa load_preset'
411
- end
412
- if options[:inc_counter_x]
413
- mto_opcode += ' xa inc'
414
- end
415
- if options[:init_counter_y]
416
- mto_opcode += ' ya load_preset'
417
- end
418
- if options[:inc_counter_y]
419
- mto_opcode += ' ya inc'
420
- end
421
- if options[:capture_vector]
422
- mto_opcode += ' stv_m0 stv_m1 stv_c'
423
- end
424
- if options[:capture_vector_mem0]
425
- mto_opcode += ' stv_m0'
426
- end
427
- if options[:capture_vector_mem1]
428
- mto_opcode += ' stv_m1'
429
- end
430
- if options[:capture_vector_mem2]
431
- mto_opcode += ' stv_c'
432
- end
433
-
434
- unless mto_opcode.eql?('')
435
- mto_opcode = '(mto:' + mto_opcode + ')'
436
- end
437
-
438
- if options[:gen_vector]
439
- if options[:pin]
440
- case options[:pin_data]
441
- when :drive
442
- # store current pin state
443
- cur_pin_state = options[:pin].state.to_sym
444
- options[:pin].drive_mem
445
- when :expect
446
- # store current pin state
447
- cur_pin_state = options[:pin].state.to_sym
448
- options[:pin].expect_mem
449
- end
450
- end
451
- cycle(microcode: "#{mto_opcode}")
452
- if options[:pin]
453
- # restore previous pin state
454
- case options[:pin_data]
455
- when :drive
456
- options[:pin].state = cur_pin_state
457
- when :expect
458
- options[:pin].state = cur_pin_state
459
- end
460
- end
461
- else
462
- microcode "#{mto_opcode}"
463
- end
464
- end
465
-
466
- # Generates a match loop on up to two pins.
467
- #
468
- # This method is not really intended to be called directly, rather you should call
469
- # via Tester#wait e.g. $tester.wait(:match => true).
470
- #
471
- # The timeout should be provided in cycles, however when called via the wait method the
472
- # time-based helpers (time_in_us, etc) will be converted to cycles for you.
473
- # The following options are available to tailor the match loop behavior, defaults in
474
- # parenthesis:
475
- # * :pin - The pin object to match on (*required*)
476
- # * :state - The pin state to match on, :low or :high (*required*)
477
- # * :pin2 (nil) - Optionally supply a second pin to match on
478
- # * :state2 (nil) - State for the second pin (required if :pin2 is supplied)
479
- # * :check_for_fails (false) - Flushes the pipeline and handshakes with the tester (passing readcode 100) prior to the match (to allow binout of fails encountered before the match)
480
- # * :force_fail_on_timeout (true) - Force a vector mis-compare if the match loop times out
481
- # * :on_timeout_goto ("") - Optionally supply a label to branch to on timeout, by default will continue from the end of the match loop
482
- # * :on_pin_match_goto ("") - Optionally supply a label to branch to when pin 1 matches, by default will continue from the end of the match loop
483
- # * :on_pin2_match_goto ("") - Optionally supply a label to branch to when pin 2 matches, by default will continue from the end of the match loop
484
- # * :multiple_entries (false) - Supply an integer to generate multiple entries into the match (each with a unique readcode), this can be useful when debugging patterns with multiple matches
485
- # * :force_fail_on_timeout (true) - force pattern to fail if timeout occurs
486
- # * :global_loops (false) - whether match loop loops should use global labels
487
- # * :manual_stop (false) - whether to use extra cpuB flag to resolve IG-XL v.3.50.xx bug where VBT clears cpuA immediately
488
- # at start of PatFlagFunc instead of at end. Use will have to manually clear cpuB to resume this pattern.
489
- # ==== Examples
490
- # $tester.wait(:match => true, :time_in_us => 5000, :pin => $top.pin(:done), :state => :high)
491
- def match(pin, state, timeout, options = {})
492
- options = {
493
- check_for_fails: false,
494
- on_timeout_goto: false,
495
- pin2: false,
496
- state2: false,
497
- on_pin_match_goto: false,
498
- multiple_entries: false,
499
- force_fail_on_timeout: true,
500
- global_loops: false,
501
- manual_stop: false,
502
- clr_fail_post_match: false
503
- }.merge(options)
504
- options[:on_block_match_goto] ||= options.delete(:on_pin_match_goto)
505
-
506
- match_block(timeout, options) do |match_conditions, fail_conditions|
507
- # Define match conditions
508
- match_conditions.add do
509
- state == :low ? pin.expect_lo : pin.expect_hi
510
- cc "Check if #{pin.name} is #{state == :low ? 'low' : 'high'}"
511
- cycle
512
- pin.dont_care
513
- end
514
-
515
- if options[:pin2]
516
- match_conditions.add do
517
- state == :low ? pin.expect_hi : pin.expect_lo
518
- options[:state2] == :low ? options[:pin2].expect_lo : options[:pin2].expect_hi
519
- cc "Check if #{options[:pin2].name} is #{options[:state2] == :low ? 'low' : 'high'}"
520
- cycle
521
- options[:pin2].dont_care
522
- pin.dont_care
523
- end
524
- end
525
-
526
- # Define fail conditions
527
- fail_conditions.add do
528
- state == :low ? pin.expect_lo : pin.expect_hi
529
- cc "Check if #{pin.name} is #{state == :low ? 'low' : 'high'}"
530
- if options[:pin2]
531
- options[:state2] == :low ? options[:pin2].expect_lo : options[:pin2].expect_hi
532
- cc "Check if #{options[:pin2].name} is #{options[:state2] == :low ? 'low' : 'high'}"
533
- end
534
- cycle
535
- pin.dont_care
536
- options[:pin2].dont_care if options[:pin2]
537
- end
538
- end
539
- end
540
-
541
- # Call a match loop.
542
- #
543
- # Normally you would put your match loop in a global subs pattern, then you can
544
- # call it via this method. This method automatically syncs match loop naming with
545
- # the match generation flow, no arguments required.
546
- #
547
- # This is an IGXLBasedTester specific API.
548
- #
549
- # ==== Examples
550
- # $tester.cycle
551
- # $tester.call_match # Calls the match loop, or the first entry point if you have multiple
552
- # $tester.cycle
553
- # $tester.call_match # Calls the match loop, or the second entry point if you have multiple
554
- def call_match
555
- @match_counter = @match_counter || 0
556
- call_subroutine("match_done_#{@match_counter}")
557
- @match_counter += 1 unless @match_counter == (@match_entries || 1) - 1
558
- end
559
-
560
- # Apply a label to the pattern.
561
- #
562
- # No additional vector is generated.
563
- # Arguments:
564
- # name : label name
565
- # global : (optional) whether to apply global label, default=false
566
- #
567
- # ==== Examples
568
- # $tester.label("something_significant")
569
- # $tester.label("something_significant",true) # apply global label
570
- def label(name, global = false)
571
- global_opt = (global) ? 'global ' : ''
572
- microcode global_opt + name + ':'
573
- end
574
-
575
- # * J750 Specific *
576
- #
577
- # Set a readcode.
578
- #
579
- # Use the set an explicit readcode for communicating with the tester. This method
580
- # will generate an additional vector.
581
- #
582
- # ==== Examples
583
- # $tester.set_code(55)
584
- def set_code(code)
585
- cycle(microcode: "set_code #{code}")
586
- end
587
-
588
- # Branch execution to the given point.
589
- #
590
- # This generates a new vector with a jump instruction to a given label. This method
591
- # will generate an additional vector.
592
- #
593
- # ==== Examples
594
- # $tester.branch_to("something_significant")
595
- def branch_to(label)
596
- cycle(microcode: "jump #{label}")
597
- end
598
- alias_method :branch, :branch_to
599
-
600
- # Add loop to the pattern.
601
- #
602
- # Pass in a name for the loop and the number of times to execute it, all vectors
603
- # generated by the given block will be captured in the loop.
604
- #
605
- # Optional arguments: global - whether to apply global label (default=false)
606
- # label_first - whether to apply loop label before loop vector or not
607
- #
608
- # ==== Examples
609
- # $tester.loop_vectors("pulse_loop", 3) do # Do this 3 times...
610
- # $tester.cycle
611
- # some_other_method_to_generate_vectors
612
- # end
613
- def loop_vectors(name, number_of_loops, global = false, label_first = false)
614
- if number_of_loops > 1
615
- @loop_counters ||= {}
616
- if @loop_counters[name]
617
- @loop_counters[name] += 1
618
- else
619
- @loop_counters[name] = 0
620
- end
621
- loop_name = @loop_counters[name] == 0 ? name : "#{name}_#{@loop_counters[name]}"
622
- if label_first
623
- global_opt = (global) ? 'global ' : ''
624
- microcode "#{global_opt}#{loop_name}: "
625
- end
626
- cycle(microcode: "loopA #{number_of_loops}")
627
- unless label_first
628
- global_opt = (global) ? 'global ' : ''
629
- cycle(microcode: "#{global_opt}#{loop_name}: ")
630
- end
631
- yield
632
- cycle(microcode: "end_loopA #{loop_name}")
633
- else
634
- yield
635
- end
636
- end
637
- alias_method :loop_vector, :loop_vectors
638
-
639
- # An internal method called by Origen Pattern Create to create the pattern header
640
- def pattern_header(options = {})
641
- options = {
642
- instruments: {}, # Provide instruments here if desired as a hash (e.g. "mto" => "dgen_2bit")
643
- subroutine_pat: false,
644
- svm_only: true, # Whether 'svm_only' can be specified
645
- group: false, # If true the end pattern is intended to run within a pattern group
646
- high_voltage: false, # Supply a pin name here to declare it as an HV instrument (not yet defined)
647
- freq_counter: false, # Supply a pin name here to declare it as a frequency counter
648
- memory_test: false, # If true, define 2-bit MTO DGEN as instrument
649
- }.merge(options)
650
-
651
- if level_period?
652
- microcode "import tset #{min_period_timeset.name};"
653
- else
654
- called_timesets.each do |timeset|
655
- microcode "import tset #{timeset.name};"
656
- end
657
- end
658
- unless options[:group] # Withhold imports for pattern groups, is this correct?
659
- called_subroutines.each do |sub_name|
660
- # Don't import any called subroutines that are declared in the current pattern
661
- microcode "import svm_subr #{sub_name};" unless local_subroutines.include?(sub_name)
662
- end
663
- end
664
-
665
- # If memory test, then add to instruments hash
666
- if options[:memory_test]
667
- options[:instruments].merge!('mto' => 'dgen_2bit')
668
- end
669
-
670
- if options[:svm_only]
671
- microcode "svm_only_file = #{options[:subroutine_pat] ? 'yes' : 'no'};"
672
- end
673
-
674
- microcode "opcode_mode = #{@opcode_mode};"
675
- microcode "digital_inst = #{options[:digital_inst]};" if options[:digital_inst]
676
- microcode 'compressed = yes;' # if $dut.gzip_patterns
677
- if tester.j750? && options[:freq_counter]
678
- # pin setup type => freq_counter is only for the J750.
679
- # UltraFLEX has frequency counter capability behind every pin.
680
- # need to make sure the pin_setup freq_count is defined after opcode_mode extended since freq count only work in extended mode
681
- if @opcode_mode == :extended
682
- microcode "pin_setup = {#{options[:freq_counter]} freq_count;}"
683
- else
684
- fail 'pin_setup freq_count can only work in extended mode'
685
- end
686
- end
687
-
688
- # Take care of any instruments
689
- if options[:instruments].length > 0
690
- microcode 'instruments = {'
691
- options[:instruments].each do |pins, instrument|
692
- if "#{pins}" == 'nil'
693
- microcode " #{instrument};"
694
- elsif instrument == 'digsrc'
695
- microcode " #{pins}:#{instrument} #{options[:digsrc_width]}:#{options[:digsrc_bit_order]}:#{options[:digsrc_mode]}:format=#{options[:digsrc_format]}:#{options[:digsrc_site_uniqueness]}:#{options[:digsrc_auto_cond]};"
696
- elsif instrument == 'digcap'
697
- microcode " #{pins}:#{instrument} #{options[:digcap_width]}:#{options[:digcap_bit_order]}:#{options[:digcap_mode]}:format=#{options[:digcap_format]}:data_type=#{options[:digcap_data_type]}:#{options[:digcap_auto_cond]}:#{options[:digcap_auto_trig_enable]}:#{options[:digcap_store_stv]}:#{options[:digcap_receive_data]};"
698
- else
699
- microcode " #{pins}:#{instrument};"
700
- end
701
- end
702
- microcode '}'
703
- end
704
-
705
- options[:high_voltage] = @use_hv_pin
706
- microcode "pin_setup = {#{options[:high_voltage]} high_voltage;}" if options[:high_voltage]
707
- microcode ''
708
-
709
- pin_list = ordered_pins.map(&:name).join(', ')
710
-
711
- # here indicate pattern header specific stuff
712
- yield pin_list
713
- if ordered_pins.size > 0
714
- max_pin_name_length = ordered_pins.map(&:name).max { |a, b| a.length <=> b.length }.length
715
- pin_widths = ordered_pins.map { |p| p.size - 1 }
716
-
717
- max_pin_name_length.times do |i|
718
- cc((' ' * 93) + ordered_pins.map.with_index { |p, x| ((p.name[i] || ' ') + ' ' * pin_widths[x]).gsub('_', '-') }.join(' '))
719
- end
720
- end
721
- end
722
-
723
- # An internal method called by Origen to generate the pattern footer
724
- def pattern_footer(options = {})
725
- options = {
726
- subroutine_pat: false,
727
- end_in_ka: false,
728
- end_with_halt: false,
729
- end_module: true
730
- }.merge(options)
731
- $tester.align_to_last
732
- # cycle(:microcode => "#{$dut.end_of_pattern_label}:") if $dut.end_of_pattern_label
733
- if options[:end_in_ka]
734
- keep_alive(options)
735
- else
736
- if options[:end_with_halt]
737
- $tester.cycle microcode: 'halt'
738
- else
739
- if options[:end_module]
740
- $tester.cycle microcode: 'end_module' unless options[:subroutine_pat]
741
- else
742
- $tester.cycle
743
- end
744
- end
745
- end
746
- microcode '}'
747
- end
748
-
749
- # Returns an array of subroutines called while generating the current pattern
750
- def called_subroutines
751
- @called_subroutines ||= []
752
- end
753
-
754
- # Returns an array of subroutines created by the current pattern
755
- def local_subroutines # :nodoc:
756
- @local_subroutines ||= []
757
- end
758
-
759
- # This is an internal method use by Origen which returns a fully formatted vector
760
- # You can override this if you wish to change the output formatting at vector level
761
- def format_vector(vec)
762
- timeset = vec.timeset ? "> #{vec.timeset.name}" : ''
763
- pin_vals = vec.pin_vals ? "#{vec.pin_vals} ;" : ''
764
- if vec.repeat > 1
765
- microcode = "repeat #{vec.repeat}"
766
- else
767
- microcode = vec.microcode ? vec.microcode : ''
768
- end
769
- if vec.pin_vals && ($_testers_enable_vector_comments || vector_comments)
770
- comment = " // #{vec.number}:#{vec.cycle} #{vec.inline_comment}"
771
- else
772
- comment = vec.inline_comment.empty? ? '' : " // #{vec.inline_comment}"
773
- end
774
-
775
- "#{microcode.ljust(65)}#{timeset.ljust(31)}#{pin_vals}#{comment}"
776
- end
777
-
778
- # Override this to force the formatting to match the v1 J750 model (easier diffs)
779
- def push_microcode(code) # :nodoc:
780
- stage.store(code.ljust(65) + ''.ljust(31))
781
- end
782
- alias_method :microcode, :push_microcode
783
-
784
- # All vectors generated with the supplied block will have all pins set
785
- # to the repeat previous state. Any pins that are changed state within
786
- # the block will still update to the supplied value.
787
- # ==== Example
788
- # # All pins except invoke will be assigned the repeat previous code
789
- # # in the generated vector. On completion of the block they will
790
- # # return to their previous state, except for invoke which will
791
- # # retain the value assigned within the block.
792
- # $tester.repeat_previous do
793
- # $top.pin(:invoke).drive(1)
794
- # $tester.cycle
795
- # end
796
- def repeat_previous
797
- pinmap = Origen.pin_bank.pins
798
- pinmap.each { |id, pin| pin.repeat_previous = true }
799
- yield
800
- pinmap.each { |id, pin| pin.repeat_previous = false }
801
- end
802
-
803
- def ignore_fails(*pins)
804
- pins.each(&:suspend)
805
- yield
806
- pins.each(&:resume)
807
- end
808
-
809
- def enable_flag(options = {})
810
- options = { flagnum: 4, # default flag to use
811
- }.merge(options)
812
-
813
- if options[:flagnum] > @flags.length
814
- abort "ERROR! Invalid flag value passed to 'enable_flag' method!\n"
815
- end
816
- flagname = @flags[options[:flagnum] - 1]
817
- update_vector(microcode: "#{@microcode[:enable]}(#{flagname})")
818
- end
819
-
820
- def set_flag(options = {})
821
- options = { flagnum: 4, # default flag to use
822
- }.merge(options)
823
-
824
- if options[:flagnum] > @flags.length
825
- abort "ERROR! Invalid flag value passed to 'set_flag' method!\n"
826
- end
827
- flagname = @flags[options[:flagnum] - 1]
828
- update_vector(microcode: "#{@microcode[:set_flag]}(#{flagname})")
829
- end
830
-
831
- def cycle(options = {})
832
- if @mask_vector
833
- # tack on masking opcodes
834
- super(options.merge(microcode: "#{options[:microcode]} #{@microcode[:mask_vector]}"))
835
- else
836
- super(options)
837
- end
838
- end
839
-
840
- # Call this method at the start of any digsrc overlay operations, this method
841
- # takes care of all the microcodes and delays that's needed for digsrc overlay
842
- # Required arguments:
843
- # pins
844
- # Optionsal arguments:
845
- # options[:dssc_mode] = :single or :dual, anything else wil be
846
- # treated as if it's operating in :quad mode
847
- def digsrc_start(pins, options = {})
848
- options = {
849
- dssc_mode: :single # defaults dssc_mode to single mode
850
- }.merge(options)
851
- if pins.size > 1
852
- microcode "((#{format_multiple_instrument_pins(pins)}):DigSrc = Start)"
853
- else
854
- microcode "((#{pin}):DigSrc = Start)"
855
- end
856
- if options[:dssc_mode] == :single
857
- $tester.cycle(repeat: 145) # minimum of 144 cycles, adding 1 for safey measures
858
- elsif options[:dssc_mode] == :dual
859
- $tester.cycle(repeat: 289) # minimum of 288 cycles, adding 1 for safety measures
860
- else
861
- $tester.cycle(repeat: 577) # minimum of 577 cycles, adding 1 for safety measures
862
- end
863
- end
864
-
865
- # Call this method at the end of each digscr overlay operation to clear the pattern
866
- # memory pipeline, so that the pattern is ready to do the next digsrc overlay operation.
867
- # Required arguments:
868
- # pins
869
- def digsrc_stop(pins, options = {})
870
- if pins.size > 1
871
- microcode "((#{format_multiple_instrument_pins(pins)}):DigSrc = Stop)"
872
- else
873
- microcode "((#{pins}):DigSrc = Stop)"
874
- end
875
- end
876
-
877
- # Call this method before each tester cycle to insert the digsrc overlay microcode
878
- def digsrc_send(pins)
879
- microcode "((#{format_multiple_instrument_pins(pins)}):DigSrc = SEND)"
880
- end
881
-
882
- # Call this method before each tester cycle to inser the digcap overlay microcode
883
- def digcap_store(pins)
884
- microcode "((#{format_multiple_instrument_pins(pins)}):DigCap = STORE)"
885
- end
886
-
887
- def apply_digsrc_settings(options = {})
888
- options.merge!(digsrc_width: 1) if options[:digsrc_width].nil? # default to digsrc 1
889
- options.merge!(digsrc_bit_order: :lsb) if options[:digsrc_bit_order].nil? # default to lsb
890
- options.merge!(digsrc_mode: :serial) if options[:digsrc_mode].nil? # default to serial mode
891
- options.merge!(digsrc_format: :binary) if options[:digsrc_format].nil? # default to binary
892
- options.merge!(digsrc_site_uniqueness: :unique_sites) if options[:digsrc_site_uniqueness].nil? # default to unique sites
893
- options.merge!(digsrc_data_type: :default) if options[:digsrc_data_type].nil? # default to default
894
- options.merge!(digsrc_auto_cond: :auto_cond_disable) if options[:digsrc_auto_cond].nil? # default to disable
895
- @digsrc_settings = options
896
- end
897
-
898
- def apply_digcap_settings(options = {})
899
- options.merge!(digcap_width: 8) if options[:digcap_width].nil? # default to digcap 8
900
- options.merge!(digcap_bit_order: :lsb) if options[:digcap_bit_order].nil? # default to lsb
901
- options.merge!(digcap_mode: :serial) if options[:digcap_mode].nil? # default to serial mode
902
- options.merge!(digcap_site_uniqueness: :unique_sites) if options[:digcap_site_uniqueness].nil? # default to unique sites
903
- options.merge!(digcap_format: :binary) if options[:digcap_format].nil? # default to binary
904
- options.merge!(digcap_data_type: :default) if options[:digcap_data_type].nil? # default to default
905
- options.merge!(digcap_auto_cond: :auto_cond_disable) if options[:digcap_auto_cond].nil? # default to disable
906
- options.merge!(digcap_auto_trig_enable: :auto_trig_disable) if options[:digcap_auto_trig_enable].nil? # default to disable
907
- options.merge!(digcap_store_stv: :store_stv_disable) if options[:digcap_store_stv].nil? # default to disable
908
- options.merge!(digcap_receive_data: :store_stv_disable) if options[:digcap_receive_data].nil? # default to logic
909
- @digcap_settings = options
910
- end
911
-
912
- # Call this method if there are more than one pin/pin groups used with an instrument,
913
- # this method will format an array of pins into the correct format required by igxl
914
- # pattern microcodes.
915
- def format_multiple_instrument_pins(pins, options = {})
916
- return_value = ''
917
- pins.each do |pin|
918
- return_value += "#{pin}"
919
- return_value += ',' unless pins.last == pin
920
- end
921
- return_value
922
- end
923
-
924
- def mask_fails(setclr)
925
- @mask_vector = setclr
926
- end
927
- end
928
- end
929
- end
1
+ module OrigenTesters
2
+ module IGXLBasedTester
3
+ # This is the base class of all IGXL-based testers
4
+ class Base
5
+ include VectorBasedTester
6
+
7
+ attr_accessor :software_version
8
+ attr_accessor :pattern_compiler_pinmap
9
+ attr_accessor :memory_test_en
10
+ attr_accessor :testerconfig
11
+ attr_accessor :channelmap
12
+ attr_accessor :default_channelmap
13
+ attr_accessor :default_testerconfig
14
+ attr_accessor :max_site
15
+ # NOTE: DO NOT USE THIS CLASS DIRECTLY ONLY USED AS PARENT FOR
16
+ # DESIRED TESTER CLASS
17
+
18
+ # Returns a new IGXLBasedTester instance, normally there would only ever be one of these
19
+ # assigned to the global variable such as $tester by your target.
20
+ def initialize
21
+ @unique_counter = 0
22
+ @counter_lsb_bits = 0
23
+ @counter_msb_bits = 0
24
+ @max_repeat_loop = 65_535 # 16 bits
25
+ @min_repeat_loop = 2
26
+ @pat_extension = 'atp'
27
+ @active_loads = true
28
+ @pipeline_depth = 34
29
+ @software_version = ''
30
+ @compress = true
31
+ @support_repeat_previous = true
32
+ @match_entries = 10
33
+ @name = ''
34
+ @program_comment_char = ['logprint', "'"]
35
+ @opcode_mode = :extended
36
+ @flags = %w(cpuA cpuB cpuC cpuD)
37
+ @microcode = {}
38
+ @microcode[:enable] = 'enable'
39
+ @microcode[:set_flag] = 'set_cpu'
40
+ @microcode[:mask_vector] = 'ign ifc icc'
41
+
42
+ @mask_vector = false # sticky option to mask all subsequent vectors
43
+
44
+ @min_pattern_vectors = 0 # no minimum
45
+
46
+ @memory_test_en = false # memory test enabled (for all patterns?)
47
+
48
+ @testerconfig ||= {}
49
+ @channelmap ||= {}
50
+ @pushed_instrument_configs = {}
51
+ @overlay_style = :subroutine # default to use subroutine for overlay
52
+ @capture_style = :hram # default to use hram for capture
53
+ @overlay_history = {} # used to track labels, subroutines, digsrc pins used etc
54
+ @overlay_subr = nil
55
+ @capture_history = {}
56
+ end
57
+
58
+ def igxl_based?
59
+ true
60
+ end
61
+
62
+ def import_tester_config(testconfigname, fullconfigpath)
63
+ # This function reads in CurrentConfig.txt file generated by IG-XL.
64
+ # testconfigname example ==> "FT", "WT", "Production"
65
+ # fullconfigpath example ==> "/product_folder/CurrentConfig.txt"
66
+
67
+ puts "importing Testerconfig #{testconfigname}..."
68
+ slotnum = Struct.new(:slot, :instrument, :idprom)
69
+ @testerconfig[testconfigname] ||= {}
70
+ current_config_file = Pathname.new(fullconfigpath)
71
+ File.open(current_config_file, 'r').each_line do |line|
72
+ if line =~ /^\d*.0/
73
+ (slot, blank1, instrument, blank2, idprom) = line.split(/\t/)
74
+ if (!slot.nil?) && (!instrument.nil?) && (!idprom.nil?)
75
+ @testerconfig[testconfigname][slot.split('.').first.to_i] = slotnum.new(slot.split('.').first.to_i, instrument, idprom.chomp)
76
+ end
77
+ end
78
+ end
79
+
80
+ @default_testerconfig ||= testconfigname # Default TesterConfig gets set if it's not nil
81
+ end
82
+
83
+ def get_tester_instrument(testconfigname, slot)
84
+ @testerconfig[testconfigname].each_with_index do |element, index|
85
+ if slot.to_s == element[0].to_s
86
+ return element[1][:instrument]
87
+ end
88
+ end
89
+ nil # if no corresponding slot
90
+ end
91
+
92
+ def get_instrument_slots(testconfigname, instrument) # testconfigname example "WT", "FT", "Production"
93
+ @slots = []
94
+ @testerconfig[testconfigname].each_with_index do |element, index|
95
+ if instrument.to_s == element[1][:instrument].to_s
96
+ @slots << element[0].to_i
97
+ end
98
+ end
99
+ @slots # if no corresponding slot
100
+ end
101
+
102
+ def import_chanmap(chanmapname, fullchanmappath)
103
+ # This function reads IG-XL ChannelMap file
104
+ # chanmapname example ==> "FT", "WT", "FTX2"
105
+ # fullchanmappath example ==> "/product_folder/Chans_FT.txt"
106
+
107
+ puts "importing ChannelMap #{fullchanmappath}..."
108
+
109
+ chanassignment = Struct.new(:pinname, :site, :channel, :type, :packagepin)
110
+ chanmap_file = Pathname.new(fullchanmappath)
111
+ @channelmap[chanmapname] ||= {}
112
+ File.open(chanmap_file, 'r').each_line.with_index do |line, index|
113
+ if index == 0
114
+ unless line =~ /DTChanMap/
115
+ puts "#{fullchanmappath} is not a valid IG-XL ChannelMap!"
116
+ break
117
+ end
118
+ end
119
+ if index == 5
120
+ siteloc = line.strip.split(/\t/).size - 1 # strip all white spaces and grab second to last
121
+ @max_site_s = line.split(/\t/)[siteloc].strip.split(/\s/)[1]
122
+ @max_site = @max_site_s.to_i
123
+ (0..@max_site).each do |sitenum|
124
+ @channelmap[chanmapname][sitenum] ||= {}
125
+ end
126
+ end
127
+ if index > 5
128
+ (blank1, pinname, packagepin, type) = line.split(/\t/)
129
+ (0..@max_site).each do |sitenum|
130
+ channel = line.split(/\t/)[4 + sitenum].to_s
131
+ @channelmap[chanmapname][sitenum][pinname.downcase.intern] = chanassignment.new(pinname.downcase.intern, sitenum, channel.chomp, type.chomp, packagepin)
132
+ end
133
+ end
134
+ end
135
+ @default_channelmap ||= chanmapname # Default Channelmap gets set if it's not nil
136
+ end
137
+
138
+ def get_tester_channel(chanmapname, pinname, sitenum)
139
+ if sitenum <= @max_site
140
+ @testerchannel = @channelmap[chanmapname][sitenum][pinname].channel
141
+ return @testerchannel
142
+ else
143
+ return nil
144
+ end
145
+ end
146
+
147
+ # Check if a specific pin for a given channelmap for a given site number is using merged channel.
148
+ # If yes, return x2 for Merged2, x4 for Merged4, etc. If no, return nil.
149
+ def merged_channels(chanmapname, pinname, sitenum)
150
+ if sitenum <= @max_site
151
+ if @channelmap[chanmapname][sitenum][pinname].type.include?('Merged')
152
+ @merged_channels = @channelmap[chanmapname][sitenum][pinname].type.split('Merged')[1]
153
+ return 'x' + @merged_channels
154
+ end
155
+ else
156
+ return nil
157
+ end
158
+ end
159
+
160
+ # Check if a specific HexVS supply is HexVS+ variety, which has +/-2mV accuracy as opposed to
161
+ # +/-7mV accuracy.
162
+ # If the specific HexVS is HexVS+ variety, returns a "+" string, otherwise nil.
163
+ def is_hexvs_plus(testconfigname, slot)
164
+ if @testerconfig[testconfigname][slot][:instrument].to_s == 'HexVS'
165
+ @productnum = @testerconfig[testconfigname][slot][:idprom].split(' ')[0]
166
+ if (@productnum.include?('974-294-')) && (@productnum.split('-')[2].to_i >= 20)
167
+ return '+'
168
+ end
169
+ end
170
+ nil # if nothing matched
171
+ end
172
+
173
+ # Check if a specific VHDVS (UVS256) supply is High-Accuracy (HA) variety, which has +/-5mV+0.1%*SUPPLY accuracy as opposed to
174
+ # +/-10mV+0.1%*SUPPLY accuracy.
175
+ # If the specific VHDVS is of High-Accuracy variety, returns a "+" string, otherwise nil.
176
+ def is_vhdvs_plus(testconfigname, slot)
177
+ if @testerconfig[testconfigname][slot][:instrument].to_s == 'VHDVS'
178
+ @productnum = @testerconfig[testconfigname][slot][:idprom].split(' ')[0]
179
+ # binding.pry
180
+ if (@productnum.include?('805-052-')) && (@productnum.split('-')[2].to_i >= 05)
181
+ return '+'
182
+ end
183
+ end
184
+ nil # if nothing matched
185
+ end
186
+ # Check if a specific VHDVS (UVS256) channel assignment is _HC variety (high-current)
187
+ # If the specific VHDVS channel is _HC variety, returns a "_HC" string, otherwise nil.
188
+ def is_vhdvs_hc(chanmapname, pinname, sitenum)
189
+ if sitenum <= @max_site
190
+ if @channelmap[chanmapname][sitenum][pinname].channel.downcase.include?('hc')
191
+ return '_HC'
192
+ end
193
+ end
194
+ nil # if nothing matched
195
+ end
196
+
197
+ def assign_dc_instr_pins(dc_pins)
198
+ if !dc_pins.is_a?(Array)
199
+ @dc_pins = [] << dc_pins
200
+ else
201
+ @dc_pins = dc_pins
202
+ end
203
+ end
204
+
205
+ def assign_digsrc_pins(digsrc_pins)
206
+ if !digsrc_pins.is_a?(Array)
207
+ @digsrc_pins = [] << digsrc_pins
208
+ else
209
+ @digsrc_pins = digsrc_pins
210
+ end
211
+ end
212
+
213
+ def assign_digcap_pins(digcap_pins)
214
+ if !digcap_pins.is_a?(Array)
215
+ @digcap_pins = [] << digcap_pins
216
+ else
217
+ @digcap_pins = digcap_pins
218
+ end
219
+ end
220
+
221
+ def get_dc_instr_pins
222
+ @dc_pins
223
+ end
224
+
225
+ def get_digsrc_pins
226
+ @digsrc_pins
227
+ end
228
+
229
+ def get_digcap_pins
230
+ @digcap_pins
231
+ end
232
+
233
+ def flows
234
+ parser.flows
235
+ end
236
+
237
+ # Main accessor to all content parsed from existing test program sheets found in the
238
+ # supplied directory or in Origen.config.test_program_output_directory
239
+ def parser(prog_dir = Origen.config.test_program_output_directory)
240
+ unless prog_dir
241
+ fail 'You must supply the directory containing the test program sheets, or define it via Origen.config.test_program_output_directory'
242
+ end
243
+ @parser ||= IGXLBasedTester::Parser.new
244
+ @parsed_dir ||= false
245
+ if @parsed_dir != prog_dir
246
+ @parser.parse(prog_dir)
247
+ @parsed_dir = prog_dir
248
+ end
249
+ @parser
250
+ end
251
+
252
+ # Capture a vector to the tester HRAM.
253
+ #
254
+ # This method applies a store vector (stv) opcode to the previous vector, note that is does
255
+ # not actually generate a new vector.
256
+ #
257
+ # Sometimes when generating vectors within a loop you may want to apply a stv opcode
258
+ # retrospectively to a previous vector, passing in an offset option will allow you
259
+ # to do this.
260
+ #
261
+ # On J750 the pins argument is ignored since the tester only supports whole vector capture.
262
+ #
263
+ # @example
264
+ # $tester.cycle # This is the vector you want to capture
265
+ # $tester.store # This applies the STV opcode
266
+ #
267
+ # $tester.cycle # This one gets stored
268
+ # $tester.cycle
269
+ # $tester.cycle
270
+ # $tester.store(:offset => -2) # Just realized I need to capture that earlier vector
271
+ def store(*pins)
272
+ options = pins.last.is_a?(Hash) ? pins.pop : {}
273
+ options = { offset: 0
274
+ }.merge(options)
275
+ update_vector microcode: 'stv', offset: options[:offset]
276
+ last_vector(options[:offset]).contains_capture = true
277
+ end
278
+ alias_method :to_hram, :store
279
+ alias_method :capture, :store
280
+
281
+ # Capture the next vector generated to HRAM
282
+ #
283
+ # This method applies a store vector (stv) opcode to the next vector to be generated,
284
+ # note that is does not actually generate a new vector.
285
+ #
286
+ # On J750 the pins argument is ignored since the tester only supports whole vector capture.
287
+ #
288
+ # @example
289
+ # $tester.store_next_cycle
290
+ # $tester.cycle # This is the vector that will be captured
291
+ def store_next_cycle(*pins)
292
+ options = pins.last.is_a?(Hash) ? pins.pop : {}
293
+ options = {
294
+ }.merge(options)
295
+
296
+ preset_next_vector microcode: 'stv' do |vector|
297
+ vector.contains_capture = true
298
+ end
299
+ end
300
+ alias_method :store!, :store_next_cycle
301
+
302
+ # @api private
303
+ def remove_store_from_vector(vector)
304
+ super
305
+ vector.microcode = nil
306
+ end
307
+
308
+ # Call a subroutine.
309
+ #
310
+ # This method applies a call subroutine opcode to the previous vector, it does not
311
+ # generate a new vector.
312
+ #
313
+ # Subroutines should always be called through this method as it ensures a running
314
+ # log of called subroutines is maintained and which then gets output in the pattern
315
+ # header to import the right dependencies.
316
+ #
317
+ # An offset option is available to make the call on earlier vectors.
318
+ #
319
+ # ==== Examples
320
+ # $tester.call_subroutine("mysub")
321
+ # $tester.call_subroutine("my_other_sub", :offset => -1)
322
+ def call_subroutine(name, options = {})
323
+ options = {
324
+ offset: 0
325
+ }.merge(options)
326
+ called_subroutines << name.to_s.chomp unless called_subroutines.include?(name.to_s.chomp) || @inhibit_vectors
327
+ update_vector microcode: "call #{name}", offset: options[:offset]
328
+ end
329
+
330
+ # Start a subroutine.
331
+ #
332
+ # Generates a global subroutine label. Global is used to adhere to the best practice of
333
+ # containing all subroutines in dedicated patterns, e.g. global_subs.atp
334
+ #
335
+ # ==== Examples
336
+ # $tester.start_subroutine("wait_for_done")
337
+ # < generate your subroutine vectors here >
338
+ # $tester.end_subroutine
339
+ def start_subroutine(name, options = {})
340
+ local_subroutines << name.to_s.chomp unless local_subroutines.include?(name.to_s.chomp) || @inhibit_vectors
341
+ if $tester.ultraflex? && (name =~ /keep_?alive/ || options[:keep_alive])
342
+ microcode "keepalive subr #{name}:"
343
+ else
344
+ microcode "global subr #{name}:"
345
+ end
346
+ end
347
+
348
+ # End a subroutine.
349
+ #
350
+ # Generates a return opcode on the last vector.
351
+ #
352
+ # ==== Examples
353
+ # $tester.start_subroutine("wait_for_done")
354
+ # < generate your subroutine vectors here >
355
+ # $tester.end_subroutine
356
+ # cond: whether return is conditional on a flag (to permit to mix subrs together)
357
+ def end_subroutine(cond = false, options = {})
358
+ (cond, options) = false, cond if cond.is_a?(Hash)
359
+ if cond
360
+ update_vector microcode: 'if (flag) return'
361
+ else
362
+ update_vector microcode: 'return'
363
+ end
364
+ end
365
+
366
+ # Do a frequency measure.
367
+ #
368
+ # Write the necessary micro code to do a frequency measure on the given pin,
369
+ # optionally supply a read code to pass information to the tester.
370
+ #
371
+ # ==== Examples
372
+ # $tester.freq_count($top.pin(:d_out)) # Freq measure on pin "d_out"
373
+ # $tester.freq_count($top.pin(:d_out):readcode => 10)
374
+ def freq_count(pin, options = {})
375
+ options = { readcode: false
376
+ }.merge(options)
377
+
378
+ set_code(options[:readcode]) if options[:readcode]
379
+ cycle(microcode: "#{@microcode[:set_flag]} (cpuA)")
380
+ cycle(microcode: "#{@microcode[:set_flag]} (cpuA)")
381
+ cycle(microcode: "#{@microcode[:set_flag]} (cpuB)")
382
+ cycle(microcode: "#{@microcode[:set_flag]} (cpuC)")
383
+ cycle(microcode: 'freq_loop_1:')
384
+ cycle(microcode: 'if (cpuA) jump freq_loop_1')
385
+ pin.drive_lo
386
+ delay(2000)
387
+ pin.dont_care
388
+ cycle(microcode: "freq_loop_2: #{@microcode[:enable]} (#{@flags[1]})")
389
+ cycle(microcode: 'if (flag) jump freq_loop_2')
390
+ cycle(microcode: "#{@microcode[:enable]} (#{@flags[2]})")
391
+ cycle(microcode: 'if (flag) jump freq_loop_1')
392
+ end
393
+
394
+ # * J750 Specific *
395
+ #
396
+ # Generates a single MTO opcode line for J750
397
+ #
398
+ # Codes implemented: xa load_preset, xa inc, ya load_preset, ya inc, stv_m0, stv_m1, stv_c<br>
399
+ def memory_test(options = {})
400
+ options = {
401
+ gen_vector: true, # Default generate vector not just MTO opcode
402
+ init_counter_x: false, # initialize counter X
403
+ inc_counter_x: false, # increment counter X
404
+ init_counter_y: false, # initialize counter X
405
+ inc_counter_y: false, # increment counter X
406
+ capture_vector: false, # capture vector to memory using all mem types
407
+ capture_vector_mem0: false, # capture vector to memory type 0, here for J750 will be stv_m0
408
+ capture_vector_mem1: false, # capture vector to memory type 1, here for J750 will be stv_m1
409
+ capture_vector_mem2: false, # capture vector to memory type 2, here for J750 will be stv_c
410
+ pin: false, # pin on which to drive or expect data, pass pin object here!
411
+ pin_data: false, # pin data (:none, :drive, :expect)
412
+ }.merge(options)
413
+
414
+ mto_opcode = ''
415
+
416
+ if options[:init_counter_x]
417
+ mto_opcode += ' xa load_preset'
418
+ end
419
+ if options[:inc_counter_x]
420
+ mto_opcode += ' xa inc'
421
+ end
422
+ if options[:init_counter_y]
423
+ mto_opcode += ' ya load_preset'
424
+ end
425
+ if options[:inc_counter_y]
426
+ mto_opcode += ' ya inc'
427
+ end
428
+ if options[:capture_vector]
429
+ mto_opcode += ' stv_m0 stv_m1 stv_c'
430
+ end
431
+ if options[:capture_vector_mem0]
432
+ mto_opcode += ' stv_m0'
433
+ end
434
+ if options[:capture_vector_mem1]
435
+ mto_opcode += ' stv_m1'
436
+ end
437
+ if options[:capture_vector_mem2]
438
+ mto_opcode += ' stv_c'
439
+ end
440
+
441
+ unless mto_opcode.eql?('')
442
+ mto_opcode = '(mto:' + mto_opcode + ')'
443
+ end
444
+
445
+ if options[:gen_vector]
446
+ if options[:pin]
447
+ case options[:pin_data]
448
+ when :drive
449
+ # store current pin state
450
+ cur_pin_state = options[:pin].state.to_sym
451
+ options[:pin].drive_mem
452
+ when :expect
453
+ # store current pin state
454
+ cur_pin_state = options[:pin].state.to_sym
455
+ options[:pin].expect_mem
456
+ end
457
+ end
458
+ cycle(microcode: "#{mto_opcode}")
459
+ if options[:pin]
460
+ # restore previous pin state
461
+ case options[:pin_data]
462
+ when :drive
463
+ options[:pin].state = cur_pin_state
464
+ when :expect
465
+ options[:pin].state = cur_pin_state
466
+ end
467
+ end
468
+ else
469
+ microcode "#{mto_opcode}"
470
+ end
471
+ end
472
+
473
+ # Generates a match loop on up to two pins.
474
+ #
475
+ # This method is not really intended to be called directly, rather you should call
476
+ # via Tester#wait e.g. $tester.wait(:match => true).
477
+ #
478
+ # The timeout should be provided in cycles, however when called via the wait method the
479
+ # time-based helpers (time_in_us, etc) will be converted to cycles for you.
480
+ # The following options are available to tailor the match loop behavior, defaults in
481
+ # parenthesis:
482
+ # * :pin - The pin object to match on (*required*)
483
+ # * :state - The pin state to match on, :low or :high (*required*)
484
+ # * :pin2 (nil) - Optionally supply a second pin to match on
485
+ # * :state2 (nil) - State for the second pin (required if :pin2 is supplied)
486
+ # * :check_for_fails (false) - Flushes the pipeline and handshakes with the tester (passing readcode 100) prior to the match (to allow binout of fails encountered before the match)
487
+ # * :force_fail_on_timeout (true) - Force a vector mis-compare if the match loop times out
488
+ # * :on_timeout_goto ("") - Optionally supply a label to branch to on timeout, by default will continue from the end of the match loop
489
+ # * :on_pin_match_goto ("") - Optionally supply a label to branch to when pin 1 matches, by default will continue from the end of the match loop
490
+ # * :on_pin2_match_goto ("") - Optionally supply a label to branch to when pin 2 matches, by default will continue from the end of the match loop
491
+ # * :multiple_entries (false) - Supply an integer to generate multiple entries into the match (each with a unique readcode), this can be useful when debugging patterns with multiple matches
492
+ # * :force_fail_on_timeout (true) - force pattern to fail if timeout occurs
493
+ # * :global_loops (false) - whether match loop loops should use global labels
494
+ # * :manual_stop (false) - whether to use extra cpuB flag to resolve IG-XL v.3.50.xx bug where VBT clears cpuA immediately
495
+ # at start of PatFlagFunc instead of at end. Use will have to manually clear cpuB to resume this pattern.
496
+ # ==== Examples
497
+ # $tester.wait(:match => true, :time_in_us => 5000, :pin => $top.pin(:done), :state => :high)
498
+ def match(pin, state, timeout, options = {})
499
+ options = {
500
+ check_for_fails: false,
501
+ on_timeout_goto: false,
502
+ pin2: false,
503
+ state2: false,
504
+ on_pin_match_goto: false,
505
+ multiple_entries: false,
506
+ force_fail_on_timeout: true,
507
+ global_loops: false,
508
+ manual_stop: false,
509
+ clr_fail_post_match: false
510
+ }.merge(options)
511
+ options[:on_block_match_goto] ||= options.delete(:on_pin_match_goto)
512
+
513
+ match_block(timeout, options) do |match_conditions, fail_conditions|
514
+ # Define match conditions
515
+ match_conditions.add do
516
+ state == :low ? pin.expect_lo : pin.expect_hi
517
+ cc "Check if #{pin.name} is #{state == :low ? 'low' : 'high'}"
518
+ cycle
519
+ pin.dont_care
520
+ end
521
+
522
+ if options[:pin2]
523
+ match_conditions.add do
524
+ state == :low ? pin.expect_hi : pin.expect_lo
525
+ options[:state2] == :low ? options[:pin2].expect_lo : options[:pin2].expect_hi
526
+ cc "Check if #{options[:pin2].name} is #{options[:state2] == :low ? 'low' : 'high'}"
527
+ cycle
528
+ options[:pin2].dont_care
529
+ pin.dont_care
530
+ end
531
+ end
532
+
533
+ # Define fail conditions
534
+ fail_conditions.add do
535
+ state == :low ? pin.expect_lo : pin.expect_hi
536
+ cc "Check if #{pin.name} is #{state == :low ? 'low' : 'high'}"
537
+ if options[:pin2]
538
+ options[:state2] == :low ? options[:pin2].expect_lo : options[:pin2].expect_hi
539
+ cc "Check if #{options[:pin2].name} is #{options[:state2] == :low ? 'low' : 'high'}"
540
+ end
541
+ cycle
542
+ pin.dont_care
543
+ options[:pin2].dont_care if options[:pin2]
544
+ end
545
+ end
546
+ end
547
+
548
+ # Call a match loop.
549
+ #
550
+ # Normally you would put your match loop in a global subs pattern, then you can
551
+ # call it via this method. This method automatically syncs match loop naming with
552
+ # the match generation flow, no arguments required.
553
+ #
554
+ # This is an IGXLBasedTester specific API.
555
+ #
556
+ # ==== Examples
557
+ # $tester.cycle
558
+ # $tester.call_match # Calls the match loop, or the first entry point if you have multiple
559
+ # $tester.cycle
560
+ # $tester.call_match # Calls the match loop, or the second entry point if you have multiple
561
+ def call_match
562
+ @match_counter = @match_counter || 0
563
+ call_subroutine("match_done_#{@match_counter}")
564
+ @match_counter += 1 unless @match_counter == (@match_entries || 1) - 1
565
+ end
566
+
567
+ # Apply a label to the pattern.
568
+ #
569
+ # No additional vector is generated.
570
+ # Arguments:
571
+ # name : label name
572
+ # global : (optional) whether to apply global label, default=false
573
+ #
574
+ # ==== Examples
575
+ # $tester.label("something_significant")
576
+ # $tester.label("something_significant",true) # apply global label
577
+ def label(name, global = false)
578
+ global_opt = (global) ? 'global ' : ''
579
+ microcode global_opt + name + ':'
580
+ end
581
+
582
+ # * J750 Specific *
583
+ #
584
+ # Set a readcode.
585
+ #
586
+ # Use the set an explicit readcode for communicating with the tester. This method
587
+ # will generate an additional vector.
588
+ #
589
+ # ==== Examples
590
+ # $tester.set_code(55)
591
+ def set_code(code)
592
+ cycle(microcode: "set_code #{code}")
593
+ end
594
+
595
+ # Branch execution to the given point.
596
+ #
597
+ # This generates a new vector with a jump instruction to a given label. This method
598
+ # will generate an additional vector.
599
+ #
600
+ # ==== Examples
601
+ # $tester.branch_to("something_significant")
602
+ def branch_to(label)
603
+ cycle(microcode: "jump #{label}")
604
+ end
605
+ alias_method :branch, :branch_to
606
+
607
+ # Add loop to the pattern.
608
+ #
609
+ # Pass in a name for the loop and the number of times to execute it, all vectors
610
+ # generated by the given block will be captured in the loop.
611
+ #
612
+ # Optional arguments: global - whether to apply global label (default=false)
613
+ # label_first - whether to apply loop label before loop vector or not
614
+ #
615
+ # ==== Examples
616
+ # $tester.loop_vectors("pulse_loop", 3) do # Do this 3 times...
617
+ # $tester.cycle
618
+ # some_other_method_to_generate_vectors
619
+ # end
620
+ def loop_vectors(name, number_of_loops, global = false, label_first = false)
621
+ if number_of_loops > 1
622
+ @loop_counters ||= {}
623
+ if @loop_counters[name]
624
+ @loop_counters[name] += 1
625
+ else
626
+ @loop_counters[name] = 0
627
+ end
628
+ loop_name = @loop_counters[name] == 0 ? name : "#{name}_#{@loop_counters[name]}"
629
+ if label_first
630
+ global_opt = (global) ? 'global ' : ''
631
+ microcode "#{global_opt}#{loop_name}: "
632
+ end
633
+ cycle(microcode: "loopA #{number_of_loops}")
634
+ unless label_first
635
+ global_opt = (global) ? 'global ' : ''
636
+ cycle(microcode: "#{global_opt}#{loop_name}: ")
637
+ end
638
+ yield
639
+ cycle(microcode: "end_loopA #{loop_name}")
640
+ else
641
+ yield
642
+ end
643
+ end
644
+ alias_method :loop_vector, :loop_vectors
645
+
646
+ # An internal method called by Origen Pattern Create to create the pattern header
647
+ def pattern_header(options = {})
648
+ options = {
649
+ instruments: {}, # Provide instruments here if desired as a hash (e.g. "mto" => "dgen_2bit")
650
+ subroutine_pat: false,
651
+ svm_only: true, # Whether 'svm_only' can be specified
652
+ group: false, # If true the end pattern is intended to run within a pattern group
653
+ high_voltage: false, # Supply a pin name here to declare it as an HV instrument (not yet defined)
654
+ freq_counter: false, # Supply a pin name here to declare it as a frequency counter
655
+ memory_test: false, # If true, define 2-bit MTO DGEN as instrument
656
+ }.merge(options)
657
+
658
+ if level_period?
659
+ microcode "import tset #{min_period_timeset.name};"
660
+ else
661
+ called_timesets.each do |timeset|
662
+ microcode "import tset #{timeset.name};"
663
+ end
664
+ end
665
+ unless options[:group] # Withhold imports for pattern groups, is this correct?
666
+ called_subroutines.each do |sub_name|
667
+ # Don't import any called subroutines that are declared in the current pattern
668
+ microcode "import svm_subr #{sub_name};" unless local_subroutines.include?(sub_name)
669
+ end
670
+ end
671
+
672
+ # If memory test, then add to instruments hash
673
+ if options[:memory_test]
674
+ options[:instruments].merge!('mto' => 'dgen_2bit')
675
+ end
676
+
677
+ if options[:svm_only]
678
+ microcode "svm_only_file = #{options[:subroutine_pat] ? 'yes' : 'no'};"
679
+ end
680
+
681
+ microcode "opcode_mode = #{@opcode_mode};"
682
+ microcode "digital_inst = #{options[:digital_inst]};" if options[:digital_inst]
683
+ microcode 'compressed = yes;' # if $dut.gzip_patterns
684
+ if tester.j750? && options[:freq_counter]
685
+ # pin setup type => freq_counter is only for the J750.
686
+ # UltraFLEX has frequency counter capability behind every pin.
687
+ # need to make sure the pin_setup freq_count is defined after opcode_mode extended since freq count only work in extended mode
688
+ if @opcode_mode == :extended
689
+ microcode "pin_setup = {#{options[:freq_counter]} freq_count;}"
690
+ else
691
+ fail 'pin_setup freq_count can only work in extended mode'
692
+ end
693
+ end
694
+
695
+ # Take care of any instruments
696
+ options[:instruments] = options[:instruments].merge(@pushed_instrument_configs)
697
+ if options[:instruments].length > 0
698
+ microcode 'instruments = {'
699
+ options[:instruments].each do |pins, instrument|
700
+ if "#{pins}" == 'nil'
701
+ microcode " #{instrument};"
702
+ elsif instrument == 'digsrc'
703
+ microcode " #{pins}:#{instrument} #{options[:digsrc_width]}:#{options[:digsrc_bit_order]}:#{options[:digsrc_mode]}:format=#{options[:digsrc_format]}:#{options[:digsrc_site_uniqueness]}:#{options[:digsrc_auto_cond]};"
704
+ elsif instrument == 'digcap'
705
+ microcode " #{pins}:#{instrument} #{options[:digcap_width]}:#{options[:digcap_bit_order]}:#{options[:digcap_mode]}:format=#{options[:digcap_format]}:data_type=#{options[:digcap_data_type]}:#{options[:digcap_auto_cond]}:#{options[:digcap_auto_trig_enable]}:#{options[:digcap_store_stv]}:#{options[:digcap_receive_data]};"
706
+ else
707
+ microcode " #{pins}:#{instrument};"
708
+ end
709
+ end
710
+ microcode '}'
711
+ end
712
+
713
+ options[:high_voltage] = @use_hv_pin
714
+ microcode "pin_setup = {#{options[:high_voltage]} high_voltage;}" if options[:high_voltage]
715
+ microcode ''
716
+
717
+ pin_list = ordered_pins.map(&:name).join(', ')
718
+
719
+ # here indicate pattern header specific stuff
720
+ yield pin_list
721
+ if ordered_pins.size > 0
722
+ max_pin_name_length = ordered_pins.map(&:name).max { |a, b| a.length <=> b.length }.length
723
+ pin_widths = ordered_pins.map { |p| p.size - 1 }
724
+
725
+ max_pin_name_length.times do |i|
726
+ cc((' ' * 93) + ordered_pins.map.with_index { |p, x| ((p.name[i] || ' ') + ' ' * pin_widths[x]).gsub('_', '-') }.join(' '))
727
+ end
728
+ end
729
+ end
730
+
731
+ # An internal method called by Origen to generate the pattern footer
732
+ def pattern_footer(options = {})
733
+ options = {
734
+ subroutine_pat: false,
735
+ end_in_ka: false,
736
+ end_with_halt: false,
737
+ end_module: true
738
+ }.merge(options)
739
+ $tester.align_to_last
740
+ # cycle(:microcode => "#{$dut.end_of_pattern_label}:") if $dut.end_of_pattern_label
741
+ if options[:end_in_ka]
742
+ keep_alive(options)
743
+ else
744
+ if options[:end_with_halt]
745
+ $tester.cycle microcode: 'halt'
746
+ else
747
+ if options[:end_module]
748
+ $tester.cycle microcode: 'end_module' unless options[:subroutine_pat]
749
+ else
750
+ $tester.cycle
751
+ end
752
+ end
753
+ end
754
+ microcode '}'
755
+ end
756
+
757
+ # Returns an array of subroutines called while generating the current pattern
758
+ def called_subroutines
759
+ @called_subroutines ||= []
760
+ end
761
+
762
+ # Returns an array of subroutines created by the current pattern
763
+ def local_subroutines # :nodoc:
764
+ @local_subroutines ||= []
765
+ end
766
+
767
+ # This is an internal method use by Origen which returns a fully formatted vector
768
+ # You can override this if you wish to change the output formatting at vector level
769
+ def format_vector(vec)
770
+ timeset = vec.timeset ? "> #{vec.timeset.name}" : ''
771
+ pin_vals = vec.pin_vals ? "#{vec.pin_vals} ;" : ''
772
+ if vec.repeat > 1
773
+ microcode = "repeat #{vec.repeat}"
774
+ else
775
+ microcode = vec.microcode ? vec.microcode : ''
776
+ end
777
+ if vec.pin_vals && ($_testers_enable_vector_comments || vector_comments)
778
+ comment = " // #{vec.number}:#{vec.cycle} #{vec.inline_comment}"
779
+ else
780
+ comment = vec.inline_comment.empty? ? '' : " // #{vec.inline_comment}"
781
+ end
782
+
783
+ "#{microcode.ljust(65)}#{timeset.ljust(31)}#{pin_vals}#{comment}"
784
+ end
785
+
786
+ # Override this to force the formatting to match the v1 J750 model (easier diffs)
787
+ def push_microcode(code) # :nodoc:
788
+ stage.store(code.ljust(65) + ''.ljust(31))
789
+ end
790
+ alias_method :microcode, :push_microcode
791
+
792
+ # All vectors generated with the supplied block will have all pins set
793
+ # to the repeat previous state. Any pins that are changed state within
794
+ # the block will still update to the supplied value.
795
+ # ==== Example
796
+ # # All pins except invoke will be assigned the repeat previous code
797
+ # # in the generated vector. On completion of the block they will
798
+ # # return to their previous state, except for invoke which will
799
+ # # retain the value assigned within the block.
800
+ # $tester.repeat_previous do
801
+ # $top.pin(:invoke).drive(1)
802
+ # $tester.cycle
803
+ # end
804
+ def repeat_previous
805
+ pinmap = Origen.pin_bank.pins
806
+ pinmap.each { |id, pin| pin.repeat_previous = true }
807
+ yield
808
+ pinmap.each { |id, pin| pin.repeat_previous = false }
809
+ end
810
+
811
+ def ignore_fails(*pins)
812
+ pins.each(&:suspend)
813
+ yield
814
+ pins.each(&:resume)
815
+ end
816
+
817
+ def enable_flag(options = {})
818
+ options = { flagnum: 4, # default flag to use
819
+ }.merge(options)
820
+
821
+ if options[:flagnum] > @flags.length
822
+ abort "ERROR! Invalid flag value passed to 'enable_flag' method!\n"
823
+ end
824
+ flagname = @flags[options[:flagnum] - 1]
825
+ update_vector(microcode: "#{@microcode[:enable]}(#{flagname})")
826
+ end
827
+
828
+ def set_flag(options = {})
829
+ options = { flagnum: 4, # default flag to use
830
+ }.merge(options)
831
+
832
+ if options[:flagnum] > @flags.length
833
+ abort "ERROR! Invalid flag value passed to 'set_flag' method!\n"
834
+ end
835
+ flagname = @flags[options[:flagnum] - 1]
836
+ update_vector(microcode: "#{@microcode[:set_flag]}(#{flagname})")
837
+ end
838
+
839
+ def cycle(options = {})
840
+ # handle overlay if requested
841
+ ovly_style = nil
842
+ if options.key?(:overlay)
843
+ ovly_style = options[:overlay][:overlay_style].nil? ? @overlay_style : options[:overlay][:overlay_style]
844
+ overlay_str = options[:overlay][:overlay_str]
845
+
846
+ # route the overlay request to the appropriate method
847
+ case ovly_style
848
+ when :subroutine, :default
849
+ subroutine_overlay(overlay_str, options)
850
+ ovly_style = :subroutine
851
+ when :label
852
+ options[:dont_compress] = true
853
+ unless @overlay_history.key?(overlay_str)
854
+ label "#{overlay_str}", true
855
+ @overlay_history[overlay_str] = { is_label: true }
856
+ end
857
+ when :digsrc
858
+ if ultraflex?
859
+ cur_pin_state = options[:overlay][:pins].state.to_sym
860
+ options[:overlay][:pins].drive_mem
861
+ options = digsrc_overlay(options)
862
+ else
863
+ ovly_style = overlay_style_warn(options[:overlay][:overlay_str], options)
864
+ end
865
+ else
866
+ ovly_style = overlay_style_warn(options[:overlay][:overlay_str], options)
867
+ end # case ovly_style
868
+ else
869
+ @overlay_subr = nil
870
+ end # of handle overlay
871
+
872
+ options_overlay = options.delete(:overlay) if options.key?(:overlay)
873
+ unless ovly_style == :subroutine
874
+ if @mask_vector
875
+ # tack on masking opcodes
876
+ super(options.merge(microcode: "#{options[:microcode]} #{@microcode[:mask_vector]}"))
877
+ else
878
+ super(options)
879
+ end
880
+ end # unless ovly_style
881
+
882
+ unless options_overlay.nil?
883
+ options_overlay[:pins].state = cur_pin_state if ovly_style == :digsrc
884
+ # stage = :body if ovly_style == :subroutine # always set stage back to body in case subr overlay was selected
885
+ end
886
+ end
887
+
888
+ # Warn user of unsupported overlay style
889
+ def overlay_style_warn(overlay_str, options)
890
+ Origen.log.warn("Unrecognized overlay style :#{@overlay_style}, defaulting to subroutine")
891
+ Origen.log.warn('Available overlay styles :label, :subroutine') if j750? || j750_hpt?
892
+ Origen.log.warn('Available overlay styles :digsrc, :digsrc_subroutine, :label, :subroutine') if ultraflex?
893
+ subroutine_overlay(overlay_str, options)
894
+ @overlay_style = :subroutine # Just give 1 warning
895
+ end
896
+
897
+ # Call this method at the start of any digsrc overlay operations, this method
898
+ # takes care of all the microcodes and delays that's needed for digsrc overlay
899
+ # Required arguments:
900
+ # pins
901
+ # Optionsal arguments:
902
+ # options[:dssc_mode] = :single or :dual, anything else wil be
903
+ # treated as if it's operating in :quad mode
904
+ def digsrc_start(pins, options = {})
905
+ options = {
906
+ dssc_mode: :single # defaults dssc_mode to single mode
907
+ }.merge(options)
908
+ if pins.size > 1
909
+ microcode "((#{format_multiple_instrument_pins(pins)}):DigSrc = Start)"
910
+ else
911
+ microcode "((#{pin}):DigSrc = Start)"
912
+ end
913
+ if options[:dssc_mode] == :single
914
+ $tester.cycle(repeat: 145) # minimum of 144 cycles, adding 1 for safey measures
915
+ elsif options[:dssc_mode] == :dual
916
+ $tester.cycle(repeat: 289) # minimum of 288 cycles, adding 1 for safety measures
917
+ else
918
+ $tester.cycle(repeat: 577) # minimum of 577 cycles, adding 1 for safety measures
919
+ end
920
+ end
921
+
922
+ # Call this method at the end of each digscr overlay operation to clear the pattern
923
+ # memory pipeline, so that the pattern is ready to do the next digsrc overlay operation.
924
+ # Required arguments:
925
+ # pins
926
+ def digsrc_stop(pins, options = {})
927
+ if pins.size > 1
928
+ microcode "((#{format_multiple_instrument_pins(pins)}):DigSrc = Stop)"
929
+ else
930
+ microcode "((#{pins}):DigSrc = Stop)"
931
+ end
932
+ end
933
+
934
+ # Call this method before each tester cycle to insert the digsrc overlay microcode
935
+ def digsrc_send(pins)
936
+ microcode "((#{format_multiple_instrument_pins(pins)}):DigSrc = SEND)"
937
+ end
938
+
939
+ # Call this method before each tester cycle to inser the digcap overlay microcode
940
+ def digcap_store(pins)
941
+ microcode "((#{format_multiple_instrument_pins(pins)}):DigCap = STORE)"
942
+ end
943
+
944
+ def apply_digsrc_settings(options = {})
945
+ options.merge!(digsrc_width: 1) if options[:digsrc_width].nil? # default to digsrc 1
946
+ options.merge!(digsrc_bit_order: :lsb) if options[:digsrc_bit_order].nil? # default to lsb
947
+ options.merge!(digsrc_mode: :serial) if options[:digsrc_mode].nil? # default to serial mode
948
+ options.merge!(digsrc_format: :binary) if options[:digsrc_format].nil? # default to binary
949
+ options.merge!(digsrc_site_uniqueness: :unique_sites) if options[:digsrc_site_uniqueness].nil? # default to unique sites
950
+ options.merge!(digsrc_data_type: :default) if options[:digsrc_data_type].nil? # default to default
951
+ options.merge!(digsrc_auto_cond: :auto_cond_disable) if options[:digsrc_auto_cond].nil? # default to disable
952
+ @digsrc_settings = options
953
+ end
954
+
955
+ def apply_digcap_settings(options = {})
956
+ options.merge!(digcap_width: 8) if options[:digcap_width].nil? # default to digcap 8
957
+ options.merge!(digcap_bit_order: :lsb) if options[:digcap_bit_order].nil? # default to lsb
958
+ options.merge!(digcap_mode: :serial) if options[:digcap_mode].nil? # default to serial mode
959
+ options.merge!(digcap_site_uniqueness: :unique_sites) if options[:digcap_site_uniqueness].nil? # default to unique sites
960
+ options.merge!(digcap_format: :binary) if options[:digcap_format].nil? # default to binary
961
+ options.merge!(digcap_data_type: :default) if options[:digcap_data_type].nil? # default to default
962
+ options.merge!(digcap_auto_cond: :auto_cond_disable) if options[:digcap_auto_cond].nil? # default to disable
963
+ options.merge!(digcap_auto_trig_enable: :auto_trig_disable) if options[:digcap_auto_trig_enable].nil? # default to disable
964
+ options.merge!(digcap_store_stv: :store_stv_disable) if options[:digcap_store_stv].nil? # default to disable
965
+ options.merge!(digcap_receive_data: :store_stv_disable) if options[:digcap_receive_data].nil? # default to logic
966
+ @digcap_settings = options
967
+ end
968
+
969
+ # Call this method if there are more than one pin/pin groups used with an instrument,
970
+ # this method will format an array of pins into the correct format required by igxl
971
+ # pattern microcodes.
972
+ def format_multiple_instrument_pins(pins, options = {})
973
+ return_value = ''
974
+ pins.each do |pin|
975
+ return_value += "#{pin}"
976
+ return_value += ',' unless pins.last == pin
977
+ end
978
+ return_value
979
+ end
980
+
981
+ def mask_fails(setclr)
982
+ @mask_vector = setclr
983
+ end
984
+
985
+ # Similar to push_microcode, but for the instrument statement in the pattern header
986
+ #
987
+ # @example
988
+ # tester.push_instrument 'SAR_IN_1', 'UltraSource'
989
+ # # results in the below line added
990
+ # # instruments = {
991
+ # # SAR_IN_1:UltraSource;
992
+ # # }
993
+ def push_instrument(pin_spec, instrument_def)
994
+ @pushed_instrument_configs[pin_spec] = instrument_def
995
+ end
996
+
997
+ # Implement subroutine overlay, called by tester.cycle
998
+ def subroutine_overlay(sub_name, options = {})
999
+ if @overlay_subr != sub_name
1000
+ # unless last staged vector already has the subr call do the following
1001
+ i = -1
1002
+ i -= 1 until stage.bank[i].is_a?(OrigenTesters::Vector)
1003
+ if stage.bank[i].microcode !~ /call #{sub_name}/
1004
+
1005
+ # check for repeat on new last vector, unroll 1 if needed
1006
+ if stage.bank[i].repeat > 1
1007
+ v = OrigenTesters::Vector.new
1008
+ v.pin_vals = stage.bank[i].pin_vals
1009
+ v.timeset = stage.bank[i].timeset
1010
+ stage.bank[i].repeat -= 1
1011
+ stage.store(v)
1012
+ i = -1
1013
+ end
1014
+
1015
+ # mark last vector as dont_compress
1016
+ stage.bank[i].dont_compress = true
1017
+ # insert subroutine call
1018
+ call_subroutine sub_name
1019
+ end # if microcode not placed
1020
+ @overlay_subr = sub_name
1021
+ end
1022
+
1023
+ # stage = sub_name
1024
+ end # subroutine_overlay
1025
+
1026
+ # Perform digsrc overlay (called by tester.cycle)
1027
+ def digsrc_overlay(options = {})
1028
+ options[:overlay] = { change_data: true }.merge(options[:overlay])
1029
+ pin_name = dut.pin(options[:overlay][:pins]).name
1030
+ repeat_count = options[:repeat].nil? ? 1 : options[:repeat]
1031
+
1032
+ if options[:overlay][:change_data]
1033
+ # add the send microcode
1034
+ microcode "((#{pin_name}):DigSrc = SEND)"
1035
+
1036
+ # keep track of amount of digsrc used for header comment
1037
+ if @overlay_history[pin_name].nil?
1038
+ @overlay_history[pin_name] = { count: repeat_count, is_digsrc: true }
1039
+ else
1040
+ @overlay_history[pin_name][:count] += repeat_count
1041
+ end
1042
+
1043
+ # ensure no unwanted repeats on the send vector
1044
+ options[:dont_compress] = true
1045
+
1046
+ # ensure start microcode is placed at the beginning of the pattern
1047
+ if @overlay_history[pin_name][:start_applied].nil?
1048
+ # insert start microcode at the beginning of the pattern
1049
+ stage.insert_from_start "((#{pin_name}):DigSrc = Start)", 0
1050
+ @overlay_history[pin_name][:start_applied] = true
1051
+
1052
+ # get the first vector of the pattern
1053
+ i = 0
1054
+ i += 1 until stage.bank[i].is_a?(OrigenTesters::Vector)
1055
+ first_vector = stage.bank[i]
1056
+
1057
+ # insert a copy of the first vector with no repeats
1058
+ unless first_vector.inline_comment == 'added for digsrc start opcode'
1059
+ v = OrigenTesters::Vector.new
1060
+ v.pin_vals = stage.bank[i].pin_vals
1061
+ v.timeset = stage.bank[i].timeset
1062
+ v.inline_comment = 'added for digsrc start opcode'
1063
+ v.dont_compress = true
1064
+ stage.insert_from_start v, i
1065
+
1066
+ # decrement repeat count of previous first vector if > 1
1067
+ first_vector.repeat -= 1 if first_vector.repeat > 1
1068
+ end
1069
+
1070
+ # get cycle count up to this point, add repeat to beginning if needed
1071
+ cycle_count = -1
1072
+ stage.bank.each { |v| cycle_count += v.repeat if v.is_a?(OrigenTesters::Vector) }
1073
+ if cycle_count < @dssc_send_delay
1074
+ d = OrigenTesters::Vector.new
1075
+ d.pin_vals = first_vector.pin_vals
1076
+ d.timeset = first_vector.timeset
1077
+ d.inline_comment = 'added for dssc start to send delay'
1078
+ d.repeat = @dssc_send_delay - cycle_count
1079
+
1080
+ # get the first vector of the pattern
1081
+ i = 0
1082
+ i += 1 until stage.bank[i].is_a?(OrigenTesters::Vector)
1083
+
1084
+ # insert new vector after the first vector
1085
+ stage.insert_from_start d, i + 1
1086
+ end
1087
+
1088
+ end # of place start microcode
1089
+
1090
+ end # if options[:change_data]
1091
+ options
1092
+ end # digsrc overlay
1093
+ end
1094
+ end
1095
+ end