origen_sim 0.12.0 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/config/application.rb +17 -2
- data/config/shared_commands.rb +7 -0
- data/config/version.rb +1 -1
- data/ext/bridge.c +13 -3
- data/lib/origen_sim.rb +10 -0
- data/lib/origen_sim/artifacts.rb +101 -0
- data/lib/origen_sim/commands/build.rb +41 -9
- data/lib/origen_sim/heartbeat.rb +13 -1
- data/lib/origen_sim/origen_testers/api.rb +90 -7
- data/lib/origen_sim/simulation.rb +49 -4
- data/lib/origen_sim/simulator.rb +171 -19
- data/lib/origen_sim/stderr_reader.rb +19 -13
- data/lib/origen_sim/stdout_reader.rb +22 -16
- data/lib/origen_sim/tester.rb +110 -1
- data/lib/origen_sim_dev/dut.rb +5 -0
- data/pattern/test.rb +143 -0
- data/templates/empty.gtkw +19 -1
- data/templates/empty.rc +86 -0
- data/templates/empty.svcf +79 -9
- data/templates/empty.tcl +37 -9
- data/templates/origen_guides/simulation/app.md.erb +131 -0
- data/templates/origen_guides/simulation/artifacts.md.erb +115 -0
- data/templates/origen_guides/simulation/compiling.md.erb +190 -0
- data/templates/origen_guides/simulation/debugging.md.erb +135 -0
- data/templates/origen_guides/simulation/environment.md.erb +217 -0
- data/templates/origen_guides/simulation/flows.md.erb +69 -0
- data/templates/origen_guides/simulation/howitworks.md.erb +64 -0
- data/templates/origen_guides/simulation/introduction.md.erb +35 -0
- data/templates/origen_guides/simulation/log.md.erb +118 -0
- data/templates/origen_guides/simulation/patterns.md.erb +193 -0
- data/templates/probe.tcl.erb +3 -0
- data/templates/rtl_v/origen.v.erb +19 -3
- data/templates/web/layouts/_guides.html.erb +15 -0
- metadata +18 -5
@@ -91,15 +91,46 @@ module OrigenSim
|
|
91
91
|
# heartbeats.
|
92
92
|
def start_heartbeat
|
93
93
|
@heartbeat = @server_heartbeat.accept
|
94
|
-
|
94
|
+
if Heartbeat::THREADSAFE
|
95
|
+
@heartbeat_thread = Heartbeat.new(@heartbeat)
|
96
|
+
else
|
97
|
+
@heartbeat_pid = fork do
|
98
|
+
loop do
|
99
|
+
begin
|
100
|
+
@heartbeat.write("OK\n")
|
101
|
+
rescue Errno::EPIPE => e
|
102
|
+
if monitor_running?
|
103
|
+
Origen.log.error 'Communication with the simulation monitor has been lost (though it seems to still be running)!'
|
104
|
+
else
|
105
|
+
Origen.log.error 'The simulation monitor has stopped unexpectedly!'
|
106
|
+
end
|
107
|
+
sleep 2 # To make sure that any log output from the simulator is captured before we pull the plug
|
108
|
+
exit 1
|
109
|
+
end
|
110
|
+
sleep 5
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
95
114
|
end
|
96
115
|
|
97
116
|
def stop_heartbeat
|
98
|
-
|
117
|
+
if Heartbeat::THREADSAFE
|
118
|
+
@heartbeat_thread.stop
|
119
|
+
else
|
120
|
+
Process.kill('SIGHUP', @heartbeat_pid)
|
121
|
+
|
122
|
+
# Ensure that the process has stopped before closing the IO pipes
|
123
|
+
begin
|
124
|
+
Process.waitpid(@heartbeat_pid)
|
125
|
+
rescue Errno::ECHILD
|
126
|
+
# Heartbeat process has already stopped, so ignore this.
|
127
|
+
end
|
128
|
+
end
|
99
129
|
end
|
100
130
|
|
101
131
|
# Open the communication channels with the simulator
|
102
|
-
def open(timeout)
|
132
|
+
def open(monitor_pid, timeout)
|
133
|
+
@monitor_pid = monitor_pid
|
103
134
|
timeout_connection(timeout) do
|
104
135
|
start_heartbeat
|
105
136
|
@stdout = @server_stdout.accept
|
@@ -169,10 +200,12 @@ module OrigenSim
|
|
169
200
|
@socket.close
|
170
201
|
@stderr.close
|
171
202
|
@stdout.close
|
203
|
+
@status.close
|
172
204
|
File.unlink(socket_id(:heartbeat)) if File.exist?(socket_id(:heartbeat))
|
173
205
|
File.unlink(socket_id) if File.exist?(socket_id)
|
174
206
|
File.unlink(socket_id(:stderr)) if File.exist?(socket_id(:stderr))
|
175
207
|
File.unlink(socket_id(:stdout)) if File.exist?(socket_id(:stdout))
|
208
|
+
File.unlink(socket_id(:status)) if File.exist?(socket_id(:status))
|
176
209
|
end
|
177
210
|
|
178
211
|
# Returns true if the simulation is running
|
@@ -186,8 +219,20 @@ module OrigenSim
|
|
186
219
|
end
|
187
220
|
end
|
188
221
|
|
222
|
+
# Returns true if the simulation monitor process (the one that receives the heartbeat
|
223
|
+
# and kills the simulation if it stops) is running
|
224
|
+
def monitor_running?
|
225
|
+
return false unless @monitor_pid
|
226
|
+
begin
|
227
|
+
Process.getpgid(@monitor_pid)
|
228
|
+
true
|
229
|
+
rescue Errno::ESRCH
|
230
|
+
false
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
189
234
|
def socket_id(type = nil)
|
190
|
-
@socket_ids[type] ||= "/tmp/#{socket_number}#{type}.sock"
|
235
|
+
@socket_ids[type] ||= "#{OrigenSim.socket_dir || '/tmp'}/#{socket_number}#{type}.sock"
|
191
236
|
end
|
192
237
|
|
193
238
|
private
|
data/lib/origen_sim/simulator.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
require 'origen_sim/simulation'
|
2
|
+
require 'origen_sim/artifacts'
|
3
|
+
|
2
4
|
module OrigenSim
|
3
5
|
# Responsible for managing and communicating with the simulator
|
4
6
|
# process, a single instance of this class is instantiated as
|
5
7
|
# OrigenSim.simulator
|
6
8
|
class Simulator
|
7
9
|
include Origen::PersistentCallbacks
|
10
|
+
include Artifacts
|
8
11
|
|
9
12
|
VENDORS = [:icarus, :cadence, :synopsys, :generic]
|
10
13
|
|
@@ -116,6 +119,78 @@ module OrigenSim
|
|
116
119
|
end
|
117
120
|
@configuration = options
|
118
121
|
@tmp_dir = nil
|
122
|
+
|
123
|
+
# Temporary workaround for bug in componentable, which is making the container a class object, instead of an
|
124
|
+
# instance object.
|
125
|
+
clear_artifacts
|
126
|
+
|
127
|
+
# Add any artifacts in the given artifact path
|
128
|
+
if Dir.exist?(default_artifact_dir)
|
129
|
+
default_artifact_dir.children.each { |a| artifact(a.basename.to_s, target: a) }
|
130
|
+
end
|
131
|
+
|
132
|
+
# Add any artifacts from the target-specific path (simulation/<target>/artifacts). Files of the same name
|
133
|
+
# will override artifacts residing in the default directory.
|
134
|
+
if Dir.exist?(target_artifact_dir)
|
135
|
+
target_artifact_dir.children.each do |a|
|
136
|
+
remove_artifact(a.basename.to_s) if has_artifact?(a.basename.to_s)
|
137
|
+
add_artifact(a.basename.to_s, target: a)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# If a user artifact path was given, add those artifacts as well, overriding any of the default and target artifacts
|
142
|
+
if user_artifact_dirs?
|
143
|
+
user_artifact_dirs.each do |d|
|
144
|
+
if Dir.exist?(d)
|
145
|
+
# Add any artifacts from any user-given paths. Files of the same name will override artifacts residing in the default directory.
|
146
|
+
d.children.each do |a|
|
147
|
+
remove_artifact(a.basename.to_s) if has_artifact?(a.basename.to_s)
|
148
|
+
add_artifact(a.basename.to_s, target: a)
|
149
|
+
end
|
150
|
+
else
|
151
|
+
Origen.app.fail! message: "Simulator configuration specified a user artifact dir at #{d} but this directory could not be found!"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
self
|
157
|
+
end
|
158
|
+
|
159
|
+
def default_artifact_dir
|
160
|
+
# Removed this from a constant at the top of the file since it gave boot errors when the file was
|
161
|
+
# being required while Origen.app was still loading
|
162
|
+
Pathname("#{Origen.app.root}/simulation/application/artifacts")
|
163
|
+
end
|
164
|
+
|
165
|
+
def user_artifact_dirs?
|
166
|
+
@configuration.key?(:user_artifact_dirs)
|
167
|
+
end
|
168
|
+
|
169
|
+
def user_artifact_dirs
|
170
|
+
@configuration.key?(:user_artifact_dirs) ? @configuration[:user_artifact_dirs].map { |d| Pathname(d) } : nil
|
171
|
+
end
|
172
|
+
|
173
|
+
def target_artifact_dir
|
174
|
+
Pathname(@configuration[:target_artifact_dir] || "#{Origen.app.root}/simulation/#{Origen.target.name}/artifacts")
|
175
|
+
end
|
176
|
+
|
177
|
+
def artifact_run_dir
|
178
|
+
p = Pathname(@configuration[:artifact_run_dir] || './application/artifacts')
|
179
|
+
if p.absolute?
|
180
|
+
p
|
181
|
+
else
|
182
|
+
Pathname(run_dir).join(p)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def artifact_populate_method
|
187
|
+
@configuration[:artifact_populate_method] || begin
|
188
|
+
if Origen.running_on_windows?
|
189
|
+
:copy
|
190
|
+
else
|
191
|
+
:symlink
|
192
|
+
end
|
193
|
+
end
|
119
194
|
end
|
120
195
|
|
121
196
|
# The ID assigned to the current simulation target, falls back to to the
|
@@ -160,7 +235,7 @@ module OrigenSim
|
|
160
235
|
end
|
161
236
|
|
162
237
|
def wave_config_file
|
163
|
-
@wave_config_file ||= begin
|
238
|
+
@wave_config_file ||= configuration[:wave_config_file] || begin
|
164
239
|
f = "#{wave_config_dir}/#{User.current.id}.#{wave_config_ext}"
|
165
240
|
unless File.exist?(f)
|
166
241
|
# Take a default wave if one has been set up
|
@@ -190,7 +265,11 @@ module OrigenSim
|
|
190
265
|
when :cadence
|
191
266
|
'svcf'
|
192
267
|
when :synopsys
|
193
|
-
|
268
|
+
if configuration[:verdi]
|
269
|
+
'rc'
|
270
|
+
else
|
271
|
+
'tcl'
|
272
|
+
end
|
194
273
|
end
|
195
274
|
end
|
196
275
|
|
@@ -231,7 +310,11 @@ module OrigenSim
|
|
231
310
|
cmd += " -nclibdirpath #{compiled_dir}"
|
232
311
|
|
233
312
|
when :synopsys
|
234
|
-
|
313
|
+
if configuration[:verdi]
|
314
|
+
cmd = "#{compiled_dir}/simv +socket+#{socket_id} +FSDB_ON +fsdbfile+#{Origen.root}/waves/#{Origen.target.name}/#{wave_file_basename}.fsdb +memcbk +vcsd"
|
315
|
+
else
|
316
|
+
cmd = "#{compiled_dir}/simv +socket+#{socket_id} -vpd_file #{wave_file_basename}.vpd"
|
317
|
+
end
|
235
318
|
|
236
319
|
when :generic
|
237
320
|
# Generic tester requires that a generic_run_command option/block be provided.
|
@@ -269,6 +352,10 @@ module OrigenSim
|
|
269
352
|
cmd = post_process_run_cmd.call(cmd, self) if post_process_run_cmd
|
270
353
|
fail "OrigenSim: :post_process_run_cmd returned object of class #{cmd.class}. Must return a String." unless cmd.is_a?(String)
|
271
354
|
|
355
|
+
# Print the command if debug is enabled
|
356
|
+
Origen.log.debug 'OrigenSim Run Command:'
|
357
|
+
Origen.log.debug cmd
|
358
|
+
|
272
359
|
cmd
|
273
360
|
end
|
274
361
|
|
@@ -279,7 +366,11 @@ module OrigenSim
|
|
279
366
|
if Origen.app.current_job
|
280
367
|
@last_wafe_file_basename = Pathname.new(Origen.app.current_job.output_file).basename('.*').to_s
|
281
368
|
else
|
282
|
-
|
369
|
+
if Origen.interactive?
|
370
|
+
'interactive'
|
371
|
+
else
|
372
|
+
@last_wafe_file_basename
|
373
|
+
end
|
283
374
|
end
|
284
375
|
end
|
285
376
|
end
|
@@ -308,12 +399,26 @@ module OrigenSim
|
|
308
399
|
when :synopsys
|
309
400
|
edir = Pathname.new(wave_config_dir).relative_path_from(Pathname.pwd)
|
310
401
|
cmd = "cd #{edir} && "
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
402
|
+
if configuration[:verdi]
|
403
|
+
unless ENV['VCS_HOME'] && ENV['LD_LIBRARY_PATH']
|
404
|
+
puts 'Please make sure the VCS_HOME and LD_LIBRARY PATH are setup correctly before using Verdi'
|
405
|
+
end
|
406
|
+
edir = Pathname.new(wave_config_dir).relative_path_from(Pathname.pwd)
|
407
|
+
cmd = "cd #{edir} && "
|
408
|
+
cmd += configuration[:verdi] || 'verdi'
|
409
|
+
dir = Pathname.new(wave_dir).relative_path_from(edir.expand_path)
|
410
|
+
cmd += " -ssz -dbdir #{Origen.root}/simulation/#{Origen.target.name}/synopsys/simv.daidir/ -ssf #{dir}/#{wave_file_basename}.fsdb"
|
411
|
+
f = Pathname.new(wave_config_file).relative_path_from(edir.expand_path)
|
412
|
+
cmd += " -sswr #{f}"
|
413
|
+
cmd += ' &'
|
414
|
+
else
|
415
|
+
cmd += configuration[:dve] || 'dve'
|
416
|
+
dir = Pathname.new(wave_dir).relative_path_from(edir.expand_path)
|
417
|
+
cmd += " -vpd #{dir}/#{wave_file_basename}.vpd"
|
418
|
+
f = Pathname.new(wave_config_file).relative_path_from(edir.expand_path)
|
419
|
+
cmd += " -session #{f}"
|
420
|
+
cmd += ' &'
|
421
|
+
end
|
317
422
|
|
318
423
|
when :generic
|
319
424
|
# Since this could be anything, the simulator will need to set this up. But, once it is, we can print it here.
|
@@ -359,6 +464,9 @@ module OrigenSim
|
|
359
464
|
|
360
465
|
fetch_simulation_objects
|
361
466
|
|
467
|
+
artifact.clean
|
468
|
+
artifact.populate
|
469
|
+
|
362
470
|
cmd = run_cmd + ' & echo \$!'
|
363
471
|
|
364
472
|
launch_simulator = %(
|
@@ -448,10 +556,10 @@ module OrigenSim
|
|
448
556
|
|
449
557
|
Origen.log.debug 'Starting the simulation monitor...'
|
450
558
|
|
451
|
-
|
452
|
-
Process.detach(
|
559
|
+
monitor_pid = spawn("ruby -e \"#{launch_simulator}\"")
|
560
|
+
Process.detach(monitor_pid)
|
453
561
|
|
454
|
-
simulation.open(config[:startup_timeout] || 60) # This will block until the simulation process has started
|
562
|
+
simulation.open(monitor_pid, config[:startup_timeout] || 60) # This will block until the simulation process has started
|
455
563
|
|
456
564
|
# The VPI extension will send 'READY!' when it starts, make sure we get it before proceeding
|
457
565
|
data = get
|
@@ -460,6 +568,8 @@ module OrigenSim
|
|
460
568
|
simulation.log_results
|
461
569
|
exit # Assume it is not worth trying another pattern in this case, some kind of environment/config issue
|
462
570
|
end
|
571
|
+
Origen.log.info "OrigenSim version #{Origen.app!.version}"
|
572
|
+
Origen.log.info "OrigenSim DUT version #{dut_version}"
|
463
573
|
# Tick the simulation on, this seems to be required since any VPI puts operations before
|
464
574
|
# the simulation has started are not applied.
|
465
575
|
# Note that this is not setting a tester timeset, so the application will still have to
|
@@ -472,6 +582,14 @@ module OrigenSim
|
|
472
582
|
# Send the given message string to the simulator
|
473
583
|
def put(msg)
|
474
584
|
simulation.socket.write(msg + "\n")
|
585
|
+
rescue Errno::EPIPE => e
|
586
|
+
if simulation.running?
|
587
|
+
Origen.log.error 'Communication with the simulator has been lost (though it seems to still be running)!'
|
588
|
+
else
|
589
|
+
Origen.log.error 'The simulator has stopped unexpectedly!'
|
590
|
+
end
|
591
|
+
sleep 2 # To make sure that any log output from the simulator is captured before we pull the plug
|
592
|
+
exit 1
|
475
593
|
end
|
476
594
|
|
477
595
|
# Get a message from the simulator, will block until one
|
@@ -536,11 +654,16 @@ module OrigenSim
|
|
536
654
|
end
|
537
655
|
end
|
538
656
|
|
539
|
-
def write_comment(comment)
|
657
|
+
def write_comment(line, comment)
|
658
|
+
return if line >= OrigenSim::NUMBER_OF_COMMENT_LINES
|
540
659
|
# Not sure what the limiting factor here is, the comment memory in the test bench should
|
541
660
|
# be able to handle 1024 / 8 length strings, but any bigger than this hangs the simulation
|
542
|
-
comment = comment[0..96]
|
543
|
-
|
661
|
+
comment = comment ? comment[0..96] : ''
|
662
|
+
if dut_version > '0.12.1'
|
663
|
+
put("c^#{line}^#{comment} ") # Space at the end is important so that an empty comment is communicated properly
|
664
|
+
else
|
665
|
+
put("c^#{comment} ")
|
666
|
+
end
|
544
667
|
end
|
545
668
|
|
546
669
|
# Applies the current state of all pins to the simulation
|
@@ -624,6 +747,17 @@ module OrigenSim
|
|
624
747
|
end
|
625
748
|
end
|
626
749
|
|
750
|
+
# Flush any buffered simulation output, this should cause live wave viewers to
|
751
|
+
# reflect the latest state
|
752
|
+
def flush
|
753
|
+
if dut_version > '0.12.0'
|
754
|
+
put('j^')
|
755
|
+
sync_up
|
756
|
+
else
|
757
|
+
OrigenSim.error "Use of flush requires a DUT model compiled with OrigenSim version > 0.12.0, the current dut was compiled with #{dut_version}"
|
758
|
+
end
|
759
|
+
end
|
760
|
+
|
627
761
|
def error(message)
|
628
762
|
simulation.logged_errors = true
|
629
763
|
Origen.log.error message
|
@@ -816,11 +950,29 @@ module OrigenSim
|
|
816
950
|
# Returns the version of Origen Sim that the current DUT object was compiled with
|
817
951
|
def dut_version
|
818
952
|
@dut_version ||= begin
|
819
|
-
|
820
|
-
|
953
|
+
# Allow configs to force a dut version, this is to allow backwards compatibility with very early
|
954
|
+
# compiled duts which do not support the command to get it from the compiled object
|
955
|
+
config[:dut_version] || begin
|
956
|
+
put('i^')
|
957
|
+
Origen::VersionString.new(get.strip)
|
958
|
+
end
|
821
959
|
end
|
822
960
|
end
|
823
961
|
|
962
|
+
# Any vectors executed within the given block will increment the match_errors counter
|
963
|
+
# rather than the errors counter.
|
964
|
+
# The match_errors counter will be returned to 0 at the end.
|
965
|
+
def match_loop
|
966
|
+
poke("#{testbench_top}.pins.match_loop", 1)
|
967
|
+
yield
|
968
|
+
poke("#{testbench_top}.pins.match_loop", 0)
|
969
|
+
poke("#{testbench_top}.pins.match_errors", 0)
|
970
|
+
end
|
971
|
+
|
972
|
+
def match_errors
|
973
|
+
peek("#{testbench_top}.pins.match_errors").to_i
|
974
|
+
end
|
975
|
+
|
824
976
|
private
|
825
977
|
|
826
978
|
# Pre 0.8.0 the simulator represented the time in ns instead of ps
|
@@ -830,7 +982,7 @@ module OrigenSim
|
|
830
982
|
|
831
983
|
def clean(net)
|
832
984
|
if net =~ /^dut\./
|
833
|
-
"
|
985
|
+
"#{testbench_top}.#{net}"
|
834
986
|
else
|
835
987
|
net
|
836
988
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'thread'
|
2
|
-
require 'io/wait'
|
3
2
|
module OrigenSim
|
4
3
|
class StderrReader < Thread
|
5
4
|
attr_reader :socket, :logged_errors
|
@@ -9,20 +8,27 @@ module OrigenSim
|
|
9
8
|
@continue = true
|
10
9
|
@logged_errors = false
|
11
10
|
super do
|
12
|
-
|
13
|
-
while @
|
14
|
-
line = @socket.gets
|
15
|
-
if
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
11
|
+
begin
|
12
|
+
while @continue
|
13
|
+
line = @socket.gets
|
14
|
+
if line
|
15
|
+
line = line.chomp
|
16
|
+
if OrigenSim.fail_on_stderr && !line.empty? &&
|
17
|
+
!OrigenSim.stderr_string_exceptions.any? { |s| s.is_a?(Regexp) ? s.match?(line) : line =~ /#{s}/i }
|
18
|
+
# We're failing on stderr, so print its results and log as errors if its not an exception.
|
19
|
+
@logged_errors = true
|
20
|
+
Origen.log.error "(STDERR): #{line}"
|
21
|
+
elsif OrigenSim.verbose?
|
22
|
+
Origen.log.info line
|
23
|
+
else
|
24
|
+
Origen.log.debug line
|
25
|
+
end
|
24
26
|
end
|
25
27
|
end
|
28
|
+
rescue IOError => e
|
29
|
+
unless e.message =~ /stream closed/
|
30
|
+
raise e
|
31
|
+
end
|
26
32
|
end
|
27
33
|
end
|
28
34
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'thread'
|
2
|
-
require 'io/wait'
|
3
2
|
module OrigenSim
|
4
3
|
class StdoutReader < Thread
|
5
4
|
attr_reader :socket, :logged_errors
|
@@ -9,25 +8,32 @@ module OrigenSim
|
|
9
8
|
@continue = true
|
10
9
|
@logged_errors = false
|
11
10
|
super do
|
12
|
-
|
13
|
-
while @
|
14
|
-
line = @socket.gets
|
15
|
-
if
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
OrigenSim.log_strings.any? { |s| line =~ /#{s}/ }
|
25
|
-
Origen.log.info line
|
11
|
+
begin
|
12
|
+
while @continue
|
13
|
+
line = @socket.gets
|
14
|
+
if line
|
15
|
+
line = line.chomp
|
16
|
+
if OrigenSim.error_strings.any? { |s| s.is_a?(Regexp) ? s.match?(line) : line =~ /#{s}/i } &&
|
17
|
+
!OrigenSim.error_string_exceptions.any? { |s| s.is_a?(Regexp) ? s.match?(line) : line =~ /#{s}/i }
|
18
|
+
@logged_errors = true
|
19
|
+
Origen.log.error "(STDOUT): #{line}"
|
20
|
+
elsif OrigenSim.warning_strings.any? { |s| s.is_a?(Regexp) ? s.match?(line) : line =~ /#{s}/i } &&
|
21
|
+
!OrigenSim.warning_string_exceptions.any? { |s| s.is_a?(Regexp) ? s.match?(line) : line =~ /#{s}/i }
|
22
|
+
Origen.log.warn line
|
26
23
|
else
|
27
|
-
|
24
|
+
if OrigenSim.verbose? ||
|
25
|
+
OrigenSim.log_strings.any? { |s| s.is_a?(Regexp) ? s.match?(line) : line =~ /#{s}/i }
|
26
|
+
Origen.log.info line
|
27
|
+
else
|
28
|
+
Origen.log.debug line
|
29
|
+
end
|
28
30
|
end
|
29
31
|
end
|
30
32
|
end
|
33
|
+
rescue IOError => e
|
34
|
+
unless e.message =~ /stream closed/
|
35
|
+
raise e
|
36
|
+
end
|
31
37
|
end
|
32
38
|
end
|
33
39
|
end
|