origen_sim 0.20.6 → 0.20.7
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/version.rb +1 -1
- data/ext/bridge.c +16 -2
- data/lib/origen_sim/commands/build.rb +1 -0
- data/lib/origen_sim/simulator.rb +14 -2
- data/lib/origen_sim/tester.rb +54 -22
- data/lib/origen_sim_dev/dut.rb +4 -0
- data/pattern/test.rb +8 -1
- data/templates/origen_guides/simulation/patterns.md.erb +8 -0
- data/templates/probe.tcl.erb +2 -2
- data/templates/rtl_v/origen.v.erb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4035df7e280d12364f716ead8d7a913c4d6ff4528319abc8864b3ef1d73126b2
|
4
|
+
data.tar.gz: 2e2fe5684ea80e5cad1816844274256879b0c73a502fa3394064634a43771488
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 705f261114c025f8470bab1504f49901fbd64127261e25216f8a3bbdb9bcc391b937781adbdcbd3bcbb3f2a4539c8eb94d6231e77e43c49925fbeaaaed40927e
|
7
|
+
data.tar.gz: 9ffeb116e814958ab5ed504b8033321ae75054728e2afcc636ec51c299826d5b5bfe7e111ba1410c744b794ae62f9391346ee8ec5ac6de832be4078f3208cb7b
|
data/config/version.rb
CHANGED
data/ext/bridge.c
CHANGED
@@ -29,6 +29,7 @@ typedef struct Pin {
|
|
29
29
|
int compare_wave_pos; // Position of the pin in the compare_wave's active pin array
|
30
30
|
int index; // The pin's index in the pins array
|
31
31
|
int previous_state; // Used to keep track of whether the pin was previously driving or comparing
|
32
|
+
int drive_data; // Used to hold the new drive data for this pin until needed by the drive wave
|
32
33
|
bool capture_en; // Used to indicated when compare data should be captured instead of compared
|
33
34
|
bool present; // Set to true if the pin is present in the testbench
|
34
35
|
} Pin;
|
@@ -108,6 +109,7 @@ static void define_pin(char * name, char * pin_ix, char * drive_wave_ix, char *
|
|
108
109
|
(*pin).compare_wave = atoi(compare_wave_ix);
|
109
110
|
(*pin).previous_state = 0;
|
110
111
|
(*pin).capture_en = false;
|
112
|
+
(*pin).drive_data = 0;
|
111
113
|
|
112
114
|
|
113
115
|
char * driver = (char *) malloc(strlen(name) + 16);
|
@@ -326,9 +328,15 @@ static void drive_pin(char * index, char * val) {
|
|
326
328
|
s_vpi_value v = {vpiIntVal, {0}};
|
327
329
|
|
328
330
|
if ((*pin).present) {
|
331
|
+
// Store the pin drive data to be applied at the data edge
|
332
|
+
(*pin).drive_data = (val[0] - '0');
|
333
|
+
|
329
334
|
// Apply the data value to the pin's driver
|
330
|
-
|
331
|
-
|
335
|
+
if (is_drive_whole_cycle(pin)) {
|
336
|
+
v.value.integer = (*pin).drive_data;
|
337
|
+
vpi_put_value((*pin).data, &v, NULL, vpiNoDelay);
|
338
|
+
}
|
339
|
+
|
332
340
|
// Make sure not comparing
|
333
341
|
v.value.integer = 0;
|
334
342
|
vpi_put_value((*pin).compare, &v, NULL, vpiNoDelay);
|
@@ -431,6 +439,7 @@ static void dont_care_pin(char * index) {
|
|
431
439
|
PLI_INT32 apply_wave_event_cb(p_cb_data data) {
|
432
440
|
s_vpi_value v = {vpiIntVal, {0}};
|
433
441
|
s_vpi_value v2 = {vpiIntVal, {0}};
|
442
|
+
s_vpi_value v3 = {vpiIntVal, {0}};
|
434
443
|
|
435
444
|
int * wave_ix = (int*)(&(data->user_data[0]));
|
436
445
|
int * event_ix = (int*)(&(data->user_data[sizeof(int)]));
|
@@ -486,6 +495,11 @@ PLI_INT32 apply_wave_event_cb(p_cb_data data) {
|
|
486
495
|
case 'D' :
|
487
496
|
d = 0;
|
488
497
|
on = 1;
|
498
|
+
// Apply the data value to the pin's driver
|
499
|
+
for (int i = 0; i < (*wave).active_pin_count; i++) {
|
500
|
+
v3.value.integer = (*(*wave).active_pins[i]).drive_data;
|
501
|
+
vpi_put_value((*(*wave).active_pins[i]).data, &v3, NULL, vpiNoDelay);
|
502
|
+
}
|
489
503
|
break;
|
490
504
|
case 'X' :
|
491
505
|
d = 0;
|
data/lib/origen_sim/simulator.rb
CHANGED
@@ -328,7 +328,13 @@ module OrigenSim
|
|
328
328
|
output: tmp_dir,
|
329
329
|
check_for_changes: false,
|
330
330
|
quiet: true,
|
331
|
-
options: { dir:
|
331
|
+
options: { dir: wave_dir,
|
332
|
+
wave_file: wave_file_basename,
|
333
|
+
force: config[:force],
|
334
|
+
setup: config[:setup],
|
335
|
+
depth: :all,
|
336
|
+
testbench_top: config[:testbench_top] || 'origen'
|
337
|
+
},
|
332
338
|
output_file_name: "#{wave_file_basename}.tcl",
|
333
339
|
preserve_target: true
|
334
340
|
end
|
@@ -340,7 +346,13 @@ module OrigenSim
|
|
340
346
|
output: tmp_dir,
|
341
347
|
check_for_changes: false,
|
342
348
|
quiet: true,
|
343
|
-
options: { dir:
|
349
|
+
options: { dir: wave_dir,
|
350
|
+
wave_file: wave_file_basename,
|
351
|
+
force: config[:force],
|
352
|
+
setup: config[:setup],
|
353
|
+
depth: fast_probe_depth,
|
354
|
+
testbench_top: config[:testbench_top] || 'origen'
|
355
|
+
},
|
344
356
|
output_file_name: "#{wave_file_basename}_fast.tcl",
|
345
357
|
preserve_target: true
|
346
358
|
end
|
data/lib/origen_sim/tester.rb
CHANGED
@@ -41,9 +41,25 @@ module OrigenSim
|
|
41
41
|
end
|
42
42
|
@sync_pins.map do |pin|
|
43
43
|
if @sync_cycles.size == 1
|
44
|
-
simulator.peek("#{simulator.testbench_top}.pins.#{pin.id}.sync_memory")[0]
|
44
|
+
b = simulator.peek("#{simulator.testbench_top}.pins.#{pin.id}.sync_memory")[0]
|
45
|
+
if b.is_a?(Integer)
|
46
|
+
b
|
47
|
+
else
|
48
|
+
Origen.log.warning "The data captured on pin #{pin.id} was undefined (X or Z), the captured value is not correct!"
|
49
|
+
0
|
50
|
+
end
|
45
51
|
else
|
46
|
-
|
52
|
+
val = 0
|
53
|
+
mem = simulator.peek("#{simulator.testbench_top}.pins.#{pin.id}.sync_memory")
|
54
|
+
@sync_cycles.times do |i|
|
55
|
+
b = mem[i]
|
56
|
+
if b.is_a?(Integer)
|
57
|
+
val |= b << i
|
58
|
+
else
|
59
|
+
Origen.log.warning "The data captured on cycle #{i} of pin #{pin.id} was undefined (X or Z), the captured value is not correct!"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
val
|
47
63
|
end
|
48
64
|
end
|
49
65
|
end
|
@@ -166,25 +182,21 @@ module OrigenSim
|
|
166
182
|
if options[:pin2]
|
167
183
|
expected_val2 = options[:state2] == :high ? 1 : 0
|
168
184
|
end
|
169
|
-
|
170
|
-
|
171
|
-
|
185
|
+
matched = false
|
186
|
+
start_cycle = cycle_count
|
187
|
+
resolution = match_loop_resolution(timeout_in_cycles, options)
|
188
|
+
until matched || cycle_count > start_cycle + timeout_in_cycles
|
189
|
+
resolution.cycles
|
172
190
|
current_val = simulator.peek("dut.#{pin.rtl_name}").to_i
|
173
191
|
if options[:pin2]
|
174
192
|
current_val2 = simulator.peek("dut.#{options[:pin2].rtl_name}").to_i
|
175
|
-
|
176
|
-
timed_out = false
|
177
|
-
break
|
178
|
-
end
|
193
|
+
matched = current_val == expected_val || current_val2 == expected_val2
|
179
194
|
else
|
180
|
-
|
181
|
-
timed_out = false
|
182
|
-
break
|
183
|
-
end
|
195
|
+
matched = current_val == expected_val
|
184
196
|
end
|
185
197
|
end
|
186
198
|
# Final assertion to make the pattern fail if the loop timed out
|
187
|
-
|
199
|
+
unless matched
|
188
200
|
pin.restore_state do
|
189
201
|
pin.assert!(expected_val)
|
190
202
|
end
|
@@ -207,23 +219,22 @@ module OrigenSim
|
|
207
219
|
else
|
208
220
|
match_conditions.add(&block)
|
209
221
|
end
|
210
|
-
|
222
|
+
matched = false
|
223
|
+
start_cycle = cycle_count
|
224
|
+
resolution = match_loop_resolution(timeout_in_cycles, options)
|
211
225
|
simulator.match_loop do
|
212
|
-
|
213
|
-
|
226
|
+
until matched || cycle_count > start_cycle + timeout_in_cycles
|
227
|
+
resolution.cycles
|
214
228
|
# Consider the match resolved if any condition can execute without generating errors
|
215
|
-
|
229
|
+
matched = match_conditions.any? do |condition|
|
216
230
|
e = simulator.match_errors
|
217
231
|
condition.call
|
218
232
|
e == simulator.match_errors
|
219
233
|
end
|
220
|
-
timed_out = false
|
221
|
-
break
|
222
|
-
end
|
223
234
|
end
|
224
235
|
end
|
225
236
|
# Final execution to make the pattern fail if the loop timed out
|
226
|
-
|
237
|
+
unless matched
|
227
238
|
if fail_conditions.instance_variable_get(:@block_args).empty?
|
228
239
|
match_conditions.each(&:call)
|
229
240
|
else
|
@@ -232,6 +243,27 @@ module OrigenSim
|
|
232
243
|
end
|
233
244
|
end
|
234
245
|
|
246
|
+
# @api private
|
247
|
+
def match_loop_resolution(timeout_in_cycles, options)
|
248
|
+
if options[:resolution]
|
249
|
+
if options[:resolution].is_a?(Hash)
|
250
|
+
return time_to_cycles(options[:resolution])
|
251
|
+
else
|
252
|
+
return options[:resolution]
|
253
|
+
end
|
254
|
+
else
|
255
|
+
# Used to use the supplied timeout / 10, thinking that the supplied number would be
|
256
|
+
# roughly how long it would take. However, found that when users didn't know the timeout
|
257
|
+
# they would just put in really large numbers, like 1sec, which would mean we would not
|
258
|
+
# check until 100ms for an operation that might be done after 100us.
|
259
|
+
# So now if the old default comes out less than the new one, then use it, otherwise use
|
260
|
+
# the newer more fine-grained default.
|
261
|
+
old_default = timeout_in_cycles / 10
|
262
|
+
new_default = time_to_cycles(time_in_us: 100)
|
263
|
+
return old_default < new_default ? old_default : new_default
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
235
267
|
def wait(*args)
|
236
268
|
super
|
237
269
|
if Origen.running_interactively? ||
|
data/lib/origen_sim_dev/dut.rb
CHANGED
@@ -35,6 +35,10 @@ module OrigenSimDev
|
|
35
35
|
w.drive 0, at: 0
|
36
36
|
w.drive :data, at: 'period / 2'
|
37
37
|
end
|
38
|
+
# Generate drive timing that has only a data event which isn't at t0
|
39
|
+
t.wave :din_port do |w|
|
40
|
+
w.drive :data, at: 'period / 2'
|
41
|
+
end
|
38
42
|
end
|
39
43
|
|
40
44
|
add_reg :dr, 0x0, size: 66 do |reg|
|
data/pattern/test.rb
CHANGED
@@ -218,6 +218,13 @@ Pattern.create do
|
|
218
218
|
60.cycles
|
219
219
|
end
|
220
220
|
|
221
|
+
ss "Test timing implementation - drive timing, single data event only, not at t0"
|
222
|
+
dut.pins(:din_port).dont_care
|
223
|
+
tester.cycle
|
224
|
+
dut.pins(:din_port).drive! 1
|
225
|
+
dut.pins(:din_port).drive! 0
|
226
|
+
dut.pins(:din_port).drive! 1
|
227
|
+
|
221
228
|
ss "Test the command works with static vectors"
|
222
229
|
dut.pin(:done).assert!(1)
|
223
230
|
dut.pin(:done).dont_care
|
@@ -262,7 +269,7 @@ Pattern.create do
|
|
262
269
|
5.cycles
|
263
270
|
dut.pin(:done).assert!(0)
|
264
271
|
dut.pin(:done).dont_care
|
265
|
-
tester.wait match: true,
|
272
|
+
tester.wait match: true, time_in_s: 2 do
|
266
273
|
dut.pin(:done).assert!(1)
|
267
274
|
end
|
268
275
|
dut.pin(:done).assert!(1)
|
@@ -28,6 +28,14 @@ normally have two options:
|
|
28
28
|
Both of these are fully supported by OrigenSim, see the
|
29
29
|
[Timing and Waiting guide](<%= path "guides/pattern/timing" %>) for more information on these APIs.
|
30
30
|
|
31
|
+
<div class="alert alert-info" role="alert"> <strong>A Note on Match Loops</strong>
|
32
|
+
<br>
|
33
|
+
When waiting for a match, the DUT will be polled every 100us by default or timeout / 10 if that
|
34
|
+
is less than 100us.
|
35
|
+
If you need it to poll more often (at the expense of simulation speed) then a `:resolution` option can
|
36
|
+
be supplied in the same way as described for the `sim_delay` method below.
|
37
|
+
</div>
|
38
|
+
|
31
39
|
However, if your pattern generation flow is going to be supported by simulation, then you also have
|
32
40
|
a third option - to derive the required wait time from the simulation itself.
|
33
41
|
|
data/templates/probe.tcl.erb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
database -open waves -into <%= options[:dir] %>/<%= options[:wave_file] %> -default -event
|
2
|
-
probe -create -shm origen -depth <%= options[:depth] %> -database waves
|
3
|
-
#probe -create -assertions -transaction origen -depth all -database waves
|
2
|
+
probe -create -shm <%= options[:testbench_top] || 'origen' %> -depth <%= options[:depth] %> -database waves
|
3
|
+
#probe -create -assertions -transaction <%= options[:testbench_top] || 'origen' %> -depth all -database waves
|
4
4
|
% Array(options[:tcl_inputs]).each do |line|
|
5
5
|
<%= line %>
|
6
6
|
% end
|
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.20.
|
4
|
+
version: 0.20.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen McGinty
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-01-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: origen
|