origen 0.5.7 → 0.5.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/config/version.rb +1 -1
- data/helpers/guides.rb +1 -0
- data/lib/origen.rb +4 -0
- data/lib/origen/commands.rb +5 -0
- data/lib/origen/core_ext/numeric.rb +4 -0
- data/lib/origen/core_ext/range.rb +9 -0
- data/lib/origen/core_ext/string.rb +2 -1
- data/lib/origen/global_methods.rb +4 -0
- data/lib/origen/model.rb +28 -0
- data/lib/origen/model_initializer.rb +4 -0
- data/lib/origen/models.rb +6 -0
- data/lib/origen/models/mux.rb +26 -0
- data/lib/origen/models/scan_register.rb +74 -0
- data/lib/origen/netlist.rb +24 -0
- data/lib/origen/netlist/connectable.rb +18 -0
- data/lib/origen/netlist/list.rb +152 -0
- data/lib/origen/pins.rb +0 -71
- data/lib/origen/pins/pin.rb +6 -10
- data/lib/origen/pins/pin_collection.rb +1 -1
- data/lib/origen/ports.rb +66 -0
- data/lib/origen/ports/bit_collection.rb +6 -0
- data/lib/origen/ports/port.rb +129 -0
- data/lib/origen/ports/port_collection.rb +19 -0
- data/lib/origen/ports/section.rb +116 -0
- data/lib/origen/registers.rb +7 -1
- data/lib/origen/registers/bit.rb +8 -3
- data/lib/origen/registers/bit_collection.rb +57 -2
- data/lib/origen/registers/reg.rb +2 -2
- data/lib/origen/revision_control/design_sync.rb +47 -3
- data/lib/origen/sub_blocks.rb +12 -3
- data/lib/origen/undefined.rb +13 -0
- data/templates/nanoc/layouts/bootstrap.html.erb +8 -0
- metadata +16 -5
- data/lib/origen/pins/port.rb +0 -268
data/lib/origen/pins.rb
CHANGED
@@ -170,7 +170,6 @@ module Origen
|
|
170
170
|
# about dealing with a single pin vs. a collection.
|
171
171
|
module Pins
|
172
172
|
autoload :Pin, 'origen/pins/pin'
|
173
|
-
autoload :Port, 'origen/pins/port'
|
174
173
|
autoload :PinCollection, 'origen/pins/pin_collection'
|
175
174
|
autoload :PinBank, 'origen/pins/pin_bank'
|
176
175
|
autoload :PinCommon, 'origen/pins/pin_common'
|
@@ -313,11 +312,6 @@ module Origen
|
|
313
312
|
Origen.app.pin_pattern_exclude << options unless options.empty?
|
314
313
|
end
|
315
314
|
|
316
|
-
# API v2, deprecated
|
317
|
-
def add_port(id, options = {})
|
318
|
-
add_pins(id, options)
|
319
|
-
end
|
320
|
-
|
321
315
|
def add_pin_alias(new_name, original_name, options = {})
|
322
316
|
if pin_groups.include?(original_name) # this is a pin group
|
323
317
|
if options[:pin] # alias single pin from a pin group
|
@@ -331,7 +325,6 @@ module Origen
|
|
331
325
|
end
|
332
326
|
alias_method :pin_alias, :add_pin_alias
|
333
327
|
alias_method :alias_pin, :add_pin_alias
|
334
|
-
alias_method :add_port_alias, :add_pin_alias
|
335
328
|
|
336
329
|
def add_pin_group_alias(new_name, original_name, options = {})
|
337
330
|
group = Origen.pin_bank.find_or_create_pin_group(new_name, self, options)
|
@@ -592,8 +585,6 @@ If you meant to define the pin then use the add_pin method instead.
|
|
592
585
|
end
|
593
586
|
end
|
594
587
|
alias_method :pin, :pins
|
595
|
-
alias_method :port, :pins
|
596
|
-
alias_method :ports, :pins
|
597
588
|
|
598
589
|
# Equivalent to the pins method but considers power pins rather than regular pins
|
599
590
|
def power_pins(id = nil, options = {}, &block)
|
@@ -630,67 +621,5 @@ If you meant to define the pin then use the add_pin method instead.
|
|
630
621
|
fail "Error: the object #{id} you tried to delete is not a pin or pingroup"
|
631
622
|
end
|
632
623
|
end
|
633
|
-
|
634
|
-
# @api private
|
635
|
-
#
|
636
|
-
# If the pin is a port it will select the target pin from it based on the options
|
637
|
-
#
|
638
|
-
# API v2, deprecated
|
639
|
-
def resolve_pin(obj, options)
|
640
|
-
if obj.is_a?(Port)
|
641
|
-
pins = options[:pin] || options[:pins]
|
642
|
-
if pins
|
643
|
-
pins = clean_pin_arg(pins)
|
644
|
-
if pins.size == 1
|
645
|
-
obj[pins.first]
|
646
|
-
else
|
647
|
-
port = Port.new("subset_of_#{obj.id}", obj.owner, add_pins: false, size: pins.size)
|
648
|
-
pins.each do |pin|
|
649
|
-
port.add_pin_object(obj[pin])
|
650
|
-
end
|
651
|
-
port
|
652
|
-
end
|
653
|
-
else
|
654
|
-
obj
|
655
|
-
end
|
656
|
-
else
|
657
|
-
obj
|
658
|
-
end
|
659
|
-
end
|
660
|
-
|
661
|
-
# @api private
|
662
|
-
#
|
663
|
-
# Returns an array of ids, regardless if the input is a single number, an array,
|
664
|
-
# a range, or an array contaning a range
|
665
|
-
#
|
666
|
-
# API v2, deprecated
|
667
|
-
def clean_pin_arg(pin)
|
668
|
-
pin = [pin].flatten
|
669
|
-
pin.map { |obj| range_to_array(obj) }.flatten.sort
|
670
|
-
end
|
671
|
-
|
672
|
-
# @api private
|
673
|
-
#
|
674
|
-
# API v2, deprecated
|
675
|
-
def range_to_array(range)
|
676
|
-
if range.is_a?(Range)
|
677
|
-
a = range.first
|
678
|
-
b = range.last
|
679
|
-
if a > b
|
680
|
-
(b..a).to_a
|
681
|
-
else
|
682
|
-
(a..b).to_a
|
683
|
-
end
|
684
|
-
else
|
685
|
-
range
|
686
|
-
end
|
687
|
-
end
|
688
|
-
|
689
|
-
# API v2, deprecated
|
690
|
-
# @api private
|
691
|
-
def add_pin_object(pin)
|
692
|
-
@pins ||= {}
|
693
|
-
@pins[@pins.size] = pin
|
694
|
-
end
|
695
624
|
end
|
696
625
|
end
|
data/lib/origen/pins/pin.rb
CHANGED
@@ -22,8 +22,6 @@ module Origen
|
|
22
22
|
attr_accessor :repeat_previous
|
23
23
|
attr_reader :owner
|
24
24
|
attr_reader :size
|
25
|
-
# If the pin belongs to a port then this will return the port object
|
26
|
-
attr_accessor :port
|
27
25
|
# Returns a hash containing the aliases associated with the given pin
|
28
26
|
attr_reader :aliases
|
29
27
|
# Returns a hash containing the functions associated with the given pin
|
@@ -273,7 +271,6 @@ module Origen
|
|
273
271
|
group.include?(self)
|
274
272
|
end
|
275
273
|
end
|
276
|
-
alias_method :ports, :groups
|
277
274
|
alias_method :pin_groups, :groups
|
278
275
|
|
279
276
|
def invalidate_group_cache
|
@@ -453,18 +450,17 @@ module Origen
|
|
453
450
|
end
|
454
451
|
end
|
455
452
|
|
456
|
-
# Returns true if the pin belongs to a
|
453
|
+
# Returns true if the pin belongs to a pin group.
|
457
454
|
#
|
458
|
-
#
|
455
|
+
# add_pins :jtag, size: 6
|
459
456
|
# add_pin :done
|
460
|
-
# add_pin_alias :fail, :jtag, :
|
457
|
+
# add_pin_alias :fail, :jtag, pin: 4
|
461
458
|
#
|
462
|
-
# pin(:done).
|
463
|
-
# pin(:fail).
|
464
|
-
def
|
459
|
+
# pin(:done).belongs_to_a_pin_group? # => false
|
460
|
+
# pin(:fail).belongs_to_a_pin_group? # => true
|
461
|
+
def belongs_to_a_pin_group?
|
465
462
|
!groups.empty?
|
466
463
|
end
|
467
|
-
alias_method :belongs_to_a_pin_group?, :belongs_to_a_port?
|
468
464
|
|
469
465
|
def value
|
470
466
|
@value
|
@@ -402,7 +402,7 @@ module Origen
|
|
402
402
|
all?(&:repeat_previous?)
|
403
403
|
end
|
404
404
|
|
405
|
-
# Returns true if the (data) from the
|
405
|
+
# Returns true if the (data) from the pin collection is marked to be captured
|
406
406
|
def to_be_captured?
|
407
407
|
all?(&:to_be_captured?)
|
408
408
|
end
|
data/lib/origen/ports.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
module Origen
|
2
|
+
module Ports
|
3
|
+
autoload :Port, 'origen/ports/port'
|
4
|
+
autoload :Section, 'origen/ports/section'
|
5
|
+
autoload :BitCollection, 'origen/ports/bit_collection'
|
6
|
+
autoload :PortCollection, 'origen/ports/port_collection'
|
7
|
+
|
8
|
+
def add_port(name, options = {})
|
9
|
+
p = Port.new(self, name, options)
|
10
|
+
if block_given?
|
11
|
+
p.send(:defining) do
|
12
|
+
yield p
|
13
|
+
end
|
14
|
+
end
|
15
|
+
_ports.add(name.to_s.symbolize, p)
|
16
|
+
p
|
17
|
+
end
|
18
|
+
|
19
|
+
def port(*args, &block)
|
20
|
+
if block_given?
|
21
|
+
add_port(*args, &block)
|
22
|
+
else
|
23
|
+
if args.first
|
24
|
+
if has_port?(args.first)
|
25
|
+
_ports[args.first.to_s.symbolize]
|
26
|
+
else
|
27
|
+
if initialized?
|
28
|
+
puts "Model #{self.class} does not have a port named #{args.first}, the available ports are:"
|
29
|
+
puts _ports.keys
|
30
|
+
puts
|
31
|
+
fail 'Missing port error'
|
32
|
+
else
|
33
|
+
# Assume this is a pin definition while the model is still initializing
|
34
|
+
add_port(*args)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
else
|
38
|
+
_ports
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
alias_method :ports, :port
|
43
|
+
|
44
|
+
def has_port?(name)
|
45
|
+
_ports.key?(name.to_s.symbolize)
|
46
|
+
end
|
47
|
+
|
48
|
+
def method_missing(method, *args, &block)
|
49
|
+
if _ports.key?(method.to_s.symbolize)
|
50
|
+
_ports[method.to_s.symbolize]
|
51
|
+
else
|
52
|
+
super
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def respond_to?(sym)
|
57
|
+
has_port?(sym) || super(sym)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def _ports
|
63
|
+
@_ports ||= PortCollection.new
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module Origen
|
2
|
+
module Ports
|
3
|
+
class Port
|
4
|
+
include Netlist::Connectable
|
5
|
+
|
6
|
+
attr_reader :size
|
7
|
+
attr_reader :parent
|
8
|
+
attr_reader :id
|
9
|
+
attr_reader :type
|
10
|
+
|
11
|
+
alias_method :name, :id
|
12
|
+
alias_method :owner, :parent
|
13
|
+
|
14
|
+
def initialize(parent, id, options = {})
|
15
|
+
@size = options[:size] || 1
|
16
|
+
@parent = parent
|
17
|
+
@id = id
|
18
|
+
@type = options[:type]
|
19
|
+
@bit_names = {}.with_indifferent_access
|
20
|
+
end
|
21
|
+
|
22
|
+
def inspect
|
23
|
+
"<#{self.class}:#{object_id} id:#{id} path:#{path}>"
|
24
|
+
end
|
25
|
+
|
26
|
+
def describe(options = {})
|
27
|
+
desc = ['********************']
|
28
|
+
desc << "Port id: #{id}"
|
29
|
+
desc << "Port path: #{path}"
|
30
|
+
desc << ''
|
31
|
+
desc << 'Connections'
|
32
|
+
desc << '-----------'
|
33
|
+
desc << ''
|
34
|
+
table = netlist.table
|
35
|
+
((size - 1)..0).to_a.each do |i|
|
36
|
+
if table[path]
|
37
|
+
c = [table[path]['*'], table[path][i]].flatten.compact.map { |n| n.is_a?(Proc) ? 'Proc' : n }
|
38
|
+
desc << "#{i} - #{c.shift}"
|
39
|
+
c.each do |n|
|
40
|
+
desc << " - #{n}"
|
41
|
+
end
|
42
|
+
else
|
43
|
+
desc << "#{i} - none"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
desc << ''
|
47
|
+
|
48
|
+
if options[:return]
|
49
|
+
desc
|
50
|
+
else
|
51
|
+
puts desc.join("\n")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def path
|
56
|
+
if parent.path.empty?
|
57
|
+
id.to_s
|
58
|
+
else
|
59
|
+
"#{parent.path}.#{id}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def bits(index, name, options = {})
|
64
|
+
if @defining
|
65
|
+
@bit_names[name] = index
|
66
|
+
else
|
67
|
+
fail 'Cannot add additional port bits once the port definition is complete'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def drive(value = nil, options = {})
|
72
|
+
value, options = nil, value if value.is_a?(Hash)
|
73
|
+
if options[:index]
|
74
|
+
if options[:index].is_a?(Fixnum)
|
75
|
+
drive_values[options[:index]] = value ? value[0] : nil
|
76
|
+
else
|
77
|
+
options[:index].to_a.each do |i|
|
78
|
+
drive_values[i] = value ? value[i] : nil
|
79
|
+
end
|
80
|
+
end
|
81
|
+
else
|
82
|
+
size.times do |i|
|
83
|
+
drive_values[i] = value ? value[i] : nil
|
84
|
+
end
|
85
|
+
end
|
86
|
+
@drive_value = value
|
87
|
+
end
|
88
|
+
|
89
|
+
def drive_values
|
90
|
+
@drive_values ||= Array.new(size)
|
91
|
+
end
|
92
|
+
|
93
|
+
def to_section
|
94
|
+
Section.new(self, (size - 1)..0)
|
95
|
+
end
|
96
|
+
|
97
|
+
def method_missing(method, *args, &block)
|
98
|
+
if @bit_names.key?(method)
|
99
|
+
Section.new(self, @bit_names[method])
|
100
|
+
elsif BitCollection.instance_methods.include?(method)
|
101
|
+
to_bc.send(method, *args, &block)
|
102
|
+
else
|
103
|
+
super
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def respond_to?(*args)
|
108
|
+
@bit_names.key?(args.first) || super(*args) ||
|
109
|
+
BitCollection.instance_methods.include?(args.first)
|
110
|
+
end
|
111
|
+
|
112
|
+
def [](val)
|
113
|
+
Section.new(self, val)
|
114
|
+
end
|
115
|
+
|
116
|
+
def to_bc
|
117
|
+
to_section.to_bc
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
def defining
|
123
|
+
@defining = true
|
124
|
+
yield
|
125
|
+
@defining = false
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Origen
|
2
|
+
module Ports
|
3
|
+
class PortCollection < ::Hash
|
4
|
+
def add(name, port)
|
5
|
+
self[name] = port
|
6
|
+
by_type[port.type] ||= []
|
7
|
+
by_type[port.type] << port
|
8
|
+
end
|
9
|
+
|
10
|
+
def by_type
|
11
|
+
@by_type ||= {}.with_indifferent_access
|
12
|
+
end
|
13
|
+
|
14
|
+
def inspect
|
15
|
+
map { |k, _v| k }.inspect
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module Origen
|
2
|
+
module Ports
|
3
|
+
class Section
|
4
|
+
include Netlist::Connectable
|
5
|
+
|
6
|
+
attr_reader :port
|
7
|
+
attr_reader :index
|
8
|
+
|
9
|
+
def initialize(port, index)
|
10
|
+
@port = port
|
11
|
+
@index = index
|
12
|
+
end
|
13
|
+
|
14
|
+
def size
|
15
|
+
size_of(index)
|
16
|
+
end
|
17
|
+
|
18
|
+
def path
|
19
|
+
if index.is_a?(Range)
|
20
|
+
port.path + "[#{index.first}:#{index.last}]"
|
21
|
+
else
|
22
|
+
port.path + "[#{index}]"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def parent
|
27
|
+
port.parent
|
28
|
+
end
|
29
|
+
alias_method :owner, :parent
|
30
|
+
|
31
|
+
def id
|
32
|
+
port.id
|
33
|
+
end
|
34
|
+
|
35
|
+
def drive(value = nil)
|
36
|
+
port.drive(value, index: index)
|
37
|
+
end
|
38
|
+
|
39
|
+
def drive_value
|
40
|
+
if size == 1
|
41
|
+
port.drive_values[index]
|
42
|
+
else
|
43
|
+
fail 'drive_value is only supported for a single bit port section'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def [](index)
|
48
|
+
Section.new(port, align_to_port(index))
|
49
|
+
end
|
50
|
+
|
51
|
+
def respond_to?(*args)
|
52
|
+
super(*args) || BitCollection.instance_methods.include?(args.first)
|
53
|
+
end
|
54
|
+
|
55
|
+
def method_missing(method, *args, &block)
|
56
|
+
if BitCollection.instance_methods.include?(method)
|
57
|
+
to_bc.send(method, *args, &block)
|
58
|
+
else
|
59
|
+
super
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_bc
|
64
|
+
b = BitCollection.new(port, port.id)
|
65
|
+
indexes = index.respond_to?(:to_a) ? index.to_a : [index]
|
66
|
+
indexes.reverse_each do |i|
|
67
|
+
b << netlist.data_bit(port.path, i)
|
68
|
+
end
|
69
|
+
b
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def size_of(index)
|
75
|
+
if index.is_a?(Range)
|
76
|
+
(index.first - index.last).abs + 1
|
77
|
+
else
|
78
|
+
1
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def align_to_port(val)
|
83
|
+
if val.is_a?(Range)
|
84
|
+
nlsb = lsb + val.last
|
85
|
+
nmsb = nlsb + size_of(val) - 1
|
86
|
+
out_of_range(val) if nmsb > msb
|
87
|
+
i = nmsb..nlsb
|
88
|
+
else
|
89
|
+
i = lsb + val
|
90
|
+
out_of_range(val) if i > msb
|
91
|
+
end
|
92
|
+
i
|
93
|
+
end
|
94
|
+
|
95
|
+
def out_of_range(val)
|
96
|
+
fail "Requested section index (#{val}) is out of range for a port section of size #{size}"
|
97
|
+
end
|
98
|
+
|
99
|
+
def msb
|
100
|
+
if index.is_a?(Range)
|
101
|
+
index.first
|
102
|
+
else
|
103
|
+
index
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def lsb
|
108
|
+
if index.is_a?(Range)
|
109
|
+
index.last
|
110
|
+
else
|
111
|
+
index
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|