class Origen::Pins::Timing::Timeset

Attributes

compare_waves[R]

Returns an array containing the defined waves for compare cycles The wave at position 0 will be applied be default to any pin which does not otherwise have a specific wave assignment.

drive_waves[R]

Returns an array containing the defined waves for drive cycles. The wave at position 0 will be applied be default to any pin which does not otherwise have a specific wave assignment.

id[R]

Public Class Methods

new(id) click to toggle source
# File lib/origen/pins/timing/timeset.rb, line 17
def initialize(id)
  @id = id
  @drive_waves = []
  @compare_waves = []
  # Look up tables that map pins to waves
  @compare_pin_map = {}
  @drive_pin_map = {}
  # Temporary storage of pin assignments
  @pin_ids = { drive: [], compare: [] }

  # Create the default waves, these can be overridden later
  wave do |w|
    w.compare :data, at: 'period / 2'
  end

  wave do |w|
    w.drive :data, at: 0
  end
end

Public Instance Methods

clear_cache() click to toggle source

The timeset will cache a view of the dut’s pins for performance, calling this method will clear that cache and regenerate the internal view. This should generally not be required, but available for corner cases where a pin is added to the dut after the cache has been generated.

# File lib/origen/pins/timing/timeset.rb, line 77
def clear_cache
  @all_pin_ids = nil
  @groups = nil
  compare_waves.each { |w| w.send(:clear_cache) }
  drive_waves.each { |w| w.send(:clear_cache) }
end
compare_wave(*pin_ids)
Alias for: wave
drive_wave(*pin_ids)
Alias for: wave
wave(*pin_ids) { |w| ... } click to toggle source

Add a new drive or compare wave to the timeset

timeset.wave :tck do |w|
  w.drive :data, at: 0
  w.drive 0, at: 25
  w.dont_care at: "period - 10"
end
# File lib/origen/pins/timing/timeset.rb, line 44
def wave(*pin_ids)
  options = pin_ids.last.is_a?(Hash) ? pin_ids.pop : {}
  w = Wave.new(self, options)
  yield w
  if w.drive?
    if pin_ids.empty?
      w.send(:index=, 0)
      drive_waves[0] = w
      @pin_ids[:drive][0] = pin_ids
    else
      w.send(:index=, drive_waves.size)
      drive_waves << w
      @pin_ids[:drive] << pin_ids
    end
  else
    if pin_ids.empty?
      w.send(:index=, 0)
      compare_waves[0] = w
      @pin_ids[:compare][0] = pin_ids
    else
      w.send(:index=, compare_waves.size)
      compare_waves << w
      @pin_ids[:compare] << pin_ids
    end
  end
end
Also aliased as: compare_wave, drive_wave

Private Instance Methods

all_pin_ids() click to toggle source
# File lib/origen/pins/timing/timeset.rb, line 163
def all_pin_ids
  @all_pin_ids ||= dut.pins.values.map(&:id)
end
assign_pins() click to toggle source

The pin assignments are done lazily to cater for the guy who will want to define waves ahead of pins or some such

# File lib/origen/pins/timing/timeset.rb, line 88
def assign_pins
  @pin_ids[:drive].each_with_index do |ids, i|
    expand_groups(ids) do |id|
      @drive_pin_map[id] ||= []
      @drive_pin_map[id] << i
    end
  end
  @pin_ids[:compare].each_with_index do |ids, i|
    expand_groups(ids) do |id|
      @compare_pin_map[id] ||= []
      @compare_pin_map[id] << i
    end
  end
  @pin_ids = :done
end
expand_groups(ids) { |id| ... } click to toggle source
# File lib/origen/pins/timing/timeset.rb, line 104
def expand_groups(ids)
  ids.each do |id|
    if g = dut.pin_groups[id]
      g.each do |pin|
        yield pin.id
      end
    else
      yield id
    end
  end
end
pin_ids_for(wave) click to toggle source
# File lib/origen/pins/timing/timeset.rb, line 153
def pin_ids_for(wave)
  assign_pins unless @pin_ids == :done
  map = wave.drive? ? @drive_pin_map : @compare_pin_map
  if wave.index == 0
    all_pin_ids.select { |id| !map[id] || map[id].include?(0) }
  else
    all_pin_ids.select { |id| map[id] && map[id].include?(wave.index) }
  end
end
wave_for(pin, options) click to toggle source
# File lib/origen/pins/timing/timeset.rb, line 116
def wave_for(pin, options)
  assign_pins unless @pin_ids == :done
  if options[:type] == :drive
    i = @drive_pin_map[pin.id]
    if i
      if i.size > 1
        code = options[:code]
        code = nil if code == 1
        code = nil if code == 0
        i.each do |ix|
          return drive_waves[ix] if drive_waves[ix].code == code
        end
      else
        drive_waves[i[0]]
      end
    else
      drive_waves[0]
    end
  else
    i = @compare_pin_map[pin.id]
    if i
      if i.size > 1
        code = options[:code]
        code = nil if code == 'L' || code == :L
        code = nil if code == 'H' || code == :H
        i.each do |ix|
          return drive_waves[ix] if drive_waves[ix].code == code
        end
      else
        compare_waves[i[0]]
      end
    else
      compare_waves[0]
    end
  end
end