Class: OrigenTesters::ATP::Processors::AdjacentIfCombiner

Inherits:
OrigenTesters::ATP::Processor show all
Defined in:
lib/origen_testers/atp/processors/adjacent_if_combiner.rb

Overview

This combines adjacent if flag nodes where the flag is in the opposite state

s(:flow,
  s(:name, "prb1"),
  s(:if_flag, "SOME_FLAG",
    s(:test,
      s(:name, "test1"))),
  s(:unless_flag, "SOME_FLAG",
    s(:test,
      s(:name, "test2"))))

s(:flow,
  s(:name, "prb1"),
  s(:if_flag, "SOME_FLAG",
    s(:test,
      s(:name, "test1"))),
    s(:else,
      s(:test,
        s(:name, "test2"))))

See here for an example of the kind of flow level effect it has: github.com/Origen-SDK/origen_testers/issues/43

Defined Under Namespace

Classes: SetRunFlagFinder

Instance Method Summary collapse

Methods inherited from OrigenTesters::ATP::Processor

#add_global_flag, #clean_flag, #extract_globals, #extract_volatiles, #global_flag?, #global_flags, #handler_missing, #process, #process_all, #run, #volatile?, #volatile_flags

Instance Method Details

#combine(node1, node2) ⇒ Object



82
83
84
# File 'lib/origen_testers/atp/processors/adjacent_if_combiner.rb', line 82

def combine(node1, node2)
  node1.updated(nil, process_all(node1.children) + [node2.updated(:else, process_all(node2.to_a[1..-1]))])
end

#on_flow(node) ⇒ Object



43
44
45
46
47
# File 'lib/origen_testers/atp/processors/adjacent_if_combiner.rb', line 43

def on_flow(node)
  extract_volatiles(node)
  name, *nodes = *node
  node.updated(nil, [name] + optimize(process_all(nodes)))
end

#on_named_collection(node) ⇒ Object Also known as: on_group, on_sub_flow



49
50
51
52
# File 'lib/origen_testers/atp/processors/adjacent_if_combiner.rb', line 49

def on_named_collection(node)
  name, *nodes = *node
  node.updated(nil, [name] + optimize(process_all(nodes)))
end

#on_unnamed_collection(node) ⇒ Object Also known as: on_on_fail, on_on_pass



56
57
58
# File 'lib/origen_testers/atp/processors/adjacent_if_combiner.rb', line 56

def on_unnamed_collection(node)
  node.updated(nil, optimize(process_all(node.children)))
end

#opposite_flag_states?(node1, node2) ⇒ Boolean

Returns:

  • (Boolean)


86
87
88
89
90
# File 'lib/origen_testers/atp/processors/adjacent_if_combiner.rb', line 86

def opposite_flag_states?(node1, node2)
  ((node1.type == :if_flag && node2.type == :unless_flag) || (node1.type == :unless_flag && node2.type == :if_flag) ||
   (node1.type == :if_enabled && node2.type == :unless_enabled) || (node1.type == :unless_enabled && node2.type == :if_enabled)) &&
    node1.to_a[0] == node2.to_a[0]
end

#optimize(nodes) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/origen_testers/atp/processors/adjacent_if_combiner.rb', line 62

def optimize(nodes)
  results = []
  node1 = nil
  nodes.each do |node2|
    if node1
      if opposite_flag_states?(node1, node2) && safe_to_combine?(node1, node2)
        results << combine(node1, node2)
        node1 = nil
      else
        results << node1
        node1 = node2
      end
    else
      node1 = node2
    end
  end
  results << node1 if node1
  results
end

#safe_to_combine?(node1, node2) ⇒ Boolean

Returns:

  • (Boolean)


92
93
94
95
96
97
# File 'lib/origen_testers/atp/processors/adjacent_if_combiner.rb', line 92

def safe_to_combine?(node1, node2)
  # Nodes won't be collapsed if node1 touches the shared run flag, i.e. if there is any chance
  # that by the time it would naturally execute node2, the flag could have been changed by node1
  (!volatile?(node1.to_a[0]) || (volatile?(node1.to_a[0]) && !node1.contains?(:test))) &&
    !SetRunFlagFinder.new.contains?(node1, node1.to_a[0])
end