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, direct_source: false, no_verify: false) ⇒ 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
# File 'lib/origen_testers/decompiler/pattern.rb', line 54

def initialize(source, direct_source: false, no_verify: false)
  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.



253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/origen_testers/decompiler/pattern.rb', line 253

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



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

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

#current_vector_indexObject



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

def current_vector_index
  @current_vector_index
end

#decompile(options = {}) ⇒ Object



207
208
209
210
211
212
213
214
215
216
# File 'lib/origen_testers/decompiler/pattern.rb', line 207

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)


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

def decompiled?
  @decompiled
end

#decompilerObject



92
93
94
# File 'lib/origen_testers/decompiler/pattern.rb', line 92

def decompiler
  self.class
end

#decompiler?(d) ⇒ Boolean

Returns:

  • (Boolean)


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

def decompiler?(d)
  decompiler == d
end

#direct_source?Boolean

Returns:

  • (Boolean)


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

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.


282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
# File 'lib/origen_testers/decompiler/pattern.rb', line 282

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



192
193
194
# File 'lib/origen_testers/decompiler/pattern.rb', line 192

def first_pin_states
  first_vector.pin_states
end

#first_pin_states_mappedObject Also known as: initial_pin_states_mapped



185
186
187
188
189
# File 'lib/origen_testers/decompiler/pattern.rb', line 185

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



180
181
182
# File 'lib/origen_testers/decompiler/pattern.rb', line 180

def first_timeset
  first_vector.timeset
end

#first_vectorObject



165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/origen_testers/decompiler/pattern.rb', line 165

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)


245
246
247
248
249
# File 'lib/origen_testers/decompiler/pattern.rb', line 245

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

#frontmatterObject



218
219
220
# File 'lib/origen_testers/decompiler/pattern.rb', line 218

def frontmatter
  @frontmatter
end

#method_parse_frontmatterObject



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

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

#method_parse_pinlistObject



124
125
126
127
128
# File 'lib/origen_testers/decompiler/pattern.rb', line 124

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

#method_parse_vectorObject



130
131
132
133
134
# File 'lib/origen_testers/decompiler/pattern.rb', line 130

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

#parser_configObject



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

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.



237
238
239
240
241
242
243
# File 'lib/origen_testers/decompiler/pattern.rb', line 237

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



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

def pinlist
  @pinlist
end

#pinlist_sizeObject Also known as: num_pins, number_of_pins



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

def pinlist_size
  pinlist.pins.size
end

#pinsObject



203
204
205
# File 'lib/origen_testers/decompiler/pattern.rb', line 203

def pins
  pinlist.pins
end

#platformObject Also known as: tester



78
79
80
# File 'lib/origen_testers/decompiler/pattern.rb', line 78

def platform
  self.class.platform
end

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

Returns:

  • (Boolean)


83
84
85
86
87
88
89
# File 'lib/origen_testers/decompiler/pattern.rb', line 83

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

#platform_tokensObject Also known as: decompiler_tokens



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

def platform_tokens
  self.class.platform_tokens
end

#splitter_configObject



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

def splitter_config
  self.class.splitter_config
end

#subclass_error(message) ⇒ Object



152
153
154
155
# File 'lib/origen_testers/decompiler/pattern.rb', line 152

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



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

def vectors
  @vector_handler ||= vector_start
end

#verify_subclass_configurationObject



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/origen_testers/decompiler/pattern.rb', line 136

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