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,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