Module: OrigenTesters::API

Defined in:
lib/origen_testers/api.rb

Overview

This module implements the basic set of methods that a tester must have in order for Origen to talk to it.

They can be overridden by tester specific classes and who may go on to add additional methods of their own.

Essentially this API means that any class that includes Origen::Tester will function as a tester, although it might not do very much!

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#capture_styleObject

Get/Set the capture style

This method changes the way tester.store() implements the store The default value and possible settings is dependent on the individual tester.

Examples:

tester.capture_style = :hram


29
30
31
# File 'lib/origen_testers/api.rb', line 29

def capture_style
  @capture_style
end

#comment_levelObject

Returns the value of attribute comment_level.



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

def comment_level
  @comment_level
end

#generatingObject

Returns the value of attribute generating.



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

def generating
  @generating
end

#includesObject

Returns the value of attribute includes.



11
12
13
# File 'lib/origen_testers/api.rb', line 11

def includes
  @includes
end

#overlay_styleObject

Get/Set the overlay style

This method changes the way overlay is handled. The default value and possible settings is dependent on the individual tester.

Examples:

tester.overlay_style = :label


21
22
23
# File 'lib/origen_testers/api.rb', line 21

def overlay_style
  @overlay_style
end

Instance Method Details

#annotate(msg, options = {}) ⇒ Object



113
114
# File 'lib/origen_testers/api.rb', line 113

def annotate(msg, options = {})
end

#any_clocks_running?Boolean

Returns:

  • (Boolean)


247
248
249
# File 'lib/origen_testers/api.rb', line 247

def any_clocks_running?
  @clocks_running.nil? ? false : @clocks_running.count > 0
end

#c1(msg, options = {}) ⇒ Object

Output a comment in the pattern, normally you would not call this directly and instead use these shorthand methods:

cc "Some comment"
ss "A single line step comment"
step_comment do
    cc "A multi line"
    cc "step comment"
end


142
143
144
145
146
# File 'lib/origen_testers/api.rb', line 142

def c1(msg, options = {})
  prefix = comment_char + ' '
  prefix += step_comment_prefix + ' ' if @step_comment_on
  push_comment(prefix + msg.to_s)
end

#c2(msg, options = {}) ⇒ Object



148
149
150
# File 'lib/origen_testers/api.rb', line 148

def c2(msg, options = {})
  c1(msg, options)
end

#capture_memory(type = :default) ⇒ Object

Configure capture memory to a non-default setting

This method changes the way the instruments statement gets rendered if the tester’s capture memory is used.

If called without a block, this method will return the instance of type OrigenTesters::MemoryStyle for the corresponding memory type

Examples:

tester.capture_memory :default do |mem|
  mem.pin :tdo, size: 32, format: :long
end
mem_style = tester.capture_memory(:default)
if mem_style.contains_pin?(:tdo)
  attributes_hash = mem_style.accumulate_attributes(:tdo)

end


375
376
377
378
379
380
381
382
383
# File 'lib/origen_testers/api.rb', line 375

def capture_memory(type = :default)
  type = :hram if type == :default
  capture_memory_config[type] = OrigenTesters::MemoryStyle.new unless capture_memory_config.key?(type)
  if block_given?
    yield capture_memory_config[type]
  else
    capture_memory_config[type]
  end
end

#capture_memory_configObject



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

def capture_memory_config
  @capture_memory_config ||= {}
end

#clocks_runningObject Also known as: running_clocks



251
252
253
# File 'lib/origen_testers/api.rb', line 251

def clocks_running
  @clocks_running
end

#comment_charObject



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

def comment_char
  @comment_char || '//'
end

#cycle(options = {}) ⇒ Object

Generate a vector. Calling this method will generate a vector in the output pattern based on the current pin states and timeset.



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/origen_testers/api.rb', line 208

def cycle(options = {})
  options = {
    microcode: '',
    timeset:   current_timeset,
    pin_vals:  current_pin_vals,
    repeat:    nil
  }.merge(options)

  if any_clocks_running?
    update_running_clocks
    if options[:repeat]
      slice_repeats(options).each do |slice|
        options[:repeat] = slice[0]
        delay(options.delete(:repeat), options) do |options|
          push_vector(options)
        end
        slice[1].each { |clock_pin_name| clocks_running[clock_pin_name].toggle_clock }
        options[:pin_vals] = current_pin_vals
      end
      pins_need_toggling.each { |clock_pin_name| clocks_running[clock_pin_name].toggle_clock }
    else
      push_vector(options)
      pins_need_toggling.each { |clock_pin_name| clocks_running[clock_pin_name].toggle_clock }
    end
  else
    if options[:repeat]
      delay(options.delete(:repeat), options) do |options|
        push_vector(options)
      end
    else
      push_vector(options)
    end
  end
end

#diff_friendly_output=(value) ⇒ Object



116
117
118
# File 'lib/origen_testers/api.rb', line 116

def diff_friendly_output=(value)
  @diff_friendly_output = value
end

#diff_friendly_output?Boolean Also known as: diff_friendly_output

Returns:

  • (Boolean)


120
121
122
# File 'lib/origen_testers/api.rb', line 120

def diff_friendly_output?
  !!@diff_friendly_output
end

#doc?Boolean

Returns:

  • (Boolean)


109
110
111
# File 'lib/origen_testers/api.rb', line 109

def doc?
  false
end

#generate?Boolean

Returns:

  • (Boolean)


35
36
37
# File 'lib/origen_testers/api.rb', line 35

def generate?
  true
end

#generating_pattern?Boolean

Returns:

  • (Boolean)


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

def generating_pattern?
  @generating == :pattern
end

#generating_program?Boolean

Returns:

  • (Boolean)


43
44
45
# File 'lib/origen_testers/api.rb', line 43

def generating_program?
  @generating == :program
end

#ignore_fails(*pins) ⇒ Object

Ignore fails on the given pins for the duration of the given block, this has the effect of temporarily setting the states of the given pins to don’t care.



128
129
130
131
132
# File 'lib/origen_testers/api.rb', line 128

def ignore_fails(*pins)
  pins.each(&:suspend)
  yield
  pins.each(&:resume)
end

#import_test_time(file, options = {}) ⇒ Object



243
244
245
# File 'lib/origen_testers/api.rb', line 243

def import_test_time(file, options = {})
  puts "Sorry but an importer doesn't exist for: #{Origen.tester.class}"
end

#inhibit_vectors_and_commentsObject

Allows a section to be run without actually generating any vectors. This can be useful to ensure the pin states end up as they otherwise would have if the section had been run. Classic example of this is a subroutine pattern, wrap this around a call to the startup routine to ensure the pin states are as they would have been immediately after the startup.

Example

# Setup state as if I had run startup without actually doing so
$tester.inhibit_vectors_and_comments do
    $soc.startup
    $top.startup
end


195
196
197
198
199
200
201
202
203
# File 'lib/origen_testers/api.rb', line 195

def inhibit_vectors_and_comments
  inhibit_vectors = @inhibit_vectors
  inhibit_comments = @inhibit_comments
  @inhibit_vectors = true
  @inhibit_comments = true
  yield
  @inhibit_vectors = inhibit_vectors      # Restore to their initial state
  @inhibit_comments = inhibit_comments
end

#is_command_based?Boolean

Returns:

  • (Boolean)


75
76
77
# File 'lib/origen_testers/api.rb', line 75

def is_command_based?
  !is_vector_based?
end

#is_vector_based?Boolean

Returns:

  • (Boolean)


70
71
72
73
# File 'lib/origen_testers/api.rb', line 70

def is_vector_based?
  return @vector_based if defined?(@vector_based)
  true
end

#j750?Boolean

Returns:

  • (Boolean)


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

def j750?
  is_a?(OrigenTesters::IGXLBasedTester::J750)
end

#j750_hpt?Boolean

Returns:

  • (Boolean)


88
89
90
# File 'lib/origen_testers/api.rb', line 88

def j750_hpt?
  is_a?(OrigenTesters::IGXLBasedTester::J750_HPT)
end

#link?Boolean

Returns:

  • (Boolean)


101
102
103
# File 'lib/origen_testers/api.rb', line 101

def link?
  !!(self.class.to_s =~ /^OrigenLink::/)
end

#nameObject



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

def name
  @name || self.class
end

#pat_extensionObject Also known as: pattern_extension



47
48
49
# File 'lib/origen_testers/api.rb', line 47

def pat_extension
  @pat_extension || 'txt'
end


63
64
# File 'lib/origen_testers/api.rb', line 63

def pattern_footer(*args)
end

#pattern_header(*args) ⇒ Object



60
61
# File 'lib/origen_testers/api.rb', line 60

def pattern_header(*args)
end

#pattern_section(msg) ⇒ Object



152
153
154
155
156
157
158
159
# File 'lib/origen_testers/api.rb', line 152

def pattern_section(msg)
  if generating_program?
    yield
  else
    step_comment(msg)
    yield
  end
end

#pins_need_togglingObject



298
299
300
301
302
303
304
# File 'lib/origen_testers/api.rb', line 298

def pins_need_toggling
  toggle_ary = []
  clocks_running.each do |name, clock_pin|
    toggle_ary.push("#{name}") if clock_pin.next_edge == cycle_count
  end
  toggle_ary
end

#pop_running_clock(pin) ⇒ Object



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

def pop_running_clock(pin)
  fail "ERROR: No clocks running, doesn't make sense to pop one" unless any_clocks_running?
  @clocks_running.delete(pin.name.to_s)
end

#program_comment_charObject



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

def program_comment_char
  @program_comment_char || comment_char
end

#push_running_clock(pin) ⇒ Object



256
257
258
# File 'lib/origen_testers/api.rb', line 256

def push_running_clock(pin)
  @clocks_running.nil? ? @clocks_running = { pin.name.to_s => pin } : @clocks_running[pin.name.to_s] = pin
end

#pxie6570?Boolean

Returns:

  • (Boolean)


105
106
107
# File 'lib/origen_testers/api.rb', line 105

def pxie6570?
  is_a?(OrigenTesters::LabVIEWBasedTester::Pxie6570)
end

#slice_repeats(options = {}) ⇒ Object



265
266
267
268
269
270
271
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
# File 'lib/origen_testers/api.rb', line 265

def slice_repeats(options = {})
  slices = {}
  repeat_ary = []
  clocks_running.each do |name, clock_pin|
    if clock_pin.next_edge < (cycle_count + options[:repeat])
      if clock_pin.respond_to?(:duty_cycles)
        d0, d1 = clock_pin.duty_cycles
      else
        # keep legacy support for older pin_clock styling, supports only 50% duty-cycle
        d0 = clock_pin.half_period
        d1 = clock_pin.half_period
      end
      pin_slices = (clock_pin.next_edge..(cycle_count + options[:repeat])).step(d0 + d1).to_a
      pin_slices += ((clock_pin.next_edge + d0)..(cycle_count + options[:repeat])).step(d0 + d1).to_a
      pin_slices.sort!
      pin_slices.insert(0, cycle_count)
    else
      pin_slices = [cycle_count]
    end
    pin_slices.each do |cycle|
      slices[cycle].nil? ? slices[cycle] = name : slices[cycle] = "#{slices[cycle]},#{name}"
    end
    slices[cycle_count + options[:repeat]] = '' if pin_slices[-1] != cycle_count + options[:repeat]
  end
  slices.keys.sort.each do |edge_cycles|
    # puts "Toggle #{slices[edge_cycles]} on #{edge_cycles}"
    repeat_ary.push([edge_cycles, slices[edge_cycles].split(',')])
  end

  (repeat_ary.count - 1).downto(1).each { |i| repeat_ary[i][0] = repeat_ary[i][0] - repeat_ary[i - 1][0] }
  repeat_ary[1..-1]
end

#snip(number, options = {}) ⇒ Object



181
182
183
# File 'lib/origen_testers/api.rb', line 181

def snip(number, options = {})
  yield
end

#source_memory(type = :default) ⇒ Object

Configure source memory to a non-default setting

This method changes the way the instruments statement gets rendered if the tester’s source memory is used.

If called without a block, this method will return the instance of type OrigenTesters::MemoryStyle for the corresponding memory type

Examples:

tester.source_memory :default do |mem|
  mem.pin :tdi, size: 32, format: :long
end
mem_style = tester.source_memory(:default)
mem_style.contained_pins.each do |pin|
  attributes_hash = mem_style.accumulate_attributes(pin)

end


345
346
347
348
349
350
351
352
353
# File 'lib/origen_testers/api.rb', line 345

def source_memory(type = :default)
  type = :subroutine if type == :default
  source_memory_config[type] = OrigenTesters::MemoryStyle.new unless source_memory_config.key?(type)
  if block_given?
    yield source_memory_config[type]
  else
    source_memory_config[type]
  end
end

#source_memory_configObject



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

def source_memory_config
  @source_memory_config ||= {}
end

#ss(msg = nil) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/origen_testers/api.rb', line 161

def ss(msg = nil)
  div = step_comment_prefix.length
  div = 1 if div == 0
  c1(step_comment_prefix * (70 / div))
  @step_comment_on = true
  if block_given?
    yield
  else
    c1(msg)
  end
  @step_comment_on = false
  if $_testers_enable_vector_comments
    timestamp = " #{execution_time_in_ns}ns #{step_comment_prefix}"
    str = step_comment_prefix * (70 / div)
    c1 str.sub(/#{step_comment_prefix}{#{timestamp.length - 1}}$/, timestamp)
  else
    c1(step_comment_prefix * (70 / div))
  end
end

#step_comment_prefixObject



66
67
68
# File 'lib/origen_testers/api.rb', line 66

def step_comment_prefix
  @step_comment_prefix || '##'
end

#stil?Boolean

Returns:

  • (Boolean)


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

def stil?
  defined?(OrigenTesters::StilBasedTester::Base) &&
    is_a?(OrigenTesters::StilBasedTester::Base)
end

#transactionObject



312
313
314
315
# File 'lib/origen_testers/api.rb', line 312

def transaction
  yield
  true
end

#ultraflex?Boolean Also known as: uflex?

Returns:

  • (Boolean)


96
97
98
# File 'lib/origen_testers/api.rb', line 96

def ultraflex?
  is_a?(OrigenTesters::IGXLBasedTester::UltraFLEX)
end

#update_running_clocksObject



306
307
308
309
310
# File 'lib/origen_testers/api.rb', line 306

def update_running_clocks
  clocks_running.each do |name, clock_pin|
    clock_pin.update_clock
  end
end

#v93k?Boolean

Returns:

  • (Boolean)


92
93
94
# File 'lib/origen_testers/api.rb', line 92

def v93k?
  is_a?(OrigenTesters::SmartestBasedTester::V93K)
end