origen_testers 0.13.1 → 0.13.2

Sign up to get free protection for your applications and to get access to all the features.
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