Class: OrigenTesters::IGXLBasedTester::J750

Inherits:
Base
  • Object
show all
Defined in:
lib/origen_testers/igxl_based_tester/j750.rb,
lib/origen_testers/igxl_based_tester/j750/flow.rb,
lib/origen_testers/igxl_based_tester/j750/patset.rb,
lib/origen_testers/igxl_based_tester/j750/patsets.rb,
lib/origen_testers/igxl_based_tester/j750/patsubr.rb,
lib/origen_testers/igxl_based_tester/j750/patgroup.rb,
lib/origen_testers/igxl_based_tester/j750/patsubrs.rb,
lib/origen_testers/igxl_based_tester/j750/flow_line.rb,
lib/origen_testers/igxl_based_tester/j750/generator.rb,
lib/origen_testers/igxl_based_tester/j750/patgroups.rb,
lib/origen_testers/igxl_based_tester/j750/test_instance.rb,
lib/origen_testers/igxl_based_tester/j750/patset_pattern.rb,
lib/origen_testers/igxl_based_tester/j750/test_instances.rb,
lib/origen_testers/igxl_based_tester/j750/patsubr_pattern.rb,
lib/origen_testers/igxl_based_tester/j750/test_instance_group.rb,
lib/origen_testers/igxl_based_tester/j750/custom_test_instance.rb

Overview

Tester model to generate .atp patterns for the Teradyne J750

Basic Usage

$tester = Testers::J750.new
$tester.cycle       # Generate a vector

Many more methods exist to generate J750 specific micro-code, see below for details.

Also note that this class inherits from the base Tester class and so all methods described there are also available.

Direct Known Subclasses

J750_HPT

Defined Under Namespace

Modules: Generator Classes: CustomTestInstance, Flow, FlowLine, Patgroup, Patgroups, Patset, PatsetPattern, Patsets, Patsubr, PatsubrPattern, Patsubrs, TestInstance, TestInstanceGroup, TestInstances

Instance Attribute Summary collapse

Attributes inherited from Base

#channelmap, #default_channelmap, #default_testerconfig, #literal_enables, #literal_flags, #max_site, #memory_test_en, #min_repeat_loop, #pattern_compiler_pinmap, #testerconfig

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#apply_digcap_settings, #apply_digsrc_settings, #assign_dc_instr_pins, #assign_digcap_pins, #assign_digsrc_pins, #branch_to, #call_match, #call_subroutine, #called_subroutines, #cycle, #digcap_store, #digsrc_overlay, #digsrc_send, #digsrc_skip_start, #digsrc_start, #digsrc_stop, #enable_flag, #end_subroutine, #flows, #format_multiple_instrument_pins, #format_vector, #freq_count, #get_dc_instr_pins, #get_digcap_pins, #get_digsrc_pins, #get_instrument_slots, #get_tester_channel, #get_tester_instrument, #ignore_fails, #igxl_based?, #import_chanmap, #import_tester_config, #is_hexvs_plus, #is_vhdvs_hc, #is_vhdvs_plus, #label, #local_subroutines, #loop_vectors, #mask_fails, #match, #memory_test, #merged_channels, #overlay_style_warn, #parser, #push_instrument, #push_microcode, #remove_store_from_vector, #repeat_previous, #set_code, #set_flag, #start_subroutine, #store, #store_next_cycle, #subroutine_overlay

Methods included from VectorBasedTester

#register_tester

Constructor Details

#initialize(options = {}) ⇒ J750

Returns a new J750 instance, normally there would only ever be one of these assigned to the global variable such as $tester by your target.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/origen_testers/igxl_based_tester/j750.rb', line 29

def initialize(options = {})
  super(options)
  @pipeline_depth = 34  # for extended mode is vectors, for normal mode is vector pairs (54 for J750Ex)
  @use_hv_pin = false   # allows to use high voltage for a pin for all patterns
  @software_version = '3.50.40'
  @name = 'j750'
  @@hpt_mode = false
  @opcode_mode = :extended
  @loop_bits_max = 16             # maximum loop bit length

  @flags = %w(cpuA cpuB cpuC cpuD)
  @microcode[:enable] = 'enable'
  @microcode[:set_flag] = 'set_cpu'
  @microcode[:mask_vector] = 'ign ifc icc'
  @microcode[:keepalive] = 'keep_alive'
end

Instance Attribute Details

#software_versionObject

Returns the value of attribute software_version.



18
19
20
# File 'lib/origen_testers/igxl_based_tester/j750.rb', line 18

def software_version
  @software_version
end

#use_hv_pinObject

Returns the value of attribute use_hv_pin.



17
18
19
# File 'lib/origen_testers/igxl_based_tester/j750.rb', line 17

def use_hv_pin
  @use_hv_pin
end

Class Method Details

.hpt_modeObject



20
21
22
# File 'lib/origen_testers/igxl_based_tester/j750.rb', line 20

def self.hpt_mode
  @@hpt_mode
end

.hpt_mode?Boolean

Returns:

  • (Boolean)


23
24
25
# File 'lib/origen_testers/igxl_based_tester/j750.rb', line 23

def self.hpt_mode?
  @@hpt_mode
end

Instance Method Details

#handshake(options = {}) ⇒ Object

Handshake with the tester.

Will set a cpu flag (A) and wait for it to be cleared by the tester, optionally pass in a read code to pass information to the tester.

Examples

$tester.handshake                   # Pass control to the tester for a measurement
$tester.handshake(:readcode => 10)  # Trigger a specific action by the tester


245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/origen_testers/igxl_based_tester/j750.rb', line 245

def handshake(options = {})
  options = {
    readcode:    false,
    manual_stop: false,    # set a 2nd CPU flag in case 1st flag is automatically cleared
  }.merge(options)
  if options[:readcode]
    set_code(options[:readcode])
  end
  if options[:manual_stop]
    cycle(microcode: "#{@microcode[:enable]} (#{@flags[1]})")
    cycle(microcode: "#{@microcode[:set_flag]} (#{@flags[0]} #{@flags[1]})")
    cycle(microcode: "loop_here_#{@unique_counter}: if (flag) jump loop_here_#{@unique_counter}")
  else
    cycle(microcode: "#{@microcode[:set_flag]} (#{@flags[0]})")
    cycle(microcode: "loop_here_#{@unique_counter}: if (#{@flags[0]}) jump loop_here_#{@unique_counter}")
  end
  @unique_counter += 1  # Increment so a different label will be applied if another
  # handshake is called in the same pattern
end

#keep_alive(options = {}) ⇒ Object



265
266
267
# File 'lib/origen_testers/igxl_based_tester/j750.rb', line 265

def keep_alive(options = {})
  $tester.cycle microcode: "#{@microcode[:keepalive]}"
end

#match_block(timeout, options = {}, &block) ⇒ Object

Generates a match loop based on vector condition passed in via block

This method is not really intended to be called directly, rather you should call via Tester#wait:

e.g. $tester.wait(:match => true) do
       reg(:status_reg).bit(:done).read(1)!  # vector condition that you want to match
     end

The timeout should be provided in cycles, however when called via the wait method the time-based helpers (time_in_us, etc) will be converted to cycles for you.

The following options are available to tailor the match loop behavior, defaults in parenthesis:

  • :check_for_fails (false) - Flushes the pipeline and handshakes with the tester (passing readcode 100) prior to the match (to allow binout of fails encountered before the match)

  • :force_fail_on_timeout (true) - Force a vector mis-compare if the match loop times out

  • :on_timeout_goto (“”) - Optionally supply a label to branch to on timeout, by default will continue from the end of the match loop

  • :on_block_match_goto (“”) - Optionally supply a label to branch to when block condition is met, by default will continue from the end of the match loop. A hash will also be accepted for this argument to supply a specific label (or no label) for each block e.g. {0 => "on_block_0_fail"}

  • :multiple_entries (false) - Supply an integer to generate multiple entries into the match (each with a unique readcode), this can be useful when debugging patterns with multiple matches

  • :force_fail_on_timeout (true) - force pattern to fail if timeout occurs

  • :global_loops (false) - whether match loop loops should use global labels

  • :manual_stop (false) - whether to use extra cpuB flag to resolve IG-XL v.3.50.xx bug where VBT clears cpuA immediately

    at start of PatFlagFunc instead of at end.  Use will have to manually clear cpuB to resume this pattern.
    

Examples

$tester.wait(:match => true, :time_in_us => 5000, :pin => $top.pin(:done), :state => :high) do
  <vectors>
end


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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
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
# File 'lib/origen_testers/igxl_based_tester/j750.rb', line 87

def match_block(timeout, options = {}, &block)
  options = {
    check_for_fails:       false,
    on_timeout_goto:       false,
    on_block_match_goto:   false,
    multiple_entries:      false,
    force_fail_on_timeout: true,
    global_loops:          false,
    manual_stop:           false,
    clr_fail_post_match:   false
  }.merge(options)

  unless block_given?
    fail 'ERROR: block not passed to match_block!'
  end

  # Create BlockArgs objects in order to receive multiple blocks
  match_conditions = Origen::Utility::BlockArgs.new
  fail_conditions = Origen::Utility::BlockArgs.new

  # yield object to calling routine to get populated with blocks
  if block.arity > 0
    yield match_conditions, fail_conditions
  else
    # for backwards compatibility with Origen core call to match_block
    match_conditions.add(&block)
    fail_conditions.add(&block)
  end

  # Flush the pipeline first and then pass control to the program to bin out any failures
  # prior to entering the match loop
  if options[:check_for_fails]
    if options[:multiple_entries]
      @match_entries.times do |i|
        microcode "global subr match_done_#{i}:"
        set_code(i + 100)
        cycle(microcode: 'jump call_tester') unless i == @match_entries - 1
      end
      microcode 'call_tester:'
    else
      set_code(100)
    end
    cc 'Wait for any prior failures to propagate through the pipeline'
    cycle(microcode: 'pipe_minus 1')
    cc 'Now handshake with the tester to bin out and parts that have failed before they got here'
    handshake(manual_stop: options[:manual_stop])
  end

  # Now do the main match loop
  cc 'Start the match loop'

  global_opt = (options[:global_loops]) ? 'global ' : ''
  microcode "#{global_opt}match_outer_loop_#{@unique_counter}:"
  cycle # (:microcode => "loopB #{outer_loop_count} ign ifc icc")
  set_loopb_vector = last_vector

  microcode "#{global_opt}match_inner_loop_#{@unique_counter}:"
  cycle # (:microcode => "loopA #{inner_loop_count} ign ifc icc")
  set_loopa_vector = last_vector

  # count cycles in match loop block passed to help with meeting
  # desired timeout value (have to back assign microcodes above)
  prematch_cycle_count = cycle_count
  match_conditions.each_with_index do |condition, i|
    mask_fails(true)
    condition.call  # match condition
    mask_fails(false)
    cc ' Wait for the result to propagate through the pipeline'
    cycle(microcode: 'pipe_minus 1 ign ifc icc')
    inc_cycle_count(@pipeline_depth - 1)                   # Account for pipeline depth
    cc "Branch if block condition #{i} met"
    cycle(microcode: "if (pass) jump block_#{i}_matched_#{@unique_counter} icc ifc")
    cycle(microcode: 'clr_flag (fail) icc')
  end
  match_conditions_cycle_count = cycle_count - prematch_cycle_count
  cc "Match loop cycle count = #{match_conditions_cycle_count}"

  # reduce timeout requested by match loop cycle count
  timeout = (timeout.to_f / match_conditions_cycle_count).ceil

  # Calculate the loop counts for the 2 loops to appropriately hit the timeout requested
  loop_value = timeout.to_f.floor

  if loop_value < (2**@loop_bits_max)
    # small value, only need to use one loop
    outer_loop_count = 1
    inner_loop_count = loop_value
  elsif loop_value < (2**(2 * @loop_bits_max))
    # 2 nested loops required
    inner_loop_count = 2**@loop_bits_max - 1
    outer_loop_count = (loop_value.to_f / inner_loop_count).ceil
  else
    abort 'ERROR: timeout value too large in tester match method!'
  end

  # retroactively set loop counter values for timeout based on cycles in match loop condition
  unless @inhibit_vectors
    set_loopb_vector.microcode = "loopB #{outer_loop_count} ign ifc icc"
    set_loopa_vector.microcode = "loopA #{inner_loop_count} ign ifc icc"
  end

  cc 'Loop back around if time remaining'
  cycle(microcode: "end_loopA match_inner_loop_#{@unique_counter} icc")
  cycle(microcode: "end_loopB match_outer_loop_#{@unique_counter} icc")

  if options[:force_fail_on_timeout]
    cc 'To get here something has gone wrong, check block again to force a pattern failure'
    fail_conditions.each(&:call)
  end

  if options[:on_timeout_goto]
    cycle(microcode: "jump #{options[:on_timeout_goto]} icc")
  else
    cycle(microcode: "jump match_loop_end_#{@unique_counter} icc")
    # cycle(:microcode => 'halt')
  end
  match_conditions.each_with_index do |condition, i|
    microcode "block_#{i}_matched_#{@unique_counter}:"
    cycle(microcode: 'pop_loop icc')
    cycle(microcode: 'clr_fail')
    if options[:on_block_match_goto]
      if options[:on_block_match_goto].is_a?(Hash)
        if options[:on_block_match_goto][i]
          custom_jump = options[:on_block_match_goto][i]
        else
          custom_jump = nil
        end
      else
        custom_jump = options[:on_block_match_goto]
      end
    end
    if custom_jump
      cycle(microcode: "jump #{custom_jump}")
    else
      # Don't do a jump on the last match block as it will naturally fall through
      # TODO: Update origen core to expose the size
      unless match_conditions.instance_variable_get(:@block_args).size == i + 1
        cycle(microcode: "jump match_loop_end_#{@unique_counter} icc")
      end
    end
  end
  microcode "match_loop_end_#{@unique_counter}:"
  if options[:clr_fail_post_match]
    cycle(microcode: 'clr_fail')
  end

  @unique_counter += 1  # Increment so a different label will be applied if another
  # handshake is called in the same pattern
end


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

def pattern_footer(options = {})
  super(options)
end

#pattern_header(options = {}) ⇒ Object



46
47
48
49
50
51
52
53
54
# File 'lib/origen_testers/igxl_based_tester/j750.rb', line 46

def pattern_header(options = {})
  super(options) do |pin_list|
    microcode "vector ($tset, #{pin_list})"
    microcode '{'
    unless options[:subroutine_pat]
      microcode 'start_label pattern_st:'
    end
  end
end