origen 0.28.2 → 0.29.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/origen +14 -2
- data/config/version.rb +2 -2
- data/lib/origen.rb +72 -45
- data/lib/origen/application.rb +29 -19
- data/lib/origen/application/deployer.rb +3 -1
- data/lib/origen/application/runner.rb +10 -8
- data/lib/origen/chip_mode.rb +1 -1
- data/lib/origen/commands.rb +24 -12
- data/lib/origen/commands/version.rb +1 -1
- data/lib/origen/commands_global.rb +32 -8
- data/lib/origen/core_ext.rb +1 -2
- data/lib/origen/core_ext/enumerable.rb +2 -2
- data/lib/origen/core_ext/integer.rb +85 -0
- data/lib/origen/core_ext/numeric.rb +28 -4
- data/lib/origen/global_app.rb +9 -0
- data/lib/origen/log.rb +1 -1
- data/lib/origen/model_initializer.rb +6 -1
- data/lib/origen/netlist/list.rb +2 -2
- data/lib/origen/org_file.rb +125 -0
- data/lib/origen/org_file/interceptable.rb +44 -0
- data/lib/origen/org_file/interceptor.rb +100 -0
- data/lib/origen/parameters/set.rb +1 -1
- data/lib/origen/pins.rb +4 -0
- data/lib/origen/pins/function_proxy.rb +8 -0
- data/lib/origen/pins/pin.rb +90 -38
- data/lib/origen/pins/pin_collection.rb +61 -21
- data/lib/origen/ports/port.rb +1 -1
- data/lib/origen/registers.rb +1 -1
- data/lib/origen/registers/reg.rb +1 -1
- data/lib/origen/remote_manager.rb +25 -15
- data/lib/origen/site_config.rb +140 -13
- data/lib/origen/specs/checkers.rb +2 -2
- data/lib/origen/sub_blocks.rb +6 -1
- data/lib/origen/value.rb +119 -0
- data/lib/origen/value/bin_str_val.rb +72 -0
- data/lib/origen/value/hex_str_val.rb +100 -0
- data/origen_site_config.yml +15 -8
- metadata +12 -6
- data/lib/origen/core_ext/bignum.rb +0 -38
- data/lib/origen/core_ext/fixnum.rb +0 -56
data/lib/origen/pins.rb
CHANGED
@@ -227,8 +227,12 @@ module Origen
|
|
227
227
|
name: ''
|
228
228
|
}.merge(options)
|
229
229
|
|
230
|
+
rtl_name = options[:rtl_name]
|
231
|
+
force = options[:force]
|
230
232
|
options.delete(:size).times do |i|
|
231
233
|
options[:name] = "#{id}#{i}".to_sym
|
234
|
+
options[:rtl_name] = "#{rtl_name}#{i}".to_sym if rtl_name
|
235
|
+
options[:force] = force[i] if force
|
232
236
|
|
233
237
|
if power_pin
|
234
238
|
group[i] = PowerPin.new(i, self, options)
|
@@ -16,6 +16,14 @@ module Origen
|
|
16
16
|
@pin
|
17
17
|
end
|
18
18
|
|
19
|
+
# @api private
|
20
|
+
#
|
21
|
+
# To play nicely with == when a function proxy is wrapping a pin that is already
|
22
|
+
# wrapped by an OrgFile interceptor
|
23
|
+
def __object__
|
24
|
+
@pin.__object__
|
25
|
+
end
|
26
|
+
|
19
27
|
# Intercept all calls to function-scoped attributes of the pin so
|
20
28
|
# that we can inject the function that we want the attribute value for
|
21
29
|
Pin::FUNCTION_SCOPED_ATTRIBUTES.each do |attribute|
|
data/lib/origen/pins/pin.rb
CHANGED
@@ -2,6 +2,17 @@ module Origen
|
|
2
2
|
module Pins
|
3
3
|
class Pin
|
4
4
|
include PinCommon
|
5
|
+
include OrgFile::Interceptable
|
6
|
+
|
7
|
+
# Don't include the ! method in here, the cycle will be captured at the tester level and
|
8
|
+
# it would cause a double cycle in the org file if also captured at the pin
|
9
|
+
ORG_FILE_INTERCEPTED_METHODS = [
|
10
|
+
:suspend, :resume, :repeat_previous=,
|
11
|
+
:drive_hi, :drive_hi, :drive_very_hi, :drive_lo, :drive_lo, :drive_mem, :expect_mem,
|
12
|
+
:assert_hi, :expect_hi, :compare_hi, :assert_lo, :expect_lo, :compare_lo, :dont_care,
|
13
|
+
:drive, :assert, :compare, :expect, :assert_midband, :compare_midband, :expect_midband,
|
14
|
+
:toggle, :capture, :store
|
15
|
+
]
|
5
16
|
|
6
17
|
# Any attributes listed here will be looked up for the current function defined
|
7
18
|
# by the current mode and configuration context before falling back to a default
|
@@ -37,8 +48,10 @@ module Origen
|
|
37
48
|
attr_accessor :ext_pulldown
|
38
49
|
# Pin type, either :analog or :digital
|
39
50
|
attr_accessor :type
|
40
|
-
# Pin RTL name
|
51
|
+
# Pin RTL name
|
41
52
|
attr_accessor :rtl_name
|
53
|
+
# Value to be forced on the pin, e.g. during simulation
|
54
|
+
attr_accessor :force
|
42
55
|
|
43
56
|
attr_accessor :description
|
44
57
|
attr_accessor :notes
|
@@ -59,6 +72,7 @@ module Origen
|
|
59
72
|
@direction = sanitize_direction(options[:direction])
|
60
73
|
@invert = options[:invert]
|
61
74
|
@reset = options[:reset]
|
75
|
+
@force = options[:force] & 1
|
62
76
|
@id = id
|
63
77
|
@name = options[:name]
|
64
78
|
@rtl_name = options[:rtl_name]
|
@@ -75,11 +89,24 @@ module Origen
|
|
75
89
|
@clock = nil
|
76
90
|
@meta = options[:meta] || {}
|
77
91
|
@dib_meta = options[:dib_meta] || {}
|
92
|
+
@_saved_state = []
|
93
|
+
@_saved_value = []
|
94
|
+
@_saved_suspend = []
|
95
|
+
@_saved_invert = []
|
96
|
+
@_saved_repeat_previous = []
|
78
97
|
on_init(owner, options)
|
79
98
|
# Assign the initial state from the method so that any inversion is picked up...
|
80
99
|
send(@reset)
|
81
100
|
end
|
82
101
|
|
102
|
+
def global_path_to
|
103
|
+
"dut.pins(:#{id})"
|
104
|
+
end
|
105
|
+
|
106
|
+
def org_file_intercepted_methods
|
107
|
+
ORG_FILE_INTERCEPTED_METHODS
|
108
|
+
end
|
109
|
+
|
83
110
|
# Returns the drive cycle wave assigned to the pin based on the currently enabled timeset,
|
84
111
|
# or nil if none is set.
|
85
112
|
# Note that if a timeset is set then all pins will always return a wave as they will pick
|
@@ -90,7 +117,7 @@ module Origen
|
|
90
117
|
# every cycle in some applications
|
91
118
|
@drive_waves ||= {}
|
92
119
|
@drive_waves[t.id] ||= {}
|
93
|
-
@drive_waves[t.id][code] ||= dut.current_timeset.send(:wave_for,
|
120
|
+
@drive_waves[t.id][code] ||= dut.current_timeset.send(:wave_for, myself, type: :drive, code: code)
|
94
121
|
end
|
95
122
|
end
|
96
123
|
|
@@ -104,7 +131,15 @@ module Origen
|
|
104
131
|
# every cycle in some applications
|
105
132
|
@compare_waves ||= {}
|
106
133
|
@compare_waves[t.id] ||= {}
|
107
|
-
@compare_waves[t.id][code] ||= dut.current_timeset.send(:wave_for,
|
134
|
+
@compare_waves[t.id][code] ||= dut.current_timeset.send(:wave_for, myself, type: :compare, code: code)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def rtl_name
|
139
|
+
if primary_group
|
140
|
+
(@rtl_name || "#{primary_group.id}#{primary_group_index}").to_s
|
141
|
+
else
|
142
|
+
(@rtl_name || id).to_s
|
108
143
|
end
|
109
144
|
end
|
110
145
|
|
@@ -123,7 +158,7 @@ module Origen
|
|
123
158
|
def hello
|
124
159
|
drive_hi
|
125
160
|
@@hello_pins ||= []
|
126
|
-
@@hello_pins <<
|
161
|
+
@@hello_pins << myself unless @@hello_pins.include?(myself)
|
127
162
|
@@hello_loop ||= Thread.new do
|
128
163
|
loop do
|
129
164
|
@@hello_pins.each(&:toggle)
|
@@ -141,7 +176,7 @@ module Origen
|
|
141
176
|
|
142
177
|
# See Pin#hello
|
143
178
|
def goodbye
|
144
|
-
@@hello_pins.delete(
|
179
|
+
@@hello_pins.delete(myself)
|
145
180
|
puts "Pin #{name} has stopped toggling"
|
146
181
|
end
|
147
182
|
|
@@ -244,7 +279,7 @@ module Origen
|
|
244
279
|
# pin.expect_lo
|
245
280
|
# pin.to_vector # => "L"
|
246
281
|
def to_vector
|
247
|
-
@vector_formatted_value ||= Origen.tester.format_pin_state(
|
282
|
+
@vector_formatted_value ||= Origen.tester.format_pin_state(myself)
|
248
283
|
end
|
249
284
|
|
250
285
|
# @api private
|
@@ -266,13 +301,13 @@ module Origen
|
|
266
301
|
# pin.value # => 1
|
267
302
|
def vector_formatted_value=(val)
|
268
303
|
unless @vector_formatted_value == val
|
269
|
-
Origen.tester.update_pin_from_formatted_state(
|
304
|
+
Origen.tester.update_pin_from_formatted_state(myself, val)
|
270
305
|
@vector_formatted_value = val
|
271
306
|
end
|
272
307
|
end
|
273
308
|
|
274
309
|
def inspect
|
275
|
-
"<#{
|
310
|
+
"<#{myself.class}:#{object_id}>"
|
276
311
|
end
|
277
312
|
|
278
313
|
def describe(options = {})
|
@@ -368,7 +403,7 @@ module Origen
|
|
368
403
|
def groups
|
369
404
|
# Origen.pin_bank.all_pin_groups.select do |name, group|
|
370
405
|
@groups ||= Origen.pin_bank.pin_groups.select do |_name, group|
|
371
|
-
group.include?(
|
406
|
+
group.include?(myself)
|
372
407
|
end
|
373
408
|
end
|
374
409
|
alias_method :pin_groups, :groups
|
@@ -391,8 +426,8 @@ module Origen
|
|
391
426
|
else
|
392
427
|
packages.each do |package_id|
|
393
428
|
package_id = package_id.respond_to?(:id) ? package_id.id : package_id
|
394
|
-
|
395
|
-
|
429
|
+
myself.packages[package_id] ||= {}
|
430
|
+
myself.packages[package_id][:location] = str
|
396
431
|
add_alias str.to_s.symbolize, package: package_id, mode: :all, configuration: :all
|
397
432
|
end
|
398
433
|
end
|
@@ -412,9 +447,9 @@ module Origen
|
|
412
447
|
else
|
413
448
|
packages.each do |package_id|
|
414
449
|
package_id = package_id.respond_to?(:id) ? package_id.id : package_id
|
415
|
-
|
416
|
-
|
417
|
-
|
450
|
+
myself.packages[package_id] ||= {}
|
451
|
+
myself.packages[package_id][:dib_assignment] ||= []
|
452
|
+
myself.packages[package_id][:dib_assignment][options[:site]] = str
|
418
453
|
add_alias str.to_s.symbolize, package: package_id, mode: :all, configuration: :all
|
419
454
|
end
|
420
455
|
end
|
@@ -468,7 +503,7 @@ module Origen
|
|
468
503
|
def add_function(id, options = {})
|
469
504
|
id = id.to_sym
|
470
505
|
add_function_attributes(options.merge(name: id, id: id.to_sym))
|
471
|
-
f = FunctionProxy.new(id,
|
506
|
+
f = FunctionProxy.new(id, myself)
|
472
507
|
add_alias id, packages: :all, obj: f
|
473
508
|
end
|
474
509
|
|
@@ -510,7 +545,7 @@ module Origen
|
|
510
545
|
# If the options contain a package, mode or configuration reference then the alias
|
511
546
|
# will only work under that context.
|
512
547
|
def add_alias(id, options = {})
|
513
|
-
obj = options.delete(:obj) ||
|
548
|
+
obj = options.delete(:obj) || myself
|
514
549
|
if aliases[id]
|
515
550
|
aliases[id][:packages] += resolve_packages(options)
|
516
551
|
aliases[id][:modes] += resolve_modes(options)
|
@@ -556,7 +591,7 @@ module Origen
|
|
556
591
|
# Returns true if the pin is an alias of the given pin name
|
557
592
|
def is_alias_of?(name)
|
558
593
|
if Origen.pin_bank.find(name)
|
559
|
-
Origen.pin_bank.find(name).id == Origen.pin_bank.find(
|
594
|
+
Origen.pin_bank.find(name).id == Origen.pin_bank.find(myself).id
|
560
595
|
else
|
561
596
|
false
|
562
597
|
end
|
@@ -610,18 +645,32 @@ module Origen
|
|
610
645
|
end
|
611
646
|
|
612
647
|
def set_value(val)
|
648
|
+
orig = val
|
613
649
|
invalidate_vector_cache
|
614
650
|
if val.is_a?(String) || val.is_a?(Symbol)
|
615
|
-
|
651
|
+
val = val.to_s
|
652
|
+
if val =~ /^(b|h).+/
|
653
|
+
val = Origen::Value.new(val)
|
654
|
+
else
|
655
|
+
@vector_formatted_value = val
|
656
|
+
return
|
657
|
+
end
|
658
|
+
end
|
659
|
+
if val.is_a?(Origen::Value)
|
660
|
+
val = val[0]
|
616
661
|
else
|
617
662
|
# If val is a data bit extract the value of it
|
618
663
|
val = val.respond_to?(:data) ? val.data : val
|
619
664
|
# Assume driving/asserting a nil value means 0
|
620
665
|
val = 0 unless val
|
621
|
-
if val > 1
|
666
|
+
if !val.x_or_z? && val > 1
|
622
667
|
fail "Attempt to set a value of #{val} on pin #{name}"
|
623
668
|
end
|
624
|
-
|
669
|
+
end
|
670
|
+
@repeat_previous = false
|
671
|
+
if val.x_or_z?
|
672
|
+
dont_care
|
673
|
+
else
|
625
674
|
if inverted?
|
626
675
|
@value = val == 0 ? 1 : 0
|
627
676
|
else
|
@@ -719,9 +768,9 @@ module Origen
|
|
719
768
|
# options = { :active => false #if active true means to take tester active load capability into account
|
720
769
|
# }.merge(options)
|
721
770
|
# unless state_to_be_inverted?
|
722
|
-
#
|
771
|
+
# myself.state = ($tester.active_loads || !options[:active]) ? $tester.pin_state(:expect_lo) : $tester.pin_state(:dont_care)
|
723
772
|
# else
|
724
|
-
#
|
773
|
+
# myself.state = ($tester.active_loads || !options[:active]) ? $tester.pin_state(:expect_hi) : $tester.pin_state(:dont_care)
|
725
774
|
# end
|
726
775
|
end
|
727
776
|
alias_method :expect_lo, :assert_lo
|
@@ -881,21 +930,24 @@ module Origen
|
|
881
930
|
restore
|
882
931
|
end
|
883
932
|
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
@
|
888
|
-
@
|
889
|
-
@
|
933
|
+
# Saves the current state of the pin, allowing it to be restored to the
|
934
|
+
# current state by calling the restore method
|
935
|
+
def save
|
936
|
+
@_saved_state << @state
|
937
|
+
@_saved_value << @value
|
938
|
+
@_saved_suspend << @suspend
|
939
|
+
@_saved_invert << @invert
|
940
|
+
@_saved_repeat_previous << @repeat_previous
|
890
941
|
end
|
891
942
|
|
892
|
-
|
943
|
+
# Restores the state of the pin to the last time save was called
|
944
|
+
def restore
|
893
945
|
invalidate_vector_cache
|
894
|
-
@state = @_saved_state
|
895
|
-
@value = @_saved_value
|
896
|
-
@suspend = @_saved_suspend
|
897
|
-
@invert = @_saved_invert
|
898
|
-
@repeat_previous = @_saved_repeat_previous
|
946
|
+
@state = @_saved_state.pop
|
947
|
+
@value = @_saved_value.pop
|
948
|
+
@suspend = @_saved_suspend.pop
|
949
|
+
@invert = @_saved_invert.pop
|
950
|
+
@repeat_previous = @_saved_repeat_previous.pop
|
899
951
|
end
|
900
952
|
|
901
953
|
def is_not_a_clock?
|
@@ -911,7 +963,7 @@ module Origen
|
|
911
963
|
end
|
912
964
|
|
913
965
|
def enable_clock(options = {})
|
914
|
-
@clock = PinClock.new(
|
966
|
+
@clock = PinClock.new(myself, options)
|
915
967
|
end
|
916
968
|
|
917
969
|
def disable_clock(options = {})
|
@@ -924,7 +976,7 @@ module Origen
|
|
924
976
|
end
|
925
977
|
|
926
978
|
def start_clock(options = {})
|
927
|
-
enable_clock(options) if
|
979
|
+
enable_clock(options) if myself.is_not_a_clock?
|
928
980
|
@clock.start_clock(options)
|
929
981
|
end
|
930
982
|
alias_method :resume_clock, :start_clock
|
@@ -951,12 +1003,12 @@ module Origen
|
|
951
1003
|
@clock.toggle
|
952
1004
|
end
|
953
1005
|
|
954
|
-
# Delete this pin (
|
1006
|
+
# Delete this pin (myself). Used bang in method name to keep same for pins and
|
955
1007
|
# pin collections. Pin collections already had a delete method which deletes
|
956
1008
|
# a pin from the collection. Needed delete! to indicate it is deleting the
|
957
1009
|
# actual pin or pin group calling the method.
|
958
1010
|
def delete!
|
959
|
-
owner.delete_pin(
|
1011
|
+
owner.delete_pin(myself)
|
960
1012
|
end
|
961
1013
|
|
962
1014
|
def type=(value)
|
@@ -5,6 +5,14 @@ module Origen
|
|
5
5
|
class PinCollection
|
6
6
|
include PinCommon
|
7
7
|
include Enumerable
|
8
|
+
include OrgFile::Interceptable
|
9
|
+
|
10
|
+
ORG_FILE_INTERCEPTED_METHODS = [
|
11
|
+
:drive, :drive_hi, :drive_lo, :drive_very_hi, :drive_mem, :expect_mem, :toggle,
|
12
|
+
:repeat_previous=, :capture, :assert, :compare, :expect,
|
13
|
+
:assert_hi, :expect_hi, :compare_hi, :assert_lo, :expect_lo, :compare_lo,
|
14
|
+
:dont_care
|
15
|
+
]
|
8
16
|
|
9
17
|
attr_accessor :endian
|
10
18
|
attr_accessor :description
|
@@ -22,6 +30,7 @@ module Origen
|
|
22
30
|
@virtual_pins = options.delete(:virtual_pin) || options.delete(:virtual_pins)
|
23
31
|
@other_pins = options.delete(:other_pin) || options.delete(:other_pins)
|
24
32
|
@endian = options[:endian]
|
33
|
+
@rtl_name = options[:rtl_name]
|
25
34
|
@description = options[:description] || options[:desc]
|
26
35
|
@options = options
|
27
36
|
@store = []
|
@@ -31,6 +40,18 @@ module Origen
|
|
31
40
|
on_init(owner, options)
|
32
41
|
end
|
33
42
|
|
43
|
+
def rtl_name
|
44
|
+
(@rtl_name || id).to_s
|
45
|
+
end
|
46
|
+
|
47
|
+
def global_path_to
|
48
|
+
"dut.pins(:#{id})"
|
49
|
+
end
|
50
|
+
|
51
|
+
def org_file_intercepted_methods
|
52
|
+
ORG_FILE_INTERCEPTED_METHODS
|
53
|
+
end
|
54
|
+
|
34
55
|
# Returns the value held by the pin group as a string formatted to the current tester's pattern syntax
|
35
56
|
#
|
36
57
|
# @example
|
@@ -70,7 +91,7 @@ module Origen
|
|
70
91
|
fail 'When setting vector_formatted_value on a pin group you must supply values for all pins!'
|
71
92
|
end
|
72
93
|
val.split(//).reverse.each_with_index do |val, i|
|
73
|
-
|
94
|
+
myself[i].vector_formatted_value = val
|
74
95
|
end
|
75
96
|
@vector_formatted_value = val
|
76
97
|
end
|
@@ -140,12 +161,12 @@ module Origen
|
|
140
161
|
|
141
162
|
def sort!(&block)
|
142
163
|
@store = sort(&block)
|
143
|
-
|
164
|
+
myself
|
144
165
|
end
|
145
166
|
|
146
167
|
def sort_by!
|
147
168
|
@store = sort_by
|
148
|
-
|
169
|
+
myself
|
149
170
|
end
|
150
171
|
|
151
172
|
def []=(index, pin)
|
@@ -207,11 +228,11 @@ module Origen
|
|
207
228
|
alias_method :<<, :add_pin
|
208
229
|
|
209
230
|
def drive(val)
|
210
|
-
|
231
|
+
value = clean_value(value)
|
211
232
|
each_with_index do |pin, i|
|
212
233
|
pin.drive(val[size - i - 1])
|
213
234
|
end
|
214
|
-
|
235
|
+
myself
|
215
236
|
end
|
216
237
|
|
217
238
|
def drive!(val)
|
@@ -222,7 +243,7 @@ module Origen
|
|
222
243
|
# Set all pins in pin group to drive 1's on future cycles
|
223
244
|
def drive_hi
|
224
245
|
each(&:drive_hi)
|
225
|
-
|
246
|
+
myself
|
226
247
|
end
|
227
248
|
|
228
249
|
def drive_hi!
|
@@ -233,7 +254,7 @@ module Origen
|
|
233
254
|
# Set all pins in pin group to drive 0's on future cycles
|
234
255
|
def drive_lo
|
235
256
|
each(&:drive_lo)
|
236
|
-
|
257
|
+
myself
|
237
258
|
end
|
238
259
|
|
239
260
|
def drive_lo!
|
@@ -245,7 +266,7 @@ module Origen
|
|
245
266
|
# For example on a J750 high-voltage channel the pin state would be set to "2"
|
246
267
|
def drive_very_hi
|
247
268
|
each(&:drive_very_hi)
|
248
|
-
|
269
|
+
myself
|
249
270
|
end
|
250
271
|
|
251
272
|
def drive_very_hi!
|
@@ -255,7 +276,7 @@ module Origen
|
|
255
276
|
|
256
277
|
def drive_mem
|
257
278
|
each(&:drive_mem)
|
258
|
-
|
279
|
+
myself
|
259
280
|
end
|
260
281
|
|
261
282
|
def drive_mem!
|
@@ -265,7 +286,7 @@ module Origen
|
|
265
286
|
|
266
287
|
def expect_mem
|
267
288
|
each(&:expect_mem)
|
268
|
-
|
289
|
+
myself
|
269
290
|
end
|
270
291
|
|
271
292
|
def expect_mem!
|
@@ -293,7 +314,7 @@ module Origen
|
|
293
314
|
|
294
315
|
def toggle
|
295
316
|
each(&:toggle)
|
296
|
-
|
317
|
+
myself
|
297
318
|
end
|
298
319
|
|
299
320
|
def toggle!
|
@@ -303,13 +324,13 @@ module Origen
|
|
303
324
|
|
304
325
|
def repeat_previous=(bool)
|
305
326
|
each { |pin| pin.repeat_previous = bool }
|
306
|
-
|
327
|
+
myself
|
307
328
|
end
|
308
329
|
|
309
330
|
# Mark the (data) from all the pins in the pin group to be captured
|
310
331
|
def capture
|
311
332
|
each(&:capture)
|
312
|
-
|
333
|
+
myself
|
313
334
|
end
|
314
335
|
alias_method :store, :capture
|
315
336
|
|
@@ -320,8 +341,16 @@ module Origen
|
|
320
341
|
alias_method :store!, :capture!
|
321
342
|
|
322
343
|
def restore_state
|
323
|
-
|
344
|
+
save
|
324
345
|
yield
|
346
|
+
restore
|
347
|
+
end
|
348
|
+
|
349
|
+
def save
|
350
|
+
each(&:save)
|
351
|
+
end
|
352
|
+
|
353
|
+
def restore
|
325
354
|
each(&:restore)
|
326
355
|
end
|
327
356
|
|
@@ -334,6 +363,7 @@ module Origen
|
|
334
363
|
end
|
335
364
|
|
336
365
|
def assert(value, options = {})
|
366
|
+
value = clean_value(value)
|
337
367
|
each_with_index do |pin, i|
|
338
368
|
if !value.respond_to?('data')
|
339
369
|
pin.assert(value[size - i - 1], options)
|
@@ -343,7 +373,7 @@ module Origen
|
|
343
373
|
pin.dont_care
|
344
374
|
end
|
345
375
|
end
|
346
|
-
|
376
|
+
myself
|
347
377
|
end
|
348
378
|
alias_method :compare, :assert
|
349
379
|
alias_method :expect, :assert
|
@@ -358,7 +388,7 @@ module Origen
|
|
358
388
|
# Set all pins in the pin group to expect 1's on future cycles
|
359
389
|
def assert_hi(options = {})
|
360
390
|
each { |pin| pin.assert_hi(options) }
|
361
|
-
|
391
|
+
myself
|
362
392
|
end
|
363
393
|
alias_method :expect_hi, :assert_hi
|
364
394
|
alias_method :compare_hi, :assert_hi
|
@@ -373,7 +403,7 @@ module Origen
|
|
373
403
|
# Set all pins in the pin group to expect 0's on future cycles
|
374
404
|
def assert_lo(options = {})
|
375
405
|
each { |pin| pin.assert_lo(options) }
|
376
|
-
|
406
|
+
myself
|
377
407
|
end
|
378
408
|
alias_method :expect_lo, :assert_lo
|
379
409
|
alias_method :compare_lo, :assert_lo
|
@@ -388,7 +418,7 @@ module Origen
|
|
388
418
|
# Set all pins in the pin group to X on future cycles
|
389
419
|
def dont_care
|
390
420
|
each(&:dont_care)
|
391
|
-
|
421
|
+
myself
|
392
422
|
end
|
393
423
|
|
394
424
|
def dont_care!
|
@@ -456,13 +486,23 @@ pins(:some_group).map(&:id).sort
|
|
456
486
|
end
|
457
487
|
end
|
458
488
|
|
459
|
-
# Delete this pingroup (
|
489
|
+
# Delete this pingroup (myself)
|
460
490
|
def delete!
|
461
|
-
owner.delete_pin(
|
491
|
+
owner.delete_pin(myself)
|
462
492
|
end
|
463
493
|
|
464
494
|
private
|
465
495
|
|
496
|
+
def clean_value(val)
|
497
|
+
return val if val.respond_to?(:contains_bits?)
|
498
|
+
val = val.data if val.respond_to?('data')
|
499
|
+
if val.is_a?(String) || val.is_a?(Symbol)
|
500
|
+
Origen::Value.new(val)
|
501
|
+
else
|
502
|
+
val
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
466
506
|
# Cleans up indexed references to pins, e.g. makes these equal:
|
467
507
|
#
|
468
508
|
# pins(:pb)[0,1,2,3]
|
@@ -501,7 +541,7 @@ pins(:some_group).map(&:id).sort
|
|
501
541
|
else
|
502
542
|
# Allow getters if all pins are the same
|
503
543
|
ref = first.send(method, *args)
|
504
|
-
if
|
544
|
+
if myself.all? { |pin| pin.send(method, *args) == ref }
|
505
545
|
ref
|
506
546
|
else
|
507
547
|
fail "The pins held by pin collection #{id} have different values for #{method}"
|