Module: OrigenTesters::VectorGenerator

Extended by:
ActiveSupport::Concern
Included in:
VectorBasedTester
Defined in:
lib/origen_testers/vector_generator.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#compressObject

Returns the value of attribute compress.



13
14
15
# File 'lib/origen_testers/vector_generator.rb', line 13

def compress
  @compress
end

#expand_repeatsObject

Returns the value of attribute expand_repeats.



14
15
16
# File 'lib/origen_testers/vector_generator.rb', line 14

def expand_repeats
  @expand_repeats
end

#vector_commentsObject

When set to true vector and cycle number comments will be appended to pattern vectors. This can also be enabled by running the generate command with the '-v' switch.



12
13
14
# File 'lib/origen_testers/vector_generator.rb', line 12

def vector_comments
  @vector_comments
end

Instance Method Details

#_render(method) ⇒ Object

:nodoc:



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

def _render(method)  # :nodoc:
  if self.respond_to?(method)
    template = send(method)
    # Record the current file, this can be used to resolve any relative path
    # references in the file about to be compiled
    Origen.file_handler.current_file = template
    # Ran into crosstalk problems when rendering ERB templates recursively, setting eoutvar based
    # on the name of the file will causes each template to be rendered into its own 'bank'.
    # Not sure why the final gsub is needed but seems to fail to parse correctly otherwise.
    eoutvar = Pathname.new(template).basename('.*').basename('.*').to_s.gsub('-', '_')
    # Make the file name available to the template
    Origen.generator.compiler.options[:file] = template
    push_microcode Origen.generator.compiler.insert(ERB.new(File.read(template.to_s), 0, Origen.config.erb_trim_mode, eoutvar).result)
  end
end

#add_microcode_to_last_or_cycle(code) ⇒ Object

Adds the given microcode to the last vector if possible. If not possible (meaning the vector already contains microcode) then a new cycle will be added with the given microcode.



271
272
273
274
# File 'lib/origen_testers/vector_generator.rb', line 271

def add_microcode_to_last_or_cycle(code)
  cycle if !stage.last_vector || stage.last_vector.has_microcode?
  stage.last_vector.update(microcode: code)
end

#alignObject Also known as: align_to_first

Duplicate the last vector as required until aligned with the start of the next vector group



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

def align
  stage.store :align
end

#align_to_lastObject

Duplicate the last vector as required until aligned to the last vector of the current vector group



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

def align_to_last
  stage.store :align_last
end

#before_write_pattern_line(line) ⇒ Object

Tester models can overwrite this if they wish to inject any additional pattern lines at final pattern dump time



317
318
319
# File 'lib/origen_testers/vector_generator.rb', line 317

def before_write_pattern_line(line)
  [line]
end

#current_pin_valsObject



536
537
538
# File 'lib/origen_testers/vector_generator.rb', line 536

def current_pin_vals
  ordered_pins_cache.map(&:to_vector).join(' ')
end

#cycle_countObject

Returns the current cycle count



74
75
76
# File 'lib/origen_testers/vector_generator.rb', line 74

def cycle_count
  @cycle_count ||= 0
end

#dec_vec_count(num = 1) ⇒ Object

decrement vector count



68
69
70
71
# File 'lib/origen_testers/vector_generator.rb', line 68

def dec_vec_count(num = 1)
  vec_count if @vec_count.nil?  # define if not already
  @vec_count = @vec_count - num
end

#dont_compressObject



325
326
327
328
329
330
331
332
333
334
# File 'lib/origen_testers/vector_generator.rb', line 325

def dont_compress
  if block_given?
    orig = @dont_compress
    @dont_compress = true
    yield
    @dont_compress = orig
  else
    @dont_compress
  end
end

#dont_compress=(val) ⇒ Object



336
337
338
# File 'lib/origen_testers/vector_generator.rb', line 336

def dont_compress=(val)
  @dont_compress = val
end

#execution_time_in_nsObject

Returns the current execution time



79
80
81
# File 'lib/origen_testers/vector_generator.rb', line 79

def execution_time_in_ns
  @execution_time_in_ns ||= 0
end

#expand_vector(vec) ⇒ Object

expands (un-compresses to pattern) vector if desired or leaves it as is allows for tracking and formatting of vector if comment then return without modification



343
344
345
346
347
348
349
350
351
352
353
354
355
356
# File 'lib/origen_testers/vector_generator.rb', line 343

def expand_vector(vec)
  if vec.is_a?(Vector)
    if expand_repeats
      vec.repeat.times do
        vec.repeat = 1
        yield track_and_format_vector(vec)
      end
    else
      yield track_and_format_vector(vec)
    end
  else
    yield track_and_format_comment(vec)  # Return comments without modification
  end
end

#format(vector_array, section) ⇒ Object

Final pass of a generator vector array which returns lines suitable for writing to the output file. This gives the tester model a chance to concatenate repeats and any other last optimization/formatting changes it wishes to make.

At this point vector array contains a combination of non-vector lines and uncompressed Vector objects (vector lines)



283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
# File 'lib/origen_testers/vector_generator.rb', line 283

def format(vector_array, section)
  tester_writing_pattern = respond_to?(:open_and_write_pattern)
  # Go through vector_array and print out both
  # vectors and non-vectors to pattern (via 'yield line')
  vector_array.each do |vec|
    # skip here important for the ways delays are currently handled
    # TODO: This seems like an upstream bug that should be investigated, why is such
    # a vector even generated?
    if vec.is_a?(String)
      if vec.strip[0] == comment_char
        pipeline.push_comment(vec)
      else
        pipeline.push_microcode(vec)
      end
    else
      next if vec.respond_to?(:repeat) && vec.repeat == 0 # skip vectors with repeat of 0!
      pipeline << vec
    end
    pipeline.flush do |vector|
      expand_vector(vector) do |line|
        yield line unless tester_writing_pattern
      end
    end
  end
  # now flush buffer if there is still a vector
  pipeline.empty(min_vectors: section == :footer ? @min_pattern_vectors : nil) do |vector|
    expand_vector(vector) do |line|
      yield line unless tester_writing_pattern
    end
  end
end

#format_pin_state(pin) ⇒ Object

See Also:

  • Origen::Pins::Pin#to_vector


634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
# File 'lib/origen_testers/vector_generator.rb', line 634

def format_pin_state(pin)
  if pin.repeat_previous? && @support_repeat_previous
    @repeat_previous || '-'
  elsif pin.driving?
    if pin.value == 1
      if pin.high_voltage?
        @drive_very_hi_state || '2'
      else
        @drive_hi_state || '1'
      end
    else
      @drive_lo_state || '0'
    end
  elsif pin.comparing_midband?
    @expect_mid_state || 'M'
  elsif pin.comparing?
    if pin.value == 1
      @expect_hi_state || 'H'
    else
      @expect_lo_state || 'L'
    end
  elsif pin.driving_mem?
    @drive_mem_state || 'D'
  elsif pin.comparing_mem?
    @expect_mem_state || 'E'
  elsif pin.to_be_captured?
    @capture_state || 'C'
  else
    @dont_care_state || 'X'
  end
end

#format_vector(vec) ⇒ Object



386
387
# File 'lib/origen_testers/vector_generator.rb', line 386

def format_vector(vec)
end

#get_pingroup(pin) ⇒ Object



598
599
600
601
602
603
# File 'lib/origen_testers/vector_generator.rb', line 598

def get_pingroup(pin)
  pingroup_map.each do |id, pins|
    return id if pins.include? pin
  end
  nil
end

#inc_cycle_count(num = 1, options = {}) ⇒ Object

increment cycle count



84
85
86
87
88
89
90
# File 'lib/origen_testers/vector_generator.rb', line 84

def inc_cycle_count(num = 1, options = {})
  num, options = 1, num if num.is_a?(Hash)
  cycle_count if @cycle_count.nil? # define if not already
  execution_time_in_ns if @execution_time_in_ns.nil? # define if not already
  @execution_time_in_ns += num * (options[:period_in_ns] || tester.timeset.period_in_ns)
  @cycle_count = @cycle_count + num
end

#inc_vec_count(num = 1) ⇒ Object

increment vector count



62
63
64
65
# File 'lib/origen_testers/vector_generator.rb', line 62

def inc_vec_count(num = 1)
  vec_count if @vec_count.nil?  # define if not already
  @vec_count = @vec_count + num
end

#inhibit_pin(*pins) ⇒ Object Also known as: inhibit_pins

Call to prevent the given pins from appearing in the generated vectors.

This is a convenient way to inhibit something like a J750 mux pin from appearing in the patterns when generating the pattern for a different platform.

When used this method must be called before the first vector is generated - it will not be retrospectively applied to existing vectors.



108
109
110
111
112
113
114
115
116
# File 'lib/origen_testers/vector_generator.rb', line 108

def inhibit_pin(*pins)
  pins.each do |pin|
    pin = $dut.pin(pin) if pin.is_a?(Symbol)
    inhibited_pins << pin
  end
  inhibited_pins.uniq!
  inhibited_pins.compact!
  inhibited_pins
end

#inhibited_pinsObject

Returns an array of pin IDs that are currently inhibited (will not be included when vectors are generated)



52
53
54
# File 'lib/origen_testers/vector_generator.rb', line 52

def inhibited_pins
  @inhibited_pins ||= []
end

#last_object(offset = 0) ⇒ Object



208
209
210
# File 'lib/origen_testers/vector_generator.rb', line 208

def last_object(offset = 0)
  stage.last_object(offset)
end

#last_vector(offset = 0) ⇒ Object



204
205
206
# File 'lib/origen_testers/vector_generator.rb', line 204

def last_vector(offset = 0)
  stage.last_vector(offset)
end

#microcode(code, options = {}) ⇒ Object Also known as: push_microcode



193
194
195
196
197
198
199
200
201
# File 'lib/origen_testers/vector_generator.rb', line 193

def microcode(code, options = {})
  unless @inhibit_vectors
    if options[:offset] && options[:offset] != 0
      stage.insert_from_end code, options[:offset]
    else
      stage.store code
    end
  end
end

#ordered_pins(options = {}) ⇒ Object



408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
# File 'lib/origen_testers/vector_generator.rb', line 408

def ordered_pins(options = {})
  options = {
    include_inhibited_pins: false,
    include_pingroups:      true
  }.merge(options)

  result = nil

  Origen.profile 'Working out pin pattern order' do
    pinorder = Origen.app.pin_pattern_order.dup
    pinexclude = Origen.app.pin_pattern_exclude.dup

    if Origen.app.pin_pattern_order.last.is_a?(Hash)
      options.merge!(pinorder.pop)
    end
    if Origen.app.pin_pattern_exclude.last.is_a?(Hash)
      options.merge!(pinexclude.pop)
    end

    ordered_pins = []

    # Create a copy of all pins and groups to be output, pins/groups will be delete from here as
    # they are output, so that at the end of the user defined pin order what is left in here can
    # either be discarded or output at the end
    pins = Origen.pin_bank.pins.dup
    pingroups = Origen.pin_bank.pin_groups.dup

    if pinorder && pinorder.size > 0
      pinorder.each do |id|
        # If the ID refers to a pin group
        if group = Origen.pin_bank.pin_groups[id]
          # If the group has still to be output just do that now
          if pingroups.include? group.id
            ordered_pins << group
            # Now delete the group from the list of groups still to be output and all of its pins
            # from the list pins still to be output
            group.each do |pin|
              pins.delete(pin.id)
              pin.groups.each do |name, _group|
                pingroups.delete(name)
              end
            end
            pingroups.delete(group.id)
          # To get here the some of the pins in the group have already been output which is preventing
          # output of the complete group at this point, in that case output any of its pins that have
          # still to go
          else
            group.each do |pin|
              if pins.include? pin.id
                ordered_pins << pin
                pin.groups.each do |name, _group|
                  pingroups.delete(name)
                end
              end
            end
          end
        # this is a pin
        else
          pin = Origen.pin_bank.find(id)
          fail "Undefined pin (#{id}) added to pin_pattern_order" unless pin
          ordered_pins << pin
          pin.groups.each do |name, _group|
            pingroups.delete(name)
          end
          pin.name = id
          pins.delete(pin.id)
        end
      end
    end

    if pinexclude && pinexclude.size > 0
      pinexclude.each do |id|
        if group = Origen.pin_bank.pin_groups[id]
          # see if group is already in ordered_pins
          fail "Pin group #{id} is defined both in pin_pattern_order and pin_pattern_exclude" unless pingroups.include? id
          # this is a pin group, delete all pins in group
          pingroups.delete(id)
          group.each do |pin|
            fail "Pin (#{pin.name}) in group (#{group.id}) is defined both in pin_pattern_order and pin_pattern_exclude" unless pins.include? pin.id
            pins.delete(pin.id)
          end
        else # this is a pin, delete the pin
          pin = Origen.pin_bank.find(id)
          fail "Undefined pin (#{id}) added to pin_pattern_exclude" unless pin
          fail "Pin #{pin.name} is defined both in pin_pattern_order and pin_pattern_exclude" unless pins.include? pin.id
          pin.name = id
          pins.delete(pin.id)
          pin.groups.each do |name, _group|
            pingroups.delete(name)
          end
        end
      end
    end

    unless options[:only]
      # all the rest of the pins to the end of the pattern order
      pins.each do |_id, pin|
        # check for port
        if pin.belongs_to_a_pin_group?
          # Are any of this pin's groups still waiting to be output? pingroups at this point contains
          # those groups which have not been rendered yet
          group = pingroups.find do |_id, group|
            pin.groups.any? { |_pid, pgroup| group == pgroup }
          end
          if group
            ordered_pins << group[1]
            group[1].each { |pin| pins.delete(pin.id) }
          else
            ordered_pins << pin
          end
        else
          ordered_pins << pin
        end
      end
    end

    result = ordered_pins.map do |pin|
      if options[:include_inhibited_pins]
        pin
      else
        inhibited_pins.include?(pin) ? nil : pin
      end
    end
    result = result.compact
  end
  result
end

#ordered_pins_cache(options = {}) ⇒ Object

Cache any pin ordering for later use since all vectors should be formatted the same



394
395
396
# File 'lib/origen_testers/vector_generator.rb', line 394

def ordered_pins_cache(options = {})
  @ordered_pins_cache ||= ordered_pins(options)
end

#ordered_pins_nameObject

Retrieve optional 'name' meta passed in with the pin_pattern_order call



399
400
401
402
403
404
405
406
# File 'lib/origen_testers/vector_generator.rb', line 399

def ordered_pins_name
  pinorder = Origen.app.pin_pattern_order.dup
  if Origen.app.pin_pattern_order.last.is_a?(Hash)
    options = pinorder.pop
    name = options[:name]
  end
  name
end

#pingroup_mapObject



389
390
391
# File 'lib/origen_testers/vector_generator.rb', line 389

def pingroup_map
  Origen.app.pingroup_map
end

#pipelineObject



321
322
323
# File 'lib/origen_testers/vector_generator.rb', line 321

def pipeline
  @pipeline ||= VectorPipeline.new(vector_group_size)
end

#preset_next_vector(attrs = {}, &block) ⇒ Object

Allows the attributes for the next vector to be setup prior to generating it.

A block can be optionally supplied to act as a clean up method, that is the block will be saved and executed after the next cycle has been generated.

See the V93K store_next_cycle method for an example of using this.



221
222
223
224
# File 'lib/origen_testers/vector_generator.rb', line 221

def preset_next_vector(attrs = {}, &block)
  @preset_next_vector = attrs
  @preset_next_vector_cleanup = block
end

#push_comment(msg) ⇒ Object



188
189
190
191
# File 'lib/origen_testers/vector_generator.rb', line 188

def push_comment(msg)
  # Comments are stored verbatim for now, can't see much use for a dedicated comment object
  stage.store msg unless @inhibit_comments
end

#push_vector(attrs = {}) ⇒ Object Also known as: vector

Called by every $tester.cycle command to push a vector to the stage object



227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/origen_testers/vector_generator.rb', line 227

def push_vector(attrs = {})
  attrs = {
    dont_compress: @dont_compress
  }.merge(attrs)
  unless @inhibit_vectors
    if @preset_next_vector
      attrs = @preset_next_vector.merge(attrs) do |key, preset, current|
        if preset && current && current != ''
          fail "Value for #{key} set by preset_next_vector clashed with the next vector!"
        else
          preset || current
        end
      end
      @preset_next_vector = nil
    end
    v = Vector.new(attrs)
    stage.store Vector.new(attrs)
    inc_vec_count
    inc_cycle_count(attrs[:repeat] || 1, period_in_ns: v.timeset.period_in_ns)
    if @preset_next_vector_cleanup
      @preset_next_vector_cleanup.call(v)
      @preset_next_vector_cleanup = nil
    end
  end
end

#regex_for_pin(pin) ⇒ Object

Returns a regular expression that can be used to get the value of the given pin within the string returned by current_pin_vals.

str = $tester.current_pin_vals                  # => "1 1 XX10 H X1"
regex = $tester.regex_for_pin($dut.pins(:jtag)) # => /\w{1} \w{1} (\w{4}) \w{1} \w{2}/
regex.match(str)
Regexp.last_match(1)   # => "XX10"


548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
# File 'lib/origen_testers/vector_generator.rb', line 548

def regex_for_pin(pin)
  @regex_for_pins ||= {}
  # Cache this as potentially called many times during pattern generation
  @regex_for_pins[pin] ||= begin
    regex = '/'
    ordered_pins_cache.each do |p|
      if pin == p
        regex += "(\\w{#{p.size}}) "
      else
        regex += "\\w{#{p.size}} "
      end
    end
    eval(regex.strip + '/')
  end
end

#regex_for_pin_sub(pin) ⇒ Object

Returns a regular expression that can be used to change the value of the given pin within the string returned by current_pin_vals.

str = $tester.current_pin_vals                      # => "1 1 XX10 H X1"
regex = $tester.regex_for_pin_sub($dut.pins(:jtag)) # => /(\w{1} \w{1} )(\w{4})( \w{1} \w{2})/
str.sub(regex, '\1LLLL\3')  # => "1 1 LLLL H X1"


571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
# File 'lib/origen_testers/vector_generator.rb', line 571

def regex_for_pin_sub(pin)
  @regex_for_pin_subs ||= {}
  # Cache this as potentially called many times during pattern generation
  @regex_for_pin_subs[pin] ||= begin
    regex = '/'
    first_pin_done = false
    match_pin_done = false
    ordered_pins_cache.each do |p|
      if pin == p
        regex += ')' if first_pin_done
        regex += "(\\w{#{p.size}})( "
      else
        regex += '(' unless first_pin_done
        regex += "\\w{#{p.size}} "
      end
      first_pin_done = true
    end
    regex.strip!
    if regex[-1] == '('
      regex.chop!
    else
      regex += ')'
    end
    eval(regex + '/')
  end
end

#remove_store_from_vector(vector) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



667
668
669
# File 'lib/origen_testers/vector_generator.rb', line 667

def remove_store_from_vector(vector)
  vector.pin_vals.sub!('C', 'X')
end

#render(template, options = {}) ⇒ Object

Render content directly into a pattern, any options will be passed to the template



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/origen_testers/vector_generator.rb', line 120

def render(template, options = {})
  # Record the current file, this can be used to resolve any relative path
  # references in the file about to be compiled
  Origen.file_handler.current_file = template
  # Ran into crosstalk problems when rendering ERB templates recursively, setting eoutvar based
  # on the name of the file will causes each template to be rendered into its own 'bank'.
  # Not sure why the final gsub is needed but seems to fail to parse correctly otherwise.
  eoutvar = Pathname.new(template).basename('.*').basename('.*').to_s.gsub('-', '_')
  # Make the file name available to the template
  Origen.generator.compiler.options[:file] = template
  options.each { |k, v| Origen.generator.compiler.options[k] = v }
  code = Origen.generator.compiler.insert(ERB.new(File.read(template.to_s), 0, Origen.config.erb_trim_mode, eoutvar).result)
  code.strip!
  push_microcode code
end

#render_bodyObject

Same as the render method, except the template method should be called body_template.



146
147
148
# File 'lib/origen_testers/vector_generator.rb', line 146

def render_body
  _render(:body_template)
end

If the tester defines a method named footer_template this method will compile whatever template file is returned by that method.

This method is called automatically during the footer section of a Pattern.create operation.



155
156
157
# File 'lib/origen_testers/vector_generator.rb', line 155

def render_footer
  _render(:footer_template)
end

#render_headerObject

If the tester defines a method named header_template this method will compile whatever template file is returned by that method.

This method is called automatically during the header section of a Pattern.create operation.



164
165
166
# File 'lib/origen_testers/vector_generator.rb', line 164

def render_header
  _render(:header_template)
end

#render_templateObject

If the tester defines a method named template this method will compile whatever template file is returned by that method.

This method is called automatically after the body section of a Pattern.create operation has completed.



141
142
143
# File 'lib/origen_testers/vector_generator.rb', line 141

def render_template
  _render(:template)
end

#reset_cycle_count(num = 0) ⇒ Object

reset_cycle_count



93
94
95
96
97
# File 'lib/origen_testers/vector_generator.rb', line 93

def reset_cycle_count(num = 0)
  cycle_count if @cycle_count.nil? # define if not already
  @execution_time_in_ns = 0
  @cycle_count = num
end

#stageObject



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

def stage
  Origen.generator.stage
end

#track_and_format_comment(comment) ⇒ Object



358
359
360
# File 'lib/origen_testers/vector_generator.rb', line 358

def track_and_format_comment(comment)
  comment
end

#track_and_format_vector(vec) ⇒ Object

Update tracking info (stats object) and allow for any additional formatting via format_vector method if overridden



365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
# File 'lib/origen_testers/vector_generator.rb', line 365

def track_and_format_vector(vec)
  unless vec.timeset
    puts 'No timeset defined!'
    puts 'Add one to your top level startup method or target like this:'
    puts '$tester.set_timeset("nvmbist", 40)   # Where 40 is the period in ns'
    exit 1
  end
  stats = Origen.app.stats
  stats.add_vector
  if vector_group_size > 1 && vec.repeat > 1
    stats.add_cycle(1)
    stats.add_cycle((vec.repeat - 1) * vector_group_size)
    stats.add_time_in_ns(vec.timeset.period_in_ns)
    stats.add_time_in_ns((vec.repeat - 1) * vector_group_size * vec.timeset.period_in_ns)
  else
    stats.add_cycle(vec.repeat)
    stats.add_time_in_ns(vec.repeat * vec.timeset.period_in_ns)
  end
  format_vector(vec)
end

#update_pin_from_formatted_state(pin, state) ⇒ Object



605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
# File 'lib/origen_testers/vector_generator.rb', line 605

def update_pin_from_formatted_state(pin, state)
  if state == @repeat_previous || state == '-'
    pin.repeat_previous = true
  elsif state == @drive_very_hi_state || state == '2'
    pin.drive_very_hi
  elsif state == @drive_hi_state || state == '1'
    pin.drive_hi
  elsif state == @drive_lo_state || state == '0'
    pin.drive_lo
  elsif state == @expect_hi_state || state == 'H'
    pin.expect_hi
  elsif state == @expect_lo_state || state == 'L'
    pin.expect_lo
  elsif state == @expect_mid_state || state == 'M'
    pin.expect_mid
  elsif state == @drive_mem_state || state == 'D'
    pin.drive_mem
  elsif state == @expect_mem_state || state == 'E'
    pin.expect_mem
  elsif state == @capture_state || state == 'C'
    pin.capture
  elsif state == @dont_care_state || state == 'X'
    pin.dont_care
  else
    fail "Unknown pin state: #{state}"
  end
end

#update_vector(attrs = {}) ⇒ Object



254
255
256
257
258
259
# File 'lib/origen_testers/vector_generator.rb', line 254

def update_vector(attrs = {})
  unless @inhibit_vectors
    offset = (attrs.delete(:offset) || 0).abs
    stage.last_vector(offset).update(attrs)
  end
end

#update_vector_pin_val(pin, options = {}) ⇒ Object



261
262
263
264
265
266
# File 'lib/origen_testers/vector_generator.rb', line 261

def update_vector_pin_val(pin, options = {})
  unless @inhibit_vectors
    offset = (options.delete(:offset) || 0).abs
    stage.last_vector(offset).update_pin_val(pin)
  end
end

#vec_countObject

init vector count when first accessed, otherwise return value



57
58
59
# File 'lib/origen_testers/vector_generator.rb', line 57

def vec_count
  @vec_count ||= 0
end

#vector_group_sizeObject



17
18
19
# File 'lib/origen_testers/vector_generator.rb', line 17

def vector_group_size
  @vector_group_size || 1
end

#vector_group_size=(number) ⇒ Object



21
22
23
24
25
26
27
28
# File 'lib/origen_testers/vector_generator.rb', line 21

def vector_group_size=(number)
  if number > 1 && number.odd?
    fail 'Only even numbers can be supplied for the vector_group_size!'
  end
  # Each pattern should run with its own tester instance, but just in case
  @pipeline = nil
  @vector_group_size = number
end

#with_vector_group_size(number) ⇒ Object



30
31
32
33
34
35
# File 'lib/origen_testers/vector_generator.rb', line 30

def with_vector_group_size(number)
  orig = vector_group_size
  self.vector_group_size = number
  yield
  self.vector_group_size = orig
end