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.
- checksums.yaml +4 -4
- data/config/application.rb +34 -1
- data/config/version.rb +1 -1
- data/lib/origen_testers/flow.rb +1 -0
- data/lib/origen_testers/interface.rb +28 -0
- data/lib/origen_testers/pattern_compilers/v93k.rb +3 -1
- data/lib/origen_testers/smartest_based_tester/base.rb +14 -1
- data/lib/origen_testers/smartest_based_tester/base/test_methods/ac_tml.rb +10 -10
- data/lib/origen_testers/test/interface.rb +3 -0
- data/pattern/tester_overlay.rb +12 -1
- data/program/_erase.rb +1 -1
- data/program/components/_prb1_main.rb +3 -3
- data/program/test.rb +2 -2
- data/templates/origen_guides/pattern/common.md.erb +376 -0
- data/templates/origen_guides/pattern/creating.md.erb +133 -0
- data/templates/origen_guides/pattern/custom.md.erb +5 -0
- data/templates/origen_guides/pattern/documenting.md.erb +431 -0
- data/templates/origen_guides/pattern/introduction.md.erb +38 -0
- data/templates/origen_guides/pattern/j750.md.erb +10 -0
- data/templates/origen_guides/pattern/name.md.erb +511 -0
- data/templates/origen_guides/pattern/pins.md.erb +125 -0
- data/templates/origen_guides/pattern/registers.md.erb +300 -0
- data/templates/origen_guides/pattern/running.md.erb +105 -0
- data/templates/origen_guides/pattern/timing.md.erb +281 -0
- data/templates/origen_guides/pattern/ultraflex.md.erb +10 -0
- data/templates/origen_guides/pattern/v93k.md.erb +41 -0
- data/templates/origen_guides/program/code.md.erb +78 -0
- data/templates/origen_guides/program/custom.md.erb +5 -0
- data/templates/origen_guides/program/doc.md.erb +402 -0
- data/templates/origen_guides/program/flowapi.md.erb +249 -0
- data/templates/origen_guides/program/flows.md.erb +429 -0
- data/templates/origen_guides/program/generating.md.erb +97 -0
- data/templates/origen_guides/program/interface.md.erb +248 -0
- data/templates/origen_guides/program/introduction.md.erb +56 -0
- data/templates/origen_guides/program/j750.md.erb +514 -0
- data/templates/origen_guides/program/philosophy.md.erb +99 -0
- data/templates/origen_guides/program/resources.md.erb +141 -0
- data/templates/origen_guides/program/ultraflex.md.erb +5 -0
- data/templates/origen_guides/program/v93k.md.erb +456 -0
- data/templates/web/layouts/_guides.html.erb +10 -0
- data/templates/web/partials/_placeholder.md.erb +10 -0
- 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,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
|