origen 0.28.2 → 0.29.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/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}"
|