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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 460b8179907e128d77b2974255f034d547f60c33c91f1ffde8e1bd25726238a7
4
- data.tar.gz: a76d417628ad05a2a8da4d6ad4a2c7d0f97e9f275c9fe8aaa8c3ec21fa2a3e57
3
+ metadata.gz: 4035df7e280d12364f716ead8d7a913c4d6ff4528319abc8864b3ef1d73126b2
4
+ data.tar.gz: 2e2fe5684ea80e5cad1816844274256879b0c73a502fa3394064634a43771488
5
5
  SHA512:
6
- metadata.gz: d7b355f2be67eab8558b7e396da1116bbb5895a12a706202e509e1d617858d711fe13f2a30ded4c575bb487358dea5d6c75bb9b7742442e6b50ea6242f8cc91c
7
- data.tar.gz: 743428765629ffc1100a2f749f99f587eaf4e673bb049b43a919f16a940e74d35d34ba49ab2c9abf6fc569951f2ce31846626e60cdb0c28a9cf40580a0394f50
6
+ metadata.gz: 705f261114c025f8470bab1504f49901fbd64127261e25216f8a3bbdb9bcc391b937781adbdcbd3bcbb3f2a4539c8eb94d6231e77e43c49925fbeaaaed40927e
7
+ data.tar.gz: 9ffeb116e814958ab5ed504b8033321ae75054728e2afcc636ec51c299826d5b5bfe7e111ba1410c744b794ae62f9391346ee8ec5ac6de832be4078f3208cb7b
@@ -1,7 +1,7 @@
1
1
  module OrigenSim
2
2
  MAJOR = 0
3
3
  MINOR = 20
4
- BUGFIX = 6
4
+ BUGFIX = 7
5
5
  DEV = nil
6
6
  VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
7
7
  end
@@ -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
- v.value.integer = (val[0] - '0');
331
- vpi_put_value((*pin).data, &v, NULL, vpiNoDelay);
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;
@@ -140,6 +140,7 @@ else
140
140
  options: {
141
141
  vendor: :cadence,
142
142
  top: dut.name,
143
+ testbench_name: options[:testbench_name],
143
144
  incl: options[:incl_files],
144
145
  device_name: options[:device_name],
145
146
  revision: options[:revision],
@@ -328,7 +328,13 @@ module OrigenSim
328
328
  output: tmp_dir,
329
329
  check_for_changes: false,
330
330
  quiet: true,
331
- options: { dir: wave_dir, wave_file: wave_file_basename, force: config[:force], setup: config[:setup], depth: :all },
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: wave_dir, wave_file: wave_file_basename, force: config[:force], setup: config[:setup], depth: fast_probe_depth },
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
@@ -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
- simulator.peek("#{simulator.testbench_top}.pins.#{pin.id}.sync_memory").to_i[(@sync_cycles - 1)..0]
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
- timed_out = true
170
- 10.times do
171
- (timeout_in_cycles / 10).cycles
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
- if current_val == expected_val || current_val2 == expected_val2
176
- timed_out = false
177
- break
178
- end
193
+ matched = current_val == expected_val || current_val2 == expected_val2
179
194
  else
180
- if current_val == expected_val
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
- if timed_out
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
- timed_out = true
222
+ matched = false
223
+ start_cycle = cycle_count
224
+ resolution = match_loop_resolution(timeout_in_cycles, options)
211
225
  simulator.match_loop do
212
- 10.times do
213
- (timeout_in_cycles / 10).cycles
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
- if match_conditions.any? do |condition|
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
- if timed_out
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? ||
@@ -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|
@@ -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, time_in_cycles: 2000 do
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
 
@@ -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
@@ -255,7 +255,7 @@ endmodule
255
255
  // | |
256
256
  // |_|
257
257
 
258
- module origen;
258
+ module <%= options[:testbench_name] || 'origen' %>;
259
259
 
260
260
  reg finish = 0;
261
261
 
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.6
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: 2019-08-02 00:00:00.000000000 Z
11
+ date: 2020-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: origen