origen_sim 0.15.0 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
data/pattern/test.rb CHANGED
@@ -35,6 +35,7 @@ Pattern.create do
35
35
 
36
36
  ss "Now try and read and write a register"
37
37
  dut.cmd.write!(0x1234_5678)
38
+ tester.marker = 1
38
39
  dut.cmd.read!(0x1234_5678)
39
40
 
40
41
  if tester.sim?
@@ -44,6 +45,7 @@ Pattern.create do
44
45
 
45
46
  ss "Test storing a register"
46
47
  dut.cmd.write!(0x2244_6688)
48
+ Origen.log.info "Should be within 'Test storing a register'"
47
49
  dut.cmd.store!
48
50
 
49
51
  if tester.sim?
@@ -1,15 +1,132 @@
1
1
  % render "layouts/guides.html" do
2
2
 
3
+ This guide describes some features that are useful for debugging a failing simulation
4
+ or when running
5
+ [an interactive ad-hoc simulation from the console.](<%= path "guides/simulation/app/#Starting_the_Simulator_in_an_Interactive_Session" %>)
6
+
7
+ #### Identifying Points in Time
8
+
9
+ All [major step comments](<%= path "guides/pattern/documenting/#Documenting_Major_Steps" %>) in pattern
10
+ source code will be simulation time-stamped and output to the console as shown below:
11
+
12
+ ~~~ruby
13
+ ss "Test basic 2-pin match loop"
14
+
15
+ # ...
16
+
17
+ ss "Test a block match loop"
18
+
19
+ # ...
20
+ ~~~
21
+
22
+ The above will produce this output where the simulation time when each operation occurs is given in ns:
23
+
24
+ ~~~text
25
+ [INFO] 6.710[0.000] || 991700 ns: ===========================================================
26
+ [INFO] 6.710[0.001] || 991700 ns: Test basic 2-pin match loop
27
+ [INFO] 6.711[0.001] || 991700 ns: ===========================================================
28
+ [INFO] 6.711[0.001] || 1207500 ns: ===========================================================
29
+ [INFO] 6.712[0.000] || 1207500 ns: Test a block match loop
30
+ [INFO] 6.712[0.000] || 1207500 ns: ===========================================================
31
+ ~~~
32
+
33
+ All [log output](<%= path "guides/misc/logger" %>) created by application code will also be simulation
34
+ time-stamped and synchronized to simulator progress:
35
+
36
+ ~~~ruby
37
+ Origen.log.info "Something important is happening!"
38
+ ~~~
39
+
40
+ ~~~text
41
+ [INFO] 6.712[0.000] || 24210200 ns: Something important is happening!
42
+ ~~~
43
+
44
+
45
+ **Note that applications should avoid the use of `puts` to output debug or status information to the console
46
+ because that will occur immediately and will not be time-stamped or synchronized with the simulator.**
47
+
48
+ Additionally, the Origen testbench contains a register that can be used to mark events like this:
49
+
50
+ ~~~ruby
51
+ tester.marker = 0x1234
52
+ ~~~
53
+
54
+ You can then view signal `origen.debug.marker` in a wave viewer and search for the appropriate value to
55
+ locate the specific point in time when the mark was applied.
56
+
57
+ When generating for non-simulation tester targets that statement will do nothing and it can be
58
+ safely left in production code.
59
+
60
+
61
+ #### Failed Register Reads
62
+
63
+ The following information is logged whenever a pin mis-compare occurs within a register read transaction:
64
+
65
+ * The path (name) of the register
66
+ * Expected data
67
+ * Received (actual) data - requires support from the physical driver, see below
68
+ * Application stack trace to identify where in the application code the read originated
69
+
70
+ Here is an example:
71
+
72
+ ~~~ruby
73
+ ss "Now try and read and write a register"
74
+ dut.cmd.write!(0x1234_5678)
75
+ dut.cmd.read!(0x1234_5078) # Note that we just wrote ..567.. but are now expecting ..507..
76
+ ~~~
77
+
78
+ ~~~text
79
+ [INFO] 4.098[0.000] || 86500 ns: ======================================================================
80
+ [INFO] 4.098[0.001] || 86500 ns: Now try and read and write a register
81
+ [INFO] 4.099[0.001] || 86500 ns: ======================================================================
82
+ [ERROR] 4.100[0.001] || 117400 ns: Miscompare on pin tdo, expected 0 received 1
83
+ [ERROR] 4.101[0.001] || 117600 ns: Miscompare on pin tdo, expected 0 received 1
84
+ [ERROR] 4.102[0.001] || 129100 ns: Errors occurred reading register cmd:
85
+ [ERROR] 4.102[0.001] || 129100 ns: cmd.d: expected 12345078 received 12345678
86
+ [ERROR] 4.103[0.001] || 129100 ns:
87
+ [ERROR] 4.104[0.001] || 129100 ns: /home/stephen/Code/github/origen_sim/pattern/test.rb:39:in `block in <top (required)>'
88
+ [ERROR] 4.110[0.006] || 129100 ns: /home/stephen/Code/github/origen_sim/pattern/test.rb:1:in `<top (required)>'
89
+ ~~~
90
+
91
+ The received data resolution does depend on the physical protocol driver supplying meta-data when
92
+ creating pin assertions (reads) that correspond to register bits, like this:
93
+
94
+ ~~~ruby
95
+ pin(:tdo).assert(bit.data, meta: { position: bit.position })
96
+ ~~~
97
+
98
+ For reference, here is the update that was made to the JTAG driver to support this feature -
99
+ [OrigenJTAG - Add meta data for OrigenSim](https://github.com/Origen-SDK/origen_jtag/pull/10/files)
100
+
101
+ If the driver has not provided this then a warning will be output and no received data will be given.
102
+
103
+ This feature will automatically be enabled for any reads launched via the register object itself, e.g.
104
+ `my_reg.read!`, but not for reads launched by calling the `read_register` method manually,
105
+ e.g. `dut.read_register(my_reg)`.
106
+
107
+ If your application has a tendency to do the latter, then the following modification can be made to your
108
+ `read_register` method to make OrigenSim aware of such transactions:
109
+
110
+ ~~~ruby
111
+ def read_register(reg_or_value, options = {})
112
+ # Make OrigenSim aware of all transactions to enable failed transaction reporting
113
+ tester.read_register(reg_or_value, options) do
114
+
115
+ # Existing implementation here
116
+
117
+ end
118
+ end
119
+ ~~~
120
+
121
+ This feature will also work in the case of the read object being a value rather than a register object.
122
+
123
+
124
+ #### Interactive Debugging
125
+
3
126
  The execution of an Origen simulation is fully controlled by Origen/Ruby, this means that if you
4
127
  insert a regular Ruby debugger breakpoint into your application code then you can step through the
5
128
  simulation in real time.
6
129
 
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
130
  When a simulation is running most of the communication is one-way, Origen tells the simulator what to do,
14
131
  and for performance reasons there is no handshake between Origen and the simulator at every instruction. Instead,
15
132
  Origen fires off instructions into a buffer, the simulator executes them as fast as it can, and then Origen
@@ -37,12 +37,9 @@ OrigenSim.cadence do |sim|
37
37
  # simulation will be abandoned and considered failed. If a particular simulation is known to be slow to start,
38
38
  # the timeout can be extended as shown in this example (5 minutes):
39
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
40
+ # Abort the simulation when this number of errors is reached (defaults to 100).
41
+ # This can also be overridden at runtime via the --max_errors switch.
42
+ sim.max_errors = 50
46
43
  end
47
44
  ~~~
48
45
 
@@ -7,7 +7,7 @@ By default, OrigenSim will automatically suppress all simulator log output excep
7
7
  contain the text _WARNING_ or _ERROR_ (case insensitive); both of these will be logged to the console and any occurrences of
8
8
  the latter will also make the result of the simulation be classed as a FAIL.
9
9
 
10
- All log output can be shown in the console by running with the `-d` or `--debug` switches, and the log files will
10
+ All log output can be shown in the console by running with the `-verbose` switch, and the log files will
11
11
  always contain everything that was output by the simulator.
12
12
 
13
13
  OrigenSim will also consider any output from the simulator to STDERR as a sign that something has gone wrong
@@ -148,6 +148,41 @@ at the point during the cycle where it will be read by the pattern.
148
148
  However, if this were to be a problem in a particular application, you would see it fail when re-playing the
149
149
  captured data in simulation.
150
150
 
151
+ #### Configuring the Capture Storage Location
152
+
153
+ By default, both `sim_delay` and `sim_capture` will save their captured data to
154
+ Org files (Origen native pattern format) using the following file naming rule:
155
+ `Origen.root/pattern/org/<target name>/<capture ID>.org`.
156
+
157
+ If your application is a top-level application then the default setting should work fine unless you wish
158
+ to share/re-use captured data between multiple targets.
159
+
160
+ Another reason to change from the default would be if data is captured at plugin-level and this needs
161
+ to be referenced later when running within a top-level application.
162
+ There are potentially two issues in that case:
163
+
164
+ * `Origen.root` will point to the top-level application's root instead of the plugin's
165
+ * The target name used at the top-level could be different from the one that was used within the plugin to capture
166
+ the data
167
+
168
+ In such cases, the default capture directory can be changed by setting the `OrigenSim.capture_dir` attribute.
169
+ This can be set anytime before the first call is made to `sim_delay` or `sim_capture`.
170
+
171
+ For example, a plugin that needs its captured data to work later as part of a top-level application,
172
+ could set the capture directory in a [startup callback](<%= path "guides/misc/callbacks/#startup(options)" %>),
173
+ like this:
174
+
175
+ ~~~ruby
176
+ def startup(options)
177
+ # Only modify this if we are the current app or plugin
178
+ if Origen.app!.current? || Origen.app!.current_plugin?
179
+ # Use a directory within our root and named after the current IP block, rather than the target
180
+ OrigenSim.capture_dir = Origen.root!.join('pattern', 'org', dut.myip.name)
181
+ end
182
+ end
183
+ ~~~
184
+
185
+
151
186
  #### Creating Simulation-Only Assertions
152
187
 
153
188
  Users are of course encouraged to write patterns that test the DUT via its pin interface since such
@@ -17,15 +17,14 @@
17
17
  // 1 - Initialize drive and assign to 1
18
18
  // 2 - Don't initialize drive and assign to Z (default)
19
19
  // -1 - Don't initialize drive or assign. Pin will be left unknown
20
- module pin_driver(error, pin, sync, match_loop);
20
+ module pin_driver(pin, sync);
21
21
  parameter init_drive = 2; // Which means don't drive initially, set to 0 or 1 to drive
22
22
  parameter pin_name = "undefined_name";
23
23
 
24
- output reg error;
25
24
  inout pin;
26
25
  input sync;
27
- input match_loop;
28
26
 
27
+ reg error;
29
28
  reg [1:0] data = 0;
30
29
  reg [1:0] force_data = 0;
31
30
  reg compare = 0;
@@ -52,9 +51,8 @@ module pin_driver(error, pin, sync, match_loop);
52
51
 
53
52
  // pin compare failure logger
54
53
  always @(posedge error) begin
55
- if (match_loop != 1) begin
56
- $display("OrigenSim Error: miscompare on pin %s, expected %d received %d at %t", pin_name, data[0], pin, $time);
57
- end
54
+ //$display("!4![%t] Miscompare on pin %s, expected %d received %d", $time, pin_name, data[0], pin);
55
+ $bridge_on_miscompare(pin_name, data[0], pin);
58
56
  end
59
57
 
60
58
  // SMcG - needs more work, causes non-genuine fails in OrigenSim test case
@@ -77,7 +75,7 @@ module pin_driver(error, pin, sync, match_loop);
77
75
 
78
76
  initial begin
79
77
  // Set the timescale to ns (-9) with 0 decimal place precision, 20 chars
80
- $timeformat(-9, 0, " ns", 20);
78
+ //$timeformat(-9, 0, "", 20);
81
79
  if (init_drive == 1) begin
82
80
  drive = 1;
83
81
  data[0] = 1;
@@ -89,39 +87,16 @@ module pin_driver(error, pin, sync, match_loop);
89
87
 
90
88
  endmodule
91
89
 
92
- module pin_drivers(errors, <%= dut.rtl_pins.map { |n, p, o| "#{p.id}_o" }.join(', ') %>);
90
+ module pin_drivers(<%= dut.rtl_pins.map { |n, p, o| "#{p.id}_o" }.join(', ') %>);
93
91
 
94
92
  % dut.rtl_pins.each do |name, pin, options|
95
93
  output <%= pin.id %>_o;
96
94
  % end
97
95
 
98
- % dut.rtl_pins.each do |name, pin, options|
99
- wire <%= pin.id %>_err;
100
- % end
101
-
102
- output reg [31:0] errors = 0;
103
96
  reg sync = 0;
104
- reg [31:0] match_errors = 0;
105
- reg match_loop = 0;
106
-
107
- always @(
108
-
109
- % dut.rtl_pins.each_with_index do |(name, pin, options), i|
110
- % if i == 0
111
- posedge <%= pin.id %>_err
112
- % else
113
- or posedge <%= pin.id %>_err
114
- % end
115
- % end
116
- ) begin
117
- if (match_loop == 1)
118
- match_errors[31:0] = match_errors[31:0] + 1;
119
- else
120
- errors[31:0] = errors[31:0] + 1;
121
- end
122
97
 
123
98
  % dut.rtl_pins.each do |name, pin, options|
124
- pin_driver #(<%= pin.meta[:origen_sim_init_pin_state].nil? ? '' : ".init_drive(#{pin.meta[:origen_sim_init_pin_state]}), "%>.pin_name("<%= pin.id %>")) <%= pin.id %>(.pin(<%= pin.id %>_o), .error(<%= pin.id %>_err), .sync(sync), .match_loop(match_loop));
99
+ pin_driver #(<%= pin.meta[:origen_sim_init_pin_state].nil? ? '' : ".init_drive(#{pin.meta[:origen_sim_init_pin_state]}), "%>.pin_name("<%= pin.id %>")) <%= pin.id %>(.pin(<%= pin.id %>_o), .sync(sync));
125
100
  % end
126
101
 
127
102
 
@@ -157,8 +132,10 @@ module snapshot_details;
157
132
 
158
133
  endmodule
159
134
 
160
- module debug(errors);
161
- input [31:0] errors;
135
+ module debug;
136
+ reg [31:0] errors = 0;
137
+ reg [15:0] marker = 0;
138
+ reg [31:0] match_errors = 0;
162
139
 
163
140
  reg [1023:0] pattern = 0;
164
141
  % OrigenSim::NUMBER_OF_COMMENT_LINES.times do |i|
@@ -179,13 +156,10 @@ module origen;
179
156
  wire <%= pin.id %>;
180
157
  % end
181
158
 
182
- wire [31:0] errors;
183
-
184
159
  pin_drivers pins (
185
160
  % dut.rtl_pins.each_with_index do |(name, pin, options), i|
186
- .<%= pin.id %>_o(<%= pin.id %>),
161
+ .<%= pin.id %>_o(<%= pin.id %>)<%= i == dut.rtl_pins.size - 1 ? '' : ',' %>
187
162
  % end
188
- .errors(errors)
189
163
  );
190
164
 
191
165
  // Instantiate the DUT
@@ -205,7 +179,7 @@ module origen;
205
179
  % pin.primary_group.each_with_index do |pin, i|
206
180
  <%= pin.id %><%= i == (pin.primary_group.size - 1) ? '' : ',' %>
207
181
  % end
208
- })<%= i == (dut.rtl_pins.size - 1) ? '' : ',' %>
182
+ })<%= (i + pin.primary_group.size) == dut.rtl_pins.size ? '' : ',' %>
209
183
  % seen_groups << pin.primary_group
210
184
  % end
211
185
  % else
@@ -214,17 +188,11 @@ module origen;
214
188
  % end
215
189
  );
216
190
 
217
- debug debug (
218
- .errors(errors)
219
- );
191
+ debug debug ();
220
192
 
221
193
  `ifdef ORIGEN_VCD
222
194
  initial
223
195
  begin
224
- //$display("********************************");
225
- //$display("Creating origen.vcd...");
226
- //$display("********************************");
227
- //$dumpfile("origen.vcd");
228
196
  $dumpvars(0,origen);
229
197
  end
230
198
  `endif
@@ -248,9 +216,6 @@ module origen;
248
216
 
249
217
 
250
218
  always @(posedge finish) begin
251
- //$display("********************************");
252
- //$display("Finishing simulation...");
253
- //$display("********************************");
254
219
  $finish(2);
255
220
  end
256
221
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: origen_sim
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.0
4
+ version: 0.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen McGinty
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-11 00:00:00.000000000 Z
11
+ date: 2019-03-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: origen
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.41.0
19
+ version: 0.43.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.41.0
26
+ version: 0.43.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: origen_testers
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -143,7 +143,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
143
143
  version: 1.8.11
144
144
  requirements: []
145
145
  rubyforge_project:
146
- rubygems_version: 2.7.7
146
+ rubygems_version: 2.7.6
147
147
  signing_key:
148
148
  specification_version: 4
149
149
  summary: Plugin that provides a testbench environment to simulate Origen test patterns