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,281 @@
1
+ % render "layouts/guides.html" do
2
+
3
+ A common workflow is to have a tester timing file defined and managed outside of Origen, in
4
+ which case the main concern within your Origen source code is simply to refer to required
5
+ timeset(s) by name.
6
+
7
+ However, Origen does also support a more complex timing definition where waveforms
8
+ can be defined and mastered in Origen source code. That is discussed later on in the
9
+ [Complex Timing](<%= path "guides/pattern/timing/#Complex_Timing" %>) section.
10
+
11
+
12
+ ### Simple Timing
13
+
14
+ This guide gives an overview of some of the most common timing related
15
+ methods, but to get a complete overview of what is available consult
16
+ the [OrigenTesters::Timing API](http://origen-sdk.org/testers/api/OrigenTesters/Timing.html).
17
+
18
+ A timeset declaration is used to provide information to Origen about what
19
+ timeset to use for future test cycles and what period of time each
20
+ cycle represents.
21
+
22
+ Normally this would be initialized within the startup method before generating any
23
+ vectors as shown below:
24
+
25
+ ~~~ruby
26
+ class MySoCController
27
+ include Origen::Controller
28
+
29
+ def startup(options)
30
+ $tester.set_timeset("mode_entry", 40)
31
+ end
32
+ end
33
+ ~~~
34
+
35
+ The first argument is the name of the timeset, this should correspond to
36
+ how the timeset will be named within the test program, and the second argument
37
+ is the cycle period in nano-seconds.
38
+
39
+ This method also accepts a block in which case the contained vectors will generate
40
+ with the supplied timeset and subsequent vectors will return to the previous timeset
41
+ automatically.
42
+
43
+ ~~~ruby
44
+ $tester.set_timeset("bist_50mhz", 20) do
45
+ # Any cycles generated in here will use 20ns for the period
46
+ end
47
+ ~~~
48
+
49
+ The arguments can also be supplied as a single array, or not at all. In the latter case
50
+ the existing timeset will simply be preserved. This is useful if you have timesets that
51
+ can be conditionally set based on the target.
52
+
53
+ ~~~ruby
54
+ # Target 1
55
+ $dut.readout_timeset = ["readout", 120]
56
+ # Target 2
57
+ $dut.readout_timeset = false
58
+
59
+ # This code is compatible with both targets, in the first case the timeset will switch
60
+ # over, in the second case the existing timeset will be preserved.
61
+ $tester.set_timeset($dut.readout_timeset) do
62
+ # Generate readout vectors...
63
+ end
64
+ ~~~
65
+
66
+ #### Creating a Timing Set
67
+
68
+ Currently the creation of the timing set for a given test platform must be
69
+ done independently of Origen, however adding an Origen API for this is on the roadmap.
70
+
71
+ #### Waiting
72
+
73
+ All $tester models will support the following API to generate wait states
74
+ in the test patterns.
75
+
76
+ Wait for specific number of cycles:
77
+
78
+ ~~~ruby
79
+ $tester.wait(cycles: 1000)
80
+ ~~~
81
+
82
+ Wait for a period of time:
83
+
84
+ ~~~ruby
85
+ $tester.wait(time_in_us: 500)
86
+ $tester.wait(time_in_ms: 10)
87
+ ~~~
88
+
89
+ A shorthand for the above cases is available:
90
+
91
+ ~~~ruby
92
+ 500.us! # Wait for 500us
93
+ 10.ms! # Wait for 10ms
94
+ ~~~
95
+
96
+ Multiple times specified in different units will be added together, this can be useful
97
+ if the delay is based on a complex calculation:
98
+
99
+ ~~~ruby
100
+ # Wait for 500us + 100 cycles
101
+ $tester.wait(time_in_us: 500, cycles: 100)
102
+ ~~~
103
+
104
+ #### Waiting for an Event
105
+
106
+ All testers provide an API for generating match loops, these can be used to
107
+ make the pattern wait dynamically for a pin-based or even a register-based
108
+ event.
109
+
110
+ To do this enable the <code>:match</code> option and supply a block, within the block
111
+ generate the vectors that will test if the condition has been met.
112
+ Any time options passed in will be applied as a timeout, i.e. the maximum time to
113
+ wait for the required condition to resolve.
114
+
115
+ Here are some examples:
116
+
117
+ ~~~ruby
118
+ # Wait for up to 1 second for the done bit to be set
119
+ $tester.wait(match: true, time_in_s: 1) do
120
+ reg(:status_reg).bit(:done).read!(1)
121
+ end
122
+
123
+ # Wait for up to 1 second for the done pin to be set
124
+ $tester.wait(match: true, time_in_s: 1) do
125
+ pin(:done).assert!(1)
126
+ end
127
+ ~~~
128
+
129
+ ### Complex Timing
130
+
131
+ #### Defining Timesets
132
+
133
+ A wave object defines the waveform that should be applied to a pin, and each pin will
134
+ have two wave objects assigned to it - one for drive cycles and one for cycles where the
135
+ pin is being read/compared.
136
+
137
+ A timeset object is used to collect the wave objects for all pins. Multiple timesets can
138
+ be defined and therefore the waveforms being applied to the pins can be changed by changing
139
+ the timeset.
140
+ The API to change the timeset is the same as that already discussed above:
141
+
142
+ ~~~ruby
143
+ tester.set_timeset('func', 100)
144
+ ~~~
145
+
146
+ The period of the timeset can be referenced in the wave definitions to make the waveforms
147
+ keep the same shape with different period settings.
148
+
149
+ Here is the most basic timeset definition, this will give all pins a default waveform which
150
+ drives for the whole period on drive cycles, and strobes at 50% of compare cycles:
151
+
152
+ ~~~ruby
153
+ # Simple definition, all pins have default waves
154
+ add_timeset :t1
155
+ ~~~
156
+
157
+ Here is a more complex definition, which changes the default compare for all pins to be at
158
+ 25% of the period, and which adds a unique drive wave to the :tck pin to create a clock:
159
+
160
+ ~~~ruby
161
+ # Complex definition, defines an alternative default compare wave and specific timing for :tck
162
+ timeset :func do |t|
163
+ t.compare_wave do |w|
164
+ w.compare :data, at: "period / 4"
165
+ end
166
+
167
+ t.drive_wave :tck do |w|
168
+ w.drive :data, at: 0
169
+ w.drive 0, at: 25
170
+ w.dont_care at: "period - 10" # Just to show that dont_care can be used
171
+ end
172
+ end
173
+ ~~~
174
+
175
+ Pin groups can also be referenced in the timeset definition, here to add common drive timing
176
+ to all pins in :gpio, and with a special compare waveform for :gpio5 only:
177
+
178
+ ~~~ruby
179
+ # Another timeset to show the wave assignment to pin groups
180
+ timeset :t2 do |t|
181
+ t.compare_wave :gpio5 do |w|
182
+ w.compare :data, at: 100
183
+ end
184
+
185
+ t.drive_wave :gpio do |w|
186
+ w.drive :data, at: 200
187
+ end
188
+ end
189
+ ~~~
190
+
191
+ Note that the API currently only supports edge compares, i.e. window compares cannot be defined.
192
+
193
+ Additional drive and compare waves can be defined for any pin by giving them a code which can
194
+ be used to select the given waveform in a pattern - i.e. [the approach used by the
195
+ V93K tester to select from multiple available waveforms.](<%= path "guides/pattern/v93k" %>)
196
+
197
+ Here is an example with a single pulse waveform defined for a clk pin which will be applied
198
+ when the pin is driven to <code>1</code>, and a double pulse waveform that will be applied when the pin
199
+ is drive to <code>T</code>:
200
+
201
+ ~~~ruby
202
+ timeset :func do |t|
203
+ t.drive_wave :tck do |w|
204
+ w.drive 1, at: 0
205
+ w.drive 0, at: 20
206
+ end
207
+
208
+ t.drive_wave :tck, code: 'T' do |w|
209
+ w.drive 1, at: 0
210
+ w.drive 0, at: 10
211
+ w.drive 1, at: 20
212
+ w.drive 0, at: 30
213
+ end
214
+ end
215
+ ~~~
216
+
217
+ #### Consuming Timeset Data
218
+
219
+ The currently selected timeset can be retrieved via the following methods which are aliases:
220
+
221
+ ~~~ruby
222
+ dut.timeset # => instance of Origen::Pins::Timing::Timeset
223
+ dut.current_timeset
224
+ ~~~
225
+
226
+ Using the plural returns a hash containing all timesets, thereby allowing access to specific timesets
227
+ regardless of the current selection:
228
+
229
+ ~~~ruby
230
+ dut.timesets # => Hash
231
+ dut.timesets[:func] # => instance of Origen::Pins::Timing::Timeset
232
+ # This will also work:
233
+ dut.timeset(:func)
234
+ ~~~
235
+
236
+ Each timeset stores the waves in two arrays, one for drive waves and another for the compare waves:
237
+
238
+ ~~~ruby
239
+ dut.timeset(:func).drive_waves # => Array containing instances of Origen::Pins::Timing::Wave
240
+ dut.timeset(:func).compare_waves
241
+ ~~~
242
+
243
+ Each wave object has an events array, and the pins assigned to it can also be retrieved:
244
+
245
+ ~~~ruby
246
+ drive_wave = dut.timeset(:func).drive_waves.first
247
+ compare_wave = dut.timeset(:func).compare_waves.first
248
+
249
+ drive_wave.events # => [[0, :data], [50, 0], [75, :x]]
250
+ drive_wave.pins # => Array of Origen::Pins::Pin instances
251
+
252
+ compare_wave.events # => [["period / 2", :data]]
253
+ ~~~
254
+
255
+ The method evaluated_events can be used to get the events with the formulas evaluated based on the
256
+ current period:
257
+
258
+ ~~~ruby
259
+ compare_wave.events # => [["period / 2", :data]]
260
+ compare_wave.evaluated_events # => [[50, :data]]
261
+ ~~~
262
+
263
+ The waves assigned to a given pin by the current timeset can also be accessed via the pin API:
264
+
265
+ ~~~ruby
266
+ dut.pin(:tms).compare_wave.events[0] # => ["period / 2", :data]
267
+ ~~~
268
+
269
+ The waveform associated with a particular code can be accessed as follows:
270
+
271
+ ~~~ruby
272
+ # The wave for driving 0 and 1 is returned by default, these are all aliases:
273
+ dut.pin(:clk).drive_wave.events # => [[0, 1], [20, 0]]
274
+ dut.pin(:clk).drive_wave(0).events # => [[0, 1], [20, 0]]
275
+ dut.pin(:clk).drive_wave(1).events # => [[0, 1], [20, 0]]
276
+
277
+ dut.pin(:clk).drive_wave('T').events # => [[0, 1], [10, 0], [20, 1], [30, 0]]
278
+ ~~~
279
+
280
+
281
+ % end
@@ -0,0 +1,10 @@
1
+ % render "layouts/guides.html" do
2
+
3
+ This page will be used to document any UltraFLEX-only APIs related to pattern generation,
4
+ however the goal is to have as few of these as possible so that Origen pattern source code can re-target
5
+ automatically to any supported platform.
6
+
7
+ There are no significant APIs in this category currently, therefore refer to the
8
+ [Common Pattern API](<%= path "guides/pattern/common" %>) which can fully target the UltraFLEX.
9
+
10
+ % end
@@ -0,0 +1,41 @@
1
+ % render "layouts/guides.html" do
2
+
3
+ All of the
4
+ [Common Pattern API](<%= path "guides/pattern/common" %>) can be used to target the V93K.
5
+
6
+ This page is used to document any additional V93K-specific APIs related to pattern generation,
7
+ however the goal is to have as few of these as possible so that Origen pattern source code can re-target
8
+ automatically to any supported platform.
9
+
10
+
11
+ #### Driving Custom Waveforms
12
+
13
+ The V93K has a very powerful waveform generator and it is common to use many more pin state codes than
14
+ other platforms in order to select particular waveforms.
15
+
16
+ Say for example that we have various waveforms defined to drive a clock pin, where a '1' on the pin
17
+ will drive a single pulse and a code of 'P' will select a different waveform which will create 4 pulses
18
+ per cycle.
19
+
20
+ The 'P' code (or any other letter) can be driven very easily as shown below:
21
+
22
+ ~~~ruby
23
+ # Example vectors
24
+ pin(:clk).drive!(1) # 1 X XXXX 10100001
25
+ 1.cycle # 1 X XXXX 10100001
26
+ pin(:clk).drive!('P') # P X XXXX 10100001
27
+ 1.cycle # P X XXXX 10100001
28
+ pin(:clk).drive!(1) # 1 X XXXX 10100001
29
+ ~~~
30
+
31
+ The above vectors would produce the following waveform per the earlier description of 'P':
32
+
33
+ ~~~text
34
+ _______ _______ _ _ _ _ _ _ _ _ _______
35
+ clk _______| |_______| |_| |_| |_| |_| |_| |_| |_| |_| |_______| |
36
+
37
+ ~~~
38
+
39
+
40
+
41
+ % end
@@ -0,0 +1,78 @@
1
+ % render "layouts/guides.html" do
2
+
3
+ A big advantage that the Origen program generator has over other
4
+ tools is that even if you need to generate a test program file that is not
5
+ officially supported by the generator you can easily work around it
6
+ by dropping down to a template for that specific section of the program.
7
+
8
+ A nice offshoot of this capability is that any custom code in your
9
+ test program (such as custom Visual Basic or C++ code for example) can be
10
+ dynamically generated via code templates.
11
+
12
+ #### A Dynamic VB Example
13
+
14
+ Generally using templates within the context of a test program is the same
15
+ as using them in any other context and therefore the
16
+ [Compiler Guide](<%= path "guides/compiler/introduction" %>) should be consulted
17
+ for more details on the compiler syntax that should be used.
18
+
19
+ For a tester oriented example here is a snippet of some VB code that has been
20
+ marked up with Origen compiler directives:
21
+
22
+ ~~~eruby
23
+ NUM_VREGS = <%= "<" + "%= $dut.vregs.size %" + ">" %>
24
+
25
+ ' Now initialize DUT variables for each site
26
+ For lSite = 0 To lSiteCnt
27
+ With oDUTData(lSite)
28
+ Call .Clear
29
+ <%= "%" %> $dut.vregs.each do |vreg|
30
+ Call .AddVreg(<%= "<" + "%= vreg.nominal_level %" + ">" %>)
31
+ <%= "%" %> end
32
+ End With
33
+ Next
34
+ ~~~
35
+
36
+ So for a device with a 1.2V and a 3V regulator this would compile to:
37
+
38
+ ~~~text
39
+ NUM_VREGS = 2
40
+
41
+ ' Now initialize DUT variables for each site
42
+ For lSite = 0 To lSiteCnt
43
+ With oDUTData(lSite)
44
+ Call .Clear
45
+ Call .AddVreg(1.2)
46
+ Call .AddVreg(3)
47
+ End With
48
+ Next
49
+ ~~~
50
+
51
+ Whereas for a device with only a single 1.2V regulator we would end up with:
52
+
53
+ ~~~text
54
+ NUM_VREGS = 1
55
+
56
+ ' Now initialize DUT variables for each site
57
+ For lSite = 0 To lSiteCnt
58
+ With oDUTData(lSite)
59
+ Call .Clear
60
+ Call .AddVreg(1.2)
61
+ End With
62
+ Next
63
+ ~~~
64
+
65
+ #### Building Dynamic Code
66
+
67
+ Compiling any templates that form part of your test program can be co-ordinated
68
+ within a Resources file by calling the <code>compile</code> method.
69
+ Any option arguments passed in will be available within the <code>options</code>
70
+ hash within the template.
71
+
72
+ ~~~ruby
73
+ Resources.create do
74
+ compile "templates/j750/vreg_funcs.bas", max_vdd: 5.V
75
+ end
76
+ ~~~
77
+
78
+ % end
@@ -0,0 +1,5 @@
1
+ % render "layouts/guides.html" do
2
+
3
+ <%= render "partials/placeholder.md" %>
4
+
5
+ % end
@@ -0,0 +1,402 @@
1
+ % render "layouts/guides.html" do
2
+
3
+ Origen allows test descriptions to be entered quickly and easily within the
4
+ test flow source file, enabling a test program document to be produced that is extremely
5
+ accurate due to it being derived from the same source as the program itself.
6
+
7
+ The application must also define a documentation interface in order to do the translation
8
+ between the application-specific flow API and the Origen test program documentation back end -
9
+ this is the exact same principle as generating an interface for a specific ATE platform.
10
+
11
+ Typically creating a documentation interface is much easier than creating an ATE platform
12
+ interface and is discussed
13
+ [later in this guide](<%= path "guides/program/doc/#Creating_A_Documentation_Interface" %>).
14
+ Note that if you don't initially have time to set up the documentation interface you should still
15
+ try and document the program as described here since the code it produces will still be
16
+ compatible with any tester interface. Then when time allows you can setup the documentation
17
+ interface with the hard part of actually describing the tests already done.
18
+
19
+ The [Documentation Helpers](http://origen-sdk.org/doc_helpers) plugin provides off
20
+ the shelf [test flow helpers](http://origen-sdk.org/doc_helpers/examples/test/flow)
21
+ to render such documentation metadata as a well formatted web document.
22
+
23
+ #### Flow Markup
24
+
25
+ Flow sections and individual tests should be documented like this:
26
+
27
+ ~~~ruby
28
+ # A Test Sub Module
29
+ # Test flow modules like this will collapse and nest when they are included in a parent
30
+ # flow via the import command. The first line will be the name assigned to the collapsible
31
+ # area, the rest of these comments will be shown when it expands. **It will be parsed for
32
+ # markdown.**
33
+ Flow.create do
34
+ # Any comments in here will attach as a description to the next test
35
+ func :measure_vreg, bin: 45, vdd: min
36
+
37
+ # This is a description of what this test does
38
+ #- Prefixing the line with a '-' will cause it to be private, so this is how you would
39
+ #- record some implementation detail that is of interest to engineers working on this
40
+ #- flow, but which is not relevant to its overall operation
41
+ func :vreg_func1, bin: 50
42
+
43
+ # All comments can contain markdown, for example
44
+ #
45
+ # * A bulleted
46
+ # * list
47
+ func :vreg_func2, bin: 55, iload: 50.uA
48
+ end
49
+ ~~~
50
+
51
+ When generated against an appropriate documentation interface and passed to the
52
+ [Documentation Helpers](http://origen-sdk.org/doc_helpers) plugin, this would generate a
53
+ flow section like this (click to expand):
54
+
55
+ <div class="panel-group" id="test_flow1">
56
+
57
+ <div class="panel panel-default">
58
+ <a href="#_" class="expandcollapse btn btn-mini pull-right" state="0"><i class="icon-plus-sign"></i></a>
59
+ <div class="panel-heading clickable" style="background:whitesmoke" data-toggle="collapse" data-parent="#blah2" href="#collapseAccordion3">
60
+ <a class="no-underline">
61
+ A Test Sub Module
62
+ </a>
63
+ </div>
64
+ <div id="collapseAccordion3" class="panel-collapse collapse">
65
+ <div class="panel-body">
66
+ <p>
67
+ Test flow modules like this will collapse and nest when they are included in a parent
68
+ flow via the import command. The first line will be the name assigned to the collapsible
69
+ area, the rest of these comments will be shown when it expands. <strong>It will be parsed for
70
+ markdown.</strong>
71
+ </p>
72
+
73
+ <table class="table table-condensed table-bordered flow-table">
74
+ <thead><tr>
75
+ <th class="col1">Test</th>
76
+ <th class="col2">Number</th>
77
+ <th class="col3">HBin</th>
78
+ <th class="col3">SBin</th>
79
+ <th class="col5">Attributes</th>
80
+ <th class="col6">Description</th>
81
+ </tr></thead>
82
+ <tbody>
83
+ <tr>
84
+ <td class="col1">
85
+ <div>measure_vreg</div>
86
+ </td>
87
+ <td class="col2">#45000</td>
88
+ <td class="col3">B45</td>
89
+ <td class="col4"></td>
90
+ <td class="col5 attributes">
91
+ <ul>
92
+ <li><strong>Vdd</strong>: min</li>
93
+ </ul>
94
+ </td>
95
+ <td class="col6">
96
+ <p>Any comments in here will attach as a description to the next test</p>
97
+ </td>
98
+ </tr>
99
+
100
+ <tr>
101
+ <td class="col1">
102
+ <div>vreg_func1</div>
103
+ </td>
104
+ <td class="col2">#50000</td>
105
+ <td class="col3">B50</td>
106
+ <td class="col4"></td>
107
+ <td class="col5 attributes">
108
+ <ul>
109
+ </ul>
110
+ </td>
111
+ <td class="col6">
112
+ <p>This is a description of what this test does</p>
113
+ </td>
114
+ </tr>
115
+
116
+ <tr>
117
+ <td class="col1">
118
+ <div>vreg_func2</div>
119
+ </td>
120
+ <td class="col2">#55000</td>
121
+ <td class="col3">B55</td>
122
+ <td class="col4"></td>
123
+ <td class="col5 attributes">
124
+ <ul>
125
+ <li><strong>iload</strong>: 50E-06</li>
126
+ </ul>
127
+ </td>
128
+ <td class="col6">
129
+ <p>All comments can contain markdown, for example</p>
130
+ <ul>
131
+ <li>A bulleted</li>
132
+ <li>list</li>
133
+ </ul>
134
+ </td>
135
+ </tr>
136
+ </tbody>
137
+ </table>
138
+ </div>
139
+ </div>
140
+ </div>
141
+ </div>
142
+
143
+
144
+ #### Documenting Structure
145
+
146
+ Tests can be grouped together by wrapping them with the <code>pp</code> helper, here are
147
+ the two functional tests grouped together with some description added about what the
148
+ group contains:
149
+
150
+ ~~~ruby
151
+ # A Test Sub Module
152
+ # Test flow modules like this will collapse and nest when they are included in a parent
153
+ # flow via the import command. The first line will be the name assigned to the collapsible
154
+ # area, the rest of these comments will be shown when it expands. **It will be parsed for
155
+ # markdown.**
156
+ Flow.create do
157
+ # Any comments in here will attach as a description to the next test
158
+ func :measure_vreg, bin: 45, vdd: min
159
+
160
+ # Within flow sections should be marked like this (this is the same API to indicate
161
+ # structure in pattern logic to). This text will appear when the collapsible area is
162
+ # shown and will be parsed for markdown.
163
+ pp "Functional Tests" do
164
+ # This is a description of what this test does
165
+ #- Prefixing the line with a '-' will cause it to be private, so this is how you would
166
+ #- record some implementation detail that is of interest to engineers working on this
167
+ #- flow, but which is not relevant to its overall operation
168
+ func :vreg_func1, bin: 50
169
+
170
+ # All comments can contain markdown, for example
171
+ #
172
+ # * A bulleted
173
+ # * list
174
+ func :vreg_func2, bin: 55, iload: 50.uA
175
+ end
176
+ end
177
+ ~~~
178
+
179
+ The functional tests will now be nested in a collapsible group:
180
+
181
+ <div class="panel-group" id="test_flow2">
182
+
183
+ <div class="panel panel-default">
184
+ <a href="#_" class="expandcollapse btn btn-mini pull-right" state="0"><i class="icon-plus-sign"></i></a>
185
+ <div class="panel-heading clickable" style="background:whitesmoke" data-toggle="collapse" data-parent="#blah2" href="#collapseAccordion4">
186
+ <a class="no-underline">
187
+ A Test Sub Module
188
+ </a>
189
+ </div>
190
+ <div id="collapseAccordion4" class="panel-collapse collapse">
191
+ <div class="panel-body">
192
+ <p>
193
+ Test flow modules like this will collapse and nest when they are included in a parent
194
+ flow via the import command. The first line will be the name assigned to the collapsible
195
+ area, the rest of these comments will be shown when it expands. <strong>It will be parsed for
196
+ markdown.</strong>
197
+ </p>
198
+
199
+ <table class="table table-condensed table-bordered flow-table">
200
+ <thead><tr>
201
+ <th class="col1">Test</th>
202
+ <th class="col2">Number</th>
203
+ <th class="col3">HBin</th>
204
+ <th class="col3">SBin</th>
205
+ <th class="col5">Attributes</th>
206
+ <th class="col6">Description</th>
207
+ </tr></thead>
208
+ <tbody>
209
+ <tr>
210
+ <td class="col1">
211
+ <div>measure_vreg</div>
212
+ </td>
213
+ <td class="col2">#45000</td>
214
+ <td class="col3">B45</td>
215
+ <td class="col4"></td>
216
+ <td class="col5 attributes">
217
+ <ul>
218
+ <li><strong>Vdd</strong>: min</li>
219
+ </ul>
220
+ </td>
221
+ <td class="col6">
222
+ <p>Any comments in here will attach as a description to the next test</p>
223
+ </td>
224
+ </tr>
225
+ </tbody>
226
+ </table>
227
+
228
+ <div class="panel panel-default">
229
+ <a href="#_" class="expandcollapse btn btn-mini pull-right" state="0"><i class="icon-plus-sign"></i></a>
230
+ <div class="panel-heading clickable" style="background:whitesmoke" data-toggle="collapse" data-parent="#blah2" href="#collapseAccordion5">
231
+ <a class="no-underscore">
232
+ Functional Tests
233
+ </a>
234
+ </div>
235
+
236
+ <div id="collapseAccordion5" class="panel-collapse collapse">
237
+ <div class="panel-body">
238
+ <p>
239
+ Within flow sections should be marked like this (this is the same API to indicate
240
+ structure in pattern logic to). This text will appear when the collapsible area is
241
+ shown and will be parsed for markdown.
242
+ </p>
243
+
244
+ <table class="table table-condensed table-bordered flow-table">
245
+ <thead><tr>
246
+ <th class="col1">Test</th>
247
+ <th class="col2">Number</th>
248
+ <th class="col3">HBin</th>
249
+ <th class="col3">SBin</th>
250
+ <th class="col5">Attributes</th>
251
+ <th class="col6">Description</th>
252
+ </tr></thead>
253
+ <tbody>
254
+ <tr>
255
+ <td class="col1">
256
+ <div>vreg_func1</div>
257
+ </td>
258
+ <td class="col2">#50000</td>
259
+ <td class="col3">B50</td>
260
+ <td class="col4"></td>
261
+ <td class="col5 attributes">
262
+ <ul>
263
+ </ul>
264
+ </td>
265
+ <td class="col6">
266
+ <p>This is a description of what this test does</p>
267
+ </td>
268
+ </tr>
269
+
270
+ <tr>
271
+ <td class="col1">
272
+ <div>vreg_func2</div>
273
+ </td>
274
+ <td class="col2">#55000</td>
275
+ <td class="col3">B55</td>
276
+ <td class="col4"></td>
277
+ <td class="col5 attributes">
278
+ <ul>
279
+ <li><strong>iload</strong>: 50E-06</li>
280
+ </ul>
281
+ </td>
282
+ <td class="col6">
283
+ <p>All comments can contain markdown, for example</p>
284
+ <ul>
285
+ <li>A bulleted</li>
286
+ <li>list</li>
287
+ </ul>
288
+ </td>
289
+ </tr>
290
+ </tbody>
291
+ </table>
292
+ </div>
293
+ </div>
294
+ </div>
295
+ </div>
296
+ </div>
297
+ </div>
298
+ </div>
299
+
300
+
301
+ #### Dynamic Documentation From Helpers
302
+
303
+ Helper methods can be added to your interface to generate multiple tests or to otherwise dynamically generate a
304
+ section of the flow.
305
+
306
+ Within these methods the <code>cc</code> method can be used to stage comments that will be attached to
307
+ the next test to be generated:
308
+
309
+ ~~~ruby
310
+ def program_sequence
311
+ cc "Issue a pulse"
312
+ func :program_20us
313
+ cc "Do a verify"
314
+ func :read_margin0
315
+ end
316
+ ~~~
317
+
318
+ #### Creating A Documentation Interface
319
+
320
+ A documentation interface can be thought of as an interface for a really simple tester which only has the
321
+ concept of a flow and a collection of tests.
322
+
323
+ Here is the basic starting point for any documentation interface:
324
+
325
+ ~~~ruby
326
+ class DocInterface
327
+ include OrigenTesters::Doc::Generator
328
+
329
+ # Add a test to the collection
330
+ def add_test(name, options)
331
+ tests.add(name, options)
332
+ end
333
+
334
+ # Add a flow entry
335
+ def add_flow_entry(test, options)
336
+ flow.test(test, options)
337
+ end
338
+ end
339
+ ~~~
340
+
341
+ As with any interface it is then required to create methods to translate your domain specific
342
+ flow API into calls to these two key methods to add a test and a flow entry.
343
+
344
+ Our example flow here has a <code>func</code> method, we might implement the handler for that like this:
345
+
346
+ ~~~ruby
347
+ def func(name, options={})
348
+ add_test(name, options)
349
+ add_flow_entry(name, options)
350
+ end
351
+ ~~~
352
+
353
+ Over and above that what happens next is very domain specific and depends if any processing
354
+ or sanitizing of the options or names are required to produce an accurate document.
355
+ Some domain specific examples from the simple flow in this guide would be:
356
+
357
+ By default any options passed to the <code>add_test</code> method will be rendered into the
358
+ attributes column. In our case we are supplying the bin as a flow line option and that will
359
+ already be displayed in the dedicated column when it is passed to the flow entry. To inhibit
360
+ the bin appearing in the test attributes we can screen the options like this:
361
+
362
+ ~~~ruby
363
+ # Add a test to the collection
364
+ def add_test(name, options)
365
+ # Delete any keys that we don't want to assign to the instance, this keeps
366
+ # the attributes column clean, flow control keys will be screened by Origen automatically
367
+ [:bin, :some, :other, :keys,
368
+ ].each { |k| options.delete(k) }
369
+ tests.add(name, options)
370
+ end
371
+ ~~~
372
+
373
+ As noted in the above comment any keys related to [flow control](<%= path "guides/program/flowapi" %>)
374
+ will be automatically screened and handled by Origen (doc helpers knows how to display this
375
+ information to).
376
+
377
+ Another convention from the above example was that we did not supply a test number and it was
378
+ automatically set to a multiple of the bin number,
379
+ we can handle that like this:
380
+
381
+ ~~~ruby
382
+ # Add a flow entry
383
+ def add_flow_entry(test, options)
384
+ options = sanitize_flow_options(options)
385
+ flow.test(test, options)
386
+ end
387
+
388
+ def sanitize_flow_options(options)
389
+ # If the number has not been set in the flow then set it to a multiple of the bin, if present
390
+ options[:number] ||= options[:bin] ? options[:bin] * 1000 : nil
391
+ options
392
+ end
393
+ ~~~
394
+
395
+ Note that many of the methods involved in processing the test options such as the
396
+ <code>sanitize_flow_options</code> method here would be common to all
397
+ interfaces and therefore should not need special handling specifically for documentation.
398
+ Rather you
399
+ should create a common module that gets included into all interfaces to handle the non-tester-platform
400
+ specific concerns like these.
401
+
402
+ % end