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