origen_sim 0.5.5 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/config/application.rb +12 -1
- data/config/commands.rb +31 -10
- data/config/global_commands.rb +12 -0
- data/config/shared_commands.rb +11 -4
- data/config/version.rb +2 -2
- data/ext/bridge.c +18 -8
- data/ext/client.c +1 -1
- data/ext/defines.h.erb +6 -0
- data/ext/origen.c +6 -6
- data/lib/origen_sim/commands/build.rb +119 -81
- data/lib/origen_sim/commands/ci.rb +36 -0
- data/lib/origen_sim/commands/co.rb +36 -0
- data/lib/origen_sim/origen/pins/pin.rb +7 -13
- data/lib/origen_sim/origen_testers/api.rb +66 -0
- data/lib/origen_sim/simulator.rb +123 -43
- data/lib/origen_sim_dev/dut.rb +6 -4
- data/pattern/test.rb +28 -16
- data/templates/empty.gtkw +26 -0
- data/templates/rtl_v/origen.v.erb +10 -49
- metadata +24 -6
- data/ext/README.md +0 -2
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'origen/commands/helpers'
|
3
|
+
|
4
|
+
options = {}
|
5
|
+
|
6
|
+
# App options are options that the application can supply to extend this command
|
7
|
+
app_options = @application_options || []
|
8
|
+
opt_parser = OptionParser.new do |opts|
|
9
|
+
opts.banner = <<-EOT
|
10
|
+
Checkin the simulation object for the current or given environment/target.
|
11
|
+
|
12
|
+
Note that this will commit whatever is in your workspace as the latest version, regardless
|
13
|
+
of whether there exists any more recent version in the repository.
|
14
|
+
|
15
|
+
Usage: origen sim:ci [options]
|
16
|
+
EOT
|
17
|
+
opts.on('-e', '--environment NAME', String, 'Override the default environment, NAME can be a full path or a fragment of an environment file name') { |e| options[:environment] = e }
|
18
|
+
opts.on('-t', '--target NAME', String, 'Override the default target, NAME can be a full path or a fragment of a target file name') { |t| options[:target] = t }
|
19
|
+
opts.on('-d', '--debugger', 'Enable the debugger') { options[:debugger] = true }
|
20
|
+
# Apply any application option extensions to the OptionParser
|
21
|
+
opts.separator ''
|
22
|
+
opts.on('-h', '--help', 'Show this message') { puts opts; exit }
|
23
|
+
end
|
24
|
+
|
25
|
+
opt_parser.parse! ARGV
|
26
|
+
|
27
|
+
Origen.environment.temporary = options[:environment] if options[:environment]
|
28
|
+
Origen.target.temporary = options[:target] if options[:target]
|
29
|
+
Origen.load_target
|
30
|
+
|
31
|
+
unless tester.sim?
|
32
|
+
Origen.log.error 'To run the sim:ci command your target/environment must instantiate an OrigenSim::Tester'
|
33
|
+
exit 1
|
34
|
+
end
|
35
|
+
|
36
|
+
tester.simulator.commit_simulation_objects(options)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'origen/commands/helpers'
|
3
|
+
|
4
|
+
options = {}
|
5
|
+
|
6
|
+
# App options are options that the application can supply to extend this command
|
7
|
+
app_options = @application_options || []
|
8
|
+
opt_parser = OptionParser.new do |opts|
|
9
|
+
opts.banner = <<-EOT
|
10
|
+
Checkout the simulation object for the current or given environment/target.
|
11
|
+
|
12
|
+
Note that this will force a new checkout and will overwrite whatever is in your workspace.
|
13
|
+
|
14
|
+
Usage: origen sim:co [options]
|
15
|
+
EOT
|
16
|
+
opts.on('-e', '--environment NAME', String, 'Override the default environment, NAME can be a full path or a fragment of an environment file name') { |e| options[:environment] = e }
|
17
|
+
opts.on('-t', '--target NAME', String, 'Override the default target, NAME can be a full path or a fragment of a target file name') { |t| options[:target] = t }
|
18
|
+
opts.on('-d', '--debugger', 'Enable the debugger') { options[:debugger] = true }
|
19
|
+
# Apply any application option extensions to the OptionParser
|
20
|
+
opts.separator ''
|
21
|
+
opts.on('-h', '--help', 'Show this message') { puts opts; exit }
|
22
|
+
end
|
23
|
+
|
24
|
+
opt_parser.parse! ARGV
|
25
|
+
|
26
|
+
Origen.environment.temporary = options[:environment] if options[:environment]
|
27
|
+
Origen.target.temporary = options[:target] if options[:target]
|
28
|
+
Origen.load_target
|
29
|
+
|
30
|
+
unless tester.sim?
|
31
|
+
Origen.log.error 'To run the sim:co command your target/environment must instantiate an OrigenSim::Tester'
|
32
|
+
exit 1
|
33
|
+
end
|
34
|
+
|
35
|
+
options[:force] = true
|
36
|
+
tester.simulator.fetch_simulation_objects(options)
|
@@ -5,24 +5,12 @@ module Origen
|
|
5
5
|
class Pin
|
6
6
|
# The index number that is used to refer to the pin within the simulation
|
7
7
|
attr_accessor :simulation_index
|
8
|
-
# When generating a testbench the top-level signal will be tied off to the given
|
9
|
-
# logic level if this is set to 0 or 1
|
10
|
-
attr_accessor :tie_off
|
11
8
|
|
12
9
|
alias_method :_orig_initialize, :initialize
|
13
10
|
def initialize(id, owner, options = {})
|
14
|
-
@tie_off = options[:tie_off]
|
15
11
|
_orig_initialize(id, owner, options)
|
16
12
|
end
|
17
13
|
|
18
|
-
def rtl_name
|
19
|
-
if primary_group
|
20
|
-
(@rtl_name || primary_group.id).to_s
|
21
|
-
else
|
22
|
-
(@rtl_name || id).to_s
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
14
|
alias_method :_orig_set_value, :set_value
|
27
15
|
def set_value(val)
|
28
16
|
ret = _orig_set_value(val)
|
@@ -63,10 +51,16 @@ module Origen
|
|
63
51
|
@simulator_value = nil
|
64
52
|
end
|
65
53
|
|
54
|
+
def apply_force
|
55
|
+
if force
|
56
|
+
simulator.put("2^#{simulation_index}^#{force}")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
66
60
|
# Applies the current pin state to the simulation, this is triggered everytime
|
67
61
|
# the pin state or value changes
|
68
62
|
def update_simulation
|
69
|
-
return if
|
63
|
+
return if force || !simulation_index || !tester.timeset || !simulator_needs_update?
|
70
64
|
case state
|
71
65
|
when :drive
|
72
66
|
@simulator_state = :drive
|
@@ -7,5 +7,71 @@ module OrigenTesters
|
|
7
7
|
is_a?(OrigenSim::Tester)
|
8
8
|
end
|
9
9
|
alias_method :simulator?, :sim?
|
10
|
+
|
11
|
+
def sim_capture(id, *pins)
|
12
|
+
if @sim_capture
|
13
|
+
fail 'Nesting of sim_capture blocks is not yet supported!'
|
14
|
+
end
|
15
|
+
options = pins.last.is_a?(Hash) ? pins.pop : {}
|
16
|
+
pins = pins.map { |p| p.is_a?(String) || p.is_a?(Symbol) ? dut.pin(p) : p }
|
17
|
+
pins.each(&:save)
|
18
|
+
@sim_capture = pins.map { |p| [p, "origen.dut.#{p.rtl_name}"] }
|
19
|
+
Origen::OrgFile.open(id) do |org_file|
|
20
|
+
@org_file = org_file
|
21
|
+
if update_capture?
|
22
|
+
@sim_capture.each { |pin, net| pin.record_to_org_file(only: :assert) }
|
23
|
+
end
|
24
|
+
yield
|
25
|
+
end
|
26
|
+
pins.each(&:restore)
|
27
|
+
@sim_capture = nil
|
28
|
+
end
|
29
|
+
|
30
|
+
alias_method :_origen_testers_cycle, :cycle
|
31
|
+
def cycle(options = {})
|
32
|
+
if @sim_capture
|
33
|
+
# Need to un-roll all repeats to be sure we observe the true data, can't
|
34
|
+
# really assume that it will be constant for all cycles covered by the repeat
|
35
|
+
cycles = options.delete(:repeat) || 1
|
36
|
+
cycles.times do
|
37
|
+
if update_capture?
|
38
|
+
_origen_testers_cycle(options)
|
39
|
+
@sim_capture.each do |pin, net|
|
40
|
+
pin.assert(simulator.peek(net))
|
41
|
+
# Remove the assertion since it is for the previous cycle in terms of the current simulation,
|
42
|
+
# this won't be captured to the org file
|
43
|
+
pin.dont_care
|
44
|
+
end
|
45
|
+
Origen::OrgFile.cycle
|
46
|
+
else
|
47
|
+
unless @org_file.exist?
|
48
|
+
fail "The simulation capture \"#{id}\" has not been made yet, re-run this pattern with a simulation target first!"
|
49
|
+
end
|
50
|
+
apply_captured_data
|
51
|
+
_origen_testers_cycle(options)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
else
|
55
|
+
_origen_testers_cycle(options)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def apply_captured_data
|
60
|
+
if @apply_captured_data_cycles && @apply_captured_data_cycles > 1
|
61
|
+
@apply_captured_data_cycles -= 1
|
62
|
+
else
|
63
|
+
@org_file.read_line do |operations, cycles|
|
64
|
+
@apply_captured_data_cycles = cycles
|
65
|
+
operations.each do |object, operation, *args|
|
66
|
+
object.send(operation, *args)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def update_capture?
|
73
|
+
return @update_capture if defined? @update_capture
|
74
|
+
@update_capture = sim? && (!@org_file.exist? || Origen.app!.update_sim_captures)
|
75
|
+
end
|
10
76
|
end
|
11
77
|
end
|
data/lib/origen_sim/simulator.rb
CHANGED
@@ -22,14 +22,72 @@ module OrigenSim
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
def fetch_simulation_objects(options = {})
|
26
|
+
sid = options[:id] || id
|
27
|
+
ldir = "#{Origen.root}/simulation/#{sid}"
|
28
|
+
tmp_dir = "#{Origen.root}/tmp/origen_sim/tmp"
|
29
|
+
if config[:rc_dir_url]
|
30
|
+
unless config[:rc_version]
|
31
|
+
puts "You must supply an :rc_version option when using :rc_dir_url (you can set this to something like 'Trunk' or 'master' if you want)"
|
32
|
+
exit 1
|
33
|
+
end
|
34
|
+
if !File.exist?(compiled_dir) ||
|
35
|
+
(File.exist?(compiled_dir) && Dir.entries(compiled_dir).size <= 2) ||
|
36
|
+
(Origen.app.session.origen_sim[sid] != config[:rc_version]) ||
|
37
|
+
options[:force]
|
38
|
+
Origen.log.info "Fetching the simulation object for #{sid}..."
|
39
|
+
Origen.app.session.origen_sim[sid] = nil # Clear this up front, if the checkout fails we won't know what we have
|
40
|
+
FileUtils.rm_rf(tmp_dir) if File.exist?(tmp_dir)
|
41
|
+
FileUtils.mkdir_p(tmp_dir)
|
42
|
+
FileUtils.mkdir_p("#{Origen.root}/simulation")
|
43
|
+
rc = Origen::RevisionControl.new remote: config[:rc_dir_url], local: tmp_dir
|
44
|
+
rc.checkout "#{sid}.tar.gz", force: true, version: config[:rc_version]
|
45
|
+
FileUtils.mv "#{tmp_dir}/#{sid}.tar.gz", "#{Origen.root}/simulation"
|
46
|
+
FileUtils.rm_rf(ldir) if File.exist?(ldir)
|
47
|
+
Dir.chdir "#{Origen.root}/simulation/" do
|
48
|
+
system "tar -xvf #{sid}.tar.gz"
|
49
|
+
end
|
50
|
+
Origen.app.session.origen_sim[sid] = config[:rc_version]
|
51
|
+
end
|
52
|
+
else
|
53
|
+
if !File.exist?(compiled_dir) ||
|
54
|
+
(File.exist?(compiled_dir) && Dir.entries(compiled_dir).size <= 2)
|
55
|
+
puts "There is no previously compiled simulation object in: #{compiled_dir}"
|
56
|
+
exit 1
|
57
|
+
end
|
58
|
+
end
|
59
|
+
ensure
|
60
|
+
FileUtils.rm_f "#{ldir}.tar.gz" if File.exist?("#{ldir}.tar.gz")
|
61
|
+
FileUtils.rm_rf tmp_dir if File.exist?(tmp_dir)
|
62
|
+
end
|
63
|
+
|
64
|
+
def commit_simulation_objects(options = {})
|
65
|
+
sid = options[:id] || id
|
66
|
+
ldir = "#{Origen.root}/simulation/#{sid}"
|
67
|
+
tmp_dir = "#{Origen.root}/tmp/origen_sim/tmp"
|
68
|
+
unless File.exist?(ldir)
|
69
|
+
fail "The simulation directory to check in does not exist: #{ldir}"
|
70
|
+
end
|
71
|
+
Dir.chdir "#{Origen.root}/simulation/" do
|
72
|
+
system "tar -cvzf #{sid}.tar.gz #{sid}"
|
73
|
+
end
|
74
|
+
|
75
|
+
FileUtils.rm_rf(tmp_dir) if File.exist?(tmp_dir)
|
76
|
+
FileUtils.mkdir_p(tmp_dir)
|
77
|
+
FileUtils.cp "#{ldir}.tar.gz", tmp_dir
|
78
|
+
|
79
|
+
rc = Origen::RevisionControl.new remote: config[:rc_dir_url], local: tmp_dir
|
80
|
+
rc.checkin "#{sid}.tar.gz", unmanaged: true, force: true, comment: 'Checked in via sim:rc command'
|
81
|
+
ensure
|
82
|
+
FileUtils.rm_f "#{ldir}.tar.gz" if File.exist?("#{ldir}.tar.gz")
|
83
|
+
FileUtils.rm_rf tmp_dir if File.exist?(tmp_dir)
|
84
|
+
end
|
85
|
+
|
25
86
|
def configure(options)
|
26
87
|
fail 'A vendor must be supplied, e.g. OrigenSim::Tester.new(vendor: :icarus)' unless options[:vendor]
|
27
88
|
unless VENDORS.include?(options[:vendor])
|
28
89
|
fail "Unknown vendor #{options[:vendor]}, valid values are: #{VENDORS.map { |v| ':' + v.to_s }.join(', ')}"
|
29
90
|
end
|
30
|
-
unless options[:rtl_top]
|
31
|
-
fail "The name of the file containing the DUT top-level must be supplied, e.g. OrigenSim::Tester.new(rtl_top: 'my_ip')" unless options[:rtl_top]
|
32
|
-
end
|
33
91
|
@configuration = options
|
34
92
|
@tmp_dir = nil
|
35
93
|
end
|
@@ -49,14 +107,6 @@ module OrigenSim
|
|
49
107
|
end
|
50
108
|
end
|
51
109
|
|
52
|
-
def artifacts_dir
|
53
|
-
@artifacts_dir ||= begin
|
54
|
-
d = "#{Origen.root}/simulation/#{id}/artifacts"
|
55
|
-
FileUtils.mkdir_p(d)
|
56
|
-
d
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
110
|
# Returns the directory where the compiled simulation object lives, this should
|
61
111
|
# be checked into your Origen app's repository
|
62
112
|
def compiled_dir
|
@@ -93,20 +143,20 @@ module OrigenSim
|
|
93
143
|
|
94
144
|
def wave_config_file
|
95
145
|
@wave_config_file ||= begin
|
96
|
-
f = "#{wave_config_dir}/#{User.current.id}
|
146
|
+
f = "#{wave_config_dir}/#{User.current.id}.#{wave_config_ext}"
|
97
147
|
unless File.exist?(f)
|
98
148
|
# Take a default wave if one has been set up
|
99
|
-
d = "#{wave_config_dir}/default
|
149
|
+
d = "#{wave_config_dir}/default.#{wave_config_ext}"
|
100
150
|
if File.exist?(d)
|
101
151
|
FileUtils.cp(d, f)
|
102
152
|
else
|
103
153
|
# Otherwise seed it with the latest existing setup by someone else
|
104
|
-
d = Dir.glob("#{wave_config_dir}
|
154
|
+
d = Dir.glob("#{wave_config_dir}/*.#{wave_config_ext}").max { |a, b| File.ctime(a) <=> File.ctime(b) }
|
105
155
|
if d
|
106
156
|
FileUtils.cp(d, f)
|
107
157
|
else
|
108
158
|
# We tried our best, start from scratch
|
109
|
-
d = "#{Origen.root!}/templates/empty
|
159
|
+
d = "#{Origen.root!}/templates/empty.#{wave_config_ext}"
|
110
160
|
FileUtils.cp(d, f)
|
111
161
|
end
|
112
162
|
end
|
@@ -115,15 +165,24 @@ module OrigenSim
|
|
115
165
|
end
|
116
166
|
end
|
117
167
|
|
168
|
+
def wave_config_ext
|
169
|
+
case config[:vendor]
|
170
|
+
when :icarus
|
171
|
+
'gtkw'
|
172
|
+
when :cadence
|
173
|
+
'svcf'
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
118
177
|
def run_cmd
|
119
178
|
case config[:vendor]
|
120
179
|
when :icarus
|
121
180
|
cmd = configuration[:vvp] || 'vvp'
|
122
|
-
cmd += " -M#{compiled_dir} -morigen #{compiled_dir}/
|
181
|
+
cmd += " -M#{compiled_dir} -morigen #{compiled_dir}/origen.vvp +socket+#{socket_id}"
|
123
182
|
|
124
183
|
when :cadence
|
125
184
|
input_file = "#{tmp_dir}/#{id}.tcl"
|
126
|
-
|
185
|
+
if !File.exist?(input_file) || config_changed?
|
127
186
|
Origen.app.runner.launch action: :compile,
|
128
187
|
files: "#{Origen.root!}/templates/probe.tcl.erb",
|
129
188
|
output: tmp_dir,
|
@@ -133,7 +192,7 @@ module OrigenSim
|
|
133
192
|
output_file_name: "#{id}.tcl"
|
134
193
|
end
|
135
194
|
input_file_fast = "#{tmp_dir}/#{id}_fast.tcl"
|
136
|
-
if
|
195
|
+
if !File.exist?(input_file_fast) || config_changed?
|
137
196
|
fast_probe_depth = config[:fast_probe_depth] || 1
|
138
197
|
Origen.app.runner.launch action: :compile,
|
139
198
|
files: "#{Origen.root!}/templates/probe.tcl.erb",
|
@@ -143,8 +202,8 @@ module OrigenSim
|
|
143
202
|
options: { dir: wave_dir, force: config[:force], setup: config[:setup], depth: fast_probe_depth },
|
144
203
|
output_file_name: "#{id}_fast.tcl"
|
145
204
|
end
|
146
|
-
|
147
|
-
# input file is already generated
|
205
|
+
save_config_signature
|
206
|
+
wave_dir # Ensure this exists since it won't be referenced above if the input file is already generated
|
148
207
|
|
149
208
|
cmd = configuration[:irun] || 'irun'
|
150
209
|
cmd += " -r origen -snapshot origen +socket+#{socket_id}"
|
@@ -157,6 +216,15 @@ module OrigenSim
|
|
157
216
|
def view_wave_command
|
158
217
|
cmd = nil
|
159
218
|
case config[:vendor]
|
219
|
+
when :icarus
|
220
|
+
edir = Pathname.new(wave_config_dir).relative_path_from(Pathname.pwd)
|
221
|
+
cmd = "cd #{edir} && "
|
222
|
+
cmd += configuration[:gtkwave] || 'gtkwave'
|
223
|
+
dir = Pathname.new(wave_dir).relative_path_from(edir.expand_path)
|
224
|
+
cmd += " #{dir}/origen.vcd "
|
225
|
+
f = Pathname.new(wave_config_file).relative_path_from(edir.expand_path)
|
226
|
+
cmd += " --save #{f} &"
|
227
|
+
|
160
228
|
when :cadence
|
161
229
|
edir = Pathname.new(wave_config_dir).relative_path_from(Pathname.pwd)
|
162
230
|
cmd = "cd #{edir} && "
|
@@ -165,6 +233,7 @@ module OrigenSim
|
|
165
233
|
cmd += " #{dir}/#{id}.dsn #{dir}/#{id}.trn"
|
166
234
|
f = Pathname.new(wave_config_file).relative_path_from(edir.expand_path)
|
167
235
|
cmd += " -input #{f} &"
|
236
|
+
|
168
237
|
end
|
169
238
|
cmd
|
170
239
|
end
|
@@ -178,22 +247,12 @@ module OrigenSim
|
|
178
247
|
end
|
179
248
|
end
|
180
249
|
|
181
|
-
def link_artifacts
|
182
|
-
done = "#{run_dir}/.artifacts_linked"
|
183
|
-
unless File.exist?(done)
|
184
|
-
Dir.foreach(artifacts_dir) do |item|
|
185
|
-
next if item == '.' || item == '..'
|
186
|
-
FileUtils.ln_s("#{artifacts_dir}/#{item}", "#{run_dir}/#{item}") unless File.exist?("#{run_dir}/#{item}")
|
187
|
-
end
|
188
|
-
FileUtils.touch(done)
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
250
|
# Starts up the simulator process
|
193
251
|
def start
|
252
|
+
fetch_simulation_objects
|
253
|
+
|
194
254
|
server = UNIXServer.new(socket_id)
|
195
255
|
verbose = Origen.debugger_enabled?
|
196
|
-
link_artifacts
|
197
256
|
cmd = run_cmd + ' & echo \$!'
|
198
257
|
|
199
258
|
launch_simulator = %(
|
@@ -224,7 +283,7 @@ module OrigenSim
|
|
224
283
|
simulator_parent_process = spawn("ruby -e \"#{launch_simulator}\"")
|
225
284
|
Process.detach(simulator_parent_process)
|
226
285
|
|
227
|
-
timeout_connection(config[:startup_timeout] ||
|
286
|
+
timeout_connection(config[:startup_timeout] || 60) do
|
228
287
|
@socket = server.accept
|
229
288
|
@connection_established = true
|
230
289
|
if @connection_timed_out
|
@@ -350,10 +409,11 @@ module OrigenSim
|
|
350
409
|
# set up internal handles to efficiently access them
|
351
410
|
def define_pins
|
352
411
|
dut.rtl_pins.each_with_index do |(name, pin), i|
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
412
|
+
pin.simulation_index = i
|
413
|
+
put("0^#{pin.rtl_name}^#{i}^#{pin.drive_wave.index}^#{pin.compare_wave.index}")
|
414
|
+
end
|
415
|
+
dut.rtl_pins.each do |name, pin|
|
416
|
+
pin.apply_force
|
357
417
|
end
|
358
418
|
end
|
359
419
|
|
@@ -407,11 +467,13 @@ module OrigenSim
|
|
407
467
|
|
408
468
|
# Returns the current simulation error count
|
409
469
|
def error_count
|
410
|
-
peek('origen.debug.errors')
|
470
|
+
peek('origen.debug.errors').to_i
|
411
471
|
end
|
412
472
|
|
413
473
|
# Returns the current value of the given net, or nil if the given path does not
|
414
474
|
# resolve to a valid node
|
475
|
+
#
|
476
|
+
# The value is returned as an instance of Origen::Value
|
415
477
|
def peek(net)
|
416
478
|
# The Verilog spec does not specify that underlying VPI put method should
|
417
479
|
# handle a part select, so some simulators do not handle it. Therefore we
|
@@ -427,21 +489,20 @@ module OrigenSim
|
|
427
489
|
|
428
490
|
sync_up
|
429
491
|
put("9^#{clean(net)}")
|
430
|
-
|
431
492
|
m = get.strip
|
493
|
+
|
432
494
|
if m == 'FAIL'
|
433
495
|
return nil
|
434
496
|
else
|
435
|
-
m = m.to_i
|
436
497
|
if msb
|
437
498
|
# Setting a range of bits
|
438
499
|
if lsb
|
439
|
-
m[msb..lsb]
|
500
|
+
Origen::Value.new('b' + m[(m.size - 1 - msb)..(m.size - 1 - lsb)])
|
440
501
|
else
|
441
|
-
m[msb]
|
502
|
+
Origen::Value.new('b' + m[m.size - 1 - msb])
|
442
503
|
end
|
443
504
|
else
|
444
|
-
m
|
505
|
+
Origen::Value.new('b' + m)
|
445
506
|
end
|
446
507
|
end
|
447
508
|
end
|
@@ -587,6 +648,25 @@ module OrigenSim
|
|
587
648
|
@sync_active
|
588
649
|
end
|
589
650
|
|
651
|
+
# Returns true if the config has been changed since the last time we called save_config_signature
|
652
|
+
def config_changed?
|
653
|
+
Origen.app.session.origen_sim["#{id}_config"] != config
|
654
|
+
end
|
655
|
+
|
656
|
+
# Locally saves a signature for the current config, this will cause config_changed? to return false
|
657
|
+
# until its contents change
|
658
|
+
def save_config_signature
|
659
|
+
Origen.app.session.origen_sim["#{id}_config"] = config
|
660
|
+
end
|
661
|
+
|
662
|
+
# Returns the version of Origen Sim that the current DUT object was compiled with
|
663
|
+
def dut_version
|
664
|
+
@dut_version ||= begin
|
665
|
+
put('i^')
|
666
|
+
Origen::VersionString.new(get.strip)
|
667
|
+
end
|
668
|
+
end
|
669
|
+
|
590
670
|
private
|
591
671
|
|
592
672
|
def clean(net)
|