origen_sim 0.20.6 → 0.20.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|