origen_testers 0.19.0 → 0.19.2

Sign up to get free protection for your applications and to get access to all the features.
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,249 @@
1
+ % render "layouts/guides.html" do
2
+
3
+ The runtime flow control of a test program is an area that can be particularly messy:
4
+
5
+ * Need to deal with different and often obscure vendor APIs
6
+ * It can be very hard to decipher both the intention and the actual behavior
7
+ during code reviews
8
+ * It is easy to make mistakes
9
+ * Mistakes can be costly - there have been many customer quality
10
+ incidents in the past from missed test caused by errors in flow control
11
+
12
+ To deal with these problems Origen provides a simple and intuitive API
13
+ to describe runtime flow logic:
14
+
15
+ * Generates legal and battle-tested code
16
+ * Takes care of cross-platform implementation
17
+ * Makes flow control easy to review
18
+ * Covers over gaps or weaknesses in the vendor APIs
19
+
20
+ Conditional tests fall into two categories:
21
+
22
+ * Those that will run based on the flow execution environment. For example based on
23
+ the job selected at runtime or on some enable flag that can be set by the user at
24
+ runtime.
25
+ * Those that will only run based on the outcome of another test - i.e. execute a given
26
+ test based on whether a previous test passed, failed or ran at all.
27
+
28
+ #### Execution Based on the Runtime Environment
29
+
30
+ The following methods are available to describe these cases:
31
+
32
+ * **if_enable / unless_enable** - Run the test if a flow runtime option is/is not enabled at runtime
33
+ * **if_job / unless_job** - Run based on the current job (P1, FR, QC, etc)
34
+
35
+ Here are some examples of how to apply these methods to single tests:
36
+
37
+ ~~~ruby
38
+ # Run this test to characterize the vreg, only if the 'vreg_cz' flag has been enabled
39
+ para :vreg_meas, softbin: 107, cz: true, if_enable: "vreg_cz"
40
+ # Apply HVST to the vreg module, unless the 'skip_hvst' flag has been enabled
41
+ func :vreg_hvst, softbin: 101, hv: 10.V, vdd: :max, unless_enable: "skip_hvst"
42
+ # Run this test only at cold
43
+ para :vreg_meas, softbin: 105, lo: 1.12, hi: 1.34V, if_job: "FC"
44
+ ~~~
45
+
46
+ The use of `if/unless_enable` will make use of flow enable words on Teradyne platforms and user
47
+ flow variables on Advantest.
48
+ The `if/unless_job` control will make use of the job column on Teradyne platforms and a user
49
+ flow variable named `@JOB` on Advantest.
50
+
51
+ Both of these controls support a block form, which allows it to be applied to a group of test
52
+ and, in the case of enable words, it also provides a way to implement AND and OR logic:
53
+
54
+ ~~~ruby
55
+ # OR - Run these tests if either word is set
56
+ if_enable [:word1, :word2] do
57
+ func: :test1
58
+ func: :test2
59
+ end
60
+
61
+ # AND - Run these tests if both words are set
62
+ if_enable :word1 do
63
+ if_enable :word2 do
64
+ func: :test1
65
+ func: :test2
66
+ end
67
+ end
68
+ ~~~
69
+
70
+ #### Execution Based on a Previous Test
71
+
72
+ The following methods are available to describe these cases:
73
+
74
+ * **if_ran / unless_ran** - Run only if a previous test did or did not run
75
+ * **if_failed (unless_passed)** - Run only if a previous test failed
76
+ * **if_passed (unless_failed)** - Run only if a previous test passed
77
+
78
+ All of these methods require you to provide the ID of the previous test on which
79
+ the conditional execution will depend.
80
+ This ID must be assigned by you in the flow line of the previous test by adding
81
+ an `:id` key, like this:
82
+
83
+ ~~~ruby
84
+ para :vreg_meas, softbin: 105, lo: 1.12, hi: 1.34, id: :vreg_meas_1
85
+ ~~~
86
+
87
+ The ID can be any value you like as long as it is unique, Origen will raise an error
88
+ if any duplicate IDs are encountered.
89
+
90
+ On the dependent tests the API is similar to the previous examples except the ID
91
+ of the previous test is given in place of the enable flag or job name.
92
+ Here are some examples:
93
+
94
+ ~~~ruby
95
+ para :vreg_meas, softbin: 105, lo: 1.12, hi: 1.34, id: :vreg_meas_1
96
+ # Automatically characterize the vreg if the measurement fails
97
+ para :vreg_meas, softbin: 107, cz: true, if_failed: :vreg_meas_1
98
+ # Then bin out
99
+ bin 3, softbin: 105, if_failed: :vreg_meas_1
100
+ # Check if the HVST has already been run on this device
101
+ func :rd_vreg_hvst_passcode, softbin: 50, vdd: :nom, id: :vreg_hvst_done
102
+ # If not run it
103
+ func :vreg_hvst, softbin: 101, hv: 10.V, vdd: :max, unless_passed: :vreg_hvst_done
104
+ # And program the flag for next time
105
+ func :pgm_vreg_hvst_passcode, softbin: 51, vdd: :nom, unless_passed: :vreg_hvst_done
106
+ ~~~
107
+
108
+ Origen automatically takes care of setting up all of the tests in the relationship:
109
+
110
+ * The parent tests in the relationship are automatically set to continue on fail
111
+ * Flag(s) will be set to indicate whether the parent test passed or failed
112
+ * Conditional execution flags are set on all dependent tests
113
+
114
+ AND and OR conditions can be created by using `if_any/all_failed/passed`
115
+ variations as follows:
116
+
117
+ ~~~ruby
118
+ func :test1, id: :t1
119
+ func :test2, id: :t2
120
+
121
+ # OR logic - This test will run if either of the referenced tests fail
122
+ func :test3, if_any_failed: [:t1, :t2]
123
+
124
+ # AND logic - This test will only run if both of the referenced tests fail
125
+ func :test4, if_all_passed: [:t1, :t2]
126
+
127
+ # Block forms are available as with all condition APIs
128
+ if_any_passed [:t1, :t2] do
129
+ #...
130
+ end
131
+ ~~~
132
+
133
+ #### References to External Tests
134
+
135
+ It is possible to generate conditional relationships between tests that span across
136
+ different flow modules, in that case the test ID must be appended with `:extern_`.
137
+ This will indicate to Origen that the reference is external and
138
+ will prevent an error being raised for the ID not being found within the current flow.
139
+
140
+ Here is an example:
141
+
142
+ ~~~ruby
143
+ # program/flow_1.rb
144
+ Flow.create do
145
+ # This ID can only be referenced within this flow
146
+ func :test1, id: :t1
147
+ # This ID can be referenced outside of this flow
148
+ func :test2 id: :extern_t2
149
+ end
150
+
151
+ # program/flow_2.rb
152
+ Flow.create do
153
+ # This will generate an undefined ID error
154
+ func :test3, if_failed: :t1
155
+ # But this will work, since the ID's name indicates that it is an intentional external reference
156
+ func :test4, if_failed: :extern_t2
157
+ end
158
+ ~~~
159
+
160
+ #### Applying Conditions to Sub-Flows
161
+
162
+ All of the flow control methods have a block form which will apply the
163
+ condition to all tests within the block.
164
+
165
+ A very useful pattern is to split your code into small re-usable snippets
166
+ and then wrap the import with these flow control methods to apply conditional
167
+ execution.
168
+ For example, here the 'FH' job requirement will be applied to all tests
169
+ imported from the vreg component:
170
+
171
+ ~~~ruby
172
+ # Only run the vreg tests at hot
173
+ if_job "FH" do
174
+ import "components/vreg"
175
+ end
176
+ ~~~
177
+
178
+ #### Conditions Applied to Groups
179
+
180
+ Groups can also be used to implement AND/OR logic, here is an example of how you
181
+ might implement a speed binning flow:
182
+
183
+ ~~~ruby
184
+ group "200Mhz", id: :spec200 do
185
+ func :test1_200
186
+ func :test2_200
187
+ end
188
+
189
+ # Bin out to bin 1 if passed at 200 Mhz, here if_passed will apply to all tests in the group
190
+ pass 1, if_passed: :spec200
191
+
192
+ group "100Mhz", id: :spec100 do
193
+ func :test1_100
194
+ func :test2_100
195
+ end
196
+
197
+ # Bin out to bin 2 if passed at 100 Mhz, here if_passed will apply to all tests in the group
198
+ pass 2, if_passed: :spec100
199
+
200
+ # Otherwise we have failed
201
+ bin 3
202
+ ~~~
203
+
204
+ #### Manually Setting and Referencing Flags
205
+
206
+ It may be sometimes be necessary to react on a flag that is controlled by a 3rd party and
207
+ which will be passed into an Origen-based test block, or to set a flag which a 3rd
208
+ party test block will later reference.
209
+
210
+ An API exists to manually set and react to flags in these situations:
211
+
212
+ ~~~ruby
213
+ log "Example of manual flag setting upon pass or fail"
214
+ test :test1, on_pass: { set_flag: :my_pass_flag }, on_fail: { set_flag: :my_fail_flag }, continue: true
215
+
216
+ # Execute only if the above pass flag was set
217
+ test :test2, if_flag: :my_pass_flag
218
+
219
+ # Execute only if the above pass flag was not set
220
+ unless_flag :my_pass_flag do
221
+ test :test3
222
+ end
223
+ ~~~
224
+
225
+ Note that flag names will usually be forced to uppercase, this is to institute a convention that
226
+ flags/flow variables are always uppercased in order to avoid any test program bugs from
227
+ incorrectly referencing a given flag due to case sensitivity.
228
+
229
+ However, if you need to reference a flag from a 3rd party test module that does not follow this
230
+ convention, then a literal flag can be supplied by prefixing it with `$` as shown below:
231
+
232
+ ~~~ruby
233
+ test :test1, on_fail: { set_flag: :$My_Mixed_Flag }, continue: true
234
+ test :test2, if_flag: "$My_Mixed_Flag"
235
+ unless_flag "$My_Mixed_Flag" do
236
+ test :test3
237
+ end
238
+
239
+ test :extra_test, if_enable: :$MCEn_extras
240
+ unless_enable "$MCEn_test" do
241
+ test :test1
242
+ test :test2
243
+ end
244
+ ~~~
245
+
246
+ In all cases the `$` will be removed from the final flag name that appears in the test program.
247
+
248
+
249
+ % end
@@ -0,0 +1,429 @@
1
+ % render "layouts/guides.html" do
2
+
3
+ The test flow is where you describe everything about what your test program
4
+ must do:
5
+
6
+ * The tests it must run
7
+ * The conditions applied by these tests
8
+ * Test limits
9
+ * Bin and test numbers
10
+ * Conditional test execution and other flow control
11
+ * Notes about the reason for running or the methodology behind each test
12
+
13
+ When writing your flow file you should try and distill down the amount of information
14
+ to the bare minimum, the goal here is to write as little as possible yet still
15
+ capture the details about what makes each test unique.
16
+
17
+ When describing each test the syntax and naming conventions are entirely
18
+ up to you and based on your knowledge about the application domain and the
19
+ type and variety of tests that you need to generate.
20
+ It will be the job of the interface (which you will write later) to translate
21
+ this description into method calls to the generation API for the target platform.
22
+
23
+ #### Your First Flow File
24
+
25
+ By convention all flow files should reside in the "program" directory within
26
+ the application top-level directory.
27
+
28
+ Create the file "program/probe.rb" as shown below:
29
+
30
+ ~~~ruby
31
+ # program/probe.rb
32
+ Flow.create do
33
+
34
+ end
35
+ ~~~
36
+
37
+ The above represents all of the officially required syntax to define a flow, what
38
+ goes inside is now completely down to the needs of the application.
39
+
40
+ When creating a flow like this it is often useful to supply some context about
41
+ the environment in which it will run. For example we have indicated via the name that this
42
+ is a flow intended to run at probe, we can also note this in the code:
43
+
44
+ ~~~ruby
45
+ # program/probe.rb
46
+ Flow.create(environment: :probe) do
47
+
48
+ end
49
+ ~~~
50
+
51
+ Again the naming of the terms <code>:environment</code> and <code>:probe</code> are
52
+ completely arbitrary, you may want to note some details about the temperature, parallelism
53
+ or other details which may be useful to you when it comes to actually generating
54
+ the flow for a given ATE platform.
55
+ Or not. Don't worry about this too much right now, in practice it is probably best to
56
+ just add things like this as you find that you need them. The main thing for now is just to
57
+ appreciate that you can pass some details about the execution environment of the given
58
+ flow to the interface via this mechanism.
59
+
60
+ #### Specifying Numbers
61
+
62
+ Origen extends Ruby to add the following methods which are very helpful
63
+ when specifying test conditions:
64
+
65
+ ~~~ruby
66
+ 3.A # => 3
67
+ 3.mA # => 0.003
68
+ 3.uA # => 0.000003
69
+ 3.nA # => 0.000000003
70
+ 3.pA # => 0.000000000003
71
+
72
+ 3.V # => 3
73
+ 3.mV # => 0.003
74
+ # => etc
75
+
76
+ 3.Hz # => 3
77
+ 3.kHz # => 3000
78
+ 3.MHz # => 3000000
79
+ ~~~
80
+
81
+ #### Adding Some Tests
82
+
83
+ So let's say we are writing a test for a voltage regulator module, we have a functional
84
+ test and then two parametric tests that we wish to run - one that simply tests the
85
+ output and one that tests the output under load.
86
+ Let's start with this:
87
+
88
+ ~~~ruby
89
+ # program/probe.rb
90
+ Flow.create(environment: :probe) do
91
+
92
+ log "Vreg test module"
93
+
94
+ func :vreg_functional, pattern: "vreg/functional", vdd: :min, bin: 5, softbin: 101, tnum: 101000
95
+
96
+ func :vreg_functional, pattern: "vreg/functional", vdd: :max, bin: 5, softbin: 101, tnum: 101001
97
+
98
+ para :vreg_meas, pattern: "vreg/meas", vdd: :min, bin: 5, softbin: 105, tnum: 105000, lo: 1.12, hi: 1.34
99
+
100
+ para :vreg_meas, pattern: "vreg/meas", vdd: :max, bin: 5, softbin: 105, tnum: 105001, lo: 1.12, hi: 1.34
101
+
102
+ para :vreg_meas, pattern: "vreg/meas", vdd: :min, bin: 5, softbin: 105, tnum: 105002, load: 5.mA, lo: 1.10, hi: 1.34
103
+
104
+ para :vreg_meas, pattern: "vreg/meas", vdd: :max, bin: 5, softbin: 105, tnum: 105003, load: 5.mA, lo: 1.12, hi: 1.34
105
+
106
+ end
107
+ ~~~
108
+
109
+ This is a good start, we have something that resembles a test flow and we have gone with the
110
+ general convention that a flow line is structured like this:
111
+
112
+ ~~~text
113
+ <function> <name>, <attributes>
114
+ ~~~
115
+
116
+ * **function** - The main function of a particular test, here we have gone with the categories
117
+ 'log', 'func(tional)' and 'para(metric)'. You may wish to have other categories based on your domain.
118
+ For example in some NVM applications we have 'program', 'read', 'erase', 'measure', 'bitmap',
119
+ and so on. Each of these functions correspond to the methods that you will need to implement
120
+ in your interface later.
121
+ * **name** - Almost every test will need a name and so we make this a mandatory argument.
122
+ * **attributes** - There then follows a free-format list of attributes, use these to describe
123
+ the test and especially including anything that makes the test unique, such as the load
124
+ attribute which has been used above.
125
+
126
+ As mentioned previously this choice of convention is just that, a personal choice, however
127
+ this is the convention that is currently used in the flagship Origen applications that are
128
+ currently driving the development of the framework.
129
+ As the Origen program generator matures and the number of applications using it grows, it is
130
+ possible that alternative and better conventions will begin to emerge.
131
+ If you come across a better approach then please come and tell us about via the
132
+ [Origen community channels](<%= path "community" %>),
133
+ however we will stick with this one for now.
134
+
135
+ #### Eliminate Anything that can be Inferred
136
+
137
+ Remember that the goal here is to be as concise as possible, since the more concise you
138
+ are at this level then the more you can automate later. This eliminates duplication and
139
+ redundancy, reduces the amount of code you need to write to add a new test later, and the
140
+ more that can be generated the less chance there is for human error.
141
+
142
+ There are a few opportunities for simplification that we can consider at this point:
143
+
144
+ * The **pattern** field seems redundant - it very closely mirrors what has been assigned to the
145
+ test name, therefore we can infer the pattern name without explicitly declaring it. It is generally
146
+ a good approach to name the test after the pattern if you normally have one pattern per test.
147
+ * The **bin** number also looks to be redundant, it is always 5. In a case like this what
148
+ we can do is set a default of 5 within the interface, then if it is not declared for a specific
149
+ test it will be 5, but we can always override it for a specific test.
150
+ * The **tnum** attribute seems to follow the general rule that it is the softbin number * 1000
151
+ and then a counter. Anything that is the result of a function based on other
152
+ attributes is ripe for elimination.
153
+
154
+ With those optimizations applied we end up with:
155
+
156
+ ~~~ruby
157
+ # program/probe.rb
158
+ Flow.create(environment: :probe) do
159
+
160
+ log "Vreg test module"
161
+
162
+ func :vreg_functional, vdd: :min, softbin: 101
163
+
164
+ func :vreg_functional, vdd: :max, softbin: 101
165
+
166
+ para :vreg_meas, vdd: :min, softbin: 105, lo: 1.12, hi: 1.34
167
+
168
+ para :vreg_meas, vdd: :max, softbin: 105, lo: 1.12, hi: 1.34
169
+
170
+ para :vreg_meas, vdd: :min, softbin: 105, load: 5.mA, lo: 1.10, hi: 1.34
171
+
172
+ para :vreg_meas, vdd: :max, softbin: 105, load: 5.mA, lo: 1.12, hi: 1.34
173
+
174
+ end
175
+ ~~~
176
+
177
+ Finally we seem to always be running our tests at min vdd and then max vdd, so again
178
+ there seems to be a convention that we could choose to implement by default. One issue we
179
+ have is that the loaded test has a different limit between min and max, so this a
180
+ good example of one case where we would override the default.
181
+
182
+ So switching to the convention that each test will execute at min and max vdd unless otherwise
183
+ specified, our final flow is:
184
+
185
+ ~~~ruby
186
+ # program/probe.rb
187
+ Flow.create(environment: :probe) do
188
+
189
+ log "Vreg test module"
190
+
191
+ func :vreg_functional, softbin: 101
192
+
193
+ para :vreg_meas, softbin: 105, lo: 1.12, hi: 1.34V
194
+
195
+ para :vreg_meas, vdd: :min, softbin: 105, load: 5.mA, lo: 1.10, hi: 1.34
196
+
197
+ para :vreg_meas, vdd: :max, softbin: 105, load: 5.mA, lo: 1.12, hi: 1.34
198
+
199
+ end
200
+ ~~~
201
+
202
+ That very clearly and concisely describes what the flow must do. Also by establishing
203
+ conventions and eliminating redundancy we have made it really easy for us to add
204
+ a new test in the future.
205
+
206
+ #### Flow Control
207
+
208
+ See the next section for details on run-time flow control.
209
+
210
+ For build-time flow control you have complete access to the current target objects if you
211
+ need to conditionally build some tests.
212
+
213
+ Lets say we have two DUT designs, and one of them has a bug which means that the
214
+ vreg load test will not work properly. Let's say its a problem with the pad connection
215
+ such that the vreg works ok but it just can't be tested via an external load.
216
+ Our models to represent this situation would look something like this:
217
+
218
+ ~~~ruby
219
+ # lib/dut_1.rb
220
+ class DUT1
221
+ include Origen::Model
222
+ end
223
+
224
+ # lib/dut_2.rb
225
+ class DUT2 < DUT
226
+ include Origen::Model
227
+
228
+ bug :vreg_pad
229
+ end
230
+
231
+ DUT1.new.has_bug?(:vreg_pad) # => false
232
+ DUT2.new.has_bug?(:vreg_pad) # => true
233
+ ~~~
234
+
235
+ There are two ways that we could build the flow to ensure that DUT2 can still give a bin 1 - either
236
+ skip the loaded test completely, or else don't care its result.
237
+ Here is an example of both:
238
+
239
+ ~~~ruby
240
+ # program/probe.rb
241
+ Flow.create(environment: :probe) do
242
+
243
+ log "Vreg test module"
244
+
245
+ func :vreg_functional, softbin: 101
246
+
247
+ para :vreg_meas, softbin: 105, lo: 1.12, hi: 1.34
248
+
249
+ # Don't build this test if the target DUT has the bug
250
+ unless $dut.has_bug?(:vreg_pad)
251
+ para :vreg_meas, vdd: :min, softbin: 105, load: 5.mA, lo: 1.10, hi: 1.34
252
+ end
253
+
254
+ # Continue on fail if the target DUT has the bug
255
+ para :vreg_meas, vdd: :max, softbin: 105, load: 5.mA, lo: 1.12, hi: 1.34, continue: $dut.has_bug?(:vreg_pad)
256
+
257
+ end
258
+ ~~~
259
+
260
+ #### Re-usable Flow Snippets
261
+
262
+ It is ofter useful to extract sections of a flow into a sub-module, so that it can be re-used
263
+ and parameterized.
264
+ In our case let's say that we have a new DUT on the horizon which has two vreg instances, so
265
+ let's extract this suite of vreg tests to a module so that we can instantiate two of them in
266
+ our flow.
267
+
268
+ All sub flow file names must begin with "_", this is what tells Origen that it is a sub-flow and
269
+ not a top-level flow.
270
+ The sub-flow syntax is virtually identical to the regular flow syntax except that a hash of
271
+ options are passed in which will contain any arguments passed in by the caller when they
272
+ instantiate the sub-flow.
273
+
274
+ Let's convert our flow to a sub-flow in file "_vreg.rb":
275
+
276
+ ~~~ruby
277
+ # program/_vreg.rb
278
+ Flow.create do |options|
279
+
280
+ log "Vreg test module"
281
+
282
+ func :vreg_functional, softbin: 101
283
+
284
+ para :vreg_meas, softbin: 105, lo: 1.12, hi: 1.34
285
+
286
+ # Don't build this test if the target DUT has the bug
287
+ unless $dut.has_bug?(:vreg_pad)
288
+ para :vreg_meas, vdd: :min, softbin: 105, load: 5.mA, lo: 1.10, hi: 1.34
289
+ end
290
+
291
+ # Continue on fail if the target DUT has the bug
292
+ para :vreg_meas, vdd: :max, softbin: 105, load: 5.mA, lo: 1.12, hi: 1.34, continue: $dut.has_bug?(:vreg_pad)
293
+
294
+ end
295
+ ~~~
296
+
297
+ Not much has changed so far - the environment option has been removed from the <code>Flow.create</code>
298
+ definition since that is more of a top-level concern, and the options have been added.
299
+
300
+ There are a couple of opportunities for improvement here:
301
+
302
+ * The flow allows the loaded tests to be skipped, however it would be better if the sub-flow
303
+ did not define the conditions under which they should be skipped - that decision should be
304
+ made by to the top-level.
305
+ * If this test is going to be instantiated multiple times it will need some kind of index
306
+ to target the test at vreg 0 or vreg 1.
307
+
308
+ Here is the flow with these modifications:
309
+
310
+ ~~~ruby
311
+ # program/_vreg.rb
312
+ Flow.create do |options|
313
+
314
+ # These are the option defaults that will be used unless specified by the caller
315
+ options = {
316
+ include_loaded_output_tests: true,
317
+ index: 0,
318
+ }.merge(options)
319
+
320
+ log "Vreg test module"
321
+
322
+ func :vreg_functional, softbin: 101, index: options[:index]
323
+
324
+ para :vreg_meas, softbin: 105, lo: 1.12, hi: 1.34, index: options[:index]
325
+
326
+ if options[:include_loaded_output_tests]
327
+
328
+ para :vreg_meas, vdd: :min, softbin: 105, load: 5.mA, lo: 1.10, hi: 1.34, index: options[:index]
329
+
330
+ para :vreg_meas, vdd: :max, softbin: 105, load: 5.mA, lo: 1.12, hi: 1.34, index: options[:index]
331
+
332
+ end
333
+
334
+ end
335
+ ~~~
336
+
337
+ For now we have not really committed to how the indexed tests will be generated, but we have
338
+ passed the information along to the interface. Most likely when it comes to generating the
339
+ pattern name within the interface we will just append the index to the name.
340
+
341
+ So the original top-level flow is now really simple:
342
+
343
+ ~~~ruby
344
+ # program/probe.rb
345
+ Flow.create(environment: :probe) do
346
+
347
+ import "vreg", include_loaded_output_tests: !$dut.has_bug?(:vreg_pad)
348
+
349
+ end
350
+ ~~~
351
+
352
+ The path argument supplied to the import method can be either a relative path from the
353
+ current file (as it is above), for example <code>"../components/vreg"</code>, or an
354
+ absolute path such as <code>"#{Origen.root}/program/components/vreg"</code>. In both cases
355
+ the underscore prefix is not required.
356
+
357
+ The original reason for doing this was to add support for testing multiple
358
+ vreg instances. To support such a case let's say that our DUT model will implement a
359
+ method called <code>vregs</code> which will return one or more vreg models wrapped
360
+ in an array.
361
+
362
+ Our final flow is:
363
+
364
+ ~~~ruby
365
+ # program/probe.rb
366
+ Flow.create(environment: :probe) do
367
+
368
+ $dut.vregs.each_with_index do |vreg, i|
369
+
370
+ import "vreg", include_loaded_output_tests: !$dut.has_bug?(:vreg_pad), index: i
371
+
372
+ end
373
+
374
+ end
375
+ ~~~
376
+
377
+ #### Documenting Tests
378
+
379
+ All of the test attributes will be available later when it comes to generating documentation
380
+ of the test program, so there is no need to document them manually.
381
+ However in some cases it will also be useful to include some
382
+ text describing perhaps how the test works, or why it is being done.
383
+ Such information can be added via regular Ruby comments immediately before the given
384
+ test.
385
+
386
+ Origen will extract these later when it comes to generating documentation.
387
+
388
+ The comments will be parsed as [Markdown](http://kramdown.rubyforge.org/quickref.html)
389
+ so this can be used to make things like bulleted lists or tables.
390
+
391
+ Here is our vreg test suite with some example documentation added:
392
+
393
+ ~~~ruby
394
+ # program/_vreg.rb
395
+ Flow.create do |options|
396
+
397
+ # These are the option defaults that will be used unless specified by the caller
398
+ options = {
399
+ include_loaded_output_tests: true,
400
+ index: 0,
401
+ }.merge(options)
402
+
403
+ log "Vreg test module"
404
+
405
+ # This test verifies that the following things work:
406
+ #
407
+ # * The vreg can be disabled
408
+ # * The trim register can be written to and read from
409
+ func :vreg_functional, softbin: 101, index: options[:index]
410
+
411
+ # Measure the output of the vreg under no load, this is a simple
412
+ # test to catch any gross defects that prevent the vreg from working
413
+ para :vreg_meas, softbin: 105, lo: 1.12, hi: 1.34, index: options[:index]
414
+
415
+ if options[:include_loaded_output_tests]
416
+
417
+ # Measure the output of the vreg under the given load, this is approximately
418
+ # equivalent to 1.5x the maximum load anticipated in a customer application.
419
+ para :vreg_meas, vdd: :min, softbin: 105, load: 5.mA, lo: 1.10, hi: 1.34, index: options[:index]
420
+
421
+ # As above
422
+ para :vreg_meas, vdd: :max, softbin: 105, load: 5.mA, lo: 1.12, hi: 1.34, index: options[:index]
423
+
424
+ end
425
+
426
+ end
427
+ ~~~
428
+
429
+ % end