origen_testers 0.19.0 → 0.19.2
Sign up to get free protection for your applications and to get access to all the features.
- 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,125 @@
|
|
1
|
+
% render "layouts/guides.html" do
|
2
|
+
|
3
|
+
The control of pin states represents the lowest level of Origen's pattern generation
|
4
|
+
API.
|
5
|
+
|
6
|
+
Generally for most modern applications you should need to do this very rarely
|
7
|
+
and mainly when creating mode entry and reset sequences for your
|
8
|
+
device.
|
9
|
+
For most applications a [plugin](<%= path "plugins" %>)
|
10
|
+
such as the [JTAG driver](http://origen-sdk.org/jtag) should be used to
|
11
|
+
abstract much of the lower level details about the values to be applied to a given
|
12
|
+
pin by a given test vector.
|
13
|
+
If your application uses a proprietary interface then it is recommended that you
|
14
|
+
create a dedicated class to implement the interface
|
15
|
+
protocol and to deal with all of the manipulation of pin states.
|
16
|
+
|
17
|
+
#### Basic Concept
|
18
|
+
|
19
|
+
All of Origen's vector-based tester models will support a <code>cycle</code> method
|
20
|
+
which will drive or expect the current values held by all pins for one clock cycle.
|
21
|
+
In other words the cycle method takes a snapshot of the current pin states and then
|
22
|
+
applies them to the DUT.
|
23
|
+
|
24
|
+
Origen's pin API provides models that represent a DUT's pins and pin groups
|
25
|
+
and methods with which to manipulate their states between tester cycles.
|
26
|
+
|
27
|
+
See the [Pins](<%= path "guides/models/pins" %>) section of
|
28
|
+
the [Models](<%= path "guides/models/introduction" %>) guide for details and examples
|
29
|
+
of how to add and manipulate pin states within your model logic.
|
30
|
+
|
31
|
+
#### Recommended Architecture
|
32
|
+
|
33
|
+
Here are the key components of the recommended architecture:
|
34
|
+
|
35
|
+
1. All pins and aliases are defined within the top-level models only, the top-level model is the only object
|
36
|
+
that owns pins in the entire application for a given target setup.
|
37
|
+
2. Functions should be added to the pins to represent the different functionality available
|
38
|
+
on the pins depending on the mode.
|
39
|
+
3. The availability of the required functions is a contract between a given sub-model
|
40
|
+
and the top-level, i.e. the NVM models and test logic assume that all top-level models will
|
41
|
+
provide functions named *nvm_fail* and *nvm_done*.
|
42
|
+
4. Each model only refers to the pins using the name/function that it understands.
|
43
|
+
5. The test block/plugin that is primarily responsible for a given test pattern
|
44
|
+
can still control the pin order of the created pattern by using the <code>pin_pattern_order</code>
|
45
|
+
method.
|
46
|
+
|
47
|
+
The above approach has the benefits of encapsulating all pin definitions within the top-level model, so
|
48
|
+
that a device's TE could implement the details straight from the top-level DFT guide for example, while the lower level
|
49
|
+
modules can talk to the pins/signals that they know about.
|
50
|
+
|
51
|
+
Here is an example of how to implement this scheme in a top-level SoC model:
|
52
|
+
|
53
|
+
~~~ruby
|
54
|
+
class MySoC
|
55
|
+
include Origen::TopLevel
|
56
|
+
|
57
|
+
def initialize(options)
|
58
|
+
instantiate_pins(options)
|
59
|
+
end
|
60
|
+
|
61
|
+
def instantiate_pins(options)
|
62
|
+
# Common pins required by all to support mode entry sequences
|
63
|
+
add_pin :tclk, reset: :drive_lo
|
64
|
+
add_pin :trst, reset: :drive_hi
|
65
|
+
add_pin :extal
|
66
|
+
add_pin :xtal, reset: :drive_lo
|
67
|
+
add_pin :tms
|
68
|
+
add_pin :tdo
|
69
|
+
add_pin :tdi
|
70
|
+
add_pin :resetb
|
71
|
+
|
72
|
+
add_pins :data, size: 8
|
73
|
+
|
74
|
+
# Add NVM BIST mode functions
|
75
|
+
pin(:extal).add_function :nvm_clk
|
76
|
+
pin(:data)[2].add_function :nvm_fail
|
77
|
+
pin(:data)[3].add_function :nvm_done
|
78
|
+
pin(:data)[4].add_function :nvm_invoke
|
79
|
+
|
80
|
+
# Add additional function groups here...
|
81
|
+
end
|
82
|
+
end
|
83
|
+
~~~
|
84
|
+
|
85
|
+
#### Controlling the Pattern Pin Order
|
86
|
+
|
87
|
+
As a test engineer for a specific test module you may want more importance to be given to some pins
|
88
|
+
than others, or to otherwise order them to make them most readable for debugging the target module.
|
89
|
+
|
90
|
+
This can be achieved by calling the <code>pin_pattern_order</code> method:
|
91
|
+
|
92
|
+
~~~ruby
|
93
|
+
class NVM
|
94
|
+
include Origen::Model
|
95
|
+
|
96
|
+
def initialize
|
97
|
+
# Unspecified pins will appear in arbitrary order at the end
|
98
|
+
pin_pattern_order :nvm_clk, :nvm_invoke, :nvm_done, :nvm_fail
|
99
|
+
end
|
100
|
+
end
|
101
|
+
~~~
|
102
|
+
|
103
|
+
Aside from specifying the order of the pins this also specifies what the name should be, i.e. if a given
|
104
|
+
pin/pin group has multiple aliases then the one used to refer to the pin in the <code>pin_pattern_order</code>
|
105
|
+
is that one that will appear in the generated pattern.
|
106
|
+
|
107
|
+
By default any unspecified pins will appear in arbitrary order at the end. To include only the pins
|
108
|
+
specified then append the <code>:only</code> option at the end:
|
109
|
+
|
110
|
+
~~~ruby
|
111
|
+
# Only include these pins in the output pattern and in this order
|
112
|
+
pin_pattern_order :nvm_clk, :nvm_invoke, :nvm_done, :nvm_fail, only: true
|
113
|
+
~~~
|
114
|
+
|
115
|
+
Alternatively specific pins or pin groups can be excluded from appearing in the output file via
|
116
|
+
the <code>pin_pattern_exclude</code> method:
|
117
|
+
|
118
|
+
~~~ruby
|
119
|
+
# Don't include these pins in the pattern
|
120
|
+
pin_pattern_exclude :porte, :portf
|
121
|
+
~~~
|
122
|
+
|
123
|
+
An error will be raised if the same pin appears in both <code>pin_pattern_order</code> and <code>pin_pattern_exclude</code>.
|
124
|
+
|
125
|
+
% end
|
@@ -0,0 +1,300 @@
|
|
1
|
+
% render "layouts/guides.html" do
|
2
|
+
|
3
|
+
The majority of patterns are concerned with reading and writing to registers to make the
|
4
|
+
DUT do something and consequently
|
5
|
+
more than 90% of your time developing an Origen test application should be concerned with
|
6
|
+
writing code at the register level.
|
7
|
+
|
8
|
+
All test [transaction drivers](<%= path "plugins/#Transaction_Protocol_Drivers" %>)
|
9
|
+
such as the [ARM Debug driver](http://origen-sdk.org/arm_debug) are expected to support the basic
|
10
|
+
Origen register API. This allows the test engineer to develop code at register level and
|
11
|
+
independently of the underlying test communication protocol which can be easily changed
|
12
|
+
to something else as required.
|
13
|
+
|
14
|
+
#### Basic Concept
|
15
|
+
|
16
|
+
See the [Registers](<%= path "guides/models/registers" %>) section of
|
17
|
+
the [Models](<%= path "guides/models/introduction" %>) guide for details and examples
|
18
|
+
of how to add and manipulate register states within your model logic.
|
19
|
+
|
20
|
+
Interaction with the registers should be limited to the [model's controller](<%= path "guides/controllers/introduction" %>)
|
21
|
+
- no one else should reach into a model to manipulate its register state (this is not prevented
|
22
|
+
but recommended), and the controllers should instead expose interface methods for the outside
|
23
|
+
world to use. Internally such methods will work by manipulating registers in a sequence.
|
24
|
+
|
25
|
+
The <code>read!</code> and <code>write!</code> methods when called on a register (or bit) will
|
26
|
+
automatically fire off a request for the register to be written using the following
|
27
|
+
rules:
|
28
|
+
|
29
|
+
* If the model or controller that owns the register implements a <code>write_register</code> method
|
30
|
+
then call this with the target register passed in as the argument
|
31
|
+
* Otherwise if the object that owns the register implements an <code>owner</code> method,
|
32
|
+
then see if the object that this returns provides a suitable <code>write_register</code>
|
33
|
+
method
|
34
|
+
* If not then if a currently instantiated model includes the <code>Origen::TopLevel</code>
|
35
|
+
module then see if it (or its controller) has a <code>write_register</code> method available
|
36
|
+
* If the request has still not been fulfilled then raise an error
|
37
|
+
|
38
|
+
Read works in the same way except that it looks for a method called <code>read_register</code>.
|
39
|
+
|
40
|
+
What this all means is that within a controller you will build your
|
41
|
+
test logic from methods that look like this:
|
42
|
+
|
43
|
+
~~~ruby
|
44
|
+
def measure_vref(setting=nil)
|
45
|
+
if setting
|
46
|
+
ss "Measure the Vref voltage for setting #{setting}"
|
47
|
+
vref.level.write(setting)
|
48
|
+
else
|
49
|
+
ss "Measure the default Vref voltage"
|
50
|
+
end
|
51
|
+
vref.test_enable.write!(1)
|
52
|
+
end
|
53
|
+
|
54
|
+
# From a pattern call like this:
|
55
|
+
Pattern.create do
|
56
|
+
$dut.nvm.measure_vref(5)
|
57
|
+
end
|
58
|
+
~~~
|
59
|
+
|
60
|
+
The actual mechanism for how the registers are written is abstracted away from the
|
61
|
+
test logic itself and therefore the test logic is generally independent from the communication
|
62
|
+
protocol. This is a very powerful concept that allows plugins to be created that provide
|
63
|
+
test sequences for a specific silicon module and these can then be re-used on DUTs that
|
64
|
+
employ completely different register access protocols.
|
65
|
+
|
66
|
+
#### Recommended Architecture
|
67
|
+
|
68
|
+
This is the recommended architecture for modern Origen applications that will lend itself
|
69
|
+
to working well within a plugin-based environment.
|
70
|
+
|
71
|
+
Define registers in the child models that own them and create test methods to manipulate them
|
72
|
+
in the controller:
|
73
|
+
|
74
|
+
~~~ruby
|
75
|
+
class NVM
|
76
|
+
include Origen::Model
|
77
|
+
|
78
|
+
def initialize
|
79
|
+
reg :vref, 0x0003, size: 16 do |reg|
|
80
|
+
reg.bit 15, :test_enable
|
81
|
+
reg.bit 7..0, :level
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
class NVMController
|
87
|
+
include Origen::Controller
|
88
|
+
|
89
|
+
def measure_vref(setting=nil)
|
90
|
+
if setting
|
91
|
+
ss "Measure the Vref voltage for setting #{setting}"
|
92
|
+
vref.level.write(setting)
|
93
|
+
else
|
94
|
+
ss "Measure the default Vref voltage"
|
95
|
+
end
|
96
|
+
vref.test_enable.write!(1)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
~~~
|
100
|
+
|
101
|
+
Defer how to actually write the register to the top-level SoC controller and normally this would
|
102
|
+
be done via one of the available protocol plugins.
|
103
|
+
Here for example is an SoC which will write the register via the [Nexus protocol](http://origen-sdk.org/nexus):
|
104
|
+
|
105
|
+
~~~ruby
|
106
|
+
class MySoC
|
107
|
+
include Origen::TopLevel # Indicate to Origen that this model represents a top-level device object
|
108
|
+
end
|
109
|
+
|
110
|
+
class MySoCController
|
111
|
+
include Origen::Controller
|
112
|
+
include Nexus
|
113
|
+
|
114
|
+
# Process register reads using the Nexus protocol
|
115
|
+
def read_register(reg, options={})
|
116
|
+
nexus.read_register(reg, options)
|
117
|
+
end
|
118
|
+
|
119
|
+
# As above for write requests
|
120
|
+
def write_register(reg, options={})
|
121
|
+
nexus.write_register(reg, options)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
~~~
|
125
|
+
|
126
|
+
And that is all that is required, Origen takes care of the hook up and the behind the scenes
|
127
|
+
communication to make it all work.
|
128
|
+
|
129
|
+
Another target may then instantiate a different SoC model which could use a completely different
|
130
|
+
protocol like [ARM Debug](http://origen-sdk.org/arm_debug), in which case the NVM test module would
|
131
|
+
still work although the generated pattern would look completely different.
|
132
|
+
|
133
|
+
#### Bit Level Access
|
134
|
+
|
135
|
+
All registers support bit level updates, we have seen an example of this already:
|
136
|
+
|
137
|
+
~~~ruby
|
138
|
+
vref.test_enable.write!(1)
|
139
|
+
~~~
|
140
|
+
|
141
|
+
What this will do is update the value held by the given bits and then send the parent
|
142
|
+
register object to the <code>write_register</code> method for processing.
|
143
|
+
All other bits in the register will maintain the state that they had prior to this
|
144
|
+
operation commencing.
|
145
|
+
|
146
|
+
Since it is not generally possible to update only a subset of bits on a device the entire
|
147
|
+
register will still be updated on silicon.
|
148
|
+
However in the case of performing a bit-level read things get a bit more interesting.
|
149
|
+
|
150
|
+
The equivalent read operation will update the data values of the bits in the same way, but
|
151
|
+
it will also set a flag on those bits marking that they have been requested for read.
|
152
|
+
|
153
|
+
~~~ruby
|
154
|
+
vref.test_enable.read!(1)
|
155
|
+
~~~
|
156
|
+
|
157
|
+
The protocol driver can then look out for this flag when generating the readout vectors
|
158
|
+
and only enable a compare on the vectors that correspond to the bits marked for read.
|
159
|
+
Generally this takes a lot of the cognitive overhead out of writing patterns since you
|
160
|
+
can mentally disregard the state of all bits except the ones that you care about.
|
161
|
+
|
162
|
+
All standard Origen protocol plugins are expected to support this feature.
|
163
|
+
|
164
|
+
The same is true for store (meaning capture the value on the tester) or overlay operations:
|
165
|
+
|
166
|
+
~~~ruby
|
167
|
+
# Capture the value of the level bits
|
168
|
+
vref.level.store!
|
169
|
+
|
170
|
+
# Dynamically overlay the value written to the level bits
|
171
|
+
vref.level.overlay("vref_setting")
|
172
|
+
vref.write!
|
173
|
+
~~~
|
174
|
+
|
175
|
+
#### Combining Multiple Bit Level Accesses Into A Single Transaction
|
176
|
+
|
177
|
+
Multiple individual bits within a register can be accessed/manipulated within a single
|
178
|
+
transaction by making multiple bit-level calls to `read` (or `write`), followed by a single
|
179
|
+
register-level `read!` (or `write!`) operation:
|
180
|
+
|
181
|
+
~~~ruby
|
182
|
+
my_reg.my_bits_x.read(1)
|
183
|
+
my_reg.my_bits_z.read(0b101)
|
184
|
+
my_reg.read!
|
185
|
+
~~~
|
186
|
+
|
187
|
+
Sometimes you will see application code that combines the final transaction request with the
|
188
|
+
final bit-level operation, this will do the same thing as the above example:
|
189
|
+
|
190
|
+
~~~ruby
|
191
|
+
my_reg.my_bits_x.read(1)
|
192
|
+
my_reg.my_bits_z.read!(0b101)
|
193
|
+
~~~
|
194
|
+
|
195
|
+
If you prefer, an equivalent block form API is also available, this is equivalent to the above example:
|
196
|
+
|
197
|
+
~~~ruby
|
198
|
+
my_reg.read! do |reg|
|
199
|
+
reg.my_bits_x.read(1)
|
200
|
+
reg.my_bits_z.read(0b101)
|
201
|
+
end
|
202
|
+
~~~
|
203
|
+
|
204
|
+
#### Writing a Driver
|
205
|
+
|
206
|
+
Generally the code for an existing driver should be reviewed to see how to go about this,
|
207
|
+
the [JTAG driver](http://origen-sdk.org/jtag) would be a good example to look at,
|
208
|
+
but here are some basic pointers on good driver design.
|
209
|
+
|
210
|
+
All drivers should implement read and write register methods:
|
211
|
+
|
212
|
+
~~~ruby
|
213
|
+
def write_register(reg, options={})
|
214
|
+
end
|
215
|
+
|
216
|
+
def read_register(reg, options={})
|
217
|
+
end
|
218
|
+
~~~
|
219
|
+
|
220
|
+
The write methods are usually fairly simple, here is a basic example of how to do a parallel
|
221
|
+
and a serial protocol write:
|
222
|
+
|
223
|
+
~~~ruby
|
224
|
+
# Writing on a parallel port, let's say we have a 16-bit register and the
|
225
|
+
# data needs to be written on a pin group called data which is 8-bits
|
226
|
+
def write_register(reg, options={})
|
227
|
+
pin(:din).drive(1) # Let's say when this pin is high data is captured
|
228
|
+
# Drive the data in MSB -> LSB order
|
229
|
+
pins(:data).drive!(reg[15..8].data)
|
230
|
+
pins(:data).drive!(reg[7..0].data)
|
231
|
+
pin(:din).drive(0) # Turn off capture
|
232
|
+
end
|
233
|
+
|
234
|
+
# Writing on a serial port, same as above only this time the :data port is
|
235
|
+
# only 1-bit wide
|
236
|
+
def read_register(reg, options={})
|
237
|
+
pin(:din).drive(1) # Let's say when this pin is high data is captured
|
238
|
+
# Drive the data in MSB -> LSB order
|
239
|
+
reg.shift_out_left do |bit|
|
240
|
+
pin(:data).drive!(bit.data)
|
241
|
+
end
|
242
|
+
pin(:din).drive(0) # Turn off capture
|
243
|
+
end
|
244
|
+
~~~
|
245
|
+
|
246
|
+
Read methods are usually a bit more involved to implement the bit-specific read and
|
247
|
+
capture operations.
|
248
|
+
Here is a parallel and serial protocol example which supports bit-level read operations:
|
249
|
+
|
250
|
+
~~~ruby
|
251
|
+
# Reading on a parallel port, let's say we have a 16-bit register and the
|
252
|
+
# data needs to be read on a pin group called data which is 8-bits
|
253
|
+
def write_register(reg, options={})
|
254
|
+
pin(:dout).drive(1) # Let's say when this pin is high data is presented
|
255
|
+
|
256
|
+
# Compare the data in MSB
|
257
|
+
8.times do |i|
|
258
|
+
bit = reg.bit(i + 8)
|
259
|
+
if bit.is_to_be_read?
|
260
|
+
pins(:data)[i].assert(bit.data)
|
261
|
+
else
|
262
|
+
pins(:data)[i].dont_care
|
263
|
+
end
|
264
|
+
end
|
265
|
+
$tester.cycle
|
266
|
+
|
267
|
+
# Now the data in LSB
|
268
|
+
8.times do |i|
|
269
|
+
bit = reg.bit(i)
|
270
|
+
if bit.is_to_be_read?
|
271
|
+
pins(:data)[i].assert(bit.data)
|
272
|
+
else
|
273
|
+
pins(:data)[i].dont_care
|
274
|
+
end
|
275
|
+
end
|
276
|
+
$tester.cycle
|
277
|
+
|
278
|
+
pin(:dout).drive(0) # Turn off read out
|
279
|
+
end
|
280
|
+
|
281
|
+
# Reading on a serial port, same as above only this time the :data port is
|
282
|
+
# only 1-bit wide
|
283
|
+
def read_register(reg, options={})
|
284
|
+
pin(:dout).drive(1) # Let's say when this pin is high data is presented
|
285
|
+
|
286
|
+
# Drive the data in MSB -> LSB order
|
287
|
+
reg.shift_out_left do |bit|
|
288
|
+
if bit.is_to_be_read?
|
289
|
+
pin(:data).assert!(bit.data)
|
290
|
+
else
|
291
|
+
pin(:data).dont_care!
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
pin(:dout).drive(0) # Turn off read out
|
296
|
+
end
|
297
|
+
~~~
|
298
|
+
|
299
|
+
|
300
|
+
% end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
% render "layouts/guides.html" do
|
2
|
+
|
3
|
+
The pattern generator is launched via the Origen generate command, see the command line
|
4
|
+
help to get details of the most up to date options:
|
5
|
+
|
6
|
+
~~~text
|
7
|
+
origen generate -h
|
8
|
+
~~~
|
9
|
+
|
10
|
+
As this is such a commonly used command it has a short cut alias:
|
11
|
+
|
12
|
+
~~~text
|
13
|
+
origen g -h
|
14
|
+
~~~
|
15
|
+
|
16
|
+
The generator can be run on a single file:
|
17
|
+
|
18
|
+
~~~text
|
19
|
+
origen g pattern/ram/march.rb
|
20
|
+
~~~
|
21
|
+
|
22
|
+
It can also be run without a path and by just supplying a name, Origen is also pretty flexible
|
23
|
+
with regards to file extensions and pre and post fixes and in most cases it should do a good
|
24
|
+
job of finding the pattern that you want:
|
25
|
+
|
26
|
+
~~~text
|
27
|
+
origen g march
|
28
|
+
~~~
|
29
|
+
|
30
|
+
It can also run on a whole directory:
|
31
|
+
|
32
|
+
~~~text
|
33
|
+
origen g pattern/ram
|
34
|
+
~~~
|
35
|
+
|
36
|
+
Pattern list files can also be used, by convention these should be kept in the list directory
|
37
|
+
and should have the extension <code>.list</code>:
|
38
|
+
|
39
|
+
~~~text
|
40
|
+
origen g list/production.list
|
41
|
+
~~~
|
42
|
+
|
43
|
+
Here is an example of a list file:
|
44
|
+
|
45
|
+
~~~text
|
46
|
+
# List files can be commented like this
|
47
|
+
# Simply list the name of the patterns that you would use on the command line
|
48
|
+
march.rb
|
49
|
+
data_retention.rb
|
50
|
+
# List files can also call other lists
|
51
|
+
probe.list
|
52
|
+
~~~
|
53
|
+
|
54
|
+
By default the generated patterns will be put in <code>output</code> or whatever directory
|
55
|
+
is returned by the <code>config.output_directory</code> attribute in <code>application.rb</code>.
|
56
|
+
|
57
|
+
Submit to the LSF by appending <code>-l</code> and optionally interactively
|
58
|
+
wait for completion:
|
59
|
+
|
60
|
+
~~~text
|
61
|
+
origen g list/production.list -l -w
|
62
|
+
~~~
|
63
|
+
|
64
|
+
#### Regression Testing
|
65
|
+
|
66
|
+
Every time Origen generates a pattern it will check to see if it has generated it before, and
|
67
|
+
if so it will compare the current version to the previous version and alert if there is a
|
68
|
+
difference. This can be used to check for regressions when making changes that you don't want
|
69
|
+
to affect the output, or to verify that the change is what you intended in cases where you
|
70
|
+
are intentionally modifying the output.
|
71
|
+
|
72
|
+
The diff is a smart diff and will not care about any changes to comments, only about changes
|
73
|
+
that will affect the pattern's operation.
|
74
|
+
|
75
|
+
In the case of a difference being found Origen will automatically present you with the diff command
|
76
|
+
to run if you want to view the change.
|
77
|
+
|
78
|
+
To accept changes or to start tracking the differences in a pattern (or patterns) run the following command
|
79
|
+
after generating:
|
80
|
+
|
81
|
+
~~~text
|
82
|
+
origen save all
|
83
|
+
~~~
|
84
|
+
|
85
|
+
#### Programmatically Launching the Generator
|
86
|
+
|
87
|
+
If you start writing your own [commands](<%= path "guides/misc/commands" %>) you may want
|
88
|
+
to launch the generator from Ruby, do that as follows:
|
89
|
+
|
90
|
+
~~~ruby
|
91
|
+
Origen.app.runner.launch action: :generate,
|
92
|
+
files: "list/production.list"
|
93
|
+
~~~
|
94
|
+
|
95
|
+
This can be combined with [Target Loops](<%= path "guides/runtime/programming" %>) to run the
|
96
|
+
generator for multiple targets.
|
97
|
+
|
98
|
+
A generate job can also be posted to the LSF by supplying the same options that you would use
|
99
|
+
on the command line like this:
|
100
|
+
|
101
|
+
~~~ruby
|
102
|
+
Origen.lsf.submit_origen_job("g march")
|
103
|
+
~~~
|
104
|
+
|
105
|
+
% end
|