origen_testers 0.19.0 → 0.19.2

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/config/application.rb +34 -1
  3. data/config/version.rb +1 -1
  4. data/lib/origen_testers/flow.rb +1 -0
  5. data/lib/origen_testers/interface.rb +28 -0
  6. data/lib/origen_testers/pattern_compilers/v93k.rb +3 -1
  7. data/lib/origen_testers/smartest_based_tester/base.rb +14 -1
  8. data/lib/origen_testers/smartest_based_tester/base/test_methods/ac_tml.rb +10 -10
  9. data/lib/origen_testers/test/interface.rb +3 -0
  10. data/pattern/tester_overlay.rb +12 -1
  11. data/program/_erase.rb +1 -1
  12. data/program/components/_prb1_main.rb +3 -3
  13. data/program/test.rb +2 -2
  14. data/templates/origen_guides/pattern/common.md.erb +376 -0
  15. data/templates/origen_guides/pattern/creating.md.erb +133 -0
  16. data/templates/origen_guides/pattern/custom.md.erb +5 -0
  17. data/templates/origen_guides/pattern/documenting.md.erb +431 -0
  18. data/templates/origen_guides/pattern/introduction.md.erb +38 -0
  19. data/templates/origen_guides/pattern/j750.md.erb +10 -0
  20. data/templates/origen_guides/pattern/name.md.erb +511 -0
  21. data/templates/origen_guides/pattern/pins.md.erb +125 -0
  22. data/templates/origen_guides/pattern/registers.md.erb +300 -0
  23. data/templates/origen_guides/pattern/running.md.erb +105 -0
  24. data/templates/origen_guides/pattern/timing.md.erb +281 -0
  25. data/templates/origen_guides/pattern/ultraflex.md.erb +10 -0
  26. data/templates/origen_guides/pattern/v93k.md.erb +41 -0
  27. data/templates/origen_guides/program/code.md.erb +78 -0
  28. data/templates/origen_guides/program/custom.md.erb +5 -0
  29. data/templates/origen_guides/program/doc.md.erb +402 -0
  30. data/templates/origen_guides/program/flowapi.md.erb +249 -0
  31. data/templates/origen_guides/program/flows.md.erb +429 -0
  32. data/templates/origen_guides/program/generating.md.erb +97 -0
  33. data/templates/origen_guides/program/interface.md.erb +248 -0
  34. data/templates/origen_guides/program/introduction.md.erb +56 -0
  35. data/templates/origen_guides/program/j750.md.erb +514 -0
  36. data/templates/origen_guides/program/philosophy.md.erb +99 -0
  37. data/templates/origen_guides/program/resources.md.erb +141 -0
  38. data/templates/origen_guides/program/ultraflex.md.erb +5 -0
  39. data/templates/origen_guides/program/v93k.md.erb +456 -0
  40. data/templates/web/layouts/_guides.html.erb +10 -0
  41. data/templates/web/partials/_placeholder.md.erb +10 -0
  42. metadata +33 -5
@@ -0,0 +1,99 @@
1
+ % render "layouts/guides.html" do
2
+
3
+ Documentation of a test program is important to allow non-test-engineering stakeholders
4
+ to understand what is in a given program, or what a given bin number refers to.
5
+ So Origen fully embraces the notion that test programs should be documented, that
6
+ this documentation should not have an opportunity to be wrong, and that no one
7
+ should have to waste their time manually trying to keep a document and the program
8
+ in sync.
9
+
10
+ However many tools in this area approach this
11
+ problem by trying to turn documentation into a test program.
12
+ Origen turns this problem on its head and unashamedly asserts that the test program
13
+ itself is the true source of authority as to what it does, and that documentation
14
+ is the follower instead of the leader.
15
+
16
+ This approach has the following advantages:
17
+
18
+ * Test programs are large and complex, who really wants to write the whole thing
19
+ out manually? It is much more efficient (and less error prone) to write it in code,
20
+ then we can use subroutines, variables, object-orientation, meta-programming (code
21
+ that generates other code) and any other programming
22
+ techniques to eliminate duplication and opportunities for error.
23
+ * Document first approaches are always constrained by the fact that some tests are
24
+ more complicated than others. In a recent industry conference a leading document-first
25
+ generator stated that typically it could handle 80% of tests, for the other 20%
26
+ you were on your own. With Origen's approach 100% of your tests will be generated.
27
+
28
+ #### The Chicken and the Egg Problem
29
+
30
+ One problem with the Origen approach is how do you bootstrap a new program, intuitively
31
+ you may want to document it first.
32
+
33
+ This problem can be solved via the following workflow:
34
+
35
+ * The Flow file syntax is designed to be as simple and human-readable as possible,
36
+ and it is self contained and can exist long before any interfaces are ever written.
37
+ Therefore it you know enough to be able to write a document of a flow, then you
38
+ know enough to be able to write an Origen flow file for that flow.
39
+ * Nonetheless some early stakeholders may want to get involved in the definition
40
+ but won't feel comfortable with the code layer. In this case it is recommended
41
+ that you immediately setup a documentation interface (these are trivially simple
42
+ and will probably eventually come from free with Origen), and begin generating
43
+ documentation of the flow from day 1.
44
+ * Definition can continue as required by iterating on the flow file, all the while
45
+ the documentation stays in sync.
46
+ * When it comes to finally implementing the flow the test engineering team will
47
+ create the interface which will turn it into a real test program.
48
+
49
+ An alternative approach is to have a short-lived hand-written document that is used
50
+ to get the team up to the first release of the test program. At that point authority
51
+ should switch to the program itself and a ticketing system should be used to iterate on
52
+ the program...
53
+
54
+ #### How Do I Specify a Program Change if I Don't Know How to Code?
55
+
56
+ The underlying program application should use a ticketing system.
57
+ Any non-test-engineering stake holders can review the documentation to see what the test program
58
+ currently does, then if they want it to do something else they will raise a ticket
59
+ requesting it.
60
+
61
+ Once the change has been implemented the ticket can be closed and the documentation
62
+ will automatically pick up the change.
63
+
64
+ This workflow is much easier to monitor and track status vs. the alternative approach where
65
+ the non-technical stakeholder release new versions of a document and the TE has the job of trying
66
+ to keep the program in sync.
67
+
68
+ #### But I already have a document containing a lot of my test details!
69
+
70
+ As the flow file is written in Ruby, it is perfectly feasible to build higher level structures
71
+ such as an importer, or even a spreadsheet-based interface on top of this.
72
+
73
+ The early users of the Origen test program generator have not had a need for such an approach,
74
+ however this is definitely an area where the [community](<%= path "community" %>) could start
75
+ to build new features.
76
+
77
+ #### Shouldn't a Program Generator build me a complete test?
78
+
79
+ It's Origen's job to provide a solid generation platform, however it deliberately does not
80
+ try to dictate how a functional/parametric/bitmap/ATD ramp/etc. test should be set up.
81
+ Firstly the scope of such an effort is too large, but secondly the Origen developers do
82
+ not necessarily have the knowledge required to dictate what is the best practice
83
+ in a lot of these areas.
84
+
85
+ However the idea of eliminating the interface layer is appealing and the good news is
86
+ that it is achievable.
87
+
88
+ The [Origen Plugins](<%= path "guides/plugins/introduction" %>) feature provides a way
89
+ for Origen code to be easily packaged into a re-usable plugin and shared between projects. So for
90
+ example, an ATD interface module could be written and then anyone wishing to create ATD
91
+ tests, could import this into their application and completely bypass the interface
92
+ creation step altogether. Just call the interface methods from the flow file and you will get a
93
+ guaranteed working (and hopefully efficient!) ATD test.
94
+
95
+ If you are a test expert in a given area, and you are using Origen to generate your program,
96
+ then we would encourage you to share your expertize by making your test setups available
97
+ as an Origen plugin.
98
+
99
+ % end
@@ -0,0 +1,141 @@
1
+ % render "layouts/guides.html" do
2
+
3
+ When generating a complete test program it may be necessary to build some components
4
+ that don't naturally fall out of the regular flow generation.
5
+ Some examples of this might be:
6
+
7
+ * Creating a test which does not have a flow entry, but perhaps you want to keep it
8
+ available in your program for engineering use.
9
+ * Creating a test program sheet or file that is not supported by an Origen generator,
10
+ e.g. the IG-XL DC Specs sheet does not currently have a generator.
11
+ * Creating custom VB, C++ or similar code to support your tests.
12
+
13
+ All of these goals can be fulfilled by using a Resources file. Resources files are
14
+ very similar to the Flow files that we have already seen, the main difference is that
15
+ any flow entries generated within a Resources file will automatically be inhibited.
16
+
17
+ This makes generating tests and their resources (e.g. pattern sets, etc.) without a flow
18
+ entry extremely easy - just use the same code that you would normally use in the Flow
19
+ file and you will automatically get everything needed for the test without the flow
20
+ entry.
21
+
22
+ Resource files are syntactically equivalent to Flow files except that all references to
23
+ <code>Flow</code> are replaced by <code>Resources</code>:
24
+
25
+ ~~~ruby
26
+ # program/probe_resources.rb
27
+ Resources.create do
28
+
29
+ end
30
+ ~~~
31
+
32
+ So for example without changing our interface at all we can drop some of our previous
33
+ Flow code into the resources file (flow specific attributes such as bin numbers can
34
+ be removed):
35
+
36
+ ~~~ruby
37
+ # program/probe_resources.rb
38
+ Resources.create do
39
+
40
+ func :vreg_functional
41
+
42
+ para :vreg_meas, lo: 1.12, hi: 1.34
43
+
44
+ end
45
+ ~~~
46
+
47
+ This would generate the same program as before but with no flow entries for the generated
48
+ tests.
49
+
50
+ Parameterizable sub-resource files can be created in exactly the same way as sub-flow files.
51
+
52
+ #### Compiling Templates
53
+
54
+ Another common use case for a Resources file is to co-ordinate the compilation of template
55
+ files.
56
+
57
+ See the [Compiler section](<%= path "guides/compiler/introduction" %>) for details on
58
+ how to create templates.
59
+
60
+ A <code>compile</code> method is available with a Resources file to invoke and customize
61
+ the compilation of a specific file. Any arguments passed in will be accessible within the
62
+ template via its <code>options</code> method.
63
+
64
+ ~~~ruby
65
+ # program/common_resources.rb
66
+ Resources.create do
67
+
68
+ compile "templates/j750/DCSpecs.txt", max_vdd: 5.V
69
+
70
+ compile "templates/j750/GlobalSpecs.txt", vreg_period: 40.ns
71
+
72
+ end
73
+ ~~~
74
+
75
+ #### Separating Test Generation from Flow Generation
76
+
77
+ As discussed previously a conventional Origen program generation flow would be to generate
78
+ both the flow and the tests from a single flow file. However it is also possible to
79
+ generate the program in a more traditional way where the test and flow generation are
80
+ separated.
81
+
82
+ To do this use Resources files to generate the tests and all of their dependencies. This
83
+ would look very much like the flow file examples we have seen so far, the main difference
84
+ would be that each test would only ever appear once (although if you did generate duplicates
85
+ by accident Origen would still take care of it).
86
+
87
+ Then to define the flow you would have Flow files that called interface methods to insert
88
+ flow entries only.
89
+ This flow file would be a simplified version of what we have seen so far since the
90
+ attributes of the test are no longer required.
91
+ For example you might make a new interface method called 'test' which calls a test
92
+ in the flow - at flow level there is no longer any conceptual difference between
93
+ a parametric test and a functional test and so they can all use the same method.
94
+ Here is a previous example that only contains the flow concerns (includes 'cz' and
95
+ 'bin_out' methods since these are also flow level concerns):
96
+
97
+ ~~~ruby
98
+ Flow.create do
99
+
100
+ test :vreg_meas, softbin: 105, id: :vreg_meas_1
101
+
102
+ if_failed :vreg_meas_1 do
103
+ # Automatically characterize the vreg if the measurement fails
104
+ cz :vreg_meas, softbin: 107
105
+ # Then bin out
106
+ bin_out softbin: 105
107
+ end
108
+
109
+ # Check if the HVST has already been run on this device
110
+ test :rd_vreg_hvst_passcode, softbin: 50, id: :vreg_hvst_done
111
+
112
+ unless_passed :vreg_hvst_done do
113
+ # If not run it
114
+ test :vreg_hvst, softbin: 101
115
+ # And program the flag for next time
116
+ test :pgm_vreg_hvst_passcode, softbin: 51
117
+ end
118
+
119
+ end
120
+ ~~~
121
+
122
+ If you want to use the same methods in the Resources and Flow files you can use the
123
+ <code>resources_mode?</code> method within your interface to control when the flow
124
+ or the tests should be generated. This method will return true if the interface method
125
+ has been called from a Resources file:
126
+
127
+ ~~~ruby
128
+ # lib/vreg/interface.rb
129
+
130
+ # Create a functional test and call it from the flow
131
+ def func(name, options={})
132
+ name = namer(name, options)
133
+ if resources_mode?
134
+ # generate the test
135
+ else
136
+ # generate the flow entry
137
+ end
138
+ end
139
+ ~~~
140
+
141
+ % end
@@ -0,0 +1,5 @@
1
+ % render "layouts/guides.html" do
2
+
3
+ <%= render "partials/placeholder.md" %>
4
+
5
+ % end
@@ -0,0 +1,456 @@
1
+ % render "layouts/guides.html" do
2
+
3
+ ### Flow Considerations
4
+
5
+ By default, a top-level `Flow.create` call in Origen will generate a standalone V93K testflow file which is
6
+ internally wrapped by a flow group, like this:
7
+
8
+ ~~~text
9
+ group <FLOW_NAME> {
10
+ // Flow content here
11
+ }
12
+ ~~~
13
+
14
+ When such flows are imported into a master flow file, SmarTest does not provide a standard enable mechanism
15
+ to control which sub-flows are executed.
16
+
17
+ However, Origen provides the ability to generate V93K flow modules with an enable-word wrapper, thereby allowing
18
+ the top-level flow to easily enable/disable the execution of flow modules via flow variables.
19
+
20
+ By enabling this feature in the target like this:
21
+
22
+ ~~~ruby
23
+ OrigenTesters::V93K.new(add_flow_enable: :enabled)
24
+ ~~~
25
+
26
+ the flow will now generate like this:
27
+
28
+ ~~~text
29
+ group <FLOW_NAME> {
30
+ if @<FLOW_NAME>_ENABLE == 1 {
31
+ // Flow content here
32
+ }
33
+ }
34
+ ~~~
35
+
36
+ The `@<FLOW_NAME>_ENABLE` variable will be initialized to 1 in the generated variables file for the given flow,
37
+ meaning that the module will run by default if the top-level flow does nothing with this variable.
38
+
39
+ Alternatively, the variable can be initialized to off like this:
40
+
41
+ ~~~ruby
42
+ OrigenTesters::V93K.new(add_flow_enable: :disabled)
43
+ ~~~
44
+
45
+ Meaning that by default, the module will not run and the top-level flow must always enable it by including
46
+ `@<FLOW_NAME>_ENABLE = 1` before hitting the module.
47
+
48
+ Setting this attribute in the target means that it will apply to all flows. Alternatively, it can be set within
49
+ the flow itself (or the interface) if it is necessary to use this feature for only a subset of flows, or to override
50
+ the default setting for a particular flow.
51
+
52
+ Here is an example:
53
+
54
+ ~~~ruby
55
+ Flow.create interface: 'MyApp::Interface' do
56
+
57
+ # Ensure that this flow is always generated with an enable word wrapper that is enabled by default
58
+ self.add_flow_enable = :enabled
59
+
60
+ # Some functional test
61
+ func :blah
62
+ end
63
+ ~~~
64
+
65
+ This same API may be used to implement similar features on other platforms in future, but for now only the V93K is implemented.
66
+
67
+
68
+ ### Interface Considerations
69
+
70
+ Be sure to read and understand the guide to
71
+ [Creating an Interface](<%= path "guides/program/interface" %>) before
72
+ reading this section.
73
+ This guide will describe the API to generate V93K/SmarTest test program
74
+ components from within an interface file.
75
+
76
+ To re-cap this is the shell required to implement an interface:
77
+
78
+ ~~~ruby
79
+ # lib/vreg/interface.rb
80
+ module Vreg
81
+ class Interface
82
+ include OrigenTesters::ProgramGenerators
83
+
84
+ # An example method that can be called from your test flow to generate a functional test
85
+ def func(name, options={})
86
+ # If your interface supports multiple platforms, add conditional logic like this, if you
87
+ # only ever want to support one platform then you don't need this
88
+ if tester.j750?
89
+ # Functional test implementation for J750
90
+ elsif tester.v93k?
91
+ # Functional test implementation for V93K
92
+ end
93
+ end
94
+
95
+ end
96
+ end
97
+ ~~~
98
+
99
+ The <code>OrigenTesters::ProgramGenerators</code> will provide the interface
100
+ with access to all of the platform generator APIs for the platforms that it supports.
101
+
102
+ If your interface supports multiple platforms then add conditional logic to separate
103
+ them as shown above.
104
+
105
+ #### Creating a Test Suite
106
+
107
+ Most of the effort in generating a V93K test program is in generating the test suites and their
108
+ associated test methods.
109
+
110
+ A new test suite and test method can be instantiated and linked together like this:
111
+
112
+ ~~~ruby
113
+ t = test_suites.add(:vreg_func)
114
+ t.test_method = test_methods.origen.functional_test
115
+ ~~~
116
+
117
+ These lines of code do the following things:
118
+
119
+ * Instantiates a new test suite object and assigns it to the local variable <code>t</code>
120
+ * Sets its name to 'vreg_func' and inserts it into the flow file (but not into the actual test flow)
121
+ * Instantiates a new functional test method object and attaches it to the test suite
122
+ * Inserts the test method into the flow file (but not into the actual test flow)
123
+
124
+ You will of course want to then decorate your new test with attributes that are specific
125
+ to your application, here for example to set the levels and timing:
126
+
127
+ ~~~ruby
128
+ t.tim_equ_set = 15
129
+ t.tim_spec_set = 1
130
+ t.timset = 1
131
+ t.lev_equ_set = 20
132
+ t.lev_spec_set = 8
133
+ t.levset = 1
134
+ ~~~
135
+
136
+ If the test method provides parameters, you can set them in the same way. As a convenience,
137
+ Origen will automatically work out whether the reference is to a parameter of the test suite
138
+ or of the test method, and will assign it accordingly.
139
+ For example, let's say this functional test method had a parameter named <code>checkShutdown</code>, you
140
+ could set that like this:
141
+
142
+ ~~~ruby
143
+ t.check_shutdown = 1 # By Ruby convention, use the lower-cased underscored version of the C++ name
144
+
145
+ # The above is a shorthand equivalent to:
146
+ t.test_method.check_shutdown = 1
147
+ ~~~
148
+
149
+ Attributes can also be passed in when instantiating the new test suite/method, this is equivalent
150
+ if you prefer:
151
+
152
+ ~~~
153
+ t = test_suites.add(:vreg_func, tim_equ_set: 15, tim_spec_set: 1, timset: 1, lev_equ_set: 20)
154
+ t.test_method = test_methods.origen.functional_test(check_shutdown: 1)
155
+ ~~~
156
+
157
+ #### Limits
158
+
159
+ The limits can be set for all test objects using the following API, see here for some examples
160
+ [of the available unit helpers](<%= path 'guides/misc/coreext/#Unit_Helpers' %>):
161
+
162
+ ~~~ruby
163
+ t.lo_limit = 100.uA
164
+ t.hi_limit = 150.uA
165
+ ~~~
166
+
167
+ #### Built-in Test Methods
168
+
169
+ SmarTest comes with a standard AC and DC test method library and Origen provides a built-in API to
170
+ generate a test flow which uses those test methods, here are some examples:
171
+
172
+ ~~~ruby
173
+ # Execute a functional test
174
+ test_method = test_methods.ac_tml.ac_test.functional_test
175
+
176
+ # A basic DC voltage measurement
177
+ test_method = test_methods.dc_tml.dc_test.general_pmu force_mode: 'CURR', force_value: 100.uA
178
+ ~~~
179
+
180
+ Generally the parameter naming is the lower-cased and underscored version of the name that appears
181
+ in the SMT documentation.
182
+
183
+ See the [DC library API](http://origen-sdk.org/testers/api/OrigenTesters/SmartestBasedTester/Base/TestMethods/DcTml.html)
184
+ and the [AC library API](http://origen-sdk.org/testers/api/OrigenTesters/SmartestBasedTester/Base/TestMethods/AcTml.html)
185
+ for up-to-date details of the implemented test methods and the parameter names.
186
+
187
+ However, some of these test methods are not particularly good and the recommendation from Advantest these
188
+ days is generally not to use them.
189
+
190
+ Since that means there is now a void where a universally available test method library should be, work is
191
+ underway to provide an Origen standard test method library.
192
+ The aim of this is to provide a complete generation solution from Origen so that those who have
193
+ a fairly conventional use case can rapidly build a complete test program from off-the-shelf
194
+ components, but that is still a work in progress and not yet ready for prime time use.
195
+
196
+ Many users of the V93K program generator however, are likely to want to use it in combination
197
+ with their own custom test method library...
198
+
199
+ #### Custom Test Methods
200
+
201
+ An API exists to define the naming and parameter signature of test methods provided by
202
+ a 3rd party library, enabling them to be used within an interface exactly like in the examples above.
203
+ Additionally, it is possible to define helper methods that are associated with each test method,
204
+ making them easier to use within an Origen test program interface.
205
+
206
+ This is best shown by example, here is how to define a custom test method library and a custom
207
+ test method within an Origen interface:
208
+
209
+ ~~~ruby
210
+ # lib/vreg/interface.rb
211
+ module Vreg
212
+ class Interface
213
+ include OrigenTesters::ProgramGenerators
214
+
215
+ def initialize(options={})
216
+ add_my_tml if tester.v93k?
217
+ end
218
+
219
+ # Define the test methods from a custom V93K library
220
+ def add_my_tml
221
+ # The identifier you give here is what you will use to access the test methods from your interface
222
+ # code, for example: test_methods.my_tml.my_test
223
+ #
224
+ # This will also be the C++ namespace that is used within SMT to access the test method classes
225
+ # defined in this library.
226
+ add_tml :my_tml,
227
+ # [OPTIONAL] If you need the C++ namespace to be different to the above identifier then you can
228
+ # specify the C++ name like this:
229
+ class_name: 'MyTmlNamespace',
230
+
231
+ # Here is a test definition.
232
+ # The identifier should be lower-cased and underscored, in-keeping with Ruby naming conventions.
233
+ # By default the class name will be the camel-cased version of this identifier, so 'myTest' in
234
+ # this case.
235
+ my_test: {
236
+ # [OPTIONAL] The C++ test method class name can be overridden from the default like this:
237
+ class_name: 'MyTestClass',
238
+ # Parameters can be defined with an underscored symbol as the name, this can be used
239
+ # if the C++ implementation follows the standard V93K convention of calling the attribute
240
+ # the camel cased version, starting with a lower-cased letter, i.e. 'testerState' in this
241
+ # first example.
242
+ # The attribute definition has two required parameters, the type and the default value.
243
+ # The type can be :string, :current, :voltage, :time, :frequency, or :integer
244
+ pin_list: [:string, ''],
245
+ samples: [:integer, 1],
246
+ precharge_voltage: [:voltage, 0],
247
+ settling_time: [:time, 0],
248
+ # An optional parameter that sets the limits name in the 'testmethodlimits' section
249
+ # of the generated .tf file. Defaults to 'Functional' if not provided.
250
+ test_name: [:string, 'SpecSearch']
251
+ # An optional 3rd parameter can be supplied to provide an array of allowed values. If supplied,
252
+ # Origen will raise an error upon an attempt to set it to an unlisted value.
253
+ tester_state: [:string, 'CONNECTED', %w(CONNECTED UNCHANGED DISCONNECTED)],
254
+ force_mode: [:string, 'VOLT', %w(VOLT CURR)],
255
+ # The name of another parameter can be supplied as the type argument, meaning that the type
256
+ # here will be either :current or :voltage depending on the value of :force_mode
257
+ force_value: [:force_mode, 3800.mV],
258
+ # In cases where the C++ library has deviated from standard attribute naming conventions
259
+ # (camel-cased with lower cased first character), the absolute attribute name can be given
260
+ # as a string.
261
+ # The Origen accessor for these will be the underscored version, with '.' characters
262
+ # converted to underscores e.g. tm.an_unusual_name
263
+ 'An.UnusualName' => [:string, 'NO', %w(NO YES)],
264
+ # Attribute aliases can be defined like this:
265
+ aliases: {
266
+ my_name: 'An.UnusualName',
267
+ precharge: :precharge_voltage,
268
+ },
269
+ # Define any methods you want the test method to have
270
+ methods: {
271
+ # If you define a method called 'finalize', it will be called automatically before the test
272
+ # method is finally rendered, making it a good place to do any last minute attribute
273
+ # manipulation based on the final values that have been set by the user.
274
+ # The test method object itself will be passed in as an argument.
275
+ #
276
+ # In this example it will set the pre-charge if it has not already been set and a voltage is
277
+ # being forced above a given threshold.
278
+ finalize: -> (tm) {
279
+ if tm.force_mode == 'VOLT' && tm.precharge_voltage == 0 && tm.force_value > 3.5.V
280
+ # Set the pre-charge level to 1V below the force value
281
+ tm.precharge_voltage = tm.force_value - 1.V
282
+ end
283
+ },
284
+ # Example of a custom helper method, here to provide a single method to force a current and
285
+ # which will configure multiple test method attributes.
286
+ force_current: -> (tm, value) {
287
+ tm.force_mode = 'CURR'
288
+ tm.force_value = value
289
+ },
290
+ }
291
+ },
292
+
293
+ my_other_test: {
294
+ # Define another test in exactly the same way...
295
+ }
296
+ end
297
+ end
298
+ end
299
+ ~~~
300
+
301
+ Here is an example of how the above definition might be used with test program interface logic:
302
+
303
+ ~~~ruby
304
+ # An example method that can be called from your test flow to generate a DC measurement test like this:
305
+ #
306
+ # measure :vreg, force: 10.uA, lo_limit: 1.25, hi_limit: 1.75
307
+ #
308
+ # measure :iref, force: 1.2.V, lo_limit: 20.uA, hi_limit: 30.uA, type: :current
309
+ def measure(name, options={})
310
+ t = test_suites.add(name, options)
311
+ t.test_method = test_methods.my_tml.my_test(pin_list: '@')
312
+ if options[:type] == :current
313
+ # Force mode is 'VOLT' by default per the above definition
314
+ t.force_value = options[:force]
315
+ else
316
+ # Here calling the helper method to configure the method for force current mode
317
+ t.force_current(options[:force])
318
+ end
319
+ end
320
+ ~~~
321
+
322
+ #### Distribute as a Plugin
323
+
324
+ Commonly, a custom test method library will not be specific to any one test program application and
325
+ it will be used by many test programs within a group or company.
326
+ In such a case, you don't want to have the Origen definition of the given library be duplicated in all
327
+ of your applications. Rather, it is preferable to develop and maintain the definition in a central place
328
+ and then include it in all of the applications that wish to use the library.
329
+
330
+ This can be easily achieved by wrapping the Origen definition
331
+ [in an Origen plugin](<%= path 'guides/plugins/introduction' %>).
332
+
333
+ Here is an example of how to package a library definition for inclusion in a plugin:
334
+
335
+ ~~~ruby
336
+ # lib/my_library.rb within the my_library plugin
337
+ module MyLibrary
338
+ # Define the test methods from a custom V93K library
339
+ def add_my_library
340
+ # The definition here is identical to the original example above
341
+ add_tml :my_tml,
342
+ # [OPTIONAL] If you need the C++ namespace to be different to the above identifier then you can
343
+ # specify the C++ name like this:
344
+ class_name: 'MyTmlNamespace',
345
+
346
+ # Here is a test definition.
347
+ # The identifier should be lower-cased and underscored, in-keeping with Ruby naming conventions.
348
+ # By default the class name will be the camel-cased version of this identifier, so 'myTest' in
349
+ # this case.
350
+ my_test: {
351
+
352
+ # ...
353
+
354
+ end
355
+ end
356
+
357
+ # [OPTIONAL] You can also supply complete interface method definitions which use this library
358
+ # An example method that can be called from your test flow to generate a DC measurement test like this:
359
+ #
360
+ # measure :vreg, force: 10.uA, lo_limit: 1.25, hi_limit: 1.75
361
+ #
362
+ # measure :iref, force: 1.2.V, lo_limit: 20.uA, hi_limit: 30.uA, type: :current
363
+ def measure(name, options={})
364
+ t = test_suites.add(name, options)
365
+ t.test_method = test_methods.my_tml.my_test(pin_list: '@')
366
+ if options[:type] == :current
367
+ # Force mode is 'VOLT' by default per the above definition
368
+ t.force_value = options[:force]
369
+ else
370
+ # Here calling the helper method to configure the method for force current mode
371
+ t.force_current(options[:force])
372
+ end
373
+ end
374
+ end
375
+ ~~~
376
+
377
+ Then simply add the plugin to a given application, and it can be used within an interface like this:
378
+
379
+ ~~~ruby
380
+ module MyApp
381
+ class Interface
382
+ include OrigenTesters::ProgramGenerators
383
+ include MyLibrary
384
+
385
+ def initialize(options={})
386
+ add_my_library
387
+ end
388
+
389
+ # You don't need to do anything here, and your flow will already support the measure method!
390
+
391
+ # Some application-specific flow method that uses the library:
392
+ def some_test(name, options = {})
393
+ t = test_suites.add(name, options)
394
+ t.test_method = test_methods.my_tml.my_other_test
395
+ t.some_parameter = #...
396
+ end
397
+ end
398
+ end
399
+ ~~~
400
+
401
+ For a more advanced integration which gets rid of the need to even call `add_my_library`, you
402
+ can refer to how the `origen_std_lib` interface integration works
403
+ [here](https://github.com/Origen-SDK/origen_std_lib/blob/master/plugin/lib/origen_std_lib.rb).
404
+
405
+ ### Test Name Uniqueness
406
+
407
+ Test (suite) naming collisions can occur when importing multiple independent test flow modules into a
408
+ V93K master flow file.
409
+
410
+ To prevent that from ever occurring, Origen will generate and append a unique signature to the end of
411
+ all test names by default, for example:
412
+
413
+ ~~~ruby
414
+ t = test_suites.add("my_test_name", options)
415
+
416
+ t.name # => "my_test_name_E32ABE8"
417
+ ~~~
418
+
419
+ Applications can override this default behavior by setting the corresponding test interface attribute,
420
+ `unique_test_names`, to one of the following values:
421
+
422
+ * `:signature` - this is the default which will generate a unique signature as shown in the above example
423
+ * `nil` - no value will be appended to the test names at all
424
+ * `:flowname` - the name of the current top-level flow will be appended to all test names
425
+ * Setting this attribute to any other value will append that value directly to all test names
426
+
427
+ This attribute can be set in the [environment file](<%= path 'guides/runtime/environment' %>) when instantiating
428
+ the tester:
429
+
430
+ ~~~ruby
431
+ OrigenTesters::V93K.new unique_test_names: nil
432
+ ~~~
433
+
434
+ This provides a single place to control the behavior within a [monolithic application architecture](<%= path 'guides/starting/architecture/#Monolithic_Application_Architecture' %>).
435
+
436
+ However, under a [distributed application architecture](<%= path 'guides/starting/architecture/#Distributed_Application_Architecture' %>)
437
+ a given test flow module may be generated under a target/environment that is controlled by a 3rd party.
438
+
439
+ In that case, it is recommended to either set it at the flow-level, which will override any setting set at the
440
+ environment-level:
441
+
442
+ ~~~ruby
443
+ # program/wt1_start.rb
444
+ Flow.create interface: 'MyApp::Interface', unique_test_names: 'wt1' do
445
+
446
+ end
447
+ ~~~
448
+
449
+ Or, it can be set directly within your interface logic which will take the highest precedence:
450
+
451
+ ~~~ruby
452
+ # lib/my_app/interface.rb
453
+ self.unique_test_names = :flowname
454
+ ~~~
455
+
456
+ % end