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

Returns the value of attribute comments.


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

def comments
  @comments
end

#contains_captureObject

Returns the value of attribute contains_capture.


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

def contains_capture
  @contains_capture
end

#cycleObject

Returns the value of attribute cycle.


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

def cycle
  @cycle
end

#cycle_numberObject

Returns the value of attribute cycle_number.


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

def cycle_number
  @cycle_number
end

#dont_compressObject

Returns the value of attribute dont_compress.


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

def dont_compress
  @dont_compress
end

#inline_commentObject

Returns the value of attribute inline_comment.


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

def inline_comment
  @inline_comment
end

#microcodeObject

Returns the value of attribute microcode.


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

def microcode
  @microcode
end

#numberObject

Returns the value of attribute number.


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

def number
  @number
end

#pin_valsObject

Returns the value of attribute pin_vals.


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


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

def repeat
  @repeat
end

#timesetObject

Returns the value of attribute timeset.


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

def timeset
  @timeset
end

Instance Method Details

#==(obj) ⇒ Object


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

def ==(obj)
  if obj.is_a?(Vector)
    self.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
# 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)

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

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"

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

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

#ordered_pinsObject


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

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:


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

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


148
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
# File 'lib/origen_testers/vector.rb', line 148

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