origen_testers 0.31.0 → 0.40.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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/config/application.rb +3 -1
  3. data/config/shared_commands.rb +4 -0
  4. data/config/version.rb +1 -1
  5. data/lib/origen_testers/api.rb +8 -0
  6. data/lib/origen_testers/atp/flow.rb +30 -9
  7. data/lib/origen_testers/flow.rb +36 -2
  8. data/lib/origen_testers/generator.rb +44 -5
  9. data/lib/origen_testers/interface.rb +22 -2
  10. data/lib/origen_testers/origen_ext/generator.rb +4 -3
  11. data/lib/origen_testers/origen_ext/generator/flow.rb +99 -5
  12. data/lib/origen_testers/program_generators.rb +5 -1
  13. data/lib/origen_testers/smartest_based_tester.rb +1 -0
  14. data/lib/origen_testers/smartest_based_tester/base.rb +177 -114
  15. data/lib/origen_testers/smartest_based_tester/base/flow.rb +329 -127
  16. data/lib/origen_testers/smartest_based_tester/base/generator.rb +25 -7
  17. data/lib/origen_testers/smartest_based_tester/base/limits_file.rb +186 -60
  18. data/lib/origen_testers/smartest_based_tester/base/pattern_compiler.rb +4 -0
  19. data/lib/origen_testers/smartest_based_tester/base/pattern_master.rb +4 -0
  20. data/lib/origen_testers/smartest_based_tester/base/processors/extract_bin_names.rb +5 -1
  21. data/lib/origen_testers/smartest_based_tester/base/processors/extract_flow_vars.rb +108 -0
  22. data/lib/origen_testers/smartest_based_tester/base/test_method.rb +8 -3
  23. data/lib/origen_testers/smartest_based_tester/base/test_suite.rb +9 -108
  24. data/lib/origen_testers/smartest_based_tester/base/test_suites.rb +17 -7
  25. data/lib/origen_testers/smartest_based_tester/base/variables_file.rb +29 -7
  26. data/lib/origen_testers/smartest_based_tester/smt7.rb +59 -0
  27. data/lib/origen_testers/smartest_based_tester/smt8.rb +218 -0
  28. data/lib/origen_testers/smartest_based_tester/v93k/flow.rb +32 -0
  29. data/lib/origen_testers/smartest_based_tester/v93k/templates/vars.tf.erb +2 -2
  30. data/lib/origen_testers/smartest_based_tester/v93k/test_suite.rb +109 -0
  31. data/lib/origen_testers/smartest_based_tester/v93k_smt8.rb +8 -0
  32. data/lib/origen_testers/smartest_based_tester/v93k_smt8/flow.rb +234 -0
  33. data/lib/origen_testers/smartest_based_tester/v93k_smt8/generator.rb +48 -0
  34. data/lib/origen_testers/smartest_based_tester/v93k_smt8/limits_file.rb +14 -0
  35. data/lib/origen_testers/smartest_based_tester/v93k_smt8/limits_workbook.rb +148 -0
  36. data/lib/origen_testers/smartest_based_tester/v93k_smt8/templates/limits.csv.erb +3 -0
  37. data/lib/origen_testers/smartest_based_tester/v93k_smt8/templates/template.flow.erb +41 -0
  38. data/lib/origen_testers/smartest_based_tester/v93k_smt8/test_suite.rb +66 -0
  39. data/lib/origen_testers/stil_based_tester/base.rb +4 -0
  40. data/lib/origen_testers/test/interface.rb +16 -2
  41. data/lib/origen_testers/vector_generator.rb +9 -4
  42. data/lib/origen_testers/vector_pipeline.rb +1 -1
  43. data/pattern/nvm/v93k/v93k_workout.rb +7 -0
  44. data/program/_erase_vfy.rb +2 -1
  45. data/program/components/_deep_nested.rb +3 -0
  46. data/program/components/_prb1_main.rb +1 -1
  47. data/program/components/_prb2_main.rb +6 -2
  48. data/program/flow_control.rb +3 -3
  49. data/program/prb1.rb +4 -0
  50. data/program/prb2.rb +7 -3
  51. data/templates/origen_guides/pattern/v93k.md.erb +24 -0
  52. data/templates/origen_guides/program/v93k.md.erb +6 -148
  53. data/templates/origen_guides/program/v93ksmt7.md.erb +165 -0
  54. data/templates/origen_guides/program/v93ksmt8.md.erb +112 -0
  55. metadata +30 -3
  56. data/lib/origen_testers/smartest_based_tester/base/test_methods/smart_calc_tml.rb +0 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 70a6d56474a5185e615615938f92867c97eae3ce7e5ef6539282de2bae8de2e1
4
- data.tar.gz: 11395fe59eb06d014ed54222f2fee16f3f19077ccb80e047eb7d1367fe0e9db4
3
+ metadata.gz: 304c4bb6a3741adaf96f451a6e26172596105d5ac20b9d609ede29dab880095b
4
+ data.tar.gz: 419c7c5276d6107ffdbab5339c442a71b91be6a7b0ad62facd168a2d29eefc74
5
5
  SHA512:
6
- metadata.gz: de963dedf5a5568b79206d8469626df8be8f7bd7a31ec84afa2cf395efc8004039f863a979c9080cc6c9efd52243018fc0a37bc4301339c1524f6a076321093f
7
- data.tar.gz: 995df0ef974169c733cba653f1ae86a418a392645df0ead8e00d98726fa2ea2da127c83a3ef66dd6c910745b48e073c4a740e2552c25f899026f13925bb1a612
6
+ metadata.gz: 89fe1fa09bf028c8bd4d4df9d23bd97c7b670ce208319a4f365380eb9fae34dc084ff4bb8d78c596e711d3a0c5056a147f04c4a5b4cdea3b854922ca6c477d71
7
+ data.tar.gz: ed28f34456af11d5e4a844911a63849aff3bb03684edbe132ebbc3dbd11d7a9248f37166e5eb6966e544653bfded4335115e4cd910d54973dac12854faf74b26
@@ -32,7 +32,9 @@ class OrigenTestersApplication < Origen::Application
32
32
  section.page :resources, heading: "Additional Resources"
33
33
  section.page :code, heading: "Dynamic Custom Code"
34
34
  section.page :j750, heading: "J750 API"
35
- section.page :v93k, heading: "V93K API"
35
+ section.page :v93k, heading: "V93K Common API"
36
+ section.page :v93ksmt7, heading: "V93K SMT7 API"
37
+ section.page :v93ksmt8, heading: "V93K SMT8 API"
36
38
  section.page :ultraflex, heading: "UltraFLEX API"
37
39
  section.page :doc, heading: "Documenting the Program"
38
40
  section.page :custom, heading: "Creating Custom Testers"
@@ -31,6 +31,10 @@ case @command
31
31
  $_testers_enable_vector_comments = ARGV.delete("-v") || ARGV.delete("--vector_comments")
32
32
  $_testers_no_inline_comments = ARGV.delete("--no_inline_comments")
33
33
 
34
+ when "program"
35
+ @application_options << ['--original_reference_file', 'Should only be used for regression testing when the reference uses a legacy version of origen_testers',
36
+ lambda { |options| OrigenTesters::Generator.original_reference_file = true }]
37
+
34
38
  when "testers:build"
35
39
  require "#{Origen.root!}/lib/commands/build"
36
40
  exit 0
@@ -1,6 +1,6 @@
1
1
  module OrigenTesters
2
2
  MAJOR = 0
3
- MINOR = 31
3
+ MINOR = 40
4
4
  BUGFIX = 0
5
5
  DEV = nil
6
6
  VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
@@ -113,6 +113,14 @@ module OrigenTesters
113
113
  false
114
114
  end
115
115
 
116
+ def smt7?
117
+ v93k? && smt_version.to_s[0] == '7'
118
+ end
119
+
120
+ def smt8?
121
+ v93k? && smt_version.to_s[0] == '8'
122
+ end
123
+
116
124
  def annotate(msg, options = {})
117
125
  end
118
126
 
@@ -222,15 +222,36 @@ module OrigenTesters::ATP
222
222
  # flow.test ...
223
223
  # flow.test ...
224
224
  # end
225
- def group(name, options = {})
226
- extract_meta!(options) do
227
- apply_conditions(options) do
228
- children = [n1(:name, name)]
229
- children << id(options[:id]) if options[:id]
230
- children << on_fail(options[:on_fail]) if options[:on_fail]
231
- children << on_pass(options[:on_pass]) if options[:on_pass]
232
- g = n(:group, children)
233
- append_to(g) { yield }
225
+ def group(name, options = {}, &block)
226
+ # The idiomatic way of creating a group in SMT8 is a sub-flow
227
+ if tester.try(:smt8?)
228
+ extract_meta!(options) do
229
+ apply_conditions(options) do
230
+ parent, sub_flow = *::Flow._sub_flow(name, options, &block)
231
+ path = sub_flow.output_file.relative_path_from(Origen.file_handler.output_directory)
232
+ ast = sub_flow.atp.raw
233
+ name, *children = *ast
234
+ nodes = [name]
235
+ nodes << id(options[:id]) if options[:id]
236
+ nodes << n1(:path, path.to_s)
237
+ nodes += children
238
+ ast = ast.updated :sub_flow, nodes,
239
+ file: options.delete(:source_file) || source_file,
240
+ line_number: options.delete(:source_line_number) || source_line_number,
241
+ description: options.delete(:description) || description
242
+ ast
243
+ end
244
+ end
245
+ else
246
+ extract_meta!(options) do
247
+ apply_conditions(options) do
248
+ children = [n1(:name, name)]
249
+ children << id(options[:id]) if options[:id]
250
+ children << on_fail(options[:on_fail]) if options[:on_fail]
251
+ children << on_pass(options[:on_pass]) if options[:on_pass]
252
+ g = n(:group, children)
253
+ append_to(g) { yield }
254
+ end
234
255
  end
235
256
  end
236
257
  end
@@ -44,6 +44,40 @@ module OrigenTesters
44
44
  @unique_ids = val
45
45
  end
46
46
 
47
+ # Returns true if this is a top-level Origen test program flow
48
+ def top_level?
49
+ top_level == self
50
+ end
51
+
52
+ # Returns the flow's parent top-level flow object, or self if this is a top-level flow
53
+ def top_level
54
+ @top_level
55
+ end
56
+
57
+ # Returns the flow's immediate parent flow object, or nil if this is a top-level flow
58
+ def parent
59
+ @parent
60
+ end
61
+
62
+ # Returns a hash containing all child flows stored by their ID
63
+ def children
64
+ @children ||= {}.with_indifferent_access
65
+ end
66
+
67
+ # Returns the flow's ID prefixed with the IDs of its parent flows, joined by '.'
68
+ def path
69
+ @path ||= begin
70
+ ids = []
71
+ p = parent
72
+ while p
73
+ ids.unshift(p.id)
74
+ p = p.parent
75
+ end
76
+ ids << id
77
+ ids.map(&:to_s).join('.')
78
+ end
79
+ end
80
+
47
81
  def lines
48
82
  @lines
49
83
  end
@@ -102,8 +136,8 @@ module OrigenTesters
102
136
  @throwaway ||= ATP::Flow.new(self)
103
137
  else
104
138
  @model ||= begin
105
- f = program.flow(id, description: OrigenTesters::Flow.flow_comments)
106
- @sig = flow_sig(id)
139
+ f = program.flow(try(:path) || id, description: OrigenTesters::Flow.flow_comments)
140
+ @sig = flow_sig(try(:path) || id)
107
141
  # f.id = @sig if OrigenTesters::Flow.unique_ids
108
142
  f
109
143
  end
@@ -13,12 +13,24 @@ module OrigenTesters
13
13
 
14
14
  included do
15
15
  include Origen::Generator::Comparator
16
+
17
+ attr_accessor :output_directory
16
18
  end
17
19
 
18
20
  def self.execute_source(file)
19
21
  load file
20
22
  end
21
23
 
24
+ # @api private
25
+ def self.original_reference_file=(val)
26
+ @original_reference_file = val
27
+ end
28
+
29
+ # @api private
30
+ def self.original_reference_file
31
+ !!@original_reference_file
32
+ end
33
+
22
34
  # When called on a generator no output files will be created from it
23
35
  def inhibit_output
24
36
  @inhibit_output = true
@@ -94,7 +106,10 @@ module OrigenTesters
94
106
  options = {
95
107
  include_extension: true
96
108
  }.merge(options)
109
+ # Allow generators to override this and fully define the filename if they want
110
+ return fully_formatted_filename if try(:fully_formatted_filename)
97
111
  name = (@filename || Origen.file_handler.current_file.basename('.rb')).to_s
112
+ name[0] = '' if name[0] == '_'
98
113
  if Origen.config.program_prefix
99
114
  unless name =~ /^#{Origen.config.program_prefix}/i
100
115
  name = "#{Origen.config.program_prefix}_#{name}"
@@ -105,7 +120,7 @@ module OrigenTesters
105
120
  body = f.basename(".#{ext}").to_s
106
121
  body.gsub!('_resources', '')
107
122
  if defined? self.class::OUTPUT_PREFIX
108
- # Unless the fixfix is already in the name
123
+ # Unless the prefix is already in the name
109
124
  unless body =~ /#{self.class::OUTPUT_PREFIX}$/i
110
125
  body = "#{self.class::OUTPUT_PREFIX}_#{body}"
111
126
  end
@@ -201,17 +216,41 @@ module OrigenTesters
201
216
  end
202
217
 
203
218
  def output_file
204
- if respond_to? :subdirectory
205
- p = Pathname.new("#{Origen.file_handler.output_directory}/#{subdirectory}/#{filename}")
219
+ # If an explicit output directory has been set, use it
220
+ if output_directory
221
+ p = Pathname.new("#{output_directory}/#{filename}")
222
+ # Otherwise resolve one
206
223
  else
207
- p = Pathname.new("#{Origen.file_handler.output_directory}/#{filename}")
224
+ if respond_to? :subdirectory
225
+ p = Pathname.new("#{Origen.file_handler.output_directory}/#{subdirectory}/#{filename}")
226
+ else
227
+ p = Pathname.new("#{Origen.file_handler.output_directory}/#{filename}")
228
+ end
208
229
  end
209
230
  FileUtils.mkdir_p p.dirname.to_s unless p.dirname.exist?
210
231
  p
211
232
  end
212
233
 
213
234
  def reference_file
214
- Pathname.new("#{Origen.file_handler.reference_directory}/#{filename}")
235
+ if OrigenTesters::Generator.original_reference_file
236
+ Pathname.new("#{Origen.file_handler.reference_directory}/#{filename}")
237
+ else
238
+ # If an explicit output directory has been set, use it
239
+ if output_directory
240
+ sub = Pathname.new(output_directory).relative_path_from(Origen.file_handler.output_directory)
241
+ dir = File.join(Origen.file_handler.reference_directory, sub)
242
+ FileUtils.mkdir_p(dir)
243
+ Pathname.new(File.join(dir, filename))
244
+ else
245
+ if respond_to? :subdirectory
246
+ dir = File.join(Origen.file_handler.reference_directory, subdirectory)
247
+ FileUtils.mkdir_p(dir)
248
+ Pathname.new(File.join(dir, filename))
249
+ else
250
+ Pathname.new("#{Origen.file_handler.reference_directory}/#{filename}")
251
+ end
252
+ end
253
+ end
215
254
  end
216
255
 
217
256
  def import(file, options = {})
@@ -46,6 +46,10 @@ module OrigenTesters
46
46
  flow.test(name, options)
47
47
  end
48
48
 
49
+ def generating_sub_program?
50
+ (defined? @@generating_sub_program) ? @@generating_sub_program : false
51
+ end
52
+
49
53
  # Returns the abstract test program model for the current flow
50
54
  def atp
51
55
  flow.model
@@ -242,9 +246,21 @@ module OrigenTesters
242
246
  nil
243
247
  end
244
248
 
245
- def pattern_references
249
+ # @api private
250
+ def clear_pattern_references
251
+ @@pattern_references = nil
252
+ end
253
+
254
+ # @api private
255
+ def merge_pattern_references(references)
256
+ references.each do |name, values|
257
+ pattern_references(name)[:main][:all].push(*values[:main][:all])
258
+ end
259
+ end
260
+
261
+ def pattern_references(name = pattern_references_name)
246
262
  @@pattern_references ||= {}
247
- @@pattern_references[pattern_references_name] ||= {
263
+ @@pattern_references[name] ||= {
248
264
  main: {
249
265
  all: [],
250
266
  origen: [],
@@ -324,6 +340,10 @@ module OrigenTesters
324
340
  end
325
341
  alias_method :top_level_flow_filename, :top_level_flow
326
342
 
343
+ def discard_top_level_flow
344
+ @@top_level_flow = nil
345
+ end
346
+
327
347
  def flow_generator
328
348
  flow
329
349
  end
@@ -9,7 +9,7 @@ module Origen
9
9
  class Generator
10
10
  include Comparator
11
11
 
12
- # Makes more sense for this plugin to own this method now
12
+ # @api private
13
13
  def generate_program(file, options)
14
14
  Origen.file_handler.resolve_files(file, ignore_with_prefix: '_', default_dir: "#{Origen.root}/program") do |path|
15
15
  Origen.file_handler.current_file = path
@@ -17,8 +17,9 @@ module Origen
17
17
  j.pattern = path
18
18
  j.run
19
19
  end
20
+ yield if block_given?
20
21
  Origen.interface.write_files(options)
21
- unless options[:quiet] || !Origen.interface.write?
22
+ unless options[:quiet] || !Origen.interface.write? || options[:skip_referenced_pattern_write]
22
23
  if options[:referenced_pattern_list]
23
24
  file = "#{Origen.root}/list/#{options[:referenced_pattern_list]}"
24
25
  else
@@ -48,7 +49,7 @@ module Origen
48
49
  ref_file = File.join(Origen.file_handler.reference_directory, Pathname.new(file).basename)
49
50
  check_for_changes(file, ref_file)
50
51
  end
51
- Origen.interface.on_program_completion(options)
52
+ Origen.interface.on_program_completion(options) unless options[:skip_on_program_completion]
52
53
  end
53
54
  end
54
55
  end
@@ -8,8 +8,6 @@ end
8
8
  module Origen
9
9
  class Generator
10
10
  class Flow
11
- alias_method :orig_create, :create
12
-
13
11
  # Create a call stack of flows so that we can work out where the nodes
14
12
  # of the ATP AST originated from
15
13
  def create(options = {}, &block)
@@ -32,10 +30,18 @@ module Origen
32
30
  if OrigenTesters::Flow.flow_comments
33
31
  top = false
34
32
  name = options[:name] || Pathname.new(file).basename('.rb').to_s.sub(/^_/, '')
35
- Origen.interface.flow.group(name, description: flow_comments) do
36
- orig_create(options, &block)
33
+ # Generate imports as separate sub-flow files on this platform
34
+ if tester.v93k? && tester.smt8?
35
+ parent, sub_flow = *_sub_flow(name, options, &block)
36
+ path = sub_flow.output_file.relative_path_from(Origen.file_handler.output_directory)
37
+ parent.atp.sub_flow(sub_flow.atp.raw, path: path.to_s)
38
+ else
39
+ Origen.interface.flow.group(name, description: flow_comments) do
40
+ _create(options, &block)
41
+ end
37
42
  end
38
43
  else
44
+ @top_level_flow = nil
39
45
  OrigenTesters::Flow.flow_comments = flow_comments
40
46
  if options.key?(:unique_ids)
41
47
  OrigenTesters::Flow.unique_ids = options.delete(:unique_ids)
@@ -43,13 +49,101 @@ module Origen
43
49
  OrigenTesters::Flow.unique_ids = true
44
50
  end
45
51
  top = true
46
- orig_create(options, &block)
52
+ _create(options, &block)
47
53
  end
48
54
  OrigenTesters::Flow.callstack.pop
49
55
  OrigenTesters::Flow.comment_stack.pop
50
56
  OrigenTesters::Flow.flow_comments = nil if top
51
57
  end
52
58
 
59
+ # @api private
60
+ def _sub_flow(name, options, &block)
61
+ @top_level_flow ||= Origen.interface.flow
62
+ parent = Origen.interface.flow
63
+ # If the parent flow already has a child flow of this name then we need to generate a
64
+ # new unique name/id
65
+ # Also generate a new name when the child flow name matches the parent flow name, SMT8.2
66
+ # onwards does not allow this
67
+ if parent.children[name] || parent.name.to_s == name.to_s
68
+ i = 0
69
+ tempname = name
70
+ while parent.children[tempname] || parent.name.to_s == tempname.to_s
71
+ i += 1
72
+ tempname = "#{name}_#{i}"
73
+ end
74
+ name = tempname
75
+ end
76
+ if parent
77
+ id = parent.path + ".#{name}"
78
+ else
79
+ id = name
80
+ end
81
+ sub_flow = Origen.interface.with_flow(id) do
82
+ Origen.interface.flow.instance_variable_set(:@top_level, @top_level_flow)
83
+ Origen.interface.flow.instance_variable_set(:@parent, parent)
84
+ _create(options, &block)
85
+ end
86
+ parent.children[name] = sub_flow
87
+ [parent, sub_flow]
88
+ end
89
+
90
+ # @api private
91
+ def _create(options = {}, &block)
92
+ # Refresh the target to start all settings from scratch each time
93
+ # This is an easy way to reset all registered values
94
+ Origen.app.reload_target!
95
+ Origen.tester.generating = :program
96
+ # Make the top level flow globally available, this helps to assign test descriptions
97
+ # to the correct flow whenever tests are instantiated from sub-flows
98
+ if Origen.interface_loaded? && Origen.interface.top_level_flow
99
+ sub_flow = true
100
+ if Origen.tester.doc?
101
+ Origen.interface.flow.start_section
102
+ end
103
+ else
104
+ sub_flow = false
105
+ end
106
+ job.output_file_body = options.delete(:name).to_s if options[:name]
107
+ if sub_flow
108
+ interface = Origen.interface
109
+ opts = Origen.generator.option_pipeline.pop || {}
110
+ Origen.interface.startup(options) if Origen.interface.respond_to?(:startup)
111
+ interface.instance_exec(opts, &block)
112
+ Origen.interface.shutdown(options) if Origen.interface.respond_to?(:shutdown)
113
+ if Origen.tester.doc?
114
+ Origen.interface.flow.stop_section
115
+ end
116
+ interface.close(flow: true, sub_flow: true)
117
+ else
118
+ Origen.log.info "Generating... #{Origen.file_handler.current_file.basename}"
119
+ interface = Origen.reset_interface(options)
120
+ Origen.interface.set_top_level_flow
121
+ Origen.interface.flow_generator.set_flow_description(Origen.interface.consume_comments)
122
+ options[:top_level] = true
123
+ Origen.interface.flow.instance_variable_set('@top_level', Origen.interface.flow)
124
+ Origen.interface.flow.on_top_level_set if Origen.interface.flow.respond_to?(:on_top_level_set)
125
+ Origen.app.listeners_for(:on_flow_start).each do |listener|
126
+ listener.on_flow_start(options)
127
+ end
128
+ Origen.interface.startup(options) if Origen.interface.respond_to?(:startup)
129
+ interface.instance_eval(&block)
130
+ Origen.interface.shutdown(options) if Origen.interface.respond_to?(:shutdown)
131
+ interface.at_flow_end if interface.respond_to?(:at_flow_end)
132
+ Origen.app.listeners_for(:on_flow_end).each do |listener|
133
+ listener.on_flow_end(options)
134
+ end
135
+ interface.close(flow: true)
136
+ end
137
+ end
138
+
139
+ def reset
140
+ Origen.interface.clear_top_level_flow if Origen.interface_loaded?
141
+ end
142
+
143
+ def job
144
+ Origen.app.current_job
145
+ end
146
+
53
147
  def _extract_comments(file, flow_line)
54
148
  flow_comments = []
55
149
  comments = {}