Class: OrigenTesters::Vector

Inherits:
Object
  • Object
show all
Defined in:
lib/origen_testers/vector.rb

Overview

A simple class to model a vector

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attrs = {}) ⇒ Vector

Returns a new instance of Vector.



8
9
10
11
12
13
# File 'lib/origen_testers/vector.rb', line 8

def initialize(attrs = {})
  @inline_comment = ''
  attrs.each do |attribute, value|
    send("#{attribute}=", value)
  end
end

Instance Attribute Details

#commentsObject

rubocop:disable Lint/DuplicateMethods



4
5
6
# File 'lib/origen_testers/vector.rb', line 4

def comments
  @comments
end

#contains_captureObject

rubocop:disable Lint/DuplicateMethods



4
5
6
# File 'lib/origen_testers/vector.rb', line 4

def contains_capture
  @contains_capture
end

#cycleObject

rubocop:disable Lint/DuplicateMethods



4
5
6
# File 'lib/origen_testers/vector.rb', line 4

def cycle
  @cycle
end

#cycle_numberObject

rubocop:disable Lint/DuplicateMethods



4
5
6
# File 'lib/origen_testers/vector.rb', line 4

def cycle_number
  @cycle_number
end

#dont_compressObject

rubocop:disable Lint/DuplicateMethods



4
5
6
# File 'lib/origen_testers/vector.rb', line 4

def dont_compress
  @dont_compress
end

#inline_commentObject

rubocop:disable Lint/DuplicateMethods



4
5
6
# File 'lib/origen_testers/vector.rb', line 4

def inline_comment
  @inline_comment
end

#microcodeObject

rubocop:disable Lint/DuplicateMethods



4
5
6
# File 'lib/origen_testers/vector.rb', line 4

def microcode
  @microcode
end

#numberObject

rubocop:disable Lint/DuplicateMethods



4
5
6
# File 'lib/origen_testers/vector.rb', line 4

def number
  @number
end

#pin_valsObject

rubocop:disable Lint/DuplicateMethods



4
5
6
# File 'lib/origen_testers/vector.rb', line 4

def pin_vals
  @pin_vals
end

#repeatObject

Since repeat 0 is non-intuitive every vector implicitly has a repeat of 1



4
5
6
# File 'lib/origen_testers/vector.rb', line 4

def repeat
  @repeat
end

#timesetObject

rubocop:disable Lint/DuplicateMethods



4
5
6
# File 'lib/origen_testers/vector.rb', line 4

def timeset
  @timeset
end

Instance Method Details

#==(obj) ⇒ Object



198
199
200
201
202
203
204
205
206
# File 'lib/origen_testers/vector.rb', line 198

def ==(obj)
  if obj.is_a?(Vector)
    has_microcode? == obj.has_microcode? &&
      timeset == obj.timeset &&
      pin_vals == obj.pin_vals
  else
    super obj
  end
end

#convert_to_timeset(tset) ⇒ Object

Converts the vector to the period specified by the given timeset (instead of the period for the timeset it was originally created with).

This may convert the single vector to multiple vectors, in which case the method will yield as many vectors as required back to the caller.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/origen_testers/vector.rb', line 65

def convert_to_timeset(tset)
  # If no conversion required
  if tset.period_in_ns == timeset.period_in_ns
    yield self
  else
    if tset.period_in_ns > timeset.period_in_ns
      fail "Cannot convert a vector with timeset #{timeset.name} to timeset #{tset.name}!"
    end
    if timeset.period_in_ns % tset.period_in_ns != 0
      fail "The period of timeset #{timeset.name} is not a multiple of the period of timeset #{tset.name}!"
    end

    if contains_capture
      vector_modification_required = true
    elsif $tester.timing_toggled_pins.empty?
      vector_modification_required = false
    else
      # If the timing toggled pins are not driving on this vector, then no
      # modification will be required
      vector_modification_required = $tester.timing_toggled_pins.any? do |pin|
        value = pin_value(pin)
        value == '1' || value == '0'
      end
    end
    number_of_base_vectors = repeat || 1
    vectors_per_period = timeset.period_in_ns / tset.period_in_ns
    self.inline_comment += "Period levelled (#{timeset.name})"
    self.timeset = tset
    if vector_modification_required && vectors_per_period > 1
      pin_values = $tester.timing_toggled_pins.map do |pin|
        on = pin_value(pin)
        if on == '1'
          { pin: pin, on: '1', off: '0' }
        elsif on == '0'
          { pin: pin, on: '0', off: '1' }
        end
      end
      pin_vals_with_compare = nil
      number_of_base_vectors.times do |i|
        # Drive the 'on' value on the first cycle, this is already setup
        v = dup
        v.repeat = 1
        v.pin_vals = inhibit_compares
        $tester.remove_store_from_vector(v) if v.contains_capture
        yield v
        # Then drive the pin 'off' value for the remainder
        v = dup
        r = vectors_per_period - 1
        if r > 1
          v = dup
          v.repeat = r - 1
          pin_values.each { |vals| v.set_pin_value(vals[:pin], vals[:off]) if vals }
          $tester.remove_store_from_vector(v) if v.contains_capture
          yield v
        end
        v = dup
        v.repeat = 1
        v.pin_vals = restore_compares
        pin_values.each { |vals| v.set_pin_value(vals[:pin], vals[:off]) if vals }
        yield v
      end
    else
      self.repeat = number_of_base_vectors * vectors_per_period
      yield self
    end
  end
end

#has_microcode?Boolean

Returns:

  • (Boolean)


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

def has_microcode?
  !!(@microcode && !@microcode.empty?)
end

#inhibit_comparesObject

Set all active compare data to X. The original values will be preserved so that they can be restored

vector.pin_vals            # => "1 1 LHLL 10001 L 1 XX 0"
vector.inhibit_compares    # => "1 1 XXXX 10001 X 1 XX 0"
vector.restore_compares    # => "1 1 LHLL 10001 L 1 XX 0"


138
139
140
141
# File 'lib/origen_testers/vector.rb', line 138

def inhibit_compares
  @orig_pin_vals = pin_vals
  @pin_vals = pin_vals.gsub(/H|L/, 'X')
end

#ordered_pinsObject



177
178
179
# File 'lib/origen_testers/vector.rb', line 177

def ordered_pins
  Origen.app.pin_map.sort_by { |id, pin| pin.order }.map { |id, pin| pin }
end

#pin_value(pin) ⇒ Object

Returns the value (a string) that is assigned to the given pin by the given vector

vector.pin_vals                     # => "1 1 XX10 H X1"
vector.pin_value($dut.pins(:jtag))  # => "XX10"


30
31
32
33
# File 'lib/origen_testers/vector.rb', line 30

def pin_value(pin)
  $tester.regex_for_pin(pin).match(pin_vals)
  Regexp.last_match(1)
end

#restore_comparesObject

See Also:



144
145
146
# File 'lib/origen_testers/vector.rb', line 144

def restore_compares
  @pin_vals = @orig_pin_vals
end

#set_pin_value(pin, value = nil) ⇒ Object

Replace the current pin value assigned to the given pin with either the state that it currently has, or with a supplied string value.

In the case of a string being supplied as the 2nd argument, the caller is responsible for ensuring that the pin state format/codes matches that used by the current tester.

vector.pin_vals                          # => "1 1 XX10 H X1"
$dut.pins(:jtag).drive(0)
vector.set_pin_value($dut.pins(:jtag))
vector.pin_vals                          # => "1 1 0000 H X1"
vector.set_pin_value($dut.pins(:jtag), "XXXX")
vector.pin_vals                          # => "1 1 XXXX H X1"


48
49
50
51
52
53
54
55
56
57
58
# File 'lib/origen_testers/vector.rb', line 48

def set_pin_value(pin, value = nil)
  regex = $tester.regex_for_pin_sub(pin)
  value ||= pin.to_vector
  if $tester.ordered_pins_cache.first == pin
    self.pin_vals = pin_vals.sub(regex, value + '\2')
  elsif $tester.ordered_pins_cache.last == pin
    self.pin_vals = pin_vals.sub(regex, '\1' + value)
  else
    self.pin_vals = pin_vals.sub(regex, '\1' + value + '\3')
  end
end

#update(attrs = {}) ⇒ Object



19
20
21
22
23
# File 'lib/origen_testers/vector.rb', line 19

def update(attrs = {})
  attrs.each do |attribute, value|
    send("#{attribute}=", value)
  end
end

#update_pin_val(pin) ⇒ Object

Updates the pin values to reflect the value currently held by the given pin



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/origen_testers/vector.rb', line 149

def update_pin_val(pin)
  vals = pin_vals.split(' ')
  if pin.belongs_to_a_pin_group? && !pin.is_a?(Origen::Pins::PinCollection)
    port = nil
    pin.groups.each { |i| port = i[1] if port.nil? && Origen.tester.ordered_pins.include?(i[1]) } # see if group is included in ordered pins
    if port
      ix = Origen.tester.ordered_pins.index(port) # find index of port
      i = port.index(pin)
    else
      ix = Origen.tester.ordered_pins.index(pin)
      i = 0
    end
  else
    ix = Origen.tester.ordered_pins.index(pin)
    i = 0
  end

  if Origen.pin_bank.pin_groups.keys.include? pin.id
    val = pin.map { |p| Origen.tester.format_pin_state(p) }.join('')
    vals[ix] = val
  else
    val = Origen.tester.format_pin_state(pin)
    vals[ix][i] = val
  end

  self.pin_vals = vals.join(' ')
end