Class: OrigenTesters::IGXLBasedTester::J750
- 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
Defined Under Namespace
Modules: Generator Classes: CustomTestInstance, Flow, FlowLine, Patgroup, Patgroups, Patset, PatsetPattern, Patsets, Patsubr, PatsubrPattern, Patsubrs, TestInstance, TestInstanceGroup, TestInstances
Instance Attribute Summary collapse
-
#software_version ⇒ Object
Returns the value of attribute software_version.
-
#use_hv_pin ⇒ Object
Returns the value of attribute use_hv_pin.
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
-
#handshake(options = {}) ⇒ Object
Handshake with the tester.
-
#initialize(options = {}) ⇒ J750
constructor
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.
- #keep_alive(options = {}) ⇒ Object
-
#match_block(timeout, options = {}, &block) ⇒ Object
Generates a match loop based on vector condition passed in via block.
- #pattern_footer(options = {}) ⇒ Object
- #pattern_header(options = {}) ⇒ Object
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
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( = {}) super() @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_version ⇒ Object
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_pin ⇒ Object
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_mode ⇒ Object
20 21 22 |
# File 'lib/origen_testers/igxl_based_tester/j750.rb', line 20 def self.hpt_mode @@hpt_mode end |
.hpt_mode? ⇒ 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( = {}) = { readcode: false, manual_stop: false, # set a 2nd CPU flag in case 1st flag is automatically cleared }.merge() if [:readcode] set_code([:readcode]) end if [: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( = {}) $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, = {}, &block) = { 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() 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 [:check_for_fails] if [: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: [:manual_stop]) end # Now do the main match loop cc 'Start the match loop' global_opt = ([: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 [: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 [:on_timeout_goto] cycle(microcode: "jump #{[: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 [:on_block_match_goto] if [:on_block_match_goto].is_a?(Hash) if [:on_block_match_goto][i] custom_jump = [:on_block_match_goto][i] else custom_jump = nil end else custom_jump = [: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 [: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 |
#pattern_footer(options = {}) ⇒ Object
56 57 58 |
# File 'lib/origen_testers/igxl_based_tester/j750.rb', line 56 def ( = {}) super() 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( = {}) super() do |pin_list| microcode "vector ($tset, #{pin_list})" microcode '{' unless [:subroutine_pat] microcode 'start_label pattern_st:' end end end |