soc_maker 0.1.1

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.
Files changed (116) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/History.txt +4 -0
  4. data/LICENSE +678 -0
  5. data/README.rdoc +228 -0
  6. data/Rakefile +46 -0
  7. data/bin/soc_maker_cli +80 -0
  8. data/bin/soc_maker_parser +85 -0
  9. data/core_lib/cores/adv_debug_sys/01_adv_debug_sys.yaml +245 -0
  10. data/core_lib/cores/or1200_rel2/01_or1200.yaml +208 -0
  11. data/core_lib/cores/or1200_rel2/02_or1200_files.yaml +421 -0
  12. data/core_lib/cores/or1200_rel2/03_or1200_sparam.yaml +188 -0
  13. data/core_lib/cores/or1200_rel2/or1200_defines.v.in +1799 -0
  14. data/core_lib/cores/ram_wb/ram_wb.yaml +102 -0
  15. data/core_lib/cores/ram_wb/ram_wb_b3.v.in +259 -0
  16. data/core_lib/cores/uart16550/01_uart16550.yaml +99 -0
  17. data/core_lib/cores/uart16550/02_uart16550_files.yaml +70 -0
  18. data/core_lib/cores/wb_connect/minsoc_tc_top.v +1802 -0
  19. data/core_lib/cores/wb_connect/wb_connect.yaml +733 -0
  20. data/core_lib/inc.yaml +13 -0
  21. data/core_lib/interfaces/clk_rst/clk.yaml +9 -0
  22. data/core_lib/interfaces/clk_rst/rst.yaml +9 -0
  23. data/core_lib/interfaces/clk_rst/single.yaml +7 -0
  24. data/core_lib/interfaces/debug/debug.yaml +32 -0
  25. data/core_lib/interfaces/jtag/jtag.yaml +13 -0
  26. data/core_lib/interfaces/jtag/jtag_tap.yaml +22 -0
  27. data/core_lib/interfaces/power/or_power.yaml +25 -0
  28. data/core_lib/interfaces/uart/uart.yaml +21 -0
  29. data/core_lib/interfaces/wishbone/wishbone_ma_b3.yaml +54 -0
  30. data/core_lib/interfaces/wishbone/wishbone_sl_b3.yaml +51 -0
  31. data/doc/class_arch.uml +5113 -0
  32. data/doc/fig/hierarchical.svg +273 -0
  33. data/examples/or1200_test/or1200_test.cmd +78 -0
  34. data/examples/or1200_test/or1200_test.rb +136 -0
  35. data/examples/or1200_test/rtl/or1200_test_top.vhd +274 -0
  36. data/examples/or1200_test/rtl/s3astarter.ucf +10 -0
  37. data/examples/or1200_test/rtl/xilinx_internal_jtag.v +438 -0
  38. data/examples/or1200_test/rtl/xilinx_internal_jtag_options.v +12 -0
  39. data/examples/or1200_test/sw/README.txt +35 -0
  40. data/examples/or1200_test/sw/bin2vmem.c +159 -0
  41. data/examples/or1200_test/sw/board.h +24 -0
  42. data/examples/or1200_test/sw/compile.sh +18 -0
  43. data/examples/or1200_test/sw/except.S +152 -0
  44. data/examples/or1200_test/sw/int.c +79 -0
  45. data/examples/or1200_test/sw/int.h +14 -0
  46. data/examples/or1200_test/sw/interconnect.h +17 -0
  47. data/examples/or1200_test/sw/interrupts.c +14 -0
  48. data/examples/or1200_test/sw/main.c +16 -0
  49. data/examples/or1200_test/sw/or1200.h +454 -0
  50. data/examples/or1200_test/sw/orp.ld +60 -0
  51. data/examples/or1200_test/sw/reset.S +112 -0
  52. data/examples/or1200_test/sw/support.c +123 -0
  53. data/examples/or1200_test/sw/support.h +33 -0
  54. data/examples/or1200_test/sw/tick.c +30 -0
  55. data/examples/or1200_test/sw/tick.h +2 -0
  56. data/examples/or1200_test/sw/uart.c +136 -0
  57. data/examples/or1200_test/sw/uart.h +126 -0
  58. data/lib/soc_maker.rb +324 -0
  59. data/lib/soc_maker/cli.rb +544 -0
  60. data/lib/soc_maker/conf.rb +310 -0
  61. data/lib/soc_maker/core_def.rb +579 -0
  62. data/lib/soc_maker/core_inst.rb +305 -0
  63. data/lib/soc_maker/err.rb +211 -0
  64. data/lib/soc_maker/hdl_coder.rb +500 -0
  65. data/lib/soc_maker/hdl_file.rb +166 -0
  66. data/lib/soc_maker/hdl_parser.rb +431 -0
  67. data/lib/soc_maker/ifc_def.rb +193 -0
  68. data/lib/soc_maker/ifc_port.rb +133 -0
  69. data/lib/soc_maker/ifc_spc.rb +180 -0
  70. data/lib/soc_maker/lib.rb +289 -0
  71. data/lib/soc_maker/lib_inc.rb +109 -0
  72. data/lib/soc_maker/parameter.rb +149 -0
  73. data/lib/soc_maker/soc_def.rb +847 -0
  74. data/lib/soc_maker/sparameter.rb +289 -0
  75. data/lib/soc_maker/version.rb +8 -0
  76. data/lib/soc_maker/ypp.rb +130 -0
  77. data/soc_maker.gemspec +28 -0
  78. data/spec/cli_cmds1.txt +39 -0
  79. data/spec/cli_spec.rb +49 -0
  80. data/spec/conf_spec.rb +44 -0
  81. data/spec/core_def_spec.rb +503 -0
  82. data/spec/core_inst_spec.rb +169 -0
  83. data/spec/hdl_file_spec.rb +154 -0
  84. data/spec/hdl_parser_spec.rb +201 -0
  85. data/spec/ifc_def_spec.rb +121 -0
  86. data/spec/ifc_port_spec.rb +92 -0
  87. data/spec/ifc_spc_spec.rb +196 -0
  88. data/spec/lib_inc_spec.rb +99 -0
  89. data/spec/lib_spec.rb +209 -0
  90. data/spec/parameter_spec.rb +86 -0
  91. data/spec/soc_def_spec.rb +611 -0
  92. data/spec/soc_maker_spec.rb +7 -0
  93. data/spec/sparameter_spec.rb +182 -0
  94. data/spec/spec_helper.rb +78 -0
  95. data/spec/test_soc.yaml +105 -0
  96. data/spec/test_soc2.yaml +60 -0
  97. data/spec/test_soc_lib/cores/core_A_rel1/00_core_a.yaml +75 -0
  98. data/spec/test_soc_lib/cores/core_A_rel1/01_core_a.yaml +57 -0
  99. data/spec/test_soc_lib/cores/core_A_rel1/core_a.vhd +29 -0
  100. data/spec/test_soc_lib/cores/core_A_rel1/core_a_pkg.vhd.src +3 -0
  101. data/spec/test_soc_lib/cores/core_A_rel1/core_a_pkg2.vhd.src +4 -0
  102. data/spec/test_soc_lib/cores/core_A_rel1/core_a_pkg3.v.src +6 -0
  103. data/spec/test_soc_lib/cores/core_B_rel1/core_b.vhd +25 -0
  104. data/spec/test_soc_lib/cores/core_B_rel1/core_b.yaml +36 -0
  105. data/spec/test_soc_lib/cores/core_C_v1/core_C.vhd +57 -0
  106. data/spec/test_soc_lib/cores/core_C_v1/core_c.yaml +42 -0
  107. data/spec/test_soc_lib/cores/soc_A/soc_A.yaml +12 -0
  108. data/spec/test_soc_lib/cores/soc_maker_include.yaml +6 -0
  109. data/spec/test_soc_lib/ifcs/core_AB_ifc/bidir_ifc.yaml +19 -0
  110. data/spec/test_soc_lib/ifcs/core_AB_ifc/core_AB_ifc.yaml +15 -0
  111. data/spec/test_soc_lib/ifcs/core_AB_ifc/top_ifc.yaml +9 -0
  112. data/spec/test_soc_lib/soc_maker_include.yaml +4 -0
  113. data/spec/yaml_examples.rb +367 -0
  114. data/spec/ypp_spec.rb +156 -0
  115. data/test/test_soc_maker.rb +0 -0
  116. metadata +255 -0
@@ -0,0 +1,193 @@
1
+ ###############################################################
2
+ #
3
+ # File: ifc_def.rb
4
+ #
5
+ # Author: Christian Hättich
6
+ #
7
+ # Project: System-On-Chip Maker
8
+ #
9
+ # Target: Linux / Windows / Mac
10
+ #
11
+ # Language: ruby
12
+ #
13
+ #
14
+ ###############################################################
15
+ #
16
+ #
17
+ # Copyright (C) 2014 Christian Hättich - feddischson [ at ] opencores.org
18
+ #
19
+ # This program is free software: you can redistribute it and/or modify
20
+ # it under the terms of the GNU General Public License as published by
21
+ # the Free Software Foundation, either version 3 of the License, or
22
+ # (at your option) any later version.
23
+ #
24
+ # This program is distributed in the hope that it will be useful,
25
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
26
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27
+ # GNU General Public License for more details.
28
+ #
29
+ # You should have received a copy of the GNU General Public License
30
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
31
+ #
32
+ #
33
+ ###############################################################
34
+ #
35
+ # Description:
36
+ #
37
+
38
+ module SOCMaker
39
+
40
+ # A small classes, used to group information
41
+ # and to verify, auto-correct and auto-complete
42
+ # this information:
43
+ # The class represents an interface definition containing
44
+ # - a #name of the interface (mandatory)
45
+ # - an #id of the instance (mandatory)
46
+ # - a #dir (direction) (mandatory)
47
+ # - some #ports (hash of type SOCMaker::IfcPort, mandatory)
48
+ #
49
+ # Note: instances of this class are used withing core-definitions.
50
+ # Different cores may use the same interface, but with a
51
+ # different naming of the ports. For this reason, the id
52
+ # is used to identify, which interface specification (SOCMaker::IfcSpc)
53
+ # is defined. The port-hash makes the relation between the core port-naming
54
+ # and the IfcSpc port-naming.
55
+ class IfcDef
56
+ include ERR
57
+
58
+ # name of interface definition
59
+ attr_accessor :name
60
+
61
+ # direction
62
+ attr_accessor :dir
63
+
64
+ # id of the interface specification
65
+ attr_accessor :id
66
+
67
+ # the port hash, containing the IfcPort instances
68
+ attr_accessor :ports
69
+
70
+ # The constructor expects a name, id, dir (direction) and ports as mandatory
71
+ # arguments.
72
+ def initialize( name, id, dir, ports )
73
+ init_with( 'name' => name,
74
+ 'dir' => dir,
75
+ 'id' => id,
76
+ 'ports' => ports )
77
+ end
78
+
79
+ #
80
+ # Encoder method (to yaml)
81
+ #
82
+ # +coder+:: An instance of the Psych::Coder to encode this class to a YAML file
83
+ #
84
+ def encode_with( coder )
85
+ init_error_if !coder.is_a?( Psych::Coder ),
86
+ 'coder is not given as Psych::Coder'
87
+ %w[ name dir ports ].
88
+ each { |v| coder[ v ] = instance_variable_get "@#{v}" }
89
+ coder[ "id" ] = @id.to_s
90
+ end
91
+
92
+ #
93
+ # Initialization method (from yaml)
94
+ #
95
+ # +coder+:: An instance of the Psych::Coder to init this class from a YAML file
96
+ #
97
+ #
98
+ def init_with( coder )
99
+
100
+ init_error_if !( coder.is_a?( Hash ) || coder.is_a?( Psych::Coder ) ),
101
+ 'coder is not given as Hash neither as Psych::Coder'
102
+
103
+ # name
104
+ init_error 'no name defined for this interface',
105
+ field: 'name' if coder[ 'name' ] == nil
106
+
107
+ @name = coder[ 'name' ]
108
+
109
+ init_error 'Interface name is not defined as string',
110
+ instance: @name,
111
+ field: 'name' if !@name.is_a?( String )
112
+
113
+
114
+ init_error "Name has zero length",
115
+ field: "name" if @name.size == 0
116
+
117
+ # id
118
+ init_error 'id is not given for interface',
119
+ instance: @name,
120
+ field: 'id' if coder[ 'id' ] == nil
121
+
122
+ init_error 'Interface id is not defined as string',
123
+ instance: @name,
124
+ field: 'id' if !coder[ 'id' ].is_a?( String )
125
+
126
+ init_error "Version has zero length",
127
+ field: "name" if coder[ 'id' ].size == 0
128
+
129
+
130
+ @id = coder[ 'id' ].to_sym
131
+
132
+
133
+ # ports
134
+ init_error "No ports are given for interface definition",
135
+ field: 'ports' if coder[ 'ports' ] == nil
136
+
137
+ @ports = coder[ 'ports' ]
138
+ init_error 'no ports are given for this interface',
139
+ instance: @name,
140
+ field: 'ports' if !@ports.is_a?( Hash ) || @ports.size == 0
141
+
142
+ @ports.each do |name, port|
143
+ init_error 'no interface port found',
144
+ instance: @name + name.to_s,
145
+ field: 'ports' if port == nil
146
+
147
+
148
+ init_error 'Port is not of type SocMaker::IfcPort (use SOCM_PORT)',
149
+ instance: @name + name.to_s,
150
+ field: 'ports' if !port.is_a?( SOCMaker::IfcPort )
151
+
152
+ end
153
+
154
+ # direction
155
+ init_error 'Interface direction is not given',
156
+ instance: @name,
157
+ field: 'dir' if coder[ 'dir' ] == nil
158
+
159
+ @dir = coder[ 'dir' ]
160
+ init_error 'Interface direction must be 0 or 1',
161
+ instance: @name,
162
+ value: coder['dir' ],
163
+ field: 'dir' if @dir != 0 && @dir != 1
164
+
165
+
166
+
167
+ end
168
+
169
+ #
170
+ # Runs a consistence check: it ensures, that the port-reference is unique.
171
+ #
172
+ def consistence_check
173
+ tmp = {}
174
+ ports.each {|k,v| tmp[v.spc_ref] = k}
175
+ consistence_error "The port reference must be unique",
176
+ name: @name if ports.size != tmp.size
177
+ end
178
+
179
+
180
+ #
181
+ # Equality operator
182
+ #
183
+ def ==(o)
184
+ o.class == self.class &&
185
+ o.name == self.name &&
186
+ o.dir == self.dir &&
187
+ o.id == self.id &&
188
+ o.ports == self.ports
189
+ end
190
+
191
+
192
+ end # IFCDef
193
+ end # SOCMaker
@@ -0,0 +1,133 @@
1
+ ###############################################################
2
+ #
3
+ # File: ifc_port.rb
4
+ #
5
+ # Author: Christian Hättich
6
+ #
7
+ # Project: System-On-Chip Maker
8
+ #
9
+ # Target: Linux / Windows / Mac
10
+ #
11
+ # Language: ruby
12
+ #
13
+ #
14
+ ###############################################################
15
+ #
16
+ #
17
+ # Copyright (C) 2014 Christian Hättich - feddischson [ at ] opencores.org
18
+ #
19
+ # This program is free software: you can redistribute it and/or modify
20
+ # it under the terms of the GNU General Public License as published by
21
+ # the Free Software Foundation, either version 3 of the License, or
22
+ # (at your option) any later version.
23
+ #
24
+ # This program is distributed in the hope that it will be useful,
25
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
26
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27
+ # GNU General Public License for more details.
28
+ #
29
+ # You should have received a copy of the GNU General Public License
30
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
31
+ #
32
+ #
33
+ ###############################################################
34
+ #
35
+ #
36
+ ###############
37
+
38
+ module SOCMaker
39
+
40
+
41
+
42
+ #
43
+ # A small classes, used to group information
44
+ # and to verify, auto-correct and auto-complete
45
+ # this information:
46
+ # The class represents an interface port within
47
+ # SOCMaker::IfcDef.
48
+ # It is used to make a relation between the naming
49
+ # of SOCMaker::IfcDef and SOCMaker::IfcSpc.
50
+ # The two data fiels are
51
+ # - #spc_ref (mandatory: must be the name of the port, defined in IfcSpc)
52
+ # - #len (optional, default is 1)
53
+ #
54
+ class IfcPort
55
+ include ERR
56
+
57
+ #
58
+ # Used as reference to a port in SOCMaker::IfcSpc
59
+ #
60
+ attr_accessor :spc_ref
61
+
62
+ #
63
+ # Length of this port
64
+ #
65
+ attr_accessor :len
66
+
67
+
68
+ #
69
+ # Constructor, which expects #spc_ref and #len. Length has the default value 1.
70
+ #
71
+ def initialize( spc_ref, len = 1 )
72
+ init_with( 'spc_ref' => spc_ref,
73
+ 'len' => len )
74
+ end
75
+
76
+
77
+ #
78
+ # Encoder method (to yaml)
79
+ #
80
+ # +coder+:: An instance of the Psych::Coder to encode this class to a YAML file
81
+ #
82
+ def encode_with( coder )
83
+
84
+ init_error_if !coder.is_a?( Psych::Coder ),
85
+ 'coder is not given as Psych::Coder'
86
+ %w[ spc_ref len ].
87
+ each { |v| coder[ v ] = instance_variable_get "@#{v}" }
88
+ end
89
+
90
+ #
91
+ # Initialization method (from yaml)
92
+ #
93
+ # +coder+:: An instance of the Psych::Coder to init this class from a YAML file
94
+ #
95
+ #
96
+ def init_with( coder )
97
+
98
+ init_error_if !( coder.is_a?( Hash ) || coder.is_a?( Psych::Coder ) ),
99
+ 'coder is not given as Hash neither as Psych::Coder'
100
+
101
+ init_error 'no relation to interface-definition is given for an interface port (nil)',
102
+ field: "spc_ref" if coder[ 'spc_ref' ] == nil
103
+ @spc_ref = coder[ 'spc_ref' ]
104
+
105
+ init_error 'Relation to interface definition is not of type string',
106
+ instance: @spc_ref.to_s,
107
+ field: "spc_ref" if !@spc_ref.is_a?( String )
108
+
109
+ init_error 'Relation to interface definition has zero length',
110
+ instance: @spc_ref.to_s,
111
+ field: "spc_ref" if @spc_ref.size == 0
112
+
113
+ @len = coder[ 'len' ] || 1
114
+
115
+ init_error 'Length is not a fixnum',
116
+ instance: @spc_ref.to_s,
117
+ field: "spc_ref" if !( @len.is_a?( Fixnum ) || @len.is_a?( String ) )
118
+ end
119
+
120
+
121
+
122
+ #
123
+ # Equality operator
124
+ #
125
+ def ==(o)
126
+ o.class == self.class &&
127
+ o.spc_ref == self.spc_ref &&
128
+ o.len == self.len
129
+ end
130
+
131
+
132
+ end
133
+ end
@@ -0,0 +1,180 @@
1
+ ###############################################################
2
+ #
3
+ # File: if_spec.rb
4
+ #
5
+ # Author: Christian Hättich
6
+ #
7
+ # Project: System-On-Chip Maker
8
+ #
9
+ # Target: Linux / Windows / Mac
10
+ #
11
+ # Language: ruby
12
+ #
13
+ #
14
+ ###############################################################
15
+ #
16
+ #
17
+ # Copyright (C) 2014 Christian Hättich - feddischson [ at ] opencores.org
18
+ #
19
+ # This program is free software: you can redistribute it and/or modify
20
+ # it under the terms of the GNU General Public License as published by
21
+ # the Free Software Foundation, either version 3 of the License, or
22
+ # (at your option) any later version.
23
+ #
24
+ # This program is distributed in the hope that it will be useful,
25
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
26
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27
+ # GNU General Public License for more details.
28
+ #
29
+ # You should have received a copy of the GNU General Public License
30
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
31
+ #
32
+ #
33
+ ###############################################################
34
+ module SOCMaker
35
+
36
+
37
+ #
38
+ # This class represents an interface specification. It defines
39
+ # the data flow of individual ports as well as how much
40
+ # cores can be connected with this interface.
41
+ #
42
+ #
43
+ class IfcSpc
44
+ include ERR
45
+ include YAML_EXT
46
+
47
+
48
+ # name of the interface specification
49
+ attr_accessor :name
50
+
51
+ # ID of the interface
52
+ attr_accessor :id
53
+
54
+ # Port hash
55
+ attr_accessor :ports
56
+
57
+ # Multiplicity definition, must be a array with two entries.
58
+ # Each entry must be >=0 or a '*'
59
+ attr_accessor :multiplicity
60
+
61
+ # This constructor expects a name and an id as mandatory arguments.
62
+ # Everything else can be given as optinal arguments.
63
+ #
64
+ # +name+:: name of the interface specification
65
+ # +id+:: id of the interface specification
66
+ #
67
+ def initialize( name, id, optional = {} )
68
+ init_with( { 'name' => name,
69
+ 'id' => id }.merge( optional ) )
70
+ end
71
+ #
72
+ # Encoder method (to yaml)
73
+ #
74
+ # +coder+:: An instance of the Psych::Coder to encode this class to a YAML file
75
+ #
76
+ def encode_with( coder )
77
+ init_error_if !coder.is_a?( Psych::Coder ),
78
+ 'coder is not given as Psych::Coder'
79
+ %w[ name ports multiplicity ].
80
+ each { |v| coder[ v ] = instance_variable_get "@#{v}" }
81
+ coder[ "id" ] = @id.to_s
82
+ end
83
+
84
+ #
85
+ # Constructor:
86
+ # there is one mandatory attributes *type* and an optional one *params*.
87
+ #
88
+ # +type+:: The id of the core-definition, which is instanciated
89
+ # +params+:: Instanciation parameters
90
+ #
91
+ def init_with( coder )
92
+ init_error_if !( coder.is_a?( Hash ) || coder.is_a?( Psych::Coder ) ),
93
+ 'coder is not given as Hash neither as Psych::Coder'
94
+
95
+ init_error "Name is not defined",
96
+ field: "name" if coder[ 'name' ] == nil
97
+ @name = coder[ 'name' ]
98
+
99
+ init_error "Name is not defined as string",
100
+ field: "name" if !@name.is_a?( String )
101
+
102
+ init_error "Name has zero length",
103
+ field: "name" if @name.size == 0
104
+
105
+
106
+ init_error "Id is not defined",
107
+ field: "id" if coder[ 'id' ] == nil
108
+
109
+ @id = coder[ 'id' ]
110
+ init_error "Version is not defined as string",
111
+ instance: @name,
112
+ field: "id" if !coder[ 'id' ].is_a?( String )
113
+
114
+ init_error "Version has zero length",
115
+ field: "name" if coder[ 'id' ].size == 0
116
+
117
+ @id = coder[ 'id' ].to_sym
118
+
119
+ @ports = coder[ 'ports' ] || {}
120
+ @ports.each do |pname, port|
121
+
122
+ init_error "Port field must be organized as a hash",
123
+ instance: @name,
124
+ field: "ports" if !port.is_a?( Hash )
125
+
126
+ init_error "No port direction specified for #{pname}",
127
+ instance: @name,
128
+ field: "ports" if !port.has_key?( :dir )
129
+
130
+
131
+ init_error_if( !port[ :dir ].is_a?( Fixnum ) ||
132
+ ( port[ :dir ] != 0 && port[ :dir ] != 1 && port[ :dir ] != 2 ) ,
133
+ "Port direction value for #{pname} is neither 0 nor 1 nor 3",
134
+ instance: @name,
135
+ field: "ports" )
136
+
137
+ port[ :mandatory ] = true if !port.has_key?( :mandatory )
138
+ port[ :default ] ||= '0'
139
+
140
+ end
141
+
142
+ @multiplicity = coder[ 'multiplicity' ] || [ 1, 1 ]
143
+
144
+ init_error "multiplicity must contain exactly two entries " if @multiplicity.size != 2
145
+
146
+ @multiplicity.each do |m|
147
+ if !( m.is_a?( Fixnum ) && m >= 0 || m.is_a?( String ) && m == "*" )
148
+ init_error "multiplicity must be a fixnum or the string '*'"
149
+ end
150
+ end
151
+
152
+ end
153
+
154
+ #
155
+ # Checks, if the number of connections for a direction is ok.
156
+ # +dir+:: direction (0 or 1)
157
+ # +n+:: number of desred connections
158
+ #
159
+ def n_connections_ok?( dir, n )
160
+ if @multiplicity[ dir ].is_a?( String ) && @multiplicity[ dir ] == "*"
161
+ return true
162
+ else
163
+ return @multiplicity[ dir ] >= n
164
+ end
165
+ end
166
+
167
+ #
168
+ # Equality operator
169
+ #
170
+ def ==(o)
171
+ o.name == self.name &&
172
+ o.id == self.id &&
173
+ o.ports.to_yaml == self.ports.to_yaml &&
174
+ o.multiplicity.to_yaml == self.multiplicity.to_yaml
175
+ end
176
+ end
177
+ end
178
+
179
+
180
+ # vim: noai:ts=2:sw=2