origen_testers 0.4.0

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 (199) hide show
  1. checksums.yaml +7 -0
  2. data/config/application.rb +140 -0
  3. data/config/commands.rb +73 -0
  4. data/config/development.rb +12 -0
  5. data/config/environment.rb +1 -0
  6. data/config/shared_commands.rb +47 -0
  7. data/config/users.rb +18 -0
  8. data/config/version.rb +8 -0
  9. data/lib/commands/build.rb +69 -0
  10. data/lib/origen_testers.rb +23 -0
  11. data/lib/origen_testers/api.rb +258 -0
  12. data/lib/origen_testers/basic_test_setups.rb +105 -0
  13. data/lib/origen_testers/callback_handlers.rb +58 -0
  14. data/lib/origen_testers/generator.rb +279 -0
  15. data/lib/origen_testers/generator/flow_control_api.rb +611 -0
  16. data/lib/origen_testers/generator/identity_map.rb +23 -0
  17. data/lib/origen_testers/generator/placeholder.rb +11 -0
  18. data/lib/origen_testers/generator/test_numberer.rb +23 -0
  19. data/lib/origen_testers/igxl_based_tester.rb +12 -0
  20. data/lib/origen_testers/igxl_based_tester/base.rb +641 -0
  21. data/lib/origen_testers/igxl_based_tester/base/flow.rb +171 -0
  22. data/lib/origen_testers/igxl_based_tester/base/flow_line.rb +322 -0
  23. data/lib/origen_testers/igxl_based_tester/base/generator.rb +217 -0
  24. data/lib/origen_testers/igxl_based_tester/base/patgroup.rb +109 -0
  25. data/lib/origen_testers/igxl_based_tester/base/patgroups.rb +38 -0
  26. data/lib/origen_testers/igxl_based_tester/base/patset.rb +68 -0
  27. data/lib/origen_testers/igxl_based_tester/base/patset_pattern.rb +56 -0
  28. data/lib/origen_testers/igxl_based_tester/base/patsets.rb +38 -0
  29. data/lib/origen_testers/igxl_based_tester/base/patsubr.rb +68 -0
  30. data/lib/origen_testers/igxl_based_tester/base/patsubr_pattern.rb +56 -0
  31. data/lib/origen_testers/igxl_based_tester/base/patsubrs.rb +38 -0
  32. data/lib/origen_testers/igxl_based_tester/base/test_instance.rb +326 -0
  33. data/lib/origen_testers/igxl_based_tester/base/test_instance_group.rb +58 -0
  34. data/lib/origen_testers/igxl_based_tester/base/test_instances.rb +179 -0
  35. data/lib/origen_testers/igxl_based_tester/files.rb +43 -0
  36. data/lib/origen_testers/igxl_based_tester/j750.rb +248 -0
  37. data/lib/origen_testers/igxl_based_tester/j750/flow.rb +10 -0
  38. data/lib/origen_testers/igxl_based_tester/j750/flow_line.rb +19 -0
  39. data/lib/origen_testers/igxl_based_tester/j750/generator.rb +19 -0
  40. data/lib/origen_testers/igxl_based_tester/j750/patgroup.rb +9 -0
  41. data/lib/origen_testers/igxl_based_tester/j750/patgroups.rb +10 -0
  42. data/lib/origen_testers/igxl_based_tester/j750/patset.rb +9 -0
  43. data/lib/origen_testers/igxl_based_tester/j750/patset_pattern.rb +18 -0
  44. data/lib/origen_testers/igxl_based_tester/j750/patsets.rb +10 -0
  45. data/lib/origen_testers/igxl_based_tester/j750/patsubr.rb +9 -0
  46. data/lib/origen_testers/igxl_based_tester/j750/patsubr_pattern.rb +18 -0
  47. data/lib/origen_testers/igxl_based_tester/j750/patsubrs.rb +10 -0
  48. data/lib/origen_testers/igxl_based_tester/j750/templates/flow.txt.erb +9 -0
  49. data/lib/origen_testers/igxl_based_tester/j750/templates/instances.txt.erb +16 -0
  50. data/lib/origen_testers/igxl_based_tester/j750/templates/patgroups.txt.erb +8 -0
  51. data/lib/origen_testers/igxl_based_tester/j750/templates/patsets.txt.erb +10 -0
  52. data/lib/origen_testers/igxl_based_tester/j750/templates/patsubrs.txt.erb +10 -0
  53. data/lib/origen_testers/igxl_based_tester/j750/test_instance.rb +547 -0
  54. data/lib/origen_testers/igxl_based_tester/j750/test_instance_group.rb +9 -0
  55. data/lib/origen_testers/igxl_based_tester/j750/test_instances.rb +10 -0
  56. data/lib/origen_testers/igxl_based_tester/j750_hpt.rb +34 -0
  57. data/lib/origen_testers/igxl_based_tester/j750_hpt/flow.rb +9 -0
  58. data/lib/origen_testers/igxl_based_tester/j750_hpt/flow_line.rb +9 -0
  59. data/lib/origen_testers/igxl_based_tester/j750_hpt/generator.rb +19 -0
  60. data/lib/origen_testers/igxl_based_tester/j750_hpt/patgroup.rb +9 -0
  61. data/lib/origen_testers/igxl_based_tester/j750_hpt/patgroups.rb +9 -0
  62. data/lib/origen_testers/igxl_based_tester/j750_hpt/patset.rb +9 -0
  63. data/lib/origen_testers/igxl_based_tester/j750_hpt/patset_pattern.rb +9 -0
  64. data/lib/origen_testers/igxl_based_tester/j750_hpt/patsets.rb +9 -0
  65. data/lib/origen_testers/igxl_based_tester/j750_hpt/patsubr.rb +9 -0
  66. data/lib/origen_testers/igxl_based_tester/j750_hpt/patsubr_pattern.rb +9 -0
  67. data/lib/origen_testers/igxl_based_tester/j750_hpt/patsubrs.rb +9 -0
  68. data/lib/origen_testers/igxl_based_tester/j750_hpt/test_instance.rb +515 -0
  69. data/lib/origen_testers/igxl_based_tester/j750_hpt/test_instance_group.rb +9 -0
  70. data/lib/origen_testers/igxl_based_tester/j750_hpt/test_instances.rb +9 -0
  71. data/lib/origen_testers/igxl_based_tester/parser.rb +102 -0
  72. data/lib/origen_testers/igxl_based_tester/parser/ac_spec.rb +9 -0
  73. data/lib/origen_testers/igxl_based_tester/parser/ac_specs.rb +0 -0
  74. data/lib/origen_testers/igxl_based_tester/parser/dc_spec.rb +33 -0
  75. data/lib/origen_testers/igxl_based_tester/parser/dc_specs.rb +48 -0
  76. data/lib/origen_testers/igxl_based_tester/parser/descriptions.rb +339 -0
  77. data/lib/origen_testers/igxl_based_tester/parser/flow.rb +109 -0
  78. data/lib/origen_testers/igxl_based_tester/parser/flow_line.rb +203 -0
  79. data/lib/origen_testers/igxl_based_tester/parser/flows.rb +21 -0
  80. data/lib/origen_testers/igxl_based_tester/parser/pattern_set.rb +92 -0
  81. data/lib/origen_testers/igxl_based_tester/parser/pattern_sets.rb +31 -0
  82. data/lib/origen_testers/igxl_based_tester/parser/test_instance.rb +341 -0
  83. data/lib/origen_testers/igxl_based_tester/parser/test_instances.rb +24 -0
  84. data/lib/origen_testers/igxl_based_tester/parser/timeset.rb +13 -0
  85. data/lib/origen_testers/igxl_based_tester/parser/timesets.rb +0 -0
  86. data/lib/origen_testers/igxl_based_tester/ultraflex.rb +477 -0
  87. data/lib/origen_testers/igxl_based_tester/ultraflex/flow.rb +10 -0
  88. data/lib/origen_testers/igxl_based_tester/ultraflex/flow_line.rb +19 -0
  89. data/lib/origen_testers/igxl_based_tester/ultraflex/generator.rb +19 -0
  90. data/lib/origen_testers/igxl_based_tester/ultraflex/patgroup.rb +9 -0
  91. data/lib/origen_testers/igxl_based_tester/ultraflex/patgroups.rb +10 -0
  92. data/lib/origen_testers/igxl_based_tester/ultraflex/patset.rb +9 -0
  93. data/lib/origen_testers/igxl_based_tester/ultraflex/patset_pattern.rb +18 -0
  94. data/lib/origen_testers/igxl_based_tester/ultraflex/patsets.rb +10 -0
  95. data/lib/origen_testers/igxl_based_tester/ultraflex/patsubr.rb +9 -0
  96. data/lib/origen_testers/igxl_based_tester/ultraflex/patsubr_pattern.rb +18 -0
  97. data/lib/origen_testers/igxl_based_tester/ultraflex/patsubrs.rb +10 -0
  98. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/flow.txt.erb +9 -0
  99. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/instances.txt.erb +16 -0
  100. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/patgroups.txt.erb +9 -0
  101. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/patsets.txt.erb +10 -0
  102. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/patsubrs.txt.erb +10 -0
  103. data/lib/origen_testers/igxl_based_tester/ultraflex/test_instance.rb +270 -0
  104. data/lib/origen_testers/igxl_based_tester/ultraflex/test_instance_group.rb +9 -0
  105. data/lib/origen_testers/igxl_based_tester/ultraflex/test_instances.rb +10 -0
  106. data/lib/origen_testers/interface.rb +183 -0
  107. data/lib/origen_testers/parser.rb +22 -0
  108. data/lib/origen_testers/parser/description_lookup.rb +62 -0
  109. data/lib/origen_testers/parser/searchable_array.rb +30 -0
  110. data/lib/origen_testers/parser/searchable_hash.rb +30 -0
  111. data/lib/origen_testers/pattern_compilers.rb +116 -0
  112. data/lib/origen_testers/pattern_compilers/assembler.rb +88 -0
  113. data/lib/origen_testers/pattern_compilers/job.rb +96 -0
  114. data/lib/origen_testers/pattern_compilers/ultraflex_pattern_compiler.rb +599 -0
  115. data/lib/origen_testers/program_generators.rb +55 -0
  116. data/lib/origen_testers/smartest_based_tester.rb +8 -0
  117. data/lib/origen_testers/smartest_based_tester/base.rb +411 -0
  118. data/lib/origen_testers/smartest_based_tester/base/flow.rb +188 -0
  119. data/lib/origen_testers/smartest_based_tester/base/flow_node.rb +476 -0
  120. data/lib/origen_testers/smartest_based_tester/base/generator.rb +123 -0
  121. data/lib/origen_testers/smartest_based_tester/base/pattern_compiler.rb +23 -0
  122. data/lib/origen_testers/smartest_based_tester/base/pattern_master.rb +47 -0
  123. data/lib/origen_testers/smartest_based_tester/base/test_method.rb +143 -0
  124. data/lib/origen_testers/smartest_based_tester/base/test_methods.rb +73 -0
  125. data/lib/origen_testers/smartest_based_tester/base/test_methods/ac_tml.rb +33 -0
  126. data/lib/origen_testers/smartest_based_tester/base/test_methods/base_tml.rb +38 -0
  127. data/lib/origen_testers/smartest_based_tester/base/test_methods/custom_tml.rb +19 -0
  128. data/lib/origen_testers/smartest_based_tester/base/test_methods/dc_tml.rb +147 -0
  129. data/lib/origen_testers/smartest_based_tester/base/test_methods/limits.rb +43 -0
  130. data/lib/origen_testers/smartest_based_tester/base/test_suite.rb +166 -0
  131. data/lib/origen_testers/smartest_based_tester/base/test_suites.rb +58 -0
  132. data/lib/origen_testers/smartest_based_tester/v93k.rb +8 -0
  133. data/lib/origen_testers/smartest_based_tester/v93k/builder.rb +89 -0
  134. data/lib/origen_testers/smartest_based_tester/v93k/builder/flow.rb +169 -0
  135. data/lib/origen_testers/smartest_based_tester/v93k/builder/pattern_master.rb +54 -0
  136. data/lib/origen_testers/smartest_based_tester/v93k/flow.rb +10 -0
  137. data/lib/origen_testers/smartest_based_tester/v93k/flow_node.rb +9 -0
  138. data/lib/origen_testers/smartest_based_tester/v93k/generator.rb +19 -0
  139. data/lib/origen_testers/smartest_based_tester/v93k/pattern_compiler.rb +10 -0
  140. data/lib/origen_testers/smartest_based_tester/v93k/pattern_master.rb +10 -0
  141. data/lib/origen_testers/smartest_based_tester/v93k/templates/template.aiv.erb +17 -0
  142. data/lib/origen_testers/smartest_based_tester/v93k/templates/template.flow.erb +201 -0
  143. data/lib/origen_testers/smartest_based_tester/v93k/templates/template.pmfl.erb +13 -0
  144. data/lib/origen_testers/smartest_based_tester/v93k/test_method.rb +9 -0
  145. data/lib/origen_testers/smartest_based_tester/v93k/test_methods.rb +9 -0
  146. data/lib/origen_testers/smartest_based_tester/v93k/test_suite.rb +9 -0
  147. data/lib/origen_testers/smartest_based_tester/v93k/test_suites.rb +9 -0
  148. data/lib/origen_testers/test/basic_interface.rb +17 -0
  149. data/lib/origen_testers/test/block.rb +21 -0
  150. data/lib/origen_testers/test/dut.rb +184 -0
  151. data/lib/origen_testers/test/dut2.rb +76 -0
  152. data/lib/origen_testers/test/j750_base_interface.rb +119 -0
  153. data/lib/origen_testers/test/j750_hpt_interface.rb +8 -0
  154. data/lib/origen_testers/test/j750_interface.rb +8 -0
  155. data/lib/origen_testers/test/nvm.rb +94 -0
  156. data/lib/origen_testers/test/ultraflex_interface.rb +110 -0
  157. data/lib/origen_testers/test/v93k_interface.rb +115 -0
  158. data/lib/origen_testers/timing.rb +362 -0
  159. data/lib/origen_testers/vector.rb +203 -0
  160. data/lib/origen_testers/vector_based_tester.rb +42 -0
  161. data/lib/origen_testers/vector_generator.rb +623 -0
  162. data/lib/origen_testers/vector_pipeline.rb +288 -0
  163. data/pattern/dc_instr.rb +7 -0
  164. data/pattern/delay.rb +7 -0
  165. data/pattern/mem_test.rb +8 -0
  166. data/pattern/multi_vector.rb +117 -0
  167. data/pattern/multi_vector_plus1.rb +125 -0
  168. data/pattern/nvm/j750/add_late_pins.rb +3 -0
  169. data/pattern/nvm/j750/iterator_postfix_test_x_bx.rb +8 -0
  170. data/pattern/nvm/j750/iterator_test_x_bx.rb +8 -0
  171. data/pattern/nvm/j750/j750_halt.rb +159 -0
  172. data/pattern/nvm/j750/j750_workout.rb +202 -0
  173. data/pattern/nvm/j750/timing.rb +73 -0
  174. data/pattern/nvm/v93k/v93k_workout.rb +136 -0
  175. data/pattern/read_write_reg.rb +58 -0
  176. data/pattern/reset.rb +4 -0
  177. data/pattern/subroutines.rb +38 -0
  178. data/program/_additional_erase.rb +7 -0
  179. data/program/_efa_resources.rb +7 -0
  180. data/program/_erase.rb +25 -0
  181. data/program/_erase_vfy.rb +5 -0
  182. data/program/_iv_resources.rb +10 -0
  183. data/program/basic_interface.rb +5 -0
  184. data/program/components/_prb2_main.rb +6 -0
  185. data/program/flow_control.rb +164 -0
  186. data/program/prb1.rb +226 -0
  187. data/program/prb1_resources.rb +28 -0
  188. data/program/prb2.rb +40 -0
  189. data/program/test.rb +20 -0
  190. data/templates/example.txt.erb +53 -0
  191. data/templates/j750/_vt_flow.txt.erb +8 -0
  192. data/templates/j750/_vt_instances.txt.erb +4 -0
  193. data/templates/j750/program_sheet.txt.erb +9 -0
  194. data/templates/manifest/v93k.yaml.erb +22 -0
  195. data/templates/web/index.md.erb +51 -0
  196. data/templates/web/layouts/_basic.html.erb +15 -0
  197. data/templates/web/partials/_navbar.html.erb +22 -0
  198. data/templates/web/release_notes.md.erb +5 -0
  199. metadata +332 -0
@@ -0,0 +1,55 @@
1
+ require 'active_support/concern'
2
+ module OrigenTesters
3
+ # Include this module to create an interface that supports multiple tester
4
+ # types.
5
+ #
6
+ # This module will expose generators for all test platforms supported by
7
+ # the Testers plugin.
8
+ module ProgramGenerators
9
+ extend ActiveSupport::Concern
10
+
11
+ PLATFORMS = [J750, J750_HPT, UltraFLEX, V93K]
12
+
13
+ included do
14
+ Origen.add_interface(self)
15
+ include Generator::FlowControlAPI::Interface
16
+ end
17
+
18
+ module ClassMethods
19
+ # Ensures that the correct generator is loaded before initialize is called
20
+ def new(*args, &block)
21
+ x = allocate
22
+ x._load_generator
23
+ x.send(:initialize, *args, &block)
24
+ x
25
+ end
26
+
27
+ # Returns true if the interface class supports the
28
+ # given tester instance
29
+ def supports?(tester_instance)
30
+ PLATFORMS.include?(tester_instance.class)
31
+ end
32
+ end
33
+
34
+ def initialize(options = {})
35
+ end
36
+
37
+ def tester
38
+ Origen.tester
39
+ end
40
+
41
+ def _load_generator
42
+ if tester.v93k?
43
+ class << self; include OrigenTesters::V93K::Generator; end
44
+ elsif tester.j750_hpt?
45
+ class << self; include OrigenTesters::J750_HPT::Generator; end
46
+ elsif tester.j750?
47
+ class << self; include OrigenTesters::J750::Generator; end
48
+ elsif tester.ultraflex?
49
+ class << self; include OrigenTesters::UltraFLEX::Generator; end
50
+ else
51
+ fail "The Testers::ProgramGenerators module does not support #{tester.class}!"
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,8 @@
1
+ module OrigenTesters
2
+ module SmartestBasedTester
3
+ autoload :Base, 'origen_testers/smartest_based_tester/base.rb'
4
+ autoload :V93K, 'origen_testers/smartest_based_tester/v93k.rb'
5
+ end
6
+ # Convenience/Legacy names without the SmartestBasedTester namespace
7
+ autoload :V93K, 'origen_testers/smartest_based_tester/v93k.rb'
8
+ end
@@ -0,0 +1,411 @@
1
+ module OrigenTesters
2
+ module SmartestBasedTester
3
+ class Base
4
+ include VectorBasedTester
5
+
6
+ # Returns a new J750 instance, normally there would only ever be one of these
7
+ # assigned to the global variable such as $tester by your target:
8
+ # $tester = J750.new
9
+ def initialize
10
+ @max_repeat_loop = 65_535
11
+ @min_repeat_loop = 17
12
+ @pat_extension = 'avc'
13
+ @compress = true
14
+ # @support_repeat_previous = true
15
+ @match_entries = 10
16
+ @name = 'v93k'
17
+ @comment_char = '#'
18
+ @level_period = true
19
+ end
20
+
21
+ # Capture the pin data from a vector to the tester.
22
+ #
23
+ # This method uses the Digital Capture feature (Selective mode) of the V93000 to capture
24
+ # the data from the given pins on the previous vector.
25
+ # Note that is does not actually generate a new vector.
26
+ #
27
+ # Note also that any drive cycles on the target pins can also be captured, to avoid this
28
+ # the wavetable should be set up like this to infer a 'D' (Don't Capture) on vectors where
29
+ # the target pin is being used to drive data:
30
+ #
31
+ # PINS nvm_fail
32
+ # 0 d1:0 r1:D 0
33
+ # 1 d1:1 r1:D 1
34
+ # 2 r1:C Capt
35
+ # 3 r1:D NoCapt
36
+ #
37
+ # Sometimes when generating vectors within a loop you may want to apply a capture
38
+ # retrospectively to a previous vector, passing in an offset option will allow you
39
+ # to do this.
40
+ #
41
+ # ==== Examples
42
+ # $tester.cycle # This is the vector you want to capture
43
+ # $tester.store :pin => pin(:fail) # This applys the required opcode to the given pins
44
+ #
45
+ # $tester.cycle # This one gets captured
46
+ # $tester.cycle
47
+ # $tester.cycle
48
+ # $tester.store(:pin => pin(:fail), :offset => -2) # Just realized I need to capture that earlier vector
49
+ #
50
+ # # Capturing multiple pins:
51
+ # $tester.cycle
52
+ # $tester.store :pins => [pin(:fail), pin(:done)]
53
+ #
54
+ # Since the V93K store operates on a pin level (rather than vector level as on the J750)
55
+ # equivalent functionality can also be achieved by setting the store attribute of the pin
56
+ # itself prior to calling $tester.cycle.
57
+ # However it is recommended to use the tester API to do the store if cross-compatiblity with
58
+ # other platforms, such as the J750, is required.
59
+ def store(*pins)
60
+ options = pins.last.is_a?(Hash) ? pins.pop : {}
61
+ options = { offset: 0
62
+ }.merge(options)
63
+ pins = pins.flatten.compact
64
+ if pins.empty?
65
+ fail 'For the V93K you must supply the pins to store/capture'
66
+ end
67
+ pins.each do |pin|
68
+ pin.restore_state do
69
+ pin.capture
70
+ update_vector_pin_val pin, offset: options[:offset]
71
+ last_vector(options[:offset]).dont_compress = true
72
+ end
73
+ end
74
+ end
75
+ alias_method :capture, :store
76
+
77
+ # Capture the next vector generated to HRAM
78
+ #
79
+ # This method applys a store vector (stv) opcode to the next vector to be generated,
80
+ # note that is does not actually generate a new vector.
81
+ #
82
+ # On J750 the pins argument is ignored since the tester only supports whole vector capture.
83
+ #
84
+ # @example
85
+ # $tester.store_next_cycle
86
+ # $tester.cycle # This is the vector that will be captured
87
+ def store_next_cycle(*pins)
88
+ options = pins.last.is_a?(Hash) ? pins.pop : {}
89
+ options = {
90
+ }.merge(options)
91
+ pins = pins.flatten.compact
92
+ if pins.empty?
93
+ fail 'For the V93K you must supply the pins to store/capture'
94
+ end
95
+ pins.each { |pin| pin.save; pin.capture }
96
+ # Register this clean up function to be run after the next vector
97
+ # is generated, cool or what!
98
+ preset_next_vector do
99
+ pins.each(&:restore)
100
+ end
101
+ end
102
+
103
+ # Start a subroutine.
104
+ #
105
+ # Generates a global subroutine label. Global is used to adhere to the best practice of
106
+ # containing all subroutines in dedicated patterns, e.g. global_subs.atp
107
+ #
108
+ # ==== Examples
109
+ # $tester.start_subroutine("wait_for_done")
110
+ # < generate your subroutine vectors here >
111
+ # $tester.end_subroutine
112
+ def start_subroutine(name)
113
+ local_subroutines << name.to_s.chomp unless local_subroutines.include?(name.to_s.chomp) || @inhibit_vectors
114
+ # name += "_subr" unless name =~ /sub/
115
+ Pattern.open name: name, call_startup_callbacks: false, subroutine: true
116
+ end
117
+
118
+ # Ends the current subroutine that was started with a previous call to start_subroutine
119
+ def end_subroutine(_cond = false)
120
+ Pattern.close call_shutdown_callbacks: false, subroutine: true
121
+ end
122
+
123
+ # Call a subroutine.
124
+ #
125
+ # This calls a subroutine immediately following previous vector, it does not
126
+ # generate a new vector.
127
+ #
128
+ # Subroutines should always be called through this method as it ensures a running
129
+ # log of called subroutines is maintained and which then gets output in the pattern
130
+ # header to import the right dependencies.
131
+ #
132
+ # An offset option is available to make the call on earlier vectors.
133
+ #
134
+ # Repeated calls to the same subroutine will automatically be compressed unless
135
+ # option :suppress_repeated_calls is supplied and set to false. This means that for
136
+ # the common use case of calling a subroutine to implement an overlay the subroutine
137
+ # can be called for every bit that has the overlay and the pattern will automatically
138
+ # generate correctly.
139
+ #
140
+ # ==== Examples
141
+ # $tester.call_subroutine("mysub")
142
+ # $tester.call_subroutine("my_other_sub", :offset => -1)
143
+ def call_subroutine(name, options = {})
144
+ options = {
145
+ offset: 0,
146
+ suppress_repeated_calls: true
147
+ }.merge(options)
148
+ called_subroutines << name.to_s.chomp unless called_subroutines.include?(name.to_s.chomp) || @inhibit_vectors
149
+
150
+ code = "SQPG JSUB #{name};"
151
+ if !options[:suppress_repeated_calls] ||
152
+ last_object != code
153
+ microcode code, offset: (options[:offset] * -1)
154
+ end
155
+ end
156
+
157
+ # Handshake with the tester.
158
+ #
159
+ # ==== Examples
160
+ # $tester.handshake # Pass control to the tester for a measurement
161
+ def handshake(options = {})
162
+ options = {
163
+ }.merge(options)
164
+ Pattern.split(options)
165
+ end
166
+
167
+ # Do a frequency measure.
168
+ #
169
+ # ==== Examples
170
+ # $tester.freq_count($top.pin(:d_out)) # Freq measure on pin "d_out"
171
+ def freq_count(_pin, options = {})
172
+ options = {
173
+ }.merge(options)
174
+ Pattern.split(options)
175
+ end
176
+
177
+ # Generates a match loop on up to two pins.
178
+ #
179
+ # This method is not really intended to be called directly, rather you should call
180
+ # via Tester#wait e.g. $tester.wait(:match => true).
181
+ #
182
+ # The timeout should be provided in cycles, however when called via the wait method the
183
+ # time-based helpers (time_in_us, etc) will be converted to cycles for you.
184
+ # The following options are available to tailor the match loop behavior, defaults in
185
+ # parenthesis:
186
+ #
187
+ # * :pin - The pin object to match on (*required*)
188
+ # * :state - The pin state to match on, :low or :high (*required*)
189
+ # * :check_for_fails (false) - Flushes the pipeline and checks for fails prior to the match (to allow binout of fails encountered before the match)
190
+ # * :pin2 (nil) - Optionally supply a second pin to match on
191
+ # * :state2 (nil) - State for the second pin (required if :pin2 is supplied)
192
+ # * :force_fail_on_timeout (true) - Force a vector mis-compare if the match loop times out
193
+ #
194
+ # ==== Examples
195
+ # $tester.wait(:match => true, :time_in_us => 5000, :pin => $top.pin(:done), :state => :high)
196
+ def match(pin, state, timeout_in_cycles, options = {})
197
+ options = {
198
+ check_for_fails: false,
199
+ pin2: false,
200
+ state2: false,
201
+ force_fail_on_timeout: true,
202
+ global_loops: false,
203
+ generate_subroutine: false,
204
+ force_fail_on_timeout: true
205
+ }.merge(options)
206
+
207
+ # Ensure the match pins are don't care by default
208
+ pin.dont_care
209
+ options[:pin2].dont_care if options[:pin2]
210
+
211
+ # Single condition loops are simple
212
+ if !options[:pin2]
213
+ # Use the counted match loop (rather than timed) which is recommended in the V93K docs for new applications
214
+ # No pre-match failure handling is required here because the system will cleanly record failure info
215
+ # for this kind of match loop
216
+ cc "for the #{pin.name.upcase} pin to go #{state.to_s.upcase}"
217
+ # Need to ensure at least 8 cycles with no compares before entering
218
+ 8.cycles
219
+ number_of_loops = (timeout_in_cycles.to_f / 72).ceil
220
+ # This seems to be a limit on the max MACT value, so account for longer times by expanding
221
+ # the wait loop
222
+ if number_of_loops > 262_144
223
+ mrpt = ((timeout_in_cycles.to_f / 262_144) - 8).ceil
224
+ mrpt = Math.sqrt(mrpt).ceil
225
+ mrpt += (8 - (mrpt % 8)) # Keep to a multiple of 8, but round up to be safe
226
+ number_of_loops = 262_144
227
+ else
228
+ mrpt = 8
229
+ end
230
+ microcode "SQPG MACT #{number_of_loops};"
231
+ # Strobe the pin for the required state
232
+ state == :low ? pin.expect_lo : pin.expect_hi
233
+ # Always do 8 vectors here as this allows reconstruction of test results if multiple loops
234
+ # are called in a pattern
235
+ 8.cycles
236
+ pin.dont_care
237
+ # Now do the wait loop, mrpt should always be a multiple of 8
238
+ microcode "SQPG MRPT #{mrpt};"
239
+ mrpt.times do
240
+ cycle(dont_compress: true)
241
+ end
242
+ microcode 'SQPG PADDING;'
243
+ 8.cycles
244
+
245
+ else
246
+
247
+ # For two pins do something more like the J750 approach where branching based on miscompares is used
248
+ # to keep the loop going
249
+ cc "for the #{pin.name.upcase} pin to go #{state.to_s.upcase}"
250
+ cc "or the #{options[:pin2].name.upcase} pin to go #{options[:state2].to_s.upcase}"
251
+
252
+ if options[:check_for_fails]
253
+ cc 'Return preserving existing errors if the pattern has already failed before arriving here'
254
+ cycle(repeat: propagation_delay)
255
+ microcode 'SQPG RETC 1 1;'
256
+ end
257
+ number_of_loops = (timeout_in_cycles.to_f / ((propagation_delay * 2) + 2)).ceil
258
+
259
+ loop_vectors number_of_loops do
260
+ # Check pin 1
261
+ cc "Check if #{pin.name.upcase} is #{state.to_s.upcase} yet"
262
+ state == :low ? pin.expect_lo! : pin.expect_hi!
263
+ pin.dont_care
264
+ cc 'Wait for failure to propagate'
265
+ cycle(repeat: propagation_delay)
266
+ cc 'Exit match loop if pin has matched (no error), otherwise clear error and remain in loop'
267
+ microcode 'SQPG RETC 0 0;'
268
+
269
+ # Check pin 2
270
+ cc "Check if #{options[:pin2].name.upcase} is #{options[:state2].to_s.upcase} yet"
271
+ options[:state2] == :low ? options[:pin2].expect_lo! : options[:pin2].expect_hi!
272
+ options[:pin2].dont_care
273
+ cc 'Wait for failure to propagate'
274
+ cycle(repeat: propagation_delay)
275
+ cc 'Exit match loop if pin has matched (no error), otherwise clear error and remain in loop'
276
+ microcode 'SQPG RETC 0 0;'
277
+ end
278
+
279
+ if options[:force_fail_on_timeout]
280
+ cc 'To get here something has gone wrong, strobe again to force a pattern failure'
281
+ state == :low ? pin.expect_lo : pin.expect_hi
282
+ options[:state2] == :low ? options[:pin2].expect_lo : options[:pin2].expect_hi if options[:pin2]
283
+ cycle
284
+ pin.dont_care
285
+ options[:pin2].dont_care if options[:pin2]
286
+ end
287
+ end
288
+ end
289
+
290
+ # Returns the number of cycles to wait for any fails to propagate through the pipeline based on
291
+ # the current timeset
292
+ def propagation_delay
293
+ # From 'Calculating the buffer cycles for JMPE and RETC (and match loops)' in SmarTest docs
294
+ data_queue_buffer = (([105, 64 + ((125 + current_period_in_ns - 1) / current_period_in_ns).ceil].min + 3) * 8) + 72
295
+ # Don't know how to calculate at runtime, hardcoding these to some default values for now
296
+ number_of_sites = 128
297
+ sclk_period = 40
298
+ prop_delay_buffer = 195 + ((2 * number_of_sites + 3) * (sclk_period / 2))
299
+ data_queue_buffer + prop_delay_buffer
300
+ end
301
+
302
+ # Add a loop to the pattern.
303
+ #
304
+ # Pass in the number of times to execute it, all vectors
305
+ # generated by the given block will be captured in the loop.
306
+ #
307
+ # ==== Examples
308
+ # $tester.loop_vectors 3 do # Do this 3 times...
309
+ # $tester.cycle
310
+ # some_other_method_to_generate_vectors
311
+ # end
312
+ #
313
+ # For compatibility with the J750 you can supply a name as the first argument
314
+ # and that will simply be ignored when generated for the V93K tester...
315
+ #
316
+ # $tester.loop_vectors "my_loop", 3 do # Do this 3 times...
317
+ # $tester.cycle
318
+ # some_other_method_to_generate_vectors
319
+ # end
320
+ def loop_vectors(name = nil, number_of_loops = 1, _global = false)
321
+ # The name argument is present to maych J750 API, sort out the
322
+ unless name.is_a?(String)
323
+ name, number_of_loops, global = nil, name, number_of_loops
324
+ end
325
+ if number_of_loops > 1
326
+ microcode "SQPG LBGN #{number_of_loops};"
327
+ yield
328
+ microcode 'SQPG LEND;'
329
+ else
330
+ yield
331
+ end
332
+ end
333
+ alias_method :loop_vector, :loop_vectors
334
+
335
+ # An internal method called by Origen to create the pattern header
336
+ def pattern_header(options = {})
337
+ options = {
338
+ }.merge(options)
339
+ pin_list = ordered_pins.map do |p|
340
+ if Origen.app.pin_pattern_order.include?(p.id)
341
+ p.id.to_s.upcase # specified name overrides pin name
342
+ else
343
+ p.name.to_s.upcase
344
+ end
345
+ end.join(' ')
346
+ microcode "FORMAT #{pin_list};"
347
+ max_pin_name_length = ordered_pins.map(&:name).max { |a, b| a.length <=> b.length }.length
348
+ pin_widths = ordered_pins.map { |p| p.size - 1 }
349
+
350
+ max_pin_name_length.times do |i|
351
+ cc((' ' * 50) + ordered_pins.map.with_index { |p, x| ((p.name[i] || ' ') + ' ' * pin_widths[x]).gsub('_', '-') }.join(' '))
352
+ end
353
+ end
354
+
355
+ # An internal method called by Origen to generate the pattern footer
356
+ def pattern_footer(options = {})
357
+ microcode 'SQPG STOP;' unless options[:subroutine]
358
+ end
359
+
360
+ # Returns an array of subroutines called while generating the current pattern
361
+ def called_subroutines
362
+ @called_subroutines ||= []
363
+ end
364
+
365
+ # Returns an array of subroutines created by the current pattern
366
+ def local_subroutines # :nodoc:
367
+ @local_subroutines ||= []
368
+ end
369
+
370
+ # This is an internal method use by Origen which returns a fully formatted vector
371
+ # You can override this if you wish to change the output formatting at vector level
372
+ def format_vector(vec)
373
+ timeset = vec.timeset ? "#{vec.timeset.name}" : ''
374
+ pin_vals = vec.pin_vals ? "#{vec.pin_vals} ;" : ''
375
+ if vec.repeat # > 1
376
+ microcode = "R#{vec.repeat}"
377
+ else
378
+ microcode = vec.microcode ? vec.microcode : ''
379
+ end
380
+ if vec.pin_vals && ($_testers_enable_vector_comments || vector_comments)
381
+ comment = " # #{vec.number}:#{vec.cycle} #{vec.inline_comment}"
382
+ else
383
+ comment = vec.inline_comment.empty? ? '' : " # #{vec.inline_comment}"
384
+ end
385
+ "#{microcode.ljust(25)}#{timeset.ljust(27)}#{pin_vals}#{comment}"
386
+ end
387
+
388
+ # All vectors generated with the supplied block will have all pins set
389
+ # to the repeat previous state. Any pins that are changed state within
390
+ # the block will still update to the supplied value.
391
+ # ==== Example
392
+ # # All pins except invoke will be assigned the repeat previous code
393
+ # # in the generated vector. On completion of the block they will
394
+ # # return to their previous state, except for invoke which will
395
+ # # retain the value assigned within the block.
396
+ # $tester.repeat_previous do
397
+ # $top.pin(:invoke).drive(1)
398
+ # $tester.cycle
399
+ # end
400
+ def repeat_previous
401
+ Origen.app.pin_map.each { |_id, pin| pin.repeat_previous = true }
402
+ yield
403
+ Origen.app.pin_map.each { |_id, pin| pin.repeat_previous = false }
404
+ end
405
+
406
+ def before_timeset_change(options = {})
407
+ microcode "SQPG CTIM #{options[:new].name};" unless level_period?
408
+ end
409
+ end
410
+ end
411
+ end