origen_sim 0.12.0 → 0.13.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 +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
|