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 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