origen_testers 0.9.9 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (254) hide show
  1. checksums.yaml +4 -4
  2. data/config/application.rb +151 -151
  3. data/config/boot.rb +13 -12
  4. data/config/commands.rb +86 -86
  5. data/config/users.rb +18 -18
  6. data/config/version.rb +8 -8
  7. data/lib/commands/build.rb +69 -69
  8. data/lib/commands/run.rb +48 -48
  9. data/lib/origen_testers.rb +47 -46
  10. data/lib/origen_testers/api.rb +381 -292
  11. data/lib/origen_testers/basic_test_setups.rb +105 -105
  12. data/lib/origen_testers/callback_handlers.rb +59 -59
  13. data/lib/origen_testers/command_based_tester.rb +45 -45
  14. data/lib/origen_testers/flow.rb +382 -382
  15. data/lib/origen_testers/generator.rb +283 -283
  16. data/lib/origen_testers/generator/identity_map.rb +23 -23
  17. data/lib/origen_testers/generator/placeholder.rb +11 -11
  18. data/lib/origen_testers/generator/test_numberer.rb +23 -23
  19. data/lib/origen_testers/igxl_based_tester.rb +12 -12
  20. data/lib/origen_testers/igxl_based_tester/base.rb +1095 -929
  21. data/lib/origen_testers/igxl_based_tester/base/ac_specsets.rb +79 -79
  22. data/lib/origen_testers/igxl_based_tester/base/custom_test_instance.rb +169 -169
  23. data/lib/origen_testers/igxl_based_tester/base/dc_specsets.rb +98 -98
  24. data/lib/origen_testers/igxl_based_tester/base/edge.rb +60 -60
  25. data/lib/origen_testers/igxl_based_tester/base/edges.rb +24 -24
  26. data/lib/origen_testers/igxl_based_tester/base/edgeset.rb +39 -39
  27. data/lib/origen_testers/igxl_based_tester/base/edgesets.rb +130 -130
  28. data/lib/origen_testers/igxl_based_tester/base/flow.rb +446 -446
  29. data/lib/origen_testers/igxl_based_tester/base/flow_line.rb +276 -276
  30. data/lib/origen_testers/igxl_based_tester/base/generator.rb +607 -607
  31. data/lib/origen_testers/igxl_based_tester/base/global_specs.rb +83 -83
  32. data/lib/origen_testers/igxl_based_tester/base/job.rb +75 -75
  33. data/lib/origen_testers/igxl_based_tester/base/jobs.rb +44 -44
  34. data/lib/origen_testers/igxl_based_tester/base/level_io_se.rb +59 -59
  35. data/lib/origen_testers/igxl_based_tester/base/level_supply.rb +39 -39
  36. data/lib/origen_testers/igxl_based_tester/base/levels.rb +31 -31
  37. data/lib/origen_testers/igxl_based_tester/base/levelset.rb +110 -110
  38. data/lib/origen_testers/igxl_based_tester/base/patgroup.rb +109 -109
  39. data/lib/origen_testers/igxl_based_tester/base/patgroups.rb +38 -38
  40. data/lib/origen_testers/igxl_based_tester/base/patset.rb +68 -68
  41. data/lib/origen_testers/igxl_based_tester/base/patset_pattern.rb +56 -56
  42. data/lib/origen_testers/igxl_based_tester/base/patsets.rb +38 -38
  43. data/lib/origen_testers/igxl_based_tester/base/patsubr.rb +68 -68
  44. data/lib/origen_testers/igxl_based_tester/base/patsubr_pattern.rb +56 -56
  45. data/lib/origen_testers/igxl_based_tester/base/patsubrs.rb +38 -38
  46. data/lib/origen_testers/igxl_based_tester/base/pinmap.rb +93 -93
  47. data/lib/origen_testers/igxl_based_tester/base/references.rb +25 -25
  48. data/lib/origen_testers/igxl_based_tester/base/test_instance.rb +322 -322
  49. data/lib/origen_testers/igxl_based_tester/base/test_instance_group.rb +66 -66
  50. data/lib/origen_testers/igxl_based_tester/base/test_instances.rb +212 -212
  51. data/lib/origen_testers/igxl_based_tester/base/test_instances/custom_til.rb +37 -37
  52. data/lib/origen_testers/igxl_based_tester/base/timeset.rb +37 -37
  53. data/lib/origen_testers/igxl_based_tester/base/timesets.rb +49 -49
  54. data/lib/origen_testers/igxl_based_tester/base/timesets_basic.rb +49 -49
  55. data/lib/origen_testers/igxl_based_tester/files.rb +43 -43
  56. data/lib/origen_testers/igxl_based_tester/j750.rb +269 -269
  57. data/lib/origen_testers/igxl_based_tester/j750/custom_test_instance.rb +32 -32
  58. data/lib/origen_testers/igxl_based_tester/j750/flow.rb +10 -10
  59. data/lib/origen_testers/igxl_based_tester/j750/flow_line.rb +19 -19
  60. data/lib/origen_testers/igxl_based_tester/j750/generator.rb +19 -19
  61. data/lib/origen_testers/igxl_based_tester/j750/patgroup.rb +9 -9
  62. data/lib/origen_testers/igxl_based_tester/j750/patgroups.rb +10 -10
  63. data/lib/origen_testers/igxl_based_tester/j750/patset.rb +9 -9
  64. data/lib/origen_testers/igxl_based_tester/j750/patset_pattern.rb +18 -18
  65. data/lib/origen_testers/igxl_based_tester/j750/patsets.rb +10 -10
  66. data/lib/origen_testers/igxl_based_tester/j750/patsubr.rb +9 -9
  67. data/lib/origen_testers/igxl_based_tester/j750/patsubr_pattern.rb +18 -18
  68. data/lib/origen_testers/igxl_based_tester/j750/patsubrs.rb +10 -10
  69. data/lib/origen_testers/igxl_based_tester/j750/test_instance.rb +746 -746
  70. data/lib/origen_testers/igxl_based_tester/j750/test_instance_group.rb +9 -9
  71. data/lib/origen_testers/igxl_based_tester/j750/test_instances.rb +10 -10
  72. data/lib/origen_testers/igxl_based_tester/j750_hpt.rb +34 -34
  73. data/lib/origen_testers/igxl_based_tester/j750_hpt/custom_test_instance.rb +32 -32
  74. data/lib/origen_testers/igxl_based_tester/j750_hpt/flow.rb +9 -9
  75. data/lib/origen_testers/igxl_based_tester/j750_hpt/flow_line.rb +9 -9
  76. data/lib/origen_testers/igxl_based_tester/j750_hpt/generator.rb +19 -19
  77. data/lib/origen_testers/igxl_based_tester/j750_hpt/patgroup.rb +9 -9
  78. data/lib/origen_testers/igxl_based_tester/j750_hpt/patgroups.rb +9 -9
  79. data/lib/origen_testers/igxl_based_tester/j750_hpt/patset.rb +9 -9
  80. data/lib/origen_testers/igxl_based_tester/j750_hpt/patset_pattern.rb +9 -9
  81. data/lib/origen_testers/igxl_based_tester/j750_hpt/patsets.rb +9 -9
  82. data/lib/origen_testers/igxl_based_tester/j750_hpt/patsubr.rb +9 -9
  83. data/lib/origen_testers/igxl_based_tester/j750_hpt/patsubr_pattern.rb +9 -9
  84. data/lib/origen_testers/igxl_based_tester/j750_hpt/patsubrs.rb +9 -9
  85. data/lib/origen_testers/igxl_based_tester/j750_hpt/test_instance.rb +599 -599
  86. data/lib/origen_testers/igxl_based_tester/j750_hpt/test_instance_group.rb +9 -9
  87. data/lib/origen_testers/igxl_based_tester/j750_hpt/test_instances.rb +9 -9
  88. data/lib/origen_testers/igxl_based_tester/parser.rb +102 -102
  89. data/lib/origen_testers/igxl_based_tester/parser/ac_spec.rb +9 -9
  90. data/lib/origen_testers/igxl_based_tester/parser/dc_spec.rb +33 -33
  91. data/lib/origen_testers/igxl_based_tester/parser/dc_specs.rb +48 -48
  92. data/lib/origen_testers/igxl_based_tester/parser/descriptions.rb +339 -339
  93. data/lib/origen_testers/igxl_based_tester/parser/flow.rb +109 -109
  94. data/lib/origen_testers/igxl_based_tester/parser/flow_line.rb +203 -203
  95. data/lib/origen_testers/igxl_based_tester/parser/flows.rb +21 -21
  96. data/lib/origen_testers/igxl_based_tester/parser/pattern_set.rb +92 -92
  97. data/lib/origen_testers/igxl_based_tester/parser/pattern_sets.rb +31 -31
  98. data/lib/origen_testers/igxl_based_tester/parser/test_instance.rb +420 -420
  99. data/lib/origen_testers/igxl_based_tester/parser/test_instances.rb +24 -24
  100. data/lib/origen_testers/igxl_based_tester/parser/timeset.rb +13 -13
  101. data/lib/origen_testers/igxl_based_tester/ultraflex.rb +798 -691
  102. data/lib/origen_testers/igxl_based_tester/ultraflex/ac_specsets.rb +10 -10
  103. data/lib/origen_testers/igxl_based_tester/ultraflex/ate_hardware.rb +949 -949
  104. data/lib/origen_testers/igxl_based_tester/ultraflex/custom_test_instance.rb +36 -36
  105. data/lib/origen_testers/igxl_based_tester/ultraflex/dc_specsets.rb +10 -10
  106. data/lib/origen_testers/igxl_based_tester/ultraflex/edge.rb +9 -9
  107. data/lib/origen_testers/igxl_based_tester/ultraflex/edges.rb +9 -9
  108. data/lib/origen_testers/igxl_based_tester/ultraflex/edgeset.rb +9 -9
  109. data/lib/origen_testers/igxl_based_tester/ultraflex/edgesets.rb +10 -10
  110. data/lib/origen_testers/igxl_based_tester/ultraflex/flow.rb +158 -158
  111. data/lib/origen_testers/igxl_based_tester/ultraflex/flow_line.rb +19 -19
  112. data/lib/origen_testers/igxl_based_tester/ultraflex/generator.rb +19 -19
  113. data/lib/origen_testers/igxl_based_tester/ultraflex/global_specs.rb +10 -10
  114. data/lib/origen_testers/igxl_based_tester/ultraflex/job.rb +9 -9
  115. data/lib/origen_testers/igxl_based_tester/ultraflex/jobs.rb +10 -10
  116. data/lib/origen_testers/igxl_based_tester/ultraflex/level_io_se.rb +9 -9
  117. data/lib/origen_testers/igxl_based_tester/ultraflex/level_supply.rb +9 -9
  118. data/lib/origen_testers/igxl_based_tester/ultraflex/levels.rb +9 -9
  119. data/lib/origen_testers/igxl_based_tester/ultraflex/levelset.rb +10 -10
  120. data/lib/origen_testers/igxl_based_tester/ultraflex/patgroup.rb +9 -9
  121. data/lib/origen_testers/igxl_based_tester/ultraflex/patgroups.rb +10 -10
  122. data/lib/origen_testers/igxl_based_tester/ultraflex/patset.rb +9 -9
  123. data/lib/origen_testers/igxl_based_tester/ultraflex/patset_pattern.rb +18 -18
  124. data/lib/origen_testers/igxl_based_tester/ultraflex/patsets.rb +10 -10
  125. data/lib/origen_testers/igxl_based_tester/ultraflex/patsubr.rb +9 -9
  126. data/lib/origen_testers/igxl_based_tester/ultraflex/patsubr_pattern.rb +18 -18
  127. data/lib/origen_testers/igxl_based_tester/ultraflex/patsubrs.rb +10 -10
  128. data/lib/origen_testers/igxl_based_tester/ultraflex/pinmap.rb +10 -10
  129. data/lib/origen_testers/igxl_based_tester/ultraflex/references.rb +10 -10
  130. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/ac_specsets.txt.erb +0 -0
  131. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/dc_specsets.txt.erb +0 -0
  132. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/edgesets.txt.erb +0 -0
  133. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/global_specs.txt.erb +0 -0
  134. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/jobs.txt.erb +0 -0
  135. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/levelset.txt.erb +0 -0
  136. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/pinmap.txt.erb +0 -0
  137. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/references.txt.erb +0 -0
  138. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/timesets.txt.erb +0 -0
  139. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/timesets_basic.txt.erb +0 -0
  140. data/lib/origen_testers/igxl_based_tester/ultraflex/test_instance.rb +315 -315
  141. data/lib/origen_testers/igxl_based_tester/ultraflex/test_instance_group.rb +9 -9
  142. data/lib/origen_testers/igxl_based_tester/ultraflex/test_instances.rb +10 -10
  143. data/lib/origen_testers/igxl_based_tester/ultraflex/timeset.rb +9 -9
  144. data/lib/origen_testers/igxl_based_tester/ultraflex/timesets.rb +10 -10
  145. data/lib/origen_testers/igxl_based_tester/ultraflex/timesets_basic.rb +10 -10
  146. data/lib/origen_testers/interface.rb +328 -328
  147. data/lib/origen_testers/memory_style.rb +77 -0
  148. data/lib/origen_testers/no_interface.rb +7 -7
  149. data/lib/origen_testers/origen_ext/application/runner.rb +25 -25
  150. data/lib/origen_testers/origen_ext/generator.rb +54 -54
  151. data/lib/origen_testers/origen_ext/generator/flow.rb +77 -77
  152. data/lib/origen_testers/origen_ext/generator/resources.rb +21 -21
  153. data/lib/origen_testers/origen_ext/pins/pin.rb +78 -78
  154. data/lib/origen_testers/origen_ext/pins/pin_collection.rb +84 -84
  155. data/lib/origen_testers/parser.rb +22 -22
  156. data/lib/origen_testers/parser/description_lookup.rb +62 -62
  157. data/lib/origen_testers/parser/searchable_array.rb +30 -30
  158. data/lib/origen_testers/parser/searchable_hash.rb +30 -30
  159. data/lib/origen_testers/pattern_compilers.rb +116 -116
  160. data/lib/origen_testers/pattern_compilers/assembler.rb +88 -88
  161. data/lib/origen_testers/pattern_compilers/job.rb +96 -96
  162. data/lib/origen_testers/pattern_compilers/ultraflex_pattern_compiler.rb +599 -599
  163. data/lib/origen_testers/program_generators.rb +62 -62
  164. data/lib/origen_testers/smartest_based_tester.rb +8 -8
  165. data/lib/origen_testers/smartest_based_tester/base.rb +562 -492
  166. data/lib/origen_testers/smartest_based_tester/base/flow.rb +279 -279
  167. data/lib/origen_testers/smartest_based_tester/base/generator.rb +193 -193
  168. data/lib/origen_testers/smartest_based_tester/base/pattern_compiler.rb +32 -32
  169. data/lib/origen_testers/smartest_based_tester/base/pattern_master.rb +69 -69
  170. data/lib/origen_testers/smartest_based_tester/base/processors.rb +13 -13
  171. data/lib/origen_testers/smartest_based_tester/base/processors/empty_branch_cleaner.rb +49 -49
  172. data/lib/origen_testers/smartest_based_tester/base/processors/extract_set_variables.rb +22 -22
  173. data/lib/origen_testers/smartest_based_tester/base/processors/flag_optimizer.rb +143 -143
  174. data/lib/origen_testers/smartest_based_tester/base/processors/if_ran_cleaner.rb +34 -34
  175. data/lib/origen_testers/smartest_based_tester/base/test_method.rb +164 -164
  176. data/lib/origen_testers/smartest_based_tester/base/test_methods.rb +73 -73
  177. data/lib/origen_testers/smartest_based_tester/base/test_methods/ac_tml.rb +33 -33
  178. data/lib/origen_testers/smartest_based_tester/base/test_methods/base_tml.rb +38 -38
  179. data/lib/origen_testers/smartest_based_tester/base/test_methods/custom_tml.rb +19 -19
  180. data/lib/origen_testers/smartest_based_tester/base/test_methods/dc_tml.rb +147 -147
  181. data/lib/origen_testers/smartest_based_tester/base/test_methods/limits.rb +65 -65
  182. data/lib/origen_testers/smartest_based_tester/base/test_suite.rb +193 -193
  183. data/lib/origen_testers/smartest_based_tester/base/test_suites.rb +54 -54
  184. data/lib/origen_testers/smartest_based_tester/base/variables_file.rb +38 -38
  185. data/lib/origen_testers/smartest_based_tester/v93k.rb +8 -8
  186. data/lib/origen_testers/smartest_based_tester/v93k/builder.rb +89 -89
  187. data/lib/origen_testers/smartest_based_tester/v93k/builder/flow.rb +181 -181
  188. data/lib/origen_testers/smartest_based_tester/v93k/builder/pattern_master.rb +54 -54
  189. data/lib/origen_testers/smartest_based_tester/v93k/flow.rb +10 -10
  190. data/lib/origen_testers/smartest_based_tester/v93k/generator.rb +19 -19
  191. data/lib/origen_testers/smartest_based_tester/v93k/pattern_compiler.rb +10 -10
  192. data/lib/origen_testers/smartest_based_tester/v93k/pattern_master.rb +10 -10
  193. data/lib/origen_testers/smartest_based_tester/v93k/templates/template.aiv.erb +17 -17
  194. data/lib/origen_testers/smartest_based_tester/v93k/templates/template.pmfl.erb +13 -13
  195. data/lib/origen_testers/smartest_based_tester/v93k/templates/template.tf.erb +214 -214
  196. data/lib/origen_testers/smartest_based_tester/v93k/templates/vars.tf.erb +48 -48
  197. data/lib/origen_testers/smartest_based_tester/v93k/test_method.rb +9 -9
  198. data/lib/origen_testers/smartest_based_tester/v93k/test_methods.rb +9 -9
  199. data/lib/origen_testers/smartest_based_tester/v93k/test_suite.rb +9 -9
  200. data/lib/origen_testers/smartest_based_tester/v93k/test_suites.rb +9 -9
  201. data/lib/origen_testers/smartest_based_tester/v93k/variables_file.rb +10 -10
  202. data/lib/origen_testers/test/basic_interface.rb +17 -17
  203. data/lib/origen_testers/test/block.rb +21 -21
  204. data/lib/origen_testers/test/custom_test_interface.rb +111 -111
  205. data/lib/origen_testers/test/dut.rb +295 -295
  206. data/lib/origen_testers/test/dut2.rb +76 -76
  207. data/lib/origen_testers/test/dut3.rb +244 -0
  208. data/lib/origen_testers/test/interface.rb +503 -503
  209. data/lib/origen_testers/test/nvm.rb +94 -94
  210. data/lib/origen_testers/timing.rb +362 -362
  211. data/lib/origen_testers/vector.rb +207 -207
  212. data/lib/origen_testers/vector_based_tester.rb +41 -41
  213. data/lib/origen_testers/vector_generator.rb +655 -655
  214. data/lib/origen_testers/vector_pipeline.rb +302 -302
  215. data/pattern/bitmap.rb +7 -7
  216. data/pattern/dc_instr.rb +7 -7
  217. data/pattern/delay.rb +7 -7
  218. data/pattern/freq_counter.rb +6 -6
  219. data/pattern/mem_test.rb +8 -8
  220. data/pattern/multi_vector.rb +122 -122
  221. data/pattern/multi_vector_plus1.rb +125 -125
  222. data/pattern/nvm/j750/add_late_pins.rb +3 -3
  223. data/pattern/nvm/j750/iterator_postfix_test_x_bx.rb +8 -8
  224. data/pattern/nvm/j750/iterator_test_x_bx.rb +8 -8
  225. data/pattern/nvm/j750/j750_halt.rb +159 -159
  226. data/pattern/nvm/j750/j750_workout.rb +209 -209
  227. data/pattern/nvm/j750/timing.rb +73 -73
  228. data/pattern/read_write_reg.rb +61 -61
  229. data/pattern/reset.rb +4 -4
  230. data/pattern/subroutines.rb +69 -69
  231. data/pattern/tester_overlay.rb +53 -0
  232. data/pattern/tester_store.rb +29 -0
  233. data/program/_additional_erase.rb +7 -7
  234. data/program/_efa_resources.rb +7 -7
  235. data/program/_erase.rb +25 -25
  236. data/program/_erase_vfy.rb +5 -5
  237. data/program/_iv_resources.rb +10 -10
  238. data/program/basic_interface.rb +5 -5
  239. data/program/components/_temp.rb +6 -6
  240. data/program/custom_tests.rb +10 -10
  241. data/program/flow_control.rb +321 -321
  242. data/program/prb1.rb +219 -219
  243. data/program/prb1_resources.rb +28 -28
  244. data/program/prb2.rb +27 -27
  245. data/program/test.rb +29 -29
  246. data/program/uflex_resources.rb +199 -199
  247. data/templates/example.txt.erb +53 -53
  248. data/templates/j750/program_sheet.txt.erb +9 -9
  249. data/templates/manifest/v93k.yaml.erb +22 -22
  250. data/templates/web/index.md.erb +51 -51
  251. data/templates/web/layouts/_basic.html.erb +15 -15
  252. data/templates/web/partials/_navbar.html.erb +22 -22
  253. data/templates/web/release_notes.md.erb +5 -5
  254. metadata +7 -3
@@ -1,62 +1,62 @@
1
- require 'active_support/concern'
2
- module OrigenTesters
3
- # Include this module to create an interface that supports multiple tester
4
- # types.
5
- #
6
- # This module will expose generators for all test platforms supported by
7
- # the Testers plugin.
8
- module ProgramGenerators
9
- extend ActiveSupport::Concern
10
- include Interface
11
-
12
- PLATFORMS = [J750, J750_HPT, UltraFLEX, V93K]
13
-
14
- included do
15
- Origen.add_interface(self)
16
- end
17
-
18
- module ClassMethods
19
- # Ensures that the correct generator is loaded before initialize is called
20
- def new(*args, &block)
21
- x = allocate
22
- x._load_generator
23
- x.send(:initialize, *args, &block)
24
- x
25
- end
26
-
27
- # Returns true if the interface class supports the
28
- # given tester instance
29
- def supports?(tester_instance)
30
- PLATFORMS.include?(tester_instance.class)
31
- end
32
- end
33
-
34
- # @api private
35
- def pre_initialize(options = {})
36
- _load_generator
37
- end
38
-
39
- def initialize(options = {})
40
- end
41
-
42
- def tester
43
- Origen.tester
44
- end
45
-
46
- def _load_generator
47
- if tester.v93k?
48
- class << self; include OrigenTesters::V93K::Generator; end
49
- elsif tester.j750_hpt?
50
- class << self; include OrigenTesters::J750_HPT::Generator; end
51
- elsif tester.j750?
52
- class << self; include OrigenTesters::J750::Generator; end
53
- elsif tester.ultraflex?
54
- class << self; include OrigenTesters::UltraFLEX::Generator; end
55
- elsif defined? tester.class::TEST_PROGRAM_GENERATOR
56
- class << self; include tester.class::TEST_PROGRAM_GENERATOR; end
57
- else
58
- fail "The OrigenTesters::ProgramGenerators module does not support #{tester.class}!"
59
- end
60
- end
61
- end
62
- end
1
+ require 'active_support/concern'
2
+ module OrigenTesters
3
+ # Include this module to create an interface that supports multiple tester
4
+ # types.
5
+ #
6
+ # This module will expose generators for all test platforms supported by
7
+ # the Testers plugin.
8
+ module ProgramGenerators
9
+ extend ActiveSupport::Concern
10
+ include Interface
11
+
12
+ PLATFORMS = [J750, J750_HPT, UltraFLEX, V93K]
13
+
14
+ included do
15
+ Origen.add_interface(self)
16
+ end
17
+
18
+ module ClassMethods
19
+ # Ensures that the correct generator is loaded before initialize is called
20
+ def new(*args, &block)
21
+ x = allocate
22
+ x._load_generator
23
+ x.send(:initialize, *args, &block)
24
+ x
25
+ end
26
+
27
+ # Returns true if the interface class supports the
28
+ # given tester instance
29
+ def supports?(tester_instance)
30
+ PLATFORMS.include?(tester_instance.class)
31
+ end
32
+ end
33
+
34
+ # @api private
35
+ def pre_initialize(options = {})
36
+ _load_generator
37
+ end
38
+
39
+ def initialize(options = {})
40
+ end
41
+
42
+ def tester
43
+ Origen.tester
44
+ end
45
+
46
+ def _load_generator
47
+ if tester.v93k?
48
+ class << self; include OrigenTesters::V93K::Generator; end
49
+ elsif tester.j750_hpt?
50
+ class << self; include OrigenTesters::J750_HPT::Generator; end
51
+ elsif tester.j750?
52
+ class << self; include OrigenTesters::J750::Generator; end
53
+ elsif tester.ultraflex?
54
+ class << self; include OrigenTesters::UltraFLEX::Generator; end
55
+ elsif defined? tester.class::TEST_PROGRAM_GENERATOR
56
+ class << self; include tester.class::TEST_PROGRAM_GENERATOR; end
57
+ else
58
+ fail "The OrigenTesters::ProgramGenerators module does not support #{tester.class}!"
59
+ end
60
+ end
61
+ end
62
+ end
@@ -1,8 +1,8 @@
1
- module OrigenTesters
2
- module SmartestBasedTester
3
- autoload :Base, 'origen_testers/smartest_based_tester/base'
4
- autoload :V93K, 'origen_testers/smartest_based_tester/v93k'
5
- end
6
- # Convenience/Legacy names without the SmartestBasedTester namespace
7
- autoload :V93K, 'origen_testers/smartest_based_tester/v93k'
8
- end
1
+ module OrigenTesters
2
+ module SmartestBasedTester
3
+ autoload :Base, 'origen_testers/smartest_based_tester/base'
4
+ autoload :V93K, 'origen_testers/smartest_based_tester/v93k'
5
+ end
6
+ # Convenience/Legacy names without the SmartestBasedTester namespace
7
+ autoload :V93K, 'origen_testers/smartest_based_tester/v93k'
8
+ end
@@ -1,492 +1,562 @@
1
- module OrigenTesters
2
- module SmartestBasedTester
3
- class Base
4
- include VectorBasedTester
5
-
6
- # Disable inline (end of vector) comments, enabled by default
7
- attr_accessor :inline_comments
8
-
9
- # Returns whether the tester has been configured to wrap top-level flow modules with an
10
- # enable or not.
11
- #
12
- # Returns nil if not.
13
- #
14
- # Returns :enabled if the enable is configured to be on by default, or :disabled if it is
15
- # configured to be off by default.
16
- attr_reader :add_flow_enable
17
-
18
- def initialize(options = {})
19
- @max_repeat_loop = 65_535
20
- @min_repeat_loop = 33
21
- @pat_extension = 'avc'
22
- @compress = true
23
- # @support_repeat_previous = true
24
- @match_entries = 10
25
- @name = 'v93k'
26
- @comment_char = '#'
27
- @level_period = true
28
- @inline_comments = true
29
- if options[:add_flow_enable]
30
- self.add_flow_enable = options[:add_flow_enable]
31
- end
32
- end
33
-
34
- # Set to :enabled to have all top-level flow modules wrapped by an enable flow variable
35
- # that is enabled by default (top-level flow has to disable modules it doesn't want).
36
- #
37
- # Set to :disabled to have the opposite, where the top-level flow has to enable all
38
- # modules.
39
- #
40
- # Note that the interface can override this setting for each flow during program generation.
41
- def add_flow_enable=(value)
42
- if value == :enable || value == :enabled
43
- @add_flow_enable = :enabled
44
- elsif value == :disable || value == :disabled
45
- @add_flow_enable = :disabled
46
- else
47
- fail "Unknown add_flow_enable value, #{value}, must be :enabled or :disabled"
48
- end
49
- end
50
-
51
- # Capture the pin data from a vector to the tester.
52
- #
53
- # This method uses the Digital Capture feature (Selective mode) of the V93000 to capture
54
- # the data from the given pins on the previous vector.
55
- # Note that is does not actually generate a new vector.
56
- #
57
- # Note also that any drive cycles on the target pins can also be captured, to avoid this
58
- # the wavetable should be set up like this to infer a 'D' (Don't Capture) on vectors where
59
- # the target pin is being used to drive data:
60
- #
61
- # PINS nvm_fail
62
- # 0 d1:0 r1:D 0
63
- # 1 d1:1 r1:D 1
64
- # 2 r1:C Capt
65
- # 3 r1:D NoCapt
66
- #
67
- # Sometimes when generating vectors within a loop you may want to apply a capture
68
- # retrospectively to a previous vector, passing in an offset option will allow you
69
- # to do this.
70
- #
71
- # ==== Examples
72
- # $tester.cycle # This is the vector you want to capture
73
- # $tester.store :pin => pin(:fail) # This applys the required opcode to the given pins
74
- #
75
- # $tester.cycle # This one gets captured
76
- # $tester.cycle
77
- # $tester.cycle
78
- # $tester.store(:pin => pin(:fail), :offset => -2) # Just realized I need to capture that earlier vector
79
- #
80
- # # Capturing multiple pins:
81
- # $tester.cycle
82
- # $tester.store :pins => [pin(:fail), pin(:done)]
83
- #
84
- # Since the V93K store operates on a pin level (rather than vector level as on the J750)
85
- # equivalent functionality can also be achieved by setting the store attribute of the pin
86
- # itself prior to calling $tester.cycle.
87
- # However it is recommended to use the tester API to do the store if cross-compatiblity with
88
- # other platforms, such as the J750, is required.
89
- def store(*pins)
90
- options = pins.last.is_a?(Hash) ? pins.pop : {}
91
- options = { offset: 0
92
- }.merge(options)
93
- pins = pins.flatten.compact
94
- if pins.empty?
95
- fail 'For the V93K you must supply the pins to store/capture'
96
- end
97
- pins.each do |pin|
98
- pin.restore_state do
99
- pin.capture
100
- update_vector_pin_val pin, offset: options[:offset]
101
- last_vector(options[:offset]).dont_compress = true
102
- last_vector(options[:offset]).contains_capture = true
103
- end
104
- end
105
- end
106
- alias_method :capture, :store
107
-
108
- # Same as the store method, except that the capture will be applied to the next
109
- # vector to be generated.
110
- #
111
- # @example
112
- # $tester.store_next_cycle
113
- # $tester.cycle # This is the vector that will be captured
114
- def store_next_cycle(*pins)
115
- options = pins.last.is_a?(Hash) ? pins.pop : {}
116
- options = {
117
- }.merge(options)
118
- pins = pins.flatten.compact
119
- if pins.empty?
120
- fail 'For the V93K you must supply the pins to store/capture'
121
- end
122
- pins.each { |pin| pin.save; pin.capture }
123
- # Register this clean up function to be run after the next vector
124
- # is generated, cool or what!
125
- preset_next_vector do |vector|
126
- vector.contains_capture = true
127
- pins.each(&:restore)
128
- end
129
- end
130
-
131
- # Start a subroutine.
132
- #
133
- # Generates a global subroutine label. Global is used to adhere to the best practice of
134
- # containing all subroutines in dedicated patterns, e.g. global_subs.atp
135
- #
136
- # ==== Examples
137
- # $tester.start_subroutine("wait_for_done")
138
- # < generate your subroutine vectors here >
139
- # $tester.end_subroutine
140
- def start_subroutine(name)
141
- local_subroutines << name.to_s.chomp unless local_subroutines.include?(name.to_s.chomp) || @inhibit_vectors
142
- # name += "_subr" unless name =~ /sub/
143
- Pattern.open name: name, call_startup_callbacks: false, subroutine: true
144
- end
145
-
146
- # Ends the current subroutine that was started with a previous call to start_subroutine
147
- def end_subroutine(_cond = false)
148
- Pattern.close call_shutdown_callbacks: false, subroutine: true
149
- end
150
-
151
- # Call a subroutine.
152
- #
153
- # This calls a subroutine immediately following previous vector, it does not
154
- # generate a new vector.
155
- #
156
- # Subroutines should always be called through this method as it ensures a running
157
- # log of called subroutines is maintained and which then gets output in the pattern
158
- # header to import the right dependencies.
159
- #
160
- # An offset option is available to make the call on earlier vectors.
161
- #
162
- # Repeated calls to the same subroutine will automatically be compressed unless
163
- # option :suppress_repeated_calls is supplied and set to false. This means that for
164
- # the common use case of calling a subroutine to implement an overlay the subroutine
165
- # can be called for every bit that has the overlay and the pattern will automatically
166
- # generate correctly.
167
- #
168
- # ==== Examples
169
- # $tester.call_subroutine("mysub")
170
- # $tester.call_subroutine("my_other_sub", :offset => -1)
171
- def call_subroutine(name, options = {})
172
- options = {
173
- offset: 0,
174
- suppress_repeated_calls: true
175
- }.merge(options)
176
- called_subroutines << name.to_s.chomp unless called_subroutines.include?(name.to_s.chomp) || @inhibit_vectors
177
-
178
- code = "SQPG JSUB #{name};"
179
- if !options[:suppress_repeated_calls] ||
180
- last_object != code
181
- microcode code, offset: (options[:offset] * -1)
182
- end
183
- end
184
-
185
- # Handshake with the tester.
186
- #
187
- # ==== Examples
188
- # $tester.handshake # Pass control to the tester for a measurement
189
- def handshake(options = {})
190
- options = {
191
- }.merge(options)
192
- Pattern.split(options)
193
- end
194
-
195
- # Do a frequency measure.
196
- #
197
- # ==== Examples
198
- # $tester.freq_count($top.pin(:d_out)) # Freq measure on pin "d_out"
199
- def freq_count(_pin, options = {})
200
- options = {
201
- }.merge(options)
202
- Pattern.split(options)
203
- end
204
-
205
- # Generates a match loop on up to two pins.
206
- #
207
- # This method is not really intended to be called directly, rather you should call
208
- # via Tester#wait e.g. $tester.wait(:match => true).
209
- #
210
- # The timeout should be provided in cycles, however when called via the wait method the
211
- # time-based helpers (time_in_us, etc) will be converted to cycles for you.
212
- # The following options are available to tailor the match loop behavior, defaults in
213
- # parenthesis:
214
- #
215
- # * :pin - The pin object to match on (*required*)
216
- # * :state - The pin state to match on, :low or :high (*required*)
217
- # * :check_for_fails (false) - Flushes the pipeline and checks for fails prior to the match (to allow binout of fails encountered before the match)
218
- # * :pin2 (nil) - Optionally supply a second pin to match on
219
- # * :state2 (nil) - State for the second pin (required if :pin2 is supplied)
220
- # * :force_fail_on_timeout (true) - Force a vector mis-compare if the match loop times out
221
- #
222
- # ==== Examples
223
- # $tester.wait(:match => true, :time_in_us => 5000, :pin => $top.pin(:done), :state => :high)
224
- def match(pin, state, timeout_in_cycles, options = {})
225
- options = {
226
- check_for_fails: false,
227
- pin2: false,
228
- state2: false,
229
- global_loops: false,
230
- generate_subroutine: false,
231
- force_fail_on_timeout: true
232
- }.merge(options)
233
-
234
- # Ensure the match pins are don't care by default
235
- pin.dont_care
236
- options[:pin2].dont_care if options[:pin2]
237
-
238
- # Single condition loops are simple
239
- if !options[:pin2]
240
- # Use the counted match loop (rather than timed) which is recommended in the V93K docs for new applications
241
- # No pre-match failure handling is required here because the system will cleanly record failure info
242
- # for this kind of match loop
243
- cc "for the #{pin.name.upcase} pin to go #{state.to_s.upcase}"
244
- # Need to ensure at least 8 cycles with no compares before entering
245
- 8.cycles
246
- number_of_loops = (timeout_in_cycles.to_f / 72).ceil
247
- # This seems to be a limit on the max MACT value, so account for longer times by expanding
248
- # the wait loop
249
- if number_of_loops > 262_144
250
- mrpt = ((timeout_in_cycles.to_f / 262_144) - 8).ceil
251
- mrpt = Math.sqrt(mrpt).ceil
252
- mrpt += (8 - (mrpt % 8)) # Keep to a multiple of 8, but round up to be safe
253
- number_of_loops = 262_144
254
- else
255
- mrpt = 8
256
- end
257
- microcode "SQPG MACT #{number_of_loops};"
258
- # Strobe the pin for the required state
259
- state == :low ? pin.expect_lo : pin.expect_hi
260
- # Always do 8 vectors here as this allows reconstruction of test results if multiple loops
261
- # are called in a pattern
262
- 8.cycles
263
- pin.dont_care
264
- # Now do the wait loop, mrpt should always be a multiple of 8
265
- microcode "SQPG MRPT #{mrpt};"
266
- mrpt.times do
267
- cycle(dont_compress: true)
268
- end
269
- microcode 'SQPG PADDING;'
270
- 8.cycles
271
-
272
- else
273
-
274
- # For two pins do something more like the J750 approach where branching based on miscompares is used
275
- # to keep the loop going
276
- cc "for the #{pin.name.upcase} pin to go #{state.to_s.upcase}"
277
- cc "or the #{options[:pin2].name.upcase} pin to go #{options[:state2].to_s.upcase}"
278
-
279
- if options[:check_for_fails]
280
- cc 'Return preserving existing errors if the pattern has already failed before arriving here'
281
- cycle(repeat: propagation_delay)
282
- microcode 'SQPG RETC 1 1;'
283
- end
284
- number_of_loops = (timeout_in_cycles.to_f / ((propagation_delay * 2) + 2)).ceil
285
-
286
- loop_vectors number_of_loops do
287
- # Check pin 1
288
- cc "Check if #{pin.name.upcase} is #{state.to_s.upcase} yet"
289
- state == :low ? pin.expect_lo! : pin.expect_hi!
290
- pin.dont_care
291
- cc 'Wait for failure to propagate'
292
- cycle(repeat: propagation_delay)
293
- cc 'Exit match loop if pin has matched (no error), otherwise clear error and remain in loop'
294
- microcode 'SQPG RETC 0 0;'
295
-
296
- # Check pin 2
297
- cc "Check if #{options[:pin2].name.upcase} is #{options[:state2].to_s.upcase} yet"
298
- options[:state2] == :low ? options[:pin2].expect_lo! : options[:pin2].expect_hi!
299
- options[:pin2].dont_care
300
- cc 'Wait for failure to propagate'
301
- cycle(repeat: propagation_delay)
302
- cc 'Exit match loop if pin has matched (no error), otherwise clear error and remain in loop'
303
- microcode 'SQPG RETC 0 0;'
304
- end
305
-
306
- if options[:force_fail_on_timeout]
307
- cc 'To get here something has gone wrong, strobe again to force a pattern failure'
308
- state == :low ? pin.expect_lo : pin.expect_hi
309
- options[:state2] == :low ? options[:pin2].expect_lo : options[:pin2].expect_hi if options[:pin2]
310
- cycle
311
- pin.dont_care
312
- options[:pin2].dont_care if options[:pin2]
313
- end
314
- end
315
- end
316
-
317
- # Returns the number of cycles to wait for any fails to propagate through the pipeline based on
318
- # the current timeset
319
- def propagation_delay
320
- # From 'Calculating the buffer cycles for JMPE and RETC (and match loops)' in SmarTest docs
321
- data_queue_buffer = (([105, 64 + ((125 + current_period_in_ns - 1) / current_period_in_ns).ceil].min + 3) * 8) + 72
322
- # Don't know how to calculate at runtime, hardcoding these to some default values for now
323
- number_of_sites = 128
324
- sclk_period = 40
325
- prop_delay_buffer = 195 + ((2 * number_of_sites + 3) * (sclk_period / 2))
326
- data_queue_buffer + prop_delay_buffer
327
- end
328
-
329
- # Add a loop to the pattern.
330
- #
331
- # Pass in the number of times to execute it, all vectors
332
- # generated by the given block will be captured in the loop.
333
- #
334
- # ==== Examples
335
- # $tester.loop_vectors 3 do # Do this 3 times...
336
- # $tester.cycle
337
- # some_other_method_to_generate_vectors
338
- # end
339
- #
340
- # For compatibility with the J750 you can supply a name as the first argument
341
- # and that will simply be ignored when generated for the V93K tester...
342
- #
343
- # $tester.loop_vectors "my_loop", 3 do # Do this 3 times...
344
- # $tester.cycle
345
- # some_other_method_to_generate_vectors
346
- # end
347
- def loop_vectors(name = nil, number_of_loops = 1, _global = false)
348
- # The name argument is present to maych J750 API, sort out the
349
- unless name.is_a?(String)
350
- name, number_of_loops, global = nil, name, number_of_loops
351
- end
352
- if number_of_loops > 1
353
- microcode "SQPG LBGN #{number_of_loops};"
354
- yield
355
- microcode 'SQPG LEND;'
356
- else
357
- yield
358
- end
359
- end
360
- alias_method :loop_vector, :loop_vectors
361
-
362
- # An internal method called by Origen to create the pattern header
363
- def pattern_header(options = {})
364
- options = {
365
- }.merge(options)
366
- pin_list = ordered_pins.map do |p|
367
- if Origen.app.pin_pattern_order.include?(p.id)
368
- # specified name overrides pin name
369
- if (p.is_a?(Origen::Pins::PinCollection)) || p.id != p.name
370
- p.id.to_s # groups or aliases can be lower case
371
- else
372
- p.id.to_s.upcase # pins must be uppercase
373
- end
374
- else
375
- if (p.is_a?(Origen::Pins::PinCollection)) || p.id != p.name
376
- p.name.to_s # groups or aliases can be lower case
377
- else
378
- p.name.to_s.upcase # pins must be uppercase
379
- end
380
- end
381
- end.join(' ')
382
- microcode "FORMAT #{pin_list};"
383
- if ordered_pins.size > 0
384
- max_pin_name_length = ordered_pins.map(&:name).max { |a, b| a.length <=> b.length }.length
385
- pin_widths = ordered_pins.map { |p| p.size - 1 }
386
-
387
- max_pin_name_length.times do |i|
388
- cc((' ' * 50) + ordered_pins.map.with_index { |p, x| ((p.name[i] || ' ') + ' ' * pin_widths[x]).gsub('_', '-') }.join(' '))
389
- end
390
- end
391
- end
392
-
393
- # An internal method called by Origen to generate the pattern footer
394
- def pattern_footer(options = {})
395
- options = {
396
- end_in_ka: false
397
- }.merge(options)
398
- if options[:end_in_ka]
399
- Origen.log.warning '93K keep alive not yet implemented!'
400
- ss 'WARNING: 93K keep alive not yet implemented!'
401
- end
402
- microcode 'SQPG STOP;' unless options[:subroutine]
403
- end
404
-
405
- # Returns an array of subroutines called while generating the current pattern
406
- def called_subroutines
407
- @called_subroutines ||= []
408
- end
409
-
410
- # Returns an array of subroutines created by the current pattern
411
- def local_subroutines # :nodoc:
412
- @local_subroutines ||= []
413
- end
414
-
415
- # This is an internal method use by Origen which returns a fully formatted vector
416
- # You can override this if you wish to change the output formatting at vector level
417
- def format_vector(vec)
418
- timeset = vec.timeset ? "#{vec.timeset.name}" : ''
419
- pin_vals = vec.pin_vals ? "#{vec.pin_vals} " : ''
420
- if vec.repeat # > 1
421
- microcode = "R#{vec.repeat}"
422
- else
423
- microcode = vec.microcode ? vec.microcode : ''
424
- end
425
-
426
- if Origen.mode.simulation? || !inline_comments || $_testers_no_inline_comments
427
- comment = ''
428
- else
429
-
430
- header_comments = []
431
- repeat_comment = ''
432
- vec.comments.each_with_index do |comment, i|
433
- if comment =~ /^#/
434
- if comment =~ /^#(R\d+)$/
435
- repeat_comment = Regexp.last_match(1) + ' '
436
- # Throw away the ############# headers and footers
437
- elsif comment !~ /^# ####################/
438
- comment = comment.strip.sub(/^# (## )?/, '')
439
- if comment == ''
440
- # Throw away empty lines at the start/end, but preserve them in the middle
441
- unless header_comments.empty? || i == vec.comments.size - 1
442
- header_comments << comment
443
- end
444
- else
445
- header_comments << comment
446
- end
447
- end
448
- end
449
- end
450
-
451
- if vec.pin_vals && ($_testers_enable_vector_comments || vector_comments)
452
- comment = "#{vec.number}:#{vec.cycle}"
453
- comment += ': ' if !header_comments.empty? || !vec.inline_comment.empty?
454
- else
455
- comment = ''
456
- end
457
- comment += header_comments.join("\cm") unless header_comments.empty?
458
- unless vec.inline_comment.empty?
459
- comment += "\cm" unless header_comments.empty?
460
- comment += "(#{vec.inline_comment})"
461
- end
462
- comment = "#{repeat_comment}#{comment}"
463
- end
464
-
465
- # Max comment length 250 at the end
466
- "#{microcode.ljust(25)}#{timeset.ljust(27)}#{pin_vals}# #{comment[0, 247]};"
467
- end
468
-
469
- # All vectors generated with the supplied block will have all pins set
470
- # to the repeat previous state. Any pins that are changed state within
471
- # the block will still update to the supplied value.
472
- # ==== Example
473
- # # All pins except invoke will be assigned the repeat previous code
474
- # # in the generated vector. On completion of the block they will
475
- # # return to their previous state, except for invoke which will
476
- # # retain the value assigned within the block.
477
- # $tester.repeat_previous do
478
- # $top.pin(:invoke).drive(1)
479
- # $tester.cycle
480
- # end
481
- def repeat_previous
482
- Origen.app.pin_map.each { |_id, pin| pin.repeat_previous = true }
483
- yield
484
- Origen.app.pin_map.each { |_id, pin| pin.repeat_previous = false }
485
- end
486
-
487
- def before_timeset_change(options = {})
488
- microcode "SQPG CTIM #{options[:new].name};" unless level_period?
489
- end
490
- end
491
- end
492
- end
1
+ module OrigenTesters
2
+ module SmartestBasedTester
3
+ class Base
4
+ include VectorBasedTester
5
+
6
+ # Disable inline (end of vector) comments, enabled by default
7
+ attr_accessor :inline_comments
8
+
9
+ # Returns whether the tester has been configured to wrap top-level flow modules with an
10
+ # enable or not.
11
+ #
12
+ # Returns nil if not.
13
+ #
14
+ # Returns :enabled if the enable is configured to be on by default, or :disabled if it is
15
+ # configured to be off by default.
16
+ attr_reader :add_flow_enable
17
+
18
+ def initialize(options = {})
19
+ @max_repeat_loop = 65_535
20
+ @min_repeat_loop = 33
21
+ @pat_extension = 'avc'
22
+ @compress = true
23
+ # @support_repeat_previous = true
24
+ @match_entries = 10
25
+ @name = 'v93k'
26
+ @comment_char = '#'
27
+ @level_period = true
28
+ @inline_comments = true
29
+ @overlay_style = :subroutine # default to use subroutine for overlay
30
+ @capture_style = :hram # default to use hram for capture
31
+ @overlay_subr = nil
32
+
33
+ if options[:add_flow_enable]
34
+ self.add_flow_enable = options[:add_flow_enable]
35
+ end
36
+ end
37
+
38
+ # Set to :enabled to have all top-level flow modules wrapped by an enable flow variable
39
+ # that is enabled by default (top-level flow has to disable modules it doesn't want).
40
+ #
41
+ # Set to :disabled to have the opposite, where the top-level flow has to enable all
42
+ # modules.
43
+ #
44
+ # Note that the interface can override this setting for each flow during program generation.
45
+ def add_flow_enable=(value)
46
+ if value == :enable || value == :enabled
47
+ @add_flow_enable = :enabled
48
+ elsif value == :disable || value == :disabled
49
+ @add_flow_enable = :disabled
50
+ else
51
+ fail "Unknown add_flow_enable value, #{value}, must be :enabled or :disabled"
52
+ end
53
+ end
54
+
55
+ def cycle(options = {})
56
+ # handle overlay if requested
57
+ ovly_style = nil
58
+ if options.key?(:overlay)
59
+ ovly_style = options[:overlay][:overlay_style].nil? ? @overlay_style : options[:overlay][:overlay_style]
60
+ overlay_str = options[:overlay][:overlay_str]
61
+
62
+ # route the overlay request to the appropriate method
63
+ case ovly_style
64
+ when :subroutine, :default
65
+ subroutine_overlay(overlay_str, options)
66
+ ovly_style = :subroutine
67
+ else
68
+ ovly_style = overlay_style_warn(options[:overlay][:overlay_str], options)
69
+ end # case ovly_style
70
+ else
71
+ @overlay_subr = nil
72
+ end # of handle overlay
73
+
74
+ options_overlay = options.delete(:overlay) if options.key?(:overlay)
75
+
76
+ super(options) unless ovly_style == :subroutine
77
+
78
+ unless options_overlay.nil?
79
+ # stage = :body if ovly_style == :subroutine # always set stage back to body in case subr overlay was selected
80
+ end
81
+ end
82
+
83
+ # Warn user of unsupported overlay style
84
+ def overlay_style_warn(overlay_str, options)
85
+ Origen.log.warn("Unrecognized overlay style :#{@overlay_style}, defaulting to subroutine")
86
+ Origen.log.warn('Available overlay styles :subroutine')
87
+ subroutine_overlay(overlay_str, options)
88
+ @overlay_style = :subroutine # Just give 1 warning
89
+ end
90
+
91
+ # Implement subroutine overlay, called by tester.cycle
92
+ def subroutine_overlay(sub_name, options = {})
93
+ if @overlay_subr != sub_name
94
+ # unless last staged vector already has the subr call do the following
95
+ i = -1
96
+ i -= 1 until stage.bank[i].is_a?(OrigenTesters::Vector)
97
+ if stage.bank[i].microcode !~ /#{sub_name}/
98
+
99
+ # check for repeat on new last vector, unroll 1 if needed
100
+ if stage.bank[i].repeat > 1
101
+ v = OrigenTesters::Vector.new
102
+ v.pin_vals = stage.bank[i].pin_vals
103
+ v.timeset = stage.bank[i].timeset
104
+ stage.bank[i].repeat -= 1
105
+ stage.store(v)
106
+ i = -1
107
+ end
108
+
109
+ # mark last vector as dont_compress
110
+ stage.bank[i].dont_compress = true
111
+ # insert subroutine call
112
+ call_subroutine sub_name
113
+ end # if microcode not placed
114
+ @overlay_subr = sub_name
115
+ end
116
+
117
+ # stage = sub_name
118
+ end # subroutine_overlay
119
+
120
+ # Capture the pin data from a vector to the tester.
121
+ #
122
+ # This method uses the Digital Capture feature (Selective mode) of the V93000 to capture
123
+ # the data from the given pins on the previous vector.
124
+ # Note that is does not actually generate a new vector.
125
+ #
126
+ # Note also that any drive cycles on the target pins can also be captured, to avoid this
127
+ # the wavetable should be set up like this to infer a 'D' (Don't Capture) on vectors where
128
+ # the target pin is being used to drive data:
129
+ #
130
+ # PINS nvm_fail
131
+ # 0 d1:0 r1:D 0
132
+ # 1 d1:1 r1:D 1
133
+ # 2 r1:C Capt
134
+ # 3 r1:D NoCapt
135
+ #
136
+ # Sometimes when generating vectors within a loop you may want to apply a capture
137
+ # retrospectively to a previous vector, passing in an offset option will allow you
138
+ # to do this.
139
+ #
140
+ # ==== Examples
141
+ # $tester.cycle # This is the vector you want to capture
142
+ # $tester.store :pin => pin(:fail) # This applys the required opcode to the given pins
143
+ #
144
+ # $tester.cycle # This one gets captured
145
+ # $tester.cycle
146
+ # $tester.cycle
147
+ # $tester.store(:pin => pin(:fail), :offset => -2) # Just realized I need to capture that earlier vector
148
+ #
149
+ # # Capturing multiple pins:
150
+ # $tester.cycle
151
+ # $tester.store :pins => [pin(:fail), pin(:done)]
152
+ #
153
+ # Since the V93K store operates on a pin level (rather than vector level as on the J750)
154
+ # equivalent functionality can also be achieved by setting the store attribute of the pin
155
+ # itself prior to calling $tester.cycle.
156
+ # However it is recommended to use the tester API to do the store if cross-compatiblity with
157
+ # other platforms, such as the J750, is required.
158
+ def store(*pins)
159
+ options = pins.last.is_a?(Hash) ? pins.pop : {}
160
+ options = { offset: 0
161
+ }.merge(options)
162
+ pins = pins.flatten.compact
163
+ if pins.empty?
164
+ fail 'For the V93K you must supply the pins to store/capture'
165
+ end
166
+ pins.each do |pin|
167
+ pin.restore_state do
168
+ pin.capture
169
+ update_vector_pin_val pin, offset: options[:offset]
170
+ last_vector(options[:offset]).dont_compress = true
171
+ last_vector(options[:offset]).contains_capture = true
172
+ end
173
+ end
174
+ end
175
+ alias_method :capture, :store
176
+
177
+ # Same as the store method, except that the capture will be applied to the next
178
+ # vector to be generated.
179
+ #
180
+ # @example
181
+ # $tester.store_next_cycle
182
+ # $tester.cycle # This is the vector that will be captured
183
+ def store_next_cycle(*pins)
184
+ options = pins.last.is_a?(Hash) ? pins.pop : {}
185
+ options = {
186
+ }.merge(options)
187
+ pins = pins.flatten.compact
188
+ if pins.empty?
189
+ fail 'For the V93K you must supply the pins to store/capture'
190
+ end
191
+ pins.each { |pin| pin.save; pin.capture }
192
+ # Register this clean up function to be run after the next vector
193
+ # is generated, cool or what!
194
+ preset_next_vector do |vector|
195
+ vector.contains_capture = true
196
+ pins.each(&:restore)
197
+ end
198
+ end
199
+ alias_method :store!, :store_next_cycle
200
+
201
+ # Start a subroutine.
202
+ #
203
+ # Generates a global subroutine label. Global is used to adhere to the best practice of
204
+ # containing all subroutines in dedicated patterns, e.g. global_subs.atp
205
+ #
206
+ # ==== Examples
207
+ # $tester.start_subroutine("wait_for_done")
208
+ # < generate your subroutine vectors here >
209
+ # $tester.end_subroutine
210
+ def start_subroutine(name)
211
+ local_subroutines << name.to_s.chomp unless local_subroutines.include?(name.to_s.chomp) || @inhibit_vectors
212
+ # name += "_subr" unless name =~ /sub/
213
+ Pattern.open name: name, call_startup_callbacks: false, subroutine: true
214
+ end
215
+
216
+ # Ends the current subroutine that was started with a previous call to start_subroutine
217
+ def end_subroutine(_cond = false)
218
+ Pattern.close call_shutdown_callbacks: false, subroutine: true
219
+ end
220
+
221
+ # Call a subroutine.
222
+ #
223
+ # This calls a subroutine immediately following previous vector, it does not
224
+ # generate a new vector.
225
+ #
226
+ # Subroutines should always be called through this method as it ensures a running
227
+ # log of called subroutines is maintained and which then gets output in the pattern
228
+ # header to import the right dependencies.
229
+ #
230
+ # An offset option is available to make the call on earlier vectors.
231
+ #
232
+ # Repeated calls to the same subroutine will automatically be compressed unless
233
+ # option :suppress_repeated_calls is supplied and set to false. This means that for
234
+ # the common use case of calling a subroutine to implement an overlay the subroutine
235
+ # can be called for every bit that has the overlay and the pattern will automatically
236
+ # generate correctly.
237
+ #
238
+ # ==== Examples
239
+ # $tester.call_subroutine("mysub")
240
+ # $tester.call_subroutine("my_other_sub", :offset => -1)
241
+ def call_subroutine(name, options = {})
242
+ options = {
243
+ offset: 0,
244
+ suppress_repeated_calls: true
245
+ }.merge(options)
246
+ called_subroutines << name.to_s.chomp unless called_subroutines.include?(name.to_s.chomp) || @inhibit_vectors
247
+
248
+ code = "SQPG JSUB #{name};"
249
+ if !options[:suppress_repeated_calls] ||
250
+ last_object != code
251
+ microcode code, offset: (options[:offset] * -1)
252
+ end
253
+ end
254
+
255
+ # Handshake with the tester.
256
+ #
257
+ # ==== Examples
258
+ # $tester.handshake # Pass control to the tester for a measurement
259
+ def handshake(options = {})
260
+ options = {
261
+ }.merge(options)
262
+ Pattern.split(options)
263
+ end
264
+
265
+ # Do a frequency measure.
266
+ #
267
+ # ==== Examples
268
+ # $tester.freq_count($top.pin(:d_out)) # Freq measure on pin "d_out"
269
+ def freq_count(_pin, options = {})
270
+ options = {
271
+ }.merge(options)
272
+ Pattern.split(options)
273
+ end
274
+
275
+ # Generates a match loop on up to two pins.
276
+ #
277
+ # This method is not really intended to be called directly, rather you should call
278
+ # via Tester#wait e.g. $tester.wait(:match => true).
279
+ #
280
+ # The timeout should be provided in cycles, however when called via the wait method the
281
+ # time-based helpers (time_in_us, etc) will be converted to cycles for you.
282
+ # The following options are available to tailor the match loop behavior, defaults in
283
+ # parenthesis:
284
+ #
285
+ # * :pin - The pin object to match on (*required*)
286
+ # * :state - The pin state to match on, :low or :high (*required*)
287
+ # * :check_for_fails (false) - Flushes the pipeline and checks for fails prior to the match (to allow binout of fails encountered before the match)
288
+ # * :pin2 (nil) - Optionally supply a second pin to match on
289
+ # * :state2 (nil) - State for the second pin (required if :pin2 is supplied)
290
+ # * :force_fail_on_timeout (true) - Force a vector mis-compare if the match loop times out
291
+ #
292
+ # ==== Examples
293
+ # $tester.wait(:match => true, :time_in_us => 5000, :pin => $top.pin(:done), :state => :high)
294
+ def match(pin, state, timeout_in_cycles, options = {})
295
+ options = {
296
+ check_for_fails: false,
297
+ pin2: false,
298
+ state2: false,
299
+ global_loops: false,
300
+ generate_subroutine: false,
301
+ force_fail_on_timeout: true
302
+ }.merge(options)
303
+
304
+ # Ensure the match pins are don't care by default
305
+ pin.dont_care
306
+ options[:pin2].dont_care if options[:pin2]
307
+
308
+ # Single condition loops are simple
309
+ if !options[:pin2]
310
+ # Use the counted match loop (rather than timed) which is recommended in the V93K docs for new applications
311
+ # No pre-match failure handling is required here because the system will cleanly record failure info
312
+ # for this kind of match loop
313
+ cc "for the #{pin.name.upcase} pin to go #{state.to_s.upcase}"
314
+ # Need to ensure at least 8 cycles with no compares before entering
315
+ 8.cycles
316
+ number_of_loops = (timeout_in_cycles.to_f / 72).ceil
317
+ # This seems to be a limit on the max MACT value, so account for longer times by expanding
318
+ # the wait loop
319
+ if number_of_loops > 262_144
320
+ mrpt = ((timeout_in_cycles.to_f / 262_144) - 8).ceil
321
+ mrpt = Math.sqrt(mrpt).ceil
322
+ mrpt += (8 - (mrpt % 8)) # Keep to a multiple of 8, but round up to be safe
323
+ number_of_loops = 262_144
324
+ else
325
+ mrpt = 8
326
+ end
327
+ microcode "SQPG MACT #{number_of_loops};"
328
+ # Strobe the pin for the required state
329
+ state == :low ? pin.expect_lo : pin.expect_hi
330
+ # Always do 8 vectors here as this allows reconstruction of test results if multiple loops
331
+ # are called in a pattern
332
+ 8.cycles
333
+ pin.dont_care
334
+ # Now do the wait loop, mrpt should always be a multiple of 8
335
+ microcode "SQPG MRPT #{mrpt};"
336
+ mrpt.times do
337
+ cycle(dont_compress: true)
338
+ end
339
+ microcode 'SQPG PADDING;'
340
+ 8.cycles
341
+
342
+ else
343
+
344
+ # For two pins do something more like the J750 approach where branching based on miscompares is used
345
+ # to keep the loop going
346
+ cc "for the #{pin.name.upcase} pin to go #{state.to_s.upcase}"
347
+ cc "or the #{options[:pin2].name.upcase} pin to go #{options[:state2].to_s.upcase}"
348
+
349
+ if options[:check_for_fails]
350
+ cc 'Return preserving existing errors if the pattern has already failed before arriving here'
351
+ cycle(repeat: propagation_delay)
352
+ microcode 'SQPG RETC 1 1;'
353
+ end
354
+ number_of_loops = (timeout_in_cycles.to_f / ((propagation_delay * 2) + 2)).ceil
355
+
356
+ loop_vectors number_of_loops do
357
+ # Check pin 1
358
+ cc "Check if #{pin.name.upcase} is #{state.to_s.upcase} yet"
359
+ state == :low ? pin.expect_lo! : pin.expect_hi!
360
+ pin.dont_care
361
+ cc 'Wait for failure to propagate'
362
+ cycle(repeat: propagation_delay)
363
+ cc 'Exit match loop if pin has matched (no error), otherwise clear error and remain in loop'
364
+ microcode 'SQPG RETC 0 0;'
365
+
366
+ # Check pin 2
367
+ cc "Check if #{options[:pin2].name.upcase} is #{options[:state2].to_s.upcase} yet"
368
+ options[:state2] == :low ? options[:pin2].expect_lo! : options[:pin2].expect_hi!
369
+ options[:pin2].dont_care
370
+ cc 'Wait for failure to propagate'
371
+ cycle(repeat: propagation_delay)
372
+ cc 'Exit match loop if pin has matched (no error), otherwise clear error and remain in loop'
373
+ microcode 'SQPG RETC 0 0;'
374
+ end
375
+
376
+ if options[:force_fail_on_timeout]
377
+ cc 'To get here something has gone wrong, strobe again to force a pattern failure'
378
+ state == :low ? pin.expect_lo : pin.expect_hi
379
+ options[:state2] == :low ? options[:pin2].expect_lo : options[:pin2].expect_hi if options[:pin2]
380
+ cycle
381
+ pin.dont_care
382
+ options[:pin2].dont_care if options[:pin2]
383
+ end
384
+ end
385
+ end
386
+
387
+ # Returns the number of cycles to wait for any fails to propagate through the pipeline based on
388
+ # the current timeset
389
+ def propagation_delay
390
+ # From 'Calculating the buffer cycles for JMPE and RETC (and match loops)' in SmarTest docs
391
+ data_queue_buffer = (([105, 64 + ((125 + current_period_in_ns - 1) / current_period_in_ns).ceil].min + 3) * 8) + 72
392
+ # Don't know how to calculate at runtime, hardcoding these to some default values for now
393
+ number_of_sites = 128
394
+ sclk_period = 40
395
+ prop_delay_buffer = 195 + ((2 * number_of_sites + 3) * (sclk_period / 2))
396
+ data_queue_buffer + prop_delay_buffer
397
+ end
398
+
399
+ # Add a loop to the pattern.
400
+ #
401
+ # Pass in the number of times to execute it, all vectors
402
+ # generated by the given block will be captured in the loop.
403
+ #
404
+ # ==== Examples
405
+ # $tester.loop_vectors 3 do # Do this 3 times...
406
+ # $tester.cycle
407
+ # some_other_method_to_generate_vectors
408
+ # end
409
+ #
410
+ # For compatibility with the J750 you can supply a name as the first argument
411
+ # and that will simply be ignored when generated for the V93K tester...
412
+ #
413
+ # $tester.loop_vectors "my_loop", 3 do # Do this 3 times...
414
+ # $tester.cycle
415
+ # some_other_method_to_generate_vectors
416
+ # end
417
+ def loop_vectors(name = nil, number_of_loops = 1, _global = false)
418
+ # The name argument is present to maych J750 API, sort out the
419
+ unless name.is_a?(String)
420
+ name, number_of_loops, global = nil, name, number_of_loops
421
+ end
422
+ if number_of_loops > 1
423
+ microcode "SQPG LBGN #{number_of_loops};"
424
+ yield
425
+ microcode 'SQPG LEND;'
426
+ else
427
+ yield
428
+ end
429
+ end
430
+ alias_method :loop_vector, :loop_vectors
431
+
432
+ # An internal method called by Origen to create the pattern header
433
+ def pattern_header(options = {})
434
+ options = {
435
+ }.merge(options)
436
+ pin_list = ordered_pins.map do |p|
437
+ if Origen.app.pin_pattern_order.include?(p.id)
438
+ # specified name overrides pin name
439
+ if (p.is_a?(Origen::Pins::PinCollection)) || p.id != p.name
440
+ p.id.to_s # groups or aliases can be lower case
441
+ else
442
+ p.id.to_s.upcase # pins must be uppercase
443
+ end
444
+ else
445
+ if (p.is_a?(Origen::Pins::PinCollection)) || p.id != p.name
446
+ p.name.to_s # groups or aliases can be lower case
447
+ else
448
+ p.name.to_s.upcase # pins must be uppercase
449
+ end
450
+ end
451
+ end.join(' ')
452
+ microcode "FORMAT #{pin_list};"
453
+ if ordered_pins.size > 0
454
+ max_pin_name_length = ordered_pins.map(&:name).max { |a, b| a.length <=> b.length }.length
455
+ pin_widths = ordered_pins.map { |p| p.size - 1 }
456
+
457
+ max_pin_name_length.times do |i|
458
+ cc((' ' * 50) + ordered_pins.map.with_index { |p, x| ((p.name[i] || ' ') + ' ' * pin_widths[x]).gsub('_', '-') }.join(' '))
459
+ end
460
+ end
461
+ end
462
+
463
+ # An internal method called by Origen to generate the pattern footer
464
+ def pattern_footer(options = {})
465
+ options = {
466
+ end_in_ka: false
467
+ }.merge(options)
468
+ if options[:end_in_ka]
469
+ Origen.log.warning '93K keep alive not yet implemented!'
470
+ ss 'WARNING: 93K keep alive not yet implemented!'
471
+ end
472
+ microcode 'SQPG STOP;' unless options[:subroutine]
473
+ end
474
+
475
+ # Returns an array of subroutines called while generating the current pattern
476
+ def called_subroutines
477
+ @called_subroutines ||= []
478
+ end
479
+
480
+ # Returns an array of subroutines created by the current pattern
481
+ def local_subroutines # :nodoc:
482
+ @local_subroutines ||= []
483
+ end
484
+
485
+ # This is an internal method use by Origen which returns a fully formatted vector
486
+ # You can override this if you wish to change the output formatting at vector level
487
+ def format_vector(vec)
488
+ timeset = vec.timeset ? "#{vec.timeset.name}" : ''
489
+ pin_vals = vec.pin_vals ? "#{vec.pin_vals} " : ''
490
+ if vec.repeat # > 1
491
+ microcode = "R#{vec.repeat}"
492
+ else
493
+ microcode = vec.microcode ? vec.microcode : ''
494
+ end
495
+
496
+ if Origen.mode.simulation? || !inline_comments || $_testers_no_inline_comments
497
+ comment = ''
498
+ else
499
+
500
+ header_comments = []
501
+ repeat_comment = ''
502
+ vec.comments.each_with_index do |comment, i|
503
+ if comment =~ /^#/
504
+ if comment =~ /^#(R\d+)$/
505
+ repeat_comment = Regexp.last_match(1) + ' '
506
+ # Throw away the ############# headers and footers
507
+ elsif comment !~ /^# ####################/
508
+ comment = comment.strip.sub(/^# (## )?/, '')
509
+ if comment == ''
510
+ # Throw away empty lines at the start/end, but preserve them in the middle
511
+ unless header_comments.empty? || i == vec.comments.size - 1
512
+ header_comments << comment
513
+ end
514
+ else
515
+ header_comments << comment
516
+ end
517
+ end
518
+ end
519
+ end
520
+
521
+ if vec.pin_vals && ($_testers_enable_vector_comments || vector_comments)
522
+ comment = "#{vec.number}:#{vec.cycle}"
523
+ comment += ': ' if !header_comments.empty? || !vec.inline_comment.empty?
524
+ else
525
+ comment = ''
526
+ end
527
+ comment += header_comments.join("\cm") unless header_comments.empty?
528
+ unless vec.inline_comment.empty?
529
+ comment += "\cm" unless header_comments.empty?
530
+ comment += "(#{vec.inline_comment})"
531
+ end
532
+ comment = "#{repeat_comment}#{comment}"
533
+ end
534
+
535
+ # Max comment length 250 at the end
536
+ "#{microcode.ljust(25)}#{timeset.ljust(27)}#{pin_vals}# #{comment[0, 247]};"
537
+ end
538
+
539
+ # All vectors generated with the supplied block will have all pins set
540
+ # to the repeat previous state. Any pins that are changed state within
541
+ # the block will still update to the supplied value.
542
+ # ==== Example
543
+ # # All pins except invoke will be assigned the repeat previous code
544
+ # # in the generated vector. On completion of the block they will
545
+ # # return to their previous state, except for invoke which will
546
+ # # retain the value assigned within the block.
547
+ # $tester.repeat_previous do
548
+ # $top.pin(:invoke).drive(1)
549
+ # $tester.cycle
550
+ # end
551
+ def repeat_previous
552
+ Origen.app.pin_map.each { |_id, pin| pin.repeat_previous = true }
553
+ yield
554
+ Origen.app.pin_map.each { |_id, pin| pin.repeat_previous = false }
555
+ end
556
+
557
+ def before_timeset_change(options = {})
558
+ microcode "SQPG CTIM #{options[:new].name};" unless level_period?
559
+ end
560
+ end
561
+ end
562
+ end