origen_testers 0.18.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/config/boot.rb +2 -1
- data/config/version.rb +1 -1
- data/lib/origen_testers/flow.rb +5 -0
- data/lib/origen_testers/generator.rb +1 -1
- data/lib/origen_testers/pattern_compilers/job.rb +3 -3
- data/lib/origen_testers/smartest_based_tester/base.rb +70 -1
- data/lib/origen_testers/smartest_based_tester/base/flow.rb +118 -13
- data/lib/origen_testers/smartest_based_tester/base/limits_file.rb +216 -0
- data/lib/origen_testers/smartest_based_tester/base/pattern_master.rb +9 -1
- data/lib/origen_testers/smartest_based_tester/base/processors/extract_bin_names.rb +64 -0
- data/lib/origen_testers/smartest_based_tester/base/test_method.rb +1 -4
- data/lib/origen_testers/smartest_based_tester/base/test_methods/limits.rb +11 -0
- data/lib/origen_testers/smartest_based_tester/base/test_suite.rb +8 -1
- data/lib/origen_testers/smartest_based_tester/v93k/limits_file.rb +10 -0
- data/lib/origen_testers/smartest_based_tester/v93k/templates/limits.csv.erb +3 -0
- data/lib/origen_testers/smartest_based_tester/v93k/templates/template.aiv.erb +17 -2
- data/lib/origen_testers/smartest_based_tester/v93k/templates/template.tf.erb +2 -0
- data/lib/origen_testers/test/dut.rb +34 -13
- data/program/test.rb +14 -9
- metadata +7 -5
- data/lib/origen_testers/smartest_based_tester/base/processors/extract_set_variables.rb +0 -22
- data/lib/origen_testers/test/dut3.rb +0 -244
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: d0f9e7b0562c602396e9cb070d57050486a854df
         | 
| 4 | 
            +
              data.tar.gz: fbde57d2fa40beae37c0443261339bb2f8c187d7
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: f58d90428732f2046cf98e8b0c175531fd1a150eb86c8771beb3e766b2ec2de483f7cd7f72d8b1d74d78edcf6c9ece7fe9a587f5945b38cb8be88e793c915e07
         | 
| 7 | 
            +
              data.tar.gz: c87af16d5020f20bdae4abcc3b6227e21f2c33d87c5e9f2d156e9d452f53840153ff1ceb1043586a0d257ebe27c30ca29f02c37ee64853e1cddbca89a7c61c48
         | 
    
        data/config/boot.rb
    CHANGED
    
    | @@ -5,7 +5,8 @@ require "origen_testers" | |
| 5 5 | 
             
            require "origen_testers/test/dut.rb"
         | 
| 6 6 | 
             
            require "origen_testers/test/block.rb"
         | 
| 7 7 | 
             
            require "origen_testers/test/dut2.rb"
         | 
| 8 | 
            -
             | 
| 8 | 
            +
            # NOTE: Before adding new duts-- consider adding option to DUT class 
         | 
| 9 | 
            +
            # so we don't reduce overall code coverage-- thx, mgmt
         | 
| 9 10 | 
             
            require "origen_testers/test/nvm.rb"
         | 
| 10 11 |  | 
| 11 12 | 
             
            require "origen_testers/test/interface"
         | 
    
        data/config/version.rb
    CHANGED
    
    
    
        data/lib/origen_testers/flow.rb
    CHANGED
    
    | @@ -48,6 +48,11 @@ module OrigenTesters | |
| 48 48 | 
             
                  @lines
         | 
| 49 49 | 
             
                end
         | 
| 50 50 |  | 
| 51 | 
            +
                def test(obj, options = {})
         | 
| 52 | 
            +
                  obj.extract_atp_attributes(options) if obj.respond_to?(:extract_atp_attributes)
         | 
| 53 | 
            +
                  super(obj, options)
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 51 56 | 
             
                # @api private
         | 
| 52 57 | 
             
                def self.ht_comments
         | 
| 53 58 | 
             
                  unless @ht_comments.is_a? Hash
         | 
| @@ -151,7 +151,6 @@ module OrigenTesters | |
| 151 151 | 
             
                end
         | 
| 152 152 |  | 
| 153 153 | 
             
                def write_to_file(options = {})
         | 
| 154 | 
            -
                  c = caller[0]
         | 
| 155 154 | 
             
                  unless output_inhibited?
         | 
| 156 155 | 
             
                    if defined? self.class::TEMPLATE || Origen.tester.is_a?(OrigenTesters::Doc)
         | 
| 157 156 | 
             
                      write_from_template(options)
         | 
| @@ -274,6 +273,7 @@ module OrigenTesters | |
| 274 273 | 
             
                  def new(*args, &block) # :nodoc:
         | 
| 275 274 | 
             
                    options = (args.last && args.last.is_a?(Hash)) ? args.last : {}
         | 
| 276 275 | 
             
                    x = allocate
         | 
| 276 | 
            +
                    x.filename = options[:filename] if options[:filename]
         | 
| 277 277 | 
             
                    x.send(:initialize, *args, &block)
         | 
| 278 278 | 
             
                    Origen.interface.sheet_generators << x unless options[:manually_register]
         | 
| 279 279 | 
             
                    x
         | 
| @@ -22,13 +22,13 @@ module OrigenTesters | |
| 22 22 | 
             
                  # Pinmap file (IGXL-Based)
         | 
| 23 23 | 
             
                  attr_accessor :pinmap_workbook
         | 
| 24 24 |  | 
| 25 | 
            -
                  #  | 
| 25 | 
            +
                  # Pin Config file (Smartest-Based)
         | 
| 26 26 | 
             
                  attr_accessor :pinconfig
         | 
| 27 27 |  | 
| 28 | 
            -
                  #  | 
| 28 | 
            +
                  # Pattern input dir (Smartest-Based)
         | 
| 29 29 | 
             
                  attr_accessor :avc_dir
         | 
| 30 30 |  | 
| 31 | 
            -
                  #  | 
| 31 | 
            +
                  # Pattern output dir (Smartest-Based)
         | 
| 32 32 | 
             
                  attr_accessor :binl_dir
         | 
| 33 33 |  | 
| 34 34 | 
             
                  # Pattern count - should be 1 for IGXL; number of AVC files listed in AIV file for Smartest
         | 
| @@ -24,7 +24,44 @@ module OrigenTesters | |
| 24 24 | 
             
                  alias_method :min_repeat_count, :min_repeat_loop
         | 
| 25 25 | 
             
                  alias_method :min_repeat_count=, :min_repeat_loop=
         | 
| 26 26 |  | 
| 27 | 
            +
                  # permit option to generate multiport type patterns
         | 
| 28 | 
            +
                  # and use multiport type code
         | 
| 29 | 
            +
                  attr_accessor :multiport
         | 
| 30 | 
            +
                  alias_method :multi_port, :multiport
         | 
| 31 | 
            +
                  alias_method :multi_port=, :multiport=
         | 
| 32 | 
            +
                  attr_accessor :multiport_prefix     # multiport burst name prefix
         | 
| 33 | 
            +
                  attr_accessor :multiport_postfix     # multiport burst name postfix
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  # When set to true, all test flows will be generated with a corresponding testtable limits
         | 
| 36 | 
            +
                  # file, rather than having the limits attached inline to the test suites
         | 
| 37 | 
            +
                  attr_accessor :create_limits_file
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  # Returns an array of strings that indicate which test modes will be included in limits files,
         | 
| 40 | 
            +
                  # by default returns an empty array.
         | 
| 41 | 
            +
                  # If no test modes have been specified then the limits file will simply be generated with no
         | 
| 42 | 
            +
                  # test modes.
         | 
| 43 | 
            +
                  attr_reader :limitfile_test_modes
         | 
| 44 | 
            +
                  alias_method :limitsfile_test_modes, :limitfile_test_modes
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  # When set to true, tests which are marked with continue: true will be forced to pass in
         | 
| 47 | 
            +
                  # generated test program flows. Flow branching based on the test result will be handled via
         | 
| 48 | 
            +
                  # some other means to give the same flow if the test 'fails', however the test will always
         | 
| 49 | 
            +
                  # appear as if it passed for data logging purposes.
         | 
| 50 | 
            +
                  #
         | 
| 51 | 
            +
                  # Testers which do not implement this option will ignore it.
         | 
| 52 | 
            +
                  attr_accessor :force_pass_on_continue
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  # When set to true, tests will be set to delayed binning by default (overon = on) unless
         | 
| 55 | 
            +
                  # delayed: false is supplied when defining the test
         | 
| 56 | 
            +
                  attr_accessor :delayed_binning
         | 
| 57 | 
            +
             | 
| 27 58 | 
             
                  def initialize(options = {})
         | 
| 59 | 
            +
                    options = {
         | 
| 60 | 
            +
                      # whether to use multiport bursts or not, if so this indicates the name of the port to use
         | 
| 61 | 
            +
                      multiport:         false,
         | 
| 62 | 
            +
                      multiport_prefix:  false,
         | 
| 63 | 
            +
                      multiport_postfix: false
         | 
| 64 | 
            +
                    }.merge(options)
         | 
| 28 65 | 
             
                    @max_repeat_loop = 65_535
         | 
| 29 66 | 
             
                    @min_repeat_loop = 33
         | 
| 30 67 | 
             
                    @pat_extension = 'avc'
         | 
| @@ -35,7 +72,10 @@ module OrigenTesters | |
| 35 72 | 
             
                    @comment_char = '#'
         | 
| 36 73 | 
             
                    @level_period = true
         | 
| 37 74 | 
             
                    @inline_comments = true
         | 
| 38 | 
            -
                    @ | 
| 75 | 
            +
                    @multiport = options[:multiport]
         | 
| 76 | 
            +
                    @multiport_prefix = options[:multiport_prefix]
         | 
| 77 | 
            +
                    @multiport_postfix = options[:multiport_postfix]
         | 
| 78 | 
            +
                    @overlay_style = :subroutine	# default to use subroutine for overlay
         | 
| 39 79 | 
             
                    @capture_style = :hram			# default to use hram for capture
         | 
| 40 80 | 
             
                    @overlay_subr = nil
         | 
| 41 81 |  | 
| @@ -47,6 +87,35 @@ module OrigenTesters | |
| 47 87 | 
             
                    else
         | 
| 48 88 | 
             
                      @unique_test_names = :signature
         | 
| 49 89 | 
             
                    end
         | 
| 90 | 
            +
                    if options.key?(:create_limits_file)
         | 
| 91 | 
            +
                      @create_limits_file = options[:create_limits_file]
         | 
| 92 | 
            +
                    else
         | 
| 93 | 
            +
                      @create_limits_file = false
         | 
| 94 | 
            +
                    end
         | 
| 95 | 
            +
                    self.limitfile_test_modes = options[:limitfile_test_modes] || options[:limitsfile_test_modes]
         | 
| 96 | 
            +
                    self.force_pass_on_continue = options[:force_pass_on_continue]
         | 
| 97 | 
            +
                    self.delayed_binning = options[:delayed_binning]
         | 
| 98 | 
            +
                  end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                  # Set the test mode(s) that you want to see in the limits files, supply an array of mode names
         | 
| 101 | 
            +
                  # to set multiple.
         | 
| 102 | 
            +
                  def limitfile_test_modes=(val)
         | 
| 103 | 
            +
                    @limitfile_test_modes = Array(val).map(&:to_s)
         | 
| 104 | 
            +
                  end
         | 
| 105 | 
            +
                  alias_method :limitsfile_test_modes, :limitfile_test_modes=
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                  # return the multiport burst name
         | 
| 108 | 
            +
                  # provide the name you want to obtain multiport for
         | 
| 109 | 
            +
                  def multiport_name(patt_name)
         | 
| 110 | 
            +
                    name = "#{patt_name}"
         | 
| 111 | 
            +
                    if @multiport
         | 
| 112 | 
            +
                      name = "#{@multiport_prefix}_#{name}" if @multiport_prefix
         | 
| 113 | 
            +
                      name = "#{name}_#{@multiport_postfix}" if @multiport_postfix
         | 
| 114 | 
            +
                      unless @multiport_prefix || @multiport_postfix
         | 
| 115 | 
            +
                        name = "#{@multiport}_#{name}"
         | 
| 116 | 
            +
                      end
         | 
| 117 | 
            +
                    end
         | 
| 118 | 
            +
                    name
         | 
| 50 119 | 
             
                  end
         | 
| 51 120 |  | 
| 52 121 | 
             
                  # Set to :enabled to have all top-level flow modules wrapped by an enable flow variable
         | 
| @@ -43,6 +43,8 @@ module OrigenTesters | |
| 43 43 | 
             
                    end
         | 
| 44 44 |  | 
| 45 45 | 
             
                    def at_flow_end
         | 
| 46 | 
            +
                      # Take whatever the test modes are set to at the end of the flow as what we go with
         | 
| 47 | 
            +
                      @test_modes = tester.limitfile_test_modes
         | 
| 46 48 | 
             
                    end
         | 
| 47 49 |  | 
| 48 50 | 
             
                    def flow_header
         | 
| @@ -86,14 +88,24 @@ module OrigenTesters | |
| 86 88 |  | 
| 87 89 | 
             
                    def finalize(options = {})
         | 
| 88 90 | 
             
                      super
         | 
| 89 | 
            -
                      test_suites.finalize
         | 
| 90 | 
            -
                      test_methods.finalize
         | 
| 91 91 | 
             
                      @indent = add_flow_enable ? 2 : 1
         | 
| 92 92 | 
             
                      @lines = []
         | 
| 93 | 
            +
                      @open_test_methods = []
         | 
| 93 94 | 
             
                      @stack = { on_fail: [], on_pass: [] }
         | 
| 94 | 
            -
                      ast = atp.ast(unique_id: sig, optimization: :smt | 
| 95 | 
            +
                      ast = atp.ast(unique_id: sig, optimization: :smt,
         | 
| 96 | 
            +
                                    implement_continue: !tester.force_pass_on_continue,
         | 
| 97 | 
            +
                                    optimize_flags_when_continue: !tester.force_pass_on_continue
         | 
| 98 | 
            +
                                   )
         | 
| 95 99 | 
             
                      @set_runtime_variables = ast.set_flags
         | 
| 96 100 | 
             
                      process(ast)
         | 
| 101 | 
            +
                      test_suites.finalize
         | 
| 102 | 
            +
                      test_methods.finalize
         | 
| 103 | 
            +
                      render_limits_file(ast) if tester.create_limits_file
         | 
| 104 | 
            +
                    end
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                    def render_limits_file(ast)
         | 
| 107 | 
            +
                      m = platform::LimitsFile.new(self, ast, manually_register: true, filename: "#{name}_limits", test_modes: @test_modes)
         | 
| 108 | 
            +
                      m.write_to_file unless m.empty?
         | 
| 97 109 | 
             
                    end
         | 
| 98 110 |  | 
| 99 111 | 
             
                    def line(str)
         | 
| @@ -109,28 +121,61 @@ module OrigenTesters | |
| 109 121 | 
             
                    # end
         | 
| 110 122 |  | 
| 111 123 | 
             
                    def on_test(node)
         | 
| 112 | 
            -
                       | 
| 113 | 
            -
                       | 
| 124 | 
            +
                      test_suite = node.find(:object).to_a[0]
         | 
| 125 | 
            +
                      if test_suite.is_a?(String)
         | 
| 126 | 
            +
                        name = test_suite
         | 
| 127 | 
            +
                      else
         | 
| 128 | 
            +
                        name = test_suite.name
         | 
| 129 | 
            +
                        test_method = test_suite.test_method
         | 
| 130 | 
            +
                        if test_method.respond_to?(:test_name) && test_method.test_name == '' &&
         | 
| 131 | 
            +
                           n = node.find(:name)
         | 
| 132 | 
            +
                          test_method.test_name = n.value
         | 
| 133 | 
            +
                        end
         | 
| 134 | 
            +
                      end
         | 
| 135 | 
            +
             | 
| 114 136 | 
             
                      if node.children.any? { |n| t = n.try(:type); t == :on_fail || t == :on_pass } ||
         | 
| 115 137 | 
             
                         !stack[:on_pass].empty? || !stack[:on_fail].empty?
         | 
| 116 138 | 
             
                        line "run_and_branch(#{name})"
         | 
| 117 139 | 
             
                        process_all(node.to_a.reject { |n| t = n.try(:type); t == :on_fail || t == :on_pass })
         | 
| 140 | 
            +
                        on_pass = node.find(:on_pass)
         | 
| 141 | 
            +
                        on_fail = node.find(:on_fail)
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                        if on_fail && on_fail.find(:continue) && tester.force_pass_on_continue
         | 
| 144 | 
            +
                          if test_method.respond_to?(:force_pass)
         | 
| 145 | 
            +
                            test_method.force_pass = 1
         | 
| 146 | 
            +
                          else
         | 
| 147 | 
            +
                            Origen.log.error 'Force pass on continue has been enabled, but the test method does not have a force_pass attribute!'
         | 
| 148 | 
            +
                            Origen.log.error "  #{node.source}"
         | 
| 149 | 
            +
                            exit 1
         | 
| 150 | 
            +
                          end
         | 
| 151 | 
            +
                          @open_test_methods << test_method
         | 
| 152 | 
            +
                        else
         | 
| 153 | 
            +
                          if test_method.respond_to?(:force_pass)
         | 
| 154 | 
            +
                            test_method.force_pass = 0
         | 
| 155 | 
            +
                          end
         | 
| 156 | 
            +
                          @open_test_methods << nil
         | 
| 157 | 
            +
                        end
         | 
| 158 | 
            +
             | 
| 118 159 | 
             
                        line 'then'
         | 
| 119 160 | 
             
                        line '{'
         | 
| 120 161 | 
             
                        @indent += 1
         | 
| 121 | 
            -
                         | 
| 122 | 
            -
             | 
| 123 | 
            -
             | 
| 162 | 
            +
                        pass_branch do
         | 
| 163 | 
            +
                          process_all(on_pass) if on_pass
         | 
| 164 | 
            +
                          stack[:on_pass].each { |n| process_all(n) }
         | 
| 165 | 
            +
                        end
         | 
| 124 166 | 
             
                        @indent -= 1
         | 
| 125 167 | 
             
                        line '}'
         | 
| 126 168 | 
             
                        line 'else'
         | 
| 127 169 | 
             
                        line '{'
         | 
| 128 170 | 
             
                        @indent += 1
         | 
| 129 | 
            -
                         | 
| 130 | 
            -
             | 
| 131 | 
            -
             | 
| 171 | 
            +
                        fail_branch do
         | 
| 172 | 
            +
                          process_all(on_fail) if on_fail
         | 
| 173 | 
            +
                          stack[:on_fail].each { |n| process_all(n) }
         | 
| 174 | 
            +
                        end
         | 
| 132 175 | 
             
                        @indent -= 1
         | 
| 133 176 | 
             
                        line '}'
         | 
| 177 | 
            +
             | 
| 178 | 
            +
                        @open_test_methods.pop
         | 
| 134 179 | 
             
                      else
         | 
| 135 180 | 
             
                        line "run(#{name});"
         | 
| 136 181 | 
             
                      end
         | 
| @@ -228,7 +273,39 @@ module OrigenTesters | |
| 228 273 | 
             
                    def on_set_flag(node)
         | 
| 229 274 | 
             
                      flag = generate_flag_name(node.value)
         | 
| 230 275 | 
             
                      runtime_control_variables << flag
         | 
| 231 | 
            -
                       | 
| 276 | 
            +
                      if @open_test_methods.last
         | 
| 277 | 
            +
                        if pass_branch?
         | 
| 278 | 
            +
                          if @open_test_methods.last.respond_to?(:on_pass_flag)
         | 
| 279 | 
            +
                            if @open_test_methods.last.on_pass_flag == ''
         | 
| 280 | 
            +
                              @open_test_methods.last.on_pass_flag = flag
         | 
| 281 | 
            +
                            else
         | 
| 282 | 
            +
                              Origen.log.error "The test method cannot set #{flag} on passing, because it already sets: #{@open_test_methods.last.on_pass_flag}"
         | 
| 283 | 
            +
                              Origen.log.error "  #{node.source}"
         | 
| 284 | 
            +
                              exit 1
         | 
| 285 | 
            +
                            end
         | 
| 286 | 
            +
                          else
         | 
| 287 | 
            +
                            Origen.log.error 'Force pass on continue has been requested, but the test method does not have an :on_pass_flag attribute:'
         | 
| 288 | 
            +
                            Origen.log.error "  #{node.source}"
         | 
| 289 | 
            +
                            exit 1
         | 
| 290 | 
            +
                          end
         | 
| 291 | 
            +
                        else
         | 
| 292 | 
            +
                          if @open_test_methods.last.respond_to?(:on_fail_flag)
         | 
| 293 | 
            +
                            if @open_test_methods.last.on_fail_flag == ''
         | 
| 294 | 
            +
                              @open_test_methods.last.on_fail_flag = flag
         | 
| 295 | 
            +
                            else
         | 
| 296 | 
            +
                              Origen.log.error "The test method cannot set #{flag} on failing, because it already sets: #{@open_test_methods.last.on_fail_flag}"
         | 
| 297 | 
            +
                              Origen.log.error "  #{node.source}"
         | 
| 298 | 
            +
                              exit 1
         | 
| 299 | 
            +
                            end
         | 
| 300 | 
            +
                          else
         | 
| 301 | 
            +
                            Origen.log.error 'Force pass on continue has been requested, but the test method does not have an :on_fail_flag attribute:'
         | 
| 302 | 
            +
                            Origen.log.error "  #{node.source}"
         | 
| 303 | 
            +
                            exit 1
         | 
| 304 | 
            +
                          end
         | 
| 305 | 
            +
                        end
         | 
| 306 | 
            +
                      else
         | 
| 307 | 
            +
                        line "@#{flag} = 1;"
         | 
| 308 | 
            +
                      end
         | 
| 232 309 | 
             
                    end
         | 
| 233 310 |  | 
| 234 311 | 
             
                    def on_group(node)
         | 
| @@ -257,7 +334,11 @@ module OrigenTesters | |
| 257 334 | 
             
                      if node.to_a[0] == 'pass'
         | 
| 258 335 | 
             
                        line "stop_bin \"#{sbin}\", \"\", , good, noreprobe, green, #{bin}, over_on;"
         | 
| 259 336 | 
             
                      else
         | 
| 260 | 
            -
                         | 
| 337 | 
            +
                        if tester.create_limits_file
         | 
| 338 | 
            +
                          line 'multi_bin;'
         | 
| 339 | 
            +
                        else
         | 
| 340 | 
            +
                          line "stop_bin \"#{sbin}\", \"#{sdesc}\", , bad, noreprobe, red, #{bin}, over_on;"
         | 
| 341 | 
            +
                        end
         | 
| 261 342 | 
             
                      end
         | 
| 262 343 | 
             
                    end
         | 
| 263 344 |  | 
| @@ -282,6 +363,30 @@ module OrigenTesters | |
| 282 363 |  | 
| 283 364 | 
             
                    private
         | 
| 284 365 |  | 
| 366 | 
            +
                    def pass_branch
         | 
| 367 | 
            +
                      open_branch_types << :pass
         | 
| 368 | 
            +
                      yield
         | 
| 369 | 
            +
                      open_branch_types.pop
         | 
| 370 | 
            +
                    end
         | 
| 371 | 
            +
             | 
| 372 | 
            +
                    def fail_branch
         | 
| 373 | 
            +
                      open_branch_types << :fail
         | 
| 374 | 
            +
                      yield
         | 
| 375 | 
            +
                      open_branch_types.pop
         | 
| 376 | 
            +
                    end
         | 
| 377 | 
            +
             | 
| 378 | 
            +
                    def pass_branch?
         | 
| 379 | 
            +
                      open_branch_types.last == :pass
         | 
| 380 | 
            +
                    end
         | 
| 381 | 
            +
             | 
| 382 | 
            +
                    def fail_branch?
         | 
| 383 | 
            +
                      open_branch_types.last == :fail
         | 
| 384 | 
            +
                    end
         | 
| 385 | 
            +
             | 
| 386 | 
            +
                    def open_branch_types
         | 
| 387 | 
            +
                      @open_branch_types ||= []
         | 
| 388 | 
            +
                    end
         | 
| 389 | 
            +
             | 
| 285 390 | 
             
                    def generate_flag_name(flag)
         | 
| 286 391 | 
             
                      case flag[0]
         | 
| 287 392 | 
             
                      when '$'
         | 
| @@ -0,0 +1,216 @@ | |
| 1 | 
            +
            require 'origen_testers/smartest_based_tester/base/processors/extract_bin_names'
         | 
| 2 | 
            +
            module OrigenTesters
         | 
| 3 | 
            +
              module SmartestBasedTester
         | 
| 4 | 
            +
                class Base
         | 
| 5 | 
            +
                  class LimitsFile < ATP::Formatter
         | 
| 6 | 
            +
                    include OrigenTesters::Generator
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                    attr_reader :ast, :flow, :test_modes, :flowname, :bin_names
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                    def initialize(flow, ast, options = {})
         | 
| 11 | 
            +
                      @flow = flow
         | 
| 12 | 
            +
                      @ast = ast
         | 
| 13 | 
            +
                      @flowname = flow.filename.sub(/\..*/, '') # Base off the filename since it will include any prefix
         | 
| 14 | 
            +
                      @used_test_numbers = {}
         | 
| 15 | 
            +
                      @bin_names = Processors::ExtractBinNames.new.run(ast)
         | 
| 16 | 
            +
                      @test_modes = Array(options[:test_modes])
         | 
| 17 | 
            +
                      @empty = true
         | 
| 18 | 
            +
                      l = '"Suite name","Pins","Test name","Test number"'
         | 
| 19 | 
            +
                      if test_modes.empty?
         | 
| 20 | 
            +
                        l += ',"Lsl","Lsl_typ","Usl_typ","Usl","Units","Bin_s_num","Bin_s_name","Bin_h_num","Bin_h_name","Bin_type","Bin_reprobe","Bin_overon","Test_remarks"'
         | 
| 21 | 
            +
                        lines << l
         | 
| 22 | 
            +
                      else
         | 
| 23 | 
            +
                        l += (',"Lsl","Lsl_typ","Usl_typ","Usl","Units"' * test_modes.size) + ',"Bin_s_num","Bin_s_name","Bin_h_num","Bin_h_name","Bin_type","Bin_reprobe","Bin_overon","Test_remarks"'
         | 
| 24 | 
            +
                        lines << l
         | 
| 25 | 
            +
                        l = '"Test mode",,,'
         | 
| 26 | 
            +
                        test_modes.each do |mode|
         | 
| 27 | 
            +
                          l += ",\"#{mode}\",\"#{mode}\",\"#{mode}\",\"#{mode}\",\"#{mode}\""
         | 
| 28 | 
            +
                        end
         | 
| 29 | 
            +
                        l += ',,,,,,,,'
         | 
| 30 | 
            +
                        lines << l
         | 
| 31 | 
            +
                      end
         | 
| 32 | 
            +
                      process(ast)
         | 
| 33 | 
            +
                    end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                    def lines
         | 
| 36 | 
            +
                      @lines ||= []
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    def subdirectory
         | 
| 40 | 
            +
                      'testtable/limits'
         | 
| 41 | 
            +
                    end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                    def on_test(node)
         | 
| 44 | 
            +
                      o = {}
         | 
| 45 | 
            +
                      o[:suite_name] = extract_test_suite_name(node, o)
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                      lines << line(extract_line_options(node, o))
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                      node.find_all(:sub_test).each do |sub_test|
         | 
| 50 | 
            +
                        lines << line(extract_line_options(sub_test, o.dup))
         | 
| 51 | 
            +
                      end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                      process_all(node.children)
         | 
| 54 | 
            +
                    end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                    # Returns true if the AST provided when initializing this limits table generator did not
         | 
| 57 | 
            +
                    # contain any tests, i.e. the resultant limits file is empty
         | 
| 58 | 
            +
                    def empty?
         | 
| 59 | 
            +
                      @empty
         | 
| 60 | 
            +
                    end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                    private
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                    def extract_line_options(node, o)
         | 
| 65 | 
            +
                      o[:test_name] = extract_test_name(node, o)
         | 
| 66 | 
            +
                      o[:test_number] = extract_test_number(node, o)
         | 
| 67 | 
            +
                      o[:limits] = extract_limits(node, o)
         | 
| 68 | 
            +
                      if on_fail = node.find(:on_fail)
         | 
| 69 | 
            +
                        if set_result = on_fail.find(:set_result)
         | 
| 70 | 
            +
                          if bin = set_result.find(:bin)
         | 
| 71 | 
            +
                            o[:bin_h_num] = bin.to_a[0] || o[:bin_h_num]
         | 
| 72 | 
            +
                            o[:bin_h_name] = bin_names[:hard][bin.to_a[0]][:name]
         | 
| 73 | 
            +
                          end
         | 
| 74 | 
            +
                          if sbin = set_result.find(:softbin)
         | 
| 75 | 
            +
                            o[:bin_s_num] = sbin.to_a[0] || o[:bin_s_num]
         | 
| 76 | 
            +
                            o[:bin_s_name] = bin_names[:soft][sbin.to_a[0]][:name]
         | 
| 77 | 
            +
                          end
         | 
| 78 | 
            +
                        end
         | 
| 79 | 
            +
                        delayed = on_fail.find(:delayed)
         | 
| 80 | 
            +
                        if delayed && !delayed.to_a[0]
         | 
| 81 | 
            +
                          o[:bin_overon] = 'no'
         | 
| 82 | 
            +
                        elsif (delayed && delayed.to_a[0]) || tester.delayed_binning
         | 
| 83 | 
            +
                          o[:bin_overon] = 'on'
         | 
| 84 | 
            +
                        else
         | 
| 85 | 
            +
                          o[:bin_overon] = 'no'
         | 
| 86 | 
            +
                        end
         | 
| 87 | 
            +
                      end
         | 
| 88 | 
            +
                      o
         | 
| 89 | 
            +
                    end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                    def extract_limits(node, o)
         | 
| 92 | 
            +
                      modes = test_modes
         | 
| 93 | 
            +
                      lims = {}
         | 
| 94 | 
            +
                      (modes + [nil]).each do |mode|
         | 
| 95 | 
            +
                        lims[mode] = {}
         | 
| 96 | 
            +
                        if node.find(:nolimits)
         | 
| 97 | 
            +
                          lims[mode][:lsl] = nil
         | 
| 98 | 
            +
                          lims[mode][:lsl_typ] = 'NA'
         | 
| 99 | 
            +
                          lims[mode][:usl] = nil
         | 
| 100 | 
            +
                          lims[mode][:usl_typ] = 'NA'
         | 
| 101 | 
            +
                        else
         | 
| 102 | 
            +
                          limits = node.find_all(:limit)
         | 
| 103 | 
            +
                          if limits.empty?
         | 
| 104 | 
            +
                            # Assume it is a functional test in this case
         | 
| 105 | 
            +
                            lims[mode][:lsl] = 0
         | 
| 106 | 
            +
                            lims[mode][:lsl_typ] = 'GE'
         | 
| 107 | 
            +
                            lims[mode][:usl] = 0
         | 
| 108 | 
            +
                            lims[mode][:usl_typ] = 'LE'
         | 
| 109 | 
            +
                          else
         | 
| 110 | 
            +
                            limits.find_all { |l| l.to_a[3].to_s == mode.to_s }.each do |limit|
         | 
| 111 | 
            +
                              limit = limit.to_a
         | 
| 112 | 
            +
                              if limit[1] =~ /^G/i
         | 
| 113 | 
            +
                                lims[mode][:lsl] = limit[0]
         | 
| 114 | 
            +
                                lims[mode][:lsl_typ] = limit[0] ? limit[1].to_s.upcase : nil
         | 
| 115 | 
            +
                                lims[mode][:lsl_typ] = 'GE' if lims[mode][:lsl_typ] == 'GTE'
         | 
| 116 | 
            +
                              else
         | 
| 117 | 
            +
                                lims[mode][:usl] = limit[0]
         | 
| 118 | 
            +
                                lims[mode][:usl_typ] = limit[0] ? limit[1].to_s.upcase : nil
         | 
| 119 | 
            +
                                lims[mode][:usl_typ] = 'LE' if lims[mode][:usl_typ] == 'LTE'
         | 
| 120 | 
            +
                              end
         | 
| 121 | 
            +
                              lims[mode][:units] = limit[2]
         | 
| 122 | 
            +
                            end
         | 
| 123 | 
            +
                          end
         | 
| 124 | 
            +
                        end
         | 
| 125 | 
            +
                      end
         | 
| 126 | 
            +
                      lims
         | 
| 127 | 
            +
                    end
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                    def extract_test_number(node, o)
         | 
| 130 | 
            +
                      number = (node.find(:number) || []).to_a[0]
         | 
| 131 | 
            +
                      if number
         | 
| 132 | 
            +
                        if n1 = @used_test_numbers[number]
         | 
| 133 | 
            +
                          if n1.has_source? && node.has_source?
         | 
| 134 | 
            +
                            Origen.log.error "Test number #{number} has been assigned more than once in limits file #{filename} (flow: #{flowname}):"
         | 
| 135 | 
            +
                            Origen.log.error "  #{n1.source}"
         | 
| 136 | 
            +
                            Origen.log.error "  #{node.source}"
         | 
| 137 | 
            +
                            exit 1
         | 
| 138 | 
            +
                          else
         | 
| 139 | 
            +
                            fail "Test number #{number} cannot be assigned to #{o[:suite_name]} in limits file #{filename} (flow: #{flowname}), since it has already be used for #{@used_test_numbers[number]}!"
         | 
| 140 | 
            +
                          end
         | 
| 141 | 
            +
                        end
         | 
| 142 | 
            +
                        @used_test_numbers[number] = node
         | 
| 143 | 
            +
                        number
         | 
| 144 | 
            +
                      end
         | 
| 145 | 
            +
                    end
         | 
| 146 | 
            +
             | 
| 147 | 
            +
                    def extract_test_suite_name(node, o)
         | 
| 148 | 
            +
                      test_obj = node.find(:object).to_a[0]
         | 
| 149 | 
            +
                      test_obj.respond_to?(:name) ? test_obj.name : test_obj if test_obj
         | 
| 150 | 
            +
                    end
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                    def extract_test_name(node, o)
         | 
| 153 | 
            +
                      (node.find(:name) || []).to_a[0] || extract_test_suite_name(node, o) || o[:suite_name]
         | 
| 154 | 
            +
                    end
         | 
| 155 | 
            +
             | 
| 156 | 
            +
                    def line(options)
         | 
| 157 | 
            +
                      @empty = false
         | 
| 158 | 
            +
                      # "Suite name"
         | 
| 159 | 
            +
                      l = "\"#{options[:suite_name]}\""
         | 
| 160 | 
            +
                      # "Pins"
         | 
| 161 | 
            +
                      l << f(options[:pins])
         | 
| 162 | 
            +
                      # "Test name"
         | 
| 163 | 
            +
                      l << f(options[:test_name])
         | 
| 164 | 
            +
                      # "Test number"
         | 
| 165 | 
            +
                      l << f(options[:test_number])
         | 
| 166 | 
            +
                      if test_modes.empty?
         | 
| 167 | 
            +
                        # "Lsl"
         | 
| 168 | 
            +
                        l << f((options[:limits][nil] || {})[:lsl])
         | 
| 169 | 
            +
                        # "Lsl_typ"
         | 
| 170 | 
            +
                        l << f((options[:limits][nil] || {})[:lsl_typ])
         | 
| 171 | 
            +
                        # "Usl_typ"
         | 
| 172 | 
            +
                        l << f((options[:limits][nil] || {})[:usl_typ])
         | 
| 173 | 
            +
                        # "Usl"
         | 
| 174 | 
            +
                        l << f((options[:limits][nil] || {})[:usl])
         | 
| 175 | 
            +
                        # "Units"
         | 
| 176 | 
            +
                        l << f((options[:limits][nil] || {})[:units])
         | 
| 177 | 
            +
                      else
         | 
| 178 | 
            +
                        test_modes.each do |mode|
         | 
| 179 | 
            +
                          # "Lsl"
         | 
| 180 | 
            +
                          l << f((options[:limits][mode] || options[:limits][nil] || {})[:lsl])
         | 
| 181 | 
            +
                          # "Lsl_typ"
         | 
| 182 | 
            +
                          l << f((options[:limits][mode] || options[:limits][nil] || {})[:lsl_typ])
         | 
| 183 | 
            +
                          # "Usl_typ"
         | 
| 184 | 
            +
                          l << f((options[:limits][mode] || options[:limits][nil] || {})[:usl_typ])
         | 
| 185 | 
            +
                          # "Usl"
         | 
| 186 | 
            +
                          l << f((options[:limits][mode] || options[:limits][nil] || {})[:usl])
         | 
| 187 | 
            +
                          # "Units"
         | 
| 188 | 
            +
                          l << f((options[:limits][mode] || options[:limits][nil] || {})[:units])
         | 
| 189 | 
            +
                        end
         | 
| 190 | 
            +
                      end
         | 
| 191 | 
            +
                      # "Bin_s_num"
         | 
| 192 | 
            +
                      l << f(options[:bin_s_num])
         | 
| 193 | 
            +
                      # "Bin_s_name"
         | 
| 194 | 
            +
                      l << f(options[:bin_s_name])
         | 
| 195 | 
            +
                      # "Bin_h_num"
         | 
| 196 | 
            +
                      l << f(options[:bin_h_num])
         | 
| 197 | 
            +
                      # "Bin_h_name"
         | 
| 198 | 
            +
                      l << f(options[:bin_h_name])
         | 
| 199 | 
            +
                      # "Bin_type"
         | 
| 200 | 
            +
                      l << f(options[:bin_type])
         | 
| 201 | 
            +
                      # "Bin_reprobe"
         | 
| 202 | 
            +
                      l << f(options[:bin_reprobe])
         | 
| 203 | 
            +
                      # "Bin_overon"
         | 
| 204 | 
            +
                      l << f(options[:bin_overon])
         | 
| 205 | 
            +
                      # "Test_remarks"
         | 
| 206 | 
            +
                      l << f(options[:test_remarks])
         | 
| 207 | 
            +
                      l
         | 
| 208 | 
            +
                    end
         | 
| 209 | 
            +
             | 
| 210 | 
            +
                    def f(value)
         | 
| 211 | 
            +
                      ",\"#{value}\""
         | 
| 212 | 
            +
                    end
         | 
| 213 | 
            +
                  end
         | 
| 214 | 
            +
                end
         | 
| 215 | 
            +
              end
         | 
| 216 | 
            +
            end
         | 
| @@ -41,11 +41,19 @@ module OrigenTesters | |
| 41 41 | 
             
                    # end
         | 
| 42 42 |  | 
| 43 43 | 
             
                    def patterns
         | 
| 44 | 
            -
                      (references[:subroutine][:all] + references[:subroutine][:ate] +
         | 
| 44 | 
            +
                      return_arr = (references[:subroutine][:all] + references[:subroutine][:ate] +
         | 
| 45 45 | 
             
                        references[:main][:all] + references[:main][:ate]).map do |p|
         | 
| 46 46 | 
             
                        p = p.strip
         | 
| 47 47 | 
             
                        p += '.binl.gz' unless p =~ /binl.gz$/
         | 
| 48 48 | 
             
                      end.uniq
         | 
| 49 | 
            +
                      if $tester.multiport
         | 
| 50 | 
            +
                        return_arr += (references[:main][:all] + references[:main][:ate]).map do |p|
         | 
| 51 | 
            +
                          p = p.strip
         | 
| 52 | 
            +
                          p = $tester.multiport_name(p)
         | 
| 53 | 
            +
                          p += '.binl.gz' unless p =~ /.binl.gz$/
         | 
| 54 | 
            +
                        end.uniq
         | 
| 55 | 
            +
                      end
         | 
| 56 | 
            +
                      return_arr
         | 
| 49 57 | 
             
                    end
         | 
| 50 58 |  | 
| 51 59 | 
             
                    def references
         | 
| @@ -0,0 +1,64 @@ | |
| 1 | 
            +
            module OrigenTesters
         | 
| 2 | 
            +
              module SmartestBasedTester
         | 
| 3 | 
            +
                class Base
         | 
| 4 | 
            +
                  module Processors
         | 
| 5 | 
            +
                    class ExtractBinNames < ATP::Processor
         | 
| 6 | 
            +
                      def run(node, options = {})
         | 
| 7 | 
            +
                        @bin_names = { soft: {}, hard: {} }
         | 
| 8 | 
            +
                        process(node)
         | 
| 9 | 
            +
                        @bin_names
         | 
| 10 | 
            +
                      end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                      def on_bin_descriptions(node)
         | 
| 13 | 
            +
                        node.children.each do |n|
         | 
| 14 | 
            +
                          number, name = *n
         | 
| 15 | 
            +
                          record number, name, type: n.type
         | 
| 16 | 
            +
                        end
         | 
| 17 | 
            +
                      end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                      def on_test(node)
         | 
| 20 | 
            +
                        if on_fail = node.find(:on_fail)
         | 
| 21 | 
            +
                          if set_result = on_fail.find(:set_result)
         | 
| 22 | 
            +
                            if bin = set_result.find(:bin)
         | 
| 23 | 
            +
                              if bin.to_a[1]
         | 
| 24 | 
            +
                                record(*bin.to_a, supplied: true, type: :hard)
         | 
| 25 | 
            +
                              else
         | 
| 26 | 
            +
                                record(*bin.to_a, default_name(node), type: :hard)
         | 
| 27 | 
            +
                              end
         | 
| 28 | 
            +
                            end
         | 
| 29 | 
            +
                            if sbin = set_result.find(:softbin)
         | 
| 30 | 
            +
                              if sbin.to_a[1]
         | 
| 31 | 
            +
                                record(*sbin.to_a, supplied: true, type: :soft)
         | 
| 32 | 
            +
                              else
         | 
| 33 | 
            +
                                record(*sbin.to_a, default_name(node), type: :soft)
         | 
| 34 | 
            +
                              end
         | 
| 35 | 
            +
                            end
         | 
| 36 | 
            +
                          end
         | 
| 37 | 
            +
                        end
         | 
| 38 | 
            +
                        process_all(node.children)
         | 
| 39 | 
            +
                      end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                      private
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                      def default_name(node)
         | 
| 44 | 
            +
                        test_obj = node.find(:object).to_a[0]
         | 
| 45 | 
            +
                        suite_name = test_obj.respond_to?(:name) ? test_obj.name : test_obj
         | 
| 46 | 
            +
                        test_name = (node.find(:name) || []).to_a[0] || suite_name
         | 
| 47 | 
            +
                        if suite_name == test_name
         | 
| 48 | 
            +
                          suite_name
         | 
| 49 | 
            +
                        else
         | 
| 50 | 
            +
                          "#{suite_name}_#{test_name}"
         | 
| 51 | 
            +
                        end
         | 
| 52 | 
            +
                      end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                      def record(number, name, options)
         | 
| 55 | 
            +
                        table = @bin_names[options[:type]]
         | 
| 56 | 
            +
                        if !table[number] || (options[:supplied] && !table[number][:supplied])
         | 
| 57 | 
            +
                          table[number] = { name: name, supplied: options[:supplied] }
         | 
| 58 | 
            +
                        end
         | 
| 59 | 
            +
                      end
         | 
| 60 | 
            +
                    end
         | 
| 61 | 
            +
                  end
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
              end
         | 
| 64 | 
            +
            end
         | 
| @@ -15,6 +15,7 @@ module OrigenTesters | |
| 15 15 | 
             
                    attr_reader :parameters
         | 
| 16 16 | 
             
                    attr_accessor :class_name
         | 
| 17 17 | 
             
                    attr_accessor :abs_class_name
         | 
| 18 | 
            +
                    attr_reader :limits
         | 
| 18 19 | 
             
                    attr_accessor :limits_id
         | 
| 19 20 |  | 
| 20 21 | 
             
                    def initialize(options)
         | 
| @@ -22,10 +23,6 @@ module OrigenTesters | |
| 22 23 | 
             
                      @library = options[:library]
         | 
| 23 24 | 
             
                      @class_name = options[:methods].delete(:class_name)
         | 
| 24 25 | 
             
                      @parameters = {}
         | 
| 25 | 
            -
                      # Add limits by default
         | 
| 26 | 
            -
                      define_singleton_method('limits') do
         | 
| 27 | 
            -
                        @limits
         | 
| 28 | 
            -
                      end
         | 
| 29 26 | 
             
                      @limits_id = options[:methods].delete(:limits_id)
         | 
| 30 27 | 
             
                      @limits = TestMethods::Limits.new(self)
         | 
| 31 28 | 
             
                      # Add any methods
         | 
| @@ -52,6 +52,17 @@ module OrigenTesters | |
| 52 52 | 
             
                        self.hi_limit = val
         | 
| 53 53 | 
             
                      end
         | 
| 54 54 |  | 
| 55 | 
            +
                      def to_atp_attributes
         | 
| 56 | 
            +
                        r = []
         | 
| 57 | 
            +
                        if lo_limit
         | 
| 58 | 
            +
                          r << { value: lo_limit, rule: 'LE', units: unit }
         | 
| 59 | 
            +
                        end
         | 
| 60 | 
            +
                        if hi_limit
         | 
| 61 | 
            +
                          r << { value: hi_limit, rule: 'GE', units: unit }
         | 
| 62 | 
            +
                        end
         | 
| 63 | 
            +
                        r
         | 
| 64 | 
            +
                      end
         | 
| 65 | 
            +
             | 
| 55 66 | 
             
                      private
         | 
| 56 67 |  | 
| 57 68 | 
             
                      def test_name
         | 
| @@ -130,6 +130,9 @@ module OrigenTesters | |
| 130 130 | 
             
                    end
         | 
| 131 131 |  | 
| 132 132 | 
             
                    def lines
         | 
| 133 | 
            +
                      if pattern
         | 
| 134 | 
            +
                        burst = $tester.multiport ? "#{$tester.multiport_name(pattern)}" : "#{pattern}"
         | 
| 135 | 
            +
                      end
         | 
| 133 136 | 
             
                      l = []
         | 
| 134 137 | 
             
                      l << "  comment = \"#{comment}\";" if comment
         | 
| 135 138 | 
             
                      l << "  ffc_on_fail = #{wrap_if_string(log_first)};" if log_first
         | 
| @@ -139,7 +142,7 @@ module OrigenTesters | |
| 139 142 | 
             
                      l << "  override_lev_equ_set = #{wrap_if_string(level_equation)};" if level_equation
         | 
| 140 143 | 
             
                      l << "  override_lev_spec_set = #{wrap_if_string(level_spec)};" if level_spec
         | 
| 141 144 | 
             
                      l << "  override_levset = #{wrap_if_string(level_set)};" if level_set
         | 
| 142 | 
            -
                      l << "  override_seqlbl = #{wrap_if_string( | 
| 145 | 
            +
                      l << "  override_seqlbl = #{wrap_if_string(burst)};" if pattern
         | 
| 143 146 | 
             
                      l << "  override_test_number = #{test_number};" if test_number
         | 
| 144 147 | 
             
                      l << "  override_testf = #{test_method.id};" if test_method
         | 
| 145 148 | 
             
                      l << "  override_tim_equ_set = #{wrap_if_string(timing_equation)};" if timing_equation
         | 
| @@ -171,6 +174,10 @@ module OrigenTesters | |
| 171 174 | 
             
                      meta || {}
         | 
| 172 175 | 
             
                    end
         | 
| 173 176 |  | 
| 177 | 
            +
                    def extract_atp_attributes(options)
         | 
| 178 | 
            +
                      options[:limits] ||= limits.to_atp_attributes
         | 
| 179 | 
            +
                    end
         | 
| 180 | 
            +
             | 
| 174 181 | 
             
                    private
         | 
| 175 182 |  | 
| 176 183 | 
             
                    def flags
         | 
| @@ -0,0 +1,10 @@ | |
| 1 | 
            +
            module OrigenTesters
         | 
| 2 | 
            +
              module SmartestBasedTester
         | 
| 3 | 
            +
                class V93K
         | 
| 4 | 
            +
                  require 'origen_testers/smartest_based_tester/base/limits_file'
         | 
| 5 | 
            +
                  class LimitsFile < Base::LimitsFile
         | 
| 6 | 
            +
                    TEMPLATE = "#{Origen.root!}/lib/origen_testers/smartest_based_tester/v93k/templates/limits.csv.erb"
         | 
| 7 | 
            +
                  end
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
            end
         | 
| @@ -8,10 +8,25 @@ single_binary_pattern_dir       ./BINL/ | |
| 8 8 |  | 
| 9 9 | 
             
            AI_V2B_OPTIONS  -ALT -c <%= $dut.name.to_s.upcase %>.vbc -k -z PS800
         | 
| 10 10 |  | 
| 11 | 
            +
            % if $tester.multiport
         | 
| 12 | 
            +
            PATTERNS name tmf_file port v2b_options
         | 
| 13 | 
            +
            %   port = !!$tester.multiport ? " #{$tester.multiport}" : ''
         | 
| 14 | 
            +
            % else
         | 
| 11 15 | 
             
            PATTERNS name tmf_file v2b_options
         | 
| 16 | 
            +
            % end
         | 
| 12 17 | 
             
            %   subroutines.each do |pattern|
         | 
| 13 | 
            -
            <%= pattern %> <%= $dut.name.to_s.upcase %>.tmf -s
         | 
| 18 | 
            +
            <%= pattern %> <%= $dut.name.to_s.upcase %>.tmf<%= port %> -s
         | 
| 14 19 | 
             
            %   end
         | 
| 15 20 | 
             
            %   patterns.each do |pattern|
         | 
| 16 | 
            -
            <%= pattern %> <%= $dut.name.to_s.upcase %>.tmf
         | 
| 21 | 
            +
            <%= pattern %> <%= $dut.name.to_s.upcase %>.tmf<%= port %>
         | 
| 17 22 | 
             
            %   end
         | 
| 23 | 
            +
            %#-
         | 
| 24 | 
            +
            % if $tester.multiport
         | 
| 25 | 
            +
            %   patterns.each do |pattern|
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            MULTI_PORT_BURST "<%= "#{$tester.multiport_name(pattern)}" %>" 
         | 
| 28 | 
            +
            PORTS     <%= $tester.multiport %>                                  
         | 
| 29 | 
            +
            SEQ_GRPS  grp1                                  
         | 
| 30 | 
            +
                      <%= pattern %>
         | 
| 31 | 
            +
            %   end
         | 
| 32 | 
            +
            % end
         | 
| @@ -124,6 +124,7 @@ end | |
| 124 124 | 
             
            -----------------------------------------------------------------
         | 
| 125 125 | 
             
            testmethodlimits
         | 
| 126 126 |  | 
| 127 | 
            +
            % unless tester.create_limits_file
         | 
| 127 128 | 
             
            % if program
         | 
| 128 129 | 
             
            %   program.testmethodlimits.each do |id, parameters|
         | 
| 129 130 | 
             
            <%= id %>:
         | 
| @@ -139,6 +140,7 @@ testmethodlimits | |
| 139 140 | 
             
            %     end
         | 
| 140 141 | 
             
            %   end
         | 
| 141 142 | 
             
            % end
         | 
| 143 | 
            +
            % end
         | 
| 142 144 |  | 
| 143 145 | 
             
            end
         | 
| 144 146 | 
             
            -----------------------------------------------------------------
         | 
| @@ -16,10 +16,26 @@ module OrigenTesters | |
| 16 16 | 
             
                  include OrigenJTAG
         | 
| 17 17 |  | 
| 18 18 | 
             
                  def initialize(options = {})
         | 
| 19 | 
            +
                    options = {
         | 
| 20 | 
            +
                      test_generic_overlay_capture: false
         | 
| 21 | 
            +
                    }.merge(options)
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    @test_options = {
         | 
| 24 | 
            +
                      test_generic_overlay_capture: options[:test_generic_overlay_capture]
         | 
| 25 | 
            +
                    }
         | 
| 26 | 
            +
             | 
| 19 27 | 
             
                    add_pin :tclk
         | 
| 20 28 | 
             
                    add_pin :tdi
         | 
| 21 29 | 
             
                    add_pin :tdo
         | 
| 22 30 | 
             
                    add_pin :tms
         | 
| 31 | 
            +
                    if @test_options[:test_generic_overlay_capture]
         | 
| 32 | 
            +
                      # approved patts for this test type do not use these
         | 
| 33 | 
            +
                      add_pin :pa0
         | 
| 34 | 
            +
                      add_pin :pa1
         | 
| 35 | 
            +
                      add_pin :pa2
         | 
| 36 | 
            +
                      add_pin_group :pa, :pa2, :pa1, :pa0
         | 
| 37 | 
            +
                      add_pin_alias :tdi_a, :tdi
         | 
| 38 | 
            +
                    end
         | 
| 23 39 | 
             
                    # add_pin_group :jtag, :tdi, :tdo, :tms
         | 
| 24 40 | 
             
                    add_power_pin_group :vdd1
         | 
| 25 41 | 
             
                    add_power_pin_group :vdd2
         | 
| @@ -32,23 +48,28 @@ module OrigenTesters | |
| 32 48 | 
             
                      reg.bits 1,      :done
         | 
| 33 49 | 
             
                      reg.bits 0,      :enable
         | 
| 34 50 | 
             
                    end
         | 
| 35 | 
            -
                    @ | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 51 | 
            +
                    unless @test_options[:test_generic_overlay_capture]
         | 
| 52 | 
            +
                      # approved patts for this test type do not use these
         | 
| 53 | 
            +
                      @hv_supply_pin = 'VDDHV'
         | 
| 54 | 
            +
                      @lv_supply_pin = 'VDDLV'
         | 
| 55 | 
            +
                      @digsrc_pins = [:tdi, :tms]
         | 
| 56 | 
            +
                      @digsrc_settings = { digsrc_mode: :parallel, digsrc_bit_order: :msb }
         | 
| 57 | 
            +
                      @digcap_pins = :tdo
         | 
| 58 | 
            +
                      @digcap_settings = { digcap_format: :twos_complement }
         | 
| 59 | 
            +
                    end
         | 
| 41 60 | 
             
                    @blocks = [Block.new(0, self), Block.new(1, self), Block.new(2, self)]
         | 
| 42 61 | 
             
                  end
         | 
| 43 62 |  | 
| 44 63 | 
             
                  def on_create
         | 
| 45 | 
            -
                     | 
| 46 | 
            -
                      tester. | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 64 | 
            +
                    unless @test_options[:test_generic_overlay_capture]
         | 
| 65 | 
            +
                      if tester && tester.uflex?
         | 
| 66 | 
            +
                        tester.assign_dc_instr_pins([hv_supply_pin, lv_supply_pin])
         | 
| 67 | 
            +
                        tester.assign_digsrc_pins(digsrc_pins)
         | 
| 68 | 
            +
                        tester.apply_digsrc_settings(digsrc_settings)
         | 
| 69 | 
            +
                        tester.assign_digcap_pins(digcap_pins)
         | 
| 70 | 
            +
                        tester.apply_digcap_settings(digcap_settings)
         | 
| 71 | 
            +
                        tester.memory_test_en = true
         | 
| 72 | 
            +
                      end
         | 
| 52 73 | 
             
                    end
         | 
| 53 74 | 
             
                  end
         | 
| 54 75 |  | 
    
        data/program/test.rb
    CHANGED
    
    | @@ -10,16 +10,21 @@ Flow.create interface: 'OrigenTesters::Test::Interface' do | |
| 10 10 |  | 
| 11 11 | 
             
            #  para 'charge_pump', :high_voltage => true, :lo_limit => 5, :hi_limit => 6
         | 
| 12 12 |  | 
| 13 | 
            +
              if tester.v93k? && tester.create_limits_file
         | 
| 14 | 
            +
                func :program_ckbd, :number => 1000, :bin => 100, :soft_bin => 1100
         | 
| 15 | 
            +
              end
         | 
| 13 16 | 
             
              meas :read_pump, tnum: 1050, bin: 119, soft_bin: 2, lo_limit: 35, number: 40000
         | 
| 14 | 
            -
              meas :read_pump, tnum:  | 
| 15 | 
            -
              meas :read_pump, tnum:  | 
| 16 | 
            -
              meas :read_pump, tnum:  | 
| 17 | 
            -
              meas :read_pump, tnum:  | 
| 18 | 
            -
              meas :read_pump, tnum:  | 
| 19 | 
            -
              meas :read_pump, tnum:  | 
| 20 | 
            -
               | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 17 | 
            +
              meas :read_pump, tnum: 1060, bin: 119, soft_bin: 2, hi_limit: 45, number: 40010
         | 
| 18 | 
            +
              meas :read_pump, tnum: 1070, bin: 119, soft_bin: 2, hi_limit: 45, lo_limit: 35, number: 40020
         | 
| 19 | 
            +
              meas :read_pump, tnum: 1080, bin: 119, soft_bin: 2, hi_limit: 45, lo_limit: 35, number: 40030
         | 
| 20 | 
            +
              meas :read_pump, tnum: 1090, bin: 119, soft_bin: 2, hi_limit: 45.mV, lo_limit: 35.mV, number: 40040
         | 
| 21 | 
            +
              meas :read_pump, tnum: 1100, bin: 119, soft_bin: 2, hi_limit: 45.mV, lo_limit: 35.mV, continue: true, number: 40050
         | 
| 22 | 
            +
              meas :read_pump, tnum: 1110, bin: 119, soft_bin: 2, hi_limit: 2000, lo_limit: 0.01, continue: true, number: 40060
         | 
| 23 | 
            +
              unless tester.v93k? && tester.create_limits_file
         | 
| 24 | 
            +
                meas :read_pump, tnum: 1120, bin: 119, soft_bin: 2, hi_limit: "_some_spec", lo_limit: 0.01, continue: true, number: 40070
         | 
| 25 | 
            +
                meas :read_pump, tnum: 1130, bin: 119, soft_bin: 2, hi_limit: [1, 2], number: 40080
         | 
| 26 | 
            +
                meas :read_pump, tnum: 1140, bin: 119, soft_bin: 2, lo_limit: [1.uA, 2.uA, 3.uA], hi_limit: [4.uA,5.uA], units: "A", defer_limits: true, number: 40090
         | 
| 27 | 
            +
              end
         | 
| 23 28 |  | 
| 24 29 | 
             
              if tester.uflex?
         | 
| 25 30 | 
             
                log "Test of ultraflex render API"
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: origen_testers
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.19.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Stephen McGinty
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2018- | 
| 11 | 
            +
            date: 2018-05-02 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: origen
         | 
| @@ -254,9 +254,10 @@ files: | |
| 254 254 | 
             
            - lib/origen_testers/smartest_based_tester/base.rb
         | 
| 255 255 | 
             
            - lib/origen_testers/smartest_based_tester/base/flow.rb
         | 
| 256 256 | 
             
            - lib/origen_testers/smartest_based_tester/base/generator.rb
         | 
| 257 | 
            +
            - lib/origen_testers/smartest_based_tester/base/limits_file.rb
         | 
| 257 258 | 
             
            - lib/origen_testers/smartest_based_tester/base/pattern_compiler.rb
         | 
| 258 259 | 
             
            - lib/origen_testers/smartest_based_tester/base/pattern_master.rb
         | 
| 259 | 
            -
            - lib/origen_testers/smartest_based_tester/base/processors/ | 
| 260 | 
            +
            - lib/origen_testers/smartest_based_tester/base/processors/extract_bin_names.rb
         | 
| 260 261 | 
             
            - lib/origen_testers/smartest_based_tester/base/test_method.rb
         | 
| 261 262 | 
             
            - lib/origen_testers/smartest_based_tester/base/test_methods.rb
         | 
| 262 263 | 
             
            - lib/origen_testers/smartest_based_tester/base/test_methods/ac_tml.rb
         | 
| @@ -273,8 +274,10 @@ files: | |
| 273 274 | 
             
            - lib/origen_testers/smartest_based_tester/v93k/builder/pattern_master.rb
         | 
| 274 275 | 
             
            - lib/origen_testers/smartest_based_tester/v93k/flow.rb
         | 
| 275 276 | 
             
            - lib/origen_testers/smartest_based_tester/v93k/generator.rb
         | 
| 277 | 
            +
            - lib/origen_testers/smartest_based_tester/v93k/limits_file.rb
         | 
| 276 278 | 
             
            - lib/origen_testers/smartest_based_tester/v93k/pattern_compiler.rb
         | 
| 277 279 | 
             
            - lib/origen_testers/smartest_based_tester/v93k/pattern_master.rb
         | 
| 280 | 
            +
            - lib/origen_testers/smartest_based_tester/v93k/templates/limits.csv.erb
         | 
| 278 281 | 
             
            - lib/origen_testers/smartest_based_tester/v93k/templates/template.aiv.erb
         | 
| 279 282 | 
             
            - lib/origen_testers/smartest_based_tester/v93k/templates/template.pmfl.erb
         | 
| 280 283 | 
             
            - lib/origen_testers/smartest_based_tester/v93k/templates/template.tf.erb
         | 
| @@ -289,7 +292,6 @@ files: | |
| 289 292 | 
             
            - lib/origen_testers/test/custom_test_interface.rb
         | 
| 290 293 | 
             
            - lib/origen_testers/test/dut.rb
         | 
| 291 294 | 
             
            - lib/origen_testers/test/dut2.rb
         | 
| 292 | 
            -
            - lib/origen_testers/test/dut3.rb
         | 
| 293 295 | 
             
            - lib/origen_testers/test/interface.rb
         | 
| 294 296 | 
             
            - lib/origen_testers/test/nvm.rb
         | 
| 295 297 | 
             
            - lib/origen_testers/timing.rb
         | 
| @@ -362,7 +364,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 362 364 | 
             
                  version: '0'
         | 
| 363 365 | 
             
            requirements: []
         | 
| 364 366 | 
             
            rubyforge_project: 
         | 
| 365 | 
            -
            rubygems_version: 2.6. | 
| 367 | 
            +
            rubygems_version: 2.6.7
         | 
| 366 368 | 
             
            signing_key: 
         | 
| 367 369 | 
             
            specification_version: 4
         | 
| 368 370 | 
             
            summary: This plugin provides Origen tester models to drive ATE type testers like
         | 
| @@ -1,22 +0,0 @@ | |
| 1 | 
            -
            module OrigenTesters
         | 
| 2 | 
            -
              module SmartestBasedTester
         | 
| 3 | 
            -
                class Base
         | 
| 4 | 
            -
                  module Processors
         | 
| 5 | 
            -
                    # Extracts all runtime variables which are set within the given flow, returning
         | 
| 6 | 
            -
                    # them in an array
         | 
| 7 | 
            -
                    class ExtractSetVariables < ATP::Processor
         | 
| 8 | 
            -
                      def run(nodes)
         | 
| 9 | 
            -
                        @results = []
         | 
| 10 | 
            -
                        process_all(nodes)
         | 
| 11 | 
            -
                        @results.uniq
         | 
| 12 | 
            -
                      end
         | 
| 13 | 
            -
             | 
| 14 | 
            -
                      def on_set_flag(node)
         | 
| 15 | 
            -
                        flag = node.value
         | 
| 16 | 
            -
                        @results << flag
         | 
| 17 | 
            -
                      end
         | 
| 18 | 
            -
                    end
         | 
| 19 | 
            -
                  end
         | 
| 20 | 
            -
                end
         | 
| 21 | 
            -
              end
         | 
| 22 | 
            -
            end
         | 
| @@ -1,244 +0,0 @@ | |
| 1 | 
            -
            module OrigenTesters
         | 
| 2 | 
            -
              module Test
         | 
| 3 | 
            -
                class DUT3
         | 
| 4 | 
            -
                  # Simple DUT using Nexus interface
         | 
| 5 | 
            -
             | 
| 6 | 
            -
                  attr_accessor :blocks
         | 
| 7 | 
            -
                  attr_accessor :hv_supply_pin
         | 
| 8 | 
            -
                  attr_accessor :lv_supply_pin
         | 
| 9 | 
            -
                  attr_accessor :digsrc_pins
         | 
| 10 | 
            -
                  attr_accessor :digcap_pins
         | 
| 11 | 
            -
                  attr_accessor :digsrc_settings
         | 
| 12 | 
            -
                  attr_accessor :digcap_settings
         | 
| 13 | 
            -
             | 
| 14 | 
            -
                  include OrigenARMDebug
         | 
| 15 | 
            -
                  include Origen::TopLevel
         | 
| 16 | 
            -
                  include OrigenJTAG
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                  def initialize(options = {})
         | 
| 19 | 
            -
                    add_pin :tclk
         | 
| 20 | 
            -
                    add_pin :tdi
         | 
| 21 | 
            -
                    add_pin :tdo
         | 
| 22 | 
            -
                    add_pin :tms
         | 
| 23 | 
            -
                    add_pin :pa0
         | 
| 24 | 
            -
                    add_pin :pa1
         | 
| 25 | 
            -
                    add_pin :pa2
         | 
| 26 | 
            -
                    add_pin_group :pa, :pa2, :pa1, :pa0
         | 
| 27 | 
            -
                    add_pin_alias :tdi_a, :tdi
         | 
| 28 | 
            -
                    # add_pin_group :jtag, :tdi, :tdo, :tms
         | 
| 29 | 
            -
                    add_power_pin_group :vdd1
         | 
| 30 | 
            -
                    add_power_pin_group :vdd2
         | 
| 31 | 
            -
                    add_virtual_pin :virtual1, type: :virtual_pin
         | 
| 32 | 
            -
                    add_virtual_pin :virtual2, type: :ate_ch
         | 
| 33 | 
            -
             | 
| 34 | 
            -
                    reg :testme32, 0x007a do |reg|
         | 
| 35 | 
            -
                      reg.bits 31..16, :portB
         | 
| 36 | 
            -
                      reg.bits 15..8,  :portA
         | 
| 37 | 
            -
                      reg.bits 1,      :done
         | 
| 38 | 
            -
                      reg.bits 0,      :enable
         | 
| 39 | 
            -
                    end
         | 
| 40 | 
            -
                    @blocks = [Block.new(0, self), Block.new(1, self), Block.new(2, self)]
         | 
| 41 | 
            -
                  end
         | 
| 42 | 
            -
             | 
| 43 | 
            -
                  def startup(options)
         | 
| 44 | 
            -
                    $tester.set_timeset('tp0', 60)
         | 
| 45 | 
            -
                  end
         | 
| 46 | 
            -
             | 
| 47 | 
            -
                  def write_register(reg, options = {})
         | 
| 48 | 
            -
                    arm_debug.write_register(reg, options)
         | 
| 49 | 
            -
                  end
         | 
| 50 | 
            -
             | 
| 51 | 
            -
                  def read_register(reg, options = {})
         | 
| 52 | 
            -
                    arm_debug.write_register(reg, options)
         | 
| 53 | 
            -
                  end
         | 
| 54 | 
            -
             | 
| 55 | 
            -
                  def execute(options = {})
         | 
| 56 | 
            -
                    options = { define:    false,          # whether to define subr or call it
         | 
| 57 | 
            -
                                name:      'executefunc1',
         | 
| 58 | 
            -
                                onemodsub: false        # whether to expects subr to be in single module
         | 
| 59 | 
            -
                            }.merge(options)
         | 
| 60 | 
            -
             | 
| 61 | 
            -
                    if options[:define]
         | 
| 62 | 
            -
                      # define subroutine
         | 
| 63 | 
            -
                      $tester.start_subroutine(options[:name], onemodsub: options[:onemodsub])
         | 
| 64 | 
            -
                      $tester.cycle
         | 
| 65 | 
            -
                      $tester.end_subroutine(onemodsub: options[:onemodsub])
         | 
| 66 | 
            -
                      $tester.cycle unless options[:onemodsub]
         | 
| 67 | 
            -
                    else
         | 
| 68 | 
            -
                      # call subroutine
         | 
| 69 | 
            -
                      $tester.cycle
         | 
| 70 | 
            -
                      $tester.call_subroutine(options[:name])
         | 
| 71 | 
            -
                      $tester.cycle
         | 
| 72 | 
            -
                    end
         | 
| 73 | 
            -
                  end
         | 
| 74 | 
            -
             | 
| 75 | 
            -
                  # Match loop functionality
         | 
| 76 | 
            -
                  def match(options = {})
         | 
| 77 | 
            -
                    options = { type:        :match_pin,    # whether to match DONE bit in register or match pin
         | 
| 78 | 
            -
                                # :match_done
         | 
| 79 | 
            -
                                # :match_2pins
         | 
| 80 | 
            -
                                delay_in_us: 5,           # match loop delay
         | 
| 81 | 
            -
                                define:      false,       # whether to define subr or call it
         | 
| 82 | 
            -
                                subr_name:   false,       # default use match type as subr name
         | 
| 83 | 
            -
                            }.merge(options)
         | 
| 84 | 
            -
             | 
| 85 | 
            -
                    subr_name = options[:subr_name] ? options[:subr_name] : options[:type].to_s
         | 
| 86 | 
            -
             | 
| 87 | 
            -
                    if options[:define]
         | 
| 88 | 
            -
                      $tester.start_subroutine(subr_name)
         | 
| 89 | 
            -
                      $tester.cycle
         | 
| 90 | 
            -
                      if options[:type] == :match_done
         | 
| 91 | 
            -
             | 
| 92 | 
            -
                        # Match DONE bit in register
         | 
| 93 | 
            -
                        $tester.wait(match:                 true,
         | 
| 94 | 
            -
                                     time_in_us:            options[:delay_in_us],
         | 
| 95 | 
            -
                                     global_loops:          true,
         | 
| 96 | 
            -
                                     check_for_fails:       true,
         | 
| 97 | 
            -
                                     force_fail_on_timeout: true,
         | 
| 98 | 
            -
                                     clr_fail_post_match:   true,
         | 
| 99 | 
            -
                                     manual_stop:           true) do
         | 
| 100 | 
            -
                          # Match on reading done bit
         | 
| 101 | 
            -
                          reg(:testme32).bits(:done).write(1)
         | 
| 102 | 
            -
                          reg(:testme32).bits(:done).read!
         | 
| 103 | 
            -
                        end
         | 
| 104 | 
            -
                      elsif options[:type] == :match_pin
         | 
| 105 | 
            -
                        # Match on TDO pin state
         | 
| 106 | 
            -
                        $tester.wait(match:                 true,
         | 
| 107 | 
            -
                                     pin:                   pin(:tdo),
         | 
| 108 | 
            -
                                     state:                 :high,
         | 
| 109 | 
            -
                                     time_in_us:            options[:delay_in_us],
         | 
| 110 | 
            -
                                     global_loops:          true,
         | 
| 111 | 
            -
                                     check_for_fails:       true,
         | 
| 112 | 
            -
                                     force_fail_on_timeout: true,
         | 
| 113 | 
            -
                                     clr_fail_post_match:   true,
         | 
| 114 | 
            -
                                     manual_stop:           true)
         | 
| 115 | 
            -
                      elsif options[:type] == :match_2pins
         | 
| 116 | 
            -
                        # Match on TDO pin state
         | 
| 117 | 
            -
                        $tester.wait(match:                 true,
         | 
| 118 | 
            -
                                     pin:                   pin(:tdo),
         | 
| 119 | 
            -
                                     state:                 :high,
         | 
| 120 | 
            -
                                     pin2:                  pin(:tms),
         | 
| 121 | 
            -
                                     state2:                :high,
         | 
| 122 | 
            -
                                     time_in_us:            options[:delay_in_us],
         | 
| 123 | 
            -
                                     global_loops:          true,
         | 
| 124 | 
            -
                                     check_for_fails:       true,
         | 
| 125 | 
            -
                                     force_fail_on_timeout: true,
         | 
| 126 | 
            -
                                     clr_fail_post_match:   true,
         | 
| 127 | 
            -
                                     manual_stop:           true)
         | 
| 128 | 
            -
                      elsif options[:type] == :multiple_entries
         | 
| 129 | 
            -
                        # Match on TDO pin state, with multiple subr entry points
         | 
| 130 | 
            -
                        $tester.wait(match:                 true,
         | 
| 131 | 
            -
                                     pin:                   pin(:tdo),
         | 
| 132 | 
            -
                                     state:                 :high,
         | 
| 133 | 
            -
                                     time_in_us:            options[:delay_in_us],
         | 
| 134 | 
            -
                                     global_loops:          true,
         | 
| 135 | 
            -
                                     multiple_entries:      true,
         | 
| 136 | 
            -
                                     check_for_fails:       true,
         | 
| 137 | 
            -
                                     force_fail_on_timeout: true,
         | 
| 138 | 
            -
                                     clr_fail_post_match:   true,
         | 
| 139 | 
            -
                                     manual_stop:           true)
         | 
| 140 | 
            -
                      end
         | 
| 141 | 
            -
                      $tester.cycle
         | 
| 142 | 
            -
                      $tester.end_subroutine
         | 
| 143 | 
            -
                      $tester.cycle
         | 
| 144 | 
            -
                    else
         | 
| 145 | 
            -
                      # call subroutine
         | 
| 146 | 
            -
                      $tester.cycle
         | 
| 147 | 
            -
                      $tester.call_subroutine(subr_name)
         | 
| 148 | 
            -
                      $tester.cycle
         | 
| 149 | 
            -
                    end
         | 
| 150 | 
            -
                  end
         | 
| 151 | 
            -
             | 
| 152 | 
            -
                  def handshake(options = {})
         | 
| 153 | 
            -
                    options = {
         | 
| 154 | 
            -
                      define: false,          # whether to define subr or call it
         | 
| 155 | 
            -
                    }.merge(options)
         | 
| 156 | 
            -
             | 
| 157 | 
            -
                    if options[:define]
         | 
| 158 | 
            -
                      $tester.start_subroutine('handshake')
         | 
| 159 | 
            -
                      $tester.handshake(readcode: 100)
         | 
| 160 | 
            -
                      $tester.cycle
         | 
| 161 | 
            -
                      $tester.cycle
         | 
| 162 | 
            -
                      $tester.cycle
         | 
| 163 | 
            -
                      $tester.end_subroutine
         | 
| 164 | 
            -
                    else
         | 
| 165 | 
            -
                      $tester.cycle
         | 
| 166 | 
            -
                      $tester.call_subroutine('handshake')
         | 
| 167 | 
            -
                    end
         | 
| 168 | 
            -
                  end
         | 
| 169 | 
            -
             | 
| 170 | 
            -
                  def digsrc_overlay(options = {})
         | 
| 171 | 
            -
                    options = { define:            false,       # whether to define subr or call it
         | 
| 172 | 
            -
                                subr_name:         false,       # default use match type as subr name
         | 
| 173 | 
            -
                                digsrc_pins:       @digsrc_pins, # defaults to what's defined in $dut
         | 
| 174 | 
            -
                                overlay_reg:       nil, # defaults to testme32 register
         | 
| 175 | 
            -
                                overlay_cycle_num: 32, # Only needed if overlay_reg is NOT nil, this specificies how many clk cycles to overlay.
         | 
| 176 | 
            -
                            }.merge(options)
         | 
| 177 | 
            -
                    if options[:define]
         | 
| 178 | 
            -
                      $tester.start_subroutine(options[:subr_name]) # Start subroutine
         | 
| 179 | 
            -
                      digsrc_pins = $tester.assign_digsrc_pins(options[:digsrc_pins])
         | 
| 180 | 
            -
                      $tester.digsrc_start(digsrc_pins, dssc_mode: :single)
         | 
| 181 | 
            -
                      original_pin_states = {}
         | 
| 182 | 
            -
                      digsrc_pins.each do |pin|
         | 
| 183 | 
            -
                        original_pin_states.merge!(pin => pin(pin).data)
         | 
| 184 | 
            -
                        pin(pin).drive_mem
         | 
| 185 | 
            -
                      end
         | 
| 186 | 
            -
                      if options[:overlay_reg].nil?
         | 
| 187 | 
            -
                        options[:overlay_cycle_num].times do
         | 
| 188 | 
            -
                          $tester.digsrc_send(digsrc_pins)
         | 
| 189 | 
            -
                          $tester.cycle
         | 
| 190 | 
            -
                        end
         | 
| 191 | 
            -
                      else
         | 
| 192 | 
            -
                        $tester.dont_compress = true
         | 
| 193 | 
            -
                        options[:overlay_reg].size.times do
         | 
| 194 | 
            -
                          $tester.digsrc_send(digsrc_pins)
         | 
| 195 | 
            -
                          $tester.cycle
         | 
| 196 | 
            -
                        end
         | 
| 197 | 
            -
                      end
         | 
| 198 | 
            -
                      original_pin_states.each do |pin, state|
         | 
| 199 | 
            -
                        pin(pin).drive(state)
         | 
| 200 | 
            -
                      end
         | 
| 201 | 
            -
                      $tester.digsrc_stop(digsrc_pins)
         | 
| 202 | 
            -
                      $tester.cycle
         | 
| 203 | 
            -
                      $tester.end_subroutine # end subroutine
         | 
| 204 | 
            -
                    else
         | 
| 205 | 
            -
                      $tester.cycle
         | 
| 206 | 
            -
                      $tester.call_subroutine(options[:subr_name])
         | 
| 207 | 
            -
                    end
         | 
| 208 | 
            -
                  end
         | 
| 209 | 
            -
             | 
| 210 | 
            -
                  def memory_test(options = {})
         | 
| 211 | 
            -
                    options = {
         | 
| 212 | 
            -
                    }.merge(options)
         | 
| 213 | 
            -
             | 
| 214 | 
            -
                    $tester.memory_test(inc_counter_x: true, gen_vector: true)
         | 
| 215 | 
            -
             | 
| 216 | 
            -
                    $tester.memory_test(inc_counter_y: true, gen_vector: true)
         | 
| 217 | 
            -
             | 
| 218 | 
            -
                    $tester.memory_test(init_counter_x: true)
         | 
| 219 | 
            -
             | 
| 220 | 
            -
                    $tester.memory_test(inc_counter_x: true, init_counter_y: true)
         | 
| 221 | 
            -
             | 
| 222 | 
            -
                    $tester.memory_test(inc_counter_y: true, capture_vector: true)
         | 
| 223 | 
            -
             | 
| 224 | 
            -
                    $tester.memory_test(pin: pin(:tdo), pin_data: :expect)
         | 
| 225 | 
            -
                  end
         | 
| 226 | 
            -
             | 
| 227 | 
            -
                  def freq_count(options = {})
         | 
| 228 | 
            -
                    options = {
         | 
| 229 | 
            -
                    }.merge(options)
         | 
| 230 | 
            -
             | 
| 231 | 
            -
                    $tester.freq_count($dut.pin(:tdo), readcode: 73)
         | 
| 232 | 
            -
                  end
         | 
| 233 | 
            -
             | 
| 234 | 
            -
                  # dummy flag to check for a particular design bug for this DUT
         | 
| 235 | 
            -
                  def has_margin0_bug?
         | 
| 236 | 
            -
                    false
         | 
| 237 | 
            -
                  end
         | 
| 238 | 
            -
             | 
| 239 | 
            -
                  def find_block_by_id(id)
         | 
| 240 | 
            -
                    @blocks.find { |block| block.id == id }
         | 
| 241 | 
            -
                  end
         | 
| 242 | 
            -
                end
         | 
| 243 | 
            -
              end
         | 
| 244 | 
            -
            end
         |