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,655 +1,655 @@
1
- require 'active_support/concern'
2
- module OrigenTesters
3
- module VectorGenerator
4
- extend ActiveSupport::Concern
5
-
6
- require 'erb'
7
-
8
- included do
9
- # When set to true vector and cycle number comments will be appended to pattern vectors.
10
- # This can also be enabled by running the generate command with the '-v' switch.
11
- attr_accessor :vector_comments
12
- attr_accessor :compress
13
- attr_accessor :expand_repeats
14
- end
15
-
16
- def vector_group_size
17
- @vector_group_size || 1
18
- end
19
-
20
- def vector_group_size=(number)
21
- if number > 1 && number.odd?
22
- fail 'Only even numbers can be supplied for the vector_group_size!'
23
- end
24
- # Each pattern should run with its own tester instance, but just in case
25
- @pipeline = nil
26
- @vector_group_size = number
27
- end
28
-
29
- def with_vector_group_size(number)
30
- orig = vector_group_size
31
- self.vector_group_size = number
32
- yield
33
- self.vector_group_size = orig
34
- end
35
-
36
- # Duplicate the last vector as required until aligned with the start of the
37
- # next vector group
38
- def align
39
- stage.store :align
40
- end
41
- alias_method :align_to_first, :align
42
-
43
- # Duplicate the last vector as required until aligned to the last vector of the
44
- # current vector group
45
- def align_to_last
46
- stage.store :align_last
47
- end
48
-
49
- # Returns an array of pin IDs that are currently inhibited (will not
50
- # be included when vectors are generated)
51
- def inhibited_pins
52
- @inhibited_pins ||= []
53
- end
54
-
55
- # init vector count when first accessed, otherwise return value
56
- def vec_count
57
- @vec_count ||= 0
58
- end
59
-
60
- # increment vector count
61
- def inc_vec_count(num = 1)
62
- vec_count if @vec_count.nil? # define if not already
63
- @vec_count = @vec_count + num
64
- end
65
-
66
- # decrement vector count
67
- def dec_vec_count(num = 1)
68
- vec_count if @vec_count.nil? # define if not already
69
- @vec_count = @vec_count - num
70
- end
71
-
72
- # Returns the current cycle count
73
- def cycle_count
74
- @cycle_count ||= 0
75
- end
76
-
77
- # Returns the current execution time
78
- def execution_time_in_ns
79
- @execution_time_in_ns ||= 0
80
- end
81
-
82
- # increment cycle count
83
- def inc_cycle_count(num = 1, options = {})
84
- num, options = 1, num if num.is_a?(Hash)
85
- cycle_count if @cycle_count.nil? # define if not already
86
- execution_time_in_ns if @execution_time_in_ns.nil? # define if not already
87
- @execution_time_in_ns += num * (options[:period_in_ns] || tester.timeset.period_in_ns)
88
- @cycle_count = @cycle_count + num
89
- end
90
-
91
- # reset_cycle_count
92
- def reset_cycle_count(num = 0)
93
- cycle_count if @cycle_count.nil? # define if not already
94
- @execution_time_in_ns = 0
95
- @cycle_count = num
96
- end
97
-
98
- # Call to prevent the given pins from appearing in the generated vectors.
99
- #
100
- # This is a convenient way to inhibit something like a J750 mux pin from
101
- # appearing in the patterns when generating the pattern for a different
102
- # platform.
103
- #
104
- # When used this
105
- # method must be called before the first vector is generated - it will not be retrospectively
106
- # applied to existing vectors.
107
- def inhibit_pin(*pins)
108
- pins.each do |pin|
109
- pin = $dut.pin(pin) if pin.is_a?(Symbol)
110
- inhibited_pins << pin
111
- end
112
- inhibited_pins.uniq!
113
- inhibited_pins.compact!
114
- inhibited_pins
115
- end
116
- alias_method :inhibit_pins, :inhibit_pin
117
-
118
- # Render content directly into a pattern, any options will be passed to the template
119
- def render(template, options = {})
120
- # Record the current file, this can be used to resolve any relative path
121
- # references in the file about to be compiled
122
- Origen.file_handler.current_file = template
123
- # Ran into crosstalk problems when rendering ERB templates recursively, setting eoutvar based
124
- # on the name of the file will causes each template to be rendered into its own 'bank'.
125
- # Not sure why the final gsub is needed but seems to fail to parse correctly otherwise.
126
- eoutvar = Pathname.new(template).basename('.*').basename('.*').to_s.gsub('-', '_')
127
- # Make the file name available to the template
128
- Origen.generator.compiler.options[:file] = template
129
- options.each { |k, v| Origen.generator.compiler.options[k] = v }
130
- code = Origen.generator.compiler.insert(ERB.new(File.read(template.to_s), 0, Origen.config.erb_trim_mode, eoutvar).result)
131
- code.strip!
132
- push_microcode code
133
- end
134
-
135
- # If the tester defines a method named template this method will compile
136
- # whatever template file is returned by that method.
137
- #
138
- # This method is called automatically after the body section of a Pattern.create
139
- # operation has completed.
140
- def render_template
141
- _render(:template)
142
- end
143
-
144
- # Same as the render method, except the template method should be called body_template.
145
- def render_body
146
- _render(:body_template)
147
- end
148
-
149
- # If the tester defines a method named footer_template this method will compile
150
- # whatever template file is returned by that method.
151
- #
152
- # This method is called automatically during the footer section of a Pattern.create
153
- # operation.
154
- def render_footer
155
- _render(:footer_template)
156
- end
157
-
158
- # If the tester defines a method named header_template this method will compile
159
- # whatever template file is returned by that method.
160
- #
161
- # This method is called automatically during the header section of a Pattern.create
162
- # operation.
163
- def render_header
164
- _render(:header_template)
165
- end
166
-
167
- def _render(method) # :nodoc:
168
- if self.respond_to?(method)
169
- template = send(method)
170
- # Record the current file, this can be used to resolve any relative path
171
- # references in the file about to be compiled
172
- Origen.file_handler.current_file = template
173
- # Ran into crosstalk problems when rendering ERB templates recursively, setting eoutvar based
174
- # on the name of the file will causes each template to be rendered into its own 'bank'.
175
- # Not sure why the final gsub is needed but seems to fail to parse correctly otherwise.
176
- eoutvar = Pathname.new(template).basename('.*').basename('.*').to_s.gsub('-', '_')
177
- # Make the file name available to the template
178
- Origen.generator.compiler.options[:file] = template
179
- push_microcode Origen.generator.compiler.insert(ERB.new(File.read(template.to_s), 0, Origen.config.erb_trim_mode, eoutvar).result)
180
- end
181
- end
182
-
183
- def stage
184
- Origen.generator.stage
185
- end
186
-
187
- def push_comment(msg)
188
- # Comments are stored verbatim for now, can't see much use for a dedicated comment object
189
- stage.store msg unless @inhibit_comments
190
- end
191
-
192
- def microcode(code, options = {})
193
- unless @inhibit_vectors
194
- if options[:offset] && options[:offset] != 0
195
- stage.insert_from_end code, options[:offset]
196
- else
197
- stage.store code
198
- end
199
- end
200
- end
201
- alias_method :push_microcode, :microcode
202
-
203
- def last_vector(offset = 0)
204
- stage.last_vector(offset)
205
- end
206
-
207
- def last_object(offset = 0)
208
- stage.last_object(offset)
209
- end
210
-
211
- # Allows the attributes for the next vector to be setup prior
212
- # to generating it.
213
- #
214
- # A block can be optionally supplied to act as a clean up method,
215
- # that is the block will be saved and executed after the next
216
- # cycle has been generated.
217
- #
218
- # See the V93K store_next_cycle method for an example of using
219
- # this.
220
- def preset_next_vector(attrs = {}, &block)
221
- @preset_next_vector = attrs
222
- @preset_next_vector_cleanup = block
223
- end
224
-
225
- # Called by every $tester.cycle command to push a vector to the stage object
226
- def push_vector(attrs = {})
227
- attrs = {
228
- dont_compress: @dont_compress
229
- }.merge(attrs)
230
- unless @inhibit_vectors
231
- if @preset_next_vector
232
- attrs = @preset_next_vector.merge(attrs) do |key, preset, current|
233
- if preset && current && current != ''
234
- fail "Value for #{key} set by preset_next_vector clashed with the next vector!"
235
- else
236
- preset || current
237
- end
238
- end
239
- @preset_next_vector = nil
240
- end
241
- v = Vector.new(attrs)
242
- stage.store Vector.new(attrs)
243
- inc_vec_count
244
- inc_cycle_count(attrs[:repeat] || 1, period_in_ns: v.timeset.period_in_ns)
245
- if @preset_next_vector_cleanup
246
- @preset_next_vector_cleanup.call(v)
247
- @preset_next_vector_cleanup = nil
248
- end
249
- end
250
- end
251
- alias_method :vector, :push_vector
252
-
253
- def update_vector(attrs = {})
254
- unless @inhibit_vectors
255
- offset = (attrs.delete(:offset) || 0).abs
256
- stage.last_vector(offset).update(attrs)
257
- end
258
- end
259
-
260
- def update_vector_pin_val(pin, options = {})
261
- unless @inhibit_vectors
262
- offset = (options.delete(:offset) || 0).abs
263
- stage.last_vector(offset).update_pin_val(pin)
264
- end
265
- end
266
-
267
- # Adds the given microcode to the last vector if possible. If not possible (meaning the
268
- # vector already contains microcode) then a new cycle will be added with the given
269
- # microcode.
270
- def add_microcode_to_last_or_cycle(code)
271
- cycle if !stage.last_vector || stage.last_vector.has_microcode?
272
- stage.last_vector.update(microcode: code)
273
- end
274
-
275
- # Final pass of a generator vector array which returns lines suitable for writing to the
276
- # output file. This gives the tester model a chance to concatenate repeats and any other
277
- # last optimization/formatting changes it wishes to make.
278
- #
279
- # At this point vector array contains a combination of non-vector lines and uncompressed
280
- # Vector objects (vector lines)
281
- #
282
- def format(vector_array, section)
283
- # Go through vector_array and print out both
284
- # vectors and non-vectors to pattern (via 'yield line')
285
- vector_array.each do |vec|
286
- # skip here important for the ways delays are currently handled
287
- # TODO: This seems like an upstream bug that should be investigated, why is such
288
- # a vector even generated?
289
- if vec.is_a?(String)
290
- if vec.strip[0] == comment_char
291
- pipeline.push_comment(vec)
292
- else
293
- pipeline.push_microcode(vec)
294
- end
295
- else
296
- next if vec.respond_to?(:repeat) && vec.repeat == 0 # skip vectors with repeat of 0!
297
- pipeline << vec
298
- end
299
- pipeline.flush do |vector|
300
- expand_vector(vector) do |line|
301
- yield line
302
- end
303
- end
304
- end
305
- # now flush buffer if there is still a vector
306
- pipeline.empty(min_vectors: section == :footer ? @min_pattern_vectors : nil) do |vector|
307
- expand_vector(vector) do |line|
308
- yield line
309
- end
310
- end
311
- end
312
-
313
- # Tester models can overwrite this if they wish to inject any additional pattern lines
314
- # at final pattern dump time
315
- def before_write_pattern_line(line)
316
- [line]
317
- end
318
-
319
- def pipeline
320
- @pipeline ||= VectorPipeline.new(vector_group_size)
321
- end
322
-
323
- def dont_compress
324
- if block_given?
325
- orig = @dont_compress
326
- @dont_compress = true
327
- yield
328
- @dont_compress = orig
329
- else
330
- @dont_compress
331
- end
332
- end
333
-
334
- def dont_compress=(val)
335
- @dont_compress = val
336
- end
337
-
338
- # expands (uncompresses to pattern) vector if desired or leaves it as is
339
- # allows for tracking and formatting of vector
340
- # if comment then return without modification
341
- def expand_vector(vec)
342
- if vec.is_a?(Vector)
343
- if expand_repeats
344
- vec.repeat.times do
345
- vec.repeat = 1
346
- yield track_and_format_vector(vec)
347
- end
348
- else
349
- yield track_and_format_vector(vec)
350
- end
351
- else
352
- yield vec # Return comments without modification
353
- end
354
- end
355
-
356
- # Update tracking info (stats object) and allow for
357
- # any additional formatting via format_vector
358
- # method if overridden
359
- def track_and_format_vector(vec)
360
- unless vec.timeset
361
- puts 'No timeset defined!'
362
- puts 'Add one to your top level startup method or target like this:'
363
- puts '$tester.set_timeset("nvmbist", 40) # Where 40 is the period in ns'
364
- exit 1
365
- end
366
- stats = Origen.app.stats
367
- stats.add_vector
368
- if vector_group_size > 1 && vec.repeat > 1
369
- stats.add_cycle(1)
370
- stats.add_cycle((vec.repeat - 1) * vector_group_size)
371
- stats.add_time_in_ns(vec.timeset.period_in_ns)
372
- stats.add_time_in_ns((vec.repeat - 1) * vector_group_size * vec.timeset.period_in_ns)
373
- else
374
- stats.add_cycle(vec.repeat)
375
- stats.add_time_in_ns(vec.repeat * vec.timeset.period_in_ns)
376
- end
377
- format_vector(vec)
378
- end
379
-
380
- def format_vector(vec)
381
- end
382
-
383
- def pingroup_map
384
- Origen.app.pingroup_map
385
- end
386
-
387
- # Cache any pin ordering for later use since all vectors should be formatted the same
388
- def ordered_pins_cache(options = {})
389
- @ordered_pins_cache ||= ordered_pins(options)
390
- end
391
-
392
- def ordered_pins(options = {})
393
- options = {
394
- include_inhibited_pins: false,
395
- include_pingroups: true
396
- }.merge(options)
397
-
398
- result = nil
399
-
400
- Origen.profile 'Working out pin pattern order' do
401
- pinorder = Origen.app.pin_pattern_order.dup
402
- pinexclude = Origen.app.pin_pattern_exclude.dup
403
-
404
- if Origen.app.pin_pattern_order.last.is_a?(Hash)
405
- options.merge!(pinorder.pop)
406
- end
407
- if Origen.app.pin_pattern_exclude.last.is_a?(Hash)
408
- options.merge!(pinexclude.pop)
409
- end
410
-
411
- ordered_pins = []
412
-
413
- # Create a copy of all pins and groups to be output, pins/groups will be delete from here as
414
- # they are output, so that at the end of the user defined pin order what is left in here can
415
- # either be discarded or output at the end
416
- pins = Origen.pin_bank.pins.dup
417
- pingroups = Origen.pin_bank.pin_groups.dup
418
-
419
- if pinorder && pinorder.size > 0
420
- pinorder.each do |id|
421
- # If the ID refers to a pin group
422
- if group = Origen.pin_bank.pin_groups[id]
423
- # If the group has still to be output just do that now
424
- if pingroups.include? group.id
425
- ordered_pins << group
426
- # Now delete the group from the list of groups still to be output and all of its pins
427
- # from the list pins still to be output
428
- group.each do |pin|
429
- pins.delete(pin.id)
430
- pin.groups.each do |name, _group|
431
- pingroups.delete(name)
432
- end
433
- end
434
- pingroups.delete(group.id)
435
- # To get here the some of the pins in the group have already been output which is preventing
436
- # output of the complete group at this point, in that case output any of its pins that have
437
- # still to go
438
- else
439
- group.each do |pin|
440
- if pins.include? pin.id
441
- ordered_pins << pin
442
- pin.groups.each do |name, _group|
443
- pingroups.delete(name)
444
- end
445
- end
446
- end
447
- end
448
- # this is a pin
449
- else
450
- pin = Origen.pin_bank.find(id)
451
- fail "Undefined pin (#{id}) added to pin_pattern_order" unless pin
452
- ordered_pins << pin
453
- pin.groups.each do |name, _group|
454
- pingroups.delete(name)
455
- end
456
- pin.name = id
457
- pins.delete(pin.id)
458
- end
459
- end
460
- end
461
-
462
- if pinexclude && pinexclude.size > 0
463
- pinexclude.each do |id|
464
- if group = Origen.pin_bank.pin_groups[id]
465
- # see if group is already in ordered_pins
466
- fail "Pin group #{id} is defined both in pin_pattern_order and pin_pattern_exclude" unless pingroups.include? id
467
- # this is a pin group, delete all pins in group
468
- pingroups.delete(id)
469
- group.each do |pin|
470
- fail "Pin (#{pin.name}) in group (#{group.id}) is defined both in pin_pattern_order and pin_pattern_exclude" unless pins.include? pin.id
471
- pins.delete(pin.id)
472
- end
473
- else # this is a pin, delete the pin
474
- pin = Origen.pin_bank.find(id)
475
- fail "Undefined pin (#{id}) added to pin_pattern_exclude" unless pin
476
- fail "Pin #{pin.name} is defined both in pin_pattern_order and pin_pattern_exclude" unless pins.include? pin.id
477
- pin.name = id
478
- pins.delete(pin.id)
479
- pin.groups.each do |name, _group|
480
- pingroups.delete(name)
481
- end
482
- end
483
- end
484
- end
485
-
486
- unless options[:only]
487
- # all the rest of the pins to the end of the pattern order
488
- pins.each do |_id, pin|
489
- # check for port
490
- if pin.belongs_to_a_pin_group?
491
- # Are any of this pin's groups still waiting to be output? pingroups at this point contains
492
- # those groups which have not been rendered yet
493
- group = pingroups.find do |_id, group|
494
- pin.groups.any? { |_pid, pgroup| group == pgroup }
495
- end
496
- if group
497
- ordered_pins << group[1]
498
- group[1].each { |pin| pins.delete(pin.id) }
499
- else
500
- ordered_pins << pin
501
- end
502
- else
503
- ordered_pins << pin
504
- end
505
- end
506
- end
507
-
508
- result = ordered_pins.map do |pin|
509
- if options[:include_inhibited_pins]
510
- pin
511
- else
512
- inhibited_pins.include?(pin) ? nil : pin
513
- end
514
- end
515
- result = result.compact
516
- end
517
- result
518
- end
519
-
520
- def current_pin_vals
521
- ordered_pins_cache.map(&:to_vector).join(' ')
522
- end
523
-
524
- # Returns a regular expression that can be used to get the value
525
- # of the given pin within the string returned by current_pin_vals.
526
- # str = $tester.current_pin_vals # => "1 1 XX10 H X1"
527
- # regex = $tester.regex_for_pin($dut.pins(:jtag)) # => /\w{1} \w{1} (\w{4}) \w{1} \w{2}/
528
- # regex.match(str)
529
- # Regexp.last_match(1) # => "XX10"
530
- #
531
- # @see Vector#pin_value
532
- def regex_for_pin(pin)
533
- @regex_for_pins ||= {}
534
- # Cache this as potentially called many times during pattern generation
535
- @regex_for_pins[pin] ||= begin
536
- regex = '/'
537
- ordered_pins_cache.each do |p|
538
- if pin == p
539
- regex += "(\\w{#{p.size}}) "
540
- else
541
- regex += "\\w{#{p.size}} "
542
- end
543
- end
544
- eval(regex.strip + '/')
545
- end
546
- end
547
-
548
- # Returns a regular expression that can be used to change the value
549
- # of the given pin within the string returned by current_pin_vals.
550
- # str = $tester.current_pin_vals # => "1 1 XX10 H X1"
551
- # regex = $tester.regex_for_pin_sub($dut.pins(:jtag)) # => /(\w{1} \w{1} )(\w{4})( \w{1} \w{2})/
552
- # str.sub(regex, '\1LLLL\3') # => "1 1 LLLL H X1"
553
- #
554
- # @see Vector#set_pin_value
555
- def regex_for_pin_sub(pin)
556
- @regex_for_pin_subs ||= {}
557
- # Cache this as potentially called many times during pattern generation
558
- @regex_for_pin_subs[pin] ||= begin
559
- regex = '/'
560
- first_pin_done = false
561
- match_pin_done = false
562
- ordered_pins_cache.each do |p|
563
- if pin == p
564
- regex += ')' if first_pin_done
565
- regex += "(\\w{#{p.size}})( "
566
- else
567
- regex += '(' unless first_pin_done
568
- regex += "\\w{#{p.size}} "
569
- end
570
- first_pin_done = true
571
- end
572
- regex.strip!
573
- if regex[-1] == '('
574
- regex.chop!
575
- else
576
- regex += ')'
577
- end
578
- eval(regex + '/')
579
- end
580
- end
581
-
582
- def get_pingroup(pin)
583
- pingroup_map.each do |id, pins|
584
- return id if pins.include? pin
585
- end
586
- nil
587
- end
588
-
589
- def update_pin_from_formatted_state(pin, state)
590
- if state == @repeat_previous || state == '-'
591
- pin.repeat_previous = true
592
- elsif state == @drive_very_hi_state || state == '2'
593
- pin.drive_very_hi
594
- elsif state == @drive_hi_state || state == '1'
595
- pin.drive_hi
596
- elsif state == @drive_lo_state || state == '0'
597
- pin.drive_lo
598
- elsif state == @expect_hi_state || state == 'H'
599
- pin.expect_hi
600
- elsif state == @expect_lo_state || state == 'L'
601
- pin.expect_lo
602
- elsif state == @expect_mid_state || state == 'M'
603
- pin.expect_mid
604
- elsif state == @drive_mem_state || state == 'D'
605
- pin.drive_mem
606
- elsif state == @expect_mem_state || state == 'E'
607
- pin.expect_mem
608
- elsif state == @capture_state || state == 'C'
609
- pin.capture
610
- elsif state == @dont_care_state || state == 'X'
611
- pin.dont_care
612
- else
613
- fail "Unknown pin state: #{state}"
614
- end
615
- end
616
-
617
- # @see Origen::Pins::Pin#to_vector
618
- def format_pin_state(pin)
619
- if pin.repeat_previous? && @support_repeat_previous
620
- @repeat_previous || '-'
621
- elsif pin.driving?
622
- if pin.value == 1
623
- if pin.high_voltage?
624
- @drive_very_hi_state || '2'
625
- else
626
- @drive_hi_state || '1'
627
- end
628
- else
629
- @drive_lo_state || '0'
630
- end
631
- elsif pin.comparing_midband?
632
- @expect_mid_state || 'M'
633
- elsif pin.comparing?
634
- if pin.value == 1
635
- @expect_hi_state || 'H'
636
- else
637
- @expect_lo_state || 'L'
638
- end
639
- elsif pin.driving_mem?
640
- @drive_mem_state || 'D'
641
- elsif pin.comparing_mem?
642
- @expect_mem_state || 'E'
643
- elsif pin.to_be_captured?
644
- @capture_state || 'C'
645
- else
646
- @dont_care_state || 'X'
647
- end
648
- end
649
-
650
- # @api private
651
- def remove_store_from_vector(vector)
652
- vector.pin_vals.sub!('C', 'X')
653
- end
654
- end
655
- end
1
+ require 'active_support/concern'
2
+ module OrigenTesters
3
+ module VectorGenerator
4
+ extend ActiveSupport::Concern
5
+
6
+ require 'erb'
7
+
8
+ included do
9
+ # When set to true vector and cycle number comments will be appended to pattern vectors.
10
+ # This can also be enabled by running the generate command with the '-v' switch.
11
+ attr_accessor :vector_comments
12
+ attr_accessor :compress
13
+ attr_accessor :expand_repeats
14
+ end
15
+
16
+ def vector_group_size
17
+ @vector_group_size || 1
18
+ end
19
+
20
+ def vector_group_size=(number)
21
+ if number > 1 && number.odd?
22
+ fail 'Only even numbers can be supplied for the vector_group_size!'
23
+ end
24
+ # Each pattern should run with its own tester instance, but just in case
25
+ @pipeline = nil
26
+ @vector_group_size = number
27
+ end
28
+
29
+ def with_vector_group_size(number)
30
+ orig = vector_group_size
31
+ self.vector_group_size = number
32
+ yield
33
+ self.vector_group_size = orig
34
+ end
35
+
36
+ # Duplicate the last vector as required until aligned with the start of the
37
+ # next vector group
38
+ def align
39
+ stage.store :align
40
+ end
41
+ alias_method :align_to_first, :align
42
+
43
+ # Duplicate the last vector as required until aligned to the last vector of the
44
+ # current vector group
45
+ def align_to_last
46
+ stage.store :align_last
47
+ end
48
+
49
+ # Returns an array of pin IDs that are currently inhibited (will not
50
+ # be included when vectors are generated)
51
+ def inhibited_pins
52
+ @inhibited_pins ||= []
53
+ end
54
+
55
+ # init vector count when first accessed, otherwise return value
56
+ def vec_count
57
+ @vec_count ||= 0
58
+ end
59
+
60
+ # increment vector count
61
+ def inc_vec_count(num = 1)
62
+ vec_count if @vec_count.nil? # define if not already
63
+ @vec_count = @vec_count + num
64
+ end
65
+
66
+ # decrement vector count
67
+ def dec_vec_count(num = 1)
68
+ vec_count if @vec_count.nil? # define if not already
69
+ @vec_count = @vec_count - num
70
+ end
71
+
72
+ # Returns the current cycle count
73
+ def cycle_count
74
+ @cycle_count ||= 0
75
+ end
76
+
77
+ # Returns the current execution time
78
+ def execution_time_in_ns
79
+ @execution_time_in_ns ||= 0
80
+ end
81
+
82
+ # increment cycle count
83
+ def inc_cycle_count(num = 1, options = {})
84
+ num, options = 1, num if num.is_a?(Hash)
85
+ cycle_count if @cycle_count.nil? # define if not already
86
+ execution_time_in_ns if @execution_time_in_ns.nil? # define if not already
87
+ @execution_time_in_ns += num * (options[:period_in_ns] || tester.timeset.period_in_ns)
88
+ @cycle_count = @cycle_count + num
89
+ end
90
+
91
+ # reset_cycle_count
92
+ def reset_cycle_count(num = 0)
93
+ cycle_count if @cycle_count.nil? # define if not already
94
+ @execution_time_in_ns = 0
95
+ @cycle_count = num
96
+ end
97
+
98
+ # Call to prevent the given pins from appearing in the generated vectors.
99
+ #
100
+ # This is a convenient way to inhibit something like a J750 mux pin from
101
+ # appearing in the patterns when generating the pattern for a different
102
+ # platform.
103
+ #
104
+ # When used this
105
+ # method must be called before the first vector is generated - it will not be retrospectively
106
+ # applied to existing vectors.
107
+ def inhibit_pin(*pins)
108
+ pins.each do |pin|
109
+ pin = $dut.pin(pin) if pin.is_a?(Symbol)
110
+ inhibited_pins << pin
111
+ end
112
+ inhibited_pins.uniq!
113
+ inhibited_pins.compact!
114
+ inhibited_pins
115
+ end
116
+ alias_method :inhibit_pins, :inhibit_pin
117
+
118
+ # Render content directly into a pattern, any options will be passed to the template
119
+ def render(template, options = {})
120
+ # Record the current file, this can be used to resolve any relative path
121
+ # references in the file about to be compiled
122
+ Origen.file_handler.current_file = template
123
+ # Ran into crosstalk problems when rendering ERB templates recursively, setting eoutvar based
124
+ # on the name of the file will causes each template to be rendered into its own 'bank'.
125
+ # Not sure why the final gsub is needed but seems to fail to parse correctly otherwise.
126
+ eoutvar = Pathname.new(template).basename('.*').basename('.*').to_s.gsub('-', '_')
127
+ # Make the file name available to the template
128
+ Origen.generator.compiler.options[:file] = template
129
+ options.each { |k, v| Origen.generator.compiler.options[k] = v }
130
+ code = Origen.generator.compiler.insert(ERB.new(File.read(template.to_s), 0, Origen.config.erb_trim_mode, eoutvar).result)
131
+ code.strip!
132
+ push_microcode code
133
+ end
134
+
135
+ # If the tester defines a method named template this method will compile
136
+ # whatever template file is returned by that method.
137
+ #
138
+ # This method is called automatically after the body section of a Pattern.create
139
+ # operation has completed.
140
+ def render_template
141
+ _render(:template)
142
+ end
143
+
144
+ # Same as the render method, except the template method should be called body_template.
145
+ def render_body
146
+ _render(:body_template)
147
+ end
148
+
149
+ # If the tester defines a method named footer_template this method will compile
150
+ # whatever template file is returned by that method.
151
+ #
152
+ # This method is called automatically during the footer section of a Pattern.create
153
+ # operation.
154
+ def render_footer
155
+ _render(:footer_template)
156
+ end
157
+
158
+ # If the tester defines a method named header_template this method will compile
159
+ # whatever template file is returned by that method.
160
+ #
161
+ # This method is called automatically during the header section of a Pattern.create
162
+ # operation.
163
+ def render_header
164
+ _render(:header_template)
165
+ end
166
+
167
+ def _render(method) # :nodoc:
168
+ if self.respond_to?(method)
169
+ template = send(method)
170
+ # Record the current file, this can be used to resolve any relative path
171
+ # references in the file about to be compiled
172
+ Origen.file_handler.current_file = template
173
+ # Ran into crosstalk problems when rendering ERB templates recursively, setting eoutvar based
174
+ # on the name of the file will causes each template to be rendered into its own 'bank'.
175
+ # Not sure why the final gsub is needed but seems to fail to parse correctly otherwise.
176
+ eoutvar = Pathname.new(template).basename('.*').basename('.*').to_s.gsub('-', '_')
177
+ # Make the file name available to the template
178
+ Origen.generator.compiler.options[:file] = template
179
+ push_microcode Origen.generator.compiler.insert(ERB.new(File.read(template.to_s), 0, Origen.config.erb_trim_mode, eoutvar).result)
180
+ end
181
+ end
182
+
183
+ def stage
184
+ Origen.generator.stage
185
+ end
186
+
187
+ def push_comment(msg)
188
+ # Comments are stored verbatim for now, can't see much use for a dedicated comment object
189
+ stage.store msg unless @inhibit_comments
190
+ end
191
+
192
+ def microcode(code, options = {})
193
+ unless @inhibit_vectors
194
+ if options[:offset] && options[:offset] != 0
195
+ stage.insert_from_end code, options[:offset]
196
+ else
197
+ stage.store code
198
+ end
199
+ end
200
+ end
201
+ alias_method :push_microcode, :microcode
202
+
203
+ def last_vector(offset = 0)
204
+ stage.last_vector(offset)
205
+ end
206
+
207
+ def last_object(offset = 0)
208
+ stage.last_object(offset)
209
+ end
210
+
211
+ # Allows the attributes for the next vector to be setup prior
212
+ # to generating it.
213
+ #
214
+ # A block can be optionally supplied to act as a clean up method,
215
+ # that is the block will be saved and executed after the next
216
+ # cycle has been generated.
217
+ #
218
+ # See the V93K store_next_cycle method for an example of using
219
+ # this.
220
+ def preset_next_vector(attrs = {}, &block)
221
+ @preset_next_vector = attrs
222
+ @preset_next_vector_cleanup = block
223
+ end
224
+
225
+ # Called by every $tester.cycle command to push a vector to the stage object
226
+ def push_vector(attrs = {})
227
+ attrs = {
228
+ dont_compress: @dont_compress
229
+ }.merge(attrs)
230
+ unless @inhibit_vectors
231
+ if @preset_next_vector
232
+ attrs = @preset_next_vector.merge(attrs) do |key, preset, current|
233
+ if preset && current && current != ''
234
+ fail "Value for #{key} set by preset_next_vector clashed with the next vector!"
235
+ else
236
+ preset || current
237
+ end
238
+ end
239
+ @preset_next_vector = nil
240
+ end
241
+ v = Vector.new(attrs)
242
+ stage.store Vector.new(attrs)
243
+ inc_vec_count
244
+ inc_cycle_count(attrs[:repeat] || 1, period_in_ns: v.timeset.period_in_ns)
245
+ if @preset_next_vector_cleanup
246
+ @preset_next_vector_cleanup.call(v)
247
+ @preset_next_vector_cleanup = nil
248
+ end
249
+ end
250
+ end
251
+ alias_method :vector, :push_vector
252
+
253
+ def update_vector(attrs = {})
254
+ unless @inhibit_vectors
255
+ offset = (attrs.delete(:offset) || 0).abs
256
+ stage.last_vector(offset).update(attrs)
257
+ end
258
+ end
259
+
260
+ def update_vector_pin_val(pin, options = {})
261
+ unless @inhibit_vectors
262
+ offset = (options.delete(:offset) || 0).abs
263
+ stage.last_vector(offset).update_pin_val(pin)
264
+ end
265
+ end
266
+
267
+ # Adds the given microcode to the last vector if possible. If not possible (meaning the
268
+ # vector already contains microcode) then a new cycle will be added with the given
269
+ # microcode.
270
+ def add_microcode_to_last_or_cycle(code)
271
+ cycle if !stage.last_vector || stage.last_vector.has_microcode?
272
+ stage.last_vector.update(microcode: code)
273
+ end
274
+
275
+ # Final pass of a generator vector array which returns lines suitable for writing to the
276
+ # output file. This gives the tester model a chance to concatenate repeats and any other
277
+ # last optimization/formatting changes it wishes to make.
278
+ #
279
+ # At this point vector array contains a combination of non-vector lines and uncompressed
280
+ # Vector objects (vector lines)
281
+ #
282
+ def format(vector_array, section)
283
+ # Go through vector_array and print out both
284
+ # vectors and non-vectors to pattern (via 'yield line')
285
+ vector_array.each do |vec|
286
+ # skip here important for the ways delays are currently handled
287
+ # TODO: This seems like an upstream bug that should be investigated, why is such
288
+ # a vector even generated?
289
+ if vec.is_a?(String)
290
+ if vec.strip[0] == comment_char
291
+ pipeline.push_comment(vec)
292
+ else
293
+ pipeline.push_microcode(vec)
294
+ end
295
+ else
296
+ next if vec.respond_to?(:repeat) && vec.repeat == 0 # skip vectors with repeat of 0!
297
+ pipeline << vec
298
+ end
299
+ pipeline.flush do |vector|
300
+ expand_vector(vector) do |line|
301
+ yield line
302
+ end
303
+ end
304
+ end
305
+ # now flush buffer if there is still a vector
306
+ pipeline.empty(min_vectors: section == :footer ? @min_pattern_vectors : nil) do |vector|
307
+ expand_vector(vector) do |line|
308
+ yield line
309
+ end
310
+ end
311
+ end
312
+
313
+ # Tester models can overwrite this if they wish to inject any additional pattern lines
314
+ # at final pattern dump time
315
+ def before_write_pattern_line(line)
316
+ [line]
317
+ end
318
+
319
+ def pipeline
320
+ @pipeline ||= VectorPipeline.new(vector_group_size)
321
+ end
322
+
323
+ def dont_compress
324
+ if block_given?
325
+ orig = @dont_compress
326
+ @dont_compress = true
327
+ yield
328
+ @dont_compress = orig
329
+ else
330
+ @dont_compress
331
+ end
332
+ end
333
+
334
+ def dont_compress=(val)
335
+ @dont_compress = val
336
+ end
337
+
338
+ # expands (uncompresses to pattern) vector if desired or leaves it as is
339
+ # allows for tracking and formatting of vector
340
+ # if comment then return without modification
341
+ def expand_vector(vec)
342
+ if vec.is_a?(Vector)
343
+ if expand_repeats
344
+ vec.repeat.times do
345
+ vec.repeat = 1
346
+ yield track_and_format_vector(vec)
347
+ end
348
+ else
349
+ yield track_and_format_vector(vec)
350
+ end
351
+ else
352
+ yield vec # Return comments without modification
353
+ end
354
+ end
355
+
356
+ # Update tracking info (stats object) and allow for
357
+ # any additional formatting via format_vector
358
+ # method if overridden
359
+ def track_and_format_vector(vec)
360
+ unless vec.timeset
361
+ puts 'No timeset defined!'
362
+ puts 'Add one to your top level startup method or target like this:'
363
+ puts '$tester.set_timeset("nvmbist", 40) # Where 40 is the period in ns'
364
+ exit 1
365
+ end
366
+ stats = Origen.app.stats
367
+ stats.add_vector
368
+ if vector_group_size > 1 && vec.repeat > 1
369
+ stats.add_cycle(1)
370
+ stats.add_cycle((vec.repeat - 1) * vector_group_size)
371
+ stats.add_time_in_ns(vec.timeset.period_in_ns)
372
+ stats.add_time_in_ns((vec.repeat - 1) * vector_group_size * vec.timeset.period_in_ns)
373
+ else
374
+ stats.add_cycle(vec.repeat)
375
+ stats.add_time_in_ns(vec.repeat * vec.timeset.period_in_ns)
376
+ end
377
+ format_vector(vec)
378
+ end
379
+
380
+ def format_vector(vec)
381
+ end
382
+
383
+ def pingroup_map
384
+ Origen.app.pingroup_map
385
+ end
386
+
387
+ # Cache any pin ordering for later use since all vectors should be formatted the same
388
+ def ordered_pins_cache(options = {})
389
+ @ordered_pins_cache ||= ordered_pins(options)
390
+ end
391
+
392
+ def ordered_pins(options = {})
393
+ options = {
394
+ include_inhibited_pins: false,
395
+ include_pingroups: true
396
+ }.merge(options)
397
+
398
+ result = nil
399
+
400
+ Origen.profile 'Working out pin pattern order' do
401
+ pinorder = Origen.app.pin_pattern_order.dup
402
+ pinexclude = Origen.app.pin_pattern_exclude.dup
403
+
404
+ if Origen.app.pin_pattern_order.last.is_a?(Hash)
405
+ options.merge!(pinorder.pop)
406
+ end
407
+ if Origen.app.pin_pattern_exclude.last.is_a?(Hash)
408
+ options.merge!(pinexclude.pop)
409
+ end
410
+
411
+ ordered_pins = []
412
+
413
+ # Create a copy of all pins and groups to be output, pins/groups will be delete from here as
414
+ # they are output, so that at the end of the user defined pin order what is left in here can
415
+ # either be discarded or output at the end
416
+ pins = Origen.pin_bank.pins.dup
417
+ pingroups = Origen.pin_bank.pin_groups.dup
418
+
419
+ if pinorder && pinorder.size > 0
420
+ pinorder.each do |id|
421
+ # If the ID refers to a pin group
422
+ if group = Origen.pin_bank.pin_groups[id]
423
+ # If the group has still to be output just do that now
424
+ if pingroups.include? group.id
425
+ ordered_pins << group
426
+ # Now delete the group from the list of groups still to be output and all of its pins
427
+ # from the list pins still to be output
428
+ group.each do |pin|
429
+ pins.delete(pin.id)
430
+ pin.groups.each do |name, _group|
431
+ pingroups.delete(name)
432
+ end
433
+ end
434
+ pingroups.delete(group.id)
435
+ # To get here the some of the pins in the group have already been output which is preventing
436
+ # output of the complete group at this point, in that case output any of its pins that have
437
+ # still to go
438
+ else
439
+ group.each do |pin|
440
+ if pins.include? pin.id
441
+ ordered_pins << pin
442
+ pin.groups.each do |name, _group|
443
+ pingroups.delete(name)
444
+ end
445
+ end
446
+ end
447
+ end
448
+ # this is a pin
449
+ else
450
+ pin = Origen.pin_bank.find(id)
451
+ fail "Undefined pin (#{id}) added to pin_pattern_order" unless pin
452
+ ordered_pins << pin
453
+ pin.groups.each do |name, _group|
454
+ pingroups.delete(name)
455
+ end
456
+ pin.name = id
457
+ pins.delete(pin.id)
458
+ end
459
+ end
460
+ end
461
+
462
+ if pinexclude && pinexclude.size > 0
463
+ pinexclude.each do |id|
464
+ if group = Origen.pin_bank.pin_groups[id]
465
+ # see if group is already in ordered_pins
466
+ fail "Pin group #{id} is defined both in pin_pattern_order and pin_pattern_exclude" unless pingroups.include? id
467
+ # this is a pin group, delete all pins in group
468
+ pingroups.delete(id)
469
+ group.each do |pin|
470
+ fail "Pin (#{pin.name}) in group (#{group.id}) is defined both in pin_pattern_order and pin_pattern_exclude" unless pins.include? pin.id
471
+ pins.delete(pin.id)
472
+ end
473
+ else # this is a pin, delete the pin
474
+ pin = Origen.pin_bank.find(id)
475
+ fail "Undefined pin (#{id}) added to pin_pattern_exclude" unless pin
476
+ fail "Pin #{pin.name} is defined both in pin_pattern_order and pin_pattern_exclude" unless pins.include? pin.id
477
+ pin.name = id
478
+ pins.delete(pin.id)
479
+ pin.groups.each do |name, _group|
480
+ pingroups.delete(name)
481
+ end
482
+ end
483
+ end
484
+ end
485
+
486
+ unless options[:only]
487
+ # all the rest of the pins to the end of the pattern order
488
+ pins.each do |_id, pin|
489
+ # check for port
490
+ if pin.belongs_to_a_pin_group?
491
+ # Are any of this pin's groups still waiting to be output? pingroups at this point contains
492
+ # those groups which have not been rendered yet
493
+ group = pingroups.find do |_id, group|
494
+ pin.groups.any? { |_pid, pgroup| group == pgroup }
495
+ end
496
+ if group
497
+ ordered_pins << group[1]
498
+ group[1].each { |pin| pins.delete(pin.id) }
499
+ else
500
+ ordered_pins << pin
501
+ end
502
+ else
503
+ ordered_pins << pin
504
+ end
505
+ end
506
+ end
507
+
508
+ result = ordered_pins.map do |pin|
509
+ if options[:include_inhibited_pins]
510
+ pin
511
+ else
512
+ inhibited_pins.include?(pin) ? nil : pin
513
+ end
514
+ end
515
+ result = result.compact
516
+ end
517
+ result
518
+ end
519
+
520
+ def current_pin_vals
521
+ ordered_pins_cache.map(&:to_vector).join(' ')
522
+ end
523
+
524
+ # Returns a regular expression that can be used to get the value
525
+ # of the given pin within the string returned by current_pin_vals.
526
+ # str = $tester.current_pin_vals # => "1 1 XX10 H X1"
527
+ # regex = $tester.regex_for_pin($dut.pins(:jtag)) # => /\w{1} \w{1} (\w{4}) \w{1} \w{2}/
528
+ # regex.match(str)
529
+ # Regexp.last_match(1) # => "XX10"
530
+ #
531
+ # @see Vector#pin_value
532
+ def regex_for_pin(pin)
533
+ @regex_for_pins ||= {}
534
+ # Cache this as potentially called many times during pattern generation
535
+ @regex_for_pins[pin] ||= begin
536
+ regex = '/'
537
+ ordered_pins_cache.each do |p|
538
+ if pin == p
539
+ regex += "(\\w{#{p.size}}) "
540
+ else
541
+ regex += "\\w{#{p.size}} "
542
+ end
543
+ end
544
+ eval(regex.strip + '/')
545
+ end
546
+ end
547
+
548
+ # Returns a regular expression that can be used to change the value
549
+ # of the given pin within the string returned by current_pin_vals.
550
+ # str = $tester.current_pin_vals # => "1 1 XX10 H X1"
551
+ # regex = $tester.regex_for_pin_sub($dut.pins(:jtag)) # => /(\w{1} \w{1} )(\w{4})( \w{1} \w{2})/
552
+ # str.sub(regex, '\1LLLL\3') # => "1 1 LLLL H X1"
553
+ #
554
+ # @see Vector#set_pin_value
555
+ def regex_for_pin_sub(pin)
556
+ @regex_for_pin_subs ||= {}
557
+ # Cache this as potentially called many times during pattern generation
558
+ @regex_for_pin_subs[pin] ||= begin
559
+ regex = '/'
560
+ first_pin_done = false
561
+ match_pin_done = false
562
+ ordered_pins_cache.each do |p|
563
+ if pin == p
564
+ regex += ')' if first_pin_done
565
+ regex += "(\\w{#{p.size}})( "
566
+ else
567
+ regex += '(' unless first_pin_done
568
+ regex += "\\w{#{p.size}} "
569
+ end
570
+ first_pin_done = true
571
+ end
572
+ regex.strip!
573
+ if regex[-1] == '('
574
+ regex.chop!
575
+ else
576
+ regex += ')'
577
+ end
578
+ eval(regex + '/')
579
+ end
580
+ end
581
+
582
+ def get_pingroup(pin)
583
+ pingroup_map.each do |id, pins|
584
+ return id if pins.include? pin
585
+ end
586
+ nil
587
+ end
588
+
589
+ def update_pin_from_formatted_state(pin, state)
590
+ if state == @repeat_previous || state == '-'
591
+ pin.repeat_previous = true
592
+ elsif state == @drive_very_hi_state || state == '2'
593
+ pin.drive_very_hi
594
+ elsif state == @drive_hi_state || state == '1'
595
+ pin.drive_hi
596
+ elsif state == @drive_lo_state || state == '0'
597
+ pin.drive_lo
598
+ elsif state == @expect_hi_state || state == 'H'
599
+ pin.expect_hi
600
+ elsif state == @expect_lo_state || state == 'L'
601
+ pin.expect_lo
602
+ elsif state == @expect_mid_state || state == 'M'
603
+ pin.expect_mid
604
+ elsif state == @drive_mem_state || state == 'D'
605
+ pin.drive_mem
606
+ elsif state == @expect_mem_state || state == 'E'
607
+ pin.expect_mem
608
+ elsif state == @capture_state || state == 'C'
609
+ pin.capture
610
+ elsif state == @dont_care_state || state == 'X'
611
+ pin.dont_care
612
+ else
613
+ fail "Unknown pin state: #{state}"
614
+ end
615
+ end
616
+
617
+ # @see Origen::Pins::Pin#to_vector
618
+ def format_pin_state(pin)
619
+ if pin.repeat_previous? && @support_repeat_previous
620
+ @repeat_previous || '-'
621
+ elsif pin.driving?
622
+ if pin.value == 1
623
+ if pin.high_voltage?
624
+ @drive_very_hi_state || '2'
625
+ else
626
+ @drive_hi_state || '1'
627
+ end
628
+ else
629
+ @drive_lo_state || '0'
630
+ end
631
+ elsif pin.comparing_midband?
632
+ @expect_mid_state || 'M'
633
+ elsif pin.comparing?
634
+ if pin.value == 1
635
+ @expect_hi_state || 'H'
636
+ else
637
+ @expect_lo_state || 'L'
638
+ end
639
+ elsif pin.driving_mem?
640
+ @drive_mem_state || 'D'
641
+ elsif pin.comparing_mem?
642
+ @expect_mem_state || 'E'
643
+ elsif pin.to_be_captured?
644
+ @capture_state || 'C'
645
+ else
646
+ @dont_care_state || 'X'
647
+ end
648
+ end
649
+
650
+ # @api private
651
+ def remove_store_from_vector(vector)
652
+ vector.pin_vals.sub!('C', 'X')
653
+ end
654
+ end
655
+ end