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,23 @@
1
+ module OrigenTesters
2
+ module Generator
3
+ class IdentityMap
4
+ def initialize
5
+ @store = {}
6
+ @versions = {}
7
+ end
8
+
9
+ def current_version_of(obj)
10
+ map = map_for(obj)
11
+ if map
12
+ map[:replaced_by] || map[:instance]
13
+ else
14
+ obj
15
+ end
16
+ end
17
+
18
+ def map_for(obj)
19
+ @store[obj.object_id]
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,11 @@
1
+ module OrigenTesters
2
+ module Generator
3
+ class Placeholder
4
+ attr_accessor :type, :file, :options, :id
5
+
6
+ def initialize(type, file, options = {})
7
+ @type, @file, @options = type, file, options
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,23 @@
1
+ module OrigenTesters
2
+ module Generator
3
+ class TestNumberer
4
+ # Will return a test number for the given test.
5
+ #
6
+ # @param [Hash] options Options to customize the number generation
7
+ # @option options [Integer] :bits (6) The number of bits in the DAC code
8
+ # @option options [Float] :range (1.26) The range parameter, see code formula
9
+ # @option options [Integer] :offset (0) The o
10
+ def test_number_for(test_name, options = {})
11
+ options = {
12
+
13
+ }.merge(options)
14
+ end
15
+
16
+ private
17
+
18
+ def store_file
19
+ @store_file ||= Pathname.new "#{Origen.root}/.test_program/test_numbers"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,12 @@
1
+ module OrigenTesters
2
+ module IGXLBasedTester
3
+ autoload :Base, 'origen_testers/igxl_based_tester/base.rb'
4
+ autoload :J750, 'origen_testers/igxl_based_tester/j750.rb'
5
+ autoload :J750_HPT, 'origen_testers/igxl_based_tester/j750_hpt.rb'
6
+ autoload :UltraFLEX, 'origen_testers/igxl_based_tester/ultraflex.rb'
7
+ end
8
+ # Convenience/Legacy names without the IGXLBasedTester namespace
9
+ autoload :J750, 'origen_testers/igxl_based_tester/j750.rb'
10
+ autoload :J750_HPT, 'origen_testers/igxl_based_tester/j750_hpt.rb'
11
+ autoload :UltraFLEX, 'origen_testers/igxl_based_tester/ultraflex.rb'
12
+ end
@@ -0,0 +1,641 @@
1
+ module OrigenTesters
2
+ module IGXLBasedTester
3
+ # This is the base class of all IGXL-based testers
4
+ class Base
5
+ include VectorBasedTester
6
+
7
+ attr_accessor :software_version
8
+ attr_accessor :pattern_compiler_pinmap
9
+ attr_accessor :memory_test_en
10
+
11
+ # NOTE: DO NOT USE THIS CLASS DIRECTLY ONLY USED AS PARENT FOR
12
+ # DESIRED TESTER CLASS
13
+
14
+ # Returns a new IGXLBasedTester instance, normally there would only ever be one of these
15
+ # assigned to the global variable such as $tester by your target.
16
+ def initialize
17
+ @unique_counter = 0
18
+ @counter_lsb_bits = 0
19
+ @counter_msb_bits = 0
20
+ @max_repeat_loop = 65_535 # 16 bits
21
+ @min_repeat_loop = 2
22
+ @pat_extension = 'atp'
23
+ @active_loads = true
24
+ @pipeline_depth = 34
25
+ @software_version = ''
26
+ @compress = true
27
+ @support_repeat_previous = true
28
+ @match_entries = 10
29
+ @name = ''
30
+ @program_comment_char = ['logprint', "'"]
31
+ @opcode_mode = :extended
32
+ @flags = %w(cpuA cpuB cpuC cpuD)
33
+ @microcode = {}
34
+ @microcode[:enable] = 'enable'
35
+ @microcode[:set_flag] = 'set_cpu'
36
+ @microcode[:mask_vector] = 'ign ifc icc'
37
+
38
+ @mask_vector = false # sticky option to mask all subsequent vectors
39
+
40
+ @min_pattern_vectors = 0 # no minimum
41
+
42
+ @memory_test_en = false # memory test enabled (for all patterns?)
43
+ end
44
+
45
+ def assign_dc_instr_pins(dc_pins)
46
+ @dc_pins = dc_pins
47
+ end
48
+
49
+ def get_dc_instr_pins
50
+ @dc_pins
51
+ end
52
+
53
+ def flows
54
+ parser.flows
55
+ end
56
+
57
+ # Main accessor to all content parsed from existing test program sheets found in the
58
+ # supplied directory or in Origen.config.test_program_output_directory
59
+ def parser(prog_dir = Origen.config.test_program_output_directory)
60
+ unless prog_dir
61
+ fail 'You must supply the directory containing the test program sheets, or define it via Origen.config.test_program_output_directory'
62
+ end
63
+ @parser ||= IGXLBasedTester::Parser.new
64
+ @parsed_dir ||= false
65
+ if @parsed_dir != prog_dir
66
+ @parser.parse(prog_dir)
67
+ @parsed_dir = prog_dir
68
+ end
69
+ @parser
70
+ end
71
+
72
+ # Capture a vector to the tester HRAM.
73
+ #
74
+ # This method applies a store vector (stv) opcode to the previous vector, note that is does
75
+ # not actually generate a new vector.
76
+ #
77
+ # Sometimes when generating vectors within a loop you may want to apply a stv opcode
78
+ # retrospectively to a previous vector, passing in an offset option will allow you
79
+ # to do this.
80
+ #
81
+ # On J750 the pins argument is ignored since the tester only supports whole vector capture.
82
+ #
83
+ # @example
84
+ # $tester.cycle # This is the vector you want to capture
85
+ # $tester.store # This applies the STV opcode
86
+ #
87
+ # $tester.cycle # This one gets stored
88
+ # $tester.cycle
89
+ # $tester.cycle
90
+ # $tester.store(:offset => -2) # Just realized I need to capture that earlier vector
91
+ def store(*pins)
92
+ options = pins.last.is_a?(Hash) ? pins.pop : {}
93
+ options = { offset: 0
94
+ }.merge(options)
95
+ update_vector microcode: 'stv', offset: options[:offset]
96
+ end
97
+ alias_method :to_hram, :store
98
+ alias_method :capture, :store
99
+
100
+ # Capture the next vector generated to HRAM
101
+ #
102
+ # This method applies a store vector (stv) opcode to the next vector to be generated,
103
+ # note that is does not actually generate a new vector.
104
+ #
105
+ # On J750 the pins argument is ignored since the tester only supports whole vector capture.
106
+ #
107
+ # @example
108
+ # $tester.store_next_cycle
109
+ # $tester.cycle # This is the vector that will be captured
110
+ def store_next_cycle(*pins)
111
+ options = pins.last.is_a?(Hash) ? pins.pop : {}
112
+ options = {
113
+ }.merge(options)
114
+ preset_next_vector microcode: 'stv'
115
+ end
116
+ alias_method :store!, :store_next_cycle
117
+
118
+ # Call a subroutine.
119
+ #
120
+ # This method applies a call subroutine opcode to the previous vector, it does not
121
+ # generate a new vector.
122
+ #
123
+ # Subroutines should always be called through this method as it ensures a running
124
+ # log of called subroutines is maintained and which then gets output in the pattern
125
+ # header to import the right dependencies.
126
+ #
127
+ # An offset option is available to make the call on earlier vectors.
128
+ #
129
+ # ==== Examples
130
+ # $tester.call_subroutine("mysub")
131
+ # $tester.call_subroutine("my_other_sub", :offset => -1)
132
+ def call_subroutine(name, options = {})
133
+ options = {
134
+ offset: 0
135
+ }.merge(options)
136
+ called_subroutines << name.to_s.chomp unless called_subroutines.include?(name.to_s.chomp) || @inhibit_vectors
137
+ update_vector microcode: "call #{name}", offset: options[:offset]
138
+ end
139
+
140
+ # Start a subroutine.
141
+ #
142
+ # Generates a global subroutine label. Global is used to adhere to the best practice of
143
+ # containing all subroutines in dedicated patterns, e.g. global_subs.atp
144
+ #
145
+ # ==== Examples
146
+ # $tester.start_subroutine("wait_for_done")
147
+ # < generate your subroutine vectors here >
148
+ # $tester.end_subroutine
149
+ def start_subroutine(name)
150
+ local_subroutines << name.to_s.chomp unless local_subroutines.include?(name.to_s.chomp) || @inhibit_vectors
151
+ microcode "global subr #{name}:"
152
+ end
153
+
154
+ # End a subroutine.
155
+ #
156
+ # Generates a return opcode on the last vector.
157
+ #
158
+ # ==== Examples
159
+ # $tester.start_subroutine("wait_for_done")
160
+ # < generate your subroutine vectors here >
161
+ # $tester.end_subroutine
162
+ # cond: whether return is conditional on a flag (to permit to mix subrs together)
163
+ def end_subroutine(cond = false)
164
+ if cond
165
+ update_vector microcode: 'if (flag) return'
166
+ else
167
+ update_vector microcode: 'return'
168
+ end
169
+ end
170
+
171
+ # Do a frequency measure.
172
+ #
173
+ # Write the necessary micro code to do a frequency measure on the given pin,
174
+ # optionally supply a read code to pass information to the tester.
175
+ #
176
+ # ==== Examples
177
+ # $tester.freq_count($top.pin(:d_out)) # Freq measure on pin "d_out"
178
+ # $tester.freq_count($top.pin(:d_out):readcode => 10)
179
+ def freq_count(pin, options = {})
180
+ options = { readcode: false
181
+ }.merge(options)
182
+
183
+ set_code(options[:readcode]) if options[:readcode]
184
+ cycle(microcode: "#{@microcode[:set_flag]} (cpuA)")
185
+ cycle(microcode: "#{@microcode[:set_flag]} (cpuA)")
186
+ cycle(microcode: "#{@microcode[:set_flag]} (cpuB)")
187
+ cycle(microcode: "#{@microcode[:set_flag]} (cpuC)")
188
+ cycle(microcode: 'freq_loop_1:')
189
+ cycle(microcode: 'if (cpuA) jump freq_loop_1')
190
+ pin.drive_lo
191
+ delay(2000)
192
+ pin.dont_care
193
+ cycle(microcode: "freq_loop_2: #{@microcode[:enable]} (#{@flags[1]})")
194
+ cycle(microcode: 'if (flag) jump freq_loop_2')
195
+ cycle(microcode: "#{@microcode[:enable]} (#{@flags[2]})")
196
+ cycle(microcode: 'if (flag) jump freq_loop_1')
197
+ end
198
+
199
+ # * J750 Specific *
200
+ #
201
+ # Generates a single MTO opcode line for J750
202
+ #
203
+ # Codes implemented: xa load_preset, xa inc, ya load_preset, ya inc, stv_m0, stv_m1, stv_c<br>
204
+ def memory_test(options = {})
205
+ options = {
206
+ gen_vector: true, # Default generate vector not just MTO opcode
207
+ init_counter_x: false, # initialize counter X
208
+ inc_counter_x: false, # increment counter X
209
+ init_counter_y: false, # initialize counter X
210
+ inc_counter_y: false, # increment counter X
211
+ capture_vector: false, # capture vector to memory using all mem types
212
+ capture_vector_mem0: false, # capture vector to memory type 0, here for J750 will be stv_m0
213
+ capture_vector_mem1: false, # capture vector to memory type 1, here for J750 will be stv_m1
214
+ capture_vector_mem2: false, # capture vector to memory type 2, here for J750 will be stv_c
215
+ pin: false, # pin on which to drive or expect data, pass pin object here!
216
+ pin_data: false, # pin data (:none, :drive, :expect)
217
+ }.merge(options)
218
+
219
+ mto_opcode = ''
220
+
221
+ if options[:init_counter_x]
222
+ mto_opcode += ' xa load_preset'
223
+ end
224
+ if options[:inc_counter_x]
225
+ mto_opcode += ' xa inc'
226
+ end
227
+ if options[:init_counter_y]
228
+ mto_opcode += ' ya load_preset'
229
+ end
230
+ if options[:inc_counter_y]
231
+ mto_opcode += ' ya inc'
232
+ end
233
+ if options[:capture_vector]
234
+ mto_opcode += ' stv_m0 stv_m1 stv_c'
235
+ end
236
+ if options[:capture_vector_mem0]
237
+ mto_opcode += ' stv_m0'
238
+ end
239
+ if options[:capture_vector_mem1]
240
+ mto_opcode += ' stv_m1'
241
+ end
242
+ if options[:capture_vector_mem2]
243
+ mto_opcode += ' stv_c'
244
+ end
245
+
246
+ unless mto_opcode.eql?('')
247
+ mto_opcode = '(mto:' + mto_opcode + ')'
248
+ end
249
+
250
+ if options[:gen_vector]
251
+ if options[:pin]
252
+ case options[:pin_data]
253
+ when :drive
254
+ # store current pin state
255
+ cur_pin_state = options[:pin].state.to_sym
256
+ options[:pin].drive_mem
257
+ when :expect
258
+ # store current pin state
259
+ cur_pin_state = options[:pin].state.to_sym
260
+ options[:pin].expect_mem
261
+ end
262
+ end
263
+ cycle(microcode: "#{mto_opcode}")
264
+ if options[:pin]
265
+ # restore previous pin state
266
+ case options[:pin_data]
267
+ when :drive
268
+ options[:pin].state = cur_pin_state
269
+ when :expect
270
+ options[:pin].state = cur_pin_state
271
+ end
272
+ end
273
+ else
274
+ microcode "#{mto_opcode}"
275
+ end
276
+ end
277
+
278
+ # Generates a match loop on up to two pins.
279
+ #
280
+ # This method is not really intended to be called directly, rather you should call
281
+ # via Tester#wait e.g. $tester.wait(:match => true).
282
+ #
283
+ # The timeout should be provided in cycles, however when called via the wait method the
284
+ # time-based helpers (time_in_us, etc) will be converted to cycles for you.
285
+ # The following options are available to tailor the match loop behavior, defaults in
286
+ # parenthesis:
287
+ # * :pin - The pin object to match on (*required*)
288
+ # * :state - The pin state to match on, :low or :high (*required*)
289
+ # * :pin2 (nil) - Optionally supply a second pin to match on
290
+ # * :state2 (nil) - State for the second pin (required if :pin2 is supplied)
291
+ # * :check_for_fails (false) - Flushes the pipeline and handshakes with the tester (passing readcode 100) prior to the match (to allow binout of fails encountered before the match)
292
+ # * :force_fail_on_timeout (true) - Force a vector mis-compare if the match loop times out
293
+ # * :on_timeout_goto ("") - Optionally supply a label to branch to on timeout, by default will continue from the end of the match loop
294
+ # * :on_pin_match_goto ("") - Optionally supply a label to branch to when pin 1 matches, by default will continue from the end of the match loop
295
+ # * :on_pin2_match_goto ("") - Optionally supply a label to branch to when pin 2 matches, by default will continue from the end of the match loop
296
+ # * :multiple_entries (false) - Supply an integer to generate multiple entries into the match (each with a unique readcode), this can be useful when debugging patterns with multiple matches
297
+ # * :force_fail_on_timeout (true) - force pattern to fail if timeout occurs
298
+ # * :global_loops (false) - whether match loop loops should use global labels
299
+ # * :manual_stop (false) - whether to use extra cpuB flag to resolve IG-XL v.3.50.xx bug where VBT clears cpuA immediately
300
+ # at start of PatFlagFunc instead of at end. Use will have to manually clear cpuB to resume this pattern.
301
+ # ==== Examples
302
+ # $tester.wait(:match => true, :time_in_us => 5000, :pin => $top.pin(:done), :state => :high)
303
+ def match(pin, state, timeout, options = {})
304
+ options = {
305
+ check_for_fails: false,
306
+ on_timeout_goto: false,
307
+ pin2: false,
308
+ state2: false,
309
+ on_pin_match_goto: false,
310
+ multiple_entries: false,
311
+ force_fail_on_timeout: true,
312
+ global_loops: false,
313
+ manual_stop: false,
314
+ clr_fail_post_match: false
315
+ }.merge(options)
316
+
317
+ match_block(timeout, options) do |match_conditions, fail_conditions|
318
+ # Define match conditions
319
+ match_conditions.add do
320
+ state == :low ? pin.expect_lo : pin.expect_hi
321
+ cc "Check if #{pin.name} is #{state == :low ? 'low' : 'high'}"
322
+ cycle
323
+ pin.dont_care
324
+ end
325
+
326
+ if options[:pin2]
327
+ match_conditions.add do
328
+ state == :low ? pin.expect_hi : pin.expect_lo
329
+ options[:state2] == :low ? options[:pin2].expect_lo : options[:pin2].expect_hi
330
+ cc "Check if #{options[:pin2].name} is #{options[:state2] == :low ? 'low' : 'high'}"
331
+ cycle
332
+ options[:pin2].dont_care
333
+ pin.dont_care
334
+ end
335
+ end
336
+
337
+ # Define fail conditions
338
+ fail_conditions.add do
339
+ state == :low ? pin.expect_lo : pin.expect_hi
340
+ cc "Check if #{pin.name} is #{state == :low ? 'low' : 'high'}"
341
+ if options[:pin2]
342
+ options[:state2] == :low ? options[:pin2].expect_lo : options[:pin2].expect_hi
343
+ cc "Check if #{options[:pin2].name} is #{options[:state2] == :low ? 'low' : 'high'}"
344
+ end
345
+ cycle
346
+ pin.dont_care
347
+ options[:pin2].dont_care if options[:pin2]
348
+ end
349
+ end
350
+ end
351
+
352
+ # Call a match loop.
353
+ #
354
+ # Normally you would put your match loop in a global subs pattern, then you can
355
+ # call it via this method. This method automatically syncs match loop naming with
356
+ # the match generation flow, no arguments required.
357
+ #
358
+ # This is an IGXLBasedTester specific API.
359
+ #
360
+ # ==== Examples
361
+ # $tester.cycle
362
+ # $tester.call_match # Calls the match loop, or the first entry point if you have multiple
363
+ # $tester.cycle
364
+ # $tester.call_match # Calls the match loop, or the second entry point if you have multiple
365
+ def call_match
366
+ @match_counter = @match_counter || 0
367
+ call_subroutine("match_done_#{@match_counter}")
368
+ @match_counter += 1 unless @match_counter == (@match_entries || 1) - 1
369
+ end
370
+
371
+ # Apply a label to the pattern.
372
+ #
373
+ # No additional vector is generated.
374
+ # Arguments:
375
+ # name : label name
376
+ # global : (optional) whether to apply global label, default=false
377
+ #
378
+ # ==== Examples
379
+ # $tester.label("something_significant")
380
+ # $tester.label("something_significant",true) # apply global label
381
+ def label(name, global = false)
382
+ global_opt = (global) ? 'global ' : ''
383
+ microcode global_opt + name + ':'
384
+ end
385
+
386
+ # * J750 Specific *
387
+ #
388
+ # Set a readcode.
389
+ #
390
+ # Use the set an explicit readcode for communicating with the tester. This method
391
+ # will generate an additional vector.
392
+ #
393
+ # ==== Examples
394
+ # $tester.set_code(55)
395
+ def set_code(code)
396
+ cycle(microcode: "set_code #{code}")
397
+ end
398
+
399
+ # Branch execution to the given point.
400
+ #
401
+ # This generates a new vector with a jump instruction to a given label. This method
402
+ # will generate an additional vector.
403
+ #
404
+ # ==== Examples
405
+ # $tester.branch_to("something_significant")
406
+ def branch_to(label)
407
+ cycle(microcode: "jump #{label}")
408
+ end
409
+ alias_method :branch, :branch_to
410
+
411
+ # Add loop to the pattern.
412
+ #
413
+ # Pass in a name for the loop and the number of times to execute it, all vectors
414
+ # generated by the given block will be captured in the loop.
415
+ #
416
+ # Optional arguments: global - whether to apply global label (default=false)
417
+ # label_first - whether to apply loop label before loop vector or not
418
+ #
419
+ # ==== Examples
420
+ # $tester.loop_vectors("pulse_loop", 3) do # Do this 3 times...
421
+ # $tester.cycle
422
+ # some_other_method_to_generate_vectors
423
+ # end
424
+ def loop_vectors(name, number_of_loops, global = false, label_first = false)
425
+ if number_of_loops > 1
426
+ @loop_counters ||= {}
427
+ if @loop_counters[name]
428
+ @loop_counters[name] += 1
429
+ else
430
+ @loop_counters[name] = 0
431
+ end
432
+ loop_name = @loop_counters[name] == 0 ? name : "#{name}_#{@loop_counters[name]}"
433
+ if label_first
434
+ global_opt = (global) ? 'global ' : ''
435
+ microcode "#{global_opt}#{loop_name}: "
436
+ end
437
+ cycle(microcode: "loopA #{number_of_loops}")
438
+ unless label_first
439
+ global_opt = (global) ? 'global ' : ''
440
+ cycle(microcode: "#{global_opt}#{loop_name}: ")
441
+ end
442
+ yield
443
+ cycle(microcode: "end_loopA #{loop_name}")
444
+ else
445
+ yield
446
+ end
447
+ end
448
+ alias_method :loop_vector, :loop_vectors
449
+
450
+ # An internal method called by Origen Pattern Create to create the pattern header
451
+ def pattern_header(options = {})
452
+ options = {
453
+ instruments: {}, # Provide instruments here if desired as a hash (e.g. "mto" => "dgen_2bit")
454
+ subroutine_pat: false,
455
+ svm_only: true, # Whether 'svm_only' can be specified
456
+ group: false, # If true the end pattern is intended to run within a pattern group
457
+ high_voltage: false, # Supply a pin name here to declare it as an HV instrument (not yet defined)
458
+ freq_counter: false, # Supply a pin name here to declare it as a frequency counter
459
+ memory_test: false, # If true, define 2-bit MTO DGEN as instrument
460
+ }.merge(options)
461
+
462
+ if level_period?
463
+ microcode "import tset #{min_period_timeset.name};"
464
+ else
465
+ called_timesets.each do |timeset|
466
+ microcode "import tset #{timeset.name};"
467
+ end
468
+ end
469
+ unless options[:group] # Withhold imports for pattern groups, is this correct?
470
+ called_subroutines.each do |sub_name|
471
+ # Don't import any called subroutines that are declared in the current pattern
472
+ microcode "import svm_subr #{sub_name};" unless local_subroutines.include?(sub_name)
473
+ end
474
+ end
475
+
476
+ # If memory test, then add to instruments hash
477
+ if options[:memory_test]
478
+ options[:instruments].merge!('mto' => 'dgen_2bit')
479
+ end
480
+
481
+ if options[:svm_only]
482
+ microcode "svm_only_file = #{options[:subroutine_pat] ? 'yes' : 'no'};"
483
+ end
484
+
485
+ microcode "opcode_mode = #{@opcode_mode};"
486
+ microcode "digital_inst = #{options[:digital_inst]};" if options[:digital_inst]
487
+ microcode 'compressed = yes;' # if $dut.gzip_patterns
488
+
489
+ # Take care of any instruments
490
+ if options[:instruments].length > 0
491
+ microcode 'instruments = {'
492
+ options[:instruments].each do |instrument, setting|
493
+ if "#{setting}" == 'nil'
494
+ microcode " #{instrument};"
495
+ else
496
+ microcode " #{instrument}:#{setting};"
497
+ end
498
+ end
499
+ microcode '}'
500
+ end
501
+
502
+ options[:high_voltage] = @use_hv_pin
503
+ microcode "pin_setup = {#{options[:high_voltage]} high_voltage;}" if options[:high_voltage]
504
+ microcode "pin_setup = {#{options[:freq_counter]} freq_count;}" if options[:freq_counter]
505
+ microcode ''
506
+
507
+ pin_list = ordered_pins.map(&:name).join(', ')
508
+
509
+ # here indicate pattern header specific stuff
510
+ yield pin_list
511
+ max_pin_name_length = ordered_pins.map(&:name).max { |a, b| a.length <=> b.length }.length
512
+ pin_widths = ordered_pins.map { |p| p.size - 1 }
513
+
514
+ max_pin_name_length.times do |i|
515
+ cc((' ' * 93) + ordered_pins.map.with_index { |p, x| ((p.name[i] || ' ') + ' ' * pin_widths[x]).gsub('_', '-') }.join(' '))
516
+ end
517
+ end
518
+
519
+ # An internal method called by Origen to generate the pattern footer
520
+ def pattern_footer(options = {})
521
+ options = {
522
+ subroutine_pat: false,
523
+ end_in_ka: false,
524
+ end_with_halt: false,
525
+ end_module: true
526
+ }.merge(options)
527
+ $tester.align_to_last
528
+ # cycle(:microcode => "#{$dut.end_of_pattern_label}:") if $dut.end_of_pattern_label
529
+ if options[:end_in_ka]
530
+ $tester.cycle microcode: 'keep_alive'
531
+ else
532
+ if options[:end_with_halt]
533
+ $tester.cycle microcode: 'halt'
534
+ else
535
+ if options[:end_module]
536
+ $tester.cycle microcode: 'end_module' unless options[:subroutine_pat]
537
+ else
538
+ $tester.cycle
539
+ end
540
+ end
541
+ end
542
+ microcode '}'
543
+ end
544
+
545
+ # Returns an array of subroutines called while generating the current pattern
546
+ def called_subroutines
547
+ @called_subroutines ||= []
548
+ end
549
+
550
+ # Returns an array of subroutines created by the current pattern
551
+ def local_subroutines # :nodoc:
552
+ @local_subroutines ||= []
553
+ end
554
+
555
+ # This is an internal method use by Origen which returns a fully formatted vector
556
+ # You can override this if you wish to change the output formatting at vector level
557
+ def format_vector(vec)
558
+ timeset = vec.timeset ? "> #{vec.timeset.name}" : ''
559
+ pin_vals = vec.pin_vals ? "#{vec.pin_vals} ;" : ''
560
+ if vec.repeat > 1
561
+ microcode = "repeat #{vec.repeat}"
562
+ else
563
+ microcode = vec.microcode ? vec.microcode : ''
564
+ end
565
+ if vec.pin_vals && ($_testers_enable_vector_comments || vector_comments)
566
+ comment = " // #{vec.number}:#{vec.cycle} #{vec.inline_comment}"
567
+ else
568
+ comment = vec.inline_comment.empty? ? '' : " // #{vec.inline_comment}"
569
+ end
570
+
571
+ "#{microcode.ljust(65)}#{timeset.ljust(31)}#{pin_vals}#{comment}"
572
+ end
573
+
574
+ # Override this to force the formatting to match the v1 J750 model (easier diffs)
575
+ def push_microcode(code) # :nodoc:
576
+ stage.store(code.ljust(65) + ''.ljust(31))
577
+ end
578
+ alias_method :microcode, :push_microcode
579
+
580
+ # All vectors generated with the supplied block will have all pins set
581
+ # to the repeat previous state. Any pins that are changed state within
582
+ # the block will still update to the supplied value.
583
+ # ==== Example
584
+ # # All pins except invoke will be assigned the repeat previous code
585
+ # # in the generated vector. On completion of the block they will
586
+ # # return to their previous state, except for invoke which will
587
+ # # retain the value assigned within the block.
588
+ # $tester.repeat_previous do
589
+ # $top.pin(:invoke).drive(1)
590
+ # $tester.cycle
591
+ # end
592
+ def repeat_previous
593
+ pinmap = Origen.pin_bank.pins
594
+ pinmap.each { |id, pin| pin.repeat_previous = true }
595
+ yield
596
+ pinmap.each { |id, pin| pin.repeat_previous = false }
597
+ end
598
+
599
+ def ignore_fails(*pins)
600
+ pins.each(&:suspend)
601
+ yield
602
+ pins.each(&:resume)
603
+ end
604
+
605
+ def enable_flag(options = {})
606
+ options = { flagnum: 4, # default flag to use
607
+ }.merge(options)
608
+
609
+ if options[:flagnum] > @flags.length
610
+ abort "ERROR! Invalid flag value passed to 'enable_flag' method!\n"
611
+ end
612
+ flagname = @flags[options[:flagnum] - 1]
613
+ update_vector(microcode: "#{@microcode[:enable]}(#{flagname})")
614
+ end
615
+
616
+ def set_flag(options = {})
617
+ options = { flagnum: 4, # default flag to use
618
+ }.merge(options)
619
+
620
+ if options[:flagnum] > @flags.length
621
+ abort "ERROR! Invalid flag value passed to 'set_flag' method!\n"
622
+ end
623
+ flagname = @flags[options[:flagnum] - 1]
624
+ update_vector(microcode: "#{@microcode[:set_flag]}(#{flagname})")
625
+ end
626
+
627
+ def cycle(options = {})
628
+ if @mask_vector
629
+ # tack on masking opcodes
630
+ super(options.merge(microcode: "#{options[:microcode]} #{@microcode[:mask_vector]}"))
631
+ else
632
+ super(options)
633
+ end
634
+ end
635
+
636
+ def mask_fails(setclr)
637
+ @mask_vector = setclr
638
+ end
639
+ end
640
+ end
641
+ end