Module: OrigenTesters::API

Included in:
Decompiler, VectorBasedTester
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


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

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


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

def overlay_style
  @overlay_style
end

Instance Method Details

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



138
139
# File 'lib/origen_testers/api.rb', line 138

def annotate(msg, options = {})
end

#any_clocks_running?Boolean

Returns:

  • (Boolean)


291
292
293
# File 'lib/origen_testers/api.rb', line 291

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


167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/origen_testers/api.rb', line 167

def c1(msg, options = {})
  PatSeq.add_thread(msg) unless options[:no_thread_id]
  prefix = comment_char + ' '
  prefix += step_comment_prefix + ' ' if @step_comment_on
  if Origen.tester.generating == :program
    cc_coms = OrigenTesters::Flow.cc_comments
    # cc call must be on line directly before test method
    line_number = caller_locations(2, 1)[0].lineno + 1
    unless cc_coms[line_number]
      cc_coms[line_number] = []
    end
    cc_coms[line_number] << msg
  else
    push_comment(prefix + msg.to_s)
  end
end

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



184
185
186
# File 'lib/origen_testers/api.rb', line 184

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


419
420
421
422
423
424
425
426
427
# File 'lib/origen_testers/api.rb', line 419

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



365
366
367
# File 'lib/origen_testers/api.rb', line 365

def capture_memory_config
  @capture_memory_config ||= {}
end

#clocks_runningObject Also known as: running_clocks



295
296
297
# File 'lib/origen_testers/api.rb', line 295

def clocks_running
  @clocks_running
end

#comment_charObject



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

def comment_char
  @comment_char || '//'
end

#comment_char=(val) ⇒ Object



54
55
56
# File 'lib/origen_testers/api.rb', line 54

def comment_char=(val)
  @comment_char = val
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.



244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
# File 'lib/origen_testers/api.rb', line 244

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

  unless timeset.period_in_ns?
    fail "You must supply a period_in_ns to timeset '#{timeset.name}' before you can cycle the tester!"
  end
  timeset.cycled = true
  if PatSeq.thread
    PatSeq.thread.cycle(options)
  else
    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
end

#d10?Boolean

Returns:

  • (Boolean)


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

def d10?
  is_a?(OrigenTesters::StilBasedTester::D10)
end

#diff_friendly_output=(value) ⇒ Object



141
142
143
# File 'lib/origen_testers/api.rb', line 141

def diff_friendly_output=(value)
  @diff_friendly_output = value
end

#diff_friendly_output?Boolean Also known as: diff_friendly_output

Returns:

  • (Boolean)


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

def diff_friendly_output?
  !!@diff_friendly_output
end

#doc?Boolean

Returns:

  • (Boolean)


126
127
128
# File 'lib/origen_testers/api.rb', line 126

def doc?
  false
end

#generate?Boolean

Returns:

  • (Boolean)


37
38
39
# File 'lib/origen_testers/api.rb', line 37

def generate?
  true
end

#generating_pattern?Boolean

Returns:

  • (Boolean)


41
42
43
# File 'lib/origen_testers/api.rb', line 41

def generating_pattern?
  @generating == :pattern
end

#generating_program?Boolean

Returns:

  • (Boolean)


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

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.



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

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

#igxl?Boolean

Returns:

  • (Boolean)


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

def igxl?
  j750? || j750_hpt? || ultraflex?
end

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



287
288
289
# File 'lib/origen_testers/api.rb', line 287

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


231
232
233
234
235
236
237
238
239
# File 'lib/origen_testers/api.rb', line 231

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)


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

def is_command_based?
  !is_vector_based?
end

#is_vector_based?Boolean

Returns:

  • (Boolean)


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

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

#j750?Boolean

Returns:

  • (Boolean)


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

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

#j750_hpt?Boolean

Returns:

  • (Boolean)


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

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

#link?Boolean

Returns:

  • (Boolean)


118
119
120
# File 'lib/origen_testers/api.rb', line 118

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

#nameObject



33
34
35
# File 'lib/origen_testers/api.rb', line 33

def name
  @name || self.class
end

#pat_extensionObject Also known as: pattern_extension



49
50
51
# File 'lib/origen_testers/api.rb', line 49

def pat_extension
  @pat_extension || 'txt'
end


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

def pattern_footer(*args)
end

#pattern_header(*args) ⇒ Object



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

def pattern_header(*args)
end

#pattern_section(msg) ⇒ Object



188
189
190
191
192
193
194
195
# File 'lib/origen_testers/api.rb', line 188

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

#pins_need_togglingObject



342
343
344
345
346
347
348
# File 'lib/origen_testers/api.rb', line 342

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



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

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



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

def program_comment_char
  @program_comment_char || comment_char
end

#program_comment_char=(val) ⇒ Object



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

def program_comment_char=(val)
  @program_comment_char = val
end

#push_running_clock(pin) ⇒ Object



300
301
302
# File 'lib/origen_testers/api.rb', line 300

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)


122
123
124
# File 'lib/origen_testers/api.rb', line 122

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

#slice_repeats(options = {}) ⇒ Object



309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
# File 'lib/origen_testers/api.rb', line 309

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

#smt7?Boolean

Returns:

  • (Boolean)


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

def smt7?
  v93k? && smt_version.to_s[0] == '7'
end

#smt8?Boolean

Returns:

  • (Boolean)


134
135
136
# File 'lib/origen_testers/api.rb', line 134

def smt8?
  v93k? && smt_version.to_s[0] == '8'
end

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



217
218
219
# File 'lib/origen_testers/api.rb', line 217

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


389
390
391
392
393
394
395
396
397
# File 'lib/origen_testers/api.rb', line 389

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



361
362
363
# File 'lib/origen_testers/api.rb', line 361

def source_memory_config
  @source_memory_config ||= {}
end

#ss(msg = nil) ⇒ Object



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/origen_testers/api.rb', line 197

def ss(msg = nil)
  div = step_comment_prefix.length
  div = 1 if div == 0
  c1(step_comment_prefix * (70 / div), no_thread_id: true)
  @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), no_thread_id: true)
  else
    c1(step_comment_prefix * (70 / div), no_thread_id: true)
  end
end

#step_comment_prefixObject



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

def step_comment_prefix
  @step_comment_prefix || '##'
end

#stil?Boolean

Returns:

  • (Boolean)


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

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

#transactionObject



356
357
358
359
# File 'lib/origen_testers/api.rb', line 356

def transaction
  yield
  true
end

#ultraflex?Boolean Also known as: uflex?

Returns:

  • (Boolean)


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

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

#update_running_clocksObject



350
351
352
353
354
# File 'lib/origen_testers/api.rb', line 350

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

#v93k?Boolean

Returns:

  • (Boolean)


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

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