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,8 @@
1
+ require 'origen_testers/test/j750_base_interface'
2
+ module OrigenTesters
3
+ module Test
4
+ class J750HPTInterface < J750BaseInterface
5
+ include OrigenTesters::J750_HPT::Generator
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ require 'origen_testers/test/j750_base_interface'
2
+ module OrigenTesters
3
+ module Test
4
+ class J750Interface < J750BaseInterface
5
+ include OrigenTesters::J750::Generator
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,94 @@
1
+ module OrigenTesters
2
+ module Test
3
+ class NVM
4
+ attr_accessor :blocks
5
+
6
+ include Origen::Pins
7
+ include Origen::Registers
8
+
9
+ def initialize
10
+ add_reg :mclkdiv, 0x03, 16, osch: { pos: 15 },
11
+ asel: { pos: 14 },
12
+ failctl: { pos: 13 },
13
+ parsel: { pos: 12 },
14
+ eccen: { pos: 11 },
15
+ cmdloc: { pos: 8, bits: 3, res: 0b001 },
16
+ clkdiv: { pos: 0, bits: 8, res: 0x18 }
17
+
18
+ add_reg :data, 0x4, 16, d: { pos: 0, bits: 16 }
19
+
20
+ @blocks = [Block.new(0, self), Block.new(1, self), Block.new(2, self)]
21
+ end
22
+
23
+ def find_block_by_id(id)
24
+ @blocks.find { |block| block.id == id }
25
+ end
26
+
27
+ def reg_owner_alias
28
+ %w(flash fmu)
29
+ end
30
+
31
+ def override_method
32
+ :overridden
33
+ end
34
+
35
+ def added_method
36
+ :added
37
+ end
38
+
39
+ def add_proth_reg
40
+ reg :proth, 0x0024, size: 32 do
41
+ bits 31..24, :fprot7, reset: 0xFF
42
+ bits 23..16, :fprot6, reset: 0xEE
43
+ bits 15..8, :fprot5, reset: 0xDD
44
+ bits 7..0, :fprot4, reset: 0x11
45
+ end
46
+ end
47
+ end
48
+
49
+ class NVMSub < NVM
50
+ def redefine_data_reg
51
+ add_reg :data, 0x40, 16, d: { pos: 0, bits: 16 }
52
+ end
53
+
54
+ # Tests that the block format for defining registers works
55
+ def add_reg_with_block_format
56
+ # ** Data Register 3 **
57
+ # This is dreg
58
+ add_reg :dreg, 0x1000, size: 16 do
59
+ # This is dreg bit 15
60
+ bit 15, :bit15, reset: 1
61
+ # **Bit 14** - This does something cool
62
+ #
63
+ # 0 | Coolness is disabled
64
+ # 1 | Coolness is enabled
65
+ bits 14, :bit14
66
+ # This is dreg bit upper
67
+ bits 13..8, :upper
68
+ # This is dreg bit lower
69
+ # This is dreg bit lower line 2
70
+ bit 7..0, :lower, writable: false, reset: 0x55
71
+ end
72
+
73
+ # This is dreg2
74
+ reg :dreg2, 0x1000, size: 16 do
75
+ # This is dreg2 bit 15
76
+ bit 15, :bit15, reset: 1
77
+ # This is dreg2 bit upper
78
+ bits 14..8, :upper
79
+ # This is dreg2 bit lower
80
+ # This is dreg2 bit lower line 2
81
+ bit 7..0, :lower, writable: false, reset: 0x55
82
+ end
83
+
84
+ # Finally a test that descriptions can be supplied via the API
85
+ reg :dreg3, 0x1000, size: 16, description: "** Data Register 3 **\nThis is dreg3" do
86
+ bit 15, :bit15, reset: 1, description: 'This is dreg3 bit 15'
87
+ bit 14, :bit14, description: "**Bit 14** - This does something cool\n\n0 | Coolness is disabled\n1 | Coolness is enabled"
88
+ bits 13..8, :upper, description: 'This is dreg3 bit upper'
89
+ bit 7..0, :lower, writable: false, reset: 0x55, description: "This is dreg3 bit lower\nThis is dreg3 bit lower line 2"
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,110 @@
1
+ module OrigenTesters
2
+ module Test
3
+ class UltraFLEXInterface
4
+ include OrigenTesters::UltraFLEX::Generator
5
+
6
+ # Options passed to Flow.create and Library.create will be passed in here, use as
7
+ # desired to configure your interface
8
+ def initialize(options = {})
9
+ end
10
+
11
+ def log(msg)
12
+ flow.logprint(msg)
13
+ end
14
+
15
+ def func(name, options = {})
16
+ options = {
17
+ duration: :static
18
+ }.merge(options)
19
+
20
+ block_loop(name, options) do |block, i, group|
21
+ ins = test_instances.functional(name)
22
+ ins.set_wait_flags(:a) if options[:duration] == :dynamic
23
+ ins.pin_levels = options.delete(:pin_levels) if options[:pin_levels]
24
+ if group
25
+ pname = "#{name}_b#{i}_pset"
26
+ patsets.add(pname, [{ pattern: "#{name}_b#{i}.PAT" },
27
+ { pattern: 'nvm_global_subs.PAT', start_label: 'subr' }])
28
+ ins.pattern = pname
29
+ flow.test(group, options) if i == 0
30
+ else
31
+ pname = "#{name}_pset"
32
+ patsets.add(pname, [{ pattern: "#{name}.PAT" },
33
+ { pattern: 'nvm_global_subs.PAT', start_label: 'subr' }])
34
+ ins.pattern = pname
35
+ if options[:cz_setup]
36
+ flow.cz(ins, options[:cz_setup], options)
37
+ else
38
+ flow.test(ins, options)
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ def meas(name, options = {})
45
+ options = {
46
+ duration: :static
47
+ }.merge(options)
48
+
49
+ name = "meas_#{name}" unless name.to_s =~ /meas/
50
+
51
+ ins = test_instances.functional(name)
52
+ ins.set_wait_flags(:a) if options[:duration] == :dynamic
53
+ ins.pin_levels = options.delete(:pin_levels) if options[:pin_levels]
54
+
55
+ pname = "#{name}_pset"
56
+ patsets.add(pname, [{ pattern: "#{name}.PAT" },
57
+ { pattern: 'nvm_global_subs.PAT', start_label: 'subr' }])
58
+ ins.pattern = pname
59
+ if options[:cz_setup]
60
+ flow.cz(ins, options[:cz_setup], options)
61
+ else
62
+ use_limit_params = [:lo_limit, :hi_limit, :scale, :units] # define options to strip for flow.test
63
+ options_use_limit = options.dup # duplicate, as modifying options directly, even an assigned copy modifies original
64
+ flow.test(ins, options.reject! { |k, _| use_limit_params.include? k }) # set up test skipping use-limit options
65
+ flow.use_limit(name, options_use_limit) if options_use_limit[:hi_limit] || options_use_limit[:lo_limit] # Only use use-limit if limits present in flow
66
+ end
67
+ end
68
+
69
+ def block_loop(name, options)
70
+ if options[:by_block]
71
+ test_instances.group do |group|
72
+ group.name = name
73
+ $dut.blocks.each_with_index do |block, i|
74
+ yield block, i, group
75
+ end
76
+ end
77
+ else
78
+ yield
79
+ end
80
+ end
81
+
82
+ def por(options = {})
83
+ options = {
84
+ instance_not_available: true
85
+ }.merge(options)
86
+ flow.test('por_ins', options)
87
+ end
88
+
89
+ def para(name, options = {})
90
+ print "UltraFLEX Parametric Test not yet supported for UltraFlex!\n"
91
+ end
92
+
93
+ # OR 2 IDS together into 1 flag
94
+ def or_ids(options = {})
95
+ flow.or_flags(options[:id1], options[:id2], options)
96
+ end
97
+
98
+ def nop(options = {})
99
+ flow.nop options
100
+ end
101
+
102
+ def mto_memory(args)
103
+ # DO NOTHING, NOT YET SUPPORTED IN ULTRAFLEX
104
+ end
105
+
106
+ def bin(number, options = {})
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,115 @@
1
+ module OrigenTesters
2
+ module Test
3
+ class V93KInterface
4
+ include OrigenTesters::V93K::Generator
5
+
6
+ # Options passed to Flow.create and Library.create will be passed in here, use as
7
+ # desired to configure your interface
8
+ def initialize(options = {})
9
+ end
10
+
11
+ def log(msg)
12
+ flow.print_to_datalog(msg)
13
+ end
14
+
15
+ def func(name, options = {})
16
+ options = {
17
+ duration: :static
18
+ }.merge(options)
19
+
20
+ block_loop(name, options) do |block, i, group|
21
+ tm = test_methods.ac_tml.ac_test.functional_test
22
+ ts = test_suites.run(name, options)
23
+ ts.test_method = tm
24
+ ts.levels = options.delete(:pin_levels) if options[:pin_levels]
25
+ if group
26
+ ts.pattern = "#{name}_b#{i}"
27
+ else
28
+ ts.pattern = name.to_s
29
+ # if options[:cz_setup]
30
+ # flow.cz(ins, options[:cz_setup], options)
31
+ # else
32
+ # end
33
+ end
34
+ flow.test ts, options
35
+ end
36
+ end
37
+
38
+ def meas(name, options = {})
39
+ options = {
40
+ duration: :static
41
+ }.merge(options)
42
+
43
+ name = "meas_#{name}" unless name.to_s =~ /meas/
44
+
45
+ tm = test_methods.dc_tml.dc_test.general_pmu
46
+ ts = test_suites.run(name, options)
47
+ ts.test_method = tm
48
+ ts.levels = options.delete(:pin_levels) if options[:pin_levels]
49
+ ts.lo_limit = options[:lo_limit] if options[:lo_limit]
50
+ ts.hi_limit = options[:hi_limit] if options[:hi_limit]
51
+ ts.pattern = name.to_s
52
+ # if options[:cz_setup]
53
+ # flow.cz(ins, options[:cz_setup], options)
54
+ # else
55
+ # use_limit_params = [:lo_limit, :hi_limit, :scale, :units] # define options to strip for flow.test
56
+ # options_use_limit = options.dup # duplicate, as modifying options directly, even an assigned copy modifies original
57
+ # flow.test(ins, options.reject! { |k, _| use_limit_params.include? k }) # set up test skipping use-limit options
58
+ # flow.use_limit(name, options_use_limit) if options_use_limit[:hi_limit] || options_use_limit[:lo_limit] # Only use use-limit if limits present in flow
59
+ # end
60
+ flow.test ts, options
61
+ end
62
+
63
+ def group(name, options = {})
64
+ flow.group name, options do |group|
65
+ yield group
66
+ end
67
+ end
68
+
69
+ def block_loop(name, options)
70
+ if options[:by_block]
71
+ flow.group name, options do |group|
72
+ $dut.blocks.each_with_index do |block, i|
73
+ yield block, i, group
74
+ end
75
+ end
76
+ else
77
+ yield
78
+ end
79
+ end
80
+
81
+ def por(options = {})
82
+ options = {
83
+ instance_not_available: true
84
+ }.merge(options)
85
+ func('por_ins', options)
86
+ end
87
+
88
+ def para(name, options = {})
89
+ # print "UltraFLEX Parametric Test not yet supported for UltraFLEX!\n"
90
+ end
91
+
92
+ # OR 2 IDS together into 1 flag
93
+ # def or_ids(options = {})
94
+ # flow.or_flags(options[:id1], options[:id2], options)
95
+ # end
96
+
97
+ def nop(options = {})
98
+ # flow.nop options
99
+ end
100
+
101
+ def mto_memory(name, options = {})
102
+ # Seriously?!
103
+ end
104
+
105
+ # OR 2 IDS together into 1 flag
106
+ def or_ids(options = {})
107
+ # Eh?
108
+ end
109
+
110
+ def bin(number, options = {})
111
+ flow.good_bin(number, bin_desc: options[:description])
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,362 @@
1
+ module OrigenTesters
2
+ module Timing
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ # When set to true all pattern vectors will be converted to use the same period (the
7
+ # shortest period used in the pattern).
8
+ #
9
+ # @example
10
+ # $tester.set_timeset("fast", 40)
11
+ # 2.cycles # fast 1 0 0 1 0
12
+ # # fast 1 0 0 1 0
13
+ #
14
+ # $tester.level_period = false # Without levelling enabled
15
+ # $tester.set_timeset("slow", 80)
16
+ # 2.cycles # slow 1 0 0 1 0
17
+ # # slow 1 0 0 1 0
18
+ #
19
+ # $tester.level_period = true # With levelling enabled
20
+ # $tester.set_timeset("slow", 80)
21
+ # 2.cycles # fast 1 0 0 1 0
22
+ # # fast 1 0 0 1 0
23
+ # # fast 1 0 0 1 0
24
+ # # fast 1 0 0 1 0
25
+ #
26
+ # @see Timing#timing_toggled_pins
27
+ attr_accessor :level_period
28
+ alias_method :level_period?, :level_period
29
+ attr_writer :timing_toggled_pins
30
+ end
31
+
32
+ class Timeset
33
+ attr_accessor :name, :period_in_ns
34
+
35
+ def initialize(attrs = {})
36
+ attrs.each do |name, value|
37
+ send("#{name}=", value)
38
+ end
39
+ end
40
+
41
+ # Returns true if the timeset has a shorter period than the supplied timeset
42
+ def shorter_period_than?(timeset)
43
+ period_in_ns < timeset.period_in_ns
44
+ end
45
+ end
46
+
47
+ # @see Timing#level_period
48
+ #
49
+ # When period levelling is enabled, vectors will be expanded like this:
50
+ # $tester.set_timeset("fast", 40)
51
+ # 2.cycles # fast 1 0 0 1 0
52
+ # # fast 1 0 0 1 0
53
+ # # Without levelling enabled
54
+ # $tester.set_timeset("slow", 80)
55
+ # 2.cycles # slow 1 0 0 1 0
56
+ # # slow 1 0 0 1 0
57
+ # # With levelling enabled
58
+ # $tester.set_timeset("slow", 80)
59
+ # 2.cycles # fast 1 0 0 1 0
60
+ # # fast 1 0 0 1 0
61
+ # # fast 1 0 0 1 0
62
+ # # fast 1 0 0 1 0
63
+ #
64
+ # The overall time of the levelled/expanded vectors matches that of the unlevelled
65
+ # case. i.e. 4 cycles at fast speed (4 * 40ns = 160ns) is equivalent to 2 cycles
66
+ # at slow speed (2 * 80ns = 160ns).
67
+ #
68
+ # However, what if pin 1 in the example above was a clk pin where the 1 -> 0 transition
69
+ # was handled by the timing setup for that pin.
70
+ # In that case the levelled code is no longer functionally correct since it contains
71
+ # 4 clock pulses while the unlevelled code only has 2.
72
+ #
73
+ # Such pins can be specified via this attribute and the levelling logic will then
74
+ # automatically adjust the drive state to keep the number of pulses correct.
75
+ # It would automatically adjust to the alternative logic state where 0 means 'on'
76
+ # and 1 means 'off' if applicable.
77
+ #
78
+ # $tester.timing_toggled_pins << $dut.pin(:tclk) # This is pin 1
79
+ #
80
+ # $tester.set_timeset("fast", 40)
81
+ # 2.cycles # fast 1 0 0 1 0
82
+ # # fast 1 0 0 1 0
83
+ # # Without levelling enabled
84
+ # $tester.set_timeset("slow", 80)
85
+ # 2.cycles # slow 1 0 0 1 0
86
+ # # slow 1 0 0 1 0
87
+ # # With levelling enabled
88
+ # $tester.set_timeset("slow", 80)
89
+ # 2.cycles # fast 1 0 0 1 0
90
+ # # fast 0 0 0 1 0
91
+ # # fast 1 0 0 1 0
92
+ # # fast 0 0 0 1 0
93
+ #
94
+ # Multiple pins an be specified like this:
95
+ # $tester.timing_toggled_pins = [$dut.pin(:tclk), $dut.pin(:clk)] # Overrides any pins added elsewhere
96
+ # $tester.timing_toggled_pins << [$dut.pin(:tclk), $dut.pin(:clk)] # In addition to any pins added elsewhere
97
+ def timing_toggled_pins
98
+ @timing_toggled_pins ||= []
99
+ @timing_toggled_pins.flatten!
100
+ @timing_toggled_pins
101
+ end
102
+
103
+ # Set the timeset for the next vectors, this will remain in place until the next
104
+ # time this is called.
105
+ #
106
+ # $tester.set_timeset("bist_25mhz", 40)
107
+ #
108
+ # This method also accepts a block in which case the contained vectors will generate
109
+ # with the supplied timeset and subsequent vectors will return to the previous timeset
110
+ # automatically.
111
+ #
112
+ # $tester.set_timeset("bist_25mhz", 40) do
113
+ # $tester.cycle
114
+ # end
115
+ #
116
+ # The arguments can also be supplied as a single array, or not at all. In the latter case
117
+ # the existing timeset will simply be preserved. This is useful if you have timesets that
118
+ # can be conditionally set based on the target.
119
+ #
120
+ # # Target 1
121
+ # $soc.readout_timeset = ["readout", 120]
122
+ # # Target 2
123
+ # $soc.readout_timeset = false
124
+ #
125
+ # # This code is compatible with both targets, in the first case the timeset will switch
126
+ # # over, in the second case the existing timeset will be preserved.
127
+ # $tester.set_timeset($soc.readout_timeset) do
128
+ # $tester.cycle
129
+ # end
130
+ def set_timeset(timeset, period_in_ns = nil)
131
+ if timeset.is_a?(Array)
132
+ timeset, period_in_ns = timeset[0], timeset[1]
133
+ end
134
+ timeset ||= @timeset
135
+ unless timeset.is_a?(Timeset)
136
+ fail 'You must supply a period_in_ns argument to set_timeset' unless period_in_ns
137
+ timeset = Timeset.new(name: timeset.to_s.chomp, period_in_ns: period_in_ns)
138
+ end
139
+ called_timesets << timeset unless called_timesets.map(&:name).include?(timeset.name)
140
+ if @min_period_timeset
141
+ @min_period_timeset = timeset if timeset.shorter_period_than?(@min_period_timeset)
142
+ else
143
+ @min_period_timeset = timeset
144
+ end
145
+ if block_given?
146
+ original = @timeset
147
+ timeset_changed(timeset)
148
+ @timeset = timeset
149
+ yield
150
+ timeset_changed(original)
151
+ @timeset = original
152
+ else
153
+ timeset_changed(timeset)
154
+ @timeset = timeset
155
+ end
156
+ end
157
+
158
+ # Returns the timeset (a Timeset object) with the shortest period that has been
159
+ # encountered so far in the course of generating the current pattern.
160
+ #
161
+ # A tester object is re-instantiated at the start of every pattern which will reset
162
+ # this variable.
163
+ def min_period_timeset
164
+ @min_period_timeset
165
+ end
166
+
167
+ def timeset_changed(timeset)
168
+ if last_vector && last_vector.timeset != timeset
169
+ change = { old: last_vector.timeset, new: timeset }
170
+ # Suppress any duplicate calls
171
+ if !@_last_timeset_change ||
172
+ (@_last_timeset_change[:new] != change[:new] &&
173
+ @_last_timeset_change[:old] != change[:old])
174
+ before_timeset_change(change)
175
+ end
176
+ @_last_timeset_change = change
177
+ end
178
+ end
179
+
180
+ def before_timeset_change(options = {})
181
+ end
182
+
183
+ # Cause the pattern to wait.
184
+ # The following options are available to help you specify the time to wait:
185
+ # * :cycles - delays specified in raw cycles, the test model is responsible for translating this into a sequence of valid repeat statements
186
+ # * :time_in_ns - time specified in nano-seconds
187
+ # * :time_in_us - time specified in micro-seconds
188
+ # * :time_in_ms - time specified in milli-seconds
189
+ # * :time_in_s - time specified in seconds
190
+ # If more than one option is supplied they will get added together to give a final
191
+ # delay time expressed in cycles.
192
+ # ==== Examples
193
+ # $tester.wait(cycles: 100, time_in_ns: 200) # Wait for 100 cycles + 200ns
194
+ # This method can also be used to trigger a match loop in which case the supplied time
195
+ # becomes the time out for the match. See the J750#match method for full details of the
196
+ # available options.
197
+ # $tester.wait(match: true, state: :high, pin: $dut.pin(:done), time_in_ms: 500)
198
+ def wait(options = {})
199
+ options = {
200
+ cycles: 0,
201
+ time_in_cycles: 0,
202
+ time_in_us: 0,
203
+ time_in_ns: 0,
204
+ time_in_ms: 0,
205
+ time_in_s: 0,
206
+ match: false, # Set to true to invoke a match loop where the supplied delay
207
+ # will become the timeout duration
208
+ }.merge(options)
209
+
210
+ cycles = 0
211
+ cycles += options[:cycles] + options[:time_in_cycles]
212
+ cycles += s_to_cycles(options[:time_in_s])
213
+ cycles += ms_to_cycles(options[:time_in_ms])
214
+ cycles += us_to_cycles(options[:time_in_us])
215
+ cycles += ns_to_cycles(options[:time_in_ns])
216
+
217
+ time = cycles * current_period_in_ns # Total delay in ns
218
+ case
219
+ when time < 1000 # When less than 1us
220
+ cc "Wait for #{'a maximum of ' if options[:match]}#{time}ns"
221
+ when time < 1_000_000 # When less than 1ms
222
+ cc "Wait for #{'a maximum of ' if options[:match]}#{(time.to_f / 1000).round(1)}us" # Display delay in us
223
+ when time < 1_000_000_000 # When less than 1s
224
+ cc "Wait for #{'a maximum of ' if options[:match]}#{(time.to_f / 1_000_000).round(1)}ms"
225
+ else
226
+ cc "Wait for #{'a maximum of ' if options[:match]}%.2fs" % (time.to_f / 1_000_000_000)
227
+ end
228
+
229
+ if cycles > 0 # Allow this function to be called with 0 in which case it will just return
230
+ if options[:match]
231
+ if block_given?
232
+ match_block(cycles, options) { yield }
233
+ else
234
+ match(options[:pin], options[:state], cycles, options)
235
+ end
236
+ else
237
+ delay(cycles)
238
+ end
239
+ end
240
+ end
241
+
242
+ # @see Timing#wait
243
+ # @api private
244
+ # This should not be called directly, call via tester#wait
245
+ def delay(cycles, options = {})
246
+ (cycles / max_repeat_loop).times do
247
+ if block_given?
248
+ yield options.merge(repeat: max_repeat_loop)
249
+ else
250
+ cycle(options.merge(repeat: max_repeat_loop))
251
+ end
252
+ end
253
+ if block_given?
254
+ yield options.merge(repeat: (cycles % max_repeat_loop))
255
+ else
256
+ cycle(options.merge(repeat: (cycles % max_repeat_loop)))
257
+ end
258
+ end
259
+
260
+ def max_repeat_loop
261
+ @max_repeat_loop || 65_535
262
+ end
263
+
264
+ def min_repeat_loop
265
+ @min_repeat_loop
266
+ end
267
+
268
+ def called_timesets
269
+ @called_timesets ||= []
270
+ end
271
+
272
+ def current_period_in_ns
273
+ if @timeset
274
+ @timeset.period_in_ns
275
+ else
276
+ fail 'No timeset has been specified yet!'
277
+ end
278
+ end
279
+ alias_method :current_period, :current_period_in_ns
280
+ alias_method :period, :current_period_in_ns
281
+
282
+ def current_timeset
283
+ @timeset
284
+ end
285
+ alias_method :timeset, :current_timeset
286
+
287
+ # Convert the supplied number of cycles to a time, based on the SoC defined cycle period
288
+ def cycles_to_time(cycles) # :nodoc:
289
+ (cycles * current_period_in_ns).to_f / 1_000_000_000
290
+ end
291
+
292
+ # This function can be used to generate a clock or some other repeating function
293
+ # that spans accross a range of vectors.
294
+ # The period of each cycle and the duration of the sequence are supplied via the following
295
+ # options:
296
+ # * :period_in_cycles
297
+ # * :period_in_ns
298
+ # * :period_in_us
299
+ # * :period_in_ms
300
+ # * :duration_in_cycles
301
+ # * :duration_in_ns
302
+ # * :duration_in_us
303
+ # * :duration_in_ms
304
+ # If multiple definitions for either option are supplied then they will be added
305
+ # together.
306
+ # ==== Example
307
+ # # Supply a clock pulse on :pinA for 100ms
308
+ # $tester.count(:period_in_cycles => 10, :duration_in_ms => 100) do
309
+ # $top.pin(:pinA).drive!(1)
310
+ # $top.pin(:pinA).drive!(0)
311
+ # end
312
+ def count(options = {})
313
+ options = { period_in_cycles: 0, period_in_ms: 0, period_in_us: 0, period_in_ns: 0,
314
+ duration_in_cycles: 0, duration_in_ms: 0, duration_in_us: 0, duration_in_ns: 0
315
+ }.merge(options)
316
+
317
+ period_cycles = options[:period_in_cycles] + ms_to_cycles(options[:period_in_ms]) +
318
+ us_to_cycles(options[:period_in_us]) + ns_to_cycles(options[:period_in_ns])
319
+
320
+ duration_cycles = options[:duration_in_cycles] + ms_to_cycles(options[:duration_in_ms]) +
321
+ us_to_cycles(options[:duration_in_us]) + ns_to_cycles(options[:duration_in_ns])
322
+
323
+ total = 0
324
+ while total < duration_cycles
325
+ wait(time_in_cycles: period_cycles)
326
+ yield # Return control back to caller
327
+ total += period_cycles
328
+ end
329
+ end
330
+
331
+ private
332
+
333
+ def s_to_cycles(time) # :nodoc:
334
+ ((time.to_f) * 1000 * 1000 * 1000 / current_period_in_ns).to_int
335
+ end
336
+
337
+ def ms_to_cycles(time) # :nodoc:
338
+ ((time.to_f) * 1000 * 1000 / current_period_in_ns).to_int
339
+ end
340
+
341
+ def us_to_cycles(time) # :nodoc:
342
+ ((time.to_f * 1000) / current_period_in_ns).to_int
343
+ end
344
+
345
+ def ns_to_cycles(time) # :nodoc:
346
+ (time.to_f / current_period_in_ns).to_int
347
+ end
348
+
349
+ def cycles_to_us(cycles) # :nodoc:
350
+ ((cycles.to_f * current_period_in_ns) / (1000)).ceil
351
+ end
352
+
353
+ def cycles_to_ms(cycles) # :nodoc:
354
+ ((cycles.to_f * current_period_in_ns) / (1000 * 1000)).ceil
355
+ end
356
+
357
+ # Cycles to tenths of a second
358
+ def cycles_to_ts(cycles) # :nodoc:
359
+ ((cycles.to_f * current_period_in_ns) / (1000 * 1000 * 100)).ceil
360
+ end
361
+ end
362
+ end