origen_testers 0.4.0

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