origen_sim 0.16.1 → 0.20.0
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/application.rb +2 -0
- data/config/commands.rb +29 -20
- data/config/version.rb +2 -2
- data/ext/bridge.c +72 -14
- data/ext/origen.c +29 -17
- data/ext/origen.h +6 -0
- data/ext/origen_tasks.tab +2 -0
- data/lib/origen_sim/commands/build.rb +90 -59
- data/lib/origen_sim/origen/pins/pin.rb +38 -0
- data/lib/origen_sim/origen/top_level.rb +8 -3
- data/lib/origen_sim/simulation.rb +1 -1
- data/lib/origen_sim/simulator/user_details.rb +0 -1
- data/lib/origen_sim/simulator.rb +70 -70
- data/lib/origen_sim/tester.rb +53 -10
- data/lib/origen_sim_dev/dut.rb +66 -46
- data/lib/origen_sim_dev/ip.rb +15 -8
- data/pattern/concurrent_ip.rb +17 -0
- data/pattern/test.rb +122 -10
- data/templates/empty.rc +16 -26
- data/templates/origen_guides/simulation/ams.md.erb +141 -0
- data/templates/origen_guides/simulation/compiling.md.erb +52 -7
- data/templates/origen_guides/simulation/debugging.md.erb +1 -1
- data/templates/origen_guides/simulation/direct.md.erb +112 -0
- data/templates/origen_guides/simulation/environment.md.erb +6 -3
- data/templates/origen_guides/simulation/patterns.md.erb +2 -7
- data/templates/rtl_v/origen.v.erb +114 -12
- metadata +13 -9
data/lib/origen_sim/simulator.rb
CHANGED
@@ -428,8 +428,8 @@ module OrigenSim
|
|
428
428
|
edir = Pathname.new(wave_config_dir).relative_path_from(Pathname.pwd)
|
429
429
|
cmd = "cd #{edir} && "
|
430
430
|
if configuration[:verdi]
|
431
|
-
unless ENV['VCS_HOME']
|
432
|
-
|
431
|
+
unless ENV['VCS_HOME']
|
432
|
+
Origen.log.warning "Your environment doesn't define VCS_HOME, you will probably need that to run Verdi"
|
433
433
|
end
|
434
434
|
edir = Pathname.new(wave_config_dir).relative_path_from(Pathname.pwd)
|
435
435
|
cmd = "cd #{edir} && "
|
@@ -778,7 +778,7 @@ module OrigenSim
|
|
778
778
|
# set up internal handles to efficiently access them
|
779
779
|
def define_pins
|
780
780
|
@pins_by_rtl_name = {}
|
781
|
-
dut.rtl_pins.each_with_index do |(name, pin), i|
|
781
|
+
dut.rtl_pins(type: :digital).each_with_index do |(name, pin), i|
|
782
782
|
@pins_by_rtl_name[pin.rtl_name] = pin
|
783
783
|
pin.simulation_index = i
|
784
784
|
put("0^#{pin.rtl_name}^#{i}^#{pin.drive_wave.index}^#{pin.compare_wave.index}")
|
@@ -865,6 +865,7 @@ module OrigenSim
|
|
865
865
|
|
866
866
|
def error(message)
|
867
867
|
simulation.logged_errors = true
|
868
|
+
poke "#{testbench_top}.debug.errors", error_count + 1
|
868
869
|
log message, :error
|
869
870
|
end
|
870
871
|
|
@@ -877,87 +878,82 @@ module OrigenSim
|
|
877
878
|
# resolve to a valid node
|
878
879
|
#
|
879
880
|
# The value is returned as an instance of Origen::Value
|
880
|
-
def peek(net)
|
881
|
-
# The Verilog spec does not specify that underlying VPI put method should
|
882
|
-
# handle a part select, so some simulators do not handle it. Therefore we
|
883
|
-
# deal with it here to ensure cross simulator compatibility.
|
884
|
-
|
885
|
-
# http://rubular.com/r/eTVGzrYmXQ
|
886
|
-
if net =~ /(.*)\[(\d+):?(\.\.)?(\d*)\]$/
|
887
|
-
net = Regexp.last_match(1)
|
888
|
-
msb = Regexp.last_match(2).to_i
|
889
|
-
lsb = Regexp.last_match(4)
|
890
|
-
lsb = lsb.empty? ? nil : lsb.to_i
|
891
|
-
end
|
892
|
-
|
881
|
+
def peek(net, real = false)
|
893
882
|
sync_up
|
894
|
-
|
895
|
-
|
883
|
+
if dut_version > '0.19.0'
|
884
|
+
if real
|
885
|
+
put("9^#{clean(net)}^f")
|
886
|
+
m = get.strip
|
887
|
+
if m == 'FAIL'
|
888
|
+
return nil
|
889
|
+
else
|
890
|
+
m.to_f
|
891
|
+
end
|
892
|
+
else
|
893
|
+
put("9^#{clean(net)}^i")
|
894
|
+
m = get.strip
|
896
895
|
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
if msb
|
901
|
-
# Setting a range of bits
|
902
|
-
if lsb
|
903
|
-
Origen::Value.new('b' + m[(m.size - 1 - msb)..(m.size - 1 - lsb)])
|
896
|
+
if m == 'FAIL'
|
897
|
+
Origen.log.warning "Peek of net #{net} failed to return any data!"
|
898
|
+
return nil
|
904
899
|
else
|
905
|
-
Origen::Value.new('b' + m
|
900
|
+
Origen::Value.new('b' + m)
|
906
901
|
end
|
902
|
+
end
|
903
|
+
else
|
904
|
+
put("9^#{clean(net)}")
|
905
|
+
m = get.strip
|
906
|
+
|
907
|
+
if m == 'FAIL'
|
908
|
+
Origen.log.warning "Peek of net #{net} failed to return any data!"
|
909
|
+
return nil
|
907
910
|
else
|
908
911
|
Origen::Value.new('b' + m)
|
909
912
|
end
|
910
913
|
end
|
911
914
|
end
|
912
915
|
|
916
|
+
def peek_real(net)
|
917
|
+
peek(net, true)
|
918
|
+
end
|
919
|
+
|
913
920
|
# Forces the given value to the given net.
|
914
921
|
# Note that no error checking is done and no error will be communicated if an illegal
|
915
922
|
# net is supplied. The user should follow up with a peek if they want to verify that
|
916
923
|
# the poke was applied.
|
917
924
|
def poke(net, value)
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
v = peek(path)
|
930
|
-
return nil unless v
|
931
|
-
# Setting a range of bits
|
932
|
-
if lsb
|
933
|
-
upper = v >> (msb + 1)
|
934
|
-
# Make sure value does not overflow
|
935
|
-
value = value[(msb - lsb)..0]
|
936
|
-
if lsb == 0
|
937
|
-
value = (upper << (msb + 1)) | value
|
938
|
-
else
|
939
|
-
lower = v[(lsb - 1)..0]
|
940
|
-
value = (upper << (msb + 1)) |
|
941
|
-
(value << lsb) | lower
|
942
|
-
end
|
925
|
+
sync_up
|
926
|
+
if dut_version > '0.19.0'
|
927
|
+
if value.is_a?(Integer)
|
928
|
+
put("b^#{clean(net)}^i^#{value}")
|
929
|
+
else
|
930
|
+
put("b^#{clean(net)}^f^#{value}")
|
931
|
+
end
|
932
|
+
else
|
933
|
+
put("b^#{clean(net)}^#{value}")
|
934
|
+
end
|
935
|
+
end
|
943
936
|
|
944
|
-
|
937
|
+
def force(net, value)
|
938
|
+
sync_up
|
939
|
+
if dut_version > '0.19.0'
|
940
|
+
if value.is_a?(Integer)
|
941
|
+
put("r^#{clean(net)}^i^#{value}")
|
945
942
|
else
|
946
|
-
|
947
|
-
upper = v >> 1
|
948
|
-
value = (upper << 1) | value[0]
|
949
|
-
else
|
950
|
-
lower = v[(msb - 1)..0]
|
951
|
-
upper = v >> (msb + 1)
|
952
|
-
value = (upper << (msb + 1)) |
|
953
|
-
(value[0] << msb) | lower
|
954
|
-
end
|
943
|
+
put("r^#{clean(net)}^f^#{value}")
|
955
944
|
end
|
956
|
-
|
945
|
+
else
|
946
|
+
OrigenSim.error 'Your DUT needs to be recompiled with OrigenSim >= 0.20.0 to support forcing, force not applied!'
|
957
947
|
end
|
948
|
+
end
|
958
949
|
|
950
|
+
def release(net)
|
959
951
|
sync_up
|
960
|
-
|
952
|
+
if dut_version > '0.19.0'
|
953
|
+
put("s^#{clean(net)}")
|
954
|
+
else
|
955
|
+
OrigenSim.error 'Your DUT needs to be recompiled with OrigenSim >= 0.20.0 to support releasing, force not released!'
|
956
|
+
end
|
961
957
|
end
|
962
958
|
|
963
959
|
def interactive_shutdown
|
@@ -1124,17 +1120,13 @@ module OrigenSim
|
|
1124
1120
|
end
|
1125
1121
|
|
1126
1122
|
def peek_str(signal)
|
1127
|
-
val =
|
1123
|
+
val = peek(signal)
|
1128
1124
|
unless val.nil?
|
1129
|
-
puts val
|
1130
|
-
puts val.class
|
1131
1125
|
# All zeros seems to be what an empty string is returned from the VPI,
|
1132
1126
|
# Otherwise, break the string up into 8-bit chunks and decode the ASCII>
|
1133
1127
|
val = (val.to_s == 'b00000000' ? '' : val.to_s[1..-1].scan(/.{1,8}/).collect { |char| char.to_i(2).chr }.join)
|
1134
1128
|
end
|
1135
1129
|
val
|
1136
|
-
# puts "Peaking #{signal}: #{a}: #{a.class}"
|
1137
|
-
# tester.simulator.peek(signal).to_s[1..-1].scan(/.{1,8}/).collect { |char| char.to_i(2).chr }.join
|
1138
1130
|
end
|
1139
1131
|
alias_method :str_peek, :peek_str
|
1140
1132
|
alias_method :peek_string, :peek_str
|
@@ -1161,8 +1153,8 @@ module OrigenSim
|
|
1161
1153
|
errors = []
|
1162
1154
|
error_count.times do |i|
|
1163
1155
|
data = get # => "tdo,648,1,0\n"
|
1164
|
-
pin_name, cycle, expected,
|
1165
|
-
errors << { pin_name: pin_name, cycle: cycle.to_i, expected: expected.to_i,
|
1156
|
+
pin_name, cycle, expected, received = *(data.strip.split(','))
|
1157
|
+
errors << { pin_name: pin_name, cycle: cycle.to_i, expected: expected.to_i, received: received.to_i }
|
1166
1158
|
end
|
1167
1159
|
[true, error_count > max_errors, errors]
|
1168
1160
|
end
|
@@ -1175,6 +1167,14 @@ module OrigenSim
|
|
1175
1167
|
get.strip.to_i
|
1176
1168
|
end
|
1177
1169
|
|
1170
|
+
# Returns true if the snapshot has been compiled with WREAL support
|
1171
|
+
def wreal?
|
1172
|
+
return @wreal if defined?(@wreal)
|
1173
|
+
@wreal = (dut_version > '0.19.0' &&
|
1174
|
+
peek("#{testbench_top}.debug.wreal_enabled").to_i == 1)
|
1175
|
+
end
|
1176
|
+
alias_method :wreal_enabled?, :wreal?
|
1177
|
+
|
1178
1178
|
private
|
1179
1179
|
|
1180
1180
|
# Will be called when the simulator has aborted due to the max error count being exceeded
|
data/lib/origen_sim/tester.rb
CHANGED
@@ -16,6 +16,7 @@ module OrigenSim
|
|
16
16
|
simulator.configure(opts, &block)
|
17
17
|
@comment_buffer = []
|
18
18
|
@last_comment_size = 0
|
19
|
+
@execution_time_in_ns = 0
|
19
20
|
super()
|
20
21
|
end
|
21
22
|
|
@@ -38,9 +39,9 @@ module OrigenSim
|
|
38
39
|
end
|
39
40
|
@sync_pins.map do |pin|
|
40
41
|
if @sync_cycles.size == 1
|
41
|
-
simulator.peek("#{simulator.testbench_top}.pins.#{pin.id}.sync_memory[0]
|
42
|
+
simulator.peek("#{simulator.testbench_top}.pins.#{pin.id}.sync_memory")[0]
|
42
43
|
else
|
43
|
-
simulator.peek("#{simulator.testbench_top}.pins.#{pin.id}.sync_memory[
|
44
|
+
simulator.peek("#{simulator.testbench_top}.pins.#{pin.id}.sync_memory").to_i[(@sync_cycles - 1)..0]
|
44
45
|
end
|
45
46
|
end
|
46
47
|
end
|
@@ -80,11 +81,13 @@ module OrigenSim
|
|
80
81
|
unless options[:timeset]
|
81
82
|
puts 'No timeset defined!'
|
82
83
|
puts 'Add one to your top level startup method or target like this:'
|
83
|
-
puts '
|
84
|
+
puts 'tester.set_timeset("nvmbist", 40) # Where 40 is the period in ns'
|
84
85
|
exit 1
|
85
86
|
end
|
86
87
|
flush_comments unless @comment_buffer.empty?
|
87
|
-
|
88
|
+
repeat = options[:repeat] || 1
|
89
|
+
simulator.cycle(repeat)
|
90
|
+
@execution_time_in_ns += repeat * tester.timeset.period_in_ns
|
88
91
|
if @after_next_vector
|
89
92
|
@after_next_vector.call(@after_next_vector_args)
|
90
93
|
@after_next_vector = nil
|
@@ -94,6 +97,7 @@ module OrigenSim
|
|
94
97
|
|
95
98
|
def c1(msg, options = {})
|
96
99
|
if @step_comment_on
|
100
|
+
PatSeq.add_thread(msg) unless options[:no_thread_id]
|
97
101
|
simulator.log msg
|
98
102
|
@comment_buffer << msg
|
99
103
|
end
|
@@ -293,7 +297,7 @@ module OrigenSim
|
|
293
297
|
if c = read_reg_cycles[error[:cycle]]
|
294
298
|
if p = c[simulator.pins_by_rtl_name[error[:pin_name]]]
|
295
299
|
if p[:position]
|
296
|
-
diffs << [p[:position], error[:
|
300
|
+
diffs << [p[:position], error[:received], error[:expected]]
|
297
301
|
end
|
298
302
|
end
|
299
303
|
end
|
@@ -301,6 +305,7 @@ module OrigenSim
|
|
301
305
|
if diffs.empty?
|
302
306
|
if @read_reg_meta_supplied
|
303
307
|
Origen.log.warning 'It looks like the miscompare(s) occurred on pins/cycles that are not associated with register data'
|
308
|
+
non_data_miscompare = true
|
304
309
|
else
|
305
310
|
Origen.log.warning 'It looks like your current read register driver does not provide the necessary meta-data to map these errors to an actual register value'
|
306
311
|
end
|
@@ -323,7 +328,11 @@ module OrigenSim
|
|
323
328
|
end
|
324
329
|
|
325
330
|
diffs.each do |position, received, expected|
|
326
|
-
|
331
|
+
if received == -1
|
332
|
+
reg_or_val[position].unknown = true
|
333
|
+
else
|
334
|
+
reg_or_val[position].data = received
|
335
|
+
end
|
327
336
|
end
|
328
337
|
|
329
338
|
actual = bit_names.map do |name|
|
@@ -357,7 +366,8 @@ module OrigenSim
|
|
357
366
|
Origen.log.error msg
|
358
367
|
end
|
359
368
|
else
|
360
|
-
|
369
|
+
# This means that the correct data was read, but errors occurred on other pins/cycles during the transaction
|
370
|
+
msg += " received #{expected}" if non_data_miscompare
|
361
371
|
Origen.log.error msg
|
362
372
|
end
|
363
373
|
end
|
@@ -367,7 +377,10 @@ module OrigenSim
|
|
367
377
|
if actual_data_available
|
368
378
|
actual = reg_or_val
|
369
379
|
diffs.each do |position, received, expected|
|
370
|
-
if received == 1
|
380
|
+
if received == -1
|
381
|
+
actual = '?' * reg_or_val.to_s(16).size
|
382
|
+
break
|
383
|
+
elsif received == 1
|
371
384
|
actual |= (1 << position)
|
372
385
|
else
|
373
386
|
lower = actual[(position - 1)..0]
|
@@ -376,9 +389,14 @@ module OrigenSim
|
|
376
389
|
actual |= lower
|
377
390
|
end
|
378
391
|
end
|
379
|
-
|
392
|
+
if actual.is_a?(String)
|
393
|
+
msg += " received #{actual}"
|
394
|
+
else
|
395
|
+
msg += " received #{actual.to_s(16).upcase}"
|
396
|
+
end
|
380
397
|
else
|
381
|
-
|
398
|
+
# This means that the correct data was read, but errors occurred on other pins/cycles during the transaction
|
399
|
+
msg += " received #{reg_or_val.to_s(16).upcase}" if non_data_miscompare
|
382
400
|
end
|
383
401
|
Origen.log.error msg
|
384
402
|
end
|
@@ -409,6 +427,31 @@ module OrigenSim
|
|
409
427
|
@read_reg_meta_supplied = val
|
410
428
|
end
|
411
429
|
|
430
|
+
# Shorthand for simulator.poke
|
431
|
+
def poke(*args)
|
432
|
+
simulator.poke(*args)
|
433
|
+
end
|
434
|
+
|
435
|
+
# Shorthand for simulator.peek
|
436
|
+
def peek(*args)
|
437
|
+
simulator.peek(*args)
|
438
|
+
end
|
439
|
+
|
440
|
+
# Shorthand for simulator.peek_real
|
441
|
+
def peek_real(*args)
|
442
|
+
simulator.peek_real(*args)
|
443
|
+
end
|
444
|
+
|
445
|
+
# Shorthand for simulator.force
|
446
|
+
def force(*args)
|
447
|
+
simulator.force(*args)
|
448
|
+
end
|
449
|
+
|
450
|
+
# Shorthand for simulator.release
|
451
|
+
def release(*args)
|
452
|
+
simulator.release(*args)
|
453
|
+
end
|
454
|
+
|
412
455
|
private
|
413
456
|
|
414
457
|
def flush_comments
|
data/lib/origen_sim_dev/dut.rb
CHANGED
@@ -26,6 +26,8 @@ module OrigenSimDev
|
|
26
26
|
add_pin :v2, rtl_name: :nc
|
27
27
|
add_pin :done
|
28
28
|
add_pin :not_present
|
29
|
+
add_power_pin :vdd
|
30
|
+
add_pin :ana, type: :analog
|
29
31
|
|
30
32
|
timeset :func do |t|
|
31
33
|
# Generate a clock pulse on TCK
|
@@ -73,6 +75,15 @@ module OrigenSimDev
|
|
73
75
|
reg.bits 2..0, :b6
|
74
76
|
end
|
75
77
|
|
78
|
+
add_reg :ana_test, 0x1C do |reg|
|
79
|
+
reg.bit 0, :vdd_valid, access: :ro
|
80
|
+
reg.bit 1, :bgap_out
|
81
|
+
reg.bit 2, :osc_out
|
82
|
+
reg.bit 3, :vdd_div4
|
83
|
+
end
|
84
|
+
|
85
|
+
add_reg :x_reg, 0x20
|
86
|
+
|
76
87
|
sub_block :ip1, class_name: 'IP'
|
77
88
|
sub_block :ip2, class_name: 'IP'
|
78
89
|
end
|
@@ -84,6 +95,10 @@ module OrigenSimDev
|
|
84
95
|
end
|
85
96
|
end
|
86
97
|
|
98
|
+
def simulation_startup
|
99
|
+
power_pin(:vdd).drive(0)
|
100
|
+
end
|
101
|
+
|
87
102
|
def startup(options = {})
|
88
103
|
# tester.simulator.log_messages = true
|
89
104
|
tester.set_timeset('func', 100)
|
@@ -101,60 +116,65 @@ module OrigenSimDev
|
|
101
116
|
end
|
102
117
|
|
103
118
|
def write_register(reg, options = {})
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
119
|
+
PatSeq.serialize :jtag do
|
120
|
+
if reg.path =~ /ip(\d)/
|
121
|
+
ir_val = 0b0100 | Regexp.last_match(1).to_i
|
122
|
+
jtag.write_ir(ir_val, size: 4)
|
123
|
+
ip = reg.parent
|
124
|
+
ip.dr.bits(:write).write(1)
|
125
|
+
ip.dr.bits(:address).write(reg.address)
|
126
|
+
ip.dr.bits(:data).write(reg.data)
|
127
|
+
jtag.write_dr(ip.dr)
|
128
|
+
# Write to top-level reg
|
129
|
+
else
|
130
|
+
jtag.write_ir(0x8, size: 4)
|
131
|
+
dr.rg_enable.write(1)
|
132
|
+
dr.rg_read.write(0)
|
133
|
+
dr.rg_addr.write(reg.address)
|
134
|
+
dr.rg_data.write(reg.data)
|
135
|
+
jtag.write_dr(dr)
|
136
|
+
end
|
120
137
|
end
|
121
138
|
end
|
122
139
|
|
123
140
|
def read_register(reg, options = {})
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
141
|
+
PatSeq.serialize :jtag do
|
142
|
+
tester.read_register(reg, options) do
|
143
|
+
# Special read for this register to test sync'ing over a parallel port
|
144
|
+
if reg.id == :parallel_read
|
145
|
+
pins = []
|
146
|
+
reg.shift_out_with_index do |bit, i|
|
147
|
+
if bit.is_to_be_stored?
|
148
|
+
pins << dut.pins(:dout)[i]
|
149
|
+
end
|
131
150
|
end
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
dut.pins(:dout).dont_care
|
136
|
-
else
|
137
|
-
if reg.path =~ /ip(\d)/
|
138
|
-
ir_val = 0b0100 | Regexp.last_match(1).to_i
|
139
|
-
jtag.write_ir(ir_val, size: 4)
|
140
|
-
ip = reg.parent
|
141
|
-
ip.dr.bits(:write).write(0)
|
142
|
-
ip.dr.bits(:address).write(reg.address)
|
143
|
-
ip.dr.bits(:data).write(0)
|
144
|
-
jtag.write_dr(ip.dr)
|
145
|
-
ip.dr.bits(:data).copy_all(reg)
|
146
|
-
jtag.read_dr(ip.dr)
|
151
|
+
tester.store_next_cycle(*pins.reverse)
|
152
|
+
1.cycle
|
153
|
+
dut.pins(:dout).dont_care
|
147
154
|
else
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
155
|
+
if reg.path =~ /ip(\d)/
|
156
|
+
ir_val = 0b0100 | Regexp.last_match(1).to_i
|
157
|
+
jtag.write_ir(ir_val, size: 4)
|
158
|
+
ip = reg.parent
|
159
|
+
ip.dr.bits(:write).write(0)
|
160
|
+
ip.dr.bits(:address).write(reg.address)
|
161
|
+
ip.dr.bits(:data).write(0)
|
162
|
+
jtag.write_dr(ip.dr)
|
163
|
+
ip.dr.bits(:data).copy_all(reg)
|
164
|
+
jtag.read_dr(ip.dr)
|
165
|
+
else
|
166
|
+
jtag.write_ir(0x8, size: 4)
|
167
|
+
dr.rg_enable.write(1)
|
168
|
+
dr.rg_read.write(1)
|
169
|
+
dr.rg_addr.write(reg.address)
|
170
|
+
jtag.write_dr(dr)
|
171
|
+
dr.rg_enable.write(0)
|
172
|
+
dr.rg_data.copy_all(reg)
|
173
|
+
jtag.read_dr(dr)
|
174
|
+
end
|
156
175
|
end
|
157
176
|
end
|
177
|
+
reg.clear_flags
|
158
178
|
end
|
159
179
|
end
|
160
180
|
end
|
data/lib/origen_sim_dev/ip.rb
CHANGED
@@ -33,14 +33,21 @@ module OrigenSimDev
|
|
33
33
|
|
34
34
|
def execute_cmd(code)
|
35
35
|
ss "Execute command #{code}"
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
36
|
+
PatSeq.reserve :jtag do
|
37
|
+
# This is redundant, but added as a test that if an embedded reservation is made to the same
|
38
|
+
# resource then the end of the inner block does not release the reservation before completion
|
39
|
+
# of the outer block
|
40
|
+
PatSeq.reserve :jtag do
|
41
|
+
# Verify that no command is currently running
|
42
|
+
status.read!(0)
|
43
|
+
end
|
44
|
+
|
45
|
+
cmd.write!(code)
|
46
|
+
10.cycles
|
47
|
+
# Verify that the command has started
|
48
|
+
|
49
|
+
status.busy.read!(1)
|
50
|
+
end
|
44
51
|
|
45
52
|
# Wait for the command to complete, a 'command' lasts for
|
46
53
|
# 1000 cycles times the command code
|