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