Module: OrigenTesters::VectorGenerator

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

Instance Method Summary collapse

Instance Method Details

#_render(method) ⇒ Object

:nodoc:



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/origen_testers/vector_generator.rb', line 158

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.



260
261
262
263
# File 'lib/origen_testers/vector_generator.rb', line 260

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



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

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



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

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



305
306
307
# File 'lib/origen_testers/vector_generator.rb', line 305

def before_write_pattern_line(line)
  [line]
end

#current_pin_valsObject



510
511
512
# File 'lib/origen_testers/vector_generator.rb', line 510

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

#cycle_countObject

init cycle count when first accessed, otherwise return value



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

def cycle_count
  @cycle_count ||= 0
end

#dec_vec_count(num = 1) ⇒ Object

decrement vector count



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

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

#dont_compressObject



313
314
315
316
317
318
319
320
321
322
# File 'lib/origen_testers/vector_generator.rb', line 313

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



324
325
326
# File 'lib/origen_testers/vector_generator.rb', line 324

def dont_compress=(val)
  @dont_compress = val
end

#expand_vector(vec) ⇒ Object

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



331
332
333
334
335
336
337
338
339
340
341
342
343
344
# File 'lib/origen_testers/vector_generator.rb', line 331

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 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)



272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
# File 'lib/origen_testers/vector_generator.rb', line 272

def format(vector_array, section)
  # 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
      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
    end
  end
end

#format_pin_state(pin) ⇒ Object

See Also:

  • Origen::Pins::Pin#to_vector


608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
# File 'lib/origen_testers/vector_generator.rb', line 608

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



370
371
# File 'lib/origen_testers/vector_generator.rb', line 370

def format_vector(vec)
end

#get_pingroup(pin) ⇒ Object



572
573
574
575
576
577
# File 'lib/origen_testers/vector_generator.rb', line 572

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

#inc_cycle_count(num = 1) ⇒ Object

increment cycle count



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

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

#inc_vec_count(num = 1) ⇒ Object

increment vector count



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

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.



98
99
100
101
102
103
104
105
106
# File 'lib/origen_testers/vector_generator.rb', line 98

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)



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

def inhibited_pins
  @inhibited_pins ||= []
end

#last_object(offset = 0) ⇒ Object



198
199
200
# File 'lib/origen_testers/vector_generator.rb', line 198

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

#last_vector(offset = 0) ⇒ Object



194
195
196
# File 'lib/origen_testers/vector_generator.rb', line 194

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

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



183
184
185
186
187
188
189
190
191
# File 'lib/origen_testers/vector_generator.rb', line 183

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



382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
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
# File 'lib/origen_testers/vector_generator.rb', line 382

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



378
379
380
# File 'lib/origen_testers/vector_generator.rb', line 378

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

#pingroup_mapObject



373
374
375
# File 'lib/origen_testers/vector_generator.rb', line 373

def pingroup_map
  Origen.app.pingroup_map
end

#pipelineObject



309
310
311
# File 'lib/origen_testers/vector_generator.rb', line 309

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.



211
212
213
214
# File 'lib/origen_testers/vector_generator.rb', line 211

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

#push_comment(msg) ⇒ Object



178
179
180
181
# File 'lib/origen_testers/vector_generator.rb', line 178

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



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/origen_testers/vector_generator.rb', line 217

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
    stage.store Vector.new(attrs)
    inc_vec_count
    inc_cycle_count(attrs[:repeat] || 1)
    if @preset_next_vector_cleanup
      @preset_next_vector_cleanup.call
      @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"


522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
# File 'lib/origen_testers/vector_generator.rb', line 522

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"


545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
# File 'lib/origen_testers/vector_generator.rb', line 545

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

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

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



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/origen_testers/vector_generator.rb', line 110

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.



136
137
138
# File 'lib/origen_testers/vector_generator.rb', line 136

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.



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

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.



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

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.



131
132
133
# File 'lib/origen_testers/vector_generator.rb', line 131

def render_template
  _render(:template)
end

#reset_cycle_count(num = 0) ⇒ Object

reset_cycle_count



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

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

#stageObject



174
175
176
# File 'lib/origen_testers/vector_generator.rb', line 174

def stage
  Origen.generator.stage
end

#track_and_format_vector(vec) ⇒ Object

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



349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
# File 'lib/origen_testers/vector_generator.rb', line 349

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



579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
# File 'lib/origen_testers/vector_generator.rb', line 579

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



243
244
245
246
247
248
# File 'lib/origen_testers/vector_generator.rb', line 243

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



250
251
252
253
254
255
# File 'lib/origen_testers/vector_generator.rb', line 250

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



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

def vec_count
  @vec_count ||= 0
end

#vector_group_sizeObject



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

def vector_group_size
  @vector_group_size || 1
end

#vector_group_size=(number) ⇒ Object



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

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



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

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