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,9 @@
1
+ module OrigenTesters
2
+ module IGXLBasedTester
3
+ class J750_HPT
4
+ require 'origen_testers/igxl_based_tester/j750/test_instance_group'
5
+ class TestInstanceGroup < J750::TestInstanceGroup
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module OrigenTesters
2
+ module IGXLBasedTester
3
+ class J750_HPT
4
+ require 'origen_testers/igxl_based_tester/j750/test_instances'
5
+ class TestInstances < J750::TestInstances
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,102 @@
1
+ module OrigenTesters
2
+ class IGXLBasedTester
3
+ class Parser
4
+ autoload :Flows, 'origen_testers/igxl_based_tester/parser/flows'
5
+ autoload :Flow, 'origen_testers/igxl_based_tester/parser/flow'
6
+ autoload :FlowLine, 'origen_testers/igxl_based_tester/parser/flow_line'
7
+ autoload :TestInstances, 'origen_testers/igxl_based_tester/parser/test_instances'
8
+ autoload :TestInstance, 'origen_testers/igxl_based_tester/parser/test_instance'
9
+ autoload :PatternSets, 'origen_testers/igxl_based_tester/parser/pattern_sets'
10
+ autoload :PatternSet, 'origen_testers/igxl_based_tester/parser/pattern_set'
11
+ autoload :DCSpecs, 'origen_testers/igxl_based_tester/parser/dc_specs'
12
+ autoload :DCSpec, 'origen_testers/igxl_based_tester/parser/dc_spec'
13
+ autoload :ACSpecs, 'origen_testers/igxl_based_tester/parser/ac_specs'
14
+ autoload :ACSpec, 'origen_testers/igxl_based_tester/parser/ac_spec'
15
+ autoload :Descriptions, 'origen_testers/igxl_based_tester/parser/descriptions'
16
+
17
+ def reset
18
+ @flows = nil
19
+ @test_instances = nil
20
+ @pattern_sets = nil
21
+ @dc_specs = nil
22
+ @ac_specs = nil
23
+ end
24
+
25
+ def descriptions
26
+ @descriptions ||= Descriptions.new(parser: self)
27
+ end
28
+
29
+ # Returns an array of test flows
30
+ def flows
31
+ @flows ||= Flows.new(parser: self)
32
+ end
33
+
34
+ def test_instances
35
+ @test_instances ||= TestInstances.new(parser: self)
36
+ end
37
+ alias_method :instances, :test_instances
38
+
39
+ def pattern_sets
40
+ @pattern_sets ||= PatternSets.new(parser: self)
41
+ end
42
+ alias_method :patsets, :pattern_sets
43
+ alias_method :pat_sets, :pattern_sets
44
+
45
+ def dc_specs
46
+ @dc_specs ||= DCSpecs.new(parser: self)
47
+ end
48
+
49
+ def ac_specs
50
+ @ac_specs ||= ACSpecs.new(parser: self)
51
+ end
52
+
53
+ def inspect
54
+ "<Parsed Program: Flows: #{flows.size}>"
55
+ end
56
+
57
+ # Parse a file, array of files, or a directory.
58
+ #
59
+ # This can be called multiple times to add new files to the
60
+ # program model.
61
+ def parse(file)
62
+ Origen.log.info ''
63
+ Origen.log.info "Parsing J750 test program from: #{file}"
64
+ Origen.log.info ''
65
+ reset
66
+ # Note use of local file handler here, this should be how it is
67
+ # done globally, otherwise we can run into hard to debug problems
68
+ # due to state/reference dir changes in the single Origen.file_handler
69
+ Origen::FileHandler.new.resolve_files(file) do |f|
70
+ parse_file(f)
71
+ end
72
+ Origen.log.info ''
73
+ self
74
+ end
75
+
76
+ def parse_file(file)
77
+ line = File.readlines(file).first
78
+ begin
79
+ if line =~ /Flow Table/
80
+ flows.import(file)
81
+ elsif line =~ /Instances/
82
+ test_instances.import(file)
83
+ elsif line =~ /Pattern Sets/
84
+ patsets.import(file)
85
+ elsif line =~ /DC Spec/
86
+ dc_specs.import(file)
87
+ else
88
+ puts "Skipped (un-supported file type): #{file}"
89
+ end
90
+ rescue Exception => e
91
+ if e.is_a?(ArgumentError) && e.message =~ /invalid byte sequence/
92
+ puts "Skipped (not ASCII): #{file}"
93
+ else
94
+ puts e.message
95
+ puts e.backtrace
96
+ exit 1
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,9 @@
1
+ module OrigenTesters
2
+ class IGXLBasedTester
3
+ class Parser
4
+ class ACSpec
5
+ attr_accessor :collection
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,33 @@
1
+ module OrigenTesters
2
+ class IGXLBasedTester
3
+ class Parser
4
+ class DCSpec
5
+ attr_accessor :parser
6
+ attr_accessor :name, :categories
7
+ alias_method :symbol, :name
8
+
9
+ def initialize(name, categories, options = {})
10
+ @parser = options[:parser]
11
+ @name = name
12
+ @categories = categories
13
+ @values = {}
14
+ end
15
+
16
+ def add_values(components)
17
+ @categories.each_with_index do |category, i|
18
+ @values[category] ||= {}
19
+ @values[category]['Typ'] ||= components[5 + (i * 3) + 0]
20
+ @values[category]['Min'] ||= components[5 + (i * 3) + 1]
21
+ @values[category]['Max'] ||= components[5 + (i * 3) + 2]
22
+ end
23
+ end
24
+
25
+ def lookup(category, selector)
26
+ if v == @values[category]
27
+ v[selector]
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,48 @@
1
+ module OrigenTesters
2
+ class IGXLBasedTester
3
+ class Parser
4
+ class DCSpecs < ::OrigenTesters::Parser::SearchableHash
5
+ attr_accessor :parser
6
+
7
+ def initialize(options = {})
8
+ @parser = options[:parser]
9
+ end
10
+
11
+ def import(file)
12
+ @categories = []
13
+ File.readlines(file).each do |line|
14
+ unless line.strip.empty?
15
+ components = line.split("\t")
16
+ if components[3] == 'Selector'
17
+ extract_categories(components)
18
+ else
19
+ unless components[1] == 'DC Specs' || components[1] == 'Symbol'
20
+ extract_spec(components)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ def inspect
28
+ "<DCSpecs: #{size}>"
29
+ end
30
+
31
+ def extract_categories(components)
32
+ components.each_with_index do |val, i|
33
+ if i > 4
34
+ @categories << val unless val.strip.empty?
35
+ end
36
+ end
37
+ @categories.uniq!
38
+ end
39
+
40
+ def extract_spec(components)
41
+ name = components[1]
42
+ self[name] ||= DCSpec.new(name, @categories, parser: parser)
43
+ self[name].add_values(components)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,339 @@
1
+ module OrigenTesters
2
+ class IGXLBasedTester
3
+ class Parser
4
+ # Extracts embedded test and flow descriptions (comments) from test
5
+ # program source files
6
+ class Descriptions
7
+ require 'fileutils'
8
+
9
+ attr_accessor :source_directories, :template_directories, :parser
10
+
11
+ SCRATCH_DIR = "#{Origen.root}/.j750_scratch"
12
+
13
+ # All descriptions are stored in this lookup table
14
+ def lookup
15
+ return @lookup if @lookup
16
+ # Use the one from the interface if present, program generation will
17
+ # automatically push descriptions in here
18
+ if Origen.interface_present?
19
+ @lookup = Origen.interface.descriptions
20
+ else
21
+ @lookup = ::OrigenTesters::Parser::DescriptionLookup.new
22
+ end
23
+ end
24
+
25
+ def initialize(options = {})
26
+ @parser = options[:parser]
27
+ FileUtils.rm_rf(SCRATCH_DIR) if File.exist?(SCRATCH_DIR)
28
+ parse_program
29
+ true
30
+ end
31
+
32
+ # Returns the description for the given flow
33
+ def flow_summary(options = {})
34
+ lookup.for_flow(options[:file])
35
+ end
36
+
37
+ # Returns the description of the given test from the test
38
+ # instance sheet declaration
39
+ def test_instance(options = {})
40
+ lookup.for_test_definition(options[:name])
41
+ end
42
+
43
+ # Returns the description of the given test from the test
44
+ # flow
45
+ def flow_line(options = {})
46
+ lookup.for_test_usage(options[:name], options[:flow])
47
+ end
48
+
49
+ def parse_program
50
+ Origen.file_handler.preserve_state do
51
+ generate_program_files
52
+ # Comments must be extracted manually for any compiled files, for
53
+ # generated files the comments will already be in the lookup
54
+ extract_flow_summaries
55
+ extract_test_instance_descriptions
56
+ extract_flow_line_descriptions
57
+ end
58
+ end
59
+
60
+ def source_directories
61
+ [@source_directories, Origen.config.test_program_source_directory].compact.flatten
62
+ end
63
+
64
+ def template_directories
65
+ [@template_directories, Origen.config.test_program_template_directory].compact.flatten
66
+ end
67
+
68
+ def extract_flow_summaries
69
+ Origen.file_handler.resolve_files(compiled_dir) do |file|
70
+ if flow_file?(file)
71
+ lookup.add_for_flow(file, parse_flow_summary(file))
72
+ end
73
+ end
74
+ end
75
+
76
+ # Parses a compiled template for marked up comments
77
+ def extract_test_instance_descriptions
78
+ Origen.file_handler.resolve_files(compiled_dir) do |file|
79
+ if instance_file?(file)
80
+ comments = []
81
+ File.readlines(file).each do |line|
82
+ if line =~ /^<comment>(.*)/
83
+ comments << Regexp.last_match[1].gsub("\r", '')
84
+ else
85
+ fields = line.split("\t")
86
+ unless ['Test Instances', '', 'Test Name'].include? fields[1]
87
+ lookup.add_for_test_definition(fields[1], comments)
88
+ end
89
+ comments = []
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ def extract_flow_line_descriptions
97
+ Origen.file_handler.resolve_files(compiled_dir) do |file|
98
+ if flow_file?(file)
99
+ f = file.basename('.txt').to_s
100
+ comments = []
101
+ header_line = true
102
+ File.readlines(file).each do |line|
103
+ if header_line
104
+ header_line = false if line =~ /^\s*Label/
105
+ else
106
+ if line =~ /^<comment>(.*)/
107
+ comments << Regexp.last_match[1].gsub("\r", '')
108
+ else
109
+ if t = FlowLine.extract_test(line)
110
+ lookup.add_for_test_usage(t, file, comments)
111
+ end
112
+ comments = []
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
119
+
120
+ def generate_program_files
121
+ a = generate_program
122
+ b = compile_program
123
+ unless a || b
124
+ fail 'No source or template files declared from which to parse descriptions!'
125
+ end
126
+ end
127
+
128
+ # Parses the given flow file for summary text and returns it, summary
129
+ # text must be the very first thing in the file.
130
+ # Returns an array of strings each representing a line of text.
131
+ def parse_flow_summary(file)
132
+ desc = []
133
+ File.readlines(file).each do |line|
134
+ if line =~ /%?\s*<comment>(.*)/
135
+ desc << Regexp.last_match[1].gsub("\r", '')
136
+ else
137
+ break
138
+ end
139
+ end
140
+ desc
141
+ end
142
+
143
+ # Generate a scratch version of the program for parsing
144
+ def generate_program
145
+ if source_directories.size > 0
146
+ unless @program_generated
147
+ Origen.log.info ''
148
+ Origen.log.info 'Extracting embedded comments:'
149
+ Origen.log.info ''
150
+ copy_source_files_to_scratch
151
+ markup_source_file_comments
152
+ # Compile the flow file, with Ruby comments now preserved and marked up
153
+ desc = Origen.app.runner.generate(program: true, patterns: ungenerated_dir, output: generated_dir,
154
+ check_for_changes: false, collect_stats: false, quiet: true,
155
+ collect_descriptions: true)
156
+ Origen.log.info ''
157
+ end
158
+ @program_generated = true
159
+ else
160
+ false
161
+ end
162
+ end
163
+
164
+ # Compile a scratch version of the program for parsing
165
+ def compile_program
166
+ if template_directories.size > 0
167
+ unless @program_compiled
168
+ Origen.log.info ''
169
+ Origen.log.info 'Extracting embedded comments:'
170
+ Origen.log.info ''
171
+ copy_templates_to_scratch
172
+ markup_template_comments
173
+ # Compile the flow file, with Ruby comments now preserved and marked up
174
+ Origen.app.runner.generate(compile: true, patterns: uncompiled_dir, output: compiled_dir,
175
+ check_for_changes: false, collect_stats: false, quiet: true)
176
+ Origen.log.info ''
177
+ end
178
+ @program_compiled = true
179
+ else
180
+ false
181
+ end
182
+ end
183
+
184
+ # Copy all flow and instance template files to the scratch dir
185
+ def copy_templates_to_scratch
186
+ uncompiled_dir(true)
187
+ template_directories.each do |dir|
188
+ Origen.file_handler.resolve_files(dir) do |file|
189
+ subdir = file.relative_path_from(Pathname.new(dir)).dirname.to_s
190
+ cpydir = "#{uncompiled_dir}/#{subdir}"
191
+ FileUtils.mkdir_p(cpydir) unless File.exist?(cpydir)
192
+ FileUtils.copy(file, cpydir) if flow_or_instance_file?(file)
193
+ end
194
+ end
195
+ `chmod -R 777 #{uncompiled_dir}/*` unless Dir["#{uncompiled_dir}/*"].empty?
196
+ end
197
+
198
+ # Copy all flow and instance source files to the scratch dir
199
+ def copy_source_files_to_scratch
200
+ source_directories.each do |dir|
201
+ Origen.file_handler.resolve_files(dir) do |file|
202
+ subdir = file.relative_path_from(Pathname.new(dir)).dirname.to_s
203
+ cpydir = "#{ungenerated_dir}/#{subdir}"
204
+ FileUtils.mkdir_p(cpydir) unless File.exist?(cpydir)
205
+ FileUtils.copy(file, cpydir)
206
+ end
207
+ end
208
+ end
209
+
210
+ def uncompiled_dir(force_make = false)
211
+ @uncompiled_dir ||= "#{SCRATCH_DIR}/uncompiled"
212
+ if force_make
213
+ FileUtils.rm_rf(@uncompiled_dir) if File.exist?(@uncompiled_dir)
214
+ @uncompiled_dir_created = false
215
+ end
216
+ unless @uncompiled_dir_created
217
+ FileUtils.mkdir_p(@uncompiled_dir) unless File.exist?(@uncompiled_dir)
218
+ @uncompiled_dir_created = true
219
+ end
220
+ @uncompiled_dir
221
+ end
222
+
223
+ def ungenerated_dir
224
+ @ungenerated_dir ||= "#{SCRATCH_DIR}/ungenerated"
225
+ unless @ungenerated_dir_created
226
+ FileUtils.mkdir_p(@ungenerated_dir) unless File.exist?(@ungenerated_dir)
227
+ @ungenerated_dir_created = true
228
+ end
229
+ @ungenerated_dir
230
+ end
231
+
232
+ def compiled_dir
233
+ @compiled_dir ||= "#{SCRATCH_DIR}/compiled"
234
+ unless @compiled_dir_created
235
+ FileUtils.mkdir_p(@compiled_dir) unless File.exist?(@compiled_dir)
236
+ @compiled_dir_created = true
237
+ end
238
+ @compiled_dir
239
+ end
240
+
241
+ def generated_dir
242
+ @generated_dir ||= "#{SCRATCH_DIR}/generated"
243
+ unless @generated_dir_created
244
+ FileUtils.mkdir_p(@generated_dir) unless File.exist?(@generated_dir)
245
+ @generated_dir_created = true
246
+ end
247
+ @generated_dir
248
+ end
249
+
250
+ # Returns true if the given file looks like a J750 flow file, works for
251
+ # templates to
252
+ def flow_or_instance_file?(file, options = {})
253
+ options = { flow: true,
254
+ instance: true
255
+ }.merge(options)
256
+ if options[:flow] && options[:instance]
257
+ match = 'Flow|Instances'
258
+ elsif options[:flow]
259
+ match = 'Flow'
260
+ else
261
+ match = 'Instances'
262
+ end
263
+ # Not sure the best way to determine the file type of a partial, just
264
+ # return true for now to play it safe
265
+ return true if file.basename.to_s =~ /^_/
266
+ File.readlines(file).each do |line|
267
+ begin
268
+ unless line =~ /^%/ || line =~ /^\s*<comment>/
269
+ return !!(line =~ /#{match}/)
270
+ end
271
+ rescue Exception => e
272
+ if e.is_a?(ArgumentError) && e.message =~ /invalid byte sequence/
273
+ return false
274
+ else
275
+ puts e.message
276
+ puts e.backtrace
277
+ exit 1
278
+ end
279
+ end
280
+ end
281
+ end
282
+
283
+ def flow_file?(file)
284
+ flow_or_instance_file?(file, instance: false)
285
+ end
286
+
287
+ def instance_file?(file)
288
+ flow_or_instance_file?(file, flow: false)
289
+ end
290
+
291
+ # Substitute Ruby line comments so they are preserved by compilation
292
+ def markup_template_comments
293
+ Origen.file_handler.resolve_files(uncompiled_dir) do |file|
294
+ lines = File.readlines(file)
295
+ File.open(file, 'w') do |f|
296
+ lines.each do |line|
297
+ if line =~ /^%\s*#\s?(.*)/ # Remove single leading whitespace from comment if it exists
298
+ comment = Regexp.last_match[1]
299
+ # If comment starts with a '#-' it should be removed by compilation
300
+ if line =~ /^%\s*#-.*/
301
+ f.write line
302
+ # Otherwise preserve it
303
+ else
304
+ f.write "<comment>#{comment}\n"
305
+ end
306
+ else
307
+ f.write line
308
+ end
309
+ end
310
+ end
311
+ end
312
+ end
313
+
314
+ # Substitute Ruby line comments so they are preserved by generation
315
+ def markup_source_file_comments
316
+ Origen.file_handler.resolve_files(ungenerated_dir) do |file|
317
+ lines = File.readlines(file)
318
+ File.open(file, 'w') do |f|
319
+ lines.each do |line|
320
+ if line =~ /^\s*#\s?(.*)/ # Remove single leading whitespace from comment if it exists
321
+ comment = Regexp.last_match[1]
322
+ # If comment starts with a '#-' it should be removed by generation
323
+ if line =~ /^\s*#-.*/
324
+ f.write line
325
+ # Otherwise preserve it
326
+ else
327
+ f.write "Origen.interface.comment '#{comment}'\n"
328
+ end
329
+ else
330
+ f.write line
331
+ end
332
+ end
333
+ end
334
+ end
335
+ end
336
+ end
337
+ end
338
+ end
339
+ end