Class: OrigenTesters::Decompiler::Pattern

Inherits:
Object
  • Object
show all
Includes:
EnumerableExt, Parsers, SpecHelpers, Splitter
Defined in:
lib/origen_testers/decompiler/pattern.rb,
lib/origen_testers/decompiler/pattern/parsers.rb,
lib/origen_testers/decompiler/pattern/splitter.rb,
lib/origen_testers/decompiler/pattern/spec_helpers.rb,
lib/origen_testers/decompiler/pattern/elements/base.rb,
lib/origen_testers/decompiler/pattern/enumerable_ext.rb,
lib/origen_testers/decompiler/pattern/elements/vector.rb,
lib/origen_testers/decompiler/pattern/elements/pinlist.rb,
lib/origen_testers/decompiler/pattern/elements/frontmatter.rb,
lib/origen_testers/decompiler/pattern/vector_delimiter_base.rb,
lib/origen_testers/decompiler/pattern/elements/comment_block.rb,
lib/origen_testers/decompiler/pattern/elements/vector_body_element.rb

Defined Under Namespace

Modules: EnumerableExt, Parsers, SpecHelpers, Splitter Classes: Base, CommentBlock, Frontmatter, Pinlist, Vector, VectorBodyElement, VectorDelimiterBase

Constant Summary

Constants included from Splitter

Splitter::OPTIONAL_KEYS, Splitter::REQUIRED_KEYS

Class Attribute Summary collapse

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from SpecHelpers

#spec_yaml_approved, #spec_yaml_output, #to_spec_yaml, #to_yaml_hash, #write_spec_yaml

Methods included from EnumerableExt

#collect, #collect_with_index, #count, #each, #each_vector_with_index, #find, #find_all, #find_index, #first, #reject, #vector_at

Methods included from Parsers

#_parse_frontmatter_, #_parse_pinlist_, #_parse_vector_

Methods included from Splitter

#check_match, #raw_endmatter, #raw_frontmatter, #raw_lines, #raw_pinlist, #raw_vectors, #section_indices, #split, #split!

Constructor Details

#initialize(source, options = {}) ⇒ Pattern

Returns a new instance of Pattern.



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
# File 'lib/origen_testers/decompiler/pattern.rb', line 54

def initialize(source, options = {})
  options = { direct_source: false, no_verify: false }.merge(options)
  direct_source = options[:direct_source]
  no_verify = options[:no_verify]

  if source.is_a?(File)
    source = source.path
  end

  if direct_source
    @source = source
    @direct_source = true
  else
    @source = Pathname(source)
    unless @source.exist?
      message = "Cannot find pattern source '#{@source}'"
      Origen.log.error(message)
      Origen.app!.fail(exception_class: OrigenTesters::Decompiler::NoSuchSource, message: message)
    end
    @direct_source = false
  end
  @decompiled = false

  unless no_verify || self.class.no_verify
    verify_subclass_configuration
  end
end

Class Attribute Details

.no_verifyObject (readonly)

Returns the value of attribute no_verify.



42
43
44
# File 'lib/origen_testers/decompiler/pattern.rb', line 42

def no_verify
  @no_verify
end

.parser_configObject (readonly)

Returns the value of attribute parser_config.



39
40
41
# File 'lib/origen_testers/decompiler/pattern.rb', line 39

def parser_config
  @parser_config
end

.platformObject (readonly)

Returns the value of attribute platform.



41
42
43
# File 'lib/origen_testers/decompiler/pattern.rb', line 41

def platform
  @platform
end

.platform_tokensObject (readonly)

Returns the value of attribute platform_tokens.



40
41
42
# File 'lib/origen_testers/decompiler/pattern.rb', line 40

def platform_tokens
  @platform_tokens
end

.splitter_configObject (readonly)

Returns the value of attribute splitter_config.



38
39
40
# File 'lib/origen_testers/decompiler/pattern.rb', line 38

def splitter_config
  @splitter_config
end

Instance Attribute Details

#decompiledObject (readonly)

Returns the value of attribute decompiled.



46
47
48
# File 'lib/origen_testers/decompiler/pattern.rb', line 46

def decompiled
  @decompiled
end

#direct_sourceObject (readonly)

Returns the value of attribute direct_source.



47
48
49
# File 'lib/origen_testers/decompiler/pattern.rb', line 47

def direct_source
  @direct_source
end

#sourceObject (readonly)

Returns the value of attribute source.



45
46
47
# File 'lib/origen_testers/decompiler/pattern.rb', line 45

def source
  @source
end

Instance Method Details

#add_pinsArray

Adds any pins in the decompiled pattern to the DUT which are not already present.

Returns:

  • (Array)

    Any pin names that were added to the DUT.



257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/origen_testers/decompiler/pattern.rb', line 257

def add_pins
  #        pin_sizes = pat_model.pattern_model.pin_sizes
  #        pat_model.pinlist.each_with_index do |(name, pin), i|
  #          dut.add_pin(name, size: pin_sizes[i]) unless dut.has_pin?(name)
  #        end
  retn = []
  if first_vector?
    pin_sizes.each do |pin, size|
      unless dut.has_pin?(pin)
        dut.add_pin(pin, size: size)
        retn << pin
      end
    end
  else
    fail(NoFirstVectorAvailable, "No first vector available for pattern '#{source}'. Cannot add pins to the DUT '#{dut.class.name}'")
  end
  retn
end

#comment_startObject Also known as: comment_token



113
114
115
# File 'lib/origen_testers/decompiler/pattern.rb', line 113

def comment_start
  self.class.platform_tokens[:comment_start]
end

#current_vector_indexObject



234
235
236
# File 'lib/origen_testers/decompiler/pattern.rb', line 234

def current_vector_index
  @current_vector_index
end

#decompile(options = {}) ⇒ Object



211
212
213
214
215
216
217
218
219
220
# File 'lib/origen_testers/decompiler/pattern.rb', line 211

def decompile(options = {})
  # Read the pattern and split it into sections then parse and store the
  # frontmatter and pinlist models
  split!
  @frontmatter = _parse_frontmatter_
  @pinlist = _parse_pinlist_

  @decompiled = true
  self
end

#decompiled?Boolean

Returns:

  • (Boolean)


161
162
163
# File 'lib/origen_testers/decompiler/pattern.rb', line 161

def decompiled?
  @decompiled
end

#decompilerObject



96
97
98
# File 'lib/origen_testers/decompiler/pattern.rb', line 96

def decompiler
  self.class
end

#decompiler?(d) ⇒ Boolean

Returns:

  • (Boolean)


100
101
102
# File 'lib/origen_testers/decompiler/pattern.rb', line 100

def decompiler?(d)
  decompiler == d
end

#direct_source?Boolean

Returns:

  • (Boolean)


165
166
167
# File 'lib/origen_testers/decompiler/pattern.rb', line 165

def direct_source?
  @direct_source
end

#execute(options = {}) ⇒ Object

Executing a pattern consist of:

1. Doing some initial setup (timesets, initial pin states, etc.)
2. Executing anything that can be executed in the frontmatter
3. Executing the vectors 1-by-1.


286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/origen_testers/decompiler/pattern.rb', line 286

def execute(options = {})
  if Origen.tester.timeset.nil?
    if first_vector?
      Origen.tester.set_timeset(first_timeset, 40)
    else
      Origen.log.error 'No first vector available and the timeset has not already been set!'
      Origen.log.error 'Please set the timeset yourself prior to calling #execute! in a pattern that does not contain a first vector.'
      fail(NoFirstVectorAvailable, "No first vector available for pattern '#{source}'. Cannot set a timeset to execute the pattern.")
    end
  end
  frontmatter.execute!
  each_vector_with_index do |vec, i|
    if Origen.debug?
      Origen.log.info("OrigenTesters: Executing Vector #{i}")
    end
    vec.execute!
  end

  self
end

#first_pin_statesObject Also known as: initial_pin_states



196
197
198
# File 'lib/origen_testers/decompiler/pattern.rb', line 196

def first_pin_states
  first_vector.pin_states
end

#first_pin_states_mappedObject Also known as: initial_pin_states_mapped



189
190
191
192
193
# File 'lib/origen_testers/decompiler/pattern.rb', line 189

def first_pin_states_mapped
  pins.each.with_index.with_object({}) do |(pin, i), hash|
    hash[pin] = initial_pin_states[i]
  end
end

#first_timesetObject Also known as: initial_timeset



184
185
186
# File 'lib/origen_testers/decompiler/pattern.rb', line 184

def first_timeset
  first_vector.timeset
end

#first_vectorObject



169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/origen_testers/decompiler/pattern.rb', line 169

def first_vector
  @first_vector || begin
    each_vector do |v|
      if v.vector?
        @first_vector = v.element
        break
      end
    end
    if @first_vector.nil?
      fail OrigenTesters::Decompiler::ParseError, "Could not locate the first vector in pattern #{@source}"
    end
    @first_vector
  end
end

#first_vector?Boolean

Returns:

  • (Boolean)


249
250
251
252
253
# File 'lib/origen_testers/decompiler/pattern.rb', line 249

def first_vector?
  first_vector
rescue OrigenTesters::Decompiler::ParseError
  return false
end

#frontmatterObject



222
223
224
# File 'lib/origen_testers/decompiler/pattern.rb', line 222

def frontmatter
  @frontmatter
end

#method_parse_frontmatterObject



122
123
124
125
126
# File 'lib/origen_testers/decompiler/pattern.rb', line 122

def method_parse_frontmatter
  if self.class.respond_to?(:parse_frontmatter)
    self.class.method(:parse_frontmatter)
  end
end

#method_parse_pinlistObject



128
129
130
131
132
# File 'lib/origen_testers/decompiler/pattern.rb', line 128

def method_parse_pinlist
  if self.class.respond_to?(:parse_pinlist)
    self.class.method(:parse_pinlist)
  end
end

#method_parse_vectorObject



134
135
136
137
138
# File 'lib/origen_testers/decompiler/pattern.rb', line 134

def method_parse_vector
  if self.class.respond_to?(:parse_vector)
    self.class.method(:parse_vector)
  end
end

#parser_configObject



104
105
106
# File 'lib/origen_testers/decompiler/pattern.rb', line 104

def parser_config
  self.class.parser_config || {}
end

#pin_sizesHash

Resolves the size of each pin in the pinlist using the initial pin states.

Returns:

  • (Hash)

    Hash wherein the keys are the pin names and each value is the corresponding size.



241
242
243
244
245
246
247
# File 'lib/origen_testers/decompiler/pattern.rb', line 241

def pin_sizes
  # initial_pin_states.map { |pin, state| state.size }
  initial_pin_states_mapped.map { |pin, state| [pin, state.size] }.to_h
  # pins.each.with_index.with_object({}) do |(pin, i), hash|
  #  hash[pin] = initial_pin_states[i].size
  # end
end

#pinlistObject



226
227
228
# File 'lib/origen_testers/decompiler/pattern.rb', line 226

def pinlist
  @pinlist
end

#pinlist_sizeObject Also known as: num_pins, number_of_pins



201
202
203
# File 'lib/origen_testers/decompiler/pattern.rb', line 201

def pinlist_size
  pinlist.pins.size
end

#pinsObject



207
208
209
# File 'lib/origen_testers/decompiler/pattern.rb', line 207

def pins
  pinlist.pins
end

#platformObject Also known as: tester



82
83
84
# File 'lib/origen_testers/decompiler/pattern.rb', line 82

def platform
  self.class.platform
end

#platform?(p = nil) ⇒ Boolean Also known as: tester?

Returns:

  • (Boolean)


87
88
89
90
91
92
93
# File 'lib/origen_testers/decompiler/pattern.rb', line 87

def platform?(p = nil)
  if p
    platform == p
  else
    platform == tester.name.to_s
  end
end

#platform_tokensObject Also known as: decompiler_tokens



108
109
110
# File 'lib/origen_testers/decompiler/pattern.rb', line 108

def platform_tokens
  self.class.platform_tokens
end

#splitter_configObject



118
119
120
# File 'lib/origen_testers/decompiler/pattern.rb', line 118

def splitter_config
  self.class.splitter_config
end

#subclass_error(message) ⇒ Object



156
157
158
159
# File 'lib/origen_testers/decompiler/pattern.rb', line 156

def subclass_error(message)
  Origen.log.error("#{self.class.name} failed to subclasss OrigenTesters::DecompilerPattern: #{message}")
  fail(SubclassError, "#{self.class.name} failed to subclasss OrigenTesters::DecompilerPattern: #{message}")
end

#vectorsObject



230
231
232
# File 'lib/origen_testers/decompiler/pattern.rb', line 230

def vectors
  @vector_handler ||= vector_start
end

#verify_subclass_configurationObject



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/origen_testers/decompiler/pattern.rb', line 140

def verify_subclass_configuration
  if method_parse_frontmatter.nil?
    subclass_error('Missing class method #parse_frontmatter')
  elsif method_parse_pinlist.nil?
    subclass_error('Missing class method #parse_pinlist')
  elsif method_parse_vector.nil?
    subclass_error('Missing class method #parse_vector')
  elsif splitter_config.nil?
    subclass_error('Missing class variable :splitter_config')
  elsif !(Splitter::REQUIRED_KEYS - splitter_config.keys).empty?
    subclass_error("Splitter config is missing required keys: #{(Splitter::REQUIRED_KEYS - splitter_config.keys).map { |k| ':' + k.to_s }.join(', ')}")
  elsif !(splitter_config.keys - Splitter::REQUIRED_KEYS - Splitter::OPTIONAL_KEYS).empty?
    subclass_error("Splitter config contains extra keys: #{(splitter_config.keys - Splitter::REQUIRED_KEYS - Splitter::OPTIONAL_KEYS).map { |k| ':' + k.to_s }.join(', ')}")
  end
end