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,24 +1,24 @@
1
- module OrigenTesters
2
- class IGXLBasedTester
3
- class Parser
4
- class TestInstances < ::OrigenTesters::Parser::SearchableHash
5
- attr_accessor :parser
6
-
7
- def initialize(options = {})
8
- @parser = options[:parser]
9
- end
10
-
11
- def import(file)
12
- File.readlines(file).each do |line|
13
- l = TestInstance.new(line, parser: parser)
14
- self[l.name] = l if l.valid?
15
- end
16
- end
17
-
18
- def inspect
19
- "<TestInstances: #{size}>"
20
- end
21
- end
22
- end
23
- end
24
- end
1
+ module OrigenTesters
2
+ class IGXLBasedTester
3
+ class Parser
4
+ class TestInstances < ::OrigenTesters::Parser::SearchableHash
5
+ attr_accessor :parser
6
+
7
+ def initialize(options = {})
8
+ @parser = options[:parser]
9
+ end
10
+
11
+ def import(file)
12
+ File.readlines(file).each do |line|
13
+ l = TestInstance.new(line, parser: parser)
14
+ self[l.name] = l if l.valid?
15
+ end
16
+ end
17
+
18
+ def inspect
19
+ "<TestInstances: #{size}>"
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,13 +1,13 @@
1
- module OrigenTesters
2
- class IGXLBasedTester
3
- class Parser
4
- class Timeset
5
- attr_accessor :parser
6
-
7
- def initialize(options = {})
8
- @parser = options[:parser]
9
- end
10
- end
11
- end
12
- end
13
- end
1
+ module OrigenTesters
2
+ class IGXLBasedTester
3
+ class Parser
4
+ class Timeset
5
+ attr_accessor :parser
6
+
7
+ def initialize(options = {})
8
+ @parser = options[:parser]
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,798 +1,798 @@
1
- require 'origen_testers/igxl_based_tester/ultraflex/ate_hardware'
2
- module OrigenTesters
3
- module IGXLBasedTester
4
- class UltraFLEX < Base
5
- autoload :Generator, 'origen_testers/igxl_based_tester/ultraflex/generator.rb'
6
-
7
- # Tester model to generate .atp patterns for the Teradyne UltraFLEX
8
- #
9
- # == Basic Usage
10
- # $tester = Testers::UltraFLEX.new
11
- # $tester.cycle # Generate a vector
12
- #
13
- # Many more methods exist to generate UltraFLEX specific micro-code, see below for
14
- # details.
15
- #
16
- # Also note that this class inherits from the base IGXLBasedTester class and so all methods
17
- # described there are also available.
18
-
19
- # Returns a new UltraFLEX instance, normally there would only ever be one of these
20
- # assigned to the global variable such as $tester by your target.
21
- def initialize
22
- super
23
- @pipeline_depth = 255 # for single mode
24
- @software_version = '8.10.10'
25
- @name = 'ultraflex'
26
- @opcode_mode = :single # there is also :dual
27
- @counter_lsb_bits = 16 # individual counter bit length
28
- @counter_msb_bits = 12 # temporary register commonly used to extend all counters
29
-
30
- @flags = %w(cpuA_cond cpuB_cond cpuC_cond cpuD_cond)
31
- @microcode[:enable] = 'branch_expr ='
32
- @microcode[:set_flag] = 'set_cpu_cond'
33
- @microcode[:mask_vector] = 'mask'
34
-
35
- # Min required for a VM module-- not for SRM modules
36
- # this handled in pattern_header below
37
- @min_pattern_vectors = (@opcode_mode == :single) ? 64 : 128
38
-
39
- @digital_instrument = 'hsdm' # 'hsdm' for HSD1000 and UP800, ok with UP1600 though
40
-
41
- @capture_state = 'V' # STV requires valid 'V' expect data
42
-
43
- @set_msb_issued = false # Internal flag to keep track of set_msb usage, allowing for set_lsb to be used as a readcode
44
- @microcode[:keepalive] = 'keepalive'
45
-
46
- @onemodsubs_found = false # flag to indicate whether a single-module subroutine has been implemented in this pattern
47
- @nonmodsubs_found = false # flag to indicate whether a normal non-single-module subroutine has been implemented in this pattern
48
-
49
- @dssc_send_delay = 144
50
- @dssc_send_delay = 288 if @opcode_mode == :dual
51
- @dssc_send_delay = 576 if @opcode_mode == :quad
52
- end
53
-
54
- # Do a frequency measure.
55
- #
56
- # Write the necessary micro code to do a frequency measure on the given pin,
57
- # optionally supply a read code to pass information to the tester.
58
- #
59
- # ==== Examples
60
- # $tester.freq_count($top.pin(:d_out)) # Freq measure on pin "d_out"
61
- # $tester.freq_count($top.pin(:d_out):readcode => 10)
62
- def freq_count(pin, options = {})
63
- options = { readcode: false
64
- }.merge(options)
65
-
66
- set_code(options[:readcode]) if options[:readcode]
67
- cycle(microcode: "#{@microcode[:set_flag]} (#{@flags[0]})") # set cpuA
68
- cycle(microcode: "#{@microcode[:set_flag]} (#{@flags[0]})") # set cpuB
69
- cycle(microcode: "#{@microcode[:set_flag]} (#{@flags[1]})") # set cpuC
70
- cycle(microcode: "#{@microcode[:set_flag]} (#{@flags[2]})") # set cpuD
71
- cycle(microcode: "freq_loop_1: #{@microcode[:enable]} (#{@flags[0]})")
72
- cycle(microcode: 'if (branch_expr) jump freq_loop_1')
73
- pin.drive_lo
74
- delay(2000)
75
- pin.dont_care
76
- cycle(microcode: "freq_loop_2: #{@microcode[:enable]} (#{@flags[1]})")
77
- cycle(microcode: 'if (branch_expr) jump freq_loop_2')
78
- cycle(microcode: "#{@microcode[:enable]} (#{@flags[2]})")
79
- cycle(microcode: 'if (branch_expr) jump freq_loop_1')
80
- end
81
-
82
- def memory_test(options = {})
83
- options = {
84
- gen_vector: true, # Default generate vector not just MTO opcode
85
- init_counter_x: false, # initialize counter X
86
- inc_counter_x: false, # increment counter X
87
- init_counter_y: false, # initialize counter X
88
- inc_counter_y: false, # increment counter X
89
- capture_vector: false, # capture vector to memory using all mem types
90
- capture_vector_mem0: false, # capture vector to memory type 0, here for J750 will be stv_m0
91
- capture_vector_mem1: false, # capture vector to memory type 1, here for J750 will be stv_m1
92
- capture_vector_mem2: false, # capture vector to memory type 2, here for J750 will be stv_c
93
- pin: false, # pin on which to drive or expect data, pass pin object here!
94
- pin_data: false, # pin data (:none, :drive, :expect)
95
- use_dgen_group: false,
96
- set_msb: false
97
- }.merge(options)
98
-
99
- mto_opcode = ''
100
-
101
- if options[:init_counter_x]
102
- mto_opcode += ' xenable_load jam_reg xa jam_reg'
103
- end
104
-
105
- if options[:init_counter_y]
106
- mto_opcode += ' yenable_load jam_reg ya jam_reg'
107
- end
108
-
109
- if options[:inc_counter_x]
110
- mto_opcode += ' xa inc'
111
- end
112
-
113
- if options[:inc_counter_y]
114
- mto_opcode += ' ya inc'
115
- end
116
-
117
- if options[:use_dgen_group]
118
- mto_opcode += ' dgroup 0'
119
- end
120
-
121
- if options[:set_msb]
122
- microcode 'set_msb 1'
123
- end
124
-
125
- unless mto_opcode.eql?('')
126
- mto_opcode = '(mto =' + mto_opcode + ')'
127
- end
128
-
129
- if options[:pin_data] == :expect
130
- mto_opcode = 'stv'
131
- end
132
-
133
- if options[:gen_vector]
134
- if options[:pin]
135
- case options[:pin_data]
136
- when :drive
137
- # store current pin state
138
- cur_pin_state = options[:pin].state.to_sym
139
- options[:pin].drive_mem
140
- when :expect
141
- # store current pin state
142
- cur_pin_state = options[:pin].state.to_sym
143
- options[:pin].expect_mem
144
- end
145
- end
146
- cycle(microcode: "#{mto_opcode}", dont_compress: false)
147
- if options[:pin]
148
- # restore previous pin state
149
- case options[:pin_data]
150
- when :drive
151
- options[:pin].state = cur_pin_state
152
- when :expect
153
- options[:pin].state = cur_pin_state
154
- end
155
- end
156
- else
157
- microcode "#{mto_opcode}"
158
- end
159
- end
160
-
161
- def call_match
162
- # fail 'Method call_match not yet supported for UltraFLEX!'
163
- @match_counter = @match_counter || 0
164
- call_subroutine("match_done_#{@match_counter}")
165
- @match_counter += 1 unless @match_counter == (@match_entries || 1) - 1
166
- end
167
-
168
- # Ultraflex implementation of J750-style 'set_code'
169
- #
170
- # Set a readcode, using one of the Ultraflex general-purpose counters.
171
- # Counter C15 is used by default, this can be changed by the caller if necessary.
172
- #
173
- # Use to set an explicit readcode for communicating with the tester. This method
174
- # will generate an additional vector (or 2, depending if set_msb is needed).
175
- #
176
- # NOTE: Some caveats when using this method:
177
- # - When setting a counter from the pattern microcode, the actual Patgen counter value is set to n-1.
178
- # This method adjusts by using a value of n+1, so the value read by the tester is the original intended value.
179
- #
180
- # - When setting a counter from pattern microcode, the upper bits must be loaded separately using 'set_msb'.
181
- # This method calls the set_msb opcode if needed - note the tester must mask the upper 16 bits to get the desired value.
182
- # The set_msb opcode will also generate a second vector the first time the set_code method is called.
183
- #
184
- # ==== Examples
185
- # $tester.set_code(55)
186
- #
187
- def set_code(*code)
188
- options = code.last.is_a?(Hash) ? code.pop : {}
189
- options = { counter: 'c15'
190
- }.merge(options)
191
- cc " Using counter #{options[:counter]} as set_code replacement - value set to #{code[0]} + 1"
192
- unless @set_msb_issued
193
- set_msb(1)
194
- cycle # set_msb doesn't issue a cycle
195
- end
196
- cycle(microcode: "set #{options[:counter]} #{code[0].next}") #+1 here to align with VBT
197
- end
198
-
199
- def set_code_no_msb(*code)
200
- options = code.last.is_a?(Hash) ? code.pop : {}
201
- options = { counter: 'c15'
202
- }.merge(options)
203
- unless @set_msb_issued
204
- cycle # set_msb doesn't issue a cycle
205
- end
206
- cycle(microcode: "set #{options[:counter]} #{code[0].next}") #+1 here to align with VBT
207
- end
208
-
209
- def loop_vectors(name, number_of_loops, global = false, label_first = false)
210
- if number_of_loops > 1
211
- @loop_counters ||= {}
212
- if @loop_counters[name]
213
- @loop_counters[name] += 1
214
- else
215
- @loop_counters[name] = 0
216
- end
217
- loop_name = @loop_counters[name] == 0 ? name : "#{name}_#{@loop_counters[name]}"
218
- if label_first
219
- global_opt = (global) ? 'global ' : ''
220
- microcode "#{global_opt}#{loop_name}: "
221
- end
222
-
223
- if "#{loop_name}" == 'row_loop'
224
- cycle(microcode: 'loop c0')
225
- elsif "#{loop_name}" == 'quad_loop'
226
- cycle(microcode: 'loop c1')
227
- elsif "#{loop_name}" == 'page_loop_red'
228
- cycle(microcode: 'loop c2')
229
- elsif "#{loop_name}" == 'page_loop_ecc'
230
- cycle(microcode: 'loop c3')
231
- elsif "#{loop_name}" == 'page_loop_data'
232
- cycle(microcode: 'loop c4')
233
- end
234
-
235
- unless label_first
236
- global_opt = (global) ? 'global ' : ''
237
- cycle(microcode: "#{global_opt}#{loop_name}: ")
238
- end
239
- yield
240
- cycle(microcode: "end_loop #{loop_name}")
241
- else
242
- yield
243
- end
244
- end
245
-
246
- alias_method :loop_vector, :loop_vectors
247
-
248
- def pattern_header(options = {})
249
- options = {
250
- instruments: {}
251
- }.merge(options)
252
-
253
- case $tester.vector_group_size
254
- when 1
255
- @opcode_mode = :single
256
- when 2
257
- @opcode_mode = :dual
258
- when 4
259
- @opcode_mode = :quad
260
- end
261
-
262
- options[:memory_test] = memory_test_en
263
- options[:dc_pins] = get_dc_instr_pins
264
- options[:digsrc_pins] = get_digsrc_pins
265
- options[:digcap_pins] = get_digcap_pins
266
- if options[:dc_pins]
267
- options[:dc_pins].each do |pin|
268
- options[:instruments].merge!(pin => 'DCVS')
269
- end
270
- end
271
-
272
- # Syntax for Digital Source
273
- # instruments = {
274
- # pin-item:digsrc instrument-width: bit-order: instrument-mode:
275
- # site-uniqueness: format: auto_cond;
276
- # }
277
-
278
- if options[:digsrc_pins]
279
- @digsrc_settings.each do |setting_name, setting|
280
- options.merge!(setting_name => setting) if options[setting_name].nil?
281
- end
282
- options[:digsrc_pins].each do |pin|
283
- options[:instruments].merge!(pin => 'digsrc')
284
- end
285
- end
286
-
287
- # Syntax for Digital Capture
288
- # instruments = {
289
- # pin-item:digcap instrument-width: bit-order: instrument-mode:
290
- # format: data-type: auto_cond: auto_trig_enable: store_stv: receive_data;
291
- # }
292
-
293
- if options[:digcap_pins]
294
- @digcap_settings.each do |setting_name, setting|
295
- options.merge!(setting_name => setting) if options[setting_name].nil?
296
- end
297
- options[:digcap_pins].each do |pin|
298
- options[:instruments].merge!(pin => 'digcap')
299
- end
300
- end
301
-
302
- # If memory test, then add to instruments hash
303
- if options[:memory_test]
304
- options[:instruments].merge!('nil' => 'mto')
305
- end
306
-
307
- # If tester.overlay was used to implement digsrc, update the header instruments
308
- auto_instr = {}
309
- @overlay_history.each_pair do |pin_name, value|
310
- if value[:is_digsrc]
311
- microcode "// DigSrc SEND count for #{pin_name}: #{value[:count]}"
312
- new_instr = 'DigSrc '
313
-
314
- # override default settings
315
- digsrc_overrides = source_memory(:digsrc).accumulate_attributes(pin_name)
316
-
317
- # append instrument width
318
- digsrc_instr_width = (dut.pin(pin_name)).size
319
- # override default width if requested
320
- digsrc_instr_width = digsrc_overrides[:size] unless digsrc_overrides[:size].nil?
321
- new_instr += digsrc_instr_width.to_s
322
-
323
- # append any other instrument override settings
324
- if digsrc_instr_width > 1 && (dut.pin(pin_name)).size == 1
325
- new_instr += ':serial'
326
- if (digsrc_overrides[:bit_order] != :msb0) && (digsrc_overrides[:bit_order] != :msb)
327
- new_instr += ':lsb'
328
- else
329
- new_instr += ':msb'
330
- end
331
- end
332
- new_instr += ":format=#{digsrc_overrides[:format]}" unless digsrc_overrides[:format].nil?
333
- new_instr += ":data_type=#{digsrc_overrides[:data_type]}" unless digsrc_overrides[:data_type].nil?
334
- auto_instr["(#{pin_name})"] = new_instr
335
- end
336
- end
337
- # If tester.store was used to implement digcap, update the header instruments
338
- # TODO: a lot of duplication of digsrc logic here. This can be smart-ified.
339
- @capture_history.each_pair do |pin_name, value|
340
- if value[:is_digcap]
341
- microcode "// DigCap Store count for #{pin_name}: #{value[:count]}"
342
- new_instr = 'DigCap '
343
-
344
- # override default settings
345
- digcap_overrides = capture_memory(:digcap).accumulate_attributes(pin_name)
346
-
347
- # append instrument width
348
- digcap_instr_width = (dut.pin(pin_name)).size
349
- digcap_instr_width = digcap_overrides[:size] unless digcap_overrides[:size].nil?
350
- new_instr += digcap_instr_width.to_s
351
- if digcap_instr_width > 1 && (dut.pin(pin_name)).size == 1
352
- new_instr += ':serial'
353
- if (digcap_overrides[:bit_order] != :msb0) && (digcap_overrides[:bit_order] != :msb)
354
- new_instr += ':lsb'
355
- else
356
- new_instr += ':msb'
357
- end
358
- end
359
- new_instr += ":format=#{digcap_overrides[:format]}" unless digcap_overrides[:format].nil?
360
- new_instr += ":data_type=#{digcap_overrides[:data_type]}" unless digcap_overrides[:data_type].nil?
361
- new_instr += ':auto_trig_enable' # always enable auto-trigger for digcap, trigger microcode isn't applied
362
- auto_instr["(#{pin_name})"] = new_instr
363
- end
364
- end
365
- options[:instruments] = options[:instruments].merge(auto_instr)
366
-
367
- super(options.merge(digital_inst: @digital_instrument,
368
- memory_test: false,
369
- high_voltage: false,
370
- svm_only: false
371
- )) do |pin_list|
372
- # if subroutine pattern has only single-module subroutines then skip module start
373
- # (will be taken care of elsewhere)
374
- unless options[:subroutine_pat] && @onemodsubs_found && !@nonmodsubs_found
375
- microcode "#{options[:subroutine_pat] ? 'srm_vector' : 'vm_vector'}"
376
- microcode "#{options[:pattern]} ($tset, #{pin_list})"
377
- microcode '{'
378
- end
379
- # override min vector limit if subroutine pattern
380
- @min_pattern_vectors = 0 if options[:subroutine_pat]
381
- unless options[:subroutine_pat]
382
- microcode "start_label #{options[:pattern]}_st:"
383
- end
384
- end
385
- end
386
-
387
- def pattern_footer(options = {})
388
- # if subroutine pattern has any single-module subroutines then skip module end
389
- # (will be taken care of elsewhere)
390
- unless options[:subroutine_pat] && @onemodsubs_found
391
- super(options.merge(end_module: false))
392
- end
393
- end
394
-
395
- # allow for option of separate modules for each subroutine
396
- # requirement is that any subroutines in their own module (options[:onemodsub] = true)
397
- # MUST be implemented AFTER any subroutines in the common pattern module!
398
- def start_subroutine(name, options = {})
399
- if options[:onemodsub]
400
- if @nonmodsubs_found && !@onemodsubs_found
401
- # this means we need to do end module for non-single-module subroutines
402
- # do only once!
403
- pattern_footer(options.merge(subroutine_pat: true, end_module: false))
404
- end
405
- @onemodsubs_found = true # importnat put this after the call to pattern_footer above
406
- pin_list = ordered_pins.map(&:name).join(', ')
407
- microcode 'srm_vector'
408
- microcode "#{name}_module ($tset, #{pin_list})"
409
- microcode '{'
410
- else
411
- # normal subroutine to use common
412
- if @onemodsubs_found
413
- # give error -- requirement is that any normal subroutines using common pattern module
414
- # must be done BEFORE any subroutines that need their own module definition!
415
- fail "ERROR: Cannot implement any common module subroutines (#{name}) after implementing any single-module subroutines in the same pattern!"
416
- end
417
- @nonmodsubs_found = true
418
- end
419
- super(name, options)
420
- end
421
-
422
- def end_subroutine(cond = false, options = {})
423
- (cond, options) = false, cond if cond.is_a?(Hash)
424
- super(cond, options)
425
- if options[:onemodsub]
426
- microcode '}'
427
- end
428
- end
429
-
430
- # Generates a match loop based on vector condition passed in via block
431
- #
432
- # This method is not really intended to be called directly, rather you should call
433
- # via Tester#wait:
434
- # e.g. $tester.wait(:match => true) do
435
- # reg(:status_reg).bit(:done).read(1)! # vector condition that you want to match
436
- # end
437
- #
438
- # The timeout should be provided in cycles, however when called via the wait method the
439
- # time-based helpers (time_in_us, etc) will be converted to cycles for you.
440
- #
441
- # The following options are available to tailor the match loop behavior, defaults in
442
- # parenthesis:
443
- # * :force_fail_on_timeout (true) - Force a vector mis-compare if the match loop times out
444
- # * :on_timeout_goto ("") - Optionally supply a label to branch to on timeout, by default will continue from the end of the match loop
445
- # * :on_block_match_goto ("") - Optionally supply a label to branch to when block condition is met, by default will continue from the end of the match loop
446
- # * :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
447
- # * :force_fail_on_timeout (true) - force pattern to fail if timeout occurs
448
- # * :global_loops (false) - whether match loop loops should use global labels
449
- # * :manual_stop (false) - whether to use extra cpuB flag to resolve IG-XL v.3.50.xx bug where VBT clears cpuA immediately
450
- # at start of PatFlagFunc instead of at end. Use will have to manually clear cpuB to resume this pattern.
451
- # ==== Examples
452
- # $tester.wait(:match => true, :time_in_us => 5000, :pin => $top.pin(:done), :state => :high) do
453
- # <vectors>
454
- # end
455
- def match_block(timeout, options = {}, &block)
456
- options = {
457
- check_for_fails: false,
458
- on_timeout_goto: false,
459
- on_block_match_goto: false,
460
- multiple_entries: false,
461
- force_fail_on_timeout: true,
462
- global_loops: false,
463
- manual_stop: false,
464
- clr_fail_post_match: false
465
- }.merge(options)
466
-
467
- unless block_given?
468
- fail 'ERROR: block not passed to match_block!'
469
- end
470
-
471
- # if options[:check_for_fails]
472
- # cc 'NOTE: check for fails prior to match loop not necessary on UltraFlex'
473
- # end
474
-
475
- # ss 'WARNING: MATCH LOOP FOR ULTRAFLEX STILL UNDER DEVELOPMENT'
476
-
477
- # Create BlockArgs objects in order to receive multiple blocks
478
- match_conditions = Origen::Utility::BlockArgs.new
479
- fail_conditions = Origen::Utility::BlockArgs.new
480
-
481
- # yield object to calling routine to get populated with blocks
482
- if block.arity > 0
483
- yield match_conditions, fail_conditions
484
- else
485
- # for backwards compatibility with Origen core call to match_block
486
- match_conditions.add(&block)
487
- fail_conditions.add(&block)
488
- end
489
-
490
- if options[:check_for_fails]
491
- if options[:multiple_entries]
492
- @match_entries.times do |i|
493
- microcode "global subr match_done_#{i}:"
494
- set_code(i + 100)
495
- cycle(microcode: 'jump call_tester') unless i == @match_entries - 1
496
- end
497
- microcode 'call_tester:'
498
- else
499
- set_code(100)
500
- end
501
- cc 'Wait for any prior failures to propagate through the pipeline'
502
- cycle(microcode: 'pipe_minus 1')
503
- cc 'Now handshake with the tester to bin out and parts that have failed before they got here'
504
- handshake(manual_stop: options[:manual_stop])
505
- end
506
-
507
- # Now do the main match loop
508
- cc 'Start the match loop'
509
-
510
- cycle # (:microcode => "set_msb #{counter_msb}") # set_msb microcode will be set below after counting match loop cycles
511
- set_msb_vector = last_vector # remember the vector with set_msb opcode
512
-
513
- cycle(microcode: 'branch_expr = (fail)')
514
-
515
- global_opt = (options[:global_loops]) ? 'global ' : ''
516
- microcode "#{global_opt}match_loop_#{@unique_counter}:"
517
-
518
- cycle # (:microcode => "set c0 #{counter_lsb}")
519
- set_c0_vector = last_vector # remember the vector with set_c0 opcode
520
-
521
- microcode "match_result_loop_#{@unique_counter}:"
522
- cycle(microcode: 'loop c0')
523
-
524
- # count cycles in match loop block passed to help with meeting
525
- # desired timeout value (have to back assign microcodes above)
526
- prematch_cycle_count = cycle_count
527
- match_conditions.each_with_index do |condition, i|
528
- mask_fails(true)
529
- condition.call # match condition
530
- mask_fails(false)
531
-
532
- cc ' Wait for the result to propagate through the pipeline'
533
- cycle(microcode: 'pipe_minus 1')
534
- inc_cycle_count(@pipeline_depth - 1) # Account for pipeline depth
535
- cc "Branch if block condition #{i} not yet met"
536
- cycle(microcode: "if (branch_expr) jump block_#{i}_notyet_matched_#{@unique_counter}")
537
- cc 'Match found'
538
- cycle(microcode: 'pop_loop')
539
- if options[:on_block_match_goto]
540
- if options[:on_block_match_goto].is_a?(Hash)
541
- if options[:on_block_match_goto][i]
542
- custom_jump = options[:on_block_match_goto][i]
543
- else
544
- custom_jump = nil
545
- end
546
- else
547
- custom_jump = options[:on_block_match_goto]
548
- end
549
- end
550
- if custom_jump
551
- cycle(microcode: "jump #{custom_jump}")
552
- else
553
- cycle(microcode: "jump match_loop_end_#{@unique_counter}")
554
- end
555
- cc 'Match not yet found'
556
- cycle(microcode: "block_#{i}_notyet_matched_#{@unique_counter}:")
557
- end
558
-
559
- match_conditions_cycle_count = cycle_count - prematch_cycle_count
560
- cc "Match loop cycle count = #{match_conditions_cycle_count}"
561
-
562
- # reduce timeout requested by match loop cycle count
563
- timeout = (timeout.to_f / match_conditions_cycle_count).ceil
564
-
565
- # Calculate the counter values appropriately hit the timeout requested
566
- match_delay_cycles = false
567
-
568
- # Determine full value of counter0
569
- counter_value = timeout.to_f.floor
570
-
571
- if counter_value < (2**@counter_lsb_bits)
572
- # small value, don't need msb temp register
573
- counter_msb = 1
574
- counter_lsb = counter_value
575
- elsif counter_value < (2**(@counter_lsb_bits + @counter_msb_bits))
576
- # larger value, but smaller than counter maximum
577
- counter_msb = counter_value # set MSB (lowest LSB bits get ignored)
578
- counter_lsb = counter_value & (2**@counter_lsb_bits - 1) # set LSB
579
- elsif counter_value < (2**(@counter_lsb_bits + @counter_msb_bits)) * @max_repeat_loop
580
- # larger value, greater than counter, so add time delay per instance of loop to avoid using second counter
581
- match_delay_cycles = (counter_value.to_f / (2**(@counter_lsb_bits + @counter_msb_bits))).ceil
582
- counter_msb = (counter_value / match_delay_cycles).floor # set MSB (lowest LSB bits get ignored)
583
- counter_lsb = counter_msb & (2**@counter_lsb_bits - 1) # set LSB
584
- else
585
- abort 'ERROR: timeout value too large in tester match method!'
586
- end
587
-
588
- # retroactively modify the counters based on cycles in match loop conditions
589
- set_msb_vector.microcode = "set_msb #{counter_msb}"
590
- set_c0_vector.microcode = "set c0 #{counter_lsb}"
591
-
592
- if match_delay_cycles
593
- cc 'Delay to meet timeout value'
594
- cycle(repeat: match_delay_cycles) if match_delay_cycles
595
- end
596
-
597
- cycle(microcode: "end_loop match_result_loop_#{@unique_counter}")
598
-
599
- if options[:force_fail_on_timeout]
600
- cc 'To get here something has gone wrong, check blocks again to force a pattern failure'
601
- fail_conditions.each do |condition|
602
- cycle(microcode: 'pipe_minus 1')
603
- condition.call
604
- end
605
- end
606
- if options[:on_timeout_goto]
607
- cycle(microcode: "jump #{options[:on_timeout_goto]}")
608
- else
609
- cycle(microcode: "jump match_loop_end_#{@unique_counter}")
610
- end
611
- cycle(microcode: "match_loop_end_#{@unique_counter}:")
612
-
613
- @unique_counter += 1 # Increment so a different label will be applied if another
614
- # handshake is called in the same pattern
615
- end
616
-
617
- # Handshake with the tester.
618
- #
619
- # Will set a cpu flag (A) and wait for it to be cleared by the tester, optionally
620
- # pass in a read code to pass information to the tester.
621
- #
622
- # ==== Examples
623
- # $tester.handshake # Pass control to the tester for a measurement
624
- # $tester.handshake(:readcode => 10) # Trigger a specific action by the tester
625
- def handshake(options = {})
626
- options = {
627
- readcode: false,
628
- manual_stop: false, # set a 2nd CPU flag in case 1st flag is automatically cleared
629
- }.merge(options)
630
- if options[:readcode]
631
- set_code(options[:readcode])
632
- end
633
- if options[:manual_stop]
634
- cycle(microcode: "#{@microcode[:enable]} (#{@flags[1]})")
635
- cycle(microcode: "#{@microcode[:set_flag]} (#{@flags[0]} #{@flags[1]})")
636
- else
637
- cycle(microcode: "#{@microcode[:enable]} (#{@flags[0]})")
638
- cycle(microcode: "#{@microcode[:set_flag]} (#{@flags[0]})")
639
- end
640
- cycle(microcode: "loop_here_#{@unique_counter}: if (branch_expr) jump loop_here_#{@unique_counter}")
641
-
642
- @unique_counter += 1 # Increment so a different label will be applied if another
643
- # handshake is called in the same pattern
644
- end
645
-
646
- def keep_alive(options = {})
647
- if options[:subroutine_pat]
648
- cycle(microcode: 'clr_subr')
649
- cycle(microcode: "#{@microcode[:enable]} (#{@flags[3]})")
650
- cycle(microcode: "#{@microcode[:set_flag]} (#{@flags[3]})")
651
- cycle(microcode: "loop_here_#{@unique_counter}: if (branch_expr) jump loop_here_#{@unique_counter}")
652
- cycle
653
- @unique_counter += 1 # Increment so a different label will be applied if another
654
- else
655
- $tester.cycle
656
- call_subroutine('keep_alive')
657
- end
658
- end
659
-
660
- # Capture a vector to the tester HRAM.
661
- #
662
- # This method applys a store vector (stv) opcode to the previous vector, note that is does
663
- # not actually generate a new vector.
664
- #
665
- # Sometimes when generating vectors within a loop you may want to apply a stv opcode
666
- # retrospectively to a previous vector, passing in an offset option will allow you
667
- # to do this.
668
- #
669
- # On J750 the pins argument is ignored since the tester only supports whole vector capture.
670
- #
671
- # @example
672
- # $tester.cycle # This is the vector you want to capture
673
- # $tester.store # This applys the STV opcode
674
- #
675
- # $tester.cycle # This one gets stored
676
- # $tester.cycle
677
- # $tester.cycle
678
- # $tester.store(:offset => -2) # Just realized I need to capture that earlier vector
679
- def store(*pins)
680
- options = pins.last.is_a?(Hash) ? pins.pop : {}
681
- options = { offset: 0,
682
- opcode: 'stv'
683
- }.merge(options)
684
- pins = pins.flatten.compact
685
- if pins.empty?
686
- fail 'For the UltraFLEX you must supply the pins to store/capture'
687
- end
688
-
689
- capt_style = options[:capture_style].nil? ? @capture_style : options[:capture_style]
690
- if capt_style == :digcap
691
- capt_microcode = dssc_store(pins, options)
692
- else
693
- capt_microcode = options[:opcode]
694
- end
695
-
696
- pins.each do |pin|
697
- pin.restore_state do
698
- pin.capture
699
- update_vector_pin_val pin, offset: options[:offset]
700
- last_vector(options[:offset]).dont_compress = true
701
- end
702
- end
703
- update_vector microcode: capt_microcode, offset: options[:offset]
704
- end
705
- alias_method :to_hram, :store
706
- alias_method :capture, :store
707
-
708
- # use digcap to store, called by tester.store()
709
- def dssc_store(pins, options)
710
- repeat_count = last_vector(options[:offset]).repeat
711
- capt_microcode = []
712
- pins.each do |pin|
713
- if @capture_history[pin.name].nil?
714
- @capture_history[pin.name] = { is_digcap: true, count: repeat_count }
715
- else
716
- @capture_history[pin.name][:count] += repeat_count
717
- end
718
- capt_microcode << "((#{pin.name}):DigCap = Store)"
719
- end
720
- capt_microcode << 'stv'
721
- capt_microcode.join(',')
722
- end
723
-
724
- def reload_counters(name)
725
- microcode "reload #{name}"
726
- end
727
-
728
- def set_msb(integer)
729
- microcode "set_msb #{integer}"
730
- end
731
-
732
- # Capture the next vector generated to HRAM
733
- #
734
- # This method applies a store vector (stv) opcode to the next vector to be generated,
735
- # note that is does not actually generate a new vector.
736
- #
737
- # pin argument must be provided so that 'V' (valid) state can be applied to the pin
738
- # if not already.
739
- #
740
- # @example
741
- # $tester.store_next_cycle
742
- # $tester.cycle # This is the vector that will be captured
743
- def store_next_cycle(*pins)
744
- options = pins.last.is_a?(Hash) ? pins.pop : {}
745
- options = {
746
- opcode: 'stv'
747
- }.merge(options)
748
- pins = pins.flatten.compact
749
- if pins.empty?
750
- fail 'For the UltraFLEX you must supply the pins to store/capture'
751
- end
752
-
753
- capt_style = options[:capture_style].nil? ? @capture_style : options[:capture_style]
754
- if capt_style == :digcap
755
- capt_microcode = []
756
- repeat_count = options[:repeat].nil? ? 1 : options[:repeat]
757
- pins.each do |pin|
758
- if @capture_history[pin.name].nil?
759
- @capture_history[pin.name] = { is_digcap: true, count: repeat_count }
760
- else
761
- @capture_history[pin.name][:count] += repeat_count
762
- end
763
- capt_microcode << "((#{pin.name}):DigCap = Store)"
764
- end
765
- capt_microcode << 'stv'
766
- capt_microcode = capt_microcode.join(',')
767
- else
768
- capt_microcode = options[:opcode]
769
- end
770
-
771
- pins.each { |pin| pin.save; pin.capture }
772
- # Register this clean up function to be run after the next vector
773
- # is generated (SMcG: cool or what! DH: Yes, very cool!)
774
- preset_next_vector(microcode: capt_microcode) do
775
- pins.each(&:restore)
776
- end
777
- end
778
- alias_method :store!, :store_next_cycle
779
-
780
- # ate_hardware stores "key" UltraFLEX hardware information needed for test program generation
781
- # Instrument types available for ppmu: "HSD-M", "HSD-U", "HSD-4G", and "HSS-6G".
782
- # Sample usage: $tester.ate_hardware("HSD-U").ppmu
783
- # Instrument types available for supply: "VSM", "VSMx2", "VSMx4", "HexVS", "HexVSx2", "HexVSx4",
784
- # "HexVSx6", "HexVS+x2", "HexVS+x4", "HexVS+x6", "HDVS1", "HDVS1x2", "HDVS1x4", "VHDVS",
785
- # "VHDVS_HC", "VHDVSx2", "VHDVS_HCx2", "VHDVS_HCx4", "VHDVS_HCx8", "VHDVS+", "VHDVS_HC+",
786
- # "VHDVS+x2", "VHDVS_HC+x2", "VHDVS_HC+x4", and "VHDVS_HC+x8".
787
- # HDVS1 is also known as HDVS. VHDVS is also known as UVS256.
788
- # x2 is Merged2, x4 is Merged4, x6 is Merged6. _HC is High-Current.
789
- # + is High-Accuracy.
790
- # Sample usage: $tester.ate_hardware("VSM").supply
791
- # Sample usage: $tester.ate_hardware("HSD-M").ppmu
792
- def ate_hardware(instrumentname = '')
793
- @ate_hardware = ATEHardware.new(instrumentname)
794
- end
795
- end
796
- end
797
- UltraFLEX = IGXLBasedTester::UltraFLEX
798
- end
1
+ require 'origen_testers/igxl_based_tester/ultraflex/ate_hardware'
2
+ module OrigenTesters
3
+ module IGXLBasedTester
4
+ class UltraFLEX < Base
5
+ autoload :Generator, 'origen_testers/igxl_based_tester/ultraflex/generator.rb'
6
+
7
+ # Tester model to generate .atp patterns for the Teradyne UltraFLEX
8
+ #
9
+ # == Basic Usage
10
+ # $tester = Testers::UltraFLEX.new
11
+ # $tester.cycle # Generate a vector
12
+ #
13
+ # Many more methods exist to generate UltraFLEX specific micro-code, see below for
14
+ # details.
15
+ #
16
+ # Also note that this class inherits from the base IGXLBasedTester class and so all methods
17
+ # described there are also available.
18
+
19
+ # Returns a new UltraFLEX instance, normally there would only ever be one of these
20
+ # assigned to the global variable such as $tester by your target.
21
+ def initialize
22
+ super
23
+ @pipeline_depth = 255 # for single mode
24
+ @software_version = '8.10.10'
25
+ @name = 'ultraflex'
26
+ @opcode_mode = :single # there is also :dual
27
+ @counter_lsb_bits = 16 # individual counter bit length
28
+ @counter_msb_bits = 12 # temporary register commonly used to extend all counters
29
+
30
+ @flags = %w(cpuA_cond cpuB_cond cpuC_cond cpuD_cond)
31
+ @microcode[:enable] = 'branch_expr ='
32
+ @microcode[:set_flag] = 'set_cpu_cond'
33
+ @microcode[:mask_vector] = 'mask'
34
+
35
+ # Min required for a VM module-- not for SRM modules
36
+ # this handled in pattern_header below
37
+ @min_pattern_vectors = (@opcode_mode == :single) ? 64 : 128
38
+
39
+ @digital_instrument = 'hsdm' # 'hsdm' for HSD1000 and UP800, ok with UP1600 though
40
+
41
+ @capture_state = 'V' # STV requires valid 'V' expect data
42
+
43
+ @set_msb_issued = false # Internal flag to keep track of set_msb usage, allowing for set_lsb to be used as a readcode
44
+ @microcode[:keepalive] = 'keepalive'
45
+
46
+ @onemodsubs_found = false # flag to indicate whether a single-module subroutine has been implemented in this pattern
47
+ @nonmodsubs_found = false # flag to indicate whether a normal non-single-module subroutine has been implemented in this pattern
48
+
49
+ @dssc_send_delay = 144
50
+ @dssc_send_delay = 288 if @opcode_mode == :dual
51
+ @dssc_send_delay = 576 if @opcode_mode == :quad
52
+ end
53
+
54
+ # Do a frequency measure.
55
+ #
56
+ # Write the necessary micro code to do a frequency measure on the given pin,
57
+ # optionally supply a read code to pass information to the tester.
58
+ #
59
+ # ==== Examples
60
+ # $tester.freq_count($top.pin(:d_out)) # Freq measure on pin "d_out"
61
+ # $tester.freq_count($top.pin(:d_out):readcode => 10)
62
+ def freq_count(pin, options = {})
63
+ options = { readcode: false
64
+ }.merge(options)
65
+
66
+ set_code(options[:readcode]) if options[:readcode]
67
+ cycle(microcode: "#{@microcode[:set_flag]} (#{@flags[0]})") # set cpuA
68
+ cycle(microcode: "#{@microcode[:set_flag]} (#{@flags[0]})") # set cpuB
69
+ cycle(microcode: "#{@microcode[:set_flag]} (#{@flags[1]})") # set cpuC
70
+ cycle(microcode: "#{@microcode[:set_flag]} (#{@flags[2]})") # set cpuD
71
+ cycle(microcode: "freq_loop_1: #{@microcode[:enable]} (#{@flags[0]})")
72
+ cycle(microcode: 'if (branch_expr) jump freq_loop_1')
73
+ pin.drive_lo
74
+ delay(2000)
75
+ pin.dont_care
76
+ cycle(microcode: "freq_loop_2: #{@microcode[:enable]} (#{@flags[1]})")
77
+ cycle(microcode: 'if (branch_expr) jump freq_loop_2')
78
+ cycle(microcode: "#{@microcode[:enable]} (#{@flags[2]})")
79
+ cycle(microcode: 'if (branch_expr) jump freq_loop_1')
80
+ end
81
+
82
+ def memory_test(options = {})
83
+ options = {
84
+ gen_vector: true, # Default generate vector not just MTO opcode
85
+ init_counter_x: false, # initialize counter X
86
+ inc_counter_x: false, # increment counter X
87
+ init_counter_y: false, # initialize counter X
88
+ inc_counter_y: false, # increment counter X
89
+ capture_vector: false, # capture vector to memory using all mem types
90
+ capture_vector_mem0: false, # capture vector to memory type 0, here for J750 will be stv_m0
91
+ capture_vector_mem1: false, # capture vector to memory type 1, here for J750 will be stv_m1
92
+ capture_vector_mem2: false, # capture vector to memory type 2, here for J750 will be stv_c
93
+ pin: false, # pin on which to drive or expect data, pass pin object here!
94
+ pin_data: false, # pin data (:none, :drive, :expect)
95
+ use_dgen_group: false,
96
+ set_msb: false
97
+ }.merge(options)
98
+
99
+ mto_opcode = ''
100
+
101
+ if options[:init_counter_x]
102
+ mto_opcode += ' xenable_load jam_reg xa jam_reg'
103
+ end
104
+
105
+ if options[:init_counter_y]
106
+ mto_opcode += ' yenable_load jam_reg ya jam_reg'
107
+ end
108
+
109
+ if options[:inc_counter_x]
110
+ mto_opcode += ' xa inc'
111
+ end
112
+
113
+ if options[:inc_counter_y]
114
+ mto_opcode += ' ya inc'
115
+ end
116
+
117
+ if options[:use_dgen_group]
118
+ mto_opcode += ' dgroup 0'
119
+ end
120
+
121
+ if options[:set_msb]
122
+ microcode 'set_msb 1'
123
+ end
124
+
125
+ unless mto_opcode.eql?('')
126
+ mto_opcode = '(mto =' + mto_opcode + ')'
127
+ end
128
+
129
+ if options[:pin_data] == :expect
130
+ mto_opcode = 'stv'
131
+ end
132
+
133
+ if options[:gen_vector]
134
+ if options[:pin]
135
+ case options[:pin_data]
136
+ when :drive
137
+ # store current pin state
138
+ cur_pin_state = options[:pin].state.to_sym
139
+ options[:pin].drive_mem
140
+ when :expect
141
+ # store current pin state
142
+ cur_pin_state = options[:pin].state.to_sym
143
+ options[:pin].expect_mem
144
+ end
145
+ end
146
+ cycle(microcode: "#{mto_opcode}", dont_compress: false)
147
+ if options[:pin]
148
+ # restore previous pin state
149
+ case options[:pin_data]
150
+ when :drive
151
+ options[:pin].state = cur_pin_state
152
+ when :expect
153
+ options[:pin].state = cur_pin_state
154
+ end
155
+ end
156
+ else
157
+ microcode "#{mto_opcode}"
158
+ end
159
+ end
160
+
161
+ def call_match
162
+ # fail 'Method call_match not yet supported for UltraFLEX!'
163
+ @match_counter = @match_counter || 0
164
+ call_subroutine("match_done_#{@match_counter}")
165
+ @match_counter += 1 unless @match_counter == (@match_entries || 1) - 1
166
+ end
167
+
168
+ # Ultraflex implementation of J750-style 'set_code'
169
+ #
170
+ # Set a readcode, using one of the Ultraflex general-purpose counters.
171
+ # Counter C15 is used by default, this can be changed by the caller if necessary.
172
+ #
173
+ # Use to set an explicit readcode for communicating with the tester. This method
174
+ # will generate an additional vector (or 2, depending if set_msb is needed).
175
+ #
176
+ # NOTE: Some caveats when using this method:
177
+ # - When setting a counter from the pattern microcode, the actual Patgen counter value is set to n-1.
178
+ # This method adjusts by using a value of n+1, so the value read by the tester is the original intended value.
179
+ #
180
+ # - When setting a counter from pattern microcode, the upper bits must be loaded separately using 'set_msb'.
181
+ # This method calls the set_msb opcode if needed - note the tester must mask the upper 16 bits to get the desired value.
182
+ # The set_msb opcode will also generate a second vector the first time the set_code method is called.
183
+ #
184
+ # ==== Examples
185
+ # $tester.set_code(55)
186
+ #
187
+ def set_code(*code)
188
+ options = code.last.is_a?(Hash) ? code.pop : {}
189
+ options = { counter: 'c15'
190
+ }.merge(options)
191
+ cc " Using counter #{options[:counter]} as set_code replacement - value set to #{code[0]} + 1"
192
+ unless @set_msb_issued
193
+ set_msb(1)
194
+ cycle # set_msb doesn't issue a cycle
195
+ end
196
+ cycle(microcode: "set #{options[:counter]} #{code[0].next}") #+1 here to align with VBT
197
+ end
198
+
199
+ def set_code_no_msb(*code)
200
+ options = code.last.is_a?(Hash) ? code.pop : {}
201
+ options = { counter: 'c15'
202
+ }.merge(options)
203
+ unless @set_msb_issued
204
+ cycle # set_msb doesn't issue a cycle
205
+ end
206
+ cycle(microcode: "set #{options[:counter]} #{code[0].next}") #+1 here to align with VBT
207
+ end
208
+
209
+ def loop_vectors(name, number_of_loops, global = false, label_first = false)
210
+ if number_of_loops > 1
211
+ @loop_counters ||= {}
212
+ if @loop_counters[name]
213
+ @loop_counters[name] += 1
214
+ else
215
+ @loop_counters[name] = 0
216
+ end
217
+ loop_name = @loop_counters[name] == 0 ? name : "#{name}_#{@loop_counters[name]}"
218
+ if label_first
219
+ global_opt = (global) ? 'global ' : ''
220
+ microcode "#{global_opt}#{loop_name}: "
221
+ end
222
+
223
+ if "#{loop_name}" == 'row_loop'
224
+ cycle(microcode: 'loop c0')
225
+ elsif "#{loop_name}" == 'quad_loop'
226
+ cycle(microcode: 'loop c1')
227
+ elsif "#{loop_name}" == 'page_loop_red'
228
+ cycle(microcode: 'loop c2')
229
+ elsif "#{loop_name}" == 'page_loop_ecc'
230
+ cycle(microcode: 'loop c3')
231
+ elsif "#{loop_name}" == 'page_loop_data'
232
+ cycle(microcode: 'loop c4')
233
+ end
234
+
235
+ unless label_first
236
+ global_opt = (global) ? 'global ' : ''
237
+ cycle(microcode: "#{global_opt}#{loop_name}: ")
238
+ end
239
+ yield
240
+ cycle(microcode: "end_loop #{loop_name}")
241
+ else
242
+ yield
243
+ end
244
+ end
245
+
246
+ alias_method :loop_vector, :loop_vectors
247
+
248
+ def pattern_header(options = {})
249
+ options = {
250
+ instruments: {}
251
+ }.merge(options)
252
+
253
+ case $tester.vector_group_size
254
+ when 1
255
+ @opcode_mode = :single
256
+ when 2
257
+ @opcode_mode = :dual
258
+ when 4
259
+ @opcode_mode = :quad
260
+ end
261
+
262
+ options[:memory_test] = memory_test_en
263
+ options[:dc_pins] = get_dc_instr_pins
264
+ options[:digsrc_pins] = get_digsrc_pins
265
+ options[:digcap_pins] = get_digcap_pins
266
+ if options[:dc_pins]
267
+ options[:dc_pins].each do |pin|
268
+ options[:instruments].merge!(pin => 'DCVS')
269
+ end
270
+ end
271
+
272
+ # Syntax for Digital Source
273
+ # instruments = {
274
+ # pin-item:digsrc instrument-width: bit-order: instrument-mode:
275
+ # site-uniqueness: format: auto_cond;
276
+ # }
277
+
278
+ if options[:digsrc_pins]
279
+ @digsrc_settings.each do |setting_name, setting|
280
+ options.merge!(setting_name => setting) if options[setting_name].nil?
281
+ end
282
+ options[:digsrc_pins].each do |pin|
283
+ options[:instruments].merge!(pin => 'digsrc')
284
+ end
285
+ end
286
+
287
+ # Syntax for Digital Capture
288
+ # instruments = {
289
+ # pin-item:digcap instrument-width: bit-order: instrument-mode:
290
+ # format: data-type: auto_cond: auto_trig_enable: store_stv: receive_data;
291
+ # }
292
+
293
+ if options[:digcap_pins]
294
+ @digcap_settings.each do |setting_name, setting|
295
+ options.merge!(setting_name => setting) if options[setting_name].nil?
296
+ end
297
+ options[:digcap_pins].each do |pin|
298
+ options[:instruments].merge!(pin => 'digcap')
299
+ end
300
+ end
301
+
302
+ # If memory test, then add to instruments hash
303
+ if options[:memory_test]
304
+ options[:instruments].merge!('nil' => 'mto')
305
+ end
306
+
307
+ # If tester.overlay was used to implement digsrc, update the header instruments
308
+ auto_instr = {}
309
+ @overlay_history.each_pair do |pin_name, value|
310
+ if value[:is_digsrc]
311
+ microcode "// DigSrc SEND count for #{pin_name}: #{value[:count]}"
312
+ new_instr = 'DigSrc '
313
+
314
+ # override default settings
315
+ digsrc_overrides = source_memory(:digsrc).accumulate_attributes(pin_name)
316
+
317
+ # append instrument width
318
+ digsrc_instr_width = (dut.pin(pin_name)).size
319
+ # override default width if requested
320
+ digsrc_instr_width = digsrc_overrides[:size] unless digsrc_overrides[:size].nil?
321
+ new_instr += digsrc_instr_width.to_s
322
+
323
+ # append any other instrument override settings
324
+ if digsrc_instr_width > 1 && (dut.pin(pin_name)).size == 1
325
+ new_instr += ':serial'
326
+ if (digsrc_overrides[:bit_order] != :msb0) && (digsrc_overrides[:bit_order] != :msb)
327
+ new_instr += ':lsb'
328
+ else
329
+ new_instr += ':msb'
330
+ end
331
+ end
332
+ new_instr += ":format=#{digsrc_overrides[:format]}" unless digsrc_overrides[:format].nil?
333
+ new_instr += ":data_type=#{digsrc_overrides[:data_type]}" unless digsrc_overrides[:data_type].nil?
334
+ auto_instr["(#{pin_name})"] = new_instr
335
+ end
336
+ end
337
+ # If tester.store was used to implement digcap, update the header instruments
338
+ # TODO: a lot of duplication of digsrc logic here. This can be smart-ified.
339
+ @capture_history.each_pair do |pin_name, value|
340
+ if value[:is_digcap]
341
+ microcode "// DigCap Store count for #{pin_name}: #{value[:count]}"
342
+ new_instr = 'DigCap '
343
+
344
+ # override default settings
345
+ digcap_overrides = capture_memory(:digcap).accumulate_attributes(pin_name)
346
+
347
+ # append instrument width
348
+ digcap_instr_width = (dut.pin(pin_name)).size
349
+ digcap_instr_width = digcap_overrides[:size] unless digcap_overrides[:size].nil?
350
+ new_instr += digcap_instr_width.to_s
351
+ if digcap_instr_width > 1 && (dut.pin(pin_name)).size == 1
352
+ new_instr += ':serial'
353
+ if (digcap_overrides[:bit_order] != :msb0) && (digcap_overrides[:bit_order] != :msb)
354
+ new_instr += ':lsb'
355
+ else
356
+ new_instr += ':msb'
357
+ end
358
+ end
359
+ new_instr += ":format=#{digcap_overrides[:format]}" unless digcap_overrides[:format].nil?
360
+ new_instr += ":data_type=#{digcap_overrides[:data_type]}" unless digcap_overrides[:data_type].nil?
361
+ new_instr += ':auto_trig_enable' # always enable auto-trigger for digcap, trigger microcode isn't applied
362
+ auto_instr["(#{pin_name})"] = new_instr
363
+ end
364
+ end
365
+ options[:instruments] = options[:instruments].merge(auto_instr)
366
+
367
+ super(options.merge(digital_inst: @digital_instrument,
368
+ memory_test: false,
369
+ high_voltage: false,
370
+ svm_only: false
371
+ )) do |pin_list|
372
+ # if subroutine pattern has only single-module subroutines then skip module start
373
+ # (will be taken care of elsewhere)
374
+ unless options[:subroutine_pat] && @onemodsubs_found && !@nonmodsubs_found
375
+ microcode "#{options[:subroutine_pat] ? 'srm_vector' : 'vm_vector'}"
376
+ microcode "#{options[:pattern]} ($tset, #{pin_list})"
377
+ microcode '{'
378
+ end
379
+ # override min vector limit if subroutine pattern
380
+ @min_pattern_vectors = 0 if options[:subroutine_pat]
381
+ unless options[:subroutine_pat]
382
+ microcode "start_label #{options[:pattern]}_st:"
383
+ end
384
+ end
385
+ end
386
+
387
+ def pattern_footer(options = {})
388
+ # if subroutine pattern has any single-module subroutines then skip module end
389
+ # (will be taken care of elsewhere)
390
+ unless options[:subroutine_pat] && @onemodsubs_found
391
+ super(options.merge(end_module: false))
392
+ end
393
+ end
394
+
395
+ # allow for option of separate modules for each subroutine
396
+ # requirement is that any subroutines in their own module (options[:onemodsub] = true)
397
+ # MUST be implemented AFTER any subroutines in the common pattern module!
398
+ def start_subroutine(name, options = {})
399
+ if options[:onemodsub]
400
+ if @nonmodsubs_found && !@onemodsubs_found
401
+ # this means we need to do end module for non-single-module subroutines
402
+ # do only once!
403
+ pattern_footer(options.merge(subroutine_pat: true, end_module: false))
404
+ end
405
+ @onemodsubs_found = true # importnat put this after the call to pattern_footer above
406
+ pin_list = ordered_pins.map(&:name).join(', ')
407
+ microcode 'srm_vector'
408
+ microcode "#{name}_module ($tset, #{pin_list})"
409
+ microcode '{'
410
+ else
411
+ # normal subroutine to use common
412
+ if @onemodsubs_found
413
+ # give error -- requirement is that any normal subroutines using common pattern module
414
+ # must be done BEFORE any subroutines that need their own module definition!
415
+ fail "ERROR: Cannot implement any common module subroutines (#{name}) after implementing any single-module subroutines in the same pattern!"
416
+ end
417
+ @nonmodsubs_found = true
418
+ end
419
+ super(name, options)
420
+ end
421
+
422
+ def end_subroutine(cond = false, options = {})
423
+ (cond, options) = false, cond if cond.is_a?(Hash)
424
+ super(cond, options)
425
+ if options[:onemodsub]
426
+ microcode '}'
427
+ end
428
+ end
429
+
430
+ # Generates a match loop based on vector condition passed in via block
431
+ #
432
+ # This method is not really intended to be called directly, rather you should call
433
+ # via Tester#wait:
434
+ # e.g. $tester.wait(:match => true) do
435
+ # reg(:status_reg).bit(:done).read(1)! # vector condition that you want to match
436
+ # end
437
+ #
438
+ # The timeout should be provided in cycles, however when called via the wait method the
439
+ # time-based helpers (time_in_us, etc) will be converted to cycles for you.
440
+ #
441
+ # The following options are available to tailor the match loop behavior, defaults in
442
+ # parenthesis:
443
+ # * :force_fail_on_timeout (true) - Force a vector mis-compare if the match loop times out
444
+ # * :on_timeout_goto ("") - Optionally supply a label to branch to on timeout, by default will continue from the end of the match loop
445
+ # * :on_block_match_goto ("") - Optionally supply a label to branch to when block condition is met, by default will continue from the end of the match loop
446
+ # * :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
447
+ # * :force_fail_on_timeout (true) - force pattern to fail if timeout occurs
448
+ # * :global_loops (false) - whether match loop loops should use global labels
449
+ # * :manual_stop (false) - whether to use extra cpuB flag to resolve IG-XL v.3.50.xx bug where VBT clears cpuA immediately
450
+ # at start of PatFlagFunc instead of at end. Use will have to manually clear cpuB to resume this pattern.
451
+ # ==== Examples
452
+ # $tester.wait(:match => true, :time_in_us => 5000, :pin => $top.pin(:done), :state => :high) do
453
+ # <vectors>
454
+ # end
455
+ def match_block(timeout, options = {}, &block)
456
+ options = {
457
+ check_for_fails: false,
458
+ on_timeout_goto: false,
459
+ on_block_match_goto: false,
460
+ multiple_entries: false,
461
+ force_fail_on_timeout: true,
462
+ global_loops: false,
463
+ manual_stop: false,
464
+ clr_fail_post_match: false
465
+ }.merge(options)
466
+
467
+ unless block_given?
468
+ fail 'ERROR: block not passed to match_block!'
469
+ end
470
+
471
+ # if options[:check_for_fails]
472
+ # cc 'NOTE: check for fails prior to match loop not necessary on UltraFlex'
473
+ # end
474
+
475
+ # ss 'WARNING: MATCH LOOP FOR ULTRAFLEX STILL UNDER DEVELOPMENT'
476
+
477
+ # Create BlockArgs objects in order to receive multiple blocks
478
+ match_conditions = Origen::Utility::BlockArgs.new
479
+ fail_conditions = Origen::Utility::BlockArgs.new
480
+
481
+ # yield object to calling routine to get populated with blocks
482
+ if block.arity > 0
483
+ yield match_conditions, fail_conditions
484
+ else
485
+ # for backwards compatibility with Origen core call to match_block
486
+ match_conditions.add(&block)
487
+ fail_conditions.add(&block)
488
+ end
489
+
490
+ if options[:check_for_fails]
491
+ if options[:multiple_entries]
492
+ @match_entries.times do |i|
493
+ microcode "global subr match_done_#{i}:"
494
+ set_code(i + 100)
495
+ cycle(microcode: 'jump call_tester') unless i == @match_entries - 1
496
+ end
497
+ microcode 'call_tester:'
498
+ else
499
+ set_code(100)
500
+ end
501
+ cc 'Wait for any prior failures to propagate through the pipeline'
502
+ cycle(microcode: 'pipe_minus 1')
503
+ cc 'Now handshake with the tester to bin out and parts that have failed before they got here'
504
+ handshake(manual_stop: options[:manual_stop])
505
+ end
506
+
507
+ # Now do the main match loop
508
+ cc 'Start the match loop'
509
+
510
+ cycle # (:microcode => "set_msb #{counter_msb}") # set_msb microcode will be set below after counting match loop cycles
511
+ set_msb_vector = last_vector # remember the vector with set_msb opcode
512
+
513
+ cycle(microcode: 'branch_expr = (fail)')
514
+
515
+ global_opt = (options[:global_loops]) ? 'global ' : ''
516
+ microcode "#{global_opt}match_loop_#{@unique_counter}:"
517
+
518
+ cycle # (:microcode => "set c0 #{counter_lsb}")
519
+ set_c0_vector = last_vector # remember the vector with set_c0 opcode
520
+
521
+ microcode "match_result_loop_#{@unique_counter}:"
522
+ cycle(microcode: 'loop c0')
523
+
524
+ # count cycles in match loop block passed to help with meeting
525
+ # desired timeout value (have to back assign microcodes above)
526
+ prematch_cycle_count = cycle_count
527
+ match_conditions.each_with_index do |condition, i|
528
+ mask_fails(true)
529
+ condition.call # match condition
530
+ mask_fails(false)
531
+
532
+ cc ' Wait for the result to propagate through the pipeline'
533
+ cycle(microcode: 'pipe_minus 1')
534
+ inc_cycle_count(@pipeline_depth - 1) # Account for pipeline depth
535
+ cc "Branch if block condition #{i} not yet met"
536
+ cycle(microcode: "if (branch_expr) jump block_#{i}_notyet_matched_#{@unique_counter}")
537
+ cc 'Match found'
538
+ cycle(microcode: 'pop_loop')
539
+ if options[:on_block_match_goto]
540
+ if options[:on_block_match_goto].is_a?(Hash)
541
+ if options[:on_block_match_goto][i]
542
+ custom_jump = options[:on_block_match_goto][i]
543
+ else
544
+ custom_jump = nil
545
+ end
546
+ else
547
+ custom_jump = options[:on_block_match_goto]
548
+ end
549
+ end
550
+ if custom_jump
551
+ cycle(microcode: "jump #{custom_jump}")
552
+ else
553
+ cycle(microcode: "jump match_loop_end_#{@unique_counter}")
554
+ end
555
+ cc 'Match not yet found'
556
+ cycle(microcode: "block_#{i}_notyet_matched_#{@unique_counter}:")
557
+ end
558
+
559
+ match_conditions_cycle_count = cycle_count - prematch_cycle_count
560
+ cc "Match loop cycle count = #{match_conditions_cycle_count}"
561
+
562
+ # reduce timeout requested by match loop cycle count
563
+ timeout = (timeout.to_f / match_conditions_cycle_count).ceil
564
+
565
+ # Calculate the counter values appropriately hit the timeout requested
566
+ match_delay_cycles = false
567
+
568
+ # Determine full value of counter0
569
+ counter_value = timeout.to_f.floor
570
+
571
+ if counter_value < (2**@counter_lsb_bits)
572
+ # small value, don't need msb temp register
573
+ counter_msb = 1
574
+ counter_lsb = counter_value
575
+ elsif counter_value < (2**(@counter_lsb_bits + @counter_msb_bits))
576
+ # larger value, but smaller than counter maximum
577
+ counter_msb = counter_value # set MSB (lowest LSB bits get ignored)
578
+ counter_lsb = counter_value & (2**@counter_lsb_bits - 1) # set LSB
579
+ elsif counter_value < (2**(@counter_lsb_bits + @counter_msb_bits)) * @max_repeat_loop
580
+ # larger value, greater than counter, so add time delay per instance of loop to avoid using second counter
581
+ match_delay_cycles = (counter_value.to_f / (2**(@counter_lsb_bits + @counter_msb_bits))).ceil
582
+ counter_msb = (counter_value / match_delay_cycles).floor # set MSB (lowest LSB bits get ignored)
583
+ counter_lsb = counter_msb & (2**@counter_lsb_bits - 1) # set LSB
584
+ else
585
+ abort 'ERROR: timeout value too large in tester match method!'
586
+ end
587
+
588
+ # retroactively modify the counters based on cycles in match loop conditions
589
+ set_msb_vector.microcode = "set_msb #{counter_msb}"
590
+ set_c0_vector.microcode = "set c0 #{counter_lsb}"
591
+
592
+ if match_delay_cycles
593
+ cc 'Delay to meet timeout value'
594
+ cycle(repeat: match_delay_cycles) if match_delay_cycles
595
+ end
596
+
597
+ cycle(microcode: "end_loop match_result_loop_#{@unique_counter}")
598
+
599
+ if options[:force_fail_on_timeout]
600
+ cc 'To get here something has gone wrong, check blocks again to force a pattern failure'
601
+ fail_conditions.each do |condition|
602
+ cycle(microcode: 'pipe_minus 1')
603
+ condition.call
604
+ end
605
+ end
606
+ if options[:on_timeout_goto]
607
+ cycle(microcode: "jump #{options[:on_timeout_goto]}")
608
+ else
609
+ cycle(microcode: "jump match_loop_end_#{@unique_counter}")
610
+ end
611
+ cycle(microcode: "match_loop_end_#{@unique_counter}:")
612
+
613
+ @unique_counter += 1 # Increment so a different label will be applied if another
614
+ # handshake is called in the same pattern
615
+ end
616
+
617
+ # Handshake with the tester.
618
+ #
619
+ # Will set a cpu flag (A) and wait for it to be cleared by the tester, optionally
620
+ # pass in a read code to pass information to the tester.
621
+ #
622
+ # ==== Examples
623
+ # $tester.handshake # Pass control to the tester for a measurement
624
+ # $tester.handshake(:readcode => 10) # Trigger a specific action by the tester
625
+ def handshake(options = {})
626
+ options = {
627
+ readcode: false,
628
+ manual_stop: false, # set a 2nd CPU flag in case 1st flag is automatically cleared
629
+ }.merge(options)
630
+ if options[:readcode]
631
+ set_code(options[:readcode])
632
+ end
633
+ if options[:manual_stop]
634
+ cycle(microcode: "#{@microcode[:enable]} (#{@flags[1]})")
635
+ cycle(microcode: "#{@microcode[:set_flag]} (#{@flags[0]} #{@flags[1]})")
636
+ else
637
+ cycle(microcode: "#{@microcode[:enable]} (#{@flags[0]})")
638
+ cycle(microcode: "#{@microcode[:set_flag]} (#{@flags[0]})")
639
+ end
640
+ cycle(microcode: "loop_here_#{@unique_counter}: if (branch_expr) jump loop_here_#{@unique_counter}")
641
+
642
+ @unique_counter += 1 # Increment so a different label will be applied if another
643
+ # handshake is called in the same pattern
644
+ end
645
+
646
+ def keep_alive(options = {})
647
+ if options[:subroutine_pat]
648
+ cycle(microcode: 'clr_subr')
649
+ cycle(microcode: "#{@microcode[:enable]} (#{@flags[3]})")
650
+ cycle(microcode: "#{@microcode[:set_flag]} (#{@flags[3]})")
651
+ cycle(microcode: "loop_here_#{@unique_counter}: if (branch_expr) jump loop_here_#{@unique_counter}")
652
+ cycle
653
+ @unique_counter += 1 # Increment so a different label will be applied if another
654
+ else
655
+ $tester.cycle
656
+ call_subroutine('keep_alive')
657
+ end
658
+ end
659
+
660
+ # Capture a vector to the tester HRAM.
661
+ #
662
+ # This method applys a store vector (stv) opcode to the previous vector, note that is does
663
+ # not actually generate a new vector.
664
+ #
665
+ # Sometimes when generating vectors within a loop you may want to apply a stv opcode
666
+ # retrospectively to a previous vector, passing in an offset option will allow you
667
+ # to do this.
668
+ #
669
+ # On J750 the pins argument is ignored since the tester only supports whole vector capture.
670
+ #
671
+ # @example
672
+ # $tester.cycle # This is the vector you want to capture
673
+ # $tester.store # This applys the STV opcode
674
+ #
675
+ # $tester.cycle # This one gets stored
676
+ # $tester.cycle
677
+ # $tester.cycle
678
+ # $tester.store(:offset => -2) # Just realized I need to capture that earlier vector
679
+ def store(*pins)
680
+ options = pins.last.is_a?(Hash) ? pins.pop : {}
681
+ options = { offset: 0,
682
+ opcode: 'stv'
683
+ }.merge(options)
684
+ pins = pins.flatten.compact
685
+ if pins.empty?
686
+ fail 'For the UltraFLEX you must supply the pins to store/capture'
687
+ end
688
+
689
+ capt_style = options[:capture_style].nil? ? @capture_style : options[:capture_style]
690
+ if capt_style == :digcap
691
+ capt_microcode = dssc_store(pins, options)
692
+ else
693
+ capt_microcode = options[:opcode]
694
+ end
695
+
696
+ pins.each do |pin|
697
+ pin.restore_state do
698
+ pin.capture
699
+ update_vector_pin_val pin, offset: options[:offset]
700
+ last_vector(options[:offset]).dont_compress = true
701
+ end
702
+ end
703
+ update_vector microcode: capt_microcode, offset: options[:offset]
704
+ end
705
+ alias_method :to_hram, :store
706
+ alias_method :capture, :store
707
+
708
+ # use digcap to store, called by tester.store()
709
+ def dssc_store(pins, options)
710
+ repeat_count = last_vector(options[:offset]).repeat
711
+ capt_microcode = []
712
+ pins.each do |pin|
713
+ if @capture_history[pin.name].nil?
714
+ @capture_history[pin.name] = { is_digcap: true, count: repeat_count }
715
+ else
716
+ @capture_history[pin.name][:count] += repeat_count
717
+ end
718
+ capt_microcode << "((#{pin.name}):DigCap = Store)"
719
+ end
720
+ capt_microcode << 'stv'
721
+ capt_microcode.join(',')
722
+ end
723
+
724
+ def reload_counters(name)
725
+ microcode "reload #{name}"
726
+ end
727
+
728
+ def set_msb(integer)
729
+ microcode "set_msb #{integer}"
730
+ end
731
+
732
+ # Capture the next vector generated to HRAM
733
+ #
734
+ # This method applies a store vector (stv) opcode to the next vector to be generated,
735
+ # note that is does not actually generate a new vector.
736
+ #
737
+ # pin argument must be provided so that 'V' (valid) state can be applied to the pin
738
+ # if not already.
739
+ #
740
+ # @example
741
+ # $tester.store_next_cycle
742
+ # $tester.cycle # This is the vector that will be captured
743
+ def store_next_cycle(*pins)
744
+ options = pins.last.is_a?(Hash) ? pins.pop : {}
745
+ options = {
746
+ opcode: 'stv'
747
+ }.merge(options)
748
+ pins = pins.flatten.compact
749
+ if pins.empty?
750
+ fail 'For the UltraFLEX you must supply the pins to store/capture'
751
+ end
752
+
753
+ capt_style = options[:capture_style].nil? ? @capture_style : options[:capture_style]
754
+ if capt_style == :digcap
755
+ capt_microcode = []
756
+ repeat_count = options[:repeat].nil? ? 1 : options[:repeat]
757
+ pins.each do |pin|
758
+ if @capture_history[pin.name].nil?
759
+ @capture_history[pin.name] = { is_digcap: true, count: repeat_count }
760
+ else
761
+ @capture_history[pin.name][:count] += repeat_count
762
+ end
763
+ capt_microcode << "((#{pin.name}):DigCap = Store)"
764
+ end
765
+ capt_microcode << 'stv'
766
+ capt_microcode = capt_microcode.join(',')
767
+ else
768
+ capt_microcode = options[:opcode]
769
+ end
770
+
771
+ pins.each { |pin| pin.save; pin.capture }
772
+ # Register this clean up function to be run after the next vector
773
+ # is generated (SMcG: cool or what! DH: Yes, very cool!)
774
+ preset_next_vector(microcode: capt_microcode) do
775
+ pins.each(&:restore)
776
+ end
777
+ end
778
+ alias_method :store!, :store_next_cycle
779
+
780
+ # ate_hardware stores "key" UltraFLEX hardware information needed for test program generation
781
+ # Instrument types available for ppmu: "HSD-M", "HSD-U", "HSD-4G", and "HSS-6G".
782
+ # Sample usage: $tester.ate_hardware("HSD-U").ppmu
783
+ # Instrument types available for supply: "VSM", "VSMx2", "VSMx4", "HexVS", "HexVSx2", "HexVSx4",
784
+ # "HexVSx6", "HexVS+x2", "HexVS+x4", "HexVS+x6", "HDVS1", "HDVS1x2", "HDVS1x4", "VHDVS",
785
+ # "VHDVS_HC", "VHDVSx2", "VHDVS_HCx2", "VHDVS_HCx4", "VHDVS_HCx8", "VHDVS+", "VHDVS_HC+",
786
+ # "VHDVS+x2", "VHDVS_HC+x2", "VHDVS_HC+x4", and "VHDVS_HC+x8".
787
+ # HDVS1 is also known as HDVS. VHDVS is also known as UVS256.
788
+ # x2 is Merged2, x4 is Merged4, x6 is Merged6. _HC is High-Current.
789
+ # + is High-Accuracy.
790
+ # Sample usage: $tester.ate_hardware("VSM").supply
791
+ # Sample usage: $tester.ate_hardware("HSD-M").ppmu
792
+ def ate_hardware(instrumentname = '')
793
+ @ate_hardware = ATEHardware.new(instrumentname)
794
+ end
795
+ end
796
+ end
797
+ UltraFLEX = IGXLBasedTester::UltraFLEX
798
+ end