origen_testers 0.13.1 → 0.13.2

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