origen_sim 0.12.0 → 0.13.0
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 +5 -5
- data/config/application.rb +17 -2
- data/config/shared_commands.rb +7 -0
- data/config/version.rb +1 -1
- data/ext/bridge.c +13 -3
- data/lib/origen_sim.rb +10 -0
- data/lib/origen_sim/artifacts.rb +101 -0
- data/lib/origen_sim/commands/build.rb +41 -9
- data/lib/origen_sim/heartbeat.rb +13 -1
- data/lib/origen_sim/origen_testers/api.rb +90 -7
- data/lib/origen_sim/simulation.rb +49 -4
- data/lib/origen_sim/simulator.rb +171 -19
- data/lib/origen_sim/stderr_reader.rb +19 -13
- data/lib/origen_sim/stdout_reader.rb +22 -16
- data/lib/origen_sim/tester.rb +110 -1
- data/lib/origen_sim_dev/dut.rb +5 -0
- data/pattern/test.rb +143 -0
- data/templates/empty.gtkw +19 -1
- data/templates/empty.rc +86 -0
- data/templates/empty.svcf +79 -9
- data/templates/empty.tcl +37 -9
- data/templates/origen_guides/simulation/app.md.erb +131 -0
- data/templates/origen_guides/simulation/artifacts.md.erb +115 -0
- data/templates/origen_guides/simulation/compiling.md.erb +190 -0
- data/templates/origen_guides/simulation/debugging.md.erb +135 -0
- data/templates/origen_guides/simulation/environment.md.erb +217 -0
- data/templates/origen_guides/simulation/flows.md.erb +69 -0
- data/templates/origen_guides/simulation/howitworks.md.erb +64 -0
- data/templates/origen_guides/simulation/introduction.md.erb +35 -0
- data/templates/origen_guides/simulation/log.md.erb +118 -0
- data/templates/origen_guides/simulation/patterns.md.erb +193 -0
- data/templates/probe.tcl.erb +3 -0
- data/templates/rtl_v/origen.v.erb +19 -3
- data/templates/web/layouts/_guides.html.erb +15 -0
- metadata +18 -5
@@ -0,0 +1,135 @@
|
|
1
|
+
% render "layouts/guides.html" do
|
2
|
+
|
3
|
+
The execution of an Origen simulation is fully controlled by Origen/Ruby, this means that if you
|
4
|
+
insert a regular Ruby debugger breakpoint into your application code then you can step through the
|
5
|
+
simulation in real time.
|
6
|
+
|
7
|
+
This guide describes some features that are useful for interacting with the DUT from a simulation
|
8
|
+
breakpoint, or when running
|
9
|
+
[an interactive ad-hoc simulation from the console.](<%= path "guides/simulation/app/#Starting_the_Simulator_in_an_Interactive_Session" %>)
|
10
|
+
|
11
|
+
#### Syncing & Flushing
|
12
|
+
|
13
|
+
When a simulation is running most of the communication is one-way, Origen tells the simulator what to do,
|
14
|
+
and for performance reasons there is no handshake between Origen and the simulator at every instruction. Instead,
|
15
|
+
Origen fires off instructions into a buffer, the simulator executes them as fast as it can, and then Origen
|
16
|
+
periodically waits for the simulator to catch up if it is running too far ahead.
|
17
|
+
|
18
|
+
If you have entered a breakpoint and you suspect that the simulator may be still catching up, you can run:
|
19
|
+
|
20
|
+
~~~ruby
|
21
|
+
tester.sync_up
|
22
|
+
~~~
|
23
|
+
|
24
|
+
When that method returns you are guaranteed that the simulator is at the same point.
|
25
|
+
|
26
|
+
Note that most of the time you will not need to do this manually since Origen will automatically sync up for
|
27
|
+
any operation that involves reading data from the simulation, e.g. peeking or reading registers.
|
28
|
+
|
29
|
+
If you have a wave viewer open during the debug session it may still look like the simulation is running behind, or the
|
30
|
+
wave viewer may appear to hang if you have tried to refresh it.
|
31
|
+
This is because the simulator is buffering output that has yet to be written to the wave dump.
|
32
|
+
|
33
|
+
You can force it to flush the buffer and update the wave viewer by running:
|
34
|
+
|
35
|
+
~~~ruby
|
36
|
+
tester.flush
|
37
|
+
~~~
|
38
|
+
|
39
|
+
Note that flushing will internally call a `sync_up` so you don't have to do both of these manually.
|
40
|
+
|
41
|
+
#### Accessing the DUT's Internal Nets
|
42
|
+
|
43
|
+
The methods `tester.simulator.peek` and `tester.simulator.poke` are available for reading and writing values
|
44
|
+
to internal DUT nets respectively.
|
45
|
+
|
46
|
+
See the section on [Creating Simulation-Only Assertions](<%= path "guides/simulation/patterns/#Creating_Simulation-Only_Assertions" %>)
|
47
|
+
for more details on these.
|
48
|
+
|
49
|
+
#### Register Reading (and Writing)
|
50
|
+
|
51
|
+
Referencing a register from the console will show you what Origen thinks the register currently contains:
|
52
|
+
|
53
|
+
~~~text
|
54
|
+
dut.my_block.my_reg
|
55
|
+
|
56
|
+
=>
|
57
|
+
0x10008000 - :my_reg
|
58
|
+
===============================================================================================================
|
59
|
+
│ 15 │ 14 │ 13 │ 12 │ 11 │ 10 │ 9 │ 8 │
|
60
|
+
│ d[15:8] │
|
61
|
+
│ 0x0 │
|
62
|
+
├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤
|
63
|
+
│ 7 │ 6 │ 5 │ 4 │ 3 │ 2 │ 1 │ 0 │
|
64
|
+
│ d[7:0] │
|
65
|
+
│ 0x0 │
|
66
|
+
└─────────────┴─────────────┴─────────────┴─────────────┴─────────────┴─────────────┴─────────────┴─────────────┘
|
67
|
+
|
68
|
+
~~~
|
69
|
+
|
70
|
+
However, this may not be what the simulation currently reflects. To see what the simulation holds, call `sync`
|
71
|
+
on the register:
|
72
|
+
|
73
|
+
~~~text
|
74
|
+
dut.my_block.my_reg.sync
|
75
|
+
|
76
|
+
=>
|
77
|
+
0x10008000 - :my_reg
|
78
|
+
===============================================================================================================
|
79
|
+
│ 15 │ 14 │ 13 │ 12 │ 11 │ 10 │ 9 │ 8 │
|
80
|
+
│ d[15:8] │
|
81
|
+
│ 0x8E │
|
82
|
+
├─────────────┼─────────────┼─────────────┼─────────────┼─────────────┼─────────────┼─────────────┼─────────────┤
|
83
|
+
│ 7 │ 6 │ 5 │ 4 │ 3 │ 2 │ 1 │ 0 │
|
84
|
+
│ d[7:0] │
|
85
|
+
│ 0xFF │
|
86
|
+
└─────────────┴─────────────┴─────────────┴─────────────┴─────────────┴─────────────┴─────────────┴─────────────┘
|
87
|
+
|
88
|
+
~~~
|
89
|
+
|
90
|
+
A convenience API exists for this by appending `!` to the register name:
|
91
|
+
|
92
|
+
~~~text
|
93
|
+
dut.my_block.my_reg!
|
94
|
+
~~~
|
95
|
+
|
96
|
+
Note that this works by firing off a conventional `read_register` request to your DUT model/controller.
|
97
|
+
|
98
|
+
That means that it should work for breakpoints in the majority of application code, however if you have stopped it
|
99
|
+
or stepped into a place in low-level code, such as in the middle of a prior transaction, then this feature may not work.
|
100
|
+
|
101
|
+
#### Advancing Time
|
102
|
+
|
103
|
+
If you have just written to a register, it may kick off some operation within the DUT and time (clock cycles)
|
104
|
+
will be required before you will be able to observe the response.
|
105
|
+
|
106
|
+
It is important to understand that the simulator is also paused during a breakpoint and therefore simulation time
|
107
|
+
is not continuing to run while you are at the console.
|
108
|
+
|
109
|
+
Simulation time can be advanced by calling the usual `tester.wait` API, however these convenience APIs exist for advancing
|
110
|
+
time during a debugger breakpoint (and they can also be used in source code if you wish):
|
111
|
+
|
112
|
+
~~~ruby
|
113
|
+
10.cycles
|
114
|
+
|
115
|
+
10.ns!
|
116
|
+
|
117
|
+
10.us!
|
118
|
+
|
119
|
+
10.ms!
|
120
|
+
|
121
|
+
10.s!
|
122
|
+
~~~
|
123
|
+
|
124
|
+
Note that 10 is just used as an example here, you can apply any number that you want.
|
125
|
+
|
126
|
+
|
127
|
+
#### Checking The Error Count
|
128
|
+
|
129
|
+
You can query the current error count by running:
|
130
|
+
|
131
|
+
~~~ruby
|
132
|
+
tester.simulator.error_count # => 0
|
133
|
+
~~~
|
134
|
+
|
135
|
+
% end
|
@@ -0,0 +1,217 @@
|
|
1
|
+
% render "layouts/guides.html" do
|
2
|
+
|
3
|
+
By convention, the OrigenSim simulator driver is configured within the file `environment/sim.rb`.
|
4
|
+
|
5
|
+
Usually the simulator configuration may be different for each DUT target, so often this file is structured like this
|
6
|
+
to enable a single Origen simulation environment setup file to support multiple DUT targets within the
|
7
|
+
application:
|
8
|
+
|
9
|
+
~~~ruby
|
10
|
+
# environment/sim.rb
|
11
|
+
|
12
|
+
case Origen.target.name
|
13
|
+
|
14
|
+
when "my_dut1"
|
15
|
+
OrigenSim.cadence do |sim|
|
16
|
+
# Configuration of Cadence simulator to be used for DUT1 here
|
17
|
+
end
|
18
|
+
|
19
|
+
when "my_dut2"
|
20
|
+
OrigenSim.synopsys do |sim|
|
21
|
+
# Configuration of Synopsys simulator to be used for DUT2 here
|
22
|
+
end
|
23
|
+
|
24
|
+
else
|
25
|
+
Origen.log.error "No simulation environment has been setup for target #{Origen.target.name}, edit environment/sim.rb to add one."
|
26
|
+
exit 1
|
27
|
+
end
|
28
|
+
~~~
|
29
|
+
|
30
|
+
#### Configuring The Simulator
|
31
|
+
|
32
|
+
Here is an example of configuring the simulator with some generic options that are supported by all simulators:
|
33
|
+
|
34
|
+
~~~ruby
|
35
|
+
OrigenSim.cadence do |sim|
|
36
|
+
# By default a simulation will be given 60 seconds to startup, if it fails to start within this time the
|
37
|
+
# simulation will be abandoned and considered failed. If a particular simulation is known to be slow to start,
|
38
|
+
# the timeout can be extended as shown in this example (5 minutes):
|
39
|
+
sim.startup_timeout 5 * 60
|
40
|
+
# Sometimes due to different Verilog timescale references, the time specified by Origen may not align to what
|
41
|
+
# is seen in the simulation. For example, your Origen application might define a cycle period of 40ns but in
|
42
|
+
# the simulation this manifests as 400ns. Such differences can be fixed by specifying this time factor which
|
43
|
+
# will be multiplied with all time advancements defined by Origen. This can be any value like 0.01, 0.1, 10,
|
44
|
+
# 100, 1000, etc. to make the cycle period seen in simulation bigger or smaller.
|
45
|
+
sim.time_factor 100
|
46
|
+
end
|
47
|
+
~~~
|
48
|
+
|
49
|
+
Note that defining a configuration like this will also instantiate an instance of `OrigenSim::Tester` and assign it to
|
50
|
+
the global variable `tester`.
|
51
|
+
This `tester` object will behave like any other Origen tester driver and your application will be unaware that it is
|
52
|
+
driving a simulator rather than an ATE-specific pattern renderer.
|
53
|
+
|
54
|
+
Note also that the `post_process_run_cmd` option is available for all simulators, however it is reserved for discussion
|
55
|
+
later in this guide since it is more of an advanced topic.
|
56
|
+
|
57
|
+
#### Cadence (irun) Specific Configuration
|
58
|
+
|
59
|
+
Additionally, a Cadence simulator setup supports the following vendor-specific options:
|
60
|
+
|
61
|
+
~~~ruby
|
62
|
+
OrigenSim.cadence do |sim|
|
63
|
+
# By default the simulation will be run by calling 'irun', this can be changed to anything you want, but it
|
64
|
+
# is usually a good idea to use this option to lock to a specific version of irun (the same version that was
|
65
|
+
# used to compile the DUT snapshot)
|
66
|
+
sim.irun '/tools/cadence/15.10.023/bin/irun'
|
67
|
+
# The default wave viewer is 'simvision', this can also be changed
|
68
|
+
sim.simvision '/tools/cadence/15.10.023/bin/simvision'
|
69
|
+
# The cadence simulator configuration does support the use of forces, though this is generally discouraged
|
70
|
+
sim.force {
|
71
|
+
'origen.dut.vref_0v8' => 1,
|
72
|
+
'origen.dut.pmc.some.internal.node' => 1,
|
73
|
+
}
|
74
|
+
# Custom probes can be specified, e.g. to include memory contents in the wave dump
|
75
|
+
sim.tcl_inputs %Q(
|
76
|
+
probe -create -shm origen.dut.mems.user -all -memories -variables -unpacked 262144 -depth all
|
77
|
+
probe -create -shm origen.dut.mems.cache -all -memories -variables -unpacked 262144 -depth all
|
78
|
+
)
|
79
|
+
end
|
80
|
+
~~~
|
81
|
+
|
82
|
+
#### Synopsys Specific Configuration
|
83
|
+
|
84
|
+
Here are the vendor-specific options for Synopsys:
|
85
|
+
|
86
|
+
~~~ruby
|
87
|
+
OrigenSim.cadence do |sim|
|
88
|
+
# By default the simulation will be run by calling 'vcs', this can be changed to anything you want, but it
|
89
|
+
# is usually a good idea to use this option to lock to a specific version of vcs (the same version that was
|
90
|
+
# used to compile the DUT snapshot)
|
91
|
+
sim.vcs "/tools/synopsys/L-2016.06/bin/vcs"
|
92
|
+
# The default wave viewer is 'dve', this can also be changed
|
93
|
+
sim.dve "/tools/synopsys/L-2016.06/bin/dve"
|
94
|
+
end
|
95
|
+
~~~
|
96
|
+
|
97
|
+
Origen Sim also offers the option to use Verdi as a wave viewer instead of 'dve', the vendor-specific options for Synopsys w/Verdi would be:
|
98
|
+
|
99
|
+
~~~ruby
|
100
|
+
OrigenSim.cadence do |sim|
|
101
|
+
sim.vcs "/tools/synopsys/L-2016.06/bin/vcs"
|
102
|
+
sim.verdi "/tools/synopsys/L-2016.06/bin/verdi"
|
103
|
+
end
|
104
|
+
~~~
|
105
|
+
|
106
|
+
#### Icarus Verilog Specific Configuration
|
107
|
+
|
108
|
+
Here are the vendor-specific options for Icarus Verilog:
|
109
|
+
|
110
|
+
~~~ruby
|
111
|
+
OrigenSim.cadence do |sim|
|
112
|
+
# By default the simulation will be run by calling 'vvp', this can be changed to anything you want, but it
|
113
|
+
# is usually a good idea to use this option to lock to a specific version of vvp (the same version that was
|
114
|
+
# used to compile the DUT snapshot)
|
115
|
+
sim.vvp "/tools/icarus/0.9.7/bin/vvp"
|
116
|
+
# The default wave viewer is 'gtkwave', this can also be changed
|
117
|
+
sim.gtkwave "/tools/gtkwave/3.3.66/bin/gtkwave"
|
118
|
+
end
|
119
|
+
~~~
|
120
|
+
|
121
|
+
#### Generic and Advanced Simulator Configuration
|
122
|
+
|
123
|
+
A generic simulator configuration allows you to use a tool that is not supported out of the box by <code>OrigenSim</code>. For these, it
|
124
|
+
is your responsibility to provide the command to start the simulation process, however, this allows for arbitrary commands to
|
125
|
+
start the process and allows end users to still use <code>origen g</code> as if with a fully <code>OrigenSim</code> supported
|
126
|
+
simulator configuration.
|
127
|
+
|
128
|
+
An example of such a configuration could be:
|
129
|
+
|
130
|
+
~~~ruby
|
131
|
+
OrigenSim.generic do |sim|
|
132
|
+
sim.generic_run_cmd do |s|
|
133
|
+
# Return the command to start the simulation
|
134
|
+
"path/to/custom/sim/script +socket+#{s.socket_id}"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
~~~
|
138
|
+
|
139
|
+
Here is an example using the predecessor of the supported Cadence tool <code>irun</code>, <code>ncsim</code>:
|
140
|
+
|
141
|
+
~~~ruby
|
142
|
+
OrigenSim.generic do |sim|
|
143
|
+
sim.testbench_top 'na_origen'
|
144
|
+
sim.generic_run_cmd do |s|
|
145
|
+
"ncsim na_origen -loadpli origen.so:bootstrap +socket+#{s.socket_id}"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
~~~
|
149
|
+
|
150
|
+
The following commonly used options are available to a generic simulation configuration:
|
151
|
+
|
152
|
+
* `testbench_top` - Defines the testbench name if different from <code>origen</code>.
|
153
|
+
* `view_waveform_cmd` - Required for generic configurations - prints out this statement following a simulation instructing the
|
154
|
+
user on how to open the waveforms for viewing. For supported simulators, this is already provided, but can be overwritten.
|
155
|
+
* `generic_run_cmd` - Either a string, array to be joined by ' && ', or a block returning either of the aforementioned that
|
156
|
+
the generic configuration will use to launch the simulation.
|
157
|
+
* `post_process_run_cmd` - Block object to post-process the command that OrigenSim will launch the simulation with. This can be used
|
158
|
+
to post-process the command for any supported vendor. This block should return the command to run, as a string.
|
159
|
+
|
160
|
+
An example of the <code>post_process_run_cmd</code> usage is:
|
161
|
+
|
162
|
+
~~~ruby
|
163
|
+
OrigenSim.cadence do |sim|
|
164
|
+
sim.post_process_run_cmd do |cmd, s|
|
165
|
+
# cmd is the current command that will be run. s is the simulator object, same as sim in this case.
|
166
|
+
# this should return either a string or an array to be joined by ' && ' (chain commands)
|
167
|
+
# note that we must RETURN the string. We cannot just edit it.
|
168
|
+
|
169
|
+
# add an environment variable and run setup script as an example
|
170
|
+
return "export PROJECT=my_rtl && source #{Origen.app.root.join('settings.sh')} && #{cmd}"
|
171
|
+
|
172
|
+
# or, we could return
|
173
|
+
return [
|
174
|
+
'export PROJECT=my_rtl',
|
175
|
+
"source #{Origen.app.root.join('settings.sh')}",
|
176
|
+
cmd
|
177
|
+
]
|
178
|
+
#=> "export PROJECT=my_rtl && source #{Origen.app.root.join('settings.sh')} && #{cmd}"
|
179
|
+
end
|
180
|
+
end
|
181
|
+
~~~
|
182
|
+
|
183
|
+
#### Simulation Object Checkin/Checkout
|
184
|
+
|
185
|
+
Environment setups can also include information on the url and version of where the compiled simulation object
|
186
|
+
is to be stored - often this will not be checked into the same repository as the main application code since
|
187
|
+
for example Git, which is good for application code storage, is not really so good for storing large binaries
|
188
|
+
like the simulation objects.
|
189
|
+
|
190
|
+
Here is an example setup:
|
191
|
+
|
192
|
+
~~~ruby
|
193
|
+
OrigenSim.synopsys do |sim|
|
194
|
+
sim.rc_dir_url 'sync://sync-12345:12345/Projects/origen_sim_snapshots'
|
195
|
+
sim.rc_version 'Trunk'
|
196
|
+
end
|
197
|
+
~~~
|
198
|
+
|
199
|
+
The `rc_dir_url` option should point to a directory in the repository where the snapshot files should be
|
200
|
+
stored, not to the snapshot file itself.
|
201
|
+
|
202
|
+
The `rc_version` can be set to the version to use, which can be a pointer to latest like 'Trunk' or 'master' or
|
203
|
+
to an absolute version.
|
204
|
+
|
205
|
+
The object should be committed to the repository by running the `origen sim:ci` command with the environment/target
|
206
|
+
setup to select the object to be checked in.
|
207
|
+
Origen Sim will then automatically tar up the object and check it in.
|
208
|
+
|
209
|
+
This same command can be run again in future to check in new versions.
|
210
|
+
|
211
|
+
Origen Sim will then automatically check for the presence of the object in the local workspace and will fetch
|
212
|
+
it as required - i.e. if not present or if the `rc_version` has been updated.
|
213
|
+
|
214
|
+
Note that when a latest pointer is used as the version, the remote repository is not automatically checked for updates.
|
215
|
+
If you want to fetch the latest version or force a re-checkout at anytime you can run the `origen sim:co` command.
|
216
|
+
|
217
|
+
% end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
% render "layouts/guides.html" do
|
2
|
+
|
3
|
+
A flow, meaning a sequence of patterns, can be simulated in two ways - by supplying
|
4
|
+
a list of patterns or by configuring a test program generator flow to support simulation.
|
5
|
+
|
6
|
+
#### Simulating a Pattern List
|
7
|
+
|
8
|
+
If you were to run this:
|
9
|
+
|
10
|
+
~~~text
|
11
|
+
origen g my_pat_1 my_pat_2 -e environment/sim.rb
|
12
|
+
~~~
|
13
|
+
|
14
|
+
then it would run the two patterns as two independent simulations, creating two waveforms named after each pattern.
|
15
|
+
|
16
|
+
They can be combined into a single simulation by adding a `--flow` option:
|
17
|
+
|
18
|
+
~~~text
|
19
|
+
origen g my_pat_1 my_pat_2 -e environment/sim.rb --flow my_flow
|
20
|
+
~~~
|
21
|
+
|
22
|
+
This will simulate the given patterns back-back and dump them to a waveform named after the flow option, in this case "my_flow".
|
23
|
+
|
24
|
+
The list of patterns can also be supplied via a list file:
|
25
|
+
|
26
|
+
|
27
|
+
~~~text
|
28
|
+
origen g list/regression.list -e environment/sim.rb --flow regression
|
29
|
+
~~~
|
30
|
+
|
31
|
+
#### Simulating a Test Program Flow
|
32
|
+
|
33
|
+
To simulate a pattern sequence defined by a [test program flow](<%= path "guides/program/flows" %>), it is necessary
|
34
|
+
to [setup your interface](<%= path "guides/program/interface" %>) to support the simulation tester driver
|
35
|
+
as if it were another ATE.
|
36
|
+
|
37
|
+
The simulation tester driver has no concept of test methods, suites or instances, so its interface setup is very simple -
|
38
|
+
once you have the pattern name simply pass that to the `test` method:
|
39
|
+
|
40
|
+
~~~ruby
|
41
|
+
# Example interface method
|
42
|
+
def func(name, options = {})
|
43
|
+
# Resolve the pattern name as required
|
44
|
+
pattern = extract_pattern_name(name, options)
|
45
|
+
|
46
|
+
if tester.sim?
|
47
|
+
test(pattern, options)
|
48
|
+
|
49
|
+
elsif tester.v93k?
|
50
|
+
t = test_suites.add(:vreg_func)
|
51
|
+
t.test_method = test_methods.origen.functional_test
|
52
|
+
t.pattern = pattern
|
53
|
+
test(t, options)
|
54
|
+
|
55
|
+
else
|
56
|
+
fail "The test program interface has not been setup for #{tester.class}!"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
~~~
|
60
|
+
|
61
|
+
To simulate the flow, run the program generator as normal but with the simulation environment selected:
|
62
|
+
|
63
|
+
~~~text
|
64
|
+
origen p program/my_flow.rb -e environment/sim.rb
|
65
|
+
~~~
|
66
|
+
|
67
|
+
The generated wave will be named after the flow, _my_flow_ in this example.
|
68
|
+
|
69
|
+
% end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
% render "layouts/guides.html" do
|
2
|
+
|
3
|
+
Here are some technical details on how OrigenSim works which should provide some context when it comes
|
4
|
+
to [compiling your DUT design to work with OrigenSim](<%= path "guides/simulation/compiling" %>).
|
5
|
+
|
6
|
+
Origen provides components that can be compiled into a simulation object along with the design under test (DUT),
|
7
|
+
a high level view of the process looks like this:
|
8
|
+
|
9
|
+
<img src="https://user-images.githubusercontent.com/158364/28324051-6a149088-6bd2-11e7-936d-49ec87b2c0bb.png" alt="origen_sim" style="
|
10
|
+
width: 100%;
|
11
|
+
">
|
12
|
+
|
13
|
+
The main Origen Ruby process is invoked by generating a pattern as usual, e.g. <code>origen g my_pattern</code>,
|
14
|
+
but with the environment setup to instantiate an instance of <code>OrigenSim::Tester</code> instead of say
|
15
|
+
<code>OrigenTesters::V93K</code>.
|
16
|
+
The OrigenSim tester will start off a Verilog process in parallel which will run a simulation on an object that
|
17
|
+
has been created beforehand. This simulation object contains the DUT wrapped in an OrigenSim testbench, and which
|
18
|
+
has been compiled into a snapshot/object that also includes a [Verilog VPI](https://en.wikipedia.org/wiki/Verilog_Procedural_Interface)
|
19
|
+
extension which provides a communication interface between Origen and the simulation world.
|
20
|
+
|
21
|
+
When the simulation process starts, the VPI extension immediately takes control and halts the simulator while it
|
22
|
+
listens for further instructions from a Linux socket which was setup by OrigenSim before the simulation was started.
|
23
|
+
As the Origen pattern generation process executes, the <code>OrigenSim::Tester</code> will translate any requests
|
24
|
+
to drive or expect pin values, or to generate a cycle, into messages which are passed into the Linux socket.
|
25
|
+
Upon receving these messages, the VPI process will manipulate the testbench's pin drivers to drive or read from
|
26
|
+
the DUT and it will advance time by a cycle period every time a cycle is generated in the pattern.
|
27
|
+
The testbench to wrap and instantiate the DUT is generated by OrigenSim and it provides a standard interface through
|
28
|
+
which Origen can access any DUT.
|
29
|
+
|
30
|
+
In principle the DUT object can be any design view that is wrapped by a conventional top-level Verilog module, meaning that
|
31
|
+
OrigenSim can be used to run RTL or gate-level simulations depending on what has been compiled into the snapshot.
|
32
|
+
|
33
|
+
**Note also that the DUT can be either an IP-block or an SoC, and so OrigenSim can be used equally well for running
|
34
|
+
both IP-level and top-level simulations.**
|
35
|
+
|
36
|
+
### The Testbench
|
37
|
+
|
38
|
+
The testbench is quite simple and it does little more than instantiate the DUT module and connect all of its pins to
|
39
|
+
instances of [this pin driver module](https://github.com/Origen-SDK/origen_sim/blob/master/templates/rtl_v/origen.v.erb#L14).
|
40
|
+
The testbench module is named `origen` by default and all OrigenSim simulation dumps will have this same top-level structure:
|
41
|
+
|
42
|
+
~~~text
|
43
|
+
.
|
44
|
+
└── my_pattern
|
45
|
+
└── origen
|
46
|
+
├── debug // Contains an error count, pattern name and comments, and other debug aids
|
47
|
+
├── dut // Your DUT
|
48
|
+
└── pins
|
49
|
+
├── tdi // Driver for the TDI pin (for example)
|
50
|
+
├── tdo
|
51
|
+
└── tck
|
52
|
+
~~~
|
53
|
+
|
54
|
+
|
55
|
+
The driver contains a number of registers which are written to directly by the VPI process, allowing it to drive or expect a
|
56
|
+
given data value (stored in <code>origen.pins.MYPIN.data</code>) by writing a 1 to <code>origen.pins.MYPIN.drive</code>
|
57
|
+
or <code>origen.pins.MYPIN.compare</code> respectively.
|
58
|
+
If the value being driven by the pin does not match the expect data during a cycle, then an error signal will be asserted by the
|
59
|
+
driver and this will increment an error counter that lives in <code>origen.debug.errors[31:0]</code>.
|
60
|
+
|
61
|
+
An error count > 0 will result in the pattern simulation status being reported as a FAIL by Origen and this can be used
|
62
|
+
to create simulation-based regression test suites for your application.
|
63
|
+
|
64
|
+
% end
|