Class: OrigenTesters::SmartestBasedTester::V93K_SMT8::Flow

Inherits:
Base::Flow show all
Defined in:
lib/origen_testers/smartest_based_tester/v93k_smt8/flow.rb

Constant Summary collapse

TEMPLATE =
"#{Origen.root!}/lib/origen_testers/smartest_based_tester/v93k_smt8/templates/template.flow.erb"

Constants inherited from Base::Flow

Base::Flow::RELATIONAL_OPERATOR_STRINGS

Constants included from Flow

Flow::PROGRAM_MODELS_DIR

Instance Attribute Summary

Attributes inherited from Base::Flow

#add_flow_enable, #flow_bypass, #flow_description, #flow_name, #lines, #set_runtime_variables, #stack, #subdirectory, #test_methods, #test_suites, #var_filename

Instance Method Summary collapse

Methods inherited from Base::Flow

#all_sub_flows, #ast, #at_flow_end, #at_flow_start, #capture_lines, #clean_job, #extract_sub_flows, #filename, #finalize, #flow_enable_var_name, #flow_variables, #generate_expr_string, #generate_expr_term, generate_flag_name, #hardware_bin_descriptions, #limits_file, #line, #on_condition_flag, #on_disable, #on_enable, #on_group, #on_if_enabled, #on_if_flag, #on_if_job, #on_log, #on_loop, #on_render, #on_set, #on_set_flag, #on_set_result, #on_top_level_set, #on_whenever, #render_limits_file, #smt8?, #sub_flow_from, #unique_group_name

Methods included from Flow

#active_description, #at_flow_start, #at_run_start, callstack, cc_comments, cc_comments=, #children, comment_stack, #context_changed?, flow_comments, flow_comments=, #generate_unique_label, ht_comments, ht_comments=, #is_the_flow?, #lines, #model, name_stack, #nop, #orig_render, #parent, #path, #program, #render, #save_program, #sig, #test, #top_level, #top_level?, unique_ids, unique_ids=

Methods included from ATP::FlowAPI

#atp, #atp=, #hi_limit, #limit, #lo_limit

Methods included from Generator

#close, #collection, #collection=, #compiler, #current_dir, #dont_diff=, execute_source, #file_extension, #file_pipeline, #filename, #filename=, #finalize, #identity_map, #import, #inhibit_output, #name, #on_close, original_reference_file, original_reference_file=, #output_file, #output_inhibited?, #platform, #reference_file, #render, #set_flow_description, #stats, #to_be_written?, #write_from_template, #write_to_file

Methods inherited from ATP::Formatter

#format, format, run, run_and_format, #run_and_format

Methods inherited from ATP::Processor

#clean_flag, #extract_volatiles, #handler_missing, #process, #process_all, #run, #volatile?, #volatile_flags

Instance Method Details



224
225
226
227
228
229
230
# File 'lib/origen_testers/smartest_based_tester/v93k_smt8/flow.rb', line 224

def flow_footer
  f = []
  if add_flow_enable && top_level?
    f << '        }'
  end
  f
end

#flow_headerObject



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/origen_testers/smartest_based_tester/v93k_smt8/flow.rb', line 205

def flow_header
  h = []
  if add_flow_enable && top_level?
    h << "        if (#{flow_enable_var_name} == 1) {"
    i = '            '
  else
    i = '        '
  end
  flow_variables[:this_flow][:set_flags].each do |var|
    if var.is_a?(Array)
      h << i + "#{var[0]} = #{var[1].is_a?(String) || var[1].is_a?(Symbol) ? '"' + var[1].to_s + '"' : var[1]};"
    else
      h << i + "#{var} = -1;"
    end
  end
  h << '' unless flow_variables[:this_flow][:set_flags].empty?
  h
end

#input_variablesObject

Variables which should be defined as an input to the current flow



154
155
156
157
158
159
160
161
162
163
164
# File 'lib/origen_testers/smartest_based_tester/v93k_smt8/flow.rb', line 154

def input_variables
  vars = flow_variables
  # Jobs and enables flow into a sub-flow
  (vars[:all][:jobs] + vars[:all][:referenced_enables] + vars[:all][:set_enables] +
    # As do any flags which are referenced by it but which are not set within it
    (vars[:all][:referenced_flags] - vars[:all][:set_flags])).uniq.sort do |x, y|
    x = x[0] if x.is_a?(Array)
    y = y[0] if y.is_a?(Array)
    x <=> y
  end
end

#intermediate_variables(*sub_flows) ⇒ Object

Output variables which are not directly referenced by this flow, but which are referenced by a parent flow and set by the given child flow and therefore must pass through the current flow. By calling this method with no argument it will consider variables set by any child flow, alternatively pass in the variables for the child flow in question and only that will be considered.



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/origen_testers/smartest_based_tester/v93k_smt8/flow.rb', line 188

def intermediate_variables(*sub_flows)
  set_flags = []
  all_sub_flows.each { |f| set_flags += f.flow_variables[:all][:set_flags] }
  if set_flags.empty?
    []
  else
    upstream_referenced_flags = []
    p = parent
    while p
      upstream_referenced_flags += p.flow_variables[:this_flow][:referenced_flags]
      p = p.parent
    end
    upstream_referenced_flags.uniq
    set_flags & upstream_referenced_flags
  end
end

#on_sub_flow(node) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/origen_testers/smartest_based_tester/v93k_smt8/flow.rb', line 91

def on_sub_flow(node)
  sub_flow = sub_flow_from(node)
  @sub_flows ||= {}
  path = Pathname.new(node.find(:path).value)
  name = path.basename('.*').to_s
  @sub_flows[name] = "#{path.dirname}.#{name}".gsub(/(\/|\\)/, '.')
  # Pass down all input variables before executing
  sub_flow.input_variables.each do |var|
    var = var[0] if var.is_a?(Array)
    line "#{name}.#{var} = #{var};"
  end
  line "#{name}.execute();"
  # And then retrieve all common output variables
  (output_variables & sub_flow.output_variables).sort.each do |var|
    var = var[0] if var.is_a?(Array)
    line "#{var} = #{name}.#{var};"
  end
  if on_pass = node.find(:on_pass)
    pass_lines = capture_lines do
      @indent += 1
      pass_branch do
        process_all(on_pass) if on_pass
      end
      @indent -= 1
    end
    on_pass = nil if pass_lines.empty?
  end

  if on_fail = node.find(:on_fail)
    fail_lines = capture_lines do
      @indent += 1
      fail_branch do
        process_all(on_fail) if on_fail
      end
      @indent -= 1
    end
    on_fail = nil if fail_lines.empty?
  end

  if on_pass && !on_fail
    line "if (#{name}.pass) {"
    pass_lines.each { |l| line l, already_indented: true }
    line '}'

  elsif !on_pass && on_fail
    line "if (!#{name}.pass) {"
    fail_lines.each { |l| line l, already_indented: true }
    line '}'

  elsif on_pass && on_fail
    line "if (#{name}.pass) {"
    pass_lines.each { |l| line l, already_indented: true }
    line '} else {'
    fail_lines.each { |l| line l, already_indented: true }
    line '}'
  end
end

#on_test(node) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/origen_testers/smartest_based_tester/v93k_smt8/flow.rb', line 8

def on_test(node)
  test_suite = node.find(:object).to_a[0]
  if test_suite.is_a?(String)
    name = test_suite
  else
    name = test_suite.name
    test_method = test_suite.test_method
    if test_method.respond_to?(:test_name) && test_method.test_name == '' &&
       n = node.find(:name)
      test_method.test_name = n.value
    end
  end

  if node.children.any? { |n| t = n.try(:type); t == :on_fail || t == :on_pass } ||
     !stack[:on_pass].empty? || !stack[:on_fail].empty?
    line "#{name}.execute();"
    @open_test_names << name
    @post_test_lines << []
    process_all(node.to_a.reject { |n| t = n.try(:type); t == :on_fail || t == :on_pass })
    on_pass = node.find(:on_pass)
    on_fail = node.find(:on_fail)

    if on_fail && on_fail.find(:continue) && tester.force_pass_on_continue
      if test_method.respond_to?(:force_pass)
        test_method.force_pass = 1
      else
        Origen.log.error 'Force pass on continue has been enabled, but the test method does not have a force_pass attribute!'
        Origen.log.error "  #{node.source}"
        exit 1
      end
      @open_test_methods << test_method
    else
      if test_method.respond_to?(:force_pass)
        test_method.force_pass = 0
      end
      @open_test_methods << nil
    end

    pass_lines = capture_lines do
      @indent += 1
      pass_branch do
        process_all(on_pass) if on_pass
        stack[:on_pass].each { |n| process_all(n) }
      end
      @indent -= 1
    end

    fail_lines = capture_lines do
      @indent += 1
      fail_branch do
        process_all(on_fail) if on_fail
        stack[:on_fail].each { |n| process_all(n) }
      end
      @indent -= 1
    end

    if !pass_lines.empty? && fail_lines.empty?
      line "if (#{name}.pass) {"
      pass_lines.each { |l| line l, already_indented: true }
      line '}'

    elsif pass_lines.empty? && !fail_lines.empty?
      line "if (!#{name}.pass) {"
      fail_lines.each { |l| line l, already_indented: true }
      line '}'

    elsif !pass_lines.empty? && !fail_lines.empty?
      line "if (#{name}.pass) {"
      pass_lines.each { |l| line l, already_indented: true }
      line '} else {'
      fail_lines.each { |l| line l, already_indented: true }
      line '}'

    end

    @open_test_methods.pop
    @open_test_names.pop
    @post_test_lines.pop.each { |l| line(l) }
  else
    line "#{name}.execute();"
  end
end

#output_variablesObject

Variables which should be defined as an output of the current flow



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/origen_testers/smartest_based_tester/v93k_smt8/flow.rb', line 167

def output_variables
  vars = flow_variables
  # Flags that are set by this flow flow out of it
  (vars[:this_flow][:set_flags] +
   # As do any flags set by its children which are marked as external
   vars[:all][:set_flags_extern] +
   # And any flags which are set by a child and referenced in this flow
   (vars[:this_flow][:referenced_flags] & vars[:sub_flows][:set_flags]) +
   # And also intermediate flags, those are flags which are set by a child and referenced
   # by a parent of the current flow
   intermediate_variables).uniq.sort do |x, y|
    x = x[0] if x.is_a?(Array)
    y = y[0] if y.is_a?(Array)
    x <=> y
  end
end

#sub_flowsObject



149
150
151
# File 'lib/origen_testers/smartest_based_tester/v93k_smt8/flow.rb', line 149

def sub_flows
  @sub_flows || {}
end