Class: OrigenTesters::SmartestBasedTester::Base
- Inherits:
-
Object
- Object
- OrigenTesters::SmartestBasedTester::Base
- Includes:
- VectorBasedTester
- Defined in:
- lib/origen_testers/smartest_based_tester/base.rb,
lib/origen_testers/smartest_based_tester/base/flow.rb,
lib/origen_testers/smartest_based_tester/base/generator.rb,
lib/origen_testers/smartest_based_tester/base/test_suite.rb,
lib/origen_testers/smartest_based_tester/base/limits_file.rb,
lib/origen_testers/smartest_based_tester/base/test_method.rb,
lib/origen_testers/smartest_based_tester/base/test_suites.rb,
lib/origen_testers/smartest_based_tester/base/test_methods.rb,
lib/origen_testers/smartest_based_tester/base/pattern_master.rb,
lib/origen_testers/smartest_based_tester/base/variables_file.rb,
lib/origen_testers/smartest_based_tester/base/pattern_compiler.rb,
lib/origen_testers/smartest_based_tester/base/test_methods/ac_tml.rb,
lib/origen_testers/smartest_based_tester/base/test_methods/dc_tml.rb,
lib/origen_testers/smartest_based_tester/base/test_methods/limits.rb,
lib/origen_testers/smartest_based_tester/base/test_methods/base_tml.rb,
lib/origen_testers/smartest_based_tester/base/test_methods/custom_tml.rb,
lib/origen_testers/smartest_based_tester/base/processors/extract_bin_names.rb,
lib/origen_testers/smartest_based_tester/base/processors/extract_flow_vars.rb
Defined Under Namespace
Modules: Generator, Processors Classes: Flow, LimitsFile, PatternCompiler, PatternMaster, TestMethod, TestMethods, TestSuite, TestSuites, VariablesFile
Instance Attribute Summary collapse
-
#add_flow_enable ⇒ Object
Returns whether the tester has been configured to wrap top-level flow modules with an enable or not.
-
#create_limits_file ⇒ Object
When set to true, all test flows will be generated with a corresponding testtable limits file, rather than having the limits attached inline to the test suites.
-
#delayed_binning ⇒ Object
When set to true, tests will be set to delayed binning by default (overon = on) unless delayed: false is supplied when defining the test.
-
#force_pass_on_continue ⇒ Object
When set to true, tests which are marked with continue: true will be forced to pass in generated test program flows.
-
#inline_comments ⇒ Object
Disable inline (end of vector) comments, enabled by default.
-
#limitfile_test_modes ⇒ Object
Returns an array of strings that indicate which test modes will be included in limits files, by default returns an empty array.
-
#min_repeat_loop ⇒ Object
(also: #min_repeat_count)
permit modification of minimum repeat count.
-
#multiport ⇒ Object
(also: #multi_port)
permit option to generate multiport type patterns and use multiport type code.
-
#multiport_postfix ⇒ Object
multiport burst name postfix.
-
#multiport_prefix ⇒ Object
multiport burst name prefix.
-
#package_namespace ⇒ Object
Returns the package namespace that all generated test collateral should be placed under, defaults to the application’s namespace if not defined.
-
#separate_bins_file ⇒ Object
When set to true, the bins and softbins sheets from the limits spreadsheet will be written out to a standalone (spreadsheet) file instead (SMT8 only).
-
#smt_version ⇒ Object
readonly
Returns the SMT version, defaults to 7.
-
#unique_test_names ⇒ Object
readonly
Returns the value defined at target-level on if/how to make test names unique within a flow, the default value is :signature.
-
#zip_patterns ⇒ Object
When set to true (the default), patterns will be generated in ZIP format instead of ASCII format (SMT8 only).
Instance Method Summary collapse
- #before_timeset_change(options = {}) ⇒ Object
-
#call_subroutine(name, options = {}) ⇒ Object
Call a subroutine.
-
#called_subroutines ⇒ Object
Returns an array of subroutines called while generating the current pattern.
- #cycle(options = {}) ⇒ Object
- #disable_pattern_diffs ⇒ Object
-
#end_subroutine(_cond = false) ⇒ Object
Ends the current subroutine that was started with a previous call to start_subroutine.
-
#freq_count(_pin, options = {}) ⇒ Object
Do a frequency measure.
-
#handshake(options = {}) ⇒ Object
Handshake with the tester.
-
#initialize(options = {}) ⇒ Base
constructor
A new instance of Base.
-
#local_subroutines ⇒ Object
Returns an array of subroutines created by the current pattern.
-
#loop_vectors(name = nil, number_of_loops = 1, _global = false) ⇒ Object
(also: #loop_vector)
Add a loop to the pattern.
-
#match(pin, state, timeout_in_cycles, options = {}) ⇒ Object
Generates a match loop on up to two pins.
- #match_block(timeout_in_cycles, options = {}, &block) ⇒ Object
-
#multiport_name(patt_name) ⇒ Object
return the multiport burst name provide the name you want to obtain multiport for.
-
#overlay_style_warn(overlay_str, options) ⇒ Object
Warn user of unsupported overlay style.
-
#pattern_footer(options = {}) ⇒ Object
An internal method called by Origen to generate the pattern footer.
-
#pattern_header(options = {}) ⇒ Object
An internal method called by Origen to create the pattern header.
-
#propagation_delay ⇒ Object
Returns the number of cycles to wait for any fails to propagate through the pipeline based on the current timeset.
-
#repeat_previous ⇒ Object
All vectors generated with the supplied block will have all pins set to the repeat previous state.
-
#start_subroutine(name) ⇒ Object
Start a subroutine.
-
#store(*pins) ⇒ Object
(also: #capture)
Capture the pin data from a vector to the tester.
-
#store_next_cycle(*pins) ⇒ Object
(also: #store!)
Same as the store method, except that the capture will be applied to the next vector to be generated.
-
#subroutine_overlay(sub_name, options = {}) ⇒ Object
Implement subroutine overlay, called by tester.cycle.
Methods included from VectorBasedTester
Constructor Details
#initialize(options = {}) ⇒ Base
Returns a new instance of Base.
73 74 75 76 77 78 79 80 81 82 83 84 85 86 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 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 73 def initialize( = {}) = { # whether to use multiport bursts or not, if so this indicates the name of the port to use multiport: false, multiport_prefix: false, multiport_postfix: false }.merge() @smt_version = [:smt_version] || 7 @separate_bins_file = [:separate_bins_file] || false if .key?(:zip_patterns) @zip_patterns = .delete(:zip_patterns) else @zip_patterns = true end if smt8? require_relative 'smt8' extend SMT8 else require_relative 'smt7' extend SMT7 end @max_repeat_loop = 65_535 @min_repeat_loop = 33 if smt8? @pat_extension = 'pat' @program_comment_char = ['println', '//'] else @pat_extension = 'avc' @program_comment_char = ['print_dl', '//'] end @compress = true # @support_repeat_previous = true @match_entries = 10 @name = 'v93k' @comment_char = '#' @level_period = true @inline_comments = true @multiport = [:multiport] @multiport_prefix = [:multiport_prefix] @multiport_postfix = [:multiport_postfix] @overlay_style = :subroutine # default to use subroutine for overlay @capture_style = :hram # default to use hram for capture @overlay_subr = nil @overlay_history = {} # used to track labels, subroutines, digsrc pins used etc if [:add_flow_enable] self.add_flow_enable = [:add_flow_enable] end if .key?(:unique_test_names) @unique_test_names = [:unique_test_names] else if smt8? @unique_test_names = nil else @unique_test_names = :signature end end if smt8? @create_limits_file = true else if .key?(:create_limits_file) @create_limits_file = [:create_limits_file] else @create_limits_file = false end end @package_namespace = .delete(:package_namespace) self.limitfile_test_modes = [:limitfile_test_modes] || [:limitsfile_test_modes] self.force_pass_on_continue = [:force_pass_on_continue] self.delayed_binning = [:delayed_binning] end |
Instance Attribute Details
#add_flow_enable ⇒ Object
Returns whether the tester has been configured to wrap top-level flow modules with an enable or not.
Returns nil if not.
Returns :enabled if the enable is configured to be on by default, or :disabled if it is configured to be off by default.
16 17 18 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 16 def add_flow_enable @add_flow_enable end |
#create_limits_file ⇒ Object
When set to true, all test flows will be generated with a corresponding testtable limits file, rather than having the limits attached inline to the test suites
40 41 42 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 40 def create_limits_file @create_limits_file end |
#delayed_binning ⇒ Object
When set to true, tests will be set to delayed binning by default (overon = on) unless delayed: false is supplied when defining the test
59 60 61 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 59 def delayed_binning @delayed_binning end |
#force_pass_on_continue ⇒ Object
When set to true, tests which are marked with continue: true will be forced to pass in generated test program flows. Flow branching based on the test result will be handled via some other means to give the same flow if the test ‘fails’, however the test will always appear as if it passed for data logging purposes.
Testers which do not implement this option will ignore it.
55 56 57 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 55 def force_pass_on_continue @force_pass_on_continue end |
#inline_comments ⇒ Object
Disable inline (end of vector) comments, enabled by default
7 8 9 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 7 def inline_comments @inline_comments end |
#limitfile_test_modes ⇒ Object
Returns an array of strings that indicate which test modes will be included in limits files, by default returns an empty array. If no test modes have been specified then the limits file will simply be generated with no test modes.
46 47 48 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 46 def limitfile_test_modes @limitfile_test_modes end |
#min_repeat_loop ⇒ Object Also known as: min_repeat_count
permit modification of minimum repeat count
26 27 28 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 26 def min_repeat_loop @min_repeat_loop end |
#multiport ⇒ Object Also known as: multi_port
permit option to generate multiport type patterns and use multiport type code
32 33 34 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 32 def multiport @multiport end |
#multiport_postfix ⇒ Object
multiport burst name postfix
36 37 38 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 36 def multiport_postfix @multiport_postfix end |
#multiport_prefix ⇒ Object
multiport burst name prefix
35 36 37 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 35 def multiport_prefix @multiport_prefix end |
#package_namespace ⇒ Object
Returns the package namespace that all generated test collateral should be placed under, defaults to the application’s namespace if not defined
155 156 157 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 155 def package_namespace @package_namespace || Origen.app.namespace end |
#separate_bins_file ⇒ Object
When set to true, the bins and softbins sheets from the limits spreadsheet will be written out to a standalone (spreadsheet) file instead (SMT8 only)
67 68 69 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 67 def separate_bins_file @separate_bins_file end |
#smt_version ⇒ Object (readonly)
Returns the SMT version, defaults to 7
23 24 25 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 23 def smt_version @smt_version end |
#unique_test_names ⇒ Object (readonly)
Returns the value defined at target-level on if/how to make test names unique within a flow, the default value is :signature
20 21 22 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 20 def unique_test_names @unique_test_names end |
#zip_patterns ⇒ Object
When set to true (the default), patterns will be generated in ZIP format instead of ASCII format (SMT8 only)
71 72 73 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 71 def zip_patterns @zip_patterns end |
Instance Method Details
#before_timeset_change(options = {}) ⇒ Object
728 729 730 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 728 def before_timeset_change( = {}) microcode "SQPG CTIM #{[:new].name};" unless level_period? end |
#call_subroutine(name, options = {}) ⇒ Object
Call a subroutine.
This calls a subroutine immediately following previous vector, it does not generate a new vector.
Subroutines should always be called through this method as it ensures a running log of called subroutines is maintained and which then gets output in the pattern header to import the right dependencies.
An offset option is available to make the call on earlier vectors.
Repeated calls to the same subroutine will automatically be compressed unless option :suppress_repeated_calls is supplied and set to false. This means that for the common use case of calling a subroutine to implement an overlay the subroutine can be called for every bit that has the overlay and the pattern will automatically generate correctly.
Examples
$tester.call_subroutine("mysub")
$tester.call_subroutine("my_other_sub", :offset => -1)
404 405 406 407 408 409 410 411 412 413 414 415 416 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 404 def call_subroutine(name, = {}) = { offset: 0, suppress_repeated_calls: true }.merge() called_subroutines << name.to_s.chomp unless called_subroutines.include?(name.to_s.chomp) || @inhibit_vectors code = "SQPG JSUB #{name};" if ![:suppress_repeated_calls] || last_object != code microcode code, offset: ([:offset] * -1) end end |
#called_subroutines ⇒ Object
Returns an array of subroutines called while generating the current pattern
701 702 703 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 701 def called_subroutines @called_subroutines ||= [] end |
#cycle(options = {}) ⇒ Object
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 236 237 238 239 240 241 242 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 197 def cycle( = {}) # handle overlay if requested ovly_style = nil if .key?(:overlay) ovly_style = [:overlay][:overlay_style].nil? ? @overlay_style : [:overlay][:overlay_style] = [:overlay][:overlay_str] # route the overlay request to the appropriate method case ovly_style when :subroutine, :default (, ) ovly_style = :subroutine when :label, :global_label [:dont_compress] = true unless @overlay_history.key?() cc "#{}" @overlay_history[] = { is_label: true } end when :handshake if @delayed_handshake if @delayed_handshake != handshake @delayed_handshake = end else @delayed_handshake = end else ovly_style = ([:overlay][:overlay_str], ) end # case ovly_style else handshake if @delayed_handshake @delayed_handshake = nil @overlay_subr = nil end # of handle overlay = .delete(:overlay) if .key?(:overlay) unless ovly_style == :subroutine || ovly_style == :handshake super() end unless .nil? # stage = :body if ovly_style == :subroutine # always set stage back to body in case subr overlay was selected end end |
#disable_pattern_diffs ⇒ Object
149 150 151 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 149 def disable_pattern_diffs smt8? && zip_patterns end |
#end_subroutine(_cond = false) ⇒ Object
Ends the current subroutine that was started with a previous call to start_subroutine
380 381 382 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 380 def end_subroutine(_cond = false) ::Pattern.close call_shutdown_callbacks: false, subroutine: true end |
#freq_count(_pin, options = {}) ⇒ Object
Do a frequency measure.
Examples
$tester.freq_count($top.pin(:d_out)) # Freq measure on pin "d_out"
432 433 434 435 436 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 432 def freq_count(_pin, = {}) = { }.merge() ::Pattern.split() end |
#handshake(options = {}) ⇒ Object
Handshake with the tester.
Examples
$tester.handshake # Pass control to the tester for a measurement
422 423 424 425 426 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 422 def handshake( = {}) = { }.merge() ::Pattern.split() end |
#local_subroutines ⇒ Object
Returns an array of subroutines created by the current pattern
706 707 708 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 706 def local_subroutines # :nodoc: @local_subroutines ||= [] end |
#loop_vectors(name = nil, number_of_loops = 1, _global = false) ⇒ Object Also known as: loop_vector
Add a loop to the pattern.
Pass in the number of times to execute it, all vectors generated by the given block will be captured in the loop.
Examples
$tester.loop_vectors 3 do # Do this 3 times...
$tester.cycle
some_other_method_to_generate_vectors
end
For compatibility with the J750 you can supply a name as the first argument and that will simply be ignored when generated for the V93K tester…
$tester.loop_vectors "my_loop", 3 do # Do this 3 times...
$tester.cycle
some_other_method_to_generate_vectors
end
642 643 644 645 646 647 648 649 650 651 652 653 654 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 642 def loop_vectors(name = nil, number_of_loops = 1, _global = false) # The name argument is present to maych J750 API, sort out the unless name.is_a?(String) name, number_of_loops, global = nil, name, number_of_loops end if number_of_loops > 1 microcode "SQPG LBGN #{number_of_loops};" yield microcode 'SQPG LEND;' else yield end end |
#match(pin, state, timeout_in_cycles, options = {}) ⇒ Object
Generates a match loop on up to two pins.
This method is not really intended to be called directly, rather you should call via Tester#wait e.g. $tester.wait(:match => true).
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:
-
:pin - The pin object to match on (required)
-
:state - The pin state to match on, :low or :high (required)
-
:check_for_fails (false) - Flushes the pipeline and checks for fails prior to the match (to allow binout of fails encountered before the match)
-
:pin2 (nil) - Optionally supply a second pin to match on
-
:state2 (nil) - State for the second pin (required if :pin2 is supplied)
-
:force_fail_on_timeout (true) - Force a vector mis-compare if the match loop times out
Examples
$tester.wait(:match => true, :time_in_us => 5000, :pin => $top.pin(:done), :state => :high)
457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 457 def match(pin, state, timeout_in_cycles, = {}) = { check_for_fails: false, pin2: false, state2: false, global_loops: false, generate_subroutine: false, force_fail_on_timeout: true }.merge() # Ensure the match pins are don't care by default pin.dont_care [:pin2].dont_care if [:pin2] if ![:pin2] cc "for the #{pin.name.upcase} pin to go #{state.to_s.upcase}" match_block(timeout_in_cycles, ) do |match_or_conditions, fail_conditions| match_or_conditions.add do state == :low ? pin.expect_lo : pin.expect_hi cycle pin.dont_care end end else cc "for the #{pin.name.upcase} pin to go #{state.to_s.upcase}" cc "or the #{[:pin2].name.upcase} pin to go #{[:state2].to_s.upcase}" match_block(timeout_in_cycles, ) do |match_or_conditions, fail_conditions| match_or_conditions.add do state == :low ? pin.expect_lo : pin.expect_hi cycle pin.dont_care end match_or_conditions.add do [:state2] == :low ? [:pin2].expect_lo : [:pin2].expect_hi cycle [:pin2].dont_care end fail_conditions.add do cc 'To get here something has gone wrong, strobe again to force a pattern failure' state == :low ? pin.expect_lo : pin.expect_hi [:state2] == :low ? [:pin2].expect_lo : [:pin2].expect_hi cycle pin.dont_care [:pin2].dont_care end end end end |
#match_block(timeout_in_cycles, options = {}, &block) ⇒ Object
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 505 def match_block(timeout_in_cycles, = {}, &block) 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 if block.arity > 0 yield match_conditions, fail_conditions else match_conditions.add(&block) end # Generate a conventional match loop when there is only one match condition block if match_conditions.instance_variable_get(:@block_args).size == 1 # Need to ensure at least 8 cycles with no compares before entering dut.pins.each do |name, pin| pin.save pin.dont_care if pin.comparing? end 8.cycles dut.pins.each { |name, pin| pin.restore } # Placeholder, real number of loops required to implement the required timeout will be # concatenated onto the end later once the length of the match loop is known microcode 'SQPG MACT' match_microcode = stage.current_bank.last prematch_cycle_count = cycle_count match_conditions.each(&:call) match_loop_cycle_count = cycle_count - prematch_cycle_count # Pad the compare vectors out to a multiple of 8 per the ADV documentation until match_loop_cycle_count % 8 == 0 cycle match_loop_cycle_count += 1 end # Use 8 wait vectors by default to keep the overall number of cycles as a multiple of 8 mrpt = 8 number_of_loops = (timeout_in_cycles.to_f / (match_loop_cycle_count + mrpt)).ceil # There seems to be a limit on the max MACT value, so account for longer times by expanding # the wait loop while number_of_loops > 262_144 mrpt = mrpt * 2 # Keep this as a multiple of 8 number_of_loops = (timeout_in_cycles.to_f / (match_loop_cycle_count + mrpt)).ceil end match_microcode.concat(" #{number_of_loops};") unless @inhibit_vectors # Now do the wait loop, mrpt should always be a multiple of 8 microcode "SQPG MRPT #{mrpt};" # Should be no compares in the wait cycles dut.pins.each do |name, pin| pin.save pin.dont_care if pin.comparing? end mrpt.cycles dut.pins.each { |name, pin| pin.restore } # This is just used as a marker by the vector translator to indicate the end of the MRPT # vectors, it does not end up in the final pattern binary. # It is also used in a similar manner by Origen when generating SMT8 patterns. microcode 'SQPG PADDING;' # For multiple match conditions do something more like the J750 approach where branching based on # miscompares is used to keep the loop going else if [:check_for_fails] cc 'Return preserving existing errors if the pattern has already failed before arriving here' cycle(repeat: propagation_delay) microcode 'SQPG RETC 1 1;' end loop_microcode = '' loop_cycles = 0 loop_vectors 2 do loop_microcode = stage.current_bank.last preloop_cycle_count = cycle_count match_conditions.each do |condition| condition.call cc 'Wait for failure to propagate' cycle(repeat: propagation_delay) cc 'Exit match loop if pin has matched (no error), otherwise clear error and remain in loop' microcode 'SQPG RETC 0 0;' end loop_cycles = cycle_count - preloop_cycle_count end unless @inhibit_vectors number_of_loops = (timeout_in_cycles.to_f / loop_cycles).ceil loop_microcode.sub!('2', number_of_loops.to_s) end if [:force_fail_on_timeout] fail_conditions.each(&:call) end end end |
#multiport_name(patt_name) ⇒ Object
return the multiport burst name provide the name you want to obtain multiport for
168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 168 def multiport_name(patt_name) name = "#{patt_name}" if @multiport name = "#{@multiport_prefix}_#{name}" if @multiport_prefix name = "#{name}_#{@multiport_postfix}" if @multiport_postfix unless @multiport_prefix || @multiport_postfix name = "#{@multiport}_#{name}" end end name end |
#overlay_style_warn(overlay_str, options) ⇒ Object
Warn user of unsupported overlay style
245 246 247 248 249 250 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 245 def (, ) Origen.log.warn("Unrecognized overlay style :#{@overlay_style}, defaulting to subroutine") Origen.log.warn('Available overlay styles :subroutine') (, ) @overlay_style = :subroutine # Just give 1 warning end |
#pattern_footer(options = {}) ⇒ Object
An internal method called by Origen to generate the pattern footer
689 690 691 692 693 694 695 696 697 698 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 689 def ( = {}) = { end_in_ka: false }.merge() if [:end_in_ka] Origen.log.warning '93K keep alive not yet implemented!' ss 'WARNING: 93K keep alive not yet implemented!' end microcode 'SQPG STOP;' unless [:subroutine] end |
#pattern_header(options = {}) ⇒ Object
An internal method called by Origen to create the pattern header
658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 658 def pattern_header( = {}) = { }.merge() pin_list = ordered_pins.map do |p| if Origen.app.pin_pattern_order.include?(p.id) # specified name overrides pin name if (p.is_a?(Origen::Pins::PinCollection)) || p.id != p.name p.id.to_s # groups or aliases can be lower case else p.id.to_s.upcase # pins must be uppercase end else if (p.is_a?(Origen::Pins::PinCollection)) || p.id != p.name p.name.to_s # groups or aliases can be lower case else p.name.to_s.upcase # pins must be uppercase end end end.join(' ') microcode "FORMAT #{pin_list};" if ordered_pins.size > 0 max_pin_name_length = ordered_pins.map(&:name).max { |a, b| a.length <=> b.length }.length pin_widths = ordered_pins.map { |p| p.size - 1 } max_pin_name_length.times do |i| cc((' ' * 50) + ordered_pins.map.with_index { |p, x| ((p.name[i] || ' ') + ' ' * pin_widths[x]).gsub('_', '-') }.join(' ')) end end end |
#propagation_delay ⇒ Object
Returns the number of cycles to wait for any fails to propagate through the pipeline based on the current timeset
614 615 616 617 618 619 620 621 622 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 614 def propagation_delay # From 'Calculating the buffer cycles for JMPE and RETC (and match loops)' in SmarTest docs data_queue_buffer = (([105, 64 + ((125 + current_period_in_ns - 1) / current_period_in_ns).ceil].min + 3) * 8) + 72 # Don't know how to calculate at runtime, hardcoding these to some default values for now number_of_sites = 128 sclk_period = 40 prop_delay_buffer = 195 + ((2 * number_of_sites + 3) * (sclk_period / 2)) data_queue_buffer + prop_delay_buffer end |
#repeat_previous ⇒ Object
All vectors generated with the supplied block will have all pins set to the repeat previous state. Any pins that are changed state within the block will still update to the supplied value.
Example
# All pins except invoke will be assigned the repeat previous code
# in the generated vector. On completion of the block they will
# return to their previous state, except for invoke which will
# retain the value assigned within the block.
$tester.repeat_previous do
$top.pin(:invoke).drive(1)
$tester.cycle
end
722 723 724 725 726 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 722 def repeat_previous Origen.app.pin_map.each { |_id, pin| pin.repeat_previous = true } yield Origen.app.pin_map.each { |_id, pin| pin.repeat_previous = false } end |
#start_subroutine(name) ⇒ Object
Start a subroutine.
Generates a global subroutine label. Global is used to adhere to the best practice of containing all subroutines in dedicated patterns, e.g. global_subs.atp
Examples
$tester.start_subroutine("wait_for_done")
< generate your subroutine vectors here >
$tester.end_subroutine
373 374 375 376 377 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 373 def start_subroutine(name) local_subroutines << name.to_s.chomp unless local_subroutines.include?(name.to_s.chomp) || @inhibit_vectors # name += "_subr" unless name =~ /sub/ ::Pattern.open name: name, call_startup_callbacks: false, subroutine: true end |
#store(*pins) ⇒ Object Also known as: capture
Capture the pin data from a vector to the tester.
This method uses the Digital Capture feature (Selective mode) of the V93000 to capture the data from the given pins on the previous vector. Note that is does not actually generate a new vector.
Note also that any drive cycles on the target pins can also be captured, to avoid this the wavetable should be set up like this to infer a ‘D’ (Don’t Capture) on vectors where the target pin is being used to drive data:
PINS nvm_fail
0 d1:0 r1:D 0
1 d1:1 r1:D 1
2 r1:C Capt
3 r1:D NoCapt
Sometimes when generating vectors within a loop you may want to apply a capture retrospectively to a previous vector, passing in an offset option will allow you to do this.
Examples
$tester.cycle # This is the vector you want to capture
$tester.store :pin => pin(:fail) # This applys the required opcode to the given pins
$tester.cycle # This one gets captured
$tester.cycle
$tester.cycle
$tester.store(:pin => pin(:fail), :offset => -2) # Just realized I need to capture that earlier vector
# Capturing multiple pins:
$tester.cycle
$tester.store :pins => [pin(:fail), pin(:done)]
Since the V93K store operates on a pin level (rather than vector level as on the J750) equivalent functionality can also be achieved by setting the store attribute of the pin itself prior to calling $tester.cycle. However it is recommended to use the tester API to do the store if cross-compatiblity with other platforms, such as the J750, is required.
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 319 def store(*pins) = pins.last.is_a?(Hash) ? pins.pop : {} = { offset: 0 }.merge() pins = pins.flatten.compact if pins.empty? fail 'For the V93K you must supply the pins to store/capture' end pins.each do |pin| pin.restore_state do pin.capture update_vector_pin_val pin, offset: [:offset] unless @inhibit_vectors last_vector([:offset]).dont_compress = true last_vector([:offset]).contains_capture = true end end end end |
#store_next_cycle(*pins) ⇒ Object Also known as: store!
Same as the store method, except that the capture will be applied to the next vector to be generated.
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 346 def store_next_cycle(*pins) = pins.last.is_a?(Hash) ? pins.pop : {} = { }.merge() pins = pins.flatten.compact if pins.empty? fail 'For the V93K you must supply the pins to store/capture' end pins.each { |pin| pin.save; pin.capture } # Register this clean up function to be run after the next vector # is generated, cool or what! preset_next_vector do |vector| vector.contains_capture = true pins.each(&:restore) end end |
#subroutine_overlay(sub_name, options = {}) ⇒ Object
Implement subroutine overlay, called by tester.cycle
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 |
# File 'lib/origen_testers/smartest_based_tester/base.rb', line 253 def (sub_name, = {}) if @overlay_subr != sub_name # unless last staged vector already has the subr call do the following i = -1 i -= 1 until stage.bank[i].is_a?(OrigenTesters::Vector) if stage.bank[i].microcode !~ /#{sub_name}/ # check for repeat on new last vector, unroll 1 if needed if stage.bank[i].repeat > 1 v = OrigenTesters::Vector.new v.pin_vals = stage.bank[i].pin_vals v.timeset = stage.bank[i].timeset stage.bank[i].repeat -= 1 stage.store(v) i = -1 end # mark last vector as dont_compress stage.bank[i].dont_compress = true # insert subroutine call call_subroutine sub_name end # if microcode not placed @overlay_subr = sub_name end # stage = sub_name end |